Bug 1800044 [wpt PR 36907] - Fix same URL navigation test, a=testonly
[gecko.git] / widget / nsPrinterListBase.cpp
bloba362474cb5b54b12768a2fbe98cdb2fb124a3575
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/gfx/Rect.h"
10 #include "mozilla/IntegerRange.h"
11 #include "mozilla/intl/Localization.h"
12 #include "mozilla/Maybe.h"
13 #include "mozilla/RefPtr.h"
14 #include "xpcpublic.h"
16 using namespace mozilla;
18 using mozilla::ErrorResult;
19 using mozilla::intl::Localization;
20 using PrinterInfo = nsPrinterListBase::PrinterInfo;
21 using MarginDouble = mozilla::gfx::MarginDouble;
23 nsPrinterListBase::nsPrinterListBase() = default;
24 nsPrinterListBase::~nsPrinterListBase() = default;
26 NS_IMPL_CYCLE_COLLECTION(nsPrinterListBase, mPrintersPromise)
28 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsPrinterListBase)
29 NS_INTERFACE_MAP_ENTRY(nsIPrinterList)
30 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrinterList)
31 NS_INTERFACE_MAP_END
33 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsPrinterListBase)
34 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsPrinterListBase)
36 namespace mozilla {
38 template <>
39 void ResolveOrReject(dom::Promise& aPromise, nsPrinterListBase& aList,
40 const nsTArray<PrinterInfo>& aInfo) {
41 nsTArray<RefPtr<nsIPrinter>> printers;
42 printers.SetCapacity(aInfo.Length());
43 for (auto& info : aInfo) {
44 printers.AppendElement(aList.CreatePrinter(info));
46 aPromise.MaybeResolve(printers);
49 template <>
50 void ResolveOrReject(dom::Promise& aPromise, nsPrinterListBase& aList,
51 const Maybe<PrinterInfo>& aInfo) {
52 if (aInfo) {
53 aPromise.MaybeResolve(aList.CreatePrinter(aInfo.value()));
54 } else {
55 aPromise.MaybeRejectWithNotFoundError("Printer not found");
59 } // namespace mozilla
61 NS_IMETHODIMP nsPrinterListBase::GetPrinters(JSContext* aCx,
62 Promise** aResult) {
63 EnsureCommonPaperInfo(aCx);
64 return mozilla::AsyncPromiseAttributeGetter(*this, mPrintersPromise, aCx,
65 aResult, "Printers"_ns,
66 &nsPrinterListBase::Printers);
69 NS_IMETHODIMP nsPrinterListBase::GetPrinterByName(const nsAString& aPrinterName,
70 JSContext* aCx,
71 Promise** aResult) {
72 EnsureCommonPaperInfo(aCx);
73 return PrintBackgroundTaskPromise(*this, aCx, aResult, "PrinterByName"_ns,
74 &nsPrinterListBase::PrinterByName,
75 nsString{aPrinterName});
78 NS_IMETHODIMP nsPrinterListBase::GetPrinterBySystemName(
79 const nsAString& aPrinterName, JSContext* aCx, Promise** aResult) {
80 EnsureCommonPaperInfo(aCx);
81 return PrintBackgroundTaskPromise(
82 *this, aCx, aResult, "PrinterBySystemName"_ns,
83 &nsPrinterListBase::PrinterBySystemName, nsString{aPrinterName});
86 NS_IMETHODIMP nsPrinterListBase::GetNamedOrDefaultPrinter(
87 const nsAString& aPrinterName, JSContext* aCx, Promise** aResult) {
88 EnsureCommonPaperInfo(aCx);
89 return PrintBackgroundTaskPromise(
90 *this, aCx, aResult, "NamedOrDefaultPrinter"_ns,
91 &nsPrinterListBase::NamedOrDefaultPrinter, nsString{aPrinterName});
94 Maybe<PrinterInfo> nsPrinterListBase::NamedOrDefaultPrinter(
95 nsString aName) const {
96 if (Maybe<PrinterInfo> value = PrinterByName(std::move(aName))) {
97 return value;
100 // Since the name had to be passed by-value, we can re-use it to fetch the
101 // default printer name, potentially avoiding an extra string allocation.
102 if (NS_SUCCEEDED(SystemDefaultPrinterName(aName))) {
103 return PrinterByName(std::move(aName));
106 return Nothing();
109 NS_IMETHODIMP nsPrinterListBase::GetFallbackPaperList(JSContext* aCx,
110 Promise** aResult) {
111 ErrorResult rv;
112 nsCOMPtr<nsIGlobalObject> global = xpc::CurrentNativeGlobal(aCx);
113 RefPtr<Promise> promise = Promise::Create(global, rv);
114 if (MOZ_UNLIKELY(rv.Failed())) {
115 *aResult = nullptr;
116 return rv.StealNSResult();
119 EnsureCommonPaperInfo(aCx);
120 nsTArray<RefPtr<nsPaper>> papers;
121 papers.SetCapacity(nsPaper::kNumCommonPaperSizes);
122 for (const auto& info : *mCommonPaperInfo) {
123 papers.AppendElement(MakeRefPtr<nsPaper>(info));
126 promise->MaybeResolve(papers);
127 promise.forget(aResult);
128 return NS_OK;
131 void nsPrinterListBase::EnsureCommonPaperInfo(JSContext* aCx) {
132 MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
133 if (mCommonPaperInfo) {
134 return;
136 RefPtr<CommonPaperInfoArray> localizedPaperInfo =
137 MakeRefPtr<CommonPaperInfoArray>();
138 CommonPaperInfoArray& paperArray = *localizedPaperInfo;
139 // Apply localization to the names while constructing the PaperInfo, if
140 // available (otherwise leave them as the internal keys, which are at least
141 // somewhat recognizable).
142 IgnoredErrorResult rv;
143 nsTArray<nsCString> resIds = {
144 "toolkit/printing/printUI.ftl"_ns,
146 RefPtr<Localization> l10n = Localization::Create(resIds, true);
148 for (auto i : IntegerRange(nsPaper::kNumCommonPaperSizes)) {
149 const CommonPaperSize& size = nsPaper::kCommonPaperSizes[i];
150 PaperInfo& info = paperArray[i];
152 nsAutoCString key{"printui-paper-"};
153 key.Append(size.mLocalizableNameKey);
154 nsAutoCString name;
155 l10n->FormatValueSync(key, {}, name, rv);
157 // Fill out the info with our PWG size and the localized name.
158 info.mId = size.mPWGName;
159 CopyUTF8toUTF16(
160 (rv.Failed() || name.IsEmpty())
161 ? static_cast<const nsCString&>(size.mLocalizableNameKey)
162 : name,
163 info.mName);
164 info.mSize = size.mSize;
165 info.mUnwriteableMargin = Some(MarginDouble{});
167 mCommonPaperInfo = std::move(localizedPaperInfo);