diff --git a/CHANGELOG.md b/CHANGELOG.md index c882050..39ebff5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,14 @@ * Added user-friendly way to export/import settings * Reworked logging +### v4.2.3 / 4.2.3.1 + +* Fixed twitchy behaviour on Twitch, Facebook and Twatter. Here's a [blog post](https://stuff.tamius.net/sacred-texts/2019/08/24/ultrawidify-the-twitchy-twitch-problem/) that covers the issue in more detail. +* Cropping now uses user styles (as opposed to modifying element's style attribute) +* Fixed the issue where one-pixel letterbox would result in constant aspect ratio corrections. +* Started using mutation observers to watch for anything modifying the size of our video. +* **[4.2.3.1]** fixed some bugs in popup. + ### v4.2.2 (current) * Fixed player detection on reddit (for videos from v.reddit) diff --git a/src/ext/lib/ActionHandler.js b/src/ext/lib/ActionHandler.js index dfd2ded..60eba42 100644 --- a/src/ext/lib/ActionHandler.js +++ b/src/ext/lib/ActionHandler.js @@ -117,6 +117,12 @@ class ActionHandler { } } + unregisterHandleMouse(videoData) { + var ths = this; + if (videoData.player && videoData.player.element) { + videoData.player.element.removeEventListener('mousemove', (event) => ths.handleMouseMove(event, videoData)); + } + } setKeyboardLocal(state) { if (state === ExtensionMode.Enabled) { diff --git a/src/ext/lib/Settings.js b/src/ext/lib/Settings.js index d1c724d..5f0e904 100644 --- a/src/ext/lib/Settings.js +++ b/src/ext/lib/Settings.js @@ -14,6 +14,7 @@ class Settings { constructor(activeSettings, updateCallback) { this.active = activeSettings ? activeSettings : undefined; this.default = ExtensionConf; + this.default['version'] = this.getExtensionVersion(); this.useSync = false; this.version = undefined; this.updateCallback = updateCallback; @@ -63,11 +64,26 @@ class Settings { } } + getExtensionVersion() { + if (currentBrowser.firefox) { + return browser.runtime.getManifest().version; + } else if (currentBrowser.chrome) { + return chrome.runtime.getManifest().version; + } else if (currentBrowser.edge) { + return browser.runtime.getManifest().version; + } + } + async init() { const settings = await this.get(); + const oldVersion = settings.version; + const currentVersion = this.getExtensionVersion(); if(Debug.debug) { - console.log("[Settings::init] Configuration fetched from storage:", settings); + console.log("[Settings::init] Configuration fetched from storage:", settings, + "\nlast saved with:", settings.version, + "\ncurrent version:", currentVersion + ); if (Debug.flushStoredSettings) { console.log("%c[Settings::init] Debug.flushStoredSettings is true. Using default settings", "background: #d00; color: #ffd"); @@ -96,18 +112,17 @@ class Settings { // if there's settings, set saved object as active settings this.active = settings; - // check if extension has been updated. If not, return settings as they were retreived - if (currentBrowser.firefox) { - this.version = browser.runtime.getManifest().version; - } else if (currentBrowser.chrome) { - this.version = chrome.runtime.getManifest().version; - } else if (currentBrowser.edge) { - this.version = browser.runtime.getManifest().version; + // from some point to 4.2.3.1, settings version wasn't saved. Fix that. + if (!settings.version) { + this.active.version = currentVersion; } - if(settings.version === this.version) { + // check if extension has been updated. If not, return settings as they were retreived + + + if(oldVersion === currentVersion) { if(Debug.debug) { - console.log("[Settings::init] extension was saved with current version of ultrawidify (", this.version, "). Returning object as-is."); + console.log("[Settings::init] extension was saved with current version of ultrawidify. Returning object as-is."); } return this.active; @@ -131,6 +146,8 @@ class Settings { // set 'whatsNewChecked' flag to false when updating this.active.whatsNewChecked = false; + // update settings version to current + this.active.version = currentVersion; this.set(this.active); return this.active; diff --git a/src/ext/lib/video-data/PageInfo.js b/src/ext/lib/video-data/PageInfo.js index f705e65..601cd2f 100644 --- a/src/ext/lib/video-data/PageInfo.js +++ b/src/ext/lib/video-data/PageInfo.js @@ -71,8 +71,12 @@ class PageInfo { clearTimeout(this.rescanTimer); } for (var video of this.videos) { - this.comms.unregisterVideo(video.id) - video.destroy(); + try { + this.comms.unregisterVideo(video.id) + video.destroy(); + } catch (e) { + console.log("unabel to destroy video!", e) + } } try { diff --git a/src/ext/lib/video-data/VideoData.js b/src/ext/lib/video-data/VideoData.js index de2bf10..d778809 100644 --- a/src/ext/lib/video-data/VideoData.js +++ b/src/ext/lib/video-data/VideoData.js @@ -51,12 +51,16 @@ class VideoData { } onVideoDimensionsChanged(mutationList, observer) { + if (!mutationList || this.video === undefined) { // something's wrong + if (observer && this.video) { + observer.disconnect(); + } + return; + } for (let mutation of mutationList) { if (mutation.type === 'attributes') { - console.log("video attributes were changed:", mutation) if (mutation.attributeName === 'class') { if (!this.video.classList.contains(this.userCssClassName)) { - console.log("class changed!") // force the page to include our class in classlist, if the classlist has been removed this.video.classList.add(this.userCssClassName); @@ -70,6 +74,13 @@ class VideoData { // if size of the video has changed, this may mean we need to recalculate/reapply // last calculated aspect ratio this.restoreAr(); + } else if (mutation.attribute = 'src' && mutation.attributeOldValue !== this.video.getAttribute('src')) { + // try fixing alignment issue on video change + try { + this.restoreAr(); + } catch (e) { + console.error("[VideoData::onVideoDimensionsChanged] There was an error when handling src change.", e); + } } } } @@ -77,7 +88,8 @@ class VideoData { firstTimeArdInit(){ if(this.destroyed) { - throw {error: 'VIDEO_DATA_DESTROYED', data: {videoData: this}}; + // throw {error: 'VIDEO_DATA_DESTROYED', data: {videoData: this}}; + return; } if(! this.arSetupComplete){ this.arDetector = new ArDetector(this); @@ -86,7 +98,8 @@ class VideoData { initArDetection() { if(this.destroyed) { - throw {error: 'VIDEO_DATA_DESTROYED', data: {videoData: this}}; + // throw {error: 'VIDEO_DATA_DESTROYED', data: {videoData: this}}; + return; } if(this.arDetector){ this.arDetector.init(); @@ -100,7 +113,8 @@ class VideoData { startArDetection() { this.logger.log('info', 'debug', "[VideoData::startArDetection] starting AR detection") if(this.destroyed) { - throw {error: 'VIDEO_DATA_DESTROYED', data: {videoData: this}}; + // throw {error: 'VIDEO_DATA_DESTROYED', data: {videoData: this}}; + return; } if(!this.arDetector) { this.arDetector.init(); @@ -110,7 +124,8 @@ class VideoData { rebootArDetection() { if(this.destroyed) { - throw {error: 'VIDEO_DATA_DESTROYED', data: {videoData: this}}; + // throw {error: 'VIDEO_DATA_DESTROYED', data: {videoData: this}}; + return; } this.arDetector.init(); } @@ -126,20 +141,31 @@ class VideoData { this.pause(); this.destroyed = true; - if(this.arDetector){ - this.arDetector.stop(); - this.arDetector.destroy(); + if (this.arDetector){ + try { + this.arDetector.stop(); + this.arDetector.destroy(); + } catch (e) {} } - this.arDetector = null; - if(this.resizer){ - this.resizer.destroy(); + this.arDetector = undefined; + if (this.resizer){ + try { + this.resizer.destroy(); + } catch (e) {} } - this.resizer = null; - if(this.player){ - this.player.destroy(); + this.resizer = undefined; + if (this.player){ + try { + this.player.destroy(); + } catch (e) {} } - this.player = null; - this.video = null; + if (this.observer) { + try { + this.observer.disconnect(); + } catch (e) {} + } + this.player = undefined; + this.video = undefined; } pause(){ @@ -147,9 +173,6 @@ class VideoData { if(this.arDetector){ this.arDetector.stop(); } - if(this.resizer){ - this.resizer.stop(); - } if(this.player){ this.player.stop(); } @@ -157,7 +180,8 @@ class VideoData { resume(){ if(this.destroyed) { - throw {error: 'VIDEO_DATA_DESTROYED', data: {videoData: this}}; + // throw {error: 'VIDEO_DATA_DESTROYED', data: {videoData: this}}; + return; } this.paused = false; try { @@ -207,7 +231,8 @@ class VideoData { panHandler(event, forcePan) { if(this.destroyed) { - throw {error: 'VIDEO_DATA_DESTROYED', data: {videoData: this}}; + // throw {error: 'VIDEO_DATA_DESTROYED', data: {videoData: this}}; + return; } if(!this.resizer) { this.destroy(); diff --git a/src/manifest.json b/src/manifest.json index 7acbe6f..608758f 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.2.3", + "version": "4.2.3.1", "applications": { "gecko": { "id": "{cf02b1a7-a01a-4e37-a609-516a283f1ed3}" diff --git a/src/popup/App.vue b/src/popup/App.vue index 5e55a87..6a7168b 100644 --- a/src/popup/App.vue +++ b/src/popup/App.vue @@ -34,7 +34,7 @@ class="tabitem ltr" :class="{ 'tabitem-selected': site.host === selectedSite, - 'tabitem-disabled': !settings.canStartExtension(site.host) + 'tabitem-disabled': (settings && !settings.canStartExtension(site.host)) }" @click="selectSite(site.host)" > @@ -59,7 +59,7 @@ class="tabitem ltr" :class="{ 'tabitem-selected': selectedFrame === frame.id, - 'disabled': !isDefaultFrame(frame.id) && !settings.canStartExtension(frame.label) + 'disabled': !isDefaultFrame(frame.id) && (settings && !settings.canStartExtension(frame.label)) }" :key="frame.id" @click="selectFrame(frame.id)" @@ -100,7 +100,7 @@ :class="{'selected-tab': selectedTab === 'whats-new'}" @click="selectTab('whats-new')" > -
What's new?
@@ -196,6 +196,7 @@ export default { siteTabDisabled: false, videoTabDisabled: false, canShowVideoTab: {canShow: true, warning: true}, + showWhatsNew: false, } }, async created() { @@ -266,7 +267,6 @@ export default { this.selectedFrame = frame; }, async updateConfig() { - // when this runs, a site could have been enabled or disabled // this means we must update canShowVideoTab this.updateCanShowVideoTab(); @@ -278,6 +278,7 @@ export default { if (!this.settings) { this.canShowVideoTab = {canShow: true, warning: false}; + return; } for (const site of this.activeSites) { t = this.settings.canStartExtension(site.host); @@ -287,8 +288,8 @@ export default { if (t === undefined) { // something isn't the way it should be. Show sites. this.canShowVideoTab = {canShow: true, warning: true}; + return; } - this.canShowVideoTab = {canShow: canShow, warning: warning}; }, processReceivedMessage(message, port) { @@ -330,7 +331,7 @@ export default { } } -return true; + return true; }, showFirstTab(videoTab) { // determine which tab to show. @@ -381,6 +382,11 @@ return true; if (videoTab.frames.length < 2 || Object.keys(videoTab.frames).length < 2) { this.selectedFrame = '__all'; + this.activeSites = [{ + host: this.site.host, + isIFrame: false, // not used tho. Maybe one day + }]; + this.updateCanShowVideoTab(); // update whether video tab can be shown return; } for (const frame in videoTab.frames) { diff --git a/src/popup/panels/WhatsNewPanel.vue b/src/popup/panels/WhatsNewPanel.vue index 7efa1d7..087b599 100644 --- a/src/popup/panels/WhatsNewPanel.vue +++ b/src/popup/panels/WhatsNewPanel.vue @@ -23,7 +23,7 @@ export default { return { BrowserDetect: BrowserDetect } - } + }, }