Move extension popup into an iframe, get it to display at least something

This commit is contained in:
Tamius Han 2022-01-07 00:50:58 +01:00
parent 761f2c21a8
commit 5a2d8d22cb
18 changed files with 26771 additions and 135 deletions

View File

@ -8,7 +8,8 @@
<div class="site-support-info"> <div class="site-support-info">
<div class="site-support-site">{{site}}</div> <div class="site-support-site">{{site}}</div>
<div v-if="siteSupportLevel === 'official'" class="site-support official"> <div v-if="siteSupportLevel === 'official'" class="site-support official">
<mdicon name="check-decagram" /> <!-- <mdicon name="check-decagram" /> -->
<span class="mdi account-edit mdi-account-edit"></span>
<div>Official</div> <div>Official</div>
<div class="tooltip">The extension is being tested and should work on this site.</div> <div class="tooltip">The extension is being tested and should work on this site.</div>
</div> </div>
@ -93,7 +94,6 @@
<template v-if="settingsInitialized"> <template v-if="settingsInitialized">
<VideoSettings <VideoSettings
:settings="settings" :settings="settings"
:eventBus="ultrawidify.eventBus"
></VideoSettings> ></VideoSettings>
<!-- <ResizerDebugPanel :debugData="debugData"> <!-- <ResizerDebugPanel :debugData="debugData">
</ResizerDebugPanel> --> </ResizerDebugPanel> -->
@ -105,12 +105,12 @@
</template> </template>
<script> <script>
import VideoSettings from './PlayerUiPanels/VideoSettings.vue' import VideoSettings from './src/PlayerUiPanels/VideoSettings.vue'
import { mapState } from 'vuex'; import { mapState } from 'vuex';
// import Icon from '../common/components/Icon'; // import Icon from '../common/components/Icon';
import ResizerDebugPanel from './PlayerUiPanels/ResizerDebugPanelComponent'; import ResizerDebugPanel from './src/PlayerUiPanels/ResizerDebugPanelComponent';
import BrowserDetect from '../ext/conf/BrowserDetect'; import BrowserDetect from '../ext/conf/BrowserDetect';
import ExecAction from './ui-libs/ExecAction'; 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';
@ -139,11 +139,12 @@ export default {
}; };
}, },
computed: { computed: {
...mapState([ // we don't have vuex here at the moment, so no mapState yet!
'showUi', // ...mapState([
'resizerDebugData', // 'showUi',
'playerDebugData' // 'resizerDebugData',
]), // 'playerDebugData'
// ]),
// LPT: NO ARROW FUNCTIONS IN COMPUTED, // LPT: NO ARROW FUNCTIONS IN COMPUTED,
// IS SUPER HARAM // IS SUPER HARAM
// THINGS WILL NOT WORK IF YOU USE ARROWS // THINGS WILL NOT WORK IF YOU USE ARROWS
@ -185,15 +186,6 @@ export default {
this.settingsInitialized = true; this.settingsInitialized = true;
console.log("settings inited") console.log("settings inited")
this.execAction.setSettings(this.settings);
console.log("created!");
console.log("store:", this.$store, this);
console.log("settings:", this.settings)
console.log("windowPD", window.ultrawidify);
console.log("this:", this);
} catch (e) { } catch (e) {
console.error('Failed to initiate ultrawidify player ui.', e); console.error('Failed to initiate ultrawidify player ui.', e);
} }
@ -208,8 +200,10 @@ export default {
<style lang="scss" src="../res/css/uwui-base.scss" scoped module></style> <style lang="scss" src="../res/css/uwui-base.scss" scoped module></style>
<style lang="scss" src="../res/css/flex.scss" scoped module></style> <style lang="scss" src="../res/css/flex.scss" scoped module></style>
<style lang="scss" src="./res-common/common.scss" scoped module></style> <style lang="scss" src="../res/css/mdi.scss" scoped module></style>
<style lang="scss" src="./src/res-common/common.scss" scoped module></style>
<style lang="scss" scoped module> <style lang="scss" scoped module>
@import '../res/css/uwui-base.scss'; @import '../res/css/uwui-base.scss';
@import '../res/css/colors.scss'; @import '../res/css/colors.scss';
@import '../res/css/font/overpass.css'; @import '../res/css/font/overpass.css';

16
src/csui/csui.html Normal file
View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ultravidify - Content Script User Interface</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 stye="color: #fff; background: #000;">it works!</div>
<div id="app"></div>
<script src="csui.js"></script>
</body>
</html>

4
src/csui/csui.js Normal file
View File

@ -0,0 +1,4 @@
import { createApp } from 'vue';
import PlayerUiBase from './PlayerUiBase';
createApp(PlayerUiBase).mount('#app');

View File

@ -64,7 +64,7 @@
</template> </template>
<script> <script>
import VideoAlignmentType from '../../common/enums/VideoAlignmentType.enum'; import VideoAlignmentType from '../../../common/enums/VideoAlignmentType.enum';
export default { export default {
@ -79,7 +79,7 @@ export default {
methods: { methods: {
align(alignmentX, alignmentY) { align(alignmentX, alignmentY) {
console.warn('sending set alignment:', {x: alignmentX, y: alignmentY}); console.warn('sending set alignment:', {x: alignmentX, y: alignmentY});
this.eventBus.send('set-alignment', {x: alignmentX, y: alignmentY}) // this.eventBus.send('set-alignment', {x: alignmentX, y: alignmentY})
} }
} }
} }

View File

@ -0,0 +1,3 @@
<template>
</template>

View File

@ -121,11 +121,11 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import '../../res/css/uwui-base.scss'; @import '../../../res/css/uwui-base.scss';
@import '../../res/css/colors.scss'; @import '../../../res/css/colors.scss';
@import '../../res/css/font/overpass.css'; @import '../../../res/css/font/overpass.css';
@import '../../res/css/font/overpass-mono.css'; @import '../../../res/css/font/overpass-mono.css';
@import '../../res/css/common.scss'; @import '../../../res/css/common.scss';
// increase specificy with this one trick (webdevs hate him!) // increase specificy with this one trick (webdevs hate him!)
.uw-ultrawidify-container-root { .uw-ultrawidify-container-root {

View File

@ -218,15 +218,15 @@
</template> </template>
<script> <script>
import Button from '../../common/components/Button.vue' import Button from '../../../common/components/Button.vue'
import KeyboardShortcutParser from '../../common/js/KeyboardShortcutParser'; import KeyboardShortcutParser from '../../../common/js/KeyboardShortcutParser';
import ShortcutButton from '../../common/components/ShortcutButton'; import ShortcutButton from '../../../common/components/ShortcutButton';
import ComputeActionsMixin from '../../common/mixins/ComputeActionsMixin'; import ComputeActionsMixin from '../../../common/mixins/ComputeActionsMixin';
import ExecAction from '../ui-libs/ExecAction'; import ExecAction from '../ui-libs/ExecAction';
import BrowserDetect from '../../ext/conf/BrowserDetect'; import BrowserDetect from '../../../ext/conf/BrowserDetect';
import AspectRatioType from '../../common/enums/AspectRatioType.enum'; import AspectRatioType from '../../../common/enums/AspectRatioType.enum';
import StretchType from '../../common/enums/StretchType.enum'; import StretchType from '../../../common/enums/StretchType.enum';
import CropModePersistence from '../../common/enums/CropModePersistence.enum'; import CropModePersistence from '../../../common/enums/CropModePersistence.enum';
import AlignmentOptionsControlComponent from './AlignmentOptionsControlComponent.vue'; import AlignmentOptionsControlComponent from './AlignmentOptionsControlComponent.vue';
export default { export default {
@ -255,14 +255,15 @@ export default {
], ],
created() { created() {
this.exec = new ExecAction(this.settings, window.location.hostname); this.exec = new ExecAction(this.settings, window.location.hostname);
this.eventBus.subscribe('announce-zoom', { // todo: replace event bus with postMessage
function: (config) => { // this.eventBus.subscribe('announce-zoom', {
this.zoom = { // function: (config) => {
x: Math.log2(config.x), // this.zoom = {
y: Math.log2(config.y) // x: Math.log2(config.x),
}; // y: Math.log2(config.y)
} // };
}); // }
// });
// this.eventBus.send('get-current-config'); // this.eventBus.send('get-current-config');
}, },
components: { components: {
@ -279,7 +280,7 @@ export default {
); );
}, },
siteDefaultCrop() { siteDefaultCrop() {
console.log('default crop for site:', JSON.parse(JSON.stringify(this.settings)), this.settings?.active.sites[window.location.hostname], this.settings?.active.sites[window.location.hostname].defaultCrop) // console.log('default crop for site:', JSON.parse(JSON.stringify(this.settings)), this.settings?.active.sites[window.location.hostname], this.settings?.active.sites[window.location.hostname].defaultCrop)
return JSON.stringify( return JSON.stringify(
this.settings?.getDefaultCrop() ?? {type: AspectRatioType.Automatic} this.settings?.getDefaultCrop() ?? {type: AspectRatioType.Automatic}
); );
@ -308,7 +309,7 @@ export default {
BrowserDetect.runtime.openOptionsPage(); BrowserDetect.runtime.openOptionsPage();
}, },
execAction(command) { execAction(command) {
this.eventBus?.send(command.action, command.arguments); // this.eventBus?.send(command.action, command.arguments);
}, },
parseShortcut(command) { parseShortcut(command) {
if (! command.shortcut) { if (! command.shortcut) {
@ -326,8 +327,9 @@ export default {
this.zoom = {x: 0, y: 0}; this.zoom = {x: 0, y: 0};
// we do not use logarithmic zoom elsewhere // we do not use logarithmic zoom elsewhere
this.eventBus.send('set-zoom', {zoom: 1, axis: 'y'}); // todo: replace eventBus with postMessage to parent
this.eventBus.send('set-zoom', {zoom: 1, axis: 'x'}); // this.eventBus.send('set-zoom', {zoom: 1, axis: 'y'});
// this.eventBus.send('set-zoom', {zoom: 1, axis: 'x'});
}, },
changeZoom(newZoom, axis) { changeZoom(newZoom, axis) {
// we store zoom logarithmically on this compnent // we store zoom logarithmically on this compnent
@ -339,7 +341,6 @@ export default {
// we do not use logarithmic zoom elsewhere, therefore we need to convert // we do not use logarithmic zoom elsewhere, therefore we need to convert
newZoom = Math.pow(2, newZoom); newZoom = Math.pow(2, newZoom);
this.eventBus.send('set-zoom', {zoom: newZoom, axis: axis, noAnnounce: true});
}, },
/** /**
@ -348,25 +349,26 @@ export default {
setDefaultCrop($event, globalOrSite) { setDefaultCrop($event, globalOrSite) {
const commandArguments = JSON.parse($event.target.value); const commandArguments = JSON.parse($event.target.value);
if (globalOrSite === 'site') { // todo: account for the fact that window.host doesnt work the way we want in an iframe
if (!this.settings.active.sites[window.location.hostname]) { // if (globalOrSite === 'site') {
this.settings.active.sites[window.location.hostname] = this.settings.getDefaultSiteConfiguration(); // if (!this.settings.active.sites[window.location.hostname]) {
} // this.settings.active.sites[window.location.hostname] = this.settings.getDefaultSiteConfiguration();
this.settings.active.sites[window.location.hostname].defaultCrop = commandArguments; // }
} else { // this.settings.active.sites[window.location.hostname].defaultCrop = commandArguments;
// eventually, this 'if' will be safe to remove (and we'll be able to only // } else {
// get away with the 'else' section) Maybe in 6 months or so. // // eventually, this 'if' will be safe to remove (and we'll be able to only
if (!this.settings.active.crop) { // // get away with the 'else' section) Maybe in 6 months or so.
console.log('active settings crop not present. Well add'); // if (!this.settings.active.crop) {
this.settings.active['crop'] = { // console.log('active settings crop not present. Well add');
default: commandArguments // this.settings.active['crop'] = {
} // default: commandArguments
} else { // }
console.log('default crop settings are present:', JSON.parse(JSON.stringify(this.settings.active.crop))) // } else {
this.settings.active.crop.default = commandArguments; // console.log('default crop settings are present:', JSON.parse(JSON.stringify(this.settings.active.crop)))
} // this.settings.active.crop.default = commandArguments;
} // }
this.settings.saveWithoutReload(); // }
// this.settings.saveWithoutReload();
}, },
/** /**
@ -399,7 +401,7 @@ export default {
</style> </style>
<style lang="scss" src="../../res/css/flex.scss" scoped module></style> <style lang="scss" src="../../../res/css/flex.scss" scoped module></style>
<style lang="scss" src="../res-common/panels.scss" scoped module></style> <style lang="scss" src="../res-common/panels.scss" scoped module></style>
<style lang="scss" src="../res-common/common.scss" scoped module></style> <style lang="scss" src="../res-common/common.scss" scoped module></style>

View File

@ -1,4 +1,4 @@
import Comms from '../../ext/lib/comms/Comms'; import Comms from '../../../ext/lib/comms/Comms';
class ExecAction { class ExecAction {
constructor(settings, site) { constructor(settings, site) {
@ -27,7 +27,8 @@ class ExecAction {
customArg: cmd.customArg customArg: cmd.customArg
} }
if (useBus) { if (useBus) {
window.ultrawidify.bus.sendMessage(message.cmd, message); // todo: postMessage out of the iframe!
// window.ultrawidify.bus.sendMessage(message.cmd, message);
} else { } else {
Comms.sendMessage(message); Comms.sendMessage(message);
} }
@ -48,7 +49,8 @@ class ExecAction {
// this hopefully delays settings.save() until current crops are saved on the site // this hopefully delays settings.save() until current crops are saved on the site
// and thus avoid any fucky-wuckies // and thus avoid any fucky-wuckies
if (useBus) { if (useBus) {
window.ultrawidify.bus.sendMessage(message.cmd, message); // todo: postMessage out of the iframe!
// window.ultrawidify.bus.sendMessage(message.cmd, message);
} else { } else {
await Comms.sendMessage(message); await Comms.sendMessage(message);
} }

View File

@ -1,6 +1,6 @@
import UI from './UI'; import UI from './UI';
import VuexWebExtensions from 'vuex-webextensions'; import VuexWebExtensions from 'vuex-webextensions';
import PlayerUiComponent from '../../../csui/PlayerUiComponent.vue'; import PlayerUiComponent from '../../../csui/PlayerUiBase.vue';
if (process.env.CHANNEL !== 'stable'){ if (process.env.CHANNEL !== 'stable'){
console.info("Loading: PlayerUi"); console.info("Loading: PlayerUi");

View File

@ -1,52 +1,21 @@
import { createApp } from 'vue';
import { createStore } from 'vuex';
import mdiVue from 'mdi-vue/v3';
import * as mdijs from '@mdi/js';
if (process.env.CHANNEL !== 'stable'){ if (process.env.CHANNEL !== 'stable'){
console.info("Loading: UI"); console.info("Loading: UI");
} }
class UI { class UI {
constructor( constructor(
interfaceId, interfaceId,
storeConfig,
uiConfig, // {component, parentElement?} uiConfig, // {component, parentElement?}
commsConfig,
ultrawidify, // or, at least, videoData instance + event bus
) { ) {
this.interfaceId = interfaceId; this.interfaceId = interfaceId;
this.commsConfig = commsConfig;
this.storeConfig = storeConfig;
this.uiConfig = uiConfig; this.uiConfig = uiConfig;
this.ultrawidify = ultrawidify;
this.init(); this.init();
} }
async init() { async init() {
// initialize vuejs, but only once (check handled in initVue())
// we need to initialize this _after_ initializing comms.
this.initVue();
}
async initVue() {
if (this.storeConfig) {
this.vuexStore = createStore(this.storeConfig);
}
this.initUi();
}
async initUi() {
if (this.app) {
this.app.unmount();
}
const random = Math.round(Math.random() * 69420); const random = Math.round(Math.random() * 69420);
const uwid = `uw-${this.interfaceId}-root-${random}` const uwid = `uw-ultrawidify-${this.interfaceId}-root-${random}`
const rootDiv = document.createElement('div'); const rootDiv = document.createElement('div');
@ -64,26 +33,20 @@ class UI {
this.element = rootDiv; this.element = rootDiv;
const app = createApp(this.uiConfig.component) try {
.use(mdiVue, {icons: mdijs}) const iframe = document.createElement('iframe');
.use({ // hand eventBus to the component iframe.setAttribute('src', browser.runtime.getURL('/csui/csui.html'));
install: (app, options) => { iframe.style.width = "100%";
app.mixin({ iframe.style.height = "100%";
data() { iframe.style.position = "absolute";
return { iframe.style.zIndex = "1000";
ultrawidify: options.ultrawidify
} rootDiv.appendChild(iframe);
} } catch(e) {
})
}
}, {ultrawidify: this.ultrawidify});
if (this.vuexStore) {
app.use(this.vuexStore);
} }
this.app = app; console.log('——————————————————————————————————————— UI IS BEING CREATED ', rootDiv);
app.mount(`#${uwid}`);
} }
/** /**
@ -92,17 +55,13 @@ class UI {
*/ */
replace(newUiConfig) { replace(newUiConfig) {
this.element?.remove(); this.element?.remove();
this.app.unmount();
this.app = undefined;
this.uiConfig = newUiConfig; this.uiConfig = newUiConfig;
this.initUi(); this.init();
} }
destroy() { destroy() {
// this.comms?.destroy(); // this.comms?.destroy();
this.element?.remove(); this.element?.remove();
this.app.unmount();
this.app = undefined;
} }
} }

View File

@ -2,7 +2,6 @@ import Debug from '../../conf/Debug';
import ExtensionMode from '../../../common/enums/ExtensionMode.enum' import ExtensionMode from '../../../common/enums/ExtensionMode.enum'
import AspectRatioType from '../../../common/enums/AspectRatioType.enum'; import AspectRatioType from '../../../common/enums/AspectRatioType.enum';
import PlayerNotificationUi from '../uwui/PlayerNotificationUI'; import PlayerNotificationUi from '../uwui/PlayerNotificationUI';
import PlayerUi from '../uwui/PlayerUI';
import BrowserDetect from '../../conf/BrowserDetect'; import BrowserDetect from '../../conf/BrowserDetect';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { sleep } from '../../../common/js/utils'; import { sleep } from '../../../common/js/utils';
@ -10,6 +9,7 @@ import VideoData from './VideoData';
import Settings from '../Settings'; import Settings from '../Settings';
import Logger from '../Logger'; import Logger from '../Logger';
import EventBus from '../EventBus'; import EventBus from '../EventBus';
import UI from '../uwui/UI';
if (process.env.CHANNEL !== 'stable'){ if (process.env.CHANNEL !== 'stable'){
console.info("Loading: PlayerData.js"); console.info("Loading: PlayerData.js");
@ -94,9 +94,9 @@ class PlayerData {
this.invalid = false; this.invalid = false;
this.element = this.getPlayer(); this.element = this.getPlayer();
this.notificationService = new PlayerNotificationUi(this.element, this.settings, this.eventBus); // this.notificationService = new PlayerNotificationUi(this.element, this.settings, this.eventBus);
this.ui = new PlayerUi(this.element, this.settings, this.eventBus, this.videoData); this.ui = new UI('ultrawidifyUi', {parentElement: this.element});
this.ui.init(); // this.ui.init();
this.dimensions = undefined; this.dimensions = undefined;
this.overlayNode = undefined; this.overlayNode = undefined;
@ -578,12 +578,12 @@ class PlayerData {
forceRefreshPlayerElement() { forceRefreshPlayerElement() {
this.element = this.getPlayer(); this.element = this.getPlayer();
this.notificationService?.replace(this.element); // this.notificationService?.replace(this.element);
this.trackDimensionChanges(); this.trackDimensionChanges();
} }
showNotification(notificationId) { showNotification(notificationId) {
this.notificationService?.showNotification(notificationId); // this.notificationService?.showNotification(notificationId);
} }
/** /**

View File

@ -43,7 +43,6 @@
"open_in_tab": true "open_in_tab": true
}, },
"web_accessible_resources": [ "web_accessible_resources": [
"./*", "./*",
"ext/*", "ext/*",
@ -51,7 +50,8 @@
"res/css/*", "res/css/*",
"res/img/settings/about-bg.png", "res/img/settings/about-bg.png",
"res/icons/*", "res/icons/*",
"res/img/*" "res/img/*",
"csui/*"
], ],
"permissions": [ "permissions": [
"storage", "storage",

26653
src/res/css/mdi.scss Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -16,6 +16,7 @@ const config = {
'ext/uw-bg': './ext/uw-bg.js', 'ext/uw-bg': './ext/uw-bg.js',
'popup/popup': './popup/popup.js', 'popup/popup': './popup/popup.js',
'options/options': './options/options.js', 'options/options': './options/options.js',
'csui/csui': './csui/csui.js',
// 'install/first-time/first-time':'./install/first-time/first-time.js', // 'install/first-time/first-time':'./install/first-time/first-time.js',
}, },
output: { output: {
@ -26,7 +27,7 @@ const config = {
devtool: "source-map", devtool: "source-map",
resolve: { resolve: {
// maybe we'll move to TS some day, but today is not the day // maybe we'll move vue stuff to TS some day, but today is not the day
extensions: [ extensions: [
'.ts', '.tsx', '.ts', '.tsx',
'.js', '.vue' '.js', '.vue'
@ -112,6 +113,7 @@ const config = {
new CopyWebpackPlugin([ new CopyWebpackPlugin([
{ from: 'res', to: 'res', ignore: ['css', 'css/**']}, { from: 'res', to: 'res', ignore: ['css', 'css/**']},
{ from: 'ext', to: 'ext', ignore: ['conf/*', 'lib/**']}, { from: 'ext', to: 'ext', ignore: ['conf/*', 'lib/**']},
{ from: 'csui', to: 'csui', ignore: ['src']},
// we need to get webextension-polyfill and put it in common/lib // we need to get webextension-polyfill and put it in common/lib
{ from: '../node_modules/webextension-polyfill/dist/browser-polyfill.js', to: 'common/lib/browser-polyfill.js'}, { from: '../node_modules/webextension-polyfill/dist/browser-polyfill.js', to: 'common/lib/browser-polyfill.js'},
@ -121,6 +123,7 @@ const config = {
// (TODO: check if this copy is even necessary — /icons has same content as /res/icons) // (TODO: check if this copy is even necessary — /icons has same content as /res/icons)
{ from: 'icons', to: 'icons', ignore: ['icon.xcf'] }, { from: 'icons', to: 'icons', ignore: ['icon.xcf'] },
{ from: 'popup/popup.html', to: 'popup/popup.html', transform: transformHtml }, { from: 'popup/popup.html', to: 'popup/popup.html', transform: transformHtml },
{ from: 'csui/csui.html', to: 'csui/csui.html', transform: transformHtml },
{ from: 'options/options.html', to: 'options/options.html', transform: transformHtml }, { from: 'options/options.html', to: 'options/options.html', transform: transformHtml },
// { from: 'install/first-time/first-time.html', to: 'install/first-time/first-time.html', transform: transformHtml}, // { from: 'install/first-time/first-time.html', to: 'install/first-time/first-time.html', transform: transformHtml},
{ {