feat: Improve options page and add toggles for the two main features. (#68)
Resolves #43. Should leave archematics ready to submit. Reviewed-on: #68 Co-authored-by: Glen Whitney <glen@studioinfinity.org> Co-committed-by: Glen Whitney <glen@studioinfinity.org>
This commit is contained in:
parent
b74921341c
commit
0567da019f
12 changed files with 215 additions and 142 deletions
|
@ -26,9 +26,9 @@ obs := new MutationObserver (mutationList) =>
|
|||
width: parseInt(newNode.getAttribute('width') ?? '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)
|
||||
return new Promise (resolve, reject) =>
|
||||
|
@ -41,6 +41,8 @@ function addScriptTag(url: string, params = '', module = false)
|
|||
document.head.appendChild script
|
||||
|
||||
document.addEventListener "DOMContentLoaded", async =>
|
||||
config := await browser.storage.local.get(flags) as ConfigType
|
||||
unless config.joyce return
|
||||
finalJoyceApplets := document.querySelectorAll "applet[code='Geometry']"
|
||||
if finalJoyceApplets.length
|
||||
joyceApplets = []
|
||||
|
@ -58,7 +60,6 @@ document.addEventListener "DOMContentLoaded", async =>
|
|||
width: parseInt(jApp.getAttribute('width') ?? '200'),
|
||||
height: parseInt(jApp.getAttribute('height') ?? '200') }
|
||||
if joyceApplets.length
|
||||
config := await browser.storage.local.get(flags) as ConfigType
|
||||
use3d .= false
|
||||
for each jApp of joyceApplets
|
||||
if contains3d jApp.params
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
// This file is a bit misnamed, as it has options for giveAwrl, too.
|
||||
|
||||
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 ConfigType = Partial<Record<FlagType, boolean>>
|
||||
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
import ./deps/jquery.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)$/
|
||||
certainlyHandled :=
|
||||
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_url .= './' + x_ite_rel
|
||||
unless typeof browser is 'undefined'
|
||||
|
@ -43,141 +46,149 @@ function makeBrowser(url: string, width: string, height: string)
|
|||
text .= await response.text()
|
||||
if /#\s*VRML\s*V?1[.]/i.test text
|
||||
text = convert text
|
||||
maybeDebug text
|
||||
maybeDebug text, config
|
||||
browser3D.baseURL = url
|
||||
scene := await browser3D.createX3DFromString text
|
||||
browser3D.replaceWorld scene
|
||||
{canvas, browser3D}
|
||||
|
||||
// Put eye icons after all of the eligible links
|
||||
links := $('a').filter -> knownExtensions.test @.getAttribute('href') ?? ''
|
||||
links.after ->
|
||||
newSpan := $('<span>👁</span>')
|
||||
newSpan.css 'overflow', 'visible'
|
||||
floatLike := this.lastElementChild as HTMLElement
|
||||
float .= ''
|
||||
if floatLike
|
||||
float = (floatLike.getAttribute('align') ?? '')
|
||||
or floatLike.style.getPropertyValue 'float'
|
||||
or window.getComputedStyle(floatLike).getPropertyValue 'float'
|
||||
switch float
|
||||
/left/i
|
||||
float = 'left'
|
||||
newSpan.css {float, position: 'relative'}
|
||||
/right/i
|
||||
float = 'right'
|
||||
newSpan.css {float, position: 'relative'}
|
||||
else float = ''
|
||||
newSpan.hover
|
||||
(-> $(@).css 'background-color', 'lightblue'),
|
||||
(-> $(@).css 'background-color', 'inherit')
|
||||
newSpan.on 'click', @,
|
||||
(e) =>
|
||||
eye := e.target
|
||||
state .= eye.getAttribute 'data'
|
||||
unless state
|
||||
state = 'off'
|
||||
url := e.data.getAttribute('href') ?? ''
|
||||
overImg := floatLike and floatLike.tagName is 'IMG'
|
||||
width := overImg ? ($(floatLike).width() + 'px') : '150px'
|
||||
height := overImg ? ($(floatLike).height() + 'px') : '150px'
|
||||
{canvas} := await makeBrowser url, width, height
|
||||
if float
|
||||
canvas.style.float = float
|
||||
if overImg
|
||||
canvas.style.position = 'absolute'
|
||||
imgSty := window.getComputedStyle floatLike
|
||||
canvas.style.marginTop = imgSty.getPropertyValue 'margin-top'
|
||||
canvas.style.marginLeft = imgSty.getPropertyValue 'margin-left'
|
||||
canvas.style.marginRight = imgSty.getPropertyValue 'margin-right'
|
||||
if float is 'right'
|
||||
canvas.style.left = $(eye).width() + 'px'
|
||||
else if float is 'left'
|
||||
canvas.style.right = $(eye).width() + 'px'
|
||||
else canvas.style.left = floatLike.offsetLeft
|
||||
$(eye).append canvas
|
||||
if state is 'off'
|
||||
eye.setAttribute 'data', 'on'
|
||||
$(eye).css 'text-decoration', 'line-through 3px'
|
||||
$(eye.lastElementChild as Element).show()
|
||||
else
|
||||
eye.setAttribute 'data', 'off'
|
||||
$(eye).css 'text-decoration', 'none'
|
||||
$(eye.lastElementChild as Element).hide()
|
||||
configPromise.then((config) =>
|
||||
// Put eye icons after all of the eligible links
|
||||
links := $('a').filter -> knownExtensions.test @.getAttribute('href') ?? ''
|
||||
links.after ->
|
||||
unless config.vrmlview return ''
|
||||
newSpan := $('<span>👁</span>')
|
||||
newSpan.css 'overflow', 'visible'
|
||||
floatLike := this.lastElementChild as HTMLElement
|
||||
float .= ''
|
||||
if floatLike
|
||||
float = (floatLike.getAttribute('align') ?? '')
|
||||
or floatLike.style.getPropertyValue 'float'
|
||||
or window.getComputedStyle(floatLike).getPropertyValue 'float'
|
||||
switch float
|
||||
/left/i
|
||||
float = 'left'
|
||||
newSpan.css {float, position: 'relative'}
|
||||
/right/i
|
||||
float = 'right'
|
||||
newSpan.css {float, position: 'relative'}
|
||||
else float = ''
|
||||
newSpan.hover
|
||||
(-> $(@).css 'background-color', 'lightblue'),
|
||||
(-> $(@).css 'background-color', 'inherit')
|
||||
newSpan.on 'click', @,
|
||||
(e) =>
|
||||
eye := e.target
|
||||
state .= eye.getAttribute 'data'
|
||||
unless state
|
||||
state = 'off'
|
||||
url := e.data.getAttribute('href') ?? ''
|
||||
overImg := floatLike and floatLike.tagName is 'IMG'
|
||||
width := overImg ? ($(floatLike).width() + 'px') : '150px'
|
||||
height := overImg ? ($(floatLike).height() + 'px') : '150px'
|
||||
{canvas} := await makeBrowser url, width, height, config
|
||||
if float
|
||||
canvas.style.float = float
|
||||
if overImg
|
||||
canvas.style.position = 'absolute'
|
||||
imgSty := window.getComputedStyle floatLike
|
||||
canvas.style.marginTop =
|
||||
imgSty.getPropertyValue 'margin-top'
|
||||
canvas.style.marginLeft =
|
||||
imgSty.getPropertyValue 'margin-left'
|
||||
canvas.style.marginRight =
|
||||
imgSty.getPropertyValue 'margin-right'
|
||||
if float is 'right'
|
||||
canvas.style.left = $(eye).width() + 'px'
|
||||
else if float is 'left'
|
||||
canvas.style.right = $(eye).width() + 'px'
|
||||
else canvas.style.left = floatLike.offsetLeft
|
||||
$(eye).append canvas
|
||||
if state is 'off'
|
||||
eye.setAttribute 'data', 'on'
|
||||
$(eye).css 'text-decoration', 'line-through 3px'
|
||||
$(eye.lastElementChild as Element).show()
|
||||
else
|
||||
eye.setAttribute 'data', 'off'
|
||||
$(eye).css 'text-decoration', 'none'
|
||||
$(eye.lastElementChild as Element).hide()
|
||||
|
||||
function maybeDebug(vrml: string)
|
||||
config := await browser.storage.local.get(['vrml97']) as ConfigType
|
||||
let conwayBrowser: any
|
||||
madeConway .= false
|
||||
|
||||
// See if we are on George Hart's Conway-notation generator page
|
||||
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) => () =>
|
||||
import(browser.runtime.getURL('conway.js')).then (conway) =>
|
||||
notation := $('input[name="notation"]').val()
|
||||
unless notation then return
|
||||
vrml := conway.generateVRML notation.toString()
|
||||
maybeDebug vrml, config
|
||||
unless madeConway
|
||||
{canvas, browser3D} :=
|
||||
await makeBrowser '', '250px', '250px', config
|
||||
conwayBrowser = browser3D
|
||||
canvas.style.float = 'left'
|
||||
canvas.style.marginRight = '1em'
|
||||
$('form[name="input"]').first().before canvas
|
||||
madeConway = true
|
||||
scene := await conwayBrowser.createX3DFromString vrml
|
||||
conwayBrowser.replaceWorld scene
|
||||
|
||||
// See if we are on George Hart's prism generator page
|
||||
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", =>
|
||||
panelDoc := frames[1].document
|
||||
vrmlDoc := frames[0].document
|
||||
vrmlBody := $('body', vrmlDoc)
|
||||
// Grab the initial text while it is still easy to get
|
||||
textNode := vrmlBody.contents()[0]
|
||||
initialVrml1: string := textNode.textContent or ''
|
||||
// Now build up the vrml frame as we want it
|
||||
viewerDiv := $('<div></div>')
|
||||
$('head').after $('<body></body>')
|
||||
$('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.
|
||||
initialVrml97 := convert initialVrml1
|
||||
{canvas, browser3D: prismBrowser} :=
|
||||
await makeBrowser '', '300px', '300px', config
|
||||
viewerDiv.append canvas
|
||||
initialScene := await prismBrowser.createX3DFromString initialVrml97
|
||||
prismBrowser.replaceWorld initialScene
|
||||
$(textNode).remove()
|
||||
$('frame[name="vrml"]').remove()
|
||||
|
||||
// OK, finally have the layout cleaned up. Now we can set up our
|
||||
// replacement generator:
|
||||
prismBtn :=
|
||||
$('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(
|
||||
$('input[name="numerator"]', panelDoc).val() as string)
|
||||
denominator := parseInt(
|
||||
$('input[name="denominator"]', panelDoc).val() as string)
|
||||
checks: boolean[] := []
|
||||
$('input[name="what"]', panelDoc).each ->
|
||||
checks.push (@ as HTMLInputElement).checked
|
||||
return
|
||||
{vrml, err} := prism.generateVRML numerator, denominator, checks
|
||||
maybeDebug vrml, config
|
||||
if err then alert err
|
||||
if vrml
|
||||
scene := await prismBrowser.createX3DFromString vrml
|
||||
prismBrowser.replaceWorld scene
|
||||
) // end of then for configPromise
|
||||
|
||||
function maybeDebug(vrml: string, config: ConfigType)
|
||||
if config.vrml97 then console.log 'Generated VRML97', vrml
|
||||
|
||||
let conwayBrowser: any
|
||||
madeConway .= false
|
||||
|
||||
// See if we are on George Hart's Conway-notation generator page
|
||||
inputs := $('input[type="button"][value="Generate"][onclick="viewVRML()"]')
|
||||
if 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) => () =>
|
||||
import(browser.runtime.getURL('conway.js')).then (conway) =>
|
||||
notation := $('input[name="notation"]').val()
|
||||
unless notation then return
|
||||
vrml := conway.generateVRML notation.toString()
|
||||
maybeDebug vrml
|
||||
unless madeConway
|
||||
{canvas, browser3D} := await makeBrowser '', '250px', '250px'
|
||||
conwayBrowser = browser3D
|
||||
canvas.style.float = 'left'
|
||||
canvas.style.marginRight = '1em'
|
||||
$('form[name="input"]').first().before canvas
|
||||
madeConway = true
|
||||
scene := await conwayBrowser.createX3DFromString vrml
|
||||
conwayBrowser.replaceWorld scene
|
||||
|
||||
// See if we are on George Hart's prism generator page
|
||||
panelFrame := $('frame[name="panel"][src="prism-maker-subpanel.html"]')
|
||||
if panelFrame.length is 1
|
||||
// Seems so, fix the generator
|
||||
panelFrame.on "load", =>
|
||||
panelDoc := frames[1].document
|
||||
vrmlDoc := frames[0].document
|
||||
vrmlBody := $('body', vrmlDoc)
|
||||
// Grab the initial text while it is still easy to get
|
||||
textNode := vrmlBody.contents()[0]
|
||||
initialVrml1: string := textNode.textContent or ''
|
||||
// Now build up the vrml frame as we want it
|
||||
viewerDiv := $('<div></div>')
|
||||
$('head').after $('<body></body>')
|
||||
$('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.
|
||||
initialVrml97 := convert initialVrml1
|
||||
{canvas, browser3D: prismBrowser} := await makeBrowser '', '300px', '300px'
|
||||
viewerDiv.append canvas
|
||||
initialScene := await prismBrowser.createX3DFromString initialVrml97
|
||||
prismBrowser.replaceWorld initialScene
|
||||
$(textNode).remove()
|
||||
$('frame[name="vrml"]').remove()
|
||||
|
||||
// OK, finally have the layout cleaned up. Now we can set up our
|
||||
// replacement generator:
|
||||
prismBtn := $('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 $('input[name="numerator"]', panelDoc).val() as string
|
||||
denominator :=
|
||||
parseInt $('input[name="denominator"]', panelDoc).val() as string
|
||||
checks: boolean[] := []
|
||||
$('input[name="what"]', panelDoc).each ->
|
||||
checks.push (@ as HTMLInputElement).checked
|
||||
return
|
||||
{vrml, err} := prism.generateVRML numerator, denominator, checks
|
||||
maybeDebug vrml
|
||||
if err then alert err
|
||||
if vrml
|
||||
scene := await prismBrowser.createX3DFromString vrml
|
||||
prismBrowser.replaceWorld scene
|
||||
|
|
|
@ -5,7 +5,7 @@ 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] ?? false
|
||||
checkbox.checked = cache[box] ?? (box is 'vrmlview' or box is 'joyce')
|
||||
|
||||
document.body.addEventListener 'click', (event) ->
|
||||
elt := event.target as HTMLInputElement
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue