feat: Improve options page and add toggles for the two main features.
This commit is contained in:
parent
b74921341c
commit
f327152309
@ -1,10 +1,16 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
"name": "archematics",
|
"name": "archematics",
|
||||||
"version": "0.1",
|
"version": "1.0",
|
||||||
|
|
||||||
"description": "unearths mathematical treasures lost in the web.",
|
|
||||||
|
|
||||||
|
"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",
|
||||||
"content_scripts": [
|
"content_scripts": [
|
||||||
{
|
{
|
||||||
"matches": ["*://*/*"],
|
"matches": ["*://*/*"],
|
||||||
|
@ -6,7 +6,54 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<h3>Debugging</h3>
|
<h2>archematics</h2>
|
||||||
|
<p>This plug-in currently has two main capabilities that can be activated
|
||||||
|
independently:</p>
|
||||||
|
<h2>Embedded VRML/X3D display</h2>
|
||||||
|
<div style="float: right;margin: 1.5em;">
|
||||||
|
<label for="vrmlview">Enable</label>
|
||||||
|
<input type="checkbox" id="vrmlview"></div>
|
||||||
|
<div style="float: left;margin: 1em;">
|
||||||
|
<a href="http://www.wiley.com/legacy/compbooks/vrml2sbk/ch14/14fig04a.htm">
|
||||||
|
<img src="assets/vrmlExample.png" width="160px"></a></div>
|
||||||
|
<p>Scans web pages for links (in text or images) to VRML or X3D files
|
||||||
|
(and other file formats compatible with the
|
||||||
|
<a href="https://create3000.github.io/x_ite/tutorials/how-to-navigate-in-a-scene/">
|
||||||
|
X_ITE X3D Browser</a>, such as glTF, obj, and STL) and inserts
|
||||||
|
"eye-cons" (👁) next to each of them. When you click the eye, it embeds
|
||||||
|
a viewer and displays the model in 3D within the page. Right-click on an
|
||||||
|
active viewer for additional options. Click the eye again
|
||||||
|
to close the viewer. Supports multiple simultaneous viewers on the same
|
||||||
|
page.</p>
|
||||||
|
<p> Be sure to visit George Hart's
|
||||||
|
<a href="http://georgehart.com/virtual-polyhedra/vp.html">
|
||||||
|
Encyclopedia of Polyhedra</a> with this module enabled for a trove of
|
||||||
|
beautiful models to play with.</p>
|
||||||
|
<h2>JavaScript reinterpretation of Geometry Applets</h2>
|
||||||
|
<div style="float: right;margin: 1.5em;">
|
||||||
|
<label for="joyce">Enable</label><input type="checkbox" id="joyce">
|
||||||
|
</div>
|
||||||
|
<div style="float: left;margin: 1em;">
|
||||||
|
<a href="https://mathcs.clarku.edu/~djoyce/java/Geometry/eulerline.html">
|
||||||
|
<img src="assets/joyceExample.png" width="150px"></a></div>
|
||||||
|
<p>In the late 1990s, <a href="https://mathcs.clarku.edu/~djoyce/">
|
||||||
|
David Joyce</a> wrote a web applet in Java that allowed for interactive
|
||||||
|
draggable 2D and 3D geometry diagrams within a page. Nearly 30 years on,
|
||||||
|
Java is no longer supported for embedded applets by any major browser. This
|
||||||
|
module scans web pages for invocations of that Java applet, and translates
|
||||||
|
them into calls to the
|
||||||
|
<a href="https://wiki.geogebra.org/en/Reference:GeoGebra_Apps_Embedding">
|
||||||
|
GeoGebra JavaScript module</a>, bringing the diagrams back to life.</p>
|
||||||
|
<p>What's more, Joyce posted an
|
||||||
|
<a href="https://mathcs.clarku.edu/~djoyce/java/elements/elements.html">
|
||||||
|
on-line version</a> of the <strong>entire</strong>
|
||||||
|
Euclid's <em>Elements</em> with all of the traditional diagrams, and many
|
||||||
|
new ones of his own creation, rendered in fully interactive versions.
|
||||||
|
Be sure to give archematics a try on
|
||||||
|
<a href="https://mathcs.clarku.edu/~djoyce/java/elements/bookI/propI47.html">
|
||||||
|
his site</a>.</p>
|
||||||
|
<hr/>
|
||||||
|
<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>
|
||||||
|
BIN
public/assets/archIcon128.png
Normal file
BIN
public/assets/archIcon128.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 39 KiB |
BIN
public/assets/archIcon256.png
Normal file
BIN
public/assets/archIcon256.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 161 KiB |
BIN
public/assets/archIcon48.png
Normal file
BIN
public/assets/archIcon48.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.2 KiB |
BIN
public/assets/joyceExample.png
Normal file
BIN
public/assets/joyceExample.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 119 KiB |
BIN
public/assets/vrmlExample.png
Normal file
BIN
public/assets/vrmlExample.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
@ -26,9 +26,9 @@ obs := new MutationObserver (mutationList) =>
|
|||||||
width: parseInt(newNode.getAttribute('width') ?? '200'),
|
width: parseInt(newNode.getAttribute('width') ?? '200'),
|
||||||
height: parseInt(newNode.getAttribute('height') ?? '200') }
|
height: parseInt(newNode.getAttribute('height') ?? '200') }
|
||||||
|
|
||||||
config := childList: true, subtree: true
|
observerConfig := childList: true, subtree: true
|
||||||
|
|
||||||
obs.observe document.documentElement, config
|
obs.observe document.documentElement, observerConfig
|
||||||
|
|
||||||
function addScriptTag(url: string, params = '', module = false)
|
function addScriptTag(url: string, params = '', module = false)
|
||||||
return new Promise (resolve, reject) =>
|
return new Promise (resolve, reject) =>
|
||||||
@ -41,6 +41,8 @@ function addScriptTag(url: string, params = '', module = false)
|
|||||||
document.head.appendChild script
|
document.head.appendChild script
|
||||||
|
|
||||||
document.addEventListener "DOMContentLoaded", async =>
|
document.addEventListener "DOMContentLoaded", async =>
|
||||||
|
config := await browser.storage.local.get(flags) as ConfigType
|
||||||
|
unless config.joyce return
|
||||||
finalJoyceApplets := document.querySelectorAll "applet[code='Geometry']"
|
finalJoyceApplets := document.querySelectorAll "applet[code='Geometry']"
|
||||||
if finalJoyceApplets.length
|
if finalJoyceApplets.length
|
||||||
joyceApplets = []
|
joyceApplets = []
|
||||||
@ -58,7 +60,6 @@ document.addEventListener "DOMContentLoaded", async =>
|
|||||||
width: parseInt(jApp.getAttribute('width') ?? '200'),
|
width: parseInt(jApp.getAttribute('width') ?? '200'),
|
||||||
height: parseInt(jApp.getAttribute('height') ?? '200') }
|
height: parseInt(jApp.getAttribute('height') ?? '200') }
|
||||||
if joyceApplets.length
|
if joyceApplets.length
|
||||||
config := await browser.storage.local.get(flags) as ConfigType
|
|
||||||
use3d .= false
|
use3d .= false
|
||||||
for each jApp of joyceApplets
|
for each jApp of joyceApplets
|
||||||
if contains3d jApp.params
|
if contains3d jApp.params
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
// This file is a bit misnamed, as it has options for giveAwrl, too.
|
// This file is a bit misnamed, as it has options for giveAwrl, too.
|
||||||
|
|
||||||
export const flags = [
|
export const flags = [
|
||||||
'color', 'commands', 'showall', 'showaux', 'algebra', 'vrml97'] as const
|
'vrmlview', 'joyce',
|
||||||
|
// debugging
|
||||||
|
'color', 'commands', 'showall', 'showaux', 'algebra', 'vrml97'
|
||||||
|
] as const
|
||||||
export type FlagType = (typeof flags)[number]
|
export type FlagType = (typeof flags)[number]
|
||||||
export type ConfigType = Partial<Record<FlagType, boolean>>
|
export type ConfigType = Partial<Record<FlagType, boolean>>
|
||||||
|
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
import ./deps/jquery.js
|
import ./deps/jquery.js
|
||||||
{convert} from ./deps/vrml1to97/index.js
|
{convert} from ./deps/vrml1to97/index.js
|
||||||
{ConfigType} from ./adapptypes.ts
|
import type {ConfigType} from ./adapptypes.ts
|
||||||
|
|
||||||
|
configPromise := browser.storage.local.get(['vrmlview', 'vrml97'])
|
||||||
|
|
||||||
knownExtensions := /[.](?:wrl|x3d|gltf|glb|obj|stl|ply)$/
|
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 '|'
|
||||||
|
|
||||||
function makeBrowser(url: string, width: string, height: string)
|
function makeBrowser(url: string, width: string, height: string,
|
||||||
|
config: ConfigType)
|
||||||
x_ite_rel := 'deps/x_ite/x_ite.mjs'
|
x_ite_rel := 'deps/x_ite/x_ite.mjs'
|
||||||
x_ite_url .= './' + x_ite_rel
|
x_ite_url .= './' + x_ite_rel
|
||||||
unless typeof browser is 'undefined'
|
unless typeof browser is 'undefined'
|
||||||
@ -43,15 +46,17 @@ function makeBrowser(url: string, width: string, height: string)
|
|||||||
text .= await response.text()
|
text .= await response.text()
|
||||||
if /#\s*VRML\s*V?1[.]/i.test text
|
if /#\s*VRML\s*V?1[.]/i.test text
|
||||||
text = convert text
|
text = convert text
|
||||||
maybeDebug text
|
maybeDebug text, config
|
||||||
browser3D.baseURL = url
|
browser3D.baseURL = url
|
||||||
scene := await browser3D.createX3DFromString text
|
scene := await browser3D.createX3DFromString text
|
||||||
browser3D.replaceWorld scene
|
browser3D.replaceWorld scene
|
||||||
{canvas, browser3D}
|
{canvas, browser3D}
|
||||||
|
|
||||||
|
configPromise.then((config) =>
|
||||||
// Put eye icons after all of the eligible links
|
// Put eye icons after all of the eligible links
|
||||||
links := $('a').filter -> knownExtensions.test @.getAttribute('href') ?? ''
|
links := $('a').filter -> knownExtensions.test @.getAttribute('href') ?? ''
|
||||||
links.after ->
|
links.after ->
|
||||||
|
unless config.vrmlview return ''
|
||||||
newSpan := $('<span>👁</span>')
|
newSpan := $('<span>👁</span>')
|
||||||
newSpan.css 'overflow', 'visible'
|
newSpan.css 'overflow', 'visible'
|
||||||
floatLike := this.lastElementChild as HTMLElement
|
floatLike := this.lastElementChild as HTMLElement
|
||||||
@ -81,15 +86,18 @@ links.after ->
|
|||||||
overImg := floatLike and floatLike.tagName is 'IMG'
|
overImg := floatLike and floatLike.tagName is 'IMG'
|
||||||
width := overImg ? ($(floatLike).width() + 'px') : '150px'
|
width := overImg ? ($(floatLike).width() + 'px') : '150px'
|
||||||
height := overImg ? ($(floatLike).height() + 'px') : '150px'
|
height := overImg ? ($(floatLike).height() + 'px') : '150px'
|
||||||
{canvas} := await makeBrowser url, width, height
|
{canvas} := await makeBrowser url, width, height, config
|
||||||
if float
|
if float
|
||||||
canvas.style.float = float
|
canvas.style.float = float
|
||||||
if overImg
|
if overImg
|
||||||
canvas.style.position = 'absolute'
|
canvas.style.position = 'absolute'
|
||||||
imgSty := window.getComputedStyle floatLike
|
imgSty := window.getComputedStyle floatLike
|
||||||
canvas.style.marginTop = imgSty.getPropertyValue 'margin-top'
|
canvas.style.marginTop =
|
||||||
canvas.style.marginLeft = imgSty.getPropertyValue 'margin-left'
|
imgSty.getPropertyValue 'margin-top'
|
||||||
canvas.style.marginRight = imgSty.getPropertyValue 'margin-right'
|
canvas.style.marginLeft =
|
||||||
|
imgSty.getPropertyValue 'margin-left'
|
||||||
|
canvas.style.marginRight =
|
||||||
|
imgSty.getPropertyValue 'margin-right'
|
||||||
if float is 'right'
|
if float is 'right'
|
||||||
canvas.style.left = $(eye).width() + 'px'
|
canvas.style.left = $(eye).width() + 'px'
|
||||||
else if float is 'left'
|
else if float is 'left'
|
||||||
@ -105,16 +113,12 @@ links.after ->
|
|||||||
$(eye).css 'text-decoration', 'none'
|
$(eye).css 'text-decoration', 'none'
|
||||||
$(eye.lastElementChild as Element).hide()
|
$(eye.lastElementChild as Element).hide()
|
||||||
|
|
||||||
function maybeDebug(vrml: string)
|
|
||||||
config := await browser.storage.local.get(['vrml97']) as ConfigType
|
|
||||||
if config.vrml97 then console.log 'Generated VRML97', vrml
|
|
||||||
|
|
||||||
let conwayBrowser: any
|
let conwayBrowser: any
|
||||||
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 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
|
// Note that modifying the onclick prop is not the recommended way to
|
||||||
// change button click functionality, but we need to clear out the old
|
// change button click functionality, but we need to clear out the old
|
||||||
@ -124,9 +128,10 @@ if inputs.length is 1
|
|||||||
notation := $('input[name="notation"]').val()
|
notation := $('input[name="notation"]').val()
|
||||||
unless notation then return
|
unless notation then return
|
||||||
vrml := conway.generateVRML notation.toString()
|
vrml := conway.generateVRML notation.toString()
|
||||||
maybeDebug vrml
|
maybeDebug vrml, config
|
||||||
unless madeConway
|
unless madeConway
|
||||||
{canvas, browser3D} := await makeBrowser '', '250px', '250px'
|
{canvas, browser3D} :=
|
||||||
|
await makeBrowser '', '250px', '250px', config
|
||||||
conwayBrowser = browser3D
|
conwayBrowser = browser3D
|
||||||
canvas.style.float = 'left'
|
canvas.style.float = 'left'
|
||||||
canvas.style.marginRight = '1em'
|
canvas.style.marginRight = '1em'
|
||||||
@ -137,7 +142,7 @@ if inputs.length is 1
|
|||||||
|
|
||||||
// See if we are on George Hart's prism generator page
|
// See if we are on George Hart's prism generator page
|
||||||
panelFrame := $('frame[name="panel"][src="prism-maker-subpanel.html"]')
|
panelFrame := $('frame[name="panel"][src="prism-maker-subpanel.html"]')
|
||||||
if 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", =>
|
panelFrame.on "load", =>
|
||||||
panelDoc := frames[1].document
|
panelDoc := frames[1].document
|
||||||
@ -153,7 +158,8 @@ if panelFrame.length is 1
|
|||||||
// We are presuming here that the body just contains a single
|
// We are presuming here that the body just contains a single
|
||||||
// text node. That should stay true unless GWH changes the page.
|
// text node. That should stay true unless GWH changes the page.
|
||||||
initialVrml97 := convert initialVrml1
|
initialVrml97 := convert initialVrml1
|
||||||
{canvas, browser3D: prismBrowser} := await makeBrowser '', '300px', '300px'
|
{canvas, browser3D: prismBrowser} :=
|
||||||
|
await makeBrowser '', '300px', '300px', config
|
||||||
viewerDiv.append canvas
|
viewerDiv.append canvas
|
||||||
initialScene := await prismBrowser.createX3DFromString initialVrml97
|
initialScene := await prismBrowser.createX3DFromString initialVrml97
|
||||||
prismBrowser.replaceWorld initialScene
|
prismBrowser.replaceWorld initialScene
|
||||||
@ -162,22 +168,27 @@ if panelFrame.length is 1
|
|||||||
|
|
||||||
// OK, finally have the layout cleaned up. Now we can set up our
|
// OK, finally have the layout cleaned up. Now we can set up our
|
||||||
// replacement generator:
|
// replacement generator:
|
||||||
prismBtn := $('input[type="button"][value="View"][onclick="ViewVRML()"]',
|
prismBtn :=
|
||||||
|
$('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 :=
|
numerator := parseInt(
|
||||||
parseInt $('input[name="numerator"]', panelDoc).val() as string
|
$('input[name="numerator"]', panelDoc).val() as string)
|
||||||
denominator :=
|
denominator := parseInt(
|
||||||
parseInt $('input[name="denominator"]', panelDoc).val() as string
|
$('input[name="denominator"]', panelDoc).val() as string)
|
||||||
checks: boolean[] := []
|
checks: boolean[] := []
|
||||||
$('input[name="what"]', panelDoc).each ->
|
$('input[name="what"]', panelDoc).each ->
|
||||||
checks.push (@ as HTMLInputElement).checked
|
checks.push (@ as HTMLInputElement).checked
|
||||||
return
|
return
|
||||||
{vrml, err} := prism.generateVRML numerator, denominator, checks
|
{vrml, err} := prism.generateVRML numerator, denominator, checks
|
||||||
maybeDebug vrml
|
maybeDebug vrml, config
|
||||||
if err then alert err
|
if err then alert err
|
||||||
if vrml
|
if vrml
|
||||||
scene := await prismBrowser.createX3DFromString vrml
|
scene := await prismBrowser.createX3DFromString vrml
|
||||||
prismBrowser.replaceWorld scene
|
prismBrowser.replaceWorld scene
|
||||||
|
) // end of then for configPromise
|
||||||
|
|
||||||
|
function maybeDebug(vrml: string, config: ConfigType)
|
||||||
|
if config.vrml97 then console.log 'Generated VRML97', vrml
|
||||||
|
@ -5,7 +5,7 @@ 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] ?? false
|
checkbox.checked = cache[box] ?? (box is 'vrmlview' or box is 'joyce')
|
||||||
|
|
||||||
document.body.addEventListener 'click', (event) ->
|
document.body.addEventListener 'click', (event) ->
|
||||||
elt := event.target as HTMLInputElement
|
elt := event.target as HTMLInputElement
|
||||||
|
@ -25,4 +25,9 @@ cp public/js/options.js public/js/adapptypes.js public/js/conway.js $1
|
|||||||
cp public/js/prism.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
|
||||||
|
cp public/assets/arch*.png $1/assets
|
||||||
|
cp public/assets/*Example.png $1/assets
|
||||||
|
# Wrap it all up
|
||||||
zip -r $1 $1
|
zip -r $1 $1
|
||||||
|
Loading…
Reference in New Issue
Block a user