fix: Get generators to work on Chrome; make wrl-only plugin also

This commit is contained in:
Glen Whitney 2024-02-22 22:29:42 -08:00
parent c895f2d30f
commit f77737db72
7 changed files with 184 additions and 40 deletions

3
.gitignore vendored
View File

@ -3,8 +3,7 @@ tsbuild
jsbuild jsbuild
public/js public/js
extension extension
archematics archematics*
archematics.zip
# Editor backups # Editor backups
*~ *~

88
etc/manifest.bash Normal file
View File

@ -0,0 +1,88 @@
# Using bash "here-documents" as quick-and-dirty template files
cat <<BREAK
{
"manifest_version": 3,
"name": "archematics",
"version": "${VERSION}",
"description": "unearths mathematical treasures lost in the web",
"icons": {
"48": "assets/archIcon48.png",
"128": "assets/archIcon128.png",
"256": "assets/archIcon256.png"
},
"author": "Glen Whitney <glen@archematics.app>",
"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 <<BREAK
{
"matches": ["*://*/*"],
"js": ["browser-polyfill.js", "adapptext.js"],
"run_at": "document_start"
},
BREAK
fi
cat <<BREAK
{
"matches": ["*://*/*"],
"js": [
"browser-polyfill.js",
"custom-elements.min.js",
"giveAwrl.js"
]
}
],
"options_ui": {
"page": "options.html",
"browser_style": false
},
"permissions": ["storage"],
"web_accessible_resources": [{
"matches": ["<all_urls>"],
"resources": [
BREAK
if [ "$WHAT" = full ]; then
cat <<BREAK
"adapptlet.js",
"adapptypes.js",
"deps/GeoGebra/deployggb.js",
"deps/GeoGebra/HTML5/5.0/webSimple/4B19686283BEF852F4C88C93522FB9A3.cache.js",
"deps/GeoGebra/HTML5/5.0/webSimple/webSimple.nocache.js",
"deps/GeoGebra/HTML5/5.0/webSimple/clear.cache.gif",
"deps/GeoGebra/HTML5/5.0/webSimple/deferredjs/*",
"deps/GeoGebra/HTML5/5.0/web3d/web3d.nocache.js",
"deps/GeoGebra/HTML5/5.0/web3d/clear.cache.gif",
"deps/GeoGebra/HTML5/5.0/web3d/289547CDA192E4FE9BAED5FF003E2ACE.cache.js",
"deps/GeoGebra/HTML5/5.0/web3d/deferredjs/*",
"deps/GeoGebra/HTML5/5.0/css/bundles/bundle.css",
"deps/GeoGebra/HTML5/5.0/css/keyboard-styles.css",
"deps/GeoGebra/HTML5/5.0/css/fonts.css",
"deps/GeoGebra/HTML5/5.0/css/greek-font.css",
"deps/GeoGebra/HTML5/5.0/css/bundles/simple-bundle.css",
"deps/GeoGebra/HTML5/5.0/web3d/fonts/base/jlm_cmmi10.js",
BREAK
fi
cat <<END
"deps/x_ite/x_ite.mjs",
"deps/x_ite/x_ite.css",
"deps/x_ite/assets/components/EventUtilities.js",
"deps/x_ite/assets/components/Geometry2D.js",
"deps/x_ite/assets/components/KeyDeviceSensor.js",
"deps/x_ite/assets/components/Scripting.js",
"deps/x_ite/assets/components/Text.js",
"deps/x_ite/assets/images/logo.128.png",
"conway.js",
"options.js",
"prism.js"
]
}]
}
END

View File

