Move settings to a different folder, iframes default to parent page settings

This commit is contained in:
Tamius Han 2025-07-15 19:42:35 +02:00
parent f88f703e84
commit 75670ef3f9
5 changed files with 137 additions and 23 deletions

View File

@ -308,6 +308,9 @@ export interface SiteSettingsInterface {
enableKeyboard: ExtensionEnvironmentSettingsInterface;
enableUI: ExtensionEnvironmentSettingsInterface; // Lies! enableUI doesn't use 'theater' property (but uses the other two)
applyToEmbeddedContent?: boolean; // presumed to be 'true' if not defined
autocreated?: boolean;
type?: 'official' | 'community' | 'user-defined' | 'testing' | 'officially-disabled' | 'unknown' | 'modified';
defaultType: 'official' | 'community' | 'user-defined' | 'testing' | 'officially-disabled' | 'unknown' | 'modified';

View File

@ -8,6 +8,7 @@ import { SiteSettings } from './lib/settings/SiteSettings';
import UI from './lib/uwui/UI';
import { BLANK_LOGGER_CONFIG, LogAggregator } from './lib/logging/LogAggregator';
import { ComponentLogger } from './lib/logging/ComponentLogger';
import { getIframeParentHost, setupHostnameReporting } from './util/getHost';
export default class UWContent {
pageInfo: PageInfo;
@ -19,6 +20,7 @@ export default class UWContent {
logger: ComponentLogger;
eventBus: EventBus;
isIframe: boolean = false;
parentHostname: string;
globalUi: any;
@ -28,7 +30,8 @@ export default class UWContent {
}
constructor(){
this.isIframe = window.self !== window.top
setupHostnameReporting();
this.isIframe = window.self !== window.top;
}
reloadSettings() {
@ -41,6 +44,11 @@ export default class UWContent {
}
async init(){
if (this.isIframe) {
this.parentHostname = await getIframeParentHost();
console.warn('[uw-content] got iframe parent:', this.parentHostname);
}
try {
if (Debug.debug) {
console.log("[uw::main] loading configuration ...");
@ -57,6 +65,7 @@ export default class UWContent {
console.error("logger init failed!", e)
}
// init() is re-run any time settings change
if (this.comms) {
this.comms.destroy();
@ -70,7 +79,7 @@ export default class UWContent {
logAggregator: this.logAggregator
});
await this.settings.init();
this.siteSettings = this.settings.getSiteSettings();
this.siteSettings = this.settings.getSiteSettings({site: window.location.hostname, isIframe: this.isIframe, parentHostname: this.parentHostname});
}
this.eventBus = new EventBus();

View File

@ -1,14 +1,14 @@
import Debug from '../conf/Debug';
import ExtensionConf from '../conf/ExtensionConf';
import ObjectCopy from './ObjectCopy';
import StretchType from '../../common/enums/StretchType.enum';
import ExtensionConfPatch from '../conf/ExtConfPatches';
import SettingsInterface from '../../common/interfaces/SettingsInterface';
import AspectRatioType from '../../common/enums/AspectRatioType.enum';
import { SiteSettings } from './settings/SiteSettings';
import { SettingsSnapshotManager } from './settings/SettingsSnapshotManager';
import { ComponentLogger } from './logging/ComponentLogger';
import { LogAggregator } from './logging/LogAggregator';
import Debug from '../../conf/Debug';
import ExtensionConf from '../../conf/ExtensionConf';
import ObjectCopy from '../ObjectCopy';
import StretchType from '../../../common/enums/StretchType.enum';
import ExtensionConfPatch from '../../conf/ExtConfPatches';
import SettingsInterface from '../../../common/interfaces/SettingsInterface';
import AspectRatioType from '../../../common/enums/AspectRatioType.enum';
import { GetSiteSettingsOptions, SiteSettings } from './SiteSettings';
import { SettingsSnapshotManager } from './SettingsSnapshotManager';
import { ComponentLogger } from '../logging/ComponentLogger';
import { LogAggregator } from '../logging/LogAggregator';
if(process.env.CHANNEL !== 'stable'){
console.info("Loading Settings");
@ -25,6 +25,7 @@ interface SetSettingsOptions {
forcePreserveVersion?: boolean,
}
const SETTINGS_LOGGER_STYLES = {
log: 'color: #81d288',
}
@ -413,8 +414,8 @@ class Settings {
}
}
getSiteSettings(site: string = window.location.hostname): SiteSettings {
return new SiteSettings(this, site);
getSiteSettings(options: GetSiteSettingsOptions = {site: window.location.hostname}): SiteSettings {
return new SiteSettings(this, options);
}
listenOnChange(fn: () => void): void {

View File

@ -6,6 +6,13 @@ import Settings from './Settings';
import StretchType from '../../../common/enums/StretchType.enum';
import VideoAlignmentType from '../../../common/enums/VideoAlignmentType.enum';
export interface GetSiteSettingsOptions {
site: string,
isIframe?: boolean,
parentHostname?: string,
}
/**
* Contains settings that are currently in effect for a given site. If a certain option
* doesn't have a value — or if it has 'default' option, SiteSettings.data will contain
@ -22,6 +29,7 @@ export class SiteSettings {
public get site() {
return this._site;
}
private options: GetSiteSettingsOptions;
raw: SiteSettingsInterface; // actual settings
data: SiteSettingsInterface; // effective settings
@ -33,10 +41,12 @@ export class SiteSettings {
storageChangeSubscriptions: {[x: string]: ((newSiteConf, changes, area) => void)[]} = {};
//#region lifecycle
constructor(settings: Settings, site: string) {
constructor(settings: Settings, options: GetSiteSettingsOptions) {
this.options = options;
this.site = options.site;
this.settings = settings;
this.raw = settings.active.sites[site];
this.site = site;
this.raw = settings.active.sites[this.site];
this.defaultSettings = settings.active.sites['@global'];
this.compileSettingsObject();
@ -56,19 +66,53 @@ export class SiteSettings {
/**
* Tries to match websites, even if we're on a different subdomain.
*
* Priority chain:
*
* START HERE
* |
* [ exact hostname match ]
* | |
* no yes > return settings for hostname
* V
* | matches hostname on |
* | different subdomain? |
* | |
* no yes > return settings for matching subdomain
* V
* [ are we inside of an iframe? ]
* | |
* no yes
* V V
* return default | exact parent |
* settings | hostname match? |
* A | |
* | no yes > [ applyToEmbeddedContent set? ]
* | V | |
* | | parent matches hostname | no yes
* | | on different subdomain? | V V
* | | | use default use parent settings
* +< no yes
* | |
* +< no [ applyToEmbeddedContent set? ]
* |
* yes
* V
* use settings for matching subdomain of parent
*
* @returns
*/
private getSettingsForSite() {
if (!this.site) {
private getSettingsForSite(options: GetSiteSettingsOptions) {
if (!options.site) {
return {
siteSettings: this.settings.active.sites['@global'],
usesSettingsFor: '@global'
};
}
if (this.settings.active.sites[this.site]) {
if (this.settings.active.sites[options.site]) {
return {
siteSettings: this.settings.active.sites[this.site],
siteSettings: this.settings.active.sites[options.site],
usesSettingsFor: undefined
};
}
@ -97,6 +141,14 @@ export class SiteSettings {
}
}
// If we're inside of an iframe, let's see whether we can use parent settings
if (options.isIframe) {
const potentialSettings = this.getSettingsForSite({site: options.parentHostname});
if (potentialSettings.siteSettings.applyToEmbeddedContent !== false) {
return potentialSettings;
}
}
return {
siteSettings: this.settings.active.sites['@global'],
usesSettingsFor: '@global'
@ -108,7 +160,7 @@ export class SiteSettings {
* Alan pls ensure default settings object follows the correct structure
*/
private compileSettingsObject() {
const {siteSettings, usesSettingsFor} = this.getSettingsForSite();
const {siteSettings, usesSettingsFor} = this.getSettingsForSite(this.options);
this.data = _cp(siteSettings);
this.usesSettingsFor = usesSettingsFor;

49
src/ext/util/getHost.ts Normal file
View File

@ -0,0 +1,49 @@
/**
* Reqzests iframe parent hostname
* @returns
*/
export async function getIframeParentHost(): Promise<string> {
return new Promise<any>((resolve) => {
let resolved = false;
let resendInterval;
function handleMessage(event) {
if (event.data.action === 'uw-parent-hostname') {
resolved = true;
clearInterval(resendInterval);
window.removeEventListener('message', handleMessage);
resolve(event.data.hostname);
}
}
window.addEventListener('message', handleMessage);
resendInterval = setInterval(
() => {
if (!resolved) {
window.parent.postMessage(
{ action: 'uw-get-parent-hostname' },
'*'
);
}
},
500
);
});
}
function handleMessage(event) {
if (event.data.action === 'uw-get-parent-hostname') {
event.source.postMessage(
{action: 'uw-parent-hostname', hostname: window.location.hostname},
'*' as any
)
}
}
export async function setupHostnameReporting() {
window.removeEventListener('message', handleMessage); // setupHostnameReporting may run more than once
window.addEventListener('message', handleMessage);
}