Bug 1631593 - Lazify JSM initialization. r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D71834
This commit is contained in:
Zibi Braniecki 2020-05-19 16:28:28 +00:00
parent a621e98eac
commit 3e0c621a68
7 changed files with 66 additions and 67 deletions

View File

@ -3865,7 +3865,12 @@ bool Document::GetAllowPlugins() {
void Document::EnsureL10n() {
if (!mDocumentL10n) {
mDocumentL10n = DocumentL10n::Create(this);
Element* elem = GetDocumentElement();
if (NS_WARN_IF(!elem)) {
return;
}
bool isSync = elem->HasAttr(kNameSpaceID_None, nsGkAtoms::datal10nsync);
mDocumentL10n = DocumentL10n::Create(this, isSync);
MOZ_ASSERT(mDocumentL10n);
}
}

View File

@ -32,8 +32,9 @@ NS_IMPL_RELEASE_INHERITED(DOMLocalization, Localization)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMLocalization)
NS_INTERFACE_MAP_END_INHERITING(Localization)
DOMLocalization::DOMLocalization(nsIGlobalObject* aGlobal)
: Localization(aGlobal) {
DOMLocalization::DOMLocalization(nsIGlobalObject* aGlobal, const bool aSync,
const BundleGenerator& aBundleGenerator)
: Localization(aGlobal, aSync, aBundleGenerator) {
mMutations = new L10nMutations(this);
}
@ -47,13 +48,14 @@ already_AddRefed<DOMLocalization> DOMLocalization::Constructor(
return nullptr;
}
RefPtr<DOMLocalization> domLoc = new DOMLocalization(global);
RefPtr<DOMLocalization> domLoc =
new DOMLocalization(global, aSync, aBundleGenerator);
if (aResourceIds.Length()) {
domLoc->AddResourceIds(aResourceIds);
}
domLoc->Activate(aSync, true, aBundleGenerator);
domLoc->Activate(true);
return domLoc.forget();
}

View File

