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
)
33 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsPrinterListBase
)
34 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsPrinterListBase
)
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
);
50 void ResolveOrReject(dom::Promise
& aPromise
, nsPrinterListBase
& aList
,
51 const Maybe
<PrinterInfo
>& aInfo
) {
53 aPromise
.MaybeResolve(aList
.CreatePrinter(aInfo
.value()));
55 aPromise
.MaybeRejectWithNotFoundError("Printer not found");
59 } // namespace mozilla
61 NS_IMETHODIMP
nsPrinterListBase::GetPrinters(JSContext
* aCx
,
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
,
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
))) {
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
));
109 NS_IMETHODIMP
nsPrinterListBase::GetFallbackPaperList(JSContext
* aCx
,
112 nsCOMPtr
<nsIGlobalObject
> global
= xpc::CurrentNativeGlobal(aCx
);
113 RefPtr
<Promise
> promise
= Promise::Create(global
, rv
);
114 if (MOZ_UNLIKELY(rv
.Failed())) {
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
);
131 void nsPrinterListBase::EnsureCommonPaperInfo(JSContext
* aCx
) {
132 MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
133 if (mCommonPaperInfo
) {
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
);
155 l10n
->FormatValueSync(key
, {}, name
, rv
);
157 // Fill out the info with our PWG size and the localized name.
158 info
.mId
= size
.mPWGName
;
160 (rv
.Failed() || name
.IsEmpty())
161 ? static_cast<const nsCString
&>(size
.mLocalizableNameKey
)
164 info
.mSize
= size
.mSize
;
165 info
.mUnwriteableMargin
= Some(MarginDouble
{});
167 mCommonPaperInfo
= std::move(localizedPaperInfo
);