Bug 1819664 - Block onload on pending l10n mutations. r=smaug,Gijs

Remove custom code doing this for <dialog>.

Differential Revision: https://phabricator.services.mozilla.com/D171475
This commit is contained in:
Emilio Cobos Álvarez 2023-03-04 00:04:45 +00:00
Родитель f3f4f3270c
Коммит 75b298315d
5 изменённых файлов: 38 добавлений и 39 удалений

Просмотреть файл

@ -3809,11 +3809,9 @@ class Document : public nsINode,
nsresult Dispatch(TaskCategory aCategory,
already_AddRefed<nsIRunnable>&& aRunnable) final;
virtual nsISerialEventTarget* EventTargetFor(
TaskCategory aCategory) const override;
nsISerialEventTarget* EventTargetFor(TaskCategory) const override;
virtual AbstractThread* AbstractMainThreadFor(
TaskCategory aCategory) override;
AbstractThread* AbstractMainThreadFor(TaskCategory) override;
// The URLs passed to this function should match what
// JS::DescribeScriptedCaller() returns, since this API is used to

Просмотреть файл

@ -9,6 +9,7 @@
#include "nsRefreshDriver.h"
#include "DOMLocalization.h"
#include "mozilla/intl/Localization.h"
#include "nsThreadManager.h"
using namespace mozilla;
using namespace mozilla::intl;
@ -132,13 +133,38 @@ void L10nMutations::ContentRemoved(nsIContent* aChild,
}
void L10nMutations::L10nElementChanged(Element* aElement) {
const bool wasEmpty = mPendingElements.IsEmpty();
if (mPendingElementsHash.EnsureInserted(aElement)) {
mPendingElements.AppendElement(aElement);
}
if (!wasEmpty) {
return;
}
if (!mRefreshDriver) {
StartRefreshObserver();
}
if (!mBlockingLoad) {
Document* doc = GetDocument();
if (doc && doc->GetReadyStateEnum() != Document::READYSTATE_COMPLETE) {
doc->BlockOnload();
mBlockingLoad = true;
// We want to make sure we flush translations and don't block the load
// indefinitely (and, in fact, that we do it rather soon, even if the
// refresh driver is not ticking yet).
//
// In some platforms (mainly Wayland) the load of the main document
// causes vsync to start running and start ticking the refresh driver,
// so we can't rely on the refresh driver ticking yet.
RefPtr<nsIRunnable> task =
NewRunnableMethod("FlushPendingTranslationsBeforeLoad", this,
&L10nMutations::FlushPendingTranslations);
nsThreadManager::get().DispatchDirectTaskToCurrentThread(task);
}
}
}
void L10nMutations::PauseObserving() { mObserving = false; }
@ -241,9 +267,14 @@ void L10nMutations::MaybeFirePendingTranslationsFinished() {
}
RefPtr doc = GetDocument();
if (!doc) {
if (NS_WARN_IF(!doc)) {
return;
}
if (mBlockingLoad) {
mBlockingLoad = false;
doc->UnblockOnload(false);
}
nsContentUtils::DispatchEventOnlyToChrome(
doc, ToSupports(doc), u"L10nMutationsFinished"_ns, CanBubble::eNo,
Cancelable::eNo, Composed::eNo, nullptr);

Просмотреть файл

@ -70,6 +70,7 @@ class L10nMutations final : public nsStubMultiMutationObserver,
private:
bool mObserving = false;
bool mBlockingLoad = false;
uint32_t mPendingPromises = 0;
RefPtr<nsRefreshDriver> mRefreshDriver;
DOMLocalization* mDOMLocalization;

Просмотреть файл

@ -14,12 +14,9 @@ var gCertDB = Cc["@mozilla.org/security/x509certdb;1"].getService(
*/
var gCert = window.arguments[0];
document.mozSubdialogReady = init();
document.addEventListener("DOMContentLoaded", init);
async function init() {
await new Promise(r => {
document.addEventListener("DOMContentLoaded", r, { once: true });
});
function init() {
document.addEventListener("dialogaccept", onDialogAccept);
let sslCheckbox = document.getElementById("trustSSL");
@ -37,12 +34,9 @@ async function init() {
);
let certMsg = document.getElementById("certmsg");
document.l10n.pauseObserving();
document.l10n.setAttributes(certMsg, "edit-trust-ca", {
certName: gCert.commonName,
});
document.l10n.resumeObserving();
await document.l10n.translateElements([certMsg]);
}
/**

Просмотреть файл

@ -14,13 +14,6 @@
class MozDialog extends MozXULElement {
constructor() {
super();
/**
* Gets populated by elements that are passed to document.l10n.setAttributes
* to localize the dialog buttons. Needed to properly size the dialog after
* the asynchronous translation.
*/
this._l10nButtons = [];
}
static get observedAttributes() {
@ -99,6 +92,7 @@
this.attachShadow({ mode: "open" });
document.documentElement.setAttribute("role", "dialog");
document.l10n?.connectRoot(this.shadowRoot);
this.shadowRoot.textContent = "";
this.shadowRoot.appendChild(
@ -148,17 +142,6 @@
}
});
if (this._l10nButtons.length) {
document.blockUnblockOnload(true);
this._translationReady = document.l10n.ready.then(async () => {
try {
await document.l10n.translateElements(this._l10nButtons);
} finally {
document.blockUnblockOnload(false);
}
});
}
// Call postLoadInit for things that we need to initialize after onload.
if (document.readyState == "complete") {
this._postLoadInit();
@ -347,13 +330,6 @@
async _postLoadInit() {
this._setInitialFocusIfNeeded();
if (this._translationReady) {
await this._translationReady;
}
if (document.mozSubDialogReady) {
await document.mozSubDialogReady;
}
let finalStep = () => {
this._sizeToPreferredSize();
this._snapCursorToDefaultButtonIfNeeded();
@ -437,7 +413,6 @@
button,
this.getAttribute("buttonid" + dlgtype)
);
this._l10nButtons.push(button);
} else if (dlgtype != "extra1" && dlgtype != "extra2") {
button.setAttribute(
"label",