Integrating OpenJSCAD into MediaWiki - javascript

The current solutions I know of for displaying JSCad Designs:
https://www.openjscad.org/
https://danmarshall.github.io/jscad-gallery/
https://risacher.org/OpenJsCad
https://johnwebbcole.gitlab.io/vesa-shelf/
https://joostn.github.io/OpenJsCad/
https://github.com/jscad/OpenJSCAD.org/blob/V2/packages/web/demo.html
all need quite some infrastructure to work.
https://www.openjscad.org/
is based on node The Userguide
https://www.openjscad.org/dokuwiki/doku.php?id=user_guide_website
states
The website can be integrated into an existing website.
But does not say how.
https://danmarshall.github.io/jscad-gallery/
Has it's sources at https://github.com/danmarshall/jscad-gallery. These were last modified in 2017 (some 2 years ago as of this post).
It use some dozen javascript files and jekyll to fulfill it's purpose.
Example: https://danmarshall.github.io/jscad-gallery/s-hook
The source code of a page is quite small:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>JSCAD Gallery s-hook</title>
<link rel="stylesheet" type="text/css" href="/jscad-gallery/site.css"/>
<script src='/jscad-gallery/browser_modules/#jscad/csg/0.3.7.js' type="text/javascript"></script>
<script src='/jscad-gallery/js/jscad-viewer.js' type="text/javascript"></script>
<script src='/jscad-gallery/js/ui.js' type="text/javascript"></script></head>
<body>
<h1>s-hook</h1>
<p>a simple S-hook design</p>
<div id="detail-viewer"></div>
<div id="inputs"></div>
<button onclick="detailView.export('stl', document.getElementById('download'))">Generate STL</button>
<div id="download"></div>
<script>
var design = {
title: "s-hook",
updated: null,
author: "Joost Nieuwenhuijse",
version: "1.0.0",
dependencies: [{"#jscad/scad-api":"^0.4.2"}],
image: "/browser_modules/s-hook/thumbnail.png",
camera: {"angle":{"x":-60,"y":0,"z":-45},"position":{"x":0,"y":0,"z":116}}
};
var detailView = new JscadGallery.DesignView();
detailView.load(document.getElementById('detail-viewer'), design, document.getElementById('inputs'));
</script>
<footer>
Jscad-gallery on GitHub
</footer>
</body>
</html>
I am looking for a (hopefully) simple solution that can be embedded in Mediawiki. For a start a plain html page with a bit of javascript would do for me.
see also:
https://openjscad.nodebb.com/topic/98/displaying-jscad-designs-in-media-wiki-or-plain-html-for-a-start
For a start I created http://wiki.bitplan.com/index.php/ParametricLampShade by simply copying the html from https://risacher.org/OpenJsCad/lampshadedemo.html.
I put the files:
csg.js
lightgl.js
openjscad.js
into the folder extensions/OpenJsCad.
With this simplistic approach i get the error:
Error in line 466: NetworkError: Failed to load worker script at http://wiki.bitplan.com/index.php/csg.js (nsresult = 0x804b001d)
The reasons seems to be in openjscad.js:
// callback: should be function(error, csg)
OpenJsCad.parseJsCadScriptASync = function(script, mainParameters, options, callback) {
var baselibraries = [
"csg.js",
"openjscad.js"
];
var baseurl = document.location.href.replace(/\?.*$/, '');
var openjscadurl = baseurl;
if (options['openJsCadPath'] != null) {
openjscadurl = OpenJsCad.makeAbsoluteUrl( options['openJsCadPath'], baseurl );
}
var libraries = [];
if (options['libraries'] != null) {
libraries = options['libraries'];
}
...
}
the openjscadurl is taken from the basepath which for Mediawiki is ../index.php.
How could I fix this?
What is the minimum set of javascript files needed and would be the proper versions of these files?

Changing the baseurl calculation to:
//alert(document.location);
var baseurl = document.location.href.replace(/index.php\/.*$/, 'extensions/OpenJsCad/');
//alert(baseurl);
fixed the issue.
See http://wiki.bitplan.com/index.php/ParametricLampShade for the result.
As a proof of concept
http://wiki.bitplan.com/index.php/Template:Jscad now has a Mediawiki Template.
I'd still like to learn about the javascript files and versions that should be used. Since the current approach use some outdated javascript files and can't even render the OpenJSCAD logo code from http://openjscad.org

