diff options
Diffstat (limited to 'intl/l10n/FileSource.cpp')
-rw-r--r-- | intl/l10n/FileSource.cpp | 192 |
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 |