Bug 1768919 - Avoid checking the original document for focus in nsPrintJob. r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D146110
This commit is contained in:
Jonathan Watt 2022-05-12 12:06:57 +00:00
Родитель 434f2762eb
Коммит ebabc1e31f
4 изменённых файлов: 36 добавлений и 68 удалений

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

@ -11482,6 +11482,7 @@ void Document::Destroy() {
} }
if (IsStaticDocument()) { if (IsStaticDocument()) {
RemoveProperty(nsGkAtoms::printisfocuseddoc);
RemoveProperty(nsGkAtoms::printselectionranges); RemoveProperty(nsGkAtoms::printselectionranges);
} }
@ -13118,11 +13119,39 @@ static nsINode* GetCorrespondingNodeInDocument(const nsINode* aOrigNode,
static void CachePrintSelectionRanges(const Document& aSourceDoc, static void CachePrintSelectionRanges(const Document& aSourceDoc,
Document& aStaticClone) { Document& aStaticClone) {
MOZ_ASSERT(aStaticClone.IsStaticDocument()); MOZ_ASSERT(aStaticClone.IsStaticDocument());
MOZ_ASSERT(!aStaticClone.GetProperty(nsGkAtoms::printisfocuseddoc));
MOZ_ASSERT(!aStaticClone.GetProperty(nsGkAtoms::printselectionranges)); MOZ_ASSERT(!aStaticClone.GetProperty(nsGkAtoms::printselectionranges));
bool sourceDocIsStatic = aSourceDoc.IsStaticDocument();
// When the user opts to "Print Selection Only", the print code prefers any
// selection in the static clone corresponding to the focused frame. If this
// is that static clone, flag it for the printing code:
const bool isFocusedDoc = [&] {
if (sourceDocIsStatic) {
return bool(aSourceDoc.GetProperty(nsGkAtoms::printisfocuseddoc));
}
nsPIDOMWindowOuter* window = aSourceDoc.GetWindow();
if (!window) {
return false;
}
nsCOMPtr<nsPIDOMWindowOuter> rootWindow = window->GetPrivateRoot();
if (!rootWindow) {
return false;
}
nsCOMPtr<nsPIDOMWindowOuter> focusedWindow;
nsFocusManager::GetFocusedDescendant(rootWindow,
nsFocusManager::eIncludeAllDescendants,
getter_AddRefs(focusedWindow));
return focusedWindow && focusedWindow->GetExtantDoc() == &aSourceDoc;
}();
if (isFocusedDoc) {
aStaticClone.SetProperty(nsGkAtoms::printisfocuseddoc,
reinterpret_cast<void*>(true));
}
const Selection* origSelection = nullptr; const Selection* origSelection = nullptr;
const nsTArray<RefPtr<nsRange>>* origRanges = nullptr; const nsTArray<RefPtr<nsRange>>* origRanges = nullptr;
bool sourceDocIsStatic = aSourceDoc.IsStaticDocument();
if (sourceDocIsStatic) { if (sourceDocIsStatic) {
origRanges = static_cast<nsTArray<RefPtr<nsRange>>*>( origRanges = static_cast<nsTArray<RefPtr<nsRange>>*>(

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

@ -206,15 +206,14 @@ static bool IsParentAFrameSet(nsIDocShell* aParent) {
* @param aPrintData nsPrintData for the current print, must not be null. * @param aPrintData nsPrintData for the current print, must not be null.
*/ */
static void BuildNestedPrintObjects(const UniquePtr<nsPrintObject>& aParentPO, static void BuildNestedPrintObjects(const UniquePtr<nsPrintObject>& aParentPO,
const RefPtr<Document>& aFocusedDoc,
RefPtr<nsPrintData>& aPrintData) { RefPtr<nsPrintData>& aPrintData) {
MOZ_ASSERT(aParentPO); MOZ_ASSERT(aParentPO);
MOZ_ASSERT(aPrintData); MOZ_ASSERT(aPrintData);
// If aParentPO is for an iframe and its original document is focusedDoc then // If aParentPO is for an iframe and its original document was the document
// always set as the selection root. // that had focus then always set as the selection root.
if (aParentPO->mFrameType == eIFrame && if (aParentPO->mFrameType == eIFrame &&
aParentPO->mDocument->GetOriginalDocument() == aFocusedDoc) { aParentPO->mDocument->GetProperty(nsGkAtoms::printisfocuseddoc)) {
aPrintData->mSelectionRoot = aParentPO.get(); aPrintData->mSelectionRoot = aParentPO.get();
} else if (!aPrintData->mSelectionRoot && aParentPO->HasSelection()) { } else if (!aPrintData->mSelectionRoot && aParentPO->HasSelection()) {
// If there is no focused iframe but there is a selection in one or more // If there is no focused iframe but there is a selection in one or more
@ -255,7 +254,7 @@ static void BuildNestedPrintObjects(const UniquePtr<nsPrintObject>& aParentPO,
} }
aPrintData->mPrintDocList.AppendElement(childPO.get()); aPrintData->mPrintDocList.AppendElement(childPO.get());
BuildNestedPrintObjects(childPO, aFocusedDoc, aPrintData); BuildNestedPrintObjects(childPO, aPrintData);
aParentPO->mKids.AppendElement(std::move(childPO)); aParentPO->mKids.AppendElement(std::move(childPO));
} }
} }
@ -496,9 +495,6 @@ nsresult nsPrintJob::DoCommonPrint(bool aIsPrintPreview,
printData->mPrintProgressListeners.AppendObject(aWebProgressListener); printData->mPrintProgressListeners.AppendObject(aWebProgressListener);
} }
// Get the document from the currently focused window.
RefPtr<Document> focusedDoc = FindFocusedDocument(aDoc);
// Get the docshell for this documentviewer // Get the docshell for this documentviewer
nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mDocShell, &rv)); nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mDocShell, &rv));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
@ -522,7 +518,7 @@ nsresult nsPrintJob::DoCommonPrint(bool aIsPrintPreview,
printData->mPrintObject->mFrameType = printData->mPrintObject->mFrameType =
printData->mIsParentAFrameSet ? eFrameSet : eDoc; printData->mIsParentAFrameSet ? eFrameSet : eDoc;
BuildNestedPrintObjects(printData->mPrintObject, focusedDoc, printData); BuildNestedPrintObjects(printData->mPrintObject, printData);
} }
// The nsAutoScriptBlocker above will now have been destroyed, which may // The nsAutoScriptBlocker above will now have been destroyed, which may
@ -2074,47 +2070,6 @@ void nsPrintJob::SetIsPrintPreview(bool aIsPrintPreview) {
} }
} }
Document* nsPrintJob::FindFocusedDocument(Document* aDoc) const {
nsFocusManager* fm = nsFocusManager::GetFocusManager();
NS_ENSURE_TRUE(fm, nullptr);
nsPIDOMWindowOuter* window = aDoc->GetOriginalDocument()->GetWindow();
NS_ENSURE_TRUE(window, nullptr);
nsCOMPtr<nsPIDOMWindowOuter> rootWindow = window->GetPrivateRoot();
NS_ENSURE_TRUE(rootWindow, nullptr);
nsCOMPtr<nsPIDOMWindowOuter> focusedWindow;
nsFocusManager::GetFocusedDescendant(rootWindow,
nsFocusManager::eIncludeAllDescendants,
getter_AddRefs(focusedWindow));
NS_ENSURE_TRUE(focusedWindow, nullptr);
if (IsWindowsInOurSubTree(focusedWindow)) {
return focusedWindow->GetDoc();
}
return nullptr;
}
//---------------------------------------------------------------------
bool nsPrintJob::IsWindowsInOurSubTree(nsPIDOMWindowOuter* window) const {
if (window) {
nsCOMPtr<nsIDocShell> ourDocShell(do_QueryReferent(mDocShell));
if (ourDocShell) {
BrowsingContext* ourBC = ourDocShell->GetBrowsingContext();
BrowsingContext* bc = window->GetBrowsingContext();
while (bc) {
if (bc == ourBC) {
return true;
}
bc = bc->GetParent();
}
}
}
return false;
}
//------------------------------------------------------- //-------------------------------------------------------
bool nsPrintJob::DonePrintingSheets(nsPrintObject* aPO, nsresult aResult) { bool nsPrintJob::DonePrintingSheets(nsPrintObject* aPO, nsresult aResult) {
// NS_ASSERTION(aPO, "Pointer is null!"); // NS_ASSERTION(aPO, "Pointer is null!");

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

@ -176,16 +176,6 @@ class nsPrintJob final : public nsIWebProgressListener,
nsresult StartPagePrintTimer(const mozilla::UniquePtr<nsPrintObject>& aPO); nsresult StartPagePrintTimer(const mozilla::UniquePtr<nsPrintObject>& aPO);
bool IsWindowsInOurSubTree(nsPIDOMWindowOuter* aDOMWindow) const;
/**
* @return The document from the focused windows for a document viewer.
*
* FIXME: This is somewhat unsound, this looks at the original document, which
* could've mutated after print was initiated.
*/
Document* FindFocusedDocument(Document* aDoc) const;
/// Customizes the behaviour of GetDisplayTitleAndURL. /// Customizes the behaviour of GetDisplayTitleAndURL.
enum class DocTitleDefault : uint32_t { eDocURLElseFallback, eFallback }; enum class DocTitleDefault : uint32_t { eDocURLElseFallback, eFallback };
@ -243,13 +233,6 @@ class nsPrintJob final : public nsIWebProgressListener,
void PageDone(nsresult aResult); void PageDone(nsresult aResult);
// The document that we were originally created for in order to print it or
// create a print preview of it. This may belong to mDocViewerPrint or may
// belong to a different docViewer in a different docShell. In reality, this
// also may not be the original document that the user selected to print (see
// the comment documenting Initialize() above).
RefPtr<Document> mOriginalDoc;
// The docViewer that owns us, and its docShell. // The docViewer that owns us, and its docShell.
nsCOMPtr<nsIDocumentViewerPrint> mDocViewerPrint; nsCOMPtr<nsIDocumentViewerPrint> mDocViewerPrint;
nsWeakPtr mDocShell; nsWeakPtr mDocShell;

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

@ -1020,6 +1020,7 @@ STATIC_ATOMS = [
Atom("previewDiv", "preview-div"), Atom("previewDiv", "preview-div"),
Atom("primary", "primary"), Atom("primary", "primary"),
Atom("print", "print"), Atom("print", "print"),
Atom("printisfocuseddoc", "printisfocuseddoc"),
Atom("printselectionranges", "printselectionranges"), Atom("printselectionranges", "printselectionranges"),
Atom("priority", "priority"), Atom("priority", "priority"),
Atom("processingInstruction", "processing-instruction"), Atom("processingInstruction", "processing-instruction"),