@ -23,7 +23,8 @@ class DOMLocalization : public intl::Localization {
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DOMLocalization, Localization)
explicit DOMLocalization(nsIGlobalObject* aGlobal);
explicit DOMLocalization(nsIGlobalObject* aGlobal, const bool aSync,
const BundleGenerator& aBundleGenerator);
static already_AddRefed<DOMLocalization> Constructor(
const GlobalObject& aGlobal, const Sequence<nsString>& aResourceIds,

View File

@ -30,8 +30,9 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DocumentL10n)
NS_INTERFACE_MAP_END_INHERITING(DOMLocalization)
/* static */
RefPtr<DocumentL10n> DocumentL10n::Create(Document* aDocument) {
RefPtr<DocumentL10n> l10n = new DocumentL10n(aDocument);
RefPtr<DocumentL10n> DocumentL10n::Create(Document* aDocument,
const bool aSync) {
RefPtr<DocumentL10n> l10n = new DocumentL10n(aDocument, aSync);
if (!l10n->Init()) {
return nullptr;
@ -39,10 +40,10 @@ RefPtr<DocumentL10n> DocumentL10n::Create(Document* aDocument) {
return l10n.forget();
}
DocumentL10n::DocumentL10n(Document* aDocument)
: DOMLocalization(aDocument->GetScopeObject()),
DocumentL10n::DocumentL10n(Document* aDocument, const bool aSync)
: DOMLocalization(aDocument->GetScopeObject(), aSync, {}),
mDocument(aDocument),
mState(DocumentL10nState::Uninitialized) {
mState(DocumentL10nState::Constructed) {
mContentSink = do_QueryInterface(aDocument->GetCurrentContentSink());
}
@ -55,30 +56,6 @@ bool DocumentL10n::Init() {
return true;
}
void DocumentL10n::Activate(const bool aLazy) {
if (mState > DocumentL10nState::Uninitialized) {
return;
}
Element* elem = mDocument->GetDocumentElement();
if (NS_WARN_IF(!elem)) {
return;
}
bool isSync = elem->HasAttr(kNameSpaceID_None, nsGkAtoms::datal10nsync);
if (aLazy) {
if (isSync) {
NS_WARNING(
"Document localization initialized lazy, data-l10n-sync attribute "
"has no effect.");
}
DOMLocalization::Activate(false, true, {});
} else {
DOMLocalization::Activate(isSync, true, {});
}
mState = DocumentL10nState::Activated;
}
JSObject* DocumentL10n::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
return DocumentL10n_Binding::Wrap(aCx, this, aGivenProto);
@ -165,8 +142,8 @@ void DocumentL10n::TriggerInitialTranslation() {
}
already_AddRefed<Promise> DocumentL10n::TranslateDocument(ErrorResult& aRv) {
MOZ_ASSERT(mState == DocumentL10nState::Activated,
"This method should be called only from Activated state.");
MOZ_ASSERT(mState == DocumentL10nState::Constructed,
"This method should be called only from Constructed state.");
RefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
Element* elem = mDocument->GetDocumentElement();

View File

@ -15,10 +15,7 @@ namespace dom {
enum class DocumentL10nState {
// State set when the DocumentL10n gets constructed.
Uninitialized = 0,
// State set when the DocumentL10n is activated and ready to be used.
Activated,
Constructed = 0,
// State set when the initial translation got triggered. This happens
// if DocumentL10n was constructed during parsing of the document.
@ -47,12 +44,10 @@ class DocumentL10n final : public DOMLocalization {
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DocumentL10n, DOMLocalization)
static RefPtr<DocumentL10n> Create(Document* aDocument);
void Activate(const bool aLazy);
static RefPtr<DocumentL10n> Create(Document* aDocument, const bool aSync);
protected:
explicit DocumentL10n(Document* aDocument);
explicit DocumentL10n(Document* aDocument, const bool aSync);
bool Init();
virtual ~DocumentL10n() = default;

View File

@ -50,21 +50,9 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Localization)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_END
Localization::Localization(nsIGlobalObject* aGlobal)
: mGlobal(aGlobal), mIsSync(false) {
nsCOMPtr<mozILocalizationJSM> jsm =
do_ImportModule("resource://gre/modules/Localization.jsm");
MOZ_RELEASE_ASSERT(jsm);
Unused << jsm->GetLocalization(getter_AddRefs(mLocalization));
MOZ_RELEASE_ASSERT(mLocalization);
mozilla::HoldJSObjects(this);
}
void Localization::Activate(const bool aSync, const bool aEager,
const BundleGenerator& aBundleGenerator) {
AutoJSContext cx;
Localization::Localization(nsIGlobalObject* aGlobal, const bool aSync,
const BundleGenerator& aBundleGenerator)
: mGlobal(aGlobal), mIsSync(aSync) {
if (aBundleGenerator.mGenerateBundles.WasPassed()) {
GenerateBundles& generateBundles =
aBundleGenerator.mGenerateBundles.Value();
@ -77,6 +65,21 @@ void Localization::Activate(const bool aSync, const bool aEager,
}
mIsSync = aSync;
mozilla::HoldJSObjects(this);
RegisterObservers();
}
void Localization::Activate(const bool aEager) {
nsCOMPtr<mozILocalizationJSM> jsm =
do_ImportModule("resource://gre/modules/Localization.jsm");
MOZ_RELEASE_ASSERT(jsm);
Unused << jsm->GetLocalization(getter_AddRefs(mLocalization));
MOZ_RELEASE_ASSERT(mLocalization);
AutoJSContext cx;
JS::Rooted<JS::Value> generateBundlesJS(cx, mGenerateBundles);
JS::Rooted<JS::Value> generateBundlesSyncJS(cx, mGenerateBundlesSync);
JS::Rooted<JS::Value> bundlesJS(cx);
@ -84,8 +87,6 @@ void Localization::Activate(const bool aSync, const bool aEager,
generateBundlesJS, generateBundlesSyncJS,
&bundlesJS);
mBundles.set(bundlesJS);
RegisterObservers();
}
already_AddRefed<Localization> Localization::Constructor(
@ -98,13 +99,13 @@ already_AddRefed<Localization> Localization::Constructor(
return nullptr;
}
RefPtr<Localization> loc = new Localization(global);
RefPtr<Localization> loc = new Localization(global, aSync, aBundleGenerator);
if (aResourceIds.Length()) {
loc->AddResourceIds(aResourceIds);
}
loc->Activate(aSync, true, aBundleGenerator);
loc->Activate(true);
return loc.forget();
}
@ -228,6 +229,9 @@ uint32_t Localization::RemoveResourceIds(
already_AddRefed<Promise> Localization::FormatValue(
JSContext* aCx, const nsACString& aId, const Optional<L10nArgs>& aArgs,
ErrorResult& aRv) {
if (!mLocalization) {
Activate(false);
}
JS::Rooted<JS::Value> args(aCx);
if (aArgs.WasPassed()) {
@ -254,6 +258,9 @@ void Localization::SetIsSync(const bool aIsSync) { mIsSync = aIsSync; }
already_AddRefed<Promise> Localization::FormatValues(
JSContext* aCx, const Sequence<L10nKey>& aKeys, ErrorResult& aRv) {
if (!mLocalization) {
Activate(false);
}
nsTArray<JS::Value> jsKeys;
SequenceRooter<JS::Value> rooter(aCx, &jsKeys);
for (auto& key : aKeys) {
@ -278,6 +285,9 @@ already_AddRefed<Promise> Localization::FormatValues(
already_AddRefed<Promise> Localization::FormatMessages(
JSContext* aCx, const Sequence<L10nKey>& aKeys, ErrorResult& aRv) {
if (!mLocalization) {
Activate(false);
}
nsTArray<JS::Value> jsKeys;
SequenceRooter<JS::Value> rooter(aCx, &jsKeys);
for (auto& key : aKeys) {
@ -308,6 +318,9 @@ void Localization::FormatValueSync(JSContext* aCx, const nsACString& aId,
"Can't use formatValueSync when state is async.");
return;
}
if (!mLocalization) {
Activate(false);
}
JS::Rooted<JS::Value> args(aCx);
if (aArgs.WasPassed()) {
@ -333,6 +346,9 @@ void Localization::FormatValuesSync(JSContext* aCx,
"Can't use formatValuesSync when state is async.");
return;
}
if (!mLocalization) {
Activate(false);
}
nsTArray<JS::Value> jsKeys;
SequenceRooter<JS::Value> rooter(aCx, &jsKeys);
for (auto& key : aKeys) {
@ -358,6 +374,9 @@ void Localization::FormatMessagesSync(JSContext* aCx,
"Can't use formatMessagesSync when state is async.");
return;
}
if (!mLocalization) {
Activate(false);
}
nsTArray<JS::Value> jsKeys;
SequenceRooter<JS::Value> rooter(aCx, &jsKeys);
for (auto& key : aKeys) {

View File

@ -32,9 +32,9 @@ class Localization : public nsIObserver,
nsIObserver)
NS_DECL_NSIOBSERVER
explicit Localization(nsIGlobalObject* aGlobal);
void Activate(const bool aSync, const bool aEager,
const BundleGenerator& aBundleGenerator);
Localization(nsIGlobalObject* aGlobal, const bool aSync,
const BundleGenerator& aBundleGenerator);
void Activate(const bool aEager);
void Destroy();