зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1662975 - Don't return from window.print() until the print dialog is closed. r=jwatt
As much as I hate nested event loops, I think we need to do it for this case :) Hopefully print() already assumes nested event loops can happen because of the native dialog so it's already properly set up for this. Differential Revision: https://phabricator.services.mozilla.com/D89254
This commit is contained in:
Родитель
473f41370a
Коммит
c0f4091be3
|
@ -3286,7 +3286,8 @@ already_AddRefed<Promise> nsFrameLoader::PrintPreview(
|
|||
sourceWindow->Print(
|
||||
aPrintSettings,
|
||||
/* aListener = */ nullptr, docShellToCloneInto,
|
||||
/* aIsPreview = */ true,
|
||||
nsGlobalWindowOuter::IsPreview::Yes,
|
||||
nsGlobalWindowOuter::BlockUntilDone::No,
|
||||
[resolve](const PrintPreviewResultInfo& aInfo) { resolve(aInfo); }, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
promise->MaybeReject(std::move(rv));
|
||||
|
@ -3357,7 +3358,8 @@ already_AddRefed<Promise> nsFrameLoader::Print(uint64_t aOuterWindowID,
|
|||
ErrorResult rv;
|
||||
outerWindow->Print(aPrintSettings, listener,
|
||||
/* aDocShellToCloneInto = */ nullptr,
|
||||
/* aIsPreview = */ false,
|
||||
nsGlobalWindowOuter::IsPreview::No,
|
||||
nsGlobalWindowOuter::BlockUntilDone::No,
|
||||
/* aPrintPreviewCallback = */ nullptr, rv);
|
||||
if (rv.Failed()) {
|
||||
promise->MaybeReject(std::move(rv));
|
||||
|
|
|
@ -3613,7 +3613,8 @@ Nullable<WindowProxyHolder> nsGlobalWindowInner::PrintPreview(
|
|||
nsIDocShell* aDocShellToCloneInto, ErrorResult& aError) {
|
||||
FORWARD_TO_OUTER_OR_THROW(Print,
|
||||
(aSettings, aListener, aDocShellToCloneInto,
|
||||
/* aIsPreview = */ true,
|
||||
nsGlobalWindowOuter::IsPreview::Yes,
|
||||
nsGlobalWindowOuter::BlockUntilDone::No,
|
||||
/* aPrintPreviewCallback = */ nullptr, aError),
|
||||
aError, nullptr);
|
||||
}
|
||||
|
|
|
@ -5274,13 +5274,15 @@ void nsGlobalWindowOuter::PrintOuter(ErrorResult& aError) {
|
|||
settings->SetShowPrintProgress(false);
|
||||
}
|
||||
|
||||
Print(settings, nullptr, nullptr, isPreview, nullptr, aError);
|
||||
Print(settings, nullptr, nullptr, IsPreview(isPreview),
|
||||
BlockUntilDone(isPreview), nullptr, aError);
|
||||
#endif
|
||||
}
|
||||
|
||||
Nullable<WindowProxyHolder> nsGlobalWindowOuter::Print(
|
||||
nsIPrintSettings* aPrintSettings, nsIWebProgressListener* aListener,
|
||||
nsIDocShell* aDocShellToCloneInto, bool aIsPreview,
|
||||
nsIDocShell* aDocShellToCloneInto, IsPreview aIsPreview,
|
||||
BlockUntilDone aBlockUntilDone,
|
||||
PrintPreviewResolver&& aPrintPreviewCallback, ErrorResult& aError) {
|
||||
#ifdef NS_PRINTING
|
||||
nsCOMPtr<nsIPrintSettingsService> printSettingsService =
|
||||
|
@ -5310,7 +5312,7 @@ Nullable<WindowProxyHolder> nsGlobalWindowOuter::Print(
|
|||
|
||||
nsCOMPtr<nsIContentViewer> cv;
|
||||
RefPtr<BrowsingContext> bc;
|
||||
if (docToPrint->IsStaticDocument() && aIsPreview) {
|
||||
if (docToPrint->IsStaticDocument() && bool(aIsPreview)) {
|
||||
// We're already a print preview window, just reuse our browsing context /
|
||||
// content viewer.
|
||||
//
|
||||
|
@ -5337,7 +5339,8 @@ Nullable<WindowProxyHolder> nsGlobalWindowOuter::Print(
|
|||
bc = aDocShellToCloneInto->GetBrowsingContext();
|
||||
} else {
|
||||
AutoNoJSAPI nojsapi;
|
||||
auto printKind = aIsPreview ? PrintKind::PrintPreview : PrintKind::Print;
|
||||
auto printKind =
|
||||
bool(aIsPreview) ? PrintKind::PrintPreview : PrintKind::Print;
|
||||
aError = OpenInternal(EmptyString(), EmptyString(), EmptyString(),
|
||||
false, // aDialog
|
||||
false, // aContentModal
|
||||
|
@ -5438,13 +5441,22 @@ Nullable<WindowProxyHolder> nsGlobalWindowOuter::Print(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if (aIsPreview) {
|
||||
if (bool(aIsPreview)) {
|
||||
aError = webBrowserPrint->PrintPreview(aPrintSettings, aListener,
|
||||
std::move(aPrintPreviewCallback));
|
||||
if (aError.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
// Historically we've eaten this error.
|
||||
webBrowserPrint->Print(aPrintSettings, aListener);
|
||||
}
|
||||
|
||||
if (bool(aBlockUntilDone)) {
|
||||
// Wait until print document is closed.
|
||||
SpinEventLoopUntil([&] { return bc->IsDiscarded(); });
|
||||
}
|
||||
|
||||
return WindowProxyHolder(std::move(bc));
|
||||
#else
|
||||
return nullptr;
|
||||
|
|
|
@ -586,9 +586,11 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
|
|||
|
||||
void PrintOuter(mozilla::ErrorResult& aError);
|
||||
|
||||
enum class IsPreview : bool { No, Yes };
|
||||
enum class BlockUntilDone : bool { No, Yes };
|
||||
mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> Print(
|
||||
nsIPrintSettings*, nsIWebProgressListener*, nsIDocShell*, bool aIsPreview,
|
||||
PrintPreviewResolver&& aPrintPreviewCallback, mozilla::ErrorResult&);
|
||||
nsIPrintSettings*, nsIWebProgressListener*, nsIDocShell*, IsPreview,
|
||||
BlockUntilDone, PrintPreviewResolver&&, mozilla::ErrorResult&);
|
||||
mozilla::dom::Selection* GetSelectionOuter();
|
||||
already_AddRefed<mozilla::dom::Selection> GetSelection() override;
|
||||
nsScreen* GetScreen();
|
||||
|
|
|
@ -2285,8 +2285,9 @@ mozilla::ipc::IPCResult BrowserChild::RecvPrintPreview(
|
|||
|
||||
sourceWindow->Print(printSettings,
|
||||
/* aListener = */ nullptr, docShellToCloneInto,
|
||||
/* aIsPreview = */ true, std::move(aCallback),
|
||||
IgnoreErrors());
|
||||
nsGlobalWindowOuter::IsPreview::Yes,
|
||||
nsGlobalWindowOuter::BlockUntilDone::No,
|
||||
std::move(aCallback), IgnoreErrors());
|
||||
#endif
|
||||
return IPC_OK();
|
||||
}
|
||||
|
@ -2338,7 +2339,8 @@ mozilla::ipc::IPCResult BrowserChild::RecvPrint(const uint64_t& aOuterWindowID,
|
|||
outerWindow->Print(printSettings,
|
||||
/* aListener = */ nullptr,
|
||||
/* aWindowToCloneInto = */ nullptr,
|
||||
/* aIsPreview = */ false,
|
||||
nsGlobalWindowOuter::IsPreview::No,
|
||||
nsGlobalWindowOuter::BlockUntilDone::No,
|
||||
/* aPrintPreviewCallback = */ nullptr, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
return IPC_OK();
|
||||
|
|
Загрузка…
Ссылка в новой задаче