migration to site settings mostly done. TODO: check if things still work
This commit is contained in:
parent
a58edad8ea
commit
9503003a4a
6
src/common/interfaces/ArInterface.ts
Normal file
6
src/common/interfaces/ArInterface.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import AspectRatioType from '../enums/AspectRatioType.enum';
|
||||
|
||||
export interface Ar {
|
||||
type: AspectRatioType,
|
||||
ratio?: number
|
||||
}
|
@ -366,7 +366,7 @@ export interface SiteSettingsInterface {
|
||||
defaults?: { // must be defined in @global and @empty
|
||||
crop?: {type: AspectRatioType, [x: string]: any},
|
||||
stretch?: StretchType,
|
||||
alignment?: any,
|
||||
alignment?: {x: VideoAlignmentType, y: VideoAlignmentType},
|
||||
}
|
||||
|
||||
cropModePersistence?: CropModePersistence;
|
||||
|
@ -39,11 +39,9 @@ import DebugPanel from './src/PlayerUiPanels/DebugPanel.vue'
|
||||
import VideoSettings from './src/PlayerUiPanels/VideoSettings.vue'
|
||||
import AutodetectionSettingsPanel from './src/PlayerUiPanels/AutodetectionSettingsPanel.vue'
|
||||
import PlayerDetectionPanel from './src/PlayerUiPanels/PlayerDetectionPanel.vue'
|
||||
import { mapState } from 'vuex';
|
||||
// import Icon from '../common/components/Icon';
|
||||
import ResizerDebugPanel from './src/PlayerUiPanels/ResizerDebugPanelComponent';
|
||||
import BrowserDetect from '../ext/conf/BrowserDetect';
|
||||
import ExecAction from './src/ui-libs/ExecAction';
|
||||
import Logger from '../ext/lib/Logger';
|
||||
import Settings from '../ext/lib/Settings';
|
||||
import EventBus from '../ext/lib/EventBus';
|
||||
@ -85,7 +83,6 @@ export default {
|
||||
settings: {},
|
||||
BrowserDetect: BrowserDetect,
|
||||
settingsInitialized: false,
|
||||
execAction: new ExecAction(),
|
||||
eventBus: new EventBus(),
|
||||
logger: null,
|
||||
|
||||
|
@ -154,6 +154,7 @@ export default {
|
||||
selectedTab: 'videoSettings',
|
||||
BrowserDetect: BrowserDetect,
|
||||
preventClose: false,
|
||||
siteSettings: null,
|
||||
}
|
||||
},
|
||||
props: [
|
||||
@ -168,9 +169,12 @@ export default {
|
||||
// IS SUPER HARAM
|
||||
// THINGS WILL NOT WORK IF YOU USE ARROWS
|
||||
siteSupportLevel() {
|
||||
return (this.site && this.settings?.active) ? this.settings.active.sites[this.site]?.type || 'no-support' : 'waiting';
|
||||
return (this.site && this.siteSettings) ? this.siteSettings.data.type || 'no-support' : 'waiting';
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.siteSettings = this.settings.getSiteSettings(this.site);
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* Gets URL of the browser settings page (i think?)
|
||||
|
@ -262,7 +262,6 @@ import Button from '../../../common/components/Button.vue'
|
||||
import KeyboardShortcutParser from '../../../common/js/KeyboardShortcutParser';
|
||||
import ShortcutButton from '../../../common/components/ShortcutButton';
|
||||
import EditShortcutButton from '../../../common/components/EditShortcutButton';
|
||||
import ExecAction from '../ui-libs/ExecAction';
|
||||
import BrowserDetect from '../../../ext/conf/BrowserDetect';
|
||||
import AspectRatioType from '../../../common/enums/AspectRatioType.enum';
|
||||
import StretchType from '../../../common/enums/StretchType.enum';
|
||||
@ -286,7 +285,6 @@ export default {
|
||||
'site'
|
||||
],
|
||||
created() {
|
||||
this.exec = new ExecAction(this.settings, window.location.hostname);
|
||||
this.eventBus.subscribe('uw-config-broadcast', {function: (config) => this.handleConfigBroadcast(config)});
|
||||
},
|
||||
mounted() {
|
||||
|
@ -191,26 +191,7 @@ export default {
|
||||
commandArguments = $event.target.value;
|
||||
}
|
||||
|
||||
if (!this.settings.active.sites[this.site]) {
|
||||
this.settings.active.sites[this.site] = this.settings.getDefaultSiteConfiguration();
|
||||
}
|
||||
|
||||
const optionPath = option.split('.');
|
||||
if (optionPath.length < 2) {
|
||||
this.settings.active.sites[this.site][option] = commandArguments;
|
||||
} else {
|
||||
let currentOptionObject = this.settings.active.sites[this.site][optionPath[0]];
|
||||
let i;
|
||||
for (i = 1; i < optionPath.length - 1; i++) {
|
||||
if (currentOptionObject[optionPath[i]] === undefined) {
|
||||
currentOptionObject[optionPath[i]] = {};
|
||||
}
|
||||
currentOptionObject = currentOptionObject[optionPath[i]];
|
||||
}
|
||||
currentOptionObject[optionPath[optionPath.length - 1]] = commandArguments;
|
||||
}
|
||||
|
||||
this.settings.saveWithoutReload();
|
||||
this.siteSettings.set(option, commandArguments);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,23 +132,6 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="label">Extension default</div>
|
||||
<div class="select">
|
||||
<select
|
||||
:value="extensionDefaultCrop"
|
||||
@click="setDefaultCrop($event, 'global')"
|
||||
>
|
||||
<option
|
||||
v-for="(command, index) of settings?.active.commands.crop"
|
||||
:key="index"
|
||||
:value="JSON.stringify(command.arguments)"
|
||||
>
|
||||
{{command.label}}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -220,23 +203,7 @@ export default {
|
||||
setDefaultCrop($event, scope) {
|
||||
const commandArguments = JSON.parse($event.target.value);
|
||||
|
||||
if (scope === 'site') {
|
||||
if (!this.settings.active.sites[this.site]) {
|
||||
this.settings.active.sites[this.site] = this.settings.getDefaultSiteConfiguration();
|
||||
}
|
||||
this.settings.active.sites[this.site].defaultCrop = commandArguments;
|
||||
} else {
|
||||
// eventually, this 'if' will be safe to remove (and we'll be able to only
|
||||
// get away with the 'else' section) Maybe in 6 months or so.
|
||||
if (!this.settings.active.crop) {
|
||||
this.settings.active['crop'] = {
|
||||
default: commandArguments
|
||||
}
|
||||
} else {
|
||||
this.settings.active.crop.default = commandArguments;
|
||||
}
|
||||
}
|
||||
|
||||
this.siteSettings.set('defaults.crop', commandArguments);
|
||||
this.settings.saveWithoutReload();
|
||||
},
|
||||
|
||||
|
@ -235,16 +235,7 @@ export default {
|
||||
*/
|
||||
setDefaultStretchingMode($event, globalOrSite) {
|
||||
const commandArguments = JSON.parse($event.target.value);
|
||||
|
||||
if (globalOrSite === 'site') {
|
||||
if (!this.settings.active.sites[this.site]) {
|
||||
this.settings.active.sites[this.site] = this.settings.getDefaultSiteConfiguration();
|
||||
}
|
||||
this.settings.active.sites[this.site].defaultStretch = commandArguments;
|
||||
} else {
|
||||
this.settings.active.stretch.default = commandArguments;
|
||||
}
|
||||
this.settings.saveWithoutReload();
|
||||
this.siteSettings.set('defaults.stretch', commandArguments);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -117,7 +117,6 @@ import Button from '../../../common/components/Button.vue'
|
||||
import ShortcutButton from '../../../common/components/ShortcutButton';
|
||||
import EditShortcutButton from '../../../common/components/EditShortcutButton';
|
||||
import ComputeActionsMixin from '../../../common/mixins/ComputeActionsMixin';
|
||||
import ExecAction from '../ui-libs/ExecAction';
|
||||
import BrowserDetect from '../../../ext/conf/BrowserDetect';
|
||||
import AlignmentOptionsControlComponent from './AlignmentOptionsControlComponent.vue';
|
||||
import CommsMixin from '../utils/CommsMixin';
|
||||
@ -149,7 +148,6 @@ export default {
|
||||
'site'
|
||||
],
|
||||
created() {
|
||||
this.exec = new ExecAction(this.settings, window.location.hostname);
|
||||
this.eventBus.subscribe('uw-config-broadcast', {function: (config) => this.handleConfigBroadcast(config)});
|
||||
},
|
||||
mounted() {
|
||||
|
@ -1,94 +0,0 @@
|
||||
import Comms from '../../../ext/lib/comms/Comms';
|
||||
|
||||
class ExecAction {
|
||||
constructor(settings, site) {
|
||||
this.settings = settings;
|
||||
this.site = site;
|
||||
}
|
||||
|
||||
setSettings(settings) {
|
||||
this.settings = settings;
|
||||
}
|
||||
setSite(site) {
|
||||
this.site = site;
|
||||
}
|
||||
|
||||
|
||||
async exec(action, scope, frame, useBus) {
|
||||
for (var cmd of action.cmd) {
|
||||
if (!scope || scope === 'page') {
|
||||
const message = {
|
||||
forwardToContentScript: true,
|
||||
targetFrame: frame,
|
||||
frame: frame,
|
||||
cmd: cmd.action,
|
||||
arg: cmd.arg,
|
||||
customArg: cmd.customArg
|
||||
}
|
||||
if (useBus) {
|
||||
// todo: postMessage out of the iframe!
|
||||
// window.ultrawidify.bus.sendMessage(message.cmd, message);
|
||||
window.parent.sendMessage(message.cmd, message);
|
||||
} else {
|
||||
Comms.sendMessage(message);
|
||||
}
|
||||
} else {
|
||||
|
||||
// set-ar-persistence sends stuff to content scripts as well (!)
|
||||
// it's important to do that BEFORE the save step
|
||||
if (cmd.action === 'set-ar-persistence') {
|
||||
// even when setting global defaults, we only send message to the current tab in
|
||||
// order to avoid problems related to
|
||||
const message = {
|
||||
forwardToActive: true,
|
||||
targetFrame: frame,
|
||||
frame: frame,
|
||||
cmd: cmd.action,
|
||||
arg: cmd.arg,
|
||||
}
|
||||
// this hopefully delays settings.save() until current crops are saved on the site
|
||||
// and thus avoid any fucky-wuckies
|
||||
if (useBus) {
|
||||
// todo: postMessage out of the iframe!
|
||||
// window.ultrawidify.bus.sendMessage(message.cmd, message);
|
||||
window.parent.sendMessage(message.cmd, message);
|
||||
} else {
|
||||
await Comms.sendMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
let site = this.site;
|
||||
if (scope === 'global') {
|
||||
site = '@global';
|
||||
} else if (!this.site) {
|
||||
site = window.location.hostname;
|
||||
}
|
||||
|
||||
if (scope === 'site' && !this.settings.active.sites[site]) {
|
||||
this.settings.active.sites[site] = this.settings.getDefaultOption();
|
||||
}
|
||||
|
||||
if (cmd.action === "set-stretch") {
|
||||
this.settings.active.sites[site].stretch = cmd.arg;
|
||||
} else if (cmd.action === "set-alignment") {
|
||||
this.settings.active.sites[site].videoAlignment = cmd.arg;
|
||||
} else if (cmd.action === "set-extension-mode") {
|
||||
this.settings.active.sites[site].mode = cmd.arg;
|
||||
} else if (cmd.action === "set-autoar-mode") {
|
||||
this.settings.active.sites[site].autoar = cmd.arg;
|
||||
} else if (cmd.action === 'set-keyboard') {
|
||||
this.settings.active.sites[site].keyboardShortcutsEnabled = cmd.arg;
|
||||
} else if (cmd.action === 'set-ar-persistence') {
|
||||
this.settings.active.sites[site]['cropModePersistence'] = cmd.arg;
|
||||
this.settings.saveWithoutReload();
|
||||
}
|
||||
|
||||
if (cmd.action !== 'set-ar-persistence') {
|
||||
this.settings.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default ExecAction;
|
@ -8,11 +8,13 @@ import Logger, { baseLoggingOptions } from './lib/Logger';
|
||||
import UWGlobals from './lib/UWGlobals';
|
||||
import EventBus from './lib/EventBus';
|
||||
import KeyboardHandler from './lib/kbm/KeyboardHandler';
|
||||
import { SiteSettings } from './lib/settings/SiteSettings';
|
||||
|
||||
export default class UWContent {
|
||||
pageInfo: PageInfo;
|
||||
comms: CommsClient;
|
||||
settings: Settings;
|
||||
siteSettings: SiteSettings;
|
||||
keyboardHandler: KeyboardHandler;
|
||||
logger: Logger;
|
||||
eventBus: EventBus;
|
||||
@ -90,6 +92,7 @@ export default class UWContent {
|
||||
logger: this.logger
|
||||
});
|
||||
await this.settings.init();
|
||||
this.siteSettings = this.settings.getSiteSettings();
|
||||
}
|
||||
|
||||
this.eventBus = new EventBus();
|
||||
@ -109,42 +112,25 @@ export default class UWContent {
|
||||
}
|
||||
}
|
||||
|
||||
// we always initialize extension, even if it's disabled.
|
||||
initPhase2() {
|
||||
// If extension is soft-disabled, don't do shit
|
||||
var extensionMode = this.settings.getExtensionMode();
|
||||
|
||||
this.logger.log('info', 'debug', "[uw::init] Extension mode:" + (extensionMode < 0 ? "disabled" : extensionMode == '1' ? 'basic' : 'full'));
|
||||
|
||||
const isSiteDisabled = extensionMode === ExtensionMode.Disabled
|
||||
|
||||
if (isSiteDisabled) {
|
||||
this.destroy();
|
||||
if (this.settings.getExtensionMode('@global') === ExtensionMode.Disabled) {
|
||||
this.logger.log('info', 'debug', "[uw::init] EXTENSION DISABLED, THEREFORE WONT BE STARTED")
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (this.pageInfo) {
|
||||
this.logger.log('info', 'debug', '[uw.js::setup] An instance of pageInfo already exists and will be destroyed.');
|
||||
this.pageInfo.destroy();
|
||||
}
|
||||
this.pageInfo = new PageInfo(this.eventBus, this.settings, this.logger, extensionMode, isSiteDisabled);
|
||||
this.pageInfo = new PageInfo(this.eventBus, this.siteSettings, this.settings, this.logger);
|
||||
this.logger.log('info', 'debug', "[uw.js::setup] pageInfo initialized.");
|
||||
|
||||
this.logger.log('info', 'debug', "[uw.js::setup] will try to initate KeyboardHandler.");
|
||||
|
||||
// start action handler only if extension is enabled for this site
|
||||
if (!isSiteDisabled) {
|
||||
if (this.keyboardHandler) {
|
||||
this.keyboardHandler.destroy();
|
||||
}
|
||||
this.keyboardHandler = new KeyboardHandler(this.eventBus, this.settings, this.logger);
|
||||
this.keyboardHandler = new KeyboardHandler(this.eventBus, this.siteSettings, this.settings, this.logger);
|
||||
this.keyboardHandler.init();
|
||||
|
||||
this.logger.log('info', 'debug', "[uw.js::setup] KeyboardHandler initiated.");
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
console.error('Ultrawidify: failed to start extension. Error:', e)
|
||||
|
@ -12,6 +12,7 @@ import Logger from './Logger';
|
||||
import SettingsInterface from '../../common/interfaces/SettingsInterface';
|
||||
import { browser } from 'webextension-polyfill-ts';
|
||||
import AspectRatioType from '../../common/enums/AspectRatioType.enum';
|
||||
import { SiteSettings } from './settings/SiteSettings';
|
||||
|
||||
if(process.env.CHANNEL !== 'stable'){
|
||||
console.info("Loading Settings");
|
||||
@ -348,189 +349,6 @@ class Settings {
|
||||
return JSON.parse(JSON.stringify(this.default));
|
||||
}
|
||||
|
||||
// -----------------------------------------
|
||||
// Config for a given page:
|
||||
//
|
||||
// <hostname> : {
|
||||
// status: <option> // should extension work on this site?
|
||||
// arStatus: <option> // should we do autodetection on this site?
|
||||
// statusEmbedded: <option> // reserved for future... maybe
|
||||
// }
|
||||
//
|
||||
// Valid values for options:
|
||||
//
|
||||
// status, arStatus, statusEmbedded:
|
||||
//
|
||||
// * enabled — always allow
|
||||
// * basic — only allow fullscreen
|
||||
// * default — allow if default is to allow, block if default is to block
|
||||
// * disabled — never allow
|
||||
|
||||
|
||||
getActionsForSite(site) {
|
||||
if (!site) {
|
||||
return this.active.actions;
|
||||
}
|
||||
if (this.active.sites[site] && this.active.sites[site].actions && this.active.sites[site].actions.length > 0) {
|
||||
return this.active.sites[site].actions;
|
||||
}
|
||||
return this.active.actions;
|
||||
}
|
||||
|
||||
getSettingsForSite(site?) {
|
||||
if (!site) {
|
||||
site = window.location.hostname;
|
||||
}
|
||||
|
||||
return this.active.sites[site];
|
||||
}
|
||||
|
||||
getExtensionMode(site?: string) {
|
||||
if (!site) {
|
||||
site = window.location.hostname;
|
||||
|
||||
if (!site) {
|
||||
this.logger?.log('info', 'settings', `[Settings::canStartExtension] window.location.hostname is null or undefined: ${window.location.hostname} \nactive settings:`, this.active);
|
||||
return ExtensionMode.Disabled;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// if site-specific settings don't exist for the site, we use default mode:
|
||||
if (! this.active.sites[site]) {
|
||||
return this.getExtensionMode('@global');
|
||||
}
|
||||
|
||||
if (this.active.sites[site].mode === ExtensionMode.Enabled) {
|
||||
return ExtensionMode.Enabled;
|
||||
} else if (this.active.sites[site].mode === ExtensionMode.Basic) {
|
||||
return ExtensionMode.Basic;
|
||||
} else if (this.active.sites[site].mode === ExtensionMode.Disabled) {
|
||||
return ExtensionMode.Disabled;
|
||||
} else {
|
||||
if (site !== '@global') {
|
||||
return this.getExtensionMode('@global');
|
||||
} else {
|
||||
return ExtensionMode.Disabled;
|
||||
}
|
||||
}
|
||||
|
||||
} catch(e){
|
||||
this.logger?.log('error', 'settings', "[Settings.js::canStartExtension] Something went wrong — are settings defined/has init() been called?\n\nerror:", e, "\n\nSettings object:", this)
|
||||
|
||||
return ExtensionMode.Disabled;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether extension can start on a given site or not.
|
||||
* @param site — default value fof this argument is window.location.hostname
|
||||
* @returns true if extension can run on this site, false otherwise
|
||||
*/
|
||||
isEnabledForSite(site = window.location.hostname) {
|
||||
if (!site) {
|
||||
this.logger?.log('info', 'settings', `[Settings::canStartExtension] window.location.hostname is null or undefined: ${window.location.hostname} \nactive settings:`, this.active);
|
||||
return false;
|
||||
}
|
||||
|
||||
// if (Debug.debug) {
|
||||
// // let's just temporarily disable debugging while recursively calling
|
||||
// // this function to get extension status on current site without duplo
|
||||
// // console logs (and without endless recursion)
|
||||
// Debug.debug = false;
|
||||
// const cse = this.canStartExtension(site);
|
||||
// Debug.debug = true;
|
||||
// }
|
||||
try{
|
||||
// if site is not defined, we use default mode:
|
||||
if (! this.active.sites[site] || this.active.sites[site].mode === ExtensionMode.Default) {
|
||||
return this.active.sites['@global'].mode === ExtensionMode.Enabled;
|
||||
}
|
||||
|
||||
if (this.active.sites['@global'].mode === ExtensionMode.Enabled) {
|
||||
return this.active.sites[site].mode !== ExtensionMode.Disabled;
|
||||
} else if (this.active.sites['@global'].mode === ExtensionMode.Whitelist) {
|
||||
return this.active.sites[site].mode === ExtensionMode.Enabled;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch(e) {
|
||||
this.logger?.log('error', 'settings', "[Settings.js::canStartExtension] Something went wrong — are settings defined/has init() been called?\nSettings object:", this);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
keyboardShortcutsEnabled(site) {
|
||||
if (!site) {
|
||||
site = window.location.hostname;
|
||||
}
|
||||
if (!site) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!this.active.sites[site]
|
||||
|| this.active.sites[site].keyboardShortcutsEnabled === undefined
|
||||
|| this.active.sites[site].keyboardShortcutsEnabled === ExtensionMode.Default) {
|
||||
return this.keyboardShortcutsEnabled('@global');
|
||||
} else {
|
||||
return this.active.sites[site].keyboardShortcutsEnabled === ExtensionMode.Enabled;
|
||||
}
|
||||
} catch (e) {
|
||||
this.logger?.log('info', 'settings',"[Settings.js::keyboardDisabled] something went wrong:", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
extensionEnabled(){
|
||||
return this.active.sites['@global'].mode !== ExtensionMode.Disabled
|
||||
}
|
||||
|
||||
canStartAutoAr(site?: string) {
|
||||
// 'site' argument is only ever used when calling this function recursively for debugging
|
||||
if (!site) {
|
||||
site = window.location.hostname;
|
||||
|
||||
if (!site) {
|
||||
this.logger?.log('warn', ['settings', 'init', 'debug'], `[Settings::canStartAutoAr] No site — even window.location.hostname returned nothing!: ${window.location.hostname}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// if (Debug.debug) {
|
||||
// let's just temporarily disable debugging while recursively calling
|
||||
// this function to get extension status on current site without duplo
|
||||
// console logs (and without endless recursion)
|
||||
// Debug.debug = false;
|
||||
// const csar = this.canStartAutoAr(site);
|
||||
// Debug.debug = true;
|
||||
|
||||
this.logger?.log('info', ['settings', 'init', 'debug'], "[Settings::canStartAutoAr] ----------------\nCAN WE START AUTOAR ON SITE", site,
|
||||
"?\n\nsettings.active.sites[site]=", this.active.sites[site], "settings.active.sites[@global]=", this.active.sites['@global'],
|
||||
"\nAutoar mode (global)?", this.active.sites['@global'].autoar,
|
||||
`\nAutoar mode (${site})`, this.active.sites[site] ? this.active.sites[site].autoar : '<not defined>',
|
||||
// "\nCan autoar be started?", csar
|
||||
);
|
||||
// }
|
||||
|
||||
// if site is not defined, we use default mode:
|
||||
if (! this.active.sites[site]) {
|
||||
this.logger?.log('info', ['settings', 'aard', 'init', 'debug'], "[Settings::canStartAutoAr] Settings not defined for this site, returning defaults.", site, this.active.sites[site], this.active.sites);
|
||||
return this.active.sites['@global'].autoar === ExtensionMode.Enabled;
|
||||
}
|
||||
|
||||
if (this.active.sites['@global'].autoar === ExtensionMode.Enabled) {
|
||||
this.logger?.log('info', ['settings', 'aard', 'init', 'debug'], `[Settings::canStartAutoAr] Aard is enabled by default. Extension can run unless disabled for this site.`, this.active.sites[site].autoar);
|
||||
return this.active.sites[site].autoar !== ExtensionMode.Disabled;
|
||||
} else if (this.active.sites['@global'].autoar === ExtensionMode.Whitelist) {
|
||||
this.logger?.log('info', ['settings', 'init', 'debug'], "canStartAutoAr — can(not) start aard because extension is in whitelist mode, and this site is (not) equal to", ExtensionMode.Enabled)
|
||||
return this.active.sites[site].autoar === ExtensionMode.Enabled;
|
||||
} else {
|
||||
this.logger?.log('info', ['settings', 'init', 'debug'], "canStartAutoAr — cannot start aard because extension is globally disabled")
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
getDefaultOption(option?) {
|
||||
const allDefault = {
|
||||
mode: ExtensionMode.Default,
|
||||
@ -547,40 +365,6 @@ class Settings {
|
||||
return allDefault[option];
|
||||
}
|
||||
|
||||
getDefaultAr(site) {
|
||||
// site = this.getSiteSettings(site);
|
||||
|
||||
// if (site.defaultAr) {
|
||||
// return site.defaultAr;
|
||||
// }
|
||||
return this.active.miscSettings.defaultAr;
|
||||
}
|
||||
|
||||
getDefaultStretchMode_legacy(site) {
|
||||
if (site && (this.active.sites[site]?.stretch ?? StretchType.Default) !== StretchType.Default) {
|
||||
return this.active.sites[site].stretch;
|
||||
}
|
||||
|
||||
return this.active.sites['@global'].stretch;
|
||||
}
|
||||
|
||||
getDefaultCropPersistenceMode(site) {
|
||||
if (site && (this.active.sites[site]?.cropModePersistence ?? StretchType.Default) !== StretchType.Default) {
|
||||
return this.active.sites[site].cropModePersistence;
|
||||
}
|
||||
|
||||
// persistence mode thing is missing from settings by default
|
||||
return this.active.sites['@global'].cropModePersistence || CropModePersistence.Disabled;
|
||||
}
|
||||
|
||||
getDefaultVideoAlignment(site) {
|
||||
if ( (this.active.sites[site]?.videoAlignment ?? VideoAlignmentType.Default) !== VideoAlignmentType.Default) {
|
||||
return this.active.sites[site].videoAlignment;
|
||||
}
|
||||
|
||||
return this.active.sites['@global'].videoAlignment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets default site configuration. Only returns essential settings.
|
||||
* @returns
|
||||
@ -597,48 +381,8 @@ class Settings {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets default cropping mode for extension.
|
||||
* Returns site default if defined, otherwise it returns extension default.
|
||||
* If extension default is not defined because extension updated but the
|
||||
* settings didn't port over, we return automatic.
|
||||
*/
|
||||
getDefaultCrop(site?: string) {
|
||||
return this.active.sites[site ?? window.location.hostname]?.defaultCrop ?? this.active.crop?.default ?? {type: AspectRatioType.Automatic};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets default stretching mode for extension.
|
||||
* Returns site default if defined, otherwise it returns extension default.
|
||||
* If extension default is not defined because extension updated but the
|
||||
* settings didn't port over, we return automatic.
|
||||
*/
|
||||
getDefaultStretchMode(site?: string) {
|
||||
return this.active.sites[site ?? window.location.hostname]?.defaultStretch ?? this.active.stretch.default ?? {type: StretchType.NoStretch};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a site option and initializes values if empty.
|
||||
* Does not save settings.
|
||||
* @param path
|
||||
* @param value
|
||||
* @param site
|
||||
*/
|
||||
setSiteOption(path: string[], value: any, site?: string) {
|
||||
site = site ?? window.location.hostname;
|
||||
|
||||
if (!this.active.sites[site]) {
|
||||
this.active.sites[site] = {};
|
||||
}
|
||||
|
||||
let object = this.active.sites[site];
|
||||
for (let i = 0; i < path.length - 1; i++) {
|
||||
if (!object[path[i]]) {
|
||||
object[path[i]] = {};
|
||||
}
|
||||
object = object[path[i]];
|
||||
}
|
||||
object[path[path.length - 1]] = value;
|
||||
getSiteSettings(site: string = window.location.hostname): SiteSettings {
|
||||
return new SiteSettings(this, site);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -252,7 +252,7 @@ class ArDetector {
|
||||
this.resetBlackLevel();
|
||||
|
||||
// if we're restarting ArDetect, we need to do this in order to force-recalculate aspect ratio
|
||||
this.conf.resizer.setLastAr({type: AspectRatioType.AutomaticUpdate, ratio: this.defaultAr});
|
||||
this.conf.resizer.lastAr = {type: AspectRatioType.AutomaticUpdate, ratio: this.defaultAr};
|
||||
|
||||
this.canvasImageDataRowLength = cwidth << 2;
|
||||
|
||||
@ -277,7 +277,7 @@ class ArDetector {
|
||||
start() {
|
||||
if (this.conf.resizer.lastAr.type === AspectRatioType.AutomaticUpdate) {
|
||||
// ensure first autodetection will run in any case
|
||||
this.conf.resizer.setLastAr({type: AspectRatioType.AutomaticUpdate, ratio: this.defaultAr});
|
||||
this.conf.resizer.lastAr = {type: AspectRatioType.AutomaticUpdate, ratio: this.defaultAr};
|
||||
}
|
||||
|
||||
// start autodetection
|
||||
@ -781,7 +781,7 @@ class ArDetector {
|
||||
}
|
||||
|
||||
// check if aspect ratio is changed:
|
||||
let lastAr = this.conf.resizer.getLastAr();
|
||||
let lastAr = this.conf.resizer.lastAr;
|
||||
if (lastAr.type === AspectRatioType.AutomaticUpdate && lastAr.ratio !== null && lastAr.ratio !== undefined){
|
||||
// we can only deny aspect ratio changes if we use automatic mode and if aspect ratio was set from here.
|
||||
|
||||
|
@ -1,11 +1,13 @@
|
||||
import EventBus, { EventBusCommand } from '../EventBus';
|
||||
import Logger from '../Logger';
|
||||
import Settings from '../Settings';
|
||||
import { SiteSettings } from '../settings/SiteSettings';
|
||||
|
||||
export class KbmBase {
|
||||
listenFor: string[] = [];
|
||||
logger: Logger;
|
||||
settings: Settings;
|
||||
siteSettings: SiteSettings;
|
||||
eventBus: EventBus;
|
||||
|
||||
eventBusCommands: { [x: string]: EventBusCommand } = {
|
||||
@ -26,7 +28,7 @@ export class KbmBase {
|
||||
},
|
||||
}
|
||||
|
||||
constructor(eventBus: EventBus, settings: Settings, logger: Logger) {
|
||||
constructor(eventBus: EventBus, siteSettings: SiteSettings, settings: Settings, logger: Logger) {
|
||||
this.logger = logger;
|
||||
this.settings = settings;
|
||||
this.eventBus = eventBus;
|
||||
@ -90,9 +92,10 @@ export class KbmBase {
|
||||
}
|
||||
|
||||
load() {
|
||||
if (! (this.settings.isEnabledForSite() && this.settings.active.kbm.enabled)) {
|
||||
return;
|
||||
}
|
||||
// if (! (this.settings.isEnabledForSite() && this.settings.active.kbm.enabled)) {
|
||||
// return;
|
||||
// }
|
||||
// todo: detect if this is enabled or not
|
||||
this.addListener();
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ import Settings from '../Settings';
|
||||
import VideoData from '../video-data/VideoData';
|
||||
import EventBus, { EventBusCommand } from '../EventBus';
|
||||
import KbmBase from './KbmBase';
|
||||
import { SiteSettings } from '../settings/SiteSettings';
|
||||
|
||||
if(process.env.CHANNEL !== 'stable'){
|
||||
console.info("Loading KeyboardHandler");
|
||||
@ -24,6 +25,7 @@ export class KeyboardHandler extends KbmBase {
|
||||
listenFor: string[] = ['keyup'];
|
||||
logger: Logger;
|
||||
settings: Settings;
|
||||
siteSettings: SiteSettings;
|
||||
eventBus: EventBus;
|
||||
|
||||
playerElements: HTMLElement[] = [];
|
||||
@ -43,8 +45,8 @@ export class KeyboardHandler extends KbmBase {
|
||||
}
|
||||
|
||||
//#region lifecycle
|
||||
constructor(eventBus: EventBus, settings: Settings, logger: Logger) {
|
||||
super(eventBus, settings, logger);
|
||||
constructor(eventBus: EventBus, siteSettings: SiteSettings, settings: Settings, logger: Logger) {
|
||||
super(eventBus, siteSettings, settings, logger);
|
||||
|
||||
this.init();
|
||||
}
|
||||
@ -124,7 +126,7 @@ export class KeyboardHandler extends KbmBase {
|
||||
"\nis type === 'text'? (yes -> prevent):", activeElement.getAttribute("type") === "text",
|
||||
"\nevent.target.isContentEditable? (yes -> prevent):", event.target.isContentEditable,
|
||||
"\nis keyboard local disabled? (yes -> prevent):", this.keyboardLocalDisabled,
|
||||
"\nis keyboard enabled in settings? (no -> prevent)", this.settings.keyboardShortcutsEnabled(window.location.hostname),
|
||||
// "\nis keyboard enabled in settings? (no -> prevent)", this.settings.keyboardShortcutsEnabled(window.location.hostname),
|
||||
"\nwill the action be prevented? (yes -> prevent)", preventAction,
|
||||
"\n-----------------{ extra debug info }-------------------",
|
||||
"\ntag name? (lowercase):", activeElement.tagName, activeElement.tagName.toLocaleLowerCase(),
|
||||
@ -139,9 +141,9 @@ export class KeyboardHandler extends KbmBase {
|
||||
if (this.keyboardLocalDisabled) {
|
||||
return true;
|
||||
}
|
||||
if (!this.settings.keyboardShortcutsEnabled(window.location.hostname)) {
|
||||
return true;
|
||||
}
|
||||
// if (!this.settings.keyboardShortcutsEnabled(window.location.hostname)) {
|
||||
// return true;
|
||||
// }
|
||||
if (this.inputs.indexOf(activeElement.tagName.toLocaleLowerCase()) !== -1) {
|
||||
return true;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import EventBus, { EventBusCommand } from '../EventBus';
|
||||
import Logger from '../Logger';
|
||||
import Settings from '../Settings';
|
||||
import { SiteSettings } from '../settings/SiteSettings';
|
||||
import KbmBase from './KbmBase';
|
||||
|
||||
if(process.env.CHANNEL !== 'stable'){
|
||||
@ -35,11 +36,12 @@ export class MouseHandler extends KbmBase {
|
||||
}
|
||||
|
||||
//#region lifecycle
|
||||
constructor(playerElement: HTMLElement, eventBus: EventBus, settings: Settings, logger: Logger) {
|
||||
super(eventBus, settings, logger);
|
||||
constructor(playerElement: HTMLElement, eventBus: EventBus, siteSettings: SiteSettings, settings: Settings, logger: Logger) {
|
||||
super(eventBus, siteSettings, settings, logger);
|
||||
|
||||
this.logger = logger;
|
||||
this.settings = settings;
|
||||
this.siteSettings = siteSettings;
|
||||
this.eventBus = eventBus;
|
||||
this.playerElement = playerElement;
|
||||
|
||||
@ -52,10 +54,7 @@ export class MouseHandler extends KbmBase {
|
||||
}
|
||||
|
||||
load() {
|
||||
if (!this.settings.isEnabledForSite() || this.settings.active.kbm.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
// todo: process whether mouse movement should be enabled or disabled
|
||||
this.addListener();
|
||||
}
|
||||
|
||||
|
@ -4,10 +4,12 @@ import { SiteSettingsInterface } from '../../../common/interfaces/SettingsInterf
|
||||
import { _cp } from '../../../common/js/utils';
|
||||
import Settings from '../Settings';
|
||||
import { browser } from 'webextension-polyfill-ts';
|
||||
import StretchType from '../../../common/enums/StretchType.enum';
|
||||
import VideoAlignmentType from '../../../common/enums/VideoAlignmentType.enum';
|
||||
|
||||
export class SiteSettings {
|
||||
private settings: Settings;
|
||||
private site: string;;
|
||||
private site: string;
|
||||
|
||||
data: SiteSettingsInterface;
|
||||
temporaryData: SiteSettingsInterface;
|
||||
@ -45,8 +47,24 @@ export class SiteSettings {
|
||||
return;
|
||||
}
|
||||
|
||||
this.data.defaultCrop = this.data.defaultCrop ?? _cp(this.defaultSettings.defaultCrop);
|
||||
this.data.defaultStretch = this.data.defaultStretch ?? _cp(this.defaultSettings.defaultStretch);
|
||||
|
||||
// 'undefined' default here means use default
|
||||
this.data.defaults.crop = this.data.defaults.crop ?? _cp(this.defaultSettings.defaults.crop);
|
||||
|
||||
// these can contain default options, but can also be undefined
|
||||
if (this.data.defaults?.stretch === StretchType.Default || this.data.defaults?.stretch === undefined) {
|
||||
this.data.defaults.stretch = _cp(this.defaultSettings.defaults.stretch);
|
||||
}
|
||||
if (this.data.defaults?.alignment === undefined) { // distinguish between undefined and 0!
|
||||
this.data.defaults.alignment = _cp(this.defaultSettings.defaults.alignment);
|
||||
} else {
|
||||
if (this.data.defaults?.alignment.x === VideoAlignmentType.Default) {
|
||||
this.data.defaults.alignment.x = _cp(this.defaultSettings.defaults.alignment.x);
|
||||
}
|
||||
if (this.data.defaults.alignment.y === VideoAlignmentType.Default) {
|
||||
this.data.defaults.alignment.y = _cp(this.defaultSettings.defaults.alignment.y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (const enableSegment of ['enable', 'enableAard', 'enableKeyboard']) {
|
||||
@ -97,8 +115,9 @@ export class SiteSettings {
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//#region get shit
|
||||
/**
|
||||
* Gets custom query selector for player or video, if element exists, is manually defined, and has querySelectors property.
|
||||
* Gets custom query selector for player or video, if configuration for it exists, is manually defined, and has querySelectors property.
|
||||
* @param element player or video
|
||||
* @returns querySelector if possible, undefined otherwise
|
||||
*/
|
||||
@ -106,6 +125,80 @@ export class SiteSettings {
|
||||
return this.data.currentDOMConfig?.elements?.[element]?.manual && this.data.currentDOMConfig?.elements?.[element]?.querySelectors || undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets custom element index for player, if configuration for player exists, is manually defined, and has index property defined.
|
||||
* NOTE: while querySelector should take priority over index, this function does NOT take that into account.
|
||||
* @returns parent element index if possible, undefined otherwise
|
||||
*/
|
||||
getPlayerIndex(): number | undefined {
|
||||
return this.data.currentDOMConfig?.elements?.player?.manual && this.data.currentDOMConfig?.elements?.player?.index || undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets default crop mode for extension, while taking persistence settings into account
|
||||
*/
|
||||
getDefaultOption(option: 'crop' | 'stretch' | 'alignment') {
|
||||
const persistenceLevel = this.data.persistOption[option];
|
||||
|
||||
switch (persistenceLevel) {
|
||||
case CropModePersistence.UntilPageReload:
|
||||
return this.temporaryData.defaults[option];
|
||||
case CropModePersistence.CurrentSession:
|
||||
return this.sessionData.defaults[option];
|
||||
case CropModePersistence.Disabled:
|
||||
case CropModePersistence.Default:
|
||||
case CropModePersistence.Forever:
|
||||
default:
|
||||
return this.data.defaults[option];
|
||||
}
|
||||
}
|
||||
|
||||
private _getEnvironment(isTheater: boolean, isFullscreen: boolean): 'fullscreen' | 'theater' | 'normal' {
|
||||
if (isFullscreen) {
|
||||
return 'fullscreen';
|
||||
}
|
||||
if (isTheater) {
|
||||
return 'theater';
|
||||
}
|
||||
return 'normal';
|
||||
}
|
||||
|
||||
/**
|
||||
* Is extension allowed to run in current environment
|
||||
* @param isTheater
|
||||
* @param isFullscreen
|
||||
* @returns
|
||||
*/
|
||||
isEnabledForEnvironment(isTheater: boolean, isFullscreen: boolean) {
|
||||
const env = this._getEnvironment(isTheater, isFullscreen);
|
||||
return this.data.enable[env];
|
||||
}
|
||||
|
||||
/**
|
||||
* Is autodetection allowed to run, given current environment
|
||||
* @param isTheater
|
||||
* @param isFullscreen
|
||||
* @returns
|
||||
*/
|
||||
isAardEnabledForEnvironment(isTheater: boolean, isFullscreen: boolean) {
|
||||
const env = this._getEnvironment(isTheater, isFullscreen);
|
||||
return this.data.enableAard[env];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether keyboard interactions are enabled in current environment
|
||||
* @param isTheater
|
||||
* @param isFullscreen
|
||||
* @returns
|
||||
*/
|
||||
isKeyboardEnabledForEnvironment(isTheater: boolean, isFullscreen: boolean) {
|
||||
const env = this._getEnvironment(isTheater, isFullscreen);
|
||||
return this.data.enableKeyboard[env];
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region set shit
|
||||
/**
|
||||
* Sets option value.
|
||||
* @param optionPath path to value in object notation (dot separated)
|
||||
@ -123,6 +216,9 @@ export class SiteSettings {
|
||||
let iterator = this.settings.active.sites[this.site];
|
||||
let i;
|
||||
for (i = 0; i < pathParts.length - 1; i++) {
|
||||
if (!iterator[pathParts[i]]) { // some optional paths may still be undefined, even after cloning empty object
|
||||
iterator[pathParts[i]] = {};
|
||||
}
|
||||
iterator = iterator[pathParts[i]];
|
||||
}
|
||||
iterator[pathParts[i]] = optionValue;
|
||||
@ -168,25 +264,6 @@ export class SiteSettings {
|
||||
sessionStorage.setItem('uw-session-defaults', JSON.stringify(this.sessionData));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets default crop mode for extension, while taking persistence settings into account
|
||||
*/
|
||||
getDefaultOption(option: 'crop' | 'stretch' | 'alignment') {
|
||||
const persistenceLevel = this.data.persistOption[option];
|
||||
|
||||
switch (persistenceLevel) {
|
||||
case CropModePersistence.UntilPageReload:
|
||||
return this.temporaryData.defaults[option];
|
||||
case CropModePersistence.CurrentSession:
|
||||
return this.sessionData.defaults[option];
|
||||
case CropModePersistence.Disabled:
|
||||
case CropModePersistence.Default:
|
||||
case CropModePersistence.Forever:
|
||||
default:
|
||||
return this.data.defaults[option];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates options while accounting for persistence settings
|
||||
* @param option
|
||||
@ -209,5 +286,6 @@ export class SiteSettings {
|
||||
return;
|
||||
}
|
||||
}
|
||||
//#endregion
|
||||
|
||||
}
|
||||
|
@ -61,7 +61,6 @@ class PageInfo {
|
||||
|
||||
//#region misc stuff
|
||||
lastUrl: string;
|
||||
extensionMode: ExtensionMode;
|
||||
defaultCrop: any;
|
||||
currentCrop: any;
|
||||
keyboardHandlerInitQueue: any[] = [];
|
||||
@ -70,14 +69,12 @@ class PageInfo {
|
||||
keyboardHandler: any;
|
||||
//#endregion
|
||||
|
||||
constructor(eventBus: EventBus, settings: Settings, logger: Logger, extensionMode, readOnly = false){
|
||||
constructor(eventBus: EventBus, siteSettings: SiteSettings, settings: Settings, logger: Logger, readOnly = false){
|
||||
this.logger = logger;
|
||||
this.settings = settings;
|
||||
|
||||
this.siteSettings = new SiteSettings(settings, window.location.hostname);
|
||||
this.siteSettings = siteSettings;
|
||||
|
||||
this.lastUrl = window.location.href;
|
||||
this.extensionMode = extensionMode;
|
||||
this.readOnly = readOnly;
|
||||
|
||||
this.isFullscreen = !!document.fullscreenElement;
|
||||
|
@ -10,6 +10,7 @@ import Settings from '../Settings';
|
||||
import Logger from '../Logger';
|
||||
import EventBus from '../EventBus';
|
||||
import UI from '../uwui/UI';
|
||||
import { SiteSettings } from '../settings/SiteSettings';
|
||||
|
||||
if (process.env.CHANNEL !== 'stable'){
|
||||
console.info("Loading: PlayerData.js");
|
||||
@ -41,7 +42,7 @@ class PlayerData {
|
||||
//#region helper objects
|
||||
logger: Logger;
|
||||
videoData: VideoData;
|
||||
settings: Settings;
|
||||
siteSettings: SiteSettings;
|
||||
notificationService: PlayerNotificationUi;
|
||||
eventBus: EventBus;
|
||||
//#endregion
|
||||
@ -90,7 +91,7 @@ class PlayerData {
|
||||
*/
|
||||
get aspectRatio() {
|
||||
try {
|
||||
if (this.isFullscreen && !this.settings.getSettingsForSite()?.usePlayerArInFullscreen) {
|
||||
if (this.isFullscreen) {
|
||||
return window.innerWidth / window.innerHeight;
|
||||
}
|
||||
|
||||
@ -106,7 +107,7 @@ class PlayerData {
|
||||
this.logger = videoData.logger;
|
||||
this.videoData = videoData;
|
||||
this.video = videoData.video;
|
||||
this.settings = videoData.settings;
|
||||
this.siteSettings = videoData.siteSettings;
|
||||
this.eventBus = videoData.eventBus;
|
||||
this.extensionMode = videoData.extensionMode;
|
||||
this.invalid = false;
|
||||
@ -122,7 +123,7 @@ class PlayerData {
|
||||
|
||||
this.periodicallyRefreshPlayerElement = false;
|
||||
try {
|
||||
this.periodicallyRefreshPlayerElement = this.settings.active.sites[window.location.hostname].DOM.player.periodicallyRefreshPlayerElement;
|
||||
this.periodicallyRefreshPlayerElement = this.siteSettings.data.currentDOMConfig.periodicallyRefreshPlayerElement;
|
||||
} catch (e) {
|
||||
// no biggie — that means we don't have any special settings for this site.
|
||||
}
|
||||
@ -225,30 +226,28 @@ class PlayerData {
|
||||
private handleSizeConstraints(currentPlayerDimensions: PlayerDimensions) {
|
||||
|
||||
// never disable ultrawidify in full screen
|
||||
if (this.isFullscreen) {
|
||||
this.enable();
|
||||
return;
|
||||
}
|
||||
|
||||
const restrictions = this.settings.getSettingsForSite()?.restrictions ?? this.settings.active?.restrictions;
|
||||
// if (this.isFullscreen) {
|
||||
// this.enable();
|
||||
// return;
|
||||
// }
|
||||
|
||||
// if 'disable on small players' option is not enabled, the extension will run in any case
|
||||
if (!restrictions?.disableOnSmallPlayers) {
|
||||
this.enable();
|
||||
return;
|
||||
}
|
||||
// if (!restrictions?.disableOnSmallPlayers) {
|
||||
// this.enable();
|
||||
// return;
|
||||
// }
|
||||
|
||||
// If we only allow ultrawidify in full screen, we disable it when not in full screen
|
||||
if (restrictions.onlyAllowInFullscreen && !currentPlayerDimensions.fullscreen) {
|
||||
this.disable();
|
||||
return;
|
||||
}
|
||||
// if (restrictions.onlyAllowInFullscreen && !currentPlayerDimensions.fullscreen) {
|
||||
// this.disable();
|
||||
// return;
|
||||
// }
|
||||
|
||||
// if current width or height are smaller than the minimum, the extension will not run
|
||||
if (restrictions.minAllowedHeight > currentPlayerDimensions?.height || restrictions.minAllowedWidth > currentPlayerDimensions?.width) {
|
||||
this.disable();
|
||||
return;
|
||||
}
|
||||
// if (restrictions.minAllowedHeight > currentPlayerDimensions?.height || restrictions.minAllowedWidth > currentPlayerDimensions?.width) {
|
||||
// this.disable();
|
||||
// return;
|
||||
// }
|
||||
|
||||
// in this case, the player is big enough to warrant enabling Ultrawidify
|
||||
this.enable();
|
||||
@ -483,26 +482,20 @@ class PlayerData {
|
||||
}
|
||||
this.elementStack = elementStack;
|
||||
|
||||
if (this.settings.active.sites[host]?.DOM?.player?.manual) {
|
||||
if (this.settings.active.sites[host]?.DOM?.player?.useRelativeAncestor
|
||||
&& this.settings.active.sites[host]?.DOM?.player?.videoAncestor) {
|
||||
playerCandidate = this.getPlayerParentIndex(elementStack);
|
||||
} else if (this.settings.active.sites[host]?.DOM?.player?.querySelectors) {
|
||||
playerCandidate = this.getPlayerQs(elementStack, videoWidth, videoHeight);
|
||||
const playerQs = this.siteSettings.getCustomDOMQuerySelector('player');
|
||||
const playerIndex = this.siteSettings.getPlayerIndex();
|
||||
|
||||
if (playerQs) {
|
||||
playerCandidate = this.getPlayerQs(playerQs, elementStack, videoWidth, videoHeight);
|
||||
} else if (playerIndex) { // btw 0 is not a valid index for player
|
||||
playerCandidate = elementStack[playerIndex];
|
||||
}
|
||||
|
||||
// if 'verbose' option is passed, we also populate the elementStack
|
||||
// with heuristics data for auto player detection.
|
||||
if (playerCandidate && !options?.verbose) {
|
||||
return playerCandidate.element;
|
||||
}
|
||||
}
|
||||
|
||||
if (options?.verbose && playerCandidate) {
|
||||
// remember — we're only populating elementStack. If we found a player
|
||||
// element using manual methods, we will still return that element.
|
||||
if (playerCandidate) {
|
||||
if (options?.verbose) {
|
||||
this.getPlayerAuto(elementStack, videoWidth, videoHeight);
|
||||
playerCandidate.heuristics['activePlayer'] = true;
|
||||
}
|
||||
return playerCandidate.element;
|
||||
} else {
|
||||
const playerCandidate = this.getPlayerAuto(elementStack, videoWidth, videoHeight);
|
||||
@ -511,6 +504,13 @@ class PlayerData {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets player based on some assumptions, without us defining shit.
|
||||
* @param elementStack
|
||||
* @param videoWidth
|
||||
* @param videoHeight
|
||||
* @returns
|
||||
*/
|
||||
private getPlayerAuto(elementStack: any[], videoWidth, videoHeight) {
|
||||
let penaltyMultiplier = 1;
|
||||
const sizePenaltyMultiplier = 0.1;
|
||||
@ -592,12 +592,29 @@ class PlayerData {
|
||||
return bestCandidate;
|
||||
}
|
||||
|
||||
private getPlayerQs(elementStack: any[], videoWidth, videoHeight) {
|
||||
const host = window.location.hostname;
|
||||
/**
|
||||
* Gets player element based on a query string.
|
||||
*
|
||||
* Since query string does not necessarily uniquely identify an element, this function also
|
||||
* tries to evaluate which candidate of element that match the query selector is the most
|
||||
* likely the one element we're looking for.
|
||||
*
|
||||
* Function prefers elements that are:
|
||||
* 1. closer to the video
|
||||
* 2. about the same size as the video
|
||||
* 3. they must appear between video and root of the DOM hierarchy
|
||||
*
|
||||
* @param queryString query string for player element
|
||||
* @param elementStack branch of DOM hierarchy that ends with a video
|
||||
* @param videoWidth width of the video
|
||||
* @param videoHeight height of the video
|
||||
* @returns best candidate or null, if nothing in elementStack matches our query selector
|
||||
*/
|
||||
private getPlayerQs(queryString: string, elementStack: any[], videoWidth, videoHeight) {
|
||||
const perLevelScorePenalty = 10;
|
||||
let penaltyMultiplier = 0;
|
||||
|
||||
const allSelectors = document.querySelectorAll(this.settings.active.sites[host].DOM.player.querySelectors);
|
||||
const allSelectors = document.querySelectorAll(queryString);
|
||||
|
||||
for (const element of elementStack) {
|
||||
if (this.collectionHas(allSelectors, element.element)) {
|
||||
@ -634,17 +651,12 @@ class PlayerData {
|
||||
return bestCandidate;
|
||||
}
|
||||
|
||||
private getPlayerParentIndex(elementStack: any[]) {
|
||||
const host = window.location.hostname;
|
||||
elementStack[this.settings.active.sites[host].DOM.player.videoAncestor].heuristics['manualElementByParentIndex'] = true;
|
||||
return elementStack[this.settings.active.sites[host].DOM.player.videoAncestor];
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists elements between video and DOM root for display in player selector (UI)
|
||||
*/
|
||||
private handlePlayerTreeRequest() {
|
||||
// this populates this.elementStack fully
|
||||
this.getPlayer({verbose: true});
|
||||
|
||||
console.info('player-tree: emitting stack:', this.elementStack);
|
||||
this.eventBus.send('uw-config-broadcast', {type: 'player-tree', config: JSON.parse(JSON.stringify(this.elementStack))});
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ import { sleep } from '../../../common/js/utils';
|
||||
import { hasDrm } from '../ar-detect/DrmDetecor';
|
||||
import EventBus from '../EventBus';
|
||||
import { SiteSettings } from '../settings/SiteSettings';
|
||||
import { Ar } from '../../../common/interfaces/ArInterface';
|
||||
|
||||
/**
|
||||
* VideoData — handles CSS for the video element.
|
||||
@ -226,7 +227,7 @@ class VideoData {
|
||||
// after we receive a "please crop" or "please stretch".
|
||||
|
||||
// Time to apply any crop from address of crop mode persistence
|
||||
const defaultCrop = this.siteSettings.getDefaultOption('crop');
|
||||
const defaultCrop = this.siteSettings.getDefaultOption('crop') as Ar;
|
||||
const defaultStretch = this.siteSettings.getDefaultOption('stretch');
|
||||
|
||||
this.resizer.setAr(defaultCrop);
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { SiteSettings } from './../settings/SiteSettings';
|
||||
import Debug from '../../conf/Debug';
|
||||
import Scaler, { CropStrategy, VideoDimensions } from './Scaler';
|
||||
import Stretcher from './Stretcher';
|
||||
@ -10,9 +11,12 @@ import AspectRatioType from '../../../common/enums/AspectRatioType.enum';
|
||||
import CropModePersistance from '../../../common/enums/CropModePersistence.enum';
|
||||
import { sleep } from '../Util';
|
||||
import Logger from '../Logger';
|
||||
import Settings from '../Settings';
|
||||
import siteSettings from '../Settings';
|
||||
import VideoData from '../video-data/VideoData';
|
||||
import EventBus from '../EventBus';
|
||||
import { _cp } from '../../../common/js/utils';
|
||||
import Settings from '../Settings';
|
||||
import { Ar } from '../../../common/interfaces/ArInterface';
|
||||
|
||||
if(Debug.debug) {
|
||||
console.log("Loading: Resizer.js");
|
||||
@ -28,6 +32,7 @@ class Resizer {
|
||||
//#region helper objects
|
||||
logger: Logger;
|
||||
settings: Settings;
|
||||
siteSettings: SiteSettings;
|
||||
scaler: Scaler;
|
||||
stretcher: Stretcher;
|
||||
zoom: Zoom;
|
||||
@ -47,8 +52,8 @@ class Resizer {
|
||||
currentCssValidFor: any;
|
||||
currentVideoSettings: any;
|
||||
|
||||
_lastAr: {type: any, ratio?: number} = {type: AspectRatioType.Initial};
|
||||
set lastAr(x: {type: any, ratio?: number}) {
|
||||
_lastAr: Ar = {type: AspectRatioType.Initial};
|
||||
set lastAr(x: Ar) {
|
||||
this._lastAr = x;
|
||||
// emit updates for UI when setting lastAr
|
||||
this.eventBus.send('uw-config-broadcast', {type: 'ar', config: x})
|
||||
@ -101,6 +106,7 @@ class Resizer {
|
||||
this.logger = videoData.logger;
|
||||
this.video = videoData.video;
|
||||
this.settings = videoData.settings;
|
||||
this.siteSettings = videoData.siteSettings;
|
||||
this.eventBus = videoData.eventBus;
|
||||
this.initEventBus();
|
||||
|
||||
@ -108,18 +114,15 @@ class Resizer {
|
||||
this.stretcher = new Stretcher(this.conf);
|
||||
this.zoom = new Zoom(this.conf);
|
||||
|
||||
this.videoAlignment = {
|
||||
x: this.settings.getDefaultVideoAlignment(window.location.hostname),
|
||||
y: VideoAlignmentType.Center
|
||||
}; // this is initial video alignment
|
||||
this.videoAlignment = this.siteSettings.getDefaultOption('alignment') as {x: VideoAlignmentType, y: VideoAlignmentType} // this is initial video alignment
|
||||
|
||||
this.destroyed = false;
|
||||
|
||||
if (this.settings.active.pan) {
|
||||
this.canPan = this.settings.active.miscSettings.mousePan.enabled;
|
||||
} else {
|
||||
this.canPan = false;
|
||||
}
|
||||
// if (this.siteSettings.active.pan) {
|
||||
// this.canPan = this.siteSettings.active.miscSettings.mousePan.enabled;
|
||||
// } else {
|
||||
// this.canPan = false;
|
||||
// }
|
||||
|
||||
this.userCssClassName = videoData.userCssClassName;
|
||||
}
|
||||
@ -215,7 +218,7 @@ class Resizer {
|
||||
}
|
||||
}
|
||||
|
||||
async setAr(ar: {type: any, ratio?: number}, lastAr?: {type: any, ratio?: number}) {
|
||||
async setAr(ar: Ar, lastAr?: Ar) {
|
||||
if (this.destroyed) {
|
||||
return;
|
||||
}
|
||||
@ -253,7 +256,6 @@ class Resizer {
|
||||
return;
|
||||
}
|
||||
|
||||
const siteSettings = this.settings.active.sites[window.location.hostname];
|
||||
let stretchFactors: {xFactor: number, yFactor: number, arCorrectionFactor?: number, ratio?: number} | any;
|
||||
|
||||
// reset zoom, but only on aspect ratio switch. We also know that aspect ratio gets converted to
|
||||
@ -271,8 +273,7 @@ class Resizer {
|
||||
// this means here's the optimal place to set or forget aspect ratio. Saving of current crop ratio
|
||||
// is handled in pageInfo.updateCurrentCrop(), which also makes sure to persist aspect ratio if ar
|
||||
// is set to persist between videos / through current session / until manual reset.
|
||||
if (ar.type === AspectRatioType.Automatic ||
|
||||
ar.type === AspectRatioType.Reset ||
|
||||
if (ar.type === AspectRatioType.Reset ||
|
||||
ar.type === AspectRatioType.Initial ) {
|
||||
// reset/undo default
|
||||
this.conf.pageInfo.updateCurrentCrop(undefined);
|
||||
@ -391,13 +392,6 @@ class Resizer {
|
||||
this.lastAr = {type: AspectRatioType.Initial};
|
||||
}
|
||||
|
||||
setLastAr(override){
|
||||
this.lastAr = override;
|
||||
}
|
||||
|
||||
getLastAr(){
|
||||
return this.lastAr;
|
||||
}
|
||||
|
||||
setStretchMode(stretchMode, fixedStretchRatio?){
|
||||
this.stretcher.setStretchMode(stretchMode, fixedStretchRatio);
|
||||
@ -481,7 +475,7 @@ class Resizer {
|
||||
}
|
||||
|
||||
reset(){
|
||||
this.setStretchMode(this.settings.active.sites[window.location.hostname]?.stretch ?? this.settings.active.sites['@global'].stretch);
|
||||
this.setStretchMode(this.siteSettings.getDefaultOption('stretch'));
|
||||
this.zoom.setZoom(1);
|
||||
this.resetPan();
|
||||
this.setAr({type: AspectRatioType.Reset});
|
||||
@ -647,7 +641,7 @@ class Resizer {
|
||||
|
||||
private _computeOffsetsRecursionGuard: boolean = false;
|
||||
computeOffsets(stretchFactors: VideoDimensions){
|
||||
this.logger.log('info', 'debug', "[Resizer::computeOffsets] <rid:"+this.resizerId+"> video will be aligned to ", this.settings.active.sites['@global'].videoAlignment);
|
||||
this.logger.log('info', 'debug', "[Resizer::computeOffsets] <rid:"+this.resizerId+"> video will be aligned to ", this.videoAlignment);
|
||||
|
||||
const {realVideoWidth, realVideoHeight, marginX, marginY} = this.computeVideoDisplayedDimensions();
|
||||
|
||||
@ -831,7 +825,7 @@ class Resizer {
|
||||
|
||||
let extraStyleString;
|
||||
try {
|
||||
extraStyleString = this.settings.active.sites[window.location.hostname].DOM.video.additionalCss;
|
||||
extraStyleString = this.siteSettings.data.currentDOMConfig.customCss;
|
||||
} catch (e) {
|
||||
// do nothing. It's ok if no special settings are defined for this site, we'll just do defaults
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { SiteSettings } from './../settings/SiteSettings';
|
||||
import StretchType from '../../../common/enums/StretchType.enum';
|
||||
import BrowserDetect from '../../conf/BrowserDetect';
|
||||
import AspectRatioType from '../../../common/enums/AspectRatioType.enum';
|
||||
@ -19,6 +20,7 @@ class Stretcher {
|
||||
conf: VideoData;
|
||||
logger: Logger;
|
||||
settings: Settings;
|
||||
siteSettings: SiteSettings;
|
||||
//#endregion
|
||||
|
||||
//#region misc data
|
||||
@ -30,14 +32,15 @@ class Stretcher {
|
||||
constructor(videoData) {
|
||||
this.conf = videoData;
|
||||
this.logger = videoData.logger;
|
||||
this.siteSettings = videoData.siteSettings;
|
||||
this.settings = videoData.settings;
|
||||
this.mode = this.settings.getDefaultStretchMode_legacy(window.location.hostname);
|
||||
this.mode = this.siteSettings.data.defaults.stretch;
|
||||
this.fixedStretchRatio = undefined;
|
||||
}
|
||||
|
||||
setStretchMode(stretchMode, fixedStretchRatio?) {
|
||||
if (stretchMode === StretchType.Default) {
|
||||
this.mode = this.settings.getDefaultStretchMode_legacy(window.location.hostname);
|
||||
this.mode = this.siteSettings.data.defaults.stretch;
|
||||
} else {
|
||||
if (stretchMode === StretchType.Fixed || stretchMode == StretchType.FixedSource) {
|
||||
this.fixedStretchRatio = fixedStretchRatio;
|
||||
|
@ -72,7 +72,6 @@ export default {
|
||||
performance: {},
|
||||
site: null,
|
||||
currentZoom: 1,
|
||||
execAction: new ExecAction(),
|
||||
settings: {},
|
||||
settingsInitialized: false,
|
||||
logger: {},
|
||||
|
@ -73,7 +73,6 @@ export default {
|
||||
performance: {},
|
||||
site: null,
|
||||
currentZoom: 1,
|
||||
execAction: new ExecAction(),
|
||||
settings: {},
|
||||
settingsInitialized: false,
|
||||
logger: {},
|
||||
|
@ -1,152 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="label">
|
||||
Enable this extension:
|
||||
</div>
|
||||
<div class="flex flex-row button-box">
|
||||
<Button label="Always"
|
||||
:selected="settings.active.sites['@global'].mode === ExtensionMode.Enabled"
|
||||
@click.native="setDefaultExtensionMode(ExtensionMode.Enabled)"
|
||||
>
|
||||
</Button>
|
||||
<Button label="On whitelisted sites"
|
||||
:selected="settings.active.sites['@global'].mode === ExtensionMode.Whitelist"
|
||||
@click.native="setDefaultExtensionMode(ExtensionMode.Whitelist)"
|
||||
>
|
||||
</Button>
|
||||
<Button label="Never"
|
||||
:selected="settings.active.sites['@global'].mode === ExtensionMode.Disabled"
|
||||
@click.native="setDefaultExtensionMode(ExtensionMode.Disabled)"
|
||||
>
|
||||
</Button>
|
||||
</div>
|
||||
<div class="description">
|
||||
<b>Always</b> enables this extension on every site you visit that you didn't blacklist.<br/>
|
||||
<b>On whitelisted sites</b> enables this extension only on sites you explicitly whitelisted.<br/>
|
||||
<b>Never</b> disables extension on all sites, even on those you whitelisted.
|
||||
</div>
|
||||
|
||||
<div class="label">
|
||||
Enable autodetection:
|
||||
</div>
|
||||
<div class="flex flex-row button-box">
|
||||
<Button label="Always"
|
||||
:selected="settings.active.sites['@global'].autoar === ExtensionMode.Enabled"
|
||||
@click.native="setDefaultAutodetectionMode(ExtensionMode.Enabled)">
|
||||
</Button>
|
||||
<Button label="On whitelisted sites"
|
||||
:selected="settings.active.sites['@global'].autoar === ExtensionMode.Whitelist"
|
||||
@click.native="setDefaultAutodetectionMode(ExtensionMode.Whitelist)">
|
||||
</Button>
|
||||
<Button label="Never"
|
||||
:selected="settings.active.sites['@global'].autoar === ExtensionMode.Disabled"
|
||||
@click.native="setDefaultAutodetectionMode(ExtensionMode.Disabled)">
|
||||
</Button>
|
||||
</div>
|
||||
<div class="description">
|
||||
<b>Always</b> enables autodetection on every site this extension is enabled for, unless blacklisted.<br/>
|
||||
<b>On whitelisted sites</b> enables autodetection only for sites that you explicitly enabled.<br/>
|
||||
<b>Never</b> disables autodetection on all sites, even on those you whitelisted.<br/>
|
||||
<!-- <br/> -->
|
||||
<!-- For more settings related to autodetection, please check the 'Autodetection' tab. -->
|
||||
</div>
|
||||
|
||||
|
||||
<div class="label">
|
||||
Default video alignment:
|
||||
</div>
|
||||
<div class="flex flex-row button-box">
|
||||
<Button label="Left"
|
||||
:selected="settings.active.sites['@global'].videoAlignment === VideoAlignmentType.Left"
|
||||
@click.native="setDefaultvideoAlignment(VideoAlignmentType.Left)">
|
||||
</Button>
|
||||
<Button label="Center"
|
||||
:selected="settings.active.sites['@global'].videoAlignment === VideoAlignmentType.Center"
|
||||
@click.native="setDefaultvideoAlignment(VideoAlignmentType.Center)">
|
||||
</Button>
|
||||
<Button label="Right"
|
||||
:selected="settings.active.sites['@global'].videoAlignment === VideoAlignmentType.Right"
|
||||
@click.native="setDefaultvideoAlignment(VideoAlignmentType.Right)">
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div class="label">
|
||||
Default stretch mode:
|
||||
</div>
|
||||
<div class="flex flex-row button-box">
|
||||
<Button label="Don't stretch"
|
||||
:selected="settings.active.sites['@global'].stretch === StretchType.NoStretch"
|
||||
@click.native="setDefaultStretchingMode(StretchType.NoStretch)">
|
||||
</Button>
|
||||
<Button label="Basic stretch"
|
||||
:selected="settings.active.sites['@global'].stretch === StretchType.Basic"
|
||||
@click.native="setDefaultStretchingMode(StretchType.Basic)">
|
||||
</Button>
|
||||
<Button label="Hybrid stretch"
|
||||
:selected="settings.active.sites['@global'].stretch === StretchType.Hybrid"
|
||||
@click.native="setDefaultStretchingMode(StretchType.Hybrid)">
|
||||
</Button>
|
||||
<Button label="Thin borders only"
|
||||
:selected="settings.active.sites['@global'].stretch === StretchType.Conditional"
|
||||
@click.native="setDefaultStretchingMode(StretchType.Conditional)"
|
||||
>
|
||||
</Button>
|
||||
</div>
|
||||
<div class="description">
|
||||
<b>None:</b> do not stretch the video at all. This is the default option, for men of culture.<br/>
|
||||
<b>Basic:</b> stretches video to fit the player or screen unconditionally. If video has letterbox encoded, this option <i>will not</i> try to remove letterbox before stretching. You probably shouldn't be using this option.<br/>
|
||||
<b>Hybrid:</b> stretches the video to fit the player, but only if cropping didn't completely remove the black bars.<br/>
|
||||
<b>Thin borders:</b> stretches only if the width of black borders after cropping is thin.
|
||||
<br/>
|
||||
Threshold for thin borders can be defined below.
|
||||
</div>
|
||||
<div class="indent">
|
||||
<div class="flex flex-row row-padding">
|
||||
<div class="flex label-secondary">
|
||||
Thin border threshold:
|
||||
</div>
|
||||
<div class="flex flex-input">
|
||||
<input type="number"
|
||||
step="any"
|
||||
:value="settings.active.stretch.conditionalDifferencePercent"
|
||||
@input="updateStretchThreshold($event.target.value)"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="label">
|
||||
Import, export, reset settings
|
||||
</div>
|
||||
<div class="flex flex-column">
|
||||
<div v-if="downloadPermissionError"
|
||||
class="w100 center-text warning-lite"
|
||||
>
|
||||
Exporting settings requires the 'downloads' permission. (If you want to export settings without granting 'downloads' permission, you can copy-paste settings from 'Super advanced settings' tab)
|
||||
</div>
|
||||
<div v-if="corruptedSettingsError"
|
||||
class="w100 center-text warning-lite"
|
||||
>
|
||||
Settings import failed. The settings file is probably corrupted.
|
||||
</div>
|
||||
<div class="flex flex-row button-box">
|
||||
<div class="button center-text flex flex-auto">
|
||||
<label for="file-upload" class="w100 h100 block">
|
||||
Import settings
|
||||
</label>
|
||||
<input id="file-upload"
|
||||
type="file"
|
||||
@input="importSettings"
|
||||
/>
|
||||
</div>
|
||||
<Button label="Export settings"
|
||||
@click.native="exportSettings()"
|
||||
/>
|
||||
<Button label="Reset settings"
|
||||
@click.native="resetSettings()"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
this component is deprecated.
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -166,110 +20,13 @@ export default {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
StretchType: StretchType,
|
||||
ExtensionMode: ExtensionMode,
|
||||
VideoAlignmentType: VideoAlignmentType,
|
||||
stretchThreshold: 0,
|
||||
corruptedSettingsError: false,
|
||||
downloadPermissionError: false,
|
||||
|
||||
}
|
||||
},
|
||||
created () {
|
||||
},
|
||||
methods: {
|
||||
setDefaultAutodetectionMode(mode) {
|
||||
this.settings.active.sites['@global'].autoar = mode;
|
||||
this.settings.save();
|
||||
},
|
||||
setDefaultExtensionMode(mode) {
|
||||
this.settings.active.sites['@global'].mode = mode;
|
||||
this.settings.save();
|
||||
|
||||
},
|
||||
setDefaultvideoAlignment(mode) {
|
||||
this.settings.active.sites['@global'].videoAlignment = mode;
|
||||
this.settings.save();
|
||||
},
|
||||
setDefaultStretchingMode(mode) {
|
||||
this.settings.active.sites['@global'].stretch = mode;
|
||||
this.settings.save();
|
||||
},
|
||||
updateStretchThreshold(newThreshold) {
|
||||
if (!newThreshold || isNaN(newThreshold)) {
|
||||
return;
|
||||
}
|
||||
this.settings.active.stretch.conditionalDifferencePercent = newThreshold;
|
||||
this.settings.save();
|
||||
},
|
||||
resetSettings() {
|
||||
this.settings.active = JSON.parse(JSON.stringify(this.settings.default));
|
||||
this.settings.save();
|
||||
},
|
||||
async exportSettings() {
|
||||
this.downloadPermissionError = false;
|
||||
|
||||
const blob = new Blob([JSON.stringify(this.settings.active)], {type: 'application/json'});
|
||||
const fileUrl = URL.createObjectURL(blob);
|
||||
|
||||
try {
|
||||
if (BrowserDetect.firefox) {
|
||||
// reminder — webextension-polyfill doesn't seem to work in vue!
|
||||
await browser.permissions.request({permissions: ['downloads']});
|
||||
browser.downloads.download({saveAs: true, filename: 'ultrawidify-settings.json', url: fileUrl});
|
||||
} else if (BrowserDetect.anyChromium) {
|
||||
const ths = this;
|
||||
|
||||
chrome.permissions.request(
|
||||
{permissions: ['downloads']},
|
||||
(granted) => {
|
||||
if (granted) {
|
||||
ths.exportSettingsChrome(fileUrl);
|
||||
} else {
|
||||
ths.downloadPermissionError = true
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
} catch (e) {
|
||||
this.downloadPermissionError = true;
|
||||
}
|
||||
},
|
||||
exportSettingsChrome(fileUrl){
|
||||
chrome.downloads.download({saveAs: true, filename: 'ultrawidify-settings.json', url: fileUrl});
|
||||
},
|
||||
async importSettings($event) {
|
||||
let file, text, settingsObj;
|
||||
this.corruptedSettingsError = false;
|
||||
|
||||
try {
|
||||
file = $event.target.files[0];
|
||||
} catch (e) {
|
||||
console.error("error grabbing a file!");
|
||||
this.corruptedSettingsError = true;
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
text = await file.text();
|
||||
settingsObj = JSON.parse(text);
|
||||
} catch (e) {
|
||||
console.error("error parsing file to json");
|
||||
this.corruptedSettingsError = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// validate settings
|
||||
for (const key in this.settings.default) {
|
||||
if (!settingsObj[key]) {
|
||||
console.error("corrupted settings!")
|
||||
this.corruptedSettingsError = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.settings.active = settingsObj;
|
||||
this.settings.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -67,7 +67,6 @@
|
||||
import ZoomOptionsPanel from '../../csui/src/PlayerUiPanels/PanelComponents/VideoSettings/ZoomOptionsPanel.vue'
|
||||
import StretchOptionsPanel from '../../csui/src/PlayerUiPanels/PanelComponents/VideoSettings/StretchOptionsPanel.vue'
|
||||
import CropOptionsPanel from '../../csui/src/PlayerUiPanels/PanelComponents/VideoSettings/CropOptionsPanel.vue'
|
||||
import ExecAction from '../../csui/src/ui-libs/ExecAction';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
@ -88,7 +87,6 @@ export default {
|
||||
CropOptionsPanel, StretchOptionsPanel, ZoomOptionsPanel
|
||||
},
|
||||
created() {
|
||||
this.exec = new ExecAction(this.settings, window.location.hostname);
|
||||
this.eventBus.subscribe('uw-config-broadcast', {function: (config) => this.handleConfigBroadcast(config)});
|
||||
},
|
||||
mounted() {
|
||||
|
@ -250,23 +250,23 @@ export default {
|
||||
},
|
||||
props: {
|
||||
site: String,
|
||||
settings: Object,
|
||||
siteSettings: Object,
|
||||
},
|
||||
created() {
|
||||
try {
|
||||
this.videoManualQs = this.settings.active.sites[this.site]?.DOM?.video?.manual ?? this.videoManualQs;
|
||||
this.videoQs = this.settings.active.sites[this.site]?.DOM?.video?.querySelectors;
|
||||
this.videoCss = this.settings.active.sites[this.site]?.DOM?.video?.additionalCss;
|
||||
this.videoManualQs = this.siteSettings.data.currentDOMConfig?.elements?.video?.manual ?? this.videoManualQs;
|
||||
this.videoQs = this.siteSettings.data.currentDOMConfig?.elements?.video?.querySelectors;
|
||||
this.videoCss = this.siteSettings.data.currentDOMConfig?.elements?.video?.nodeCss;
|
||||
} catch (e) {
|
||||
// that's here just in case relevant settings for this site don't exist yet
|
||||
}
|
||||
|
||||
try {
|
||||
this.playerManualQs = this.settings.active.sites[this.site]?.DOM?.player?.manual ?? this.playerManualQs;
|
||||
this.playerQs = this.settings.active.sites[this.site]?.DOM?.player?.querySelectors;
|
||||
this.playerByNodeIndex = this.settings.active.sites[this.site]?.DOM?.player?.useRelativeAncestor ?? this.playerByNodeIndex;
|
||||
this.playerParentNodeIndex = this.settings.active.sites[this.site]?.DOM?.player?.videoAncestor;
|
||||
this.usePlayerAr = this.settings.active.sites[this.site]?.usePlayerArInFullscreen;
|
||||
this.playerManualQs = this.siteSettings.data.currentDOMConfig?.elements?.player?.manual ?? this.playerManualQs;
|
||||
this.playerQs = this.siteSettings.data.currentDOMConfig?.elements?.player?.querySelectors;
|
||||
this.playerByNodeIndex = !this.siteSettings.data.currentDOMConfig?.elements?.player?.querySelectors || this.playerByNodeIndex;
|
||||
this.playerParentNodeIndex = this.siteSettings.data.currentDOMConfig?.elements?.player?.index;
|
||||
// this.usePlayerAr = this.settings.active.sites[this.site]?.usePlayerArInFullscreen;
|
||||
} catch (e) {
|
||||
// that's here just in case relevant settings for this site don't exist yet
|
||||
}
|
||||
@ -295,32 +295,8 @@ export default {
|
||||
|
||||
observer.observe(saveButtonBait);
|
||||
},
|
||||
ensureSettings(scope) {
|
||||
if (! this.settings.active.sites[this.site]) {
|
||||
this.settings.active.sites[this.site] = {
|
||||
mode: ExtensionMode.Default,
|
||||
autoar: ExtensionMode.Default,
|
||||
type: 'user-added',
|
||||
stretch: StretchType.Default,
|
||||
videoAlignment: VideoAlignmentType.Default,
|
||||
keyboardShortcutsEnabled: ExtensionMode.Default,
|
||||
}
|
||||
}
|
||||
if (! this.settings.active.sites[this.site].DOM) {
|
||||
this.settings.active.sites[this.site].DOM = {};
|
||||
}
|
||||
if (! this.settings.active.sites[this.site].DOM[scope]) {
|
||||
this.settings.active.sites[this.site].DOM[scope] = {
|
||||
manual: false,
|
||||
querySelectors: '',
|
||||
additionalCss: '',
|
||||
useRelativeAncestor: scope === 'player' ? false : undefined,
|
||||
videoAncestor: undefined,
|
||||
playerNodeCss: scope === 'player' ? '' : undefined,
|
||||
}
|
||||
}
|
||||
},
|
||||
updateVideoQuerySelector() {
|
||||
this.siteSettings.set('currentDOMConfig')
|
||||
this.ensureSettings('video');
|
||||
this.settings.active.sites[this.site].DOM.video.querySelectors = this.videoQs;
|
||||
this.settings.save();
|
||||
|
Loading…
Reference in New Issue
Block a user