import ./deps/jquery.js {convert} from ./deps/vrml1to97/index.js 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, config: ConfigType) x_ite_rel := 'deps/x_ite/x_ite.mjs' x_ite_url .= './' + x_ite_rel unless typeof browser is 'undefined' if browser?.runtime?.getURL x_ite_url = browser.runtime.getURL x_ite_rel const { default: X3D } = await import x_ite_url canvas := X3D.createBrowser() // Fix up css: smaller browser, but we can see the world info $(canvas).css {width, height, overflow: 'visible', 'vertical-align': 'top'} x_ite_shadow := canvas.shadowRoot if x_ite_shadow x_ite_style := x_ite_shadow.querySelector 'link' if x_ite_style $(x_ite_style).after '' x_ite_browser := x_ite_shadow.querySelector '.x_ite-private-browser' if x_ite_browser $(x_ite_browser).css overflow: 'visible' // Now get the browser and load the requested VRML, converting if need be browser3D := X3D.getBrowser canvas browser3D.setBrowserOption 'StraightenHorizon', false if certainlyHandled.some((ext) => url.includes ext) canvas.setAttribute 'src', url else if url.includes '.wrl' // Need to obtain the text and check what level it is response := await fetch url text .= await response.text() if /#\s*VRML\s*V?1[.]/i.test text text = convert text maybeDebug text, config browser3D.baseURL = url scene := await browser3D.createX3DFromString text browser3D.replaceWorld scene {canvas, browser3D} 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 := $('👁') 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() 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 := $('
') $('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. 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