@ -1,3 +1,5 @@
# Using bash "here-documents" as quick-and-dirty template files
cat <<BREAK
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
@ -7,8 +9,8 @@
<body> <body>
<h2>archematics</h2> <h2>archematics</h2>
<p>This plug-in currently has two main capabilities that can be activated <p>This plug-in currently has the following main capabilities that can
independently:</p> be activated:</p>
<h2>Embedded VRML/X3D display</h2> <h2>Embedded VRML/X3D display</h2>
<div style="float: right;margin: 1.5em;"> <div style="float: right;margin: 1.5em;">
<label for="vrmlview">Enable</label> <label for="vrmlview">Enable</label>
@ -29,6 +31,9 @@
<a href="http://georgehart.com/virtual-polyhedra/vp.html"> <a href="http://georgehart.com/virtual-polyhedra/vp.html">
Encyclopedia of Polyhedra</a> with this module enabled for a trove of Encyclopedia of Polyhedra</a> with this module enabled for a trove of
beautiful models to play with.</p> beautiful models to play with.</p>
BREAK
if [ "$WHAT" = full ]; then
cat <<BREAK
<h2>JavaScript reinterpretation of Geometry Applets</h2> <h2>JavaScript reinterpretation of Geometry Applets</h2>
<div style="float: right;margin: 1.5em;"> <div style="float: right;margin: 1.5em;">
<label for="joyce">Enable</label><input type="checkbox" id="joyce"> <label for="joyce">Enable</label><input type="checkbox" id="joyce">
@ -52,12 +57,18 @@
Be sure to give archematics a try on Be sure to give archematics a try on
<a href="https://mathcs.clarku.edu/~djoyce/java/elements/bookI/propI47.html"> <a href="https://mathcs.clarku.edu/~djoyce/java/elements/bookI/propI47.html">
his site</a>.</p> his site</a>.</p>
BREAK
fi
cat <<BREAK
<hr/> <hr/>
<h3>Debugging-only options</h3> <h3>Debugging-only options</h3>
<h4>Embedded VRML/X3D display</h4> <h4>Embedded VRML/X3D display</h4>
Write to the JavaScript console: <br/> Write to the JavaScript console: <br/>
<label for="vrml97">Generated VRML97 specifications</label> <label for="vrml97">Generated VRML97 specifications</label>
<input type="checkbox" id="vrml97"> <input type="checkbox" id="vrml97">
BREAK
if [ "$WHAT" = full ]; then
cat <<BREAK
<br /> <br />
<h4>Java Geometry Applets</h4> <h4>Java Geometry Applets</h4>
Trace the following to the JavaScript console: <br/> Trace the following to the JavaScript console: <br/>
@ -76,8 +87,12 @@
<br/> <br/>
<label for="algebra">Show the GeoGebra algebra pane</label> <label for="algebra">Show the GeoGebra algebra pane</label>
<input type="checkbox" id="algebra"> <input type="checkbox" id="algebra">
BREAK
fi
cat <<END
<script src="browser-polyfill.js" type="module"></script> <script src="browser-polyfill.js" type="module"></script>
<script src="options.js" type="module"></script> <script src="options.js" type="module"></script>
</body> </body>
</html> </html>
END

View File

@ -1,6 +1,6 @@
{ {
name: 'archematics', name: 'archematics',
version: '0.3.0', version: '0.4.0',
description: 'Uncovering lost digital mathematical treasures', description: 'Uncovering lost digital mathematical treasures',
scripts: { scripts: {
test: 'echo "Error: no test specified" && exit 1', test: 'echo "Error: no test specified" && exit 1',
@ -14,12 +14,13 @@
// Use the Typescript compiler to create the final .js files: // Use the Typescript compiler to create the final .js files:
build_js: 'tsc && mkdir -p public/js && cp -r jsbuild/* public/js', build_js: 'tsc && mkdir -p public/js && cp -r jsbuild/* public/js',
build_deps: 'bash tools/copyDeps.bash public/js/deps', 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_/', build: 'pnpm --sequential /build_/',
start: 'node public/js', start: 'node public/js',
go: 'pnpm --sequential "/build|start/"', go: 'pnpm --sequential "/build|start/"',
serve: 'pnpm build && http-server', 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', packageManager: 'pnpm',
keywords: [ keywords: [

View File

@ -8,6 +8,16 @@ knownExtensions := /[.](?:wrl|x3d|gltf|glb|obj|stl|ply)$/
certainlyHandled := certainlyHandled :=
knownExtensions.source.slice(0, -2).split('wrl|')[1].split '|' 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<boolean>): Promise<void> =>
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, function makeBrowser(url: string, width: string, height: string,
config: ConfigType) config: ConfigType)
x_ite_rel := 'deps/x_ite/x_ite.mjs' x_ite_rel := 'deps/x_ite/x_ite.mjs'
@ -117,13 +127,16 @@ configPromise.then((config) =>
madeConway .= false madeConway .= false
// See if we are on George Hart's Conway-notation generator page // 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 if config.vrmlview and inputs.length is 1
// Seems so, fix the generator // Seems so, fix the generator
// Note that modifying the onclick prop is not the recommended way to // Remove old button and add new copy:
// change button click functionality, but we need to clear out the old predecessor := $('input[name="notation"]')
// behavior so I wasn't sure how else to do it inputs.remove()
inputs.prop 'onclick', (i, val) => () => predecessor.after('<input type="button" value="Generate">')
inputs = $('input[type="button"][value="Generate"]')
// now add new handler
inputs.on 'click', =>
import(browser.runtime.getURL('conway.js')).then (conway) => import(browser.runtime.getURL('conway.js')).then (conway) =>
notation := $('input[name="notation"]').val() notation := $('input[name="notation"]').val()
unless notation then return unless notation then return
@ -144,19 +157,26 @@ configPromise.then((config) =>
panelFrame := $('frame[name="panel"][src="prism-maker-subpanel.html"]') panelFrame := $('frame[name="panel"][src="prism-maker-subpanel.html"]')
if config.vrmlview and panelFrame.length is 1 if config.vrmlview and panelFrame.length is 1
// Seems so, fix the generator // 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 panelDoc := frames[1].document
vrmlDoc := frames[0].document vrmlDoc := frames[0].document
vrmlBody := $('body', vrmlDoc) vrmlBody := $('body', vrmlDoc)
// Grab the initial text while it is still easy to get // 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] textNode := vrmlBody.contents()[0]
unless textNode return false // ask to go again
return := true // OK, this is it
initialVrml1: string := textNode.textContent or '' initialVrml1: string := textNode.textContent or ''
// Now build up the vrml frame as we want it // Now build up the vrml frame as we want it
viewerDiv := $('<div></div>') viewerDiv := $('<div></div>')
$('head').after $('<body></body>') $('head').after $('<body></body>')
$('body').append viewerDiv newBody := $('body')
// We are presuming here that the body just contains a single newBody[0].style.maxHeight = '310px'
// text node. That should stay true unless GWH changes the page. newBody.append viewerDiv
initialVrml97 := convert initialVrml1 initialVrml97 := convert initialVrml1
{canvas, browser3D: prismBrowser} := {canvas, browser3D: prismBrowser} :=
await makeBrowser '', '300px', '300px', config await makeBrowser '', '300px', '300px', config
@ -172,6 +192,7 @@ configPromise.then((config) =>
$('input[type="button"][value="View"][onclick="ViewVRML()"]', $('input[type="button"][value="View"][onclick="ViewVRML()"]',
panelDoc) panelDoc)
unless prismBtn.length is 1 return unless prismBtn.length is 1 return
prismBtn.prop 'onclick', (i, val) => => prismBtn.prop 'onclick', (i, val) => =>
import(browser.runtime.getURL('prism.js')).then (prism) => import(browser.runtime.getURL('prism.js')).then (prism) =>
numerator := parseInt( numerator := parseInt(

View File

@ -5,7 +5,11 @@ cache := await browser.storage.local.get flags
for each box of flags for each box of flags
checkbox := document.getElementById(box) as HTMLInputElement checkbox := document.getElementById(box) as HTMLInputElement
unless checkbox then continue 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) -> document.body.addEventListener 'click', (event) ->
elt := event.target as HTMLInputElement elt := event.target as HTMLInputElement

View File

@ -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/images
mkdir -p $1/deps/x_ite/assets/components mkdir -p $1/deps/x_ite/assets/components
versionLine=$(grep version package.json5) versionLine=$(grep version package.json5)
regex="'(.*)'" regex="'(.*)'"
if [[ $versionLine =~ $regex ]] if [[ $versionLine =~ $regex ]]
then then
version=${BASH_REMATCH[1]} version="${BASH_REMATCH[1]}"
fi
# Mark full versions with an extra version number field:
if [ "$modules" = full ]
then
version="${version}.2"
fi fi
echo "Building plugin version $version" echo "Building plugin version $version"
sed "s/<<FROM_PACKAGE_JSON>>/$version/" etc/manifest.json > $1/manifest.json VERSION="$version" WHAT="$modules" bash etc/manifest.bash > $1/manifest.json
cp etc/options.html $1 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/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/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/x_ite.mjs $1/deps/x_ite
cp etc/deps/x_ite/assets/components/* $1/deps/x_ite/assets/components 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/giveAwrl.js --dir $1
npx rollup public/js/adapptlet.js --file $1/adapptlet.js cp public/js/options.js public/js/conway.js public/js/prism.js $1
npx rollup public/js/adapptext.js --file $1/adapptext.js cp public/js/adapptypes.js $1
cp public/js/options.js public/js/adapptypes.js public/js/conway.js $1
cp public/js/prism.js $1
cp node_modules/webextension-polyfill/dist/browser-polyfill.js $1 cp node_modules/webextension-polyfill/dist/browser-polyfill.js $1
cp node_modules/@webcomponents/custom-elements/custom-elements.min.js $1 cp node_modules/@webcomponents/custom-elements/custom-elements.min.js $1
# Images etc
mkdir -p $1/assets mkdir -p $1/assets
cp public/assets/arch*.png $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 # Wrap it all up
cd $1 cd $1
zip -r ../$1 * zip -r ../$1 *