From f77737db7201a1af423003ba56be3e5feef93c38 Mon Sep 17 00:00:00 2001 From: Glen Whitney Date: Thu, 22 Feb 2024 22:29:42 -0800 Subject: [PATCH] fix: Get generators to work on Chrome; make wrl-only plugin also --- .gitignore | 3 +- etc/manifest.bash | 88 ++++++++++++++++++++++++++++++ etc/{options.html => options.bash} | 19 ++++++- package.json5 | 7 ++- src/giveAwrl.civet | 39 ++++++++++--- src/options.civet | 6 +- tools/makePlugin.bash | 62 +++++++++++++-------- 7 files changed, 184 insertions(+), 40 deletions(-) create mode 100644 etc/manifest.bash rename etc/{options.html => options.bash} (92%) diff --git a/.gitignore b/.gitignore index ca6ef17..c3f96c4 100644 --- a/.gitignore +++ b/.gitignore @@ -3,8 +3,7 @@ tsbuild jsbuild public/js extension -archematics -archematics.zip +archematics* # Editor backups *~ diff --git a/etc/manifest.bash b/etc/manifest.bash new file mode 100644 index 0000000..3245df3 --- /dev/null +++ b/etc/manifest.bash @@ -0,0 +1,88 @@ +# Using bash "here-documents" as quick-and-dirty template files +cat <", + "homepage_url": "https://archematics.app", + "browser_specific_settings": { + "gecko": { + "id": "{8b22a3b8-57f1-45f4-8e87-9043115a8093}", + "update_url": "https://archematics.app/updates.json" + } + }, + "content_scripts": [ +BREAK +if [ "$WHAT" = full ]; then + cat <"], + "resources": [ +BREAK +if [ "$WHAT" = full ]; then + cat < @@ -7,8 +9,8 @@

archematics

-

This plug-in currently has two main capabilities that can be activated - independently:

+

This plug-in currently has the following main capabilities that can + be activated:

Embedded VRML/X3D display

@@ -29,6 +31,9 @@ Encyclopedia of Polyhedra with this module enabled for a trove of beautiful models to play with.

+BREAK +if [ "$WHAT" = full ]; then + cat <JavaScript reinterpretation of Geometry Applets
@@ -52,12 +57,18 @@ Be sure to give archematics a try on his site.

+BREAK +fi +cat <

Debugging-only options

Embedded VRML/X3D display

Write to the JavaScript console:
+BREAK +if [ "$WHAT" = full ]; then + cat <

Java Geometry Applets

