diff --git a/src/csui/GlobalFrame.vue b/src/csui/GlobalFrame.vue new file mode 100644 index 0000000..72de3da --- /dev/null +++ b/src/csui/GlobalFrame.vue @@ -0,0 +1,69 @@ + + + diff --git a/src/csui/PlayerUiBase.vue b/src/csui/PlayerUiBase.vue index 5d580bc..e0e25bf 100644 --- a/src/csui/PlayerUiBase.vue +++ b/src/csui/PlayerUiBase.vue @@ -149,6 +149,7 @@ import ExecAction from './src/ui-libs/ExecAction'; import Logger from '../ext/lib/Logger'; import Settings from '../ext/lib/Settings'; import EventBus from '../ext/lib/EventBus'; +import UIProbeMixin from './src/utils/UIProbeMixin'; export default { components: { @@ -158,6 +159,9 @@ export default { PlayerDetectionPanel, AutodetectionSettingsPanel, DebugPanel, BaseExtensionSettings }, + mixins: [ + UIProbeMixin + ], data() { return { uwTriggerZoneVisible: false, @@ -246,6 +250,8 @@ export default { async created() { this.logger = new Logger(); + + // this prolly needs to be taken out await this.logger.init({ allowLogging: true, }); @@ -264,14 +270,18 @@ export default { * We can handle events with the same function we use to handle events from * the content script. */ - document.addEventListener('mousemove', (event) => { - this.handleProbe({ - coords: { - x: event.clientX, - y: event.clientY - } - }, this.origin); - }); + + // this is handled in UIProbeMixin.js now — if UIProbeMixin works, then + // this can be safely removed. Note to self — leave the comment explaining + // UI probes are set in the mixin. + // document.addEventListener('mousemove', (event) => { + // this.handleProbe({ + // coords: { + // x: event.clientX, + // y: event.clientY + // } + // }, this.origin); + // }); this.eventBus.subscribe('uw-config-broadcast', {function: (data) => { if (data.type === 'drm-status') { @@ -299,66 +309,12 @@ export default { this.origin = event.origin; this.site = event.origin.split('//')[1]; } - this.handleProbe(event.data, event.origin); + this.handleProbe(event.data, event.origin); // handleProbe is defined in UIProbeMixin } else if (event.data.action === 'uw-bus-tunnel') { this.handleBusTunnelIn(event.data.payload); } }, - /** - * Handles 'uwui-probe' events. It checks whether there's a clickable element under - * cursor, and sends a reply to the content scripts that indicates whether pointer-events - * property of the iframe should be set to capture or ignore the clicks. - */ - handleProbe(eventData, origin) { - if (eventData.ts < this.lastProbeTs) { - return; // i don't know if events can arrive out-of-order. Prolly not. We still check. - } - this.lastProbeTs = eventData.ts; - - // show ultrawidify trigger zone and set it to vanish after 250ms - // but don't show the trigger zone behind an active popup - if (! this.uwWindowVisible) { - this.uwTriggerZoneVisible = true; - clearTimeout(this.uwTriggerZoneTimeout); - this.uwTriggerZoneTimeout = setTimeout( - () => this.uwTriggerZoneVisible = false, - 250 - ); - } - - /* we check if our mouse is hovering over an element. - * - * 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. - * - * TODO: rename uw-clickable to something else, since we pretty much need that on - * our top-level element. - */ - let isClickable = false; - let element = document.elementFromPoint(eventData.coords.x, eventData.coords.y); - - while (element) { - if (element?.classList.contains('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; - } - element = element.parentElement; - } - - window.parent.postMessage( - { - action: 'uwui-clickable', - clickable: isClickable, - ts: +new Date() - }, - origin - ); - }, - showUwWindow() { this.uwWindowFadeOut = false; this.uwWindowVisible = true; diff --git a/src/csui/csui-global.html b/src/csui/csui-global.html new file mode 100644 index 0000000..339a9da --- /dev/null +++ b/src/csui/csui-global.html @@ -0,0 +1,15 @@ + + + + + Ultrawidify - Content Script User Interface (global overlay) + + <% if (NODE_ENV === 'development') { %> + + <% } %> + + +
+ + + diff --git a/src/csui/csui-global.js b/src/csui/csui-global.js new file mode 100644 index 0000000..e639126 --- /dev/null +++ b/src/csui/csui-global.js @@ -0,0 +1,11 @@ +import { createApp } from 'vue'; +import GlobalFrame from './GlobalFrame'; +import mdiVue from 'mdi-vue/v3'; +import * as mdijs from '@mdi/js'; + +// NOTE — this is in-player interface for ultrawidify +// it is injected into the page in UI.init() + +createApp(GlobalFrame) + .use(mdiVue, {icons: mdijs}) + .mount('#app'); diff --git a/src/csui/csui.html b/src/csui/csui.html index c2711f8..96c0a54 100644 --- a/src/csui/csui.html +++ b/src/csui/csui.html @@ -2,7 +2,7 @@ - Ultravidify - Content Script User Interface + Ultrawidify - Content Script User Interface (in-player overlay) <% if (NODE_ENV === 'development') { %> diff --git a/src/csui/src/utils/UIProbeMixin.js b/src/csui/src/utils/UIProbeMixin.js new file mode 100644 index 0000000..650917c --- /dev/null +++ b/src/csui/src/utils/UIProbeMixin.js @@ -0,0 +1,72 @@ +export default { + created() { + /** + * Setup the "companion" onMouseMove handler to the one in the content script. + * We can handle events with the same function we use to handle events from + * the content script. + */ + document.addEventListener('mousemove', (event) => { + this.handleProbe({ + coords: { + x: event.clientX, + y: event.clientY + } + }, this.origin); + }); + }, + methods: { + /** + * Handles 'uwui-probe' events. It checks whether there's a clickable element under + * cursor, and sends a reply to the content scripts that indicates whether pointer-events + * property of the iframe should be set to capture or ignore the clicks. + */ + handleProbe(eventData, origin) { + if (eventData.ts < this.lastProbeTs) { + return; // i don't know if events can arrive out-of-order. Prolly not. We still check. + } + this.lastProbeTs = eventData.ts; + + // show ultrawidify trigger zone and set it to vanish after 250ms + // but don't show the trigger zone behind an active popup + if (! this.uwWindowVisible) { + this.uwTriggerZoneVisible = true; + clearTimeout(this.uwTriggerZoneTimeout); + this.uwTriggerZoneTimeout = setTimeout( + () => this.uwTriggerZoneVisible = false, + 250 + ); + } + + /* we check if our mouse is hovering over an element. + * + * 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. + * + * TODO: rename uw-clickable to something else, since we pretty much need that on + * our top-level element. + */ + let isClickable = false; + let element = document.elementFromPoint(eventData.coords.x, eventData.coords.y); + + while (element) { + if (element?.classList.contains('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; + } + element = element.parentElement; + } + + window.parent.postMessage( + { + action: 'uwui-clickable', + clickable: isClickable, + ts: +new Date() + }, + origin + ); + }, + } +}