зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1663826 - Keep freezing navigation during window.print() for compat. r=smaug
This broke in bug 1636728 because we started setting the bit in the cloned docshell rather than the original one. Behavior in other browsers seems to be a bit all over the place, but for now keeping our behavior during window.print() seems sane. Differential Revision: https://phabricator.services.mozilla.com/D90456
This commit is contained in:
Родитель
df6bc55b1b
Коммит
567d300760
|
@ -6117,11 +6117,10 @@ void Document::SetHeaderData(nsAtom* aHeaderField, const nsAString& aData) {
|
|||
SetPreferredStyleSheetSet(aData);
|
||||
}
|
||||
|
||||
if (aHeaderField == nsGkAtoms::refresh) {
|
||||
// We get into this code before we have a script global yet, so get to
|
||||
// our container via mDocumentContainer.
|
||||
nsCOMPtr<nsIRefreshURI> refresher(mDocumentContainer);
|
||||
if (refresher) {
|
||||
if (aHeaderField == nsGkAtoms::refresh && !IsStaticDocument()) {
|
||||
// We get into this code before we have a script global yet, so get to our
|
||||
// container via mDocumentContainer.
|
||||
if (nsCOMPtr<nsIRefreshURI> refresher = mDocumentContainer.get()) {
|
||||
// Note: using mDocumentURI instead of mBaseURI here, for consistency
|
||||
// (used to just use the current URI of our webnavigation, but that
|
||||
// should really be the same thing). Note that this code can run
|
||||
|
|
|
@ -5232,6 +5232,46 @@ static void DispatchPrintEventToWindowTree(Document& aDoc,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef NS_PRINTING
|
||||
static void SetIsPrintingInDocShellTree(nsIDocShellTreeItem* aParentNode,
|
||||
bool aIsPrintingOrPP,
|
||||
bool aStartAtTop = true) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> parentItem(aParentNode);
|
||||
|
||||
// find top of "same parent" tree
|
||||
if (aStartAtTop) {
|
||||
while (parentItem) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> parent;
|
||||
parentItem->GetInProcessSameTypeParent(getter_AddRefs(parent));
|
||||
if (!parent) {
|
||||
break;
|
||||
}
|
||||
parentItem = parent;
|
||||
}
|
||||
}
|
||||
|
||||
if (nsCOMPtr<nsIDocShell> viewerContainer = do_QueryInterface(parentItem)) {
|
||||
viewerContainer->SetIsPrinting(aIsPrintingOrPP);
|
||||
}
|
||||
|
||||
if (!aParentNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Traverse children to see if any of them are printing.
|
||||
int32_t n;
|
||||
aParentNode->GetInProcessChildCount(&n);
|
||||
for (int32_t i = 0; i < n; i++) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> child;
|
||||
aParentNode->GetInProcessChildAt(i, getter_AddRefs(child));
|
||||
NS_ASSERTION(child, "child isn't nsIDocShell");
|
||||
if (child) {
|
||||
SetIsPrintingInDocShellTree(child, aIsPrintingOrPP, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void nsGlobalWindowOuter::PrintOuter(ErrorResult& aError) {
|
||||
if (!AreDialogsEnabled()) {
|
||||
// We probably want to keep throwing here; silently doing nothing is a bit
|
||||
|
@ -5271,6 +5311,11 @@ void nsGlobalWindowOuter::PrintOuter(ErrorResult& aError) {
|
|||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShell = mDocShell;
|
||||
SetIsPrintingInDocShellTree(docShell, true);
|
||||
auto unset =
|
||||
MakeScopeExit([&] { SetIsPrintingInDocShellTree(docShell, false); });
|
||||
|
||||
const bool isPreview = StaticPrefs::print_tab_modal_enabled() &&
|
||||
!StaticPrefs::print_always_print_silent();
|
||||
if (isPreview) {
|
||||
|
|
|
@ -401,13 +401,6 @@ class nsDocumentViewer final : public nsIContentViewer,
|
|||
|
||||
void InvalidatePotentialSubDocDisplayItem();
|
||||
|
||||
#ifdef NS_PRINTING
|
||||
// Called when the DocViewer is notified that the state
|
||||
// of Printing or PP has changed
|
||||
void SetIsPrintingInDocShellTree(nsIDocShellTreeItem* aParentNode,
|
||||
bool aIsPrintingOrPP, bool aStartAtTop);
|
||||
#endif // NS_PRINTING
|
||||
|
||||
// Whether we should attach to the top level widget. This is true if we
|
||||
// are sharing/recycling a single base widget and not creating multiple
|
||||
// child widgets.
|
||||
|
@ -431,7 +424,6 @@ class nsDocumentViewer final : public nsIContentViewer,
|
|||
// class, please make the ownership explicit (pinkerton, scc).
|
||||
|
||||
WeakPtr<nsDocShell> mContainer; // it owns me!
|
||||
nsWeakPtr mTopContainerWhilePrinting;
|
||||
RefPtr<nsDeviceContext> mDeviceContext; // We create and own this baby
|
||||
|
||||
// the following six items are explicitly in this order
|
||||
|
@ -3588,49 +3580,6 @@ nsDocumentViewer::GetPrintPreviewNumPages(int32_t* aPrintPreviewNumPages) {
|
|||
//----------------------------------------------------------------------------------
|
||||
// Walks the document tree and tells each DocShell whether Printing/PP is
|
||||
// happening
|
||||
void nsDocumentViewer::SetIsPrintingInDocShellTree(
|
||||
nsIDocShellTreeItem* aParentNode, bool aIsPrintingOrPP, bool aStartAtTop) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> parentItem(aParentNode);
|
||||
|
||||
// find top of "same parent" tree
|
||||
if (aStartAtTop) {
|
||||
if (aIsPrintingOrPP) {
|
||||
while (parentItem) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> parent;
|
||||
parentItem->GetInProcessSameTypeParent(getter_AddRefs(parent));
|
||||
if (!parent) {
|
||||
break;
|
||||
}
|
||||
parentItem = parent;
|
||||
}
|
||||
mTopContainerWhilePrinting = do_GetWeakReference(parentItem);
|
||||
} else {
|
||||
parentItem = do_QueryReferent(mTopContainerWhilePrinting);
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if the DocShell's ContentViewer is printing/PP
|
||||
nsCOMPtr<nsIDocShell> viewerContainer = do_QueryInterface(parentItem);
|
||||
if (viewerContainer) {
|
||||
viewerContainer->SetIsPrinting(aIsPrintingOrPP);
|
||||
}
|
||||
|
||||
if (!aParentNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Traverse children to see if any of them are printing.
|
||||
int32_t n;
|
||||
aParentNode->GetInProcessChildCount(&n);
|
||||
for (int32_t i = 0; i < n; i++) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> child;
|
||||
aParentNode->GetInProcessChildAt(i, getter_AddRefs(child));
|
||||
NS_ASSERTION(child, "child isn't nsIDocShell");
|
||||
if (child) {
|
||||
SetIsPrintingInDocShellTree(child, aIsPrintingOrPP, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // NS_PRINTING
|
||||
|
||||
bool nsDocumentViewer::ShouldAttachToTopLevel() {
|
||||
|
@ -3677,21 +3626,6 @@ bool nsDocumentViewer::GetIsPrinting() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
// Notification from the PrintJob of the current Printing status
|
||||
void nsDocumentViewer::SetIsPrinting(bool aIsPrinting) {
|
||||
#ifdef NS_PRINTING
|
||||
// Set all the docShells in the docshell tree to be printing.
|
||||
// that way if anyone of them tries to "navigate" it can't
|
||||
nsCOMPtr<nsIDocShell> docShell(mContainer);
|
||||
if (docShell || !aIsPrinting) {
|
||||
SetIsPrintingInDocShellTree(docShell, aIsPrinting, true);
|
||||
} else {
|
||||
NS_WARNING("Did you close a window before printing?");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
// The PrintJob holds the current value
|
||||
// this called from inside the DocViewer.
|
||||
|
@ -3707,15 +3641,6 @@ bool nsDocumentViewer::GetIsPrintPreview() const {
|
|||
//------------------------------------------------------------
|
||||
// Notification from the PrintJob of the current PP status
|
||||
void nsDocumentViewer::SetIsPrintPreview(bool aIsPrintPreview) {
|
||||
#ifdef NS_PRINTING
|
||||
// Set all the docShells in the docshell tree to be printing.
|
||||
// that way if anyone of them tries to "navigate" it can't
|
||||
nsCOMPtr<nsIDocShell> docShell(mContainer);
|
||||
if (docShell || !aIsPrintPreview) {
|
||||
SetIsPrintingInDocShellTree(docShell, aIsPrintPreview, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Protect against pres shell destruction running scripts.
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
|
||||
|
|
|
@ -33,7 +33,6 @@ class nsIDocumentViewerPrint : public nsISupports {
|
|||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOCUMENT_VIEWER_PRINT_IID)
|
||||
|
||||
virtual void SetIsPrinting(bool aIsPrinting) = 0;
|
||||
virtual bool GetIsPrinting() const = 0;
|
||||
|
||||
virtual void SetIsPrintPreview(bool aIsPrintPreview) = 0;
|
||||
|
@ -62,7 +61,6 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocumentViewerPrint,
|
|||
|
||||
/* Use this macro when declaring classes that implement this interface. */
|
||||
#define NS_DECL_NSIDOCUMENTVIEWERPRINT \
|
||||
void SetIsPrinting(bool aIsPrinting) override; \
|
||||
bool GetIsPrinting() const override; \
|
||||
void SetIsPrintPreview(bool aIsPrintPreview) override; \
|
||||
bool GetIsPrintPreview() const override; \
|
||||
|
|
|
@ -538,12 +538,10 @@ nsresult nsPrintJob::DoCommonPrint(bool aIsPrintPreview,
|
|||
// clear mPtrPreview so that code will use mPtr until that happens.
|
||||
mPrtPreview = nullptr;
|
||||
|
||||
// ensures docShell tree navigation in frozen
|
||||
SetIsPrintPreview(true);
|
||||
} else {
|
||||
mProgressDialogIsShown = false;
|
||||
|
||||
// ensures docShell tree navigation in frozen
|
||||
SetIsPrinting(true);
|
||||
}
|
||||
|
||||
|
@ -2318,11 +2316,6 @@ void nsPrintJob::SetIsPrinting(bool aIsPrinting) {
|
|||
if (aIsPrinting) {
|
||||
mHasEverPrinted = true;
|
||||
}
|
||||
// Calling SetIsPrinting while in print preview confuses the document viewer
|
||||
// This is safe because we prevent exiting print preview while printing
|
||||
if (!mCreatedForPrintPreview && mDocViewerPrint) {
|
||||
mDocViewerPrint->SetIsPrinting(aIsPrinting);
|
||||
}
|
||||
if (mPrt && aIsPrinting) {
|
||||
mPrt->mPreparingForPrint = true;
|
||||
}
|
||||
|
|
|
@ -5,8 +5,16 @@
|
|||
onload = function() {
|
||||
// window.print() is special until after the load event is finished firing.
|
||||
setTimeout(function() {
|
||||
// This one should block until we're done printing.
|
||||
// This fires a timer which would trigger a navigation and prevent the
|
||||
// test from completing if it happens during window.print().
|
||||
let meta = document.createElement("meta");
|
||||
meta.setAttribute("http-equiv", "refresh");
|
||||
meta.setAttribute("content", "0; url=/unlikely-to-be-found");
|
||||
document.head.appendChild(meta);
|
||||
// This one should block until we're done printing, and block the
|
||||
// navigation too.
|
||||
window.print();
|
||||
meta.remove();
|
||||
document.body.insertAdjacentHTML('beforeend', `<div id="after-first-print">After first print</div>`);
|
||||
|
||||
let canvas = document.getElementById("canvas");
|
||||
|
|
Загрузка…
Ссылка в новой задаче