diff --git a/CHANGELOG.md b/CHANGELOG.md index 3667e30..b7fd25a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,15 @@ * Settings page looks ugly af right now. Maybe fix it some time later +### v4.2.0 + +* Slightly improved popup design. (Design change suggested by PortaTrekos) +* Player detection: youtube and twitch now have manual player element detection, with strictly defined players. +* Improved site settings control in extension popup. It's possible to enable extension for previously disabled embedded sites. +* Improved incompatibilities with reddit, where videos would be vertically misaligned when not using RES +* Fixed imcompatibilities with Iridium. Flicker when clicking play/pause or switching between big and popup player is caused by either Youtube or Iridium trying to apply their styles over mine. +* Issues with inconsistent alignment that some people reported are potentially fixed + ### v4.1.2 (current) * Fixed video alignment issues on www.reddit as well (for people who use old reddit without going to old.reddit) diff --git a/src/ext/conf/ExtConfPatches.js b/src/ext/conf/ExtConfPatches.js new file mode 100644 index 0000000..a9d4701 --- /dev/null +++ b/src/ext/conf/ExtConfPatches.js @@ -0,0 +1,44 @@ +// How to use: +// version: {ExtensionConf object, but only properties that get overwritten} + +const ExtensionConfPatch = { + '4.2.0': { + sites: { + "old.reddit.com" : { + type: 'testing', + DOM: { + player: { + manual: true, + useRelativeAncestor: false, + querySelectors: '.media-preview-content' + } + }, + css: '', + }, + "www.reddit.com" : { + type: 'testing', + DOM: { + player: { + manual: true, + useRelativeAncestor: false, + querySelectors: '.media-preview-content' + } + }, + css: '', + }, + "www.youtube.com" : { + DOM: { + player: { + manual: true, + querySelectors: "#movie_player, #player", + additionalCss: "", + useRelativeAncestor: false, + playerNodeCss: "", + } + } + }, + } + } +} + +export default ExtensionConfPatch; \ No newline at end of file diff --git a/src/ext/conf/ExtensionConf.js b/src/ext/conf/ExtensionConf.js index 02fc2b6..9a4d4ec 100644 --- a/src/ext/conf/ExtensionConf.js +++ b/src/ext/conf/ExtensionConf.js @@ -836,6 +836,7 @@ var ExtensionConf = { } }, ], +whatsNewChecked: true, // ----------------------------------------- // ::: SITE CONFIGURATION ::: // ----------------------------------------- @@ -896,6 +897,15 @@ var ExtensionConf = { stretch: Stretch.Default, videoAlignment: VideoAlignment.Default, keyboardShortcutsEnabled: ExtensionMode.Default, + DOM: { + player: { + manual: true, + querySelectors: "#movie_player, #player", + additionalCss: "", + useRelativeAncestor: false, + playerNodeCss: "", + } + } }, "www.netflix.com" : { mode: ExtensionMode.Enabled, @@ -919,49 +929,23 @@ var ExtensionConf = { } } }, - "old.reddit.com" : { + "www.twitch.tv": { mode: ExtensionMode.Enabled, autoar: currentBrowser.firefox ? ExtensionMode.Enabled : ExtensionMode.Disabled, - override: false, + override: true, type: 'official', stretch: Stretch.Default, videoAlignment: VideoAlignment.Default, keyboardShortcutsEnabled: ExtensionMode.Default, DOM: { - video: { - manual: false, - querySelectors: '', - additionalCss: '', - }, player: { manual: true, - useRelativeAncestor: true, - videoAncestor: 1, + querySelectors: ".video-player__container.player", + additionalCss: "", + useRelativeAncestor: false, + playerNodeCss: "" } - }, - css: '', - }, - "www.reddit.com" : { - mode: ExtensionMode.Enabled, - autoar: currentBrowser.firefox ? ExtensionMode.Enabled : ExtensionMode.Disabled, - override: false, - type: 'official', - stretch: Stretch.Default, - videoAlignment: VideoAlignment.Default, - keyboardShortcutsEnabled: ExtensionMode.Default, - DOM: { - video: { - manual: false, - querySelectors: '', - additionalCss: '', - }, - player: { - manual: true, - useRelativeAncestor: true, - videoAncestor: 1, - } - }, - css: '', + } }, "vimeo.com": { mode: 3, @@ -979,26 +963,63 @@ var ExtensionConf = { }, css: ".player_outro_area {\n width: 100% !important;\n display: flex !important;\n justify-content: center !important;\n}\n\n.player_container, .player {\n width: 100% !important; \n}" }, + "old.reddit.com" : { + mode: ExtensionMode.Enabled, + autoar: currentBrowser.firefox ? ExtensionMode.Enabled : ExtensionMode.Disabled, + override: false, + type: 'testing', + stretch: Stretch.Default, + videoAlignment: VideoAlignment.Default, + keyboardShortcutsEnabled: ExtensionMode.Default, + DOM: { + player: { + manual: true, + useRelativeAncestor: false, + querySelectors: '.media-preview-content' + } + }, + css: '', + }, + "www.reddit.com" : { + mode: ExtensionMode.Enabled, + autoar: currentBrowser.firefox ? ExtensionMode.Enabled : ExtensionMode.Disabled, + override: false, + type: 'testing', + stretch: Stretch.Default, + videoAlignment: VideoAlignment.Default, + keyboardShortcutsEnabled: ExtensionMode.Default, + DOM: { + player: { + manual: true, + useRelativeAncestor: false, + querySelectors: '.media-preview-content' + } + }, + css: '', + }, "imgur.com": { mode: -1, autoar: -1, autoarFallback: 0, stretch: -1, - videoAlignment: 1 + videoAlignment: 1, + type: 'official', }, "gfycat.com": { mode: -1, autoar: -1, autoarFallback: 0, stretch: -1, - videoAlignment: 1 + videoAlignment: 1, + type: 'official,' }, "giant.gfycat.com": { mode: -1, autoar: -1, autoarFallback: 0, stretch: -1, - videoAlignment: 1 + videoAlignment: 1, + type: 'official', }, } } diff --git a/src/ext/lib/ObjectCopy.js b/src/ext/lib/ObjectCopy.js index 398d26e..705613b 100644 --- a/src/ext/lib/ObjectCopy.js +++ b/src/ext/lib/ObjectCopy.js @@ -46,6 +46,32 @@ class ObjectCopy { return out; } + static overwrite(existing, target){ + for(var k in target) { + // if current key exist, replace it with existing value. Take no action otherwise. + if (existing[k]) { + + // Types and constructors of objects must match. If they don't, we always use the new value. + if (typeof target[k] === typeof existing[k] && target[k].constructor === existing[k].constructor) { + + // objects are special, we need to check them recursively. + if(existing[k] && typeof existing[k] === 'object' && existing[k].constructor === Object ) { + if(Debug.debug && Debug.settings) { + console.log("[ObjectCopy::addNew] current key contains an object. Recursing!") + } + + existing[k] = this.overwrite(existing[k], target[k]); + } else { + existing[k] = target[k]; + } + } else { + existing[k] = target[k]; + } + } + } + return existing; + } + static pruneUnused(existing, target, ignoreKeys) { // TODO: implement at some other date // existing: object that we have. diff --git a/src/ext/lib/Settings.js b/src/ext/lib/Settings.js index 91b6eba..d1c724d 100644 --- a/src/ext/lib/Settings.js +++ b/src/ext/lib/Settings.js @@ -5,6 +5,7 @@ import ExtensionMode from '../../common/enums/extension-mode.enum'; import ObjectCopy from '../lib/ObjectCopy'; import Stretch from '../../common/enums/stretch.enum'; import VideoAlignment from '../../common/enums/video-alignment.enum'; +import ExtensionConfPatch from '../conf/ExtConfPatches'; @@ -108,6 +109,7 @@ class Settings { if(Debug.debug) { console.log("[Settings::init] extension was saved with current version of ultrawidify (", this.version, "). Returning object as-is."); } + return this.active; } @@ -124,6 +126,12 @@ class Settings { this.active = JSON.parse(JSON.stringify(this.default)); } + // in case settings in previous version contained a fucky wucky, we overwrite existing settings with a patch + ObjectCopy.overwrite(this.active, ExtensionConfPatch['4.2.0']); + + // set 'whatsNewChecked' flag to false when updating + this.active.whatsNewChecked = false; + this.set(this.active); return this.active; } @@ -290,11 +298,11 @@ class Settings { // } try{ // if site is not defined, we use default mode: - if (! this.active.sites[site]) { + 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) { + 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; diff --git a/src/ext/lib/ar-detect/ArDetector.js b/src/ext/lib/ar-detect/ArDetector.js index cfc7f83..37bbe18 100644 --- a/src/ext/lib/ar-detect/ArDetector.js +++ b/src/ext/lib/ar-detect/ArDetector.js @@ -195,7 +195,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: AspectRatio.Automatic, ratio: null}); + this.conf.resizer.setLastAr({type: AspectRatio.Automatic, ratio: this.getDefaultAr()}); this.canvasImageDataRowLength = cwidth << 2; this.noLetterboxCanvasReset = false; @@ -218,7 +218,7 @@ class ArDetector { } if (this.conf.resizer.lastAr.type === AspectRatio.Automatic) { // ensure first autodetection will run in any case - this.conf.resizer.setLastAr({type: AspectRatio.Automatic, ratio: null}); + this.conf.resizer.setLastAr({type: AspectRatio.Automatic, ratio: this.getDefaultAr()}); } // launch main() if it's currently not running: @@ -247,7 +247,7 @@ class ArDetector { console.log("%c[ArDetect::_ard_stop] Stopping automatic aspect ratio detection", _ard_console_stop); } this._halted = true; - // this.conf.resizer.resetLastAr(); + // this.conf.resizer.setArLastAr(); } async main() { @@ -428,6 +428,10 @@ class ArDetector { } //#endregion + getDefaultAr() { + return this.video.videoWidth / this.video.videoHeight; + } + calculateArFromEdges(edges) { // if we don't specify these things, they'll have some default values. if(edges.top === undefined){ @@ -632,7 +636,7 @@ class ArDetector { // da je letterbox izginil. // If we don't detect letterbox, we reset aspect ratio to aspect ratio of the video file. The aspect ratio could // have been corrected manually. It's also possible that letterbox (that was there before) disappeared. - this.conf.resizer.reset({type: AspectRatio.Automatic, ratio: null}); + this.conf.resizer.setAr({type: AspectRatio.Automatic, ratio: this.getDefaultAr()}); this.guardLine.reset(); this.noLetterboxCanvasReset = true; @@ -675,7 +679,7 @@ class ArDetector { // (since the new letterbox edge isn't present in our sample due to technical // limitations) if (this.fallbackMode && guardLineOut.blackbarFail) { - this.conf.resizer.reset({type: AspectRatio.Automatic, ratio: null}); + this.conf.resizer.setAr({type: AspectRatio.Automatic, ratio: this.getDefaultAr()}); this.guardLine.reset(); this.noLetterboxCanvasReset = true; @@ -701,7 +705,7 @@ class ArDetector { } if(guardLineOut.blackbarFail){ - this.conf.resizer.reset({type: AspectRatio.Automatic, ratio: null}); + this.conf.resizer.setAr({type: AspectRatio.Automatic, ratio: this.getDefaultAr()}); this.guardLine.reset(); } diff --git a/src/ext/lib/comms/CommsClient.js b/src/ext/lib/comms/CommsClient.js index 82c7d78..5b2a5e1 100644 --- a/src/ext/lib/comms/CommsClient.js +++ b/src/ext/lib/comms/CommsClient.js @@ -160,7 +160,7 @@ class CommsClient { console.log(`[CommsClient::registerVideo] <${this.commsId}>`, "Registering video for current page."); } if (this.pageInfo) { - if (this.pageInfo.videos.length) { + if (this.pageInfo.hasVideo()) { this.port.postMessage({cmd: "has-video"}); } } else { diff --git a/src/ext/lib/video-data/PageInfo.js b/src/ext/lib/video-data/PageInfo.js index e27ea5e..dbc76f2 100644 --- a/src/ext/lib/video-data/PageInfo.js +++ b/src/ext/lib/video-data/PageInfo.js @@ -9,7 +9,7 @@ if(Debug.debug) class PageInfo { - constructor(comms, settings, extensionMode){ + constructor(comms, settings, extensionMode, readOnly = false){ this.hasVideos = false; this.siteDisabled = false; this.videos = []; @@ -18,8 +18,9 @@ class PageInfo { this.lastUrl = window.location.href; this.extensionMode = extensionMode; + this.readOnly = readOnly; - if(comms){ + if (comms){ this.comms = comms; } @@ -27,18 +28,6 @@ class PageInfo { this.scheduleUrlCheck(); this.currentZoomScale = 1; - - try { - const playerStyleString = this.settings.active.sites[window.location.host].css; - if (playerStyleString) { - this.comms.sendMessage({ - cmd: 'inject-css', - cssString: playerStyleString - }); - } - } catch (e) { - // do nothing. It's ok if there's no special settings for the player element - } } destroy() { @@ -104,6 +93,10 @@ class PageInfo { return document.getElementsByTagName('video'); } + hasVideo() { + return this.readOnly ? this.hasVideos : this.videos.length; + } + rescan(rescanReason){ const oldVideoCount = this.videos.length; @@ -135,6 +128,16 @@ class PageInfo { // if video lacks either of the two properties, we skip all further checks cos pointless if(video.offsetWidth && video.offsetHeight){ this.hasVideos = true; + + if (this.readOnly) { + // in lite mode, we're done. This is all the info we want, but we want to actually start doing + // things that interfere with the website. We still want to be runnig a rescan, tho. + + if(rescanReason == RescanReason.PERIODIC){ + this.scheduleRescan(RescanReason.PERIODIC); + } + return; + } } else { continue; } @@ -158,6 +161,7 @@ class PageInfo { if (Debug.debug && Debug.periodic && Debug.videoRescan) { console.log("[PageInfo::rescan] found new video candidate:", video, "NOTE:: Video initialization starts here:\n--------------------------------\n") } + v = new VideoData(video, this.settings, this); // console.log("[PageInfo::rescan] v is:", v) v.initArDetection(); diff --git a/src/ext/lib/video-data/PlayerData.js b/src/ext/lib/video-data/PlayerData.js index a3ce545..1b654bf 100644 --- a/src/ext/lib/video-data/PlayerData.js +++ b/src/ext/lib/video-data/PlayerData.js @@ -381,9 +381,10 @@ class PlayerData { console.log("[PlayerDetect] player size changed. reason: exited fullscreen"); } } - if(! this.element) + if(! this.element && Debug.debug && Debug.playerDetect) { console.log("[PlayerDetect] player element isnt defined"); - + } + if ( this.element && ( this.dimensions.width != this.element.offsetWidth || this.dimensions.height != this.element.offsetHeight ) diff --git a/src/ext/uw.js b/src/ext/uw.js index 37a3aea..b553026 100644 --- a/src/ext/uw.js +++ b/src/ext/uw.js @@ -65,15 +65,19 @@ class UW { console.log("[uw::init] Extension mode:" + (extensionMode < 0 ? "disabled" : extensionMode == '1' ? 'basic' : 'full')); } - if(extensionMode === ExtensionMode.Disabled){ - if(Debug.debug) { - console.log("[uw::init] EXTENSION DISABLED, THEREFORE WONT BE STARTED") + const isSiteDisabled = extensionMode === ExtensionMode.Disabled + + if (isSiteDisabled) { + if (this.settings.getExtensionMode('@global') === ExtensionMode.Disabled) { + if (Debug.debug) { + console.log("[uw::init] EXTENSION DISABLED, THEREFORE WONT BE STARTED") + } + return; } - return; } try { - this.pageInfo = new PageInfo(this.comms, this.settings, extensionMode); + this.pageInfo = new PageInfo(this.comms, this.settings, extensionMode, isSiteDisabled); if(Debug.debug){ console.log("[uw.js::setup] pageInfo initialized. Here's the object:", this.pageInfo); } @@ -83,11 +87,14 @@ class UW { console.log("[uw.js::setup] will try to initate ActionHandler. Settings are:", this.settings, this.settings.active) } - this.actionHandler = new ActionHandler(this.pageInfo); - this.actionHandler.init(); - - if(Debug.debug) { - console.log("[uw.js::setup] ActionHandler initiated:", this.actionHandler); + // start action handler only if extension is enabled for this site + if (!isSiteDisabled) { + this.actionHandler = new ActionHandler(this.pageInfo); + this.actionHandler.init(); + + if(Debug.debug) { + console.log("[uw.js::setup] ActionHandler initiated:", this.actionHandler); + } } } catch (e) { diff --git a/src/manifest.json b/src/manifest.json index 3a305e3..f802033 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 2, "name": "Ultrawidify", "description": "Removes black bars on ultrawide videos and offers advanced options to fix aspect ratio.", - "version": "4.1.2", + "version": "4.2.0", "applications": { "gecko": { "id": "{cf02b1a7-a01a-4e37-a609-516a283f1ed3}" diff --git a/src/popup/App.vue b/src/popup/App.vue index 0d01dc3..5e55a87 100644 --- a/src/popup/App.vue +++ b/src/popup/App.vue @@ -1,12 +1,12 @@