migrate settings to new and simplified SiteSettings

This commit is contained in:
Tamius Han 2023-01-07 03:06:37 +01:00
parent d0ba619b45
commit a58edad8ea
7 changed files with 330 additions and 284 deletions

View File

@ -1,3 +1,12 @@
export async function sleep(timeout) {
return new Promise<void>( (resolve, reject) => setTimeout(() => resolve(), timeout));
}
/**
* Creates deep copy of an object
* @param obj
* @returns
*/
export function _cp(obj) {
return JSON.parse(JSON.stringify(obj));
}

View File

@ -1,189 +0,0 @@
class PlayerPickerHelper {
constructor (settings, callbacks) {
this.settings = settings;
this.videos = document.selectElementsByTagName('video');
this.selectedParentIndex = this.findPlayerForVideos(settings, this.videos)[0];
this.savedCss = [];
this.markVideos();
this.markIndexForAll(index);
this.markInitialQuerySelectors();
}
/*
*
* Internal functions
*
*/
saveBorder(element) {
if (this.savedCss.findIndex(x => x.element === element) !== -1) {
this.savedCss.push({element: element, border: element.style.border});
}
}
restoreBorders() {
for (const e of this.savedCss) {
e.element.style.border = e.border;
}
}
findPlayerForVideos(settings, videos) {
const playerIndexes = [];
for (const v of videos) {
playerIndexes.push(this.findPlayerForVideo(settings, v));
}
return playerIndexes;
}
findPlayerForVideo(settings, video) {
const host = window.location.hostname;
let element = video.parentNode;
if (this.settings.active.sites[host]
&& this.settings.active.sites[host].DOM
&& this.settings.active.sites[host].DOM.player
&& 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) {
return this.settings.active.sites[host].DOM.player.videoAncestor;
} else if (this.settings.active.sites[host].DOM.player.querySelectors) {
const allSelectors = document.querySelectorAll(this.settings.active.sites[host].DOM.player.querySelectors);
let elementIndex = 1;
while (element && !this.collectionHas(allSelectors, element)) {
element = element.parentNode;
elementIndex++;
}
return elementIndex;
}
}
let elementIndex = 0;
var trustCandidateAfterGrows = 2; // if candidate_width or candidate_height increases in either dimensions this many
// times, we say we found our player. (This number ignores weird elements)
// in case our <video> is bigger than player in one dimension but smaller in the other
// if site is coded properly, player can't be wider than that
var candidate_width = Math.max(element.offsetWidth, window.innerWidth);
var candidate_height = Math.max(element.offsetHeight, window.innerHeight);
var playerCandidateNode = element;
// if we haven't found element using fancy methods, we resort to the good old fashioned way
var grows = trustCandidateAfterGrows;
while(element != undefined){
// odstranimo čudne elemente, ti bi pokvarili zadeve
// remove weird elements, those would break our stuff
if ( element.offsetWidth == 0 || element.offsetHeight == 0){
element = element.parentNode;
elementIndex++;
continue;
}
if ( element.offsetHeight <= candidate_height &&
element.offsetWidth <= candidate_width ){
// if we're in fullscreen, we only consider elements that are exactly as big as the monitor.
if( ! isFullScreen ||
(element.offsetWidth == window.innerWidth && element.offsetHeight == window.innerHeight) ){
playerCandidateNode = element;
candidate_width = element.offsetWidth;
candidate_height = element.offsetHeight;
grows = trustCandidateAfterGrows;
this.logger.log('info', 'debug', "Found new candidate for player. Dimensions: w:", candidate_width, "h:",candidate_height, "node:", playerCandidateNode);
}
}
else if(grows --<= 0){
this.logger.log('info', 'playerDetect', "Current element grew in comparrison to the child. We probably found the player. breaking loop, returning current result");
break;
}
element = element.parentNode;
elementIndex++;
}
return elementIndex;
}
markVideos() {
for (const v of this.videos) {
this.markVideo(v);
}
}
markVideo(video) {
this.saveBorder(video);
video.style.border = "1px solid #00f";
}
markIndexForAll(index){
for (const v of this.videos) {
this.markIndex(index, v);
}
}
markIndex(index, video) {
el = video.parentNode;
while (index --> 1) {
el = el.parentNode;
}
this.saveBorder(el);
el.style.border = "1px solid #88f";
}
markInitialQuerySelectors() {
try {
if (this.settings.active.sites[host].DOM.player.querySelectors.trim()) {
this.markQuerySelectorMatches(this.settings.active.sites[host].DOM.player.querySelectors);
}
} catch (e) {
// nothing to see here. something in that if spaghett is undefined, which causes
// everything to fail. Since this means we've got zero query string matches to mark,
// we just ignore the failure
}
}
markQuerySelectorMatches(qsString) {
const allSelectors = document.querySelectorAll(qsString);
for (e of allSelectors) {
this.saveBorder(e);
e.style.border = "1px dashed fd2";
}
}
markQsPlayerDetection(qsString, index, video) {
let element = video.parentNode;
let elementIndex = 1;
const allSelectors = document.querySelectorAll(qsString);
while (element && !this.collectionHas(allSelectors, element)) {
element = element.parentNode;
elementIndex++;
}
this.saveBorder(element)
if (elementIndex > index) {
element.style.border = "2px solid #f00"
} else if (elementIndex === index) {
element.style.border = "2px solid #027a5c"
}
}
/*
*
*
* Function that actually interface with playerpicker and do stuff
*
*
*/
setQuerySelectors(querySelectorString) {
}
}
export default PlayerPickerHelper

View File

@ -50,7 +50,7 @@ class Settings {
browser.storage.onChanged.addListener((changes, area) => {this.storageChangeListener(changes, area)});
}
storageChangeListener(changes, area) {
private storageChangeListener(changes, area) {
if (!changes.uwSettings) {
return;
}
@ -84,7 +84,7 @@ class Settings {
return Settings.getExtensionVersion();
}
compareExtensionVersions(a, b) {
private compareExtensionVersions(a, b) {
let aa = a.split('.');
let bb = b.split('.');
@ -135,7 +135,7 @@ class Settings {
}
}
getPrereleaseVersionHierarchy(version) {
private getPrereleaseVersionHierarchy(version) {
if (version.startsWith('dev')) {
return 0;
}
@ -148,15 +148,15 @@ class Settings {
return 3;
}
sortConfPatches(patchesIn) {
private sortConfPatches(patchesIn) {
return patchesIn.sort( (a, b) => this.compareExtensionVersions(a.forVersion, b.forVersion));
}
findFirstNecessaryPatch(version, extconfPatches) {
private findFirstNecessaryPatch(version, extconfPatches) {
const sorted = this.sortConfPatches(extconfPatches);
return sorted.findIndex(x => this.compareExtensionVersions(x.forVersion, version) > 0);
}
applySettingsPatches(oldVersion, patches) {
private applySettingsPatches(oldVersion, patches) {
let index = this.findFirstNecessaryPatch(oldVersion, patches);
if (index === -1) {
this.logger?.log('info','settings','[Settings::applySettingsPatches] There are no pending conf patches.');

View File

@ -0,0 +1,213 @@
import CropModePersistence from '../../../common/enums/CropModePersistence.enum';
import ExtensionMode from '../../../common/enums/ExtensionMode.enum';
import { SiteSettingsInterface } from '../../../common/interfaces/SettingsInterface';
import { _cp } from '../../../common/js/utils';
import Settings from '../Settings';
import { browser } from 'webextension-polyfill-ts';
export class SiteSettings {
private settings: Settings;
private site: string;;
data: SiteSettingsInterface;
temporaryData: SiteSettingsInterface;
sessionData: SiteSettingsInterface;
private defaultSettings: SiteSettingsInterface;
//#region lifecycle
constructor(settings: Settings, site: string) {
this.settings = settings;
this.data = settings.active.sites[site];
this.defaultSettings = settings.default.sites['@global'];
this.compileSettingsObject();
// temporary data starts as a copy of real data. This ensures defaults are correct if nothing
// modifies temporary settings. (Purpose: providing until-reload persistence option)
this.temporaryData = _cp(this.data);
this.sessionData = JSON.parse(sessionStorage.getItem('uw-session-defaults'));
if (!this.sessionData) {
this.sessionData = _cp(this.data);
sessionStorage.setItem('uw-session-defaults', JSON.stringify(this.sessionData));
}
browser.storage.onChanged.addListener((changes, area) => {this.storageChangeListener(changes, area)})
}
/**
* Merges defaultSettings into site settings where appropriate.
* Alan pls ensure default settings object follows the correct structure
*/
private compileSettingsObject() {
if (!this.data) {
this.data = _cp(this.defaultSettings);
return;
}
this.data.defaultCrop = this.data.defaultCrop ?? _cp(this.defaultSettings.defaultCrop);
this.data.defaultStretch = this.data.defaultStretch ?? _cp(this.defaultSettings.defaultStretch);
for (const enableSegment of ['enable', 'enableAard', 'enableKeyboard']) {
if (!this.data[enableSegment]) {
this.data[enableSegment] = {};
}
for (const environment of ['normal', 'theater', 'fullscreen']) {
if (!this.data[enableSegment][environment] || this.data[enableSegment][environment] === ExtensionMode.Default) {
this.data[enableSegment][environment] = _cp(this.defaultSettings[enableSegment][environment]);
}
}
}
// ensure data.persistOption exists:
if (!this.data.persistOption) {
this.data.persistOption = {} as any; // this will get populated correctly soon
}
for (const persistOption of ['crop', 'stretch', 'alignment']) {
if ( (this.data.persistOption[persistOption] ?? CropModePersistence.Default) === CropModePersistence.Default ) {
this.data.persistOption[persistOption] = this.defaultSettings.persistOption[persistOption];
}
}
if (this.data.activeDOMConfig && this.data.DOMConfig) {
this.data.currentDOMConfig = this.data.DOMConfig[this.data.activeDOMConfig];
}
}
//#endregion
//#region events
/**
* Updates setting values for current and default site
* @param changes
* @param area
* @returns
*/
private storageChangeListener(changes, area) {
if (!changes.uwSettings) {
return;
}
const parsedSettings = JSON.parse(changes.uwSettings.newValue);
this.data = parsedSettings.active.sites[this.site];
this.defaultSettings = parsedSettings.active.sites['@global'];
this.compileSettingsObject();
}
//#endregion
/**
* Gets custom query selector for player or video, if element exists, is manually defined, and has querySelectors property.
* @param element player or video
* @returns querySelector if possible, undefined otherwise
*/
getCustomDOMQuerySelector(element: 'video' | 'player'): string | undefined {
return this.data.currentDOMConfig?.elements?.[element]?.manual && this.data.currentDOMConfig?.elements?.[element]?.querySelectors || undefined;
}
/**
* Sets option value.
* @param optionPath path to value in object notation (dot separated)
* @param optionValue new value of option
* @param reload whether we should trigger a reload in components that require it
*/
async set(optionPath: string, optionValue: any, reload: boolean = false) {
// if no settings exist for this site, create an empty object
if (!this.settings.active.sites[this.site]) {
this.settings.active.sites[this.site] = _cp(this.settings.active.sites['@empty']);
}
const pathParts = optionPath.split('.');
let iterator = this.settings.active.sites[this.site];
let i;
for (i = 0; i < pathParts.length - 1; i++) {
iterator = iterator[pathParts[i]];
}
iterator[pathParts[i]] = optionValue;
if (reload) {
this.settings.save();
} else {
this.settings.saveWithoutReload();
}
}
/**
* Sets temporary option value (for Persistence.UntilReload)
* @param optionPath path to value in object notation (dot separated)
* @param optionValue new value of option
*/
setTemporary(optionPath: string, optionValue: any) {
const pathParts = optionPath.split('.');
let iterator = this.temporaryData;
let i;
for (i = 0; i < pathParts.length - 1; i++) {
iterator = iterator[pathParts[i]];
}
iterator[pathParts[i]] = optionValue;
}
/**
* Sets option value to sessionStorage (for Persistence.CurrentSession)
* @param optionPath path to value in object notation (dot separated)
* @param optionValue new value of option
*/
setSession(optionPath: string, optionValue: any) {
const pathParts = optionPath.split('.');
let iterator = this.sessionData;
let i;
for (i = 0; i < pathParts.length - 1; i++) {
iterator = iterator[pathParts[i]];
}
iterator[pathParts[i]] = optionValue;
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
* @param value
* @returns
*/
async updatePersistentOption(option: 'crop' | 'stretch' | 'alignment', value) {
const persistenceLevel = this.data.persistOption[option];
switch (persistenceLevel) {
case CropModePersistence.Disabled:
return;
case CropModePersistence.UntilPageReload:
return this.temporaryData.defaults[option] = value;
case CropModePersistence.CurrentSession:
this.sessionData.defaults[option] = value;
return sessionStorage.setItem('uw-session-defaults', JSON.stringify(this.sessionData));
case CropModePersistence.Forever:
return this.set(`defaults.${option}`, value); // async, but we don't care in this case IIRC
default:
return;
}
}
}

View File

@ -8,6 +8,7 @@ import Settings from '../Settings';
import ExtensionMode from '../../../common/enums/ExtensionMode.enum';
import CommsClient from '../comms/CommsClient';
import EventBus from '../EventBus';
import { SiteSettings } from '../settings/SiteSettings';
if (process.env.CHANNEL !== 'stable'){
console.info("Loading PageInfo");
@ -40,6 +41,7 @@ class PageInfo {
readOnly: boolean = false;
hasVideos: boolean = false;
siteDisabled: boolean = false;
isFullscreen: boolean = false;
//#endregion
//#region timers and timeouts
@ -51,6 +53,7 @@ class PageInfo {
//#region helper objects
logger: Logger;
settings: Settings;
siteSettings: SiteSettings;
comms: CommsClient;
eventBus: EventBus;
videos: {videoData: VideoData, element: HTMLVideoElement}[] = [];
@ -71,17 +74,21 @@ class PageInfo {
this.logger = logger;
this.settings = settings;
this.siteSettings = new SiteSettings(settings, window.location.hostname);
this.lastUrl = window.location.href;
this.extensionMode = extensionMode;
this.readOnly = readOnly;
this.isFullscreen = !!document.fullscreenElement;
if (eventBus){
this.eventBus = eventBus;
}
try {
// request inject css immediately
const playerStyleString = this.settings.active.sites[window.location.hostname].css.replace('\\n', '');
const playerStyleString = this.siteSettings.data.currentDOMConfig?.customCss?.replace('\\n', '');
this.eventBus.send('inject-css', {cssString: playerStyleString});
} catch (e) {
// do nothing. It's ok if there's no special settings for the player element or crop persistence
@ -91,6 +98,8 @@ class PageInfo {
this.rescan(RescanReason.PERIODIC);
this.scheduleUrlCheck();
document.addEventListener('fullscreenchange', this.fullscreenHandler);
}
destroy() {
@ -108,13 +117,40 @@ class PageInfo {
}
try {
const playerStyleString = this.settings.active.sites[window.location.hostname].css;
const playerStyleString = this.siteSettings.data.currentDOMConfig?.customCss?.replace('\\n', '');
this.eventBus.send('eject-css', {cssString: playerStyleString});
} catch (e) {
// do nothing. It's ok if there's no special settings for the player element
}
}
/**
* Handler for fullscreenchanged event.
*/
fullscreenHandler() {
this.isFullscreen = !!document.fullscreenElement;
if (this.isFullscreen) {
this.enterFullscreen();
} else {
this.exitFullscreen();
}
}
/**
* Runs when browser enters full screen.
*/
enterFullscreen() {
this.eventBus.send('page-fs-enter', {});
}
/**
* Runs when browser exits full screen
*/
exitFullscreen() {
this.eventBus.send('page-fs-exit', {});
}
reset() {
for(let video of this.videos) {
video.videoData.destroy();
@ -133,9 +169,9 @@ class PageInfo {
}
getVideos(host) {
if (this.settings.active.sites[host]?.DOM?.video?.manual
&& this.settings.active.sites[host]?.DOM?.video?.querySelectors){
const videos = document.querySelectorAll(this.settings.active.sites[host].DOM.video.querySelectors) as NodeListOf<HTMLVideoElement>;
const videoQs = this.siteSettings.getCustomDOMQuerySelector('video');
if (videoQs){
const videos = document.querySelectorAll(videoQs) as NodeListOf<HTMLVideoElement>;
if (videos.length) {
return videos;
@ -214,7 +250,7 @@ class PageInfo {
this.logger.log('info', 'videoRescan', "[PageInfo::rescan] found new video candidate:", videoElement, "NOTE:: Video initialization starts here:\n--------------------------------\n")
try {
const newVideo = new VideoData(videoElement, this.settings, this);
const newVideo = new VideoData(videoElement, this.siteSettings, this);
this.videos.push({videoData: newVideo, element: videoElement});
} catch (e) {
this.logger.log('error', 'debug', "rescan error: failed to initialize videoData. Skipping this video.",e);
@ -327,51 +363,21 @@ class PageInfo {
this.scheduleUrlCheck();
}
setArPersistence(persistenceMode) {
// name of this function is mildly misleading — we don't really _set_ ar persistence. (Ar persistence
// mode is set and saved via popup or keyboard shortcuts, if user defined them) We just save the current
// aspect ratio whenever aspect ratio persistence mode changes.
if (persistenceMode === CropModePersistence.CurrentSession) {
sessionStorage.setItem('uw-crop-mode-session-persistence', JSON.stringify(this.currentCrop));
} else if (persistenceMode === CropModePersistence.Forever) {
if (this.settings.active.sites[window.location.hostname]) {
// | key may be missing, so we do this
this.settings.active.sites[window.location.hostname]['defaultAr'] = this.currentCrop;
} else {
this.settings.active.sites[window.location.hostname] = this.settings.getDefaultOption();
this.settings.active.sites[window.location.hostname]['defaultAr'] = this.currentCrop;
}
this.settings.saveWithoutReload();
}
}
/**
* Updates current crop configuration.
*
* If crop persistence is set to; then
* disabled do nothing
* until tab reload set this.defaultCrop
* current session set current AR to session storage
* forever save settings
* @param ar
* @returns
*/
updateCurrentCrop(ar) {
this.currentCrop = ar;
// This means crop persistance is disabled. If crop persistance is enabled, then settings for current
// site MUST exist (crop persistence mode is disabled by default)
const cropModePersistence = this.settings.getDefaultCropPersistenceMode(window.location.hostname);
if (cropModePersistence === CropModePersistence.Disabled) {
return;
}
this.defaultCrop = ar;
if (cropModePersistence === CropModePersistence.CurrentSession) {
sessionStorage.setItem('uw-crop-mode-session-persistence', JSON.stringify(ar));
} else if (cropModePersistence === CropModePersistence.Forever) {
if (this.settings.active.sites[window.location.hostname]) {
// | key may be missing, so we do this
this.settings.active.sites[window.location.hostname]['defaultAr'] = ar;
} else {
this.settings.active.sites[window.location.hostname] = this.settings.getDefaultOption();
this.settings.active.sites[window.location.hostname]['defaultAr'] = ar;
}
this.settings.saveWithoutReload();
}
this.siteSettings.updatePersistentOption('crop', ar);
}
}

View File

@ -57,6 +57,8 @@ class PlayerData {
invalid: boolean = false;
private periodicallyRefreshPlayerElement: boolean = false;
halted: boolean = true;
isFullscreen: boolean = !!document.fullscreenElement;
isTheaterMode: boolean = false; // note: fullscreen mode will count as theaterMode if player was in theater mode before fs switch. This is desired, so far.
//#region misc stuff
extensionMode: any;
@ -79,7 +81,7 @@ class PlayerData {
}],
'update-player': [{
function: () => this.getPlayer()
}]
}],
}
//#endregion
@ -88,7 +90,7 @@ class PlayerData {
*/
get aspectRatio() {
try {
if (this.dimensions?.fullscreen && !this.settings.getSettingsForSite()?.usePlayerArInFullscreen) {
if (this.isFullscreen && !this.settings.getSettingsForSite()?.usePlayerArInFullscreen) {
return window.innerWidth / window.innerHeight;
}
@ -151,40 +153,47 @@ class PlayerData {
}
/**
* Returns whether we're in fullscreen mode or not.
* Detects whether player element is in theater mode or not.
* If theater mode changed, emits event.
* @returns whether player is in theater mode
*/
static isFullScreen(){
const ihdiff = Math.abs(window.screen.height - window.innerHeight);
const iwdiff = Math.abs(window.screen.width - window.innerWidth);
private detectTheaterMode() {
const oldTheaterMode = this.isTheaterMode;
const newTheaterMode = this.equalish(window.innerWidth, this.element.offsetWidth, 32);
// Chrome on linux on X on mixed PPI displays may return ever so slightly different values
// for innerHeight vs screen.height abd innerWidth vs. screen.width, probably courtesy of
// fractional scaling or something. This means we'll give ourself a few px of margin — the
// window elements visible in not-fullscreen are usually double digit px tall
return ( ihdiff < 5 && iwdiff < 5 );
this.isTheaterMode = newTheaterMode;
// theater mode changed
if (oldTheaterMode !== newTheaterMode) {
if (newTheaterMode) {
this.eventBus.send('player-theater-enter', {});
} else {
this.eventBus.send('player-theater-exit', {});
}
}
return newTheaterMode;
}
/**
*
*/
trackDimensionChanges() {
// get player dimensions _once_
let currentPlayerDimensions;
const isFullScreen = PlayerData.isFullScreen();
if (isFullScreen) {
if (this.isFullscreen) {
currentPlayerDimensions = {
width: window.innerWidth,
height: window.innerHeight,
fullscreen: true
};
} else {
currentPlayerDimensions = {
width: this.element.offsetWidth,
height: this.element.offsetHeight,
fullscreen: false,
}
height: this.element.offsetHeight
};
this.detectTheaterMode();
}
// if dimensions of the player box are the same as the last known
@ -216,7 +225,7 @@ class PlayerData {
private handleSizeConstraints(currentPlayerDimensions: PlayerDimensions) {
// never disable ultrawidify in full screen
if (currentPlayerDimensions.fullscreen) {
if (this.isFullscreen) {
this.enable();
return;
}

View File

@ -12,7 +12,15 @@ import PageInfo from './PageInfo';
import { sleep } from '../../../common/js/utils';
import { hasDrm } from '../ar-detect/DrmDetecor';
import EventBus from '../EventBus';
import { SiteSettings } from '../settings/SiteSettings';
/**
* VideoData handles CSS for the video element.
*
* To quickly disable or revert all modifications extension has made to the
* video element, you can call disable() function. Calling disable() also
* toggles autodetection off.
*/
class VideoData {
private baseCssName: string = 'uw-ultrawidify-base-wide-screen';
@ -46,7 +54,7 @@ class VideoData {
//#region helper objects
logger: Logger;
settings: Settings;
siteSettings: SiteSettings;
pageInfo: PageInfo;
player: PlayerData;
resizer: Resizer;
@ -64,12 +72,12 @@ class VideoData {
}
}
constructor(video, settings, pageInfo){
constructor(video, siteSettings: SiteSettings, pageInfo){
this.logger = pageInfo.logger;
this.arSetupComplete = false;
this.video = video;
this.destroyed = false;
this.settings = settings;
this.siteSettings = siteSettings;
this.pageInfo = pageInfo;
this.extensionMode = pageInfo.extensionMode;
this.videoStatusOk = false;
@ -96,7 +104,7 @@ class VideoData {
}});
}
this.setupStageOne();
this.setupEventListeners();
}
async onVideoLoaded() {
@ -181,10 +189,10 @@ class VideoData {
//#region lifecycle-ish
/**
* Injects base CSS and sets up handlers for <video> tag events
* Sets up event listeners for this video
*/
async setupStageOne() {
this.logger.log('info', 'init', '%c[VideoData::setupStageOne] ——————————— Starting setup stage one! ———————————', 'color: #0f9');
async setupEventListeners() {
this.logger.log('info', 'init', '%c[VideoData::setupEventListeners] ——————————— Starting event listener setup! ———————————', 'color: #0f9');
// this is in case extension loads before the video
this.video.addEventListener('loadeddata', this.onLoadedData.bind(this));
@ -193,7 +201,7 @@ class VideoData {
// this one is in case extension loads after the video is loaded
this.video.addEventListener('timeupdate', this.onTimeUpdate.bind(this));
this.logger.log('info', 'init', '%c[VideoData::setupStageOne] ——————————— Setup stage one complete! ———————————', 'color: #0f9');
this.logger.log('info', 'init', '%c[VideoData::setupEventListeners] ——————————— Event listeners setup complete! ———————————', 'color: #0f9');
}
/**
@ -218,21 +226,11 @@ 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.settings.getDefaultCrop();
const defaultStretch = this.settings.getDefaultStretchMode();
const defaultCrop = this.siteSettings.getDefaultOption('crop');
const defaultStretch = this.siteSettings.getDefaultOption('stretch');
// Crop mode persistence is intended to avoid resetting video aspect ratio to site or extension default
// when going from one video to another. As such, crop persistence takes priority over site defaults.
// This option should only trigger if we have modified the aspect ratio manually.
if (
this.settings.getDefaultCropPersistenceMode(window.location.hostname) !== CropModePersistence.Disabled
&& this.pageInfo.defaultCrop
) {
this.resizer.setAr(this.pageInfo.defaultCrop);
} else {
this.resizer.setAr(defaultCrop);
this.resizer.setStretchMode(defaultStretch);
}
this.resizer.setAr(defaultCrop);
this.resizer.setStretchMode(defaultStretch);
}
/**