Bug 1769775 - Add a MozPromise version of CanonicalBrowsingContext::Print. r=jwatt

And use it to implement the JS version of the method. This should avoid
the various complications that bug 1659819 hit.

Differential Revision: https://phabricator.services.mozilla.com/D146590
This commit is contained in:
Emilio Cobos Álvarez 2022-05-17 16:02:35 +00:00
Родитель 63a6d7f639
Коммит 4843d67a94
4 изменённых файлов: 36 добавлений и 24 удалений

Просмотреть файл

@ -627,10 +627,12 @@ CanonicalBrowsingContext::ReplaceLoadingSessionHistoryEntryForLoad(
return nullptr;
}
using PrintPromise = CanonicalBrowsingContext::PrintPromise;
#ifdef NS_PRINTING
class PrintListenerAdapter final : public nsIWebProgressListener {
public:
explicit PrintListenerAdapter(Promise* aPromise) : mPromise(aPromise) {}
explicit PrintListenerAdapter(PrintPromise::Private* aPromise)
: mPromise(aPromise) {}
NS_DECL_ISUPPORTS
@ -639,7 +641,7 @@ class PrintListenerAdapter final : public nsIWebProgressListener {
uint32_t aStateFlags, nsresult aStatus) override {
if (aStateFlags & nsIWebProgressListener::STATE_STOP &&
aStateFlags & nsIWebProgressListener::STATE_IS_DOCUMENT && mPromise) {
mPromise->MaybeResolveWithUndefined();
mPromise->Resolve(true, __func__);
mPromise = nullptr;
}
return NS_OK;
@ -648,7 +650,7 @@ class PrintListenerAdapter final : public nsIWebProgressListener {
nsresult aStatus,
const char16_t* aMessage) override {
if (aStatus != NS_OK && mPromise) {
mPromise->MaybeReject(ErrorResult(aStatus));
mPromise->Reject(aStatus, __func__);
mPromise = nullptr;
}
return NS_OK;
@ -678,31 +680,41 @@ class PrintListenerAdapter final : public nsIWebProgressListener {
private:
~PrintListenerAdapter() = default;
RefPtr<Promise> mPromise;
RefPtr<PrintPromise::Private> mPromise;
};
NS_IMPL_ISUPPORTS(PrintListenerAdapter, nsIWebProgressListener)
#endif
already_AddRefed<Promise> CanonicalBrowsingContext::Print(
already_AddRefed<Promise> CanonicalBrowsingContext::PrintJS(
nsIPrintSettings* aPrintSettings, ErrorResult& aRv) {
RefPtr<Promise> promise = Promise::Create(GetIncumbentGlobal(), aRv);
if (NS_WARN_IF(aRv.Failed())) {
return promise.forget();
}
#ifndef NS_PRINTING
promise->MaybeReject(ErrorResult(NS_ERROR_NOT_AVAILABLE));
Print(aPrintSettings)
->Then(
GetCurrentSerialEventTarget(), __func__,
[promise](bool) { promise->MaybeResolveWithUndefined(); },
[promise](nsresult aResult) { promise->MaybeReject(aResult); });
return promise.forget();
}
RefPtr<PrintPromise> CanonicalBrowsingContext::Print(
nsIPrintSettings* aPrintSettings) {
#ifndef NS_PRINTING
return PrintPromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE, __func__);
#else
auto promise = MakeRefPtr<PrintPromise::Private>(__func__);
auto listener = MakeRefPtr<PrintListenerAdapter>(promise);
if (IsInProcess()) {
RefPtr<nsGlobalWindowOuter> outerWindow =
nsGlobalWindowOuter::Cast(GetDOMWindow());
if (NS_WARN_IF(!outerWindow)) {
promise->MaybeReject(ErrorResult(NS_ERROR_FAILURE));
return promise.forget();
promise->Reject(NS_ERROR_FAILURE, __func__);
return promise;
}
ErrorResult rv;
@ -713,22 +725,22 @@ already_AddRefed<Promise> CanonicalBrowsingContext::Print(
nsGlobalWindowOuter::IsForWindowDotPrint::No,
/* aPrintPreviewCallback = */ nullptr, rv);
if (rv.Failed()) {
promise->MaybeReject(std::move(rv));
promise->Reject(rv.StealNSResult(), __func__);
}
return promise.forget();
return promise;
}
auto* browserParent = GetBrowserParent();
if (NS_WARN_IF(!browserParent)) {
promise->MaybeReject(ErrorResult(NS_ERROR_FAILURE));
return promise.forget();
promise->Reject(NS_ERROR_FAILURE, __func__);
return promise;
}
nsCOMPtr<nsIPrintSettingsService> printSettingsSvc =
do_GetService("@mozilla.org/gfx/printsettings-service;1");
if (NS_WARN_IF(!printSettingsSvc)) {
promise->MaybeReject(ErrorResult(NS_ERROR_FAILURE));
return promise.forget();
promise->Reject(NS_ERROR_FAILURE, __func__);
return promise;
}
nsresult rv;
@ -737,16 +749,16 @@ already_AddRefed<Promise> CanonicalBrowsingContext::Print(
rv =
printSettingsSvc->CreateNewPrintSettings(getter_AddRefs(printSettings));
if (NS_WARN_IF(NS_FAILED(rv))) {
promise->MaybeReject(ErrorResult(rv));
return promise.forget();
promise->Reject(rv, __func__);
return promise;
}
}
embedding::PrintData printData;
rv = printSettingsSvc->SerializeToPrintData(printSettings, &printData);
if (NS_WARN_IF(NS_FAILED(rv))) {
promise->MaybeReject(ErrorResult(rv));
return promise.forget();
promise->Reject(rv, __func__);
return promise;
}
layout::RemotePrintJobParent* remotePrintJob =
@ -759,7 +771,7 @@ already_AddRefed<Promise> CanonicalBrowsingContext::Print(
}
if (NS_WARN_IF(!browserParent->SendPrint(this, printData))) {
promise->MaybeReject(ErrorResult(NS_ERROR_FAILURE));
promise->Reject(NS_ERROR_FAILURE, __func__);
}
return promise.forget();
#endif

Просмотреть файл

@ -134,8 +134,9 @@ class CanonicalBrowsingContext final : public BrowsingContext {
UniquePtr<LoadingSessionHistoryInfo> ReplaceLoadingSessionHistoryEntryForLoad(
LoadingSessionHistoryInfo* aInfo, nsIChannel* aNewChannel);
already_AddRefed<Promise> Print(nsIPrintSettings* aPrintSettings,
ErrorResult& aRv);
using PrintPromise = MozPromise</* unused */ bool, nsresult, false>;
RefPtr<PrintPromise> Print(nsIPrintSettings*);
already_AddRefed<Promise> PrintJS(nsIPrintSettings*, ErrorResult&);
// Call the given callback on all top-level descendant BrowsingContexts.
// Return Callstate::Stop from the callback to stop calling

Просмотреть файл

@ -299,7 +299,7 @@ interface CanonicalBrowsingContext : BrowsingContext {
* set to prevent prompting.
* @return A Promise that resolves once printing is finished.
*/
[NewObject]
[NewObject, BinaryName="printJS"]
Promise<void> print(nsIPrintSettings aPrintSettings);
/**

Просмотреть файл

@ -10,7 +10,6 @@
#include "mozilla/Attributes.h"
#include "mozilla/IntegerRange.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/CanonicalBrowsingContext.h"
#include "mozilla/dom/SessionStoreUtilsBinding.h"
#include "SessionStoreData.h"
#include "SessionStoreRestoreData.h"