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 #include "FileSource.h"
8 #include "mozilla/dom/Promise.h"
10 using namespace mozilla::dom
;
12 namespace mozilla::intl
{
14 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(L10nFileSource
, mGlobal
)
16 L10nFileSource::L10nFileSource(RefPtr
<const ffi::FileSource
> aRaw
,
17 nsIGlobalObject
* aGlobal
)
18 : mGlobal(aGlobal
), mRaw(std::move(aRaw
)) {}
21 already_AddRefed
<L10nFileSource
> L10nFileSource::Constructor(
22 const GlobalObject
& aGlobal
, const nsACString
& aName
,
23 const nsACString
& aMetaSource
, const nsTArray
<nsCString
>& aLocales
,
24 const nsACString
& aPrePath
, const dom::FileSourceOptions
& aOptions
,
25 const Optional
<Sequence
<nsCString
>>& aIndex
, ErrorResult
& aRv
) {
26 nsCOMPtr
<nsIGlobalObject
> global
= do_QueryInterface(aGlobal
.GetAsSupports());
28 ffi::L10nFileSourceStatus status
;
30 bool allowOverrides
= aOptions
.mAddResourceOptions
.mAllowOverrides
;
32 RefPtr
<const ffi::FileSource
> raw
;
33 if (aIndex
.WasPassed()) {
34 raw
= dont_AddRef(ffi::l10nfilesource_new_with_index(
35 &aName
, &aMetaSource
, &aLocales
, &aPrePath
, aIndex
.Value().Elements(),
36 aIndex
.Value().Length(), allowOverrides
, &status
));
38 raw
= dont_AddRef(ffi::l10nfilesource_new(
39 &aName
, &aMetaSource
, &aLocales
, &aPrePath
, allowOverrides
, &status
));
42 if (PopulateError(aRv
, status
)) {
45 return MakeAndAddRef
<L10nFileSource
>(std::move(raw
), global
);
49 already_AddRefed
<L10nFileSource
> L10nFileSource::CreateMock(
50 const GlobalObject
& aGlobal
, const nsACString
& aName
,
51 const nsACString
& aMetaSource
, const nsTArray
<nsCString
>& aLocales
,
52 const nsACString
& aPrePath
, const nsTArray
<L10nFileSourceMockFile
>& aFS
,
54 nsTArray
<ffi::L10nFileSourceMockFile
> fs(aFS
.Length());
55 for (const auto& file
: aFS
) {
56 auto f
= fs
.AppendElement();
58 f
->source
= file
.mSource
;
60 nsCOMPtr
<nsIGlobalObject
> global
= do_QueryInterface(aGlobal
.GetAsSupports());
62 ffi::L10nFileSourceStatus status
;
64 RefPtr
<const ffi::FileSource
> raw(dont_AddRef(ffi::l10nfilesource_new_mock(
65 &aName
, &aMetaSource
, &aLocales
, &aPrePath
, &fs
, &status
)));
67 if (PopulateError(aRv
, status
)) {
70 return MakeAndAddRef
<L10nFileSource
>(std::move(raw
), global
);
73 JSObject
* L10nFileSource::WrapObject(JSContext
* aCx
,
74 JS::Handle
<JSObject
*> aGivenProto
) {
75 return L10nFileSource_Binding::Wrap(aCx
, this, aGivenProto
);
78 void L10nFileSource::GetName(nsCString
& aRetVal
) {
79 ffi::l10nfilesource_get_name(mRaw
.get(), &aRetVal
);
82 void L10nFileSource::GetMetaSource(nsCString
& aRetVal
) {
83 ffi::l10nfilesource_get_metasource(mRaw
.get(), &aRetVal
);
86 void L10nFileSource::GetLocales(nsTArray
<nsCString
>& aRetVal
) {
87 ffi::l10nfilesource_get_locales(mRaw
.get(), &aRetVal
);
90 void L10nFileSource::GetPrePath(nsCString
& aRetVal
) {
91 ffi::l10nfilesource_get_prepath(mRaw
.get(), &aRetVal
);
94 void L10nFileSource::GetIndex(Nullable
<nsTArray
<nsCString
>>& aRetVal
) {
96 ffi::l10nfilesource_get_index(mRaw
.get(), &aRetVal
.SetValue());
102 L10nFileSourceHasFileStatus
L10nFileSource::HasFile(const nsACString
& aLocale
,
103 const nsACString
& aPath
,
105 ffi::L10nFileSourceStatus status
;
107 bool isPresent
= false;
108 bool hasValue
= ffi::l10nfilesource_has_file(mRaw
.get(), &aLocale
, &aPath
,
109 &status
, &isPresent
);
111 if (!PopulateError(aRv
, status
) && hasValue
) {
113 return L10nFileSourceHasFileStatus::Present
;
116 return L10nFileSourceHasFileStatus::Missing
;
118 return L10nFileSourceHasFileStatus::Unknown
;
121 already_AddRefed
<FluentResource
> L10nFileSource::FetchFileSync(
122 const nsACString
& aLocale
, const nsACString
& aPath
, ErrorResult
& aRv
) {
123 ffi::L10nFileSourceStatus status
;
125 RefPtr
<const ffi::FluentResource
> raw
=
126 dont_AddRef(ffi::l10nfilesource_fetch_file_sync(mRaw
.get(), &aLocale
,
129 if (!PopulateError(aRv
, status
) && raw
) {
130 return MakeAndAddRef
<FluentResource
>(mGlobal
, raw
);
136 already_AddRefed
<Promise
> L10nFileSource::FetchFile(const nsACString
& aLocale
,
137 const nsACString
& aPath
,
139 RefPtr
<Promise
> promise
= Promise::Create(mGlobal
, aRv
);
144 ffi::L10nFileSourceStatus status
;
146 ffi::l10nfilesource_fetch_file(
147 mRaw
.get(), &aLocale
, &aPath
, promise
,
148 [](const Promise
* aPromise
, const ffi::FluentResource
* aRes
) {
149 Promise
* promise
= const_cast<Promise
*>(aPromise
);
152 nsIGlobalObject
* global
= promise
->GetGlobalObject();
153 RefPtr
<FluentResource
> res
= new FluentResource(global
, aRes
);
154 promise
->MaybeResolve(res
);
156 promise
->MaybeResolve(JS::NullHandleValue
);
161 if (PopulateError(aRv
, status
)) {
165 return promise
.forget();
169 bool L10nFileSource::PopulateError(ErrorResult
& aError
,
170 ffi::L10nFileSourceStatus
& aStatus
) {
172 case ffi::L10nFileSourceStatus::InvalidLocaleCode
:
173 aError
.ThrowTypeError("Invalid locale code");
175 case ffi::L10nFileSourceStatus::EmptyName
:
176 aError
.ThrowTypeError("Name cannot be empty.");
178 case ffi::L10nFileSourceStatus::EmptyPrePath
:
179 aError
.ThrowTypeError("prePath cannot be empty.");
181 case ffi::L10nFileSourceStatus::EmptyResId
:
182 aError
.ThrowTypeError("resId cannot be empty.");
185 case ffi::L10nFileSourceStatus::None
:
188 MOZ_ASSERT_UNREACHABLE("Unknown status");
192 } // namespace mozilla::intl