Compare commits

...

3 Commits

20 changed files with 452 additions and 871 deletions

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{
"name": "ultrawidify",
"version": "6.3.995",
"version": "6.3.996",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "ultrawidify",
"version": "6.3.995",
"version": "6.3.996",
"dependencies": {
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@mdi/font": "^7.4.47",

View File

@ -1,6 +1,6 @@
{
"name": "ultrawidify",
"version": "6.3.995",
"version": "6.3.996",
"description": "Aspect ratio fixer for youtube and other sites, with automatic aspect ratio detection. Supports ultrawide and other ratios.",
"author": "Tamius Han <tamius.han@gmail.com>",
"scripts": {

View File

@ -1,4 +1,5 @@
enum AspectRatioType {
Default = -3, // inherit from global settings
Cycle = -2,
Initial = -1, // page default
Reset = 0, // reset to initial

View File

@ -1,7 +1,8 @@
enum EmbeddedContentSettingsOverridePolicy {
Always = 2,
UseAsDefault = 1,
Never = 0,
Default = 0,
Never = -1,
}
export default EmbeddedContentSettingsOverridePolicy;

View File

@ -1,5 +1,5 @@
export enum PlayerDetectionMode {
Auto = 0,
AncestorIndex = 1,
querySelectors = 2,
QuerySelectors = 2,
};

View File

@ -1,3 +1,4 @@
import { SiteSupportLevel } from './../enums/SiteSupportLevel.enum';
import { Action } from '../../../node_modules/vuex/types/index'
import { AardPollingOptions } from '../../ext/lib/aard/enums/aard-polling-options.enum'
import { AardSubtitleCropMode } from '../../ext/lib/aard/enums/aard-subtitle-crop-mode.enum'
@ -9,6 +10,7 @@ import ExtensionMode from '../enums/ExtensionMode.enum'
import { SiteSupportLevel } from '../enums/SiteSupportLevel.enum'
import StretchType from '../enums/StretchType.enum'
import VideoAlignmentType from '../enums/VideoAlignmentType.enum'
import { PlayerDetectionMode } from '../enums/PlayerDetectionMode.enum';
export enum ExtensionEnvironment {
Normal = ExtensionMode.All,
@ -443,8 +445,8 @@ export interface SiteSettingsInterface {
enableKeyboard: ExtensionMode;
enableUI: ExtensionMode;
applyToEmbeddedContent: EmbeddedContentSettingsOverridePolicy; // presumed to be 'Always' if not defined
overrideWhenEmbedded?: boolean;
applyToEmbeddedContent: EmbeddedContentSettingsOverridePolicy; // presumed to be 'Use as default' if not defined
overrideWhenEmbedded?: EmbeddedContentSettingsOverridePolicy;
autocreated?: boolean;
@ -484,11 +486,10 @@ export interface PlayerAutoConfigInterface {
}
export interface SiteDOMSettingsInterface {
type: 'official' | 'community' | 'user-defined' | 'modified' | undefined;
type: SiteSupportLevel; // 'official' | 'community' | 'user-defined' | 'modified' | undefined;
elements?: {
player?: SiteDOMElementSettingsInterface,
video?: SiteDOMElementSettingsInterface,
other?: { [x: number]: SiteDOMElementSettingsInterface }
player?: PlayerDOMSettingsInterface,
video?: PlayerDOMSettingsInterface,
};
customCss?: string;
periodicallyRefreshPlayerElement?: boolean;
@ -499,12 +500,19 @@ export interface SiteDOMSettingsInterface {
anchorElement?: HTMLElement;
}
export interface PlayerDOMSettingsInterface {
playerDetectionMode: PlayerDetectionMode,
allowAutoFallback: boolean,
ancestorIndex?: number,
querySelectors?: string,
customCSS?: string,
}
export interface SiteDOMElementSettingsInterface {
manual?: boolean;
querySelectors?: string;
index?: number; // previously: useRelativeAncestor + videoAncestor
mode?: 'index' | 'qs';
nodeCss?: {[x: string]: string};
}
export default SettingsInterface;

View File

@ -1,597 +0,0 @@
<template>
<div>
<!-- Enable extension -->
<pre>{{simpleExtensionSettings}}</pre>
<div class="field">
<div class="label">
Enable <span class="color-emphasis">extension</span>
<span class="sub-label"><br/>under the following conditions:</span>
</div>
<pre>{{simpleExtensionSettings}}</pre>
<div class="select">
<select
:value="simpleExtensionSettings.enable"
@click="setExtensionMode('enable', $event)"
>
<template v-if="isDefaultConfiguration">
<option :value="ExtensionMode.Disabled">
Disabled by default
</option>
</template>
<template v-else>
<option :value="ExtensionMode.Default">
Use default ({{simpleDefaultSettings.enableAard}})
</option>
<option :value="ExtensionMode.Disabled">
Never
</option>
</template>
<option :value="ExtensionMode.FullScreen">
Fullscreen only
</option>
<option :value="ExtensionMode.Theater">
Fullscreen and theater mode
</option>
<option :value="ExtensionMode.All">
Always
</option>
</select>
</div>
</div>
<!-- The rest of the menu is disabled when extension is disabled -->
<div :class="{disabled: simpleEffectiveSettings.enable === 'disabled' && !isDefaultConfiguration}">
<!-- Enable AARD -->
<div class="field">
<div class="label">
Enable <span class="color-emphasis">automatic aspect ratio detection</span>
<span class="sub-label"><br/>under the following conditions:</span>
</div>
<div class="select">
<select
:value="simpleExtensionSettings.enableAard"
@click="setExtensionMode('enableAard', $event)"
>
<template v-if="isDefaultConfiguration">
<option :value="ExtensionMode.Disabled">
Disabled by default
</option>
</template>
<template v-else>
<option :value="ExtensionMode.Default">
Use default ({{simpleDefaultSettings.enableAard}})
</option>
<option :value="ExtensionMode.Disabled">
Never
</option>
</template>
<option :value="ExtensionMode.FullScreen">
Fullscreen only
</option>
<option :value="ExtensionMode.Theater">
Fullscreen and theater mode
</option>
<option :value="ExtensionMode.All">
Always
</option>
</select>
</div>
</div>
<!-- Enable keyboard -->
<div class="field">
<div class="label">
Enable <span class="color-emphasis">keyboard shortcuts</span>
<span class="sub-label"><br/>under the following conditions:</span>
</div>
<div class="select">
<select
:value="simpleExtensionSettings.enableKeyboard"
@click="setExtensionMode('enableKeyboard', $event)"
>
<template v-if="isDefaultConfiguration">
<option :value="ExtensionMode.Disabled">
Disabled by default
</option>
</template>
<template v-else>
<option :value="ExtensionMode.Default">
Use default ({{simpleDefaultSettings.enableAard}})
</option>
<option :value="ExtensionMode.Disabled">
Never
</option>
</template>
<option :value="ExtensionMode.FullScreen">
Fullscreen only
</option>
<option :value="ExtensionMode.Theater">
Fullscreen and theater mode
</option>
<option :value="ExtensionMode.All">
Always
</option>
</select>
</div>
</div>
<!-- Enable UI -->
<div class="field">
<div class="label">
Enable <span class="color-emphasis">in-player UI</span>
<span class="sub-label"><br/>under the following conditions:</span>
</div>
<div class="select">
<select
:value="simpleExtensionSettings.enableUI"
@click="setExtensionMode('enableUI', $event)"
>
<template v-if="isDefaultConfiguration">
<option :value="ExtensionMode.Disabled">
Disabled by default
</option>
</template>
<template v-else>
<option :value="ExtensionMode.Default">
Use default ({{simpleDefaultSettings.enableAard}})
</option>
<option :value="ExtensionMode.Disabled">
Never
</option>
</template>
<option :value="ExtensionMode.FullScreen">
Fullscreen only
</option>
<option :value="ExtensionMode.Theater">
Fullscreen and theater mode
</option>
<option :value="ExtensionMode.All">
Always
</option>
</select>
</div>
</div>
<div class="field">
<div class="label">
Use these settings for <span class="color-emphasis">embedded content</span>?
<!-- <span class="sub-label"><br/>under the following conditions:</span> -->
</div>
<div class="select">
<select
:value="siteDefaultForEmbedded"
@click="setSiteOption('applyToEmbeddedContent', $event)"
>
<option :value="EmbeddedContentSettingsOverridePolicy.Always">
Always(-ish)
</option>
<option :value="EmbeddedContentSettingsOverridePolicy.UseAsDefault">
Use as default
</option>
<option :value="EmbeddedContentSettingsOverridePolicy.Never">
Never
</option>
</select>
</div>
</div>
<div class="field">
<div class="label">
Force these settings <span class="color-emphasis">when embedded</span>?
<!-- <span class="sub-label"><br/>under the following conditions:</span> -->
</div>
<div class="select">
<select
:value="siteDefaultOverrideEmbedded"
@click="setSiteOption('overrideWhenEmbedded', $event)"
>
<option :value="true">
Yes
</option>
<option :value="false">
No
</option>
</select>
</div>
</div>
<!-- Default crop -->
<div class="field">
<div class="label">Default crop:</div>
<div class="select">
<select
:value="siteDefaultCrop"
@change="setOption('defaults.crop', $event)"
>
<option
v-if="!isDefaultConfiguration"
:value="JSON.stringify({useDefault: true})"
>
Use default ({{getCommandValue(settings?.active.commands.crop, siteSettings.data.defaults.crop)}})
</option>
<option
v-for="(command, index) of settings?.active.commands.crop"
:key="index"
:value="JSON.stringify(command.arguments)"
>
{{command.label}}
</option>
</select>
</div>
</div>
<div class="hint">This is how extension will crop video if/when autodetection is disabled. Pick 'Reset' option to keep aspect ratio as-is by default.</div>
<!-- Default stretch -->
<div class="field">
<div class="label">Default stretch:</div>
<div class="select">
<select
v-model="siteDefaultStretch"
@change="setOption('defaults.stretch', $event)"
>
<option
v-if="!isDefaultConfiguration"
:value="JSON.stringify({useDefault: true})"
>
Use default ({{getCommandValue(settings?.active.commands.stretch, siteSettings.data.defaults.stretch)}})
</option>
<option
v-for="(command, index) of settings?.active.commands.stretch"
:key="index"
:value="JSON.stringify(command.arguments)"
>
{{command.label}}
</option>
</select>
</div>
</div>
<!-- Default alignment -->
<div class="field">
<div class="label">Default alignment:</div>
<div class="select">
<select
v-model="siteDefaultAlignment"
@change="setOption('defaults.alignment', $event)"
>
<option
v-if="!isDefaultConfiguration"
:value="JSON.stringify({useDefault: true})"
>
Use default ({{getAlignmentLabel(siteSettings.data.defaults.alignment)}})
</option>
<option
v-for="(command, index) of alignmentOptions"
:key="index"
:value="JSON.stringify(command.arguments)"
>
{{command.label}}
</option>
</select>
</div>
</div>
<!-- Crop, et. al. Persistence -->
<div class="field">
<div class="label">Persist crop, stretch, and alignment between videos</div>
<div class="select">
<select
v-model="siteDefaultCropPersistence"
@click="setOption('persistCSA', $event)"
>
<option
v-if="!isDefaultConfiguration"
:value="CropModePersistence.Default"
>
Use default ({{defaultPersistenceLabel}})
</option>
<option :value="CropModePersistence.Disabled">Disabled</option>
<option :value="CropModePersistence.UntilPageReload">Until page reload</option>
<option :value="CropModePersistence.CurrentSession">Current session</option>
<option :value="CropModePersistence.Forever">Always persist</option>
</select>
</div>
</div>
</div>
</div>
</template>
<script>
import ExtensionMode from '@src/common/enums/ExtensionMode.enum';
import VideoAlignmentType from '@src/common/enums/VideoAlignmentType.enum';
import CropModePersistence from '@src/common/enums/CropModePersistence.enum';
import EmbeddedContentSettingsOverridePolicy from '@src/common/enums/EmbeddedContentSettingsOverridePolicy.enum';
export default {
data() {
return {
CropModePersistence: CropModePersistence,
ExtensionMode,
EmbeddedContentSettingsOverridePolicy,
alignmentOptions: [
{label: 'Top left', arguments: {x: VideoAlignmentType.Left, y: VideoAlignmentType.Top}},
{label: 'Top center', arguments: {x: VideoAlignmentType.Center, y: VideoAlignmentType.Top}},
{label: 'Top right', arguments: {x: VideoAlignmentType.Right, y: VideoAlignmentType.Top}},
{label: 'Left', arguments: {x: VideoAlignmentType.Left, y: VideoAlignmentType.Center}},
{label: 'Center', arguments: {x: VideoAlignmentType.Center, y: VideoAlignmentType.Center}},
{label: 'Right', arguments: {x: VideoAlignmentType.Right, y: VideoAlignmentType.Center}},
{label: 'Bottom left', arguments: {x: VideoAlignmentType.Left, y: VideoAlignmentType.Bottom}},
{label: 'Bottom center', arguments: {x: VideoAlignmentType.Center, y: VideoAlignmentType.Bottom}},
{label: 'Bottom right', arguments: {x: VideoAlignmentType.Right, y: VideoAlignmentType.Bottom}}
]
}
},
mixins: [
],
props: [
'settings',
'siteSettings',
'isDefaultConfiguration'
],
components: {
},
computed: {
simpleExtensionSettings() {
return {
enable: this.compileSimpleSettings('enable'),
enableAard: this.compileSimpleSettings('enableAard'),
enableKeyboard: this.compileSimpleSettings('enableKeyboard'),
enableUI: this.compileSimpleSettings('enableUI')
}
},
simpleEffectiveSettings() {
return {
enable: this.compileSimpleSettings('enable', 'site-effective'),
enableAard: this.compileSimpleSettings('enableAard', 'site-effective'),
enableKeyboard: this.compileSimpleSettings('enableKeyboard', 'site-effective'),
enableUI: this.compileSimpleSettings('enableUI', 'site-effective')
}
},
simpleDefaultSettings() {
return {
enable: this.getDefaultOptionLabel('enable'),
enableAard: this.getDefaultOptionLabel('enableAard'),
enableKeyboard: this.getDefaultOptionLabel('enableKeyboard'),
enableUI: this.getDefaultOptionLabel('enableUI')
};
},
siteDefaultForEmbedded() {
return this.siteSettings.raw?.applyToEmbeddedContent;
},
siteDefaultOverrideEmbedded() {
return this.siteSettings.raw?.overrideWhenEmbedded ?? false;
},
siteDefaultCrop() {
return this.siteSettings.raw?.defaults?.crop ? JSON.stringify(this.siteSettings.raw?.defaults?.crop) : JSON.stringify({useDefault: true});
},
siteDefaultStretch() {
return this.siteSettings.raw?.defaults?.stretch ? JSON.stringify(this.siteSettings.raw?.defaults?.stretch) : JSON.stringify({useDefault: true});
},
siteDefaultAlignment() {
return this.siteSettings.raw?.defaults?.alignment ? JSON.stringify(this.siteSettings.raw?.defaults?.alignment) : JSON.stringify({useDefault: true});
},
siteDefaultCropPersistence() {
return this.siteSettings.raw?.persistCSA ?? undefined;
},
defaultPersistenceLabel() {
switch (this.siteSettings.defaultSettings.persistCSA) {
case CropModePersistence.CurrentSession:
return 'current session';
case CropModePersistence.Disabled:
return 'disabled';
case CropModePersistence.UntilPageReload:
return 'until page reload';
case CropModePersistence.Forever:
return 'Always persist';
}
return '??';
}
},
mounted() {
this.forceRefreshPage();
},
methods: {
/**
* Compiles our extension settings into more user-friendly options
*/
compileSimpleSettings(component, getFor = 'site') {
let settingsData;
switch (getFor) {
case 'site':
settingsData = this.siteSettings?.raw;
break;
case 'site-effective':
settingsData = this.siteSettings?.data;
break;
case 'default':
settingsData = this.settings.active.sites['@global'];
break;
}
return settingsData[component];
},
getDefaultOptionLabel(component) {
const componentValue = this.compileSimpleSettings(component, 'default');
if (component === 'enableUI') {
switch (componentValue) {
case 'fs':
return 'fullscreen only';
case 'enabled':
case 'theater':
return 'where possible';
case 'disabled':
return 'disabled';
}
}
switch (componentValue) {
case 'fs':
return 'Fullscreen only';
case 'theater':
return 'theater & FS';
case 'enabled':
return 'always';
case 'disabled':
return 'disabled';
case 'default':
return 'complex'
}
},
getCommandValue(availableCommands, command) {
for (const cmd of availableCommands) {
if (JSON.stringify(cmd.arguments) === JSON.stringify(command)) {
return cmd.label;
}
}
return 'Unknown command';
},
getAlignmentLabel(alignment) {
// in case default settings don't have this set
if (!alignment) {
return 'Center'
}
let x, y;
if (alignment.x === VideoAlignmentType.Center) {
x = 'center';
} else if (alignment.x === VideoAlignmentType.Left) {
x = 'left';
} else if (alignment.x === VideoAlignmentType.Right) {
x = 'right';
} else {
x = '??'
}
if (alignment.y === VideoAlignmentType.Center) {
y = 'center';
} else if (alignment.y === VideoAlignmentType.Bottom) {
y = 'bottom';
} else if (alignment.y === VideoAlignmentType.Top) {
y = 'top';
} else {
y = '???'
};
if (x === y) {
return x;
}
return `${y} ${x}`;
},
getOption(option) {
},
async setOption(option, $event) {
const value = $event.target.value;
let commandArguments;
// if argument is json, parse json. Otherwise, pass the value as-is
try {
commandArguments = value !== undefined ? JSON.parse(value) : undefined;
} catch(e) {
commandArguments = value;
}
if (commandArguments.useDefault) {
commandArguments = undefined;
}
await this.siteSettings.set(option, commandArguments, {reload: false});
// we also need to force re-compute all watchers, otherwise UI will lag behind
// actual state of settings until reload
this.forceRefreshPage();
},
forceRefreshPage() {
this._computedWatchers?.simpleExtensionSettings?.run();
this._computedWatchers?.simpleDefaultSettings?.run();
this._computedWatchers?.siteDefaultCrop?.run();
this._computedWatchers?.siteDefaultStretch?.run();
this._computedWatchers?.siteDefaultAlignment?.run();
this._computedWatchers?.siteDefaultCropPersistence?.run();
this._computedWatchers?.defaultPersistenceLabel?.run();
this.$nextTick( () => this.$forceUpdate());
},
setSiteOption(optionPath, event) {
const value = event.target.value;
this.siteSettings.set(optionPath, value);
},
setExtensionMode(component, event) {
const option = event.target.value;
if (option === 'complex') {
return;
}
if (component === 'enable' && !this.isDefaultConfiguration) {
this.setExtensionMode('enableAard', event);
this.setExtensionMode('enableKeyboard', event);
// in enableUI, 'enabled' is unused and 'theater' uses its place
if (option === 'enabled') {
this.setExtensionMode('enableUI', {target: {value: 'theater'}});
} else {
this.setExtensionMode('enableUI', event);
}
}
if (option === 'default') {
return this.siteSettings.set(component, {
normal: ExtensionMode.Default,
theater: ExtensionMode.Default,
fullscreen: ExtensionMode.Default
});
}
if (option === 'disabled') {
return this.siteSettings.set(component, {
normal: ExtensionMode.Disabled,
theater: ExtensionMode.Disabled,
fullscreen: ExtensionMode.Disabled
});
}
if (option === 'enabled') {
return this.siteSettings.set(component, {
normal: ExtensionMode.Enabled,
theater: ExtensionMode.Enabled,
fullscreen: ExtensionMode.Enabled
});
}
if (option === 'theater') {
return this.siteSettings.set(component, {
normal: ExtensionMode.Disabled,
theater: ExtensionMode.Enabled,
fullscreen: ExtensionMode.Enabled
});
}
if (option === 'fs') {
return this.siteSettings.set(component, {
normal: ExtensionMode.Disabled,
theater: ExtensionMode.Disabled,
fullscreen: ExtensionMode.Enabled
});
}
}
}
}
</script>
<style lang="scss" src="../../../../res/css/flex.scss" scoped></style>
<style lang="scss" src="@csui/src/res-common/panels.scss" scoped></style>
<style lang="scss" src="@csui/src/res-common/common.scss" scoped></style>
<style scoped>
.button-hover:hover {
color: #fa6;
}
</style>

View File

@ -12,6 +12,7 @@ import { update } from 'lodash';
import EmbeddedContentSettingsOverridePolicy from '../../common/enums/EmbeddedContentSettingsOverridePolicy.enum';
import LegacyExtensionMode from '../../common/enums/LegacyExtensionMode.enum';
import ExtensionMode from '../../common/enums/ExtensionMode.enum';
import { PlayerDetectionMode } from '../../common/enums/PlayerDetectionMode.enum';
const ExtensionConfPatch = Object.freeze([
@ -248,7 +249,7 @@ const ExtensionConfPatch = Object.freeze([
// applyToEmbeddedContent is now an enum, and also no longer optional
for (const site in userOptions.sites) {
if (userOptions.sites[site].applyToEmbeddedContent === undefined) {
userOptions.sites[site].applyToEmbeddedContent = EmbeddedContentSettingsOverridePolicy.Always;
userOptions.sites[site].applyToEmbeddedContent = EmbeddedContentSettingsOverridePolicy.UseAsDefault;
} else {
userOptions.sites[site].applyToEmbeddedContent = userOptions.sites[site].applyToEmbeddedContent ? EmbeddedContentSettingsOverridePolicy.Always : EmbeddedContentSettingsOverridePolicy.Never;
}
@ -316,6 +317,53 @@ const ExtensionConfPatch = Object.freeze([
userOptions.ui = defaultOptions.ui
};
}
}, {
forVersion: '6.3.996',
updateFn: (userOptions: SettingsInterface, defaultOptions: SettingsInterface, logger?) => {
for (const site in userOptions.sites) {
for (const domConf in userOptions.sites.DOMConfig) {
const oldConf = userOptions.sites[site].DOMConfig[domConf] as any;
const newConf: any = {
type: oldConf.type ?? userOptions.sites[site].type,
elements: {}
};
if (oldConf.elements.player) {
newConf.elements['player'] = {
playerDetectionMode: oldConf?.elements?.player?.manual ? (
oldConf?.elements?.player?.querySelectors.trim() ? PlayerDetectionMode.QuerySelectors : PlayerDetectionMode.AncestorIndex
) : PlayerDetectionMode.Auto,
allowAutoFallback: true,
ancestorIndex: oldConf?.elements?.player?.parentIndex,
querySelectors: oldConf?.elements?.player?.querySelectors,
customCSS: oldConf?.elements?.player?.customCss,
}
} else {
newConf.elements['player'] = {
playerDetectionMode: PlayerDetectionMode.Auto,
allowAutoFallback: true,
}
}
if (oldConf.elements.video) {
newConf.elements['video'] = {
type: oldConf.type ?? userOptions.sites[site].type,
elements: {
video: {
playerDetectionMode: oldConf?.elements?.video?.manual ? PlayerDetectionMode.QuerySelectors : PlayerDetectionMode.Auto,
allowAutoFallback: true,
querySelectors: oldConf?.elements?.video?.querySelectors,
customCSS: oldConf?.elements?.video?.customCss,
}
}
}
}
userOptions.sites[site].DOMConfig[domConf] = newConf;
}
}
}
}
]);

View File

@ -13,6 +13,7 @@ import EmbeddedContentSettingsOverridePolicy from '../../common/enums/EmbeddedCo
import { AardPollingOptions } from '../lib/aard/enums/aard-polling-options.enum';
import { AardSubtitleCropMode } from '../lib/aard/enums/aard-subtitle-crop-mode.enum';
import { SiteSupportLevel } from '../../common/enums/SiteSupportLevel.enum';
import { PlayerDetectionMode } from '../../common/enums/PlayerDetectionMode.enum';
if(Debug.debug)
console.log("Loading: ExtensionConf.js");
@ -803,11 +804,15 @@ const ExtensionConf: SettingsInterface = {
// #g — only available in @global
// #s — only available for specific site
enable: ExtensionMode.Disabled,
enableAard: ExtensionMode.Disabled,
enableKeyboard: ExtensionMode.Disabled,
enableAard: ExtensionMode.Theater,
enableKeyboard: ExtensionMode.All,
enableUI: ExtensionMode.FullScreen,
applyToEmbeddedContent: EmbeddedContentSettingsOverridePolicy.Always,
applyToEmbeddedContent: EmbeddedContentSettingsOverridePolicy.UseAsDefault,
overrideWhenEmbedded: EmbeddedContentSettingsOverridePolicy.Never, // Usually, less-than-legitimate websites embed content from different domains.
// Setting this to 'always' would ensure embedded content always uses extension's
// default settings. It is presumed most people are too dumb to visit "for embedded sizes"
// part of the popup, and those who aren't will prolly find that annoying.
defaultType: SiteSupportLevel.Unknown,
persistCSA: CropModePersistence.Disabled,
@ -816,33 +821,73 @@ const ExtensionConf: SettingsInterface = {
crop: {type: AspectRatioType.Automatic},
stretch: {type: StretchType.NoStretch},
alignment: {x: VideoAlignmentType.Center, y: VideoAlignmentType.Center},
},
activeDOMConfig: 'blank',
DOMConfig: {
'blank': {
type: SiteSupportLevel.Unknown,
elements: {
player: {
playerDetectionMode: PlayerDetectionMode.Auto,
allowAutoFallback: true,
// ancestorIndex: 1, // we leave those on undefined,
// querySelectors: '',
// customCSS: ''
}
}
}
}
},
"@empty": { // placeholder settings object with fallbacks to @global
"@empty": {
defaultType: SiteSupportLevel.Unknown,
enable: ExtensionMode.Default,
enableAard: ExtensionMode.Default,
enableKeyboard: ExtensionMode.Default,
enableUI: ExtensionMode.Default,
applyToEmbeddedContent: EmbeddedContentSettingsOverridePolicy.Default,
overrideWhenEmbedded: EmbeddedContentSettingsOverridePolicy.Default,
applyToEmbeddedContent: EmbeddedContentSettingsOverridePolicy.Always,
type: SiteSupportLevel.UserDefined,
defaultType: SiteSupportLevel.UserDefined,
persistCSA: CropModePersistence.Default,
defaults: {
crop: null,
crop: {type: AspectRatioType.Default},
stretch: {type: StretchType.Default},
alignment: {x: VideoAlignmentType.Default, y: VideoAlignmentType.Default},
alignment: {x: VideoAlignmentType.Default, y: VideoAlignmentType.Default}
},
persistCSA: CropModePersistence.Default,
activeDOMConfig: 'empty',
DOMConfig: {
'empty': {
type: SiteSupportLevel.UserDefined,
elements: {
player: {
playerDetectionMode: PlayerDetectionMode.Auto,
allowAutoFallback: true,
// ancestorIndex: 1,
// querySelectors: '',
// customCSS: ''
},
video: {
playerDetectionMode: PlayerDetectionMode.Auto,
allowAutoFallback: true,
// ancestorIndex: 1,
// querySelectors: '',
// customCSS: ''
}
},
"www.youtube.com" : {
}
}
},
"www.youtube.com": {
enable: ExtensionMode.All,
enableAard: ExtensionMode.All,
enableKeyboard: ExtensionMode.All,
enableUI: ExtensionMode.All,
enableUI: ExtensionMode.Default,
applyToEmbeddedContent: EmbeddedContentSettingsOverridePolicy.Always,
overrideWhenEmbedded: true,
applyToEmbeddedContent: EmbeddedContentSettingsOverridePolicy.UseAsDefault,
overrideWhenEmbedded: EmbeddedContentSettingsOverridePolicy.Always,
override: false, // ignore value localStorage in favour of this
type: SiteSupportLevel.OfficialSupport, // is officially supported? (Alternatives are 'community' and 'user-defined')
defaultType: SiteSupportLevel.OfficialSupport, // if user mucks around with settings, type changes to 'user-defined'.
@ -854,7 +899,8 @@ const ExtensionConf: SettingsInterface = {
type: SiteSupportLevel.OfficialSupport,
elements: {
player: {
manual: true,
playerDetectionMode: PlayerDetectionMode.QuerySelectors,
allowAutoFallback: true,
querySelectors: "#movie_player, #player, #c4-player",
}
}
@ -867,8 +913,8 @@ const ExtensionConf: SettingsInterface = {
enableKeyboard: ExtensionMode.All,
enableUI: ExtensionMode.FullScreen,
applyToEmbeddedContent: EmbeddedContentSettingsOverridePolicy.Always,
overrideWhenEmbedded: true,
applyToEmbeddedContent: EmbeddedContentSettingsOverridePolicy.UseAsDefault,
overrideWhenEmbedded: EmbeddedContentSettingsOverridePolicy.Always,
override: false, // ignore value localStorage in favour of this
type: SiteSupportLevel.OfficialSupport, // is officially supported? (Alternatives are 'community' and 'user-defined')
@ -881,7 +927,8 @@ const ExtensionConf: SettingsInterface = {
type: SiteSupportLevel.OfficialSupport,
elements: {
player: {
manual: true,
playerDetectionMode: PlayerDetectionMode.QuerySelectors,
allowAutoFallback: true,
querySelectors: "#movie_player, #player, #c4-player",
}
}
@ -893,10 +940,25 @@ const ExtensionConf: SettingsInterface = {
enableAard: ExtensionMode.Disabled,
enableKeyboard: ExtensionMode.All,
enableUI: ExtensionMode.All,
applyToEmbeddedContent: EmbeddedContentSettingsOverridePolicy.Always,
applyToEmbeddedContent: EmbeddedContentSettingsOverridePolicy.UseAsDefault,
override: false,
type: SiteSupportLevel.CommunitySupport,
defaultType: SiteSupportLevel.CommunitySupport,
DOMConfig: {
'community': {
type: SiteSupportLevel.CommunitySupport,
elements: {
player: {
playerDetectionMode: PlayerDetectionMode.Auto,
allowAutoFallback: true,
// ancestorIndex: 1,
// querySelectors: '',
// customCSS: ''
}
}
}
}
},
"www.disneyplus.com" : {
enable: ExtensionMode.Theater,
@ -904,7 +966,7 @@ const ExtensionConf: SettingsInterface = {
enableKeyboard: ExtensionMode.All,
enableUI: ExtensionMode.FullScreen,
applyToEmbeddedContent: EmbeddedContentSettingsOverridePolicy.Always,
applyToEmbeddedContent: EmbeddedContentSettingsOverridePolicy.UseAsDefault,
type: SiteSupportLevel.CommunitySupport,
defaultType: SiteSupportLevel.CommunitySupport,
activeDOMConfig: 'community-mstefan99',
@ -913,11 +975,13 @@ const ExtensionConf: SettingsInterface = {
type: SiteSupportLevel.OfficialSupport,
elements: {
player: {
manual: true,
playerDetectionMode: PlayerDetectionMode.QuerySelectors,
allowAutoFallback: true,
querySelectors: ".btm-media-player",
},
video: {
manual: true,
playerDetectionMode: PlayerDetectionMode.QuerySelectors,
allowAutoFallback: true,
querySelectors: ".btm-media-client-element"
}
},
@ -931,9 +995,23 @@ const ExtensionConf: SettingsInterface = {
enableKeyboard: ExtensionMode.All,
enableUI: ExtensionMode.FullScreen,
applyToEmbeddedContent: EmbeddedContentSettingsOverridePolicy.Always,
applyToEmbeddedContent: EmbeddedContentSettingsOverridePolicy.UseAsDefault,
type: SiteSupportLevel.OfficialSupport,
defaultType: SiteSupportLevel.OfficialSupport,
activeDOMConfig: 'official',
DOMConfig: {
'official': {
type: SiteSupportLevel.OfficialSupport,
elements: {
player: {
playerDetectionMode: PlayerDetectionMode.QuerySelectors,
allowAutoFallback: true,
querySelectors: "#movie_player, #player, #c4-player",
}
}
}
}
},
"old.reddit.com" : {
enable: ExtensionMode.Disabled,
@ -944,19 +1022,6 @@ const ExtensionConf: SettingsInterface = {
applyToEmbeddedContent: EmbeddedContentSettingsOverridePolicy.Never,
type: SiteSupportLevel.OfficialBlacklist,
defaultType: SiteSupportLevel.OfficialBlacklist,
activeDOMConfig: 'official',
DOMConfig: {
'official': {
type: SiteSupportLevel.OfficialSupport,
// customCss: 'video {\n width: 100% !important;\n height: 100% !important;\n}',
elements: {
player: {
manual: false,
querySelectors: '.reddit-video-player-root, .media-preview-content'
}
}
}
},
},
"www.reddit.com" : {
enable: ExtensionMode.Disabled,
@ -967,19 +1032,6 @@ const ExtensionConf: SettingsInterface = {
applyToEmbeddedContent: EmbeddedContentSettingsOverridePolicy.Never,
type: SiteSupportLevel.OfficialBlacklist,
defaultType: SiteSupportLevel.OfficialBlacklist,
activeDOMConfig: 'official',
DOMConfig: {
'official': {
type: SiteSupportLevel.OfficialSupport,
// customCss: 'video {\n width: 100% !important;\n height: 100% !important;\n}',
elements: {
player: {
manual: false,
querySelectors: '.reddit-video-player-root, .media-preview-content'
}
}
}
},
},
"imgur.com": {
enable: ExtensionMode.Disabled,
@ -997,7 +1049,7 @@ const ExtensionConf: SettingsInterface = {
enableKeyboard: ExtensionMode.All,
enableUI: ExtensionMode.FullScreen,
applyToEmbeddedContent: EmbeddedContentSettingsOverridePolicy.Always,
applyToEmbeddedContent: EmbeddedContentSettingsOverridePolicy.UseAsDefault,
type: SiteSupportLevel.CommunitySupport,
defaultType: SiteSupportLevel.CommunitySupport,
activeDOMConfig: 'community',
@ -1006,7 +1058,8 @@ const ExtensionConf: SettingsInterface = {
type: SiteSupportLevel.CommunitySupport,
elements: {
player: {
manual: true,
playerDetectionMode: PlayerDetectionMode.QuerySelectors,
allowAutoFallback: true,
querySelectors: "#jwplayer-container"
}
}
@ -1019,36 +1072,18 @@ const ExtensionConf: SettingsInterface = {
enableKeyboard: ExtensionMode.Theater,
enableUI: ExtensionMode.FullScreen,
applyToEmbeddedContent: EmbeddedContentSettingsOverridePolicy.Always,
applyToEmbeddedContent: EmbeddedContentSettingsOverridePolicy.UseAsDefault,
type: SiteSupportLevel.CommunitySupport,
defaultType: SiteSupportLevel.CommunitySupport,
activeDOMConfig: 'community',
DOMConfig: {
'community': {
type: SiteSupportLevel.CommunitySupport,
// customCss: "body {\n background-color: #000;\n}\n\n.application {\n background-color: #000;\n}"
}
}
},
"metaivi.com": {
enable: ExtensionMode.Theater,
enableAard: ExtensionMode.Theater,
enableKeyboard: ExtensionMode.Theater,
enableUI: ExtensionMode.FullScreen,
applyToEmbeddedContent: EmbeddedContentSettingsOverridePolicy.Always,
applyToEmbeddedContent: EmbeddedContentSettingsOverridePolicy.UseAsDefault,
type: SiteSupportLevel.CommunitySupport,
defaultType: SiteSupportLevel.CommunitySupport,
activeDOMConfig: 'community',
DOMConfig: {
'community': {
type: SiteSupportLevel.CommunitySupport,
elements: {
video: {
nodeCss: {'position': 'absolute !important'}
}
}
}
},
},
"piped.kavin.rocks": {
enable: ExtensionMode.Theater,
@ -1056,16 +1091,9 @@ const ExtensionConf: SettingsInterface = {
enableKeyboard: ExtensionMode.Theater,
enableUI: ExtensionMode.FullScreen,
applyToEmbeddedContent: EmbeddedContentSettingsOverridePolicy.Always,
applyToEmbeddedContent: EmbeddedContentSettingsOverridePolicy.UseAsDefault,
type: SiteSupportLevel.CommunitySupport,
defaultType: SiteSupportLevel.CommunitySupport,
activeDOMConfig: 'community',
DOMConfig: {
'community': {
type: SiteSupportLevel.CommunitySupport,
// customCss: ".shaka-video-container {\n flex-direction: column !important;\n}"
}
}
},
}
}

View File

@ -39,6 +39,7 @@ export class SiteSettings {
temporaryData: SiteSettingsInterface;
sessionData: SiteSettingsInterface;
readonly defaultSettings: SiteSettingsInterface;
readonly blankSettings: SiteSettingsInterface;
storageChangeSubscriptions: {[x: string]: ((newSiteConf, changes, area) => void)[]} = {};
@ -50,6 +51,7 @@ export class SiteSettings {
this.settings = settings;
this.raw = settings.active.sites[this.site];
this.defaultSettings = settings.active.sites['@global'];
this.blankSettings = settings.active.sites['@empty'];
this.compileSettingsObject();
@ -472,7 +474,7 @@ export class SiteSettings {
// If this function is not being called in response to user actin,
// create fake settings object.
if (options.scripted && !this.settings.active.sites[targetSite]) {
this.settings.active.sites[targetSite] = _cp(this.settings.active.sites['@global']);
this.settings.active.sites[targetSite] = _cp(this.blankSettings);
this.settings.active.sites[targetSite].autocreated = true;
this.settings.active.sites[targetSite].type = SiteSupportLevel.Unknown;
} else {

View File

@ -2,7 +2,7 @@
"manifest_version": 3,
"name": "Ultrawidify",
"description": "Removes black bars on ultrawide videos and offers advanced options to fix aspect ratio.",
"version": "6.3.995",
"version": "6.3.996",
"icons": {
"32":"res/icons/uw-32.png",
"64":"res/icons/uw-64.png"

View File

@ -37,7 +37,7 @@
v-for="suboption of tab.children"
:key="suboption.id"
class="suboption"
:class="{'active': suboption.id === selectedTab}"
:class="{'active': suboption.id === selectedTab, 'disabled': suboption.disabled }"
@click="selectTab(suboption.id)"
>
<div class="label">
@ -50,6 +50,9 @@
:size="32"
/>
</div>
<div v-if="suboption.badgeCount" class="badge">
{{suboption.badgeCount >= 10 ? '...' : suboption.badgeCount}}
</div>
</div>
</div>
</div>
@ -111,7 +114,7 @@
</template>
<OtherSiteSettings
v-if="selectedTab === 'extensionSettings'"
v-if="selectedTab === 'website-extension-settings'"
:settings="settings"
:enableSettingsEditor="true"
></OtherSiteSettings>
@ -216,15 +219,15 @@ const AVAILABLE_TABS = {
id: 'site-extension-settings', label: 'Site and Extension options', icon: 'cogs',
children: [
{ id: 'site-extension-settings', label: 'For this site', },
{ id: 'embedded-extension-settings', label: 'For embedded sites' },
{ id: 'embedded-extension-settings', label: 'For embedded sites', disabled: true, badgeCount: 0, },
{ id: 'default-extension-settings', label: 'Default settings' }
]
},
'extension-settings': {
id: 'extensionSettings', label: 'Site and Extension options', icon: 'cogs',
'default-extension-settings': {
id: 'default-extension-settings', label: 'Site and Extension options', icon: 'cogs',
children: [
{ id: 'default-extension-settings', label: 'Default settings' },
{ id: 'website-extension-list', label: 'Website settings', },
{ id: 'website-extension-settings', label: 'Website exceptions', },
]
},
'siteSettings': {id: 'extensionSettings', label: 'Site and Extension options', icon: 'cogs' },
@ -246,7 +249,7 @@ const AVAILABLE_TABS = {
const TAB_LOADOUT = {
'settings': [
'extension-settings',
'default-extension-settings',
'settings.player-element-settings',
'autodetectionSettings',
'ui-settings',
@ -331,7 +334,7 @@ export default defineComponent({
// THINGS WILL NOT WORK IF YOU USE ARROWS
siteSupportLevel() {
return (this.site && this.siteSettings) ? this.siteSettings.data.type || 'no-support' : 'waiting';
}
},
},
created() {
this.generateTabs();
@ -370,6 +373,9 @@ export default defineComponent({
*/
updateSite(newSite: {host: string, hostnames: string[],}) {
this.siteSettings = this.settings.getSiteSettings({site: newSite.host});
this.generateTabs(newSite);
this.$nextTick( () => this.$forceUpdate());
},
/**
@ -378,14 +384,26 @@ export default defineComponent({
getUrl(url) {
return BrowserDetect.getURL(url);
},
generateTabs() {
generateTabs(site = this.site) {
const tabs = [];
for (const tab of TAB_LOADOUT[this.role]) {
if (!AVAILABLE_TABS[tab]) {
console.warn('[uw:SettingsWindowContent] tab', tab, 'is not present in available tabs:', AVAILABLE_TABS, '— tabs for role', this.role, TAB_LOADOUT[this.role]);
continue;
} else {
console.log('pushing tab:', tab, AVAILABLE_TABS[tab])
if (tab === 'site-extension-settings') {
const frames = AVAILABLE_TABS[tab].children?.find(x => x.id === 'embedded-extension-settings');
if (frames) {
let frameCount = site?.hostnames?.length;
if (site?.hostnames?.includes(site.host)) {
frameCount--;
}
frames.badgeCount = frameCount;
frames.disabled = !frameCount;
}
}
tabs.push(AVAILABLE_TABS[tab]);
}
}
@ -451,6 +469,9 @@ export default defineComponent({
@apply !bg-transparent !text-primary-300 bg-gradient-to-r from-transparent to-black hover:!text-primary-200 ;
}
}
&.disabled {
@apply pointer-events-none;
}
}
.main-tab {
@ -471,7 +492,8 @@ export default defineComponent({
.suboption {
@apply
px-6 py-2
text-[1.125rem] text-stone-500 font-mono
uppercase text-stone-400/75 font-mono
relative
hover:bg-stone-800
hover:text-primary-200
hover:border-r-stone-600;
@ -479,6 +501,17 @@ export default defineComponent({
&.active {
@apply !bg-transparent !text-primary-300 bg-gradient-to-r from-transparent to-black hover:!text-primary-200;
}
&.disabled {
@apply pointer-events-none text-stone-600/75;
}
.badge {
@apply absolute right-[0.25rem] bottom-0 w-4 h-4 text-stone-950 bg-primary-300 rounded flex justify-center items-center font-bold text-[0.8rem];
}
&:last-child {
@apply
mb-2;
}
}
}
}

View File

@ -5,7 +5,11 @@
<b class="text-white">Potentially breaking:</b>
<ul>
<li>De-spaghettified the part of the settings that controls whether extension runs on a given site or not.</li>
<li>
De-spaghettified the part of the settings that controls whether extension runs on a given site or not.<br/>
<small>NOTE "Don't fix what ain't broken" only applies when the thing that keeps it working is NOT merely
a few patches of questionably applied silvertape.</small>
</li>
</ul>
<b class="text-white">Autodetection:</b>

View File

@ -9,12 +9,14 @@
</div>
</div>
</div>
<div v-for="host of hosts" :key="host" @click="selectedSite = host" class="flex flex-col container pointer hoverable" style="margin-top: 4px; padding: 0.5rem 1rem;">
<div v-for="host of hosts" :key="host" @click="selectedSite = host" class="flex flex-col">
<template v-if="host !== parentHost">
<SiteListItem
:parentHost="parentHost"
:host="host"
:settings="settings"
></SiteListItem>
</template>
</div>
</template>
<template v-if="selectedSite">

View File

@ -1,31 +1,6 @@
<template>
<div class="flex flex-row gap-8">
<div v-if="!selectedSite || !isCompact">
<div
class="flex flex-col cursor-pointer mt-1 px-4 py-2 bg-black border-1 border-stone-500"
:class="{'opacity-50 hover:opacity-100': selectedSite && selectedSite !== '@global' }"
@click="selectedSite = '@global'"
>
<div class="flex flex-row">
<div class="flex-grow pointer">
<b style="color: #fa6">Default settings</b>
</div>
<div>Edit</div>
</div>
<div class="flex flex-row">
<small>
<span style="text-transform: uppercase; font-size: 0.9rem">
Enable extension: <span style="font-size: 0.9rem;" :style="getSiteEnabledColor('@global', 'enable')">{{ getSiteEnabledModes('@global', 'enable') }}</span>
<span v-if="getSiteEnabledModes('@global', 'enable') === 'disabled'" class="text-[0.75em] lowercase text-stone-400">&nbsp;(except on whitelisted sites)</span>
</span>&nbsp;<br/>
Autodetection: <span :style="getSiteEnabledColor('@global', 'enableAard')"><small>{{ getSiteEnabledModes('@global', 'enableAard') }}</small></span>;&nbsp;
Keyboard shortcuts: <span :style="getSiteEnabledColor('@global', 'enableKeyboard')"><small>{{ getSiteEnabledModes('@global', 'enableKeyboard') }}</small></span>;
In-player UI: <span :style="getSiteEnabledColor('@global', 'enableUI')"><small>{{ getSiteEnabledModes('@global', 'enableUI') }}</small></span>;
</small>
</div>
</div>
<div style="margin-top: 1rem; margin-bottom: 1rem;">
<div class="border border-blue-500 text-blue-500 bg-slate-950 px-4 py-2" style="float: none">
<b>NOTE:</b> Sites not on this list use default extension settings.

View File

@ -168,6 +168,7 @@
</div>
</div>
<!-- Use for embedded content -->
<div class="field">
<div class="label">
Use these settings for <span class="color-emphasis">embedded content</span>?
@ -175,14 +176,17 @@
</div>
<div class="select">
<select
:value="siteDefaultForEmbedded"
:value="simpleExtensionSettings.applyToEmbeddedContent"
@click="setSiteOption('applyToEmbeddedContent', $event)"
>
<option :value="EmbeddedContentSettingsOverridePolicy.Default">
Use default ({{simpleDefaultSettings.applyToEmbeddedContent}})
</option>
<option :value="EmbeddedContentSettingsOverridePolicy.Always">
Always(-ish)
</option>
<option :value="EmbeddedContentSettingsOverridePolicy.UseAsDefault">
Use as default
When no settings exist for embedded content
</option>
<option :value="EmbeddedContentSettingsOverridePolicy.Never">
Never
@ -198,13 +202,16 @@
</div>
<div class="select">
<select
:value="siteDefaultOverrideEmbedded"
:value="simpleExtensionSettings.overrideWhenEmbedded"
@click="setSiteOption('overrideWhenEmbedded', $event)"
>
<option :value="true">
<option :value="EmbeddedContentSettingsOverridePolicy.Default">
Use default ({{simpleDefaultSettings.overrideWhenEmbedded}})
</option>
<option :value="EmbeddedContentSettingsOverridePolicy.Always">
Yes
</option>
<option :value="false">
<option :value="EmbeddedContentSettingsOverridePolicy.Never">
No
</option>
</select>
@ -310,18 +317,50 @@
</div>
</div>
<div class="mt-4">
<h4 class="mt-4 text-primary-400 text-[1.125em] font-bold mb-2">Other options</h4>
<button @click="playerDetectionOptionsDialog.visible = true">Advanced video player options</button>
<p>{{playerDetectionOptionsDialog.visible}}</p>
</div>
</div>
<Popup
v-if="playerDetectionOptionsDialog.visible"
title="Player detection options"
confirmButtonText="Save"
cancelButtonText="Cancel"
>
<PlayerSelectorAdvancedForm
:settings="settings"
:siteSettings="siteSettings"
></PlayerSelectorAdvancedForm>
</Popup>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import Popup from '@components/common/Popup.vue';
import PlayerSelectorAdvancedForm from '@components/segments/PlayerElementSelection/Panels/PlayerSelectorAdvancedForm.vue';
import ExtensionMode from '@src/common/enums/ExtensionMode.enum';
import VideoAlignmentType from '@src/common/enums/VideoAlignmentType.enum';
import CropModePersistence from '@src/common/enums/CropModePersistence.enum';
import EmbeddedContentSettingsOverridePolicy from '@src/common/enums/EmbeddedContentSettingsOverridePolicy.enum';
export default defineComponent({
components: {
Popup,
PlayerSelectorAdvancedForm,
},
props: [
'settings',
'siteSettings',
'isDefaultConfiguration',
'showPlayerSettings',
],
data() {
return {
CropModePersistence: CropModePersistence,
@ -337,50 +376,24 @@ export default defineComponent({
{label: 'Bottom left', arguments: {x: VideoAlignmentType.Left, y: VideoAlignmentType.Bottom}},
{label: 'Bottom center', arguments: {x: VideoAlignmentType.Center, y: VideoAlignmentType.Bottom}},
{label: 'Bottom right', arguments: {x: VideoAlignmentType.Right, y: VideoAlignmentType.Bottom}}
]
],
playerDetectionOptionsDialog: {
visible: false,
}
}
},
mixins: [
],
props: [
'settings',
'siteSettings',
'isDefaultConfiguration'
],
components: {
},
computed: {
simpleExtensionSettings() {
return {
enable: this.compileSimpleSettings('enable'),
enableAard: this.compileSimpleSettings('enableAard'),
enableKeyboard: this.compileSimpleSettings('enableKeyboard'),
enableUI: this.compileSimpleSettings('enableUI')
}
return this.computeSiteSettingsObject('site');
},
simpleEffectiveSettings() {
return {
enable: this.compileSimpleSettings('enable', 'site-effective'),
enableAard: this.compileSimpleSettings('enableAard', 'site-effective'),
enableKeyboard: this.compileSimpleSettings('enableKeyboard', 'site-effective'),
enableUI: this.compileSimpleSettings('enableUI', 'site-effective')
}
return this.computeSiteSettingsObject('site-effective');
},
simpleDefaultSettings() {
return {
enable: this.getDefaultOptionLabel('enable'),
enableAard: this.getDefaultOptionLabel('enableAard'),
enableKeyboard: this.getDefaultOptionLabel('enableKeyboard'),
enableUI: this.getDefaultOptionLabel('enableUI')
};
},
siteDefaultForEmbedded() {
return this.siteSettings.raw?.applyToEmbeddedContent;
},
siteDefaultOverrideEmbedded() {
return this.siteSettings.raw?.overrideWhenEmbedded ?? false;
return this.computeDefaultOptionLabels();
},
siteDefaultCrop() {
return this.siteSettings.raw?.defaults?.crop ? JSON.stringify(this.siteSettings.raw?.defaults?.crop) : JSON.stringify({useDefault: true});
@ -413,11 +426,25 @@ export default defineComponent({
this.forceRefreshPage();
},
methods: {
computeSiteSettingsObject(getFor = 'site') {
const out = {};
for (const key in this.settings.default.sites['@global']) {
out[key] = this.compileSimpleSettings(key, getFor);
}
return out;
},
computeDefaultOptionLabels() {
const out = {};
for (const key in this.settings.default.sites['@global']) {
out[key] = this.getDefaultOptionLabel(key);
}
return out;
},
/**
* Compiles our extension settings into more user-friendly options
*/
compileSimpleSettings(component, getFor = 'site'): ExtensionMode {
let settingsData;
switch (getFor) {
case 'site':
@ -431,15 +458,44 @@ export default defineComponent({
break;
}
console.log('compiling simple settings;', settingsData, 'original settings:', this.siteSettings)
return settingsData?.[component];
return settingsData?.[component] ?? ExtensionMode.Default;
},
/**
* Gets option labels for default values of each option
*/
getDefaultOptionLabel(component) {
const componentValue: ExtensionMode = this.compileSimpleSettings(component, 'default');
const componentValue: ExtensionMode | EmbeddedContentSettingsOverridePolicy = this.compileSimpleSettings(component, 'default');
if (component === 'overrideWhenEmbedded') {
switch (componentValue) {
case EmbeddedContentSettingsOverridePolicy.Default:
return 'default';
case EmbeddedContentSettingsOverridePolicy.Always:
return 'yes';
case EmbeddedContentSettingsOverridePolicy.Never:
return 'no';
default:
return '<invalid value>';
}
}
if (component === 'applyToEmbeddedContent') {
switch (componentValue as EmbeddedContentSettingsOverridePolicy) {
case EmbeddedContentSettingsOverridePolicy.Always:
return 'always(-ish)';
case EmbeddedContentSettingsOverridePolicy.UseAsDefault:
return 'when no settings exist for embedded content';
case EmbeddedContentSettingsOverridePolicy.Never:
return 'never';
case EmbeddedContentSettingsOverridePolicy.Default:
return 'default';
default:
return '<invalid value>';
}
}
switch (componentValue as ExtensionMode) {
case ExtensionMode.Disabled:
return 'disabled';
case ExtensionMode.Default:
@ -540,7 +596,13 @@ export default defineComponent({
setExtensionMode(component, event) {
const option = event.target.value;
this.siteSettings.set(component, option);
}
},
//#region ADVANCED VIDEO PLAYER SETTINGS
/**
*
*/
//#endregion
}
});

View File

@ -1,10 +1,12 @@
<template>
<!-- ADVANCED OPTIONS -->
<div v-if="DOMConfigData" class="flex flex-col gap-2">
<div class="flex flex-col gap-2">
<div class="flex flex-row gap-2 justify-end">
<button>Load existing config</button>
<button>Import from file</button>
</div>
<template v-if="DOMConfigData" >
<div class="field">
<div class="label">Player detection:</div>
<div class="select">
@ -49,12 +51,18 @@
<div class="field">
<div class="label">Additional CSS for the page</div>
<div class="input">
<textbox v-model="DOMConfigData.customCss" />
<textarea v-model="DOMConfigData.customCSS" />
</div>
<div class="hint">
You should be at least somewhat proficient with CSS in order to use this option.
</div>
</div>
</template>
<template v-else>
No DOM config for this site.
</template>
</div>
<div class="w-full flex flex-row gap-2 justify-end">
@ -75,6 +83,7 @@ import { SiteSettings } from '@src/ext/lib/settings/SiteSettings';
import { PlayerDetectionMode } from '@src/common/enums/PlayerDetectionMode.enum';
import Popup from '@components/common/Popup.vue';
import { _cp } from '../../../../../common/js/utils';
export default({
@ -88,6 +97,7 @@ export default({
],
data() {
return {
PlayerDetectionMode,
DOMConfigData: undefined as any,
selectSnapshotDialog: {visible: false},
}
@ -104,7 +114,11 @@ export default({
},
methods: {
loadSiteSettings(siteSettings: SiteSettings) {
if (siteSettings.data.DOMConfig) {
this.DOMConfigData = siteSettings.data.DOMConfig[siteSettings.data.activeDOMConfig];
} else {
this.DOMConfigData = _cp(siteSettings.blankSettings.DOMConfig.blank)
}
}
}

View File

@ -200,23 +200,23 @@ export default defineComponent({
},
async setPlayer(index) {
// yup.
this.siteSettings.getDOMConfig('modified', 'original');
await this.siteSettings.setUpdateFlags(['PlayerData']);
await this.siteSettings.set('DOMConfig.modified.type', 'modified', {noSave: true});
await this.siteSettings.set('activeDOMConfig', 'modified', {noSave: true});
// this.siteSettings.getDOMConfig('modified', 'original');
// await this.siteSettings.setUpdateFlags(['PlayerData']);
// await this.siteSettings.set('DOMConfig.modified.type', 'modified', {noSave: true});
// await this.siteSettings.set('activeDOMConfig', 'modified', {noSave: true});
// if user agrees with ultrawidify on what element player should be,
// we just unset our settings for this site
if (this.elementStack[index].heuristics?.autoMatch) {
await this.siteSettings.set('DOMConfig.modified.elements.player.manual', false);
this.getPlayerTree();
} else {
// ensure settings exist:
await this.siteSettings.set('DOMConfig.modified.elements.player.manual', true, {noSave: true});
await this.siteSettings.set('DOMConfig.modified.elements.player.mode', 'index', {noSave: true});
await this.siteSettings.set('DOMConfig.modified.elements.player.index', index, true);
this.getPlayerTree();
}
// // if user agrees with ultrawidify on what element player should be,
// // we just unset our settings for this site
// if (this.elementStack[index].heuristics?.autoMatch) {
// await this.siteSettings.set('DOMConfig.modified.elements.player.manual', false);
// this.getPlayerTree();
// } else {
// // ensure settings exist:
// await this.siteSettings.set('DOMConfig.modified.elements.player.manual', true, {noSave: true});
// await this.siteSettings.set('DOMConfig.modified.elements.player.mode', 'index', {noSave: true});
// await this.siteSettings.set('DOMConfig.modified.elements.player.index', index, true);
// this.getPlayerTree();
// }
},
/**
* Toggles active CSS for element of certain parent index.

View File

@ -56,23 +56,23 @@ export default({
},
async setPlayer(index) {
// yup.
this.siteSettings.getDOMConfig('modified', 'original');
await this.siteSettings.setUpdateFlags(['PlayerData']);
await this.siteSettings.set('DOMConfig.modified.type', 'modified', {noSave: true});
await this.siteSettings.set('activeDOMConfig', 'modified', {noSave: true});
// this.siteSettings.getDOMConfig('modified', 'original');
// await this.siteSettings.setUpdateFlags(['PlayerData']);
// await this.siteSettings.set('DOMConfig.modified.type', 'modified', {noSave: true});
// await this.siteSettings.set('activeDOMConfig', 'modified', {noSave: true});
// if user agrees with ultrawidify on what element player should be,
// we just unset our settings for this site
if (this.elementStack[index].heuristics?.autoMatch) {
await this.siteSettings.set('DOMConfig.modified.elements.player.manual', false);
this.getPlayerTree();
} else {
// ensure settings exist:
await this.siteSettings.set('DOMConfig.modified.elements.player.manual', true, {noSave: true});
await this.siteSettings.set('DOMConfig.modified.elements.player.mode', 'index', {noSave: true});
await this.siteSettings.set('DOMConfig.modified.elements.player.index', index, true);
this.getPlayerTree();
}
// // if user agrees with ultrawidify on what element player should be,
// // we just unset our settings for this site
// if (this.elementStack[index].heuristics?.autoMatch) {
// await this.siteSettings.set('DOMConfig.modified.elements.player.manual', false);
// this.getPlayerTree();
// } else {
// // ensure settings exist:
// await this.siteSettings.set('DOMConfig.modified.elements.player.manual', true, {noSave: true});
// await this.siteSettings.set('DOMConfig.modified.elements.player.mode', 'index', {noSave: true});
// await this.siteSettings.set('DOMConfig.modified.elements.player.index', index, true);
// this.getPlayerTree();
// }
},
edit() {

View File

@ -156,23 +156,23 @@ export default({
},
async setPlayer(index) {
// yup.
this.siteSettings.getDOMConfig('modified', 'original');
await this.siteSettings.setUpdateFlags(['PlayerData']);
await this.siteSettings.set('DOMConfig.modified.type', 'modified', {noSave: true});
await this.siteSettings.set('activeDOMConfig', 'modified', {noSave: true});
// this.siteSettings.getDOMConfig('modified', 'original');
// await this.siteSettings.setUpdateFlags(['PlayerData']);
// await this.siteSettings.set('DOMConfig.modified.type', 'modified', {noSave: true});
// await this.siteSettings.set('activeDOMConfig', 'modified', {noSave: true});
// if user agrees with ultrawidify on what element player should be,
// we just unset our settings for this site
if (this.elementStack[index].heuristics?.autoMatch) {
await this.siteSettings.set('DOMConfig.modified.elements.player.manual', false);
this.getPlayerTree();
} else {
// ensure settings exist:
await this.siteSettings.set('DOMConfig.modified.elements.player.manual', true, {noSave: true});
await this.siteSettings.set('DOMConfig.modified.elements.player.mode', 'index', {noSave: true});
await this.siteSettings.set('DOMConfig.modified.elements.player.index', index, true);
this.getPlayerTree();
}
// // if user agrees with ultrawidify on what element player should be,
// // we just unset our settings for this site
// if (this.elementStack[index].heuristics?.autoMatch) {
// await this.siteSettings.set('DOMConfig.modified.elements.player.manual', false);
// this.getPlayerTree();
// } else {
// // ensure settings exist:
// await this.siteSettings.set('DOMConfig.modified.elements.player.manual', true, {noSave: true});
// await this.siteSettings.set('DOMConfig.modified.elements.player.mode', 'index', {noSave: true});
// await this.siteSettings.set('DOMConfig.modified.elements.player.index', index, true);
// this.getPlayerTree();
// }
},
/**
* Toggles active CSS for element of certain parent index.