The 1.10.0 version of https://www.npmjs.com/package/#jscad/web allows you to host a JsCad file with a single package. https://github.com/jscad/OpenJSCAD.org/pull/413
While this doesn't directly help you, I have a Vue component that allows you to show a JsCad file at https://gitlab.com/johnwebbcole/vue-openjscad
You may be able to use that to update your Mediawiki plugin.
J

Related

How to import a blazor custom element in another JS application?

I have a blazor server app, with a registered custom element as below code:
builder.Services.AddServerSideBlazor(options =>
{
options.RootComponents.RegisterAsCustomElement<Counter>("my-blazor-counter");
});
I want to import this blazor custom element in another node.js application to convert it into a lit element(web component).
I have added below scripts in my node.js app
<script src="https://localhost:7075/_framework/blazor.server.js"></script>
<script src="https://localhost:7075/_content/Microsoft.AspNetCore.Components.CustomElements/BlazorCustomElements.js"></script>
but while initializing the Blazor it still using node app port and failing while initialization.
I am not sure I am missing anything here or if there is any other way to do it.
The following describes how I resolved an issue similar to yours: trying to register a custom element, the client not rendering the component and no error message anywhere.
I followed the instructions but the there was nothing happening client-side. After inspecting the websocket's traffic using Firefox I ran into the following message from the client to the server (slightly edited for readability):
ùÀµEndInvokeJSFromDotNetÂÚÙ[
2,
false,
"Could not find 'registerBlazorCustomElement' ('registerBlazorCustomElement' was undefined).
findFunction/<#https://localhost:5001/_framework/blazor.server.js:1:497
findFunction#https://localhost:5001/_framework/blazor.server.js:1:465
E#https://localhost:5001/_framework/blazor.server.js:1:2606
attachWebRendererInterop/<#https://localhost:5001/_framework/blazor.server.js:1:33097
attachWebRendererInterop#https://localhost:5001/_framework/blazor.server.js:1:33145
beginInvokeJSFromDotNet/s<#https://localhost:5001/_framework/blazor.server.js:1:3501
beginInvokeJSFromDotNet#https://localhost:5001/_framework/blazor.server.js:1:3475
_invokeClientMethod/<#https://localhost:5001/_framework/blazor.server.js:1:71894
_invokeClientMethod#https://localhost:5001/_framework/blazor.server.js:1:71880
_processIncomingData#https://localhost:5001/_framework/blazor.server.js:1:69922
kt/this.connection.onreceive#https://localhost:5001/_framework/blazor.server.js:1:64322
connect/</o.onmessage#https://localhost:5001/_framework/blazor.server.js:1:48638
EventHandlerNonNull*connect/<#https://localhost:5001/_framework/blazor.server.js:1:48489
connect#https://localhost:5001/_framework/blazor.server.js:1:48005
_startTransport#https://localhost:5001/_framework/blazor.server.js:1:57626
_createTransport#https://localhost:5001/_framework/blazor.server.js:1:56195
_startInternal#https://localhost:5001/_framework/blazor.server.js:1:54044
async*start#https://localhost:5001/_framework/blazor.server.js:1:51309
_startInternal#https://localhost:5001/_framework/blazor.server.js:1:66198
_startWithStateTransitions#https://localhost:5001/_framework/blazor.server.js:1:65598
start#https://localhost:5001/_framework/blazor.server.js:1:65262
Gn#https://localhost:5001/_framework/blazor.server.js:1:129904
Yn#https://localhost:5001/_framework/blazor.server.js:1:127771
async*#https://localhost:5001/_framework/blazor.server.js:1:131523
#https://localhost:5001/_framework/blazor.server.js:1:131529
"
]
In my case it was that I hadn't added <script src="/_content/Microsoft.AspNetCore.Components.CustomElements/BlazorCustomElements.js"></script> to the html.
I was struggling to get this working for a Blazor serverside app. I created a test.html page in the wwwroot of the blazor project.
The fix for me was to specify the base url.
My html looks like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- my component is here -->
<blazor-counter></blazor-counter>
<base href="http://localhost:5144">
</head>
<body>
<script src="_framework/blazor.server.js"></script>
</body>
</html>

How do I access an array stored in a .js file from a ReactJs .html file?

