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 Logger from '../ext/lib/Logger';
|
||||||
import Settings from '../ext/lib/Settings';
|
import Settings from '../ext/lib/Settings';
|
||||||
import EventBus from '../ext/lib/EventBus';
|
import EventBus from '../ext/lib/EventBus';
|
||||||
|
import UIProbeMixin from './src/utils/UIProbeMixin';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@ -158,6 +159,9 @@ export default {
|
|||||||
PlayerDetectionPanel,
|
PlayerDetectionPanel,
|
||||||
AutodetectionSettingsPanel, DebugPanel, BaseExtensionSettings
|
AutodetectionSettingsPanel, DebugPanel, BaseExtensionSettings
|
||||||
},
|
},
|
||||||
|
mixins: [
|
||||||
|
UIProbeMixin
|
||||||
|
],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
uwTriggerZoneVisible: false,
|
uwTriggerZoneVisible: false,
|
||||||
@ -246,6 +250,8 @@ export default {
|
|||||||
|
|
||||||
async created() {
|
async created() {
|
||||||
this.logger = new Logger();
|
this.logger = new Logger();
|
||||||
|
|
||||||
|
// this prolly needs to be taken out
|
||||||
await this.logger.init({
|
await this.logger.init({
|
||||||
allowLogging: true,
|
allowLogging: true,
|
||||||
});
|
});
|
||||||
@ -264,14 +270,18 @@ export default {
|
|||||||
* We can handle events with the same function we use to handle events from
|
* We can handle events with the same function we use to handle events from
|
||||||
* the content script.
|
* the content script.
|
||||||
*/
|
*/
|
||||||
document.addEventListener('mousemove', (event) => {
|
|
||||||
this.handleProbe({
|
// this is handled in UIProbeMixin.js now — if UIProbeMixin works, then
|
||||||
coords: {
|
// this can be safely removed. Note to self — leave the comment explaining
|
||||||
x: event.clientX,
|
// UI probes are set in the mixin.
|
||||||
y: event.clientY
|
// document.addEventListener('mousemove', (event) => {
|
||||||
}
|
// this.handleProbe({
|
||||||
}, this.origin);
|
// coords: {
|
||||||
});
|
// x: event.clientX,
|
||||||
|
// y: event.clientY
|
||||||
|
// }
|
||||||
|
// }, this.origin);
|
||||||
|
// });
|
||||||
|
|
||||||
this.eventBus.subscribe('uw-config-broadcast', {function: (data) => {
|
this.eventBus.subscribe('uw-config-broadcast', {function: (data) => {
|
||||||
if (data.type === 'drm-status') {
|
if (data.type === 'drm-status') {
|
||||||
@ -299,66 +309,12 @@ export default {
|
|||||||
this.origin = event.origin;
|
this.origin = event.origin;
|
||||||
this.site = event.origin.split('//')[1];
|
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') {
|
} else if (event.data.action === 'uw-bus-tunnel') {
|
||||||
this.handleBusTunnelIn(event.data.payload);
|
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() {
|
showUwWindow() {
|
||||||
this.uwWindowFadeOut = false;
|
this.uwWindowFadeOut = false;
|
||||||
this.uwWindowVisible = true;
|
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">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<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"> -->
|
<!-- <link rel="stylesheet" href="csui.css"> -->
|
||||||
<% if (NODE_ENV === 'development') { %>
|
<% if (NODE_ENV === 'development') { %>
|
||||||
<!-- Load some resources only in development environment -->
|
<!-- 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