Compare commits

..

No commits in common. "3d8d8eb19924be2e988fbb788fab748e0305558c" and "c9818c92b36105b1550725c364e228b2b77c7884" have entirely different histories.

10 changed files with 123 additions and 148 deletions

View File

@ -446,8 +446,6 @@ interface SettingsInterface {
} }
export interface SiteSettingsInterface { export interface SiteSettingsInterface {
notes?: string; // any special things related to this site.
enable: ExtensionMode; enable: ExtensionMode;
enableAard: ExtensionMode; enableAard: ExtensionMode;
enableKeyboard: InputHandlingMode; enableKeyboard: InputHandlingMode;

View File

@ -120,12 +120,9 @@ export default class UWContent {
this.logger.debug('setup', "KeyboardHandler initiated."); this.logger.debug('setup', "KeyboardHandler initiated.");
if (this.globalUi) { this.globalUi = new UI('ultrawidify-global-ui', {eventBus: this.eventBus, isGlobal: true});
this.globalUi.destroy(); this.globalUi.enable();
} this.globalUi.setUiVisibility(false);
// this.globalUi = new UI('ultrawidify-global-ui', {eventBus: this.eventBus, isGlobal: true});
// this.globalUi.enable();
// this.globalUi.setUiVisibility(false);
} catch (e) { } catch (e) {
console.error('Ultrawidify: failed to start extension. Error:', e) console.error('Ultrawidify: failed to start extension. Error:', e)

View File

@ -9,7 +9,6 @@ import LegacyExtensionMode from '@src/common/enums/LegacyExtensionMode.enum';
import { PlayerDetectionMode } from '@src/common/enums/PlayerDetectionMode.enum'; import { PlayerDetectionMode } from '@src/common/enums/PlayerDetectionMode.enum';
import { SiteSupportLevel } from '@src/common/enums/SiteSupportLevel.enum'; import { SiteSupportLevel } from '@src/common/enums/SiteSupportLevel.enum';
import SettingsInterface from '@src/common/interfaces/SettingsInterface'; import SettingsInterface from '@src/common/interfaces/SettingsInterface';
import { _cp } from '@src/common/utils/_cp';
import { update } from 'lodash'; import { update } from 'lodash';
@ -479,13 +478,6 @@ const ExtensionConfPatch = Object.freeze([
} }
} }
} }
}, {
forVersion: '6.3.998',
updateFn: (userOptions: SettingsInterface, defaultOptions: SettingsInterface, logger?) => {
if (!userOptions.sites["www.amazon.com"]) {
userOptions.sites["www.amazon.com"] = _cp(defaultOptions.sites["www.amazon.com"] );
}
}
} }
]); ]);

View File

