summaryrefslogtreecommitdiffstats
path: root/intl/l10n/FileSource.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'intl/l10n/FileSource.cpp')
-rw-r--r--intl/l10n/FileSource.cpp192
1 files changed, 192 insertions, 0 deletions
diff --git a/intl/l10n/FileSource.cpp b/intl/l10n/FileSource.cpp
new file mode 100644
index 0000000000..2469f597c6
--- /dev/null
+++ b/intl/l10n/FileSource.cpp
@@ -0,0 +1,192 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "FileSource.h"
+#include "mozilla/dom/Promise.h"
+
+using namespace mozilla::dom;
+
+namespace mozilla::intl {
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(L10nFileSource, mGlobal)
+
+L10nFileSource::L10nFileSource(RefPtr<const ffi::FileSource> aRaw,
+ nsIGlobalObject* aGlobal)
+ : mGlobal(aGlobal), mRaw(std::move(aRaw)) {}
+
+/* static */
+already_AddRefed<L10nFileSource> L10nFileSource::Constructor(
+ const GlobalObject& aGlobal, const nsACString& aName,
+ const nsACString& aMetaSource, const nsTArray<nsCString>& aLocales,
+ const nsACString& aPrePath, const dom::FileSourceOptions& aOptions,
+ const Optional<Sequence<nsCString>>& aIndex, ErrorResult& aRv) {
+ nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
+
+ ffi::L10nFileSourceStatus status;
+
+ bool allowOverrides = aOptions.mAddResourceOptions.mAllowOverrides;
+
+ RefPtr<const ffi::FileSource> raw;
+ if (aIndex.WasPassed()) {
+ raw = dont_AddRef(ffi::l10nfilesource_new_with_index(
+ &aName, &aMetaSource, &aLocales, &aPrePath, aIndex.Value().Elements(),
+ aIndex.Value().Length(), allowOverrides, &status));
+ } else {
+ raw = dont_AddRef(ffi::l10nfilesource_new(
+ &aName, &aMetaSource, &aLocales, &aPrePath, allowOverrides, &status));
+ }
+
+ if (PopulateError(aRv, status)) {
+ return nullptr;
+ }
+ return MakeAndAddRef<L10nFileSource>(std::move(raw), global);
+}
+
+/* static */
+already_AddRefed<L10nFileSource> L10nFileSource::CreateMock(
+ const GlobalObject& aGlobal, const nsACString& aName,
+ const nsACString& aMetaSource, const nsTArray<nsCString>& aLocales,
+ const nsACString& aPrePath, const nsTArray<L10nFileSourceMockFile>& aFS,
+ ErrorResult& aRv) {
+ nsTArray<ffi::L10nFileSourceMockFile> fs(aFS.Length());
+ for (const auto& file : aFS) {
+ auto f = fs.AppendElement();
+ f->path = file.mPath;
+ f->source = file.mSource;
+ }
+ nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
+
+ ffi::L10nFileSourceStatus status;
+
+ RefPtr<const ffi::FileSource> raw(dont_AddRef(ffi::l10nfilesource_new_mock(
+ &aName, &aMetaSource, &aLocales, &aPrePath, &fs, &status)));
+
+ if (PopulateError(aRv, status)) {
+ return nullptr;
+ }
+ return MakeAndAddRef<L10nFileSource>(std::move(raw), global);
+}
+
+JSObject* L10nFileSource::WrapObject(JSContext* aCx,
+ JS::Handle<JSObject*> aGivenProto) {
+ return L10nFileSource_Binding::Wrap(aCx, this, aGivenProto);
+}
+
+void L10nFileSource::GetName(nsCString& aRetVal) {
+ ffi::l10nfilesource_get_name(mRaw.get(), &aRetVal);
+}
+
+void L10nFileSource::GetMetaSource(nsCString& aRetVal) {
+ ffi::l10nfilesource_get_metasource(mRaw.get(), &aRetVal);
+}
+
+void L10nFileSource::GetLocales(nsTArray<nsCString>& aRetVal) {
+ ffi::l10nfilesource_get_locales(mRaw.get(), &aRetVal);
+}
+
+void L10nFileSource::GetPrePath(nsCString& aRetVal) {
+ ffi::l10nfilesource_get_prepath(mRaw.get(), &aRetVal);
+}
+
+void L10nFileSource::GetIndex(Nullable<nsTArray<nsCString>>& aRetVal) {
+ bool hasIndex =
+ ffi::l10nfilesource_get_index(mRaw.get(), &aRetVal.SetValue());
+ if (!hasIndex) {
+ aRetVal.SetNull();
+ }
+}
+
+L10nFileSourceHasFileStatus L10nFileSource::HasFile(const nsACString& aLocale,
+ const nsACString& aPath,
+ ErrorResult& aRv) {
+ ffi::L10nFileSourceStatus status;
+
+ bool isPresent = false;
+ bool hasValue = ffi::l10nfilesource_has_file(mRaw.get(), &aLocale, &aPath,
+ &status, &isPresent);
+
+ if (!PopulateError(aRv, status) && hasValue) {
+ if (isPresent) {
+ return L10nFileSourceHasFileStatus::Present;
+ }
+
+ return L10nFileSourceHasFileStatus::Missing;
+ }
+ return L10nFileSourceHasFileStatus::Unknown;
+}
+
+already_AddRefed<FluentResource> L10nFileSource::FetchFileSync(
+ const nsACString& aLocale, const nsACString& aPath, ErrorResult& aRv) {
+ ffi::L10nFileSourceStatus status;
+
+ RefPtr<const ffi::FluentResource> raw =
+ dont_AddRef(ffi::l10nfilesource_fetch_file_sync(mRaw.get(), &aLocale,
+ &aPath, &status));
+
+ if (!PopulateError(aRv, status) && raw) {
+ return MakeAndAddRef<FluentResource>(mGlobal, raw);
+ }
+
+ return nullptr;
+}
+
+already_AddRefed<Promise> L10nFileSource::FetchFile(const nsACString& aLocale,
+ const nsACString& aPath,
+ ErrorResult& aRv) {
+ RefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
+ if (aRv.Failed()) {
+ return nullptr;
+ }
+
+ ffi::L10nFileSourceStatus status;
+
+ ffi::l10nfilesource_fetch_file(
+ mRaw.get(), &aLocale, &aPath, promise,
+ [](const Promise* aPromise, const ffi::FluentResource* aRes) {
+ Promise* promise = const_cast<Promise*>(aPromise);
+
+ if (aRes) {
+ nsIGlobalObject* global = promise->GetGlobalObject();
+ RefPtr<FluentResource> res = new FluentResource(global, aRes);
+ promise->MaybeResolve(res);
+ } else {
+ promise->MaybeResolve(JS::NullHandleValue);
+ }
+ },
+ &status);
+
+ if (PopulateError(aRv, status)) {
+ return nullptr;
+ }
+
+ return promise.forget();
+}
+
+/* static */
+bool L10nFileSource::PopulateError(ErrorResult& aError,
+ ffi::L10nFileSourceStatus& aStatus) {
+ switch (aStatus) {
+ case ffi::L10nFileSourceStatus::InvalidLocaleCode:
+ aError.ThrowTypeError("Invalid locale code");
+ return true;
+ case ffi::L10nFileSourceStatus::EmptyName:
+ aError.ThrowTypeError("Name cannot be empty.");
+ return true;
+ case ffi::L10nFileSourceStatus::EmptyPrePath:
+ aError.ThrowTypeError("prePath cannot be empty.");
+ return true;
+ case ffi::L10nFileSourceStatus::EmptyResId:
+ aError.ThrowTypeError("resId cannot be empty.");
+ return true;
+
+ case ffi::L10nFileSourceStatus::None:
+ return false;
+ }
+ MOZ_ASSERT_UNREACHABLE("Unknown status");
+ return false;
+}
+
+} // namespace mozilla::intl