Compare commits

..

No commits in common. "f7f046ea536f7fea38f4be603adb86cf47571314" and "a89eb8e857d178370e0414464058a5ffce9e1f44" have entirely different histories.

25 changed files with 248 additions and 449 deletions

View File

@ -2,14 +2,6 @@
## v6.0 (current major) ## v6.0 (current major)
### v6.3.0
* Added zoom segment to in-player UI and popup.
* Fixed keyboard zoom
* Added additional zoom options. If you wonder how zoom options differ from crop, mess around and find out.
* Subdomains now inherit same settings as their parent domain by default
* Extension detects embedded content (but not always)
* Added `www.youtube-nocookie.com` to "officially supported" list
### v6.2.5 ### v6.2.5
* Popup appearance changed — UI advertisement panel was moved to the popup header * Popup appearance changed — UI advertisement panel was moved to the popup header

View File

@ -44,6 +44,13 @@ export default {
}, },
async created() { 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. * 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 * We can handle events with the same function we use to handle events from

View File

@ -64,7 +64,7 @@
</GhettoContextMenuOption> </GhettoContextMenuOption>
</slot> </slot>
</GhettoContextMenu> </GhettoContextMenu>
<GhettoContextMenu alignment="right"> <!-- <GhettoContextMenu alignment="right">
<template v-slot:activator> <template v-slot:activator>
Zoom Zoom
</template> </template>
@ -86,7 +86,7 @@
/> />
</GhettoContextMenuItem> </GhettoContextMenuItem>
</slot> </slot>
</GhettoContextMenu> </GhettoContextMenu> -->
<GhettoContextMenu alignment="right"> <GhettoContextMenu alignment="right">
<template v-slot:activator> <template v-slot:activator>
<div class="context-item"> <div class="context-item">
@ -213,8 +213,6 @@ import CommsMixin from '@csui/src/utils/CommsMixin';
import SupportLevelIndicator from '@csui/src/components/SupportLevelIndicator.vue'; import SupportLevelIndicator from '@csui/src/components/SupportLevelIndicator.vue';
import TriggerZoneEditor from '@csui/src/components/TriggerZoneEditor.vue'; import TriggerZoneEditor from '@csui/src/components/TriggerZoneEditor.vue';
import ZoomControl from '@csui/src/popup/player-menu/ZoomControl.vue'; import ZoomControl from '@csui/src/popup/player-menu/ZoomControl.vue';
import { LogAggregator } from '@src/ext/lib/logging/LogAggregator';
import { ComponentLogger } from '@src/ext/lib/logging/ComponentLogger';
export default { export default {
components: { components: {
@ -331,6 +329,11 @@ export default {
this.logAggregator = new LogAggregator('player-overlay'); this.logAggregator = new LogAggregator('player-overlay');
this.logger = new ComponentLogger(this.logAggregator, 'PlayerOverlay.vue'); this.logger = new ComponentLogger(this.logAggregator, 'PlayerOverlay.vue');
// this prolly needs to be taken out
await this.logger.init({
allowLogging: true,
});
this.settings = new Settings({afterSettingsSaved: this.updateConfig, logger: this.logger}); this.settings = new Settings({afterSettingsSaved: this.updateConfig, logger: this.logger});
this.settings.listenAfterChange(() => this.updateTriggerZones()); this.settings.listenAfterChange(() => this.updateTriggerZones());
@ -572,17 +575,7 @@ export default {
}, },
handleBusTunnelIn(payload) { handleBusTunnelIn(payload) {
this.eventBus.send( this.eventBus.send(payload.action, payload.config, payload.routingData);
payload.action,
payload.config,
{
...payload.context,
borderCrossings: {
...payload.context?.borderCrossings,
iframe: true
}
}
);
}, },
updateConfig() { updateConfig() {

View File

@ -176,8 +176,11 @@ export default {
try { try {
this.logAggregator = new LogAggregator('🔵ext-popup🔵'); this.logAggregator = new LogAggregator('🔵ext-popup🔵');
this.logger = new ComponentLogger(this.logAggregator, 'Popup'); this.logger = new ComponentLogger(this.logAggregator, 'Popup');
await this.logger.init({
allowLogging: true,
});
this.settings = new Settings({afterSettingsSaved: () => this.updateConfig(), logAggregator: this.logAggregator}); this.settings = new Settings({afterSettingsSaved: () => this.updateConfig(), logger: this.logger});
await this.settings.init(); await this.settings.init();
this.settingsInitialized = true; this.settingsInitialized = true;
@ -274,14 +277,8 @@ export default {
try { try {
this.logger.log('info','popup', '[popup::getSite] Requesting current site ...') this.logger.log('info','popup', '[popup::getSite] Requesting current site ...')
// CSM.port.postMessage({command: 'get-current-site'}); // CSM.port.postMessage({command: 'get-current-site'});
this.eventBus.send(
'probe-video',
{},
{ comms: {forwardTo: 'active'} }
);
this.eventBus.send( this.eventBus.send(
'get-current-site', 'get-current-site',
{},
{ {
comms: {forwardTo: 'active'} comms: {forwardTo: 'active'}
} }

View File

@ -5,15 +5,13 @@
<h1>What's new</h1> <h1>What's new</h1>
<!-- <p>Full changelog for older versions <a href="https://github.com/tamius-han/ultrawidify/blob/master/CHANGELOG.md" target="_blank">is available here</a>.</p> --> <!-- <p>Full changelog for older versions <a href="https://github.com/tamius-han/ultrawidify/blob/master/CHANGELOG.md" target="_blank">is available here</a>.</p> -->
<h2>6.3.0</h2> <h2>6.2.6</h2>
<ul> <ul>
<li>Automatic aspect ratio detection: do not apply negative aspect ratios</li> <li>Automatic aspect ratio detection: do not apply negative aspect ratios</li>
<li>Keyboard zoom now works</li> <li>Keyboard zoom now works</li>
<li><code>www.youtube-nocookie.com</code> has been added to the "officially supported" list</li> <li><code>www.youtube-nocookie.com</code> has been added to the "officially supported" list</li>
<li>Fixed the bug where UI would sometimes refuse to stay hidden</li> <li>Fixed the bug where UI would sometimes refuse to stay hidden</li>
<li>New experimental zoom options</li> <li>New experimental zoom options</li>
<li>Subdomains now inherit same settings as their parent domain by default</li>
<li>Extension attempts to detect embedded content.</li>
</ul> </ul>
</div> </div>
<div style="width: 1rem; height: 0px;"></div> <div style="width: 1rem; height: 0px;"></div>

View File

@ -27,7 +27,7 @@
</template> </template>
<script> <script>
import { LogAggregator, BLANK_LOGGER_CONFIG } from '@src/ext/lib/logging/LogAggregator'; import { LogAggregator } from '@src/ext/lib/logging/LogAggregator';
import JsonEditor from '@csui/src/components/JsonEditor'; import JsonEditor from '@csui/src/components/JsonEditor';
export default { export default {
@ -79,23 +79,21 @@ export default {
...this.loggerPanelRotation[Math.floor(Math.random() * this.loggerPanelRotation.length)], ...this.loggerPanelRotation[Math.floor(Math.random() * this.loggerPanelRotation.length)],
pasteConfMode: false, pasteConfMode: false,
}; };
this.getLoggerSettings(); this.loadDefaultConfig();
}, },
methods: { methods: {
loadDefaultConfig() { loadDefaultConfig() {
this.lastSettings = JSON.parse(JSON.stringify(BLANK_LOGGER_CONFIG)); this.lastSettings = baseLoggingOptions;
}, },
async getLoggerSettings() { async getLoggerSettings() {
this.lastSettings = await LogAggregator.getConfig() || BLANK_LOGGER_CONFIG; this.lastSettings = await LogAggregator.getConfig() || baseLoggingOptions;
}, },
async saveLoggerSettings() { saveLoggerSettings() {
console.log('Saving logger settings', this.lastSettings); LogAggregator.saveConfig({...this.lastSettings});
await LogAggregator.saveConfig({...this.lastSettings});
console.log('[ok] logger settings saved');
}, },
async startLogging(){ async startLogging(){
this.logStringified = undefined; this.logStringified = undefined;
await LogAggregator.saveConfig({...this.lastSettings}); await LogAggregator.saveConfig({...this.lastSettings, allowLogging: true});
window.location.reload(); window.location.reload();
}, },
} }

View File

@ -108,6 +108,26 @@
</div> </div>
</div> </div>
<!-- <div v-if="siteSettings && allowSettingSiteDefault" class="edit-action-area">
<div class="field">
<div class="label">Default for this site</div>
<div class="select">
<select
:value="siteDefaultZoom"
@change="setDefaultZoom($event, 'site')"
>
<option
v-for="(command, index) of settings?.active.commands.zoom"
:key="index"
:value="JSON.stringify(command.arguments)"
>
{{command.label}}
</option>
</select>
</div>
</div>
</div> -->
</template> </template>
<template v-else> <template v-else>
<!-- <!--
@ -208,13 +228,6 @@ export default {
KeyboardShortcutParserMixin, KeyboardShortcutParserMixin,
CommsMixin CommsMixin
], ],
props: [
'settings', // required for buttons and actions, which are global
'siteSettings',
'eventBus',
'isEditing',
'compact',
],
data() { data() {
return { return {
AspectRatioType, AspectRatioType,
@ -234,6 +247,13 @@ export default {
} }
} }
}, },
props: [
'settings', // required for buttons and actions, which are global
'siteSettings',
'eventBus',
'isEditing',
'compact',
],
created() { created() {
if (this.isEditing) { if (this.isEditing) {
this.enableEditMode(); this.enableEditMode();
@ -252,6 +272,7 @@ export default {
getZoomForDisplay(axis) { getZoomForDisplay(axis) {
// zoom is internally handled logarithmically, because we want to have x0.5, x1, x2, x4 ... magnifications // zoom is internally handled logarithmically, because we want to have x0.5, x1, x2, x4 ... magnifications
// spaced out at regular intervals. When displaying, we need to convert that to non-logarithmic values. // spaced out at regular intervals. When displaying, we need to convert that to non-logarithmic values.
return `${(Math.pow(2, this.zoom[axis]) * 100).toFixed()}%` return `${(Math.pow(2, this.zoom[axis]) * 100).toFixed()}%`
}, },
toggleZoomAr() { toggleZoomAr() {

View File

@ -6,79 +6,74 @@
current settings do not allow the extension to only be disabled while in full screen current settings do not allow the extension to only be disabled while in full screen
--> -->
<template v-if="siteSettings.isEnabledForEnvironment(false, true) === ExtensionMode.Disabled"> <template v-if="siteSettings.isEnabledForEnvironment(false, true) === ExtensionMode.Disabled">
<div class="h-full flex flex-col items-center justify-center"> <div class="info">
<div class="info"> Extension is not enabled for this site.
Extension is not enabled for this site.
</div>
<div>
Please enable extension for this site.
</div>
</div> </div>
</template> </template>
<template v-else>
<div class="flex flex-row">
<mdicon name="crop" :size="16" />&nbsp;&nbsp;
<span>CROP</span>
</div>
<div
style="margin-top: -0.69rem; margin-bottom: 0.88rem;"
>
<CropOptionsPanel
:settings="settings"
:eventBus="eventBus"
:siteSettings="siteSettings"
:isEditing="false"
:compact="true"
>
</CropOptionsPanel>
</div>
<div class="flex flex-row"> <div class="flex flex-row">
<mdicon name="crop" :size="16" />&nbsp;&nbsp; <mdicon name="crop" :size="16" />&nbsp;&nbsp;
<span>STRETCH</span> <span>CROP</span>
</div> </div>
<div <div
style="margin-top: -0.69rem; margin-bottom: 0.88rem;" style="margin-top: -0.69rem; margin-bottom: 0.88rem;"
>
<CropOptionsPanel
:settings="settings"
:eventBus="eventBus"
:siteSettings="siteSettings"
:isEditing="false"
:compact="true"
> >
<StretchOptionsPanel </CropOptionsPanel>
:settings="settings" </div>
:eventBus="eventBus"
:siteSettings="siteSettings"
:isEditing="false"
:compact="true"
></StretchOptionsPanel>
</div>
<div class="flex flex-row"> <div class="flex flex-row">
<mdicon name="crop" :size="16" />&nbsp;&nbsp; <mdicon name="crop" :size="16" />&nbsp;&nbsp;
<span>ZOOM</span> <span>STRETCH</span>
</div> </div>
<div <div
style="margin-top: -0.69rem; margin-bottom: 0.88rem;" style="margin-top: -0.69rem; margin-bottom: 0.88rem;"
> >
<ZoomOptionsPanel <StretchOptionsPanel
:settings="settings" :settings="settings"
:eventBus="eventBus" :eventBus="eventBus"
:siteSettings="siteSettings" :siteSettings="siteSettings"
:isEditing="false" :isEditing="false"
:compact="true" :compact="true"
> ></StretchOptionsPanel>
</ZoomOptionsPanel> </div>
</div>
<div class="flex flex-row"> <div class="flex flex-row">
<mdicon name="crop" :size="16" />&nbsp;&nbsp; <mdicon name="crop" :size="16" />&nbsp;&nbsp;
<span>ALIGN</span> <span>ZOOM</span>
</div> </div>
<div <div
style="margin-bottom: 0.88rem;" style="margin-top: -0.69rem; margin-bottom: 0.88rem;"
>
<ZoomOptionsPanel
:settings="settings"
:eventBus="eventBus"
:siteSettings="siteSettings"
:isEditing="false"
:compact="true"
> >
<AlignmentOptionsControlComponent </ZoomOptionsPanel>
:eventBus="eventBus" </div>
:large="true"
> </AlignmentOptionsControlComponent> <div class="flex flex-row">
</div> <mdicon name="crop" :size="16" />&nbsp;&nbsp;
</template> <span>ALIGN</span>
</div>
<div
style="margin-bottom: 0.88rem;"
>
<AlignmentOptionsControlComponent
:eventBus="eventBus"
:large="true"
> </AlignmentOptionsControlComponent>
</div>
</div> </div>

View File

@ -1,109 +1,42 @@
<template> <template>
<div class="flex flex-row" style="width: 250px;"> <div>
<div class="flex-grow"> Custom zoom
Custom zoom
</div>
<div class="flex flex-row">
<Button
v-if="zoomAspectRatioLocked"
icon="lock"
:iconSize="16"
:fixedWidth="true"
:noPad="true"
@click="toggleZoomAr()"
>
</Button>
<Button
v-else
icon="lock-open-variant"
:iconSize="16"
:fixedWidth="true"
:noPad="true"
@click="toggleZoomAr()"
>
</Button>
<Button
icon="restore"
:iconSize="16"
:noPad="true"
@click="resetZoom()"
></Button>
</div>
</div> </div>
<template v-if="zoomAspectRatioLocked"> <div class="top-label">Zoom:</div>
<div class="input range-input no-bg"> <div class="input range-input">
<input <input
type="range" type="range"
class="slider" class="slider"
min="-1" min="0"
max="3" max="3"
step="0.01" step="0.01"
:value="zoom.x" />
@input="changeZoom($event.target.value)" <input
/> />
<input </div>
class="disabled"
style="width: 2rem;"
:value="getZoomForDisplay('x')"
/>
</div>
</template> <template v-if="true">
<template v-else>
<div class="top-label">Horizontal zoom:</div>
<div class="input range-input no-bg">
<input
type="range"
class="slider"
min="-1"
max="3"
step="0.01"
:value="zoom.x"
@input="changeZoom($event.target.value, 'x')"
/>
<input
class="disabled"
style="width: 2rem;"
:value="getZoomForDisplay('x')"
/>
</div>
<div class="top-label">Vertical zoom:</div> <div class="top-label">Vertical zoom:</div>
<div class="input range-input no-bg"> <div class="input range-input">
<input <input
type="range" type="range"
class="slider" class="slider"
min="-1" min="0"
max="3" max="3"
step="0.01" step="0.01"
:value="zoom.y"
@input="changeZoom($event.target.value, 'y')"
/> />
<input <input
class="disabled"
style="width: 2rem;"
:value="getZoomForDisplay('y')"
/> />
</div> </div>
</template> </template>
<div><input type="checkbox"/> Control vertical and horizontal zoom independently.</div>
</template> </template>
<script> <script>
import Button from '@csui/src/components/Button.vue';
import * as _ from 'lodash';
export default { export default {
components: {
Button,
},
mixins: [
],
props: [
'settings', // required for buttons and actions, which are global
'eventBus'
],
data() { data() {
return { return {
zoomAspectRatioLocked: true, zoomAspectRatioLocked: true,
@ -118,42 +51,17 @@ export default {
stretch: null, stretch: null,
zoom: null, zoom: null,
pan: null pan: null
}, }
pollingInterval: undefined,
debouncedGetEffectiveZoom: undefined,
} }
}, },
created() { mixins: [
this.eventBus?.subscribeMulti(
{ ],
'announce-zoom': { props: [
function: (data) => { 'settings', // required for buttons and actions, which are global
this.zoom = { 'eventBus'
x: Math.log2(data.x), ],
y: Math.log2(data.y)
};
}
}
},
this
);
this.debouncedGetEffectiveZoom = _.debounce(
() => {
this.getEffectiveZoom();
},
250
),
this.getEffectiveZoom();
this.pollingInterval = setInterval(this.debouncedGetEffectiveZoom, 2000);
},
destroyed() {
this.eventBus.unsubscribe(this);
clearInterval(this.pollingInterval);
},
methods: { methods: {
getEffectiveZoom() {
this.eventBus?.sendToTunnel('get-effective-zoom', {});
},
getZoomForDisplay(axis) { getZoomForDisplay(axis) {
// zoom is internally handled logarithmically, because we want to have x0.5, x1, x2, x4 ... magnifications // zoom is internally handled logarithmically, because we want to have x0.5, x1, x2, x4 ... magnifications
// spaced out at regular intervals. When displaying, we need to convert that to non-logarithmic values. // spaced out at regular intervals. When displaying, we need to convert that to non-logarithmic values.
@ -173,36 +81,25 @@ export default {
// this.eventBus.send('set-zoom', {zoom: 1, axis: 'y'}); // this.eventBus.send('set-zoom', {zoom: 1, axis: 'y'});
// this.eventBus.send('set-zoom', {zoom: 1, axis: 'x'}); // this.eventBus.send('set-zoom', {zoom: 1, axis: 'x'});
this.eventBus?.sendToTunnel('set-zoom', {zoom: 1}); this.eventBus?.sendToTunnel('set-zoom', {zoom: 1, axis: 'y'});
this.eventBus?.sendToTunnel('set-zoom', {zoom: 1, axis: 'x'});
}, },
changeZoom(newZoom, axis, isLinear) { changeZoom(newZoom, axis) {
if (isNaN(+newZoom)) { // we store zoom logarithmically on this compnent
return;
}
let logZoom, linZoom;
if (isLinear) {
newZoom /= 100;
logZoom = Math.log2(newZoom);
linZoom = newZoom;
} else {
logZoom = newZoom;
linZoom = Math.pow(2, newZoom);
}
// we store zoom logarithmically on this component
if (!axis) { if (!axis) {
this.zoom.x = logZoom; this.zoom.x = newZoom;
} else { } else {
this.zoom[axis] = logZoom; this.zoom[axis] = newZoom;
} }
// 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);
if (this.zoomAspectRatioLocked) { if (this.zoomAspectRatioLocked) {
this.eventBus?.sendToTunnel('set-zoom', {zoom: linZoom}); this.eventBus?.sendToTunnel('set-zoom', {zoom: newZoom, axis: 'y'});
this.eventBus?.sendToTunnel('set-zoom', {zoom: newZoom, axis: 'x'});
} else { } else {
this.eventBus?.sendToTunnel('set-zoom', {zoom: {[axis ?? 'x']: linZoom}}); this.eventBus?.sendToTunnel('set-zoom', {zoom: newZoom, axis: axis ?? 'x'});
} }
}, },
} }

View File

@ -89,12 +89,6 @@ button, .button {
border-bottom: 1px solid rgba($primary, 0.5); border-bottom: 1px solid rgba($primary, 0.5);
} }
&.no-bg {
background-color: transparent;
border-color: transparent;
}
input { input {
width: 100%; width: 100%;
outline: none; outline: none;

View File

@ -119,9 +119,6 @@ const ExtensionConfPatch = Object.freeze([
onKeyUp: true, onKeyUp: true,
onKeyDown: false, onKeyDown: false,
}, },
arguments: {
zoom: 1
},
internalOnly: true, internalOnly: true,
actionId: 'set-zoom-reset' actionId: 'set-zoom-reset'
}, { }, {

View File

@ -411,9 +411,6 @@ const ExtensionConf: SettingsInterface = {
onKeyUp: true, onKeyUp: true,
onKeyDown: false, onKeyDown: false,
}, },
arguments: {
zoom: 1,
},
internalOnly: true, internalOnly: true,
actionId: 'set-zoom-reset' actionId: 'set-zoom-reset'
}, { }, {

View File

@ -19,10 +19,6 @@ export interface EventBusContext {
frame?: any, frame?: any,
sourceFrame?: IframeData sourceFrame?: IframeData
forwardTo?: 'all' | 'active' | 'contentScript' | 'server' | 'sameOrigin' | 'popup' | 'all-frames', forwardTo?: 'all' | 'active' | 'contentScript' | 'server' | 'sameOrigin' | 'popup' | 'all-frames',
};
borderCrossings?: {
commsServer?: boolean,
iframe?: boolean,
} }
} }
@ -33,9 +29,6 @@ export default class EventBus {
private disableTunnel: boolean = false; private disableTunnel: boolean = false;
private popupContext: any = {}; private popupContext: any = {};
private iframeForwardingList: {iframe: any, fn: (action, payload, context?) => void}[] = [];
// private uiUri = window.location.href; // private uiUri = window.location.href;
constructor(options?: {isUWServer?: boolean}) { constructor(options?: {isUWServer?: boolean}) {
@ -90,18 +83,6 @@ export default class EventBus {
} }
} }
forwardToIframe(iframe: any, fn: (action: string, payload: any, context?: EventBusContext) => void) {
this.cancelIframeForwarding(iframe);
this.iframeForwardingList.push({iframe, fn});
}
cancelIframeForwarding(iframe: any) {
const existingForwarding = this.iframeForwardingList.findIndex((x: any) => x.iframe === iframe);
if (existingForwarding !== -1) {
this.iframeForwardingList.splice(existingForwarding, 1);
}
}
send(command: string, commandData: any, context?: EventBusContext) { send(command: string, commandData: any, context?: EventBusContext) {
// execute commands we have subscriptions for // execute commands we have subscriptions for
@ -113,27 +94,8 @@ export default class EventBus {
// preventing messages from flowing back to their original senders is // preventing messages from flowing back to their original senders is
// CommsServer's job. EventBus does not have enough data for this decision. // CommsServer's job. EventBus does not have enough data for this decision.
// We do, however, have enough data to prevent backflow of messages that if (this.comms) {
// crossed CommsServer once already.
if (this.comms && context?.origin !== CommsOrigin.Server && !context?.borderCrossings?.commsServer) {
this.comms.sendMessage({command, config: commandData, context}, context); this.comms.sendMessage({command, config: commandData, context}, context);
};
// call forwarding functions if they exist
if (!context?.borderCrossings?.iframe) {
for (const forwarding of this.iframeForwardingList) {
forwarding.fn(
command,
commandData,
{
...context,
borderCrossings: {
...context?.borderCrossings,
iframe: true
}
}
);
}
} }
if (context?.stopPropagation) { if (context?.stopPropagation) {

View File

@ -186,9 +186,7 @@ export class AardDebugUi {
<div style="flex-grow: 1">${this.generateMiniGraphBar(this.aard.timer.average)}</div> <div style="flex-grow: 1">${this.generateMiniGraphBar(this.aard.timer.average)}</div>
</div> </div>
<div style="display: flex; flex-direction: row"> <div style="display: flex; flex-direction: row">
<div style="width: 120px">Last chg.:</div> <div style="width: 120px">Last chg.:</div><div style="flex-grow: 1">${this.generateMiniGraphBar(this.aard.timer.lastChange)}</div>
<div></div>
<div style="flex-grow: 1">${this.generateMiniGraphBar(this.aard.timer.lastChange)}</div>
</div> </div>
`; `;

View File

@ -128,7 +128,7 @@ class CommsClient {
} }
//#endregion //#endregion
async sendMessage(message, context?: EventBusContext, borderCrossings?){ async sendMessage(message, context?: EventBusContext){
this.logger.info('sendMessage', ' <<< Sending message to background script:', message); this.logger.info('sendMessage', ' <<< Sending message to background script:', message);
message = JSON.parse(JSON.stringify(message)); // vue quirk. We should really use vue store instead message = JSON.parse(JSON.stringify(message)); // vue quirk. We should really use vue store instead
@ -144,11 +144,8 @@ class CommsClient {
return port.postMessage(message); return port.postMessage(message);
} }
} }
// send to server // send to server
if (!context?.borderCrossings?.commsServer) { return chrome.runtime.sendMessage(null, message, null);
return chrome.runtime.sendMessage(null, message, null);
}
} }
/** /**
@ -173,10 +170,7 @@ class CommsClient {
message.config, message.config,
{ {
comms, comms,
origin: CommsOrigin.Server, origin: CommsOrigin.Server
borderCrossings: {
commsServer: true
}
} }
); );
} }

View File

@ -52,26 +52,9 @@ class CommsServer {
} = {}; } = {};
popupPort: any; popupPort: any;
private _lastActiveTab: chrome.tabs.Tab | undefined;
//#region getters //#region getters
get activeTab(): Promise<chrome.tabs.Tab | undefined> { get activeTab() {
return new Promise((resolve, reject) => { return chrome.tabs.query({currentWindow: true, active: true});
chrome.tabs
.query({currentWindow: true, active: true})
.then((tabs) => {
if (tabs.length === 0) {
this.logger.warn('<getter-activeTab>', 'no active tab found, returning last valid active tab instead ...', this._lastActiveTab);
resolve(this._lastActiveTab);
} else {
this.logger.log('<getter-activeTab>', 'getting active tab', tabs[0]);
this._lastActiveTab = tabs[0];
resolve(tabs[0]);
}
})
.catch((err) => {
this.logger.error('<getter-activeTab>', 'error while getting active tab — returned last valid active tab instead ...', err, this._lastActiveTab);
});
});
} }
//#endregion //#endregion
@ -127,10 +110,6 @@ class CommsServer {
// stop messages from returning where they came from, and prevent // stop messages from returning where they came from, and prevent
// cross-pollination between content scripts running in different // cross-pollination between content scripts running in different
// tabs. // tabs.
if (!context) {
this.logger.debug('sendMessage', 'context was not passed in as parameter - does message have context?', message.context);
context = message.context;
}
if (context?.origin !== CommsOrigin.ContentScript) { if (context?.origin !== CommsOrigin.ContentScript) {
if (context?.comms.forwardTo === 'all') { if (context?.comms.forwardTo === 'all') {
@ -257,13 +236,13 @@ class CommsServer {
private async sendToActive(message) { private async sendToActive(message) {
this.logger.info('sendToActive', ` <——— trying to send a message ${message.command ?? ''} to active tab. Message:`, message); this.logger.info('sendToActive', ` <——— trying to send a message ${message.command ?? ''} to active tab. Message:`, message);
const tab = await this.activeTab; const tabs = await this.activeTab;
this.logger.info('sendToActive', "currently active tab?", tab); this.logger.info('sendToActive', "currently active tab(s)?", tabs);
for (const frame in this.ports[tab.id]) { for (const frame in this.ports[tabs[0].id]) {
this.logger.info('sendToActive', "sending message to frame:", frame, this.ports[tab.id][frame], '; message:', message); this.logger.info('sendToActive', "sending message to frame:", frame, this.ports[tabs[0].id][frame], '; message:', message);
this.sendToFrameContentScripts(message, tab.id, frame); this.sendToFrameContentScripts(message, tabs[0].id, frame);
} }
} }
@ -290,7 +269,7 @@ class CommsServer {
} }
private processReceivedMessage_nonpersistent(message, sender){ private processReceivedMessage_nonpersistent(message, sender){
this.logger.info('processMessage_nonpersistent', ` ==> Received message from background script!`, message, sender); this.logger.info('processMessage_nonpersistent', ` ==> Received message from background script!`, "background-color: #11D; color: #aad", message, sender);
this.eventBus.send( this.eventBus.send(
message.command, message.command,

View File

@ -22,13 +22,12 @@ export class ComponentLogger {
constructor(logAggregator: LogAggregator, component: string, componentOptions?: ComponentLoggerOptions) { constructor(logAggregator: LogAggregator, component: string, componentOptions?: ComponentLoggerOptions) {
this.logAggregator = logAggregator; this.logAggregator = logAggregator;
this.component = component; this.component = component;
this.componentOptions = componentOptions;
} }
private handleLog(logLevel: LogLevel, sourceFunction: string | LogSourceOptions, ...message: any) { private handleLog(logLevel: LogLevel, sourceFunction: string | LogSourceOptions, ...message: any) {
let functionSource = typeof sourceFunction === 'string' ? sourceFunction : sourceFunction?.src; let functionSource = typeof sourceFunction === 'string' ? sourceFunction : sourceFunction?.src;
let consoleMessageString = `[${this.component}${functionSource ? `::${functionSource}` : ''}]`; let consoleMessageString = `[${this.component}${functionSource ? `::${functionSource}` : ''}] `;
const consoleMessageData = [] const consoleMessageData = []
for (const m of message) { for (const m of message) {
@ -36,13 +35,10 @@ export class ComponentLogger {
consoleMessageString = `${consoleMessageString} ${m}`; consoleMessageString = `${consoleMessageString} ${m}`;
} else if (typeof m === 'number') { } else if (typeof m === 'number') {
consoleMessageString = `${consoleMessageString} %f`; consoleMessageString = `${consoleMessageString} %f`;
consoleMessageData.unshift(m); } else if (m instanceof HTMLElement) {
} else if (typeof HTMLElement !== 'undefined' && m instanceof HTMLElement) { // HTMLElement does not exist in background script, but this class may
consoleMessageString = `${consoleMessageString} %o`; consoleMessageString = `${consoleMessageString} %o`;
consoleMessageData.unshift(m);
} else { } else {
consoleMessageString = `${consoleMessageString} %O`; consoleMessageString = `${consoleMessageString} %O`;
consoleMessageData.unshift(m);
} }
} }

View File

@ -4,6 +4,11 @@ export const BLANK_LOGGER_CONFIG: LogConfig = {
logToConsole: false, logToConsole: false,
logToFile: false, logToFile: false,
component: { component: {
aard: { enabled: false },
resizer: { enabled: false },
comms: { enabled: false },
settings: { enabled: false },
eventBus: { enabled: false },
}, },
origins: { origins: {
videoRescan: { disabled: true}, videoRescan: { disabled: true},
@ -31,7 +36,6 @@ export interface LogConfig {
} }
} }
const STORAGE_LOG_SETTINGS_KEY = 'uw-log-config';
export class LogAggregator { export class LogAggregator {
private segment: string; private segment: string;
@ -42,34 +46,29 @@ export class LogAggregator {
history: any[]; history: any[];
static async getConfig() { static async getConfig() {
let ret = await chrome.storage.local.get(STORAGE_LOG_SETTINGS_KEY); let ret = await chrome.storage.local.get('uw-log-config');
if (process.env.CHANNEL === 'dev') { if (process.env.CHANNEL === 'dev') {
try { try {
console.info("[LogAggregator::getSaved] Got settings:", JSON.parse(ret[STORAGE_LOG_SETTINGS_KEY])); console.info("[Logger::getSaved] Got settings:", JSON.parse(ret.uwLogger));
} catch (e) { } catch (e) {
console.info("[LogAggregator::getSaved] No settings.", ret) console.info("[Logger::getSaved] No settings.")
} }
} }
try { try {
return JSON.parse(ret[STORAGE_LOG_SETTINGS_KEY]); return JSON.parse(ret['uw-log-config']);
} catch (e) { } catch (e) {
return JSON.parse(JSON.stringify(BLANK_LOGGER_CONFIG)); return JSON.parse(JSON.stringify(BLANK_LOGGER_CONFIG));
} }
} }
static async saveConfig(conf: LogConfig) { static saveConfig(conf: LogConfig) {
try { if (process.env.CHANNEL === 'dev') {
const confCp = JSON.parse(JSON.stringify(conf)); console.info('Saving logger conf:', conf)
if (process.env.CHANNEL === 'dev') {
console.info('Saving logger conf:', confCp)
}
await chrome.storage.local.set({[STORAGE_LOG_SETTINGS_KEY]: JSON.stringify(confCp)} );
} catch (e) {
console.warn('[LogAggregator::saveConfig] Error while trying to save logger config:', e);
} }
chrome.storage.local.set( {'uw-log-config': JSON.stringify(conf)});
} }
static syncConfig(callback: (x) => void) { static syncConfig(callback: (x) => void) {
@ -90,35 +89,26 @@ export class LogAggregator {
chrome.storage.onChanged.addListener((changes, area) => { chrome.storage.onChanged.addListener((changes, area) => {
this.storageChangeListener(changes, area) this.storageChangeListener(changes, area)
}); });
this.init();
} }
private canLog(component: string, sourceOptions?: LogSourceOptions): boolean { private canLog(component: string, sourceOptions?: LogSourceOptions): boolean {
// component is not in config, so we add a blank entry
if (this.config && !this.config.component[component]) {
this.config.component[component] = {enabled: false};
LogAggregator.saveConfig(this.config);
return false;
}
if (this.config?.component?.[component]?.enabled) { if (this.config?.component?.[component]?.enabled) {
if (sourceOptions?.origin && this.config?.origins?.[sourceOptions.origin]?.disabled) { if (sourceOptions?.origin && this.config?.origins?.[sourceOptions.origin]?.disabled) {
return false; return false;
} }
return true; return true;
} }
return false; return false;
} }
private storageChangeListener(changes, area) { private storageChangeListener(changes, area) {
if (!changes[STORAGE_LOG_SETTINGS_KEY]) { if (!changes.uwLogger) {
console.info('We dont have any logging settings, not processing frther', changes); console.info('We dont have any logging settings, not processing frther');
return; return;
} }
try { try {
this.config = JSON.parse(changes[STORAGE_LOG_SETTINGS_KEY].newValue); this.config = JSON.parse(changes['uw-log-config'].newValue);
} catch (e) { } catch (e) {
console.warn('[uwLogger] Error while trying to parse new conf for logger:', e, '\nWe received the following changes:', changes, 'for area:', area); console.warn('[uwLogger] Error while trying to parse new conf for logger:', e, '\nWe received the following changes:', changes, 'for area:', area);
} }
@ -198,11 +188,7 @@ export class LogAggregator {
} }
async init(config?: LogConfig) { async init(config: LogConfig) {
if (!config) {
config = await LogAggregator.getConfig();
}
this.config = config; this.config = config;
this.startTime = performance.now(); this.startTime = performance.now();
@ -225,7 +211,7 @@ export class LogAggregator {
} }
if (this.config.logToConsole){ if (this.config.logToConsole) {
console[logLevel](`[${this.segment}]>>${message}`, ...data, {stack: this.parseStack()}); console[logLevel](`[${this.segment}]>>${message}`, ...data, {stack: this.parseStack()});
} }
} }

View File

@ -205,18 +205,10 @@ class UI {
document.addEventListener('mousemove', fn, true); document.addEventListener('mousemove', fn, true);
} }
this.eventBus.forwardToIframe(
this.uiIframe,
(action, payload) => {
this.sendToIframe(action, payload, {})
}
);
this.rootDiv.appendChild(iframe); this.rootDiv.appendChild(iframe);
} }
unloadIframe() { unloadIframe() {
this.eventBus.cancelIframeForwarding(this.uiIframe);
window.removeEventListener('message', this.messageHandlerFn); window.removeEventListener('message', this.messageHandlerFn);
this.uiIframe?.remove(); this.uiIframe?.remove();
delete this.uiIframe; delete this.uiIframe;
@ -424,17 +416,7 @@ class UI {
break; break;
case 'uw-bus-tunnel': case 'uw-bus-tunnel':
const busCommand = event.data.payload; const busCommand = event.data.payload;
this.eventBus.send( this.eventBus.send(busCommand.action, busCommand.config, busCommand.routingData);
busCommand.action,
busCommand.config,
{
...busCommand?.context,
borderCrossings: {
...busCommand?.context?.borderCrossings,
iframe: true,
}
}
);
break; break;
case 'uwui-get-role': case 'uwui-get-role':
this.sendToIframeLowLevel('uwui-set-role', {role: this.isGlobal ? 'global' : 'player'}); this.sendToIframeLowLevel('uwui-set-role', {role: this.isGlobal ? 'global' : 'player'});

View File

@ -190,7 +190,7 @@ class PlayerData {
constructor(videoData) { constructor(videoData) {
try { try {
// set all our helper objects // set all our helper objects
this.logger = new ComponentLogger(videoData.logAggregator, 'PlayerData', {styles: {}}); this.logger = new ComponentLogger(videoData.logAggregator, 'PlayerData', {styles: Debug.getLoggingStyles()});
this.videoData = videoData; this.videoData = videoData;
this.videoElement = videoData.video; this.videoElement = videoData.video;
this.pageInfo = videoData.pageInfo; this.pageInfo = videoData.pageInfo;
@ -482,17 +482,10 @@ class PlayerData {
} }
} }
onPlayerDimensionsChanged: ResizeObserverCallback = _.debounce( onPlayerDimensionsChanged(mutationList?, observer?) {
(mutationList?, observer?) => { this.trackDimensionChanges();
this.trackDimensionChanges(); this.trackEnvironmentChanges();
this.trackEnvironmentChanges(); }
},
250, // do it once per this many ms
{
leading: true, // do it when we call this fallback first
trailing: true // do it after the timeout if we call this callback few more times
}
);
//#region player element change detection //#region player element change detection
@ -506,19 +499,29 @@ class PlayerData {
} }
try { try {
if (this.observer) {
this.observer.disconnect();
}
this.observer = new ResizeObserver( this.observer = new ResizeObserver(
this.onPlayerDimensionsChanged _.debounce( // don't do this too much:
(m,o) => {
this.onPlayerDimensionsChanged(m,o)
},
250, // do it once per this many ms
{
leading: true, // do it when we call this fallback first
trailing: true // do it after the timeout if we call this callback few more times
}
)
); );
const observerConf = {
attributes: true,
// attributeFilter: ['style', 'class'],
attributeOldValue: true,
};
this.observer.observe(this.element); this.observer.observe(this.element);
} catch (e) { } catch (e) {
console.error("failed to set observer",e ); console.error("failed to set observer",e )
} }
// legacy mode still exists, but acts as a fallback for observers and is triggered less // legacy mode still exists, but acts as a fallback for observers and is triggered less
// frequently in order to avoid too many pointless checks // frequently in order to avoid too many pointless checks
this.legacyChangeDetection(); this.legacyChangeDetection();

View File

@ -63,8 +63,6 @@ class Resizer {
currentCssValidFor: any; currentCssValidFor: any;
currentVideoSettings: any; currentVideoSettings: any;
private effectiveZoom: {x: number, y: number} = {x: 1, y: 1};
_lastAr: Ar = {type: AspectRatioType.Initial}; _lastAr: Ar = {type: AspectRatioType.Initial};
set lastAr(x: Ar) { set lastAr(x: Ar) {
// emit updates for UI when setting lastAr, but only if AR really changed // emit updates for UI when setting lastAr, but only if AR really changed
@ -90,11 +88,6 @@ class Resizer {
//#region event bus configuration //#region event bus configuration
private eventBusCommands = { private eventBusCommands = {
'get-effective-zoom': [{
function: () => {
this.eventBus.send('announce-zoom', this.manualZoom ? {x: this.zoom.scale, y: this.zoom.scaleY} : this.zoom.effectiveZoom);
}
}],
'set-ar': [{ 'set-ar': [{
function: (config: any) => { function: (config: any) => {
this.manualZoom = false; // this only gets called from UI or keyboard shortcuts, making this action safe. this.manualZoom = false; // this only gets called from UI or keyboard shortcuts, making this action safe.
@ -143,9 +136,7 @@ class Resizer {
} }
}], }],
'set-zoom': [{ 'set-zoom': [{
function: (config: any) => { function: (config: any) => this.setZoom(config.zoom)
this.setZoom(config?.zoom ?? {zoom: 1});
}
}], }],
'change-zoom': [{ 'change-zoom': [{
function: (config: any) => this.zoomStep(config.zoom) function: (config: any) => this.zoomStep(config.zoom)
@ -458,12 +449,12 @@ class Resizer {
} }
applyScaling(stretchFactors: VideoDimensions, options?: {noAnnounce?: boolean, ar?: Ar}) { applyScaling(stretchFactors: VideoDimensions, options?: {noAnnounce?: boolean, ar?: Ar}) {
this.zoom.effectiveZoom = {x: stretchFactors.xFactor, y: stretchFactors.yFactor}; // this.stretcher.chromeBugMitigation(stretchFactors);
// announcing zoom somehow keeps incorrectly resetting zoom sliders in UI — UI is now polling for effective zoom while visible // let the UI know
// if(!options?.noAnnounce) { if(!options?.noAnnounce) {
// this.videoData.eventBus.send('announce-zoom', this.manualZoom ? {x: this.zoom.scale, y: this.zoom.scaleY} : this.zoom.effectiveZoom); this.videoData.eventBus.send('announce-zoom', {x: stretchFactors.xFactor, y: stretchFactors.yFactor});
// } }
let translate = this.computeOffsets(stretchFactors, options?.ar); let translate = this.computeOffsets(stretchFactors, options?.ar);
this.applyCss(stretchFactors, translate); this.applyCss(stretchFactors, translate);

View File

@ -30,7 +30,6 @@ class Zoom {
maxScale = 8; maxScale = 8;
//#endregion //#endregion
effectiveZoom: {x: number, y: number}; // we're setting this in Resizer based on Resizer data!
constructor(videoData) { constructor(videoData) {
this.conf = videoData; this.conf = videoData;
@ -51,12 +50,7 @@ class Zoom {
* @param axis leave undefined to apply zoom to both axes * @param axis leave undefined to apply zoom to both axes
*/ */
zoomStep(amount: number, axis?: 'x' | 'y') { zoomStep(amount: number, axis?: 'x' | 'y') {
const effectiveLog = { let newLog = axis === 'y' ? this.logScaleY : this.logScale;
x: Math.log2(this.effectiveZoom.x),
y: Math.log2(this.effectiveZoom.y)
};
let newLog = axis === 'y' ? effectiveLog.y : effectiveLog.x;
newLog += amount; newLog += amount;
newLog = Math.min(Math.max(newLog, LOG_MIN_SCALE), LOG_MAX_SCALE); newLog = Math.min(Math.max(newLog, LOG_MIN_SCALE), LOG_MAX_SCALE);
@ -71,6 +65,7 @@ class Zoom {
this.scale = Math.pow(2, this.logScale); this.scale = Math.pow(2, this.logScale);
this.scaleY = Math.pow(2, this.logScaleY); this.scaleY = Math.pow(2, this.logScaleY);
this.logger.info('zoomStep', "changing zoom by", amount, ". New zoom level:", this.scale);
this.processZoom(); this.processZoom();
} }
@ -99,6 +94,18 @@ class Zoom {
this.conf.resizer.toFixedAr(); this.conf.resizer.toFixedAr();
this.conf.resizer.applyScaling({xFactor: this.scale, yFactor: this.scaleY}, {noAnnounce: true}); this.conf.resizer.applyScaling({xFactor: this.scale, yFactor: this.scaleY}, {noAnnounce: true});
} }
applyZoom(stretchFactors){
if (!stretchFactors) {
return;
}
this.logger.info('setZoom', "Applying zoom. Stretch factors pre:", stretchFactors, " —> scale:", this.scale);
stretchFactors.xFactor *= this.scale;
stretchFactors.yFactor *= this.scale;
this.logger.info('setZoom', "Applying zoom. Stretch factors post:", stretchFactors);
}
} }
export default Zoom; export default Zoom;

View File

@ -85,8 +85,11 @@ export default {
async created() { async created() {
this.logAggregator = new LogAggregator(''); this.logAggregator = new LogAggregator('');
this.logger = new ComponentLogger(this.logAggregator, 'App.vue'); this.logger = new ComponentLogger(this.logAggregator, 'App.vue');
await this.logger.init({
allowLogging: true,
});
this.settings = new Settings({updateCallback: () => this.updateConfig(), logAggregator: this.logAggregator }); this.settings = new Settings({updateCallback: () => this.updateConfig(), logger: this.logger});
await this.settings.init(); await this.settings.init();
this.settingsInitialized = true; this.settingsInitialized = true;
}, },

View File

@ -87,7 +87,11 @@ export default {
this.logAggregator = new LogAggregator(''); this.logAggregator = new LogAggregator('');
this.logger = new ComponentLogger(this.logAggregator, 'App.vue'); this.logger = new ComponentLogger(this.logAggregator, 'App.vue');
this.settings = new Settings({updateCallback: () => this.updateConfig(), logAggregator: this.logAggregator}); await this.logger.init({
allowLogging: true,
});
this.settings = new Settings({updateCallback: () => this.updateConfig(), logger: this.logger});
await this.settings.init(); await this.settings.init();
this.settingsInitialized = true; this.settingsInitialized = true;
}, },

View File

@ -111,6 +111,10 @@
<script> <script>
import Donate from '../common/misc/Donate.vue'; import Donate from '../common/misc/Donate.vue';
import SuperAdvancedSettings from './SuperAdvancedSettings.vue'; import SuperAdvancedSettings from './SuperAdvancedSettings.vue';
import Debug from '../ext/conf/Debug';
import BrowserDetect from '../ext/conf/BrowserDetect';
import ExtensionConf from '../ext/conf/ExtensionConf';
import ObjectCopy from '../ext/lib/ObjectCopy';
import Settings from '../ext/lib/Settings'; import Settings from '../ext/lib/Settings';
import GeneralSettings from './GeneralSettings'; import GeneralSettings from './GeneralSettings';
import ControlsSettings from './controls-settings/ControlsSettings'; import ControlsSettings from './controls-settings/ControlsSettings';
@ -118,6 +122,7 @@ import AddEditActionPopup from './controls-settings/AddEditActionPopup';
import ConfirmPopup from './common/ConfirmationPopup'; import ConfirmPopup from './common/ConfirmationPopup';
import About from './about' import About from './about'
import AutodetectionSettings from './AutodetectionSettings'; import AutodetectionSettings from './AutodetectionSettings';
// import SuperAdvancedSettings from './'
import { LogAggregator } from '@src/ext/lib/logging/LogAggregator'; import { LogAggregator } from '@src/ext/lib/logging/LogAggregator';
import { ComponentLogger } from '@src/ext/lib/logging/ComponentLogger'; import { ComponentLogger } from '@src/ext/lib/logging/ComponentLogger';
@ -144,8 +149,11 @@ export default {
async created () { async created () {
this.logAggregator = new LogAggregator(''); this.logAggregator = new LogAggregator('');
this.logger = new ComponentLogger(this.logAggregator, 'App.vue'); this.logger = new ComponentLogger(this.logAggregator, 'App.vue');
await this.logger.init({
allowLogging: true,
});
this.settings = new Settings({updateCallback: this.updateSettings, logAggregator: this.logAggregator}); this.settings = new Settings({updateCallback: this.updateSettings, logger: this.logger});
await this.settings.init(); await this.settings.init();
this.settingsInitialized = true; this.settingsInitialized = true;