Bug 1737746 - Use Permission spec's PermissionState r=mt,peterv
[gecko.git] / widget / nsPrinterListBase.cpp
bloba1ba5a7c8eeae7041a942b34d9192dbb206dfd8e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "nsPrinterListBase.h"
7 #include "PrintBackgroundTask.h"
8 #include "mozilla/ErrorResult.h"
9 #include "mozilla/intl/Localization.h"
10 #include "xpcpublic.h"
12 using mozilla::ErrorResult;
13 using mozilla::intl::Localization;
14 using PrinterInfo = nsPrinterListBase::PrinterInfo;
16 nsPrinterListBase::nsPrinterListBase() = default;
17 nsPrinterListBase::~nsPrinterListBase() = default;
19 NS_IMPL_CYCLE_COLLECTION(nsPrinterListBase, mPrintersPromise)
21 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsPrinterListBase)
22 NS_INTERFACE_MAP_ENTRY(nsIPrinterList)
23 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrinterList)
24 NS_INTERFACE_MAP_END
26 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsPrinterListBase)
27 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsPrinterListBase)
29 namespace mozilla {
31 template <>
32 void ResolveOrReject(dom::Promise& aPromise, nsPrinterListBase& aList,
33 const nsTArray<PrinterInfo>& aInfo) {
34 nsTArray<RefPtr<nsIPrinter>> printers;
35 printers.SetCapacity(aInfo.Length());
36 for (auto& info : aInfo) {
37 printers.AppendElement(aList.CreatePrinter(info));
39 aPromise.MaybeResolve(printers);
42 template <>
43 void ResolveOrReject(dom::Promise& aPromise, nsPrinterListBase& aList,
44 const Maybe<PrinterInfo>& aInfo) {
45 if (aInfo) {
46 aPromise.MaybeResolve(aList.CreatePrinter(aInfo.value()));
47 } else {
48 aPromise.MaybeRejectWithNotFoundError("Printer not found");
52 } // namespace mozilla
54 NS_IMETHODIMP nsPrinterListBase::GetPrinters(JSContext* aCx,
55 Promise** aResult) {
56 EnsureCommonPaperInfo(aCx);
57 return mozilla::AsyncPromiseAttributeGetter(*this, mPrintersPromise, aCx,
58 aResult, "Printers"_ns,
59 &nsPrinterListBase::Printers);
62 NS_IMETHODIMP nsPrinterListBase::GetPrinterByName(const nsAString& aPrinterName,
63 JSContext* aCx,
64 Promise** aResult) {
65 EnsureCommonPaperInfo(aCx);
66 return PrintBackgroundTaskPromise(*this, aCx, aResult, "PrinterByName"_ns,
67 &nsPrinterListBase::PrinterByName,
68 nsString{aPrinterName});
71 NS_IMETHODIMP nsPrinterListBase::GetPrinterBySystemName(
72 const nsAString& aPrinterName, JSContext* aCx, Promise** aResult) {
73 EnsureCommonPaperInfo(aCx);
74 return PrintBackgroundTaskPromise(
75 *this, aCx, aResult, "PrinterBySystemName"_ns,
76 &nsPrinterListBase::PrinterBySystemName, nsString{aPrinterName});
79 NS_IMETHODIMP nsPrinterListBase::GetNamedOrDefaultPrinter(
80 const nsAString& aPrinterName, JSContext* aCx, Promise** aResult) {
81 EnsureCommonPaperInfo(aCx);
82 return PrintBackgroundTaskPromise(
83 *this, aCx, aResult, "NamedOrDefaultPrinter"_ns,
84 &nsPrinterListBase::NamedOrDefaultPrinter, nsString{aPrinterName});
87 Maybe<PrinterInfo> nsPrinterListBase::NamedOrDefaultPrinter(
88 nsString aName) const {
89 if (Maybe<PrinterInfo> value = PrinterByName(std::move(aName))) {
90 return value;
93 // Since the name had to be passed by-value, we can re-use it to fetch the
94 // default printer name, potentially avoiding an extra string allocation.
95 if (NS_SUCCEEDED(SystemDefaultPrinterName(aName))) {
96 return PrinterByName(std::move(aName));
99 return Nothing();
102 NS_IMETHODIMP nsPrinterListBase::GetFallbackPaperList(JSContext* aCx,
103 Promise** aResult) {
104 ErrorResult rv;
105 nsCOMPtr<nsIGlobalObject> global = xpc::CurrentNativeGlobal(aCx);
106 RefPtr<Promise> promise = Promise::Create(global, rv);
107 if (MOZ_UNLIKELY(rv.Failed())) {
108 *aResult = nullptr;
109 return rv.StealNSResult();
112 EnsureCommonPaperInfo(aCx);
113 nsTArray<RefPtr<nsPaper>> papers;
114 papers.SetCapacity(nsPaper::kNumCommonPaperSizes);
115 for (const auto& info : *mCommonPaperInfo) {
116 papers.AppendElement(MakeRefPtr<nsPaper>(info));
119 promise->MaybeResolve(papers);
120 promise.forget(aResult);
121 return NS_OK;
124 void nsPrinterListBase::EnsureCommonPaperInfo(JSContext* aCx) {
125 MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
126 if (mCommonPaperInfo) {
127 return;
129 RefPtr<CommonPaperInfoArray> localizedPaperInfo =
130 MakeRefPtr<CommonPaperInfoArray>();
131 CommonPaperInfoArray& paperArray = *localizedPaperInfo;
132 // Apply localization to the names while constructing the PaperInfo, if
133 // available (otherwise leave them as the internal keys, which are at least
134 // somewhat recognizable).
135 IgnoredErrorResult rv;
136 nsTArray<nsCString> resIds = {
137 "toolkit/printing/printUI.ftl"_ns,
139 RefPtr<Localization> l10n = Localization::Create(resIds, true);
141 for (auto i : IntegerRange(nsPaper::kNumCommonPaperSizes)) {
142 const CommonPaperSize& size = nsPaper::kCommonPaperSizes[i];
143 PaperInfo& info = paperArray[i];
145 nsAutoCString key{"printui-paper-"};
146 key.Append(size.mLocalizableNameKey);
147 nsAutoCString name;
148 l10n->FormatValueSync(key, {}, name, rv);
150 // Fill out the info with our PWG size and the localized name.
151 info.mId = size.mPWGName;
152 CopyUTF8toUTF16(
153 (rv.Failed() || name.IsEmpty())
154 ? static_cast<const nsCString&>(size.mLocalizableNameKey)
155 : name,
156 info.mName);
157 info.mSize = size.mSize;
158 info.mUnwriteableMargin = Some(MarginDouble{});
160 mCommonPaperInfo = std::move(localizedPaperInfo);