1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_intl_l10n_Localization_h
8 #define mozilla_intl_l10n_Localization_h
10 #include "nsCycleCollectionParticipant.h"
11 #include "nsIObserver.h"
12 #include "nsWeakReference.h"
13 #include "nsWrapperCache.h"
14 #include "nsWeakReference.h"
15 #include "nsIScriptError.h"
16 #include "nsContentUtils.h"
17 #include "nsPIDOMWindow.h"
18 #include "mozilla/ErrorResult.h"
19 #include "mozilla/dom/Promise.h"
20 #include "mozilla/dom/BindingDeclarations.h"
21 #include "mozilla/dom/LocalizationBinding.h"
22 #include "mozilla/intl/LocalizationBindings.h"
23 #include "mozilla/intl/L10nRegistry.h"
28 // The state where the application contains incomplete localization resources
29 // is much more common than for other types of core resources.
31 // In result, our localization is designed to handle missing resources
32 // gracefully, and we need a more fine-tuned way to communicate those problems
35 // In particular, we want developers and early adopters to be able to reason
36 // about missing translations, without bothering end user in production, where
37 // the user cannot react to that.
39 // We currently differentiate between nightly/dev-edition builds or automation
40 // where we report the errors, and beta/release, where we silence them.
42 // A side effect of the conditional model of strict vs loose error handling is
43 // that we don't have a way to write integration tests for behavior we expect
44 // out of production environment. See bug 1741430.
45 [[maybe_unused
]] static bool MaybeReportErrorsToGecko(
46 const nsTArray
<nsCString
>& aErrors
, ErrorResult
& aRv
,
47 nsIGlobalObject
* aGlobal
) {
48 if (!aErrors
.IsEmpty()) {
49 if (xpc::IsInAutomation()) {
50 aRv
.ThrowInvalidStateError(aErrors
.ElementAt(0));
54 #if defined(NIGHTLY_BUILD) || defined(MOZ_DEV_EDITION) || defined(DEBUG)
55 dom::Document
* doc
= nullptr;
57 nsPIDOMWindowInner
* innerWindow
= aGlobal
->GetAsInnerWindow();
59 doc
= innerWindow
->GetExtantDoc();
63 for (const auto& error
: aErrors
) {
64 nsContentUtils::ReportToConsoleNonLocalized(NS_ConvertUTF8toUTF16(error
),
65 nsIScriptError::warningFlag
,
67 printf_stderr("%s\n", error
.get());
75 class Localization
: public nsIObserver
,
76 public nsWrapperCache
,
77 public nsSupportsWeakReference
{
78 template <typename T
, typename
... Args
>
79 friend already_AddRefed
<T
> mozilla::MakeAndAddRef(Args
&&... aArgs
);
82 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
83 NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS_AMBIGUOUS(Localization
,
87 static already_AddRefed
<Localization
> Constructor(
88 const dom::GlobalObject
& aGlobal
,
89 const dom::Sequence
<dom::OwningUTF8StringOrResourceId
>& aResourceIds
,
90 bool aIsSync
, const dom::Optional
<dom::NonNull
<L10nRegistry
>>& aRegistry
,
91 const dom::Optional
<dom::Sequence
<nsCString
>>& aLocales
,
93 static already_AddRefed
<Localization
> Create(
94 const nsTArray
<nsCString
>& aResourceIds
, bool aIsSync
);
95 static already_AddRefed
<Localization
> Create(
96 const nsTArray
<ffi::GeckoResourceId
>& aResourceIds
, bool aIsSync
);
98 JSObject
* WrapObject(JSContext
* aCx
,
99 JS::Handle
<JSObject
*> aGivenProto
) override
;
100 nsIGlobalObject
* GetParentObject() const { return mGlobal
; }
102 void SetIsSync(bool aIsSync
);
104 already_AddRefed
<dom::Promise
> FormatValue(
105 const nsACString
& aId
, const dom::Optional
<L10nArgs
>& aArgs
,
108 already_AddRefed
<dom::Promise
> FormatValues(
109 const dom::Sequence
<dom::OwningUTF8StringOrL10nIdArgs
>& aKeys
,
112 already_AddRefed
<dom::Promise
> FormatMessages(
113 const dom::Sequence
<dom::OwningUTF8StringOrL10nIdArgs
>& aKeys
,
116 void FormatValueSync(const nsACString
& aId
,
117 const dom::Optional
<L10nArgs
>& aArgs
,
118 nsACString
& aRetVal
, ErrorResult
& aRv
);
119 void FormatValuesSync(
120 const dom::Sequence
<dom::OwningUTF8StringOrL10nIdArgs
>& aKeys
,
121 nsTArray
<nsCString
>& aRetVal
, ErrorResult
& aRv
);
122 void FormatMessagesSync(
123 const dom::Sequence
<dom::OwningUTF8StringOrL10nIdArgs
>& aKeys
,
124 nsTArray
<dom::Nullable
<dom::L10nMessage
>>& aRetVal
, ErrorResult
& aRv
);
126 void AddResourceId(const ffi::GeckoResourceId
& aResourceId
);
127 void AddResourceId(const nsCString
& aResourceId
);
128 void AddResourceId(const dom::OwningUTF8StringOrResourceId
& aResourceId
);
129 uint32_t RemoveResourceId(const ffi::GeckoResourceId
& aResourceId
);
130 uint32_t RemoveResourceId(const nsCString
& aResourceId
);
131 uint32_t RemoveResourceId(
132 const dom::OwningUTF8StringOrResourceId
& aResourceId
);
134 const nsTArray
<dom::OwningUTF8StringOrResourceId
>& aResourceIds
);
135 uint32_t RemoveResourceIds(
136 const nsTArray
<dom::OwningUTF8StringOrResourceId
>& aResourceIds
);
142 Localization(const nsTArray
<nsCString
>& aResIds
, bool aIsSync
);
143 Localization(const nsTArray
<ffi::GeckoResourceId
>& aResIds
, bool aIsSync
);
144 Localization(nsIGlobalObject
* aGlobal
, bool aIsSync
);
146 Localization(nsIGlobalObject
* aGlobal
, const nsTArray
<nsCString
>& aResIds
,
149 Localization(nsIGlobalObject
* aGlobal
, bool aIsSync
,
150 const ffi::LocalizationRc
* aRaw
);
152 virtual ~Localization();
154 void RegisterObservers();
155 virtual void OnChange();
156 already_AddRefed
<dom::Promise
> MaybeWrapPromise(dom::Promise
* aInnerPromise
);
158 nsCOMPtr
<nsIGlobalObject
> mGlobal
;
159 RefPtr
<const ffi::LocalizationRc
> mRaw
;
163 } // namespace mozilla