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-site">{{site}}</div>
<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 class="tooltip">The extension is being tested and should work on this site.</div>
</div>
@ -93,7 +94,6 @@
<template v-if="settingsInitialized">
<VideoSettings
:settings="settings"
:eventBus="ultrawidify.eventBus"
></VideoSettings>
<!-- <ResizerDebugPanel :debugData="debugData">
</ResizerDebugPanel> -->
@ -105,12 +105,12 @@
</template>
<script>
import VideoSettings from './PlayerUiPanels/VideoSettings.vue'
import VideoSettings from './src/PlayerUiPanels/VideoSettings.vue'
import { mapState } from 'vuex';
// import Icon from '../common/components/Icon';
import ResizerDebugPanel from './PlayerUiPanels/ResizerDebugPanelComponent';
import ResizerDebugPanel from './src/PlayerUiPanels/ResizerDebugPanelComponent';
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 Settings from '../ext/lib/Settings';
@ -139,11 +139,12 @@ export default {
};
},
computed: {
...mapState([
'showUi',
'resizerDebugData',
'playerDebugData'
]),
// we don't have vuex here at the moment, so no mapState yet!
// ...mapState([
// 'showUi',
// 'resizerDebugData',
// 'playerDebugData'
// ]),
// LPT: NO ARROW FUNCTIONS IN COMPUTED,
// IS SUPER HARAM
// THINGS WILL NOT WORK IF YOU USE ARROWS
@ -185,15 +186,6 @@ export default {
this.settingsInitialized = true;
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) {
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/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>
@import '../res/css/uwui-base.scss';
@import '../res/css/colors.scss';
@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>
<script>
import VideoAlignmentType from '../../common/enums/VideoAlignmentType.enum';
import VideoAlignmentType from '../../../common/enums/VideoAlignmentType.enum';
export default {
@ -79,7 +79,7 @@ export default {
methods: {
align(alignmentX, 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>
<style lang="scss" scoped>
@import '../../res/css/uwui-base.scss';
@import '../../res/css/colors.scss';
@import '../../res/css/font/overpass.css';
@import '../../res/css/font/overpass-mono.css';
@import '../../res/css/common.scss';
@import '../../../res/css/uwui-base.scss';
@import '../../../res/css/colors.scss';
@import '../../../res/css/font/overpass.css';
@import '../../../res/css/font/overpass-mono.css';
@import '../../../res/css/common.scss';
// increase specificy with this one trick (webdevs hate him!)
.uw-ultrawidify-container-root {

View File

@ -218,15 +218,15 @@
</template>
<script>
import Button from '../../common/components/Button.vue'
import KeyboardShortcutParser from '../../common/js/KeyboardShortcutParser';
import ShortcutButton from '../../common/components/ShortcutButton';
import ComputeActionsMixin from '../../common/mixins/ComputeActionsMixin';
import Button from '../../../common/components/Button.vue'
import KeyboardShortcutParser from '../../../common/js/KeyboardShortcutParser';
import ShortcutButton from '../../../common/components/ShortcutButton';
import ComputeActionsMixin from '../../../common/mixins/ComputeActionsMixin';
import ExecAction from '../ui-libs/ExecAction';
import BrowserDetect from '../../ext/conf/BrowserDetect';
import AspectRatioType from '../../common/enums/AspectRatioType.enum';
import StretchType from '../../common/enums/StretchType.enum';
import CropModePersistence from '../../common/enums/CropModePersistence.enum';
import BrowserDetect from '../../../ext/conf/BrowserDetect';
import AspectRatioType from '../../../common/enums/AspectRatioType.enum';
import StretchType from '../../../common/enums/StretchType.enum';
import CropModePersistence from '../../../common/enums/CropModePersistence.enum';
import AlignmentOptionsControlComponent from './AlignmentOptionsControlComponent.vue';
export default {
@ -255,14 +255,15 @@ export default {
],
created() {
this.exec = new ExecAction(this.settings, window.location.hostname);
this.eventBus.subscribe('announce-zoom', {
function: (config) => {
this.zoom = {
x: Math.log2(config.x),
y: Math.log2(config.y)
};
}
});
// todo: replace event bus with postMessage
// this.eventBus.subscribe('announce-zoom', {
// function: (config) => {
// this.zoom = {
// x: Math.log2(config.x),
// y: Math.log2(config.y)
// };
// }
// });
// this.eventBus.send('get-current-config');
},
components: {
@ -279,7 +280,7 @@ export default {
);
},
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(
this.settings?.getDefaultCrop() ?? {type: AspectRatioType.Automatic}
);
@ -308,7 +309,7 @@ export default {
BrowserDetect.runtime.openOptionsPage();
},
execAction(command) {
this.eventBus?.send(command.action, command.arguments);
// this.eventBus?.send(command.action, command.arguments);
},
parseShortcut(command) {
if (! command.shortcut) {
@ -326,8 +327,9 @@ export default {
this.zoom = {x: 0, y: 0};
// we do not use logarithmic zoom elsewhere
this.eventBus.send('set-zoom', {zoom: 1, axis: 'y'});
this.eventBus.send('set-zoom', {zoom: 1, axis: 'x'});
// todo: replace eventBus with postMessage to parent
// this.eventBus.send('set-zoom', {zoom: 1, axis: 'y'});
// this.eventBus.send('set-zoom', {zoom: 1, axis: 'x'});
},
changeZoom(newZoom, axis) {
// 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
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) {
const commandArguments = JSON.parse($event.target.value);
if (globalOrSite === 'site') {
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 {
// eventually, this 'if' will be safe to remove (and we'll be able to only
// get away with the 'else' section) Maybe in 6 months or so.
if (!this.settings.active.crop) {
console.log('active settings crop not present. Well add');
this.settings.active['crop'] = {
default: commandArguments
}
} else {
console.log('default crop settings are present:', JSON.parse(JSON.stringify(this.settings.active.crop)))
this.settings.active.crop.default = commandArguments;
}
}
this.settings.saveWithoutReload();
// todo: account for the fact that window.host doesnt work the way we want in an iframe
// if (globalOrSite === 'site') {
// 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 {
// // eventually, this 'if' will be safe to remove (and we'll be able to only
// // get away with the 'else' section) Maybe in 6 months or so.
// if (!this.settings.active.crop) {
// console.log('active settings crop not present. Well add');
// this.settings.active['crop'] = {
// default: commandArguments
// }
// } else {
// console.log('default crop settings are present:', JSON.parse(JSON.stringify(this.settings.active.crop)))
// this.settings.active.crop.default = commandArguments;
// }
// }
// this.settings.saveWithoutReload();
},
/**
@ -399,7 +401,7 @@ export default {
</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/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 {
constructor(settings, site) {
@ -27,7 +27,8 @@ class ExecAction {
customArg: cmd.customArg
}
if (useBus) {
window.ultrawidify.bus.sendMessage(message.cmd, message);
// todo: postMessage out of the iframe!
// window.ultrawidify.bus.sendMessage(message.cmd, message);
} else {
Comms.sendMessage(message);
}
@ -48,7 +49,8 @@ class ExecAction {
// this hopefully delays settings.save() until current crops are saved on the site
// and thus avoid any fucky-wuckies
if (useBus) {
window.ultrawidify.bus.sendMessage(message.cmd, message);
// todo: postMessage out of the iframe!
// window.ultrawidify.bus.sendMessage(message.cmd, message);
} else {
await Comms.sendMessage(message);
}

View File

@ -1,6 +1,6 @@
import UI from './UI';
import VuexWebExtensions from 'vuex-webextensions';
import PlayerUiComponent from '../../../csui/PlayerUiComponent.vue';
import PlayerUiComponent from '../../../csui/PlayerUiBase.vue';
if (process.env.CHANNEL !== 'stable'){
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'){
console.info("Loading: UI");
}
class UI {
constructor(
interfaceId,
storeConfig,
uiConfig, // {component, parentElement?}
commsConfig,
ultrawidify, // or, at least, videoData instance + event bus
) {
this.interfaceId = interfaceId;
this.commsConfig = commsConfig;
this.storeConfig = storeConfig;
this.uiConfig = uiConfig;
this.ultrawidify = ultrawidify;
this.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 uwid = `uw-${this.interfaceId}-root-${random}`
const uwid = `uw-ultrawidify-${this.interfaceId}-root-${random}`
const rootDiv = document.createElement('div');
@ -64,26 +33,20 @@ class UI {
this.element = rootDiv;
const app = createApp(this.uiConfig.component)
.use(mdiVue, {icons: mdijs})
.use({ // hand eventBus to the component
install: (app, options) => {
app.mixin({
data() {
return {
ultrawidify: options.ultrawidify
}
}
})
}
}, {ultrawidify: this.ultrawidify});
try {
const iframe = document.createElement('iframe');
iframe.setAttribute('src', browser.runtime.getURL('/csui/csui.html'));
iframe.style.width = "100%";
iframe.style.height = "100%";
iframe.style.position = "absolute";
iframe.style.zIndex = "1000";
rootDiv.appendChild(iframe);
} catch(e) {
if (this.vuexStore) {
app.use(this.vuexStore);
}
this.app = app;
app.mount(`#${uwid}`);
console.log('——————————————————————————————————————— UI IS BEING CREATED ', rootDiv);
}
/**
@ -92,17 +55,13 @@ class UI {
*/
replace(newUiConfig) {
this.element?.remove();
this.app.unmount();
this.app = undefined;
this.uiConfig = newUiConfig;
this.initUi();
this.init();
}
destroy() {
// this.comms?.destroy();
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 AspectRatioType from '../../../common/enums/AspectRatioType.enum';
import PlayerNotificationUi from '../uwui/PlayerNotificationUI';
import PlayerUi from '../uwui/PlayerUI';
import BrowserDetect from '../../conf/BrowserDetect';
import * as _ from 'lodash';
import { sleep } from '../../../common/js/utils';
@ -10,6 +9,7 @@ import VideoData from './VideoData';
import Settings from '../Settings';
import Logger from '../Logger';
import EventBus from '../EventBus';
import UI from '../uwui/UI';
if (process.env.CHANNEL !== 'stable'){
console.info("Loading: PlayerData.js");
@ -94,9 +94,9 @@ class PlayerData {
this.invalid = false;
this.element = this.getPlayer();
this.notificationService = new PlayerNotificationUi(this.element, this.settings, this.eventBus);
this.ui = new PlayerUi(this.element, this.settings, this.eventBus, this.videoData);
this.ui.init();
// this.notificationService = new PlayerNotificationUi(this.element, this.settings, this.eventBus);
this.ui = new UI('ultrawidifyUi', {parentElement: this.element});
// this.ui.init();
this.dimensions = undefined;
this.overlayNode = undefined;
@ -578,12 +578,12 @@ class PlayerData {
forceRefreshPlayerElement() {
this.element = this.getPlayer();
this.notificationService?.replace(this.element);
// this.notificationService?.replace(this.element);
this.trackDimensionChanges();
}
showNotification(notificationId) {
this.notificationService?.showNotification(notificationId);
// this.notificationService?.showNotification(notificationId);
}
/**

View File

@ -43,7 +43,6 @@
"open_in_tab": true
},
"web_accessible_resources": [
"./*",
"ext/*",
@ -51,7 +50,8 @@
"res/css/*",
"res/img/settings/about-bg.png",
"res/icons/*",
"res/img/*"
"res/img/*",
"csui/*"
],
"permissions": [
"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',
'popup/popup': './popup/popup.js',
'options/options': './options/options.js',
'csui/csui': './csui/csui.js',
// 'install/first-time/first-time':'./install/first-time/first-time.js',
},
output: {
@ -26,7 +27,7 @@ const config = {
devtool: "source-map",
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: [
'.ts', '.tsx',
'.js', '.vue'
@ -112,6 +113,7 @@ const config = {
new CopyWebpackPlugin([
{ from: 'res', to: 'res', ignore: ['css', 'css/**']},
{ 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
{ 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)
{ from: 'icons', to: 'icons', ignore: ['icon.xcf'] },
{ 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: 'install/first-time/first-time.html', to: 'install/first-time/first-time.html', transform: transformHtml},
{