diff --git a/.vscode/settings.json b/.vscode/settings.json index 2436251..62236a5 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,6 +9,7 @@ "blackbars", "blackframe", "canvas", + "clickthrough", "com", "comms", "csui", diff --git a/src/ext/lib/uwui/UI.js b/src/ext/lib/uwui/UI.js index 0a24bdc..e1a5c1c 100644 --- a/src/ext/lib/uwui/UI.js +++ b/src/ext/lib/uwui/UI.js @@ -9,6 +9,9 @@ class UI { ) { this.interfaceId = interfaceId; this.uiConfig = uiConfig; + this.lastProbeResponseTs = null; + this.uiURI = browser.runtime.getURL('/csui/csui.html'); + this.extensionBase = browser.runtime.getURL('').replace(/\/$/, ""); console.log('init init'); @@ -16,8 +19,6 @@ class UI { } async init() { - try { - console.log('—————————————— init'); const random = Math.round(Math.random() * 69420); const uwid = `uw-ultrawidify-${this.interfaceId}-root-${random}` @@ -37,89 +38,85 @@ class UI { this.element = rootDiv; - try { - const uiURI = browser.runtime.getURL('/csui/csui.html'); + // in onMouseMove, we currently can't access this because we didn't + // do things the most properly + const uiURI = this.uiURI; - const iframe = document.createElement('iframe'); - iframe.setAttribute('src', uiURI); - iframe.style.width = "100%"; - iframe.style.height = "100%"; - iframe.style.position = "absolute"; - iframe.style.zIndex = "1000"; - iframe.style.border = 0; - iframe.style.pointerEvents = 'none'; + const iframe = document.createElement('iframe'); + iframe.setAttribute('src', uiURI); + iframe.style.width = "100%"; + iframe.style.height = "100%"; + iframe.style.position = "absolute"; + iframe.style.zIndex = "1000"; + iframe.style.border = 0; + iframe.style.pointerEvents = 'none'; - // so we have a problem: we want iframe to be clickthrough everywhere except - // on our actual overlay. There's no nice way of doing that, so we need some - // extra javascript to deal with this + // so we have a problem: we want iframe to be clickthrough everywhere except + // on our actual overlay. There's no nice way of doing that, so we need some + // extra javascript to deal with this - iframe.onload = function() { - console.log('[iframe-onload]: we are doing the onload!') - const iframeDocument = iframe.contentDocument; + iframe.onload = function() { - // console.log('[iframe-onload] iframe:', iframe, 'document:', iframeDocument); - - function onMouseMove(event) { - const iframeDocument = iframe.contentDocument; - - let coords; - if (event.currentTarget === document) { - coords = { - x: event.pageX - iframe.offsetLeft, - y: event.pageY - iframe.offsetTop - } - } else { - coords = { - x: event.clientX, - y: event.clientY - } + function onMouseMove(event) { + let coords; + if (event.currentTarget === document) { + coords = { + x: event.pageX - iframe.offsetLeft, + y: event.pageY - iframe.offsetTop } - - console.log('[iframe-mm] mouse coords:', coords.x, coords.y, 'ui URI:', uiURI) - - // ask the iframe to check whether there's a clickable element - iframe.contentWindow.postMessage( - { - cmd: 'uwui-probe', - coords, - ts: +new Date() // this should be accurate enough for our purposes - }, - uiURI - ); - - // gentleman's agreement: elements with uw-clickable inside the iframe will - // toggle pointerEvents on the iframe from 'none' to 'auto' - // Children of uw-clickable events should also do that. - - let isClickable = false; - let element = iframeDocument.elementFromPoint(coords.x, coords.y); - - while (element) { - if (element?.classList.includes('uw-clickable')) { - // we could set 'pointerEvents' here and now & simply use return, but that - // might cause us a problem if we ever try to add more shit to this function - isClickable = true; - break; - } + } else { + coords = { + x: event.clientX, + y: event.clientY } - - iframe.style.pointerEvents = isClickable ? 'auto' : 'none'; } - document.addEventListener('mousemove', onMouseMove, true); - // iframeDocument.addEventListener('mousemove', onMouseMove, true); + console.warn('coords:', coords, 'uiURI:', uiURI); + + // ask the iframe to check whether there's a clickable element + iframe.contentWindow.postMessage( + { + cmd: 'uwui-probe', + coords, + ts: +new Date() // this should be accurate enough for our purposes + }, + uiURI + ); + + // iframe.style.pointerEvents = isClickable ? 'auto' : 'none'; } - rootDiv.appendChild(iframe); - console.log('ui created') - } catch(e) { - console.error('there was an oopsie while creating ui:', e) + document.addEventListener('mousemove', onMouseMove, true); } - console.log('——————————————————————————————————————— UI IS BEING CREATED ', rootDiv); - } catch (e) { - console.error('something went VERY wrong while creating ui:', e) + rootDiv.appendChild(iframe); + console.log('ui created') + + // subscribe to events coming back to us + window.addEventListener('message', (event) => this.handleMessage(event)); + + // set uiIframe for handleMessage + this.uiIframe = iframe; } + + /** + * Handles events received from the iframe. + * @param {*} event + */ + handleMessage(event) { + console.log('[main] received event:', event.origin, this.uiURI, this.extensionBase, event) + if (event.origin === this.extensionBase) { + console.log('this is the event we want', this.uiIframe ); + if (event.data.cmd === 'uwui-clickable') { + if (event.data.ts < this.lastProbeResponseTs) { + console.log('event too early') + return; + } + this.lastProbeResponseTs = event.data.ts; + console.log('---- event is clickable?', event.data.clickable) + this.uiIframe.style.pointerEvents = event.data.clickable ? 'auto' : 'none'; + } + } } /**