mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-11-11 21:58:41 +02:00
Bug 1627809 - Move Localization.jsm construction to Localization constructor. r=smaug
Differential Revision: https://phabricator.services.mozilla.com/D70973
This commit is contained in:
parent
9211c5cc8a
commit
1427870732
8 changed files with 120 additions and 65 deletions
|
|
@ -3841,12 +3841,14 @@ bool Document::GetAllowPlugins() {
|
||||||
void Document::InitializeLocalization(Sequence<nsString>& aResourceIds) {
|
void Document::InitializeLocalization(Sequence<nsString>& aResourceIds) {
|
||||||
MOZ_ASSERT(!mDocumentL10n, "mDocumentL10n should not be initialized yet");
|
MOZ_ASSERT(!mDocumentL10n, "mDocumentL10n should not be initialized yet");
|
||||||
|
|
||||||
RefPtr<DocumentL10n> l10n = new DocumentL10n(this);
|
RefPtr<DocumentL10n> l10n = DocumentL10n::Create(this);
|
||||||
ErrorResult rv;
|
if (NS_WARN_IF(!l10n)) {
|
||||||
l10n->Init(aResourceIds, rv);
|
|
||||||
if (NS_WARN_IF(rv.Failed())) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (aResourceIds.Length()) {
|
||||||
|
l10n->AddResourceIds(aResourceIds);
|
||||||
|
}
|
||||||
|
l10n->Activate();
|
||||||
mDocumentL10n = l10n;
|
mDocumentL10n = l10n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,12 +48,13 @@ already_AddRefed<DOMLocalization> DOMLocalization::Constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<DOMLocalization> domLoc = new DOMLocalization(global);
|
RefPtr<DOMLocalization> domLoc = new DOMLocalization(global);
|
||||||
domLoc->Init(aResourceIds, aSync, aBundleGenerator, aRv);
|
|
||||||
|
|
||||||
if (NS_WARN_IF(aRv.Failed())) {
|
if (aResourceIds.Length()) {
|
||||||
return nullptr;
|
domLoc->AddResourceIds(aResourceIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
domLoc->Activate(aSync, true, aBundleGenerator);
|
||||||
|
|
||||||
return domLoc.forget();
|
return domLoc.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,28 +29,46 @@ NS_IMPL_RELEASE_INHERITED(DocumentL10n, DOMLocalization)
|
||||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DocumentL10n)
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DocumentL10n)
|
||||||
NS_INTERFACE_MAP_END_INHERITING(DOMLocalization)
|
NS_INTERFACE_MAP_END_INHERITING(DOMLocalization)
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
RefPtr<DocumentL10n> DocumentL10n::Create(Document* aDocument) {
|
||||||
|
RefPtr<DocumentL10n> l10n = new DocumentL10n(aDocument);
|
||||||
|
|
||||||
|
if (!l10n->Init()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return l10n.forget();
|
||||||
|
}
|
||||||
|
|
||||||
DocumentL10n::DocumentL10n(Document* aDocument)
|
DocumentL10n::DocumentL10n(Document* aDocument)
|
||||||
: DOMLocalization(aDocument->GetScopeObject()),
|
: DOMLocalization(aDocument->GetScopeObject()),
|
||||||
mDocument(aDocument),
|
mDocument(aDocument),
|
||||||
mState(DocumentL10nState::Initialized) {
|
mState(DocumentL10nState::Uninitialized) {
|
||||||
mContentSink = do_QueryInterface(aDocument->GetCurrentContentSink());
|
mContentSink = do_QueryInterface(aDocument->GetCurrentContentSink());
|
||||||
|
|
||||||
Element* elem = mDocument->GetDocumentElement();
|
|
||||||
if (elem) {
|
|
||||||
mIsSync = elem->HasAttr(kNameSpaceID_None, nsGkAtoms::datal10nsync);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentL10n::Init(Sequence<nsString>& aResourceIds, ErrorResult& aRv) {
|
bool DocumentL10n::Init() {
|
||||||
DOMLocalization::Init(aResourceIds, mIsSync, {}, aRv);
|
ErrorResult rv;
|
||||||
if (NS_WARN_IF(aRv.Failed())) {
|
mReady = Promise::Create(mGlobal, rv);
|
||||||
|
if (NS_WARN_IF(rv.Failed())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DocumentL10n::Activate() {
|
||||||
|
if (mState > DocumentL10nState::Uninitialized) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mReady = Promise::Create(mGlobal, aRv);
|
Element* elem = mDocument->GetDocumentElement();
|
||||||
if (NS_WARN_IF(aRv.Failed())) {
|
bool isSync = false;
|
||||||
return;
|
if (elem) {
|
||||||
|
isSync = elem->HasAttr(kNameSpaceID_None, nsGkAtoms::datal10nsync);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DOMLocalization::Activate(isSync, true, {});
|
||||||
|
|
||||||
|
mState = DocumentL10nState::Activated;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSObject* DocumentL10n::WrapObject(JSContext* aCx,
|
JSObject* DocumentL10n::WrapObject(JSContext* aCx,
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,22 @@ namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
enum class DocumentL10nState {
|
enum class DocumentL10nState {
|
||||||
Initialized = 0,
|
// State set when the DocumentL10n gets constructed.
|
||||||
|
Uninitialized = 0,
|
||||||
|
|
||||||
|
// State set when the DocumentL10n is activated and ready to be used.
|
||||||
|
Activated,
|
||||||
|
|
||||||
|
// State set when the initial translation got triggered. This happens
|
||||||
|
// if DocumentL10n was constructed during parsing of the document.
|
||||||
|
//
|
||||||
|
// If the DocumentL10n gets constructed later, we'll skip directly to
|
||||||
|
// Ready state.
|
||||||
InitialTranslationTriggered,
|
InitialTranslationTriggered,
|
||||||
InitialTranslationCompleted
|
|
||||||
|
// State set the DocumentL10n has been fully initialized, potentially
|
||||||
|
// with initial translation being completed.
|
||||||
|
InitialTranslationCompleted,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -34,10 +47,14 @@ class DocumentL10n final : public DOMLocalization {
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DocumentL10n, DOMLocalization)
|
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DocumentL10n, DOMLocalization)
|
||||||
|
|
||||||
explicit DocumentL10n(Document* aDocument);
|
static RefPtr<DocumentL10n> Create(Document* aDocument);
|
||||||
void Init(Sequence<nsString>& aResourceIds, ErrorResult& aRv);
|
|
||||||
|
void Activate();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
explicit DocumentL10n(Document* aDocument);
|
||||||
|
bool Init();
|
||||||
|
|
||||||
virtual ~DocumentL10n() = default;
|
virtual ~DocumentL10n() = default;
|
||||||
|
|
||||||
RefPtr<Document> mDocument;
|
RefPtr<Document> mDocument;
|
||||||
|
|
|
||||||
|
|
@ -43,37 +43,36 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Localization)
|
||||||
NS_INTERFACE_MAP_END
|
NS_INTERFACE_MAP_END
|
||||||
|
|
||||||
Localization::Localization(nsIGlobalObject* aGlobal)
|
Localization::Localization(nsIGlobalObject* aGlobal)
|
||||||
: mGlobal(aGlobal), mIsSync(false) {}
|
: mGlobal(aGlobal), mIsSync(false) {
|
||||||
|
|
||||||
void Localization::Init(const Sequence<nsString>& aResourceIds,
|
|
||||||
const bool aSync,
|
|
||||||
const BundleGenerator& aBundleGenerator,
|
|
||||||
ErrorResult& aRv) {
|
|
||||||
nsCOMPtr<mozILocalizationJSM> jsm =
|
nsCOMPtr<mozILocalizationJSM> jsm =
|
||||||
do_ImportModule("resource://gre/modules/Localization.jsm");
|
do_ImportModule("resource://gre/modules/Localization.jsm");
|
||||||
MOZ_RELEASE_ASSERT(jsm);
|
MOZ_RELEASE_ASSERT(jsm);
|
||||||
|
|
||||||
Unused << jsm->GetLocalization(aResourceIds, getter_AddRefs(mLocalization));
|
Unused << jsm->GetLocalization(getter_AddRefs(mLocalization));
|
||||||
MOZ_RELEASE_ASSERT(mLocalization);
|
MOZ_RELEASE_ASSERT(mLocalization);
|
||||||
mLocalization->SetIsSync(aSync);
|
}
|
||||||
|
|
||||||
|
void Localization::Activate(const bool aSync, const bool aEager,
|
||||||
|
const BundleGenerator& aBundleGenerator) {
|
||||||
AutoJSContext cx;
|
AutoJSContext cx;
|
||||||
|
JS::Rooted<JS::Value> generateBundlesJS(cx);
|
||||||
|
JS::Rooted<JS::Value> generateBundlesSyncJS(cx);
|
||||||
|
|
||||||
if (aBundleGenerator.mGenerateBundles.WasPassed()) {
|
if (aBundleGenerator.mGenerateBundles.WasPassed()) {
|
||||||
GenerateBundles& generateBundles =
|
GenerateBundles& generateBundles =
|
||||||
aBundleGenerator.mGenerateBundles.Value();
|
aBundleGenerator.mGenerateBundles.Value();
|
||||||
JS::Rooted<JS::Value> generateBundlesJS(
|
generateBundlesJS.set(JS::ObjectValue(*generateBundles.CallbackOrNull()));
|
||||||
cx, JS::ObjectValue(*generateBundles.CallbackOrNull()));
|
|
||||||
mLocalization->SetGenerateBundles(generateBundlesJS);
|
|
||||||
}
|
}
|
||||||
if (aBundleGenerator.mGenerateBundlesSync.WasPassed()) {
|
if (aBundleGenerator.mGenerateBundlesSync.WasPassed()) {
|
||||||
GenerateBundlesSync& generateBundlesSync =
|
GenerateBundlesSync& generateBundlesSync =
|
||||||
aBundleGenerator.mGenerateBundlesSync.Value();
|
aBundleGenerator.mGenerateBundlesSync.Value();
|
||||||
JS::Rooted<JS::Value> generateBundlesSyncJS(
|
generateBundlesSyncJS.set(
|
||||||
cx, JS::ObjectValue(*generateBundlesSync.CallbackOrNull()));
|
JS::ObjectValue(*generateBundlesSync.CallbackOrNull()));
|
||||||
mLocalization->SetGenerateBundlesSync(generateBundlesSyncJS);
|
|
||||||
}
|
}
|
||||||
|
mIsSync = aSync;
|
||||||
|
|
||||||
mLocalization->Init(true);
|
mLocalization->Activate(aSync, aEager, generateBundlesJS,
|
||||||
|
generateBundlesSyncJS);
|
||||||
|
|
||||||
RegisterObservers();
|
RegisterObservers();
|
||||||
}
|
}
|
||||||
|
|
@ -90,12 +89,12 @@ already_AddRefed<Localization> Localization::Constructor(
|
||||||
|
|
||||||
RefPtr<Localization> loc = new Localization(global);
|
RefPtr<Localization> loc = new Localization(global);
|
||||||
|
|
||||||
loc->Init(aResourceIds, aSync, aBundleGenerator, aRv);
|
if (aResourceIds.Length()) {
|
||||||
|
loc->AddResourceIds(aResourceIds);
|
||||||
if (NS_WARN_IF(aRv.Failed())) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loc->Activate(aSync, true, aBundleGenerator);
|
||||||
|
|
||||||
return loc.forget();
|
return loc.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -197,6 +196,7 @@ already_AddRefed<Promise> Localization::FormatValue(
|
||||||
}
|
}
|
||||||
|
|
||||||
void Localization::SetIsSync(const bool aIsSync) {
|
void Localization::SetIsSync(const bool aIsSync) {
|
||||||
|
mIsSync = aIsSync;
|
||||||
mLocalization->SetIsSync(aIsSync);
|
mLocalization->SetIsSync(aIsSync);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,8 @@ class Localization : public nsIObserver,
|
||||||
NS_DECL_NSIOBSERVER
|
NS_DECL_NSIOBSERVER
|
||||||
|
|
||||||
explicit Localization(nsIGlobalObject* aGlobal);
|
explicit Localization(nsIGlobalObject* aGlobal);
|
||||||
void Init(const Sequence<nsString>& aResourceIds, const bool aSync,
|
void Activate(const bool aSync, const bool aEager,
|
||||||
const BundleGenerator& aBundleGenerator, ErrorResult& aRv);
|
const BundleGenerator& aBundleGenerator);
|
||||||
|
|
||||||
static already_AddRefed<Localization> Constructor(
|
static already_AddRefed<Localization> Constructor(
|
||||||
const GlobalObject& aGlobal, const Sequence<nsString>& aResourceIds,
|
const GlobalObject& aGlobal, const Sequence<nsString>& aResourceIds,
|
||||||
|
|
|
||||||
|
|
@ -211,32 +211,42 @@ function maybeReportErrorToGecko(error) {
|
||||||
*/
|
*/
|
||||||
class Localization {
|
class Localization {
|
||||||
/**
|
/**
|
||||||
* @param {Array<String>} resourceIds - List of resource IDs
|
* `Activate` has to be called for this object to be usable.
|
||||||
*
|
*
|
||||||
* @returns {Localization}
|
* @returns {Localization}
|
||||||
*/
|
*/
|
||||||
constructor(resourceIds = []) {
|
constructor() {
|
||||||
this.resourceIds = resourceIds;
|
this.resourceIds = [];
|
||||||
this.generateBundles = defaultGenerateBundles;
|
this.generateBundles = undefined;
|
||||||
this.generateBundlesSync = defaultGenerateBundlesSync;
|
this.generateBundlesSync = undefined;
|
||||||
|
this.isSync = undefined;
|
||||||
|
this.bundles = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
setGenerateBundles(generateBundles) {
|
/**
|
||||||
|
* Activate the instance of the `Localization` class.
|
||||||
|
*
|
||||||
|
* @param {bool} sync - Whether the instance should be
|
||||||
|
* synchronous.
|
||||||
|
* @param {bool} eager - Whether the initial bundles should be
|
||||||
|
* fetched eagerly.
|
||||||
|
* @param {Function} generateBundles - Custom FluentBundle asynchronous generator.
|
||||||
|
* @param {Function} generateBundlesSync - Custom FluentBundle generator.
|
||||||
|
*/
|
||||||
|
activate(sync, eager, generateBundles = defaultGenerateBundles, generateBundlesSync = defaultGenerateBundlesSync) {
|
||||||
|
if (this.bundles) {
|
||||||
|
throw new Error("Attempt to initialize an already initialized instance.");
|
||||||
|
}
|
||||||
this.generateBundles = generateBundles;
|
this.generateBundles = generateBundles;
|
||||||
}
|
|
||||||
|
|
||||||
setGenerateBundlesSync(generateBundlesSync) {
|
|
||||||
this.generateBundlesSync = generateBundlesSync;
|
this.generateBundlesSync = generateBundlesSync;
|
||||||
|
this.isSync = sync;
|
||||||
|
this.regenerateBundles(eager);
|
||||||
}
|
}
|
||||||
|
|
||||||
setIsSync(isSync) {
|
setIsSync(isSync) {
|
||||||
this.isSync = isSync;
|
this.isSync = isSync;
|
||||||
}
|
}
|
||||||
|
|
||||||
init(eager = false) {
|
|
||||||
this.regenerateBundles(eager);
|
|
||||||
}
|
|
||||||
|
|
||||||
cached(iterable) {
|
cached(iterable) {
|
||||||
if (this.isSync) {
|
if (this.isSync) {
|
||||||
return CachedSyncIterable.from(iterable);
|
return CachedSyncIterable.from(iterable);
|
||||||
|
|
@ -273,6 +283,9 @@ class Localization {
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
async formatWithFallback(keys, method) {
|
async formatWithFallback(keys, method) {
|
||||||
|
if (!this.bundles) {
|
||||||
|
throw new Error("Attempt to format on an uninitialized instance.");
|
||||||
|
}
|
||||||
const translations = new Array(keys.length).fill(null);
|
const translations = new Array(keys.length).fill(null);
|
||||||
let hasAtLeastOneBundle = false;
|
let hasAtLeastOneBundle = false;
|
||||||
|
|
||||||
|
|
@ -312,6 +325,10 @@ class Localization {
|
||||||
if (!this.isSync) {
|
if (!this.isSync) {
|
||||||
throw new Error("Can't use sync formatWithFallback when state is async.");
|
throw new Error("Can't use sync formatWithFallback when state is async.");
|
||||||
}
|
}
|
||||||
|
if (!this.bundles) {
|
||||||
|
throw new Error("Attempt to format on an uninitialized instance.");
|
||||||
|
}
|
||||||
|
|
||||||
const translations = new Array(keys.length).fill(null);
|
const translations = new Array(keys.length).fill(null);
|
||||||
let hasAtLeastOneBundle = false;
|
let hasAtLeastOneBundle = false;
|
||||||
|
|
||||||
|
|
@ -488,7 +505,9 @@ class Localization {
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange() {
|
onChange() {
|
||||||
this.regenerateBundles(false);
|
if (this.bundles) {
|
||||||
|
this.regenerateBundles(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -641,8 +660,8 @@ function keysFromBundle(method, bundle, keys, translations) {
|
||||||
* Helper function which allows us to construct a new
|
* Helper function which allows us to construct a new
|
||||||
* Localization from Localization.
|
* Localization from Localization.
|
||||||
*/
|
*/
|
||||||
var getLocalization = (resourceIds) => {
|
var getLocalization = () => {
|
||||||
return new Localization(resourceIds);
|
return new Localization();
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Localization = Localization;
|
this.Localization = Localization;
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,9 @@
|
||||||
[scriptable, uuid(7d468600-551f-4fe0-98c9-92a53b63ec8d)]
|
[scriptable, uuid(7d468600-551f-4fe0-98c9-92a53b63ec8d)]
|
||||||
interface mozILocalization : nsISupports
|
interface mozILocalization : nsISupports
|
||||||
{
|
{
|
||||||
void setGenerateBundles(in jsval generateBundles);
|
void activate(in bool aSync, in bool aEager, in jsval aGenerateBundles, in jsval aGenerateBundlesSync);
|
||||||
void setGenerateBundlesSync(in jsval generateBundlesSync);
|
|
||||||
void setIsSync(in boolean isSync);
|
|
||||||
|
|
||||||
void init(in boolean aEager);
|
void setIsSync(in boolean isSync);
|
||||||
|
|
||||||
unsigned long addResourceIds(in Array<AString> resourceIds);
|
unsigned long addResourceIds(in Array<AString> resourceIds);
|
||||||
unsigned long removeResourceIds(in Array<AString> resourceIds);
|
unsigned long removeResourceIds(in Array<AString> resourceIds);
|
||||||
|
|
@ -37,5 +35,5 @@ interface mozILocalization : nsISupports
|
||||||
[scriptable, uuid(96632d26-1422-12e9-b1ce-9bb586acd241)]
|
[scriptable, uuid(96632d26-1422-12e9-b1ce-9bb586acd241)]
|
||||||
interface mozILocalizationJSM : nsISupports
|
interface mozILocalizationJSM : nsISupports
|
||||||
{
|
{
|
||||||
mozILocalization getLocalization(in Array<AString> resourceIds);
|
mozILocalization getLocalization();
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue