Bug 1653319. Use the new FrameLoader.printPreview API in the frontend. r=mstriemer,emalysz,emilio

Differential Revision: https://phabricator.services.mozilla.com/D88704
This commit is contained in:
Jonathan Watt 2020-09-02 15:13:14 +00:00
Родитель c965e9c886
Коммит 937e0617f0
2 изменённых файлов: 60 добавлений и 74 удалений

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

@ -651,10 +651,28 @@ nsresult nsPrintJob::DoCommonPrint(bool aIsPrintPreview,
// The dialog is not shown, but this means we don't need to access the printer
// driver from the child, which causes sandboxing issues.
if (!mIsCreatingPrintPreview || printingViaParent) {
bool printSilently = false;
printData->mPrintSettings->GetPrintSilent(&printSilently);
if (StaticPrefs::print_always_print_silent()) {
printSilently = true;
bool printSilentOnSettings = false;
printData->mPrintSettings->GetPrintSilent(&printSilentOnSettings);
bool printSilently =
printSilentOnSettings || StaticPrefs::print_always_print_silent();
// The new print UI does not need to enter ShowPrintDialog below to spin
// the event loop and fetch real printer settings from the parent process,
// since it always passes complete print settings. (In fact, trying to
// fetch them from the parent can cause crashes.) Here we check for that
// case so that we can avoid calling ShowPrintDialog below. To err on the
// safe side, we exclude the old UI and non-frontend callers
// (Extensions.tabs.saveAsPDF()) which set `printSilent` on the settings
// object.
// We should remove the exception for tabx.saveAsPDF soon:
// https://bugzilla.mozilla.org/show_bug.cgi?id=1662222
// Slightly longer term we'll remove the old print UI, and even change the
// check for `isInitializedFromPrinter` to a MOZ_DIAGNOSTIC_ASSERT.
bool settingsAreComplete = false;
if (StaticPrefs::print_tab_modal_enabled() && !printSilentOnSettings) {
printData->mPrintSettings->GetIsInitializedFromPrinter(
&settingsAreComplete);
}
// Ask dialog to be Print Shown via the Plugable Printing Dialog Service
@ -662,7 +680,7 @@ nsresult nsPrintJob::DoCommonPrint(bool aIsPrintPreview,
// If printing silently or you can't get the service continue on
// If printing via the parent then we need to confirm that the pref is set
// and get a remote print job, but the parent won't display a prompt.
if (!printSilently || printingViaParent) {
if (!settingsAreComplete && (!printSilently || printingViaParent)) {
nsCOMPtr<nsIPrintingPromptService> printPromptService(
do_GetService(kPrintingPromptService));
if (printPromptService) {
@ -752,7 +770,16 @@ nsresult nsPrintJob::DoCommonPrint(bool aIsPrintPreview,
// No dialog service available
rv = NS_ERROR_NOT_IMPLEMENTED;
}
} else {
} else if (printSilently && !printingViaParent) {
// The condition above is only so contorted in order to enter this block
// under the exact same circumstances as we used to, in order to
// minimize risk for this change which may be getting late Beta uplift.
// Frankly calling SetupSilentPrinting should not be necessary any more
// since nsDeviceContextSpecGTK::EndDocument does what we need using a
// Runnable instead of spinning an event loop in a risk place like here.
// Additionally we should never need to do this when setting up print
// preview, we would only need it for printing.
// Call any code that requires a run of the event loop.
rv = printData->mPrintSettings->SetupSilentPrinting();
}
@ -1077,6 +1104,11 @@ nsresult nsPrintJob::CleanupOnFailure(nsresult aResult, bool aIsPrinting) {
//---------------------------------------------------------------------
void nsPrintJob::FirePrintingErrorEvent(nsresult aPrintError) {
if (mPrintPreviewCallback) {
mPrintPreviewCallback(PrintPreviewResultInfo(0, 0)); // signal error
mPrintPreviewCallback = nullptr;
}
nsCOMPtr<nsIContentViewer> cv = do_QueryInterface(mDocViewerPrint);
if (NS_WARN_IF(!cv)) {
return;
@ -2422,7 +2454,7 @@ nsresult nsPrintJob::EnablePOsForPrinting() {
// NOTE: All POs have been "turned off" for printing
// this is where we decided which POs get printed.
if (!printData->mPrintSettings) {
if (!printData || !printData->mPrintSettings) {
return NS_ERROR_FAILURE;
}

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

@ -178,9 +178,7 @@ var PrintEventHandler = {
},
unload() {
this.previewBrowser.messageManager.sendAsyncMessage(
"Printing:Preview:Exit"
);
this.previewBrowser.frameLoader.exitPrintPreview();
},
_createPreviewBrowser(sourceBrowsingContext) {
@ -251,7 +249,6 @@ var PrintEventHandler = {
async print(systemDialogSettings) {
let settings = systemDialogSettings || this.settings;
settings.printSilent = true;
if (settings.printerName == PrintUtils.SAVE_TO_PDF_PRINTER) {
try {
@ -363,77 +360,32 @@ var PrintEventHandler = {
* Create a print preview for the provided source browsingContext, or refresh
* the preview with new settings when omitted.
*
* @param browsingContext {BrowsingContext} [optional]
* @param sourceBrowsingContext {BrowsingContext} [optional]
* The source BrowsingContext (the one associated with a tab or
* subdocument) that should be previewed.
*
* @return {Promise} Resolves when the preview has been updated.
*/
async _updatePrintPreview(browsingContext) {
async _updatePrintPreview(sourceBrowsingContext) {
let { previewBrowser, settings } = this;
// We never want the progress dialog to show
settings.showPrintProgress = false;
let stack = previewBrowser.parentElement;
stack.setAttribute("rendering", true);
document.body.setAttribute("rendering", true);
let networkDone = false;
let documentDone = false;
let totalPages = await new Promise(resolve => {
let numPages;
function onStateChange(msg) {
// We get 2 STATE_STOP events, make sure they've both completed.
if (msg.data.stateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
networkDone =
networkDone ||
msg.data.stateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK;
documentDone =
documentDone ||
msg.data.stateFlags & Ci.nsIWebProgressListener.STATE_IS_DOCUMENT;
if (networkDone && documentDone) {
cleanup();
resolve(numPages);
}
}
}
function onUpdatePageCount(msg) {
numPages = msg.data.totalPages;
}
function cleanup() {
previewBrowser.messageManager.removeMessageListener(
"Printing:Preview:UpdatePageCount",
onUpdatePageCount
);
previewBrowser.messageManager.removeMessageListener(
"Printing:Preview:StateChange",
onStateChange
);
}
previewBrowser.messageManager.addMessageListener(
"Printing:Preview:StateChange",
onStateChange
);
previewBrowser.messageManager.addMessageListener(
"Printing:Preview:UpdatePageCount",
onUpdatePageCount
);
previewBrowser.messageManager.sendAsyncMessage("Printing:Preview:Enter", {
changingBrowsers: false,
lastUsedPrinterName: settings.printerName,
simplifiedMode: false,
browsingContextId:
browsingContext?.id || previewBrowser.browsingContext.id,
outputFormat: settings.outputFormat,
startPageRange: settings.startPageRange,
endPageRange: settings.endPageRange,
printRange: settings.printRange,
});
});
let sourceWinId;
if (sourceBrowsingContext) {
sourceWinId = sourceBrowsingContext.currentWindowGlobal.outerWindowId;
}
// This resolves with a PrintPreviewSuccessInfo dictionary. That also has
// a `sheetCount` property available which we should use (bug 1662331).
let { totalPageCount } = await previewBrowser.frameLoader.printPreview(
settings,
sourceWinId
);
if (this._queuedPreviewUpdatePromise) {
// Now that we're done, the queued update (if there is one) will start.
@ -441,13 +393,15 @@ var PrintEventHandler = {
this._queuedPreviewUpdatePromise = null;
} else {
// No other update queued, send the page count and show the preview.
let numPages = totalPages;
let numPages = totalPageCount;
// Adjust number of pages if the user specifies the pages they want printed
if (settings.printRange == Ci.nsIPrintSettings.kRangeSpecifiedPageRange) {
numPages = settings.endPageRange - settings.startPageRange + 1;
}
document.dispatchEvent(
new CustomEvent("page-count", { detail: { numPages, totalPages } })
new CustomEvent("page-count", {
detail: { numPages, totalPages: totalPageCount },
})
);
stack.removeAttribute("rendering");