Okay, I've tried to figure this one out on my own and I just can't. I'm making a loot logging web app for a game I play online. The web app is hosted on pythonanywhere. It's coded in ReactJS in the main html file entirely so no databases or anything like that. I store loot tables for different monsters in an array like
var monsterName = [
["item 1 name", [#,#,#], id],
["item 2 name", [#], id]
];
Etc... The loot arrays are a lot longer than that but you get the idea. I had the code working properly to use these arrays for grabbing item names and image paths and all. I figured if I was going to add more monsters now that my code worked, I should relocate these arrays to a separate file. I called this file 'droptables.js'. I saved it in the same directory as the main html file so it would be easy to find it. I then named an array in the main html script tags (where all of the Reactjs code is) like this
lootTable = monsterName;
I tried and tried to use various methods to export it from the .js file and import it into the html file, and none work.
import monsterName from './droptables.js';
coupled with
exports.monsterName = [array info]
I tried
module.exports = monsterName;
export default monsterName;
I tried importing in the header of the html instead like
<script src="./droptables.js" />
I haven't listed every attempt here because I tried several different paths too thinking maybe that was it
'/droptables.js'
'droptables.js'
'droptables'
'/templates/droptables.js'
You get the idea. Hopefully someone out there can help me figure this out. It's one of the last roadblocks I have before my app is complete at least in the base functionality sense and it's driving me crazy that I can't get this solved. Thank you for any help!
EDIT: I added the beginning of my HTML/React sheet below so you can see what it looks like and where I'm trying to import.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>LootLogger Webapp 1.1</title>
<link rel="stylesheet" type="text/css" href="/static/css/main.css">
<script src="react url"></script>
<script src="react url"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-
core/5.8.34/browser.min.js"></script>
</head>
<body>
<div id="container"></div>
<script type="text/babel">
import abyssalDemon from './droptables.js';
var monsterLoot = abyssalDemon;
var LootEntry = React.createClass({
render: function() {
return (
<div>{this.props.children}</div>
);
}
});
As you can see, abyssalDemon is what I named my array in the other javascript file, monsterLoot is the array I use in the actual code here on the html sheet, so I need monsterLoot to equal abyssalDemon from the other js file for everything to work. LootEntry is just the first React component I make, it's an entry in the list of loots the user has logged.
Okay, I figured out how to do it a different way without using required and instead using Jquery. I modified my original html document like the following.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>LootLogger Webapp 1.1</title>
<link rel="stylesheet" type="text/css" href="/static/css/main.css">
<script src="react url"></script>
<script src="react url"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-
core/5.8.34/browser.min.js"></script>
<script
src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"
type="text/javascript"></script>
</head>
<body>
<div id="container"></div>
<script type='text/javascript' src='/static/javascript/droptables.js'>
</script>
<script type="text/javascript">
var monsterLoot = new Array();
$(document).ready(function () {
monsterLoot = AbyssalDemon;
});
</script>
<script type="text/babel">
var LootEntry = React.createClass({
render: function() {
return (
<div>{this.props.children}</div>
);
}
});
I added the import of Jquery in the header tags. I also added a tag in my body to reference my droptables.js file. Finally, I added a the Jquery function to make my monsterLoot array equal to the AbyssalDemon array from the external js file. I did this in a document ready function because I believe part of my problem was my page was trying to generate my buttons before the monsterLoot array had been imported so it was throwing an error because the array was undefined. At least that's my guess. It works now though!

Embed markdown (md) into HTML

I need help embedding a markdown, or *.md, file inside of an HTML index file. I have found that I can embed HTML inside of markdown, but not vice-versa. This would help to increase the speed of my editing because markdown format is extremely easy to use, (as I'm using it now) and I don't have to change the format of the rest of my site. I know that something like this is done to embed another HTML file with <iframe src="path/to/html>html-name</iframe>. I could also use javascript to interpret the md format on page load. Thanks ahead of time.
Here's the solution that I have long since forgotten about:
Forgetting that I asked this question and getting no answers, I created my own solution as an extension off of Chris Jeffrey's marked.js.
I call it tagdown.js.
Here it is: http://spikespaz.com/tagdownjs/
Just in case that link, or my domain, expires: https://spikespaz.github.io/tagdownjs/
Github: https://github.com/spikespaz/tagdownjs
This allows markdown to be added directly to the site, within a tag set with the class markdown. See the example on the site. There is no theme system in it, it's just the markdown parser.
Update
The project, TagdownJS, has been deleted from Github. The code for it seems so simple that it doesn't deserve its own repository.
Until it finds a new home, just go find Christopher Jeffery's Marked.js, and use this following code with it.
document.body.style.display = "none"; // Hide the page until it's finished rendering.
document.createElement("markdown");
var md_tags = document.getElementsByTagName("markdown"); // Returns array of all markdown tags.
for (var i = 0; i < md_tags.length; i++) { // Iterate through all the tags, and generate the HTML.
var md_text = md_tags[i].textContent.replace(/^[^\S\n]+/mg, ""); // I love regex, so shoot me.
var md_div = document.createElement("div"); // Make a new div to replace the fake tag.
md_div.id = "content";
md_div.innerHTML = marked(md_text);
md_tags[i].parentNode.appendChild(md_div); // Add remove the old raw markdown.
md_tags[i].parentNode.removeChild(md_tags[i]);
}
document.body.style.display = ""; // Show the rendered page.
https://github.com/zhlicen/md.htm An example of zeromd.js Just serve the md.htm file and md files, and visit directly by url:
/md.htm?src=README.md
Live demo: https://b.0-0.plus/blog/md.htm?src=https://raw.githubusercontent.com/microsoft/vscode/main/README.md
Basicly, you need to interpret MD format into HTML. Javascript is an option.
Take below as an example. (Though Windows, independent of OS)
Let's say a folder mytest looks like,
D:\mytest>dir
Volume in drive D is Data
Volume Serial Number is ABCD-EFGH
Directory of D:\mytest
12/03/2020 10:10 AM <DIR> .
12/03/2020 10:10 AM <DIR> ..
12/03/2020 10:09 AM 7,973 example-image.jpg
12/03/2020 10:12 AM 4,619 md_html.html
12/03/2020 10:00 AM 2,299 md_html.min.js
3 File(s) 14,891 bytes
2 Dir(s) 778,204,147,712 bytes free
D:\mytest>
Here is the html content,
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<link rel="stylesheet" href="https://cdn.bootcss.com/highlight.js/9.12.0/styles/atom-one-light.min.css" />
<link rel="stylesheet" href="https://cdn.bootcss.com/github-markdown-css/2.8.0/github-markdown.min.css" />
<title>Marked In HTML</title>
</head>
<body>
<template type="markdown">
Try Marked In HTML !
====
</template>
</body>
<script src="https://cdn.bootcss.com/marked/0.3.6/marked.min.js" charset="utf-8"></script>
<script src="https://cdn.bootcss.com/highlight.js/9.12.0/highlight.min.js" charset="utf-8"></script>
<script src="https://cdn.bootcss.com/highlight.js/9.12.0/languages/javascript.min.js" charset="utf-8"></script>
<script src="md_html.min.js" charset="utf-8"></script>
<script type="text/javascript">
markedInHtml.init()
</script>
</html>
And the js,
!function(n){function t(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return n[r].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var e={};t.m=n,t.c=e,t.i=function(n){return n},t.d=function(n,e,r){t.o(n,e)||Object.defineProperty(n,e,{configurable:!1,enumerable:!0,get:r})},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},t.p="",t(t.s=1)}([function(n,t,e){"use strict";function r(n){return n&&n.__esModule?n:{default:n}}function i(n){if(Array.isArray(n)){for(var t=0,e=Array(n.length);t<n.length;t++)e[t]=n[t];return e}return Array.from(n)}function a(n,t){if(!(n instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0}),t.MarkedInHtml=void 0;var o=function(){function n(n,t){for(var e=0;e<t.length;e++){var r=t[e];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(n,r.key,r)}}return function(t,e,r){return e&&n(t.prototype,e),r&&n(t,r),t}}(),u=e(3),l=r(u),s=e(2),c=r(s);t.MarkedInHtml=function(){function n(){a(this,n),l.default.setOptions(this.options||{gfm:!0,tables:!0,breaks:!1,pedantic:!1,sanitize:!1,smartLists:!0,smartypants:!1,highlight:function(n,t,e){return c.default.highlightAuto(n).value}})}return o(n,[{key:"init",value:function(){var n=this;document.querySelectorAll('template[type="markdown"]').forEach(function(t){var e=document.createElement("div");e.innerHTML=n.parse(t),e.id=t.id,e.classList.add(["markdown-body"].concat(i(Array.from(t.classList)))),e.dataset.markdown=n.intelligentProcessingIndent(t),t.parentElement.replaceChild(e,t)})}},{key:"parse",value:function(n){return(0,l.default)(this.intelligentProcessingIndent(n))}},{key:"intelligentProcessingIndent",value:function(n){var t=n.innerHTML.split("\n");t.length&&/^\s*$/.test(t[0])&&t.shift(),t.length&&/^\s*$/.test(t[t.length-1])&&t.pop();var e=Math.min.apply(Math,i(t.map(function(n){return n.length?n.match(/^\s*/)[0].length:1/0})));return t.map(function(n){return n.substring(e)}).join("\n")}}]),n}()},function(n,t,e){"use strict";var r=e(0);window&&(window.markedInHtml=new r.MarkedInHtml)},function(n,t){n.exports=hljs},function(n,t){n.exports=marked}]);
And the jpg,
After open the html, you should be able to convert
Try Marked In HTML !
====
into
You can try to replace the template, some effect may not be able to present. For example, use quick markdown example by John Gabriele, the equation are not shown well.
Someone, like 🎅 would suggest to use snippet, yet I failed to get that ❄️ work, parsing not successful. 🥺

Compile LESS on the client side?

I'm new to LESS. I'm trying to compile less on the client side. I found an article that says to use the below script.
<script src="http://lesscss.googlecode.com/files/less-1.0.30.min.js">
</script>
But when I include it in my html (after the .less file) and open my local file in Chrome. The developer console says: http://lesscss.googlecode.com/files/less-1.0.30.min.js 404 (Not Found)
you can download the latest release from https://github.com/less/less.js/archive/v2.5.1.zip
or
https://raw.githubusercontent.com/less/less.js/master/dist/less.min.js
minified : https://raw.githubusercontent.com/less/less.js/master/dist/less.min.js
Updated
you have to use you own local server because some browsers will prevent .less serving from file:// protocol
To use your own server
Install Node
npm install http-server -g
then go to you folder using your console
http-server
now you can use http://localhost:8080 as your own server and .less will work
You want to compile on your local machine, then push the compiled file up to the server. And then you want to make sure that your CSS file references that compiled file.
The LESS docs recommend this java script to compile on your computer: http://lesscss.org/#download-options-browser-downloads
Or you can do the compile on client side approach, but you should update your script to use <script src="//cdnjs.cloudflare.com/ajax/libs/less.js/2.5.1/less.min.js"></script>, the CDN link from their site.
I'd still urge you to compile on your local machine, as this saves lots of precious time that your page would be without any styles. This article sums up other ways to go about a more robust build process.
Refer to the docs for usage. Download the less.js file and refer to it using <script src="less.js" type="text/javascript"></script>.
I made the example already mentioned using the link tag, but I also leave the example with the style tag that makes testing in development much easier.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSS -->
<!-- example with link tag -->
<link href="css/app.less" rel="stylesheet/less">
<!-- example with style tag -->
<style type="text/less">
html {
body {
background-color: red;
}
}
</style>
<!-- JS -->
<!-- The library automatically converts <link> tags -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/less.js/4.1.3/less.min.js"></script>
<!-- Convert style tags -->
<script>
const lessStyles = document.querySelectorAll('style[type="text/less"]')
lessStyles.forEach(styleElement => {
const lessCode = styleElement.innerText
less.render(lessCode, (error, output) => {
const cssCode = output.css
styleElement.innerText = cssCode
styleElement.setAttribute('type', 'text/css')
})
})
</script>
</head>
<body></body>
</html>
// Convert style tags
const lessStyles = document.querySelectorAll('style[type="text/less"]')
lessStyles.forEach(styleElement => {
const lessCode = styleElement.innerText
less.render(lessCode, (error, output) => {
const cssCode = output.css
styleElement.innerText = cssCode
styleElement.setAttribute('type', 'text/css')
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/less.js/4.1.3/less.min.js"></script>
<head>
<!-- example with link tag -->
<link href="css/app.less" rel="stylesheet/less">
<!-- example with style tag -->
<style type="text/less">
html {
body {
background-color: red;
}
}
</style>
</head>

merge jquery-1.9.1.min.js and query.mobile-1.3.0.min.js in a single file give error

I'm developing a jquery mobile webapp
The base structure require jquery.js and jquery-mobile.js ad documented in jqueryMobile doc.
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.css" />
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="myjqueryconfig.js"></script>
<script src="http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.js"></script>
</head>
All works good with this structure but I want to merge jquery js file with jquery-mobile js file to have a single js file but when I do that (simply by cut and pust jquery mobile code to the end of jquery file) page stop working and firebug give me a javascript error:
TypeError: $(...).bind(...) is not a function
My single .js file is structured as:
//jquery 1.9.1 min source code
$(document).bind("mobileinit", function(){
$.mobile.autoInitializePage = false
})
//jquery mobile min 1.3.0 source code
Adding a ; between the files when concatenating them solves the problem.
Look at this code :
(function(){
console.log('A');
}())
(function(){
console.log('B');
}())
Without an intermediary semicolon, the second IIFE looks like an argument passed to the first one. And so it fails. Adding the semicolon solves the problem as it specifies those are two statements.
Semicolons in JavaScript are optional but it's very dangerous to omit them.

Categories

Resources