Bug 1425641, part 3 - Remove lots of static methods from the nsPrintJob interface. r=bobowen

MozReview-Commit-ID: 6T3h7hR6Kcg

--HG--
extra : rebase_source : ba29d0f4b15c575ccfceee6caf084b43cf59f124
This commit is contained in:
Jonathan Watt 2017-12-06 12:47:19 +00:00
Родитель 1d609cb1b5
Коммит 4ba31c1984
2 изменённых файлов: 273 добавлений и 294 удалений

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

@ -207,6 +207,276 @@ protected:
bool mSuppressed;
};
// -------------------------------------------------------
// Helpers
// -------------------------------------------------------
static bool
HasFramesetChild(nsIContent* aContent)
{
if (!aContent) {
return false;
}
// do a breadth search across all siblings
for (nsIContent* child = aContent->GetFirstChild();
child;
child = child->GetNextSibling()) {
if (child->IsHTMLElement(nsGkAtoms::frameset)) {
return true;
}
}
return false;
}
static bool
IsParentAFrameSet(nsIDocShell* aParent)
{
// See if the incoming doc is the root document
if (!aParent) return false;
// When it is the top level document we need to check
// to see if it contains a frameset. If it does, then
// we only want to print the doc's children and not the document itself
// For anything else we always print all the children and the document
// for example, if the doc contains an IFRAME we eant to print the child
// document (the IFRAME) and then the rest of the document.
//
// XXX we really need to search the frame tree, and not the content
// but there is no way to distinguish between IFRAMEs and FRAMEs
// with the GetFrameType call.
// Bug 53459 has been files so we can eventually distinguish
// between IFRAME frames and FRAME frames
bool isFrameSet = false;
// only check to see if there is a frameset if there is
// NO parent doc for this doc. meaning this parent is the root doc
nsCOMPtr<nsIDocument> doc = aParent->GetDocument();
if (doc) {
nsIContent *rootElement = doc->GetRootElement();
if (rootElement) {
isFrameSet = HasFramesetChild(rootElement);
}
}
return isFrameSet;
}
static nsPrintObject*
FindPrintObjectByDOMWin(nsPrintObject* aPO,
nsPIDOMWindowOuter* aDOMWin)
{
NS_ASSERTION(aPO, "Pointer is null!");
// Often the CurFocused DOMWindow is passed in
// andit is valid for it to be null, so short circut
if (!aDOMWin) {
return nullptr;
}
nsCOMPtr<nsIDocument> doc = aDOMWin->GetDoc();
if (aPO->mDocument && aPO->mDocument->GetOriginalDocument() == doc) {
return aPO;
}
for (const UniquePtr<nsPrintObject>& kid : aPO->mKids) {
nsPrintObject* po = FindPrintObjectByDOMWin(kid.get(), aDOMWin);
if (po) {
return po;
}
}
return nullptr;
}
static void
GetDocumentTitleAndURL(nsIDocument* aDoc,
nsAString& aTitle,
nsAString& aURLStr)
{
NS_ASSERTION(aDoc, "Pointer is null!");
aTitle.Truncate();
aURLStr.Truncate();
nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(aDoc);
doc->GetTitle(aTitle);
nsIURI* url = aDoc->GetDocumentURI();
if (!url) return;
nsCOMPtr<nsIURIFixup> urifixup(do_GetService(NS_URIFIXUP_CONTRACTID));
if (!urifixup) return;
nsCOMPtr<nsIURI> exposableURI;
urifixup->CreateExposableURI(url, getter_AddRefs(exposableURI));
if (!exposableURI) return;
nsAutoCString urlCStr;
nsresult rv = exposableURI->GetSpec(urlCStr);
if (NS_FAILED(rv)) return;
nsCOMPtr<nsITextToSubURI> textToSubURI =
do_GetService(NS_ITEXTTOSUBURI_CONTRACTID, &rv);
if (NS_FAILED(rv)) return;
textToSubURI->UnEscapeURIForUI(NS_LITERAL_CSTRING("UTF-8"),
urlCStr, aURLStr);
}
static nsresult
GetSeqFrameAndCountPagesInternal(const UniquePtr<nsPrintObject>& aPO,
nsIFrame*& aSeqFrame,
int32_t& aCount)
{
NS_ENSURE_ARG_POINTER(aPO);
// This is sometimes incorrectly called before the pres shell has been created
// (bug 1141756). MOZ_DIAGNOSTIC_ASSERT so we'll still see the crash in
// Nightly/Aurora in case the other patch fixes this.
if (!aPO->mPresShell) {
MOZ_DIAGNOSTIC_ASSERT(false,
"GetSeqFrameAndCountPages needs a non-null pres shell");
return NS_ERROR_FAILURE;
}
// Finds the SimplePageSequencer frame
nsIPageSequenceFrame* seqFrame = aPO->mPresShell->GetPageSequenceFrame();
aSeqFrame = do_QueryFrame(seqFrame);
if (!aSeqFrame) {
return NS_ERROR_FAILURE;
}
// count the total number of pages
aCount = aSeqFrame->PrincipalChildList().GetLength();
return NS_OK;
}
/**
* Recursively sets the PO items to be printed "As Is"
* from the given item down into the treei
*/
static void
SetPrintAsIs(nsPrintObject* aPO, bool aAsIs = true)
{
NS_ASSERTION(aPO, "Pointer is null!");
aPO->mPrintAsIs = aAsIs;
for (const UniquePtr<nsPrintObject>& kid : aPO->mKids) {
SetPrintAsIs(kid.get(), aAsIs);
}
}
/**
* This method is key to the entire print mechanism.
*
* This "maps" or figures out which sub-doc represents a
* given Frame or IFrame in its parent sub-doc.
*
* So the Mcontent pointer in the child sub-doc points to the
* content in the its parent document, that caused it to be printed.
* This is used later to (after reflow) to find the absolute location
* of the sub-doc on its parent's page frame so it can be
* printed in the correct location.
*
* This method recursvely "walks" the content for a document finding
* all the Frames and IFrames, then sets the "mFrameType" data member
* which tells us what type of PO we have
*/
static void
MapContentForPO(const UniquePtr<nsPrintObject>& aPO,
nsIContent* aContent)
{
NS_PRECONDITION(aPO && aContent, "Null argument");
nsIDocument* doc = aContent->GetComposedDoc();
NS_ASSERTION(doc, "Content without a document from a document tree?");
nsIDocument* subDoc = doc->GetSubDocumentFor(aContent);
if (subDoc) {
nsCOMPtr<nsIDocShell> docShell(subDoc->GetDocShell());
if (docShell) {
nsPrintObject * po = nullptr;
for (const UniquePtr<nsPrintObject>& kid : aPO->mKids) {
if (kid->mDocument == subDoc) {
po = kid.get();
break;
}
}
// XXX If a subdocument has no onscreen presentation, there will be no PO
// This is even if there should be a print presentation
if (po) {
// "frame" elements not in a frameset context should be treated
// as iframes
if (aContent->IsHTMLElement(nsGkAtoms::frame) && po->mParent->mFrameType == eFrameSet) {
po->mFrameType = eFrame;
} else {
// Assume something iframe-like, i.e. iframe, object, or embed
po->mFrameType = eIFrame;
SetPrintAsIs(po, true);
NS_ASSERTION(po->mParent, "The root must be a parent");
po->mParent->mPrintAsIs = true;
}
}
}
}
// walk children content
for (nsIContent* child = aContent->GetFirstChild();
child;
child = child->GetNextSibling()) {
MapContentForPO(aPO, child);
}
}
/**
* The walks the PO tree and for each document it walks the content
* tree looking for any content that are sub-shells
*
* It then sets the mContent pointer in the "found" PO object back to the
* the document that contained it.
*/
static void
MapContentToWebShells(const UniquePtr<nsPrintObject>& aRootPO,
const UniquePtr<nsPrintObject>& aPO)
{
NS_ASSERTION(aRootPO, "Pointer is null!");
NS_ASSERTION(aPO, "Pointer is null!");
// Recursively walk the content from the root item
// XXX Would be faster to enumerate the subdocuments, although right now
// nsIDocument doesn't expose quite what would be needed.
nsCOMPtr<nsIContentViewer> viewer;
aPO->mDocShell->GetContentViewer(getter_AddRefs(viewer));
if (!viewer) return;
nsCOMPtr<nsIDOMDocument> domDoc;
viewer->GetDOMDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
if (!doc) return;
Element* rootElement = doc->GetRootElement();
if (rootElement) {
MapContentForPO(aPO, rootElement);
} else {
NS_WARNING("Null root content on (sub)document.");
}
// Continue recursively walking the chilren of this PO
for (const UniquePtr<nsPrintObject>& kid : aPO->mKids) {
MapContentToWebShells(aRootPO, kid);
}
}
//-------------------------------------------------------
NS_IMPL_ISUPPORTS(nsPrintJob, nsIWebProgressListener,
nsISupportsWeakReference, nsIObserver)
@ -307,36 +577,6 @@ nsPrintJob::InstallPrintPreviewListener()
}
}
//----------------------------------------------------------------------
nsresult
nsPrintJob::GetSeqFrameAndCountPagesInternal(const UniquePtr<nsPrintObject>& aPO,
nsIFrame*& aSeqFrame,
int32_t& aCount)
{
NS_ENSURE_ARG_POINTER(aPO);
// This is sometimes incorrectly called before the pres shell has been created
// (bug 1141756). MOZ_DIAGNOSTIC_ASSERT so we'll still see the crash in
// Nightly/Aurora in case the other patch fixes this.
if (!aPO->mPresShell) {
MOZ_DIAGNOSTIC_ASSERT(false,
"GetSeqFrameAndCountPages needs a non-null pres shell");
return NS_ERROR_FAILURE;
}
// Finds the SimplePageSequencer frame
nsIPageSequenceFrame* seqFrame = aPO->mPresShell->GetPageSequenceFrame();
aSeqFrame = do_QueryFrame(seqFrame);
if (!aSeqFrame) {
return NS_ERROR_FAILURE;
}
// count the total number of pages
aCount = aSeqFrame->PrincipalChildList().GetLength();
return NS_OK;
}
//-----------------------------------------------------------------
nsresult
nsPrintJob::GetSeqFrameAndCountPages(nsIFrame*& aSeqFrame, int32_t& aCount)
@ -1140,39 +1380,6 @@ nsPrintJob::IsThereARangeSelection(nsPIDOMWindowOuter* aDOMWin)
return selection->GetRangeAt(0) && !selection->IsCollapsed();
}
//---------------------------------------------------------------------
bool
nsPrintJob::IsParentAFrameSet(nsIDocShell* aParent)
{
// See if the incoming doc is the root document
if (!aParent) return false;
// When it is the top level document we need to check
// to see if it contains a frameset. If it does, then
// we only want to print the doc's children and not the document itself
// For anything else we always print all the children and the document
// for example, if the doc contains an IFRAME we eant to print the child
// document (the IFRAME) and then the rest of the document.
//
// XXX we really need to search the frame tree, and not the content
// but there is no way to distinguish between IFRAMEs and FRAMEs
// with the GetFrameType call.
// Bug 53459 has been files so we can eventually distinguish
// between IFRAME frames and FRAME frames
bool isFrameSet = false;
// only check to see if there is a frameset if there is
// NO parent doc for this doc. meaning this parent is the root doc
nsCOMPtr<nsIDocument> doc = aParent->GetDocument();
if (doc) {
nsIContent *rootElement = doc->GetRootElement();
if (rootElement) {
isFrameSet = HasFramesetChild(rootElement);
}
}
return isFrameSet;
}
//---------------------------------------------------------------------
// Recursively build a list of sub documents to be printed
// that mirrors the document tree
@ -1210,82 +1417,6 @@ nsPrintJob::BuildDocTree(nsIDocShell* aParentNode,
}
}
//---------------------------------------------------------------------
void
nsPrintJob::GetDocumentTitleAndURL(nsIDocument* aDoc,
nsAString& aTitle,
nsAString& aURLStr)
{
NS_ASSERTION(aDoc, "Pointer is null!");
aTitle.Truncate();
aURLStr.Truncate();
nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(aDoc);
doc->GetTitle(aTitle);
nsIURI* url = aDoc->GetDocumentURI();
if (!url) return;
nsCOMPtr<nsIURIFixup> urifixup(do_GetService(NS_URIFIXUP_CONTRACTID));
if (!urifixup) return;
nsCOMPtr<nsIURI> exposableURI;
urifixup->CreateExposableURI(url, getter_AddRefs(exposableURI));
if (!exposableURI) return;
nsAutoCString urlCStr;
nsresult rv = exposableURI->GetSpec(urlCStr);
if (NS_FAILED(rv)) return;
nsCOMPtr<nsITextToSubURI> textToSubURI =
do_GetService(NS_ITEXTTOSUBURI_CONTRACTID, &rv);
if (NS_FAILED(rv)) return;
textToSubURI->UnEscapeURIForUI(NS_LITERAL_CSTRING("UTF-8"),
urlCStr, aURLStr);
}
//---------------------------------------------------------------------
// The walks the PO tree and for each document it walks the content
// tree looking for any content that are sub-shells
//
// It then sets the mContent pointer in the "found" PO object back to the
// the document that contained it.
void
nsPrintJob::MapContentToWebShells(const UniquePtr<nsPrintObject>& aRootPO,
const UniquePtr<nsPrintObject>& aPO)
{
NS_ASSERTION(aRootPO, "Pointer is null!");
NS_ASSERTION(aPO, "Pointer is null!");
// Recursively walk the content from the root item
// XXX Would be faster to enumerate the subdocuments, although right now
// nsIDocument doesn't expose quite what would be needed.
nsCOMPtr<nsIContentViewer> viewer;
aPO->mDocShell->GetContentViewer(getter_AddRefs(viewer));
if (!viewer) return;
nsCOMPtr<nsIDOMDocument> domDoc;
viewer->GetDOMDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
if (!doc) return;
Element* rootElement = doc->GetRootElement();
if (rootElement) {
MapContentForPO(aPO, rootElement);
} else {
NS_WARNING("Null root content on (sub)document.");
}
// Continue recursively walking the chilren of this PO
for (const UniquePtr<nsPrintObject>& kid : aPO->mKids) {
MapContentToWebShells(aRootPO, kid);
}
}
//-------------------------------------------------------
// A Frame's sub-doc may contain content or a FrameSet
// When it contains a FrameSet the mFrameType for the PrintObject
@ -1319,71 +1450,6 @@ nsPrintJob::CheckForChildFrameSets(const UniquePtr<nsPrintObject>& aPO)
}
}
//---------------------------------------------------------------------
// This method is key to the entire print mechanism.
//
// This "maps" or figures out which sub-doc represents a
// given Frame or IFrame in its parent sub-doc.
//
// So the Mcontent pointer in the child sub-doc points to the
// content in the its parent document, that caused it to be printed.
// This is used later to (after reflow) to find the absolute location
// of the sub-doc on its parent's page frame so it can be
// printed in the correct location.
//
// This method recursvely "walks" the content for a document finding
// all the Frames and IFrames, then sets the "mFrameType" data member
// which tells us what type of PO we have
void
nsPrintJob::MapContentForPO(const UniquePtr<nsPrintObject>& aPO,
nsIContent* aContent)
{
NS_PRECONDITION(aPO && aContent, "Null argument");
nsIDocument* doc = aContent->GetComposedDoc();
NS_ASSERTION(doc, "Content without a document from a document tree?");
nsIDocument* subDoc = doc->GetSubDocumentFor(aContent);
if (subDoc) {
nsCOMPtr<nsIDocShell> docShell(subDoc->GetDocShell());
if (docShell) {
nsPrintObject * po = nullptr;
for (const UniquePtr<nsPrintObject>& kid : aPO->mKids) {
if (kid->mDocument == subDoc) {
po = kid.get();
break;
}
}
// XXX If a subdocument has no onscreen presentation, there will be no PO
// This is even if there should be a print presentation
if (po) {
// "frame" elements not in a frameset context should be treated
// as iframes
if (aContent->IsHTMLElement(nsGkAtoms::frame) && po->mParent->mFrameType == eFrameSet) {
po->mFrameType = eFrame;
} else {
// Assume something iframe-like, i.e. iframe, object, or embed
po->mFrameType = eIFrame;
SetPrintAsIs(po, true);
NS_ASSERTION(po->mParent, "The root must be a parent");
po->mParent->mPrintAsIs = true;
}
}
}
}
// walk children content
for (nsIContent* child = aContent->GetFirstChild();
child;
child = child->GetNextSibling()) {
MapContentForPO(aPO, child);
}
}
//---------------------------------------------------------------------
bool
nsPrintJob::IsThereAnIFrameSelected(nsIDocShell* aDocShell,
@ -2919,29 +2985,6 @@ nsPrintJob::CleanupDocTitleArray(char16_t**& aArray, int32_t& aCount)
aCount = 0;
}
//---------------------------------------------------------------------
// static
bool
nsPrintJob::HasFramesetChild(nsIContent* aContent)
{
if (!aContent) {
return false;
}
// do a breadth search across all siblings
for (nsIContent* child = aContent->GetFirstChild();
child;
child = child->GetNextSibling()) {
if (child->IsHTMLElement(nsGkAtoms::frameset)) {
return true;
}
}
return false;
}
/** ---------------------------------------------------
* Get the Focused Frame for a documentviewer
*/
@ -3050,49 +3093,6 @@ nsPrintJob::DonePrintingPages(nsPrintObject* aPO, nsresult aResult)
return true;
}
//-------------------------------------------------------
// Recursively sets the PO items to be printed "As Is"
// from the given item down into the tree
void
nsPrintJob::SetPrintAsIs(nsPrintObject* aPO, bool aAsIs)
{
NS_ASSERTION(aPO, "Pointer is null!");
aPO->mPrintAsIs = aAsIs;
for (const UniquePtr<nsPrintObject>& kid : aPO->mKids) {
SetPrintAsIs(kid.get(), aAsIs);
}
}
//-------------------------------------------------------
// Given a DOMWindow it recursively finds the PO object that matches
nsPrintObject*
nsPrintJob::FindPrintObjectByDOMWin(nsPrintObject* aPO,
nsPIDOMWindowOuter* aDOMWin)
{
NS_ASSERTION(aPO, "Pointer is null!");
// Often the CurFocused DOMWindow is passed in
// andit is valid for it to be null, so short circut
if (!aDOMWin) {
return nullptr;
}
nsCOMPtr<nsIDocument> doc = aDOMWin->GetDoc();
if (aPO->mDocument && aPO->mDocument->GetOriginalDocument() == doc) {
return aPO;
}
for (const UniquePtr<nsPrintObject>& kid : aPO->mKids) {
nsPrintObject* po = FindPrintObjectByDOMWin(kid.get(), aDOMWin);
if (po) {
return po;
}
}
return nullptr;
}
//-------------------------------------------------------
nsresult
nsPrintJob::EnablePOsForPrinting()

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

