From e1e962df04d8c66f4784931bd1585115b0e3fb74 Mon Sep 17 00:00:00 2001 From: Tamius Han Date: Wed, 18 Sep 2019 01:03:04 +0200 Subject: [PATCH] If no element fits the criteria for the video player, have extension ignore such videos. Also, sometimes mutationObserver doesn't catch all mutations/we miss some mutations. Added a delay that validates offsets. If validation fails, retrigger aspect ratio correction to make sure there's no misalignments. (That last bit was mostly needed for new reddit) --- src/ext/lib/video-data/PageInfo.js | 6 +- src/ext/lib/video-data/PlayerData.js | 200 ++++++++++++++------------- src/ext/lib/video-data/VideoData.js | 140 ++++++++++++++----- 3 files changed, 217 insertions(+), 129 deletions(-) diff --git a/src/ext/lib/video-data/PageInfo.js b/src/ext/lib/video-data/PageInfo.js index 9acd3bf..de2720c 100644 --- a/src/ext/lib/video-data/PageInfo.js +++ b/src/ext/lib/video-data/PageInfo.js @@ -197,7 +197,11 @@ class PageInfo { try { v = new VideoData(video, this.settings, this); - v.initArDetection(); + if (!v.invalid) { + v.initArDetection(); + } else { + this.logger.log('error', 'debug', 'Video is invalid. Aard not started.', video); + } this.videos.push(v); } catch (e) { this.logger.log('error', 'debug', "rescan error: failed to initialize videoData. Skipping this video.",e); diff --git a/src/ext/lib/video-data/PlayerData.js b/src/ext/lib/video-data/PlayerData.js index a5612cb..ac4ff0b 100644 --- a/src/ext/lib/video-data/PlayerData.js +++ b/src/ext/lib/video-data/PlayerData.js @@ -39,10 +39,17 @@ class PlayerData { this.video = videoData.video; this.settings = videoData.settings; this.extensionMode = videoData.extensionMode; + this.invalid = false; this.element = this.getPlayer(); this.dimensions = undefined; this.overlayNode = undefined; + // this happens when we don't find a matching player element + if (!this.element) { + this.invalid = true; + return; + } + if (this.extensionMode === ExtensionMode.Enabled) { this.checkPlayerSizeChange(); } @@ -76,15 +83,11 @@ class PlayerData { } startChangeDetection(){ - const ths = this; - this.observer = new MutationObserver((m,o) => this.onPlayerDimensionsChanged(m,o,ths)); - - const isFullScreen = PlayerData.isFullScreen(); - this.element = this.getPlayer(isFullScreen); - - if (!this.element) { + if (this.invalid) { return; } + const ths = this; + this.observer = new MutationObserver((m,o) => this.onPlayerDimensionsChanged(m,o,ths)); const observerConf = { attributes: true, @@ -157,7 +160,7 @@ class PlayerData { return false; } - getPlayer(isFullScreen) { + getPlayer() { const host = window.location.host; let element = this.video.parentNode; const videoWidth = this.video.offsetWidth, videoHeight = this.video.offsetHeight; @@ -165,112 +168,119 @@ class PlayerData { let scorePenalty = 0; let score; - if(! element ){ - this.logger.log('info', 'debug', "[PlayerDetect::_pd_getPlayer] element is not valid, doing nothing.", element) - if(this.element) { - const ths = this; + try { + if(! element ){ + this.logger.log('info', 'debug', "[PlayerDetect::_pd_getPlayer] element is not valid, doing nothing.", element) + if(this.element) { + const ths = this; + } + this.element = undefined; + this.dimensions = undefined; + return; } - this.element = undefined; - this.dimensions = undefined; - return; - } - 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) { + 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) { - let parentsLeft = this.settings.active.sites[host].DOM.player.videoAncestor - 1; - while (parentsLeft --> 0) { - element = element.parentNode; - } - if (element) { - return element; - } - } else if (this.settings.active.sites[host].DOM.player.querySelectors) { - const allSelectors = document.querySelectorAll(this.settings.active.sites[host].DOM.player.querySelectors); + let parentsLeft = this.settings.active.sites[host].DOM.player.videoAncestor - 1; + while (parentsLeft --> 0) { + element = element.parentNode; + } + if (element) { + return element; + } + } else if (this.settings.active.sites[host].DOM.player.querySelectors) { + const allSelectors = document.querySelectorAll(this.settings.active.sites[host].DOM.player.querySelectors); + // actually we'll also score this branch in a similar way we score the regular, auto branch + while (element) { - // actually we'll also score this branch in a similar way we score the regular, auto branch - while (element) { + // Let's see how this works + if (this.collectionHas(allSelectors, element)) { + score = 100; // every matching element gets a baseline 100 points + + // elements that match the size get a hefty bonus + if ( (element.offsetWidth >= videoWidth && this.equalish(element.offsetHeight, videoHeight, 2)) + || (element.offsetHeight >= videoHeight && this.equalish(element.offsetWidth, videoHeight, 2))) { + score += 75; + } - // Let's see how this works - if (this.collectionHas(allSelectors, element)) { - score = 100; // every matching element gets a baseline 100 points - - // elements that match the size get a hefty bonus - if ( (element.offsetWidth >= videoWidth && this.equalish(element.offsetHeight, videoHeight, 2)) - || (element.offsetHeight >= videoHeight && this.equalish(element.offsetWidth, videoHeight, 2))) { - score += 75; + // elements farther away from the video get a penalty + score -= (scorePenalty++) * 20; + + // push the element on the queue/stack: + elementQ.push({ + score: score, + element: element, + }); } - // elements farther away from the video get a penalty - score -= (scorePenalty++) * 20; - - // push the element on the queue/stack: - elementQ.push({ - score: score, - element: element, - }); + element = element.parentNode; } + if (elementQ.length) { + // return element with biggest score + // if video player has not been found, proceed to automatic detection + return elementQ.sort( (a,b) => b.score - a.score)[0].element; + } + } + } + + // try to find element the old fashioned way + + while (element){ + // 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; + continue; } - if (elementQ.length) { - // return element with biggest score - // if video player has not been found, proceed to automatic detection - return elementQ.sort( (a,b) => b.score - a.score)[0].element; - } - } - } - + // element je player, če je ena stranica enako velika kot video, druga pa večja ali enaka. + // za enakost dovolimo mala odstopanja + // element is player, if one of the sides is as long as the video and the other bigger (or same) + // we allow for tiny variations when checking for equality + if ( (element.offsetWidth >= videoWidth && this.equalish(element.offsetHeight, videoHeight, 2)) + || (element.offsetHeight >= videoHeight && this.equalish(element.offsetWidth, videoHeight, 2))) { + + // todo — in case the match is only equalish and not exact, take difference into account when + // calculating score + + score = 100; - while (element){ - // odstranimo čudne elemente, ti bi pokvarili zadeve - // remove weird elements, those would break our stuff - if ( element.offsetWidth == 0 || element.offsetHeight == 0){ + if (element.id.indexOf('player') !== -1) { // prefer elements with 'player' in id + score += 75; + } + if (element.classList.toString().indexOf('player') !== -1) { // prefer elements with 'player' in classlist, but a bit less than id + score += 50; + } + score -= scorePenalty++; // prefer elements closer to