Bug 1631593 - Lazify JSM initialization. r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D71834
This commit is contained in:
Zibi Braniecki 2020-06-04 17:02:01 +00:00
Родитель 79c24a615e
Коммит 065441a790
7 изменённых файлов: 100 добавлений и 63 удалений

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

@ -3858,7 +3858,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);
}
}

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

@ -32,8 +32,21 @@ 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) {
/* static */
already_AddRefed<DOMLocalization> DOMLocalization::Create(
nsIGlobalObject* aGlobal, const bool aSync,
const BundleGenerator& aBundleGenerator) {
RefPtr<DOMLocalization> domLoc =
new DOMLocalization(aGlobal, aSync, aBundleGenerator);
domLoc->Init();
return domLoc.forget();
}
DOMLocalization::DOMLocalization(nsIGlobalObject* aGlobal, const bool aSync,
const BundleGenerator& aBundleGenerator)
: Localization(aGlobal, aSync, aBundleGenerator) {
mMutations = new L10nMutations(this);
}
@ -47,13 +60,14 @@ already_AddRefed<DOMLocalization> DOMLocalization::Constructor(
return nullptr;
}
RefPtr<DOMLocalization> domLoc = new DOMLocalization(global);
RefPtr<DOMLocalization> domLoc =
DOMLocalization::Create(global, aSync, aBundleGenerator);
if (aResourceIds.Length()) {
domLoc->AddResourceIds(aResourceIds);
}
domLoc->Activate(aSync, true, aBundleGenerator);
domLoc->Activate(true);
return domLoc.forget();
}

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

@ -23,7 +23,9 @@ class DOMLocalization : public intl::Localization {
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DOMLocalization, Localization)
explicit DOMLocalization(nsIGlobalObject* aGlobal);
static already_AddRefed<DOMLocalization> Create(
nsIGlobalObject* aGlobal, const bool aSync,
const BundleGenerator& aBundleGenerator);
void Destroy();
@ -104,6 +106,8 @@ class DOMLocalization : public intl::Localization {
}
protected:
explicit DOMLocalization(nsIGlobalObject* aGlobal, const bool aSync,
const BundleGenerator& aBundleGenerator);
virtual ~DOMLocalization();
void OnChange() override;
void DisconnectMutations();

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

@ -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,14 +40,15 @@ 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());
}
bool DocumentL10n::Init() {
DOMLocalization::Init();
ErrorResult rv;
mReady = Promise::Create(mGlobal, rv);
if (NS_WARN_IF(rv.Failed())) {
@ -55,30 +57,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 +143,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();

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

@ -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,13 +44,11 @@ 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);
bool Init();
explicit DocumentL10n(Document* aDocument, const bool aSync);
bool Init() override;
virtual ~DocumentL10n() = default;

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

@ -50,20 +50,20 @@ 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);
/* static */
already_AddRefed<Localization> Localization::Create(
nsIGlobalObject* aGlobal, const bool aSync,
const BundleGenerator& aBundleGenerator) {
RefPtr<Localization> loc = new Localization(aGlobal, aSync, aBundleGenerator);
Unused << jsm->GetLocalization(getter_AddRefs(mLocalization));
MOZ_RELEASE_ASSERT(mLocalization);
loc->Init();
return loc.forget();
}
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();
@ -75,6 +75,23 @@ void Localization::Activate(const bool aSync, const bool aEager,
mGenerateBundlesSync.setObject(*generateBundlesSync.CallbackOrNull());
}
mIsSync = aSync;
}
bool Localization::Init() {
RegisterObservers();
return true;
}
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);
@ -84,7 +101,6 @@ void Localization::Activate(const bool aSync, const bool aEager,
&bundlesJS);
mBundles.set(bundlesJS);
RegisterObservers();
mozilla::HoldJSObjects(this);
}
@ -98,13 +114,14 @@ already_AddRefed<Localization> Localization::Constructor(
return nullptr;
}
RefPtr<Localization> loc = new Localization(global);
RefPtr<Localization> loc =
Localization::Create(global, aSync, aBundleGenerator);
if (aResourceIds.Length()) {
loc->AddResourceIds(aResourceIds);
}
loc->Activate(aSync, true, aBundleGenerator);
loc->Activate(true);
return loc.forget();
}
@ -228,6 +245,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 +274,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 +301,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 +334,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 +362,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 +390,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) {

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

@ -32,9 +32,11 @@ class Localization : public nsIObserver,
nsIObserver)
NS_DECL_NSIOBSERVER
explicit Localization(nsIGlobalObject* aGlobal);
void Activate(const bool aSync, const bool aEager,
const BundleGenerator& aBundleGenerator);
static already_AddRefed<Localization> Create(
nsIGlobalObject* aGlobal, const bool aSync,
const BundleGenerator& aBundleGenerator);
void Activate(const bool aEager);
void Destroy();
@ -84,6 +86,10 @@ class Localization : public nsIObserver,
ErrorResult& aRv);
protected:
Localization(nsIGlobalObject* aGlobal, const bool aSync,
const BundleGenerator& aBundleGenerator);
virtual bool Init();
virtual ~Localization();
void RegisterObservers();
virtual void OnChange();