Bug 1627809 - Move Localization.jsm construction to Localization constructor. r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D70973
This commit is contained in:
Zibi Braniecki 2020-04-30 18:22:38 +00:00
Родитель 9211c5cc8a
Коммит 1427870732
8 изменённых файлов: 120 добавлений и 65 удалений

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

@ -3841,12 +3841,14 @@ bool Document::GetAllowPlugins() {
void Document::InitializeLocalization(Sequence<nsString>& aResourceIds) {
MOZ_ASSERT(!mDocumentL10n, "mDocumentL10n should not be initialized yet");
RefPtr<DocumentL10n> l10n = new DocumentL10n(this);
ErrorResult rv;
l10n->Init(aResourceIds, rv);
if (NS_WARN_IF(rv.Failed())) {
RefPtr<DocumentL10n> l10n = DocumentL10n::Create(this);
if (NS_WARN_IF(!l10n)) {
return;
}
if (aResourceIds.Length()) {
l10n->AddResourceIds(aResourceIds);
}
l10n->Activate();
mDocumentL10n = l10n;
}

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

@ -48,12 +48,13 @@ already_AddRefed<DOMLocalization> DOMLocalization::Constructor(
}
RefPtr<DOMLocalization> domLoc = new DOMLocalization(global);
domLoc->Init(aResourceIds, aSync, aBundleGenerator, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
if (aResourceIds.Length()) {
domLoc->AddResourceIds(aResourceIds);
}
domLoc->Activate(aSync, true, aBundleGenerator);
return domLoc.forget();
}

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

@ -29,28 +29,46 @@ NS_IMPL_RELEASE_INHERITED(DocumentL10n, DOMLocalization)
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);
if (!l10n->Init()) {
return nullptr;
}
return l10n.forget();
}
DocumentL10n::DocumentL10n(Document* aDocument)
: DOMLocalization(aDocument->GetScopeObject()),
mDocument(aDocument),
mState(DocumentL10nState::Initialized) {
mState(DocumentL10nState::Uninitialized) {
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) {
DOMLocalization::Init(aResourceIds, mIsSync, {}, aRv);
if (NS_WARN_IF(aRv.Failed())) {
bool DocumentL10n::Init() {
ErrorResult rv;
mReady = Promise::Create(mGlobal, rv);
if (NS_WARN_IF(rv.Failed())) {
return false;
}
return true;
}
void DocumentL10n::Activate() {
if (mState > DocumentL10nState::Uninitialized) {
return;
}
mReady = Promise::Create(mGlobal, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
Element* elem = mDocument->GetDocumentElement();
bool isSync = false;
if (elem) {
isSync = elem->HasAttr(kNameSpaceID_None, nsGkAtoms::datal10nsync);
}
DOMLocalization::Activate(isSync, true, {});
mState = DocumentL10nState::Activated;
}
JSObject* DocumentL10n::WrapObject(JSContext* aCx,

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

@ -14,9 +14,22 @@ namespace mozilla {
namespace dom {
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,
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_CYCLE_COLLECTION_CLASS_INHERITED(DocumentL10n, DOMLocalization)
explicit DocumentL10n(Document* aDocument);
void Init(Sequence<nsString>& aResourceIds, ErrorResult& aRv);
static RefPtr<DocumentL10n> Create(Document* aDocument);
void Activate();
protected:
explicit DocumentL10n(Document* aDocument);
bool Init();
virtual ~DocumentL10n() = default;
RefPtr<Document> mDocument;

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

@ -43,37 +43,36 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Localization)
NS_INTERFACE_MAP_END
Localization::Localization(nsIGlobalObject* aGlobal)
: mGlobal(aGlobal), mIsSync(false) {}
void Localization::Init(const Sequence<nsString>& aResourceIds,
const bool aSync,
const BundleGenerator& aBundleGenerator,
ErrorResult& aRv) {
: mGlobal(aGlobal), mIsSync(false) {
nsCOMPtr<mozILocalizationJSM> jsm =
do_ImportModule("resource://gre/modules/Localization.jsm");
MOZ_RELEASE_ASSERT(jsm);
Unused << jsm->GetLocalization(aResourceIds, getter_AddRefs(mLocalization));
Unused << jsm->GetLocalization(getter_AddRefs(mLocalization));
MOZ_RELEASE_ASSERT(mLocalization);
mLocalization->SetIsSync(aSync);
}
void Localization::Activate(const bool aSync, const bool aEager,
const BundleGenerator& aBundleGenerator) {
AutoJSContext cx;
JS::Rooted<JS::Value> generateBundlesJS(cx);
JS::Rooted<JS::Value> generateBundlesSyncJS(cx);
if (aBundleGenerator.mGenerateBundles.WasPassed()) {
GenerateBundles& generateBundles =
aBundleGenerator.mGenerateBundles.Value();
JS::Rooted<JS::Value> generateBundlesJS(
cx, JS::ObjectValue(*generateBundles.CallbackOrNull()));
mLocalization->SetGenerateBundles(generateBundlesJS);
generateBundlesJS.set(JS::ObjectValue(*generateBundles.CallbackOrNull()));
}
if (aBundleGenerator.mGenerateBundlesSync.WasPassed()) {
GenerateBundlesSync& generateBundlesSync =
aBundleGenerator.mGenerateBundlesSync.Value();
JS::Rooted<JS::Value> generateBundlesSyncJS(
cx, JS::ObjectValue(*generateBundlesSync.CallbackOrNull()));
mLocalization->SetGenerateBundlesSync(generateBundlesSyncJS);
generateBundlesSyncJS.set(
JS::ObjectValue(*generateBundlesSync.CallbackOrNull()));
}
mIsSync = aSync;
mLocalization->Init(true);
mLocalization->Activate(aSync, aEager, generateBundlesJS,
generateBundlesSyncJS);
RegisterObservers();
}
@ -90,12 +89,12 @@ already_AddRefed<Localization> Localization::Constructor(
RefPtr<Localization> loc = new Localization(global);
loc->Init(aResourceIds, aSync, aBundleGenerator, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
if (aResourceIds.Length()) {
loc->AddResourceIds(aResourceIds);
}
loc->Activate(aSync, true, aBundleGenerator);
return loc.forget();
}
@ -197,6 +196,7 @@ already_AddRefed<Promise> Localization::FormatValue(
}
void Localization::SetIsSync(const bool aIsSync) {
mIsSync = aIsSync;
mLocalization->SetIsSync(aIsSync);
}

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

@ -33,8 +33,8 @@ class Localization : public nsIObserver,
NS_DECL_NSIOBSERVER
explicit Localization(nsIGlobalObject* aGlobal);
void Init(const Sequence<nsString>& aResourceIds, const bool aSync,
const BundleGenerator& aBundleGenerator, ErrorResult& aRv);
void Activate(const bool aSync, const bool aEager,
const BundleGenerator& aBundleGenerator);
static already_AddRefed<Localization> Constructor(
const GlobalObject& aGlobal, const Sequence<nsString>& aResourceIds,

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

@ -211,32 +211,42 @@ function maybeReportErrorToGecko(error) {
*/
class Localization {
/**
* @param {Array<String>} resourceIds - List of resource IDs
* `Activate` has to be called for this object to be usable.
*
* @returns {Localization}
*/
constructor(resourceIds = []) {
this.resourceIds = resourceIds;
this.generateBundles = defaultGenerateBundles;
this.generateBundlesSync = defaultGenerateBundlesSync;
constructor() {
this.resourceIds = [];
this.generateBundles = undefined;
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;
}
setGenerateBundlesSync(generateBundlesSync) {
this.generateBundlesSync = generateBundlesSync;
this.isSync = sync;
this.regenerateBundles(eager);
}
setIsSync(isSync) {
this.isSync = isSync;
}
init(eager = false) {
this.regenerateBundles(eager);
}
cached(iterable) {
if (this.isSync) {
return CachedSyncIterable.from(iterable);
@ -273,6 +283,9 @@ class Localization {
* @private
*/
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);
let hasAtLeastOneBundle = false;
@ -312,6 +325,10 @@ class Localization {
if (!this.isSync) {
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);
let hasAtLeastOneBundle = false;
@ -488,7 +505,9 @@ class Localization {
}
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
* Localization from Localization.
*/
var getLocalization = (resourceIds) => {
return new Localization(resourceIds);
var getLocalization = () => {
return new Localization();
};
this.Localization = Localization;

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

@ -14,11 +14,9 @@
[scriptable, uuid(7d468600-551f-4fe0-98c9-92a53b63ec8d)]
interface mozILocalization : nsISupports
{
void setGenerateBundles(in jsval generateBundles);
void setGenerateBundlesSync(in jsval generateBundlesSync);
void setIsSync(in boolean isSync);
void activate(in bool aSync, in bool aEager, in jsval aGenerateBundles, in jsval aGenerateBundlesSync);
void init(in boolean aEager);
void setIsSync(in boolean isSync);
unsigned long addResourceIds(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)]
interface mozILocalizationJSM : nsISupports
{
mozILocalization getLocalization(in Array<AString> resourceIds);
mozILocalization getLocalization();
};