Replace (video) cssWatcher with mutation observer
This commit is contained in:
parent
13104609cd
commit
d7b3508f85
@ -16,6 +16,16 @@ class VideoData {
|
|||||||
this.vdid = (Math.random()*100).toFixed();
|
this.vdid = (Math.random()*100).toFixed();
|
||||||
this.userCssClassName = `uw-fuck-you-and-do-what-i-tell-you_${this.vdid}`;
|
this.userCssClassName = `uw-fuck-you-and-do-what-i-tell-you_${this.vdid}`;
|
||||||
|
|
||||||
|
|
||||||
|
// We'll replace cssWatcher (in resizer) with mutationObserver
|
||||||
|
const observerConf = {
|
||||||
|
attributes: true,
|
||||||
|
// attributeFilter: ['style', 'class'],
|
||||||
|
attributeOldValue: true,
|
||||||
|
};
|
||||||
|
this.observer = new MutationObserver(this.onVideoDimensionsChanged);
|
||||||
|
this.observer.observe(video, observerConf);
|
||||||
|
|
||||||
// POZOR: VRSTNI RED JE POMEMBEN (arDetect mora bit zadnji)
|
// POZOR: VRSTNI RED JE POMEMBEN (arDetect mora bit zadnji)
|
||||||
// NOTE: ORDERING OF OBJ INITIALIZATIONS IS IMPORTANT (arDetect needs to go last)
|
// NOTE: ORDERING OF OBJ INITIALIZATIONS IS IMPORTANT (arDetect needs to go last)
|
||||||
this.player = new PlayerData(this);
|
this.player = new PlayerData(this);
|
||||||
@ -38,7 +48,32 @@ class VideoData {
|
|||||||
|
|
||||||
this.pageInfo.initMouseActionHandler(this);
|
this.pageInfo.initMouseActionHandler(this);
|
||||||
|
|
||||||
this.video.classList.add(this.userCssClassName);
|
this.video.classList.add(this.userCssClassName); // this also needs to be applied BEFORE we initialize resizer!
|
||||||
|
}
|
||||||
|
|
||||||
|
onVideoDimensionsChanged(mutationList, observer) {
|
||||||
|
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);
|
||||||
|
|
||||||
|
// } else if () {
|
||||||
|
// this bug should really get
|
||||||
|
} else {
|
||||||
|
this.restoreAr();
|
||||||
|
}
|
||||||
|
} else if (mutation.attributeName === 'style' && mutation.attributeOldValue !== this.video.getAttribute('style')) {
|
||||||
|
console.log("style changed")
|
||||||
|
// if size of the video has changed, this may mean we need to recalculate/reapply
|
||||||
|
// last calculated aspect ratio
|
||||||
|
this.restoreAr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
firstTimeArdInit(){
|
firstTimeArdInit(){
|
||||||
|
@ -24,8 +24,6 @@ class Resizer {
|
|||||||
this.stretcher = new Stretcher(this.conf);
|
this.stretcher = new Stretcher(this.conf);
|
||||||
this.zoom = new Zoom(this.conf);
|
this.zoom = new Zoom(this.conf);
|
||||||
|
|
||||||
this.cssCheckDisabled = false;
|
|
||||||
|
|
||||||
// load up default values
|
// load up default values
|
||||||
this.correctedVideoDimensions = {};
|
this.correctedVideoDimensions = {};
|
||||||
this.currentCss = {};
|
this.currentCss = {};
|
||||||
@ -33,16 +31,6 @@ class Resizer {
|
|||||||
this.currentPlayerStyleString = "";
|
this.currentPlayerStyleString = "";
|
||||||
this.currentCssValidFor = {};
|
this.currentCssValidFor = {};
|
||||||
|
|
||||||
// restore watchdog. While true, applyCss() tries to re-apply new css until this value becomes false again
|
|
||||||
// value becomes false when width and height of <video> tag match with what we want to set. Only necessary when
|
|
||||||
// calling _res_restore() for some weird reason.
|
|
||||||
this.restore_wd = false;
|
|
||||||
|
|
||||||
// CSS watcher will trigger _very_ often for this many iterations
|
|
||||||
this.cssWatcherIncreasedFrequencyCounter = 0;
|
|
||||||
|
|
||||||
|
|
||||||
// this.lastAr = this.settings.getDefaultAr(); // this is the aspect ratio we start with
|
|
||||||
this.lastAr = {type: AspectRatio.Initial};
|
this.lastAr = {type: AspectRatio.Initial};
|
||||||
this.videoAlignment = this.settings.getDefaultVideoAlignment(window.location.hostname); // this is initial video alignment
|
this.videoAlignment = this.settings.getDefaultVideoAlignment(window.location.hostname); // this is initial video alignment
|
||||||
this.destroyed = false;
|
this.destroyed = false;
|
||||||
@ -50,7 +38,7 @@ class Resizer {
|
|||||||
this.resizerId = (Math.random(99)*100).toFixed(0);
|
this.resizerId = (Math.random(99)*100).toFixed(0);
|
||||||
|
|
||||||
if (this.settings.active.pan) {
|
if (this.settings.active.pan) {
|
||||||
console.log("can pan:", this.settings.active.miscSettings.mousePan.enabled, "(default:", this.settings.active.miscSettings.mousePan.enabled, ")")
|
// console.log("can pan:", this.settings.active.miscSettings.mousePan.enabled, "(default:", this.settings.active.miscSettings.mousePan.enabled, ")")
|
||||||
this.canPan = this.settings.active.miscSettings.mousePan.enabled;
|
this.canPan = this.settings.active.miscSettings.mousePan.enabled;
|
||||||
} else {
|
} else {
|
||||||
this.canPan = false;
|
this.canPan = false;
|
||||||
@ -60,16 +48,6 @@ class Resizer {
|
|||||||
this.userCssClassName = videoData.userCssClassName;
|
this.userCssClassName = videoData.userCssClassName;
|
||||||
}
|
}
|
||||||
|
|
||||||
start(){
|
|
||||||
if(!this.destroyed) {
|
|
||||||
this.startCssWatcher();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stop(){
|
|
||||||
this.stopCssWatcher();
|
|
||||||
}
|
|
||||||
|
|
||||||
injectCss(css) {
|
injectCss(css) {
|
||||||
this.conf.pageInfo.injectCss(css);
|
this.conf.pageInfo.injectCss(css);
|
||||||
}
|
}
|
||||||
@ -91,7 +69,6 @@ class Resizer {
|
|||||||
console.log(`[Resizer::destroy] <rid:${this.resizerId}> received destroy command.`);
|
console.log(`[Resizer::destroy] <rid:${this.resizerId}> received destroy command.`);
|
||||||
}
|
}
|
||||||
this.destroyed = true;
|
this.destroyed = true;
|
||||||
this.stopCssWatcher();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
calculateRatioForLegacyOptions(ar){
|
calculateRatioForLegacyOptions(ar){
|
||||||
@ -233,11 +210,6 @@ class Resizer {
|
|||||||
this.conf.destroy();
|
this.conf.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.extensionMode === ExtensionMode.Enabled || PlayerData.isFullScreen()) {
|
|
||||||
this.startCssWatcher();
|
|
||||||
}
|
|
||||||
this.cssWatcherIncreasedFrequencyCounter = 20;
|
|
||||||
|
|
||||||
// // pause AR on basic stretch, unpause when using other mdoes
|
// // pause AR on basic stretch, unpause when using other mdoes
|
||||||
// fir sine reason unpause doesn't unpause. investigate that later
|
// fir sine reason unpause doesn't unpause. investigate that later
|
||||||
try {
|
try {
|
||||||
@ -267,13 +239,8 @@ class Resizer {
|
|||||||
if(Debug.debug){
|
if(Debug.debug){
|
||||||
console.log("[Resizer::setAr] <rid:"+this.resizerId+"> Illegal video dimensions found. We will pause everything.");
|
console.log("[Resizer::setAr] <rid:"+this.resizerId+"> Illegal video dimensions found. We will pause everything.");
|
||||||
}
|
}
|
||||||
// if we get illegal video dimensions, cssWatcher goes nuts. This is harmful,
|
|
||||||
// so we stop it until that sorts itself out
|
|
||||||
this.stopCssWatcher();
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else {
|
|
||||||
this.startCssWatcher();
|
|
||||||
}
|
}
|
||||||
if(this.stretcher.mode === Stretch.Conditional){
|
if(this.stretcher.mode === Stretch.Conditional){
|
||||||
this.stretcher.applyConditionalStretch(stretchFactors, ar.ratio);
|
this.stretcher.applyConditionalStretch(stretchFactors, ar.ratio);
|
||||||
@ -373,74 +340,12 @@ class Resizer {
|
|||||||
this.restore();
|
this.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
startCssWatcher(){
|
|
||||||
if(Debug.debug) {
|
|
||||||
console.log("[Resizer.js::startCssWatcher] starting css watcher. Is resizer destroyed?", this.destroyed);
|
|
||||||
}
|
|
||||||
if (this.destroyed) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.cssCheckDisabled = false;
|
|
||||||
|
|
||||||
if(!this.cssWatcherTimer){
|
|
||||||
this.scheduleCssWatcher(1);
|
|
||||||
} else {
|
|
||||||
clearTimeout(this.cssWatcherTimer);
|
|
||||||
this.scheduleCssWatcher(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scheduleCssWatcher(timeout, force_reset) {
|
|
||||||
if (this.destroyed || (this.extensionMode !== ExtensionMode.Enabled && !PlayerData.isFullScreen())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(timeout === undefined) {
|
|
||||||
this.cssCheck(); // no timeout = one-off
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// one extra check to ensure we don't run css checks when we aren't supposed to
|
|
||||||
if (this.cssCheckDisabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this.cssWatcherTimeout) {
|
|
||||||
clearTimeout(this.cssWatcherTimer);
|
|
||||||
}
|
|
||||||
|
|
||||||
var ths = this;
|
|
||||||
this.cssWatcherTimer = setTimeout(function () {
|
|
||||||
ths.cssWatcherTimer = null;
|
|
||||||
try {
|
|
||||||
if (! ths.cssCheckDisabled) {
|
|
||||||
ths.cssCheck();
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
if(Debug.debug) {
|
|
||||||
console.log("[Resizer.js::scheduleCssWatcher] Css check failed. Error:", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
stopCssWatcher() {
|
|
||||||
if (Debug.debug) {
|
|
||||||
console.log(`[Resizer.js] <${this.resizerId}> STOPPING CSS WATCHER!`)
|
|
||||||
}
|
|
||||||
this.cssCheckDisabled = true;
|
|
||||||
clearInterval(this.cssWatcherTimeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
restore() {
|
restore() {
|
||||||
if(Debug.debug){
|
if(Debug.debug){
|
||||||
console.log("[Resizer::restore] <rid:"+this.resizerId+"> attempting to restore aspect ratio. this & settings:", {'a_lastAr': this.lastAr, 'this': this, "settings": this.settings} );
|
console.log("[Resizer::restore] <rid:"+this.resizerId+"> attempting to restore aspect ratio. this & settings:", {'a_lastAr': this.lastAr, 'this': this, "settings": this.settings} );
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is true until we verify that css has actually been applied
|
// this is true until we verify that css has actually been applied
|
||||||
this.restore_wd = true;
|
|
||||||
|
|
||||||
if(this.lastAr.type === AspectRatio.Initial){
|
if(this.lastAr.type === AspectRatio.Initial){
|
||||||
this.setAr({type: AspectRatio.Reset});
|
this.setAr({type: AspectRatio.Reset});
|
||||||
}
|
}
|
||||||
@ -655,80 +560,6 @@ class Resizer {
|
|||||||
this.replaceCss(this.userCss, newCssString);
|
this.replaceCss(this.userCss, newCssString);
|
||||||
this.userCss = newCssString;
|
this.userCss = newCssString;
|
||||||
}
|
}
|
||||||
|
|
||||||
// browser checks and ignores duplicate classes, so no point in checking whether we've already
|
|
||||||
// added the extra class ourselves on top of that. Twice the work, but not much benefit
|
|
||||||
this.video.classList.add(this.userCssClassName);
|
|
||||||
|
|
||||||
if (this.restore_wd) {
|
|
||||||
if (!this.video){
|
|
||||||
if(Debug.debug)
|
|
||||||
console.log("[Resizer::_res_setStyleString] <rid:"+this.resizerId+"> Video element went missing, nothing to do here.")
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.restore_wd = false;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
if(Debug.debug)
|
|
||||||
console.log("[Resizer::_res_setStyleString] <rid:"+this.resizerId+"> css applied. Style string:", styleString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cssCheck(){
|
|
||||||
if (this.cssCheckDisabled) {
|
|
||||||
throw "fucking dont"
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// this means we haven't set our CSS yet, or that we changed video.
|
|
||||||
// if(! this.currentCss.tranform) {
|
|
||||||
// this.scheduleCssWatcher(200);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// this means video went missing. videoData will be re-initialized when the next video is found
|
|
||||||
if (!this.video){
|
|
||||||
if(Debug.debug && Debug.resizer) {
|
|
||||||
console.log("[Resizer::cssCheck] <rid:"+this.resizerId+"> no video detecting, issuing destroy command");
|
|
||||||
}
|
|
||||||
this.conf.destroy();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this.destroyed) {
|
|
||||||
if(Debug.debug && Debug.resizer) {
|
|
||||||
console.log("[Resizer::cssCheck] <rid:"+this.resizerId+"> destroyed flag is set, we shouldnt be running");
|
|
||||||
}
|
|
||||||
this.stopCssWatcher();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let cssValid = true;
|
|
||||||
|
|
||||||
// first, a quick test:
|
|
||||||
cssValid &= this.currentVideoSettings.validFor.width === this.conf.player.dimensions.width;
|
|
||||||
|
|
||||||
if (cssValid) {
|
|
||||||
cssValid &= this.video.classList.contains(this.userCssClassName);
|
|
||||||
}
|
|
||||||
if (cssValid && this.currentPlayerStyleString) { // only check for changes to player element if we applied them before
|
|
||||||
const playerStyleString = this.player.element.getAttribute('style');
|
|
||||||
cssValid &= this.currentPlayerStyleString === playerStyleString;
|
|
||||||
}
|
|
||||||
if (!cssValid){
|
|
||||||
if(Debug.debug && Debug.resizer) {
|
|
||||||
console.log(`%c[Resizer::cssCheck] <rid:${this.resizerId}> something touched our style string. We need to re-apply the style.`, {background: '#ddf', color: '#007'});
|
|
||||||
}
|
|
||||||
this.restore();
|
|
||||||
this.scheduleCssWatcher(10);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this.cssWatcherIncreasedFrequencyCounter > 0) {
|
|
||||||
--this.cssWatcherIncreasedFrequencyCounter;
|
|
||||||
this.scheduleCssWatcher(20);
|
|
||||||
} else {
|
|
||||||
this.scheduleCssWatcher(1000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user