Bug 1705757 - Make printing a single frame choose the right process for the preview frame. r=nika
We were using the top BrowsingContextGroup id in this case, which is obviously wrong. Also make the API take a BrowsingContext directly, rather than passing outerwindowids around. Differential Revision: https://phabricator.services.mozilla.com/D112413
This commit is contained in:
@@ -3253,8 +3253,8 @@ void nsFrameLoader::RequestSHistoryUpdate(bool aImmediately) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<Promise> nsFrameLoader::PrintPreview(
|
already_AddRefed<Promise> nsFrameLoader::PrintPreview(
|
||||||
nsIPrintSettings* aPrintSettings,
|
nsIPrintSettings* aPrintSettings, BrowsingContext* aSourceBrowsingContext,
|
||||||
const Optional<uint64_t>& aSourceOuterWindowID, ErrorResult& aRv) {
|
ErrorResult& aRv) {
|
||||||
auto* ownerDoc = GetOwnerDoc();
|
auto* ownerDoc = GetOwnerDoc();
|
||||||
if (!ownerDoc) {
|
if (!ownerDoc) {
|
||||||
aRv.ThrowNotSupportedError("No owner document");
|
aRv.ThrowNotSupportedError("No owner document");
|
||||||
@@ -3299,11 +3299,7 @@ already_AddRefed<Promise> nsFrameLoader::PrintPreview(
|
|||||||
return promise.forget();
|
return promise.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto winID(aSourceOuterWindowID.WasPassed()
|
browserParent->SendPrintPreview(printData, aSourceBrowsingContext)
|
||||||
? Some(aSourceOuterWindowID.Value())
|
|
||||||
: Nothing());
|
|
||||||
|
|
||||||
browserParent->SendPrintPreview(printData, winID)
|
|
||||||
->Then(
|
->Then(
|
||||||
GetMainThreadSerialEventTarget(), __func__, std::move(resolve),
|
GetMainThreadSerialEventTarget(), __func__, std::move(resolve),
|
||||||
[promise](const mozilla::ipc::ResponseRejectReason) {
|
[promise](const mozilla::ipc::ResponseRejectReason) {
|
||||||
@@ -3314,9 +3310,9 @@ already_AddRefed<Promise> nsFrameLoader::PrintPreview(
|
|||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<nsGlobalWindowOuter> sourceWindow;
|
RefPtr<nsGlobalWindowOuter> sourceWindow;
|
||||||
if (aSourceOuterWindowID.WasPassed()) {
|
if (aSourceBrowsingContext) {
|
||||||
sourceWindow =
|
sourceWindow =
|
||||||
nsGlobalWindowOuter::GetOuterWindowWithId(aSourceOuterWindowID.Value());
|
nsGlobalWindowOuter::Cast(aSourceBrowsingContext->GetDOMWindow());
|
||||||
} else {
|
} else {
|
||||||
auto* ourDocshell = static_cast<nsDocShell*>(GetExistingDocShell());
|
auto* ourDocshell = static_cast<nsDocShell*>(GetExistingDocShell());
|
||||||
if (NS_WARN_IF(!ourDocshell)) {
|
if (NS_WARN_IF(!ourDocshell)) {
|
||||||
@@ -3331,7 +3327,7 @@ already_AddRefed<Promise> nsFrameLoader::PrintPreview(
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsIDocShell* docShellToCloneInto = nullptr;
|
nsIDocShell* docShellToCloneInto = nullptr;
|
||||||
if (aSourceOuterWindowID.WasPassed()) {
|
if (aSourceBrowsingContext) {
|
||||||
// We're going to call `Print()` below on a window that is not our own,
|
// We're going to call `Print()` below on a window that is not our own,
|
||||||
// which happens when we are creating a new print preview document instead
|
// which happens when we are creating a new print preview document instead
|
||||||
// of just applying a settings change to the existing PP document. In this
|
// of just applying a settings change to the existing PP document. In this
|
||||||
|
|||||||
@@ -229,10 +229,9 @@ class nsFrameLoader final : public nsStubMutationObserver,
|
|||||||
|
|
||||||
void RequestSHistoryUpdate(bool aImmediately = false);
|
void RequestSHistoryUpdate(bool aImmediately = false);
|
||||||
|
|
||||||
already_AddRefed<Promise> PrintPreview(
|
already_AddRefed<Promise> PrintPreview(nsIPrintSettings* aPrintSettings,
|
||||||
nsIPrintSettings* aPrintSettings,
|
BrowsingContext* aSourceBC,
|
||||||
const mozilla::dom::Optional<uint64_t>& aSourceOuterWindowID,
|
mozilla::ErrorResult& aRv);
|
||||||
mozilla::ErrorResult& aRv);
|
|
||||||
|
|
||||||
void ExitPrintPreview();
|
void ExitPrintPreview();
|
||||||
|
|
||||||
|
|||||||
@@ -124,16 +124,19 @@ interface FrameLoader {
|
|||||||
*
|
*
|
||||||
* @param aPrintSettings The print settings to use to layout the print
|
* @param aPrintSettings The print settings to use to layout the print
|
||||||
* preview document.
|
* preview document.
|
||||||
* @param aSourceOuterWindowID Optionally, the ID of the nsGlobalWindowOuter
|
* @param aSourceBrowsingContext Optionally, the browsing context that
|
||||||
* that contains the document from which the print preview is to be
|
* contains the document from which the print preview is to be generated,
|
||||||
* generated. This should only be passed on the first call. It should not
|
* which must be in the same process as the browsing context of the frame
|
||||||
* be passed for any subsequent calls that are made to update the existing
|
* loader itself.
|
||||||
* print preview document with a new print settings object.
|
*
|
||||||
|
* This should only be passed on the first call. It should not be passed
|
||||||
|
* for any subsequent calls that are made to update the existing print
|
||||||
|
* preview document with a new print settings object.
|
||||||
* @return A Promise that resolves with a PrintPreviewSuccessInfo on success.
|
* @return A Promise that resolves with a PrintPreviewSuccessInfo on success.
|
||||||
*/
|
*/
|
||||||
[ChromeOnly, Throws]
|
[ChromeOnly, Throws]
|
||||||
Promise<unsigned long> printPreview(nsIPrintSettings aPrintSettings,
|
Promise<unsigned long> printPreview(nsIPrintSettings aPrintSettings,
|
||||||
optional unsigned long long aSourceOuterWindowID);
|
BrowsingContext? aSourceBrowsingContext);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inform the print preview document that we're done with it.
|
* Inform the print preview document that we're done with it.
|
||||||
|
|||||||
@@ -2302,8 +2302,7 @@ mozilla::ipc::IPCResult BrowserChild::RecvHandleAccessKey(
|
|||||||
}
|
}
|
||||||
|
|
||||||
mozilla::ipc::IPCResult BrowserChild::RecvPrintPreview(
|
mozilla::ipc::IPCResult BrowserChild::RecvPrintPreview(
|
||||||
const PrintData& aPrintData,
|
const PrintData& aPrintData, const MaybeDiscardedBrowsingContext& aSourceBC,
|
||||||
const mozilla::Maybe<uint64_t>& aSourceOuterWindowID,
|
|
||||||
PrintPreviewResolver&& aCallback) {
|
PrintPreviewResolver&& aCallback) {
|
||||||
#ifdef NS_PRINTING
|
#ifdef NS_PRINTING
|
||||||
// If we didn't succeed in passing off ownership of aCallback, then something
|
// If we didn't succeed in passing off ownership of aCallback, then something
|
||||||
@@ -2315,10 +2314,13 @@ mozilla::ipc::IPCResult BrowserChild::RecvPrintPreview(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (NS_WARN_IF(aSourceBC.IsDiscarded())) {
|
||||||
|
return IPC_OK();
|
||||||
|
}
|
||||||
|
|
||||||
RefPtr<nsGlobalWindowOuter> sourceWindow;
|
RefPtr<nsGlobalWindowOuter> sourceWindow;
|
||||||
if (aSourceOuterWindowID) {
|
if (!aSourceBC.IsNull()) {
|
||||||
sourceWindow =
|
sourceWindow = nsGlobalWindowOuter::Cast(aSourceBC.get()->GetDOMWindow());
|
||||||
nsGlobalWindowOuter::GetOuterWindowWithId(aSourceOuterWindowID.value());
|
|
||||||
if (NS_WARN_IF(!sourceWindow)) {
|
if (NS_WARN_IF(!sourceWindow)) {
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
}
|
}
|
||||||
@@ -2343,7 +2345,7 @@ mozilla::ipc::IPCResult BrowserChild::RecvPrintPreview(
|
|||||||
printSettingsSvc->DeserializeToPrintSettings(aPrintData, printSettings);
|
printSettingsSvc->DeserializeToPrintSettings(aPrintData, printSettings);
|
||||||
|
|
||||||
nsCOMPtr<nsIDocShell> docShellToCloneInto;
|
nsCOMPtr<nsIDocShell> docShellToCloneInto;
|
||||||
if (aSourceOuterWindowID) {
|
if (!aSourceBC.IsNull()) {
|
||||||
docShellToCloneInto = do_GetInterface(WebNavigation());
|
docShellToCloneInto = do_GetInterface(WebNavigation());
|
||||||
if (NS_WARN_IF(!docShellToCloneInto)) {
|
if (NS_WARN_IF(!docShellToCloneInto)) {
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
@@ -2371,11 +2373,14 @@ mozilla::ipc::IPCResult BrowserChild::RecvExitPrintPreview() {
|
|||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
mozilla::ipc::IPCResult BrowserChild::RecvPrint(const uint64_t& aOuterWindowID,
|
mozilla::ipc::IPCResult BrowserChild::RecvPrint(
|
||||||
const PrintData& aPrintData) {
|
const MaybeDiscardedBrowsingContext& aBc, const PrintData& aPrintData) {
|
||||||
#ifdef NS_PRINTING
|
#ifdef NS_PRINTING
|
||||||
|
if (NS_WARN_IF(aBc.IsNullOrDiscarded())) {
|
||||||
|
return IPC_OK();
|
||||||
|
}
|
||||||
RefPtr<nsGlobalWindowOuter> outerWindow =
|
RefPtr<nsGlobalWindowOuter> outerWindow =
|
||||||
nsGlobalWindowOuter::GetOuterWindowWithId(aOuterWindowID);
|
nsGlobalWindowOuter::Cast(aBc.get()->GetDOMWindow());
|
||||||
if (NS_WARN_IF(!outerWindow)) {
|
if (NS_WARN_IF(!outerWindow)) {
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -545,10 +545,9 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
|
|||||||
mozilla::ipc::IPCResult RecvHandleAccessKey(const WidgetKeyboardEvent& aEvent,
|
mozilla::ipc::IPCResult RecvHandleAccessKey(const WidgetKeyboardEvent& aEvent,
|
||||||
nsTArray<uint32_t>&& aCharCodes);
|
nsTArray<uint32_t>&& aCharCodes);
|
||||||
|
|
||||||
mozilla::ipc::IPCResult RecvPrintPreview(
|
mozilla::ipc::IPCResult RecvPrintPreview(const PrintData& aPrintData,
|
||||||
const PrintData& aPrintData,
|
const MaybeDiscardedBrowsingContext&,
|
||||||
const mozilla::Maybe<uint64_t>& aSourceOuterWindowID,
|
PrintPreviewResolver&& aCallback);
|
||||||
PrintPreviewResolver&& aCallback);
|
|
||||||
|
|
||||||
mozilla::ipc::IPCResult RecvExitPrintPreview();
|
mozilla::ipc::IPCResult RecvExitPrintPreview();
|
||||||
|
|
||||||
|
|||||||
@@ -965,14 +965,14 @@ child:
|
|||||||
*
|
*
|
||||||
* @param aPrintData The serialized print settings to use to layout the
|
* @param aPrintData The serialized print settings to use to layout the
|
||||||
* print preview document.
|
* print preview document.
|
||||||
* @param aSourceOuterWindowID Optionally, the ID of the nsGlobalWindowOuter
|
* @param aSourceBrowsingContext Optionally, the browsing context that
|
||||||
* that contains the document from which the print preview is to be
|
* contains the document from which the print preview is to be generated.
|
||||||
* generated. This should only be passed on the first call. It should
|
* This should only be passed on the first call. It should not be passed
|
||||||
* not be passed for any subsequent calls that are made to update the
|
* for any subsequent calls that are made to update the existing print
|
||||||
* existing print preview document with a new print settings object.
|
* preview document with a new print settings object.
|
||||||
*/
|
*/
|
||||||
async PrintPreview(PrintData aPrintData,
|
async PrintPreview(PrintData aPrintData,
|
||||||
uint64_t? aSourceOuterWindowID) returns (PrintPreviewResultInfo aInfo);
|
MaybeDiscardedBrowsingContext aSourceBrowsingContext) returns (PrintPreviewResultInfo aInfo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inform the print preview document that we're done with it.
|
* Inform the print preview document that we're done with it.
|
||||||
|
|||||||
@@ -163,16 +163,22 @@ var PrintEventHandler = {
|
|||||||
// is initiated and the print preview clone must be a snapshot from the
|
// is initiated and the print preview clone must be a snapshot from the
|
||||||
// time that the print was started.
|
// time that the print was started.
|
||||||
let sourceBrowsingContext = this.getSourceBrowsingContext();
|
let sourceBrowsingContext = this.getSourceBrowsingContext();
|
||||||
|
|
||||||
|
let args = window.arguments[0];
|
||||||
|
this.printFrameOnly = args.getProperty("printFrameOnly");
|
||||||
|
|
||||||
({
|
({
|
||||||
previewBrowser: this.previewBrowser,
|
previewBrowser: this.previewBrowser,
|
||||||
selectionPreviewBrowser: this.selectionPreviewBrowser,
|
selectionPreviewBrowser: this.selectionPreviewBrowser,
|
||||||
} = PrintUtils.createPreviewBrowsers(sourceBrowsingContext, ourBrowser));
|
} = PrintUtils.createPreviewBrowsers(
|
||||||
|
sourceBrowsingContext,
|
||||||
|
ourBrowser,
|
||||||
|
this.printFrameOnly
|
||||||
|
));
|
||||||
|
|
||||||
let args = window.arguments[0];
|
|
||||||
this.printSelectionOnly = args.getProperty("printSelectionOnly");
|
this.printSelectionOnly = args.getProperty("printSelectionOnly");
|
||||||
this.hasSelection =
|
this.hasSelection =
|
||||||
args.getProperty("hasSelection") && this.selectionPreviewBrowser;
|
args.getProperty("hasSelection") && this.selectionPreviewBrowser;
|
||||||
this.printFrameOnly = args.getProperty("printFrameOnly");
|
|
||||||
// Get the temporary browser that will previously have been created for the
|
// Get the temporary browser that will previously have been created for the
|
||||||
// platform code to generate the static clone printing doc into if this
|
// platform code to generate the static clone printing doc into if this
|
||||||
// print is for a window.print() call. In that case we steal the browser's
|
// print is for a window.print() call. In that case we steal the browser's
|
||||||
@@ -195,12 +201,10 @@ var PrintEventHandler = {
|
|||||||
this.originalSourceCurrentURI =
|
this.originalSourceCurrentURI =
|
||||||
sourceBrowsingContext.currentWindowContext.documentURI.spec;
|
sourceBrowsingContext.currentWindowContext.documentURI.spec;
|
||||||
|
|
||||||
this.sourceWindowId = this.printFrameOnly
|
this.nonSelectionBrowsingContextId = this.printFrameOnly
|
||||||
? sourceBrowsingContext.currentWindowGlobal.outerWindowId
|
? sourceBrowsingContext.id
|
||||||
: sourceBrowsingContext.top.embedderElement.browsingContext
|
: sourceBrowsingContext.top.id;
|
||||||
.currentWindowGlobal.outerWindowId;
|
this.selectionBrowsingContextId = sourceBrowsingContext.id;
|
||||||
this.selectionWindowId =
|
|
||||||
sourceBrowsingContext.currentWindowGlobal.outerWindowId;
|
|
||||||
|
|
||||||
// We don't need the sourceBrowsingContext anymore, get rid of it.
|
// We don't need the sourceBrowsingContext anymore, get rid of it.
|
||||||
sourceBrowsingContext = undefined;
|
sourceBrowsingContext = undefined;
|
||||||
@@ -775,14 +779,14 @@ var PrintEventHandler = {
|
|||||||
|
|
||||||
this._showRenderingIndicator();
|
this._showRenderingIndicator();
|
||||||
|
|
||||||
let sourceWinId;
|
let sourceBCId;
|
||||||
|
|
||||||
// If it's the first time loading this type of browser, get the stored window id.
|
// If it's the first time loading this type of browser, get the stored window id.
|
||||||
if (printSelectionOnly && !this._hasRenderedSelectionPreview) {
|
if (printSelectionOnly && !this._hasRenderedSelectionPreview) {
|
||||||
sourceWinId = this.selectionWindowId;
|
sourceBCId = this.selectionBrowsingContextId;
|
||||||
this._hasRenderedSelectionPreview = true;
|
this._hasRenderedSelectionPreview = true;
|
||||||
} else if (!printSelectionOnly && !this._hasRenderedPrimaryPreview) {
|
} else if (!printSelectionOnly && !this._hasRenderedPrimaryPreview) {
|
||||||
sourceWinId = this.sourceWindowId;
|
sourceBCId = this.nonSelectionBrowsingContextId;
|
||||||
this._hasRenderedPrimaryPreview = true;
|
this._hasRenderedPrimaryPreview = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -817,7 +821,7 @@ var PrintEventHandler = {
|
|||||||
isEmpty,
|
isEmpty,
|
||||||
} = await this.currentPreviewBrowser.frameLoader.printPreview(
|
} = await this.currentPreviewBrowser.frameLoader.printPreview(
|
||||||
settings,
|
settings,
|
||||||
sourceWinId
|
sourceBCId ? BrowsingContext.get(sourceBCId) : null
|
||||||
));
|
));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.reportPrintingError("PRINT_PREVIEW");
|
this.reportPrintingError("PRINT_PREVIEW");
|
||||||
|
|||||||
@@ -143,12 +143,12 @@ var PrintUtils = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
createPreviewBrowsers(aBrowsingContext, aDialogBrowser) {
|
createPreviewBrowsers(aBrowsingContext, aDialogBrowser, aPrintFrameOnly) {
|
||||||
let _createPreviewBrowser = previewType => {
|
let _createPreviewBrowser = previewType => {
|
||||||
// When we're not previewing the selection we want to make
|
// When we're not previewing the selection or printing only the frame, we
|
||||||
// sure that the top-level browser is being printed.
|
// want to make sure that the top-level browser is being printed.
|
||||||
let browsingContext =
|
let browsingContext =
|
||||||
previewType == "selection"
|
previewType == "selection" || aPrintFrameOnly
|
||||||
? aBrowsingContext
|
? aBrowsingContext
|
||||||
: aBrowsingContext.top.embedderElement.browsingContext;
|
: aBrowsingContext.top.embedderElement.browsingContext;
|
||||||
let browser = gBrowser.createBrowser({
|
let browser = gBrowser.createBrowser({
|
||||||
|
|||||||
Reference in New Issue
Block a user