archematics/src/giveAwrl.civet
Glen Whitney e7361f94a7 feat: Produce an archematics plugin that works in Firefox (#38)
With this loaded in under the Firefox debugger, one can see linked WRL files and Java Geometry Applets on arbitrary web pages.
This represents significant progress on #28, but getting more controls and getting it to work in other browsers is still on deck.

Reviewed-on: #38
Co-authored-by: Glen Whitney <glen@studioinfinity.org>
Co-committed-by: Glen Whitney <glen@studioinfinity.org>
2023-10-05 06:19:11 +00:00

104 lines
4.0 KiB
Plaintext

import ./deps/jquery.js
{convert} from ./deps/vrml1to97/index.js
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)
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 '<style type="text/css">
.x_ite-private-world-info-overlay {
inset: unset;
width: 300px;
height: 300px;
}</style>'
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
browser3D.baseURL = url
scene := await browser3D.createX3DFromString text
browser3D.replaceWorld scene
canvas
// 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
canvas.style.right = $(eye).width() + 'px'
$(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()