Trace the following to the JavaScript console:
@@ -76,8 +87,12 @@
+BREAK +fi +cat < +END diff --git a/package.json5 b/package.json5 index df1f603..fc8b7f7 100644 --- a/package.json5 +++ b/package.json5 @@ -1,6 +1,6 @@ { name: 'archematics', - version: '0.3.0', + version: '0.4.0', description: 'Uncovering lost digital mathematical treasures', scripts: { test: 'echo "Error: no test specified" && exit 1', @@ -14,12 +14,13 @@ // Use the Typescript compiler to create the final .js files: build_js: 'tsc && mkdir -p public/js && cp -r jsbuild/* public/js', build_deps: 'bash tools/copyDeps.bash public/js/deps', - build_plugin: 'bash tools/makePlugin.bash archematics', + build_plugin: 'bash tools/makePlugin.bash archematicsFull full', + build_half: 'bash tools/makePlugin.bash archematics wrl', build: 'pnpm --sequential /build_/', start: 'node public/js', go: 'pnpm --sequential "/build|start/"', serve: 'pnpm build && http-server', - clean: 'rm -rf tsbuild jsbuild public/js archematics archematics.zip', + clean: 'rm -rf tsbuild jsbuild public/js archematics*', }, packageManager: 'pnpm', keywords: [ diff --git a/src/giveAwrl.civet b/src/giveAwrl.civet index 8c3a844..3ae78f6 100644 --- a/src/giveAwrl.civet +++ b/src/giveAwrl.civet @@ -8,6 +8,16 @@ knownExtensions := /[.](?:wrl|x3d|gltf|glb|obj|stl|ply)$/ certainlyHandled := knownExtensions.source.slice(0, -2).split('wrl|')[1].split '|' +// Basic poller, loosely based on +// https://codereview.stackexchange.com/questions/272936/retry-a-callback-function-n-times-until-success +// modified so delay doubles each time +tryN := (tries: number, delay: number, + callback: () => Promise): Promise => + if tries + worked := await callback() + unless worked + setTimeout tryN.bind(this, tries-1, delay*2, callback), delay + function makeBrowser(url: string, width: string, height: string, config: ConfigType) x_ite_rel := 'deps/x_ite/x_ite.mjs' @@ -117,13 +127,16 @@ configPromise.then((config) => madeConway .= false // See if we are on George Hart's Conway-notation generator page - inputs := $('input[type="button"][value="Generate"][onclick="viewVRML()"]') + inputs .= $('input[type="button"][value="Generate"][onclick="viewVRML()"]') if config.vrmlview and inputs.length is 1 // Seems so, fix the generator - // Note that modifying the onclick prop is not the recommended way to - // change button click functionality, but we need to clear out the old - // behavior so I wasn't sure how else to do it - inputs.prop 'onclick', (i, val) => () => + // Remove old button and add new copy: + predecessor := $('input[name="notation"]') + inputs.remove() + predecessor.after('') + inputs = $('input[type="button"][value="Generate"]') + // now add new handler + inputs.on 'click', => import(browser.runtime.getURL('conway.js')).then (conway) => notation := $('input[name="notation"]').val() unless notation then return @@ -144,19 +157,26 @@ configPromise.then((config) => panelFrame := $('frame[name="panel"][src="prism-maker-subpanel.html"]') if config.vrmlview and panelFrame.length is 1 // Seems so, fix the generator - panelFrame.on "load", => + // unfortunately, in Chrome it is necessary to poll + // until the frame is done loading. + tryN 5, 100, => + unless frames[1] return false panelDoc := frames[1].document vrmlDoc := frames[0].document vrmlBody := $('body', vrmlDoc) // Grab the initial text while it is still easy to get + // We are presuming here that the body just contains a single + // text node. That should stay true unless GWH changes the page. textNode := vrmlBody.contents()[0] + unless textNode return false // ask to go again + return := true // OK, this is it initialVrml1: string := textNode.textContent or '' // Now build up the vrml frame as we want it viewerDiv := $('
') $('head').after $('') - $('body').append viewerDiv - // We are presuming here that the body just contains a single - // text node. That should stay true unless GWH changes the page. + newBody := $('body') + newBody[0].style.maxHeight = '310px' + newBody.append viewerDiv initialVrml97 := convert initialVrml1 {canvas, browser3D: prismBrowser} := await makeBrowser '', '300px', '300px', config @@ -172,6 +192,7 @@ configPromise.then((config) => $('input[type="button"][value="View"][onclick="ViewVRML()"]', panelDoc) unless prismBtn.length is 1 return + prismBtn.prop 'onclick', (i, val) => => import(browser.runtime.getURL('prism.js')).then (prism) => numerator := parseInt( diff --git a/src/options.civet b/src/options.civet index bf48c35..6eadd99 100644 --- a/src/options.civet +++ b/src/options.civet @@ -5,7 +5,11 @@ cache := await browser.storage.local.get flags for each box of flags checkbox := document.getElementById(box) as HTMLInputElement unless checkbox then continue - checkbox.checked = cache[box] ?? (box is 'vrmlview' or box is 'joyce') + if box in cache + checkbox.checked = cache[box] + else + checkbox.checked = box is 'vrmlview' or box is 'joyce' + browser.storage.local.set [box]: checkbox.checked document.body.addEventListener 'click', (event) -> elt := event.target as HTMLInputElement diff --git a/tools/makePlugin.bash b/tools/makePlugin.bash index 77ef3cd..66e183b 100644 --- a/tools/makePlugin.bash +++ b/tools/makePlugin.bash @@ -1,43 +1,59 @@ -# Takes one parameter, the destination directory +# Takes two parameters, the destination directory and what to include +# in the plugin: +# full - everything +# wrl - just the wrl viewer +modules="$2" mkdir -p $1/deps/x_ite/assets/images mkdir -p $1/deps/x_ite/assets/components versionLine=$(grep version package.json5) regex="'(.*)'" if [[ $versionLine =~ $regex ]] then - version=${BASH_REMATCH[1]} -fi + version="${BASH_REMATCH[1]}" +fi +# Mark full versions with an extra version number field: +if [ "$modules" = full ] +then + version="${version}.2" +fi echo "Building plugin version $version" -sed "s/<>/$version/" etc/manifest.json > $1/manifest.json -cp etc/options.html $1 +VERSION="$version" WHAT="$modules" bash etc/manifest.bash > $1/manifest.json +WHAT="$modules" bash etc/options.bash > $1/options.html + cp etc/deps/x_ite/x_ite.css $1/deps/x_ite cp etc/deps/x_ite/assets/images/logo.128.png $1/deps/x_ite/assets/images cp etc/deps/x_ite/x_ite.mjs $1/deps/x_ite cp etc/deps/x_ite/assets/components/* $1/deps/x_ite/assets/components - -geoFiles=($(grep deps/GeoGebra etc/manifest.json)) -for spec in "${geoFiles[@]}" -do - quotspec=${spec%,} - trimRspec="${quotspec%\"}" - trimspec="${trimRspec#\"}" - dest=${trimspec%/*} - mkdir -p $1/$dest - cp -r etc/$trimspec $1/$dest -done - npx rollup public/js/giveAwrl.js --dir $1 -npx rollup public/js/adapptlet.js --file $1/adapptlet.js -npx rollup public/js/adapptext.js --file $1/adapptext.js -cp public/js/options.js public/js/adapptypes.js public/js/conway.js $1 -cp public/js/prism.js $1 +cp public/js/options.js public/js/conway.js public/js/prism.js $1 +cp public/js/adapptypes.js $1 + cp node_modules/webextension-polyfill/dist/browser-polyfill.js $1 cp node_modules/@webcomponents/custom-elements/custom-elements.min.js $1 -# Images etc mkdir -p $1/assets cp public/assets/arch*.png $1/assets -cp public/assets/*Example.png $1/assets +cp public/assets/vrmlExample.png $1/assets + +if [ "$modules" = full ] +then + geoFiles=($(grep deps/GeoGebra $1/manifest.json)) + for spec in "${geoFiles[@]}" + do + quotspec=${spec%,} + trimRspec="${quotspec%\"}" + trimspec="${trimRspec#\"}" + dest=${trimspec%/*} + mkdir -p $1/$dest + cp -r etc/$trimspec $1/$dest + done + + npx rollup public/js/adapptlet.js --file $1/adapptlet.js + npx rollup public/js/adapptext.js --file $1/adapptext.js + + cp public/assets/joyceExample.png $1/assets +fi + # Wrap it all up cd $1 zip -r ../$1 *