@ -983,29 +983,6 @@ const ExtensionConf: SettingsInterface = {
} }
} }
}, },
"www.amazon.com": {
enable: ExtensionMode.Default,
enableAard: ExtensionMode.Default,
enableKeyboard: InputHandlingMode.Enabled,
enableUI: ExtensionMode.Default,
applyToEmbeddedContent: EmbeddedContentSettingsOverridePolicy.Default,
overrideWhenEmbedded: EmbeddedContentSettingsOverridePolicy.Default,
type: SiteSupportLevel.CommunitySupport,
defaultType: SiteSupportLevel.CommunitySupport,
persistCSA: CropModePersistence.Default,
activeDOMConfig: "@community",
DOMConfig: {
"@community": {
type: SiteSupportLevel.CommunitySupport,
elements: {
player: {
detectionMode: PlayerDetectionMode.Auto,
allowAutoFallback: true
}
}
},
},
},
"www.twitch.tv": { "www.twitch.tv": {
enable: ExtensionMode.All, enable: ExtensionMode.All,
enableAard: ExtensionMode.All, enableAard: ExtensionMode.All,

View File

@ -107,6 +107,10 @@ export default class EventBus {
eventBusCommand.function(commandData, context); eventBusCommand.function(commandData, context);
} }
} }
if (context.commandId) {
const i = this.lastExecutedCommandIndex++ % this.lastExecutedCommandIds.length;
this.lastExecutedCommandIds[i] = context.commandId;
}
// 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.
@ -115,11 +119,6 @@ export default class EventBus {
if (!context.commandId) { if (!context.commandId) {
context.commandId = crypto.randomUUID(); context.commandId = crypto.randomUUID();
} }
if (context.commandId) {
const i = this.lastExecutedCommandIndex++ % this.lastExecutedCommandIds.length;
this.lastExecutedCommandIds[i] = context.commandId;
}
if ( if (
this.comms this.comms
&& context?.origin !== CommsOrigin.Server && context?.origin !== CommsOrigin.Server
@ -144,21 +143,12 @@ export default class EventBus {
...context, ...context,
borderCrossings: { borderCrossings: {
...context?.borderCrossings, ...context?.borderCrossings,
// iframe: true // we actually no longer check this prop, we should instead rely on visitedBusses
} }
} }
); );
} }
this.sendToTunnel(command, commandData, context);
// send to parent iframe
if (!this.disableTunnel && typeof window !== 'undefined') {
window.parent.postMessage(
{
action: 'uw-bus-tunnel',
payload: {command, config: commandData, context} as EventBusMessage
},
'*'
);
}
if (context?.stopPropagation) { if (context?.stopPropagation) {
return; return;
@ -166,6 +156,52 @@ export default class EventBus {
} }
//#endregion //#endregion
/**
* Send, but intended for sending commands from iframe to content scripts
* @param command
* @param config
*/
private sendToTunnel(command: string, config: any, context: EventBusContext = {}) {
if (!context.visitedBusses) {
// this should never trigger on production version of the extension.
console.error('Visited busses is missing from context. This is illegal.');
return;
}
if (!this.disableTunnel && typeof window !== 'undefined') {
window.parent.postMessage(
{
action: 'uw-bus-tunnel',
payload: {command, config, context} as EventBusMessage
},
'*'
);
} else {
// because iframe UI components get reused in the popup, we
// also need to set up a detour because the tunnel is closed
// in the popup
if (this.comms) {
try {
this.comms.sendMessage(
{
command,
config,
context: {
...this.popupContext,
...context
}
},
this.popupContext
);
} catch (e) {
if (command !== 'reload-required') {
this.send('reload-required', {}, context);
}
}
}
}
}
//#region iframe tunnelling //#region iframe tunnelling
private setupIframeTunnelling() { private setupIframeTunnelling() {
// forward messages coming from iframe tunnels // forward messages coming from iframe tunnels

View File

@ -176,7 +176,7 @@ class CommsServer {
if (context?.comms.forwardTo === 'all') { if (context?.comms.forwardTo === 'all') {
return this.sendToAll(message); return this.sendToAll(message);
} }
if (context?.comms.forwardTo === 'active' || !context?.comms.forwardTo) { if (context?.comms.forwardTo === 'active') {
return this.sendToActive(message); return this.sendToActive(message);
} }
if (context?.comms.forwardTo === 'contentScript') { if (context?.comms.forwardTo === 'contentScript') {

View File

@ -19,8 +19,6 @@ import { UwuiWindow } from './UwuiWindow';
import { createApp } from 'vue'; import { createApp } from 'vue';
import SettingsWindowContent from '@components/SettingsWindowContent.vue'; import SettingsWindowContent from '@components/SettingsWindowContent.vue';
import { Ar } from '@src/common/interfaces/ArInterface';
import { Stretch } from '@src/common/interfaces/StretchInterface';
// import jsonEditorCSS from 'vanilla-jsoneditor/themes/jse-theme-dark.css?inline' // import jsonEditorCSS from 'vanilla-jsoneditor/themes/jse-theme-dark.css?inline'
if (process.env.CHANNEL !== 'stable'){ if (process.env.CHANNEL !== 'stable'){
@ -41,9 +39,6 @@ class UI {
private extensionMenu: ClientMenu; private extensionMenu: ClientMenu;
private logger: ComponentLogger; private logger: ComponentLogger;
private forwardedCommandIds: string[] = new Array(64);
private lastForwardedCommandIndex = 0;
private uiState = { private uiState = {
lockXY: true, lockXY: true,
zoom: { // log2 scale — 100% is 0 zoom: { // log2 scale — 100% is 0
@ -95,12 +90,6 @@ class UI {
function: (commandData, context) => { function: (commandData, context) => {
this.createSettingsWindow(commandData?.initialState); this.createSettingsWindow(commandData?.initialState);
} }
},
'broadcast-scaling-params': {
function: (commandData: {effectiveZoom: {x: number, y: number}, lastAr: Ar, stretch: Stretch}, context) => {
console.warn('got scaling params:', commandData)
}
} }
}); });
} }
@ -132,7 +121,7 @@ class UI {
private initMessaging() { private initMessaging() {
if (this.messageListener) { if (this.messageListener) {
this.destroyMessaging(); window.removeEventListener('message', this.messageListener);
} else { } else {
this.messageListener = (event: MessageEvent) => { this.messageListener = (event: MessageEvent) => {
const data = event.data; const data = event.data;
@ -144,26 +133,7 @@ class UI {
const payload = data.payload; const payload = data.payload;
/** console.log('forwarding from tunnel to event bus. payload', payload);
* it appears that forwarded commands can be multiplying to ridiculous degree,
* but i didn't find anything that would obviously cause the message forwarding storm
* this means we'll try to avoid that via brute force.
*
* How bad is it?
* can get as bad as 100k messages a minute (!)
*/
if (!payload.context?.commandId) {
// user should never see this log
console.warn('Command context does not contain commandId. This is illegal. Message will not be forwarded.', {payload});
return;
}
if (this.forwardedCommandIds.includes(payload.context.commandId)) {
console.warn('this command was already forwarded, doing nothing:', {payload});
return;
}
const i = this.lastForwardedCommandIndex++ % this.forwardedCommandIds.length;
this.forwardedCommandIds[i] = payload.id;
// Forward to all iframes except the source // Forward to all iframes except the source
(UwuiWindow as any).instances?.forEach(win => { (UwuiWindow as any).instances?.forEach(win => {
@ -184,12 +154,6 @@ class UI {
window.addEventListener('message', this.messageListener); window.addEventListener('message', this.messageListener);
} }
private destroyMessaging() {
if (this.messageListener) {
window.removeEventListener('message', this.messageListener);
}
}
executeCommand(x: CommandInterface) { executeCommand(x: CommandInterface) {
this.eventBus.send(x.action, x.arguments); this.eventBus.send(x.action, x.arguments);
} }
@ -547,6 +511,10 @@ class UI {
}); });
} }
setUiVisibility(visible) {
return;
}
async enable() { async enable() {
// if root element is not present, we need to init the UI. // if root element is not present, we need to init the UI.
// if (!this.rootDiv) { // if (!this.rootDiv) {
@ -567,7 +535,6 @@ class UI {
* @param {*} newUiConfig * @param {*} newUiConfig
*/ */
replace(newUiConfig) { replace(newUiConfig) {
this.destroy();
this.uiConfig = newUiConfig; this.uiConfig = newUiConfig;
this.init(); this.init();
} }
@ -576,7 +543,6 @@ class UI {
if (this.extensionMenu) { if (this.extensionMenu) {
this.extensionMenu.destroy(); this.extensionMenu.destroy();
} }
this.destroyMessaging();
} }

View File

@ -195,10 +195,6 @@ class PlayerData {
//#region lifecycle //#region lifecycle
constructor(videoData) { constructor(videoData) {
if (!(window as any).uiCount) {
(window as any).uiCount = 1;
}
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: {}});
@ -879,9 +875,7 @@ class PlayerData {
bestCandidate.heuristics['qsMatch'] = true; bestCandidate.heuristics['qsMatch'] = true;
} }
if (bestCandidate) { bestCandidate.heuristics['activePlayer'] = true;
bestCandidate.heuristics['activePlayer'] = true;
}
return bestCandidate; return bestCandidate;
} }

View File

@ -298,16 +298,33 @@ class VideoData {
initializeObservers() { initializeObservers() {
try { try {
this.observer = new ResizeObserver( if (BrowserDetect.firefox) {
_.debounce( this.observer = new ResizeObserver(
() => this.onVideoDimensionsChanged, _.debounce(
250, this.onVideoDimensionsChanged,
{ 250,
leading: true, {
trailing: true leading: true,
} trailing: true
) }
); )
);
} else {
// Chrome for some reason insists that this.onPlayerDimensionsChanged is not a function
// when it's not wrapped into an anonymous function
this.observer = new ResizeObserver(
_.debounce(
(m, o) => {
this.onVideoDimensionsChanged(m, o)
},
250,
{
leading: true,
trailing: true
}
)
);
}
} catch (e) { } catch (e) {
console.error('[VideoData] Observer setup failed:', e); console.error('[VideoData] Observer setup failed:', e);
} }
@ -315,20 +332,34 @@ class VideoData {
} }
setupMutationObserver() { setupMutationObserver() {
if (this.mutationObserver) {
this.mutationObserver.disconnect();
}
try { try {
this.mutationObserver = new MutationObserver( if (BrowserDetect.firefox) {
_.debounce( this.mutationObserver = new MutationObserver(
() => this.onVideoMutation(), _.debounce(
250, this.onVideoMutation,
{ 250,
leading: true, {
trailing: true leading: true,
} trailing: true
}
)
) )
) } else {
// Chrome for some reason insists that this.onPlayerDimensionsChanged is not a function
// when it's not wrapped into an anonymous function
this.mutationObserver = new MutationObserver(
_.debounce(
(m, o) => {
this.onVideoMutation(m, o)
},
250,
{
leading: true,
trailing: true
}
)
)
}
} catch (e) { } catch (e) {
console.error('[VideoData] Observer setup failed:', e); console.error('[VideoData] Observer setup failed:', e);
} }
@ -341,17 +372,6 @@ class VideoData {
destroy() { destroy() {
this.logger.info('destroy', `<vdid:${this.vdid}> received destroy command`); this.logger.info('destroy', `<vdid:${this.vdid}> received destroy command`);
// Disconnect observer and set destroyed to 'true' _before_ removing classes from
// the video element
this.destroyed = true;
try {
this.observer.disconnect();
} catch (e) {}
try {
this.mutationObserver.disconnect();
} catch (e) {}
if (this.video) { if (this.video) {
this.video.classList.remove(this.userCssClassName); this.video.classList.remove(this.userCssClassName);
this.video.classList.remove('uw-ultrawidify-base-wide-screen'); this.video.classList.remove('uw-ultrawidify-base-wide-screen');
@ -361,6 +381,8 @@ class VideoData {
this.video.removeEventListener('ontimeupdate', this.onTimeUpdate); this.video.removeEventListener('ontimeupdate', this.onTimeUpdate);
} }
this.eventBus.send('set-run-level', RunLevel.Off);
this.destroyed = true;
this.eventBus.unsubscribeAll(this); this.eventBus.unsubscribeAll(this);
try { try {
@ -375,6 +397,9 @@ class VideoData {
try { try {
this.player.destroy(); this.player.destroy();
} catch (e) {} } catch (e) {}
try {
this.observer.disconnect();
} catch (e) {}
this.player = undefined; this.player = undefined;
this.video = undefined; this.video = undefined;
} }
@ -438,7 +463,7 @@ class VideoData {
this.runLevel = runLevel; this.runLevel = runLevel;
if (!options?.fromPlayer) { if (!options?.fromPlayer) {
this.player?.setRunLevel(runLevel); this.player.setRunLevel(runLevel);
} }
} }
@ -507,10 +532,6 @@ class VideoData {
} }
onVideoMutation(mutationList?: MutationRecord[], observer?) { onVideoMutation(mutationList?: MutationRecord[], observer?) {
if (this.destroyed) {
return;
}
// verify that mutation didn't remove our class. Some pages like to do that. // verify that mutation didn't remove our class. Some pages like to do that.
let confirmAspectRatioRestore = false; let confirmAspectRatioRestore = false;

View File

@ -495,14 +495,8 @@ class Resizer {
try { try {
const translate = this.computeOffsets(stretchFactors, options?.ar); const translate = this.computeOffsets(stretchFactors, options?.ar);
this.applyCss(stretchFactors, translate); this.applyCss(stretchFactors, translate);
this.eventBus.send('broadcast-scaling-params', {
effectiveZoom: {x: stretchFactors.xFactor, y: stretchFactors.yFactor},
lastAr: this.lastAr,
stretch: this.stretcher.stretch
});
} catch (e) { } catch (e) {
this.logger.warn('applyScaling', 'error while applying CSS:', e); this.logger.warn('setAr', 'error while applying CSS:', e);
// don't apply CSS if there's an error // don't apply CSS if there's an error
} }
} }