Fixed issues with mutation observers

This commit is contained in:
Tamius Han 2019-09-14 23:23:00 +02:00
parent ef9f106e18
commit 44caa5f492
2 changed files with 51 additions and 76 deletions

View File

@ -39,14 +39,12 @@ class PlayerData {
this.video = videoData.video; this.video = videoData.video;
this.settings = videoData.settings; this.settings = videoData.settings;
this.extensionMode = videoData.extensionMode; this.extensionMode = videoData.extensionMode;
this.element = undefined; this.element = this.getPlayer();
this.dimensions = undefined; this.dimensions = undefined;
this.overlayNode = undefined; this.overlayNode = undefined;
this.observer = new MutationObserver(this.onPlayerDimensionsChanged);
if (this.extensionMode === ExtensionMode.Enabled) { if (this.extensionMode === ExtensionMode.Enabled) {
this.getPlayerDimensions(); this.checkPlayerSizeChange();
} }
this.startChangeDetection(); this.startChangeDetection();
} }
@ -56,18 +54,9 @@ class PlayerData {
} }
// player size observer may not be strictly necessary here // player size observer may not be strictly necessary here
onPlayerDimensionsChanged(mutationList, observer) { onPlayerDimensionsChanged(mutationList, observer, context) {
if (!mutationList || this.element === undefined) { // something's wrong if (context.checkPlayerSizeChange()) {
return; context.videoData.resizer.restore();
}
for (let mutation of mutationList) {
if (mutation.type === 'attributes') {
if (mutation.attributeName === 'style' && this.checkPlayerSizeChange()) {
// if size of the player has changed, this may mean we need to recalculate/reapply
// last calculated aspect ratio
this.videoData.resizer.restore();
}
}
} }
} }
@ -82,15 +71,19 @@ class PlayerData {
} }
destroy() { destroy() {
console.log("PLAYER DIMENSION — DSTROYING")
this.stopChangeDetection(); this.stopChangeDetection();
this.destroyOverlay(); this.destroyOverlay();
} }
startChangeDetection(){ startChangeDetection(){
const ths = this;
this.observer = new MutationObserver((m,o) => this.onPlayerDimensionsChanged(m,o,ths));
const isFullScreen = PlayerData.isFullScreen(); const isFullScreen = PlayerData.isFullScreen();
const element = this.getPlayer(isFullScreen); this.element = this.getPlayer(isFullScreen);
if (!element) { if (!this.element) {
return; return;
} }
@ -100,7 +93,7 @@ class PlayerData {
attributeOldValue: true, attributeOldValue: true,
}; };
this.observer.observe(element, observerConf); this.observer.observe(this.element, observerConf);
} }
stopChangeDetection(){ stopChangeDetection(){
this.observer.disconnect(); this.observer.disconnect();
@ -285,60 +278,26 @@ class PlayerData {
return a > b - tolerance && a < b + tolerance; return a > b - tolerance && a < b + tolerance;
} }
getPlayerDimensions(){
const isFullScreen = PlayerData.isFullScreen();
const element = this.getPlayer(isFullScreen);
if(! element ){
this.logger.log('error', 'debug', "[PlayerDetect::getPlayerDimensions] element is not valid, doing nothing.", element)
this.element = undefined;
this.dimensions = undefined;
return;
}
if (isFullScreen) {
this.dimensions = {
width: window.innerWidth,
height: window.innerHeight,
fullscreen: true
}
if (this.element != element) {
this.element = element;
this.makeOverlay()
}
} else {
this.dimensions = {
width: element.offsetWidth,
height: element.offsetHeight,
fullscreen: isFullScreen
};
if(this.element != element) {
this.element = element;
this.makeOverlay();
}
}
}
forceRefreshPlayerElement() { forceRefreshPlayerElement() {
this.getPlayerDimensions(); this.checkPlayerSizeChange();
} }
checkPlayerSizeChange(){ checkPlayerSizeChange(){
// this 'if' is just here for debugging — real code starts later. It's safe to collapse and // this 'if' is just here for debugging — real code starts later. It's safe to collapse and
// ignore the contents of this if (unless we need to change how logging works) // ignore the contents of this if (unless we need to change how logging works)
if (this.logger.canLog('debug')){ if (this.logger.canLog('debug')){
if (this.dimensions && this.dimensions.fullscreen){ if (!this.dimensions) {
} else if (this.dimensions && this.dimensions.fullscreen){
if(! PlayerData.isFullScreen()){ if(! PlayerData.isFullScreen()){
this.logger.log('info', 'debug', "[PlayerDetect] player size changed. reason: exited fullscreen"); this.logger.log('info', 'debug', "[PlayerDetect] player size changed. reason: exited fullscreen");
} }
} }
if(! this.element) { if(! this.element) {
this.logger.log('info', 'playerDetect', "[PlayerDetect] player element isnt defined"); this.logger.log('info', 'playerDetect', "[PlayerDetect] player element isn't defined");
} }
if ( this.element && if ( this.element && this.dimensions &&
( this.dimensions.width != this.element.offsetWidth || ( this.dimensions.width != this.element.offsetWidth ||
this.dimensions.height != this.element.offsetHeight ) this.dimensions.height != this.element.offsetHeight )
) { ) {
@ -346,11 +305,26 @@ class PlayerData {
} }
} }
if(this.element == undefined){ // if size doesn't match, update & return true
this.element = this.getPlayer(); if (!this.dimensions
return true; || this.dimensions.width != this.element.offsetWidth
} else if(this.dimensions.width != this.element.offsetWidth || this.dimensions.height != this.element.offsetHeight ){ || this.dimensions.height != this.element.offsetHeight ){
this.element = this.getPlayer();
const isFullScreen = PlayerData.isFullScreen();
if (isFullScreen) {
this.dimensions = {
width: window.innerWidth,
height: window.innerHeight,
fullscreen: true
}
} else {
this.dimensions = {
width: this.element.offsetWidth,
height: this.element.offsetHeight,
fullscreen: isFullScreen
};
}
return true; return true;
} }

View File

@ -24,7 +24,8 @@ class VideoData {
// attributeFilter: ['style', 'class'], // attributeFilter: ['style', 'class'],
attributeOldValue: true, attributeOldValue: true,
}; };
this.observer = new MutationObserver(this.onVideoDimensionsChanged); const ths = this;
this.observer = new MutationObserver( (m, o) => this.onVideoDimensionsChanged(m, o, ths));
this.observer.observe(video, observerConf); this.observer.observe(video, observerConf);
// POZOR: VRSTNI RED JE POMEMBEN (arDetect mora bit zadnji) // POZOR: VRSTNI RED JE POMEMBEN (arDetect mora bit zadnji)
@ -46,9 +47,9 @@ class VideoData {
this.video.classList.add(this.userCssClassName); // this also needs to be applied BEFORE we initialize resizer! this.video.classList.add(this.userCssClassName); // this also needs to be applied BEFORE we initialize resizer!
} }
onVideoDimensionsChanged(mutationList, observer) { onVideoDimensionsChanged(mutationList, observer, context) {
if (!mutationList || this.video === undefined) { // something's wrong if (!mutationList || context.video === undefined) { // something's wrong
if (observer && this.video) { if (observer && context.video) {
observer.disconnect(); observer.disconnect();
} }
return; return;
@ -56,25 +57,25 @@ class VideoData {
for (let mutation of mutationList) { for (let mutation of mutationList) {
if (mutation.type === 'attributes') { if (mutation.type === 'attributes') {
if (mutation.attributeName === 'class') { if (mutation.attributeName === 'class') {
if (!this.video.classList.contains(this.userCssClassName)) { if (!context.video.classList.contains(this.userCssClassName)) {
// force the page to include our class in classlist, if the classlist has been removed // force the page to include our class in classlist, if the classlist has been removed
this.video.classList.add(this.userCssClassName); context.video.classList.add(this.userCssClassName);
// } else if () { // } else if () {
// this bug should really get // this bug should really get
} else { } else {
this.restoreAr(); context.restoreAr();
} }
} else if (mutation.attributeName === 'style' && mutation.attributeOldValue !== this.video.getAttribute('style')) { } else if (mutation.attributeName === 'style' && mutation.attributeOldValue !== context.video.getAttribute('style')) {
// if size of the video has changed, this may mean we need to recalculate/reapply // if size of the video has changed, this may mean we need to recalculate/reapply
// last calculated aspect ratio // last calculated aspect ratio
this.player.forceRefreshPlayerElement(); context.player.forceRefreshPlayerElement();
this.restoreAr(); context.restoreAr();
} else if (mutation.attribute = 'src' && mutation.attributeOldValue !== this.video.getAttribute('src')) { } else if (mutation.attribute = 'src' && mutation.attributeOldValue !== this.video.getAttribute('src')) {
// try fixing alignment issue on video change // try fixing alignment issue on video change
try { try {
this.player.forceRefreshPlayerElement(); context.player.forceRefreshPlayerElement();
this.restoreAr(); context.restoreAr();
} catch (e) { } catch (e) {
console.error("[VideoData::onVideoDimensionsChanged] There was an error when handling src change.", e); console.error("[VideoData::onVideoDimensionsChanged] There was an error when handling src change.", e);
} }