@ -41,6 +41,9 @@ class nsPrintJob final : public nsIObserver
, public nsSupportsWeakReference
{
public:
static nsresult GetGlobalPrintSettings(nsIPrintSettings** aPrintSettings);
static void CloseProgressDialog(nsIWebProgressListener* aWebProgressListener);
nsPrintJob() = default;
// nsISupports interface...
@ -63,7 +66,6 @@ public:
NS_IMETHOD GetIsFramesetFrameSelected(bool *aIsFramesetFrameSelected);
NS_IMETHOD GetPrintPreviewNumPages(int32_t *aPrintPreviewNumPages);
NS_IMETHOD EnumerateDocumentNames(uint32_t* aCount, char16_t*** aResult);
static nsresult GetGlobalPrintSettings(nsIPrintSettings** aPrintSettings);
NS_IMETHOD GetDoingPrint(bool *aDoingPrint);
NS_IMETHOD GetDoingPrintPreview(bool *aDoingPrintPreview);
NS_IMETHOD GetCurrentPrintSettings(nsIPrintSettings **aCurrentPrintSettings);
@ -130,7 +132,6 @@ public:
// If FinishPrintPreview() fails, caller may need to reset the state of the
// object, for example by calling CleanupOnFailure().
nsresult FinishPrintPreview();
static void CloseProgressDialog(nsIWebProgressListener* aWebProgressListener);
void SetDocAndURLIntoProgress(const mozilla::UniquePtr<nsPrintObject>& aPO,
nsIPrintProgressParams* aParams);
void EllipseLongString(nsAString& aStr, const uint32_t aLen, bool aDoFront);
@ -147,27 +148,18 @@ public:
nsresult StartPagePrintTimer(const mozilla::UniquePtr<nsPrintObject>& aPO);
bool IsWindowsInOurSubTree(nsPIDOMWindowOuter* aDOMWindow);
static bool IsParentAFrameSet(nsIDocShell * aParent);
bool IsThereAnIFrameSelected(nsIDocShell* aDocShell,
nsPIDOMWindowOuter* aDOMWin,
bool& aIsParentFrameSet);
static nsPrintObject* FindPrintObjectByDOMWin(nsPrintObject* aParentObject,
nsPIDOMWindowOuter* aDOMWin);
// get the currently infocus frame for the document viewer
already_AddRefed<nsPIDOMWindowOuter> FindFocusedDOMWindow();
static void GetDocumentTitleAndURL(nsIDocument* aDoc,
nsAString& aTitle,
nsAString& aURLStr);
void GetDisplayTitleAndURL(const mozilla::UniquePtr<nsPrintObject>& aPO,
nsAString& aTitle,
nsAString& aURLStr,
eDocTitleDefault aDefType);
static bool HasFramesetChild(nsIContent* aContent);
bool CheckBeforeDestroy();
nsresult Cancelled();
@ -176,8 +168,6 @@ public:
float GetPrintPreviewScale() { return mPrtPreview->mPrintObject->
mPresContext->GetPrintPreviewScale(); }
static nsIPresShell* GetPresShellFor(nsIDocShell* aDocShell);
// These calls also update the DocViewer
void SetIsPrinting(bool aIsPrinting);
bool GetIsPrinting()
@ -213,17 +203,6 @@ private:
nsIDOMDocument* aDoc);
void FirePrintCompletionEvent();
static nsresult GetSeqFrameAndCountPagesInternal(const mozilla::UniquePtr<nsPrintObject>& aPO,
nsIFrame*& aSeqFrame,
int32_t& aCount);
static void MapContentForPO(const mozilla::UniquePtr<nsPrintObject>& aPO,
nsIContent* aContent);
static void MapContentToWebShells(const mozilla::UniquePtr<nsPrintObject>& aRootPO,
const mozilla::UniquePtr<nsPrintObject>& aPO);
static void SetPrintAsIs(nsPrintObject* aPO, bool aAsIs = true);
void DisconnectPagePrintTimer();