зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1434376 - Switch over all uses of BrowserUtils.promiseLayoutFlushed to window.promiseDocumentFlushed. r=Paolo
window.promiseDocumentFlushed will call a callback as soon as a style or layout flush is not required for the document (which might be immediately). This is a new ChromeOnly API introduced in an earlier patch in this series. This patch also removes the now-unneeded BrowserUtils.promiseLayoutFlushed and BrowserUtils.promiseReflowed methods and infrastructure. MozReview-Commit-ID: Jv7KoxBXhHG --HG-- extra : rebase_source : b8c9ae40dbdd0f5587d03e8b7c0833bd94032a78
This commit is contained in:
Родитель
262bcb1bef
Коммит
4e9c3d2fe2
|
@ -8010,7 +8010,7 @@ var gIdentityHandler = {
|
||||||
classes += " in-use";
|
classes += " in-use";
|
||||||
|
|
||||||
// Synchronize control center and identity block blinking animations.
|
// Synchronize control center and identity block blinking animations.
|
||||||
BrowserUtils.promiseLayoutFlushed(document, "style", () => {
|
window.promiseDocumentFlushed(() => {}).then(() => {
|
||||||
let sharingIconBlink = document.getElementById("sharing-icon").getAnimations()[0];
|
let sharingIconBlink = document.getElementById("sharing-icon").getAnimations()[0];
|
||||||
if (sharingIconBlink) {
|
if (sharingIconBlink) {
|
||||||
let startTime = sharingIconBlink.startTime;
|
let startTime = sharingIconBlink.startTime;
|
||||||
|
|
|
@ -283,7 +283,7 @@
|
||||||
<parameter name="aTab"/>
|
<parameter name="aTab"/>
|
||||||
<body>
|
<body>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
BrowserUtils.promiseLayoutFlushed(aTab.ownerDocument, "style", () => {
|
aTab.ownerGlobal.promiseDocumentFlushed(() => {
|
||||||
if (!aTab.parentNode) {
|
if (!aTab.parentNode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,9 +82,8 @@ async function withReflowObserver(testFn, expectedReflows = [], win = window) {
|
||||||
},
|
},
|
||||||
|
|
||||||
reflowInterruptible(start, end) {
|
reflowInterruptible(start, end) {
|
||||||
// We're not interested in interruptible reflows, but might as well take the
|
// Interruptible reflows are the reflows caused by the refresh
|
||||||
// opportuntiy to dirty the root frame.
|
// driver ticking. These are fine.
|
||||||
dirtyFrameFn();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIReflowObserver,
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsIReflowObserver,
|
||||||
|
|
|
@ -569,11 +569,7 @@ CustomizeMode.prototype = {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until the next frame before setting the class to ensure
|
// Wait until the next frame before setting the class to ensure
|
||||||
// we do start the animation. We cannot use promiseLayoutFlushed
|
// we do start the animation.
|
||||||
// here because callback is only invoked when any actual reflow
|
|
||||||
// happens, while that may not happen soonish enough. If we have
|
|
||||||
// an observer for style flush, we may be able to replace the
|
|
||||||
// nested rAFs with that.
|
|
||||||
this.window.requestAnimationFrame(() => {
|
this.window.requestAnimationFrame(() => {
|
||||||
this.window.requestAnimationFrame(() => {
|
this.window.requestAnimationFrame(() => {
|
||||||
animationNode.classList.add("animate-out");
|
animationNode.classList.add("animate-out");
|
||||||
|
@ -2421,7 +2417,8 @@ CustomizeMode.prototype = {
|
||||||
panelOnTheLeft = true;
|
panelOnTheLeft = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
await BrowserUtils.promiseLayoutFlushed(doc, "display", () => {});
|
await this.window.promiseDocumentFlushed(() => {});
|
||||||
|
|
||||||
if (!this._customizing || !this._wantToBeInCustomizeMode) {
|
if (!this._customizing || !this._wantToBeInCustomizeMode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -495,8 +495,8 @@ var PanelMultiView = class extends this.AssociatedToNode {
|
||||||
// binding for the <panelmultiview> element may still be disconnected.
|
// binding for the <panelmultiview> element may still be disconnected.
|
||||||
// In this case, give the layout code a chance to run.
|
// In this case, give the layout code a chance to run.
|
||||||
if (!this.connected) {
|
if (!this.connected) {
|
||||||
await BrowserUtils.promiseLayoutFlushed(this.document, "layout",
|
await this.window.promiseDocumentFlushed(() => {});
|
||||||
() => {});
|
|
||||||
// The XBL binding must be connected at this point. If this is not the
|
// The XBL binding must be connected at this point. If this is not the
|
||||||
// case, the calling code should be updated to unhide the panel.
|
// case, the calling code should be updated to unhide the panel.
|
||||||
if (!this.connected) {
|
if (!this.connected) {
|
||||||
|
@ -788,7 +788,7 @@ var PanelMultiView = class extends this.AssociatedToNode {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const {window, document} = this;
|
const { window } = this;
|
||||||
|
|
||||||
let nextPanelView = PanelView.forNode(viewNode);
|
let nextPanelView = PanelView.forNode(viewNode);
|
||||||
let prevPanelView = PanelView.forNode(previousViewNode);
|
let prevPanelView = PanelView.forNode(previousViewNode);
|
||||||
|
@ -847,7 +847,7 @@ var PanelMultiView = class extends this.AssociatedToNode {
|
||||||
// description elements it contains.
|
// description elements it contains.
|
||||||
nextPanelView.descriptionHeightWorkaround();
|
nextPanelView.descriptionHeightWorkaround();
|
||||||
|
|
||||||
viewRect = await BrowserUtils.promiseLayoutFlushed(this.document, "layout", () => {
|
viewRect = await window.promiseDocumentFlushed(() => {
|
||||||
return this._dwu.getBoundsWithoutFlushing(viewNode);
|
return this._dwu.getBoundsWithoutFlushing(viewNode);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -894,7 +894,7 @@ var PanelMultiView = class extends this.AssociatedToNode {
|
||||||
// sliding animation with smaller views.
|
// sliding animation with smaller views.
|
||||||
viewNode.style.width = viewRect.width + "px";
|
viewNode.style.width = viewRect.width + "px";
|
||||||
|
|
||||||
await BrowserUtils.promiseLayoutFlushed(document, "layout", () => {});
|
await window.promiseDocumentFlushed(() => {});
|
||||||
|
|
||||||
// Kick off the transition!
|
// Kick off the transition!
|
||||||
details.phase = TRANSITION_PHASES.TRANSITION;
|
details.phase = TRANSITION_PHASES.TRANSITION;
|
||||||
|
@ -1000,7 +1000,7 @@ var PanelMultiView = class extends this.AssociatedToNode {
|
||||||
// We force 'display: none' on the previous view node to make sure that it
|
// We force 'display: none' on the previous view node to make sure that it
|
||||||
// doesn't cause an annoying flicker whilst resetting the styles above.
|
// doesn't cause an annoying flicker whilst resetting the styles above.
|
||||||
previousViewNode.style.display = "none";
|
previousViewNode.style.display = "none";
|
||||||
await BrowserUtils.promiseLayoutFlushed(this.document, "layout", () => {});
|
await this.window.promiseDocumentFlushed(() => {});
|
||||||
previousViewNode.style.removeProperty("display");
|
previousViewNode.style.removeProperty("display");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1608,10 +1608,8 @@ PlacesToolbar.prototype = {
|
||||||
notify: function PT_notify(aTimer) {
|
notify: function PT_notify(aTimer) {
|
||||||
if (aTimer == this._updateNodesVisibilityTimer) {
|
if (aTimer == this._updateNodesVisibilityTimer) {
|
||||||
this._updateNodesVisibilityTimer = null;
|
this._updateNodesVisibilityTimer = null;
|
||||||
// TODO: This should use promiseLayoutFlushed("layout"), so that
|
// Bug 1440070: This should use promiseDocumentFlushed, so that
|
||||||
// _updateNodesVisibilityTimerCallback can use getBoundsWithoutFlush. But
|
// _updateNodesVisibilityTimerCallback can use getBoundsWithoutFlush.
|
||||||
// for yet unknown reasons doing that causes intermittent failures,
|
|
||||||
// apparently due the flush not happening in a meaningful time.
|
|
||||||
window.requestAnimationFrame(this._updateNodesVisibilityTimerCallback.bind(this));
|
window.requestAnimationFrame(this._updateNodesVisibilityTimerCallback.bind(this));
|
||||||
} else if (aTimer == this._ibTimer) {
|
} else if (aTimer == this._ibTimer) {
|
||||||
// * Timer to turn off indicator bar.
|
// * Timer to turn off indicator bar.
|
||||||
|
|
|
@ -14,48 +14,6 @@ ChromeUtils.defineModuleGetter(this, "PlacesUtils",
|
||||||
|
|
||||||
Cu.importGlobalProperties(["URL"]);
|
Cu.importGlobalProperties(["URL"]);
|
||||||
|
|
||||||
let reflowObservers = new WeakMap();
|
|
||||||
|
|
||||||
function ReflowObserver(doc) {
|
|
||||||
this._doc = doc;
|
|
||||||
|
|
||||||
doc.docShell.addWeakReflowObserver(this);
|
|
||||||
reflowObservers.set(this._doc, this);
|
|
||||||
|
|
||||||
this.callbacks = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
ReflowObserver.prototype = {
|
|
||||||
QueryInterface: XPCOMUtils.generateQI(["nsIReflowObserver", "nsISupportsWeakReference"]),
|
|
||||||
|
|
||||||
_onReflow() {
|
|
||||||
reflowObservers.delete(this._doc);
|
|
||||||
this._doc.docShell.removeWeakReflowObserver(this);
|
|
||||||
|
|
||||||
for (let callback of this.callbacks) {
|
|
||||||
try {
|
|
||||||
callback();
|
|
||||||
} catch (e) {
|
|
||||||
Cu.reportError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
reflow() {
|
|
||||||
this._onReflow();
|
|
||||||
},
|
|
||||||
|
|
||||||
reflowInterruptible() {
|
|
||||||
this._onReflow();
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const FLUSH_TYPES = {
|
|
||||||
"style": Ci.nsIDOMWindowUtils.FLUSH_STYLE,
|
|
||||||
"layout": Ci.nsIDOMWindowUtils.FLUSH_LAYOUT,
|
|
||||||
"display": Ci.nsIDOMWindowUtils.FLUSH_DISPLAY,
|
|
||||||
};
|
|
||||||
|
|
||||||
var BrowserUtils = {
|
var BrowserUtils = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -428,8 +386,7 @@ var BrowserUtils = {
|
||||||
}
|
}
|
||||||
let bounds = dwu.getBoundsWithoutFlushing(toolbarItem);
|
let bounds = dwu.getBoundsWithoutFlushing(toolbarItem);
|
||||||
if (!bounds.height) {
|
if (!bounds.height) {
|
||||||
let document = element.ownerDocument;
|
await window.promiseDocumentFlushed(() => {
|
||||||
await BrowserUtils.promiseLayoutFlushed(document, "layout", () => {
|
|
||||||
bounds = dwu.getBoundsWithoutFlushing(toolbarItem);
|
bounds = dwu.getBoundsWithoutFlushing(toolbarItem);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -687,65 +644,6 @@ var BrowserUtils = {
|
||||||
return [url, postData];
|
return [url, postData];
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Calls the given function when the given document has just reflowed,
|
|
||||||
* and returns a promise which resolves to its return value after it
|
|
||||||
* has been called.
|
|
||||||
*
|
|
||||||
* The function *must not trigger any reflows*, or make any changes
|
|
||||||
* which would require a layout flush.
|
|
||||||
*
|
|
||||||
* @param {Document} doc
|
|
||||||
* @param {function} callback
|
|
||||||
* @returns {Promise}
|
|
||||||
*/
|
|
||||||
promiseReflowed(doc, callback) {
|
|
||||||
let observer = reflowObservers.get(doc);
|
|
||||||
if (!observer) {
|
|
||||||
observer = new ReflowObserver(doc);
|
|
||||||
reflowObservers.set(doc, observer);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
observer.callbacks.push(() => {
|
|
||||||
try {
|
|
||||||
resolve(callback());
|
|
||||||
} catch (e) {
|
|
||||||
reject(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calls the given function as soon as a layout flush of the given
|
|
||||||
* type is not necessary, and returns a promise which resolves to the
|
|
||||||
* callback's return value after it executes.
|
|
||||||
*
|
|
||||||
* The function *must not trigger any reflows*, or make any changes
|
|
||||||
* which would require a layout flush.
|
|
||||||
*
|
|
||||||
* @param {Document} doc
|
|
||||||
* @param {string} flushType
|
|
||||||
* The flush type required. Must be one of:
|
|
||||||
*
|
|
||||||
* - "style"
|
|
||||||
* - "layout"
|
|
||||||
* - "display"
|
|
||||||
* @param {function} callback
|
|
||||||
* @returns {Promise}
|
|
||||||
*/
|
|
||||||
async promiseLayoutFlushed(doc, flushType, callback) {
|
|
||||||
let utils = doc.defaultView.QueryInterface(Ci.nsIInterfaceRequestor)
|
|
||||||
.getInterface(Ci.nsIDOMWindowUtils);
|
|
||||||
|
|
||||||
if (!utils.needsFlush(FLUSH_TYPES[flushType])) {
|
|
||||||
return callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.promiseReflowed(doc, callback);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a document fragment for a localized string that has DOM
|
* Generate a document fragment for a localized string that has DOM
|
||||||
* node replacements. This avoids using getFormattedString followed
|
* node replacements. This avoids using getFormattedString followed
|
||||||
|
|
Загрузка…
Ссылка в новой задаче