Bug 1580015 - part1 : do not reentry function 'processCues()'. r=heycam

Accessing `offsetXXX` attributes of element, it would trigger reflow, and sometime it would result in a re-entry of `processCue()` because we would call `processCue()` when `resizecaption` occurs.

One specifical case is that, assigning CSS properties `min-width` and `max-width` at the same video element, in thise case, when we re-enter the `processCues()` and access `offsetXXX`. It seems that the layout system would reprocess those properites again and again and dispatch `resizecaption` when we access `offsetXXX`, which causes an infinite loop, starting from receving `resizecaption`, then calling `processCue()`, accessing `offSetXXX`, triggering reflow, sending `resizecaption` event again.

Therefore, we should stop revisiting `processCues()` if we're already running a processing, we should run a processing once at a time.

Differential Revision: https://phabricator.services.mozilla.com/D45421

--HG--
extra : moz-landing-system : lando
This commit is contained in:
alwu 2019-09-12 08:13:46 +00:00
parent 95fbf0abf7
commit 104f98fb8c

View File

@ -1104,6 +1104,7 @@ XPCOMUtils.defineLazyPreferenceGetter(this, "DEBUG_LOG",
}
function WebVTT() {
this.isProcessingCues = false;
// Nothing
}
@ -1152,7 +1153,7 @@ XPCOMUtils.defineLazyPreferenceGetter(this, "DEBUG_LOG",
// and regions will be placed into.
// @param controls : A Control bar element. Cues' position will be
// affected and repositioned according to it.
WebVTT.processCues = function(window, cues, overlay, controls) {
function processCuesInternal(window, cues, overlay, controls) {
LOG(`=== processCues ===`);
if (!cues) {
LOG(`clear display and abort processing because of no cue.`);
@ -1307,6 +1308,18 @@ XPCOMUtils.defineLazyPreferenceGetter(this, "DEBUG_LOG",
}
};
WebVTT.processCues = function(window, cues, overlay, controls) {
// When accessing `offsetXXX` attributes of element, it would trigger reflow
// and might result in a re-entry of this function. In order to avoid doing
// redundant computation, we would only do one processing at a time.
if (this.isProcessingCues) {
return;
}
this.isProcessingCues = true;
processCuesInternal(window, cues, overlay, controls);
this.isProcessingCues = false;
};
WebVTT.Parser = function(window, decoder) {
this.window = window;
this.state = "INITIAL";