зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1631593 - Cache bundles in Localization C++. r=jfkthame,smaug
Differential Revision: https://phabricator.services.mozilla.com/D71815
This commit is contained in:
Родитель
b99acebc08
Коммит
2a163b0aca
|
@ -63,7 +63,9 @@ JSObject* DOMLocalization::WrapObject(JSContext* aCx,
|
||||||
return DOMLocalization_Binding::Wrap(aCx, this, aGivenProto);
|
return DOMLocalization_Binding::Wrap(aCx, this, aGivenProto);
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMLocalization::~DOMLocalization() { DisconnectMutations(); }
|
void DOMLocalization::Destroy() { DisconnectMutations(); }
|
||||||
|
|
||||||
|
DOMLocalization::~DOMLocalization() { Destroy(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DOMLocalization API
|
* DOMLocalization API
|
||||||
|
|
|
@ -25,6 +25,8 @@ class DOMLocalization : public intl::Localization {
|
||||||
|
|
||||||
explicit DOMLocalization(nsIGlobalObject* aGlobal);
|
explicit DOMLocalization(nsIGlobalObject* aGlobal);
|
||||||
|
|
||||||
|
void Destroy();
|
||||||
|
|
||||||
static already_AddRefed<DOMLocalization> Constructor(
|
static already_AddRefed<DOMLocalization> Constructor(
|
||||||
const GlobalObject& aGlobal, const Sequence<nsString>& aResourceIds,
|
const GlobalObject& aGlobal, const Sequence<nsString>& aResourceIds,
|
||||||
const bool aSync, const BundleGenerator& aBundleGenerator,
|
const bool aSync, const BundleGenerator& aBundleGenerator,
|
||||||
|
|
|
@ -19,7 +19,7 @@ static const char* kObservedPrefs[] = {L10N_PSEUDO_PREF, INTL_UI_DIRECTION_PREF,
|
||||||
using namespace mozilla::intl;
|
using namespace mozilla::intl;
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_CLASS(Localization)
|
NS_IMPL_CYCLE_COLLECTION_MULTI_ZONE_JSHOLDER_CLASS(Localization)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Localization)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Localization)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocalization)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocalization)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlobal)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlobal)
|
||||||
|
@ -37,6 +37,7 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Localization)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
|
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mGenerateBundles)
|
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mGenerateBundles)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mGenerateBundlesSync)
|
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mGenerateBundlesSync)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mBundles)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(Localization)
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(Localization)
|
||||||
|
@ -77,8 +78,11 @@ void Localization::Activate(const bool aSync, const bool aEager,
|
||||||
|
|
||||||
JS::Rooted<JS::Value> generateBundlesJS(cx, mGenerateBundles);
|
JS::Rooted<JS::Value> generateBundlesJS(cx, mGenerateBundles);
|
||||||
JS::Rooted<JS::Value> generateBundlesSyncJS(cx, mGenerateBundlesSync);
|
JS::Rooted<JS::Value> generateBundlesSyncJS(cx, mGenerateBundlesSync);
|
||||||
mLocalization->Activate(mResourceIds, mIsSync, aEager, generateBundlesJS,
|
JS::Rooted<JS::Value> bundlesJS(cx);
|
||||||
generateBundlesSyncJS);
|
mLocalization->GenerateBundles(mResourceIds, mIsSync, aEager,
|
||||||
|
generateBundlesJS, generateBundlesSyncJS,
|
||||||
|
&bundlesJS);
|
||||||
|
mBundles.set(bundlesJS);
|
||||||
|
|
||||||
RegisterObservers();
|
RegisterObservers();
|
||||||
mozilla::HoldJSObjects(this);
|
mozilla::HoldJSObjects(this);
|
||||||
|
@ -127,6 +131,7 @@ Localization::~Localization() {
|
||||||
void Localization::Destroy() {
|
void Localization::Destroy() {
|
||||||
mGenerateBundles.setUndefined();
|
mGenerateBundles.setUndefined();
|
||||||
mGenerateBundlesSync.setUndefined();
|
mGenerateBundlesSync.setUndefined();
|
||||||
|
mBundles.setUndefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Protected */
|
/* Protected */
|
||||||
|
@ -163,8 +168,11 @@ void Localization::OnChange() {
|
||||||
AutoJSContext cx;
|
AutoJSContext cx;
|
||||||
JS::Rooted<JS::Value> generateBundlesJS(cx, mGenerateBundles);
|
JS::Rooted<JS::Value> generateBundlesJS(cx, mGenerateBundles);
|
||||||
JS::Rooted<JS::Value> generateBundlesSyncJS(cx, mGenerateBundlesSync);
|
JS::Rooted<JS::Value> generateBundlesSyncJS(cx, mGenerateBundlesSync);
|
||||||
mLocalization->OnChange(mResourceIds, mIsSync, generateBundlesJS,
|
JS::Rooted<JS::Value> bundlesJS(cx);
|
||||||
generateBundlesSyncJS);
|
mLocalization->GenerateBundles(mResourceIds, mIsSync, false,
|
||||||
|
generateBundlesJS, generateBundlesSyncJS,
|
||||||
|
&bundlesJS);
|
||||||
|
mBundles.set(bundlesJS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,7 +240,8 @@ already_AddRefed<Promise> Localization::FormatValue(
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<Promise> promise;
|
RefPtr<Promise> promise;
|
||||||
nsresult rv = mLocalization->FormatValue(mResourceIds, aId, args,
|
JS::Rooted<JS::Value> bundlesJS(aCx, mBundles);
|
||||||
|
nsresult rv = mLocalization->FormatValue(mResourceIds, bundlesJS, aId, args,
|
||||||
getter_AddRefs(promise));
|
getter_AddRefs(promise));
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
aRv.Throw(rv);
|
aRv.Throw(rv);
|
||||||
|
@ -257,7 +266,8 @@ already_AddRefed<Promise> Localization::FormatValues(
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<Promise> promise;
|
RefPtr<Promise> promise;
|
||||||
aRv = mLocalization->FormatValues(mResourceIds, jsKeys,
|
JS::Rooted<JS::Value> bundlesJS(aCx, mBundles);
|
||||||
|
aRv = mLocalization->FormatValues(mResourceIds, bundlesJS, jsKeys,
|
||||||
getter_AddRefs(promise));
|
getter_AddRefs(promise));
|
||||||
if (NS_WARN_IF(aRv.Failed())) {
|
if (NS_WARN_IF(aRv.Failed())) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -280,7 +290,8 @@ already_AddRefed<Promise> Localization::FormatMessages(
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<Promise> promise;
|
RefPtr<Promise> promise;
|
||||||
aRv = mLocalization->FormatMessages(mResourceIds, jsKeys,
|
JS::Rooted<JS::Value> bundlesJS(aCx, mBundles);
|
||||||
|
aRv = mLocalization->FormatMessages(mResourceIds, bundlesJS, jsKeys,
|
||||||
getter_AddRefs(promise));
|
getter_AddRefs(promise));
|
||||||
if (NS_WARN_IF(aRv.Failed())) {
|
if (NS_WARN_IF(aRv.Failed())) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -308,7 +319,9 @@ void Localization::FormatValueSync(JSContext* aCx, const nsACString& aId,
|
||||||
args = JS::UndefinedValue();
|
args = JS::UndefinedValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
aRv = mLocalization->FormatValueSync(mResourceIds, aId, args, aRetVal);
|
JS::Rooted<JS::Value> bundlesJS(aCx, mBundles);
|
||||||
|
aRv = mLocalization->FormatValueSync(mResourceIds, bundlesJS, aId, args,
|
||||||
|
aRetVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Localization::FormatValuesSync(JSContext* aCx,
|
void Localization::FormatValuesSync(JSContext* aCx,
|
||||||
|
@ -331,7 +344,9 @@ void Localization::FormatValuesSync(JSContext* aCx,
|
||||||
jsKeys.AppendElement(jsKey);
|
jsKeys.AppendElement(jsKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
aRv = mLocalization->FormatValuesSync(mResourceIds, jsKeys, aRetVal);
|
JS::Rooted<JS::Value> bundlesJS(aCx, mBundles);
|
||||||
|
aRv =
|
||||||
|
mLocalization->FormatValuesSync(mResourceIds, bundlesJS, jsKeys, aRetVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Localization::FormatMessagesSync(JSContext* aCx,
|
void Localization::FormatMessagesSync(JSContext* aCx,
|
||||||
|
@ -357,7 +372,9 @@ void Localization::FormatMessagesSync(JSContext* aCx,
|
||||||
nsTArray<JS::Value> messages;
|
nsTArray<JS::Value> messages;
|
||||||
|
|
||||||
SequenceRooter<JS::Value> messagesRooter(aCx, &messages);
|
SequenceRooter<JS::Value> messagesRooter(aCx, &messages);
|
||||||
aRv = mLocalization->FormatMessagesSync(mResourceIds, jsKeys, messages);
|
JS::Rooted<JS::Value> bundlesJS(aCx, mBundles);
|
||||||
|
aRv = mLocalization->FormatMessagesSync(mResourceIds, bundlesJS, jsKeys,
|
||||||
|
messages);
|
||||||
if (NS_WARN_IF(aRv.Failed())) {
|
if (NS_WARN_IF(aRv.Failed())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,6 +97,8 @@ class Localization : public nsIObserver,
|
||||||
|
|
||||||
bool mIsSync;
|
bool mIsSync;
|
||||||
nsTArray<nsString> mResourceIds;
|
nsTArray<nsString> mResourceIds;
|
||||||
|
|
||||||
|
JS::Heap<JS::Value> mBundles;
|
||||||
JS::Heap<JS::Value> mGenerateBundles;
|
JS::Heap<JS::Value> mGenerateBundles;
|
||||||
JS::Heap<JS::Value> mGenerateBundlesSync;
|
JS::Heap<JS::Value> mGenerateBundlesSync;
|
||||||
};
|
};
|
||||||
|
|
|
@ -209,42 +209,14 @@ function maybeReportErrorToGecko(error) {
|
||||||
* It combines language negotiation, FluentBundle and I/O to
|
* It combines language negotiation, FluentBundle and I/O to
|
||||||
* provide a scriptable API to format translations.
|
* provide a scriptable API to format translations.
|
||||||
*/
|
*/
|
||||||
class Localization {
|
const Localization = {
|
||||||
/**
|
|
||||||
* `Activate` has to be called for this object to be usable.
|
|
||||||
*
|
|
||||||
* @returns {Localization}
|
|
||||||
*/
|
|
||||||
constructor() {
|
|
||||||
this.resourceIds = [];
|
|
||||||
this.generateBundles = undefined;
|
|
||||||
this.generateBundlesSync = undefined;
|
|
||||||
this.bundles = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Activate the instance of the `Localization` class.
|
|
||||||
*
|
|
||||||
* @param {Array<String>} resourceIds - List of resource ids used by this
|
|
||||||
* localization.
|
|
||||||
* @param {bool} isSync - 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(resourceIds, isSync, eager, generateBundles, generateBundlesSync) {
|
|
||||||
this.regenerateBundles(resourceIds, isSync, eager, generateBundles, generateBundlesSync);
|
|
||||||
}
|
|
||||||
|
|
||||||
cached(iterable, isSync) {
|
cached(iterable, isSync) {
|
||||||
if (isSync) {
|
if (isSync) {
|
||||||
return CachedSyncIterable.from(iterable);
|
return CachedSyncIterable.from(iterable);
|
||||||
} else {
|
} else {
|
||||||
return CachedAsyncIterable.from(iterable);
|
return CachedAsyncIterable.from(iterable);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format translations and handle fallback if needed.
|
* Format translations and handle fallback if needed.
|
||||||
|
@ -255,19 +227,21 @@ class Localization {
|
||||||
*
|
*
|
||||||
* @param {Array<String>} resourceIds - List of resource ids used by this
|
* @param {Array<String>} resourceIds - List of resource ids used by this
|
||||||
* localization.
|
* localization.
|
||||||
|
* @param {Iter<FluentBundle>} bundles - Iterator over bundles.
|
||||||
* @param {Array<Object>} keys - Translation keys to format.
|
* @param {Array<Object>} keys - Translation keys to format.
|
||||||
* @param {Function} method - Formatting function.
|
* @param {Function} method - Formatting function.
|
||||||
* @returns {Promise<Array<string?|Object?>>}
|
* @returns {Promise<Array<string?|Object?>>}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
async formatWithFallback(resourceIds, keys, method) {
|
async formatWithFallback(resourceIds, bundles, keys, method) {
|
||||||
if (!this.bundles) {
|
if (!bundles) {
|
||||||
throw new Error("Attempt to format on an uninitialized instance.");
|
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;
|
||||||
|
|
||||||
for await (const bundle of this.bundles) {
|
for await (const bundle of bundles) {
|
||||||
hasAtLeastOneBundle = true;
|
hasAtLeastOneBundle = true;
|
||||||
const missingIds = keysFromBundle(method, bundle, keys, translations);
|
const missingIds = keysFromBundle(method, bundle, keys, translations);
|
||||||
|
|
||||||
|
@ -285,7 +259,7 @@ class Localization {
|
||||||
}
|
}
|
||||||
|
|
||||||
return translations;
|
return translations;
|
||||||
}
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format translations and handle fallback if needed.
|
* Format translations and handle fallback if needed.
|
||||||
|
@ -296,20 +270,21 @@ class Localization {
|
||||||
*
|
*
|
||||||
* @param {Array<String>} resourceIds - List of resource ids used by this
|
* @param {Array<String>} resourceIds - List of resource ids used by this
|
||||||
* localization.
|
* localization.
|
||||||
|
* @param {Iter<FluentBundle>} bundles - Iterator over bundles.
|
||||||
* @param {Array<Object>} keys - Translation keys to format.
|
* @param {Array<Object>} keys - Translation keys to format.
|
||||||
* @param {Function} method - Formatting function.
|
* @param {Function} method - Formatting function.
|
||||||
* @returns {Array<string|Object>}
|
* @returns {Array<string|Object>}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
formatWithFallbackSync(resourceIds, keys, method) {
|
formatWithFallbackSync(resourceIds, bundles, keys, method) {
|
||||||
if (!this.bundles) {
|
if (!bundles) {
|
||||||
throw new Error("Attempt to format on an uninitialized instance.");
|
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;
|
||||||
|
|
||||||
for (const bundle of this.bundles) {
|
for (const bundle of bundles) {
|
||||||
hasAtLeastOneBundle = true;
|
hasAtLeastOneBundle = true;
|
||||||
const missingIds = keysFromBundle(method, bundle, keys, translations);
|
const missingIds = keysFromBundle(method, bundle, keys, translations);
|
||||||
|
|
||||||
|
@ -327,7 +302,7 @@ class Localization {
|
||||||
}
|
}
|
||||||
|
|
||||||
return translations;
|
return translations;
|
||||||
}
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -354,13 +329,14 @@ class Localization {
|
||||||
*
|
*
|
||||||
* @param {Array<String>} resourceIds - List of resource ids used by this
|
* @param {Array<String>} resourceIds - List of resource ids used by this
|
||||||
* localization.
|
* localization.
|
||||||
|
* @param {Iter<FluentBundle>} bundles - Iterator over bundles.
|
||||||
* @param {Array<Object>} keys - Translation keys to format.
|
* @param {Array<Object>} keys - Translation keys to format.
|
||||||
* @returns {Promise<Array<{value: string, attributes: Object}?>>}
|
* @returns {Promise<Array<{value: string, attributes: Object}?>>}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
formatMessages(resourceIds, keys) {
|
formatMessages(resourceIds, bundles, keys) {
|
||||||
return this.formatWithFallback(resourceIds, keys, messageFromBundle);
|
return this.formatWithFallback(resourceIds, bundles, keys, messageFromBundle);
|
||||||
}
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sync version of `formatMessages`.
|
* Sync version of `formatMessages`.
|
||||||
|
@ -369,13 +345,14 @@ class Localization {
|
||||||
*
|
*
|
||||||
* @param {Array<String>} resourceIds - List of resource ids used by this
|
* @param {Array<String>} resourceIds - List of resource ids used by this
|
||||||
* localization.
|
* localization.
|
||||||
|
* @param {Iter<FluentBundle>} bundles - Iterator over bundles.
|
||||||
* @param {Array<Object>} keys - Translation keys to format.
|
* @param {Array<Object>} keys - Translation keys to format.
|
||||||
* @returns {Array<{value: string, attributes: Object}?>}
|
* @returns {Array<{value: string, attributes: Object}?>}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
formatMessagesSync(resourceIds, keys) {
|
formatMessagesSync(resourceIds, bundles, keys) {
|
||||||
return this.formatWithFallbackSync(resourceIds, keys, messageFromBundle);
|
return this.formatWithFallbackSync(resourceIds, bundles, keys, messageFromBundle);
|
||||||
}
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve translations corresponding to the passed keys.
|
* Retrieve translations corresponding to the passed keys.
|
||||||
|
@ -395,12 +372,13 @@ class Localization {
|
||||||
*
|
*
|
||||||
* @param {Array<String>} resourceIds - List of resource ids used by this
|
* @param {Array<String>} resourceIds - List of resource ids used by this
|
||||||
* localization.
|
* localization.
|
||||||
|
* @param {Iter<FluentBundle>} bundles - Iterator over bundles.
|
||||||
* @param {Array<Object>} keys - Translation keys to format.
|
* @param {Array<Object>} keys - Translation keys to format.
|
||||||
* @returns {Promise<Array<string?>>}
|
* @returns {Promise<Array<string?>>}
|
||||||
*/
|
*/
|
||||||
formatValues(resourceIds, keys) {
|
formatValues(resourceIds, bundles, keys) {
|
||||||
return this.formatWithFallback(resourceIds, keys, valueFromBundle);
|
return this.formatWithFallback(resourceIds, bundles, keys, valueFromBundle);
|
||||||
}
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sync version of `formatValues`.
|
* Sync version of `formatValues`.
|
||||||
|
@ -409,13 +387,14 @@ class Localization {
|
||||||
*
|
*
|
||||||
* @param {Array<String>} resourceIds - List of resource ids used by this
|
* @param {Array<String>} resourceIds - List of resource ids used by this
|
||||||
* localization.
|
* localization.
|
||||||
|
* @param {Iter<FluentBundle>} bundles - Iterator over bundles.
|
||||||
* @param {Array<Object>} keys - Translation keys to format.
|
* @param {Array<Object>} keys - Translation keys to format.
|
||||||
* @returns {Array<string?>}
|
* @returns {Array<string?>}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
formatValuesSync(resourceIds, keys) {
|
formatValuesSync(resourceIds, bundles, keys) {
|
||||||
return this.formatWithFallbackSync(resourceIds, keys, valueFromBundle);
|
return this.formatWithFallbackSync(resourceIds, bundles, keys, valueFromBundle);
|
||||||
}
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the translation corresponding to the `id` identifier.
|
* Retrieve the translation corresponding to the `id` identifier.
|
||||||
|
@ -437,14 +416,15 @@ class Localization {
|
||||||
*
|
*
|
||||||
* @param {Array<String>} resourceIds - List of resource ids used by this
|
* @param {Array<String>} resourceIds - List of resource ids used by this
|
||||||
* localization.
|
* localization.
|
||||||
|
* @param {Iter<FluentBundle>} bundles - Iterator over bundles.
|
||||||
* @param {string} id - Identifier of the translation to format
|
* @param {string} id - Identifier of the translation to format
|
||||||
* @param {Object} [args] - Optional external arguments
|
* @param {Object} [args] - Optional external arguments
|
||||||
* @returns {Promise<string?>}
|
* @returns {Promise<string?>}
|
||||||
*/
|
*/
|
||||||
async formatValue(resourceIds, id, args) {
|
async formatValue(resourceIds, bundles, id, args) {
|
||||||
const [val] = await this.formatValues(resourceIds, [{id, args}]);
|
const [val] = await this.formatValues(resourceIds, bundles, [{id, args}]);
|
||||||
return val;
|
return val;
|
||||||
}
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sync version of `formatValue`.
|
* Sync version of `formatValue`.
|
||||||
|
@ -453,29 +433,16 @@ class Localization {
|
||||||
*
|
*
|
||||||
* @param {Array<String>} resourceIds - List of resource ids used by this
|
* @param {Array<String>} resourceIds - List of resource ids used by this
|
||||||
* localization.
|
* localization.
|
||||||
|
* @param {Iter<FluentBundle>} bundles - Iterator over bundles.
|
||||||
* @param {string} id - Identifier of the translation to format
|
* @param {string} id - Identifier of the translation to format
|
||||||
* @param {Object} [args] - Optional external arguments
|
* @param {Object} [args] - Optional external arguments
|
||||||
* @returns {string?}
|
* @returns {string?}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
formatValueSync(resourceIds, id, args) {
|
formatValueSync(resourceIds, bundles, id, args) {
|
||||||
const [val] = this.formatValuesSync(resourceIds, [{id, args}]);
|
const [val] = this.formatValuesSync(resourceIds, bundles, [{id, args}]);
|
||||||
return val;
|
return val;
|
||||||
}
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Array<String>} resourceIds - List of resource ids used by this
|
|
||||||
* localization.
|
|
||||||
* @param {bool} isSync - Whether the instance should be
|
|
||||||
* synchronous.
|
|
||||||
* @param {Function} generateBundles - Custom FluentBundle asynchronous generator.
|
|
||||||
* @param {Function} generateBundlesSync - Custom FluentBundle generator.
|
|
||||||
*/
|
|
||||||
onChange(resourceIds, isSync, generateBundles, generateBundlesSync) {
|
|
||||||
if (this.bundles) {
|
|
||||||
this.regenerateBundles(resourceIds, isSync, false, generateBundles, generateBundlesSync);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method should be called when there's a reason to believe
|
* This method should be called when there's a reason to believe
|
||||||
|
@ -488,11 +455,12 @@ class Localization {
|
||||||
* @param {bool} eager - whether the I/O for new context should begin eagerly
|
* @param {bool} eager - whether the I/O for new context should begin eagerly
|
||||||
* @param {Function} generateBundles - Custom FluentBundle asynchronous generator.
|
* @param {Function} generateBundles - Custom FluentBundle asynchronous generator.
|
||||||
* @param {Function} generateBundlesSync - Custom FluentBundle generator.
|
* @param {Function} generateBundlesSync - Custom FluentBundle generator.
|
||||||
|
* @returns {Iter<FluentBundle>}
|
||||||
*/
|
*/
|
||||||
regenerateBundles(resourceIds, isSync, eager = false, generateBundles = defaultGenerateBundles, generateBundlesSync = defaultGenerateBundlesSync) {
|
generateBundles(resourceIds, isSync, eager = false, generateBundles = defaultGenerateBundles, generateBundlesSync = defaultGenerateBundlesSync) {
|
||||||
// Store for error reporting from `formatWithFallback`.
|
// Store for error reporting from `formatWithFallback`.
|
||||||
let generateMessages = isSync ? generateBundlesSync : generateBundles;
|
let generateMessages = isSync ? generateBundlesSync : generateBundles;
|
||||||
this.bundles = this.cached(generateMessages(resourceIds), isSync);
|
let bundles = this.cached(generateMessages(resourceIds), isSync);
|
||||||
if (eager) {
|
if (eager) {
|
||||||
// If the first app locale is the same as last fallback
|
// If the first app locale is the same as last fallback
|
||||||
// it means that we have all resources in this locale, and
|
// it means that we have all resources in this locale, and
|
||||||
|
@ -502,15 +470,12 @@ class Localization {
|
||||||
const appLocale = Services.locale.appLocaleAsBCP47;
|
const appLocale = Services.locale.appLocaleAsBCP47;
|
||||||
const lastFallback = Services.locale.lastFallbackLocale;
|
const lastFallback = Services.locale.lastFallbackLocale;
|
||||||
const prefetchCount = appLocale === lastFallback ? 1 : 2;
|
const prefetchCount = appLocale === lastFallback ? 1 : 2;
|
||||||
this.bundles.touchNext(prefetchCount);
|
bundles.touchNext(prefetchCount);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return bundles;
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
Localization.prototype.QueryInterface = ChromeUtils.generateQI([
|
|
||||||
Ci.nsISupportsWeakReference,
|
|
||||||
]);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format the value of a message into a string or `null`.
|
* Format the value of a message into a string or `null`.
|
||||||
*
|
*
|
||||||
|
@ -630,13 +595,5 @@ function keysFromBundle(method, bundle, keys, translations) {
|
||||||
return missingIds;
|
return missingIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function which allows us to construct a new
|
|
||||||
* Localization from Localization.
|
|
||||||
*/
|
|
||||||
var getLocalization = () => {
|
|
||||||
return new Localization();
|
|
||||||
};
|
|
||||||
|
|
||||||
this.Localization = Localization;
|
this.Localization = Localization;
|
||||||
var EXPORTED_SYMBOLS = ["Localization", "getLocalization"];
|
var EXPORTED_SYMBOLS = ["Localization"];
|
||||||
|
|
|
@ -29,21 +29,19 @@
|
||||||
[scriptable, uuid(7d468600-551f-4fe0-98c9-92a53b63ec8d)]
|
[scriptable, uuid(7d468600-551f-4fe0-98c9-92a53b63ec8d)]
|
||||||
interface mozILocalization : nsISupports
|
interface mozILocalization : nsISupports
|
||||||
{
|
{
|
||||||
void activate(in Array<AString> aResourceIds, in bool aIsSync, in bool aEager, in jsval aGenerateBundles, in jsval aGenerateBundlesSync);
|
jsval generateBundles(in Array<AString> aResourceIds, in bool aIsSync, in bool eager, in jsval aGenerateBundles, in jsval aGenerateBundlesSync);
|
||||||
|
|
||||||
Promise formatMessages(in Array<AString> aResourceIds, in Array<jsval> aKeys);
|
Promise formatMessages(in Array<AString> aResourceIds, in jsval aBundles, in Array<jsval> aKeys);
|
||||||
Promise formatValues(in Array<AString> aResourceIds, in Array<jsval> aKeys);
|
Promise formatValues(in Array<AString> aResourceIds, in jsval aBundles, in Array<jsval> aKeys);
|
||||||
Promise formatValue(in Array<AString> aResourceIds, in AUTF8String aId, [optional] in jsval aArgs);
|
Promise formatValue(in Array<AString> aResourceIds, in jsval aBundles, in AUTF8String aId, [optional] in jsval aArgs);
|
||||||
|
|
||||||
AUTF8String formatValueSync(in Array<AString> aResourceIds, in AUTF8String aId, [optional] in jsval aArgs);
|
AUTF8String formatValueSync(in Array<AString> aResourceIds, in jsval aBundles, in AUTF8String aId, [optional] in jsval aArgs);
|
||||||
Array<AUTF8String> formatValuesSync(in Array<AString> aResourceIds, in Array<jsval> aKeys);
|
Array<AUTF8String> formatValuesSync(in Array<AString> aResourceIds, in jsval aBundles, in Array<jsval> aKeys);
|
||||||
Array<jsval> formatMessagesSync(in Array<AString> aResourceIds, in Array<jsval> aKeys);
|
Array<jsval> formatMessagesSync(in Array<AString> aResourceIds, in jsval aBundles, in Array<jsval> aKeys);
|
||||||
|
|
||||||
void onChange(in Array<AString> aResourceIds, in bool aIsSync, in jsval aGenerateBundles, in jsval aGenerateBundlesSync);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
[scriptable, uuid(96632d26-1422-12e9-b1ce-9bb586acd241)]
|
[scriptable, uuid(96632d26-1422-12e9-b1ce-9bb586acd241)]
|
||||||
interface mozILocalizationJSM : nsISupports
|
interface mozILocalizationJSM : nsISupports
|
||||||
{
|
{
|
||||||
mozILocalization getLocalization();
|
readonly attribute mozILocalization Localization;
|
||||||
};
|
};
|
||||||
|
|
Загрузка…
Ссылка в новой задаче