Bug 1437427 - Workaround promise/microtask bug with a callback in Fluent runtime. r?pike
Due to
bug 1193394 triggering a Promise in the event loop causes the Promise to be
resolved after the event loop microtask.
In this particular case the result is that the document localization is triggered
right before initial layout, but is executed much later, only after DOMContentLoaded.
This in turn causes an additional reflow and frame creation.
In order to workaround this, we're adding a callback method that is executed synchronously
after the event resolves which puts back the initial document localization to happen
right before layout.
MozReview-Commit-ID: HXuMJPwS24N
--- a/intl/l10n/l10n.js
+++ b/intl/l10n/l10n.js
@@ -1,36 +1,45 @@
{
const { DOMLocalization } =
ChromeUtils.import("resource://gre/modules/DOMLocalization.jsm");
/**
* Polyfill for document.ready polyfill.
* See: https://github.com/whatwg/html/issues/127 for details.
*
+ * XXX: The callback is a temporary workaround for bug 1193394. Once Promises in Gecko
+ * start beeing a microtask and stop pushing translation post-layout, we can
+ * remove it and start using the returned Promise again.
+ *
+ * @param {Function} callback - function to be called when the document is ready.
* @returns {Promise}
*/
- function documentReady() {
+ function documentReady(callback) {
if (document.contentType === 'application/vnd.mozilla.xul+xml') {
// XUL
return new Promise(
resolve => document.addEventListener(
- 'MozBeforeInitialXULLayout', resolve, { once: true }
+ 'MozBeforeInitialXULLayout', () => {
+ resolve(callback());
+ }, { once: true }
)
);
}
// HTML
const rs = document.readyState;
if (rs === 'interactive' || rs === 'completed') {
- return Promise.resolve();
+ return Promise.resolve(callback());
}
return new Promise(
resolve => document.addEventListener(
- 'readystatechange', resolve, { once: true }
+ 'readystatechange', () => {
+ resolve(callback());
+ }, { once: true }
)
);
}
/**
* Scans the `elem` for links with localization resources.
*
* @param {Element} elem
@@ -44,17 +53,17 @@
const resourceIds = getResourceLinks(document.head || document);
document.l10n = new DOMLocalization(window, resourceIds);
// trigger first context to be fetched eagerly
document.l10n.ctxs.touchNext();
- document.l10n.ready = documentReady().then(() => {
+ document.l10n.ready = documentReady(() => {
document.l10n.registerObservers();
window.addEventListener('unload', () => {
document.l10n.unregisterObservers();
});
document.l10n.connectRoot(document.documentElement);
return document.l10n.translateRoots();
});
}