зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1831259 - prevent initialization re-entrancy for preference panes, r=mconley
This should fix the issue experienced by the reporter. It also pushes the re-entrancy guard into the the 'init' method we define on gCategoryInits objects, and removes the asynchronicity which was only there for fluent's sake. Instead of blocking the insertion on fluent, which meant that for the in-page find functionality we do N initializations and fluent passes, we make each of the 2 consumers responsible for checking translation has completed. This means find in page now just has 1 fluent pass, instead of N passes for N categories. This should speed up the find in page initialization, and means initialization of a category is now sync instead of async. Differential Revision: https://phabricator.services.mozilla.com/D178232
This commit is contained in:
Родитель
40c92c02c2
Коммит
3c8d3721dd
|
@ -105,10 +105,13 @@ var gSearchResultsPane = {
|
|||
if (!this.categoriesInitialized) {
|
||||
this.categoriesInitialized = true;
|
||||
// Each element of gCategoryInits is a name
|
||||
for (let [, /* name */ category] of gCategoryInits) {
|
||||
if (!category.inited) {
|
||||
await category.init();
|
||||
}
|
||||
for (let category of gCategoryInits.values()) {
|
||||
category.init();
|
||||
}
|
||||
if (document.hasPendingL10nMutations) {
|
||||
await new Promise(r =>
|
||||
document.addEventListener("L10nMutationsFinished", r, { once: true })
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -155,43 +155,24 @@ var gLastCategory = { category: undefined, subcategory: undefined };
|
|||
const gXULDOMParser = new DOMParser();
|
||||
var gCategoryModules = new Map();
|
||||
var gCategoryInits = new Map();
|
||||
function init_category_if_required(category) {
|
||||
let categoryInfo = gCategoryInits.get(category);
|
||||
if (!categoryInfo) {
|
||||
throw new Error(
|
||||
"Unknown in-content prefs category! Can't init " + category
|
||||
);
|
||||
}
|
||||
if (categoryInfo.inited) {
|
||||
return null;
|
||||
}
|
||||
return categoryInfo.init();
|
||||
}
|
||||
|
||||
function register_module(categoryName, categoryObject) {
|
||||
gCategoryModules.set(categoryName, categoryObject);
|
||||
gCategoryInits.set(categoryName, {
|
||||
inited: false,
|
||||
async init() {
|
||||
_initted: false,
|
||||
init() {
|
||||
let startTime = performance.now();
|
||||
if (this._initted) {
|
||||
return;
|
||||
}
|
||||
this._initted = true;
|
||||
let template = document.getElementById("template-" + categoryName);
|
||||
if (template) {
|
||||
// Replace the template element with the nodes inside of it.
|
||||
let frag = template.content;
|
||||
await document.l10n.translateFragment(frag);
|
||||
|
||||
// Actually insert them into the DOM.
|
||||
document.l10n.pauseObserving();
|
||||
template.replaceWith(frag);
|
||||
document.l10n.resumeObserving();
|
||||
|
||||
// We need to queue an update again because the previous update might
|
||||
// have happened while we awaited on translateFragment.
|
||||
Preferences.queueUpdateOfAllElements();
|
||||
template.replaceWith(template.content);
|
||||
}
|
||||
|
||||
categoryObject.init();
|
||||
this.inited = true;
|
||||
ChromeUtils.addProfilerMarker(
|
||||
"Preferences",
|
||||
{ startTime },
|
||||
|
@ -386,24 +367,28 @@ async function gotoPref(
|
|||
}
|
||||
window.history.replaceState(category, document.title);
|
||||
|
||||
try {
|
||||
await init_category_if_required(category);
|
||||
} catch (ex) {
|
||||
console.error(
|
||||
new Error(
|
||||
"Error initializing preference category " + category + ": " + ex
|
||||
)
|
||||
let categoryInfo = gCategoryInits.get(category);
|
||||
if (!categoryInfo) {
|
||||
let err = new Error(
|
||||
"Unknown in-content prefs category! Can't init " + category
|
||||
);
|
||||
throw ex;
|
||||
console.error(err);
|
||||
throw err;
|
||||
}
|
||||
categoryInfo.init();
|
||||
|
||||
// Bail out of this goToPref if the category
|
||||
// or subcategory changed during async operation.
|
||||
if (
|
||||
gLastCategory.category !== category ||
|
||||
gLastCategory.subcategory !== subcategory
|
||||
) {
|
||||
return;
|
||||
if (document.hasPendingL10nMutations) {
|
||||
await new Promise(r =>
|
||||
document.addEventListener("L10nMutationsFinished", r, { once: true })
|
||||
);
|
||||
// Bail out of this goToPref if the category
|
||||
// or subcategory changed during async operation.
|
||||
if (
|
||||
gLastCategory.category !== category ||
|
||||
gLastCategory.subcategory !== subcategory
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
search(category, "data-category");
|
||||
|
|
|
@ -143,17 +143,27 @@ add_task(async function testFilterFeatures() {
|
|||
);
|
||||
}
|
||||
|
||||
// Check that switching to a non-find-in-page category changes item
|
||||
// visibility appropriately.
|
||||
EventUtils.synthesizeMouseAtCenter(
|
||||
doc.getElementById(category),
|
||||
{},
|
||||
gBrowser.contentWindow
|
||||
);
|
||||
|
||||
// Ensure that async passes of localization and any code waiting for
|
||||
// those passes have finished running.
|
||||
await new Promise(r =>
|
||||
requestAnimationFrame(() => requestAnimationFrame(r))
|
||||
);
|
||||
let shouldShow = category == "category-experimental";
|
||||
for (let definition of definitions) {
|
||||
checkVisibility(
|
||||
doc.getElementById(definition.id),
|
||||
true,
|
||||
`${definition.id} should be visible after category change to ${category}`
|
||||
shouldShow,
|
||||
`${definition.id} should be ${
|
||||
shouldShow ? "visible" : "hidden"
|
||||
} after category change to ${category}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче