Add global page (not loaded by extension yet), put mousemove probes in a separate file
This commit is contained in:
parent
a94092ac78
commit
3c324aa1b2
69
src/csui/GlobalFrame.vue
Normal file
69
src/csui/GlobalFrame.vue
Normal file
@ -0,0 +1,69 @@
|
||||
<template>
|
||||
<div class="uw-clickthrough relative w-100 h-100">
|
||||
<template v-for="rectangle of drawnRectangles" :key="rectangle.id ?? rectangle">
|
||||
|
||||
<!-- Player element overlays -->
|
||||
<div class="absolute z-index-overlay"
|
||||
:style="rectangle.style"
|
||||
>
|
||||
<!-- used for drawing player element overlay rectangles - keep this section empty -->
|
||||
</div>
|
||||
|
||||
<!-- Notification overlay -->
|
||||
<div class="absolute z-index-notification notification-area">
|
||||
<template v-for="notification of displayedNotifications" :key="notification.id">
|
||||
<div class="notification d-flex flex-row">
|
||||
<div class="notification-icon">
|
||||
<mdicon :name="notification.icon ?? 'alert'" :size="128"></mdicon>
|
||||
</div>
|
||||
<div class="notification-text">
|
||||
<h3 class="notification-title">{{ notification.title }}</h3>
|
||||
<p class="notification-verbose">{{ notification.text }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import UIProbeMixin from './src/utils/UIProbeMixin';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
},
|
||||
mixins: [
|
||||
UIProbeMixin
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
drawnRectangles: [],
|
||||
displayedNotifications: [],
|
||||
}
|
||||
},
|
||||
|
||||
async created() {
|
||||
this.logger = new Logger();
|
||||
|
||||
// this prolly needs to be taken out
|
||||
await this.logger.init({
|
||||
allowLogging: true,
|
||||
});
|
||||
|
||||
/**
|
||||
* 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);
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
@ -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;
|
||||
|
15
src/csui/csui-global.html
Normal file
15
src/csui/csui-global.html
Normal file
@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Ultrawidify - Content Script User Interface (global overlay)</title>
|
||||
<!-- <link rel="stylesheet" href="csui.css"> -->
|
||||
<% if (NODE_ENV === 'development') { %>
|
||||
<!-- Load some resources only in development environment -->
|
||||
<% } %>
|
||||
</head>
|
||||
<body class="uw-ultrawidify-container-root">
|
||||
<div id="app"></div>
|
||||
<script src="csui-global.js"></script>
|
||||
</body>
|
||||
</html>
|
11
src/csui/csui-global.js
Normal file
11
src/csui/csui-global.js
Normal file
@ -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');
|
@ -2,7 +2,7 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Ultravidify - Content Script User Interface</title>
|
||||
<title>Ultrawidify - Content Script User Interface (in-player overlay)</title>
|
||||
<!-- <link rel="stylesheet" href="csui.css"> -->
|
||||
<% if (NODE_ENV === 'development') { %>
|
||||
<!-- Load some resources only in development environment -->
|
||||
|
72
src/csui/src/utils/UIProbeMixin.js
Normal file
72
src/csui/src/utils/UIProbeMixin.js
Normal file
@ -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
|
||||
);
|
||||
},
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user