tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

FileSource.cpp (6450B)


      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/. */
      6 
      7 #include "FileSource.h"
      8 #include "mozilla/dom/Promise.h"
      9 
     10 using namespace mozilla::dom;
     11 
     12 namespace mozilla::intl {
     13 
     14 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(L10nFileSource, mGlobal)
     15 
     16 L10nFileSource::L10nFileSource(RefPtr<const ffi::FileSource> aRaw,
     17                               nsIGlobalObject* aGlobal)
     18    : mGlobal(aGlobal), mRaw(std::move(aRaw)) {}
     19 
     20 /* static */
     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());
     27 
     28  ffi::L10nFileSourceStatus status;
     29 
     30  bool allowOverrides = aOptions.mAddResourceOptions.mAllowOverrides;
     31 
     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));
     37  } else {
     38    raw = dont_AddRef(ffi::l10nfilesource_new(
     39        &aName, &aMetaSource, &aLocales, &aPrePath, allowOverrides, &status));
     40  }
     41 
     42  if (PopulateError(aRv, status)) {
     43    return nullptr;
     44  }
     45  return MakeAndAddRef<L10nFileSource>(std::move(raw), global);
     46 }
     47 
     48 /* static */
     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,
     53    ErrorResult& aRv) {
     54  nsTArray<ffi::L10nFileSourceMockFile> fs(aFS.Length());
     55  for (const auto& file : aFS) {
     56    auto f = fs.AppendElement();
     57    f->path = file.mPath;
     58    f->source = file.mSource;
     59  }
     60  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
     61 
     62  ffi::L10nFileSourceStatus status;
     63 
     64  RefPtr<const ffi::FileSource> raw(dont_AddRef(ffi::l10nfilesource_new_mock(
     65      &aName, &aMetaSource, &aLocales, &aPrePath, &fs, &status)));
     66 
     67  if (PopulateError(aRv, status)) {
     68    return nullptr;
     69  }
     70  return MakeAndAddRef<L10nFileSource>(std::move(raw), global);
     71 }
     72 
     73 JSObject* L10nFileSource::WrapObject(JSContext* aCx,
     74                                     JS::Handle<JSObject*> aGivenProto) {
     75  return L10nFileSource_Binding::Wrap(aCx, this, aGivenProto);
     76 }
     77 
     78 void L10nFileSource::GetName(nsCString& aRetVal) {
     79  ffi::l10nfilesource_get_name(mRaw.get(), &aRetVal);
     80 }
     81 
     82 void L10nFileSource::GetMetaSource(nsCString& aRetVal) {
     83  ffi::l10nfilesource_get_metasource(mRaw.get(), &aRetVal);
     84 }
     85 
     86 void L10nFileSource::GetLocales(nsTArray<nsCString>& aRetVal) {
     87  ffi::l10nfilesource_get_locales(mRaw.get(), &aRetVal);
     88 }
     89 
     90 void L10nFileSource::GetPrePath(nsCString& aRetVal) {
     91  ffi::l10nfilesource_get_prepath(mRaw.get(), &aRetVal);
     92 }
     93 
     94 void L10nFileSource::GetIndex(Nullable<nsTArray<nsCString>>& aRetVal) {
     95  bool hasIndex =
     96      ffi::l10nfilesource_get_index(mRaw.get(), &aRetVal.SetValue());
     97  if (!hasIndex) {
     98    aRetVal.SetNull();
     99  }
    100 }
    101 
    102 L10nFileSourceHasFileStatus L10nFileSource::HasFile(const nsACString& aLocale,
    103                                                    const nsACString& aPath,
    104                                                    ErrorResult& aRv) {
    105  ffi::L10nFileSourceStatus status;
    106 
    107  bool isPresent = false;
    108  bool hasValue = ffi::l10nfilesource_has_file(mRaw.get(), &aLocale, &aPath,
    109                                               &status, &isPresent);
    110 
    111  if (!PopulateError(aRv, status) && hasValue) {
    112    if (isPresent) {
    113      return L10nFileSourceHasFileStatus::Present;
    114    }
    115 
    116    return L10nFileSourceHasFileStatus::Missing;
    117  }
    118  return L10nFileSourceHasFileStatus::Unknown;
    119 }
    120 
    121 already_AddRefed<FluentResource> L10nFileSource::FetchFileSync(
    122    const nsACString& aLocale, const nsACString& aPath, ErrorResult& aRv) {
    123  ffi::L10nFileSourceStatus status;
    124 
    125  RefPtr<const ffi::FluentResource> raw =
    126      dont_AddRef(ffi::l10nfilesource_fetch_file_sync(mRaw.get(), &aLocale,
    127                                                      &aPath, &status));
    128 
    129  if (!PopulateError(aRv, status) && raw) {
    130    return MakeAndAddRef<FluentResource>(mGlobal, raw);
    131  }
    132 
    133  return nullptr;
    134 }
    135 
    136 already_AddRefed<Promise> L10nFileSource::FetchFile(const nsACString& aLocale,
    137                                                    const nsACString& aPath,
    138                                                    ErrorResult& aRv) {
    139  RefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
    140  if (aRv.Failed()) {
    141    return nullptr;
    142  }
    143 
    144  ffi::L10nFileSourceStatus status;
    145 
    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);
    150 
    151        if (aRes) {
    152          nsIGlobalObject* global = promise->GetGlobalObject();
    153          RefPtr<FluentResource> res = new FluentResource(global, aRes);
    154          promise->MaybeResolve(res);
    155        } else {
    156          promise->MaybeResolve(JS::NullHandleValue);
    157        }
    158      },
    159      &status);
    160 
    161  if (PopulateError(aRv, status)) {
    162    return nullptr;
    163  }
    164 
    165  return promise.forget();
    166 }
    167 
    168 /* static */
    169 bool L10nFileSource::PopulateError(ErrorResult& aError,
    170                                   ffi::L10nFileSourceStatus& aStatus) {
    171  switch (aStatus) {
    172    case ffi::L10nFileSourceStatus::InvalidLocaleCode:
    173      aError.ThrowTypeError("Invalid locale code");
    174      return true;
    175    case ffi::L10nFileSourceStatus::EmptyName:
    176      aError.ThrowTypeError("Name cannot be empty.");
    177      return true;
    178    case ffi::L10nFileSourceStatus::EmptyPrePath:
    179      aError.ThrowTypeError("prePath cannot be empty.");
    180      return true;
    181    case ffi::L10nFileSourceStatus::EmptyResId:
    182      aError.ThrowTypeError("resId cannot be empty.");
    183      return true;
    184 
    185    case ffi::L10nFileSourceStatus::None:
    186      return false;
    187  }
    188  MOZ_ASSERT_UNREACHABLE("Unknown status");
    189  return false;
    190 }
    191 
    192 }  // namespace mozilla::intl