From 21ff37f2ef6f6c89dfa911a026675ca0b98223f8 Mon Sep 17 00:00:00 2001 From: "jst%netscape.com" Date: Wed, 17 Apr 2002 04:17:16 +0000 Subject: [PATCH] Checking in the fix for bug 52334 for the third time. This time it should stick! Making iframe's load their document even if they're not displayed. r=jkeiser@netscape.com, sr=rpotts@netscape.com. --- .../src/base/nsAccessibilityService.cpp | 79 +- content/base/public/MANIFEST | 1 + content/base/public/Makefile.in | 1 + content/base/public/makefile.win | 75 - content/base/public/nsIDocument.h | 37 +- content/base/public/nsIFrameLoader.h | 37 +- content/base/src/Makefile.in | 8 +- content/base/src/makefile.win | 26 +- content/base/src/nsDocument.cpp | 229 ++- content/base/src/nsDocument.h | 42 +- content/base/src/nsDocumentViewer.cpp | 1562 ++++++++++------- content/base/src/nsFrameLoader.cpp | 457 +++-- content/base/src/nsGenericElement.cpp | 4 +- content/base/src/nsGenericElement.h | 9 +- content/base/src/nsPrintPreviewListener.h | 3 + content/build/nsContentDLF.cpp | 5 + content/build/nsContentModule.cpp | 8 + content/events/src/nsEventStateManager.cpp | 131 +- content/html/content/src/makefile.win | 2 +- .../html/content/src/nsGenericHTMLElement.cpp | 66 +- .../html/content/src/nsGenericHTMLElement.h | 2 - .../html/content/src/nsHTMLFrameElement.cpp | 44 +- .../html/content/src/nsHTMLIFrameElement.cpp | 157 +- .../html/content/src/nsHTMLObjectElement.cpp | 30 +- .../content/src/nsHTMLSharedObjectElement.cpp | 30 +- .../content/src/nsHTMLTableCellElement.cpp | 11 +- .../html/document/src/nsHTMLContentSink.cpp | 130 +- content/html/document/src/nsHTMLDocument.cpp | 54 +- content/html/document/src/nsHTMLDocument.h | 1 - content/html/style/src/nsCSSStyleSheet.cpp | 2 +- content/macbuild/content.xml | 30 + content/xul/document/src/nsXULDocument.cpp | 186 +- content/xul/document/src/nsXULDocument.h | 12 +- docshell/base/nsDocShell.cpp | 44 +- docshell/base/nsWebShell.cpp | 2 +- dom/public/base/nsPIDOMWindow.h | 9 +- dom/public/idl/base/nsIDOMWindowInternal.idl | 2 + dom/src/base/nsGlobalWindow.cpp | 92 +- dom/src/base/nsGlobalWindow.h | 5 + dom/src/events/nsJSEventListener.cpp | 6 +- editor/libeditor/base/nsEditor.cpp | 3 +- .../inspector/base/src/inLayoutUtils.cpp | 39 +- layout/base/nsDocumentViewer.cpp | 1562 ++++++++++------- layout/base/nsIPresShell.h | 22 - layout/base/nsPresShell.cpp | 115 -- layout/base/public/nsIPresShell.h | 22 - layout/build/nsContentDLF.cpp | 5 + layout/generic/nsFrameFrame.cpp | 776 ++++---- layout/generic/nsFrameSetFrame.cpp | 36 +- layout/generic/nsFrameSetFrame.h | 7 +- layout/html/base/src/nsPresShell.cpp | 115 -- layout/html/document/src/Makefile.in | 3 +- layout/html/document/src/makefile.win | 1 + layout/html/document/src/nsFrameFrame.cpp | 776 ++++---- layout/html/document/src/nsFrameSetFrame.cpp | 36 +- layout/html/document/src/nsFrameSetFrame.h | 7 +- layout/printing/nsPrintPreviewListener.h | 3 + layout/style/nsCSSStyleSheet.cpp | 2 +- layout/xul/base/src/nsBrowserBoxObject.cpp | 28 +- layout/xul/base/src/nsEditorBoxObject.cpp | 27 +- layout/xul/base/src/nsIFrameBoxObject.cpp | 26 +- 61 files changed, 3994 insertions(+), 3248 deletions(-) diff --git a/accessible/src/base/nsAccessibilityService.cpp b/accessible/src/base/nsAccessibilityService.cpp index efa6df66e1c..5d89efeebe2 100644 --- a/accessible/src/base/nsAccessibilityService.cpp +++ b/accessible/src/base/nsAccessibilityService.cpp @@ -132,17 +132,28 @@ nsAccessibilityService::GetInfo(nsISupports* aFrame, nsIFrame** aRealFrame, nsIW return NS_OK; } -void nsAccessibilityService::GetOwnerFor(nsIPresShell *aPresShell, nsIPresShell **aOwnerShell, nsIContent **aOwnerContent) +void nsAccessibilityService::GetOwnerFor(nsIPresShell *aPresShell, + nsIPresShell **aOwnerShell, + nsIContent **aOwnerContent) { + *aOwnerShell = nsnull; + *aOwnerContent = nsnull; + nsCOMPtr presContext; aPresShell->GetPresContext(getter_AddRefs(presContext)); if (!presContext) return; + + nsCOMPtr doc; + aPresShell->GetDocument(getter_AddRefs(doc)); + + if (!doc) + return; + nsCOMPtr pcContainer; presContext->GetContainer(getter_AddRefs(pcContainer)); if (!pcContainer) return; - nsCOMPtr docShellSupports(do_QueryInterface(pcContainer)); nsCOMPtr treeItem(do_QueryInterface(pcContainer)); if (!treeItem) @@ -168,17 +179,11 @@ void nsAccessibilityService::GetOwnerFor(nsIPresShell *aPresShell, nsIPresShell if (!parentDoc) return; - nsCOMPtr rootContent; - parentDoc->GetRootContent(getter_AddRefs(rootContent)); + parentDoc->FindContentForSubDocument(doc, aOwnerContent); - nsCOMPtr tempContent; - parentPresShell->FindContentForShell(docShellSupports, getter_AddRefs(tempContent)); - - if (tempContent) { - *aOwnerContent = tempContent; + if (*aOwnerContent) { *aOwnerShell = parentPresShell; NS_ADDREF(*aOwnerShell); - NS_ADDREF(*aOwnerContent); } } @@ -252,46 +257,46 @@ nsAccessibilityService::CreateIFrameAccessible(nsIDOMNode* aDOMNode, nsIAccessib NS_WARNING("No outer pres shell in CreateHTMLIFrameAccessible!"); return NS_ERROR_FAILURE; } - + nsCOMPtr outerPresContext; outerPresShell->GetPresContext(getter_AddRefs(outerPresContext)); if (!outerPresContext) { NS_WARNING("No outer pres context in CreateHTMLIFrameAccessible!"); return NS_ERROR_FAILURE; } - + nsCOMPtr doc; if (NS_SUCCEEDED(content->GetDocument(*getter_AddRefs(doc))) && doc) { - if (outerPresShell) { - nsCOMPtr supps; - outerPresShell->GetSubShellFor(content, getter_AddRefs(supps)); - if (supps) { - nsCOMPtr docShell(do_QueryInterface(supps)); - if (docShell) { - nsCOMPtr innerPresShell; - docShell->GetPresShell(getter_AddRefs(innerPresShell)); - if (innerPresShell) { - nsCOMPtr innerWeakShell(do_GetWeakReference(innerPresShell)); - nsCOMPtr innerDoc; - innerPresShell->GetDocument(getter_AddRefs(innerDoc)); - if (innerDoc) { - nsCOMPtr innerRootAccessible(new nsHTMLIFrameRootAccessible(aDOMNode, innerWeakShell)); - if (innerRootAccessible) { - nsHTMLIFrameAccessible* outerRootAccessible = new nsHTMLIFrameAccessible(aDOMNode, innerRootAccessible, outerWeakShell, innerDoc); - if (outerRootAccessible) { - *_retval = NS_STATIC_CAST(nsIAccessible*, outerRootAccessible); - if (*_retval) { - NS_ADDREF(*_retval); - return NS_OK; - } - } - } - } + nsCOMPtr sub_doc; + doc->GetSubDocumentFor(content, getter_AddRefs(sub_doc)); + + if (sub_doc) { + nsCOMPtr innerPresShell; + sub_doc->GetShellAt(0, getter_AddRefs(innerPresShell)); + + if (innerPresShell) { + nsCOMPtr innerWeakShell = + do_GetWeakReference(innerPresShell); + + nsCOMPtr innerRootAccessible = + new nsHTMLIFrameRootAccessible(aDOMNode, innerWeakShell); + + if (innerRootAccessible) { + nsHTMLIFrameAccessible* outerRootAccessible = + new nsHTMLIFrameAccessible(aDOMNode, innerRootAccessible, + outerWeakShell, sub_doc); + + if (outerRootAccessible) { + *_retval = outerRootAccessible; + NS_ADDREF(*_retval); + + return NS_OK; } } } } } + return NS_ERROR_FAILURE; } diff --git a/content/base/public/MANIFEST b/content/base/public/MANIFEST index 78e4e5cf058..245cbe5ec1d 100644 --- a/content/base/public/MANIFEST +++ b/content/base/public/MANIFEST @@ -27,4 +27,5 @@ nsIStyleSheet.h nsIStyleSheetLinkingElement.h nsITextContent.h nsIContentList.h +nsIFrameLoader.h mozISanitizingSerializer.h diff --git a/content/base/public/Makefile.in b/content/base/public/Makefile.in index 0d8c24e8d47..0447d40b9db 100644 --- a/content/base/public/Makefile.in +++ b/content/base/public/Makefile.in @@ -57,6 +57,7 @@ nsIContentSerializer.h \ nsIHTMLToTextSink.h \ mozISanitizingSerializer.h \ nsIContentList.h \ +nsIFrameLoader.h \ $(NULL) XPIDLSRCS = \ diff --git a/content/base/public/makefile.win b/content/base/public/makefile.win index 78870f8bf27..e69de29bb2d 100644 --- a/content/base/public/makefile.win +++ b/content/base/public/makefile.win @@ -1,75 +0,0 @@ -#!nmake -# -# The contents of this file are subject to the Netscape Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/NPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is Netscape -# Communications Corporation. Portions created by Netscape are -# Copyright (C) 1998 Netscape Communications Corporation. All -# Rights Reserved. -# -# Contributor(s): - -DEPTH=..\..\.. - -EXPORTS = \ - nsContentPolicyUtils.h \ - nsIContent.h \ - nsIAnonymousContent.h \ - nsIContentIterator.h \ - nsIDocument.h \ - nsIDocumentContainer.h \ - nsIDocumentEncoder.h \ - nsIDocumentObserver.h \ - nsIDocumentViewer.h \ - nsIElementFactory.h \ - nsINameSpace.h \ - nsINameSpaceManager.h \ - nsINodeInfo.h \ - nsIRangeUtils.h \ - nsIStyledContent.h \ - nsIStyleRule.h \ - nsIStyleRuleSupplier.h \ - nsIStyleSheet.h \ - nsIStyleSheetLinkingElement.h \ - nsIStyleRuleProcessor.h \ - nsITextContent.h \ - nsContentUtils.h \ - nsIPrivateDOMImplementation.h \ - nsIContentSerializer.h \ - nsIHTMLToTextSink.h \ - mozISanitizingSerializer.h \ - nsIContentList.h \ - $(NULL) - -MODULE=content -XPIDL_MODULE=content_base - -XPIDLSRCS= \ - .\nsIContentPolicy.idl \ - .\nsISelectionController.idl \ - .\nsISelectionDisplay.idl \ - .\nsISelectionListener.idl \ - .\nsISelection.idl \ - .\nsISelectionPrivate.idl \ - .\nsIScriptLoader.idl \ - .\nsIScriptLoaderObserver.idl \ - .\nsIPrintProgress.idl \ - .\nsIPrintStatusFeedback.idl \ - .\nsIPrintProgressParams.idl \ - .\nsIDragDropHandler.idl \ - .\nsIDragDropOverride.idl \ - $(NULL) - - -include <$(DEPTH)\config\rules.mak> - diff --git a/content/base/public/nsIDocument.h b/content/base/public/nsIDocument.h index 884e23f2920..0e04926e779 100644 --- a/content/base/public/nsIDocument.h +++ b/content/base/public/nsIDocument.h @@ -227,13 +227,32 @@ public: /** * Return the parent document of this document. Will return null - * unless this document is within a compound document and has a parent. + * unless this document is within a compound document and has a + * parent. Note that this parent chain may cross chrome boundaries. */ NS_IMETHOD GetParentDocument(nsIDocument** aParent) = 0; + + /** + * Set the parent document of this document. + */ NS_IMETHOD SetParentDocument(nsIDocument* aParent) = 0; - NS_IMETHOD AddSubDocument(nsIDocument* aSubDoc) = 0; - NS_IMETHOD GetNumberOfSubDocuments(PRInt32* aCount) = 0; - NS_IMETHOD GetSubDocumentAt(PRInt32 aIndex, nsIDocument** aSubDoc) = 0; + + /** + * Set the sub document for aContent to aSubDoc. + */ + NS_IMETHOD SetSubDocumentFor(nsIContent *aContent, nsIDocument* aSubDoc) = 0; + + /** + * Get the sub document for aContent + */ + NS_IMETHOD GetSubDocumentFor(nsIContent *aContent, + nsIDocument** aSubDoc) = 0; + + /** + * Find the content node for which aDocument is a sub document. + */ + NS_IMETHOD FindContentForSubDocument(nsIDocument *aDocument, + nsIContent **aContent) = 0; /** * Return the root content object for this document. @@ -373,6 +392,16 @@ public: NS_IMETHOD AddReference(void *aKey, nsISupports *aReference) = 0; NS_IMETHOD RemoveReference(void *aKey, nsISupports **aOldReference) = 0; + + /** + * Set the container (docshell) for this document. + */ + NS_IMETHOD SetContainer(nsISupports *aContainer) = 0; + + /** + * Get the container (docshell) for this document. + */ + NS_IMETHOD GetContainer(nsISupports **aContainer) = 0; }; diff --git a/content/base/public/nsIFrameLoader.h b/content/base/public/nsIFrameLoader.h index 1fcfcc4b1d4..b4f2517e3ed 100644 --- a/content/base/public/nsIFrameLoader.h +++ b/content/base/public/nsIFrameLoader.h @@ -43,7 +43,7 @@ #include "nsAString.h" // Forward declarations -class nsIDOMElement; +class nsIContent; class nsIDocShell; class nsIURI; @@ -57,18 +57,46 @@ class nsIURI; { 0x0080d493, 0x96b4, 0x4606, \ {0xa7, 0x43, 0x0f, 0x47, 0xee, 0x87, 0x14, 0xd1} } +// CID for the nsIFrameLoader implementation +#define NS_FRAMELOADER_CID \ +{ 0x712603da, 0xf245, 0x4503, \ + {0xa5, 0x41, 0xb0, 0x49, 0xcb, 0x06, 0x81, 0xae} } + +#define NS_FRAMELOADER_CONTRACTID "@mozilla.org/content/frameloader" class nsIFrameLoader : public nsISupports { public: NS_DEFINE_STATIC_IID_ACCESSOR(NS_IFRAMELOADER_IID) - NS_IMETHOD Init(nsIDOMElement *aOwner) = 0; + /** + * Initialize the frame loader, hand it the owner content. Note that + * the owner content reference is a weak reference, if the owner + * content is destroyed before the frame loader goes away the owner + * content must call the Destroy() method to clear the owner content + * reference. + */ + NS_IMETHOD Init(nsIContent *aOwner) = 0; - NS_IMETHOD LoadURI(nsIURI *aURI) = 0; + /** + * Start loading the frame. This method figures out what to load + * from the owner content in the frame loader. + */ + NS_IMETHOD LoadFrame() = 0; + /** + * Get the docshell from the frame loader. + */ NS_IMETHOD GetDocShell(nsIDocShell **aDocShell) = 0; + /** + * Tells whether or not the loader started loading a document. + */ + NS_IMETHOD GetIsDocumentLoading(PRBool *aIsDocumentLoading) = 0; + + /** + * Destroy the frame loader and everything inside it. This will + * clear the weak owner content reference. */ NS_IMETHOD Destroy() = 0; }; @@ -78,6 +106,9 @@ class nsIFrameLoaderOwner : public nsISupports public: NS_DEFINE_STATIC_IID_ACCESSOR(NS_IFRAMELOADEROWNER_IID) + /** + * Get the frame loader from the frame loader owner. + */ NS_IMETHOD GetFrameLoader(nsIFrameLoader **aFrameLoader) = 0; }; diff --git a/content/base/src/Makefile.in b/content/base/src/Makefile.in index 01f1bf33d6a..c407c58886b 100644 --- a/content/base/src/Makefile.in +++ b/content/base/src/Makefile.in @@ -56,8 +56,8 @@ REQUIRES = xpcom \ imglib2 \ gfx2 \ uriloader \ - webbrwsr \ - webBrowser_core \ + webbrwsr \ + webBrowser_core \ $(NULL) CPPSRCS = \ @@ -99,9 +99,11 @@ CPPSRCS = \ nsScriptLoader.cpp \ nsStyleLinkElement.cpp \ nsContentAreaDragDrop.cpp \ + nsFrameLoader.cpp \ $(NULL) -# we don't want the shared lib, but we want to force the creation of a static lib. +# we don't want the shared lib, but we want to force the creation of a +# static lib. FORCE_STATIC_LIB = 1 include $(topsrcdir)/config/rules.mk diff --git a/content/base/src/makefile.win b/content/base/src/makefile.win index 36ad94a636b..34c578e05bc 100644 --- a/content/base/src/makefile.win +++ b/content/base/src/makefile.win @@ -43,6 +43,7 @@ REQUIRES = xpcom \ uconv \ chrome \ docshell \ + uriloader \ pref \ xpconnect \ util \ @@ -69,10 +70,10 @@ CPP_OBJS= \ .\$(OBJDIR)\nsCommentNode.obj \ .\$(OBJDIR)\nsGenericDOMDataNode.obj \ .\$(OBJDIR)\nsGenericDOMNodeList.obj \ - .\$(OBJDIR)\nsGenericElement.obj \ - .\$(OBJDIR)\nsContentList.obj \ - .\$(OBJDIR)\nsContentIterator.obj \ - .\$(OBJDIR)\nsContentPolicy.obj \ + .\$(OBJDIR)\nsGenericElement.obj \ + .\$(OBJDIR)\nsContentList.obj \ + .\$(OBJDIR)\nsContentIterator.obj \ + .\$(OBJDIR)\nsContentPolicy.obj \ .\$(OBJDIR)\nsDocument.obj \ .\$(OBJDIR)\nsDocumentEncoder.obj \ .\$(OBJDIR)\nsDocumentFragment.obj \ @@ -80,7 +81,7 @@ CPP_OBJS= \ .\$(OBJDIR)\nsDOMAttribute.obj \ .\$(OBJDIR)\nsDOMAttributeMap.obj \ .\$(OBJDIR)\nsDOMDocumentType.obj \ - .\$(OBJDIR)\nsGeneratedIterator.obj \ + .\$(OBJDIR)\nsGeneratedIterator.obj \ .\$(OBJDIR)\nsNameSpaceManager.obj \ .\$(OBJDIR)\nsNodeInfo.obj \ .\$(OBJDIR)\nsNodeInfoManager.obj \ @@ -92,13 +93,14 @@ CPP_OBJS= \ .\$(OBJDIR)\nsTreeWalker.obj \ .\$(OBJDIR)\nsXMLContentSerializer.obj \ .\$(OBJDIR)\nsHTMLContentSerializer.obj \ - .\$(OBJDIR)\nsParserUtils.obj \ - .\$(OBJDIR)\nsPlainTextSerializer.obj \ - .\$(OBJDIR)\mozSanitizingSerializer.obj \ - .\$(OBJDIR)\nsContentUtils.obj \ - .\$(OBJDIR)\nsScriptLoader.obj \ - .\$(OBJDIR)\nsStyleLinkElement.obj \ - .\$(OBJDIR)\nsContentAreaDragDrop.obj \ + .\$(OBJDIR)\nsParserUtils.obj \ + .\$(OBJDIR)\nsPlainTextSerializer.obj \ + .\$(OBJDIR)\mozSanitizingSerializer.obj \ + .\$(OBJDIR)\nsContentUtils.obj \ + .\$(OBJDIR)\nsScriptLoader.obj \ + .\$(OBJDIR)\nsStyleLinkElement.obj \ + .\$(OBJDIR)\nsContentAreaDragDrop.obj \ + .\$(OBJDIR)\nsFrameLoader.obj \ $(NULL) LINCS=-I..\..\html\base\src -I..\..\html\style\src \ diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index dccd192f2de..82ccca41634 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -178,7 +178,7 @@ NS_IMPL_RELEASE(nsDOMStyleSheetList) NS_IMETHODIMP nsDOMStyleSheetList::GetLength(PRUint32* aLength) { - if (nsnull != mDocument) { + if (mDocument) { // XXX Find the number and then cache it. We'll use the // observer notification to figure out if new ones have // been added or removed. @@ -473,7 +473,7 @@ NS_IMPL_RELEASE_USING_AGGREGATOR(nsXPathDocumentTearoff, mDocument) // ================================================================== nsDocument::nsDocument() : mIsGoingAway(PR_FALSE), - mCSSLoader(nsnull), + mCSSLoader(nsnull), mSubDocuments(nsnull), mXPathDocument(nsnull) { NS_INIT_REFCNT(); @@ -505,6 +505,7 @@ nsDocument::nsDocument() : mIsGoingAway(PR_FALSE), mObservers.InsertElementAt(observer, 0); } + nsDocument::~nsDocument() { delete mXPathDocument; @@ -532,11 +533,12 @@ nsDocument::~nsDocument() mParentDocument = nsnull; - // Delete references to sub-documents - indx = mSubDocuments.Count(); - while (--indx >= 0) { - nsIDocument* subdoc = (nsIDocument*) mSubDocuments.ElementAt(indx); - NS_RELEASE(subdoc); + // Kill the subdocument map, doing this will release its strong + // references, if any. + if (mSubDocuments) { + PL_DHashTableDestroy(mSubDocuments); + + mSubDocuments = nsnull; } if (mRootContent) { @@ -723,25 +725,28 @@ nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup) NS_IF_RELEASE(mPrincipal); mDocumentLoadGroup = nsnull; - // Delete references to sub-documents - PRInt32 indx = mSubDocuments.Count(); - while (--indx >= 0) { - nsIDocument* subdoc = (nsIDocument*) mSubDocuments.ElementAt(indx); - NS_RELEASE(subdoc); + // Delete references to sub-documents and kill the subdocument map, + // if any. It holds strong references + if (mSubDocuments) { + PL_DHashTableDestroy(mSubDocuments); + + mSubDocuments = nsnull; } mRootContent = nsnull; PRUint32 count, i; mChildren->Count(&count); for (i = 0; i < count; i++) { - nsCOMPtr content(dont_AddRef(NS_STATIC_CAST(nsIContent*,mChildren->ElementAt(i)))); + nsCOMPtr content = + dont_AddRef(NS_STATIC_CAST(nsIContent *, mChildren->ElementAt(i))); + content->SetDocument(nsnull, PR_TRUE, PR_TRUE); - ContentRemoved(nsnull, content, indx); + ContentRemoved(nsnull, content, i); } mChildren->Clear(); // Delete references to style sheets - indx = mStyleSheets.Count(); + PRInt32 indx = mStyleSheets.Count(); while (--indx >= 0) { nsIStyleSheet* sheet = (nsIStyleSheet*) mStyleSheets.ElementAt(indx); sheet->SetOwningDocument(nsnull); @@ -775,8 +780,9 @@ nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup) if (aLoadGroup) { mDocumentLoadGroup = getter_AddRefs(NS_GetWeakReference(aLoadGroup)); - // there was an assertion here that aLoadGroup was not null. This is no longer valid - // nsWebShell::SetDocument does not create a load group, and it works just fine. + // there was an assertion here that aLoadGroup was not null. This + // is no longer valid nsWebShell::SetDocument does not create a + // load group, and it works just fine. } if (NS_OK == rv) @@ -1211,26 +1217,151 @@ nsDocument::SetParentDocument(nsIDocument* aParent) return NS_OK; } -NS_IMETHODIMP -nsDocument::AddSubDocument(nsIDocument* aSubDoc) +PR_STATIC_CALLBACK(void) +SubDocClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry) { - NS_ADDREF(aSubDoc); - mSubDocuments.AppendElement(aSubDoc); + SubDocMapEntry *e = NS_STATIC_CAST(SubDocMapEntry *, entry); + + NS_RELEASE(e->mKey); + NS_IF_RELEASE(e->mSubDocument); +} + +PR_STATIC_CALLBACK(void) +SubDocInitEntry(PLDHashTable *table, PLDHashEntryHdr *entry, const void *key) +{ + SubDocMapEntry *e = + NS_CONST_CAST(SubDocMapEntry *, + NS_STATIC_CAST(const SubDocMapEntry *, entry)); + + e->mKey = NS_CONST_CAST(nsIContent *, + NS_STATIC_CAST(const nsIContent *, key)); + NS_ADDREF(e->mKey); + + e->mSubDocument = nsnull; +} + +NS_IMETHODIMP +nsDocument::SetSubDocumentFor(nsIContent *aContent, nsIDocument* aSubDoc) +{ + NS_ENSURE_TRUE(aContent, NS_ERROR_UNEXPECTED); + + if (!aSubDoc) { + // aSubDoc is nsnull, remove the mapping + + if (mSubDocuments) { + SubDocMapEntry *entry = + NS_STATIC_CAST(SubDocMapEntry*, + PL_DHashTableOperate(mSubDocuments, aContent, + PL_DHASH_LOOKUP)); + + if (PL_DHASH_ENTRY_IS_LIVE(entry)) { + entry->mSubDocument->SetParentDocument(nsnull); + + PL_DHashTableRawRemove(mSubDocuments, entry); + } + } + } else { + if (!mSubDocuments) { + // Create a new hashtable + + static PLDHashTableOps hash_table_ops = + { + PL_DHashAllocTable, + PL_DHashFreeTable, + PL_DHashGetKeyStub, + PL_DHashVoidPtrKeyStub, + PL_DHashMatchEntryStub, + PL_DHashMoveEntryStub, + SubDocClearEntry, + PL_DHashFinalizeStub, + SubDocInitEntry + }; + + mSubDocuments = PL_NewDHashTable(&hash_table_ops, nsnull, + sizeof(SubDocMapEntry), 16); + if (!mSubDocuments) { + return NS_ERROR_OUT_OF_MEMORY; + } + } + + // Add a mapping to the hash table + SubDocMapEntry *entry = + NS_STATIC_CAST(SubDocMapEntry*, + PL_DHashTableOperate(mSubDocuments, aContent, + PL_DHASH_ADD)); + + if (!entry) { + return NS_ERROR_OUT_OF_MEMORY; + } + + if (entry->mSubDocument) { + entry->mSubDocument->SetParentDocument(nsnull); + + // Release the old sub document + NS_RELEASE(entry->mSubDocument); + } + + entry->mSubDocument = aSubDoc; + NS_ADDREF(entry->mSubDocument); + + aSubDoc->SetParentDocument(this); + } + return NS_OK; } NS_IMETHODIMP -nsDocument::GetNumberOfSubDocuments(PRInt32* aCount) +nsDocument::GetSubDocumentFor(nsIContent *aContent, nsIDocument** aSubDoc) { - *aCount = mSubDocuments.Count(); + *aSubDoc = nsnull; + + if (mSubDocuments) { + SubDocMapEntry *entry = + NS_STATIC_CAST(SubDocMapEntry*, + PL_DHashTableOperate(mSubDocuments, aContent, + PL_DHASH_LOOKUP)); + + if (PL_DHASH_ENTRY_IS_LIVE(entry)) { + *aSubDoc = entry->mSubDocument; + NS_ADDREF(*aSubDoc); + } + } + return NS_OK; } -NS_IMETHODIMP -nsDocument::GetSubDocumentAt(PRInt32 aIndex, nsIDocument** aSubDoc) +PR_STATIC_CALLBACK(PLDHashOperator) +FindContentEnumerator(PLDHashTable *table, PLDHashEntryHdr *hdr, + PRUint32 number, void *arg) { - *aSubDoc = (nsIDocument*) mSubDocuments.SafeElementAt(aIndex); - NS_IF_ADDREF(*aSubDoc); + SubDocMapEntry *entry = NS_STATIC_CAST(SubDocMapEntry*, hdr); + FindContentData *data = NS_STATIC_CAST(FindContentData*, arg); + + if (entry->mSubDocument == data->mSubDocument) { + data->mResult = entry->mKey; + + return PL_DHASH_STOP; + } + + return PL_DHASH_NEXT; +} + +NS_IMETHODIMP +nsDocument::FindContentForSubDocument(nsIDocument *aDocument, + nsIContent **aContent) +{ + NS_ENSURE_ARG_POINTER(aDocument); + + if (!mSubDocuments) { + *aContent = nsnull; + return NS_OK; + } + + FindContentData data(aDocument); + PL_DHashTableEnumerate(mSubDocuments, FindContentEnumerator, &data); + + *aContent = data.mResult; + NS_IF_ADDREF(*aContent); return NS_OK; } @@ -1792,23 +1923,18 @@ nsDocument::EndLoad() if (docShellAsItem) { docShellAsItem->GetSameTypeParent(getter_AddRefs(docShellParent)); - nsCOMPtr doc; + nsCOMPtr parent_doc; - GetDocumentFromDocShellTreeItem(docShellParent, getter_AddRefs(doc)); + GetDocumentFromDocShellTreeItem(docShellParent, + getter_AddRefs(parent_doc)); - if (doc) { - nsCOMPtr shell; - doc->GetShellAt(0, getter_AddRefs(shell)); + if (parent_doc) { + nsCOMPtr target_content; - if (shell) { - nsCOMPtr target_content; + parent_doc->FindContentForSubDocument(this, + getter_AddRefs(target_content)); - nsCOMPtr docshell_identity(docShell); - shell->FindContentForShell(docshell_identity, - getter_AddRefs(target_content)); - - target_frame = do_QueryInterface(target_content); - } + target_frame = do_QueryInterface(target_content); } } } @@ -2197,8 +2323,8 @@ nsDocument::GetDocumentElement(nsIDOMElement** aDocumentElement) nsresult res = NS_OK; - if (nsnull != mRootContent) { - res = mRootContent->QueryInterface(NS_GET_IID(nsIDOMElement), (void**)aDocumentElement); + if (mRootContent) { + res = CallQueryInterface(mRootContent, aDocumentElement); NS_ASSERTION(NS_OK == res, "Must be a DOM Element"); } else { *aDocumentElement = nsnull; @@ -3523,6 +3649,25 @@ nsDocument::RemoveReference(void *aKey, nsISupports **aOldReference) return NS_OK; } +NS_IMETHODIMP +nsDocument::SetContainer(nsISupports *aContainer) +{ + mDocumentContainer = dont_AddRef(NS_GetWeakReference(aContainer)); + + return NS_OK; +} + +NS_IMETHODIMP +nsDocument::GetContainer(nsISupports **aContainer) +{ + nsCOMPtr container = do_QueryReferent(mDocumentContainer); + + *aContainer = container; + NS_IF_ADDREF(*aContainer); + + return NS_OK; +} + #ifdef IBMBIDI /** * Check if bidi enabled (set depending on the presence of RTL diff --git a/content/base/src/nsDocument.h b/content/base/src/nsDocument.h index d32a2185ea5..66586a9a58d 100644 --- a/content/base/src/nsDocument.h +++ b/content/base/src/nsDocument.h @@ -70,6 +70,8 @@ #include "nsICSSLoader.h" #include "nsIDOMXPathEvaluator.h" +#include "pldhash.h" + class nsIEventListenerManager; class nsDOMStyleSheetList; class nsIOutputStream; @@ -214,6 +216,29 @@ protected: void* mScriptObject; }; + +// Helper structs for the content->subdoc map + +class SubDocMapEntry : public PLDHashEntryHdr +{ +public: + // Both of these are strong references + nsIContent *mKey; // must be first, to look like PLDHashEntryStub + nsIDocument *mSubDocument; +}; + +struct FindContentData +{ + FindContentData(nsIDocument *aSubDoc) + : mSubDocument(aSubDoc), mResult(nsnull) + { + } + + nsISupports *mSubDocument; + nsIContent *mResult; +}; + + // Base class for our document implementations. // // Note that this class *implements* nsIDOMXMLDocument, but it's not @@ -369,9 +394,11 @@ public: */ NS_IMETHOD GetParentDocument(nsIDocument** aParent); NS_IMETHOD SetParentDocument(nsIDocument* aParent); - NS_IMETHOD AddSubDocument(nsIDocument* aSubDoc); - NS_IMETHOD GetNumberOfSubDocuments(PRInt32* aCount); - NS_IMETHOD GetSubDocumentAt(PRInt32 aIndex, nsIDocument** aSubDoc); + + NS_IMETHOD SetSubDocumentFor(nsIContent *aContent, nsIDocument* aSubDoc); + NS_IMETHOD GetSubDocumentFor(nsIContent *aContent, nsIDocument** aSubDoc); + NS_IMETHOD FindContentForSubDocument(nsIDocument *aDocument, + nsIContent **aContent); /** * Return the root content object for this document. @@ -494,6 +521,8 @@ public: NS_IMETHOD GetNodeInfoManager(nsINodeInfoManager*& aNodeInfoManager); NS_IMETHOD AddReference(void *aKey, nsISupports *aReference); NS_IMETHOD RemoveReference(void *aKey, nsISupports **aOldReference); + NS_IMETHOD SetContainer(nsISupports *aContainer); + NS_IMETHOD GetContainer(nsISupports **aContainer); // nsIDOMNode NS_DECL_NSIDOMNODE @@ -575,13 +604,16 @@ protected: nsCOMPtr mDocumentBaseURL; nsIPrincipal* mPrincipal; nsWeakPtr mDocumentLoadGroup; - + nsWeakPtr mDocumentContainer; + nsString mCharacterSet; PRInt32 mCharacterSetSource; nsVoidArray mCharSetObservers; nsIDocument* mParentDocument; - nsVoidArray mSubDocuments; + + PLDHashTable *mSubDocuments; + nsVoidArray mPresShells; nsCOMPtr mChildren; // contains owning references nsIContent* mRootContent; // a weak reference to the only element in diff --git a/content/base/src/nsDocumentViewer.cpp b/content/base/src/nsDocumentViewer.cpp index 52364c8d931..73050b89b52 100644 --- a/content/base/src/nsDocumentViewer.cpp +++ b/content/base/src/nsDocumentViewer.cpp @@ -93,6 +93,7 @@ #include "nsIDocShellTreeNode.h" #include "nsIDocShellTreeOwner.h" #include "nsIDocShell.h" +#include "nsIBaseWindow.h" #include "nsIFrameDebug.h" #include "nsILayoutHistoryState.h" #include "nsLayoutAtoms.h" @@ -146,7 +147,7 @@ static NS_DEFINE_IID(kPrinterEnumeratorCID, NS_PRINTER_ENUMERATOR_CID); // Print Preview #include "nsIPrintPreviewContext.h" #include "imgIContainer.h" // image animation mode constants -#include "nsIScrollableView.h" +#include "nsIScrollableView.h" #include "nsIWebBrowserPrint.h" // needed for PrintPreview Navigation constants // Print Progress @@ -170,7 +171,7 @@ static NS_DEFINE_IID(kPrinterEnumeratorCID, NS_PRINTER_ENUMERATOR_CID); #include "nsIWebShell.h" //focus -#include "nsIDOMEventReceiver.h" +#include "nsIDOMEventReceiver.h" #include "nsIDOMFocusListener.h" #include "nsISelectionController.h" @@ -199,7 +200,7 @@ static NS_DEFINE_CID(kStyleSetCID, NS_STYLESET_CID); #ifdef DEBUG_PRINTING // XXX NOTE: I am including a header from the layout directory // merely to set up a file pointer for debug logging. This is -// fragile and may break in the future, which means it can be +// fragile and may break in the future, which means it can be // removed if necessary #if defined(XP_PC) #include "../../../layout/html/base/src/nsSimplePageSequence.h" @@ -213,20 +214,20 @@ static const char * gPrintRangeStr[] = {"kRangeAllPages", "kRangeSpecified static PRUint32 gDumpFileNameCnt = 0; static PRUint32 gDumpLOFileNameCnt = 0; -#define PRINT_DEBUG_MSG1(_msg1) fprintf(mPrt->mDebugFD, (_msg1)); -#define PRINT_DEBUG_MSG2(_msg1, _msg2) fprintf(mPrt->mDebugFD, (_msg1), (_msg2)); -#define PRINT_DEBUG_MSG3(_msg1, _msg2, _msg3) fprintf(mPrt->mDebugFD, (_msg1), (_msg2), (_msg3)); -#define PRINT_DEBUG_MSG4(_msg1, _msg2, _msg3, _msg4) fprintf(mPrt->mDebugFD, (_msg1), (_msg2), (_msg3), (_msg4)); -#define PRINT_DEBUG_MSG5(_msg1, _msg2, _msg3, _msg4, _msg5) fprintf(mPrt->mDebugFD, (_msg1), (_msg2), (_msg3), (_msg4), (_msg5)); +#define PRINT_DEBUG_MSG1(_msg1) fprintf(mPrt->mDebugFD, (_msg1)); +#define PRINT_DEBUG_MSG2(_msg1, _msg2) fprintf(mPrt->mDebugFD, (_msg1), (_msg2)); +#define PRINT_DEBUG_MSG3(_msg1, _msg2, _msg3) fprintf(mPrt->mDebugFD, (_msg1), (_msg2), (_msg3)); +#define PRINT_DEBUG_MSG4(_msg1, _msg2, _msg3, _msg4) fprintf(mPrt->mDebugFD, (_msg1), (_msg2), (_msg3), (_msg4)); +#define PRINT_DEBUG_MSG5(_msg1, _msg2, _msg3, _msg4, _msg5) fprintf(mPrt->mDebugFD, (_msg1), (_msg2), (_msg3), (_msg4), (_msg5)); #define PRINT_DEBUG_FLUSH fflush(mPrt->mDebugFD); #else //-------------- -#define PRT_YESNO(_p) -#define PRINT_DEBUG_MSG1(_msg) -#define PRINT_DEBUG_MSG2(_msg1, _msg2) -#define PRINT_DEBUG_MSG3(_msg1, _msg2, _msg3) -#define PRINT_DEBUG_MSG4(_msg1, _msg2, _msg3, _msg4) -#define PRINT_DEBUG_MSG5(_msg1, _msg2, _msg3, _msg4, _msg5) -#define PRINT_DEBUG_FLUSH +#define PRT_YESNO(_p) +#define PRINT_DEBUG_MSG1(_msg) +#define PRINT_DEBUG_MSG2(_msg1, _msg2) +#define PRINT_DEBUG_MSG3(_msg1, _msg2, _msg3) +#define PRINT_DEBUG_MSG4(_msg1, _msg2, _msg3, _msg4) +#define PRINT_DEBUG_MSG5(_msg1, _msg2, _msg3, _msg4, _msg5) +#define PRINT_DEBUG_FLUSH #endif @@ -252,7 +253,7 @@ public: NS_DECL_ISUPPORTS // nsISelectionListerner interface - NS_DECL_NSISELECTIONLISTENER + NS_DECL_NSISELECTIONLISTENER nsDocViewerSelectionListener() : mDocViewer(NULL) @@ -261,9 +262,9 @@ public: { NS_INIT_REFCNT(); } - + virtual ~nsDocViewerSelectionListener() {} - + nsresult Init(DocumentViewerImpl *aDocViewer); protected: @@ -271,13 +272,13 @@ protected: DocumentViewerImpl* mDocViewer; PRPackedBool mGotSelectionState; PRPackedBool mSelectionWasCollapsed; - + }; /** editor Implementation of the FocusListener interface */ -class nsDocViewerFocusListener : public nsIDOMFocusListener +class nsDocViewerFocusListener : public nsIDOMFocusListener { public: /** default constructor @@ -314,12 +315,14 @@ private: class CachedPresentationObj { public: - CachedPresentationObj(nsIPresShell* aShell, nsIPresContext* aPC, nsIViewManager* aVM, nsIWidget* aW): - mPresShell(aShell), mPresContext(aPC), mViewManager(aVM), mWindow(aW) {} + CachedPresentationObj(nsIPresShell* aShell, nsIPresContext* aPC, + nsIViewManager* aVM, nsIWidget* aW): + mPresShell(aShell), mPresContext(aPC), mViewManager(aVM), mWindow(aW) + { + } - - nsCOMPtr mPresContext; nsCOMPtr mPresShell; + nsCOMPtr mPresContext; nsCOMPtr mViewManager; nsCOMPtr mWindow; }; @@ -400,8 +403,8 @@ public: // Listener Helper Methods void OnEndPrinting(); void OnStartPrinting(); - static void DoOnProgressChange(nsVoidArray& aListeners, - PRInt32 aProgess, + static void DoOnProgressChange(nsVoidArray& aListeners, + PRInt32 aProgess, PRInt32 aMaxProgress, PRBool aDoStartStop = PR_FALSE, PRInt32 aFlag = 0); @@ -418,7 +421,7 @@ public: nsCOMPtr mPrintProgress; nsCOMPtr mPrintProgressParams; PRBool mShowProgressDialog; - + nsCOMPtr mCurrentFocusWin; // cache a pointer to the currently focused window nsVoidArray* mPrintDocList; @@ -476,11 +479,11 @@ class DocumentViewerImpl : public nsIDocumentViewer, friend class nsDocViewerSelectionListener; friend class nsPagePrintTimer; friend class PrintData; - + public: DocumentViewerImpl(); DocumentViewerImpl(nsIPresContext* aPresContext); - + NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW // nsISupports interface... @@ -515,15 +518,24 @@ public: nsresult CallChildren(CallChildFunc aFunc, void* aClosure); // Printing Methods - PRBool PrintPage(nsIPresContext* aPresContext,nsIPrintSettings* aPrintSettings,PrintObject* aPOect, PRBool& aInRange); + PRBool PrintPage(nsIPresContext* aPresContext, + nsIPrintSettings* aPrintSettings, + PrintObject* aPOect, PRBool& aInRange); PRBool DonePrintingPages(PrintObject* aPO); - + // helper method - static void GetWebShellTitleAndURL(nsIWebShell * aWebShell, PRUnichar** aTitle, PRUnichar** aURLStr); + static void GetWebShellTitleAndURL(nsIWebShell* aWebShell, + PRUnichar** aTitle, PRUnichar** aURLStr); // This enum tells indicates what the default should be for the title // if the title from the document is null - enum eDocTitleDefault {eDocTitleDefNone, eDocTitleDefBlank, eDocTitleDefDocument, eDocTitleDefURLDoc}; + enum eDocTitleDefault { + eDocTitleDefNone, + eDocTitleDefBlank, + eDocTitleDefDocument, + eDocTitleDefURLDoc + }; + static void GetDisplayTitleAndURL(PrintObject* aPO, nsIPrintSettings* aPrintSettings, const PRUnichar* aBrandName, @@ -543,12 +555,15 @@ private: nsIDeviceContext* aDeviceContext, const nsRect& aBounds, PRBool aDoCreation); - nsresult GetDocumentSelection(nsISelection **aSelection, nsIPresShell * aPresShell = nsnull); + nsresult InitPresentationStuff(PRBool aDoInitialReflow); + + nsresult GetDocumentSelection(nsISelection **aSelection, + nsIPresShell * aPresShell = nsnull); nsresult FindFrameSetWithIID(nsIContent * aParentContent, const nsIID& aIID); PRBool IsThereARangeSelection(nsIDOMWindowInternal * aDOMWin); PRBool IsParentAFrameSet(nsIWebShell * aParent); PRBool IsWebShellAFrameSet(nsIWebShell * aParent); - + PRBool IsThereAnIFrameSelected(nsIWebShell* aWebShell, nsIDOMWindowInternal * aDOMWin, PRPackedBool& aDoesContainFrameset); @@ -560,11 +575,12 @@ private: nsresult GetPopupImageNode(nsIDOMNode** aNode); //--------------------------------------------------------------------- - void BuildDocTree(nsIDocShellTreeNode * aParentNode, - nsVoidArray * aDocList, + void BuildDocTree(nsIDocShellTreeNode * aParentNode, + nsVoidArray * aDocList, PrintObject * aPO); - nsresult ReflowDocList(PrintObject * aPO, PRBool aSetPixelScale, PRBool aDoCalcShrink); - void SetClipRect(PrintObject* aPO, + nsresult ReflowDocList(PrintObject * aPO, PRBool aSetPixelScale, + PRBool aDoCalcShrink); + void SetClipRect(PrintObject* aPO, const nsRect& aClipRect, nscoord aOffsetX, nscoord aOffsetY, @@ -579,14 +595,18 @@ private: nsIContent* aContent); void MapContentToWebShells(PrintObject* aRootPO, PrintObject* aPO); nsresult MapSubDocFrameLocations(PrintObject* aPO); - PrintObject* FindPrintObjectByDOMWin(PrintObject* aParentObject, nsIDOMWindowInternal * aDOMWin); - void GetPresShellAndRootContent(nsIWebShell * aWebShell, nsIPresShell** aPresShell, nsIContent** aContent); + PrintObject* FindPrintObjectByDOMWin(PrintObject* aParentObject, + nsIDOMWindowInternal * aDOMWin); + void GetPresShellAndRootContent(nsIWebShell * aWebShell, + nsIPresShell** aPresShell, + nsIContent** aContent); void CalcNumPrintableDocsAndPages(PRInt32& aNumDocs, PRInt32& aNumPages); void DoProgressForAsIsFrames(); void DoProgressForSeparateFrames(); void DoPrintProgress(PRBool aIsForPrinting); - void SetDocAndURLIntoProgress(PrintObject* aPO, nsIPrintProgressParams* aParams); + void SetDocAndURLIntoProgress(PrintObject* aPO, + nsIPrintProgressParams* aParams); nsresult CheckForPrinters(nsIPrintOptions* aPrintOptions, nsIPrintSettings* aPrintSettings, PRUint32 aErrorCode, @@ -605,7 +625,8 @@ private: // nsresult DocumentReadyForPrinting(); //nsresult PrintSelection(nsIDeviceContextSpec * aDevSpec); - nsresult GetSelectionDocument(nsIDeviceContextSpec * aDevSpec, nsIDocument ** aNewDoc); + nsresult GetSelectionDocument(nsIDeviceContextSpec * aDevSpec, + nsIDocument ** aNewDoc); static void PR_CALLBACK HandlePLEvent(PLEvent* aEvent); static void PR_CALLBACK DestroyPLEvent(PLEvent* aEvent); @@ -615,12 +636,17 @@ private: nsIDOMWindowInternal* aCurrentFocusedDOMWin); nsresult EnablePOsForPrinting(); PrintObject* FindXMostPO(); - void FindXMostFrameSize(nsIPresContext* aPresContext, nsIRenderingContext* aRC, nsIFrame* aFrame, nscoord aX, nscoord aY, PRInt32& aMaxWidth); - void FindXMostFrameInList(nsIPresContext* aPresContext, nsIRenderingContext* aRC, nsIAtom* aList, nsIFrame* aFrame, - nscoord aX, nscoord aY, PRInt32& aMaxWidth); + void FindXMostFrameSize(nsIPresContext* aPresContext, + nsIRenderingContext* aRC, nsIFrame* aFrame, + nscoord aX, nscoord aY, PRInt32& aMaxWidth); + void FindXMostFrameInList(nsIPresContext* aPresContext, + nsIRenderingContext* aRC, nsIAtom* aList, + nsIFrame* aFrame, nscoord aX, nscoord aY, + PRInt32& aMaxWidth); PRBool PrintDocContent(PrintObject* aPO, nsresult& aStatus); - nsresult DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& aDonePrinting); + nsresult DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, + PRBool& aDonePrinting); void SetPrintAsIs(PrintObject* aPO, PRBool aAsIs = PR_TRUE); enum ePrintFlags {eSetPrintFlag = 1U, eSetHiddenFlag = 2U }; @@ -637,15 +663,18 @@ private: // Timer Methods - nsresult StartPagePrintTimer(nsIPresContext * aPresContext, + nsresult StartPagePrintTimer(nsIPresContext * aPresContext, nsIPrintSettings* aPrintSettings, PrintObject* aPO, PRUint32 aDelay); void PrepareToStartLoad(void); - + + nsresult SyncParentSubDocMap(); + // Misc - static void ShowPrintErrorDialog(nsresult printerror, PRBool aIsPrinting = PR_TRUE); + static void ShowPrintErrorDialog(nsresult printerror, + PRBool aIsPrinting = PR_TRUE); protected: // IMPORTANT: The ownership implicit in the following member @@ -653,10 +682,9 @@ protected: // for owning pointers and raw COM interface pointers for weak // (ie, non owning) references. If you add any members to this // class, please make the ownership explicit (pinkerton, scc). - + nsISupports* mContainer; // [WEAK] it owns me! nsCOMPtr mDeviceContext; // ??? can't hurt, but... - nsIView* mView; // [WEAK] cleaned up by view mgr // the following seven items are explicitly in this order // so they will be destroyed in the reverse order (pinkerton, scc) @@ -671,7 +699,7 @@ protected: nsCOMPtr mSelectionListener; nsCOMPtr mFocusListener; - + nsCOMPtr mPreviousViewer; PRBool mEnableRendering; @@ -746,7 +774,7 @@ public: NS_WARNING("unable to start the timer"); } else { mTimer->Init(this, aUseDelay?mDelay:0, NS_PRIORITY_NORMAL, NS_TYPE_ONE_SHOT); - } + } return result; } @@ -767,7 +795,7 @@ public: if (mDocViewer->DonePrintingPages(mPrintObj)) { initNewTimer = PR_FALSE; } - } + } Stop(); if (initNewTimer) { @@ -780,15 +808,15 @@ public: } } - void Init(DocumentViewerImpl* aDocViewerImpl, + void Init(DocumentViewerImpl* aDocViewerImpl, nsIPresContext* aPresContext, nsIPrintSettings* aPrintSettings, PrintObject* aPO, - PRUint32 aDelay) + PRUint32 aDelay) { NS_IF_RELEASE(mDocViewer); mDocViewer = aDocViewerImpl; - NS_ADDREF(mDocViewer); + NS_ADDREF(mDocViewer); mPresContext = aPresContext; mPrintSettings = aPrintSettings; @@ -796,11 +824,11 @@ public: mDelay = aDelay; } - nsresult Start(DocumentViewerImpl* aDocViewerImpl, + nsresult Start(DocumentViewerImpl* aDocViewerImpl, nsIPresContext* aPresContext, nsIPrintSettings* aPrintSettings, PrintObject* aPO, - PRUint32 aDelay) + PRUint32 aDelay) { Init(aDocViewerImpl, aPresContext, aPrintSettings, aPO, aDelay); return StartTimer(PR_FALSE); @@ -850,7 +878,7 @@ static nsresult NS_NewUpdateTimer(nsPagePrintTimer **aResult) PrintData::PrintData() : mPrintView(nsnull), mDebugFilePtr(nsnull), mPrintObject(nsnull), mSelectedPO(nsnull), mShowProgressDialog(PR_TRUE), mPrintDocList(nsnull), mIsIFrameSelected(PR_FALSE), - mIsParentAFrameSet(PR_FALSE), mPrintingAsIsSubDoc(PR_FALSE), mOnStartSent(PR_FALSE), + mIsParentAFrameSet(PR_FALSE), mPrintingAsIsSubDoc(PR_FALSE), mOnStartSent(PR_FALSE), mIsAborted(PR_FALSE), mPreparingForPrint(PR_FALSE), mDocWasToBeDestroyed(PR_FALSE), mShrinkToFit(PR_FALSE), mPrintFrameType(nsIPrintSettings::kFramesAsIs), mNumPrintableDocs(0), mNumDocsPrinted(0), mNumPrintablePages(0), mNumPagesPrinted(0), @@ -876,7 +904,7 @@ PrintData::PrintData() : } -PrintData::~PrintData() +PrintData::~PrintData() { // Set the cached Zoom value back into the DC @@ -912,7 +940,7 @@ PrintData::~PrintData() if (!isCancelled && !mIsAborted) { rv = mPrintDC->EndDocument(); } else { - rv = mPrintDC->AbortDocument(); + rv = mPrintDC->AbortDocument(); } if (NS_FAILED(rv)) { DocumentViewerImpl::ShowPrintErrorDialog(rv); @@ -961,8 +989,8 @@ void PrintData::OnEndPrinting() } void -PrintData::DoOnProgressChange(nsVoidArray& aListeners, - PRInt32 aProgess, +PrintData::DoOnProgressChange(nsVoidArray& aListeners, + PRInt32 aProgess, PRInt32 aMaxProgress, PRBool aDoStartStop, PRInt32 aFlag) @@ -972,7 +1000,7 @@ PrintData::DoOnProgressChange(nsVoidArray& aListeners, for (PRInt32 i=0;iOnProgressChange(nsnull, nsnull, aProgess, aMaxProgress, aProgess, aMaxProgress); + wpl->OnProgressChange(nsnull, nsnull, aProgess, aMaxProgress, aProgess, aMaxProgress); if (aDoStartStop) { wpl->OnStateChange(nsnull, nsnull, aFlag, 0); } @@ -983,10 +1011,10 @@ PrintData::DoOnProgressChange(nsVoidArray& aListeners, //--------------------------------------------------- //-- PrintObject Class Impl //--------------------------------------------------- -PrintObject::PrintObject() : +PrintObject::PrintObject() : mFrameType(eFrame), mRootView(nsnull), mContent(nsnull), - mSeqFrame(nsnull), mPageFrame(nsnull), mPageNum(-1), + mSeqFrame(nsnull), mPageFrame(nsnull), mPageNum(-1), mRect(0,0,0,0), mReflowRect(0,0,0,0), mParent(nsnull), mHasBeenPrinted(PR_FALSE), mDontPrint(PR_TRUE), mPrintAsIs(PR_FALSE), mSkippedPageEject(PR_FALSE), mSharedPresShell(PR_FALSE), mIsHidden(PR_FALSE), @@ -1006,7 +1034,7 @@ PrintObject::~PrintObject() PrintObject* po = (PrintObject*)mKids[i]; NS_ASSERTION(po, "PrintObject can't be null!"); delete po; - } + } if (mPresShell && !mSharedPresShell) { mPresShell->Destroy(); @@ -1045,16 +1073,14 @@ PRBool DocumentViewerImpl::mIsDoingPrinting = PR_FALSE; nsresult NS_NewDocumentViewer(nsIDocumentViewer** aResult) { - NS_PRECONDITION(aResult, "null OUT ptr"); - if (!aResult) { - return NS_ERROR_NULL_POINTER; - } - DocumentViewerImpl* it = new DocumentViewerImpl(); - if (nsnull == it) { - *aResult = nsnull; + *aResult = new DocumentViewerImpl(); + if (!*aResult) { return NS_ERROR_OUT_OF_MEMORY; } - return CallQueryInterface(it, aResult); + + NS_ADDREF(*aResult); + + return NS_OK; } // Note: operator new zeros our memory @@ -1068,7 +1094,8 @@ DocumentViewerImpl::DocumentViewerImpl() #endif } -void DocumentViewerImpl::PrepareToStartLoad() { +void DocumentViewerImpl::PrepareToStartLoad() +{ mEnableRendering = PR_TRUE; mStopped = PR_FALSE; mLoaded = PR_FALSE; @@ -1106,12 +1133,14 @@ NS_IMPL_ISUPPORTS6(DocumentViewerImpl, DocumentViewerImpl::~DocumentViewerImpl() { NS_ASSERTION(!mDocument, "User did not call nsIContentViewer::Close"); - if (mDocument) + if (mDocument) { Close(); + } NS_ASSERTION(!mPresShell, "User did not call nsIContentViewer::Destroy"); - if (mPresShell) + if (mPresShell) { Destroy(); + } // XXX(?) Revoke pending invalidate events @@ -1139,10 +1168,10 @@ DocumentViewerImpl::LoadStart(nsISupports *aDoc) nsresult rv; if (!mDocument) { - mDocument = do_QueryInterface(aDoc,&rv); + mDocument = do_QueryInterface(aDoc, &rv); } else if (mDocument == aDoc) { - // Reset the document viewer's state back to what it was + // Reset the document viewer's state back to what it was // when the document load started. PrepareToStartLoad(); } @@ -1150,6 +1179,42 @@ DocumentViewerImpl::LoadStart(nsISupports *aDoc) return rv; } +nsresult +DocumentViewerImpl::SyncParentSubDocMap() +{ + nsCOMPtr item(do_QueryInterface(mContainer)); + nsCOMPtr win(do_GetInterface(item)); + nsCOMPtr pwin(do_QueryInterface(win)); + nsCOMPtr content; + + if (mDocument && pwin) { + nsCOMPtr frame_element; + pwin->GetFrameElementInternal(getter_AddRefs(frame_element)); + + content = do_QueryInterface(frame_element); + } + + if (content) { + nsCOMPtr parent; + item->GetParent(getter_AddRefs(parent)); + + nsCOMPtr parent_win(do_GetInterface(parent)); + + if (parent_win) { + nsCOMPtr dom_doc; + parent_win->GetDocument(getter_AddRefs(dom_doc)); + + nsCOMPtr parent_doc(do_QueryInterface(dom_doc)); + + if (parent_doc) { + return parent_doc->SetSubDocumentFor(content, mDocument); + } + } + } + + return NS_OK; +} + NS_IMETHODIMP DocumentViewerImpl::SetContainer(nsISupports* aContainer) { @@ -1157,7 +1222,12 @@ DocumentViewerImpl::SetContainer(nsISupports* aContainer) if (mPresContext) { mPresContext->SetContainer(aContainer); } - return NS_OK; + + // We're loading a new document into the window where this document + // viewer lives, sync the parent document's frame element -> sub + // document map + + return SyncParentSubDocMap(); } NS_IMETHODIMP @@ -1179,6 +1249,100 @@ DocumentViewerImpl::Init(nsIWidget* aParentWidget, return InitInternal(aParentWidget, aDeviceContext, aBounds, PR_TRUE); } +nsresult +DocumentViewerImpl::InitPresentationStuff(PRBool aDoInitialReflow) +{ + // Create the style set... + nsCOMPtr styleSet; + nsresult rv = CreateStyleSet(mDocument, getter_AddRefs(styleSet)); + NS_ENSURE_SUCCESS(rv, rv); + + // Now make the shell for the document + rv = mDocument->CreateShell(mPresContext, mViewManager, styleSet, + getter_AddRefs(mPresShell)); + + NS_ENSURE_SUCCESS(rv, rv); + + mPresShell->BeginObservingDocument(); + + // Initialize our view manager + nsRect bounds; + mWindow->GetBounds(bounds); + + float p2t; + + mPresContext->GetPixelsToTwips(&p2t); + + nscoord width = NSIntPixelsToTwips(bounds.width, p2t); + nscoord height = NSIntPixelsToTwips(bounds.height, p2t); + + mViewManager->DisableRefresh(); + mViewManager->SetWindowDimensions(width, height); + + // Setup default view manager background color + + // This may be overridden by the docshell with the background color + // for the last document loaded into the docshell + nscolor bgcolor = NS_RGB(0, 0, 0); + mPresContext->GetDefaultBackgroundColor(&bgcolor); + mViewManager->SetDefaultBackgroundColor(bgcolor); + + if (aDoInitialReflow) { + // Initial refllow + mPresShell->InitialReflow(width, height); + + // Now trigger a refresh + if (mEnableRendering) { + mViewManager->EnableRefresh(NS_VMREFRESH_IMMEDIATE); + } + } + + // now register ourselves as a selection listener, so that we get + // called when the selection changes in the window + nsDocViewerSelectionListener *selectionListener = + new nsDocViewerSelectionListener(); + NS_ENSURE_TRUE(selectionListener, NS_ERROR_OUT_OF_MEMORY); + + selectionListener->Init(this); + + // mSelectionListener is a owning reference + mSelectionListener = selectionListener; + + nsCOMPtr selection; + rv = GetDocumentSelection(getter_AddRefs(selection)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr selPrivate(do_QueryInterface(selection)); + rv = selPrivate->AddSelectionListener(mSelectionListener); + if (NS_FAILED(rv)) + return rv; + + // focus listener + // + // now register ourselves as a focus listener, so that we get called + // when the focus changes in the window + nsDocViewerFocusListener *focusListener; + NS_NEWXPCOM(focusListener, nsDocViewerFocusListener); + NS_ENSURE_TRUE(focusListener, NS_ERROR_OUT_OF_MEMORY); + + focusListener->Init(this); + + // mFocusListener is a strong reference + mFocusListener = focusListener; + + // get the DOM event receiver + nsCOMPtr erP(do_QueryInterface(mDocument)); + NS_WARN_IF_FALSE(erP, "No event receiver in document!"); + + if (erP) { + rv = erP->AddEventListenerByIID(mFocusListener, + NS_GET_IID(nsIDOMFocusListener)); + NS_ASSERTION(NS_SUCCEEDED(rv), "failed to register focus listener"); + } + + return NS_OK; +} + //----------------------------------------------- // This method can be used to initial the "presentation" // The aDoCreation indicates whether it should create @@ -1189,16 +1353,15 @@ DocumentViewerImpl::InitInternal(nsIWidget* aParentWidget, const nsRect& aBounds, PRBool aDoCreation) { - NS_ASSERTION(aParentWidget != nsnull, "Null aParentWidget"); - #ifdef NS_PRINT_PREVIEW mParentWidget = aParentWidget; // not ref counted #endif - nsresult rv; + nsresult rv = NS_OK; NS_ENSURE_TRUE(mDocument, NS_ERROR_NULL_POINTER); mDeviceContext = dont_QueryInterface(aDeviceContext); + #ifdef NS_PRINT_PREVIEW // Clear PrintPreview Alternate Device if (mDeviceContext) { @@ -1209,16 +1372,18 @@ DocumentViewerImpl::InitInternal(nsIWidget* aParentWidget, PRBool makeCX = PR_FALSE; if (aDoCreation) { - if (!mPresContext) { + if (aParentWidget && !mPresContext) { // Create presentation context if (mIsCreatingPrintPreview) { - mPresContext = do_CreateInstance(kPrintPreviewContextCID,&rv); + mPresContext = do_CreateInstance(kPrintPreviewContextCID, &rv); } else { - mPresContext = do_CreateInstance(kGalleyContextCID,&rv); + mPresContext = do_CreateInstance(kGalleyContextCID, &rv); } - if (NS_FAILED(rv)) return rv; + if (NS_FAILED(rv)) + return rv; mPresContext->Init(aDeviceContext); + #ifdef NS_PRINT_PREVIEW makeCX = !mIsDoingPrintPreview; // needs to be true except when we are already in PP #else @@ -1227,142 +1392,52 @@ DocumentViewerImpl::InitInternal(nsIWidget* aParentWidget, } } + if (aDoCreation && mPresContext) { + // Create the ViewManager and Root View... + + // We must do this before we tell the script global object about + // this new document since doing that will cause us to re-enter + // into nsHTMLFrameInnerFrame code through reflows caused by + // FlushPendingNotifications() calls down the road... + + rv = MakeWindow(aParentWidget, aBounds); + NS_ENSURE_SUCCESS(rv, rv); + Hide(); + } + nsCOMPtr requestor(do_QueryInterface(mContainer)); if (requestor) { - nsCOMPtr linkHandler; - requestor->GetInterface(NS_GET_IID(nsILinkHandler), - getter_AddRefs(linkHandler)); - mPresContext->SetContainer(mContainer); - mPresContext->SetLinkHandler(linkHandler); + if (mPresContext) { + nsCOMPtr linkHandler; + requestor->GetInterface(NS_GET_IID(nsILinkHandler), + getter_AddRefs(linkHandler)); + mPresContext->SetContainer(mContainer); + mPresContext->SetLinkHandler(linkHandler); + } if (!mIsDoingPrintPreview) { // Set script-context-owner in the document - nsCOMPtr owner; - requestor->GetInterface(NS_GET_IID(nsIScriptGlobalObjectOwner), - getter_AddRefs(owner)); - if (owner) { - nsCOMPtr global; - owner->GetScriptGlobalObject(getter_AddRefs(global)); + nsCOMPtr global; + requestor->GetInterface(NS_GET_IID(nsIScriptGlobalObject), + getter_AddRefs(global)); - if (global) { - mDocument->SetScriptGlobalObject(global); - nsCOMPtr domdoc(do_QueryInterface(mDocument)); + if (global) { + mDocument->SetScriptGlobalObject(global); + nsCOMPtr domdoc(do_QueryInterface(mDocument)); - if (domdoc) { - global->SetNewDocument(domdoc, PR_TRUE); - } + if (domdoc) { + global->SetNewDocument(domdoc, PR_TRUE); } } } } - if (aDoCreation) { - // Create the ViewManager and Root View... - rv = MakeWindow(aParentWidget, aBounds); - Hide(); + if (aDoCreation && mPresContext) { + // The ViewManager and Root View was created above (in + // MakeWindow())... - if (NS_FAILED(rv)) return rv; - - // Create the style set... - nsIStyleSet* styleSet; - rv = CreateStyleSet(mDocument, &styleSet); - if (NS_FAILED(rv)) return rv; - - // Now make the shell for the document - rv = mDocument->CreateShell(mPresContext, mViewManager, styleSet, - getter_AddRefs(mPresShell)); - NS_RELEASE(styleSet); - if (NS_FAILED(rv)) return rv; - - mPresShell->BeginObservingDocument(); - - // Initialize our view manager - nsRect bounds; - mWindow->GetBounds(bounds); - nscoord width = bounds.width; - nscoord height = bounds.height; - float p2t; - mPresContext->GetPixelsToTwips(&p2t); - width = NSIntPixelsToTwips(width, p2t); - height = NSIntPixelsToTwips(height, p2t); - mViewManager->DisableRefresh(); - mViewManager->SetWindowDimensions(width, height); - - /* Setup default view manager background color */ - /* This may be overridden by the docshell with the background color for the - last document loaded into the docshell */ - nscolor bgcolor = NS_RGB(0, 0, 0); - mPresContext->GetDefaultBackgroundColor(&bgcolor); - mViewManager->SetDefaultBackgroundColor(bgcolor); - - if (!makeCX) { - // Make shell an observer for next time - // XXX - we observe the docuement always, see above after preshell is created - // mPresShell->BeginObservingDocument(); - - //XXX I don't think this should be done *here*; and why paint nothing - //(which turns out to cause black flashes!)??? - // Resize-reflow this time - mPresShell->InitialReflow(width, height); - - // Now trigger a refresh - if (mEnableRendering) { - mViewManager->EnableRefresh(NS_VMREFRESH_IMMEDIATE); - } - } - } else { - mPresShell->BeginObservingDocument(); - } - // now register ourselves as a selection listener, so that we get called - // when the selection changes in the window - nsDocViewerSelectionListener *selectionListener; - NS_NEWXPCOM(selectionListener, nsDocViewerSelectionListener); - if (!selectionListener) return NS_ERROR_OUT_OF_MEMORY; - selectionListener->Init(this); - - // this is the owning reference. The nsCOMPtr will take care of releasing - // our ref to the listener on destruction. - NS_ADDREF(selectionListener); - mSelectionListener = do_QueryInterface(selectionListener); - NS_RELEASE(selectionListener); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr selection; - rv = GetDocumentSelection(getter_AddRefs(selection)); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr selPrivate(do_QueryInterface(selection)); - rv = selPrivate->AddSelectionListener(mSelectionListener); - if (NS_FAILED(rv)) return rv; - - //focus listener - // now register ourselves as a focus listener, so that we get called - // when the focus changes in the window - nsDocViewerFocusListener *focusListener; - NS_NEWXPCOM(focusListener, nsDocViewerFocusListener); - if (!focusListener) return NS_ERROR_OUT_OF_MEMORY; - focusListener->Init(this); - - // this is the owning reference. The nsCOMPtr will take care of releasing - // our ref to the listener on destruction. - NS_ADDREF(focusListener); - mFocusListener = do_QueryInterface(focusListener); - NS_RELEASE(focusListener); - if (NS_FAILED(rv)) - return rv; - - if(mDocument) - { - // get the DOM event receiver - nsCOMPtr erP (do_QueryInterface(mDocument, &rv)); - if(NS_FAILED(rv)) - return rv; - if(!erP) - return NS_ERROR_FAILURE; - - rv = erP->AddEventListenerByIID(mFocusListener, NS_GET_IID(nsIDOMFocusListener)); - NS_ASSERTION(NS_SUCCEEDED(rv), "failed to register focus listener"); + rv = InitPresentationStuff(!makeCX); } return rv; @@ -1388,14 +1463,14 @@ DocumentViewerImpl::LoadComplete(nsresult aStatus) rv = mDocument->GetScriptGlobalObject(getter_AddRefs(global)); // Fail if no ScriptGlobalObject is available... - NS_ASSERTION(global, "nsIScriptGlobalObject not set for document!"); - if (!global) return NS_ERROR_NULL_POINTER; + NS_ENSURE_TRUE(global, NS_ERROR_NULL_POINTER); mLoaded = PR_TRUE; - /* We need to protect ourself against auto-destruction in case the window is closed - while processing the OnLoad event. - See bug http://bugzilla.mozilla.org/show_bug.cgi?id=78445 for more explanation. + /* We need to protect ourself against auto-destruction in case the + window is closed while processing the OnLoad event. See bug + http://bugzilla.mozilla.org/show_bug.cgi?id=78445 for more + explanation. */ NS_ADDREF_THIS(); @@ -1411,11 +1486,14 @@ DocumentViewerImpl::LoadComplete(nsresult aStatus) #ifdef MOZ_TIMELINE // if navigator.xul's load is complete, the main nav window is visible // mark that point. + if (mDocument) { //printf("DEBUG: getting uri from document (%p)\n", mDocument.get()); + nsCOMPtr uri; mDocument->GetDocumentURL(getter_AddRefs(uri)); - if (uri.get() != nsnull) { + + if (uri) { //printf("DEBUG: getting spec fro uri (%p)\n", uri.get()); nsCAutoString spec; uri->GetSpec(spec); @@ -1428,11 +1506,12 @@ DocumentViewerImpl::LoadComplete(nsresult aStatus) } else { // XXX: Should fire error event to the document... } - + // Now that the document has loaded, we can tell the presshell // to unsuppress painting. - if (mPresShell && !mStopped) + if (mPresShell && !mStopped) { mPresShell->UnsuppressPainting(); + } NS_RELEASE_THIS(); @@ -1484,11 +1563,9 @@ DocumentViewerImpl::Close() // for an object that can be switched in and out so that we don't need // to disable scripts during paint suppression. - nsresult rv; - if (mDocument) { #ifdef NS_PRINT_PREVIEW - // Turn scripting back on + // Turn scripting back on // after PrintPreview had turned it off if (mPrtPreview) { TurnScriptingOn(PR_TRUE); @@ -1499,20 +1576,28 @@ DocumentViewerImpl::Close() // in the DocViewer Init nsCOMPtr globalObject; mDocument->GetScriptGlobalObject(getter_AddRefs(globalObject)); + if (globalObject) { globalObject->SetNewDocument(nsnull, PR_TRUE); } + // out of band cleanup of webshell mDocument->SetScriptGlobalObject(nsnull); + if (mFocusListener) { // get the DOM event receiver - nsCOMPtr erP( do_QueryInterface(mDocument, &rv) ); - if(NS_SUCCEEDED(rv) && erP) - erP->RemoveEventListenerByIID(mFocusListener, NS_GET_IID(nsIDOMFocusListener)); + nsCOMPtr erP(do_QueryInterface(mDocument)); + NS_WARN_IF_FALSE(erP, "No event receiver in document!"); + + if (erP) { + erP->RemoveEventListenerByIID(mFocusListener, + NS_GET_IID(nsIDOMFocusListener)); + } } - } + } mDocument = nsnull; + return NS_OK; } @@ -1566,21 +1651,27 @@ DocumentViewerImpl::Destroy() mPreviousViewer = nsnull; } - if (mDeviceContext) + if (mDeviceContext) { mDeviceContext->FlushFontCache(); + mDeviceContext = nsnull; + } if (mPresShell) { // Break circular reference (or something) mPresShell->EndObservingDocument(); + nsCOMPtr selection; - nsresult rv = GetDocumentSelection(getter_AddRefs(selection)); + GetDocumentSelection(getter_AddRefs(selection)); + nsCOMPtr selPrivate(do_QueryInterface(selection)); - if (NS_SUCCEEDED(rv) && selPrivate && mSelectionListener) + + if (selPrivate && mSelectionListener) selPrivate->RemoveSelectionListener(mSelectionListener); + mPresShell->Destroy(); mPresShell = nsnull; } - + return NS_OK; } @@ -1615,15 +1706,17 @@ DocumentViewerImpl::SetDOMDocument(nsIDOMDocument *aDocument) // Assumptions: // // 1) this document viewer has been initialized with a call to Init(). - // 2) the stylesheets associated with the document have been added to the document. + // 2) the stylesheets associated with the document have been added + // to the document. - // XXX Right now, this method assumes that the layout of the current document - // hasn't started yet. More cleanup will probably be necessary to make this - // method work for the case when layout *has* occurred for the current document. + // XXX Right now, this method assumes that the layout of the current + // document hasn't started yet. More cleanup will probably be + // necessary to make this method work for the case when layout *has* + // occurred for the current document. // That work can happen when and if it is needed. - + nsresult rv; - if (nsnull == aDocument) + if (!aDocument) return NS_ERROR_NULL_POINTER; nsCOMPtr newDoc = do_QueryInterface(aDocument, &rv); @@ -1633,46 +1726,50 @@ DocumentViewerImpl::SetDOMDocument(nsIDOMDocument *aDocument) mDocument = newDoc; // 1) Set the script global object on the new document - nsCOMPtr requestor(do_QueryInterface(mContainer)); - if (requestor) { - nsCOMPtr owner; - requestor->GetInterface(NS_GET_IID(nsIScriptGlobalObjectOwner), - getter_AddRefs(owner)); - if (nsnull != owner) { - nsCOMPtr global; - rv = owner->GetScriptGlobalObject(getter_AddRefs(global)); - if (NS_SUCCEEDED(rv) && (nsnull != global)) { - mDocument->SetScriptGlobalObject(global); - global->SetNewDocument(aDocument, PR_TRUE); - } - } - } + nsCOMPtr global(do_GetInterface(mContainer)); - // 2) Create a new style set for the document - nsCOMPtr styleSet; - rv = CreateStyleSet(mDocument, getter_AddRefs(styleSet)); - if (NS_FAILED(rv)) return rv; + if (global) { + mDocument->SetScriptGlobalObject(global); + global->SetNewDocument(aDocument, PR_TRUE); - // 3) Replace the current pres shell with a new shell for the new document - mPresShell->EndObservingDocument(); - mPresShell->Destroy(); + rv = SyncParentSubDocMap(); + NS_ENSURE_SUCCESS(rv, rv); + } - mPresShell = nsnull; - rv = newDoc->CreateShell(mPresContext, mViewManager, styleSet, - getter_AddRefs(mPresShell)); - if (NS_FAILED(rv)) return rv; + // 2) Replace the current pres shell with a new shell for the new document - mPresShell->BeginObservingDocument(); + if (mPresShell) { + mPresShell->EndObservingDocument(); + mPresShell->Destroy(); + + mPresShell = nsnull; + } + + // And if we're already given a prescontext... + if (mPresContext) { + // 3) Create a new style set for the document + + nsCOMPtr styleSet; + rv = CreateStyleSet(mDocument, getter_AddRefs(styleSet)); + if (NS_FAILED(rv)) + return rv; + + rv = newDoc->CreateShell(mPresContext, mViewManager, styleSet, + getter_AddRefs(mPresShell)); + NS_ENSURE_SUCCESS(rv, rv); + + mPresShell->BeginObservingDocument(); + + // 4) Register the focus listener on the new document - // 4) Register the focus listener on the new document - if(mDocument) - { nsCOMPtr erP = do_QueryInterface(mDocument, &rv); - if(NS_FAILED(rv) || !erP) - return rv ? rv : NS_ERROR_FAILURE; + NS_WARN_IF_FALSE(erP, "No event receiver in document!"); - rv = erP->AddEventListenerByIID(mFocusListener, NS_GET_IID(nsIDOMFocusListener)); - NS_ASSERTION(NS_SUCCEEDED(rv), "failed to register focus listener"); + if (erP) { + rv = erP->AddEventListenerByIID(mFocusListener, + NS_GET_IID(nsIDOMFocusListener)); + NS_ASSERTION(NS_SUCCEEDED(rv), "failed to register focus listener"); + } } return rv; @@ -1689,7 +1786,7 @@ DocumentViewerImpl::SetUAStyleSheet(nsIStyleSheet* aUAStyleSheet) } return NS_OK; } - + NS_IMETHODIMP DocumentViewerImpl::GetDocument(nsIDocument*& aResult) { @@ -1697,7 +1794,7 @@ DocumentViewerImpl::GetDocument(nsIDocument*& aResult) NS_IF_ADDREF(aResult); return NS_OK; } - + NS_IMETHODIMP DocumentViewerImpl::GetPresShell(nsIPresShell*& aResult) { @@ -1705,7 +1802,7 @@ DocumentViewerImpl::GetPresShell(nsIPresShell*& aResult) NS_IF_ADDREF(aResult); return NS_OK; } - + NS_IMETHODIMP DocumentViewerImpl::GetPresContext(nsIPresContext*& aResult) { @@ -1747,7 +1844,7 @@ DocumentViewerImpl::SetPreviousViewer(nsIContentViewer* aViewer) "can't set previous viewer when there already is one"); // In a multiple chaining situation (which occurs when running a thrashing - // test like i-bench or jrgm's tests with no delay), we can build up a + // test like i-bench or jrgm's tests with no delay), we can build up a // whole chain of viewers. In order to avoid this, we always set our previous // viewer to the MOST previous viewer in the chain, and then dump the intermediate // link from the chain. This ensures that at most only 2 documents are alive @@ -1770,7 +1867,7 @@ NS_IMETHODIMP DocumentViewerImpl::SetBounds(const nsRect& aBounds) { NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE); - NS_PRECONDITION(mWindow, "null window"); + if (mWindow) { // Don't have the widget repaint. Layout will generate repaint requests // during reflow @@ -1795,7 +1892,6 @@ NS_IMETHODIMP DocumentViewerImpl::Show(void) { NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE); - NS_PRECONDITION(mWindow, "null window"); // We don't need the previous viewer anymore since we're not // displaying it. @@ -1810,17 +1906,176 @@ DocumentViewerImpl::Show(void) if (mWindow) { mWindow->Show(PR_TRUE); } + + if (mDocument && !mPresShell && !mWindow) { + nsresult rv; + + nsCOMPtr base_win(do_QueryInterface(mContainer)); + NS_ENSURE_TRUE(base_win, NS_ERROR_UNEXPECTED); + + base_win->GetParentWidget(&mParentWidget); + NS_ENSURE_TRUE(mParentWidget, NS_ERROR_UNEXPECTED); + + mDeviceContext = dont_AddRef(mParentWidget->GetDeviceContext()); + +#ifdef NS_PRINT_PREVIEW + // Clear PrintPreview Alternate Device + if (mDeviceContext) { + mDeviceContext->SetAltDevice(nsnull); + } +#endif + + // Create presentation context + if (mIsCreatingPrintPreview) { + NS_ERROR("Whoa, we should not get here!"); + + return NS_ERROR_UNEXPECTED; + } + + mPresContext = do_CreateInstance(kGalleyContextCID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + mPresContext->Init(mDeviceContext); + + nsRect tbounds; + mParentWidget->GetBounds(tbounds); + + float p2t; + mPresContext->GetPixelsToTwips(&p2t); + tbounds *= p2t; + + // Create the view manager + mViewManager = do_CreateInstance(kViewManagerCID); + NS_ENSURE_TRUE(mViewManager, NS_ERROR_NOT_AVAILABLE); + + // Initialize the view manager with an offset. This allows the + // viewmanager to manage a coordinate space offset from (0,0) + rv = mViewManager->Init(mDeviceContext); + if (NS_FAILED(rv)) + return rv; + + rv = mViewManager->SetWindowOffset(tbounds.x, tbounds.y); + if (NS_FAILED(rv)) + return rv; + + // Reset the bounds offset so the root view is set to 0,0. The + // offset is specified in nsIViewManager::Init above. + // Besides, layout will reset the root view to (0,0) during reflow, + // so changing it to 0,0 eliminates placing the root view in the + // wrong place initially. + tbounds.x = 0; + tbounds.y = 0; + + // Create a child window of the parent that is our "root + // view/window" Create a view + + nsIView *view = nsnull; + rv = CallCreateInstance(kViewCID, &view); + if (NS_FAILED(rv)) + return rv; + rv = view->Init(mViewManager, tbounds, nsnull); + if (NS_FAILED(rv)) + return rv; + + rv = view->CreateWidget(kWidgetCID, nsnull, + mParentWidget->GetNativeData(NS_NATIVE_WIDGET), + PR_TRUE, PR_FALSE); + + if (NS_FAILED(rv)) + return rv; + + // Setup hierarchical relationship in view manager + mViewManager->SetRootView(view); + + view->GetWidget(*getter_AddRefs(mWindow)); + + if (mPresContext && mContainer) { + nsCOMPtr linkHandler(do_GetInterface(mContainer)); + + if (linkHandler) { + mPresContext->SetLinkHandler(linkHandler); + } + + mPresContext->SetContainer(mContainer); + } + + if (mPresContext) { + Hide(); + + rv = InitPresentationStuff(PR_TRUE); + } + + // If we get here the document load has already started and the + // window is shown because some JS on the page caused it to be + // shown... + + mPresShell->UnsuppressPainting(); + } + return NS_OK; } NS_IMETHODIMP DocumentViewerImpl::Hide(void) { + PRBool is_in_print_preview = PR_FALSE; + + GetDoingPrintPreview(&is_in_print_preview); + + if (is_in_print_preview) { + // If we, or one of our parents, is in print preview mode it means + // we're right now returning from print preview and the layout + // frame that was created for this document is being destroyed. In + // such a case we ignore the Hide() call. + + return NS_OK; + } + NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE); NS_PRECONDITION(mWindow, "null window"); if (mWindow) { mWindow->Show(PR_FALSE); } + + if (!mPresShell || mIsDoingPrintPreview) { + return NS_OK; + } + + // Avoid leaking the old viewer. + if (mPreviousViewer) { + mPreviousViewer->Destroy(); + mPreviousViewer = nsnull; + } + + if (mDeviceContext) + mDeviceContext->FlushFontCache(); + + // Break circular reference (or something) + mPresShell->EndObservingDocument(); + nsCOMPtr selection; + + GetDocumentSelection(getter_AddRefs(selection)); + + nsCOMPtr selPrivate(do_QueryInterface(selection)); + + if (selPrivate && mSelectionListener) + selPrivate->RemoveSelectionListener(mSelectionListener); + + mPresShell->Destroy(); + + mPresShell = nsnull; + mPresContext = nsnull; + mViewManager = nsnull; + mWindow = nsnull; + mDeviceContext = nsnull; + mParentWidget = nsnull; + + nsCOMPtr base_win(do_QueryInterface(mContainer)); + + if (base_win) { + base_win->SetParentWidget(nsnull); + } + return NS_OK; } @@ -1846,7 +2101,7 @@ DocumentViewerImpl::FindFrameSetWithIID(nsIContent * aParentContent, const nsIID } /** --------------------------------------------------- - * Helper function + * Helper function */ static nsIPresShell* GetPresShellFor(nsIDocShell* aDocShell) @@ -1873,10 +2128,10 @@ GetPresShellFor(nsIDocShell* aDocShell) #include "process.h" #include "direct.h" -#define MY_FINDFIRST(a,b) FindFirstFile(a,b) -#define MY_FINDNEXT(a,b) FindNextFile(a,b) -#define ISDIR(a) (a.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) -#define MY_FINDCLOSE(a) FindClose(a) +#define MY_FINDFIRST(a,b) FindFirstFile(a,b) +#define MY_FINDNEXT(a,b) FindNextFile(a,b) +#define ISDIR(a) (a.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) +#define MY_FINDCLOSE(a) FindClose(a) #define MY_FILENAME(a) a.cFileName #define MY_FILESIZE(a) (a.nFileSizeHigh * MAXDWORD) + a.nFileSizeLow @@ -1951,10 +2206,10 @@ static void RootFrameList(nsIPresContext* aPresContext, FILE* out, PRInt32 aInde /** --------------------------------------------------- * Dumps Frames for Printing */ -static void DumpFrames(FILE* out, - nsIPresContext* aPresContext, - nsIRenderingContext * aRendContext, - nsIFrame * aFrame, +static void DumpFrames(FILE* out, + nsIPresContext* aPresContext, + nsIRenderingContext * aRendContext, + nsIFrame * aFrame, PRInt32 aLevel) { NS_ASSERTION(out, "Pointer is null!"); @@ -2122,16 +2377,16 @@ static void DumpPrintObjectsList(nsVoidArray * aDocList, FILE* aFD = nsnull) } } - fprintf(fd, "%s %d %d %d %p %p %p %p %p %d %d,%d,%d,%d\n", types[po->mFrameType], + fprintf(fd, "%s %d %d %d %p %p %p %p %p %d %d,%d,%d,%d\n", types[po->mFrameType], po->IsPrintable(), po->mPrintAsIs, po->mHasBeenPrinted, po, po->mWebShell, po->mSeqFrame, - po->mPageFrame, rootFrame, po->mPageNum, po->mRect.x, po->mRect.y, po->mRect.width, po->mRect.height); + po->mPageFrame, rootFrame, po->mPageNum, po->mRect.x, po->mRect.y, po->mRect.width, po->mRect.height); if (fd != nsnull && fd != stdout) { - fprintf(stdout, "%s %d %d %d %p %p %p %p %p %d %d,%d,%d,%d\n", types[po->mFrameType], + fprintf(stdout, "%s %d %d %d %p %p %p %p %p %d %d,%d,%d,%d\n", types[po->mFrameType], po->IsPrintable(), po->mPrintAsIs, po->mHasBeenPrinted, po, po->mWebShell, po->mSeqFrame, - po->mPageFrame, rootFrame, po->mPageNum, po->mRect.x, po->mRect.y, po->mRect.width, po->mRect.height); + po->mPageFrame, rootFrame, po->mPageNum, po->mRect.x, po->mRect.y, po->mRect.width, po->mRect.height); } - } -} + } +} static void DumpPrintObjectsTree(PrintObject * aPO, int aLevel= 0, FILE* aFD = nsnull) { NS_ASSERTION(aPO, "Pointer is null!"); @@ -2148,11 +2403,12 @@ static void DumpPrintObjectsTree(PrintObject * aPO, int aLevel= 0, FILE* aFD = n NS_ASSERTION(po, "PrintObject can't be null!"); for (PRInt32 k=0;kmFrameType], po, po->mWebShell, po->mSeqFrame, - po->mPageFrame, po->mPageNum, po->mRect.x, po->mRect.y, po->mRect.width, po->mRect.height); - } + po->mPageFrame, po->mPageNum, po->mRect.x, po->mRect.y, po->mRect.width, po->mRect.height); + } } - -static void GetDocTitleAndURL(PrintObject* aPO, char *& aDocStr, char *& aURLStr) + +static void GetDocTitleAndURL(PrintObject* aPO, char *& aDocStr, + char *& aURLStr) { aDocStr = nsnull; aURLStr = nsnull; @@ -2160,7 +2416,9 @@ static void GetDocTitleAndURL(PrintObject* aPO, char *& aDocStr, char *& aURLStr PRUnichar * mozillaDoc = ToNewUnicode(NS_LITERAL_STRING("Mozilla Document")); PRUnichar * docTitleStr; PRUnichar * docURLStr; - DocumentViewerImpl::GetDisplayTitleAndURL(aPO, nsnull, mozillaDoc, &docTitleStr, &docURLStr, DocumentViewerImpl::eDocTitleDefURLDoc); + DocumentViewerImpl::GetDisplayTitleAndURL(aPO, nsnull, mozillaDoc, + &docTitleStr, &docURLStr, + DocumentViewerImpl::eDocTitleDefURLDoc); if (docTitleStr) { nsAutoString strDocTitle(docTitleStr); @@ -2179,7 +2437,7 @@ static void GetDocTitleAndURL(PrintObject* aPO, char *& aDocStr, char *& aURLStr } } -static void DumpPrintObjectsTreeLayout(PrintObject * aPO, +static void DumpPrintObjectsTreeLayout(PrintObject * aPO, nsIDeviceContext * aDC, int aLevel= 0, FILE * aFD = nsnull) { @@ -2203,7 +2461,7 @@ static void DumpPrintObjectsTreeLayout(PrintObject * aPO, } for (PRInt32 k=0;kmFrameType], aPO, aPO->mWebShell, aPO->mSeqFrame, - aPO->mPageFrame, aPO->mPageNum, aPO->mRect.x, aPO->mRect.y, aPO->mRect.width, aPO->mRect.height); + aPO->mPageFrame, aPO->mPageNum, aPO->mRect.x, aPO->mRect.y, aPO->mRect.width, aPO->mRect.height); if (aPO->IsPrintable()) { char * docStr; char * urlStr; @@ -2224,7 +2482,7 @@ static void DumpPrintObjectsTreeLayout(PrintObject * aPO, if (aLevel == 0 && fd) { fclose(fd); } -} +} static void DumpPrintObjectsListStart(char * aStr, nsVoidArray * aDocList, FILE* aFD = nsnull) { @@ -2242,7 +2500,7 @@ static void DumpPrintObjectsListStart(char * aStr, nsVoidArray * aDocList, FILE* #else #define DUMP_DOC_LIST(_title) #define DUMP_DOC_TREE -#define DUMP_DOC_TREELAYOUT +#define DUMP_DOC_TREELAYOUT #endif //--------------------------------------------------------------- @@ -2252,7 +2510,7 @@ static void DumpPrintObjectsListStart(char * aStr, nsVoidArray * aDocList, FILE* //--------------------------------------------------------------- /** --------------------------------------------------- - * Giving a child frame it searches "up" the tree until it + * Giving a child frame it searches "up" the tree until it * finds a "Page" frame. */ static nsIFrame * GetPageFrame(nsIFrame * aFrame) @@ -2277,7 +2535,7 @@ static nsIFrame * FindFrameByType(nsIPresContext* aPresContext, nsIFrame * aParentFrame, nsIAtom * aType, nsRect& aRect, - nsRect& aChildRect) + nsRect& aChildRect) { NS_ASSERTION(aPresContext, "Pointer is null!"); NS_ASSERTION(aParentFrame, "Pointer is null!"); @@ -2404,7 +2662,7 @@ static nsresult GetPageRangeForSelection(nsIPresShell * aPresShell, seqFrame->GetRect(rect); // start out with the sequence frame and search the entire frame tree - // capturing the the starting and ending child frames of the selection + // capturing the the starting and ending child frames of the selection // and their rects FindSelectionBounds(aPresContext, aRC, seqFrame, rect, startFrame, aStartRect, endFrame, aEndRect); @@ -2413,7 +2671,7 @@ static nsresult GetPageRangeForSelection(nsIPresShell * aPresShell, printf("End Frame: %p\n", endFrame); #endif - // initial the page numbers here + // initial the page numbers here // in case we don't find and frames aStartPageNum = -1; aEndPageNum = -1; @@ -2429,7 +2687,7 @@ static nsresult GetPageRangeForSelection(nsIPresShell * aPresShell, // Check to see if start should be same as end if // the end frame comes back null if (endFrame == nsnull) { - // XXX the "GetPageFrame" step could be integrated into + // XXX the "GetPageFrame" step could be integrated into // the FindSelectionBounds step, but walking up to find // the parent of a child frame isn't expensive and it makes // FindSelectionBounds a little easier to understand @@ -2469,7 +2727,7 @@ static nsresult GetPageRangeForSelection(nsIPresShell * aPresShell, while (page != nsnull) { if (page == startPageFrame) { aStartPageNum = pageNum; - } + } if (page == endPageFrame) { aEndPageNum = pageNum; } @@ -2489,7 +2747,7 @@ static nsresult GetPageRangeForSelection(nsIPresShell * aPresShell, } //------------------------------------------------------- -PRBool +PRBool DocumentViewerImpl::IsParentAFrameSet(nsIWebShell * aParent) { NS_ASSERTION(aParent, "Pointer is null!"); @@ -2498,8 +2756,8 @@ DocumentViewerImpl::IsParentAFrameSet(nsIWebShell * aParent) nsCOMPtr parentAsItem(do_QueryInterface(aParent)); if (!parentAsItem) return PR_FALSE; - // When it is the top level document we need to check - // to see if it contains a frameset. If it does, then + // 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 @@ -2508,10 +2766,10 @@ DocumentViewerImpl::IsParentAFrameSet(nsIWebShell * aParent) // 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 + // Bug 53459 has been files so we can eventually distinguish // between IFRAME frames and FRAME frames PRBool isFrameSet = PR_FALSE; - // only check to see if there is a frameset if there is + // 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 shell; mPresContext->GetShell(getter_AddRefs(shell)); @@ -2532,7 +2790,7 @@ DocumentViewerImpl::IsParentAFrameSet(nsIWebShell * aParent) } //------------------------------------------------------- -PRBool +PRBool DocumentViewerImpl::IsWebShellAFrameSet(nsIWebShell * aWebShell) { NS_ASSERTION(aWebShell, "Pointer is null!"); @@ -2551,8 +2809,8 @@ DocumentViewerImpl::IsWebShellAFrameSet(nsIWebShell * aWebShell) //------------------------------------------------------- void -DocumentViewerImpl::GetWebShellTitleAndURL(nsIWebShell * aWebShell, - PRUnichar** aTitle, +DocumentViewerImpl::GetWebShellTitleAndURL(nsIWebShell * aWebShell, + PRUnichar** aTitle, PRUnichar** aURLStr) { NS_ASSERTION(aWebShell, "Pointer is null!"); @@ -2648,7 +2906,7 @@ DocumentViewerImpl::GetDisplayTitleAndURL(PrintObject* aPO, case eDocTitleDefDocument: if (aBrandName) *aTitle = nsCRT::strdup(aBrandName); break; - case eDocTitleDefURLDoc: + case eDocTitleDefURLDoc: if (*aURLStr) { *aTitle = nsCRT::strdup(*aURLStr); } else { @@ -2784,12 +3042,12 @@ DocumentViewerImpl::PrintPage(nsIPresContext* aPresContext, if (mPrt->mPrintFrameType == nsIPrintSettings::kEachFrameSep) { DoProgressForSeparateFrames(); - } else if (mPrt->mPrintFrameType != nsIPrintSettings::kFramesAsIs || + } else if (mPrt->mPrintFrameType != nsIPrintSettings::kFramesAsIs || mPrt->mPrintObject->mFrameType == eDoc && aPO == mPrt->mPrintObject) { PrintData::DoOnProgressChange(mPrt->mPrintProgressListeners, curPage, endPage); } - // Set Clip when Printing "AsIs" or + // Set Clip when Printing "AsIs" or // when printing an IFrame for SelectedFrame or EachFrame PRBool setClip = PR_FALSE; switch (mPrt->mPrintFrameType) { @@ -2814,7 +3072,7 @@ DocumentViewerImpl::PrintPage(nsIPresContext* aPresContext, } break; - } //switch + } //switch if (setClip) { // Always set the clip x,y to zero because it isn't going to have any margins @@ -2828,7 +3086,7 @@ DocumentViewerImpl::PrintPage(nsIPresContext* aPresContext, // fail and the failure is passed back here. // Returning PR_TRUE means we are done printing. // - // When rv == NS_ERROR_ABORT, it means we want out of the + // When rv == NS_ERROR_ABORT, it means we want out of the // print job without displaying any error messages nsresult rv = mPageSeqFrame->PrintNextPage(aPresContext); if (NS_FAILED(rv)) { @@ -2837,7 +3095,7 @@ DocumentViewerImpl::PrintPage(nsIPresContext* aPresContext, mPrt->mIsAborted = PR_TRUE; } return PR_TRUE; - } + } // Now see if any of the SubDocs are on this page if (aPO->mPrintAsIs) { @@ -2904,9 +3162,9 @@ PrintObject * DocumentViewerImpl::FindPrintObjectByWS(PrintObject* aPO, nsIWebSh //------------------------------------------------------- // Recursively build a list of of sub documents to be printed // that mirrors the document tree -void -DocumentViewerImpl::BuildDocTree(nsIDocShellTreeNode * aParentNode, - nsVoidArray * aDocList, +void +DocumentViewerImpl::BuildDocTree(nsIDocShellTreeNode * aParentNode, + nsVoidArray * aDocList, PrintObject * aPO) { NS_ASSERTION(aParentNode, "Pointer is null!"); @@ -2914,7 +3172,7 @@ DocumentViewerImpl::BuildDocTree(nsIDocShellTreeNode * aParentNode, NS_ASSERTION(aPO, "Pointer is null!"); // Get the Doc and Title String - GetWebShellTitleAndURL(aPO->mWebShell, &aPO->mDocTitle, &aPO->mDocURL); + GetWebShellTitleAndURL(aPO->mWebShell, &aPO->mDocTitle, &aPO->mDocURL); PRInt32 childWebshellCount; aParentNode->GetChildCount(&childWebshellCount); @@ -2923,6 +3181,14 @@ DocumentViewerImpl::BuildDocTree(nsIDocShellTreeNode * aParentNode, nsCOMPtr child; aParentNode->GetChildAt(i, getter_AddRefs(child)); nsCOMPtr childAsShell(do_QueryInterface(child)); + + nsCOMPtr presShell; + childAsShell->GetPresShell(getter_AddRefs(presShell)); + + if (!presShell) { + continue; + } + nsCOMPtr viewer; childAsShell->GetContentViewer(getter_AddRefs(viewer)); if (viewer) { @@ -2953,14 +3219,15 @@ DocumentViewerImpl::SetPrintAsIs(PrintObject* aPO, PRBool aAsIs) aPO->mPrintAsIs = aAsIs; for (PRInt32 i=0;imKids.Count();i++) { SetPrintAsIs((PrintObject*)aPO->mKids[i], aAsIs); - } + } } //------------------------------------------------------- // Recursively sets all the PO items to be printed // from the given item down into the tree void -DocumentViewerImpl::SetPrintPO(PrintObject* aPO, PRBool aPrint, PRBool aIsHidden, PRUint32 aFlags) +DocumentViewerImpl::SetPrintPO(PrintObject* aPO, PRBool aPrint, + PRBool aIsHidden, PRUint32 aFlags) { NS_ASSERTION(aPO, "Pointer is null!"); @@ -2984,7 +3251,7 @@ DocumentViewerImpl::SetPrintPO(PrintObject* aPO, PRBool aPrint, PRBool aIsHidden // NOTE: This MUST be done after the sub-doc has been laid out // This is called by "MapSubDocFrameLocations" // -nsresult +nsresult DocumentViewerImpl::CalcPageFrameLocation(nsIPresShell * aPresShell, PrintObject* aPO) { @@ -2995,7 +3262,7 @@ DocumentViewerImpl::CalcPageFrameLocation(nsIPresShell * aPresShell, // Find that frame for the sub-doc's content element // in the parent document - // if it comes back null it probably has the style + // if it comes back null it probably has the style // set to "display:none" nsIFrame * frame; aPresShell->GetPrimaryFrameFor(aPO->mContent, &frame); @@ -3025,9 +3292,9 @@ DocumentViewerImpl::CalcPageFrameLocation(nsIPresShell * aPresShell, rect.y += rr.y; nsIFrame * temp = parent; temp->GetParent(&parent); - // Keep a pointer to the Seq and Page frames + // Keep a pointer to the Seq and Page frames nsIPageSequenceFrame * sqf = nsnull; - if (parent != nsnull && + if (parent != nsnull && NS_SUCCEEDED(CallQueryInterface(parent, &sqf)) && sqf) { pageFrame = temp; seqFrame = parent; @@ -3091,17 +3358,17 @@ DocumentViewerImpl::MapSubDocFrameLocations(PrintObject* aPO) // // This "maps" or figures out which sub-doc represents a // given Frame or IFrame in it's parent sub-doc. -// +// // So the Mcontent pointer in the child sub-doc points to the // content in the it's 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 it's parent's page frame so it can be +// of the sub-doc on it's 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 +void DocumentViewerImpl::MapContentForPO(PrintObject* aRootObject, nsIPresShell* aPresShell, nsIContent* aContent) @@ -3110,19 +3377,38 @@ DocumentViewerImpl::MapContentForPO(PrintObject* aRootObject, NS_ASSERTION(aPresShell, "Pointer is null!"); NS_ASSERTION(aContent, "Pointer is null!"); - nsCOMPtr supps; - aPresShell->GetSubShellFor(aContent, getter_AddRefs(supps)); - if (supps) { - nsCOMPtr webShell(do_QueryInterface(supps)); - if (webShell) { + nsCOMPtr doc; + aContent->GetDocument(*getter_AddRefs(doc)); + + if (!doc) { + NS_ERROR("No document!"); + + return; + } + + nsCOMPtr subDoc; + doc->GetSubDocumentFor(aContent, getter_AddRefs(subDoc)); + + if (subDoc) { + nsCOMPtr container; + subDoc->GetContainer(getter_AddRefs(container)); + + nsCOMPtr presShell; + subDoc->GetShellAt(0, getter_AddRefs(presShell)); + + nsCOMPtr webShell(do_QueryInterface(container)); + + if (presShell && webShell) { PrintObject * po = FindPrintObjectByWS(aRootObject, webShell); NS_ASSERTION(po, "PO can't be null!"); - if (po != nsnull) { + if (po) { po->mContent = aContent; - // Now, "type" the PO - nsCOMPtr frameSet(do_QueryInterface(aContent)); + // Now, "type" the PO + nsCOMPtr frameSet = + do_QueryInterface(aContent); + if (frameSet) { po->mFrameType = eFrameSet; } else { @@ -3130,8 +3416,11 @@ DocumentViewerImpl::MapContentForPO(PrintObject* aRootObject, if (frame) { po->mFrameType = eFrame; } else { - nsCOMPtr objElement(do_QueryInterface(aContent)); - nsCOMPtr iFrame(do_QueryInterface(aContent)); + nsCOMPtr objElement = + do_QueryInterface(aContent); + nsCOMPtr iFrame = + do_QueryInterface(aContent); + if (iFrame || objElement) { po->mFrameType = eIFrame; po->mPrintAsIs = PR_TRUE; @@ -3157,11 +3446,11 @@ DocumentViewerImpl::MapContentForPO(PrintObject* aRootObject, //------------------------------------------------------- // The walks the PO tree and for each document it walks the content -// tree looking for any content that are sub-shells +// tree looking for any content that are sub-shells // -// It then sets the mContent pointer in the "found" PO object back to the +// It then sets the mContent pointer in the "found" PO object back to the // the document that contained it. -void +void DocumentViewerImpl::MapContentToWebShells(PrintObject* aRootPO, PrintObject* aPO) { @@ -3179,16 +3468,16 @@ DocumentViewerImpl::MapContentToWebShells(PrintObject* aRootPO, // Continue recursively walking the chilren of this PO for (PRInt32 i=0;imKids.Count();i++) { MapContentToWebShells(aRootPO, (PrintObject*)aPO->mKids[i]); - } + } } //------------------------------------------------------- // This gets ref counted copies of the PresShell and Root Content // for a given nsIWebShell -void -DocumentViewerImpl::GetPresShellAndRootContent(nsIWebShell * aWebShell, - nsIPresShell** aPresShell, +void +DocumentViewerImpl::GetPresShellAndRootContent(nsIWebShell * aWebShell, + nsIPresShell** aPresShell, nsIContent** aContent) { NS_ASSERTION(aWebShell, "Pointer is null!"); @@ -3214,8 +3503,8 @@ DocumentViewerImpl::GetPresShellAndRootContent(nsIWebShell * aWebShell, //------------------------------------------------------- // Recursively sets the clip rect on all thchildren -void -DocumentViewerImpl::SetClipRect(PrintObject* aPO, +void +DocumentViewerImpl::SetClipRect(PrintObject* aPO, const nsRect& aClipRect, nscoord aOffsetX, nscoord aOffsetY, @@ -3229,8 +3518,8 @@ DocumentViewerImpl::SetClipRect(PrintObject* aPO, nscoord height = (aPO->mRect.y+aPO->mRect.height) > aClipRect.height?aClipRect.height-aPO->mRect.y:aPO->mRect.height; aPO->mClipRect.SetRect(aPO->mRect.x, aPO->mRect.y, width, height); - } - + } + PRBool doClip = aDoingSetClip; if (aPO->mFrameType == eFrame) { @@ -3271,7 +3560,7 @@ DocumentViewerImpl::SetClipRect(PrintObject* aPO, PRInt32 cnt = aPO->mKids.Count(); for (PRInt32 i=0;imKids[i], clipRect, + SetClipRect((PrintObject *)aPO->mKids[i], clipRect, aOffsetX+aPO->mRect.x, aOffsetY+aPO->mRect.y, doClip); } } @@ -3279,7 +3568,7 @@ DocumentViewerImpl::SetClipRect(PrintObject* aPO, //------------------------------------------------------- // Recursively reflow each sub-doc and then calc // all the frame locations of the sub-docs -nsresult +nsresult DocumentViewerImpl::ReflowDocList(PrintObject* aPO, PRBool aSetPixelScale, PRBool aDoCalcShrink) { NS_ASSERTION(aPO, "Pointer is null!"); @@ -3288,7 +3577,7 @@ DocumentViewerImpl::ReflowDocList(PrintObject* aPO, PRBool aSetPixelScale, PRBoo // Don't reflow hidden POs if (aPO->mIsHidden) return NS_OK; - // Here is where we set the shrinkage value into the DC + // Here is where we set the shrinkage value into the DC // and this is what actually makes it shrink if (aSetPixelScale && aPO->mFrameType != eIFrame) { float ratio; @@ -3300,7 +3589,7 @@ DocumentViewerImpl::ReflowDocList(PrintObject* aPO, PRBool aSetPixelScale, PRBoo mPrt->mPrintDC->SetCanonicalPixelScale(ratio*mPrt->mOrigDCScale); } - // Reflow the PO + // Reflow the PO if (NS_FAILED(ReflowPrintObject(aPO, aDoCalcShrink))) { return NS_ERROR_FAILURE; } @@ -3384,7 +3673,8 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO, PRBool aDoCalcShrink) return rv; } - rv = document->CreateShell(aPO->mPresContext, aPO->mViewManager, aPO->mStyleSet, getter_AddRefs(aPO->mPresShell)); + rv = document->CreateShell(aPO->mPresContext, aPO->mViewManager, + aPO->mStyleSet, getter_AddRefs(aPO->mPresShell)); if (NS_FAILED(rv)) { return rv; } @@ -3394,7 +3684,7 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO, PRBool aDoCalcShrink) PRInt32 width, height; if (aPO->mContent == nsnull || !aPO->mPrintAsIs || - (aPO->mPrintAsIs && aPO->mParent != nsnull && !aPO->mParent->mPrintAsIs) || + (aPO->mPrintAsIs && aPO->mParent && !aPO->mParent->mPrintAsIs) || (aPO->mFrameType == eIFrame && aPO == mPrt->mSelectedPO)) { width = pageWidth; height = pageHeight; @@ -3405,22 +3695,25 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO, PRBool aDoCalcShrink) PRINT_DEBUG_MSG5("In DV::ReflowPrintObject PO: %p (%9s) Setting w,h to %d,%d\n", aPO, gFrameTypesStr[aPO->mFrameType], width, height); - nsCOMPtr domWinIntl(do_QueryInterface(mPrt->mPrintDocDW)); + nsCOMPtr domWinIntl = + do_QueryInterface(mPrt->mPrintDocDW); // XXX - Hack Alert - // OK, so ther eis a selection, we will print the entire selection + // OK, so ther eis a selection, we will print the entire selection // on one page and then crop the page. - // This means you can never print any selection that is longer than one page - // put it keeps it from page breaking in the middle of your print of the selection - // (see also nsSimplePageSequence.cpp) + // This means you can never print any selection that is longer than + // one page put it keeps it from page breaking in the middle of your + // print of the selection (see also nsSimplePageSequence.cpp) PRInt16 printRangeType = nsIPrintSettings::kRangeAllPages; if (mPrt->mPrintSettings != nsnull) { mPrt->mPrintSettings->GetPrintRange(&printRangeType); } - if (printRangeType == nsIPrintSettings::kRangeSelection && IsThereARangeSelection(domWinIntl)) { + if (printRangeType == nsIPrintSettings::kRangeSelection && + IsThereARangeSelection(domWinIntl)) { height = NS_UNCONSTRAINEDSIZE; } + nsRect tbounds = nsRect(0, 0, width, height); // Create a child window of the parent that is our "root view/window" @@ -3434,7 +3727,7 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO, PRBool aDoCalcShrink) } #ifdef NS_PRINT_PREVIEW - // Here we decide whether we need scrollbars and + // Here we decide whether we need scrollbars and // what the parent will be of the widget if (mIsCreatingPrintPreview) { PRBool canCreateScrollbars = PR_FALSE; @@ -3446,16 +3739,17 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO, PRBool aDoCalcShrink) NS_ASSERTION(frameMan, "No Frame manager!"); nsIFrame* frame; frameMan->GetPrimaryFrameFor(aPO->mContent, &frame); - if (frame != nsnull && (aPO->mFrameType == eIFrame || aPO->mFrameType == eFrame)) { + if (frame && (aPO->mFrameType == eIFrame || aPO->mFrameType == eFrame)) { frame->FirstChild(aPO->mParent->mPresContext, nsnull, &frame); } - if (frame != nsnull) { + + if (frame) { nsIView* view = nsnull; frame->GetView(aPO->mParent->mPresContext, &view); - if (view != nsnull) { + if (view) { nsCOMPtr w2; view->GetWidget(*getter_AddRefs(w2)); - if (nsnull != w2) { + if (w2) { widget = w2; } canCreateScrollbars = PR_FALSE; @@ -3487,7 +3781,7 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO, PRBool aDoCalcShrink) nsCOMPtr presShell; nsCOMPtr layoutState; NS_ENSURE_SUCCESS(GetPresShell(*(getter_AddRefs(presShell))), NS_ERROR_FAILURE); - presShell->CaptureHistoryState(getter_AddRefs(layoutState),PR_TRUE); + presShell->CaptureHistoryState(getter_AddRefs(layoutState), PR_TRUE); // set it on the new pres shell aPO->mPresShell->SetHistoryState(layoutState); @@ -3506,9 +3800,9 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO, PRBool aDoCalcShrink) // initialize it with the default/generic case nsRect adjRect(aPO->mRect.x != 0?margin.left:0, aPO->mRect.y != 0?margin.top:0, width, height); - // XXX This is an arbitray height, + // XXX This is an arbitray height, // but reflow somethimes gets upset when using max int - // basically, we want to reflow a single page that is large + // basically, we want to reflow a single page that is large // enough to fit any atomic object like an IFrame const PRInt32 kFivePagesHigh = 5; @@ -3600,7 +3894,7 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO, PRBool aDoCalcShrink) nsRect rect; child->GetRect(rect); - // Create a RenderingContext and set the PresContext + // Create a RenderingContext and set the PresContext // appropriately if we are printing selection nsCOMPtr rc; if (nsIPrintSettings::kRangeSelection == printRangeType) { @@ -3683,7 +3977,7 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO, PRBool aDoCalcShrink) //------------------------------------------------------- // Given a DOMWindow it recursively finds the PO object that matches -PrintObject* +PrintObject* DocumentViewerImpl::FindPrintObjectByDOMWin(PrintObject* aPO, nsIDOMWindowInternal * aDOMWin) { NS_ASSERTION(aPO, "Pointer is null!"); @@ -3717,12 +4011,11 @@ DocumentViewerImpl::GetDOMWinForWebShell(nsIWebShell* aWebShell) NS_ASSERTION(aWebShell, "Pointer is null!"); nsCOMPtr domWin = do_GetInterface(aWebShell); - if (!domWin) return nsnull; nsCOMPtr domWinInt(do_QueryInterface(domWin)); if (!domWinInt) return nsnull; - nsIDOMWindowInternal * dw = NS_STATIC_CAST(nsIDOMWindowInternal *, domWinInt.get()); + nsIDOMWindowInternal * dw = domWinInt.get(); NS_ADDREF(dw); return dw; @@ -3740,10 +4033,10 @@ DocumentViewerImpl::EnablePOsForPrinting() return NS_ERROR_FAILURE; } - mPrt->mPrintFrameType = nsIPrintSettings::kNoFrames; + mPrt->mPrintFrameType = nsIPrintSettings::kNoFrames; mPrt->mPrintSettings->GetPrintFrameType(&mPrt->mPrintFrameType); - PRInt16 printHowEnable = nsIPrintSettings::kFrameEnableNone; + PRInt16 printHowEnable = nsIPrintSettings::kFrameEnableNone; mPrt->mPrintSettings->GetHowToEnableFrameUI(&printHowEnable); PRInt16 printRangeType = nsIPrintSettings::kRangeAllPages; @@ -3761,13 +4054,13 @@ DocumentViewerImpl::EnablePOsForPrinting() // then set the mPrintFrameType as if it were the selected frame if (printRangeType == nsIPrintSettings::kRangeSelection) { mPrt->mPrintFrameType = nsIPrintSettings::kSelectedFrame; - printHowEnable = nsIPrintSettings::kFrameEnableNone; + printHowEnable = nsIPrintSettings::kFrameEnableNone; } // This tells us that the "Frame" UI has turned off, // so therefore there are no FrameSets/Frames/IFrames to be printed // - // This means there are not FrameSets, + // This means there are not FrameSets, // but the document could contain an IFrame if (printHowEnable == nsIPrintSettings::kFrameEnableNone) { @@ -3793,7 +4086,7 @@ DocumentViewerImpl::EnablePOsForPrinting() PRINT_DEBUG_MSG2("PrintRange: %s \n", gPrintRangeStr[printRangeType]); return NS_OK; } - + // This means we are either printed a selected IFrame or // we are printing the current selection if (printRangeType == nsIPrintSettings::kRangeSelection) { @@ -3810,12 +4103,12 @@ DocumentViewerImpl::EnablePOsForPrinting() // Now, only enable this POs (the selected PO) and all of its children SetPrintPO(po, PR_TRUE); - // check to see if we have a range selection, + // check to see if we have a range selection, // as oppose to a insert selection - // this means if the user just clicked on the IFrame then + // this means if the user just clicked on the IFrame then // there will not be a selection so we want the entire page to print // - // XXX this is sort of a hack right here to make the page + // XXX this is sort of a hack right here to make the page // not try to reposition itself when printing selection nsCOMPtr domWin = getter_AddRefs(GetDOMWinForWebShell(po->mWebShell)); if (!IsThereARangeSelection(domWin)) { @@ -3857,12 +4150,12 @@ DocumentViewerImpl::EnablePOsForPrinting() // Now, only enable this POs (the selected PO) and all of its children SetPrintPO(po, PR_TRUE); - // check to see if we have a range selection, + // check to see if we have a range selection, // as oppose to a insert selection - // this means if the user just clicked on the IFrame then + // this means if the user just clicked on the IFrame then // there will not be a selection so we want the entire page to print // - // XXX this is sort of a hack right here to make the page + // XXX this is sort of a hack right here to make the page // not try to reposition itself when printing selection nsCOMPtr domWin = getter_AddRefs(GetDOMWinForWebShell(po->mWebShell)); if (!IsThereARangeSelection(domWin)) { @@ -3893,9 +4186,9 @@ DocumentViewerImpl::EnablePOsForPrinting() PrintObject * po = FindPrintObjectByDOMWin(mPrt->mPrintObject, mPrt->mCurrentFocusWin); if (po != nsnull) { mPrt->mSelectedPO = po; - // NOTE: Calling this sets the "po" and + // NOTE: Calling this sets the "po" and // we don't want to do this for documents that have no children, - // because then the "DoEndPage" gets called and it shouldn't + // because then the "DoEndPage" gets called and it shouldn't if (po->mKids.Count() > 0) { // Makes sure that itself, and all of its children are printed "AsIs" SetPrintAsIs(po); @@ -3906,10 +4199,10 @@ DocumentViewerImpl::EnablePOsForPrinting() } } return NS_OK; - } - - // If we are print each subdoc separately, - // then don't print any of the FraneSet Docs + } + + // If we are print each subdoc separately, + // then don't print any of the FraneSet Docs if (mPrt->mPrintFrameType == nsIPrintSettings::kEachFrameSep) { SetPrintPO(mPrt->mPrintObject, PR_TRUE); PRInt32 cnt = mPrt->mPrintDocList->Count(); @@ -3927,11 +4220,11 @@ DocumentViewerImpl::EnablePOsForPrinting() //--------------------------------------------------- // Find the Frame in a Frame List that is XMost -void -DocumentViewerImpl::FindXMostFrameInList(nsIPresContext* aPresContext, +void +DocumentViewerImpl::FindXMostFrameInList(nsIPresContext* aPresContext, nsIRenderingContext* aRC, nsIAtom* aList, - nsIFrame* aFrame, + nsIFrame* aFrame, nscoord aX, nscoord aY, PRInt32& aMaxWidth) @@ -3940,7 +4233,7 @@ DocumentViewerImpl::FindXMostFrameInList(nsIPresContext* aPresContext, aFrame->FirstChild(aPresContext, aList, &child); while (child) { PRBool isVisible = PR_TRUE; - // If the aRC is nsnull, then we skip the more expensive check and + // If the aRC is nsnull, then we skip the more expensive check and // just check visibility if (aRC) { child->IsVisibleForPainting(aPresContext, *aRC, PR_TRUE, &isVisible); @@ -3993,10 +4286,10 @@ DocumentViewerImpl::FindXMostFrameInList(nsIPresContext* aPresContext, //--------------------------------------------------- // Find the Frame that is XMost -void -DocumentViewerImpl::FindXMostFrameSize(nsIPresContext* aPresContext, +void +DocumentViewerImpl::FindXMostFrameSize(nsIPresContext* aPresContext, nsIRenderingContext* aRC, - nsIFrame* aFrame, + nsIFrame* aFrame, nscoord aX, nscoord aY, PRInt32& aMaxWidth) @@ -4011,15 +4304,15 @@ DocumentViewerImpl::FindXMostFrameSize(nsIPresContext* aPresContext, FindXMostFrameInList(aPresContext, aRC, childListName, aFrame, aX, aY, aMaxWidth); NS_IF_RELEASE(childListName); aFrame->GetAdditionalChildListName(childListIndex++, &childListName); - } while (childListName); + } while (childListName); } //------------------------------------------------------- -// Return the PrintObject with that is XMost (The widest frameset frame) AND -// contains the XMost (widest) layout frame -PrintObject* +// Return the PrintObject with that is XMost (The widest frameset frame) AND +// contains the XMost (widest) layout frame +PrintObject* DocumentViewerImpl::FindXMostPO() { nscoord xMostForPO = 0; @@ -4130,7 +4423,7 @@ DocumentViewerImpl::SetupToPrintContent(nsIWebShell* aParent, PRINT_DEBUG_MSG1("\n-------------------------------------------------------\n\n"); // Set up the clipping rectangle for all documents - // When frames are being printed as part of a frame set and also IFrames, + // When frames are being printed as part of a frame set and also IFrames, // they are reflowed with a very large page height. We need to setup the // clipping so they do not rpint over top of anything else PRINT_DEBUG_MSG1("SetClipRect-------------------------------------------------------\n"); @@ -4165,7 +4458,7 @@ DocumentViewerImpl::SetupToPrintContent(nsIWebShell* aParent, // This will print the webshell document // when it completes asynchronously in the DonePrintingPages method - // it will check to see if there are more webshells to be printed and + // it will check to see if there are more webshells to be printed and // then PrintDocContent will be called again. nsresult rv = NS_OK; @@ -4222,7 +4515,7 @@ DocumentViewerImpl::DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& a if (aPO->mFrameType == eFrame) { switch (mPrt->mPrintFrameType) { - case nsIPrintSettings::kFramesAsIs: + case nsIPrintSettings::kFramesAsIs: skipAllPageAdjustments = PR_TRUE; doOffsetting = PR_TRUE; break; @@ -4271,7 +4564,7 @@ DocumentViewerImpl::DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& a skipPageEjectOnly = aPO->mPrintAsIs; } - // That we are all configured, + // That we are all configured, // let's set everything up to print if (skipPageEjectOnly) { pageSequence->SkipPageEnd(); @@ -4305,8 +4598,8 @@ DocumentViewerImpl::DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& a } } - PRINT_DEBUG_MSG5("*** skipPageEjectOnly: %s skipAllPageAdjustments: %s doOffsetting: %s doAddInParentsOffset: %s\n", - PRT_YESNO(skipPageEjectOnly), PRT_YESNO(skipAllPageAdjustments), + PRINT_DEBUG_MSG5("*** skipPageEjectOnly: %s skipAllPageAdjustments: %s doOffsetting: %s doAddInParentsOffset: %s\n", + PRT_YESNO(skipPageEjectOnly), PRT_YESNO(skipAllPageAdjustments), PRT_YESNO(doOffsetting), PRT_YESNO(doAddInParentsOffset)); // We are done preparing for printing, so we can turn this off @@ -4323,7 +4616,7 @@ DocumentViewerImpl::DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& a if (NS_SUCCEEDED(CallQueryInterface(root, &fdbg))) { fdbg->DumpRegressionData(poPresContext, mPrt->mDebugFilePtr, 0, PR_TRUE); } - fclose(mPrt->mDebugFilePtr); + fclose(mPrt->mDebugFilePtr); #endif } else { nsIFrame* rootFrame; @@ -4344,9 +4637,10 @@ DocumentViewerImpl::DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& a if (!skipSetTitle) { PRUnichar * docTitleStr; PRUnichar * docURLStr; - GetDisplayTitleAndURL(aPO, mPrt->mPrintSettings, mPrt->mBrandName, &docTitleStr, &docURLStr, eDocTitleDefBlank); + GetDisplayTitleAndURL(aPO, mPrt->mPrintSettings, mPrt->mBrandName, + &docTitleStr, &docURLStr, eDocTitleDefBlank); - // Set them down into the PrintOptions so + // Set them down into the PrintOptions so // they can used by the DeviceContext if (docTitleStr) { mPrt->mPrintOptions->SetTitle(docTitleStr); @@ -4380,8 +4674,8 @@ DocumentViewerImpl::DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& a if (NS_SUCCEEDED(rvv) && selectionPS) { } - rv = GetPageRangeForSelection(poPresShell, poPresContext, *rc, selectionPS, pageSequence, - &startFrame, startPageNum, startRect, + rv = GetPageRangeForSelection(poPresShell, poPresContext, *rc, selectionPS, pageSequence, + &startFrame, startPageNum, startRect, &endFrame, endPageNum, endRect); if (NS_SUCCEEDED(rv)) { mPrt->mPrintSettings->SetStartPageRange(startPageNum); @@ -4549,7 +4843,7 @@ DocumentViewerImpl::PrintDocContent(PrintObject* aPO, nsresult& aStatus) if (!aPO->mHasBeenPrinted && aPO->IsPrintable()) { PRBool donePrinting; // donePrinting is only valid when when doing synchronous printing - aStatus = DoPrint(aPO, PR_FALSE, donePrinting); + aStatus = DoPrint(aPO, PR_FALSE, donePrinting); if (donePrinting) { return PR_TRUE; } @@ -4561,8 +4855,8 @@ DocumentViewerImpl::PrintDocContent(PrintObject* aPO, nsresult& aStatus) if (printed || NS_FAILED(aStatus)) { return PR_TRUE; } - } - return PR_FALSE; + } + return PR_FALSE; } NS_IMETHODIMP @@ -4573,11 +4867,11 @@ DocumentViewerImpl::SetEnableRendering(PRBool aOn) if (mViewManager) { if (aOn) { mViewManager->EnableRefresh(NS_VMREFRESH_IMMEDIATE); - nsIView* view; - mViewManager->GetRootView(view); // views are not refCounted - if (view) { + nsIView* view; + mViewManager->GetRootView(view); // views are not refCounted + if (view) { mViewManager->UpdateView(view, NS_VMREFRESH_IMMEDIATE); - } + } } else { mViewManager->DisableRefresh(); @@ -4637,9 +4931,10 @@ DocumentViewerImpl::CreateStyleSet(nsIDocument* aDocument, } } - nsCOMPtr chromeRegistry = - do_GetService("@mozilla.org/chrome/chrome-registry;1", &rv); - if (NS_SUCCEEDED(rv) && chromeRegistry) { + nsCOMPtr chromeRegistry = + do_GetService("@mozilla.org/chrome/chrome-registry;1"); + + if (chromeRegistry) { nsCOMPtr sheets; // Now handle the user sheets. @@ -4693,7 +4988,7 @@ DocumentViewerImpl::MakeWindow(nsIWidget* aParentWidget, nsCOMPtr dx; mPresContext->GetDeviceContext(getter_AddRefs(dx)); - + nsRect tbounds = aBounds; float p2t; mPresContext->GetPixelsToTwips(&p2t); @@ -4708,17 +5003,19 @@ DocumentViewerImpl::MakeWindow(nsIWidget* aParentWidget, if (NS_FAILED(rv)) return rv; - // Reset the bounds offset so the root view is set to 0,0. The offset is - // specified in nsIViewManager::Init above. - // Besides, layout will reset the root view to (0,0) during reflow, - // so changing it to 0,0 eliminates placing - // the root view in the wrong place initially. + // Reset the bounds offset so the root view is set to 0,0. The + // offset is specified in nsIViewManager::Init above. + // Besides, layout will reset the root view to (0,0) during reflow, + // so changing it to 0,0 eliminates placing the root view in the + // wrong place initially. tbounds.x = 0; tbounds.y = 0; // Create a child window of the parent that is our "root view/window" // Create a view - rv = CallCreateInstance(kViewCID, &mView); + + nsIView *view = nsnull; + rv = CallCreateInstance(kViewCID, &view); if (NS_FAILED(rv)) return rv; @@ -4727,13 +5024,13 @@ DocumentViewerImpl::MakeWindow(nsIWidget* aParentWidget, nsIView* containerView = nsnull; if (NS_SUCCEEDED(aParentWidget->GetClientData(clientData))) { nsISupports* data = (nsISupports*)clientData; - - if (nsnull != data) { + + if (data) { data->QueryInterface(NS_GET_IID(nsIView), (void **)&containerView); } } - if (nsnull != containerView) { + if (containerView) { // see if the containerView has already been hooked into a foreign view manager hierarchy // if it has, then we have to hook into the hierarchy too otherwise bad things will happen. nsCOMPtr containerVM; @@ -4745,13 +5042,13 @@ DocumentViewerImpl::MakeWindow(nsIWidget* aParentWidget, } while (pView != nsnull && NS_SUCCEEDED(pView->GetViewManager(*getter_AddRefs(checkVM))) && checkVM == containerVM); - if (nsnull == pView) { + if (!pView) { // OK, so the container is not already hooked up into a foreign view manager hierarchy. // That means we can choose not to hook ourselves up. // // If the parent container is a chrome shell, or a frameset, then we won't hook into its view // tree. This will improve performance a little bit (especially given scrolling/painting perf bugs) - // but is really just for peace of mind. This check can be removed if we want to support fancy + // but is really just for peace of mind. This check can be removed if we want to support fancy // chrome effects like transparent controls floating over content, transparent Web browsers, and // things like that, and the perf bugs are fixed. nsCOMPtr container(do_QueryInterface(mContainer)); @@ -4772,20 +5069,20 @@ DocumentViewerImpl::MakeWindow(nsIWidget* aParentWidget, } } - rv = mView->Init(mViewManager, tbounds, containerView); + rv = view->Init(mViewManager, tbounds, containerView); if (NS_FAILED(rv)) return rv; - rv = mView->CreateWidget(kWidgetCID, nsnull, - aParentWidget->GetNativeData(NS_NATIVE_WIDGET), - PR_TRUE, PR_FALSE); + rv = view->CreateWidget(kWidgetCID, nsnull, + aParentWidget->GetNativeData(NS_NATIVE_WIDGET), + PR_TRUE, PR_FALSE); if (rv != NS_OK) return rv; // Setup hierarchical relationship in view manager - mViewManager->SetRootView(mView); + mViewManager->SetRootView(view); - mView->GetWidget(*getter_AddRefs(mWindow)); + view->GetWidget(*getter_AddRefs(mWindow)); // This SetFocus is necessary so the Arrow Key and Page Key events // go to the scrolled view as soon as the Window is created instead of going to @@ -4795,21 +5092,25 @@ DocumentViewerImpl::MakeWindow(nsIWidget* aParentWidget, return rv; } -nsresult DocumentViewerImpl::GetDocumentSelection(nsISelection **aSelection, nsIPresShell * aPresShell) +nsresult DocumentViewerImpl::GetDocumentSelection(nsISelection **aSelection, + nsIPresShell *aPresShell) { - if (aPresShell == nsnull) { + if (!aPresShell) { if (!mPresShell) { return NS_ERROR_NOT_INITIALIZED; } aPresShell = mPresShell; } - if (!aSelection) return NS_ERROR_NULL_POINTER; - if (!aPresShell) return NS_ERROR_NULL_POINTER; + if (!aSelection) + return NS_ERROR_NULL_POINTER; + if (!aPresShell) + return NS_ERROR_NULL_POINTER; nsCOMPtr selcon; selcon = do_QueryInterface(aPresShell); - if (selcon) - return selcon->GetSelection(nsISelectionController::SELECTION_NORMAL, aSelection); + if (selcon) + return selcon->GetSelection(nsISelectionController::SELECTION_NORMAL, + aSelection); return NS_ERROR_FAILURE; } @@ -4821,13 +5122,13 @@ DocumentViewerImpl::CreateDocumentViewerUsing(nsIPresContext* aPresContext, // XXX better error return NS_ERROR_NULL_POINTER; } - if (nsnull == aPresContext) { + if (!aPresContext) { return NS_ERROR_NULL_POINTER; } // Create new viewer DocumentViewerImpl* viewer = new DocumentViewerImpl(aPresContext); - if (nsnull == viewer) { + if (!viewer) { return NS_ERROR_OUT_OF_MEMORY; } NS_ADDREF(viewer); @@ -4838,7 +5139,7 @@ DocumentViewerImpl::CreateDocumentViewerUsing(nsIPresContext* aPresContext, // Bind the new viewer to the old document nsresult rv = viewer->LoadStart(mDocument); - + aResult = viewer; return rv; @@ -4887,7 +5188,7 @@ nsresult DocumentViewerImpl::DocumentReadyForPrinting() return rv; } -NS_IMETHODIMP +NS_IMETHODIMP DocumentViewerImpl::SetTransformMediator(nsITransformMediator* aMediator) { NS_ASSERTION(nsnull == mTransformMediator, "nsXMLDocument::SetTransformMediator(): \ @@ -4939,7 +5240,7 @@ NS_IMETHODIMP DocumentViewerImpl::SelectAll() nsCOMPtr htmldoc = do_QueryInterface(mDocument); nsCOMPtr bodyNode; - + if (htmldoc) { nsCOMPtrbodyElement; @@ -4954,8 +5255,8 @@ NS_IMETHODIMP DocumentViewerImpl::SelectAll() mDocument->GetRootContent(getter_AddRefs(rootContent)); bodyNode = do_QueryInterface(rootContent); } - if (!bodyNode) return NS_ERROR_FAILURE; - + if (!bodyNode) return NS_ERROR_FAILURE; + rv = selection->RemoveAllRanges(); if (NS_FAILED(rv)) return rv; @@ -5008,10 +5309,10 @@ NS_IMETHODIMP DocumentViewerImpl::GetCopyable(PRBool *aCopyable) nsresult rv; rv = GetDocumentSelection(getter_AddRefs(selection)); if (NS_FAILED(rv)) return rv; - + PRBool isCollapsed; selection->GetIsCollapsed(&isCollapsed); - + *aCopyable = !isCollapsed; return NS_OK; } @@ -5096,7 +5397,7 @@ nsresult DocumentViewerImpl::GetSelectionDocument(nsIDeviceContextSpec * aDevSpe if (NS_FAILED(rv)) { return rv; } rv = htmlElement->AppendChildTo(bodyElement, PR_FALSE, PR_FALSE); if (NS_FAILED(rv)) { return rv; } - + // load the document into the docshell nsCOMPtr domDoc = do_QueryInterface(doc); if (!domDoc) { return NS_ERROR_NULL_POINTER; } @@ -5114,8 +5415,8 @@ nsresult DocumentViewerImpl::GetSelectionDocument(nsIDeviceContextSpec * aDevSpe } //------------------------------------------------------ -PRBool -DocumentViewerImpl::IsThereAnIFrameSelected(nsIWebShell* aWebShell, +PRBool +DocumentViewerImpl::IsThereAnIFrameSelected(nsIWebShell* aWebShell, nsIDOMWindowInternal * aDOMWin, PRPackedBool& aIsParentFrameSet) { @@ -5131,7 +5432,7 @@ DocumentViewerImpl::IsThereAnIFrameSelected(nsIWebShell* aWebShell, // if so, it means the selected frame is either the main webshell // or an IFRAME if (aDOMWin != nsnull) { - // Get the main webshell's DOMWin to see if it matches + // Get the main webshell's DOMWin to see if it matches // the frame that is selected nsCOMPtr domWin = getter_AddRefs(GetDOMWinForWebShell(aWebShell)); if (aDOMWin != nsnull && domWin != aDOMWin) { @@ -5145,7 +5446,7 @@ DocumentViewerImpl::IsThereAnIFrameSelected(nsIWebShell* aWebShell, //------------------------------------------------------ -PRBool +PRBool DocumentViewerImpl::IsThereARangeSelection(nsIDOMWindowInternal * aDOMWin) { nsCOMPtr presShell; @@ -5180,7 +5481,7 @@ DocumentViewerImpl::IsThereARangeSelection(nsIDOMWindowInternal * aDOMWin) //------------------------------------------------------- // Recursively walks the PrintObject tree and installs the DocViewer // as an event processor and it shows the window -nsresult +nsresult DocumentViewerImpl::ShowDocList(PrintObject* aPO, PRBool aShow) { NS_ASSERTION(aPO, "Pointer is null!"); @@ -5189,7 +5490,8 @@ DocumentViewerImpl::ShowDocList(PrintObject* aPO, PRBool aShow) PRBool donePrinting; DoPrint(aPO, PR_FALSE, donePrinting); - // mWindow will be null for POs that are hidden, so they don't get shown + // mWindow will be null for POs that are hidden, so they don't get + // shown if (aPO->mWindow) { aPO->mWindow->Show(aShow); } @@ -5201,6 +5503,7 @@ DocumentViewerImpl::ShowDocList(PrintObject* aPO, PRBool aShow) return NS_ERROR_FAILURE; } } + return NS_OK; } @@ -5240,7 +5543,7 @@ DocumentViewerImpl::InstallPrintPreviewListener() //---------------------------------------------------------------------- static nsresult GetSeqFrameAndCountPages(PrintObject* aPO, - nsIFrame*& aSeqFrame, + nsIFrame*& aSeqFrame, PRInt32& aCount) { NS_ENSURE_ARG_POINTER(aPO); @@ -5389,7 +5692,7 @@ DocumentViewerImpl::PrintPreviewNavigate(PRInt16 aType, PRInt32 aPageNum) } /* readonly attribute boolean isFramesetDocument; */ -NS_IMETHODIMP +NS_IMETHODIMP DocumentViewerImpl::GetIsFramesetDocument(PRBool *aIsFramesetDocument) { nsCOMPtr webContainer(do_QueryInterface(mContainer)); @@ -5438,7 +5741,7 @@ DocumentViewerImpl::GetIsFramesetFrameSelected(PRBool *aIsFramesetFrameSelected) } /* readonly attribute long printPreviewNumPages; */ -NS_IMETHODIMP +NS_IMETHODIMP DocumentViewerImpl::GetPrintPreviewNumPages(PRInt32 *aPrintPreviewNumPages) { NS_ENSURE_ARG_POINTER(aPrintPreviewNumPages); @@ -5455,7 +5758,7 @@ DocumentViewerImpl::GetPrintPreviewNumPages(PRInt32 *aPrintPreviewNumPages) } /* void exitPrintPreview (); */ -NS_IMETHODIMP +NS_IMETHODIMP DocumentViewerImpl::ExitPrintPreview() { if (mIsDoingPrinting) return NS_ERROR_FAILURE; @@ -5490,7 +5793,8 @@ DocumentViewerImpl::InstallNewPresentation() } // turn off selection painting - nsCOMPtr selectionController = do_QueryInterface(mPresShell); + nsCOMPtr selectionController = + do_QueryInterface(mPresShell); if (selectionController) { selectionController->SetDisplaySelection(nsISelectionController::SELECTION_OFF); } @@ -5503,7 +5807,7 @@ DocumentViewerImpl::InstallNewPresentation() nsCOMPtr selection; nsresult rv = GetDocumentSelection(getter_AddRefs(selection)); nsCOMPtr selPrivate(do_QueryInterface(selection)); - if (NS_SUCCEEDED(rv) && selPrivate && mSelectionListener) + if (NS_SUCCEEDED(rv) && selPrivate && mSelectionListener) selPrivate->RemoveSelectionListener(mSelectionListener); // We need to destroy the PreShell if there is an existing PP @@ -5539,7 +5843,7 @@ DocumentViewerImpl::InstallNewPresentation() // This is the new code for selecting the appropriate Frame of a Frameset // for Print Preview. But it can't be turned on yet -#if 0 +#if 0 // If it is a Frameset then choose the selected one // or select the one with the largest area if (mPrt->mPrintObject->mFrameType == eFrameSet) { @@ -5614,7 +5918,6 @@ DocumentViewerImpl::InstallNewPresentation() Show(); ShowDocList(mPrt->mPrintObject, PR_TRUE); - } void @@ -5657,7 +5960,7 @@ DocumentViewerImpl::ReturnToGalleyPresentation() nsCOMPtr selection; nsresult rv = GetDocumentSelection(getter_AddRefs(selection)); nsCOMPtr selPrivate(do_QueryInterface(selection)); - if (NS_SUCCEEDED(rv) && selPrivate && mSelectionListener) + if (NS_SUCCEEDED(rv) && selPrivate && mSelectionListener) selPrivate->RemoveSelectionListener(mSelectionListener); mPresShell->Destroy(); } @@ -5680,6 +5983,10 @@ DocumentViewerImpl::ReturnToGalleyPresentation() mViewManager = mPrtPreview->mCachedPresObj->mViewManager; mWindow = mPrtPreview->mCachedPresObj->mWindow; + // Tell the "real" presshell to start observing the document + // again. + mPresShell->BeginObservingDocument(); + mWindow->Show(PR_TRUE); // Very important! Turn On scripting @@ -5689,7 +5996,6 @@ DocumentViewerImpl::ReturnToGalleyPresentation() mPrtPreview = nsnull; wasCached = PR_TRUE; - } else { // Destroy the old Presentation mPresShell = nsnull; @@ -5708,8 +6014,8 @@ DocumentViewerImpl::ReturnToGalleyPresentation() mIsDoingPrintPreview = PR_FALSE; mViewManager->EnableRefresh(NS_VMREFRESH_NO_SYNC); - Show(); + Show(); } #endif // NS_PRINT_PREVIEW @@ -5718,7 +6024,7 @@ DocumentViewerImpl::ReturnToGalleyPresentation() // This method checks to see if there is at least one printer defined // and if so, it sets the first printer in the list as the default name // in the PrintSettings which is then used for Printer Preview -nsresult +nsresult DocumentViewerImpl::CheckForPrinters(nsIPrintOptions* aPrintOptions, nsIPrintSettings* aPrintSettings, PRUint32 aErrorCode, @@ -5736,7 +6042,7 @@ DocumentViewerImpl::CheckForPrinters(nsIPrintOptions* aPrintOptions, simpEnum->HasMoreElements(&fndPrinter); if (fndPrinter) { // For now, it assumes the first item in the list - // is the default printer, but only set the + // is the default printer, but only set the // printer name if there isn't one nsCOMPtr supps; simpEnum->GetNext(getter_AddRefs(supps)); @@ -5893,13 +6199,24 @@ void DocumentViewerImpl::CheckForHiddenFrameSetFrames() * See documentation above in the nsIContentViewerfile class definition * @update 11/01/01 rods * - * For a full and detailed understanding of the issues with - * PrintPreview: See the design spec that is attached to Bug 107562 + * For a full and detailed understanding of the issues with + * PrintPreview: See the design spec that is attached to Bug 107562 */ NS_IMETHODIMP DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) { - if (mIsDoingPrinting) return NS_ERROR_FAILURE; + if (!mPresShell) { + // A frame that's not displayed can't be printed! + + return NS_OK; + } + + if (mIsDoingPrinting) { + return NS_ERROR_FAILURE; + } + + nsCOMPtr docShell(do_QueryInterface(mContainer)); + NS_ASSERTION(docShell, "This has to be a docshell"); // Temporary code for Bug 136185 nsCOMPtr xulDoc(do_QueryInterface(mDocument)); @@ -5910,15 +6227,20 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) // Get the webshell for this documentviewer nsCOMPtr webContainer(do_QueryInterface(mContainer)); + // Get the DocShell and see if it is busy // We can't Print or Print Preview this document if it is still busy - nsCOMPtr docShell(do_QueryInterface(webContainer)); - NS_ASSERTION(docShell.get(), "This has to be a docshell"); + PRUint32 busyFlags = nsIDocShell::BUSY_FLAGS_NONE; - if (NS_FAILED(docShell->GetBusyFlags(&busyFlags)) || busyFlags != nsIDocShell::BUSY_FLAGS_NONE) { + + // Preview this document if it is still busy + + if (NS_FAILED(docShell->GetBusyFlags(&busyFlags)) || + busyFlags != nsIDocShell::BUSY_FLAGS_NONE) { ShowPrintErrorDialog(NS_ERROR_GFX_PRINTER_DOC_IS_BUSY_PP, PR_FALSE); return NS_ERROR_FAILURE; } + nsresult rv = NS_OK; #if defined(XP_PC) && defined(DEBUG_rods) && defined(DEBUG_PRINTING) @@ -5934,7 +6256,7 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) } mPrt = new PrintData(); - if (mPrt == nsnull) { + if (!mPrt) { mIsCreatingPrintPreview = PR_FALSE; return NS_ERROR_OUT_OF_MEMORY; } @@ -5956,12 +6278,13 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) } } - // You have to have both a PrintOptions and a PrintSetting to call CheckForPrinters. - // The user can pass in a null PrintSettings, - // but you can only create one if you have a PrintOptions. - // So we we might as check to if we have a PrintOptions first, - // because we can't do anything below without it - // then inside we check to se if the printSettings is null to know if we need to create on. + // You have to have both a PrintOptions and a PrintSetting to call + // CheckForPrinters. + // The user can pass in a null PrintSettings, but you can only + // create one if you have a PrintOptions. So we we might as check + // to if we have a PrintOptions first, because we can't do anything + // below without it then inside we check to se if the printSettings + // is null to know if we need to create on. mPrt->mPrintSettings = aPrintSettings; mPrt->mPrintOptions = do_GetService(kPrintOptionsCID, &rv); if (NS_SUCCEEDED(rv) && mPrt->mPrintOptions) { @@ -5978,7 +6301,7 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) return NS_ERROR_FAILURE; } } - + // Let's print ... mIsCreatingPrintPreview = PR_TRUE; mIsDoingPrintPreview = PR_TRUE; @@ -5996,14 +6319,14 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) PRBool isSelection = IsThereARangeSelection(mPrt->mCurrentFocusWin); // Create a list for storing the WebShells that need to be printed - if (mPrt->mPrintDocList == nsnull) { + if (!mPrt->mPrintDocList) { mPrt->mPrintDocList = new nsVoidArray(); - if (mPrt->mPrintDocList == nsnull) { + if (!mPrt->mPrintDocList) { mIsCreatingPrintPreview = PR_FALSE; mIsDoingPrintPreview = PR_FALSE; aPrintSettings->SetIsPrintPreview(mIsDoingPrintPreview); TurnScriptingOn(PR_TRUE); - return NS_ERROR_FAILURE; + return NS_ERROR_OUT_OF_MEMORY; } } else { mPrt->mPrintDocList->Clear(); @@ -6015,7 +6338,7 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) mPrt->mPrintDocList->AppendElement(mPrt->mPrintObject); mPrt->mIsParentAFrameSet = IsParentAFrameSet(webContainer); - mPrt->mPrintObject->mFrameType = mPrt->mIsParentAFrameSet?eFrameSet:eDoc; + mPrt->mPrintObject->mFrameType = mPrt->mIsParentAFrameSet ? eFrameSet : eDoc; // Build the "tree" of PrintObjects nsCOMPtr parentAsNode(do_QueryInterface(webContainer)); @@ -6025,8 +6348,8 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) // in the parent document MapContentToWebShells(mPrt->mPrintObject, mPrt->mPrintObject); - // Get whether the doc contains a frameset - // Also, check to see if the currently focus webshell + // Get whether the doc contains a frameset + // Also, check to see if the currently focus webshell // is a child of this webshell mPrt->mIsIFrameSelected = IsThereAnIFrameSelected(webContainer, mPrt->mCurrentFocusWin, mPrt->mIsParentAFrameSet); @@ -6054,7 +6377,7 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) #ifdef DEBUG_PRINTING if (mPrt->mPrintSettings) { - PRInt16 printHowEnable = nsIPrintSettings::kFrameEnableNone; + PRInt16 printHowEnable = nsIPrintSettings::kFrameEnableNone; mPrt->mPrintSettings->GetHowToEnableFrameUI(&printHowEnable); PRBool val; mPrt->mPrintSettings->GetPrintOptions(nsIPrintSettings::kEnableSelectionRB, &val); @@ -6082,7 +6405,7 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) nsCOMPtr dx; nsresult rv = factory->CreateDeviceContextSpec(mWindow, aPrintSettings, *getter_AddRefs(devspec), doSilent); if (NS_SUCCEEDED(rv)) { - rv = mDeviceContext->GetDeviceContextFor(devspec, *getter_AddRefs(ppDC)); + rv = mDeviceContext->GetDeviceContextFor(devspec, *getter_AddRefs(ppDC)); if (NS_SUCCEEDED(rv)) { mDeviceContext->SetAltDevice(ppDC); if (mPrt->mPrintSettings != nsnull) { @@ -6109,7 +6432,7 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) mPrt->mPrintSettings->SetPrintRange(nsIPrintSettings::kRangeAllPages); } - mPrt->mPrintDC = mDeviceContext; + mPrt->mPrintDC = mDeviceContext; // Get the Original PixelScale incase we need to start changing it mPrt->mPrintDC->GetCanonicalPixelScale(mPrt->mOrigDCScale); @@ -6145,8 +6468,8 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) } /* cleanup done, let's fire-up an error dialog to notify the user - * what went wrong... - */ + * what went wrong... + */ ShowPrintErrorDialog(rv, PR_FALSE); TurnScriptingOn(PR_TRUE); mIsCreatingPrintPreview = PR_FALSE; @@ -6155,7 +6478,7 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) } - // At this point we are done preparing everything + // At this point we are done preparing everything // before it is to be created // Noew create the new Presentation and display it @@ -6173,7 +6496,8 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) void -DocumentViewerImpl::SetDocAndURLIntoProgress(PrintObject* aPO, nsIPrintProgressParams* aParams) +DocumentViewerImpl::SetDocAndURLIntoProgress(PrintObject* aPO, + nsIPrintProgressParams* aParams) { NS_ASSERTION(aPO, "Must have vaild PrintObject"); NS_ASSERTION(aParams, "Must have vaild nsIPrintProgressParams"); @@ -6181,11 +6505,12 @@ DocumentViewerImpl::SetDocAndURLIntoProgress(PrintObject* aPO, nsIPrintProgressP if (!aPO || !aPO->mWebShell || !aParams) { return; } - const PRInt32 kTitleLength = 64; + const PRUint32 kTitleLength = 64; PRUnichar * docTitleStr; PRUnichar * docURLStr; - GetDisplayTitleAndURL(aPO, mPrt->mPrintSettings, mPrt->mBrandName, &docTitleStr, &docURLStr, eDocTitleDefDocument); + GetDisplayTitleAndURL(aPO, mPrt->mPrintSettings, mPrt->mBrandName, + &docTitleStr, &docURLStr, eDocTitleDefDocument); // Make sure the URLS don't get too long for the progress dialog if (docURLStr && nsCRT::strlen(docURLStr) > kTitleLength) { @@ -6252,7 +6577,7 @@ DocumentViewerImpl::DoPrintProgress(PRBool aIsForPrinting) */ NS_IMETHODIMP DocumentViewerImpl::Print(PRBool aSilent, - FILE * aDebugFile, + FILE * aDebugFile, nsIPrintSettings* aPrintSettings) { nsCOMPtr printSettings; @@ -6276,7 +6601,7 @@ DocumentViewerImpl::Print(PRBool aSilent, return Print(printSettings, nsnull); - + } /** --------------------------------------------------- @@ -6301,6 +6626,17 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, nsresult rv = NS_ERROR_FAILURE; + nsCOMPtr docShell(do_QueryInterface(mContainer)); + NS_ASSERTION(docShell, "This has to be a docshell"); + + nsCOMPtr presShell; + docShell->GetPresShell(getter_AddRefs(presShell)); + + if (!presShell) { + // A frame that's not displayed can't be printed! + + return NS_OK; + } if (mIsDoingPrintPreview) { PRBool okToPrint = PR_FALSE; @@ -6315,7 +6651,7 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, } // if we are printing another URL, then exit - // the reason we check here is because this method can be called while + // the reason we check here is because this method can be called while // another is still in here (the printing dialog is a good example). // the only time we can print more than one job at a time is the regression tests if (mIsDoingPrinting) { @@ -6324,7 +6660,7 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, ShowPrintErrorDialog(rv); return rv; } - + mPrt = new PrintData(); if (mPrt == nsnull) { return NS_ERROR_OUT_OF_MEMORY; @@ -6363,7 +6699,7 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, mPrt->mPrintProgressListeners.AppendElement((void*)aWebProgressListener); NS_ADDREF(aWebProgressListener); } - + // Get the currently focused window and cache it // because the Print Dialog will "steal" focus and later when you try // to get the currently focused windows it will be NULL @@ -6405,8 +6741,8 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, MapContentToWebShells(mPrt->mPrintObject, mPrt->mPrintObject); - // Get whether the doc contains a frameset - // Also, check to see if the currently focus webshell + // Get whether the doc contains a frameset + // Also, check to see if the currently focus webshell // is a child of this webshell mPrt->mIsIFrameSelected = IsThereAnIFrameSelected(webContainer, mPrt->mCurrentFocusWin, mPrt->mIsParentAFrameSet); @@ -6430,7 +6766,7 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, #ifdef DEBUG_PRINTING if (mPrt->mPrintSettings) { - PRInt16 printHowEnable = nsIPrintSettings::kFrameEnableNone; + PRInt16 printHowEnable = nsIPrintSettings::kFrameEnableNone; mPrt->mPrintSettings->GetHowToEnableFrameUI(&printHowEnable); PRBool val; mPrt->mPrintSettings->GetPrintOptions(nsIPrintSettings::kEnableSelectionRB, &val); @@ -6449,7 +6785,7 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, /* create factory (incl. create print dialog) */ nsCOMPtr factory = do_CreateInstance(kDeviceContextSpecFactoryCID, &rv); - + if (NS_SUCCEEDED(rv)) { #ifdef DEBUG_dcone printf("PRINT JOB STARTING\n"); @@ -6464,7 +6800,7 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, #endif // we have to turn off printpreview mode for now.. because this is a real request to print. - if ( mIsDoingPrintPreview == PR_TRUE) { + if (mIsDoingPrintPreview) { aPrintSettings->SetIsPrintPreview(PR_FALSE); } @@ -6571,7 +6907,7 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, mPrt->mPrintFrameType = nsIPrintSettings::kEachFrameSep; mPrt->mPrintSettings->SetPrintFrameType(mPrt->mPrintFrameType); } else { - // First find out from the PrinService what options are available + // First find out from the PrinService what options are available // to us for Printing FrameSets PRInt16 howToEnableFrameUI; mPrt->mPrintSettings->GetHowToEnableFrameUI(&howToEnableFrameUI); @@ -6616,12 +6952,14 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, PRUnichar * docTitleStr; PRUnichar * docURLStr; - GetDisplayTitleAndURL(mPrt->mPrintObject, mPrt->mPrintSettings, mPrt->mBrandName, &docTitleStr, &docURLStr, eDocTitleDefURLDoc); + GetDisplayTitleAndURL(mPrt->mPrintObject, mPrt->mPrintSettings, + mPrt->mBrandName, &docTitleStr, &docURLStr, + eDocTitleDefURLDoc); // BeginDocument may pass back a FAILURE code - // i.e. On Windows, if you are printing to a file and hit "Cancel" + // i.e. On Windows, if you are printing to a file and hit "Cancel" // to the "File Name" dialog, this comes back as an error - // Don't start printing when regression test are executed + // Don't start printing when regression test are executed rv = mPrt->mDebugFilePtr ? NS_OK: mPrt->mPrintDC->BeginDocument(docTitleStr); PRINT_DEBUG_MSG1("****************** Begin Document ************************\n"); @@ -6634,12 +6972,12 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, // Print listener setup... if (mPrt != nsnull) { - mPrt->OnStartPrinting(); + mPrt->OnStartPrinting(); } // // The mIsPrinting flag is set when the ImageGroup observer is - // notified that images must be loaded as a result of the + // notified that images must be loaded as a result of the // InitialReflow... // if(!mIsPrinting || mPrt->mDebugFilePtr) { @@ -6652,20 +6990,18 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, } } } - } + } } else { mPrt->mPrintSettings->SetIsCancelled(PR_TRUE); mPrt->mPrintOptions->SetIsCancelled(PR_TRUE); } - - // Set that we are once again in print preview - if ( mIsDoingPrintPreview == PR_TRUE) { + + // Set that we are once again in print preview + if (mIsDoingPrintPreview) { aPrintSettings->SetIsPrintPreview(PR_TRUE); } } - - /* cleaup on failure + notify user */ if (NS_FAILED(rv)) { /* cleanup... */ @@ -6673,7 +7009,7 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, mPagePrintTimer->Stop(); NS_RELEASE(mPagePrintTimer); } - + if (mPrt) { delete mPrt; mPrt = nsnull; @@ -6681,16 +7017,16 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, mIsDoingPrinting = PR_FALSE; /* cleanup done, let's fire-up an error dialog to notify the user - * what went wrong... - * - * When rv == NS_ERROR_ABORT, it means we want out of the + * what went wrong... + * + * When rv == NS_ERROR_ABORT, it means we want out of the * print job without displaying any error messages */ if (rv != NS_ERROR_ABORT) { ShowPrintErrorDialog(rv); } } - + return rv; } @@ -6699,19 +7035,19 @@ void DocumentViewerImpl::ShowPrintErrorDialog(nsresult aPrintError, PRBool aIsPrinting) { nsresult rv; - + static NS_DEFINE_CID(kCStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID); nsCOMPtr stringBundleService = do_GetService(kCStringBundleServiceCID); - - if (!stringBundleService) { + + if (!stringBundleService) { NS_WARNING("ERROR: Failed to get StringBundle Service instance.\n"); return; } nsCOMPtr myStringBundle; - rv = stringBundleService->CreateBundle(NS_ERROR_GFX_PRINTER_BUNDLE_URL, getter_AddRefs(myStringBundle)); - if (NS_FAILED(rv)) + rv = stringBundleService->CreateBundle(NS_ERROR_GFX_PRINTER_BUNDLE_URL, getter_AddRefs(myStringBundle)); + if (NS_FAILED(rv)) return; - + nsXPIDLString msg, title; nsAutoString stringName; @@ -6753,7 +7089,7 @@ DocumentViewerImpl::ShowPrintErrorDialog(nsresult aPrintError, PRBool aIsPrintin default: NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_FAILURE) -#undef NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG +#undef NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG } myStringBundle->GetStringFromName(stringName.get(), getter_Copies(msg)); @@ -6765,7 +7101,7 @@ DocumentViewerImpl::ShowPrintErrorDialog(nsresult aPrintError, PRBool aIsPrintin if (!msg) return; - + nsCOMPtr wwatch = do_GetService("@mozilla.org/embedcomp/window-watcher;1", &rv); if (NS_FAILED(rv)) return; @@ -6776,27 +7112,22 @@ DocumentViewerImpl::ShowPrintErrorDialog(nsresult aPrintError, PRBool aIsPrintin nsCOMPtr parent = do_QueryInterface(active, &rv); if (NS_FAILED(rv)) return; - - nsCOMPtr dialog; - parent->GetPrompter(getter_AddRefs(dialog)); + + nsCOMPtr dialog; + parent->GetPrompter(getter_AddRefs(dialog)); if (!dialog) return; - + dialog->Alert(title, msg); } // nsIContentViewerFile interface NS_IMETHODIMP -DocumentViewerImpl::GetPrintable(PRBool *aPrintable) +DocumentViewerImpl::GetPrintable(PRBool *aPrintable) { NS_ENSURE_ARG_POINTER(aPrintable); - - if(mIsDoingPrinting==PR_TRUE){ - *aPrintable = PR_FALSE; - } else { - *aPrintable = PR_TRUE; - } + *aPrintable = !mIsDoingPrinting; return NS_OK; } @@ -6807,7 +7138,7 @@ DocumentViewerImpl::GetPrintable(PRBool *aPrintable) //***************************************************************************** // nsIMarkupDocumentViewer -//***************************************************************************** +//***************************************************************************** NS_IMETHODIMP DocumentViewerImpl::ScrollToNode(nsIDOMNode* aNode) { @@ -6816,25 +7147,25 @@ NS_IMETHODIMP DocumentViewerImpl::ScrollToNode(nsIDOMNode* aNode) nsCOMPtr presShell; NS_ENSURE_SUCCESS(GetPresShell(*(getter_AddRefs(presShell))), NS_ERROR_FAILURE); - // Get the nsIContent interface, because that's what we need to + // Get the nsIContent interface, because that's what we need to // get the primary frame - + nsCOMPtr content(do_QueryInterface(aNode)); NS_ENSURE_TRUE(content, NS_ERROR_FAILURE); // Get the primary frame - nsIFrame* frame; // Remember Frames aren't ref-counted. They are in their + nsIFrame* frame; // Remember Frames aren't ref-counted. They are in their // own special little world. NS_ENSURE_SUCCESS(presShell->GetPrimaryFrameFor(content, &frame), NS_ERROR_FAILURE); // tell the pres shell to scroll to the frame - NS_ENSURE_SUCCESS(presShell->ScrollFrameIntoView(frame, - NS_PRESSHELL_SCROLL_TOP, - NS_PRESSHELL_SCROLL_ANYWHERE), - NS_ERROR_FAILURE); - return NS_OK; + NS_ENSURE_SUCCESS(presShell->ScrollFrameIntoView(frame, + NS_PRESSHELL_SCROLL_TOP, + NS_PRESSHELL_SCROLL_ANYWHERE), + NS_ERROR_FAILURE); + return NS_OK; } NS_IMETHODIMP DocumentViewerImpl::GetAllowPlugins(PRBool* aAllowPlugins) @@ -6860,17 +7191,17 @@ DocumentViewerImpl::CallChildren(CallChildFunc aFunc, void* aClosure) PRInt32 i; PRInt32 n; docShellNode->GetChildCount(&n); - for (i=0; i < n; i++) + for (i=0; i < n; i++) { nsCOMPtr child; docShellNode->GetChildAt(i, getter_AddRefs(child)); nsCOMPtr childAsShell(do_QueryInterface(child)); NS_ASSERTION(childAsShell, "null child in docshell"); - if (childAsShell) + if (childAsShell) { nsCOMPtr childCV; childAsShell->GetContentViewer(getter_AddRefs(childCV)); - if (childCV) + if (childCV) { nsCOMPtr markupCV = do_QueryInterface(childCV); if (markupCV) { @@ -6921,7 +7252,7 @@ NS_IMETHODIMP DocumentViewerImpl::GetTextZoom(float* aTextZoom) return NS_OK; } -// XXX: SEMANTIC CHANGE! +// XXX: SEMANTIC CHANGE! // returns a copy of the string. Caller is responsible for freeing result // using Recycle(aDefaultCharacterSet) NS_IMETHODIMP DocumentViewerImpl::GetDefaultCharacterSet(PRUnichar** aDefaultCharacterSet) @@ -6929,18 +7260,18 @@ NS_IMETHODIMP DocumentViewerImpl::GetDefaultCharacterSet(PRUnichar** aDefaultCha NS_ENSURE_ARG_POINTER(aDefaultCharacterSet); NS_ENSURE_STATE(mContainer); - if (mDefaultCharacterSet.IsEmpty()) + if (mDefaultCharacterSet.IsEmpty()) { nsXPIDLString defCharset; nsCOMPtr webShell; webShell = do_QueryInterface(mContainer); if (webShell) - { + { nsCOMPtr prefs(do_GetService(NS_PREF_CONTRACTID)); if (prefs) prefs->GetLocalizedUnicharPref("intl.charset.default", getter_Copies(defCharset)); - } + } if (!defCharset.IsEmpty()) mDefaultCharacterSet.Assign(defCharset.get()); @@ -6965,7 +7296,7 @@ NS_IMETHODIMP DocumentViewerImpl::SetDefaultCharacterSet(const PRUnichar* aDefau (void*) aDefaultCharacterSet); } -// XXX: SEMANTIC CHANGE! +// XXX: SEMANTIC CHANGE! // returns a copy of the string. Caller is responsible for freeing result // using Recycle(aForceCharacterSet) NS_IMETHODIMP DocumentViewerImpl::GetForceCharacterSet(PRUnichar** aForceCharacterSet) @@ -6995,7 +7326,7 @@ NS_IMETHODIMP DocumentViewerImpl::SetForceCharacterSet(const PRUnichar* aForceCh return CallChildren(SetChildForceCharacterSet, (void*) aForceCharacterSet); } -// XXX: SEMANTIC CHANGE! +// XXX: SEMANTIC CHANGE! // returns a copy of the string. Caller is responsible for freeing result // using Recycle(aHintCharacterSet) NS_IMETHODIMP DocumentViewerImpl::GetHintCharacterSet(PRUnichar * *aHintCharacterSet) @@ -7080,7 +7411,7 @@ NS_IMETHODIMP DocumentViewerImpl::GetBidiTextDirection(PRUint8* aTextDirection) #endif return NS_OK; } - + NS_IMETHODIMP DocumentViewerImpl::SetBidiTextType(PRUint8 aTextType) { #ifdef IBMBIDI @@ -7236,9 +7567,9 @@ NS_IMETHODIMP DocumentViewerImpl::SetBidiOptions(PRUint32 aBidiOptions) #ifdef IBMBIDI if (mPresContext) { #if 1 - // forcing reflow will cause bug 80352. Temp turn off force reflow and + // forcing reflow will cause bug 80352. Temp turn off force reflow and // wait for simon@softel.co.il to find the real solution - mPresContext->SetBidi(aBidiOptions, PR_FALSE); + mPresContext->SetBidi(aBidiOptions, PR_FALSE); #else mPresContext->SetBidi(aBidiOptions, PR_TRUE); // force reflow #endif @@ -7273,7 +7604,7 @@ NS_IMETHODIMP DocumentViewerImpl::SizeToContent() nsCOMPtr docShellParent; docShellAsItem->GetSameTypeParent(getter_AddRefs(docShellParent)); - // It's only valid to access this from a top frame. Doesn't work from + // It's only valid to access this from a top frame. Doesn't work from // sub-frames. NS_ENSURE_TRUE(!docShellParent, NS_ERROR_FAILURE); @@ -7362,7 +7693,7 @@ DocumentViewerImpl::GetPopupNode(nsIDOMNode** aNode) // get the internal dom window nsCOMPtr internalWin(do_QueryInterface(global, &rv)); NS_ENSURE_SUCCESS(rv, rv); - NS_ENSURE_TRUE(internalWin, NS_ERROR_FAILURE); + NS_ENSURE_TRUE(internalWin, NS_ERROR_FAILURE); // get the private dom window nsCOMPtr privateWin(do_QueryInterface(internalWin, &rv)); @@ -7534,20 +7865,20 @@ NS_IMETHODIMP nsDocViewerSelectionListener::NotifySelectionChanged(nsIDOMDocumen if (!mGotSelectionState || mSelectionWasCollapsed != selectionCollapsed) { nsCOMPtr theDoc; - mDocViewer->GetDocument(*getter_AddRefs(theDoc)); + mDocViewer->GetDocument(*getter_AddRefs(theDoc)); if (!theDoc) return NS_ERROR_FAILURE; - + nsCOMPtr scriptGlobalObject; theDoc->GetScriptGlobalObject(getter_AddRefs(scriptGlobalObject)); nsCOMPtr domWindow = do_QueryInterface(scriptGlobalObject); if (!domWindow) return NS_ERROR_FAILURE; - + domWindow->UpdateCommands(NS_LITERAL_STRING("select")); mGotSelectionState = PR_TRUE; mSelectionWasCollapsed = selectionCollapsed; - } - + } + return NS_OK; } @@ -7584,7 +7915,7 @@ nsDocViewerFocusListener::Focus(nsIDOMEvent* aEvent) selCon->GetDisplaySelection( &selectionStatus); //if selection was nsISelectionController::SELECTION_OFF, do nothing - //otherwise re-enable it. + //otherwise re-enable it. if(selectionStatus == nsISelectionController::SELECTION_DISABLED || selectionStatus == nsISelectionController::SELECTION_HIDDEN) { @@ -7598,7 +7929,7 @@ NS_IMETHODIMP nsDocViewerFocusListener::Blur(nsIDOMEvent* aEvent) { nsCOMPtr shell; - if(!mDocViewer) + if(!mDocViewer) return NS_ERROR_FAILURE; nsresult result = mDocViewer->GetPresShell(*getter_AddRefs(shell));//deref once cause it take a ptr ref @@ -7608,7 +7939,7 @@ nsDocViewerFocusListener::Blur(nsIDOMEvent* aEvent) selCon = do_QueryInterface(shell); PRInt16 selectionStatus; selCon->GetDisplaySelection(&selectionStatus); - + //if selection was nsISelectionController::SELECTION_OFF, do nothing //otherwise re-enable it. if(selectionStatus == nsISelectionController::SELECTION_ON) @@ -7628,7 +7959,7 @@ nsDocViewerFocusListener::Init(DocumentViewerImpl *aDocViewer) } -PRBool +PRBool DocumentViewerImpl::IsWindowsInOurSubTree(nsIDOMWindowInternal * aDOMWindow) { PRBool found = PR_FALSE; @@ -7669,7 +8000,7 @@ DocumentViewerImpl::IsWindowsInOurSubTree(nsIDOMWindowInternal * aDOMWindow) //---------------------------------------------------------------------------------- -void +void DocumentViewerImpl::CleanupDocTitleArray(PRUnichar**& aArray, PRInt32& aCount) { for (PRInt32 i = aCount - 1; i >= 0; i--) { @@ -7682,8 +8013,8 @@ DocumentViewerImpl::CleanupDocTitleArray(PRUnichar**& aArray, PRInt32& aCount) //---------------------------------------------------------------------------------- // Enumerate all the documents for their titles -NS_IMETHODIMP -DocumentViewerImpl::EnumerateDocumentNames(PRUint32* aCount, +NS_IMETHODIMP +DocumentViewerImpl::EnumerateDocumentNames(PRUint32* aCount, PRUnichar*** aResult) { NS_ENSURE_ARG(aCount); @@ -7691,12 +8022,12 @@ DocumentViewerImpl::EnumerateDocumentNames(PRUint32* aCount, *aCount = 0; *aResult = nsnull; - + PRInt32 numDocs = mPrt->mPrintDocList->Count(); PRUnichar** array = (PRUnichar**) nsMemory::Alloc(numDocs * sizeof(PRUnichar*)); - if (!array) + if (!array) return NS_ERROR_OUT_OF_MEMORY; - + for (PRInt32 i=0;imPrintDocList->ElementAt(i); NS_ASSERTION(po, "PrintObject can't be null!"); @@ -7729,7 +8060,7 @@ DocumentViewerImpl::EnumerateDocumentNames(PRUint32* aCount, } /* readonly attribute nsIPrintSettings newPrintSettings; */ -NS_IMETHODIMP +NS_IMETHODIMP DocumentViewerImpl::GetNewPrintSettings(nsIPrintSettings * *aNewPrintSettings) { NS_ENSURE_ARG_POINTER(aNewPrintSettings); @@ -7744,7 +8075,7 @@ DocumentViewerImpl::GetNewPrintSettings(nsIPrintSettings * *aNewPrintSettings) } /* readonly attribute wstring defaultPrinterName; */ -NS_IMETHODIMP +NS_IMETHODIMP DocumentViewerImpl::GetDefaultPrinterName(PRUnichar * *aDefaultPrinterName) { NS_ENSURE_ARG_POINTER(aDefaultPrinterName); @@ -7758,7 +8089,7 @@ DocumentViewerImpl::GetDefaultPrinterName(PRUnichar * *aDefaultPrinterName) } /* void initPrintSettingsFromPrinter (in wstring aPrinterName, in nsIPrintSettings aPrintSettings); */ -NS_IMETHODIMP +NS_IMETHODIMP DocumentViewerImpl::InitPrintSettingsFromPrinter(const PRUnichar *aPrinterName, nsIPrintSettings *aPrintSettings) { NS_ENSURE_ARG_POINTER(aPrintSettings); @@ -7780,7 +8111,7 @@ DocumentViewerImpl::InitPrintSettingsFromPrinter(const PRUnichar *aPrinterName, } /* readonly attribute nsIPrintSettings globalPrintSettings; */ -NS_IMETHODIMP +NS_IMETHODIMP DocumentViewerImpl::GetGlobalPrintSettings(nsIPrintSettings * *aGlobalPrintSettings) { NS_ENSURE_ARG_POINTER(aGlobalPrintSettings); @@ -7799,11 +8130,34 @@ DocumentViewerImpl::GetDoingPrintPreview(PRBool *aDoingPrintPreview) { NS_ENSURE_ARG_POINTER(aDoingPrintPreview); *aDoingPrintPreview = mIsDoingPrintPreview; + + if (!*aDoingPrintPreview) { + nsCOMPtr item(do_QueryInterface(mContainer)); + nsCOMPtr viewer; + + if (item) { + nsCOMPtr parent; + item->GetParent(getter_AddRefs(parent)); + + nsCOMPtr docShell(do_QueryInterface(parent)); + + if (docShell) { + docShell->GetContentViewer(getter_AddRefs(viewer)); + } + } + + nsCOMPtr wbp(do_QueryInterface(viewer)); + + if (wbp) { + return wbp->GetDoingPrintPreview(aDoingPrintPreview); + } + } + return NS_OK; } /* readonly attribute nsIPrintSettings currentPrintSettings; */ -NS_IMETHODIMP +NS_IMETHODIMP DocumentViewerImpl::GetCurrentPrintSettings(nsIPrintSettings * *aCurrentPrintSettings) { NS_ENSURE_ARG_POINTER(aCurrentPrintSettings); @@ -7822,7 +8176,7 @@ DocumentViewerImpl::GetCurrentPrintSettings(nsIPrintSettings * *aCurrentPrintSet } /* void cancel (); */ -NS_IMETHODIMP +NS_IMETHODIMP DocumentViewerImpl::Cancel() { nsresult rv; @@ -7834,7 +8188,7 @@ DocumentViewerImpl::Cancel() } /* void initPrintSettingsFromPrefs (in nsIPrintSettings aPrintSettings, in boolean aUsePrinterNamePrefix, in unsigned long aFlags); */ -NS_IMETHODIMP +NS_IMETHODIMP DocumentViewerImpl::InitPrintSettingsFromPrefs(nsIPrintSettings *aPrintSettings, PRBool aUsePrinterNamePrefix, PRUint32 aFlags) { nsresult rv; @@ -7846,7 +8200,7 @@ DocumentViewerImpl::InitPrintSettingsFromPrefs(nsIPrintSettings *aPrintSettings, } /* void savePrintSettingsToPrefs (in nsIPrintSettings aPrintSettings, in boolean aUsePrinterNamePrefix, in unsigned long aFlags); */ -NS_IMETHODIMP +NS_IMETHODIMP DocumentViewerImpl::SavePrintSettingsToPrefs(nsIPrintSettings *aPrintSettings, PRBool aUsePrinterNamePrefix, PRUint32 aFlags) { nsresult rv; @@ -7859,7 +8213,7 @@ DocumentViewerImpl::SavePrintSettingsToPrefs(nsIPrintSettings *aPrintSettings, P /** --------------------------------------------------- * Get the Focused Frame for a documentviewer - * + * */ nsIDOMWindowInternal* DocumentViewerImpl::FindFocusedDOMWindowInternal() @@ -7870,7 +8224,7 @@ DocumentViewerImpl::FindFocusedDOMWindowInternal() nsCOMPtr focusController; nsIDOMWindowInternal * domWin = nsnull; - this->GetDocument(*getter_AddRefs(theDoc)); + this->GetDocument(*getter_AddRefs(theDoc)); if(theDoc){ theDoc->GetScriptGlobalObject(getter_AddRefs(theSGO)); if(theSGO){ @@ -7896,7 +8250,7 @@ DocumentViewerImpl::FindFocusedDOMWindowInternal() /*=============== Timer Related Code ======================*/ nsresult -DocumentViewerImpl::StartPagePrintTimer(nsIPresContext * aPresContext, +DocumentViewerImpl::StartPagePrintTimer(nsIPresContext * aPresContext, nsIPrintSettings* aPrintSettings, PrintObject* aPOect, PRUint32 aDelay) diff --git a/content/base/src/nsFrameLoader.cpp b/content/base/src/nsFrameLoader.cpp index 1a4e5c9f97d..0f208679ed5 100644 --- a/content/base/src/nsFrameLoader.cpp +++ b/content/base/src/nsFrameLoader.cpp @@ -40,13 +40,14 @@ #include "nsIFrameLoader.h" #include "nsIDOMHTMLIFrameElement.h" #include "nsIDOMHTMLFrameElement.h" -#include "nsIDOMEventListener.h" -#include "nsIDOMEventTarget.h" #include "nsIDOMWindow.h" #include "nsIPresContext.h" #include "nsIPresShell.h" +#include "nsIContent.h" #include "nsIDocument.h" #include "nsIDOMDocument.h" +#include "nsIDOMWindow.h" +#include "nsPIDOMWindow.h" #include "nsIWebNavigation.h" #include "nsIChromeEventHandler.h" #include "nsIDocShell.h" @@ -56,9 +57,6 @@ #include "nsIDocShellLoadInfo.h" #include "nsIBaseWindow.h" #include "nsIWebShell.h" -#include "nsIWebProgressListener.h" -#include "nsIWebProgress.h" -#include "nsWeakReference.h" #include "nsIScriptSecurityManager.h" #include "nsICodebasePrincipal.h" @@ -66,10 +64,17 @@ #include "nsIURI.h" #include "nsNetUtil.h" -class nsFrameLoader : public nsIFrameLoader, - public nsIDOMEventListener, - public nsIWebProgressListener, - public nsSupportsWeakReference +#include "nsHTMLAtoms.h" +#include "nsINameSpaceManager.h" + + +// Bug 8065: Limit content frame depth to some reasonable level. This +// does not count chrome frames when determining depth, nor does it +// prevent chrome recursion. +#define MAX_DEPTH_CONTENT_FRAMES 8 + + +class nsFrameLoader : public nsIFrameLoader { public: nsFrameLoader(); @@ -79,26 +84,22 @@ public: NS_DECL_ISUPPORTS // nsIFrameLoader - NS_IMETHOD Init(nsIDOMElement *aOwner); - NS_IMETHOD LoadURI(nsIURI *aURI); + NS_IMETHOD Init(nsIContent *aOwner); + NS_IMETHOD LoadFrame(); NS_IMETHOD GetDocShell(nsIDocShell **aDocShell); + NS_IMETHOD GetIsDocumentLoading(PRBool* aIsDocumentLoading); NS_IMETHOD Destroy(); - // nsIDOMEventListener - NS_DECL_NSIDOMEVENTLISTENER - - // nsIWebProgressListener - NS_DECL_NSIWEBPROGRESSLISTENER - protected: nsresult GetPresContext(nsIPresContext **aPresContext); nsresult EnsureDocShell(); + void GetURL(nsAString& aURL); nsCOMPtr mDocShell; - nsCOMPtr mOwnerElement; + nsIContent *mOwnerContent; // WEAK - nsCOMPtr mURI; + PRBool mIsLoadStarted; }; nsresult @@ -112,26 +113,22 @@ NS_NewFrameLoader(nsIFrameLoader **aFrameLoader) return NS_OK; } - nsFrameLoader::nsFrameLoader() + : mOwnerContent(nsnull), mIsLoadStarted(PR_FALSE) { NS_INIT_ISUPPORTS(); } nsFrameLoader::~nsFrameLoader() { - nsCOMPtr treeOwnerAsWin(do_QueryInterface(mDocShell)); - - if (treeOwnerAsWin) { - treeOwnerAsWin->Destroy(); - } + Destroy(); } // QueryInterface implementation for nsFrameLoader NS_INTERFACE_MAP_BEGIN(nsFrameLoader) - NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) NS_INTERFACE_MAP_ENTRY(nsIFrameLoader) + NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_END @@ -139,27 +136,51 @@ NS_IMPL_ADDREF(nsFrameLoader); NS_IMPL_RELEASE(nsFrameLoader); NS_IMETHODIMP -nsFrameLoader::Init(nsIDOMElement *aOwner) +nsFrameLoader::Init(nsIContent *aOwner) { - mOwnerElement = aOwner; + mOwnerContent = aOwner; // WEAK return NS_OK; } NS_IMETHODIMP -nsFrameLoader::LoadURI(nsIURI *aURI) +nsFrameLoader::LoadFrame() { - mURI = aURI; + NS_ENSURE_TRUE(mOwnerContent, NS_ERROR_NOT_INITIALIZED); nsresult rv = EnsureDocShell(); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr doc; + mOwnerContent->GetDocument(*getter_AddRefs(doc)); + if (!doc) { + return NS_OK; + } - // Prevent recursion + nsAutoString src; + GetURL(src); + src.Trim(" \t\n\r"); + if (src.IsEmpty()) { + // about:blank will be synthesized into a frame if not URL is + // loaded into it (bug 35986) - // mCreatingViewer=PR_TRUE; + return NS_OK; + } + // Make an absolute URI + nsCOMPtr base_uri; + doc->GetBaseURL(*getter_AddRefs(base_uri)); + + nsAutoString doc_charset; + doc->GetDocumentCharacterSet(doc_charset); + + nsCOMPtr uri; + rv = NS_NewURI(getter_AddRefs(uri), src, + doc_charset.IsEmpty() ? nsnull : + NS_ConvertUCS2toUTF8(doc_charset).get(), base_uri); + NS_ENSURE_SUCCESS(rv, rv); // Check for security nsCOMPtr secMan = @@ -197,33 +218,25 @@ nsFrameLoader::LoadURI(nsIURI *aURI) loadInfo->SetInheritOwner(PR_TRUE); - nsCOMPtr dom_doc; - mOwnerElement->GetOwnerDocument(getter_AddRefs(dom_doc)); - nsCOMPtr doc(do_QueryInterface(dom_doc)); - - if (doc) { - doc->GetBaseURL(*getter_AddRefs(referrer)); - } + referrer = base_uri; } loadInfo->SetReferrer(referrer); // Check if we are allowed to load absURL - rv = secMan->CheckLoadURI(referrer, mURI, + rv = secMan->CheckLoadURI(referrer, uri, nsIScriptSecurityManager::STANDARD); if (NS_FAILED(rv)) { return rv; // We're not } - nsCOMPtr webProgress(do_GetInterface(mDocShell)); - - if (webProgress) { - webProgress->AddProgressListener(this); - } - - rv = mDocShell->LoadURI(mURI, loadInfo, nsIWebNavigation::LOAD_FLAGS_NONE); + // Kick off the load... + rv = mDocShell->LoadURI(uri, loadInfo, nsIWebNavigation::LOAD_FLAGS_NONE, + PR_FALSE); NS_ASSERTION(NS_SUCCEEDED(rv), "failed to load URL"); + mIsLoadStarted = NS_SUCCEEDED(rv); + return rv; } @@ -239,14 +252,35 @@ nsFrameLoader::GetDocShell(nsIDocShell **aDocShell) } NS_IMETHODIMP -nsFrameLoader::Destroy() +nsFrameLoader::GetIsDocumentLoading(PRBool* aIsDocumentLoading) { + *aIsDocumentLoading = mIsLoadStarted; + return NS_OK; } NS_IMETHODIMP -nsFrameLoader::HandleEvent(nsIDOMEvent *aEvent) +nsFrameLoader::Destroy() { + if (mOwnerContent) { + nsCOMPtr doc; + + mOwnerContent->GetDocument(*getter_AddRefs(doc)); + + if (doc) { + doc->SetSubDocumentFor(mOwnerContent, nsnull); + } + + mOwnerContent = nsnull; + } + + nsCOMPtr base_win(do_QueryInterface(mDocShell)); + + if (base_win) { + base_win->Destroy(); + } + + mDocShell = nsnull; return NS_OK; } @@ -256,10 +290,8 @@ nsFrameLoader::GetPresContext(nsIPresContext **aPresContext) { *aPresContext = nsnull; - nsCOMPtr dom_doc; - mOwnerElement->GetOwnerDocument(getter_AddRefs(dom_doc)); - - nsCOMPtr doc(do_QueryInterface(dom_doc)); + nsCOMPtr doc; + mOwnerContent->GetDocument(*getter_AddRefs(doc)); while (doc) { nsCOMPtr presShell; @@ -287,16 +319,15 @@ nsFrameLoader::EnsureDocShell() return NS_OK; } -#if 0 - - - + nsCOMPtr presContext; + GetPresContext(getter_AddRefs(presContext)); + NS_ENSURE_TRUE(presContext, NS_ERROR_UNEXPECTED); // Bug 8065: Don't exceed some maximum depth in content frames // (MAX_DEPTH_CONTENT_FRAMES) PRInt32 depth = 0; nsCOMPtr parentAsSupports; - aPresContext->GetContainer(getter_AddRefs(parentAsSupports)); + presContext->GetContainer(getter_AddRefs(parentAsSupports)); if (parentAsSupports) { nsCOMPtr parentAsItem = @@ -305,8 +336,11 @@ nsFrameLoader::EnsureDocShell() while (parentAsItem) { ++depth; - if (MAX_DEPTH_CONTENT_FRAMES < depth) + if (MAX_DEPTH_CONTENT_FRAMES < depth) { + NS_WARNING("Too many nested content frames so giving up"); + return NS_ERROR_UNEXPECTED; // Too deep, give up! (silently?) + } // Only count depth on content, not chrome. // If we wanted to limit total depth, skip the following check: @@ -321,32 +355,16 @@ nsFrameLoader::EnsureDocShell() } } } -#endif + // Create the docshell... mDocShell = do_CreateInstance("@mozilla.org/webshell;1"); NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE); -#if 0 - // notify the pres shell that a docshell has been created - nsCOMPtr presShell; - aPresContext->GetShell(getter_AddRefs(presShell)); - - if (presShell) { - nsCOMPtr subShellAsSupports(do_QueryInterface(mDocShell)); - NS_ENSURE_TRUE(subShellAsSupports, NS_ERROR_FAILURE); - - presShell->SetSubShellFor(mContent, subShellAsSupports); - - // We need to be able to get back to the presShell to unset the - // subshell at destruction - mPresShellWeak = getter_AddRefs(NS_GetWeakReference(presShell)); - } -#endif - + // Get the frame name and tell the docshell about it. nsCOMPtr docShellAsItem(do_QueryInterface(mDocShell)); NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE); nsAutoString frameName; - mOwnerElement->GetAttribute(NS_LITERAL_STRING("name"), frameName); + mOwnerContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::name, frameName); if (!frameName.IsEmpty()) { docShellAsItem->SetName(frameName.get()); @@ -356,178 +374,147 @@ nsFrameLoader::EnsureDocShell() // child. If it's not a web-shell then some things will not operate // properly. - - nsCOMPtr presContext; - GetPresContext(getter_AddRefs(presContext)); - - - - - - - - - - - - // what if !presContext ? - - - - - - - - - nsCOMPtr container; presContext->GetContainer(getter_AddRefs(container)); - if (container) { - nsCOMPtr parentAsNode(do_QueryInterface(container)); - if (parentAsNode) { - nsCOMPtr parentAsItem = - do_QueryInterface(parentAsNode); + nsCOMPtr parentAsNode(do_QueryInterface(container)); + if (parentAsNode) { + nsCOMPtr parentAsItem = + do_QueryInterface(parentAsNode); - PRInt32 parentType; - parentAsItem->GetItemType(&parentType); + PRInt32 parentType; + parentAsItem->GetItemType(&parentType); - nsAutoString value, valuePiece; - PRBool isContent; + nsAutoString value; + PRBool isContent; - isContent = PR_FALSE; - mOwnerElement->GetAttribute(NS_LITERAL_STRING("type"), value); + isContent = PR_FALSE; - if (!value.IsEmpty()) { - // we accept "content" and "content-xxx" values. - // at time of writing, we expect "xxx" to be "primary", but - // someday it might be an integer expressing priority - - - - - // string iterators! - - - value.Left(valuePiece, 7); - if (valuePiece.EqualsIgnoreCase("content") && - (value.Length() == 7 || - value.Mid(valuePiece, 7, 1) == 1 && - valuePiece.EqualsWithConversion("-"))) { - isContent = PR_TRUE; - } - } - - if (isContent) { - // The web shell's type is content. - docShellAsItem->SetItemType(nsIDocShellTreeItem::typeContent); - } else { - // Inherit our type from our parent webshell. If it is - // chrome, we'll be chrome. If it is content, we'll be - // content. - docShellAsItem->SetItemType(parentType); - } - - parentAsNode->AddChild(docShellAsItem); - - if (isContent) { - nsCOMPtr parentTreeOwner; - parentAsItem->GetTreeOwner(getter_AddRefs(parentTreeOwner)); - if(parentTreeOwner) { - PRBool is_primary = value.EqualsIgnoreCase("content-primary"); - - parentTreeOwner->ContentShellAdded(docShellAsItem, is_primary, - value.get()); - } - } - - // connect the container... - nsCOMPtr webShell(do_QueryInterface(mDocShell)); - nsCOMPtr outerContainer = - do_QueryInterface(container); - - if (outerContainer) { - webShell->SetContainer(outerContainer); - } - - // Make sure all shells have links back to the content element - // in the nearest enclosing chrome shell. - nsCOMPtr chromeEventHandler; - - if (parentType == nsIDocShellTreeItem::typeChrome) { - // Our parent shell is a chrome shell. It is therefore our nearest - // enclosing chrome shell. - chromeEventHandler = do_QueryInterface(mOwnerElement); - NS_WARN_IF_FALSE(chromeEventHandler, - "This mContent should implement this."); - } else { - nsCOMPtr parentShell(do_QueryInterface(parentAsNode)); - - // Our parent shell is a content shell. Get the chrome info from - // it and use that for our shell as well. - parentShell->GetChromeEventHandler(getter_AddRefs(chromeEventHandler)); - } - - - - // Should this be in the layout code? - - mDocShell->SetChromeEventHandler(chromeEventHandler); + if (mOwnerContent->IsContentOfType(nsIContent::eXUL)) { + mOwnerContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::type, value); } + + // we accept "content" and "content-xxx" values. + // at time of writing, we expect "xxx" to be "primary", but + // someday it might be an integer expressing priority + + if (value.Length() >= 7) { + // Lowercase the value, ContentShellAdded() further down relies + // on it being lowercased. + ToLowerCase(value); + + nsAutoString::const_iterator start, end; + value.BeginReading(start); + value.EndReading(end); + + nsAutoString::const_iterator iter(start); + iter.advance(7); + + const nsAString& valuePiece = Substring(start, iter); + + if (valuePiece.Equals(NS_LITERAL_STRING("content")) && + (iter == end || *iter == '-')) { + isContent = PR_TRUE; + } + } + + if (isContent) { + // The web shell's type is content. + + docShellAsItem->SetItemType(nsIDocShellTreeItem::typeContent); + } else { + // Inherit our type from our parent webshell. If it is + // chrome, we'll be chrome. If it is content, we'll be + // content. + + docShellAsItem->SetItemType(parentType); + } + + parentAsNode->AddChild(docShellAsItem); + + if (isContent) { + nsCOMPtr parentTreeOwner; + parentAsItem->GetTreeOwner(getter_AddRefs(parentTreeOwner)); + + if(parentTreeOwner) { + PRBool is_primary = value.Equals(NS_LITERAL_STRING("content-primary")); + + parentTreeOwner->ContentShellAdded(docShellAsItem, is_primary, + value.get()); + } + } + + // connect the container... + nsCOMPtr webShell(do_QueryInterface(mDocShell)); + nsCOMPtr outerContainer = + do_QueryInterface(container); + + if (outerContainer) { + webShell->SetContainer(outerContainer); + } + + // Make sure all shells have links back to the content element + // in the nearest enclosing chrome shell. + nsCOMPtr chromeEventHandler; + + if (parentType == nsIDocShellTreeItem::typeChrome) { + // Our parent shell is a chrome shell. It is therefore our nearest + // enclosing chrome shell. + + chromeEventHandler = do_QueryInterface(mOwnerContent); + NS_WARN_IF_FALSE(chromeEventHandler, + "This mContent should implement this."); + } else { + nsCOMPtr parentShell(do_QueryInterface(parentAsNode)); + + // Our parent shell is a content shell. Get the chrome event + // handler from it and use that for our shell as well. + + parentShell->GetChromeEventHandler(getter_AddRefs(chromeEventHandler)); + } + + mDocShell->SetChromeEventHandler(chromeEventHandler); } + // This is nasty, this code (the do_GetInterface(mDocShell) below) + // *must* come *after* the above call to + // mDocShell->SetChromeEventHandler() for the global window to get + // the right chrome event handler. + + // Tell the window about the frame that hosts it. + nsCOMPtr frame_element(do_QueryInterface(mOwnerContent)); + NS_ASSERTION(frame_element, "frame loader owner element not a DOM element!"); + + nsCOMPtr win(do_GetInterface(mDocShell)); + nsCOMPtr win_private(do_QueryInterface(win)); + NS_ENSURE_TRUE(win_private, NS_ERROR_UNEXPECTED); + + win_private->SetFrameElementInternal(frame_element); + + nsCOMPtr base_win(do_QueryInterface(mDocShell)); + NS_ENSURE_TRUE(base_win, NS_ERROR_UNEXPECTED); + + // This is kinda whacky, this call doesn't really create anything, + // but it must be called to make sure things are properly + // initialized + + base_win->Create(); + return NS_OK; } -NS_IMETHODIMP -nsFrameLoader::OnStateChange(nsIWebProgress *aWebProgress, - nsIRequest *aRequest, - PRInt32 aStateFlags, PRUint32 aStatus) +void +nsFrameLoader::GetURL(nsAString& aURI) { - if (!((~aStateFlags) & (nsIWebProgressListener::STATE_IS_DOCUMENT | - nsIWebProgressListener::STATE_TRANSFERRING))) { - nsCOMPtr win(do_GetInterface(mDocShell)); - nsCOMPtr eventTarget(do_QueryInterface(win)); + aURI.Truncate(); - if (eventTarget) { - eventTarget->AddEventListener(NS_LITERAL_STRING("load"), this, - PR_FALSE); - } + nsCOMPtr type; + mOwnerContent->GetTag(*getter_AddRefs(type)); + + if (type == nsHTMLAtoms::object) { + mOwnerContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::data, aURI); + } else { + mOwnerContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::src, aURI); } - - return NS_OK; -} - -NS_IMETHODIMP -nsFrameLoader::OnProgressChange(nsIWebProgress *aWebProgress, - nsIRequest *aRequest, - PRInt32 aCurSelfProgress, - PRInt32 aMaxSelfProgress, - PRInt32 aCurTotalProgress, - PRInt32 aMaxTotalProgress) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsFrameLoader::OnLocationChange(nsIWebProgress *aWebProgress, - nsIRequest *aRequest, nsIURI *location) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsFrameLoader::OnStatusChange(nsIWebProgress *aWebProgress, - nsIRequest *aRequest, nsresult aStatus, - const PRUnichar *aMessage) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsFrameLoader::OnSecurityChange(nsIWebProgress *aWebProgress, - nsIRequest *aRequest, PRInt32 state) -{ - return NS_OK; } diff --git a/content/base/src/nsGenericElement.cpp b/content/base/src/nsGenericElement.cpp index df4473e6ec7..fcb1edd318e 100644 --- a/content/base/src/nsGenericElement.cpp +++ b/content/base/src/nsGenericElement.cpp @@ -1634,8 +1634,8 @@ nsGenericElement::HandleDOMEvent(nsIPresContext* aPresContext, PRBool intermediateCapture = PR_FALSE; //Capturing stage evaluation - if (NS_EVENT_FLAG_BUBBLE != aFlags && aEvent->message != NS_PAGE_LOAD - && aEvent->message != NS_SCRIPT_LOAD && + if (NS_EVENT_FLAG_BUBBLE != aFlags && aEvent->message != NS_PAGE_LOAD && + aEvent->message != NS_SCRIPT_LOAD && aEvent->message != NS_IMAGE_ERROR && aEvent->message != NS_IMAGE_LOAD) { //Initiate capturing phase. Special case first call to document if (parent) { diff --git a/content/base/src/nsGenericElement.h b/content/base/src/nsGenericElement.h index e5b9a3b83ab..c015fb4d281 100644 --- a/content/base/src/nsGenericElement.h +++ b/content/base/src/nsGenericElement.h @@ -91,15 +91,16 @@ private: // objects for each of these instance variables, we put them off // in a side structure that's only allocated when the content is // accessed through the DOM. -typedef struct { +struct nsDOMSlots +{ nsChildContentList *mChildNodes; nsDOMCSSDeclaration *mStyle; nsDOMAttributeMap* mAttributeMap; nsVoidArray *mRangeList; nsIEventListenerManager* mListenerManager; - nsIContent* mBindingParent; // The nearest enclosing content node with a binding - // that created us. [Weak] -} nsDOMSlots; + nsIContent* mBindingParent; // The nearest enclosing content node with a + // binding that created us. [Weak] +}; class nsNode3Tearoff : public nsIDOM3Node diff --git a/content/base/src/nsPrintPreviewListener.h b/content/base/src/nsPrintPreviewListener.h index e54ae20aa51..9efa2808bd0 100644 --- a/content/base/src/nsPrintPreviewListener.h +++ b/content/base/src/nsPrintPreviewListener.h @@ -56,6 +56,9 @@ public: NS_DECL_ISUPPORTS nsPrintPreviewListener(nsIDOMEventReceiver* aEVRec); + virtual ~nsPrintPreviewListener() + { + } // nsIDOMContextMenuListener NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; } diff --git a/content/build/nsContentDLF.cpp b/content/build/nsContentDLF.cpp index 5dbb7e3668c..98026f58e1d 100644 --- a/content/build/nsContentDLF.cpp +++ b/content/build/nsContentDLF.cpp @@ -416,6 +416,8 @@ nsContentDLF::CreateDocument(const char* aCommand, break; docv->SetUAStyleSheet(gUAStyleSheet); + doc->SetContainer(aContainer); + // Initialize the document to begin loading the data. An // nsIStreamListener connected to the parser is returned in // aDocListener. @@ -512,6 +514,9 @@ nsContentDLF::CreateRDFDocument(const char* aCommand, * An nsIStreamListener connected to the parser is returned in * aDocListener. */ + + doc->SetContainer(aContainer); + rv = doc->StartDocumentLoad(aCommand, aChannel, aLoadGroup, aContainer, aDocListener, PR_TRUE); if (NS_SUCCEEDED(rv)) { /* diff --git a/content/build/nsContentModule.cpp b/content/build/nsContentModule.cpp index 45a6f65361a..3980126ed6f 100644 --- a/content/build/nsContentModule.cpp +++ b/content/build/nsContentModule.cpp @@ -97,6 +97,7 @@ #include "nsISelection.h" #include "nsITextContent.h" #include "nsIXBLService.h" +#include "nsIFrameLoader.h" #include "nsLayoutAtoms.h" #include "nsPlainTextSerializer.h" #include "mozSanitizingSerializer.h" @@ -276,6 +277,7 @@ extern nsresult NS_NewXBLService(nsIXBLService** aResult); extern nsresult NS_NewBindingManager(nsIBindingManager** aResult); extern nsresult NS_NewNodeInfoManager(nsINodeInfoManager** aResult); extern nsresult NS_NewContentPolicy(nsIContentPolicy** aResult); +extern nsresult NS_NewFrameLoader(nsIFrameLoader** aResult); #ifdef MOZ_XUL extern nsresult NS_NewXULElementFactory(nsIElementFactory** aResult); @@ -348,6 +350,7 @@ MAKE_CTOR(CreateSanitizingHTMLSerializer, nsIContentSerializer, NS_NewSan MAKE_CTOR(CreateXBLService, nsIXBLService, NS_NewXBLService) MAKE_CTOR(CreateBindingManager, nsIBindingManager, NS_NewBindingManager) MAKE_CTOR(CreateContentPolicy, nsIContentPolicy, NS_NewContentPolicy) +MAKE_CTOR(CreateFrameLoader, nsIFrameLoader, NS_NewFrameLoader) MAKE_CTOR(CreateNodeInfoManager, nsINodeInfoManager, NS_NewNodeInfoManager) MAKE_CTOR(CreateComputedDOMStyle, nsIComputedDOMStyle, NS_NewComputedDOMStyle) #ifdef MOZ_XUL @@ -742,6 +745,11 @@ static const nsModuleComponentInfo gComponents[] = { NS_CONTENTPOLICY_CONTRACTID, CreateContentPolicy }, + { "Frame Loader", + NS_FRAMELOADER_CID, + NS_FRAMELOADER_CONTRACTID, + CreateFrameLoader }, + { "NodeInfoManager", NS_NODEINFOMANAGER_CID, NS_NODEINFOMANAGER_CONTRACTID, diff --git a/content/events/src/nsEventStateManager.cpp b/content/events/src/nsEventStateManager.cpp index 6e67285b04e..c0c26b8dad2 100644 --- a/content/events/src/nsEventStateManager.cpp +++ b/content/events/src/nsEventStateManager.cpp @@ -1511,7 +1511,7 @@ nsEventStateManager::DoWheelScroll(nsIPresContext* aPresContext, rv = GetParentScrollingView(msEvent, aPresContext, newFrame, *getter_AddRefs(newPresContext)); - if (NS_SUCCEEDED(rv)) + if (NS_SUCCEEDED(rv) && newFrame) return DoWheelScroll(newPresContext, newFrame, msEvent, numLines, scrollPage, PR_TRUE); else @@ -1527,41 +1527,40 @@ nsEventStateManager::GetParentScrollingView(nsMouseScrollEvent *aEvent, nsIFrame* &targetOuterFrame, nsIPresContext* &presCtxOuter) { + targetOuterFrame = nsnull; + if (!aEvent) return NS_ERROR_FAILURE; if (!aPresContext) return NS_ERROR_FAILURE; - - nsCOMPtr shell; - aPresContext->GetContainer(getter_AddRefs(shell)); - if (!shell) return NS_ERROR_FAILURE; - - nsCOMPtr treeItem = do_QueryInterface(shell); - if (!treeItem) return NS_ERROR_FAILURE; - /* get our docshell's parent */ - nsCOMPtr parent; - treeItem->GetParent(getter_AddRefs(parent)); - if (!parent) return NS_ERROR_FAILURE; - - nsCOMPtr pDocShell = do_QueryInterface(parent); - if (!pDocShell) return NS_ERROR_FAILURE; + nsCOMPtr doc; - nsCOMPtr pPresShell; - pDocShell->GetPresShell(getter_AddRefs(pPresShell)); - if (!pPresShell) return NS_ERROR_FAILURE; + { + nsCOMPtr presShell; + aPresContext->GetShell(getter_AddRefs(presShell)); + NS_ASSERTION(presShell, "No presshell in prescontext!"); + + presShell->GetDocument(getter_AddRefs(doc)); + } + + NS_ASSERTION(doc, "No document in prescontext!"); nsCOMPtr parentDoc; - pPresShell->GetDocument(getter_AddRefs(parentDoc)); + doc->GetParentDocument(getter_AddRefs(parentDoc)); - nsCOMPtr rootContent; - parentDoc->GetRootContent(getter_AddRefs(rootContent)); + if (!parentDoc) { + return NS_OK; + } - nsCOMPtr ourDS = do_QueryInterface(shell); + nsCOMPtr pPresShell; + parentDoc->GetShellAt(0, getter_AddRefs(pPresShell)); + NS_ENSURE_TRUE(pPresShell, NS_ERROR_FAILURE); - /* now find the content node in our parent docshell's document that corresponds - to our docshell */ + /* now find the content node in our parent docshell's document that + corresponds to our docshell */ nsCOMPtr frameContent; - pPresShell->FindContentForShell(ourDS, getter_AddRefs(frameContent)); - if (!frameContent) return NS_ERROR_FAILURE; + + parentDoc->FindContentForSubDocument(doc, getter_AddRefs(frameContent)); + NS_ENSURE_TRUE(frameContent, NS_ERROR_FAILURE); /* get this content node's frame, and use it as the new event target, @@ -1569,6 +1568,7 @@ nsEventStateManager::GetParentScrollingView(nsMouseScrollEvent *aEvent, Note that we don't actually need to translate the event coordinates because they are not used by DoWheelScroll(). */ + nsIFrame* frameFrame = nsnull; pPresShell->GetPrimaryFrameFor(frameContent, &frameFrame); if (!frameFrame) return NS_ERROR_FAILURE; @@ -2745,7 +2745,7 @@ nsEventStateManager::ShiftFocusInternal(PRBool aForward, nsIContent* aStart) nsCOMPtr pcContainer; mPresContext->GetContainer(getter_AddRefs(pcContainer)); NS_ASSERTION(pcContainer, "no container for presContext"); - + nsCOMPtr docShell(do_QueryInterface(pcContainer)); PRBool docHasFocus = PR_FALSE; @@ -2838,19 +2838,32 @@ nsEventStateManager::ShiftFocusInternal(PRBool aForward, nsIContent* aStart) // Check to see if the next focused element has a subshell. // This is the case for an IFRAME or FRAME element. If it // does, we send focus into the subshell. - nsCOMPtr shellObject; - presShell->GetSubShellFor(nextFocus, getter_AddRefs(shellObject)); - if (shellObject) { - nsCOMPtr subShell = do_QueryInterface(shellObject); - if (subShell) { - SetContentState(nsnull, NS_EVENT_STATE_FOCUS); - nsIFrame* nextFocusFrame = nsnull; - presShell->GetPrimaryFrameFor(nextFocus, &nextFocusFrame); - presShell->ScrollFrameIntoView(nextFocusFrame, NS_PRESSHELL_SCROLL_ANYWHERE, - NS_PRESSHELL_SCROLL_ANYWHERE); - TabIntoDocument(subShell, aForward); + nsCOMPtr sub_shell; + + nsCOMPtr doc, sub_doc; + nextFocus->GetDocument(*getter_AddRefs(doc)); + + if (doc) { + doc->GetSubDocumentFor(nextFocus, getter_AddRefs(sub_doc)); + + if (sub_doc) { + nsCOMPtr container; + sub_doc->GetContainer(getter_AddRefs(container)); + + sub_shell = do_QueryInterface(container); } + } + + if (sub_shell) { + SetContentState(nsnull, NS_EVENT_STATE_FOCUS); + + nsIFrame* nextFocusFrame = nsnull; + presShell->GetPrimaryFrameFor(nextFocus, &nextFocusFrame); + presShell->ScrollFrameIntoView(nextFocusFrame, + NS_PRESSHELL_SCROLL_ANYWHERE, + NS_PRESSHELL_SCROLL_ANYWHERE); + TabIntoDocument(sub_shell, aForward); } else { // there is no subshell, so just focus nextFocus #ifdef DEBUG_DOCSHELL_FOCUS @@ -2927,23 +2940,28 @@ nsEventStateManager::ShiftFocusInternal(PRBool aForward, nsIContent* aStart) if (parentDS) { nsCOMPtr parentShell; parentDS->GetPresShell(getter_AddRefs(parentShell)); - - nsCOMPtr shellContent; - parentShell->FindContentForShell(docShell, getter_AddRefs(shellContent)); - + + nsCOMPtr docContent; + nsCOMPtr parent_doc; + + parentShell->GetDocument(getter_AddRefs(parent_doc)); + + parent_doc->FindContentForSubDocument(mDocument, + getter_AddRefs(docContent)); + nsCOMPtr parentPC; parentShell->GetPresContext(getter_AddRefs(parentPC)); - + nsCOMPtr parentESM; parentPC->GetEventStateManager(getter_AddRefs(parentESM)); - + SetContentState(nsnull, NS_EVENT_STATE_FOCUS); #ifdef DEBUG_DOCSHELL_FOCUS printf("popping out focus to parent docshell\n"); #endif parentESM->MoveCaretToFocus(); - parentESM->ShiftFocus(aForward, shellContent); + parentESM->ShiftFocus(aForward, docContent); } } else { PRBool tookFocus = PR_FALSE; @@ -4619,6 +4637,14 @@ PRBool nsEventStateManager::IsIFrameDoc(nsIDocShell* aDocShell) { NS_ASSERTION(aDocShell, "docshell is null"); + + nsCOMPtr presShell; + aDocShell->GetPresShell(getter_AddRefs(presShell)); + + nsCOMPtr doc; + presShell->GetDocument(getter_AddRefs(doc)); + NS_ASSERTION(doc, "No document in presshell!"); + nsCOMPtr treeItem = do_QueryInterface(aDocShell); nsCOMPtr parentItem; treeItem->GetParent(getter_AddRefs(parentItem)); @@ -4626,12 +4652,17 @@ nsEventStateManager::IsIFrameDoc(nsIDocShell* aDocShell) return PR_FALSE; nsCOMPtr parentDS = do_QueryInterface(parentItem); - nsCOMPtr parentShell; - parentDS->GetPresShell(getter_AddRefs(parentShell)); - NS_ASSERTION(parentShell, "presshell is null"); - + nsCOMPtr parentPresShell; + parentDS->GetPresShell(getter_AddRefs(parentPresShell)); + NS_ASSERTION(parentPresShell, "presshell is null"); + + nsCOMPtr parentDoc; + parentPresShell->GetDocument(getter_AddRefs(parentDoc)); + nsCOMPtr docContent; - parentShell->FindContentForShell(aDocShell, getter_AddRefs(docContent)); + + parentDoc->FindContentForSubDocument(doc, getter_AddRefs(docContent)); + if (!docContent) return PR_FALSE; diff --git a/content/html/content/src/makefile.win b/content/html/content/src/makefile.win index 48fe2267239..5d4fe888565 100644 --- a/content/html/content/src/makefile.win +++ b/content/html/content/src/makefile.win @@ -32,10 +32,10 @@ REQUIRES = xpcom \ webshell \ htmlparser \ necko \ - uriloader \ view \ pref \ docshell \ + uriloader \ xpconnect \ caps \ editor \ diff --git a/content/html/content/src/nsGenericHTMLElement.cpp b/content/html/content/src/nsGenericHTMLElement.cpp index f8fef88e76a..b763e499ad3 100644 --- a/content/html/content/src/nsGenericHTMLElement.cpp +++ b/content/html/content/src/nsGenericHTMLElement.cpp @@ -1237,22 +1237,19 @@ PRBool nsGenericHTMLElement::InNavQuirksMode(nsIDocument* aDoc) { PRBool status = PR_FALSE; - if (aDoc) { - nsCompatibility mode; - // multiple shells on the same doc are out of luck - nsCOMPtr shell; - aDoc->GetShellAt(0, getter_AddRefs(shell)); - if (shell) { - nsCOMPtr presContext; - shell->GetPresContext(getter_AddRefs(presContext)); - if (presContext) { - presContext->GetCompatibilityMode(&mode); - if (eCompatibility_NavQuirks == mode) { - status = PR_TRUE; - } - } + + nsCOMPtr doc(do_QueryInterface(aDoc)); + + if (doc) { + nsDTDMode mode; + + doc->GetDTDMode(mode); + + if (mode == eDTDMode_quirks) { + status = PR_TRUE; } } + return status; } @@ -2314,12 +2311,12 @@ nsGenericHTMLElement::GetBaseURL(const nsHTMLValue& aBaseHref, baseHref.Trim(" \t\n\r"); nsIURI* url = nsnull; - { - result = NS_NewURI(&url, baseHref, nsnull, docBaseURL); - } + result = NS_NewURI(&url, baseHref, nsnull, docBaseURL); + NS_IF_RELEASE(docBaseURL); *aBaseURL = url; } + return result; } @@ -3704,17 +3701,20 @@ nsGenericHTMLElement::MapBackgroundAttributesInto(const nsIHTMLMappedAttributes* getter_AddRefs(docURL)); rv = NS_MakeAbsoluteURI(absURLSpec, spec, docURL); if (NS_SUCCEEDED(rv)) - aData->mColorData->mBackImage.SetStringValue(absURLSpec, eCSSUnit_URL); + aData->mColorData->mBackImage.SetStringValue(absURLSpec, + eCSSUnit_URL); } } } } else if (aData->mPresContext) { - // in NavQuirks mode, allow the empty string to set the background to empty + // in NavQuirks mode, allow the empty string to set the + // background to empty nsCompatibility mode; aData->mPresContext->GetCompatibilityMode(&mode); if (eCompatibility_NavQuirks == mode && eHTMLUnit_Empty == value.GetUnit()) - aData->mColorData->mBackImage.SetStringValue(NS_LITERAL_STRING(""), eCSSUnit_URL); + aData->mColorData->mBackImage.SetStringValue(NS_LITERAL_STRING(""), + eCSSUnit_URL); } } } @@ -4554,32 +4554,6 @@ nsGenericHTMLElement::SetElementFocus(PRBool aDoFocus) return RemoveFocus(presContext); } -nsresult -nsGenericHTMLElement::HandleFrameOnloadEvent(nsIDOMEvent* aEvent) -{ - NS_ENSURE_TRUE(aEvent, NS_OK); - - nsAutoString type; - aEvent->GetType(type); - - if (!type.EqualsIgnoreCase("load")) { - return NS_OK; - } - - nsCOMPtr ctx; - - GetPresContext(this, getter_AddRefs(ctx)); - NS_ENSURE_TRUE(ctx, NS_OK); - - nsEventStatus status = nsEventStatus_eIgnore; - nsEvent event; - - event.eventStructType = NS_EVENT; - event.message = NS_PAGE_LOAD; - - return HandleDOMEvent(ctx, &event, nsnull, NS_EVENT_FLAG_INIT, &status); -} - // static nsresult nsGenericHTMLElement::SetProtocolInHrefString(const nsAString &aHref, diff --git a/content/html/content/src/nsGenericHTMLElement.h b/content/html/content/src/nsGenericHTMLElement.h index f9bd9042635..204ebf84274 100644 --- a/content/html/content/src/nsGenericHTMLElement.h +++ b/content/html/content/src/nsGenericHTMLElement.h @@ -465,8 +465,6 @@ public: protected: nsresult SetElementFocus(PRBool aDoFocus); - nsresult HandleFrameOnloadEvent(nsIDOMEvent* aEvent); - PRBool IsEventName(nsIAtom* aName); }; diff --git a/content/html/content/src/nsHTMLFrameElement.cpp b/content/html/content/src/nsHTMLFrameElement.cpp index 53af3188dc0..f517094295c 100644 --- a/content/html/content/src/nsHTMLFrameElement.cpp +++ b/content/html/content/src/nsHTMLFrameElement.cpp @@ -37,7 +37,6 @@ * ***** END LICENSE BLOCK ***** */ #include "nsIDOMHTMLFrameElement.h" #include "nsIDOMNSHTMLFrameElement.h" -#include "nsIDOMEventListener.h" #include "nsIDOMEventReceiver.h" #include "nsIDOMWindow.h" #include "nsIScriptGlobalObject.h" @@ -49,14 +48,14 @@ #include "nsIDOMDocument.h" #include "nsIWebNavigation.h" #include "nsIChromeEventHandler.h" +#include "nsIDocShell.h" #include "nsDOMError.h" class nsHTMLFrameElement : public nsGenericHTMLLeafElement, public nsIDOMHTMLFrameElement, public nsIDOMNSHTMLFrameElement, - public nsIChromeEventHandler, - public nsIDOMEventListener + public nsIChromeEventHandler { public: nsHTMLFrameElement(); @@ -83,9 +82,6 @@ public: // nsIChromeEventHandler NS_DECL_NSICHROMEEVENTHANDLER - // nsIDOMEventListener - NS_DECL_NSIDOMEVENTLISTENER - NS_IMETHOD StringToAttribute(nsIAtom* aAttribute, const nsAString& aValue, nsHTMLValue& aResult); @@ -143,7 +139,6 @@ NS_HTML_CONTENT_INTERFACE_MAP_BEGIN(nsHTMLFrameElement, NS_INTERFACE_MAP_ENTRY(nsIDOMHTMLFrameElement) NS_INTERFACE_MAP_ENTRY(nsIDOMNSHTMLFrameElement) NS_INTERFACE_MAP_ENTRY(nsIChromeEventHandler) - NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener) NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(HTMLFrameElement) NS_HTML_CONTENT_INTERFACE_MAP_END @@ -191,33 +186,21 @@ NS_IMETHODIMP nsHTMLFrameElement::GetContentDocument(nsIDOMDocument** aContentDocument) { NS_ENSURE_ARG_POINTER(aContentDocument); - *aContentDocument = nsnull; - NS_ENSURE_TRUE(mDocument, NS_OK); + if (!mDocument) { + return NS_OK; + } - nsCOMPtr presShell; + nsCOMPtr content_document; - mDocument->GetShellAt(0, getter_AddRefs(presShell)); - NS_ENSURE_TRUE(presShell, NS_OK); + mDocument->GetSubDocumentFor(this, getter_AddRefs(content_document)); - nsCOMPtr tmp; + if (!content_document) { + return NS_OK; + } - presShell->GetSubShellFor(this, getter_AddRefs(tmp)); - NS_ENSURE_TRUE(tmp, NS_OK); - - nsCOMPtr webNav = do_QueryInterface(tmp); - NS_ENSURE_TRUE(webNav, NS_OK); - - nsCOMPtr domDoc; - - webNav->GetDocument(getter_AddRefs(domDoc)); - - *aContentDocument = domDoc; - - NS_IF_ADDREF(*aContentDocument); - - return NS_OK; + return CallQueryInterface(content_document, aContentDocument); } NS_IMETHODIMP @@ -329,8 +312,3 @@ nsHTMLFrameElement::HandleChromeEvent(nsIPresContext* aPresContext, return HandleDOMEvent(aPresContext, aEvent, aDOMEvent, aFlags,aEventStatus); } -nsresult -nsHTMLFrameElement::HandleEvent(nsIDOMEvent *aEvent) -{ - return HandleFrameOnloadEvent(aEvent); -} diff --git a/content/html/content/src/nsHTMLIFrameElement.cpp b/content/html/content/src/nsHTMLIFrameElement.cpp index 161391af067..7fb5d1daa2f 100644 --- a/content/html/content/src/nsHTMLIFrameElement.cpp +++ b/content/html/content/src/nsHTMLIFrameElement.cpp @@ -37,11 +37,10 @@ * ***** END LICENSE BLOCK ***** */ #include "nsIDOMHTMLIFrameElement.h" #include "nsIDOMNSHTMLFrameElement.h" -#include "nsIDOMEventListener.h" #include "nsIDOMEventReceiver.h" #include "nsIDOMWindow.h" #include "nsIScriptGlobalObject.h" -#include "nsIHTMLContent.h" +#include "nsIFrameLoader.h" #include "nsGenericHTMLElement.h" #include "nsHTMLAtoms.h" #include "nsIStyleContext.h" @@ -54,12 +53,14 @@ #include "nsIChromeEventHandler.h" #include "nsDOMError.h" #include "nsRuleNode.h" +#include "nsIDocShell.h" +#include "nsIInterfaceRequestorUtils.h" class nsHTMLIFrameElement : public nsGenericHTMLContainerElement, public nsIDOMHTMLIFrameElement, public nsIDOMNSHTMLFrameElement, public nsIChromeEventHandler, - public nsIDOMEventListener + public nsIFrameLoaderOwner { public: nsHTMLIFrameElement(); @@ -86,8 +87,11 @@ public: // nsIChromeEventHandler NS_DECL_NSICHROMEEVENTHANDLER - // nsIDOMEventListener - NS_DECL_NSIDOMEVENTLISTENER + // nsIFrameLoaderOwner + NS_IMETHOD GetFrameLoader(nsIFrameLoader **aFrameLoader); + + // nsIContent + NS_IMETHOD SetParent(nsIContent *aParent); NS_IMETHOD StringToAttribute(nsIAtom* aAttribute, const nsAString& aValue, @@ -101,6 +105,14 @@ public: #ifdef DEBUG NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const; #endif + +protected: + // This doesn't really ensure a frame loade in all cases, only when + // it makes sense. + nsresult EnsureFrameLoader(); + nsresult LoadSrc(); + + nsCOMPtr mFrameLoader; }; nsresult @@ -136,6 +148,9 @@ nsHTMLIFrameElement::nsHTMLIFrameElement() nsHTMLIFrameElement::~nsHTMLIFrameElement() { + if (mFrameLoader) { + mFrameLoader->Destroy(); + } } @@ -148,7 +163,7 @@ NS_HTML_CONTENT_INTERFACE_MAP_BEGIN(nsHTMLIFrameElement, NS_INTERFACE_MAP_ENTRY(nsIDOMHTMLIFrameElement) NS_INTERFACE_MAP_ENTRY(nsIDOMNSHTMLFrameElement) NS_INTERFACE_MAP_ENTRY(nsIChromeEventHandler) - NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener) + NS_INTERFACE_MAP_ENTRY(nsIFrameLoaderOwner) NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(HTMLIFrameElement) NS_HTML_CONTENT_INTERFACE_MAP_END @@ -189,71 +204,123 @@ NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, MarginHeight, marginheight) NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, MarginWidth, marginwidth) NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, Name, name) NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, Scrolling, scrolling) -NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, Src, src) NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, Width, width) +NS_IMETHODIMP +nsHTMLIFrameElement::GetSrc(nsAString& aSrc) +{ + nsGenericHTMLContainerElement::GetAttr(kNameSpaceID_None, nsHTMLAtoms::src, + aSrc); + + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLIFrameElement::SetSrc(const nsAString& aSrc) +{ + SetAttribute(NS_LITERAL_STRING("src"), aSrc); + + return LoadSrc(); +} NS_IMETHODIMP nsHTMLIFrameElement::GetContentDocument(nsIDOMDocument** aContentDocument) { NS_ENSURE_ARG_POINTER(aContentDocument); - *aContentDocument = nsnull; - NS_ENSURE_TRUE(mDocument, NS_OK); + nsresult rv = EnsureFrameLoader(); + NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr presShell; + if (!mFrameLoader) { + return NS_OK; + } - mDocument->GetShellAt(0, getter_AddRefs(presShell)); - NS_ENSURE_TRUE(presShell, NS_OK); + nsCOMPtr doc_shell; + mFrameLoader->GetDocShell(getter_AddRefs(doc_shell)); - nsCOMPtr tmp; + nsCOMPtr win(do_GetInterface(doc_shell)); - presShell->GetSubShellFor(this, getter_AddRefs(tmp)); - NS_ENSURE_TRUE(tmp, NS_OK); + if (!win) { + return NS_OK; + } - nsCOMPtr webNav = do_QueryInterface(tmp); - NS_ENSURE_TRUE(webNav, NS_OK); - - nsCOMPtr domDoc; - - webNav->GetDocument(getter_AddRefs(domDoc)); - - *aContentDocument = domDoc; - - NS_IF_ADDREF(*aContentDocument); - - return NS_OK; + return win->GetDocument(aContentDocument); } NS_IMETHODIMP nsHTMLIFrameElement::GetContentWindow(nsIDOMWindow** aContentWindow) { NS_ENSURE_ARG_POINTER(aContentWindow); - *aContentWindow = nsnull; - nsCOMPtr content_doc; - - nsresult rv = GetContentDocument(getter_AddRefs(content_doc)); + nsresult rv = EnsureFrameLoader(); NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr doc(do_QueryInterface(content_doc)); - - if (!doc) { + if (!mFrameLoader) { return NS_OK; } - nsCOMPtr globalObj; - doc->GetScriptGlobalObject(getter_AddRefs(globalObj)); + nsCOMPtr doc_shell; + mFrameLoader->GetDocShell(getter_AddRefs(doc_shell)); - nsCOMPtr window (do_QueryInterface(globalObj)); + nsCOMPtr win(do_GetInterface(doc_shell)); - *aContentWindow = window; + *aContentWindow = win; NS_IF_ADDREF(*aContentWindow); return NS_OK; } +nsresult +nsHTMLIFrameElement::EnsureFrameLoader() +{ + if (mFrameLoader || !mParent) { + return NS_OK; + } + + nsresult rv = NS_NewFrameLoader(getter_AddRefs(mFrameLoader)); + NS_ENSURE_SUCCESS(rv, rv); + + mFrameLoader->Init(this); + + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLIFrameElement::GetFrameLoader(nsIFrameLoader **aFrameLoader) +{ + *aFrameLoader = mFrameLoader; + NS_IF_ADDREF(*aFrameLoader); + + return NS_OK; +} + +nsresult +nsHTMLIFrameElement::LoadSrc() +{ + nsresult rv = EnsureFrameLoader(); + NS_ENSURE_SUCCESS(rv, rv); + + if (!mFrameLoader) { + return NS_OK; + } + + rv = mFrameLoader->LoadFrame(); + NS_ASSERTION(NS_SUCCEEDED(rv), "failed to load URL"); + + return rv; +} + + +NS_IMETHODIMP +nsHTMLIFrameElement::SetParent(nsIContent *aParent) +{ + nsresult rv = nsGenericHTMLContainerElement::SetParent(aParent); + NS_ENSURE_SUCCESS(rv, rv); + + return LoadSrc(); +} + NS_IMETHODIMP nsHTMLIFrameElement::StringToAttribute(nsIAtom* aAttribute, const nsAString& aValue, @@ -366,7 +433,7 @@ MapAttributesIntoRule(const nsIHTMLMappedAttributes* aAttributes, if (aData->mPositionData->mHeight.GetUnit() == eCSSUnit_Null) { aAttributes->GetAttribute(nsHTMLAtoms::height, value); if (value.GetUnit() == eHTMLUnit_Pixel) - aData->mPositionData->mHeight.SetFloatValue((float)value.GetPixelValue(), eCSSUnit_Pixel); + aData->mPositionData->mHeight.SetFloatValue((float)value.GetPixelValue(), eCSSUnit_Pixel); else if (value.GetUnit() == eHTMLUnit_Percent) aData->mPositionData->mHeight.SetPercentValue(value.GetPercentValue()); } @@ -377,7 +444,8 @@ MapAttributesIntoRule(const nsIHTMLMappedAttributes* aAttributes, } NS_IMETHODIMP -nsHTMLIFrameElement::GetMappedAttributeImpact(const nsIAtom* aAttribute, PRInt32 aModType, +nsHTMLIFrameElement::GetMappedAttributeImpact(const nsIAtom* aAttribute, + PRInt32 aModType, PRInt32& aHint) const { if ((aAttribute == nsHTMLAtoms::width) || @@ -419,20 +487,15 @@ nsHTMLIFrameElement::SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const //***************************************************************************** // nsHTMLIFrameElement::nsIChromeEventHandler -//***************************************************************************** +//***************************************************************************** NS_IMETHODIMP nsHTMLIFrameElement::HandleChromeEvent(nsIPresContext* aPresContext, nsEvent* aEvent, nsIDOMEvent** aDOMEvent, - PRUint32 aFlags, + PRUint32 aFlags, nsEventStatus* aEventStatus) { return HandleDOMEvent(aPresContext, aEvent, aDOMEvent, aFlags,aEventStatus); } -nsresult -nsHTMLIFrameElement::HandleEvent(nsIDOMEvent *aEvent) -{ - return HandleFrameOnloadEvent(aEvent); -} diff --git a/content/html/content/src/nsHTMLObjectElement.cpp b/content/html/content/src/nsHTMLObjectElement.cpp index 27aa9de2798..898df0ab117 100644 --- a/content/html/content/src/nsHTMLObjectElement.cpp +++ b/content/html/content/src/nsHTMLObjectElement.cpp @@ -190,30 +190,18 @@ nsHTMLObjectElement::GetContentDocument(nsIDOMDocument** aContentDocument) *aContentDocument = nsnull; - NS_ENSURE_TRUE(mDocument, NS_OK); + if (!mDocument) { + return NS_OK; + } - nsCOMPtr presShell; + nsCOMPtr sub_doc; + mDocument->GetSubDocumentFor(this, getter_AddRefs(sub_doc)); - mDocument->GetShellAt(0, getter_AddRefs(presShell)); - NS_ENSURE_TRUE(presShell, NS_OK); + if (!sub_doc) { + return NS_OK; + } - nsCOMPtr tmp; - - presShell->GetSubShellFor(this, getter_AddRefs(tmp)); - if (!tmp) return NS_OK; - - nsCOMPtr webNav = do_QueryInterface(tmp); - NS_ENSURE_TRUE(webNav, NS_OK); - - nsCOMPtr domDoc; - - webNav->GetDocument(getter_AddRefs(domDoc)); - - *aContentDocument = domDoc; - - NS_IF_ADDREF(*aContentDocument); - - return NS_OK; + return CallQueryInterface(sub_doc, aContentDocument); } NS_IMETHODIMP diff --git a/content/html/content/src/nsHTMLSharedObjectElement.cpp b/content/html/content/src/nsHTMLSharedObjectElement.cpp index 27aa9de2798..898df0ab117 100644 --- a/content/html/content/src/nsHTMLSharedObjectElement.cpp +++ b/content/html/content/src/nsHTMLSharedObjectElement.cpp @@ -190,30 +190,18 @@ nsHTMLObjectElement::GetContentDocument(nsIDOMDocument** aContentDocument) *aContentDocument = nsnull; - NS_ENSURE_TRUE(mDocument, NS_OK); + if (!mDocument) { + return NS_OK; + } - nsCOMPtr presShell; + nsCOMPtr sub_doc; + mDocument->GetSubDocumentFor(this, getter_AddRefs(sub_doc)); - mDocument->GetShellAt(0, getter_AddRefs(presShell)); - NS_ENSURE_TRUE(presShell, NS_OK); + if (!sub_doc) { + return NS_OK; + } - nsCOMPtr tmp; - - presShell->GetSubShellFor(this, getter_AddRefs(tmp)); - if (!tmp) return NS_OK; - - nsCOMPtr webNav = do_QueryInterface(tmp); - NS_ENSURE_TRUE(webNav, NS_OK); - - nsCOMPtr domDoc; - - webNav->GetDocument(getter_AddRefs(domDoc)); - - *aContentDocument = domDoc; - - NS_IF_ADDREF(*aContentDocument); - - return NS_OK; + return CallQueryInterface(sub_doc, aContentDocument); } NS_IMETHODIMP diff --git a/content/html/content/src/nsHTMLTableCellElement.cpp b/content/html/content/src/nsHTMLTableCellElement.cpp index 45c72c94261..57f03609734 100644 --- a/content/html/content/src/nsHTMLTableCellElement.cpp +++ b/content/html/content/src/nsHTMLTableCellElement.cpp @@ -308,8 +308,8 @@ static nsGenericHTMLElement::EnumTable kCellScopeTable[] = { NS_IMETHODIMP nsHTMLTableCellElement::StringToAttribute(nsIAtom* aAttribute, - const nsAString& aValue, - nsHTMLValue& aResult) + const nsAString& aValue, + nsHTMLValue& aResult) { /* ignore these attributes, stored simply as strings abbr, axis, ch, headers @@ -379,8 +379,8 @@ nsHTMLTableCellElement::StringToAttribute(nsIAtom* aAttribute, NS_IMETHODIMP nsHTMLTableCellElement::AttributeToString(nsIAtom* aAttribute, - const nsHTMLValue& aValue, - nsAString& aResult) const + const nsHTMLValue& aValue, + nsAString& aResult) const { /* ignore these attributes, stored already as strings abbr, axis, ch, headers @@ -409,7 +409,8 @@ nsHTMLTableCellElement::AttributeToString(nsIAtom* aAttribute, } static -void MapAttributesIntoRule(const nsIHTMLMappedAttributes* aAttributes, nsRuleData* aData) +void MapAttributesIntoRule(const nsIHTMLMappedAttributes* aAttributes, + nsRuleData* aData) { if (!aAttributes || !aData) return; diff --git a/content/html/document/src/nsHTMLContentSink.cpp b/content/html/document/src/nsHTMLContentSink.cpp index 930a61dc450..5fd39e818a9 100644 --- a/content/html/document/src/nsHTMLContentSink.cpp +++ b/content/html/document/src/nsHTMLContentSink.cpp @@ -1512,7 +1512,7 @@ SinkContext::CloseContainer(const nsIParserNode& aNode) // Flush any collected text content. Release the last text // node to indicate that no more should be added to it. FlushTextAndRelease(); - + SINK_TRACE_NODE(SINK_TRACE_CALLS, "SinkContext::CloseContainer", aNode, mStackPos-1, mSink); @@ -1614,7 +1614,8 @@ SinkContext::CloseContainer(const nsIParserNode& aNode) case eHTMLTag_select: { - nsCOMPtr select = do_QueryInterface(content, &result); + nsCOMPtr select = do_QueryInterface(content); + if (select) { result = select->DoneAddingChildren(); } @@ -3848,43 +3849,57 @@ HTMLContentSink::DidProcessAToken(void) PRInt32 oldMaxTokenProcessingTime = GetMaxTokenProcessingTime(); #endif - // There is both a high frequency interrupt mode and a low frequency - // interupt mode controlled by the flag NS_SINK_FLAG_DYNAMIC_LOWER_VALUE - // The high frequency mode interupts the parser frequently to provide - // UI responsiveness at the expense of page load time. The low frequency mode - // interrupts the parser and samples the system clock infrequently to provide fast - // page load time. When the user moves the mouse, clicks or types the mode switches - // to the high frequency interrupt mode. If the user stops moving the mouse or typing - // for a duration of time (mDynamicIntervalSwitchThreshold) it switches to low - // frequency interrupt mode. + // There is both a high frequency interrupt mode and a low + // frequency interupt mode controlled by the flag + // NS_SINK_FLAG_DYNAMIC_LOWER_VALUE The high frequency mode + // interupts the parser frequently to provide UI responsiveness at + // the expense of page load time. The low frequency mode + // interrupts the parser and samples the system clock infrequently + // to provide fast page load time. When the user moves the mouse, + // clicks or types the mode switches to the high frequency + // interrupt mode. If the user stops moving the mouse or typing + // for a duration of time (mDynamicIntervalSwitchThreshold) it + // switches to low frequency interrupt mode. // Get the current user event time nsCOMPtr shell; mDocument->GetShellAt(0, getter_AddRefs(shell)); - NS_ENSURE_TRUE(shell, NS_ERROR_FAILURE); + + if (!shell) { + // If there's no pres shell in the document, return early since + // we're not laying anything out here. + + return NS_OK; + } + nsCOMPtr vm; shell->GetViewManager(getter_AddRefs(vm)); NS_ENSURE_TRUE(vm, NS_ERROR_FAILURE); PRUint32 eventTime; nsresult rv = vm->GetLastUserEventTime(eventTime); NS_ENSURE_TRUE(NS_SUCCEEDED(rv), NS_ERROR_FAILURE); - if ((!(mFlags & NS_SINK_FLAG_DYNAMIC_LOWER_VALUE)) && (mLastSampledUserEventTime == eventTime)) { - // The magic value of NS_MAX_TOKENS_DEFLECTED_IN_LOW_FREQ_MODE was selected by - // empirical testing. It provides reasonable - // user response and prevents us from sampling the clock too frequently. + // The magic value of NS_MAX_TOKENS_DEFLECTED_IN_LOW_FREQ_MODE + // was selected by empirical testing. It provides reasonable + // user response and prevents us from sampling the clock too + // frequently. if (mDeflectedCount < NS_MAX_TOKENS_DEFLECTED_IN_LOW_FREQ_MODE) { mDeflectedCount++; - return NS_OK; // return early to prevent sampling the clock. Note: This prevents - // us from switching to higher frequency (better UI responsive) mode, so - // limit ourselves to doing for no more than - // NS_MAX_TOKENS_DEFLECTED_IN_LOW_FREQ_MODE tokens. + + // return early to prevent sampling the clock. Note: This + // prevents us from switching to higher frequency (better UI + // responsive) mode, so limit ourselves to doing for no more + // than NS_MAX_TOKENS_DEFLECTED_IN_LOW_FREQ_MODE tokens. + + return NS_OK; } else { - mDeflectedCount = 0; // reset count and drop through to the code which samples the clock and - // does the dynamic switch between the high frequency and low frequency - // interruption of the parser. + // reset count and drop through to the code which samples the + // clock and does the dynamic switch between the high + // frequency and low frequency interruption of the parser. + + mDeflectedCount = 0; } } @@ -3892,48 +3907,49 @@ PRInt32 oldMaxTokenProcessingTime = GetMaxTokenProcessingTime(); PRUint32 currentTime = PR_IntervalToMicroseconds(PR_IntervalNow()); - // Get the last user event time and compare it with - // the current time to determine if the lower value - // for content notification and max token processing - // should be used. But only consider using the lower - // value if the document has already been loading - // for 2 seconds. 2 seconds was chosen because it is - // greater than the default 3/4 of second that is used - // to determine when to switch between the modes and it - // gives the document a little time to create windows. - // This is important because on some systems (Windows, - // for example) when a window is created and the mouse - // is over it, a mouse move event is sent, which will kick - // us into interactive mode otherwise. It also supresses - // reaction to pressing the ENTER key in the URL bar... + // Get the last user event time and compare it with the current + // time to determine if the lower value for content notification + // and max token processing should be used. But only consider + // using the lower value if the document has already been loading + // for 2 seconds. 2 seconds was chosen because it is greater than + // the default 3/4 of second that is used to determine when to + // switch between the modes and it gives the document a little + // time to create windows. This is important because on some + // systems (Windows, for example) when a window is created and the + // mouse is over it, a mouse move event is sent, which will kick + // us into interactive mode otherwise. It also supresses reaction + // to pressing the ENTER key in the URL bar... PRUint32 delayBeforeLoweringThreshold = NS_STATIC_CAST(PRUint32, ((2 * mDynamicIntervalSwitchThreshold) + NS_DELAY_FOR_WINDOW_CREATION)); - if (((currentTime - mBeginLoadTime) > delayBeforeLoweringThreshold) && mDocument) { - if ((currentTime - eventTime) < NS_STATIC_CAST(PRUint32, mDynamicIntervalSwitchThreshold)) { - // lower the dynamic values to favor - // application responsiveness over page load - // time. - mFlags |= NS_SINK_FLAG_DYNAMIC_LOWER_VALUE; - } - else { - // raise the content notification and - // MaxTokenProcessing time to favor overall - // page load speed over responsiveness - mFlags &= ~NS_SINK_FLAG_DYNAMIC_LOWER_VALUE; + + if ((currentTime - mBeginLoadTime) > delayBeforeLoweringThreshold) { + if ((currentTime - eventTime) < + NS_STATIC_CAST(PRUint32, mDynamicIntervalSwitchThreshold)) { + // lower the dynamic values to favor application + // responsiveness over page load time. + + mFlags |= NS_SINK_FLAG_DYNAMIC_LOWER_VALUE; + } else { + // raise the content notification and MaxTokenProcessing time + // to favor overall page load speed over responsiveness + + mFlags &= ~NS_SINK_FLAG_DYNAMIC_LOWER_VALUE; } } #ifdef NS_DEBUG -PRInt32 newMaxTokenProcessingTime = GetMaxTokenProcessingTime(); + PRInt32 newMaxTokenProcessingTime = GetMaxTokenProcessingTime(); - if (newMaxTokenProcessingTime != oldMaxTokenProcessingTime) { -// printf("Changed dynamic interval : MaxTokenProcessingTime %d\n", GetMaxTokenProcessingTime()); - } + if (newMaxTokenProcessingTime != oldMaxTokenProcessingTime) { +// printf("Changed dynamic interval : MaxTokenProcessingTime %d\n", +// GetMaxTokenProcessingTime()); + } #endif - if ((currentTime - mDelayTimerStart) > NS_STATIC_CAST(PRUint32, GetMaxTokenProcessingTime())) { - return NS_ERROR_HTMLPARSER_INTERRUPTED; - } + if ((currentTime - mDelayTimerStart) > + NS_STATIC_CAST(PRUint32, GetMaxTokenProcessingTime())) { + return NS_ERROR_HTMLPARSER_INTERRUPTED; + } } return NS_OK; @@ -4180,7 +4196,7 @@ nsresult HTMLContentSink::ProcessAREATag(const nsIParserNode& aNode) { nsresult rv = NS_OK; - if (nsnull != mCurrentMap) { + if (mCurrentMap) { nsHTMLTag nodeType = nsHTMLTag(aNode.GetNodeType()); nsIHTMLContent* area; rv = CreateContentObject(aNode, nodeType, nsnull, nsnull, &area); diff --git a/content/html/document/src/nsHTMLDocument.cpp b/content/html/document/src/nsHTMLDocument.cpp index 83c5068bcc6..152ddaee9ce 100644 --- a/content/html/document/src/nsHTMLDocument.cpp +++ b/content/html/document/src/nsHTMLDocument.cpp @@ -416,28 +416,15 @@ nsHTMLDocument::Init() return NS_OK; } -NS_IMETHODIMP -nsHTMLDocument::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup) -{ - nsresult result = nsDocument::Reset(aChannel, aLoadGroup); - nsCOMPtr aURL; - - if (aChannel) { - result = aChannel->GetURI(getter_AddRefs(aURL)); - if (NS_FAILED(result)) - return result; - } - - return BaseResetToURI(aURL); -} - NS_IMETHODIMP nsHTMLDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup) { nsresult result = nsDocument::ResetToURI(aURI, aLoadGroup); + if (NS_SUCCEEDED(result)) result = BaseResetToURI(aURI); + return result; } @@ -469,7 +456,7 @@ nsHTMLDocument::BaseResetToURI(nsIURI *aURL) NS_GET_IID(nsIHTMLStyleSheet), (void**)&mAttrStyleSheet); if (NS_SUCCEEDED(result)) { - result = mAttrStyleSheet->Init(aURL,this); + result = mAttrStyleSheet->Init(aURL, this); if (NS_FAILED(result)) { NS_RELEASE(mAttrStyleSheet); } @@ -1479,7 +1466,7 @@ nsHTMLDocument::FlushPendingNotifications(PRBool aFlushReflows, } } - if ((isSafeToFlush) && (mParser)) { + if (isSafeToFlush && mParser) { nsCOMPtr sink; // XXX Ack! Parser doesn't addref sink before passing it back @@ -3777,34 +3764,33 @@ nsHTMLDocument::ResolveName(const nsAString& aName, PRBool nsHTMLDocument::GetBodyContent() { - nsCOMPtr root; + nsCOMPtr root; - GetDocumentElement(getter_AddRefs(root)); + GetRootContent(getter_AddRefs(root)); if (!root) { return PR_FALSE; } - NS_NAMED_LITERAL_STRING(bodyStr, "BODY"); - nsCOMPtr child; - root->GetFirstChild(getter_AddRefs(child)); + PRInt32 i, child_count; + root->ChildCount(child_count); - while (child) { - nsCOMPtr domElement(do_QueryInterface(child)); + for (i = 0; i < child_count; i++) { + nsCOMPtr child; - if (domElement) { - nsAutoString tagName; - domElement->GetTagName(tagName); + root->ChildAt(i, *getter_AddRefs(child)); + NS_ENSURE_TRUE(child, NS_ERROR_UNEXPECTED); - ToUpperCase(tagName); - if (bodyStr.Equals(tagName)) { - mBodyContent = child; + nsCOMPtr ni; + child->GetNodeInfo(*getter_AddRefs(ni)); - return PR_TRUE; - } + if (ni && ni->Equals(nsHTMLAtoms::body) && + (ni->NamespaceEquals(kNameSpaceID_None) || + ni->NamespaceEquals(kNameSpaceID_HTML))) { + mBodyContent = do_QueryInterface(child); + + return PR_TRUE; } - nsIDOMNode *tmpNode = child; - tmpNode->GetNextSibling(getter_AddRefs(child)); } return PR_FALSE; diff --git a/content/html/document/src/nsHTMLDocument.h b/content/html/document/src/nsHTMLDocument.h index c75aaed50cf..7df8119c165 100644 --- a/content/html/document/src/nsHTMLDocument.h +++ b/content/html/document/src/nsHTMLDocument.h @@ -85,7 +85,6 @@ public: NS_IMETHOD_(nsrefcnt) AddRef(void); NS_IMETHOD_(nsrefcnt) Release(void); - NS_IMETHOD Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup); NS_IMETHOD ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup); NS_IMETHOD CreateShell(nsIPresContext* aContext, diff --git a/content/html/style/src/nsCSSStyleSheet.cpp b/content/html/style/src/nsCSSStyleSheet.cpp index cb0e42c7224..aeb399462ca 100644 --- a/content/html/style/src/nsCSSStyleSheet.cpp +++ b/content/html/style/src/nsCSSStyleSheet.cpp @@ -2637,7 +2637,7 @@ CSSStyleSheetImpl::SetDisabled(PRBool aDisabled) PRBool oldState = mDisabled; mDisabled = aDisabled; - if ((nsnull != mDocument) && (mDisabled != oldState)) { + if (mDocument && (mDisabled != oldState)) { mDocument->SetStyleSheetDisabledState(this, mDisabled); } diff --git a/content/macbuild/content.xml b/content/macbuild/content.xml index bb5a351586e..4567798cb5a 100644 --- a/content/macbuild/content.xml +++ b/content/macbuild/content.xml @@ -2310,6 +2310,13 @@ Text Debug + + Name + nsFrameLoader.cpp + MacOS + Text + Debug + Name UnicharUtilsStatic.o @@ -3452,6 +3459,11 @@ nsContentAreaDragDrop.cpp MacOS + + Name + nsFrameLoader.cpp + MacOS + Name UnicharUtilsStatic.o @@ -5811,6 +5823,13 @@ Text Debug + + Name + nsFrameLoader.cpp + MacOS + Text + Debug + Name UnicharUtilsStaticDebug.o @@ -6953,6 +6972,11 @@ nsContentAreaDragDrop.cpp MacOS + + Name + nsFrameLoader.cpp + MacOS + Name UnicharUtilsStaticDebug.o @@ -7286,6 +7310,12 @@ nsContentAreaDragDrop.cpp MacOS + + content.shlb + Name + nsFrameLoader.cpp + MacOS + content.shlb Name diff --git a/content/xul/document/src/nsXULDocument.cpp b/content/xul/document/src/nsXULDocument.cpp index 3a2dc119bde..279006a6461 100644 --- a/content/xul/document/src/nsXULDocument.cpp +++ b/content/xul/document/src/nsXULDocument.cpp @@ -445,6 +445,8 @@ nsXULDocument::nsXULDocument(void) #ifdef IBMBIDI mBidiEnabled = PR_FALSE; #endif // IBMBIDI + + mSubDocuments = nsnull; } nsIFastLoadService* nsXULDocument::gFastLoadService = nsnull; @@ -472,14 +474,11 @@ nsXULDocument::~nsXULDocument() observer->DocumentWillBeDestroyed(this); } - // mParentDocument is never refcounted - // Delete references to sub-documents - { - i = mSubDocuments.Count(); - while (--i >= 0) { - nsIDocument* subdoc = (nsIDocument*) mSubDocuments.ElementAt(i); - NS_RELEASE(subdoc); - } + // Delete references to sub-documents and kill the subdocument map, + // if any. It holds strong references + if (mSubDocuments) { + PL_DHashTableDestroy(mSubDocuments); + mSubDocuments = nsnull; } // Delete references to style sheets but only if we aren't a popup document. @@ -526,7 +525,8 @@ nsXULDocument::~nsXULDocument() NS_IF_RELEASE(gXMLElementFactory); if (gNameSpaceManager) { - nsServiceManager::ReleaseService(kNameSpaceManagerCID, gNameSpaceManager); + nsServiceManager::ReleaseService(kNameSpaceManagerCID, + gNameSpaceManager); gNameSpaceManager = nsnull; } @@ -1122,27 +1122,154 @@ nsXULDocument::SetParentDocument(nsIDocument* aParent) return NS_OK; } -NS_IMETHODIMP -nsXULDocument::AddSubDocument(nsIDocument* aSubDoc) +PR_STATIC_CALLBACK(void) +SubDocClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry) { - NS_ADDREF(aSubDoc); - mSubDocuments.AppendElement(aSubDoc); - return NS_OK; + SubDocMapEntry *e = NS_STATIC_CAST(SubDocMapEntry *, entry); + + NS_RELEASE(e->mKey); + NS_IF_RELEASE(e->mSubDocument); +} + +PR_STATIC_CALLBACK(void) +SubDocInitEntry(PLDHashTable *table, PLDHashEntryHdr *entry, const void *key) +{ + SubDocMapEntry *e = + NS_CONST_CAST(SubDocMapEntry *, + NS_STATIC_CAST(const SubDocMapEntry *, entry)); + + e->mKey = NS_CONST_CAST(nsIContent *, + NS_STATIC_CAST(const nsIContent *, key)); + NS_ADDREF(e->mKey); + + e->mSubDocument = nsnull; } NS_IMETHODIMP -nsXULDocument::GetNumberOfSubDocuments(PRInt32 *aCount) +nsXULDocument::SetSubDocumentFor(nsIContent *aContent, nsIDocument* aSubDoc) { - *aCount = mSubDocuments.Count(); - return NS_OK; + NS_ENSURE_TRUE(aContent, NS_ERROR_UNEXPECTED); + + if (!aSubDoc) { + // aSubDoc is nsnull, remove the mapping + + if (mSubDocuments) { + SubDocMapEntry *entry = + NS_STATIC_CAST(SubDocMapEntry*, + PL_DHashTableOperate(mSubDocuments, aContent, + PL_DHASH_LOOKUP)); + + if (PL_DHASH_ENTRY_IS_LIVE(entry)) { + entry->mSubDocument->SetParentDocument(nsnull); + + PL_DHashTableRawRemove(mSubDocuments, entry); + } + } + } else { + if (!mSubDocuments) { + // Create a new hashtable + + static PLDHashTableOps hash_table_ops = + { + PL_DHashAllocTable, + PL_DHashFreeTable, + PL_DHashGetKeyStub, + PL_DHashVoidPtrKeyStub, + PL_DHashMatchEntryStub, + PL_DHashMoveEntryStub, + SubDocClearEntry, + PL_DHashFinalizeStub, + SubDocInitEntry + }; + + mSubDocuments = PL_NewDHashTable(&hash_table_ops, nsnull, + sizeof(SubDocMapEntry), 16); + if (!mSubDocuments) { + return NS_ERROR_OUT_OF_MEMORY; + } + } + + // Add a mapping to the hash table + SubDocMapEntry *entry = + NS_STATIC_CAST(SubDocMapEntry*, + PL_DHashTableOperate(mSubDocuments, aContent, + PL_DHASH_ADD)); + + if (!entry) { + return NS_ERROR_OUT_OF_MEMORY; + } + + if (entry->mSubDocument) { + entry->mSubDocument->SetParentDocument(nsnull); + + // Release the old sub document + NS_RELEASE(entry->mSubDocument); + } + + entry->mSubDocument = aSubDoc; + NS_ADDREF(entry->mSubDocument); + + aSubDoc->SetParentDocument(this); + } + + return NS_OK; } NS_IMETHODIMP -nsXULDocument::GetSubDocumentAt(PRInt32 aIndex, nsIDocument** aSubDoc) +nsXULDocument::GetSubDocumentFor(nsIContent *aContent, nsIDocument** aSubDoc) { - *aSubDoc = (nsIDocument*) mSubDocuments.SafeElementAt(aIndex); - NS_IF_ADDREF(*aSubDoc); + *aSubDoc = nsnull; + + if (mSubDocuments) { + SubDocMapEntry *entry = + NS_STATIC_CAST(SubDocMapEntry*, + PL_DHashTableOperate(mSubDocuments, aContent, + PL_DHASH_LOOKUP)); + + if (PL_DHASH_ENTRY_IS_BUSY(entry)) { + *aSubDoc = entry->mSubDocument; + NS_ADDREF(*aSubDoc); + } + } + + return NS_OK; +} + +PR_STATIC_CALLBACK(PLDHashOperator) +FindContentEnumerator(PLDHashTable *table, PLDHashEntryHdr *hdr, + PRUint32 number, void *arg) +{ + SubDocMapEntry *entry = NS_STATIC_CAST(SubDocMapEntry*, hdr); + FindContentData *data = NS_STATIC_CAST(FindContentData*, arg); + + if (entry->mSubDocument == data->mSubDocument) { + data->mResult = NS_CONST_CAST(nsIContent *, entry->mKey); + + return PL_DHASH_STOP; + } + + return PL_DHASH_NEXT; +} + +NS_IMETHODIMP +nsXULDocument::FindContentForSubDocument(nsIDocument *aDocument, + nsIContent **aContent) +{ + NS_ENSURE_ARG_POINTER(aDocument); + + if (!mSubDocuments) { + *aContent = nsnull; + return NS_OK; + } + + FindContentData data(aDocument); + PL_DHashTableEnumerate(mSubDocuments, FindContentEnumerator, &data); + + *aContent = data.mResult; + NS_IF_ADDREF(*aContent); + + return NS_OK; } NS_IMETHODIMP @@ -2404,6 +2531,25 @@ nsXULDocument::RemoveReference(void *aKey, nsISupports **aOldReference) return NS_OK; } +NS_IMETHODIMP +nsXULDocument::SetContainer(nsISupports *aContainer) +{ + mDocumentContainer = dont_AddRef(NS_GetWeakReference(aContainer)); + + return NS_OK; +} + +NS_IMETHODIMP +nsXULDocument::GetContainer(nsISupports **aContainer) +{ + nsCOMPtr container = do_QueryReferent(mDocumentContainer); + + *aContainer = container; + NS_IF_ADDREF(*aContainer); + + return NS_OK; +} + void nsXULDocument::SetDisplaySelection(PRInt8 aToggle) { diff --git a/content/xul/document/src/nsXULDocument.h b/content/xul/document/src/nsXULDocument.h index fe3dd40f55d..b562a129e01 100644 --- a/content/xul/document/src/nsXULDocument.h +++ b/content/xul/document/src/nsXULDocument.h @@ -222,11 +222,12 @@ public: NS_IMETHOD SetParentDocument(nsIDocument* aParent); - NS_IMETHOD AddSubDocument(nsIDocument* aSubDoc); + NS_IMETHOD SetSubDocumentFor(nsIContent *aContent, nsIDocument* aSubDoc); - NS_IMETHOD GetNumberOfSubDocuments(PRInt32* aCount); + NS_IMETHOD GetSubDocumentFor(nsIContent *aContent, nsIDocument** aSubDoc); - NS_IMETHOD GetSubDocumentAt(PRInt32 aIndex, nsIDocument** aSubDoc); + NS_IMETHOD FindContentForSubDocument(nsIDocument *aDocument, + nsIContent **aContent); NS_IMETHOD GetRootContent(nsIContent** aRoot); @@ -333,6 +334,8 @@ public: NS_IMETHOD AddReference(void *aKey, nsISupports *aReference); NS_IMETHOD RemoveReference(void *aKey, nsISupports **aOldReference); + NS_IMETHOD SetContainer(nsISupports *aContainer); + NS_IMETHOD GetContainer(nsISupports **aContainer); virtual void SetDisplaySelection(PRInt8 aToggle); @@ -562,6 +565,7 @@ protected: nsCOMPtr mDocumentURL; // [OWNER] ??? compare with loader nsCOMPtr mDocumentBaseURL; nsWeakPtr mDocumentLoadGroup; // [WEAK] leads to loader + nsWeakPtr mDocumentContainer; // [WEAK] leads to container nsCOMPtr mDocumentPrincipal; // [OWNER] nsCOMPtr mRootContent; // [OWNER] nsIDocument* mParentDocument; // [WEAK] @@ -590,7 +594,7 @@ protected: nsCOMPtr mLocalStore; nsCOMPtr mLineBreaker; // [OWNER] nsCOMPtr mWordBreaker; // [OWNER] - nsVoidArray mSubDocuments; // [OWNER] of subelements + PLDHashTable *mSubDocuments; // [OWNER] of subelements PRPackedBool mIsPopup; PRPackedBool mIsFastLoad; PRPackedBool mApplyingPersistedAttrs; diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index afe2d996307..44cb077a920 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -1166,6 +1166,14 @@ nsDocShell::SetChromeEventHandler(nsIChromeEventHandler * aChromeEventHandler) { // Weak reference. Don't addref. mChromeEventHandler = aChromeEventHandler; + + NS_ASSERTION(!mScriptGlobal, + "SetChromeEventHandler() called after the script global " + "object was created! This means that the script global " + "object in this docshell won't get the right chrome event " + "handler. You really don't want to see this assert, FIX " + "YOUR CODE!"); + return NS_OK; } @@ -2449,7 +2457,6 @@ nsDocShell::Stop(PRUint32 aStopFlags) if (nsIWebNavigation::STOP_CONTENT & aStopFlags) { if (mContentViewer) mContentViewer->Stop(); - } if (nsIWebNavigation::STOP_NETWORK & aStopFlags) { @@ -2658,7 +2665,6 @@ nsDocShell::InitWindow(nativeWindow parentNativeWindow, NS_IMETHODIMP nsDocShell::Create() { - NS_ENSURE_STATE(!mContentViewer); mPrefs = do_GetService(NS_PREF_CONTRACTID); //GlobalHistory is now set in SetGlobalHistory // mGlobalHistory = do_GetService(NS_GLOBALHISTORY_CONTRACTID); @@ -2843,10 +2849,17 @@ nsDocShell::GetParentWidget(nsIWidget ** parentWidget) NS_IMETHODIMP nsDocShell::SetParentWidget(nsIWidget * aParentWidget) { - NS_ENSURE_STATE(!mContentViewer); - mParentWidget = aParentWidget; + if (!mParentWidget) { + // If the parent widget is set to null we don't want to hold + // on to the current device context any more since it is + // associated with the parent widget we no longer own. We'll + // need to create a new device context if one is needed again. + + mDeviceContext = nsnull; + } + return NS_OK; } @@ -2914,12 +2927,22 @@ nsDocShell::GetVisibility(PRBool * aVisibility) nsCOMPtr parentItem; treeItem->GetParent(getter_AddRefs(parentItem)); while (parentItem) { + nsCOMPtr docShell(do_QueryInterface(treeItem)); + docShell->GetPresShell(getter_AddRefs(presShell)); + + nsCOMPtr doc; + presShell->GetDocument(getter_AddRefs(doc)); + nsCOMPtr parentDS = do_QueryInterface(parentItem); nsCOMPtr pPresShell; parentDS->GetPresShell(getter_AddRefs(pPresShell)); + + nsCOMPtr pDoc; + pPresShell->GetDocument(getter_AddRefs(pDoc)); + nsCOMPtr shellContent; nsCOMPtr shellISupports = do_QueryInterface(treeItem); - pPresShell->FindContentForShell(shellISupports, getter_AddRefs(shellContent)); + pDoc->FindContentForSubDocument(doc, getter_AddRefs(shellContent)); NS_ASSERTION(shellContent, "subshell not in the map"); nsIFrame* frame; @@ -4016,6 +4039,7 @@ nsDocShell::CreateAboutBlankContentViewer() // generate (about:blank) document to load docFactory->CreateBlankDocument(loadGroup, getter_AddRefs(blankDoc)); if (blankDoc) { + blankDoc->SetContainer(NS_STATIC_CAST(nsIDocShell *, this)); // create a content viewer for us and the new document docFactory->CreateInstanceForDocument(NS_ISUPPORTS_CAST(nsIDocShell *, this), @@ -4357,13 +4381,13 @@ nsDocShell::SetupNewViewer(nsIContentViewer * aNewViewer) nsCOMPtr widget; NS_ENSURE_SUCCESS(GetMainWidget(getter_AddRefs(widget)), NS_ERROR_FAILURE); - if (!widget) { - NS_ERROR("GetMainWidget coughed up a null widget"); - return NS_ERROR_FAILURE; + + if (widget) { + NS_ENSURE_SUCCESS(EnsureDeviceContext(), NS_ERROR_FAILURE); } nsRect bounds(x, y, cx, cy); - NS_ENSURE_SUCCESS(EnsureDeviceContext(), NS_ERROR_FAILURE); + if (NS_FAILED(mContentViewer->Init(widget, mDeviceContext, bounds))) { mContentViewer = nsnull; NS_ERROR("ContentViewer Initialization failed"); @@ -4386,7 +4410,7 @@ nsDocShell::SetupNewViewer(nsIContentViewer * aNewViewer) focusController->SetSuppressFocus(PR_FALSE, "Win32-Only Link Traversal Issue"); - if (bgSet) { + if (bgSet && widget) { // Stuff the bgcolor from the last view manager into the new // view manager. This improves page load continuity. nsCOMPtr docviewer = diff --git a/docshell/base/nsWebShell.cpp b/docshell/base/nsWebShell.cpp index 96a696364a4..814d19bd5c2 100644 --- a/docshell/base/nsWebShell.cpp +++ b/docshell/base/nsWebShell.cpp @@ -1254,7 +1254,7 @@ NS_IMETHODIMP nsWebShell::Create() // Set the webshell as the default IContentViewerContainer for the loader... mDocLoader->SetContainer(shellAsContainer); - return nsDocShell::Create(); + return nsDocShell::Create(); } NS_IMETHODIMP nsWebShell::Destroy() diff --git a/dom/public/base/nsPIDOMWindow.h b/dom/public/base/nsPIDOMWindow.h index a2a11aab22a..6ec2fe92478 100644 --- a/dom/public/base/nsPIDOMWindow.h +++ b/dom/public/base/nsPIDOMWindow.h @@ -46,6 +46,7 @@ #include "nsIDOMLocation.h" #include "nsIDOMXULCommandDispatcher.h" #include "nsIDocument.h" +#include "nsIDOMElement.h" class nsIDocShell; class nsIDOMWindowInternal; @@ -66,7 +67,7 @@ public: NS_IMETHOD GetObjectProperty(const PRUnichar* aProperty, nsISupports** aObject) = 0; - + // This is private because activate/deactivate events are not part // of the DOM spec. NS_IMETHOD Activate() = 0; @@ -85,6 +86,12 @@ public: NS_IMETHOD ReallyCloseWindow() = 0; + // Internal getter/setter for the frame element, this version of the + // getter crosses chrome boundaries whereas the public scriptable + // one doesn't for security reasons. + NS_IMETHOD GetFrameElementInternal(nsIDOMElement** aFrameElement) = 0; + NS_IMETHOD SetFrameElementInternal(nsIDOMElement* aFrameElement) = 0; + NS_IMETHOD IsLoadingOrRunningTimeout(PRBool* aResult) = 0; }; diff --git a/dom/public/idl/base/nsIDOMWindowInternal.idl b/dom/public/idl/base/nsIDOMWindowInternal.idl index d549ea82980..3489a71b15a 100644 --- a/dom/public/idl/base/nsIDOMWindowInternal.idl +++ b/dom/public/idl/base/nsIDOMWindowInternal.idl @@ -185,4 +185,6 @@ interface nsIDOMWindowInternal : nsIDOMWindow // Ascii base64 data to binary data and vice versa... DOMString atob(in DOMString aAsciiString); DOMString btoa(in DOMString aBase64Data); + + readonly attribute nsIDOMElement frameElement; }; diff --git a/dom/src/base/nsGlobalWindow.cpp b/dom/src/base/nsGlobalWindow.cpp index 8a0dcd4f66f..85cdbd74f86 100644 --- a/dom/src/base/nsGlobalWindow.cpp +++ b/dom/src/base/nsGlobalWindow.cpp @@ -229,7 +229,8 @@ GlobalWindowImpl::GlobalWindowImpl() : mLastMouseButtonAction(LL_ZERO), mFullScreen(PR_FALSE), mOriginalPos(nsnull), mOriginalSize(nsnull), mGlobalObjectOwner(nsnull), - mDocShell(nsnull), mMutationBits(0), mChromeEventHandler(nsnull) + mDocShell(nsnull), mMutationBits(0), mChromeEventHandler(nsnull), + mFrameElement(nsnull) { NS_INIT_REFCNT(); // We could have failed the first time through trying @@ -760,6 +761,38 @@ GlobalWindowImpl::HandleDOMEvent(nsIPresContext* aPresContext, } } + if (aEvent->message == NS_PAGE_LOAD) { + nsCOMPtr content(do_QueryInterface(mFrameElement)); + + nsCOMPtr parent; + GetParentInternal(getter_AddRefs(parent)); + + nsCOMPtr treeItem(do_QueryInterface(mDocShell)); + + PRInt32 itemType = nsIDocShellTreeItem::typeChrome; + + if (treeItem) { + treeItem->GetItemType(&itemType); + } + + if (content && parent && itemType != nsIDocShellTreeItem::typeChrome) { + // If we're not in chrome, or at a chrome boundary, fire the + // onload event for the frame element. + + nsCOMPtr ctx; + mDocShell->GetPresContext(getter_AddRefs(ctx)); + NS_ENSURE_TRUE(ctx, NS_OK); + + nsEventStatus status = nsEventStatus_eIgnore; + nsEvent event; + + event.eventStructType = NS_EVENT; + event.message = NS_PAGE_LOAD; + + return content->HandleDOMEvent(ctx, &event, nsnull, NS_EVENT_FLAG_INIT, + &status); + } + } if (NS_EVENT_FLAG_INIT & aFlags) { // We're leaving the DOM event loop so if we created an event, @@ -868,10 +901,11 @@ GlobalWindowImpl::GetPrincipal(nsIPrincipal** result) NS_IMETHODIMP GlobalWindowImpl::GetDocument(nsIDOMDocument** aDocument) { - /* lazily instantiate an about:blank document if necessary, and if we have - what it takes to do so. Note that domdoc here is the same thing as - our mDocument, but we don't have to explicitly set the member variable - because the docshell has already called SetNewDocument(). */ + // lazily instantiate an about:blank document if necessary, and if + // we have what it takes to do so. Note that domdoc here is the same + // thing as our mDocument, but we don't have to explicitly set the + // member variable because the docshell has already called + // SetNewDocument(). if (!mDocument && mDocShell) nsCOMPtr domdoc(do_GetInterface(mDocShell)); @@ -2984,6 +3018,53 @@ GlobalWindowImpl::ReallyCloseWindow() return NS_OK; } +NS_IMETHODIMP +GlobalWindowImpl::GetFrameElement(nsIDOMElement** aFrameElement) +{ + *aFrameElement = nsnull; + + nsCOMPtr docShell; + GetDocShell(getter_AddRefs(docShell)); + + nsCOMPtr docShellTI(do_QueryInterface(docShell)); + + if (!docShellTI) { + return NS_OK; + } + + nsCOMPtr parent; + docShellTI->GetSameTypeParent(getter_AddRefs(parent)); + + if (!parent || parent == docShellTI) { + // We're at a chrome boundary, don't expose the chrome iframe + // element to content code. + + return NS_OK; + } + + *aFrameElement = mFrameElement; + NS_IF_ADDREF(*aFrameElement); + + return NS_OK; +} + +NS_IMETHODIMP +GlobalWindowImpl::GetFrameElementInternal(nsIDOMElement** aFrameElement) +{ + *aFrameElement = mFrameElement; + NS_IF_ADDREF(*aFrameElement); + + return NS_OK; +} + +NS_IMETHODIMP +GlobalWindowImpl::SetFrameElementInternal(nsIDOMElement* aFrameElement) +{ + mFrameElement = aFrameElement; + + return NS_OK; +} + NS_IMETHODIMP GlobalWindowImpl::IsLoadingOrRunningTimeout(PRBool* aResult) { @@ -4950,6 +5031,7 @@ nsGlobalChromeWindow::GetWindowState(PRUint16* aWindowState) break; case nsSizeMode_Normal: *aWindowState = nsIDOMChromeWindow::STATE_NORMAL; + break; default: NS_WARNING("Illegal window state for this chrome window"); break; diff --git a/dom/src/base/nsGlobalWindow.h b/dom/src/base/nsGlobalWindow.h index 31ac7fb4c49..d9ec2f96510 100644 --- a/dom/src/base/nsGlobalWindow.h +++ b/dom/src/base/nsGlobalWindow.h @@ -189,6 +189,9 @@ public: NS_IMETHOD ReallyCloseWindow(); NS_IMETHOD IsLoadingOrRunningTimeout(PRBool* aResult); + NS_IMETHOD GetFrameElementInternal(nsIDOMElement** aFrameElement); + NS_IMETHOD SetFrameElementInternal(nsIDOMElement* aFrameElement); + // nsIDOMViewCSS NS_DECL_NSIDOMVIEWCSS @@ -303,6 +306,8 @@ protected: nsCOMPtr mPkcs11; nsCOMPtr mDocumentPrincipal; + nsIDOMElement* mFrameElement; // WEAK + friend class nsDOMScriptableHelper; static nsIXPConnect *sXPConnect; }; diff --git a/dom/src/events/nsJSEventListener.cpp b/dom/src/events/nsJSEventListener.cpp index 7ccbf6f760a..28f1c42c4a5 100644 --- a/dom/src/events/nsJSEventListener.cpp +++ b/dom/src/events/nsJSEventListener.cpp @@ -151,9 +151,11 @@ nsresult nsJSEventListener::HandleEvent(nsIDOMEvent* aEvent) nsEvent* event; priv->GetInternalNSEvent(&event); if (event->message == NS_SCRIPT_ERROR) { - nsScriptErrorEvent *scriptEvent = NS_STATIC_CAST(nsScriptErrorEvent*, event); + nsScriptErrorEvent *scriptEvent = + NS_STATIC_CAST(nsScriptErrorEvent*, event); + argv = ::JS_PushArguments(cx, &stackPtr, "WWi", scriptEvent->errorMsg, - scriptEvent->fileName, scriptEvent->lineNr); + scriptEvent->fileName, scriptEvent->lineNr); NS_ENSURE_TRUE(argv, NS_ERROR_OUT_OF_MEMORY); argc = 3; handledScriptError = PR_TRUE; diff --git a/editor/libeditor/base/nsEditor.cpp b/editor/libeditor/base/nsEditor.cpp index 4f664740587..b539914aef4 100644 --- a/editor/libeditor/base/nsEditor.cpp +++ b/editor/libeditor/base/nsEditor.cpp @@ -261,6 +261,8 @@ nsEditor::~nsEditor() IMETextTxn::ClassShutdown(); PR_AtomicDecrement(&gInstanceCount); + + NS_IF_RELEASE(mViewManager); } @@ -304,7 +306,6 @@ nsEditor::Init(nsIDOMDocument *aDoc, nsIPresShell* aPresShell, nsIContent *aRoot ps->GetViewManager(&mViewManager); if (!mViewManager) {return NS_ERROR_NULL_POINTER;} - mViewManager->Release(); //we want a weak link mUpdateCount=0; InsertTextTxn::ClassInit(); diff --git a/extensions/inspector/base/src/inLayoutUtils.cpp b/extensions/inspector/base/src/inLayoutUtils.cpp index 12a7a733330..b3de7a49420 100644 --- a/extensions/inspector/base/src/inLayoutUtils.cpp +++ b/extensions/inspector/base/src/inLayoutUtils.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: NPL 1.1/GPL 2.0/LGPL 2.1 * @@ -253,22 +253,12 @@ inLayoutUtils::GetSubDocumentFor(nsIDOMNode* aNode) nsCOMPtr doc; content->GetDocument(*getter_AddRefs(doc)); if (doc) { - nsCOMPtr shell; - doc->GetShellAt(0, getter_AddRefs(shell)); - if (shell) { - nsCOMPtr supports; - shell->GetSubShellFor(content, getter_AddRefs(supports)); - nsCOMPtr docShell = do_QueryInterface(supports); - if (docShell) { - nsCOMPtr contentViewer; - docShell->GetContentViewer(getter_AddRefs(contentViewer)); - if (contentViewer) { - nsCOMPtr domdoc; - contentViewer->GetDOMDocument(getter_AddRefs(domdoc)); - return domdoc; - } - } - } + nsCOMPtr sub_doc; + doc->GetSubDocumentFor(content, getter_AddRefs(sub_doc)); + + nsCOMPtr domdoc(do_QueryInterface(sub_doc)); + + return domdoc; } } @@ -279,6 +269,7 @@ nsIDOMNode* inLayoutUtils::GetContainerFor(nsIDOMDocument* aDoc) { nsCOMPtr container; + nsCOMPtr doc(do_QueryInterface(aDoc)); // get the doc shell for this document and look for the parent doc shell nsCOMPtr win = inLayoutUtils::GetWindowFor(aDoc); @@ -297,9 +288,17 @@ inLayoutUtils::GetContainerFor(nsIDOMDocument* aDoc) nsCOMPtr presShell; parentDocShell->GetPresShell(getter_AddRefs(presShell)); - nsCOMPtr content; - presShell->FindContentForShell(docShell, getter_AddRefs(content)); - nsCOMPtr node = do_QueryInterface(content); + nsCOMPtr parent_doc; + presShell->GetDocument(getter_AddRefs(parent_doc)); + + nsCOMPtr node; + + if (parent_doc) { + nsCOMPtr content; + parent_doc->FindContentForSubDocument(doc, getter_AddRefs(content)); + + node = do_QueryInterface(content); + } return node; } diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index 52364c8d931..73050b89b52 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -93,6 +93,7 @@ #include "nsIDocShellTreeNode.h" #include "nsIDocShellTreeOwner.h" #include "nsIDocShell.h" +#include "nsIBaseWindow.h" #include "nsIFrameDebug.h" #include "nsILayoutHistoryState.h" #include "nsLayoutAtoms.h" @@ -146,7 +147,7 @@ static NS_DEFINE_IID(kPrinterEnumeratorCID, NS_PRINTER_ENUMERATOR_CID); // Print Preview #include "nsIPrintPreviewContext.h" #include "imgIContainer.h" // image animation mode constants -#include "nsIScrollableView.h" +#include "nsIScrollableView.h" #include "nsIWebBrowserPrint.h" // needed for PrintPreview Navigation constants // Print Progress @@ -170,7 +171,7 @@ static NS_DEFINE_IID(kPrinterEnumeratorCID, NS_PRINTER_ENUMERATOR_CID); #include "nsIWebShell.h" //focus -#include "nsIDOMEventReceiver.h" +#include "nsIDOMEventReceiver.h" #include "nsIDOMFocusListener.h" #include "nsISelectionController.h" @@ -199,7 +200,7 @@ static NS_DEFINE_CID(kStyleSetCID, NS_STYLESET_CID); #ifdef DEBUG_PRINTING // XXX NOTE: I am including a header from the layout directory // merely to set up a file pointer for debug logging. This is -// fragile and may break in the future, which means it can be +// fragile and may break in the future, which means it can be // removed if necessary #if defined(XP_PC) #include "../../../layout/html/base/src/nsSimplePageSequence.h" @@ -213,20 +214,20 @@ static const char * gPrintRangeStr[] = {"kRangeAllPages", "kRangeSpecified static PRUint32 gDumpFileNameCnt = 0; static PRUint32 gDumpLOFileNameCnt = 0; -#define PRINT_DEBUG_MSG1(_msg1) fprintf(mPrt->mDebugFD, (_msg1)); -#define PRINT_DEBUG_MSG2(_msg1, _msg2) fprintf(mPrt->mDebugFD, (_msg1), (_msg2)); -#define PRINT_DEBUG_MSG3(_msg1, _msg2, _msg3) fprintf(mPrt->mDebugFD, (_msg1), (_msg2), (_msg3)); -#define PRINT_DEBUG_MSG4(_msg1, _msg2, _msg3, _msg4) fprintf(mPrt->mDebugFD, (_msg1), (_msg2), (_msg3), (_msg4)); -#define PRINT_DEBUG_MSG5(_msg1, _msg2, _msg3, _msg4, _msg5) fprintf(mPrt->mDebugFD, (_msg1), (_msg2), (_msg3), (_msg4), (_msg5)); +#define PRINT_DEBUG_MSG1(_msg1) fprintf(mPrt->mDebugFD, (_msg1)); +#define PRINT_DEBUG_MSG2(_msg1, _msg2) fprintf(mPrt->mDebugFD, (_msg1), (_msg2)); +#define PRINT_DEBUG_MSG3(_msg1, _msg2, _msg3) fprintf(mPrt->mDebugFD, (_msg1), (_msg2), (_msg3)); +#define PRINT_DEBUG_MSG4(_msg1, _msg2, _msg3, _msg4) fprintf(mPrt->mDebugFD, (_msg1), (_msg2), (_msg3), (_msg4)); +#define PRINT_DEBUG_MSG5(_msg1, _msg2, _msg3, _msg4, _msg5) fprintf(mPrt->mDebugFD, (_msg1), (_msg2), (_msg3), (_msg4), (_msg5)); #define PRINT_DEBUG_FLUSH fflush(mPrt->mDebugFD); #else //-------------- -#define PRT_YESNO(_p) -#define PRINT_DEBUG_MSG1(_msg) -#define PRINT_DEBUG_MSG2(_msg1, _msg2) -#define PRINT_DEBUG_MSG3(_msg1, _msg2, _msg3) -#define PRINT_DEBUG_MSG4(_msg1, _msg2, _msg3, _msg4) -#define PRINT_DEBUG_MSG5(_msg1, _msg2, _msg3, _msg4, _msg5) -#define PRINT_DEBUG_FLUSH +#define PRT_YESNO(_p) +#define PRINT_DEBUG_MSG1(_msg) +#define PRINT_DEBUG_MSG2(_msg1, _msg2) +#define PRINT_DEBUG_MSG3(_msg1, _msg2, _msg3) +#define PRINT_DEBUG_MSG4(_msg1, _msg2, _msg3, _msg4) +#define PRINT_DEBUG_MSG5(_msg1, _msg2, _msg3, _msg4, _msg5) +#define PRINT_DEBUG_FLUSH #endif @@ -252,7 +253,7 @@ public: NS_DECL_ISUPPORTS // nsISelectionListerner interface - NS_DECL_NSISELECTIONLISTENER + NS_DECL_NSISELECTIONLISTENER nsDocViewerSelectionListener() : mDocViewer(NULL) @@ -261,9 +262,9 @@ public: { NS_INIT_REFCNT(); } - + virtual ~nsDocViewerSelectionListener() {} - + nsresult Init(DocumentViewerImpl *aDocViewer); protected: @@ -271,13 +272,13 @@ protected: DocumentViewerImpl* mDocViewer; PRPackedBool mGotSelectionState; PRPackedBool mSelectionWasCollapsed; - + }; /** editor Implementation of the FocusListener interface */ -class nsDocViewerFocusListener : public nsIDOMFocusListener +class nsDocViewerFocusListener : public nsIDOMFocusListener { public: /** default constructor @@ -314,12 +315,14 @@ private: class CachedPresentationObj { public: - CachedPresentationObj(nsIPresShell* aShell, nsIPresContext* aPC, nsIViewManager* aVM, nsIWidget* aW): - mPresShell(aShell), mPresContext(aPC), mViewManager(aVM), mWindow(aW) {} + CachedPresentationObj(nsIPresShell* aShell, nsIPresContext* aPC, + nsIViewManager* aVM, nsIWidget* aW): + mPresShell(aShell), mPresContext(aPC), mViewManager(aVM), mWindow(aW) + { + } - - nsCOMPtr mPresContext; nsCOMPtr mPresShell; + nsCOMPtr mPresContext; nsCOMPtr mViewManager; nsCOMPtr mWindow; }; @@ -400,8 +403,8 @@ public: // Listener Helper Methods void OnEndPrinting(); void OnStartPrinting(); - static void DoOnProgressChange(nsVoidArray& aListeners, - PRInt32 aProgess, + static void DoOnProgressChange(nsVoidArray& aListeners, + PRInt32 aProgess, PRInt32 aMaxProgress, PRBool aDoStartStop = PR_FALSE, PRInt32 aFlag = 0); @@ -418,7 +421,7 @@ public: nsCOMPtr mPrintProgress; nsCOMPtr mPrintProgressParams; PRBool mShowProgressDialog; - + nsCOMPtr mCurrentFocusWin; // cache a pointer to the currently focused window nsVoidArray* mPrintDocList; @@ -476,11 +479,11 @@ class DocumentViewerImpl : public nsIDocumentViewer, friend class nsDocViewerSelectionListener; friend class nsPagePrintTimer; friend class PrintData; - + public: DocumentViewerImpl(); DocumentViewerImpl(nsIPresContext* aPresContext); - + NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW // nsISupports interface... @@ -515,15 +518,24 @@ public: nsresult CallChildren(CallChildFunc aFunc, void* aClosure); // Printing Methods - PRBool PrintPage(nsIPresContext* aPresContext,nsIPrintSettings* aPrintSettings,PrintObject* aPOect, PRBool& aInRange); + PRBool PrintPage(nsIPresContext* aPresContext, + nsIPrintSettings* aPrintSettings, + PrintObject* aPOect, PRBool& aInRange); PRBool DonePrintingPages(PrintObject* aPO); - + // helper method - static void GetWebShellTitleAndURL(nsIWebShell * aWebShell, PRUnichar** aTitle, PRUnichar** aURLStr); + static void GetWebShellTitleAndURL(nsIWebShell* aWebShell, + PRUnichar** aTitle, PRUnichar** aURLStr); // This enum tells indicates what the default should be for the title // if the title from the document is null - enum eDocTitleDefault {eDocTitleDefNone, eDocTitleDefBlank, eDocTitleDefDocument, eDocTitleDefURLDoc}; + enum eDocTitleDefault { + eDocTitleDefNone, + eDocTitleDefBlank, + eDocTitleDefDocument, + eDocTitleDefURLDoc + }; + static void GetDisplayTitleAndURL(PrintObject* aPO, nsIPrintSettings* aPrintSettings, const PRUnichar* aBrandName, @@ -543,12 +555,15 @@ private: nsIDeviceContext* aDeviceContext, const nsRect& aBounds, PRBool aDoCreation); - nsresult GetDocumentSelection(nsISelection **aSelection, nsIPresShell * aPresShell = nsnull); + nsresult InitPresentationStuff(PRBool aDoInitialReflow); + + nsresult GetDocumentSelection(nsISelection **aSelection, + nsIPresShell * aPresShell = nsnull); nsresult FindFrameSetWithIID(nsIContent * aParentContent, const nsIID& aIID); PRBool IsThereARangeSelection(nsIDOMWindowInternal * aDOMWin); PRBool IsParentAFrameSet(nsIWebShell * aParent); PRBool IsWebShellAFrameSet(nsIWebShell * aParent); - + PRBool IsThereAnIFrameSelected(nsIWebShell* aWebShell, nsIDOMWindowInternal * aDOMWin, PRPackedBool& aDoesContainFrameset); @@ -560,11 +575,12 @@ private: nsresult GetPopupImageNode(nsIDOMNode** aNode); //--------------------------------------------------------------------- - void BuildDocTree(nsIDocShellTreeNode * aParentNode, - nsVoidArray * aDocList, + void BuildDocTree(nsIDocShellTreeNode * aParentNode, + nsVoidArray * aDocList, PrintObject * aPO); - nsresult ReflowDocList(PrintObject * aPO, PRBool aSetPixelScale, PRBool aDoCalcShrink); - void SetClipRect(PrintObject* aPO, + nsresult ReflowDocList(PrintObject * aPO, PRBool aSetPixelScale, + PRBool aDoCalcShrink); + void SetClipRect(PrintObject* aPO, const nsRect& aClipRect, nscoord aOffsetX, nscoord aOffsetY, @@ -579,14 +595,18 @@ private: nsIContent* aContent); void MapContentToWebShells(PrintObject* aRootPO, PrintObject* aPO); nsresult MapSubDocFrameLocations(PrintObject* aPO); - PrintObject* FindPrintObjectByDOMWin(PrintObject* aParentObject, nsIDOMWindowInternal * aDOMWin); - void GetPresShellAndRootContent(nsIWebShell * aWebShell, nsIPresShell** aPresShell, nsIContent** aContent); + PrintObject* FindPrintObjectByDOMWin(PrintObject* aParentObject, + nsIDOMWindowInternal * aDOMWin); + void GetPresShellAndRootContent(nsIWebShell * aWebShell, + nsIPresShell** aPresShell, + nsIContent** aContent); void CalcNumPrintableDocsAndPages(PRInt32& aNumDocs, PRInt32& aNumPages); void DoProgressForAsIsFrames(); void DoProgressForSeparateFrames(); void DoPrintProgress(PRBool aIsForPrinting); - void SetDocAndURLIntoProgress(PrintObject* aPO, nsIPrintProgressParams* aParams); + void SetDocAndURLIntoProgress(PrintObject* aPO, + nsIPrintProgressParams* aParams); nsresult CheckForPrinters(nsIPrintOptions* aPrintOptions, nsIPrintSettings* aPrintSettings, PRUint32 aErrorCode, @@ -605,7 +625,8 @@ private: // nsresult DocumentReadyForPrinting(); //nsresult PrintSelection(nsIDeviceContextSpec * aDevSpec); - nsresult GetSelectionDocument(nsIDeviceContextSpec * aDevSpec, nsIDocument ** aNewDoc); + nsresult GetSelectionDocument(nsIDeviceContextSpec * aDevSpec, + nsIDocument ** aNewDoc); static void PR_CALLBACK HandlePLEvent(PLEvent* aEvent); static void PR_CALLBACK DestroyPLEvent(PLEvent* aEvent); @@ -615,12 +636,17 @@ private: nsIDOMWindowInternal* aCurrentFocusedDOMWin); nsresult EnablePOsForPrinting(); PrintObject* FindXMostPO(); - void FindXMostFrameSize(nsIPresContext* aPresContext, nsIRenderingContext* aRC, nsIFrame* aFrame, nscoord aX, nscoord aY, PRInt32& aMaxWidth); - void FindXMostFrameInList(nsIPresContext* aPresContext, nsIRenderingContext* aRC, nsIAtom* aList, nsIFrame* aFrame, - nscoord aX, nscoord aY, PRInt32& aMaxWidth); + void FindXMostFrameSize(nsIPresContext* aPresContext, + nsIRenderingContext* aRC, nsIFrame* aFrame, + nscoord aX, nscoord aY, PRInt32& aMaxWidth); + void FindXMostFrameInList(nsIPresContext* aPresContext, + nsIRenderingContext* aRC, nsIAtom* aList, + nsIFrame* aFrame, nscoord aX, nscoord aY, + PRInt32& aMaxWidth); PRBool PrintDocContent(PrintObject* aPO, nsresult& aStatus); - nsresult DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& aDonePrinting); + nsresult DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, + PRBool& aDonePrinting); void SetPrintAsIs(PrintObject* aPO, PRBool aAsIs = PR_TRUE); enum ePrintFlags {eSetPrintFlag = 1U, eSetHiddenFlag = 2U }; @@ -637,15 +663,18 @@ private: // Timer Methods - nsresult StartPagePrintTimer(nsIPresContext * aPresContext, + nsresult StartPagePrintTimer(nsIPresContext * aPresContext, nsIPrintSettings* aPrintSettings, PrintObject* aPO, PRUint32 aDelay); void PrepareToStartLoad(void); - + + nsresult SyncParentSubDocMap(); + // Misc - static void ShowPrintErrorDialog(nsresult printerror, PRBool aIsPrinting = PR_TRUE); + static void ShowPrintErrorDialog(nsresult printerror, + PRBool aIsPrinting = PR_TRUE); protected: // IMPORTANT: The ownership implicit in the following member @@ -653,10 +682,9 @@ protected: // for owning pointers and raw COM interface pointers for weak // (ie, non owning) references. If you add any members to this // class, please make the ownership explicit (pinkerton, scc). - + nsISupports* mContainer; // [WEAK] it owns me! nsCOMPtr mDeviceContext; // ??? can't hurt, but... - nsIView* mView; // [WEAK] cleaned up by view mgr // the following seven items are explicitly in this order // so they will be destroyed in the reverse order (pinkerton, scc) @@ -671,7 +699,7 @@ protected: nsCOMPtr mSelectionListener; nsCOMPtr mFocusListener; - + nsCOMPtr mPreviousViewer; PRBool mEnableRendering; @@ -746,7 +774,7 @@ public: NS_WARNING("unable to start the timer"); } else { mTimer->Init(this, aUseDelay?mDelay:0, NS_PRIORITY_NORMAL, NS_TYPE_ONE_SHOT); - } + } return result; } @@ -767,7 +795,7 @@ public: if (mDocViewer->DonePrintingPages(mPrintObj)) { initNewTimer = PR_FALSE; } - } + } Stop(); if (initNewTimer) { @@ -780,15 +808,15 @@ public: } } - void Init(DocumentViewerImpl* aDocViewerImpl, + void Init(DocumentViewerImpl* aDocViewerImpl, nsIPresContext* aPresContext, nsIPrintSettings* aPrintSettings, PrintObject* aPO, - PRUint32 aDelay) + PRUint32 aDelay) { NS_IF_RELEASE(mDocViewer); mDocViewer = aDocViewerImpl; - NS_ADDREF(mDocViewer); + NS_ADDREF(mDocViewer); mPresContext = aPresContext; mPrintSettings = aPrintSettings; @@ -796,11 +824,11 @@ public: mDelay = aDelay; } - nsresult Start(DocumentViewerImpl* aDocViewerImpl, + nsresult Start(DocumentViewerImpl* aDocViewerImpl, nsIPresContext* aPresContext, nsIPrintSettings* aPrintSettings, PrintObject* aPO, - PRUint32 aDelay) + PRUint32 aDelay) { Init(aDocViewerImpl, aPresContext, aPrintSettings, aPO, aDelay); return StartTimer(PR_FALSE); @@ -850,7 +878,7 @@ static nsresult NS_NewUpdateTimer(nsPagePrintTimer **aResult) PrintData::PrintData() : mPrintView(nsnull), mDebugFilePtr(nsnull), mPrintObject(nsnull), mSelectedPO(nsnull), mShowProgressDialog(PR_TRUE), mPrintDocList(nsnull), mIsIFrameSelected(PR_FALSE), - mIsParentAFrameSet(PR_FALSE), mPrintingAsIsSubDoc(PR_FALSE), mOnStartSent(PR_FALSE), + mIsParentAFrameSet(PR_FALSE), mPrintingAsIsSubDoc(PR_FALSE), mOnStartSent(PR_FALSE), mIsAborted(PR_FALSE), mPreparingForPrint(PR_FALSE), mDocWasToBeDestroyed(PR_FALSE), mShrinkToFit(PR_FALSE), mPrintFrameType(nsIPrintSettings::kFramesAsIs), mNumPrintableDocs(0), mNumDocsPrinted(0), mNumPrintablePages(0), mNumPagesPrinted(0), @@ -876,7 +904,7 @@ PrintData::PrintData() : } -PrintData::~PrintData() +PrintData::~PrintData() { // Set the cached Zoom value back into the DC @@ -912,7 +940,7 @@ PrintData::~PrintData() if (!isCancelled && !mIsAborted) { rv = mPrintDC->EndDocument(); } else { - rv = mPrintDC->AbortDocument(); + rv = mPrintDC->AbortDocument(); } if (NS_FAILED(rv)) { DocumentViewerImpl::ShowPrintErrorDialog(rv); @@ -961,8 +989,8 @@ void PrintData::OnEndPrinting() } void -PrintData::DoOnProgressChange(nsVoidArray& aListeners, - PRInt32 aProgess, +PrintData::DoOnProgressChange(nsVoidArray& aListeners, + PRInt32 aProgess, PRInt32 aMaxProgress, PRBool aDoStartStop, PRInt32 aFlag) @@ -972,7 +1000,7 @@ PrintData::DoOnProgressChange(nsVoidArray& aListeners, for (PRInt32 i=0;iOnProgressChange(nsnull, nsnull, aProgess, aMaxProgress, aProgess, aMaxProgress); + wpl->OnProgressChange(nsnull, nsnull, aProgess, aMaxProgress, aProgess, aMaxProgress); if (aDoStartStop) { wpl->OnStateChange(nsnull, nsnull, aFlag, 0); } @@ -983,10 +1011,10 @@ PrintData::DoOnProgressChange(nsVoidArray& aListeners, //--------------------------------------------------- //-- PrintObject Class Impl //--------------------------------------------------- -PrintObject::PrintObject() : +PrintObject::PrintObject() : mFrameType(eFrame), mRootView(nsnull), mContent(nsnull), - mSeqFrame(nsnull), mPageFrame(nsnull), mPageNum(-1), + mSeqFrame(nsnull), mPageFrame(nsnull), mPageNum(-1), mRect(0,0,0,0), mReflowRect(0,0,0,0), mParent(nsnull), mHasBeenPrinted(PR_FALSE), mDontPrint(PR_TRUE), mPrintAsIs(PR_FALSE), mSkippedPageEject(PR_FALSE), mSharedPresShell(PR_FALSE), mIsHidden(PR_FALSE), @@ -1006,7 +1034,7 @@ PrintObject::~PrintObject() PrintObject* po = (PrintObject*)mKids[i]; NS_ASSERTION(po, "PrintObject can't be null!"); delete po; - } + } if (mPresShell && !mSharedPresShell) { mPresShell->Destroy(); @@ -1045,16 +1073,14 @@ PRBool DocumentViewerImpl::mIsDoingPrinting = PR_FALSE; nsresult NS_NewDocumentViewer(nsIDocumentViewer** aResult) { - NS_PRECONDITION(aResult, "null OUT ptr"); - if (!aResult) { - return NS_ERROR_NULL_POINTER; - } - DocumentViewerImpl* it = new DocumentViewerImpl(); - if (nsnull == it) { - *aResult = nsnull; + *aResult = new DocumentViewerImpl(); + if (!*aResult) { return NS_ERROR_OUT_OF_MEMORY; } - return CallQueryInterface(it, aResult); + + NS_ADDREF(*aResult); + + return NS_OK; } // Note: operator new zeros our memory @@ -1068,7 +1094,8 @@ DocumentViewerImpl::DocumentViewerImpl() #endif } -void DocumentViewerImpl::PrepareToStartLoad() { +void DocumentViewerImpl::PrepareToStartLoad() +{ mEnableRendering = PR_TRUE; mStopped = PR_FALSE; mLoaded = PR_FALSE; @@ -1106,12 +1133,14 @@ NS_IMPL_ISUPPORTS6(DocumentViewerImpl, DocumentViewerImpl::~DocumentViewerImpl() { NS_ASSERTION(!mDocument, "User did not call nsIContentViewer::Close"); - if (mDocument) + if (mDocument) { Close(); + } NS_ASSERTION(!mPresShell, "User did not call nsIContentViewer::Destroy"); - if (mPresShell) + if (mPresShell) { Destroy(); + } // XXX(?) Revoke pending invalidate events @@ -1139,10 +1168,10 @@ DocumentViewerImpl::LoadStart(nsISupports *aDoc) nsresult rv; if (!mDocument) { - mDocument = do_QueryInterface(aDoc,&rv); + mDocument = do_QueryInterface(aDoc, &rv); } else if (mDocument == aDoc) { - // Reset the document viewer's state back to what it was + // Reset the document viewer's state back to what it was // when the document load started. PrepareToStartLoad(); } @@ -1150,6 +1179,42 @@ DocumentViewerImpl::LoadStart(nsISupports *aDoc) return rv; } +nsresult +DocumentViewerImpl::SyncParentSubDocMap() +{ + nsCOMPtr item(do_QueryInterface(mContainer)); + nsCOMPtr win(do_GetInterface(item)); + nsCOMPtr pwin(do_QueryInterface(win)); + nsCOMPtr content; + + if (mDocument && pwin) { + nsCOMPtr frame_element; + pwin->GetFrameElementInternal(getter_AddRefs(frame_element)); + + content = do_QueryInterface(frame_element); + } + + if (content) { + nsCOMPtr parent; + item->GetParent(getter_AddRefs(parent)); + + nsCOMPtr parent_win(do_GetInterface(parent)); + + if (parent_win) { + nsCOMPtr dom_doc; + parent_win->GetDocument(getter_AddRefs(dom_doc)); + + nsCOMPtr parent_doc(do_QueryInterface(dom_doc)); + + if (parent_doc) { + return parent_doc->SetSubDocumentFor(content, mDocument); + } + } + } + + return NS_OK; +} + NS_IMETHODIMP DocumentViewerImpl::SetContainer(nsISupports* aContainer) { @@ -1157,7 +1222,12 @@ DocumentViewerImpl::SetContainer(nsISupports* aContainer) if (mPresContext) { mPresContext->SetContainer(aContainer); } - return NS_OK; + + // We're loading a new document into the window where this document + // viewer lives, sync the parent document's frame element -> sub + // document map + + return SyncParentSubDocMap(); } NS_IMETHODIMP @@ -1179,6 +1249,100 @@ DocumentViewerImpl::Init(nsIWidget* aParentWidget, return InitInternal(aParentWidget, aDeviceContext, aBounds, PR_TRUE); } +nsresult +DocumentViewerImpl::InitPresentationStuff(PRBool aDoInitialReflow) +{ + // Create the style set... + nsCOMPtr styleSet; + nsresult rv = CreateStyleSet(mDocument, getter_AddRefs(styleSet)); + NS_ENSURE_SUCCESS(rv, rv); + + // Now make the shell for the document + rv = mDocument->CreateShell(mPresContext, mViewManager, styleSet, + getter_AddRefs(mPresShell)); + + NS_ENSURE_SUCCESS(rv, rv); + + mPresShell->BeginObservingDocument(); + + // Initialize our view manager + nsRect bounds; + mWindow->GetBounds(bounds); + + float p2t; + + mPresContext->GetPixelsToTwips(&p2t); + + nscoord width = NSIntPixelsToTwips(bounds.width, p2t); + nscoord height = NSIntPixelsToTwips(bounds.height, p2t); + + mViewManager->DisableRefresh(); + mViewManager->SetWindowDimensions(width, height); + + // Setup default view manager background color + + // This may be overridden by the docshell with the background color + // for the last document loaded into the docshell + nscolor bgcolor = NS_RGB(0, 0, 0); + mPresContext->GetDefaultBackgroundColor(&bgcolor); + mViewManager->SetDefaultBackgroundColor(bgcolor); + + if (aDoInitialReflow) { + // Initial refllow + mPresShell->InitialReflow(width, height); + + // Now trigger a refresh + if (mEnableRendering) { + mViewManager->EnableRefresh(NS_VMREFRESH_IMMEDIATE); + } + } + + // now register ourselves as a selection listener, so that we get + // called when the selection changes in the window + nsDocViewerSelectionListener *selectionListener = + new nsDocViewerSelectionListener(); + NS_ENSURE_TRUE(selectionListener, NS_ERROR_OUT_OF_MEMORY); + + selectionListener->Init(this); + + // mSelectionListener is a owning reference + mSelectionListener = selectionListener; + + nsCOMPtr selection; + rv = GetDocumentSelection(getter_AddRefs(selection)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr selPrivate(do_QueryInterface(selection)); + rv = selPrivate->AddSelectionListener(mSelectionListener); + if (NS_FAILED(rv)) + return rv; + + // focus listener + // + // now register ourselves as a focus listener, so that we get called + // when the focus changes in the window + nsDocViewerFocusListener *focusListener; + NS_NEWXPCOM(focusListener, nsDocViewerFocusListener); + NS_ENSURE_TRUE(focusListener, NS_ERROR_OUT_OF_MEMORY); + + focusListener->Init(this); + + // mFocusListener is a strong reference + mFocusListener = focusListener; + + // get the DOM event receiver + nsCOMPtr erP(do_QueryInterface(mDocument)); + NS_WARN_IF_FALSE(erP, "No event receiver in document!"); + + if (erP) { + rv = erP->AddEventListenerByIID(mFocusListener, + NS_GET_IID(nsIDOMFocusListener)); + NS_ASSERTION(NS_SUCCEEDED(rv), "failed to register focus listener"); + } + + return NS_OK; +} + //----------------------------------------------- // This method can be used to initial the "presentation" // The aDoCreation indicates whether it should create @@ -1189,16 +1353,15 @@ DocumentViewerImpl::InitInternal(nsIWidget* aParentWidget, const nsRect& aBounds, PRBool aDoCreation) { - NS_ASSERTION(aParentWidget != nsnull, "Null aParentWidget"); - #ifdef NS_PRINT_PREVIEW mParentWidget = aParentWidget; // not ref counted #endif - nsresult rv; + nsresult rv = NS_OK; NS_ENSURE_TRUE(mDocument, NS_ERROR_NULL_POINTER); mDeviceContext = dont_QueryInterface(aDeviceContext); + #ifdef NS_PRINT_PREVIEW // Clear PrintPreview Alternate Device if (mDeviceContext) { @@ -1209,16 +1372,18 @@ DocumentViewerImpl::InitInternal(nsIWidget* aParentWidget, PRBool makeCX = PR_FALSE; if (aDoCreation) { - if (!mPresContext) { + if (aParentWidget && !mPresContext) { // Create presentation context if (mIsCreatingPrintPreview) { - mPresContext = do_CreateInstance(kPrintPreviewContextCID,&rv); + mPresContext = do_CreateInstance(kPrintPreviewContextCID, &rv); } else { - mPresContext = do_CreateInstance(kGalleyContextCID,&rv); + mPresContext = do_CreateInstance(kGalleyContextCID, &rv); } - if (NS_FAILED(rv)) return rv; + if (NS_FAILED(rv)) + return rv; mPresContext->Init(aDeviceContext); + #ifdef NS_PRINT_PREVIEW makeCX = !mIsDoingPrintPreview; // needs to be true except when we are already in PP #else @@ -1227,142 +1392,52 @@ DocumentViewerImpl::InitInternal(nsIWidget* aParentWidget, } } + if (aDoCreation && mPresContext) { + // Create the ViewManager and Root View... + + // We must do this before we tell the script global object about + // this new document since doing that will cause us to re-enter + // into nsHTMLFrameInnerFrame code through reflows caused by + // FlushPendingNotifications() calls down the road... + + rv = MakeWindow(aParentWidget, aBounds); + NS_ENSURE_SUCCESS(rv, rv); + Hide(); + } + nsCOMPtr requestor(do_QueryInterface(mContainer)); if (requestor) { - nsCOMPtr linkHandler; - requestor->GetInterface(NS_GET_IID(nsILinkHandler), - getter_AddRefs(linkHandler)); - mPresContext->SetContainer(mContainer); - mPresContext->SetLinkHandler(linkHandler); + if (mPresContext) { + nsCOMPtr linkHandler; + requestor->GetInterface(NS_GET_IID(nsILinkHandler), + getter_AddRefs(linkHandler)); + mPresContext->SetContainer(mContainer); + mPresContext->SetLinkHandler(linkHandler); + } if (!mIsDoingPrintPreview) { // Set script-context-owner in the document - nsCOMPtr owner; - requestor->GetInterface(NS_GET_IID(nsIScriptGlobalObjectOwner), - getter_AddRefs(owner)); - if (owner) { - nsCOMPtr global; - owner->GetScriptGlobalObject(getter_AddRefs(global)); + nsCOMPtr global; + requestor->GetInterface(NS_GET_IID(nsIScriptGlobalObject), + getter_AddRefs(global)); - if (global) { - mDocument->SetScriptGlobalObject(global); - nsCOMPtr domdoc(do_QueryInterface(mDocument)); + if (global) { + mDocument->SetScriptGlobalObject(global); + nsCOMPtr domdoc(do_QueryInterface(mDocument)); - if (domdoc) { - global->SetNewDocument(domdoc, PR_TRUE); - } + if (domdoc) { + global->SetNewDocument(domdoc, PR_TRUE); } } } } - if (aDoCreation) { - // Create the ViewManager and Root View... - rv = MakeWindow(aParentWidget, aBounds); - Hide(); + if (aDoCreation && mPresContext) { + // The ViewManager and Root View was created above (in + // MakeWindow())... - if (NS_FAILED(rv)) return rv; - - // Create the style set... - nsIStyleSet* styleSet; - rv = CreateStyleSet(mDocument, &styleSet); - if (NS_FAILED(rv)) return rv; - - // Now make the shell for the document - rv = mDocument->CreateShell(mPresContext, mViewManager, styleSet, - getter_AddRefs(mPresShell)); - NS_RELEASE(styleSet); - if (NS_FAILED(rv)) return rv; - - mPresShell->BeginObservingDocument(); - - // Initialize our view manager - nsRect bounds; - mWindow->GetBounds(bounds); - nscoord width = bounds.width; - nscoord height = bounds.height; - float p2t; - mPresContext->GetPixelsToTwips(&p2t); - width = NSIntPixelsToTwips(width, p2t); - height = NSIntPixelsToTwips(height, p2t); - mViewManager->DisableRefresh(); - mViewManager->SetWindowDimensions(width, height); - - /* Setup default view manager background color */ - /* This may be overridden by the docshell with the background color for the - last document loaded into the docshell */ - nscolor bgcolor = NS_RGB(0, 0, 0); - mPresContext->GetDefaultBackgroundColor(&bgcolor); - mViewManager->SetDefaultBackgroundColor(bgcolor); - - if (!makeCX) { - // Make shell an observer for next time - // XXX - we observe the docuement always, see above after preshell is created - // mPresShell->BeginObservingDocument(); - - //XXX I don't think this should be done *here*; and why paint nothing - //(which turns out to cause black flashes!)??? - // Resize-reflow this time - mPresShell->InitialReflow(width, height); - - // Now trigger a refresh - if (mEnableRendering) { - mViewManager->EnableRefresh(NS_VMREFRESH_IMMEDIATE); - } - } - } else { - mPresShell->BeginObservingDocument(); - } - // now register ourselves as a selection listener, so that we get called - // when the selection changes in the window - nsDocViewerSelectionListener *selectionListener; - NS_NEWXPCOM(selectionListener, nsDocViewerSelectionListener); - if (!selectionListener) return NS_ERROR_OUT_OF_MEMORY; - selectionListener->Init(this); - - // this is the owning reference. The nsCOMPtr will take care of releasing - // our ref to the listener on destruction. - NS_ADDREF(selectionListener); - mSelectionListener = do_QueryInterface(selectionListener); - NS_RELEASE(selectionListener); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr selection; - rv = GetDocumentSelection(getter_AddRefs(selection)); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr selPrivate(do_QueryInterface(selection)); - rv = selPrivate->AddSelectionListener(mSelectionListener); - if (NS_FAILED(rv)) return rv; - - //focus listener - // now register ourselves as a focus listener, so that we get called - // when the focus changes in the window - nsDocViewerFocusListener *focusListener; - NS_NEWXPCOM(focusListener, nsDocViewerFocusListener); - if (!focusListener) return NS_ERROR_OUT_OF_MEMORY; - focusListener->Init(this); - - // this is the owning reference. The nsCOMPtr will take care of releasing - // our ref to the listener on destruction. - NS_ADDREF(focusListener); - mFocusListener = do_QueryInterface(focusListener); - NS_RELEASE(focusListener); - if (NS_FAILED(rv)) - return rv; - - if(mDocument) - { - // get the DOM event receiver - nsCOMPtr erP (do_QueryInterface(mDocument, &rv)); - if(NS_FAILED(rv)) - return rv; - if(!erP) - return NS_ERROR_FAILURE; - - rv = erP->AddEventListenerByIID(mFocusListener, NS_GET_IID(nsIDOMFocusListener)); - NS_ASSERTION(NS_SUCCEEDED(rv), "failed to register focus listener"); + rv = InitPresentationStuff(!makeCX); } return rv; @@ -1388,14 +1463,14 @@ DocumentViewerImpl::LoadComplete(nsresult aStatus) rv = mDocument->GetScriptGlobalObject(getter_AddRefs(global)); // Fail if no ScriptGlobalObject is available... - NS_ASSERTION(global, "nsIScriptGlobalObject not set for document!"); - if (!global) return NS_ERROR_NULL_POINTER; + NS_ENSURE_TRUE(global, NS_ERROR_NULL_POINTER); mLoaded = PR_TRUE; - /* We need to protect ourself against auto-destruction in case the window is closed - while processing the OnLoad event. - See bug http://bugzilla.mozilla.org/show_bug.cgi?id=78445 for more explanation. + /* We need to protect ourself against auto-destruction in case the + window is closed while processing the OnLoad event. See bug + http://bugzilla.mozilla.org/show_bug.cgi?id=78445 for more + explanation. */ NS_ADDREF_THIS(); @@ -1411,11 +1486,14 @@ DocumentViewerImpl::LoadComplete(nsresult aStatus) #ifdef MOZ_TIMELINE // if navigator.xul's load is complete, the main nav window is visible // mark that point. + if (mDocument) { //printf("DEBUG: getting uri from document (%p)\n", mDocument.get()); + nsCOMPtr uri; mDocument->GetDocumentURL(getter_AddRefs(uri)); - if (uri.get() != nsnull) { + + if (uri) { //printf("DEBUG: getting spec fro uri (%p)\n", uri.get()); nsCAutoString spec; uri->GetSpec(spec); @@ -1428,11 +1506,12 @@ DocumentViewerImpl::LoadComplete(nsresult aStatus) } else { // XXX: Should fire error event to the document... } - + // Now that the document has loaded, we can tell the presshell // to unsuppress painting. - if (mPresShell && !mStopped) + if (mPresShell && !mStopped) { mPresShell->UnsuppressPainting(); + } NS_RELEASE_THIS(); @@ -1484,11 +1563,9 @@ DocumentViewerImpl::Close() // for an object that can be switched in and out so that we don't need // to disable scripts during paint suppression. - nsresult rv; - if (mDocument) { #ifdef NS_PRINT_PREVIEW - // Turn scripting back on + // Turn scripting back on // after PrintPreview had turned it off if (mPrtPreview) { TurnScriptingOn(PR_TRUE); @@ -1499,20 +1576,28 @@ DocumentViewerImpl::Close() // in the DocViewer Init nsCOMPtr globalObject; mDocument->GetScriptGlobalObject(getter_AddRefs(globalObject)); + if (globalObject) { globalObject->SetNewDocument(nsnull, PR_TRUE); } + // out of band cleanup of webshell mDocument->SetScriptGlobalObject(nsnull); + if (mFocusListener) { // get the DOM event receiver - nsCOMPtr erP( do_QueryInterface(mDocument, &rv) ); - if(NS_SUCCEEDED(rv) && erP) - erP->RemoveEventListenerByIID(mFocusListener, NS_GET_IID(nsIDOMFocusListener)); + nsCOMPtr erP(do_QueryInterface(mDocument)); + NS_WARN_IF_FALSE(erP, "No event receiver in document!"); + + if (erP) { + erP->RemoveEventListenerByIID(mFocusListener, + NS_GET_IID(nsIDOMFocusListener)); + } } - } + } mDocument = nsnull; + return NS_OK; } @@ -1566,21 +1651,27 @@ DocumentViewerImpl::Destroy() mPreviousViewer = nsnull; } - if (mDeviceContext) + if (mDeviceContext) { mDeviceContext->FlushFontCache(); + mDeviceContext = nsnull; + } if (mPresShell) { // Break circular reference (or something) mPresShell->EndObservingDocument(); + nsCOMPtr selection; - nsresult rv = GetDocumentSelection(getter_AddRefs(selection)); + GetDocumentSelection(getter_AddRefs(selection)); + nsCOMPtr selPrivate(do_QueryInterface(selection)); - if (NS_SUCCEEDED(rv) && selPrivate && mSelectionListener) + + if (selPrivate && mSelectionListener) selPrivate->RemoveSelectionListener(mSelectionListener); + mPresShell->Destroy(); mPresShell = nsnull; } - + return NS_OK; } @@ -1615,15 +1706,17 @@ DocumentViewerImpl::SetDOMDocument(nsIDOMDocument *aDocument) // Assumptions: // // 1) this document viewer has been initialized with a call to Init(). - // 2) the stylesheets associated with the document have been added to the document. + // 2) the stylesheets associated with the document have been added + // to the document. - // XXX Right now, this method assumes that the layout of the current document - // hasn't started yet. More cleanup will probably be necessary to make this - // method work for the case when layout *has* occurred for the current document. + // XXX Right now, this method assumes that the layout of the current + // document hasn't started yet. More cleanup will probably be + // necessary to make this method work for the case when layout *has* + // occurred for the current document. // That work can happen when and if it is needed. - + nsresult rv; - if (nsnull == aDocument) + if (!aDocument) return NS_ERROR_NULL_POINTER; nsCOMPtr newDoc = do_QueryInterface(aDocument, &rv); @@ -1633,46 +1726,50 @@ DocumentViewerImpl::SetDOMDocument(nsIDOMDocument *aDocument) mDocument = newDoc; // 1) Set the script global object on the new document - nsCOMPtr requestor(do_QueryInterface(mContainer)); - if (requestor) { - nsCOMPtr owner; - requestor->GetInterface(NS_GET_IID(nsIScriptGlobalObjectOwner), - getter_AddRefs(owner)); - if (nsnull != owner) { - nsCOMPtr global; - rv = owner->GetScriptGlobalObject(getter_AddRefs(global)); - if (NS_SUCCEEDED(rv) && (nsnull != global)) { - mDocument->SetScriptGlobalObject(global); - global->SetNewDocument(aDocument, PR_TRUE); - } - } - } + nsCOMPtr global(do_GetInterface(mContainer)); - // 2) Create a new style set for the document - nsCOMPtr styleSet; - rv = CreateStyleSet(mDocument, getter_AddRefs(styleSet)); - if (NS_FAILED(rv)) return rv; + if (global) { + mDocument->SetScriptGlobalObject(global); + global->SetNewDocument(aDocument, PR_TRUE); - // 3) Replace the current pres shell with a new shell for the new document - mPresShell->EndObservingDocument(); - mPresShell->Destroy(); + rv = SyncParentSubDocMap(); + NS_ENSURE_SUCCESS(rv, rv); + } - mPresShell = nsnull; - rv = newDoc->CreateShell(mPresContext, mViewManager, styleSet, - getter_AddRefs(mPresShell)); - if (NS_FAILED(rv)) return rv; + // 2) Replace the current pres shell with a new shell for the new document - mPresShell->BeginObservingDocument(); + if (mPresShell) { + mPresShell->EndObservingDocument(); + mPresShell->Destroy(); + + mPresShell = nsnull; + } + + // And if we're already given a prescontext... + if (mPresContext) { + // 3) Create a new style set for the document + + nsCOMPtr styleSet; + rv = CreateStyleSet(mDocument, getter_AddRefs(styleSet)); + if (NS_FAILED(rv)) + return rv; + + rv = newDoc->CreateShell(mPresContext, mViewManager, styleSet, + getter_AddRefs(mPresShell)); + NS_ENSURE_SUCCESS(rv, rv); + + mPresShell->BeginObservingDocument(); + + // 4) Register the focus listener on the new document - // 4) Register the focus listener on the new document - if(mDocument) - { nsCOMPtr erP = do_QueryInterface(mDocument, &rv); - if(NS_FAILED(rv) || !erP) - return rv ? rv : NS_ERROR_FAILURE; + NS_WARN_IF_FALSE(erP, "No event receiver in document!"); - rv = erP->AddEventListenerByIID(mFocusListener, NS_GET_IID(nsIDOMFocusListener)); - NS_ASSERTION(NS_SUCCEEDED(rv), "failed to register focus listener"); + if (erP) { + rv = erP->AddEventListenerByIID(mFocusListener, + NS_GET_IID(nsIDOMFocusListener)); + NS_ASSERTION(NS_SUCCEEDED(rv), "failed to register focus listener"); + } } return rv; @@ -1689,7 +1786,7 @@ DocumentViewerImpl::SetUAStyleSheet(nsIStyleSheet* aUAStyleSheet) } return NS_OK; } - + NS_IMETHODIMP DocumentViewerImpl::GetDocument(nsIDocument*& aResult) { @@ -1697,7 +1794,7 @@ DocumentViewerImpl::GetDocument(nsIDocument*& aResult) NS_IF_ADDREF(aResult); return NS_OK; } - + NS_IMETHODIMP DocumentViewerImpl::GetPresShell(nsIPresShell*& aResult) { @@ -1705,7 +1802,7 @@ DocumentViewerImpl::GetPresShell(nsIPresShell*& aResult) NS_IF_ADDREF(aResult); return NS_OK; } - + NS_IMETHODIMP DocumentViewerImpl::GetPresContext(nsIPresContext*& aResult) { @@ -1747,7 +1844,7 @@ DocumentViewerImpl::SetPreviousViewer(nsIContentViewer* aViewer) "can't set previous viewer when there already is one"); // In a multiple chaining situation (which occurs when running a thrashing - // test like i-bench or jrgm's tests with no delay), we can build up a + // test like i-bench or jrgm's tests with no delay), we can build up a // whole chain of viewers. In order to avoid this, we always set our previous // viewer to the MOST previous viewer in the chain, and then dump the intermediate // link from the chain. This ensures that at most only 2 documents are alive @@ -1770,7 +1867,7 @@ NS_IMETHODIMP DocumentViewerImpl::SetBounds(const nsRect& aBounds) { NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE); - NS_PRECONDITION(mWindow, "null window"); + if (mWindow) { // Don't have the widget repaint. Layout will generate repaint requests // during reflow @@ -1795,7 +1892,6 @@ NS_IMETHODIMP DocumentViewerImpl::Show(void) { NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE); - NS_PRECONDITION(mWindow, "null window"); // We don't need the previous viewer anymore since we're not // displaying it. @@ -1810,17 +1906,176 @@ DocumentViewerImpl::Show(void) if (mWindow) { mWindow->Show(PR_TRUE); } + + if (mDocument && !mPresShell && !mWindow) { + nsresult rv; + + nsCOMPtr base_win(do_QueryInterface(mContainer)); + NS_ENSURE_TRUE(base_win, NS_ERROR_UNEXPECTED); + + base_win->GetParentWidget(&mParentWidget); + NS_ENSURE_TRUE(mParentWidget, NS_ERROR_UNEXPECTED); + + mDeviceContext = dont_AddRef(mParentWidget->GetDeviceContext()); + +#ifdef NS_PRINT_PREVIEW + // Clear PrintPreview Alternate Device + if (mDeviceContext) { + mDeviceContext->SetAltDevice(nsnull); + } +#endif + + // Create presentation context + if (mIsCreatingPrintPreview) { + NS_ERROR("Whoa, we should not get here!"); + + return NS_ERROR_UNEXPECTED; + } + + mPresContext = do_CreateInstance(kGalleyContextCID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + mPresContext->Init(mDeviceContext); + + nsRect tbounds; + mParentWidget->GetBounds(tbounds); + + float p2t; + mPresContext->GetPixelsToTwips(&p2t); + tbounds *= p2t; + + // Create the view manager + mViewManager = do_CreateInstance(kViewManagerCID); + NS_ENSURE_TRUE(mViewManager, NS_ERROR_NOT_AVAILABLE); + + // Initialize the view manager with an offset. This allows the + // viewmanager to manage a coordinate space offset from (0,0) + rv = mViewManager->Init(mDeviceContext); + if (NS_FAILED(rv)) + return rv; + + rv = mViewManager->SetWindowOffset(tbounds.x, tbounds.y); + if (NS_FAILED(rv)) + return rv; + + // Reset the bounds offset so the root view is set to 0,0. The + // offset is specified in nsIViewManager::Init above. + // Besides, layout will reset the root view to (0,0) during reflow, + // so changing it to 0,0 eliminates placing the root view in the + // wrong place initially. + tbounds.x = 0; + tbounds.y = 0; + + // Create a child window of the parent that is our "root + // view/window" Create a view + + nsIView *view = nsnull; + rv = CallCreateInstance(kViewCID, &view); + if (NS_FAILED(rv)) + return rv; + rv = view->Init(mViewManager, tbounds, nsnull); + if (NS_FAILED(rv)) + return rv; + + rv = view->CreateWidget(kWidgetCID, nsnull, + mParentWidget->GetNativeData(NS_NATIVE_WIDGET), + PR_TRUE, PR_FALSE); + + if (NS_FAILED(rv)) + return rv; + + // Setup hierarchical relationship in view manager + mViewManager->SetRootView(view); + + view->GetWidget(*getter_AddRefs(mWindow)); + + if (mPresContext && mContainer) { + nsCOMPtr linkHandler(do_GetInterface(mContainer)); + + if (linkHandler) { + mPresContext->SetLinkHandler(linkHandler); + } + + mPresContext->SetContainer(mContainer); + } + + if (mPresContext) { + Hide(); + + rv = InitPresentationStuff(PR_TRUE); + } + + // If we get here the document load has already started and the + // window is shown because some JS on the page caused it to be + // shown... + + mPresShell->UnsuppressPainting(); + } + return NS_OK; } NS_IMETHODIMP DocumentViewerImpl::Hide(void) { + PRBool is_in_print_preview = PR_FALSE; + + GetDoingPrintPreview(&is_in_print_preview); + + if (is_in_print_preview) { + // If we, or one of our parents, is in print preview mode it means + // we're right now returning from print preview and the layout + // frame that was created for this document is being destroyed. In + // such a case we ignore the Hide() call. + + return NS_OK; + } + NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE); NS_PRECONDITION(mWindow, "null window"); if (mWindow) { mWindow->Show(PR_FALSE); } + + if (!mPresShell || mIsDoingPrintPreview) { + return NS_OK; + } + + // Avoid leaking the old viewer. + if (mPreviousViewer) { + mPreviousViewer->Destroy(); + mPreviousViewer = nsnull; + } + + if (mDeviceContext) + mDeviceContext->FlushFontCache(); + + // Break circular reference (or something) + mPresShell->EndObservingDocument(); + nsCOMPtr selection; + + GetDocumentSelection(getter_AddRefs(selection)); + + nsCOMPtr selPrivate(do_QueryInterface(selection)); + + if (selPrivate && mSelectionListener) + selPrivate->RemoveSelectionListener(mSelectionListener); + + mPresShell->Destroy(); + + mPresShell = nsnull; + mPresContext = nsnull; + mViewManager = nsnull; + mWindow = nsnull; + mDeviceContext = nsnull; + mParentWidget = nsnull; + + nsCOMPtr base_win(do_QueryInterface(mContainer)); + + if (base_win) { + base_win->SetParentWidget(nsnull); + } + return NS_OK; } @@ -1846,7 +2101,7 @@ DocumentViewerImpl::FindFrameSetWithIID(nsIContent * aParentContent, const nsIID } /** --------------------------------------------------- - * Helper function + * Helper function */ static nsIPresShell* GetPresShellFor(nsIDocShell* aDocShell) @@ -1873,10 +2128,10 @@ GetPresShellFor(nsIDocShell* aDocShell) #include "process.h" #include "direct.h" -#define MY_FINDFIRST(a,b) FindFirstFile(a,b) -#define MY_FINDNEXT(a,b) FindNextFile(a,b) -#define ISDIR(a) (a.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) -#define MY_FINDCLOSE(a) FindClose(a) +#define MY_FINDFIRST(a,b) FindFirstFile(a,b) +#define MY_FINDNEXT(a,b) FindNextFile(a,b) +#define ISDIR(a) (a.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) +#define MY_FINDCLOSE(a) FindClose(a) #define MY_FILENAME(a) a.cFileName #define MY_FILESIZE(a) (a.nFileSizeHigh * MAXDWORD) + a.nFileSizeLow @@ -1951,10 +2206,10 @@ static void RootFrameList(nsIPresContext* aPresContext, FILE* out, PRInt32 aInde /** --------------------------------------------------- * Dumps Frames for Printing */ -static void DumpFrames(FILE* out, - nsIPresContext* aPresContext, - nsIRenderingContext * aRendContext, - nsIFrame * aFrame, +static void DumpFrames(FILE* out, + nsIPresContext* aPresContext, + nsIRenderingContext * aRendContext, + nsIFrame * aFrame, PRInt32 aLevel) { NS_ASSERTION(out, "Pointer is null!"); @@ -2122,16 +2377,16 @@ static void DumpPrintObjectsList(nsVoidArray * aDocList, FILE* aFD = nsnull) } } - fprintf(fd, "%s %d %d %d %p %p %p %p %p %d %d,%d,%d,%d\n", types[po->mFrameType], + fprintf(fd, "%s %d %d %d %p %p %p %p %p %d %d,%d,%d,%d\n", types[po->mFrameType], po->IsPrintable(), po->mPrintAsIs, po->mHasBeenPrinted, po, po->mWebShell, po->mSeqFrame, - po->mPageFrame, rootFrame, po->mPageNum, po->mRect.x, po->mRect.y, po->mRect.width, po->mRect.height); + po->mPageFrame, rootFrame, po->mPageNum, po->mRect.x, po->mRect.y, po->mRect.width, po->mRect.height); if (fd != nsnull && fd != stdout) { - fprintf(stdout, "%s %d %d %d %p %p %p %p %p %d %d,%d,%d,%d\n", types[po->mFrameType], + fprintf(stdout, "%s %d %d %d %p %p %p %p %p %d %d,%d,%d,%d\n", types[po->mFrameType], po->IsPrintable(), po->mPrintAsIs, po->mHasBeenPrinted, po, po->mWebShell, po->mSeqFrame, - po->mPageFrame, rootFrame, po->mPageNum, po->mRect.x, po->mRect.y, po->mRect.width, po->mRect.height); + po->mPageFrame, rootFrame, po->mPageNum, po->mRect.x, po->mRect.y, po->mRect.width, po->mRect.height); } - } -} + } +} static void DumpPrintObjectsTree(PrintObject * aPO, int aLevel= 0, FILE* aFD = nsnull) { NS_ASSERTION(aPO, "Pointer is null!"); @@ -2148,11 +2403,12 @@ static void DumpPrintObjectsTree(PrintObject * aPO, int aLevel= 0, FILE* aFD = n NS_ASSERTION(po, "PrintObject can't be null!"); for (PRInt32 k=0;kmFrameType], po, po->mWebShell, po->mSeqFrame, - po->mPageFrame, po->mPageNum, po->mRect.x, po->mRect.y, po->mRect.width, po->mRect.height); - } + po->mPageFrame, po->mPageNum, po->mRect.x, po->mRect.y, po->mRect.width, po->mRect.height); + } } - -static void GetDocTitleAndURL(PrintObject* aPO, char *& aDocStr, char *& aURLStr) + +static void GetDocTitleAndURL(PrintObject* aPO, char *& aDocStr, + char *& aURLStr) { aDocStr = nsnull; aURLStr = nsnull; @@ -2160,7 +2416,9 @@ static void GetDocTitleAndURL(PrintObject* aPO, char *& aDocStr, char *& aURLStr PRUnichar * mozillaDoc = ToNewUnicode(NS_LITERAL_STRING("Mozilla Document")); PRUnichar * docTitleStr; PRUnichar * docURLStr; - DocumentViewerImpl::GetDisplayTitleAndURL(aPO, nsnull, mozillaDoc, &docTitleStr, &docURLStr, DocumentViewerImpl::eDocTitleDefURLDoc); + DocumentViewerImpl::GetDisplayTitleAndURL(aPO, nsnull, mozillaDoc, + &docTitleStr, &docURLStr, + DocumentViewerImpl::eDocTitleDefURLDoc); if (docTitleStr) { nsAutoString strDocTitle(docTitleStr); @@ -2179,7 +2437,7 @@ static void GetDocTitleAndURL(PrintObject* aPO, char *& aDocStr, char *& aURLStr } } -static void DumpPrintObjectsTreeLayout(PrintObject * aPO, +static void DumpPrintObjectsTreeLayout(PrintObject * aPO, nsIDeviceContext * aDC, int aLevel= 0, FILE * aFD = nsnull) { @@ -2203,7 +2461,7 @@ static void DumpPrintObjectsTreeLayout(PrintObject * aPO, } for (PRInt32 k=0;kmFrameType], aPO, aPO->mWebShell, aPO->mSeqFrame, - aPO->mPageFrame, aPO->mPageNum, aPO->mRect.x, aPO->mRect.y, aPO->mRect.width, aPO->mRect.height); + aPO->mPageFrame, aPO->mPageNum, aPO->mRect.x, aPO->mRect.y, aPO->mRect.width, aPO->mRect.height); if (aPO->IsPrintable()) { char * docStr; char * urlStr; @@ -2224,7 +2482,7 @@ static void DumpPrintObjectsTreeLayout(PrintObject * aPO, if (aLevel == 0 && fd) { fclose(fd); } -} +} static void DumpPrintObjectsListStart(char * aStr, nsVoidArray * aDocList, FILE* aFD = nsnull) { @@ -2242,7 +2500,7 @@ static void DumpPrintObjectsListStart(char * aStr, nsVoidArray * aDocList, FILE* #else #define DUMP_DOC_LIST(_title) #define DUMP_DOC_TREE -#define DUMP_DOC_TREELAYOUT +#define DUMP_DOC_TREELAYOUT #endif //--------------------------------------------------------------- @@ -2252,7 +2510,7 @@ static void DumpPrintObjectsListStart(char * aStr, nsVoidArray * aDocList, FILE* //--------------------------------------------------------------- /** --------------------------------------------------- - * Giving a child frame it searches "up" the tree until it + * Giving a child frame it searches "up" the tree until it * finds a "Page" frame. */ static nsIFrame * GetPageFrame(nsIFrame * aFrame) @@ -2277,7 +2535,7 @@ static nsIFrame * FindFrameByType(nsIPresContext* aPresContext, nsIFrame * aParentFrame, nsIAtom * aType, nsRect& aRect, - nsRect& aChildRect) + nsRect& aChildRect) { NS_ASSERTION(aPresContext, "Pointer is null!"); NS_ASSERTION(aParentFrame, "Pointer is null!"); @@ -2404,7 +2662,7 @@ static nsresult GetPageRangeForSelection(nsIPresShell * aPresShell, seqFrame->GetRect(rect); // start out with the sequence frame and search the entire frame tree - // capturing the the starting and ending child frames of the selection + // capturing the the starting and ending child frames of the selection // and their rects FindSelectionBounds(aPresContext, aRC, seqFrame, rect, startFrame, aStartRect, endFrame, aEndRect); @@ -2413,7 +2671,7 @@ static nsresult GetPageRangeForSelection(nsIPresShell * aPresShell, printf("End Frame: %p\n", endFrame); #endif - // initial the page numbers here + // initial the page numbers here // in case we don't find and frames aStartPageNum = -1; aEndPageNum = -1; @@ -2429,7 +2687,7 @@ static nsresult GetPageRangeForSelection(nsIPresShell * aPresShell, // Check to see if start should be same as end if // the end frame comes back null if (endFrame == nsnull) { - // XXX the "GetPageFrame" step could be integrated into + // XXX the "GetPageFrame" step could be integrated into // the FindSelectionBounds step, but walking up to find // the parent of a child frame isn't expensive and it makes // FindSelectionBounds a little easier to understand @@ -2469,7 +2727,7 @@ static nsresult GetPageRangeForSelection(nsIPresShell * aPresShell, while (page != nsnull) { if (page == startPageFrame) { aStartPageNum = pageNum; - } + } if (page == endPageFrame) { aEndPageNum = pageNum; } @@ -2489,7 +2747,7 @@ static nsresult GetPageRangeForSelection(nsIPresShell * aPresShell, } //------------------------------------------------------- -PRBool +PRBool DocumentViewerImpl::IsParentAFrameSet(nsIWebShell * aParent) { NS_ASSERTION(aParent, "Pointer is null!"); @@ -2498,8 +2756,8 @@ DocumentViewerImpl::IsParentAFrameSet(nsIWebShell * aParent) nsCOMPtr parentAsItem(do_QueryInterface(aParent)); if (!parentAsItem) return PR_FALSE; - // When it is the top level document we need to check - // to see if it contains a frameset. If it does, then + // 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 @@ -2508,10 +2766,10 @@ DocumentViewerImpl::IsParentAFrameSet(nsIWebShell * aParent) // 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 + // Bug 53459 has been files so we can eventually distinguish // between IFRAME frames and FRAME frames PRBool isFrameSet = PR_FALSE; - // only check to see if there is a frameset if there is + // 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 shell; mPresContext->GetShell(getter_AddRefs(shell)); @@ -2532,7 +2790,7 @@ DocumentViewerImpl::IsParentAFrameSet(nsIWebShell * aParent) } //------------------------------------------------------- -PRBool +PRBool DocumentViewerImpl::IsWebShellAFrameSet(nsIWebShell * aWebShell) { NS_ASSERTION(aWebShell, "Pointer is null!"); @@ -2551,8 +2809,8 @@ DocumentViewerImpl::IsWebShellAFrameSet(nsIWebShell * aWebShell) //------------------------------------------------------- void -DocumentViewerImpl::GetWebShellTitleAndURL(nsIWebShell * aWebShell, - PRUnichar** aTitle, +DocumentViewerImpl::GetWebShellTitleAndURL(nsIWebShell * aWebShell, + PRUnichar** aTitle, PRUnichar** aURLStr) { NS_ASSERTION(aWebShell, "Pointer is null!"); @@ -2648,7 +2906,7 @@ DocumentViewerImpl::GetDisplayTitleAndURL(PrintObject* aPO, case eDocTitleDefDocument: if (aBrandName) *aTitle = nsCRT::strdup(aBrandName); break; - case eDocTitleDefURLDoc: + case eDocTitleDefURLDoc: if (*aURLStr) { *aTitle = nsCRT::strdup(*aURLStr); } else { @@ -2784,12 +3042,12 @@ DocumentViewerImpl::PrintPage(nsIPresContext* aPresContext, if (mPrt->mPrintFrameType == nsIPrintSettings::kEachFrameSep) { DoProgressForSeparateFrames(); - } else if (mPrt->mPrintFrameType != nsIPrintSettings::kFramesAsIs || + } else if (mPrt->mPrintFrameType != nsIPrintSettings::kFramesAsIs || mPrt->mPrintObject->mFrameType == eDoc && aPO == mPrt->mPrintObject) { PrintData::DoOnProgressChange(mPrt->mPrintProgressListeners, curPage, endPage); } - // Set Clip when Printing "AsIs" or + // Set Clip when Printing "AsIs" or // when printing an IFrame for SelectedFrame or EachFrame PRBool setClip = PR_FALSE; switch (mPrt->mPrintFrameType) { @@ -2814,7 +3072,7 @@ DocumentViewerImpl::PrintPage(nsIPresContext* aPresContext, } break; - } //switch + } //switch if (setClip) { // Always set the clip x,y to zero because it isn't going to have any margins @@ -2828,7 +3086,7 @@ DocumentViewerImpl::PrintPage(nsIPresContext* aPresContext, // fail and the failure is passed back here. // Returning PR_TRUE means we are done printing. // - // When rv == NS_ERROR_ABORT, it means we want out of the + // When rv == NS_ERROR_ABORT, it means we want out of the // print job without displaying any error messages nsresult rv = mPageSeqFrame->PrintNextPage(aPresContext); if (NS_FAILED(rv)) { @@ -2837,7 +3095,7 @@ DocumentViewerImpl::PrintPage(nsIPresContext* aPresContext, mPrt->mIsAborted = PR_TRUE; } return PR_TRUE; - } + } // Now see if any of the SubDocs are on this page if (aPO->mPrintAsIs) { @@ -2904,9 +3162,9 @@ PrintObject * DocumentViewerImpl::FindPrintObjectByWS(PrintObject* aPO, nsIWebSh //------------------------------------------------------- // Recursively build a list of of sub documents to be printed // that mirrors the document tree -void -DocumentViewerImpl::BuildDocTree(nsIDocShellTreeNode * aParentNode, - nsVoidArray * aDocList, +void +DocumentViewerImpl::BuildDocTree(nsIDocShellTreeNode * aParentNode, + nsVoidArray * aDocList, PrintObject * aPO) { NS_ASSERTION(aParentNode, "Pointer is null!"); @@ -2914,7 +3172,7 @@ DocumentViewerImpl::BuildDocTree(nsIDocShellTreeNode * aParentNode, NS_ASSERTION(aPO, "Pointer is null!"); // Get the Doc and Title String - GetWebShellTitleAndURL(aPO->mWebShell, &aPO->mDocTitle, &aPO->mDocURL); + GetWebShellTitleAndURL(aPO->mWebShell, &aPO->mDocTitle, &aPO->mDocURL); PRInt32 childWebshellCount; aParentNode->GetChildCount(&childWebshellCount); @@ -2923,6 +3181,14 @@ DocumentViewerImpl::BuildDocTree(nsIDocShellTreeNode * aParentNode, nsCOMPtr child; aParentNode->GetChildAt(i, getter_AddRefs(child)); nsCOMPtr childAsShell(do_QueryInterface(child)); + + nsCOMPtr presShell; + childAsShell->GetPresShell(getter_AddRefs(presShell)); + + if (!presShell) { + continue; + } + nsCOMPtr viewer; childAsShell->GetContentViewer(getter_AddRefs(viewer)); if (viewer) { @@ -2953,14 +3219,15 @@ DocumentViewerImpl::SetPrintAsIs(PrintObject* aPO, PRBool aAsIs) aPO->mPrintAsIs = aAsIs; for (PRInt32 i=0;imKids.Count();i++) { SetPrintAsIs((PrintObject*)aPO->mKids[i], aAsIs); - } + } } //------------------------------------------------------- // Recursively sets all the PO items to be printed // from the given item down into the tree void -DocumentViewerImpl::SetPrintPO(PrintObject* aPO, PRBool aPrint, PRBool aIsHidden, PRUint32 aFlags) +DocumentViewerImpl::SetPrintPO(PrintObject* aPO, PRBool aPrint, + PRBool aIsHidden, PRUint32 aFlags) { NS_ASSERTION(aPO, "Pointer is null!"); @@ -2984,7 +3251,7 @@ DocumentViewerImpl::SetPrintPO(PrintObject* aPO, PRBool aPrint, PRBool aIsHidden // NOTE: This MUST be done after the sub-doc has been laid out // This is called by "MapSubDocFrameLocations" // -nsresult +nsresult DocumentViewerImpl::CalcPageFrameLocation(nsIPresShell * aPresShell, PrintObject* aPO) { @@ -2995,7 +3262,7 @@ DocumentViewerImpl::CalcPageFrameLocation(nsIPresShell * aPresShell, // Find that frame for the sub-doc's content element // in the parent document - // if it comes back null it probably has the style + // if it comes back null it probably has the style // set to "display:none" nsIFrame * frame; aPresShell->GetPrimaryFrameFor(aPO->mContent, &frame); @@ -3025,9 +3292,9 @@ DocumentViewerImpl::CalcPageFrameLocation(nsIPresShell * aPresShell, rect.y += rr.y; nsIFrame * temp = parent; temp->GetParent(&parent); - // Keep a pointer to the Seq and Page frames + // Keep a pointer to the Seq and Page frames nsIPageSequenceFrame * sqf = nsnull; - if (parent != nsnull && + if (parent != nsnull && NS_SUCCEEDED(CallQueryInterface(parent, &sqf)) && sqf) { pageFrame = temp; seqFrame = parent; @@ -3091,17 +3358,17 @@ DocumentViewerImpl::MapSubDocFrameLocations(PrintObject* aPO) // // This "maps" or figures out which sub-doc represents a // given Frame or IFrame in it's parent sub-doc. -// +// // So the Mcontent pointer in the child sub-doc points to the // content in the it's 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 it's parent's page frame so it can be +// of the sub-doc on it's 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 +void DocumentViewerImpl::MapContentForPO(PrintObject* aRootObject, nsIPresShell* aPresShell, nsIContent* aContent) @@ -3110,19 +3377,38 @@ DocumentViewerImpl::MapContentForPO(PrintObject* aRootObject, NS_ASSERTION(aPresShell, "Pointer is null!"); NS_ASSERTION(aContent, "Pointer is null!"); - nsCOMPtr supps; - aPresShell->GetSubShellFor(aContent, getter_AddRefs(supps)); - if (supps) { - nsCOMPtr webShell(do_QueryInterface(supps)); - if (webShell) { + nsCOMPtr doc; + aContent->GetDocument(*getter_AddRefs(doc)); + + if (!doc) { + NS_ERROR("No document!"); + + return; + } + + nsCOMPtr subDoc; + doc->GetSubDocumentFor(aContent, getter_AddRefs(subDoc)); + + if (subDoc) { + nsCOMPtr container; + subDoc->GetContainer(getter_AddRefs(container)); + + nsCOMPtr presShell; + subDoc->GetShellAt(0, getter_AddRefs(presShell)); + + nsCOMPtr webShell(do_QueryInterface(container)); + + if (presShell && webShell) { PrintObject * po = FindPrintObjectByWS(aRootObject, webShell); NS_ASSERTION(po, "PO can't be null!"); - if (po != nsnull) { + if (po) { po->mContent = aContent; - // Now, "type" the PO - nsCOMPtr frameSet(do_QueryInterface(aContent)); + // Now, "type" the PO + nsCOMPtr frameSet = + do_QueryInterface(aContent); + if (frameSet) { po->mFrameType = eFrameSet; } else { @@ -3130,8 +3416,11 @@ DocumentViewerImpl::MapContentForPO(PrintObject* aRootObject, if (frame) { po->mFrameType = eFrame; } else { - nsCOMPtr objElement(do_QueryInterface(aContent)); - nsCOMPtr iFrame(do_QueryInterface(aContent)); + nsCOMPtr objElement = + do_QueryInterface(aContent); + nsCOMPtr iFrame = + do_QueryInterface(aContent); + if (iFrame || objElement) { po->mFrameType = eIFrame; po->mPrintAsIs = PR_TRUE; @@ -3157,11 +3446,11 @@ DocumentViewerImpl::MapContentForPO(PrintObject* aRootObject, //------------------------------------------------------- // The walks the PO tree and for each document it walks the content -// tree looking for any content that are sub-shells +// tree looking for any content that are sub-shells // -// It then sets the mContent pointer in the "found" PO object back to the +// It then sets the mContent pointer in the "found" PO object back to the // the document that contained it. -void +void DocumentViewerImpl::MapContentToWebShells(PrintObject* aRootPO, PrintObject* aPO) { @@ -3179,16 +3468,16 @@ DocumentViewerImpl::MapContentToWebShells(PrintObject* aRootPO, // Continue recursively walking the chilren of this PO for (PRInt32 i=0;imKids.Count();i++) { MapContentToWebShells(aRootPO, (PrintObject*)aPO->mKids[i]); - } + } } //------------------------------------------------------- // This gets ref counted copies of the PresShell and Root Content // for a given nsIWebShell -void -DocumentViewerImpl::GetPresShellAndRootContent(nsIWebShell * aWebShell, - nsIPresShell** aPresShell, +void +DocumentViewerImpl::GetPresShellAndRootContent(nsIWebShell * aWebShell, + nsIPresShell** aPresShell, nsIContent** aContent) { NS_ASSERTION(aWebShell, "Pointer is null!"); @@ -3214,8 +3503,8 @@ DocumentViewerImpl::GetPresShellAndRootContent(nsIWebShell * aWebShell, //------------------------------------------------------- // Recursively sets the clip rect on all thchildren -void -DocumentViewerImpl::SetClipRect(PrintObject* aPO, +void +DocumentViewerImpl::SetClipRect(PrintObject* aPO, const nsRect& aClipRect, nscoord aOffsetX, nscoord aOffsetY, @@ -3229,8 +3518,8 @@ DocumentViewerImpl::SetClipRect(PrintObject* aPO, nscoord height = (aPO->mRect.y+aPO->mRect.height) > aClipRect.height?aClipRect.height-aPO->mRect.y:aPO->mRect.height; aPO->mClipRect.SetRect(aPO->mRect.x, aPO->mRect.y, width, height); - } - + } + PRBool doClip = aDoingSetClip; if (aPO->mFrameType == eFrame) { @@ -3271,7 +3560,7 @@ DocumentViewerImpl::SetClipRect(PrintObject* aPO, PRInt32 cnt = aPO->mKids.Count(); for (PRInt32 i=0;imKids[i], clipRect, + SetClipRect((PrintObject *)aPO->mKids[i], clipRect, aOffsetX+aPO->mRect.x, aOffsetY+aPO->mRect.y, doClip); } } @@ -3279,7 +3568,7 @@ DocumentViewerImpl::SetClipRect(PrintObject* aPO, //------------------------------------------------------- // Recursively reflow each sub-doc and then calc // all the frame locations of the sub-docs -nsresult +nsresult DocumentViewerImpl::ReflowDocList(PrintObject* aPO, PRBool aSetPixelScale, PRBool aDoCalcShrink) { NS_ASSERTION(aPO, "Pointer is null!"); @@ -3288,7 +3577,7 @@ DocumentViewerImpl::ReflowDocList(PrintObject* aPO, PRBool aSetPixelScale, PRBoo // Don't reflow hidden POs if (aPO->mIsHidden) return NS_OK; - // Here is where we set the shrinkage value into the DC + // Here is where we set the shrinkage value into the DC // and this is what actually makes it shrink if (aSetPixelScale && aPO->mFrameType != eIFrame) { float ratio; @@ -3300,7 +3589,7 @@ DocumentViewerImpl::ReflowDocList(PrintObject* aPO, PRBool aSetPixelScale, PRBoo mPrt->mPrintDC->SetCanonicalPixelScale(ratio*mPrt->mOrigDCScale); } - // Reflow the PO + // Reflow the PO if (NS_FAILED(ReflowPrintObject(aPO, aDoCalcShrink))) { return NS_ERROR_FAILURE; } @@ -3384,7 +3673,8 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO, PRBool aDoCalcShrink) return rv; } - rv = document->CreateShell(aPO->mPresContext, aPO->mViewManager, aPO->mStyleSet, getter_AddRefs(aPO->mPresShell)); + rv = document->CreateShell(aPO->mPresContext, aPO->mViewManager, + aPO->mStyleSet, getter_AddRefs(aPO->mPresShell)); if (NS_FAILED(rv)) { return rv; } @@ -3394,7 +3684,7 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO, PRBool aDoCalcShrink) PRInt32 width, height; if (aPO->mContent == nsnull || !aPO->mPrintAsIs || - (aPO->mPrintAsIs && aPO->mParent != nsnull && !aPO->mParent->mPrintAsIs) || + (aPO->mPrintAsIs && aPO->mParent && !aPO->mParent->mPrintAsIs) || (aPO->mFrameType == eIFrame && aPO == mPrt->mSelectedPO)) { width = pageWidth; height = pageHeight; @@ -3405,22 +3695,25 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO, PRBool aDoCalcShrink) PRINT_DEBUG_MSG5("In DV::ReflowPrintObject PO: %p (%9s) Setting w,h to %d,%d\n", aPO, gFrameTypesStr[aPO->mFrameType], width, height); - nsCOMPtr domWinIntl(do_QueryInterface(mPrt->mPrintDocDW)); + nsCOMPtr domWinIntl = + do_QueryInterface(mPrt->mPrintDocDW); // XXX - Hack Alert - // OK, so ther eis a selection, we will print the entire selection + // OK, so ther eis a selection, we will print the entire selection // on one page and then crop the page. - // This means you can never print any selection that is longer than one page - // put it keeps it from page breaking in the middle of your print of the selection - // (see also nsSimplePageSequence.cpp) + // This means you can never print any selection that is longer than + // one page put it keeps it from page breaking in the middle of your + // print of the selection (see also nsSimplePageSequence.cpp) PRInt16 printRangeType = nsIPrintSettings::kRangeAllPages; if (mPrt->mPrintSettings != nsnull) { mPrt->mPrintSettings->GetPrintRange(&printRangeType); } - if (printRangeType == nsIPrintSettings::kRangeSelection && IsThereARangeSelection(domWinIntl)) { + if (printRangeType == nsIPrintSettings::kRangeSelection && + IsThereARangeSelection(domWinIntl)) { height = NS_UNCONSTRAINEDSIZE; } + nsRect tbounds = nsRect(0, 0, width, height); // Create a child window of the parent that is our "root view/window" @@ -3434,7 +3727,7 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO, PRBool aDoCalcShrink) } #ifdef NS_PRINT_PREVIEW - // Here we decide whether we need scrollbars and + // Here we decide whether we need scrollbars and // what the parent will be of the widget if (mIsCreatingPrintPreview) { PRBool canCreateScrollbars = PR_FALSE; @@ -3446,16 +3739,17 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO, PRBool aDoCalcShrink) NS_ASSERTION(frameMan, "No Frame manager!"); nsIFrame* frame; frameMan->GetPrimaryFrameFor(aPO->mContent, &frame); - if (frame != nsnull && (aPO->mFrameType == eIFrame || aPO->mFrameType == eFrame)) { + if (frame && (aPO->mFrameType == eIFrame || aPO->mFrameType == eFrame)) { frame->FirstChild(aPO->mParent->mPresContext, nsnull, &frame); } - if (frame != nsnull) { + + if (frame) { nsIView* view = nsnull; frame->GetView(aPO->mParent->mPresContext, &view); - if (view != nsnull) { + if (view) { nsCOMPtr w2; view->GetWidget(*getter_AddRefs(w2)); - if (nsnull != w2) { + if (w2) { widget = w2; } canCreateScrollbars = PR_FALSE; @@ -3487,7 +3781,7 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO, PRBool aDoCalcShrink) nsCOMPtr presShell; nsCOMPtr layoutState; NS_ENSURE_SUCCESS(GetPresShell(*(getter_AddRefs(presShell))), NS_ERROR_FAILURE); - presShell->CaptureHistoryState(getter_AddRefs(layoutState),PR_TRUE); + presShell->CaptureHistoryState(getter_AddRefs(layoutState), PR_TRUE); // set it on the new pres shell aPO->mPresShell->SetHistoryState(layoutState); @@ -3506,9 +3800,9 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO, PRBool aDoCalcShrink) // initialize it with the default/generic case nsRect adjRect(aPO->mRect.x != 0?margin.left:0, aPO->mRect.y != 0?margin.top:0, width, height); - // XXX This is an arbitray height, + // XXX This is an arbitray height, // but reflow somethimes gets upset when using max int - // basically, we want to reflow a single page that is large + // basically, we want to reflow a single page that is large // enough to fit any atomic object like an IFrame const PRInt32 kFivePagesHigh = 5; @@ -3600,7 +3894,7 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO, PRBool aDoCalcShrink) nsRect rect; child->GetRect(rect); - // Create a RenderingContext and set the PresContext + // Create a RenderingContext and set the PresContext // appropriately if we are printing selection nsCOMPtr rc; if (nsIPrintSettings::kRangeSelection == printRangeType) { @@ -3683,7 +3977,7 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO, PRBool aDoCalcShrink) //------------------------------------------------------- // Given a DOMWindow it recursively finds the PO object that matches -PrintObject* +PrintObject* DocumentViewerImpl::FindPrintObjectByDOMWin(PrintObject* aPO, nsIDOMWindowInternal * aDOMWin) { NS_ASSERTION(aPO, "Pointer is null!"); @@ -3717,12 +4011,11 @@ DocumentViewerImpl::GetDOMWinForWebShell(nsIWebShell* aWebShell) NS_ASSERTION(aWebShell, "Pointer is null!"); nsCOMPtr domWin = do_GetInterface(aWebShell); - if (!domWin) return nsnull; nsCOMPtr domWinInt(do_QueryInterface(domWin)); if (!domWinInt) return nsnull; - nsIDOMWindowInternal * dw = NS_STATIC_CAST(nsIDOMWindowInternal *, domWinInt.get()); + nsIDOMWindowInternal * dw = domWinInt.get(); NS_ADDREF(dw); return dw; @@ -3740,10 +4033,10 @@ DocumentViewerImpl::EnablePOsForPrinting() return NS_ERROR_FAILURE; } - mPrt->mPrintFrameType = nsIPrintSettings::kNoFrames; + mPrt->mPrintFrameType = nsIPrintSettings::kNoFrames; mPrt->mPrintSettings->GetPrintFrameType(&mPrt->mPrintFrameType); - PRInt16 printHowEnable = nsIPrintSettings::kFrameEnableNone; + PRInt16 printHowEnable = nsIPrintSettings::kFrameEnableNone; mPrt->mPrintSettings->GetHowToEnableFrameUI(&printHowEnable); PRInt16 printRangeType = nsIPrintSettings::kRangeAllPages; @@ -3761,13 +4054,13 @@ DocumentViewerImpl::EnablePOsForPrinting() // then set the mPrintFrameType as if it were the selected frame if (printRangeType == nsIPrintSettings::kRangeSelection) { mPrt->mPrintFrameType = nsIPrintSettings::kSelectedFrame; - printHowEnable = nsIPrintSettings::kFrameEnableNone; + printHowEnable = nsIPrintSettings::kFrameEnableNone; } // This tells us that the "Frame" UI has turned off, // so therefore there are no FrameSets/Frames/IFrames to be printed // - // This means there are not FrameSets, + // This means there are not FrameSets, // but the document could contain an IFrame if (printHowEnable == nsIPrintSettings::kFrameEnableNone) { @@ -3793,7 +4086,7 @@ DocumentViewerImpl::EnablePOsForPrinting() PRINT_DEBUG_MSG2("PrintRange: %s \n", gPrintRangeStr[printRangeType]); return NS_OK; } - + // This means we are either printed a selected IFrame or // we are printing the current selection if (printRangeType == nsIPrintSettings::kRangeSelection) { @@ -3810,12 +4103,12 @@ DocumentViewerImpl::EnablePOsForPrinting() // Now, only enable this POs (the selected PO) and all of its children SetPrintPO(po, PR_TRUE); - // check to see if we have a range selection, + // check to see if we have a range selection, // as oppose to a insert selection - // this means if the user just clicked on the IFrame then + // this means if the user just clicked on the IFrame then // there will not be a selection so we want the entire page to print // - // XXX this is sort of a hack right here to make the page + // XXX this is sort of a hack right here to make the page // not try to reposition itself when printing selection nsCOMPtr domWin = getter_AddRefs(GetDOMWinForWebShell(po->mWebShell)); if (!IsThereARangeSelection(domWin)) { @@ -3857,12 +4150,12 @@ DocumentViewerImpl::EnablePOsForPrinting() // Now, only enable this POs (the selected PO) and all of its children SetPrintPO(po, PR_TRUE); - // check to see if we have a range selection, + // check to see if we have a range selection, // as oppose to a insert selection - // this means if the user just clicked on the IFrame then + // this means if the user just clicked on the IFrame then // there will not be a selection so we want the entire page to print // - // XXX this is sort of a hack right here to make the page + // XXX this is sort of a hack right here to make the page // not try to reposition itself when printing selection nsCOMPtr domWin = getter_AddRefs(GetDOMWinForWebShell(po->mWebShell)); if (!IsThereARangeSelection(domWin)) { @@ -3893,9 +4186,9 @@ DocumentViewerImpl::EnablePOsForPrinting() PrintObject * po = FindPrintObjectByDOMWin(mPrt->mPrintObject, mPrt->mCurrentFocusWin); if (po != nsnull) { mPrt->mSelectedPO = po; - // NOTE: Calling this sets the "po" and + // NOTE: Calling this sets the "po" and // we don't want to do this for documents that have no children, - // because then the "DoEndPage" gets called and it shouldn't + // because then the "DoEndPage" gets called and it shouldn't if (po->mKids.Count() > 0) { // Makes sure that itself, and all of its children are printed "AsIs" SetPrintAsIs(po); @@ -3906,10 +4199,10 @@ DocumentViewerImpl::EnablePOsForPrinting() } } return NS_OK; - } - - // If we are print each subdoc separately, - // then don't print any of the FraneSet Docs + } + + // If we are print each subdoc separately, + // then don't print any of the FraneSet Docs if (mPrt->mPrintFrameType == nsIPrintSettings::kEachFrameSep) { SetPrintPO(mPrt->mPrintObject, PR_TRUE); PRInt32 cnt = mPrt->mPrintDocList->Count(); @@ -3927,11 +4220,11 @@ DocumentViewerImpl::EnablePOsForPrinting() //--------------------------------------------------- // Find the Frame in a Frame List that is XMost -void -DocumentViewerImpl::FindXMostFrameInList(nsIPresContext* aPresContext, +void +DocumentViewerImpl::FindXMostFrameInList(nsIPresContext* aPresContext, nsIRenderingContext* aRC, nsIAtom* aList, - nsIFrame* aFrame, + nsIFrame* aFrame, nscoord aX, nscoord aY, PRInt32& aMaxWidth) @@ -3940,7 +4233,7 @@ DocumentViewerImpl::FindXMostFrameInList(nsIPresContext* aPresContext, aFrame->FirstChild(aPresContext, aList, &child); while (child) { PRBool isVisible = PR_TRUE; - // If the aRC is nsnull, then we skip the more expensive check and + // If the aRC is nsnull, then we skip the more expensive check and // just check visibility if (aRC) { child->IsVisibleForPainting(aPresContext, *aRC, PR_TRUE, &isVisible); @@ -3993,10 +4286,10 @@ DocumentViewerImpl::FindXMostFrameInList(nsIPresContext* aPresContext, //--------------------------------------------------- // Find the Frame that is XMost -void -DocumentViewerImpl::FindXMostFrameSize(nsIPresContext* aPresContext, +void +DocumentViewerImpl::FindXMostFrameSize(nsIPresContext* aPresContext, nsIRenderingContext* aRC, - nsIFrame* aFrame, + nsIFrame* aFrame, nscoord aX, nscoord aY, PRInt32& aMaxWidth) @@ -4011,15 +4304,15 @@ DocumentViewerImpl::FindXMostFrameSize(nsIPresContext* aPresContext, FindXMostFrameInList(aPresContext, aRC, childListName, aFrame, aX, aY, aMaxWidth); NS_IF_RELEASE(childListName); aFrame->GetAdditionalChildListName(childListIndex++, &childListName); - } while (childListName); + } while (childListName); } //------------------------------------------------------- -// Return the PrintObject with that is XMost (The widest frameset frame) AND -// contains the XMost (widest) layout frame -PrintObject* +// Return the PrintObject with that is XMost (The widest frameset frame) AND +// contains the XMost (widest) layout frame +PrintObject* DocumentViewerImpl::FindXMostPO() { nscoord xMostForPO = 0; @@ -4130,7 +4423,7 @@ DocumentViewerImpl::SetupToPrintContent(nsIWebShell* aParent, PRINT_DEBUG_MSG1("\n-------------------------------------------------------\n\n"); // Set up the clipping rectangle for all documents - // When frames are being printed as part of a frame set and also IFrames, + // When frames are being printed as part of a frame set and also IFrames, // they are reflowed with a very large page height. We need to setup the // clipping so they do not rpint over top of anything else PRINT_DEBUG_MSG1("SetClipRect-------------------------------------------------------\n"); @@ -4165,7 +4458,7 @@ DocumentViewerImpl::SetupToPrintContent(nsIWebShell* aParent, // This will print the webshell document // when it completes asynchronously in the DonePrintingPages method - // it will check to see if there are more webshells to be printed and + // it will check to see if there are more webshells to be printed and // then PrintDocContent will be called again. nsresult rv = NS_OK; @@ -4222,7 +4515,7 @@ DocumentViewerImpl::DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& a if (aPO->mFrameType == eFrame) { switch (mPrt->mPrintFrameType) { - case nsIPrintSettings::kFramesAsIs: + case nsIPrintSettings::kFramesAsIs: skipAllPageAdjustments = PR_TRUE; doOffsetting = PR_TRUE; break; @@ -4271,7 +4564,7 @@ DocumentViewerImpl::DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& a skipPageEjectOnly = aPO->mPrintAsIs; } - // That we are all configured, + // That we are all configured, // let's set everything up to print if (skipPageEjectOnly) { pageSequence->SkipPageEnd(); @@ -4305,8 +4598,8 @@ DocumentViewerImpl::DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& a } } - PRINT_DEBUG_MSG5("*** skipPageEjectOnly: %s skipAllPageAdjustments: %s doOffsetting: %s doAddInParentsOffset: %s\n", - PRT_YESNO(skipPageEjectOnly), PRT_YESNO(skipAllPageAdjustments), + PRINT_DEBUG_MSG5("*** skipPageEjectOnly: %s skipAllPageAdjustments: %s doOffsetting: %s doAddInParentsOffset: %s\n", + PRT_YESNO(skipPageEjectOnly), PRT_YESNO(skipAllPageAdjustments), PRT_YESNO(doOffsetting), PRT_YESNO(doAddInParentsOffset)); // We are done preparing for printing, so we can turn this off @@ -4323,7 +4616,7 @@ DocumentViewerImpl::DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& a if (NS_SUCCEEDED(CallQueryInterface(root, &fdbg))) { fdbg->DumpRegressionData(poPresContext, mPrt->mDebugFilePtr, 0, PR_TRUE); } - fclose(mPrt->mDebugFilePtr); + fclose(mPrt->mDebugFilePtr); #endif } else { nsIFrame* rootFrame; @@ -4344,9 +4637,10 @@ DocumentViewerImpl::DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& a if (!skipSetTitle) { PRUnichar * docTitleStr; PRUnichar * docURLStr; - GetDisplayTitleAndURL(aPO, mPrt->mPrintSettings, mPrt->mBrandName, &docTitleStr, &docURLStr, eDocTitleDefBlank); + GetDisplayTitleAndURL(aPO, mPrt->mPrintSettings, mPrt->mBrandName, + &docTitleStr, &docURLStr, eDocTitleDefBlank); - // Set them down into the PrintOptions so + // Set them down into the PrintOptions so // they can used by the DeviceContext if (docTitleStr) { mPrt->mPrintOptions->SetTitle(docTitleStr); @@ -4380,8 +4674,8 @@ DocumentViewerImpl::DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& a if (NS_SUCCEEDED(rvv) && selectionPS) { } - rv = GetPageRangeForSelection(poPresShell, poPresContext, *rc, selectionPS, pageSequence, - &startFrame, startPageNum, startRect, + rv = GetPageRangeForSelection(poPresShell, poPresContext, *rc, selectionPS, pageSequence, + &startFrame, startPageNum, startRect, &endFrame, endPageNum, endRect); if (NS_SUCCEEDED(rv)) { mPrt->mPrintSettings->SetStartPageRange(startPageNum); @@ -4549,7 +4843,7 @@ DocumentViewerImpl::PrintDocContent(PrintObject* aPO, nsresult& aStatus) if (!aPO->mHasBeenPrinted && aPO->IsPrintable()) { PRBool donePrinting; // donePrinting is only valid when when doing synchronous printing - aStatus = DoPrint(aPO, PR_FALSE, donePrinting); + aStatus = DoPrint(aPO, PR_FALSE, donePrinting); if (donePrinting) { return PR_TRUE; } @@ -4561,8 +4855,8 @@ DocumentViewerImpl::PrintDocContent(PrintObject* aPO, nsresult& aStatus) if (printed || NS_FAILED(aStatus)) { return PR_TRUE; } - } - return PR_FALSE; + } + return PR_FALSE; } NS_IMETHODIMP @@ -4573,11 +4867,11 @@ DocumentViewerImpl::SetEnableRendering(PRBool aOn) if (mViewManager) { if (aOn) { mViewManager->EnableRefresh(NS_VMREFRESH_IMMEDIATE); - nsIView* view; - mViewManager->GetRootView(view); // views are not refCounted - if (view) { + nsIView* view; + mViewManager->GetRootView(view); // views are not refCounted + if (view) { mViewManager->UpdateView(view, NS_VMREFRESH_IMMEDIATE); - } + } } else { mViewManager->DisableRefresh(); @@ -4637,9 +4931,10 @@ DocumentViewerImpl::CreateStyleSet(nsIDocument* aDocument, } } - nsCOMPtr chromeRegistry = - do_GetService("@mozilla.org/chrome/chrome-registry;1", &rv); - if (NS_SUCCEEDED(rv) && chromeRegistry) { + nsCOMPtr chromeRegistry = + do_GetService("@mozilla.org/chrome/chrome-registry;1"); + + if (chromeRegistry) { nsCOMPtr sheets; // Now handle the user sheets. @@ -4693,7 +4988,7 @@ DocumentViewerImpl::MakeWindow(nsIWidget* aParentWidget, nsCOMPtr dx; mPresContext->GetDeviceContext(getter_AddRefs(dx)); - + nsRect tbounds = aBounds; float p2t; mPresContext->GetPixelsToTwips(&p2t); @@ -4708,17 +5003,19 @@ DocumentViewerImpl::MakeWindow(nsIWidget* aParentWidget, if (NS_FAILED(rv)) return rv; - // Reset the bounds offset so the root view is set to 0,0. The offset is - // specified in nsIViewManager::Init above. - // Besides, layout will reset the root view to (0,0) during reflow, - // so changing it to 0,0 eliminates placing - // the root view in the wrong place initially. + // Reset the bounds offset so the root view is set to 0,0. The + // offset is specified in nsIViewManager::Init above. + // Besides, layout will reset the root view to (0,0) during reflow, + // so changing it to 0,0 eliminates placing the root view in the + // wrong place initially. tbounds.x = 0; tbounds.y = 0; // Create a child window of the parent that is our "root view/window" // Create a view - rv = CallCreateInstance(kViewCID, &mView); + + nsIView *view = nsnull; + rv = CallCreateInstance(kViewCID, &view); if (NS_FAILED(rv)) return rv; @@ -4727,13 +5024,13 @@ DocumentViewerImpl::MakeWindow(nsIWidget* aParentWidget, nsIView* containerView = nsnull; if (NS_SUCCEEDED(aParentWidget->GetClientData(clientData))) { nsISupports* data = (nsISupports*)clientData; - - if (nsnull != data) { + + if (data) { data->QueryInterface(NS_GET_IID(nsIView), (void **)&containerView); } } - if (nsnull != containerView) { + if (containerView) { // see if the containerView has already been hooked into a foreign view manager hierarchy // if it has, then we have to hook into the hierarchy too otherwise bad things will happen. nsCOMPtr containerVM; @@ -4745,13 +5042,13 @@ DocumentViewerImpl::MakeWindow(nsIWidget* aParentWidget, } while (pView != nsnull && NS_SUCCEEDED(pView->GetViewManager(*getter_AddRefs(checkVM))) && checkVM == containerVM); - if (nsnull == pView) { + if (!pView) { // OK, so the container is not already hooked up into a foreign view manager hierarchy. // That means we can choose not to hook ourselves up. // // If the parent container is a chrome shell, or a frameset, then we won't hook into its view // tree. This will improve performance a little bit (especially given scrolling/painting perf bugs) - // but is really just for peace of mind. This check can be removed if we want to support fancy + // but is really just for peace of mind. This check can be removed if we want to support fancy // chrome effects like transparent controls floating over content, transparent Web browsers, and // things like that, and the perf bugs are fixed. nsCOMPtr container(do_QueryInterface(mContainer)); @@ -4772,20 +5069,20 @@ DocumentViewerImpl::MakeWindow(nsIWidget* aParentWidget, } } - rv = mView->Init(mViewManager, tbounds, containerView); + rv = view->Init(mViewManager, tbounds, containerView); if (NS_FAILED(rv)) return rv; - rv = mView->CreateWidget(kWidgetCID, nsnull, - aParentWidget->GetNativeData(NS_NATIVE_WIDGET), - PR_TRUE, PR_FALSE); + rv = view->CreateWidget(kWidgetCID, nsnull, + aParentWidget->GetNativeData(NS_NATIVE_WIDGET), + PR_TRUE, PR_FALSE); if (rv != NS_OK) return rv; // Setup hierarchical relationship in view manager - mViewManager->SetRootView(mView); + mViewManager->SetRootView(view); - mView->GetWidget(*getter_AddRefs(mWindow)); + view->GetWidget(*getter_AddRefs(mWindow)); // This SetFocus is necessary so the Arrow Key and Page Key events // go to the scrolled view as soon as the Window is created instead of going to @@ -4795,21 +5092,25 @@ DocumentViewerImpl::MakeWindow(nsIWidget* aParentWidget, return rv; } -nsresult DocumentViewerImpl::GetDocumentSelection(nsISelection **aSelection, nsIPresShell * aPresShell) +nsresult DocumentViewerImpl::GetDocumentSelection(nsISelection **aSelection, + nsIPresShell *aPresShell) { - if (aPresShell == nsnull) { + if (!aPresShell) { if (!mPresShell) { return NS_ERROR_NOT_INITIALIZED; } aPresShell = mPresShell; } - if (!aSelection) return NS_ERROR_NULL_POINTER; - if (!aPresShell) return NS_ERROR_NULL_POINTER; + if (!aSelection) + return NS_ERROR_NULL_POINTER; + if (!aPresShell) + return NS_ERROR_NULL_POINTER; nsCOMPtr selcon; selcon = do_QueryInterface(aPresShell); - if (selcon) - return selcon->GetSelection(nsISelectionController::SELECTION_NORMAL, aSelection); + if (selcon) + return selcon->GetSelection(nsISelectionController::SELECTION_NORMAL, + aSelection); return NS_ERROR_FAILURE; } @@ -4821,13 +5122,13 @@ DocumentViewerImpl::CreateDocumentViewerUsing(nsIPresContext* aPresContext, // XXX better error return NS_ERROR_NULL_POINTER; } - if (nsnull == aPresContext) { + if (!aPresContext) { return NS_ERROR_NULL_POINTER; } // Create new viewer DocumentViewerImpl* viewer = new DocumentViewerImpl(aPresContext); - if (nsnull == viewer) { + if (!viewer) { return NS_ERROR_OUT_OF_MEMORY; } NS_ADDREF(viewer); @@ -4838,7 +5139,7 @@ DocumentViewerImpl::CreateDocumentViewerUsing(nsIPresContext* aPresContext, // Bind the new viewer to the old document nsresult rv = viewer->LoadStart(mDocument); - + aResult = viewer; return rv; @@ -4887,7 +5188,7 @@ nsresult DocumentViewerImpl::DocumentReadyForPrinting() return rv; } -NS_IMETHODIMP +NS_IMETHODIMP DocumentViewerImpl::SetTransformMediator(nsITransformMediator* aMediator) { NS_ASSERTION(nsnull == mTransformMediator, "nsXMLDocument::SetTransformMediator(): \ @@ -4939,7 +5240,7 @@ NS_IMETHODIMP DocumentViewerImpl::SelectAll() nsCOMPtr htmldoc = do_QueryInterface(mDocument); nsCOMPtr bodyNode; - + if (htmldoc) { nsCOMPtrbodyElement; @@ -4954,8 +5255,8 @@ NS_IMETHODIMP DocumentViewerImpl::SelectAll() mDocument->GetRootContent(getter_AddRefs(rootContent)); bodyNode = do_QueryInterface(rootContent); } - if (!bodyNode) return NS_ERROR_FAILURE; - + if (!bodyNode) return NS_ERROR_FAILURE; + rv = selection->RemoveAllRanges(); if (NS_FAILED(rv)) return rv; @@ -5008,10 +5309,10 @@ NS_IMETHODIMP DocumentViewerImpl::GetCopyable(PRBool *aCopyable) nsresult rv; rv = GetDocumentSelection(getter_AddRefs(selection)); if (NS_FAILED(rv)) return rv; - + PRBool isCollapsed; selection->GetIsCollapsed(&isCollapsed); - + *aCopyable = !isCollapsed; return NS_OK; } @@ -5096,7 +5397,7 @@ nsresult DocumentViewerImpl::GetSelectionDocument(nsIDeviceContextSpec * aDevSpe if (NS_FAILED(rv)) { return rv; } rv = htmlElement->AppendChildTo(bodyElement, PR_FALSE, PR_FALSE); if (NS_FAILED(rv)) { return rv; } - + // load the document into the docshell nsCOMPtr domDoc = do_QueryInterface(doc); if (!domDoc) { return NS_ERROR_NULL_POINTER; } @@ -5114,8 +5415,8 @@ nsresult DocumentViewerImpl::GetSelectionDocument(nsIDeviceContextSpec * aDevSpe } //------------------------------------------------------ -PRBool -DocumentViewerImpl::IsThereAnIFrameSelected(nsIWebShell* aWebShell, +PRBool +DocumentViewerImpl::IsThereAnIFrameSelected(nsIWebShell* aWebShell, nsIDOMWindowInternal * aDOMWin, PRPackedBool& aIsParentFrameSet) { @@ -5131,7 +5432,7 @@ DocumentViewerImpl::IsThereAnIFrameSelected(nsIWebShell* aWebShell, // if so, it means the selected frame is either the main webshell // or an IFRAME if (aDOMWin != nsnull) { - // Get the main webshell's DOMWin to see if it matches + // Get the main webshell's DOMWin to see if it matches // the frame that is selected nsCOMPtr domWin = getter_AddRefs(GetDOMWinForWebShell(aWebShell)); if (aDOMWin != nsnull && domWin != aDOMWin) { @@ -5145,7 +5446,7 @@ DocumentViewerImpl::IsThereAnIFrameSelected(nsIWebShell* aWebShell, //------------------------------------------------------ -PRBool +PRBool DocumentViewerImpl::IsThereARangeSelection(nsIDOMWindowInternal * aDOMWin) { nsCOMPtr presShell; @@ -5180,7 +5481,7 @@ DocumentViewerImpl::IsThereARangeSelection(nsIDOMWindowInternal * aDOMWin) //------------------------------------------------------- // Recursively walks the PrintObject tree and installs the DocViewer // as an event processor and it shows the window -nsresult +nsresult DocumentViewerImpl::ShowDocList(PrintObject* aPO, PRBool aShow) { NS_ASSERTION(aPO, "Pointer is null!"); @@ -5189,7 +5490,8 @@ DocumentViewerImpl::ShowDocList(PrintObject* aPO, PRBool aShow) PRBool donePrinting; DoPrint(aPO, PR_FALSE, donePrinting); - // mWindow will be null for POs that are hidden, so they don't get shown + // mWindow will be null for POs that are hidden, so they don't get + // shown if (aPO->mWindow) { aPO->mWindow->Show(aShow); } @@ -5201,6 +5503,7 @@ DocumentViewerImpl::ShowDocList(PrintObject* aPO, PRBool aShow) return NS_ERROR_FAILURE; } } + return NS_OK; } @@ -5240,7 +5543,7 @@ DocumentViewerImpl::InstallPrintPreviewListener() //---------------------------------------------------------------------- static nsresult GetSeqFrameAndCountPages(PrintObject* aPO, - nsIFrame*& aSeqFrame, + nsIFrame*& aSeqFrame, PRInt32& aCount) { NS_ENSURE_ARG_POINTER(aPO); @@ -5389,7 +5692,7 @@ DocumentViewerImpl::PrintPreviewNavigate(PRInt16 aType, PRInt32 aPageNum) } /* readonly attribute boolean isFramesetDocument; */ -NS_IMETHODIMP +NS_IMETHODIMP DocumentViewerImpl::GetIsFramesetDocument(PRBool *aIsFramesetDocument) { nsCOMPtr webContainer(do_QueryInterface(mContainer)); @@ -5438,7 +5741,7 @@ DocumentViewerImpl::GetIsFramesetFrameSelected(PRBool *aIsFramesetFrameSelected) } /* readonly attribute long printPreviewNumPages; */ -NS_IMETHODIMP +NS_IMETHODIMP DocumentViewerImpl::GetPrintPreviewNumPages(PRInt32 *aPrintPreviewNumPages) { NS_ENSURE_ARG_POINTER(aPrintPreviewNumPages); @@ -5455,7 +5758,7 @@ DocumentViewerImpl::GetPrintPreviewNumPages(PRInt32 *aPrintPreviewNumPages) } /* void exitPrintPreview (); */ -NS_IMETHODIMP +NS_IMETHODIMP DocumentViewerImpl::ExitPrintPreview() { if (mIsDoingPrinting) return NS_ERROR_FAILURE; @@ -5490,7 +5793,8 @@ DocumentViewerImpl::InstallNewPresentation() } // turn off selection painting - nsCOMPtr selectionController = do_QueryInterface(mPresShell); + nsCOMPtr selectionController = + do_QueryInterface(mPresShell); if (selectionController) { selectionController->SetDisplaySelection(nsISelectionController::SELECTION_OFF); } @@ -5503,7 +5807,7 @@ DocumentViewerImpl::InstallNewPresentation() nsCOMPtr selection; nsresult rv = GetDocumentSelection(getter_AddRefs(selection)); nsCOMPtr selPrivate(do_QueryInterface(selection)); - if (NS_SUCCEEDED(rv) && selPrivate && mSelectionListener) + if (NS_SUCCEEDED(rv) && selPrivate && mSelectionListener) selPrivate->RemoveSelectionListener(mSelectionListener); // We need to destroy the PreShell if there is an existing PP @@ -5539,7 +5843,7 @@ DocumentViewerImpl::InstallNewPresentation() // This is the new code for selecting the appropriate Frame of a Frameset // for Print Preview. But it can't be turned on yet -#if 0 +#if 0 // If it is a Frameset then choose the selected one // or select the one with the largest area if (mPrt->mPrintObject->mFrameType == eFrameSet) { @@ -5614,7 +5918,6 @@ DocumentViewerImpl::InstallNewPresentation() Show(); ShowDocList(mPrt->mPrintObject, PR_TRUE); - } void @@ -5657,7 +5960,7 @@ DocumentViewerImpl::ReturnToGalleyPresentation() nsCOMPtr selection; nsresult rv = GetDocumentSelection(getter_AddRefs(selection)); nsCOMPtr selPrivate(do_QueryInterface(selection)); - if (NS_SUCCEEDED(rv) && selPrivate && mSelectionListener) + if (NS_SUCCEEDED(rv) && selPrivate && mSelectionListener) selPrivate->RemoveSelectionListener(mSelectionListener); mPresShell->Destroy(); } @@ -5680,6 +5983,10 @@ DocumentViewerImpl::ReturnToGalleyPresentation() mViewManager = mPrtPreview->mCachedPresObj->mViewManager; mWindow = mPrtPreview->mCachedPresObj->mWindow; + // Tell the "real" presshell to start observing the document + // again. + mPresShell->BeginObservingDocument(); + mWindow->Show(PR_TRUE); // Very important! Turn On scripting @@ -5689,7 +5996,6 @@ DocumentViewerImpl::ReturnToGalleyPresentation() mPrtPreview = nsnull; wasCached = PR_TRUE; - } else { // Destroy the old Presentation mPresShell = nsnull; @@ -5708,8 +6014,8 @@ DocumentViewerImpl::ReturnToGalleyPresentation() mIsDoingPrintPreview = PR_FALSE; mViewManager->EnableRefresh(NS_VMREFRESH_NO_SYNC); - Show(); + Show(); } #endif // NS_PRINT_PREVIEW @@ -5718,7 +6024,7 @@ DocumentViewerImpl::ReturnToGalleyPresentation() // This method checks to see if there is at least one printer defined // and if so, it sets the first printer in the list as the default name // in the PrintSettings which is then used for Printer Preview -nsresult +nsresult DocumentViewerImpl::CheckForPrinters(nsIPrintOptions* aPrintOptions, nsIPrintSettings* aPrintSettings, PRUint32 aErrorCode, @@ -5736,7 +6042,7 @@ DocumentViewerImpl::CheckForPrinters(nsIPrintOptions* aPrintOptions, simpEnum->HasMoreElements(&fndPrinter); if (fndPrinter) { // For now, it assumes the first item in the list - // is the default printer, but only set the + // is the default printer, but only set the // printer name if there isn't one nsCOMPtr supps; simpEnum->GetNext(getter_AddRefs(supps)); @@ -5893,13 +6199,24 @@ void DocumentViewerImpl::CheckForHiddenFrameSetFrames() * See documentation above in the nsIContentViewerfile class definition * @update 11/01/01 rods * - * For a full and detailed understanding of the issues with - * PrintPreview: See the design spec that is attached to Bug 107562 + * For a full and detailed understanding of the issues with + * PrintPreview: See the design spec that is attached to Bug 107562 */ NS_IMETHODIMP DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) { - if (mIsDoingPrinting) return NS_ERROR_FAILURE; + if (!mPresShell) { + // A frame that's not displayed can't be printed! + + return NS_OK; + } + + if (mIsDoingPrinting) { + return NS_ERROR_FAILURE; + } + + nsCOMPtr docShell(do_QueryInterface(mContainer)); + NS_ASSERTION(docShell, "This has to be a docshell"); // Temporary code for Bug 136185 nsCOMPtr xulDoc(do_QueryInterface(mDocument)); @@ -5910,15 +6227,20 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) // Get the webshell for this documentviewer nsCOMPtr webContainer(do_QueryInterface(mContainer)); + // Get the DocShell and see if it is busy // We can't Print or Print Preview this document if it is still busy - nsCOMPtr docShell(do_QueryInterface(webContainer)); - NS_ASSERTION(docShell.get(), "This has to be a docshell"); + PRUint32 busyFlags = nsIDocShell::BUSY_FLAGS_NONE; - if (NS_FAILED(docShell->GetBusyFlags(&busyFlags)) || busyFlags != nsIDocShell::BUSY_FLAGS_NONE) { + + // Preview this document if it is still busy + + if (NS_FAILED(docShell->GetBusyFlags(&busyFlags)) || + busyFlags != nsIDocShell::BUSY_FLAGS_NONE) { ShowPrintErrorDialog(NS_ERROR_GFX_PRINTER_DOC_IS_BUSY_PP, PR_FALSE); return NS_ERROR_FAILURE; } + nsresult rv = NS_OK; #if defined(XP_PC) && defined(DEBUG_rods) && defined(DEBUG_PRINTING) @@ -5934,7 +6256,7 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) } mPrt = new PrintData(); - if (mPrt == nsnull) { + if (!mPrt) { mIsCreatingPrintPreview = PR_FALSE; return NS_ERROR_OUT_OF_MEMORY; } @@ -5956,12 +6278,13 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) } } - // You have to have both a PrintOptions and a PrintSetting to call CheckForPrinters. - // The user can pass in a null PrintSettings, - // but you can only create one if you have a PrintOptions. - // So we we might as check to if we have a PrintOptions first, - // because we can't do anything below without it - // then inside we check to se if the printSettings is null to know if we need to create on. + // You have to have both a PrintOptions and a PrintSetting to call + // CheckForPrinters. + // The user can pass in a null PrintSettings, but you can only + // create one if you have a PrintOptions. So we we might as check + // to if we have a PrintOptions first, because we can't do anything + // below without it then inside we check to se if the printSettings + // is null to know if we need to create on. mPrt->mPrintSettings = aPrintSettings; mPrt->mPrintOptions = do_GetService(kPrintOptionsCID, &rv); if (NS_SUCCEEDED(rv) && mPrt->mPrintOptions) { @@ -5978,7 +6301,7 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) return NS_ERROR_FAILURE; } } - + // Let's print ... mIsCreatingPrintPreview = PR_TRUE; mIsDoingPrintPreview = PR_TRUE; @@ -5996,14 +6319,14 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) PRBool isSelection = IsThereARangeSelection(mPrt->mCurrentFocusWin); // Create a list for storing the WebShells that need to be printed - if (mPrt->mPrintDocList == nsnull) { + if (!mPrt->mPrintDocList) { mPrt->mPrintDocList = new nsVoidArray(); - if (mPrt->mPrintDocList == nsnull) { + if (!mPrt->mPrintDocList) { mIsCreatingPrintPreview = PR_FALSE; mIsDoingPrintPreview = PR_FALSE; aPrintSettings->SetIsPrintPreview(mIsDoingPrintPreview); TurnScriptingOn(PR_TRUE); - return NS_ERROR_FAILURE; + return NS_ERROR_OUT_OF_MEMORY; } } else { mPrt->mPrintDocList->Clear(); @@ -6015,7 +6338,7 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) mPrt->mPrintDocList->AppendElement(mPrt->mPrintObject); mPrt->mIsParentAFrameSet = IsParentAFrameSet(webContainer); - mPrt->mPrintObject->mFrameType = mPrt->mIsParentAFrameSet?eFrameSet:eDoc; + mPrt->mPrintObject->mFrameType = mPrt->mIsParentAFrameSet ? eFrameSet : eDoc; // Build the "tree" of PrintObjects nsCOMPtr parentAsNode(do_QueryInterface(webContainer)); @@ -6025,8 +6348,8 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) // in the parent document MapContentToWebShells(mPrt->mPrintObject, mPrt->mPrintObject); - // Get whether the doc contains a frameset - // Also, check to see if the currently focus webshell + // Get whether the doc contains a frameset + // Also, check to see if the currently focus webshell // is a child of this webshell mPrt->mIsIFrameSelected = IsThereAnIFrameSelected(webContainer, mPrt->mCurrentFocusWin, mPrt->mIsParentAFrameSet); @@ -6054,7 +6377,7 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) #ifdef DEBUG_PRINTING if (mPrt->mPrintSettings) { - PRInt16 printHowEnable = nsIPrintSettings::kFrameEnableNone; + PRInt16 printHowEnable = nsIPrintSettings::kFrameEnableNone; mPrt->mPrintSettings->GetHowToEnableFrameUI(&printHowEnable); PRBool val; mPrt->mPrintSettings->GetPrintOptions(nsIPrintSettings::kEnableSelectionRB, &val); @@ -6082,7 +6405,7 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) nsCOMPtr dx; nsresult rv = factory->CreateDeviceContextSpec(mWindow, aPrintSettings, *getter_AddRefs(devspec), doSilent); if (NS_SUCCEEDED(rv)) { - rv = mDeviceContext->GetDeviceContextFor(devspec, *getter_AddRefs(ppDC)); + rv = mDeviceContext->GetDeviceContextFor(devspec, *getter_AddRefs(ppDC)); if (NS_SUCCEEDED(rv)) { mDeviceContext->SetAltDevice(ppDC); if (mPrt->mPrintSettings != nsnull) { @@ -6109,7 +6432,7 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) mPrt->mPrintSettings->SetPrintRange(nsIPrintSettings::kRangeAllPages); } - mPrt->mPrintDC = mDeviceContext; + mPrt->mPrintDC = mDeviceContext; // Get the Original PixelScale incase we need to start changing it mPrt->mPrintDC->GetCanonicalPixelScale(mPrt->mOrigDCScale); @@ -6145,8 +6468,8 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) } /* cleanup done, let's fire-up an error dialog to notify the user - * what went wrong... - */ + * what went wrong... + */ ShowPrintErrorDialog(rv, PR_FALSE); TurnScriptingOn(PR_TRUE); mIsCreatingPrintPreview = PR_FALSE; @@ -6155,7 +6478,7 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) } - // At this point we are done preparing everything + // At this point we are done preparing everything // before it is to be created // Noew create the new Presentation and display it @@ -6173,7 +6496,8 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) void -DocumentViewerImpl::SetDocAndURLIntoProgress(PrintObject* aPO, nsIPrintProgressParams* aParams) +DocumentViewerImpl::SetDocAndURLIntoProgress(PrintObject* aPO, + nsIPrintProgressParams* aParams) { NS_ASSERTION(aPO, "Must have vaild PrintObject"); NS_ASSERTION(aParams, "Must have vaild nsIPrintProgressParams"); @@ -6181,11 +6505,12 @@ DocumentViewerImpl::SetDocAndURLIntoProgress(PrintObject* aPO, nsIPrintProgressP if (!aPO || !aPO->mWebShell || !aParams) { return; } - const PRInt32 kTitleLength = 64; + const PRUint32 kTitleLength = 64; PRUnichar * docTitleStr; PRUnichar * docURLStr; - GetDisplayTitleAndURL(aPO, mPrt->mPrintSettings, mPrt->mBrandName, &docTitleStr, &docURLStr, eDocTitleDefDocument); + GetDisplayTitleAndURL(aPO, mPrt->mPrintSettings, mPrt->mBrandName, + &docTitleStr, &docURLStr, eDocTitleDefDocument); // Make sure the URLS don't get too long for the progress dialog if (docURLStr && nsCRT::strlen(docURLStr) > kTitleLength) { @@ -6252,7 +6577,7 @@ DocumentViewerImpl::DoPrintProgress(PRBool aIsForPrinting) */ NS_IMETHODIMP DocumentViewerImpl::Print(PRBool aSilent, - FILE * aDebugFile, + FILE * aDebugFile, nsIPrintSettings* aPrintSettings) { nsCOMPtr printSettings; @@ -6276,7 +6601,7 @@ DocumentViewerImpl::Print(PRBool aSilent, return Print(printSettings, nsnull); - + } /** --------------------------------------------------- @@ -6301,6 +6626,17 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, nsresult rv = NS_ERROR_FAILURE; + nsCOMPtr docShell(do_QueryInterface(mContainer)); + NS_ASSERTION(docShell, "This has to be a docshell"); + + nsCOMPtr presShell; + docShell->GetPresShell(getter_AddRefs(presShell)); + + if (!presShell) { + // A frame that's not displayed can't be printed! + + return NS_OK; + } if (mIsDoingPrintPreview) { PRBool okToPrint = PR_FALSE; @@ -6315,7 +6651,7 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, } // if we are printing another URL, then exit - // the reason we check here is because this method can be called while + // the reason we check here is because this method can be called while // another is still in here (the printing dialog is a good example). // the only time we can print more than one job at a time is the regression tests if (mIsDoingPrinting) { @@ -6324,7 +6660,7 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, ShowPrintErrorDialog(rv); return rv; } - + mPrt = new PrintData(); if (mPrt == nsnull) { return NS_ERROR_OUT_OF_MEMORY; @@ -6363,7 +6699,7 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, mPrt->mPrintProgressListeners.AppendElement((void*)aWebProgressListener); NS_ADDREF(aWebProgressListener); } - + // Get the currently focused window and cache it // because the Print Dialog will "steal" focus and later when you try // to get the currently focused windows it will be NULL @@ -6405,8 +6741,8 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, MapContentToWebShells(mPrt->mPrintObject, mPrt->mPrintObject); - // Get whether the doc contains a frameset - // Also, check to see if the currently focus webshell + // Get whether the doc contains a frameset + // Also, check to see if the currently focus webshell // is a child of this webshell mPrt->mIsIFrameSelected = IsThereAnIFrameSelected(webContainer, mPrt->mCurrentFocusWin, mPrt->mIsParentAFrameSet); @@ -6430,7 +6766,7 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, #ifdef DEBUG_PRINTING if (mPrt->mPrintSettings) { - PRInt16 printHowEnable = nsIPrintSettings::kFrameEnableNone; + PRInt16 printHowEnable = nsIPrintSettings::kFrameEnableNone; mPrt->mPrintSettings->GetHowToEnableFrameUI(&printHowEnable); PRBool val; mPrt->mPrintSettings->GetPrintOptions(nsIPrintSettings::kEnableSelectionRB, &val); @@ -6449,7 +6785,7 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, /* create factory (incl. create print dialog) */ nsCOMPtr factory = do_CreateInstance(kDeviceContextSpecFactoryCID, &rv); - + if (NS_SUCCEEDED(rv)) { #ifdef DEBUG_dcone printf("PRINT JOB STARTING\n"); @@ -6464,7 +6800,7 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, #endif // we have to turn off printpreview mode for now.. because this is a real request to print. - if ( mIsDoingPrintPreview == PR_TRUE) { + if (mIsDoingPrintPreview) { aPrintSettings->SetIsPrintPreview(PR_FALSE); } @@ -6571,7 +6907,7 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, mPrt->mPrintFrameType = nsIPrintSettings::kEachFrameSep; mPrt->mPrintSettings->SetPrintFrameType(mPrt->mPrintFrameType); } else { - // First find out from the PrinService what options are available + // First find out from the PrinService what options are available // to us for Printing FrameSets PRInt16 howToEnableFrameUI; mPrt->mPrintSettings->GetHowToEnableFrameUI(&howToEnableFrameUI); @@ -6616,12 +6952,14 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, PRUnichar * docTitleStr; PRUnichar * docURLStr; - GetDisplayTitleAndURL(mPrt->mPrintObject, mPrt->mPrintSettings, mPrt->mBrandName, &docTitleStr, &docURLStr, eDocTitleDefURLDoc); + GetDisplayTitleAndURL(mPrt->mPrintObject, mPrt->mPrintSettings, + mPrt->mBrandName, &docTitleStr, &docURLStr, + eDocTitleDefURLDoc); // BeginDocument may pass back a FAILURE code - // i.e. On Windows, if you are printing to a file and hit "Cancel" + // i.e. On Windows, if you are printing to a file and hit "Cancel" // to the "File Name" dialog, this comes back as an error - // Don't start printing when regression test are executed + // Don't start printing when regression test are executed rv = mPrt->mDebugFilePtr ? NS_OK: mPrt->mPrintDC->BeginDocument(docTitleStr); PRINT_DEBUG_MSG1("****************** Begin Document ************************\n"); @@ -6634,12 +6972,12 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, // Print listener setup... if (mPrt != nsnull) { - mPrt->OnStartPrinting(); + mPrt->OnStartPrinting(); } // // The mIsPrinting flag is set when the ImageGroup observer is - // notified that images must be loaded as a result of the + // notified that images must be loaded as a result of the // InitialReflow... // if(!mIsPrinting || mPrt->mDebugFilePtr) { @@ -6652,20 +6990,18 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, } } } - } + } } else { mPrt->mPrintSettings->SetIsCancelled(PR_TRUE); mPrt->mPrintOptions->SetIsCancelled(PR_TRUE); } - - // Set that we are once again in print preview - if ( mIsDoingPrintPreview == PR_TRUE) { + + // Set that we are once again in print preview + if (mIsDoingPrintPreview) { aPrintSettings->SetIsPrintPreview(PR_TRUE); } } - - /* cleaup on failure + notify user */ if (NS_FAILED(rv)) { /* cleanup... */ @@ -6673,7 +7009,7 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, mPagePrintTimer->Stop(); NS_RELEASE(mPagePrintTimer); } - + if (mPrt) { delete mPrt; mPrt = nsnull; @@ -6681,16 +7017,16 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, mIsDoingPrinting = PR_FALSE; /* cleanup done, let's fire-up an error dialog to notify the user - * what went wrong... - * - * When rv == NS_ERROR_ABORT, it means we want out of the + * what went wrong... + * + * When rv == NS_ERROR_ABORT, it means we want out of the * print job without displaying any error messages */ if (rv != NS_ERROR_ABORT) { ShowPrintErrorDialog(rv); } } - + return rv; } @@ -6699,19 +7035,19 @@ void DocumentViewerImpl::ShowPrintErrorDialog(nsresult aPrintError, PRBool aIsPrinting) { nsresult rv; - + static NS_DEFINE_CID(kCStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID); nsCOMPtr stringBundleService = do_GetService(kCStringBundleServiceCID); - - if (!stringBundleService) { + + if (!stringBundleService) { NS_WARNING("ERROR: Failed to get StringBundle Service instance.\n"); return; } nsCOMPtr myStringBundle; - rv = stringBundleService->CreateBundle(NS_ERROR_GFX_PRINTER_BUNDLE_URL, getter_AddRefs(myStringBundle)); - if (NS_FAILED(rv)) + rv = stringBundleService->CreateBundle(NS_ERROR_GFX_PRINTER_BUNDLE_URL, getter_AddRefs(myStringBundle)); + if (NS_FAILED(rv)) return; - + nsXPIDLString msg, title; nsAutoString stringName; @@ -6753,7 +7089,7 @@ DocumentViewerImpl::ShowPrintErrorDialog(nsresult aPrintError, PRBool aIsPrintin default: NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_FAILURE) -#undef NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG +#undef NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG } myStringBundle->GetStringFromName(stringName.get(), getter_Copies(msg)); @@ -6765,7 +7101,7 @@ DocumentViewerImpl::ShowPrintErrorDialog(nsresult aPrintError, PRBool aIsPrintin if (!msg) return; - + nsCOMPtr wwatch = do_GetService("@mozilla.org/embedcomp/window-watcher;1", &rv); if (NS_FAILED(rv)) return; @@ -6776,27 +7112,22 @@ DocumentViewerImpl::ShowPrintErrorDialog(nsresult aPrintError, PRBool aIsPrintin nsCOMPtr parent = do_QueryInterface(active, &rv); if (NS_FAILED(rv)) return; - - nsCOMPtr dialog; - parent->GetPrompter(getter_AddRefs(dialog)); + + nsCOMPtr dialog; + parent->GetPrompter(getter_AddRefs(dialog)); if (!dialog) return; - + dialog->Alert(title, msg); } // nsIContentViewerFile interface NS_IMETHODIMP -DocumentViewerImpl::GetPrintable(PRBool *aPrintable) +DocumentViewerImpl::GetPrintable(PRBool *aPrintable) { NS_ENSURE_ARG_POINTER(aPrintable); - - if(mIsDoingPrinting==PR_TRUE){ - *aPrintable = PR_FALSE; - } else { - *aPrintable = PR_TRUE; - } + *aPrintable = !mIsDoingPrinting; return NS_OK; } @@ -6807,7 +7138,7 @@ DocumentViewerImpl::GetPrintable(PRBool *aPrintable) //***************************************************************************** // nsIMarkupDocumentViewer -//***************************************************************************** +//***************************************************************************** NS_IMETHODIMP DocumentViewerImpl::ScrollToNode(nsIDOMNode* aNode) { @@ -6816,25 +7147,25 @@ NS_IMETHODIMP DocumentViewerImpl::ScrollToNode(nsIDOMNode* aNode) nsCOMPtr presShell; NS_ENSURE_SUCCESS(GetPresShell(*(getter_AddRefs(presShell))), NS_ERROR_FAILURE); - // Get the nsIContent interface, because that's what we need to + // Get the nsIContent interface, because that's what we need to // get the primary frame - + nsCOMPtr content(do_QueryInterface(aNode)); NS_ENSURE_TRUE(content, NS_ERROR_FAILURE); // Get the primary frame - nsIFrame* frame; // Remember Frames aren't ref-counted. They are in their + nsIFrame* frame; // Remember Frames aren't ref-counted. They are in their // own special little world. NS_ENSURE_SUCCESS(presShell->GetPrimaryFrameFor(content, &frame), NS_ERROR_FAILURE); // tell the pres shell to scroll to the frame - NS_ENSURE_SUCCESS(presShell->ScrollFrameIntoView(frame, - NS_PRESSHELL_SCROLL_TOP, - NS_PRESSHELL_SCROLL_ANYWHERE), - NS_ERROR_FAILURE); - return NS_OK; + NS_ENSURE_SUCCESS(presShell->ScrollFrameIntoView(frame, + NS_PRESSHELL_SCROLL_TOP, + NS_PRESSHELL_SCROLL_ANYWHERE), + NS_ERROR_FAILURE); + return NS_OK; } NS_IMETHODIMP DocumentViewerImpl::GetAllowPlugins(PRBool* aAllowPlugins) @@ -6860,17 +7191,17 @@ DocumentViewerImpl::CallChildren(CallChildFunc aFunc, void* aClosure) PRInt32 i; PRInt32 n; docShellNode->GetChildCount(&n); - for (i=0; i < n; i++) + for (i=0; i < n; i++) { nsCOMPtr child; docShellNode->GetChildAt(i, getter_AddRefs(child)); nsCOMPtr childAsShell(do_QueryInterface(child)); NS_ASSERTION(childAsShell, "null child in docshell"); - if (childAsShell) + if (childAsShell) { nsCOMPtr childCV; childAsShell->GetContentViewer(getter_AddRefs(childCV)); - if (childCV) + if (childCV) { nsCOMPtr markupCV = do_QueryInterface(childCV); if (markupCV) { @@ -6921,7 +7252,7 @@ NS_IMETHODIMP DocumentViewerImpl::GetTextZoom(float* aTextZoom) return NS_OK; } -// XXX: SEMANTIC CHANGE! +// XXX: SEMANTIC CHANGE! // returns a copy of the string. Caller is responsible for freeing result // using Recycle(aDefaultCharacterSet) NS_IMETHODIMP DocumentViewerImpl::GetDefaultCharacterSet(PRUnichar** aDefaultCharacterSet) @@ -6929,18 +7260,18 @@ NS_IMETHODIMP DocumentViewerImpl::GetDefaultCharacterSet(PRUnichar** aDefaultCha NS_ENSURE_ARG_POINTER(aDefaultCharacterSet); NS_ENSURE_STATE(mContainer); - if (mDefaultCharacterSet.IsEmpty()) + if (mDefaultCharacterSet.IsEmpty()) { nsXPIDLString defCharset; nsCOMPtr webShell; webShell = do_QueryInterface(mContainer); if (webShell) - { + { nsCOMPtr prefs(do_GetService(NS_PREF_CONTRACTID)); if (prefs) prefs->GetLocalizedUnicharPref("intl.charset.default", getter_Copies(defCharset)); - } + } if (!defCharset.IsEmpty()) mDefaultCharacterSet.Assign(defCharset.get()); @@ -6965,7 +7296,7 @@ NS_IMETHODIMP DocumentViewerImpl::SetDefaultCharacterSet(const PRUnichar* aDefau (void*) aDefaultCharacterSet); } -// XXX: SEMANTIC CHANGE! +// XXX: SEMANTIC CHANGE! // returns a copy of the string. Caller is responsible for freeing result // using Recycle(aForceCharacterSet) NS_IMETHODIMP DocumentViewerImpl::GetForceCharacterSet(PRUnichar** aForceCharacterSet) @@ -6995,7 +7326,7 @@ NS_IMETHODIMP DocumentViewerImpl::SetForceCharacterSet(const PRUnichar* aForceCh return CallChildren(SetChildForceCharacterSet, (void*) aForceCharacterSet); } -// XXX: SEMANTIC CHANGE! +// XXX: SEMANTIC CHANGE! // returns a copy of the string. Caller is responsible for freeing result // using Recycle(aHintCharacterSet) NS_IMETHODIMP DocumentViewerImpl::GetHintCharacterSet(PRUnichar * *aHintCharacterSet) @@ -7080,7 +7411,7 @@ NS_IMETHODIMP DocumentViewerImpl::GetBidiTextDirection(PRUint8* aTextDirection) #endif return NS_OK; } - + NS_IMETHODIMP DocumentViewerImpl::SetBidiTextType(PRUint8 aTextType) { #ifdef IBMBIDI @@ -7236,9 +7567,9 @@ NS_IMETHODIMP DocumentViewerImpl::SetBidiOptions(PRUint32 aBidiOptions) #ifdef IBMBIDI if (mPresContext) { #if 1 - // forcing reflow will cause bug 80352. Temp turn off force reflow and + // forcing reflow will cause bug 80352. Temp turn off force reflow and // wait for simon@softel.co.il to find the real solution - mPresContext->SetBidi(aBidiOptions, PR_FALSE); + mPresContext->SetBidi(aBidiOptions, PR_FALSE); #else mPresContext->SetBidi(aBidiOptions, PR_TRUE); // force reflow #endif @@ -7273,7 +7604,7 @@ NS_IMETHODIMP DocumentViewerImpl::SizeToContent() nsCOMPtr docShellParent; docShellAsItem->GetSameTypeParent(getter_AddRefs(docShellParent)); - // It's only valid to access this from a top frame. Doesn't work from + // It's only valid to access this from a top frame. Doesn't work from // sub-frames. NS_ENSURE_TRUE(!docShellParent, NS_ERROR_FAILURE); @@ -7362,7 +7693,7 @@ DocumentViewerImpl::GetPopupNode(nsIDOMNode** aNode) // get the internal dom window nsCOMPtr internalWin(do_QueryInterface(global, &rv)); NS_ENSURE_SUCCESS(rv, rv); - NS_ENSURE_TRUE(internalWin, NS_ERROR_FAILURE); + NS_ENSURE_TRUE(internalWin, NS_ERROR_FAILURE); // get the private dom window nsCOMPtr privateWin(do_QueryInterface(internalWin, &rv)); @@ -7534,20 +7865,20 @@ NS_IMETHODIMP nsDocViewerSelectionListener::NotifySelectionChanged(nsIDOMDocumen if (!mGotSelectionState || mSelectionWasCollapsed != selectionCollapsed) { nsCOMPtr theDoc; - mDocViewer->GetDocument(*getter_AddRefs(theDoc)); + mDocViewer->GetDocument(*getter_AddRefs(theDoc)); if (!theDoc) return NS_ERROR_FAILURE; - + nsCOMPtr scriptGlobalObject; theDoc->GetScriptGlobalObject(getter_AddRefs(scriptGlobalObject)); nsCOMPtr domWindow = do_QueryInterface(scriptGlobalObject); if (!domWindow) return NS_ERROR_FAILURE; - + domWindow->UpdateCommands(NS_LITERAL_STRING("select")); mGotSelectionState = PR_TRUE; mSelectionWasCollapsed = selectionCollapsed; - } - + } + return NS_OK; } @@ -7584,7 +7915,7 @@ nsDocViewerFocusListener::Focus(nsIDOMEvent* aEvent) selCon->GetDisplaySelection( &selectionStatus); //if selection was nsISelectionController::SELECTION_OFF, do nothing - //otherwise re-enable it. + //otherwise re-enable it. if(selectionStatus == nsISelectionController::SELECTION_DISABLED || selectionStatus == nsISelectionController::SELECTION_HIDDEN) { @@ -7598,7 +7929,7 @@ NS_IMETHODIMP nsDocViewerFocusListener::Blur(nsIDOMEvent* aEvent) { nsCOMPtr shell; - if(!mDocViewer) + if(!mDocViewer) return NS_ERROR_FAILURE; nsresult result = mDocViewer->GetPresShell(*getter_AddRefs(shell));//deref once cause it take a ptr ref @@ -7608,7 +7939,7 @@ nsDocViewerFocusListener::Blur(nsIDOMEvent* aEvent) selCon = do_QueryInterface(shell); PRInt16 selectionStatus; selCon->GetDisplaySelection(&selectionStatus); - + //if selection was nsISelectionController::SELECTION_OFF, do nothing //otherwise re-enable it. if(selectionStatus == nsISelectionController::SELECTION_ON) @@ -7628,7 +7959,7 @@ nsDocViewerFocusListener::Init(DocumentViewerImpl *aDocViewer) } -PRBool +PRBool DocumentViewerImpl::IsWindowsInOurSubTree(nsIDOMWindowInternal * aDOMWindow) { PRBool found = PR_FALSE; @@ -7669,7 +8000,7 @@ DocumentViewerImpl::IsWindowsInOurSubTree(nsIDOMWindowInternal * aDOMWindow) //---------------------------------------------------------------------------------- -void +void DocumentViewerImpl::CleanupDocTitleArray(PRUnichar**& aArray, PRInt32& aCount) { for (PRInt32 i = aCount - 1; i >= 0; i--) { @@ -7682,8 +8013,8 @@ DocumentViewerImpl::CleanupDocTitleArray(PRUnichar**& aArray, PRInt32& aCount) //---------------------------------------------------------------------------------- // Enumerate all the documents for their titles -NS_IMETHODIMP -DocumentViewerImpl::EnumerateDocumentNames(PRUint32* aCount, +NS_IMETHODIMP +DocumentViewerImpl::EnumerateDocumentNames(PRUint32* aCount, PRUnichar*** aResult) { NS_ENSURE_ARG(aCount); @@ -7691,12 +8022,12 @@ DocumentViewerImpl::EnumerateDocumentNames(PRUint32* aCount, *aCount = 0; *aResult = nsnull; - + PRInt32 numDocs = mPrt->mPrintDocList->Count(); PRUnichar** array = (PRUnichar**) nsMemory::Alloc(numDocs * sizeof(PRUnichar*)); - if (!array) + if (!array) return NS_ERROR_OUT_OF_MEMORY; - + for (PRInt32 i=0;imPrintDocList->ElementAt(i); NS_ASSERTION(po, "PrintObject can't be null!"); @@ -7729,7 +8060,7 @@ DocumentViewerImpl::EnumerateDocumentNames(PRUint32* aCount, } /* readonly attribute nsIPrintSettings newPrintSettings; */ -NS_IMETHODIMP +NS_IMETHODIMP DocumentViewerImpl::GetNewPrintSettings(nsIPrintSettings * *aNewPrintSettings) { NS_ENSURE_ARG_POINTER(aNewPrintSettings); @@ -7744,7 +8075,7 @@ DocumentViewerImpl::GetNewPrintSettings(nsIPrintSettings * *aNewPrintSettings) } /* readonly attribute wstring defaultPrinterName; */ -NS_IMETHODIMP +NS_IMETHODIMP DocumentViewerImpl::GetDefaultPrinterName(PRUnichar * *aDefaultPrinterName) { NS_ENSURE_ARG_POINTER(aDefaultPrinterName); @@ -7758,7 +8089,7 @@ DocumentViewerImpl::GetDefaultPrinterName(PRUnichar * *aDefaultPrinterName) } /* void initPrintSettingsFromPrinter (in wstring aPrinterName, in nsIPrintSettings aPrintSettings); */ -NS_IMETHODIMP +NS_IMETHODIMP DocumentViewerImpl::InitPrintSettingsFromPrinter(const PRUnichar *aPrinterName, nsIPrintSettings *aPrintSettings) { NS_ENSURE_ARG_POINTER(aPrintSettings); @@ -7780,7 +8111,7 @@ DocumentViewerImpl::InitPrintSettingsFromPrinter(const PRUnichar *aPrinterName, } /* readonly attribute nsIPrintSettings globalPrintSettings; */ -NS_IMETHODIMP +NS_IMETHODIMP DocumentViewerImpl::GetGlobalPrintSettings(nsIPrintSettings * *aGlobalPrintSettings) { NS_ENSURE_ARG_POINTER(aGlobalPrintSettings); @@ -7799,11 +8130,34 @@ DocumentViewerImpl::GetDoingPrintPreview(PRBool *aDoingPrintPreview) { NS_ENSURE_ARG_POINTER(aDoingPrintPreview); *aDoingPrintPreview = mIsDoingPrintPreview; + + if (!*aDoingPrintPreview) { + nsCOMPtr item(do_QueryInterface(mContainer)); + nsCOMPtr viewer; + + if (item) { + nsCOMPtr parent; + item->GetParent(getter_AddRefs(parent)); + + nsCOMPtr docShell(do_QueryInterface(parent)); + + if (docShell) { + docShell->GetContentViewer(getter_AddRefs(viewer)); + } + } + + nsCOMPtr wbp(do_QueryInterface(viewer)); + + if (wbp) { + return wbp->GetDoingPrintPreview(aDoingPrintPreview); + } + } + return NS_OK; } /* readonly attribute nsIPrintSettings currentPrintSettings; */ -NS_IMETHODIMP +NS_IMETHODIMP DocumentViewerImpl::GetCurrentPrintSettings(nsIPrintSettings * *aCurrentPrintSettings) { NS_ENSURE_ARG_POINTER(aCurrentPrintSettings); @@ -7822,7 +8176,7 @@ DocumentViewerImpl::GetCurrentPrintSettings(nsIPrintSettings * *aCurrentPrintSet } /* void cancel (); */ -NS_IMETHODIMP +NS_IMETHODIMP DocumentViewerImpl::Cancel() { nsresult rv; @@ -7834,7 +8188,7 @@ DocumentViewerImpl::Cancel() } /* void initPrintSettingsFromPrefs (in nsIPrintSettings aPrintSettings, in boolean aUsePrinterNamePrefix, in unsigned long aFlags); */ -NS_IMETHODIMP +NS_IMETHODIMP DocumentViewerImpl::InitPrintSettingsFromPrefs(nsIPrintSettings *aPrintSettings, PRBool aUsePrinterNamePrefix, PRUint32 aFlags) { nsresult rv; @@ -7846,7 +8200,7 @@ DocumentViewerImpl::InitPrintSettingsFromPrefs(nsIPrintSettings *aPrintSettings, } /* void savePrintSettingsToPrefs (in nsIPrintSettings aPrintSettings, in boolean aUsePrinterNamePrefix, in unsigned long aFlags); */ -NS_IMETHODIMP +NS_IMETHODIMP DocumentViewerImpl::SavePrintSettingsToPrefs(nsIPrintSettings *aPrintSettings, PRBool aUsePrinterNamePrefix, PRUint32 aFlags) { nsresult rv; @@ -7859,7 +8213,7 @@ DocumentViewerImpl::SavePrintSettingsToPrefs(nsIPrintSettings *aPrintSettings, P /** --------------------------------------------------- * Get the Focused Frame for a documentviewer - * + * */ nsIDOMWindowInternal* DocumentViewerImpl::FindFocusedDOMWindowInternal() @@ -7870,7 +8224,7 @@ DocumentViewerImpl::FindFocusedDOMWindowInternal() nsCOMPtr focusController; nsIDOMWindowInternal * domWin = nsnull; - this->GetDocument(*getter_AddRefs(theDoc)); + this->GetDocument(*getter_AddRefs(theDoc)); if(theDoc){ theDoc->GetScriptGlobalObject(getter_AddRefs(theSGO)); if(theSGO){ @@ -7896,7 +8250,7 @@ DocumentViewerImpl::FindFocusedDOMWindowInternal() /*=============== Timer Related Code ======================*/ nsresult -DocumentViewerImpl::StartPagePrintTimer(nsIPresContext * aPresContext, +DocumentViewerImpl::StartPagePrintTimer(nsIPresContext * aPresContext, nsIPrintSettings* aPrintSettings, PrintObject* aPOect, PRUint32 aDelay) diff --git a/layout/base/nsIPresShell.h b/layout/base/nsIPresShell.h index e018c206ce5..8293f2fc5b2 100644 --- a/layout/base/nsIPresShell.h +++ b/layout/base/nsIPresShell.h @@ -265,28 +265,6 @@ public: NS_IMETHOD GetLayoutObjectFor(nsIContent* aContent, nsISupports** aResult) const = 0; - /** - * Returns the object that acts as a subshell for aContent. - * For example, for an html frame aResult will be an nsIDocShell. - */ - NS_IMETHOD GetSubShellFor(nsIContent* aContent, - nsISupports** aResult) const = 0; - - /** - * Establish a relationship between aContent and aSubShell. - * aSubShell will be returned from GetSubShellFor(aContent, ...); - */ - NS_IMETHOD SetSubShellFor(nsIContent* aContent, - nsISupports* aSubShell) = 0; - - /** - * Find the content in the map that has aSubShell set - * as its subshell. If there is more than one mapping for - * aSubShell, the result is undefined. - */ - NS_IMETHOD FindContentForShell(nsISupports* aSubShell, - nsIContent** aContent) const = 0; - /** * Gets the placeholder frame associated with the specified frame. This is * a helper frame that forwards the request to the frame manager. diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 8cff3e1ac5d..eae9dbe2552 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -166,9 +166,6 @@ #include "nsIContentViewer.h" #include "nsIDocumentViewer.h" -// SubShell map -#include "pldhash.h" - #ifdef IBMBIDI #include "nsIBidiKeyboard.h" #endif // IBMBIDI @@ -809,14 +806,6 @@ DummyLayoutRequest::Cancel(nsresult status) // ---------------------------------------------------------------------------- -class SubShellMapEntry : public PLDHashEntryHdr { - public: - nsIContent *key; // must be first, to look like PLDHashEntryStub - nsISupports *subShell; -}; - -// ---------------------------------------------------------------------------- - class PresShell : public nsIPresShell, public nsIViewObserver, private nsIDocumentObserver, public nsIFocusTracker, public nsISelectionController, @@ -877,12 +866,6 @@ public: nsIStyleContext** aStyleContext) const; NS_IMETHOD GetLayoutObjectFor(nsIContent* aContent, nsISupports** aResult) const; - NS_IMETHOD GetSubShellFor(nsIContent* aContent, - nsISupports** aResult) const; - NS_IMETHOD SetSubShellFor(nsIContent* aContent, - nsISupports* aSubShell); - NS_IMETHOD FindContentForShell(nsISupports* aSubShell, - nsIContent** aContent) const; NS_IMETHOD GetPlaceholderFrameFor(nsIFrame* aFrame, nsIFrame** aPlaceholderFrame) const; NS_IMETHOD AppendReflowCommand(nsHTMLReflowCommand* aReflowCommand); @@ -1235,9 +1218,6 @@ protected: static void sPaintSuppressionCallback(nsITimer* aTimer, void* aPresShell); // A callback for the timer. - // subshell map - PLDHashTable* mSubShellMap; // map of content/subshell pairs - MOZ_TIMER_DECLARE(mReflowWatch) // Used for measuring time spent in reflow MOZ_TIMER_DECLARE(mFrameCreationWatch) // Used for measuring time spent in frame creation @@ -1678,13 +1658,6 @@ PresShell::Destroy() // Clobber weak leaks in case of re-entrancy during tear down mHistoryState = nsnull; - // kill subshell map, if any. It holds only weak references - if (mSubShellMap) - { - PL_DHashTableDestroy(mSubShellMap); - mSubShellMap = nsnull; - } - // release current event content and any content on event stack NS_IF_RELEASE(mCurrentEventContent); @@ -5553,94 +5526,6 @@ PresShell::GetLayoutObjectFor(nsIContent* aContent, return result; } - -NS_IMETHODIMP -PresShell::GetSubShellFor(nsIContent* aContent, - nsISupports** aResult) const -{ - NS_ENSURE_ARG_POINTER(aContent); - - if (mSubShellMap) { - SubShellMapEntry *entry = NS_STATIC_CAST(SubShellMapEntry*, - PL_DHashTableOperate(mSubShellMap, aContent, PL_DHASH_LOOKUP)); - if (PL_DHASH_ENTRY_IS_BUSY(entry)) { - NS_ADDREF(*aResult = entry->subShell); - return NS_OK; - } - } - - *aResult = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -PresShell::SetSubShellFor(nsIContent* aContent, - nsISupports* aSubShell) -{ - NS_ENSURE_ARG_POINTER(aContent); - - // If aSubShell is NULL, then remove the mapping - if (!aSubShell) { - if (mSubShellMap) - PL_DHashTableOperate(mSubShellMap, aContent, PL_DHASH_REMOVE); - } else { - // Create a new hashtable if necessary - if (!mSubShellMap) { - mSubShellMap = PL_NewDHashTable(PL_DHashGetStubOps(), nsnull, - sizeof(SubShellMapEntry), 16); - if (!mSubShellMap) - return NS_ERROR_OUT_OF_MEMORY; - } - - // Add a mapping to the hash table - SubShellMapEntry *entry = NS_STATIC_CAST(SubShellMapEntry*, - PL_DHashTableOperate(mSubShellMap, aContent, PL_DHASH_ADD)); - entry->key = aContent; - entry->subShell = aSubShell; - } - return NS_OK; -} - -struct FindContentData { - FindContentData(nsISupports *aSubShell) - : subShell(aSubShell), result(nsnull) {} - - nsISupports *subShell; - nsIContent *result; -}; - -PR_STATIC_CALLBACK(PLDHashOperator) -FindContentEnumerator(PLDHashTable *table, PLDHashEntryHdr *hdr, - PRUint32 number, void *arg) -{ - SubShellMapEntry *entry = NS_STATIC_CAST(SubShellMapEntry*, hdr); - FindContentData *data = NS_STATIC_CAST(FindContentData*, arg); - - if (entry->subShell == data->subShell) { - data->result = entry->key; - return PL_DHASH_STOP; - } - return PL_DHASH_NEXT; -} - -NS_IMETHODIMP -PresShell::FindContentForShell(nsISupports* aSubShell, - nsIContent** aContent) const -{ - NS_ENSURE_ARG_POINTER(aSubShell); - - if (!mSubShellMap) { - *aContent = nsnull; - return NS_OK; - } - - FindContentData data(aSubShell); - PL_DHashTableEnumerate(mSubShellMap, FindContentEnumerator, &data); - NS_IF_ADDREF(*aContent = data.result); - - return NS_OK; -} - NS_IMETHODIMP PresShell::GetPlaceholderFrameFor(nsIFrame* aFrame, nsIFrame** aResult) const diff --git a/layout/base/public/nsIPresShell.h b/layout/base/public/nsIPresShell.h index e018c206ce5..8293f2fc5b2 100644 --- a/layout/base/public/nsIPresShell.h +++ b/layout/base/public/nsIPresShell.h @@ -265,28 +265,6 @@ public: NS_IMETHOD GetLayoutObjectFor(nsIContent* aContent, nsISupports** aResult) const = 0; - /** - * Returns the object that acts as a subshell for aContent. - * For example, for an html frame aResult will be an nsIDocShell. - */ - NS_IMETHOD GetSubShellFor(nsIContent* aContent, - nsISupports** aResult) const = 0; - - /** - * Establish a relationship between aContent and aSubShell. - * aSubShell will be returned from GetSubShellFor(aContent, ...); - */ - NS_IMETHOD SetSubShellFor(nsIContent* aContent, - nsISupports* aSubShell) = 0; - - /** - * Find the content in the map that has aSubShell set - * as its subshell. If there is more than one mapping for - * aSubShell, the result is undefined. - */ - NS_IMETHOD FindContentForShell(nsISupports* aSubShell, - nsIContent** aContent) const = 0; - /** * Gets the placeholder frame associated with the specified frame. This is * a helper frame that forwards the request to the frame manager. diff --git a/layout/build/nsContentDLF.cpp b/layout/build/nsContentDLF.cpp index 5dbb7e3668c..98026f58e1d 100644 --- a/layout/build/nsContentDLF.cpp +++ b/layout/build/nsContentDLF.cpp @@ -416,6 +416,8 @@ nsContentDLF::CreateDocument(const char* aCommand, break; docv->SetUAStyleSheet(gUAStyleSheet); + doc->SetContainer(aContainer); + // Initialize the document to begin loading the data. An // nsIStreamListener connected to the parser is returned in // aDocListener. @@ -512,6 +514,9 @@ nsContentDLF::CreateRDFDocument(const char* aCommand, * An nsIStreamListener connected to the parser is returned in * aDocListener. */ + + doc->SetContainer(aContainer); + rv = doc->StartDocumentLoad(aCommand, aChannel, aLoadGroup, aContainer, aDocListener, PR_TRUE); if (NS_SUCCEEDED(rv)) { /* diff --git a/layout/generic/nsFrameFrame.cpp b/layout/generic/nsFrameFrame.cpp index bbff77b79d8..2c7fa1b714c 100644 --- a/layout/generic/nsFrameFrame.cpp +++ b/layout/generic/nsFrameFrame.cpp @@ -72,6 +72,7 @@ #include "nsFrameSetFrame.h" #include "nsIDOMHTMLFrameElement.h" #include "nsIDOMHTMLIFrameElement.h" +#include "nsIFrameLoader.h" #include "nsLayoutAtoms.h" #include "nsIChromeEventHandler.h" #include "nsIScriptSecurityManager.h" @@ -84,13 +85,16 @@ #include "nsIWidget.h" #include "nsIWebProgress.h" #include "nsIWebProgressListener.h" +#include "nsIWebBrowserPrint.h" #include "nsWeakReference.h" #include "nsIDOMEventTarget.h" #include "nsIDOMEventListener.h" #include "nsIDOMWindow.h" +#include "nsIDOMDocument.h" +#include "nsPIDOMWindow.h" #include "nsIRenderingContext.h" -// For Accessibility +// For Accessibility #ifdef ACCESSIBILITY #include "nsIAccessibilityService.h" #endif @@ -98,20 +102,12 @@ class nsHTMLFrame; -static NS_DEFINE_IID(kIFramesetFrameIID, NS_IFRAMESETFRAME_IID); -static NS_DEFINE_CID(kWebShellCID, NS_WEB_SHELL_CID); static NS_DEFINE_CID(kCViewCID, NS_VIEW_CID); static NS_DEFINE_CID(kCChildCID, NS_CHILD_CID); -// Bug 8065: Limit content frame depth to some reasonable level. -// This does not count chrome frames when determining depth, -// nor does it prevent chrome recursion. -// Also see bug 126466. -#define MAX_DEPTH_CONTENT_FRAMES 8 - -/******************************************************************************* +/****************************************************************************** * FrameLoadingInfo - ******************************************************************************/ + *****************************************************************************/ class FrameLoadingInfo : public nsISupports { public: @@ -128,9 +124,9 @@ public: }; -/******************************************************************************* +/****************************************************************************** * nsHTMLFrameOuterFrame - ******************************************************************************/ + *****************************************************************************/ #define nsHTMLFrameOuterFrameSuper nsHTMLContainerFrame class nsHTMLFrameOuterFrame : public nsHTMLFrameOuterFrameSuper { @@ -142,7 +138,7 @@ public: NS_IMETHOD GetFrameName(nsAString& aResult) const; #endif - // nsISupports + // nsISupports NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); NS_IMETHOD GetFrameType(nsIAtom** aType) const; @@ -168,7 +164,7 @@ public: nsIContent* aChild, PRInt32 aNameSpaceID, nsIAtom* aAttribute, - PRInt32 aModType, + PRInt32 aModType, PRInt32 aHint); #ifdef ACCESSIBILITY @@ -188,11 +184,10 @@ protected: nsCOMPtr mPresContext; }; -/******************************************************************************* +/****************************************************************************** * nsHTMLFrameInnerFrame - ******************************************************************************/ + *****************************************************************************/ class nsHTMLFrameInnerFrame : public nsLeafFrame, - public nsIWebProgressListener, public nsSupportsWeakReference { public: @@ -202,8 +197,6 @@ public: NS_IMETHOD_(nsrefcnt) AddRef(void) { return 2; } NS_IMETHOD_(nsrefcnt) Release(void) { return 1; } - NS_DECL_NSIWEBPROGRESSLISTENER - #ifdef DEBUG NS_IMETHOD GetFrameName(nsAString& aResult) const; #endif @@ -237,7 +230,9 @@ public: nsIStyleContext* aContext, nsIFrame* aPrevInFlow); - NS_IMETHOD GetParentContent(nsIContent*& aContent); + void GetParentContent(nsIContent** aContent); + nsresult GetDocShell(nsIDocShell **aDocShell); + PRBool GetURL(nsIContent* aContent, nsString& aResult); PRBool GetName(nsIContent* aContent, nsString& aResult); PRInt32 GetScrolling(nsIContent* aContent); @@ -245,13 +240,10 @@ public: PRInt32 GetMarginWidth(nsIPresContext* aPresContext, nsIContent* aContent); PRInt32 GetMarginHeight(nsIPresContext* aPresContext, nsIContent* aContent); - nsresult ReloadURL(nsIPresContext* aPresContext); - friend class nsHTMLFrameOuterFrame; protected: - nsresult CreateDocShell(nsIPresContext* aPresContext); - nsresult DoLoadURL(nsIPresContext* aPresContext); + nsresult ShowDocShell(nsIPresContext* aPresContext); nsresult CreateViewAndWidget(nsIPresContext* aPresContext, nsIWidget** aWidget); @@ -261,15 +253,18 @@ protected: const nsHTMLReflowState& aReflowState, nsHTMLReflowMetrics& aDesiredSize); - nsCOMPtr mSubShell; - nsWeakPtr mPresShellWeak; // weak reference to the nsIPresShell - PRBool mCreatingViewer; + nsresult ReloadURL(); + + nsCOMPtr mFrameLoader; + PRPackedBool mOwnsFrameLoader; + + PRPackedBool mCreatingViewer; }; -/******************************************************************************* +/****************************************************************************** * nsHTMLFrameOuterFrame - ******************************************************************************/ + *****************************************************************************/ nsHTMLFrameOuterFrame::nsHTMLFrameOuterFrame() : nsHTMLContainerFrame() { @@ -349,7 +344,7 @@ nsHTMLFrameOuterFrame::Init(nsIPresContext* aPresContext, view->GetWidget(*getter_AddRefs(widget)); if (!widget) - view->CreateWidget(kCChildCID); + view->CreateWidget(kCChildCID); } nsCOMPtr shell; @@ -387,7 +382,7 @@ nsHTMLFrameOuterFrame::GetSkipSides() const return 0; } -void +void nsHTMLFrameOuterFrame::GetDesiredSize(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsHTMLReflowMetrics& aDesiredSize) @@ -422,7 +417,7 @@ nsHTMLFrameOuterFrame::GetDesiredSize(nsIPresContext* aPresContext, } PRBool nsHTMLFrameOuterFrame::IsInline() -{ +{ return mIsInline; } @@ -463,7 +458,7 @@ NS_IMETHODIMP nsHTMLFrameOuterFrame::GetFrameType(nsIAtom** aType) const { NS_PRECONDITION(nsnull != aType, "null OUT parameter pointer"); - *aType = nsLayoutAtoms::htmlFrameOuterFrame; + *aType = nsLayoutAtoms::htmlFrameOuterFrame; NS_ADDREF(*aType); return NS_OK; } @@ -476,7 +471,7 @@ nsHTMLFrameOuterFrame::Reflow(nsIPresContext* aPresContext, { DO_GLOBAL_REFLOW_COUNT("nsHTMLFrameOuterFrame", aReflowState.reason); DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus); - //printf("OuterFrame::Reflow %X (%d,%d) \n", this, aReflowState.availableWidth, aReflowState.availableHeight); + //printf("OuterFrame::Reflow %X (%d,%d) \n", this, aReflowState.availableWidth, aReflowState.availableHeight); NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS, ("enter nsHTMLFrameOuterFrame::Reflow: maxSize=%d,%d reason=%d", aReflowState.availableWidth, aReflowState.availableHeight, aReflowState.reason)); @@ -551,37 +546,40 @@ nsHTMLFrameOuterFrame::AttributeChanged(nsIPresContext* aPresContext, nsIContent* aChild, PRInt32 aNameSpaceID, nsIAtom* aAttribute, - PRInt32 aModType, + PRInt32 aModType, PRInt32 aHint) { nsCOMPtr type; aChild->GetTag(*getter_AddRefs(type)); - if (((nsHTMLAtoms::src == aAttribute) && (nsHTMLAtoms::object != type)) || - ((nsHTMLAtoms::data == aAttribute) && (nsHTMLAtoms::object == type))) { - nsHTMLFrameInnerFrame* firstChild = NS_STATIC_CAST(nsHTMLFrameInnerFrame*, - mFrames.FirstChild()); + if ((type != nsHTMLAtoms::object && aAttribute == nsHTMLAtoms::src) || + (type == nsHTMLAtoms::object && aAttribute == nsHTMLAtoms::data)) { + nsHTMLFrameInnerFrame* firstChild = + NS_STATIC_CAST(nsHTMLFrameInnerFrame*, mFrames.FirstChild()); + if (firstChild) { - firstChild->ReloadURL(aPresContext); + firstChild->ReloadURL(); } } // If the noResize attribute changes, dis/allow frame to be resized - else if (nsHTMLAtoms::noresize == aAttribute) { + else if (aAttribute == nsHTMLAtoms::noresize) { nsCOMPtr parentContent; mContent->GetParent(*getter_AddRefs(parentContent)); nsCOMPtr parentTag; parentContent->GetTag(*getter_AddRefs(parentTag)); - if (nsHTMLAtoms::frameset == parentTag) { + if (parentTag == nsHTMLAtoms::frameset) { nsIFrame* parentFrame = nsnull; GetParent(&parentFrame); if (parentFrame) { - // There is no interface for kIFramesetFrameIID - // so QI'ing to concrete class, yay! + // There is no interface for nsHTMLFramesetFrame so QI'ing to + // concrete class, yay! nsHTMLFramesetFrame* framesetFrame = nsnull; - parentFrame->QueryInterface(kIFramesetFrameIID, (void **)&framesetFrame); + parentFrame->QueryInterface(NS_GET_IID(nsHTMLFramesetFrame), + (void **)&framesetFrame); + if (framesetFrame) { framesetFrame->RecalculateBorderResize(); } @@ -590,37 +588,45 @@ nsHTMLFrameOuterFrame::AttributeChanged(nsIPresContext* aPresContext, } else if (aAttribute == nsHTMLAtoms::type) { nsHTMLFrameInnerFrame* firstChild = NS_STATIC_CAST(nsHTMLFrameInnerFrame*, - mFrames.FirstChild()); - if (!firstChild) + mFrames.FirstChild()); + if (!firstChild || !firstChild->mFrameLoader) return NS_OK; nsAutoString value; aChild->GetAttr(kNameSpaceID_None, nsHTMLAtoms::type, value); - + // Notify our enclosing chrome that the primary content shell // has changed. - nsCOMPtr docShell(do_QueryInterface(firstChild->mSubShell)); - nsCOMPtr docShellAsItem(do_QueryInterface(firstChild->mSubShell)); - + + nsCOMPtr docShell; + firstChild->mFrameLoader->GetDocShell(getter_AddRefs(docShell)); + + nsCOMPtr docShellAsItem(do_QueryInterface(docShell)); + // If our container is a web-shell, inform it that it has a new // child. If it's not a web-shell then some things will not operate // properly. nsCOMPtr container; aPresContext->GetContainer(getter_AddRefs(container)); - if (container) { - nsCOMPtr parentAsNode(do_QueryInterface(container)); - if (parentAsNode) { - nsCOMPtr parentAsItem(do_QueryInterface(parentAsNode)); - - nsCOMPtr parentTreeOwner; - parentAsItem->GetTreeOwner(getter_AddRefs(parentTreeOwner)); - if (parentTreeOwner) - parentTreeOwner->ContentShellAdded(docShellAsItem, - value.EqualsIgnoreCase("content-primary") ? PR_TRUE : PR_FALSE, - value.get()); + + nsCOMPtr parentAsNode(do_QueryInterface(container)); + + if (parentAsNode) { + nsCOMPtr parentAsItem = + do_QueryInterface(parentAsNode); + + nsCOMPtr parentTreeOwner; + parentAsItem->GetTreeOwner(getter_AddRefs(parentTreeOwner)); + if (parentTreeOwner) { + PRBool is_primary_content = + value.EqualsIgnoreCase("content-primary"); + + parentTreeOwner->ContentShellAdded(docShellAsItem, is_primary_content, + value.get()); } } } + return NS_OK; } @@ -639,49 +645,50 @@ NS_NewHTMLFrameOuterFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) return NS_OK; } -/******************************************************************************* +/****************************************************************************** * nsHTMLFrameInnerFrame - ******************************************************************************/ + *****************************************************************************/ nsHTMLFrameInnerFrame::nsHTMLFrameInnerFrame() - : nsLeafFrame() + : nsLeafFrame(), mOwnsFrameLoader(PR_FALSE), mCreatingViewer(PR_FALSE) { - mCreatingViewer = PR_FALSE; - mPresShellWeak = nsnull; } nsHTMLFrameInnerFrame::~nsHTMLFrameInnerFrame() { - //printf("nsHTMLFrameInnerFrame destructor %X \n", this); + if (mFrameLoader) { + // Get the content viewer through the docshell, but don't call + // GetDocShell() since we don't want to create one if we don't + // have one. - nsCOMPtr win(do_GetInterface(mSubShell)); - nsCOMPtr eventTarget(do_QueryInterface(win)); - nsCOMPtr eventListener(do_QueryInterface(mContent)); + nsCOMPtr docShell; + mFrameLoader->GetDocShell(getter_AddRefs(docShell)); - if (eventTarget && eventListener) { - eventTarget->RemoveEventListener(NS_LITERAL_STRING("load"), eventListener, - PR_FALSE); - } + if (docShell) { + nsCOMPtr content_viewer; + docShell->GetContentViewer(getter_AddRefs(content_viewer)); - if(mSubShell) { - // notify the pres shell that a docshell has been destroyed - if (mPresShellWeak) { - nsCOMPtr ps = do_QueryReferent(mPresShellWeak); - if (ps) { - ps->SetSubShellFor(mContent, nsnull); + if (content_viewer) { + // Hide the content viewer now that the frame is going away... + + content_viewer->Hide(); } } - mSubShell->Destroy(); } - mSubShell = nsnull; // This is the location it was released before... - // Not sure if there is ordering depending on this. + + if (mFrameLoader && mOwnsFrameLoader) { + // We own this frame loader, and we're going away, so destroy our + // frame loader. + + mFrameLoader->Destroy(); + } } PRBool nsHTMLFrameInnerFrame::GetURL(nsIContent* aContent, nsString& aResult) { - aResult.SetLength(0); + aResult.SetLength(0); nsCOMPtr type; aContent->GetTag(*getter_AddRefs(type)); - + if (type.get() == nsHTMLAtoms::object) { if (NS_CONTENT_ATTR_HAS_VALUE == (aContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::data, aResult))) if (aResult.Length() > 0) @@ -696,7 +703,7 @@ PRBool nsHTMLFrameInnerFrame::GetURL(nsIContent* aContent, nsString& aResult) PRBool nsHTMLFrameInnerFrame::GetName(nsIContent* aContent, nsString& aResult) { - aResult.SetLength(0); + aResult.SetLength(0); if (NS_CONTENT_ATTR_HAS_VALUE == (aContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::name, aResult))) { if (aResult.Length() > 0) { @@ -735,7 +742,7 @@ PRInt32 nsHTMLFrameInnerFrame::GetScrolling(nsIContent* aContent) returnValue = NS_STYLE_OVERFLOW_AUTO; break; } - } + } } // Check style for overflow @@ -809,12 +816,6 @@ nsHTMLFrameInnerFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr) { NS_ENSURE_ARG_POINTER(aInstancePtr); - if (aIID.Equals(NS_GET_IID(nsIWebProgressListener))) { - nsISupports *tmp = NS_STATIC_CAST(nsIWebProgressListener *, this); - *aInstancePtr = tmp; - return NS_OK; - } - if (aIID.Equals(NS_GET_IID(nsISupportsWeakReference))) { nsISupports *tmp = NS_STATIC_CAST(nsISupportsWeakReference *, this); *aInstancePtr = tmp; @@ -824,60 +825,6 @@ nsHTMLFrameInnerFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr) return nsLeafFrame::QueryInterface(aIID, aInstancePtr); } -NS_IMETHODIMP -nsHTMLFrameInnerFrame::OnStateChange(nsIWebProgress *aWebProgress, - nsIRequest *aRequest, - PRInt32 aStateFlags, PRUint32 aStatus) -{ - if (!((~aStateFlags) & (nsIWebProgressListener::STATE_IS_DOCUMENT | - nsIWebProgressListener::STATE_TRANSFERRING))) { - nsCOMPtr win(do_GetInterface(mSubShell)); - nsCOMPtr eventTarget(do_QueryInterface(win)); - nsCOMPtr eventListener(do_QueryInterface(mContent)); - - if (eventTarget && eventListener) { - eventTarget->AddEventListener(NS_LITERAL_STRING("load"), eventListener, - PR_FALSE); - } - } - - return NS_OK; -} - -NS_IMETHODIMP -nsHTMLFrameInnerFrame::OnProgressChange(nsIWebProgress *aWebProgress, - nsIRequest *aRequest, - PRInt32 aCurSelfProgress, - PRInt32 aMaxSelfProgress, - PRInt32 aCurTotalProgress, - PRInt32 aMaxTotalProgress) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsHTMLFrameInnerFrame::OnLocationChange(nsIWebProgress *aWebProgress, - nsIRequest *aRequest, nsIURI *location) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsHTMLFrameInnerFrame::OnStatusChange(nsIWebProgress *aWebProgress, - nsIRequest *aRequest, - nsresult aStatus, - const PRUnichar *aMessage) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsHTMLFrameInnerFrame::OnSecurityChange(nsIWebProgress *aWebProgress, - nsIRequest *aRequest, PRInt32 state) -{ - return NS_OK; -} - #ifdef DEBUG NS_IMETHODIMP nsHTMLFrameInnerFrame::GetFrameName(nsAString& aResult) const { @@ -889,7 +836,7 @@ NS_IMETHODIMP nsHTMLFrameInnerFrame::GetFrameType(nsIAtom** aType) const { NS_PRECONDITION(nsnull != aType, "null OUT parameter pointer"); - *aType = nsLayoutAtoms::htmlFrameInnerFrame; + *aType = nsLayoutAtoms::htmlFrameInnerFrame; NS_ADDREF(*aType); return NS_OK; } @@ -901,33 +848,90 @@ nsHTMLFrameInnerFrame::Paint(nsIPresContext* aPresContext, nsFramePaintLayer aWhichLayer, PRUint32 aFlags) { - //printf("inner paint %X (%d,%d,%d,%d) \n", this, aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height); - // if there is not web shell paint based on our background color, - // otherwise let the web shell paint the sub document + //printf("inner paint %X (%d,%d,%d,%d) \n", this, aDirtyRect.x, + //aDirtyRect.y, aDirtyRect.width, aDirtyRect.height); if there is + //not web shell paint based on our background color, otherwise let + //the web shell paint the sub document - // isPaginated is a temporary fix for Bug 75737 - // and this should all be fixed correctly by Bug 75739 + // isPaginated is a temporary fix for Bug 75737 and this should all + // be fixed correctly by Bug 75739 PRBool isPaginated; aPresContext->IsPaginated(&isPaginated); - if (!mSubShell && !isPaginated) { - const nsStyleBackground* color = - (const nsStyleBackground*)mStyleContext->GetStyleData(eStyleStruct_Background); - aRenderingContext.SetColor(color->mBackgroundColor); - aRenderingContext.FillRect(mRect); + + if (!isPaginated) { + nsCOMPtr docShell; + GetDocShell(getter_AddRefs(docShell)); + + if (!docShell) { + const nsStyleBackground* color = + (const nsStyleBackground*)mStyleContext-> + GetStyleData(eStyleStruct_Background); + + aRenderingContext.SetColor(color->mBackgroundColor); + aRenderingContext.FillRect(mRect); + } } + DO_GLOBAL_REFLOW_COUNT_DSP("nsHTMLFrameInnerFrame", &aRenderingContext); + return NS_OK; } -NS_IMETHODIMP -nsHTMLFrameInnerFrame::GetParentContent(nsIContent*& aContent) +void +nsHTMLFrameInnerFrame::GetParentContent(nsIContent** aContent) { - nsHTMLFrameOuterFrame* parent; - nsresult rv = GetParent((nsIFrame**)&parent); - if (NS_SUCCEEDED(rv) && parent) { - rv = parent->GetContent(&aContent); + *aContent = nsnull; + + nsIFrame* parent = nsnull; + GetParent(&parent); + + if (parent) { + parent->GetContent(aContent); } - return rv; +} + +nsresult +nsHTMLFrameInnerFrame::GetDocShell(nsIDocShell **aDocShell) +{ + *aDocShell = nsnull; + + nsCOMPtr content; + GetParentContent(getter_AddRefs(content)); + + if (!content) { + // Hmm, no content in this frame (or in the parent, really), + // that's odd, not much to be done here then. + + return NS_OK; + } + + if (!mFrameLoader) { + nsCOMPtr frame_loader_owner = + do_QueryInterface(content); + + if (frame_loader_owner) { + frame_loader_owner->GetFrameLoader(getter_AddRefs(mFrameLoader)); + } + + if (!mFrameLoader) { + nsresult rv = NS_OK; + + // No frame loader available from the content, create our own... + mFrameLoader = do_CreateInstance(NS_FRAMELOADER_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + // ... remember that we own this frame loader... + mOwnsFrameLoader = PR_TRUE; + + // ... initialize it... + mFrameLoader->Init(content); + + // ... and tell it to start loading. + mFrameLoader->LoadFrame(); + } + } + + return mFrameLoader->GetDocShell(aDocShell); } NS_IMETHODIMP @@ -953,289 +957,131 @@ nsHTMLFrameInnerFrame::DidReflow(nsIPresContext* aPresContext, if (newVis != oldVis) { nsCOMPtr vm; view->GetViewManager(*getter_AddRefs(vm)); - if (vm != nsnull) { + if (vm) { vm->SetViewVisibility(view, newVis); } } } } - + return rv; } nsresult -nsHTMLFrameInnerFrame::CreateDocShell(nsIPresContext* aPresContext) +nsHTMLFrameInnerFrame::ShowDocShell(nsIPresContext* aPresContext) { - nsresult rv; - nsCOMPtr parentContent; - GetParentContent(*getter_AddRefs(parentContent)); + nsCOMPtr docShell; + nsresult rv = GetDocShell(getter_AddRefs(docShell)); + NS_ENSURE_SUCCESS(rv, rv); - // Bug 8065: Don't exceed some maximum depth in content frames (MAX_DEPTH_CONTENT_FRAMES) - PRInt32 depth = 0; - nsCOMPtr parentAsSupports; - aPresContext->GetContainer(getter_AddRefs(parentAsSupports)); - if (parentAsSupports) { - nsCOMPtr parentAsItem(do_QueryInterface(parentAsSupports)); - while (parentAsItem) { - depth++; - if (MAX_DEPTH_CONTENT_FRAMES < depth) { - NS_WARNING("Too many nested content frames so giving up"); - return NS_ERROR_UNEXPECTED; // Too deep, give up! (silently?) - } + PRBool is_document_synthetic = PR_FALSE; - // Only count depth on content, not chrome. - // If we wanted to limit total depth, skip the following check: - PRInt32 parentType; - parentAsItem->GetItemType(&parentType); - if (nsIDocShellTreeItem::typeContent == parentType) { - nsIDocShellTreeItem* temp = parentAsItem; - temp->GetParent(getter_AddRefs(parentAsItem)); - } else { - break; // we have exited content, stop counting, depth is OK! - } + if (mContent->IsContentOfType(nsIContent::eXUL)) { + // We're a XUL iframe/browser tag, for the XUL box object to + // docshell mapping to work we must force a document to be created + // at this point, if we don't, mozilla won't even start since it + // can't reach the docshell from the iframe/browser tags. That + // mapping is based on the subdocument map in the document, which + // obviously won't be setup until the subdocument is created. + + // Make sure there's a document in the docshell. + nsCOMPtr win(do_GetInterface(docShell)); + NS_ENSURE_TRUE(win, NS_ERROR_UNEXPECTED); + + nsCOMPtr pwin(do_QueryInterface(win)); + + nsCOMPtr extant_dom_doc; + pwin->GetExtantDocument(getter_AddRefs(extant_dom_doc)); + + // This will synchronously create a document if there is no + // document in the window yet. + + nsCOMPtr dom_doc; + win->GetDocument(getter_AddRefs(dom_doc)); + + if (dom_doc != extant_dom_doc) { + is_document_synthetic = PR_TRUE; } } - mSubShell = do_CreateInstance(kWebShellCID); - NS_ENSURE_TRUE(mSubShell, NS_ERROR_FAILURE); - - // notify the pres shell that a docshell has been created nsCOMPtr presShell; - aPresContext->GetShell(getter_AddRefs(presShell)); - if (presShell) - { - nsCOMPtr subShellAsSupports(do_QueryInterface(mSubShell)); - NS_ENSURE_TRUE(subShellAsSupports, NS_ERROR_FAILURE); - presShell->SetSubShellFor(mContent, subShellAsSupports); - //We need to be able to get back to the presShell to unset the subshell at destruction - mPresShellWeak = getter_AddRefs(NS_GetWeakReference(presShell)); + docShell->GetPresShell(getter_AddRefs(presShell)); + + if (presShell) { + // The docshell is already showing, nothing left to do... + + return NS_OK; } - - nsCOMPtr docShell(do_QueryInterface(mSubShell)); - NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE); - // pass along marginwidth, marginheight, scrolling so sub document can use it - docShell->SetMarginWidth(GetMarginWidth(aPresContext, parentContent)); - docShell->SetMarginHeight(GetMarginHeight(aPresContext, parentContent)); + + nsCOMPtr docShellTreeItem(do_QueryInterface(docShell)); + + nsCOMPtr parentDocShellTreeItem; + docShellTreeItem->GetParent(getter_AddRefs(parentDocShellTreeItem)); + + nsCOMPtr parentDocShell = + do_QueryInterface(parentDocShellTreeItem); + + nsCOMPtr parentPresShell; + parentDocShell->GetPresShell(getter_AddRefs(parentPresShell)); + + nsCOMPtr content; + GetParentContent(getter_AddRefs(content)); + + // pass along marginwidth, marginheight, scrolling so sub document + // can use it + docShell->SetMarginWidth(GetMarginWidth(aPresContext, content)); + docShell->SetMarginHeight(GetMarginHeight(aPresContext, content)); // Current and initial scrolling is set so that all succeeding docs // will use the scrolling value set here, regardless if scrolling is // set by viewing a particular document (e.g. XUL turns off scrolling) - nsCOMPtr scrollableContainer(do_QueryInterface(mSubShell)); + nsCOMPtr scrollableContainer(do_QueryInterface(docShell)); + if (scrollableContainer) { scrollableContainer->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_Y, - GetScrolling(parentContent)); + GetScrolling(content)); scrollableContainer->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X, - GetScrolling(parentContent)); + GetScrolling(content)); } - nsCOMPtr docShellAsItem(do_QueryInterface(mSubShell)); + nsCOMPtr docShellAsItem(do_QueryInterface(docShell)); NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE); - nsString frameName; - if (GetName(parentContent, frameName)) { - docShellAsItem->SetName(frameName.get()); - } - - // If our container is a web-shell, inform it that it has a new - // child. If it's not a web-shell then some things will not operate - // properly. - nsCOMPtr container; - aPresContext->GetContainer(getter_AddRefs(container)); - if (container) { - nsCOMPtr parentAsNode(do_QueryInterface(container)); - if (parentAsNode) { - nsCOMPtr parentAsItem(do_QueryInterface(parentAsNode)); - PRInt32 parentType; - parentAsItem->GetItemType(&parentType); - - nsIAtom* typeAtom = NS_NewAtom("type"); - nsAutoString value, valuePiece; - PRBool isContent; - - isContent = PR_FALSE; - if (NS_SUCCEEDED(parentContent->GetAttr(kNameSpaceID_None, - typeAtom, value))) { - - // we accept "content" and "content-xxx" values. - // at time of writing, we expect "xxx" to be "primary", but - // someday it might be an integer expressing priority - value.Left(valuePiece, 7); - if (valuePiece.EqualsIgnoreCase("content") && - (value.Length() == 7 || - value.Mid(valuePiece, 7, 1) == 1 && valuePiece.Equals(NS_LITERAL_STRING("-")))) - isContent = PR_TRUE; - } - NS_IF_RELEASE(typeAtom); - if (isContent) { - // The web shell's type is content. - docShellAsItem->SetItemType(nsIDocShellTreeItem::typeContent); - } else { - // Inherit our type from our parent webshell. If it is - // chrome, we'll be chrome. If it is content, we'll be - // content. - docShellAsItem->SetItemType(parentType); - } - - parentAsNode->AddChild(docShellAsItem); - - if (isContent) { - nsCOMPtr parentTreeOwner; - parentAsItem->GetTreeOwner(getter_AddRefs(parentTreeOwner)); - if(parentTreeOwner) - parentTreeOwner->ContentShellAdded(docShellAsItem, - value.EqualsIgnoreCase("content-primary") ? PR_TRUE : PR_FALSE, - value.get()); - } - // connect the container... - nsCOMPtr webShell(do_QueryInterface(mSubShell)); - nsCOMPtr outerContainer(do_QueryInterface(container)); - if (outerContainer) - webShell->SetContainer(outerContainer); - - - // Make sure all shells have links back to the content element in the - // nearest enclosing chrome shell. - nsCOMPtr parentShell(do_QueryInterface(parentAsNode)); - nsCOMPtr chromeEventHandler; - if (parentType == nsIDocShellTreeItem::typeChrome) { - // Our parent shell is a chrome shell. It is therefore our nearest - // enclosing chrome shell. - chromeEventHandler = do_QueryInterface(mContent); - NS_WARN_IF_FALSE(chromeEventHandler, "This mContent should implement this."); - } - else { - // Our parent shell is a content shell. Get the chrome info from - // it and use that for our shell as well. - parentShell->GetChromeEventHandler(getter_AddRefs(chromeEventHandler)); - } - - docShell->SetChromeEventHandler(chromeEventHandler); - } - } nsCOMPtr widget; + rv = CreateViewAndWidget(aPresContext, getter_AddRefs(widget)); if (NS_FAILED(rv)) { return rv; } - mSubShell->InitWindow(nsnull, widget, 0, 0, 10, 10); - mSubShell->Create(); + nsCOMPtr baseWindow(do_QueryInterface(docShell)); - mSubShell->SetVisibility(PR_TRUE); + if (baseWindow) { + baseWindow->InitWindow(nsnull, widget, 0, 0, 10, 10); + + // This is kinda whacky, this "Create()" call doesn't really + // create anything, one starts to wonder why this was named + // "Create"... + + baseWindow->Create(); + + PRBool is_document_loading = PR_TRUE; + mFrameLoader->GetIsDocumentLoading(&is_document_loading); + + if (!is_document_synthetic || !is_document_loading) { + // We're about to either show a "real" document (i.e. not a + // synthetic about:blank document) or we're showing an iframe + // that we didn't load anything into yet (i.e. there was no + // src="..." attribute on the iframe element. Make sure we show + // the window. + + baseWindow->SetVisibility(PR_TRUE); + } + } return NS_OK; } -nsresult -nsHTMLFrameInnerFrame::DoLoadURL(nsIPresContext* aPresContext) -{ - // Bug 8065: Preventing frame nesting recursion - if the frames are - // too deep we don't create a mSubShell, so this isn't an assert: - if (!mSubShell) return NS_OK; - - // Prevent recursion - mCreatingViewer=PR_TRUE; - - // Get the URL to load - nsCOMPtr parentContent; - nsresult rv = GetParentContent(*getter_AddRefs(parentContent)); - NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && parentContent, rv); - - nsAutoString url; - GetURL(parentContent, url); - url.Trim(" \t\n\r"); - if (url.IsEmpty()) // Load about:blank into a frame if not URL is specified (bug 35986) - url = NS_LITERAL_STRING("about:blank"); - - // Make an absolute URL - nsCOMPtr baseURL; - nsCOMPtr htmlContent = do_QueryInterface(parentContent, &rv); - nsCOMPtr doc; - if (NS_SUCCEEDED(rv) && htmlContent) { - htmlContent->GetBaseURL(*getter_AddRefs(baseURL)); - (void) htmlContent->GetDocument(*getter_AddRefs(doc)); - } - else { - rv = parentContent->GetDocument(*getter_AddRefs(doc)); - if (NS_SUCCEEDED(rv) && doc) { - doc->GetBaseURL(*getter_AddRefs(baseURL)); - } - } - if (!baseURL) return NS_ERROR_NULL_POINTER; - - nsAutoString docCharset; - if (doc) - (void) doc->GetDocumentCharacterSet(docCharset); - - nsAutoString absURL; - rv = NS_MakeAbsoluteURI(absURL, url, baseURL); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr uri; - NS_NewURI(getter_AddRefs(uri), absURL, - docCharset.IsEmpty() ? nsnull : NS_ConvertUCS2toUTF8(docCharset).get()); - - // Check for security - nsCOMPtr secMan = - do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - - // Get base URL - nsCOMPtr baseURI; - rv = aPresContext->GetBaseURL(getter_AddRefs(baseURI)); - - // Get docshell and create load info - nsCOMPtr docShell(do_QueryInterface(mSubShell)); - NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE); - nsCOMPtr loadInfo; - docShell->CreateLoadInfo(getter_AddRefs(loadInfo)); - NS_ENSURE_TRUE(loadInfo, NS_ERROR_FAILURE); - - // Get referring URL - nsCOMPtr referrer; - nsCOMPtr principal; - rv = secMan->GetSubjectPrincipal(getter_AddRefs(principal)); - NS_ENSURE_SUCCESS(rv, rv); - // If we were called from script, get the referring URL from the script - if (principal) { - nsCOMPtr codebase = do_QueryInterface(principal); - if (codebase) { - rv = codebase->GetURI(getter_AddRefs(referrer)); - NS_ENSURE_SUCCESS(rv, rv); - } - // Pass the script principal to the docshell - nsCOMPtr owner = do_QueryInterface(principal); - loadInfo->SetOwner(owner); - } - if (!referrer) { // We're not being called form script, tell the docshell - // to inherit an owner from the current document. - loadInfo->SetInheritOwner(PR_TRUE); - referrer = baseURI; - } - - loadInfo->SetReferrer(referrer); - - // Check if we are allowed to load absURL - nsCOMPtr newURI; - rv = NS_NewURI(getter_AddRefs(newURI), absURL, nsnull, baseURI); - NS_ENSURE_SUCCESS(rv, rv); - rv = secMan->CheckLoadURI(referrer, newURI, nsIScriptSecurityManager::STANDARD); - if (NS_FAILED(rv)) - return rv; // We're not - - nsCOMPtr webProgress(do_GetInterface(mSubShell)); - - if (webProgress) { - webProgress->AddProgressListener(this); - } - - rv = docShell->LoadURI(uri, loadInfo, nsIWebNavigation::LOAD_FLAGS_NONE, PR_FALSE); - NS_ASSERTION(NS_SUCCEEDED(rv), "failed to load URL"); - - return rv; -} - - nsresult nsHTMLFrameInnerFrame::CreateViewAndWidget(nsIPresContext* aPresContext, nsIWidget** aWidget) @@ -1245,28 +1091,29 @@ nsHTMLFrameInnerFrame::CreateViewAndWidget(nsIPresContext* aPresContext, nsCOMPtr presShell; aPresContext->GetShell(getter_AddRefs(presShell)); - if (!presShell) return NS_ERROR_FAILURE; + NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE); float t2p; aPresContext->GetTwipsToPixels(&t2p); // create, init, set the parent of the view nsIView* view; - nsresult rv = nsComponentManager::CreateInstance(kCViewCID, nsnull, NS_GET_IID(nsIView), - (void **)&view); + nsresult rv = nsComponentManager::CreateInstance(kCViewCID, nsnull, + NS_GET_IID(nsIView), + (void **)&view); + if (NS_FAILED(rv)) { + NS_ERROR("Could not create view for nsHTMLFrame"); - if (NS_OK != rv) { - NS_ASSERTION(0, "Could not create view for nsHTMLFrame"); return rv; } nsIView* parView; nsPoint origin; - GetOffsetFromView(aPresContext, origin, &parView); + GetOffsetFromView(aPresContext, origin, &parView); nsRect viewBounds(origin.x, origin.y, 10, 10); nsCOMPtr viewMan; - presShell->GetViewManager(getter_AddRefs(viewMan)); + presShell->GetViewManager(getter_AddRefs(viewMan)); rv = view->Init(viewMan, viewBounds, parView); // XXX put it at the end of the document order until we can do better viewMan->InsertChild(parView, view, nsnull, PR_TRUE); @@ -1295,41 +1142,39 @@ nsHTMLFrameInnerFrame::Init(nsIPresContext* aPresContext, nsIStyleContext* aContext, nsIFrame* aPrevInFlow) { - nsresult rv = nsLeafFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow); + nsresult rv = nsLeafFrame::Init(aPresContext, aContent, aParent, aContext, + aPrevInFlow); if (NS_FAILED(rv)) return rv; // determine if we are a printcontext PRBool shouldCreateDoc = PR_TRUE; - nsCOMPtr thePrinterContext = do_QueryInterface(aPresContext); - if (thePrinterContext) { + nsCOMPtr thePrinterContext(do_QueryInterface(aPresContext)); + + if (thePrinterContext) { // we are printing shouldCreateDoc = PR_FALSE; } - // for print preview we want to create the view and widget but + // for print preview we want to create the view and widget but // we do not want to load the document, it is alerady loaded. - nsCOMPtr thePrintPreviewContext = do_QueryInterface(aPresContext); - if (thePrintPreviewContext) { + nsCOMPtr thePrintPreviewContext = + do_QueryInterface(aPresContext); + + if (thePrintPreviewContext) { nsCOMPtr widget; rv = CreateViewAndWidget(aPresContext, getter_AddRefs(widget)); + if (NS_FAILED(rv)) { return rv; } + // we are in PrintPreview shouldCreateDoc = PR_FALSE; } - - if (!mCreatingViewer && shouldCreateDoc) { - // create the web shell - // we do this even if the size is not positive (bug 11762) - // we do this even if there is no src (bug 16218) - if (!mSubShell) - rv = CreateDocShell(aPresContext); - // Whether or not we had to create a webshell, load the document - if (NS_SUCCEEDED(rv)) { - DoLoadURL(aPresContext); - } + + if (shouldCreateDoc) { + ShowDocShell(aPresContext); } return NS_OK; @@ -1350,41 +1195,55 @@ nsHTMLFrameInnerFrame::Reflow(nsIPresContext* aPresContext, nsresult rv = NS_OK; - // use the max size set in aReflowState by the nsHTMLFrameOuterFrame as our size + // use the max size set in aReflowState by the nsHTMLFrameOuterFrame + // as our size GetDesiredSize(aPresContext, aReflowState, aDesiredSize); aStatus = NS_FRAME_COMPLETE; + nsCOMPtr docShell; + GetDocShell(getter_AddRefs(docShell)); + + nsCOMPtr baseWindow(do_QueryInterface(docShell)); + // resize the sub document - if(mSubShell) { + if (baseWindow) { float t2p; aPresContext->GetTwipsToPixels(&t2p); PRInt32 x = 0; PRInt32 y = 0; - mSubShell->GetPositionAndSize(&x, &y, nsnull, nsnull); - PRInt32 cx = NSToCoordRound(aDesiredSize.width * t2p); + baseWindow->GetPositionAndSize(&x, &y, nsnull, nsnull); + PRInt32 cx = NSToCoordRound(aDesiredSize.width * t2p); PRInt32 cy = NSToCoordRound(aDesiredSize.height * t2p); - mSubShell->SetPositionAndSize(x, y, cx, cy, PR_FALSE); + baseWindow->SetPositionAndSize(x, y, cx, cy, PR_FALSE); NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS, - ("exit nsHTMLFrameInnerFrame::Reflow: size=%d,%d rv=%x", - aDesiredSize.width, aDesiredSize.height, aStatus)); + ("exit nsHTMLFrameInnerFrame::Reflow: size=%d,%d rv=%x", + aDesiredSize.width, aDesiredSize.height, aStatus)); } - + return rv; } // load a new url nsresult -nsHTMLFrameInnerFrame::ReloadURL(nsIPresContext* aPresContext) +nsHTMLFrameInnerFrame::ReloadURL() { - return DoLoadURL(aPresContext); + if (!mOwnsFrameLoader || !mFrameLoader) { + // If we don't own the frame loader, we're not in charge of what's + // loaded into it. + + return NS_OK; + } + + return mFrameLoader->LoadFrame(); } -void + +void nsHTMLFrameInnerFrame::GetDesiredSize(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsHTMLReflowMetrics& aDesiredSize) @@ -1394,19 +1253,28 @@ nsHTMLFrameInnerFrame::GetDesiredSize(nsIPresContext* aPresContext, aDesiredSize.ascent = aDesiredSize.height; aDesiredSize.descent = 0; - // For unknown reasons, the maxElementSize for the InnerFrame is used, but the - // maxElementSize for the OuterFrame is ignored, make sure to get it right here! + // For unknown reasons, the maxElementSize for the InnerFrame is + // used, but the maxElementSize for the OuterFrame is ignored, make + // sure to get it right here! + if (aDesiredSize.maxElementSize) { if ((NS_UNCONSTRAINEDSIZE == aReflowState.availableWidth) || - (eStyleUnit_Percent == aReflowState.mStylePosition->mWidth.GetUnit())) { - aDesiredSize.maxElementSize->width = 0; // percent width springy down to 0 px + (eStyleUnit_Percent == + aReflowState.mStylePosition->mWidth.GetUnit())) { + // percent width springy down to 0 px + + aDesiredSize.maxElementSize->width = 0; } else { aDesiredSize.maxElementSize->width = aDesiredSize.width; } + if ((NS_UNCONSTRAINEDSIZE == aReflowState.availableHeight) || - (eStyleUnit_Percent == aReflowState.mStylePosition->mHeight.GetUnit())) { - aDesiredSize.maxElementSize->height = 0; // percent height springy down to 0px + (eStyleUnit_Percent == + aReflowState.mStylePosition->mHeight.GetUnit())) { + // percent height springy down to 0px + + aDesiredSize.maxElementSize->height = 0; } else { aDesiredSize.maxElementSize->height = aDesiredSize.height; @@ -1414,9 +1282,9 @@ nsHTMLFrameInnerFrame::GetDesiredSize(nsIPresContext* aPresContext, } } -/******************************************************************************* +/****************************************************************************** * FrameLoadingInfo - ******************************************************************************/ + *****************************************************************************/ FrameLoadingInfo::FrameLoadingInfo(const nsSize& aSize) { NS_INIT_REFCNT(); diff --git a/layout/generic/nsFrameSetFrame.cpp b/layout/generic/nsFrameSetFrame.cpp index a1a4b002844..6820963d6ee 100644 --- a/layout/generic/nsFrameSetFrame.cpp +++ b/layout/generic/nsFrameSetFrame.cpp @@ -63,7 +63,6 @@ #define ALL_VIS 0x000F #define NONE_VIS 0x0000 -static NS_DEFINE_IID(kIFramesetFrameIID, NS_IFRAMESETFRAME_IID); static NS_DEFINE_IID(kLookAndFeelCID, NS_LOOKANDFEEL_CID); /******************************************************************************* @@ -231,19 +230,29 @@ nsHTMLFramesetFrame::nsHTMLFramesetFrame() nsHTMLFramesetFrame::~nsHTMLFramesetFrame() { - if (mRowSizes) delete [] mRowSizes; - if (mRowSpecs) delete [] mRowSpecs; - if (mColSizes) delete [] mColSizes; - if (mColSpecs) delete [] mColSpecs; - if (mVerBorders) delete[] mVerBorders; - if (mHorBorders) delete[] mHorBorders; + delete [] mRowSizes; + delete [] mRowSpecs; + delete [] mColSizes; + delete [] mColSpecs; + delete[] mVerBorders; + delete[] mHorBorders; + mRowSizes = mColSizes = nsnull; mRowSpecs = mColSpecs = nsnull; - nsCOMPtr prefBranch(do_QueryReferent(mPrefBranchWeakRef)); + + nsCOMPtr prefBranch = + do_QueryReferent(mPrefBranchWeakRef); + if (prefBranch) { - nsresult rv = prefBranch->RemoveObserver(kFrameResizePref, this); - NS_ASSERTION(NS_SUCCEEDED(rv), "Can't remove frameset as pref branch observer"); +#ifdef DEBUG + nsresult rv = +#endif + prefBranch->RemoveObserver(kFrameResizePref, this); + + NS_ASSERTION(NS_SUCCEEDED(rv), + "Can't remove frameset as pref branch observer"); } + mPrefBranchWeakRef = nsnull; } @@ -252,7 +261,7 @@ nsresult nsHTMLFramesetFrame::QueryInterface(const nsIID& aIID, { if (NULL == aInstancePtr) { return NS_ERROR_NULL_POINTER; - } else if (aIID.Equals(kIFramesetFrameIID)) { + } else if (aIID.Equals(NS_GET_IID(nsHTMLFramesetFrame))) { *aInstancePtr = (void*)this; return NS_OK; } else if (aIID.Equals(NS_GET_IID(nsIObserver))) { @@ -327,7 +336,8 @@ nsHTMLFramesetFrame::Init(nsIPresContext* aPresContext, mTopLevelFrameset = (nsHTMLFramesetFrame*)this; while (parentFrame) { nsHTMLFramesetFrame* frameset; - rv = parentFrame->QueryInterface(kIFramesetFrameIID, (void**)&frameset); + rv = parentFrame->QueryInterface(NS_GET_IID(nsHTMLFramesetFrame), + (void**)&frameset); if (NS_SUCCEEDED(rv)) { mTopLevelFrameset = frameset; parentFrame->GetParent((nsIFrame**)&parentFrame); @@ -1404,7 +1414,7 @@ PRBool nsHTMLFramesetFrame::ChildIsFrameset(nsIFrame* aChild) { nsIFrame* childFrame = nsnull; - aChild->QueryInterface(kIFramesetFrameIID, (void**)&childFrame); + aChild->QueryInterface(NS_GET_IID(nsHTMLFramesetFrame), (void**)&childFrame); if (childFrame) { return PR_TRUE; } diff --git a/layout/generic/nsFrameSetFrame.h b/layout/generic/nsFrameSetFrame.h index fe786185fd8..88000505dff 100644 --- a/layout/generic/nsFrameSetFrame.h +++ b/layout/generic/nsFrameSetFrame.h @@ -57,7 +57,8 @@ struct nsGUIEvent; class nsHTMLFramesetFrame; #define NS_IFRAMESETFRAME_IID \ -{ 0xf47deac0, 0x4200, 0x11d2, { 0x80, 0x3c, 0x0, 0x60, 0x8, 0x15, 0xa7, 0x91 } } +{ 0xf47deac0, 0x4200, 0x11d2, \ + { 0x80, 0x3c, 0x0, 0x60, 0x8, 0x15, 0xa7, 0x91 } } #define NO_COLOR 0xFFFFFFFA @@ -115,8 +116,10 @@ struct nsFramesetDrag { class nsHTMLFramesetFrame : public nsHTMLContainerFrame, public nsIObserver { - public: + // Woohoo, concrete class with an IID! + NS_DEFINE_STATIC_IID_ACCESSOR(NS_IFRAMESETFRAME_IID) + nsHTMLFramesetFrame(); virtual ~nsHTMLFramesetFrame(); diff --git a/layout/html/base/src/nsPresShell.cpp b/layout/html/base/src/nsPresShell.cpp index 8cff3e1ac5d..eae9dbe2552 100644 --- a/layout/html/base/src/nsPresShell.cpp +++ b/layout/html/base/src/nsPresShell.cpp @@ -166,9 +166,6 @@ #include "nsIContentViewer.h" #include "nsIDocumentViewer.h" -// SubShell map -#include "pldhash.h" - #ifdef IBMBIDI #include "nsIBidiKeyboard.h" #endif // IBMBIDI @@ -809,14 +806,6 @@ DummyLayoutRequest::Cancel(nsresult status) // ---------------------------------------------------------------------------- -class SubShellMapEntry : public PLDHashEntryHdr { - public: - nsIContent *key; // must be first, to look like PLDHashEntryStub - nsISupports *subShell; -}; - -// ---------------------------------------------------------------------------- - class PresShell : public nsIPresShell, public nsIViewObserver, private nsIDocumentObserver, public nsIFocusTracker, public nsISelectionController, @@ -877,12 +866,6 @@ public: nsIStyleContext** aStyleContext) const; NS_IMETHOD GetLayoutObjectFor(nsIContent* aContent, nsISupports** aResult) const; - NS_IMETHOD GetSubShellFor(nsIContent* aContent, - nsISupports** aResult) const; - NS_IMETHOD SetSubShellFor(nsIContent* aContent, - nsISupports* aSubShell); - NS_IMETHOD FindContentForShell(nsISupports* aSubShell, - nsIContent** aContent) const; NS_IMETHOD GetPlaceholderFrameFor(nsIFrame* aFrame, nsIFrame** aPlaceholderFrame) const; NS_IMETHOD AppendReflowCommand(nsHTMLReflowCommand* aReflowCommand); @@ -1235,9 +1218,6 @@ protected: static void sPaintSuppressionCallback(nsITimer* aTimer, void* aPresShell); // A callback for the timer. - // subshell map - PLDHashTable* mSubShellMap; // map of content/subshell pairs - MOZ_TIMER_DECLARE(mReflowWatch) // Used for measuring time spent in reflow MOZ_TIMER_DECLARE(mFrameCreationWatch) // Used for measuring time spent in frame creation @@ -1678,13 +1658,6 @@ PresShell::Destroy() // Clobber weak leaks in case of re-entrancy during tear down mHistoryState = nsnull; - // kill subshell map, if any. It holds only weak references - if (mSubShellMap) - { - PL_DHashTableDestroy(mSubShellMap); - mSubShellMap = nsnull; - } - // release current event content and any content on event stack NS_IF_RELEASE(mCurrentEventContent); @@ -5553,94 +5526,6 @@ PresShell::GetLayoutObjectFor(nsIContent* aContent, return result; } - -NS_IMETHODIMP -PresShell::GetSubShellFor(nsIContent* aContent, - nsISupports** aResult) const -{ - NS_ENSURE_ARG_POINTER(aContent); - - if (mSubShellMap) { - SubShellMapEntry *entry = NS_STATIC_CAST(SubShellMapEntry*, - PL_DHashTableOperate(mSubShellMap, aContent, PL_DHASH_LOOKUP)); - if (PL_DHASH_ENTRY_IS_BUSY(entry)) { - NS_ADDREF(*aResult = entry->subShell); - return NS_OK; - } - } - - *aResult = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -PresShell::SetSubShellFor(nsIContent* aContent, - nsISupports* aSubShell) -{ - NS_ENSURE_ARG_POINTER(aContent); - - // If aSubShell is NULL, then remove the mapping - if (!aSubShell) { - if (mSubShellMap) - PL_DHashTableOperate(mSubShellMap, aContent, PL_DHASH_REMOVE); - } else { - // Create a new hashtable if necessary - if (!mSubShellMap) { - mSubShellMap = PL_NewDHashTable(PL_DHashGetStubOps(), nsnull, - sizeof(SubShellMapEntry), 16); - if (!mSubShellMap) - return NS_ERROR_OUT_OF_MEMORY; - } - - // Add a mapping to the hash table - SubShellMapEntry *entry = NS_STATIC_CAST(SubShellMapEntry*, - PL_DHashTableOperate(mSubShellMap, aContent, PL_DHASH_ADD)); - entry->key = aContent; - entry->subShell = aSubShell; - } - return NS_OK; -} - -struct FindContentData { - FindContentData(nsISupports *aSubShell) - : subShell(aSubShell), result(nsnull) {} - - nsISupports *subShell; - nsIContent *result; -}; - -PR_STATIC_CALLBACK(PLDHashOperator) -FindContentEnumerator(PLDHashTable *table, PLDHashEntryHdr *hdr, - PRUint32 number, void *arg) -{ - SubShellMapEntry *entry = NS_STATIC_CAST(SubShellMapEntry*, hdr); - FindContentData *data = NS_STATIC_CAST(FindContentData*, arg); - - if (entry->subShell == data->subShell) { - data->result = entry->key; - return PL_DHASH_STOP; - } - return PL_DHASH_NEXT; -} - -NS_IMETHODIMP -PresShell::FindContentForShell(nsISupports* aSubShell, - nsIContent** aContent) const -{ - NS_ENSURE_ARG_POINTER(aSubShell); - - if (!mSubShellMap) { - *aContent = nsnull; - return NS_OK; - } - - FindContentData data(aSubShell); - PL_DHashTableEnumerate(mSubShellMap, FindContentEnumerator, &data); - NS_IF_ADDREF(*aContent = data.result); - - return NS_OK; -} - NS_IMETHODIMP PresShell::GetPlaceholderFrameFor(nsIFrame* aFrame, nsIFrame** aResult) const diff --git a/layout/html/document/src/Makefile.in b/layout/html/document/src/Makefile.in index 1c8a759de45..8e451e509cb 100644 --- a/layout/html/document/src/Makefile.in +++ b/layout/html/document/src/Makefile.in @@ -46,7 +46,8 @@ REQUIRES = xpcom \ shistory \ xpconnect \ accessibility \ - webbrwsr \ + webbrwsr \ + webBrowser_core \ $(NULL) CPPSRCS = \ diff --git a/layout/html/document/src/makefile.win b/layout/html/document/src/makefile.win index b9ef02d3f2f..1fe676d95e2 100644 --- a/layout/html/document/src/makefile.win +++ b/layout/html/document/src/makefile.win @@ -40,6 +40,7 @@ REQUIRES = xpcom \ accessibility \ gfx \ content \ + webBrowser_core \ $(NULL) DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN diff --git a/layout/html/document/src/nsFrameFrame.cpp b/layout/html/document/src/nsFrameFrame.cpp index bbff77b79d8..2c7fa1b714c 100644 --- a/layout/html/document/src/nsFrameFrame.cpp +++ b/layout/html/document/src/nsFrameFrame.cpp @@ -72,6 +72,7 @@ #include "nsFrameSetFrame.h" #include "nsIDOMHTMLFrameElement.h" #include "nsIDOMHTMLIFrameElement.h" +#include "nsIFrameLoader.h" #include "nsLayoutAtoms.h" #include "nsIChromeEventHandler.h" #include "nsIScriptSecurityManager.h" @@ -84,13 +85,16 @@ #include "nsIWidget.h" #include "nsIWebProgress.h" #include "nsIWebProgressListener.h" +#include "nsIWebBrowserPrint.h" #include "nsWeakReference.h" #include "nsIDOMEventTarget.h" #include "nsIDOMEventListener.h" #include "nsIDOMWindow.h" +#include "nsIDOMDocument.h" +#include "nsPIDOMWindow.h" #include "nsIRenderingContext.h" -// For Accessibility +// For Accessibility #ifdef ACCESSIBILITY #include "nsIAccessibilityService.h" #endif @@ -98,20 +102,12 @@ class nsHTMLFrame; -static NS_DEFINE_IID(kIFramesetFrameIID, NS_IFRAMESETFRAME_IID); -static NS_DEFINE_CID(kWebShellCID, NS_WEB_SHELL_CID); static NS_DEFINE_CID(kCViewCID, NS_VIEW_CID); static NS_DEFINE_CID(kCChildCID, NS_CHILD_CID); -// Bug 8065: Limit content frame depth to some reasonable level. -// This does not count chrome frames when determining depth, -// nor does it prevent chrome recursion. -// Also see bug 126466. -#define MAX_DEPTH_CONTENT_FRAMES 8 - -/******************************************************************************* +/****************************************************************************** * FrameLoadingInfo - ******************************************************************************/ + *****************************************************************************/ class FrameLoadingInfo : public nsISupports { public: @@ -128,9 +124,9 @@ public: }; -/******************************************************************************* +/****************************************************************************** * nsHTMLFrameOuterFrame - ******************************************************************************/ + *****************************************************************************/ #define nsHTMLFrameOuterFrameSuper nsHTMLContainerFrame class nsHTMLFrameOuterFrame : public nsHTMLFrameOuterFrameSuper { @@ -142,7 +138,7 @@ public: NS_IMETHOD GetFrameName(nsAString& aResult) const; #endif - // nsISupports + // nsISupports NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); NS_IMETHOD GetFrameType(nsIAtom** aType) const; @@ -168,7 +164,7 @@ public: nsIContent* aChild, PRInt32 aNameSpaceID, nsIAtom* aAttribute, - PRInt32 aModType, + PRInt32 aModType, PRInt32 aHint); #ifdef ACCESSIBILITY @@ -188,11 +184,10 @@ protected: nsCOMPtr mPresContext; }; -/******************************************************************************* +/****************************************************************************** * nsHTMLFrameInnerFrame - ******************************************************************************/ + *****************************************************************************/ class nsHTMLFrameInnerFrame : public nsLeafFrame, - public nsIWebProgressListener, public nsSupportsWeakReference { public: @@ -202,8 +197,6 @@ public: NS_IMETHOD_(nsrefcnt) AddRef(void) { return 2; } NS_IMETHOD_(nsrefcnt) Release(void) { return 1; } - NS_DECL_NSIWEBPROGRESSLISTENER - #ifdef DEBUG NS_IMETHOD GetFrameName(nsAString& aResult) const; #endif @@ -237,7 +230,9 @@ public: nsIStyleContext* aContext, nsIFrame* aPrevInFlow); - NS_IMETHOD GetParentContent(nsIContent*& aContent); + void GetParentContent(nsIContent** aContent); + nsresult GetDocShell(nsIDocShell **aDocShell); + PRBool GetURL(nsIContent* aContent, nsString& aResult); PRBool GetName(nsIContent* aContent, nsString& aResult); PRInt32 GetScrolling(nsIContent* aContent); @@ -245,13 +240,10 @@ public: PRInt32 GetMarginWidth(nsIPresContext* aPresContext, nsIContent* aContent); PRInt32 GetMarginHeight(nsIPresContext* aPresContext, nsIContent* aContent); - nsresult ReloadURL(nsIPresContext* aPresContext); - friend class nsHTMLFrameOuterFrame; protected: - nsresult CreateDocShell(nsIPresContext* aPresContext); - nsresult DoLoadURL(nsIPresContext* aPresContext); + nsresult ShowDocShell(nsIPresContext* aPresContext); nsresult CreateViewAndWidget(nsIPresContext* aPresContext, nsIWidget** aWidget); @@ -261,15 +253,18 @@ protected: const nsHTMLReflowState& aReflowState, nsHTMLReflowMetrics& aDesiredSize); - nsCOMPtr mSubShell; - nsWeakPtr mPresShellWeak; // weak reference to the nsIPresShell - PRBool mCreatingViewer; + nsresult ReloadURL(); + + nsCOMPtr mFrameLoader; + PRPackedBool mOwnsFrameLoader; + + PRPackedBool mCreatingViewer; }; -/******************************************************************************* +/****************************************************************************** * nsHTMLFrameOuterFrame - ******************************************************************************/ + *****************************************************************************/ nsHTMLFrameOuterFrame::nsHTMLFrameOuterFrame() : nsHTMLContainerFrame() { @@ -349,7 +344,7 @@ nsHTMLFrameOuterFrame::Init(nsIPresContext* aPresContext, view->GetWidget(*getter_AddRefs(widget)); if (!widget) - view->CreateWidget(kCChildCID); + view->CreateWidget(kCChildCID); } nsCOMPtr shell; @@ -387,7 +382,7 @@ nsHTMLFrameOuterFrame::GetSkipSides() const return 0; } -void +void nsHTMLFrameOuterFrame::GetDesiredSize(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsHTMLReflowMetrics& aDesiredSize) @@ -422,7 +417,7 @@ nsHTMLFrameOuterFrame::GetDesiredSize(nsIPresContext* aPresContext, } PRBool nsHTMLFrameOuterFrame::IsInline() -{ +{ return mIsInline; } @@ -463,7 +458,7 @@ NS_IMETHODIMP nsHTMLFrameOuterFrame::GetFrameType(nsIAtom** aType) const { NS_PRECONDITION(nsnull != aType, "null OUT parameter pointer"); - *aType = nsLayoutAtoms::htmlFrameOuterFrame; + *aType = nsLayoutAtoms::htmlFrameOuterFrame; NS_ADDREF(*aType); return NS_OK; } @@ -476,7 +471,7 @@ nsHTMLFrameOuterFrame::Reflow(nsIPresContext* aPresContext, { DO_GLOBAL_REFLOW_COUNT("nsHTMLFrameOuterFrame", aReflowState.reason); DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus); - //printf("OuterFrame::Reflow %X (%d,%d) \n", this, aReflowState.availableWidth, aReflowState.availableHeight); + //printf("OuterFrame::Reflow %X (%d,%d) \n", this, aReflowState.availableWidth, aReflowState.availableHeight); NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS, ("enter nsHTMLFrameOuterFrame::Reflow: maxSize=%d,%d reason=%d", aReflowState.availableWidth, aReflowState.availableHeight, aReflowState.reason)); @@ -551,37 +546,40 @@ nsHTMLFrameOuterFrame::AttributeChanged(nsIPresContext* aPresContext, nsIContent* aChild, PRInt32 aNameSpaceID, nsIAtom* aAttribute, - PRInt32 aModType, + PRInt32 aModType, PRInt32 aHint) { nsCOMPtr type; aChild->GetTag(*getter_AddRefs(type)); - if (((nsHTMLAtoms::src == aAttribute) && (nsHTMLAtoms::object != type)) || - ((nsHTMLAtoms::data == aAttribute) && (nsHTMLAtoms::object == type))) { - nsHTMLFrameInnerFrame* firstChild = NS_STATIC_CAST(nsHTMLFrameInnerFrame*, - mFrames.FirstChild()); + if ((type != nsHTMLAtoms::object && aAttribute == nsHTMLAtoms::src) || + (type == nsHTMLAtoms::object && aAttribute == nsHTMLAtoms::data)) { + nsHTMLFrameInnerFrame* firstChild = + NS_STATIC_CAST(nsHTMLFrameInnerFrame*, mFrames.FirstChild()); + if (firstChild) { - firstChild->ReloadURL(aPresContext); + firstChild->ReloadURL(); } } // If the noResize attribute changes, dis/allow frame to be resized - else if (nsHTMLAtoms::noresize == aAttribute) { + else if (aAttribute == nsHTMLAtoms::noresize) { nsCOMPtr parentContent; mContent->GetParent(*getter_AddRefs(parentContent)); nsCOMPtr parentTag; parentContent->GetTag(*getter_AddRefs(parentTag)); - if (nsHTMLAtoms::frameset == parentTag) { + if (parentTag == nsHTMLAtoms::frameset) { nsIFrame* parentFrame = nsnull; GetParent(&parentFrame); if (parentFrame) { - // There is no interface for kIFramesetFrameIID - // so QI'ing to concrete class, yay! + // There is no interface for nsHTMLFramesetFrame so QI'ing to + // concrete class, yay! nsHTMLFramesetFrame* framesetFrame = nsnull; - parentFrame->QueryInterface(kIFramesetFrameIID, (void **)&framesetFrame); + parentFrame->QueryInterface(NS_GET_IID(nsHTMLFramesetFrame), + (void **)&framesetFrame); + if (framesetFrame) { framesetFrame->RecalculateBorderResize(); } @@ -590,37 +588,45 @@ nsHTMLFrameOuterFrame::AttributeChanged(nsIPresContext* aPresContext, } else if (aAttribute == nsHTMLAtoms::type) { nsHTMLFrameInnerFrame* firstChild = NS_STATIC_CAST(nsHTMLFrameInnerFrame*, - mFrames.FirstChild()); - if (!firstChild) + mFrames.FirstChild()); + if (!firstChild || !firstChild->mFrameLoader) return NS_OK; nsAutoString value; aChild->GetAttr(kNameSpaceID_None, nsHTMLAtoms::type, value); - + // Notify our enclosing chrome that the primary content shell // has changed. - nsCOMPtr docShell(do_QueryInterface(firstChild->mSubShell)); - nsCOMPtr docShellAsItem(do_QueryInterface(firstChild->mSubShell)); - + + nsCOMPtr docShell; + firstChild->mFrameLoader->GetDocShell(getter_AddRefs(docShell)); + + nsCOMPtr docShellAsItem(do_QueryInterface(docShell)); + // If our container is a web-shell, inform it that it has a new // child. If it's not a web-shell then some things will not operate // properly. nsCOMPtr container; aPresContext->GetContainer(getter_AddRefs(container)); - if (container) { - nsCOMPtr parentAsNode(do_QueryInterface(container)); - if (parentAsNode) { - nsCOMPtr parentAsItem(do_QueryInterface(parentAsNode)); - - nsCOMPtr parentTreeOwner; - parentAsItem->GetTreeOwner(getter_AddRefs(parentTreeOwner)); - if (parentTreeOwner) - parentTreeOwner->ContentShellAdded(docShellAsItem, - value.EqualsIgnoreCase("content-primary") ? PR_TRUE : PR_FALSE, - value.get()); + + nsCOMPtr parentAsNode(do_QueryInterface(container)); + + if (parentAsNode) { + nsCOMPtr parentAsItem = + do_QueryInterface(parentAsNode); + + nsCOMPtr parentTreeOwner; + parentAsItem->GetTreeOwner(getter_AddRefs(parentTreeOwner)); + if (parentTreeOwner) { + PRBool is_primary_content = + value.EqualsIgnoreCase("content-primary"); + + parentTreeOwner->ContentShellAdded(docShellAsItem, is_primary_content, + value.get()); } } } + return NS_OK; } @@ -639,49 +645,50 @@ NS_NewHTMLFrameOuterFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) return NS_OK; } -/******************************************************************************* +/****************************************************************************** * nsHTMLFrameInnerFrame - ******************************************************************************/ + *****************************************************************************/ nsHTMLFrameInnerFrame::nsHTMLFrameInnerFrame() - : nsLeafFrame() + : nsLeafFrame(), mOwnsFrameLoader(PR_FALSE), mCreatingViewer(PR_FALSE) { - mCreatingViewer = PR_FALSE; - mPresShellWeak = nsnull; } nsHTMLFrameInnerFrame::~nsHTMLFrameInnerFrame() { - //printf("nsHTMLFrameInnerFrame destructor %X \n", this); + if (mFrameLoader) { + // Get the content viewer through the docshell, but don't call + // GetDocShell() since we don't want to create one if we don't + // have one. - nsCOMPtr win(do_GetInterface(mSubShell)); - nsCOMPtr eventTarget(do_QueryInterface(win)); - nsCOMPtr eventListener(do_QueryInterface(mContent)); + nsCOMPtr docShell; + mFrameLoader->GetDocShell(getter_AddRefs(docShell)); - if (eventTarget && eventListener) { - eventTarget->RemoveEventListener(NS_LITERAL_STRING("load"), eventListener, - PR_FALSE); - } + if (docShell) { + nsCOMPtr content_viewer; + docShell->GetContentViewer(getter_AddRefs(content_viewer)); - if(mSubShell) { - // notify the pres shell that a docshell has been destroyed - if (mPresShellWeak) { - nsCOMPtr ps = do_QueryReferent(mPresShellWeak); - if (ps) { - ps->SetSubShellFor(mContent, nsnull); + if (content_viewer) { + // Hide the content viewer now that the frame is going away... + + content_viewer->Hide(); } } - mSubShell->Destroy(); } - mSubShell = nsnull; // This is the location it was released before... - // Not sure if there is ordering depending on this. + + if (mFrameLoader && mOwnsFrameLoader) { + // We own this frame loader, and we're going away, so destroy our + // frame loader. + + mFrameLoader->Destroy(); + } } PRBool nsHTMLFrameInnerFrame::GetURL(nsIContent* aContent, nsString& aResult) { - aResult.SetLength(0); + aResult.SetLength(0); nsCOMPtr type; aContent->GetTag(*getter_AddRefs(type)); - + if (type.get() == nsHTMLAtoms::object) { if (NS_CONTENT_ATTR_HAS_VALUE == (aContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::data, aResult))) if (aResult.Length() > 0) @@ -696,7 +703,7 @@ PRBool nsHTMLFrameInnerFrame::GetURL(nsIContent* aContent, nsString& aResult) PRBool nsHTMLFrameInnerFrame::GetName(nsIContent* aContent, nsString& aResult) { - aResult.SetLength(0); + aResult.SetLength(0); if (NS_CONTENT_ATTR_HAS_VALUE == (aContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::name, aResult))) { if (aResult.Length() > 0) { @@ -735,7 +742,7 @@ PRInt32 nsHTMLFrameInnerFrame::GetScrolling(nsIContent* aContent) returnValue = NS_STYLE_OVERFLOW_AUTO; break; } - } + } } // Check style for overflow @@ -809,12 +816,6 @@ nsHTMLFrameInnerFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr) { NS_ENSURE_ARG_POINTER(aInstancePtr); - if (aIID.Equals(NS_GET_IID(nsIWebProgressListener))) { - nsISupports *tmp = NS_STATIC_CAST(nsIWebProgressListener *, this); - *aInstancePtr = tmp; - return NS_OK; - } - if (aIID.Equals(NS_GET_IID(nsISupportsWeakReference))) { nsISupports *tmp = NS_STATIC_CAST(nsISupportsWeakReference *, this); *aInstancePtr = tmp; @@ -824,60 +825,6 @@ nsHTMLFrameInnerFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr) return nsLeafFrame::QueryInterface(aIID, aInstancePtr); } -NS_IMETHODIMP -nsHTMLFrameInnerFrame::OnStateChange(nsIWebProgress *aWebProgress, - nsIRequest *aRequest, - PRInt32 aStateFlags, PRUint32 aStatus) -{ - if (!((~aStateFlags) & (nsIWebProgressListener::STATE_IS_DOCUMENT | - nsIWebProgressListener::STATE_TRANSFERRING))) { - nsCOMPtr win(do_GetInterface(mSubShell)); - nsCOMPtr eventTarget(do_QueryInterface(win)); - nsCOMPtr eventListener(do_QueryInterface(mContent)); - - if (eventTarget && eventListener) { - eventTarget->AddEventListener(NS_LITERAL_STRING("load"), eventListener, - PR_FALSE); - } - } - - return NS_OK; -} - -NS_IMETHODIMP -nsHTMLFrameInnerFrame::OnProgressChange(nsIWebProgress *aWebProgress, - nsIRequest *aRequest, - PRInt32 aCurSelfProgress, - PRInt32 aMaxSelfProgress, - PRInt32 aCurTotalProgress, - PRInt32 aMaxTotalProgress) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsHTMLFrameInnerFrame::OnLocationChange(nsIWebProgress *aWebProgress, - nsIRequest *aRequest, nsIURI *location) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsHTMLFrameInnerFrame::OnStatusChange(nsIWebProgress *aWebProgress, - nsIRequest *aRequest, - nsresult aStatus, - const PRUnichar *aMessage) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsHTMLFrameInnerFrame::OnSecurityChange(nsIWebProgress *aWebProgress, - nsIRequest *aRequest, PRInt32 state) -{ - return NS_OK; -} - #ifdef DEBUG NS_IMETHODIMP nsHTMLFrameInnerFrame::GetFrameName(nsAString& aResult) const { @@ -889,7 +836,7 @@ NS_IMETHODIMP nsHTMLFrameInnerFrame::GetFrameType(nsIAtom** aType) const { NS_PRECONDITION(nsnull != aType, "null OUT parameter pointer"); - *aType = nsLayoutAtoms::htmlFrameInnerFrame; + *aType = nsLayoutAtoms::htmlFrameInnerFrame; NS_ADDREF(*aType); return NS_OK; } @@ -901,33 +848,90 @@ nsHTMLFrameInnerFrame::Paint(nsIPresContext* aPresContext, nsFramePaintLayer aWhichLayer, PRUint32 aFlags) { - //printf("inner paint %X (%d,%d,%d,%d) \n", this, aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height); - // if there is not web shell paint based on our background color, - // otherwise let the web shell paint the sub document + //printf("inner paint %X (%d,%d,%d,%d) \n", this, aDirtyRect.x, + //aDirtyRect.y, aDirtyRect.width, aDirtyRect.height); if there is + //not web shell paint based on our background color, otherwise let + //the web shell paint the sub document - // isPaginated is a temporary fix for Bug 75737 - // and this should all be fixed correctly by Bug 75739 + // isPaginated is a temporary fix for Bug 75737 and this should all + // be fixed correctly by Bug 75739 PRBool isPaginated; aPresContext->IsPaginated(&isPaginated); - if (!mSubShell && !isPaginated) { - const nsStyleBackground* color = - (const nsStyleBackground*)mStyleContext->GetStyleData(eStyleStruct_Background); - aRenderingContext.SetColor(color->mBackgroundColor); - aRenderingContext.FillRect(mRect); + + if (!isPaginated) { + nsCOMPtr docShell; + GetDocShell(getter_AddRefs(docShell)); + + if (!docShell) { + const nsStyleBackground* color = + (const nsStyleBackground*)mStyleContext-> + GetStyleData(eStyleStruct_Background); + + aRenderingContext.SetColor(color->mBackgroundColor); + aRenderingContext.FillRect(mRect); + } } + DO_GLOBAL_REFLOW_COUNT_DSP("nsHTMLFrameInnerFrame", &aRenderingContext); + return NS_OK; } -NS_IMETHODIMP -nsHTMLFrameInnerFrame::GetParentContent(nsIContent*& aContent) +void +nsHTMLFrameInnerFrame::GetParentContent(nsIContent** aContent) { - nsHTMLFrameOuterFrame* parent; - nsresult rv = GetParent((nsIFrame**)&parent); - if (NS_SUCCEEDED(rv) && parent) { - rv = parent->GetContent(&aContent); + *aContent = nsnull; + + nsIFrame* parent = nsnull; + GetParent(&parent); + + if (parent) { + parent->GetContent(aContent); } - return rv; +} + +nsresult +nsHTMLFrameInnerFrame::GetDocShell(nsIDocShell **aDocShell) +{ + *aDocShell = nsnull; + + nsCOMPtr content; + GetParentContent(getter_AddRefs(content)); + + if (!content) { + // Hmm, no content in this frame (or in the parent, really), + // that's odd, not much to be done here then. + + return NS_OK; + } + + if (!mFrameLoader) { + nsCOMPtr frame_loader_owner = + do_QueryInterface(content); + + if (frame_loader_owner) { + frame_loader_owner->GetFrameLoader(getter_AddRefs(mFrameLoader)); + } + + if (!mFrameLoader) { + nsresult rv = NS_OK; + + // No frame loader available from the content, create our own... + mFrameLoader = do_CreateInstance(NS_FRAMELOADER_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + // ... remember that we own this frame loader... + mOwnsFrameLoader = PR_TRUE; + + // ... initialize it... + mFrameLoader->Init(content); + + // ... and tell it to start loading. + mFrameLoader->LoadFrame(); + } + } + + return mFrameLoader->GetDocShell(aDocShell); } NS_IMETHODIMP @@ -953,289 +957,131 @@ nsHTMLFrameInnerFrame::DidReflow(nsIPresContext* aPresContext, if (newVis != oldVis) { nsCOMPtr vm; view->GetViewManager(*getter_AddRefs(vm)); - if (vm != nsnull) { + if (vm) { vm->SetViewVisibility(view, newVis); } } } } - + return rv; } nsresult -nsHTMLFrameInnerFrame::CreateDocShell(nsIPresContext* aPresContext) +nsHTMLFrameInnerFrame::ShowDocShell(nsIPresContext* aPresContext) { - nsresult rv; - nsCOMPtr parentContent; - GetParentContent(*getter_AddRefs(parentContent)); + nsCOMPtr docShell; + nsresult rv = GetDocShell(getter_AddRefs(docShell)); + NS_ENSURE_SUCCESS(rv, rv); - // Bug 8065: Don't exceed some maximum depth in content frames (MAX_DEPTH_CONTENT_FRAMES) - PRInt32 depth = 0; - nsCOMPtr parentAsSupports; - aPresContext->GetContainer(getter_AddRefs(parentAsSupports)); - if (parentAsSupports) { - nsCOMPtr parentAsItem(do_QueryInterface(parentAsSupports)); - while (parentAsItem) { - depth++; - if (MAX_DEPTH_CONTENT_FRAMES < depth) { - NS_WARNING("Too many nested content frames so giving up"); - return NS_ERROR_UNEXPECTED; // Too deep, give up! (silently?) - } + PRBool is_document_synthetic = PR_FALSE; - // Only count depth on content, not chrome. - // If we wanted to limit total depth, skip the following check: - PRInt32 parentType; - parentAsItem->GetItemType(&parentType); - if (nsIDocShellTreeItem::typeContent == parentType) { - nsIDocShellTreeItem* temp = parentAsItem; - temp->GetParent(getter_AddRefs(parentAsItem)); - } else { - break; // we have exited content, stop counting, depth is OK! - } + if (mContent->IsContentOfType(nsIContent::eXUL)) { + // We're a XUL iframe/browser tag, for the XUL box object to + // docshell mapping to work we must force a document to be created + // at this point, if we don't, mozilla won't even start since it + // can't reach the docshell from the iframe/browser tags. That + // mapping is based on the subdocument map in the document, which + // obviously won't be setup until the subdocument is created. + + // Make sure there's a document in the docshell. + nsCOMPtr win(do_GetInterface(docShell)); + NS_ENSURE_TRUE(win, NS_ERROR_UNEXPECTED); + + nsCOMPtr pwin(do_QueryInterface(win)); + + nsCOMPtr extant_dom_doc; + pwin->GetExtantDocument(getter_AddRefs(extant_dom_doc)); + + // This will synchronously create a document if there is no + // document in the window yet. + + nsCOMPtr dom_doc; + win->GetDocument(getter_AddRefs(dom_doc)); + + if (dom_doc != extant_dom_doc) { + is_document_synthetic = PR_TRUE; } } - mSubShell = do_CreateInstance(kWebShellCID); - NS_ENSURE_TRUE(mSubShell, NS_ERROR_FAILURE); - - // notify the pres shell that a docshell has been created nsCOMPtr presShell; - aPresContext->GetShell(getter_AddRefs(presShell)); - if (presShell) - { - nsCOMPtr subShellAsSupports(do_QueryInterface(mSubShell)); - NS_ENSURE_TRUE(subShellAsSupports, NS_ERROR_FAILURE); - presShell->SetSubShellFor(mContent, subShellAsSupports); - //We need to be able to get back to the presShell to unset the subshell at destruction - mPresShellWeak = getter_AddRefs(NS_GetWeakReference(presShell)); + docShell->GetPresShell(getter_AddRefs(presShell)); + + if (presShell) { + // The docshell is already showing, nothing left to do... + + return NS_OK; } - - nsCOMPtr docShell(do_QueryInterface(mSubShell)); - NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE); - // pass along marginwidth, marginheight, scrolling so sub document can use it - docShell->SetMarginWidth(GetMarginWidth(aPresContext, parentContent)); - docShell->SetMarginHeight(GetMarginHeight(aPresContext, parentContent)); + + nsCOMPtr docShellTreeItem(do_QueryInterface(docShell)); + + nsCOMPtr parentDocShellTreeItem; + docShellTreeItem->GetParent(getter_AddRefs(parentDocShellTreeItem)); + + nsCOMPtr parentDocShell = + do_QueryInterface(parentDocShellTreeItem); + + nsCOMPtr parentPresShell; + parentDocShell->GetPresShell(getter_AddRefs(parentPresShell)); + + nsCOMPtr content; + GetParentContent(getter_AddRefs(content)); + + // pass along marginwidth, marginheight, scrolling so sub document + // can use it + docShell->SetMarginWidth(GetMarginWidth(aPresContext, content)); + docShell->SetMarginHeight(GetMarginHeight(aPresContext, content)); // Current and initial scrolling is set so that all succeeding docs // will use the scrolling value set here, regardless if scrolling is // set by viewing a particular document (e.g. XUL turns off scrolling) - nsCOMPtr scrollableContainer(do_QueryInterface(mSubShell)); + nsCOMPtr scrollableContainer(do_QueryInterface(docShell)); + if (scrollableContainer) { scrollableContainer->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_Y, - GetScrolling(parentContent)); + GetScrolling(content)); scrollableContainer->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X, - GetScrolling(parentContent)); + GetScrolling(content)); } - nsCOMPtr docShellAsItem(do_QueryInterface(mSubShell)); + nsCOMPtr docShellAsItem(do_QueryInterface(docShell)); NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE); - nsString frameName; - if (GetName(parentContent, frameName)) { - docShellAsItem->SetName(frameName.get()); - } - - // If our container is a web-shell, inform it that it has a new - // child. If it's not a web-shell then some things will not operate - // properly. - nsCOMPtr container; - aPresContext->GetContainer(getter_AddRefs(container)); - if (container) { - nsCOMPtr parentAsNode(do_QueryInterface(container)); - if (parentAsNode) { - nsCOMPtr parentAsItem(do_QueryInterface(parentAsNode)); - PRInt32 parentType; - parentAsItem->GetItemType(&parentType); - - nsIAtom* typeAtom = NS_NewAtom("type"); - nsAutoString value, valuePiece; - PRBool isContent; - - isContent = PR_FALSE; - if (NS_SUCCEEDED(parentContent->GetAttr(kNameSpaceID_None, - typeAtom, value))) { - - // we accept "content" and "content-xxx" values. - // at time of writing, we expect "xxx" to be "primary", but - // someday it might be an integer expressing priority - value.Left(valuePiece, 7); - if (valuePiece.EqualsIgnoreCase("content") && - (value.Length() == 7 || - value.Mid(valuePiece, 7, 1) == 1 && valuePiece.Equals(NS_LITERAL_STRING("-")))) - isContent = PR_TRUE; - } - NS_IF_RELEASE(typeAtom); - if (isContent) { - // The web shell's type is content. - docShellAsItem->SetItemType(nsIDocShellTreeItem::typeContent); - } else { - // Inherit our type from our parent webshell. If it is - // chrome, we'll be chrome. If it is content, we'll be - // content. - docShellAsItem->SetItemType(parentType); - } - - parentAsNode->AddChild(docShellAsItem); - - if (isContent) { - nsCOMPtr parentTreeOwner; - parentAsItem->GetTreeOwner(getter_AddRefs(parentTreeOwner)); - if(parentTreeOwner) - parentTreeOwner->ContentShellAdded(docShellAsItem, - value.EqualsIgnoreCase("content-primary") ? PR_TRUE : PR_FALSE, - value.get()); - } - // connect the container... - nsCOMPtr webShell(do_QueryInterface(mSubShell)); - nsCOMPtr outerContainer(do_QueryInterface(container)); - if (outerContainer) - webShell->SetContainer(outerContainer); - - - // Make sure all shells have links back to the content element in the - // nearest enclosing chrome shell. - nsCOMPtr parentShell(do_QueryInterface(parentAsNode)); - nsCOMPtr chromeEventHandler; - if (parentType == nsIDocShellTreeItem::typeChrome) { - // Our parent shell is a chrome shell. It is therefore our nearest - // enclosing chrome shell. - chromeEventHandler = do_QueryInterface(mContent); - NS_WARN_IF_FALSE(chromeEventHandler, "This mContent should implement this."); - } - else { - // Our parent shell is a content shell. Get the chrome info from - // it and use that for our shell as well. - parentShell->GetChromeEventHandler(getter_AddRefs(chromeEventHandler)); - } - - docShell->SetChromeEventHandler(chromeEventHandler); - } - } nsCOMPtr widget; + rv = CreateViewAndWidget(aPresContext, getter_AddRefs(widget)); if (NS_FAILED(rv)) { return rv; } - mSubShell->InitWindow(nsnull, widget, 0, 0, 10, 10); - mSubShell->Create(); + nsCOMPtr baseWindow(do_QueryInterface(docShell)); - mSubShell->SetVisibility(PR_TRUE); + if (baseWindow) { + baseWindow->InitWindow(nsnull, widget, 0, 0, 10, 10); + + // This is kinda whacky, this "Create()" call doesn't really + // create anything, one starts to wonder why this was named + // "Create"... + + baseWindow->Create(); + + PRBool is_document_loading = PR_TRUE; + mFrameLoader->GetIsDocumentLoading(&is_document_loading); + + if (!is_document_synthetic || !is_document_loading) { + // We're about to either show a "real" document (i.e. not a + // synthetic about:blank document) or we're showing an iframe + // that we didn't load anything into yet (i.e. there was no + // src="..." attribute on the iframe element. Make sure we show + // the window. + + baseWindow->SetVisibility(PR_TRUE); + } + } return NS_OK; } -nsresult -nsHTMLFrameInnerFrame::DoLoadURL(nsIPresContext* aPresContext) -{ - // Bug 8065: Preventing frame nesting recursion - if the frames are - // too deep we don't create a mSubShell, so this isn't an assert: - if (!mSubShell) return NS_OK; - - // Prevent recursion - mCreatingViewer=PR_TRUE; - - // Get the URL to load - nsCOMPtr parentContent; - nsresult rv = GetParentContent(*getter_AddRefs(parentContent)); - NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && parentContent, rv); - - nsAutoString url; - GetURL(parentContent, url); - url.Trim(" \t\n\r"); - if (url.IsEmpty()) // Load about:blank into a frame if not URL is specified (bug 35986) - url = NS_LITERAL_STRING("about:blank"); - - // Make an absolute URL - nsCOMPtr baseURL; - nsCOMPtr htmlContent = do_QueryInterface(parentContent, &rv); - nsCOMPtr doc; - if (NS_SUCCEEDED(rv) && htmlContent) { - htmlContent->GetBaseURL(*getter_AddRefs(baseURL)); - (void) htmlContent->GetDocument(*getter_AddRefs(doc)); - } - else { - rv = parentContent->GetDocument(*getter_AddRefs(doc)); - if (NS_SUCCEEDED(rv) && doc) { - doc->GetBaseURL(*getter_AddRefs(baseURL)); - } - } - if (!baseURL) return NS_ERROR_NULL_POINTER; - - nsAutoString docCharset; - if (doc) - (void) doc->GetDocumentCharacterSet(docCharset); - - nsAutoString absURL; - rv = NS_MakeAbsoluteURI(absURL, url, baseURL); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr uri; - NS_NewURI(getter_AddRefs(uri), absURL, - docCharset.IsEmpty() ? nsnull : NS_ConvertUCS2toUTF8(docCharset).get()); - - // Check for security - nsCOMPtr secMan = - do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - - // Get base URL - nsCOMPtr baseURI; - rv = aPresContext->GetBaseURL(getter_AddRefs(baseURI)); - - // Get docshell and create load info - nsCOMPtr docShell(do_QueryInterface(mSubShell)); - NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE); - nsCOMPtr loadInfo; - docShell->CreateLoadInfo(getter_AddRefs(loadInfo)); - NS_ENSURE_TRUE(loadInfo, NS_ERROR_FAILURE); - - // Get referring URL - nsCOMPtr referrer; - nsCOMPtr principal; - rv = secMan->GetSubjectPrincipal(getter_AddRefs(principal)); - NS_ENSURE_SUCCESS(rv, rv); - // If we were called from script, get the referring URL from the script - if (principal) { - nsCOMPtr codebase = do_QueryInterface(principal); - if (codebase) { - rv = codebase->GetURI(getter_AddRefs(referrer)); - NS_ENSURE_SUCCESS(rv, rv); - } - // Pass the script principal to the docshell - nsCOMPtr owner = do_QueryInterface(principal); - loadInfo->SetOwner(owner); - } - if (!referrer) { // We're not being called form script, tell the docshell - // to inherit an owner from the current document. - loadInfo->SetInheritOwner(PR_TRUE); - referrer = baseURI; - } - - loadInfo->SetReferrer(referrer); - - // Check if we are allowed to load absURL - nsCOMPtr newURI; - rv = NS_NewURI(getter_AddRefs(newURI), absURL, nsnull, baseURI); - NS_ENSURE_SUCCESS(rv, rv); - rv = secMan->CheckLoadURI(referrer, newURI, nsIScriptSecurityManager::STANDARD); - if (NS_FAILED(rv)) - return rv; // We're not - - nsCOMPtr webProgress(do_GetInterface(mSubShell)); - - if (webProgress) { - webProgress->AddProgressListener(this); - } - - rv = docShell->LoadURI(uri, loadInfo, nsIWebNavigation::LOAD_FLAGS_NONE, PR_FALSE); - NS_ASSERTION(NS_SUCCEEDED(rv), "failed to load URL"); - - return rv; -} - - nsresult nsHTMLFrameInnerFrame::CreateViewAndWidget(nsIPresContext* aPresContext, nsIWidget** aWidget) @@ -1245,28 +1091,29 @@ nsHTMLFrameInnerFrame::CreateViewAndWidget(nsIPresContext* aPresContext, nsCOMPtr presShell; aPresContext->GetShell(getter_AddRefs(presShell)); - if (!presShell) return NS_ERROR_FAILURE; + NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE); float t2p; aPresContext->GetTwipsToPixels(&t2p); // create, init, set the parent of the view nsIView* view; - nsresult rv = nsComponentManager::CreateInstance(kCViewCID, nsnull, NS_GET_IID(nsIView), - (void **)&view); + nsresult rv = nsComponentManager::CreateInstance(kCViewCID, nsnull, + NS_GET_IID(nsIView), + (void **)&view); + if (NS_FAILED(rv)) { + NS_ERROR("Could not create view for nsHTMLFrame"); - if (NS_OK != rv) { - NS_ASSERTION(0, "Could not create view for nsHTMLFrame"); return rv; } nsIView* parView; nsPoint origin; - GetOffsetFromView(aPresContext, origin, &parView); + GetOffsetFromView(aPresContext, origin, &parView); nsRect viewBounds(origin.x, origin.y, 10, 10); nsCOMPtr viewMan; - presShell->GetViewManager(getter_AddRefs(viewMan)); + presShell->GetViewManager(getter_AddRefs(viewMan)); rv = view->Init(viewMan, viewBounds, parView); // XXX put it at the end of the document order until we can do better viewMan->InsertChild(parView, view, nsnull, PR_TRUE); @@ -1295,41 +1142,39 @@ nsHTMLFrameInnerFrame::Init(nsIPresContext* aPresContext, nsIStyleContext* aContext, nsIFrame* aPrevInFlow) { - nsresult rv = nsLeafFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow); + nsresult rv = nsLeafFrame::Init(aPresContext, aContent, aParent, aContext, + aPrevInFlow); if (NS_FAILED(rv)) return rv; // determine if we are a printcontext PRBool shouldCreateDoc = PR_TRUE; - nsCOMPtr thePrinterContext = do_QueryInterface(aPresContext); - if (thePrinterContext) { + nsCOMPtr thePrinterContext(do_QueryInterface(aPresContext)); + + if (thePrinterContext) { // we are printing shouldCreateDoc = PR_FALSE; } - // for print preview we want to create the view and widget but + // for print preview we want to create the view and widget but // we do not want to load the document, it is alerady loaded. - nsCOMPtr thePrintPreviewContext = do_QueryInterface(aPresContext); - if (thePrintPreviewContext) { + nsCOMPtr thePrintPreviewContext = + do_QueryInterface(aPresContext); + + if (thePrintPreviewContext) { nsCOMPtr widget; rv = CreateViewAndWidget(aPresContext, getter_AddRefs(widget)); + if (NS_FAILED(rv)) { return rv; } + // we are in PrintPreview shouldCreateDoc = PR_FALSE; } - - if (!mCreatingViewer && shouldCreateDoc) { - // create the web shell - // we do this even if the size is not positive (bug 11762) - // we do this even if there is no src (bug 16218) - if (!mSubShell) - rv = CreateDocShell(aPresContext); - // Whether or not we had to create a webshell, load the document - if (NS_SUCCEEDED(rv)) { - DoLoadURL(aPresContext); - } + + if (shouldCreateDoc) { + ShowDocShell(aPresContext); } return NS_OK; @@ -1350,41 +1195,55 @@ nsHTMLFrameInnerFrame::Reflow(nsIPresContext* aPresContext, nsresult rv = NS_OK; - // use the max size set in aReflowState by the nsHTMLFrameOuterFrame as our size + // use the max size set in aReflowState by the nsHTMLFrameOuterFrame + // as our size GetDesiredSize(aPresContext, aReflowState, aDesiredSize); aStatus = NS_FRAME_COMPLETE; + nsCOMPtr docShell; + GetDocShell(getter_AddRefs(docShell)); + + nsCOMPtr baseWindow(do_QueryInterface(docShell)); + // resize the sub document - if(mSubShell) { + if (baseWindow) { float t2p; aPresContext->GetTwipsToPixels(&t2p); PRInt32 x = 0; PRInt32 y = 0; - mSubShell->GetPositionAndSize(&x, &y, nsnull, nsnull); - PRInt32 cx = NSToCoordRound(aDesiredSize.width * t2p); + baseWindow->GetPositionAndSize(&x, &y, nsnull, nsnull); + PRInt32 cx = NSToCoordRound(aDesiredSize.width * t2p); PRInt32 cy = NSToCoordRound(aDesiredSize.height * t2p); - mSubShell->SetPositionAndSize(x, y, cx, cy, PR_FALSE); + baseWindow->SetPositionAndSize(x, y, cx, cy, PR_FALSE); NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS, - ("exit nsHTMLFrameInnerFrame::Reflow: size=%d,%d rv=%x", - aDesiredSize.width, aDesiredSize.height, aStatus)); + ("exit nsHTMLFrameInnerFrame::Reflow: size=%d,%d rv=%x", + aDesiredSize.width, aDesiredSize.height, aStatus)); } - + return rv; } // load a new url nsresult -nsHTMLFrameInnerFrame::ReloadURL(nsIPresContext* aPresContext) +nsHTMLFrameInnerFrame::ReloadURL() { - return DoLoadURL(aPresContext); + if (!mOwnsFrameLoader || !mFrameLoader) { + // If we don't own the frame loader, we're not in charge of what's + // loaded into it. + + return NS_OK; + } + + return mFrameLoader->LoadFrame(); } -void + +void nsHTMLFrameInnerFrame::GetDesiredSize(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsHTMLReflowMetrics& aDesiredSize) @@ -1394,19 +1253,28 @@ nsHTMLFrameInnerFrame::GetDesiredSize(nsIPresContext* aPresContext, aDesiredSize.ascent = aDesiredSize.height; aDesiredSize.descent = 0; - // For unknown reasons, the maxElementSize for the InnerFrame is used, but the - // maxElementSize for the OuterFrame is ignored, make sure to get it right here! + // For unknown reasons, the maxElementSize for the InnerFrame is + // used, but the maxElementSize for the OuterFrame is ignored, make + // sure to get it right here! + if (aDesiredSize.maxElementSize) { if ((NS_UNCONSTRAINEDSIZE == aReflowState.availableWidth) || - (eStyleUnit_Percent == aReflowState.mStylePosition->mWidth.GetUnit())) { - aDesiredSize.maxElementSize->width = 0; // percent width springy down to 0 px + (eStyleUnit_Percent == + aReflowState.mStylePosition->mWidth.GetUnit())) { + // percent width springy down to 0 px + + aDesiredSize.maxElementSize->width = 0; } else { aDesiredSize.maxElementSize->width = aDesiredSize.width; } + if ((NS_UNCONSTRAINEDSIZE == aReflowState.availableHeight) || - (eStyleUnit_Percent == aReflowState.mStylePosition->mHeight.GetUnit())) { - aDesiredSize.maxElementSize->height = 0; // percent height springy down to 0px + (eStyleUnit_Percent == + aReflowState.mStylePosition->mHeight.GetUnit())) { + // percent height springy down to 0px + + aDesiredSize.maxElementSize->height = 0; } else { aDesiredSize.maxElementSize->height = aDesiredSize.height; @@ -1414,9 +1282,9 @@ nsHTMLFrameInnerFrame::GetDesiredSize(nsIPresContext* aPresContext, } } -/******************************************************************************* +/****************************************************************************** * FrameLoadingInfo - ******************************************************************************/ + *****************************************************************************/ FrameLoadingInfo::FrameLoadingInfo(const nsSize& aSize) { NS_INIT_REFCNT(); diff --git a/layout/html/document/src/nsFrameSetFrame.cpp b/layout/html/document/src/nsFrameSetFrame.cpp index a1a4b002844..6820963d6ee 100644 --- a/layout/html/document/src/nsFrameSetFrame.cpp +++ b/layout/html/document/src/nsFrameSetFrame.cpp @@ -63,7 +63,6 @@ #define ALL_VIS 0x000F #define NONE_VIS 0x0000 -static NS_DEFINE_IID(kIFramesetFrameIID, NS_IFRAMESETFRAME_IID); static NS_DEFINE_IID(kLookAndFeelCID, NS_LOOKANDFEEL_CID); /******************************************************************************* @@ -231,19 +230,29 @@ nsHTMLFramesetFrame::nsHTMLFramesetFrame() nsHTMLFramesetFrame::~nsHTMLFramesetFrame() { - if (mRowSizes) delete [] mRowSizes; - if (mRowSpecs) delete [] mRowSpecs; - if (mColSizes) delete [] mColSizes; - if (mColSpecs) delete [] mColSpecs; - if (mVerBorders) delete[] mVerBorders; - if (mHorBorders) delete[] mHorBorders; + delete [] mRowSizes; + delete [] mRowSpecs; + delete [] mColSizes; + delete [] mColSpecs; + delete[] mVerBorders; + delete[] mHorBorders; + mRowSizes = mColSizes = nsnull; mRowSpecs = mColSpecs = nsnull; - nsCOMPtr prefBranch(do_QueryReferent(mPrefBranchWeakRef)); + + nsCOMPtr prefBranch = + do_QueryReferent(mPrefBranchWeakRef); + if (prefBranch) { - nsresult rv = prefBranch->RemoveObserver(kFrameResizePref, this); - NS_ASSERTION(NS_SUCCEEDED(rv), "Can't remove frameset as pref branch observer"); +#ifdef DEBUG + nsresult rv = +#endif + prefBranch->RemoveObserver(kFrameResizePref, this); + + NS_ASSERTION(NS_SUCCEEDED(rv), + "Can't remove frameset as pref branch observer"); } + mPrefBranchWeakRef = nsnull; } @@ -252,7 +261,7 @@ nsresult nsHTMLFramesetFrame::QueryInterface(const nsIID& aIID, { if (NULL == aInstancePtr) { return NS_ERROR_NULL_POINTER; - } else if (aIID.Equals(kIFramesetFrameIID)) { + } else if (aIID.Equals(NS_GET_IID(nsHTMLFramesetFrame))) { *aInstancePtr = (void*)this; return NS_OK; } else if (aIID.Equals(NS_GET_IID(nsIObserver))) { @@ -327,7 +336,8 @@ nsHTMLFramesetFrame::Init(nsIPresContext* aPresContext, mTopLevelFrameset = (nsHTMLFramesetFrame*)this; while (parentFrame) { nsHTMLFramesetFrame* frameset; - rv = parentFrame->QueryInterface(kIFramesetFrameIID, (void**)&frameset); + rv = parentFrame->QueryInterface(NS_GET_IID(nsHTMLFramesetFrame), + (void**)&frameset); if (NS_SUCCEEDED(rv)) { mTopLevelFrameset = frameset; parentFrame->GetParent((nsIFrame**)&parentFrame); @@ -1404,7 +1414,7 @@ PRBool nsHTMLFramesetFrame::ChildIsFrameset(nsIFrame* aChild) { nsIFrame* childFrame = nsnull; - aChild->QueryInterface(kIFramesetFrameIID, (void**)&childFrame); + aChild->QueryInterface(NS_GET_IID(nsHTMLFramesetFrame), (void**)&childFrame); if (childFrame) { return PR_TRUE; } diff --git a/layout/html/document/src/nsFrameSetFrame.h b/layout/html/document/src/nsFrameSetFrame.h index fe786185fd8..88000505dff 100644 --- a/layout/html/document/src/nsFrameSetFrame.h +++ b/layout/html/document/src/nsFrameSetFrame.h @@ -57,7 +57,8 @@ struct nsGUIEvent; class nsHTMLFramesetFrame; #define NS_IFRAMESETFRAME_IID \ -{ 0xf47deac0, 0x4200, 0x11d2, { 0x80, 0x3c, 0x0, 0x60, 0x8, 0x15, 0xa7, 0x91 } } +{ 0xf47deac0, 0x4200, 0x11d2, \ + { 0x80, 0x3c, 0x0, 0x60, 0x8, 0x15, 0xa7, 0x91 } } #define NO_COLOR 0xFFFFFFFA @@ -115,8 +116,10 @@ struct nsFramesetDrag { class nsHTMLFramesetFrame : public nsHTMLContainerFrame, public nsIObserver { - public: + // Woohoo, concrete class with an IID! + NS_DEFINE_STATIC_IID_ACCESSOR(NS_IFRAMESETFRAME_IID) + nsHTMLFramesetFrame(); virtual ~nsHTMLFramesetFrame(); diff --git a/layout/printing/nsPrintPreviewListener.h b/layout/printing/nsPrintPreviewListener.h index e54ae20aa51..9efa2808bd0 100644 --- a/layout/printing/nsPrintPreviewListener.h +++ b/layout/printing/nsPrintPreviewListener.h @@ -56,6 +56,9 @@ public: NS_DECL_ISUPPORTS nsPrintPreviewListener(nsIDOMEventReceiver* aEVRec); + virtual ~nsPrintPreviewListener() + { + } // nsIDOMContextMenuListener NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; } diff --git a/layout/style/nsCSSStyleSheet.cpp b/layout/style/nsCSSStyleSheet.cpp index cb0e42c7224..aeb399462ca 100644 --- a/layout/style/nsCSSStyleSheet.cpp +++ b/layout/style/nsCSSStyleSheet.cpp @@ -2637,7 +2637,7 @@ CSSStyleSheetImpl::SetDisabled(PRBool aDisabled) PRBool oldState = mDisabled; mDisabled = aDisabled; - if ((nsnull != mDocument) && (mDisabled != oldState)) { + if (mDocument && (mDisabled != oldState)) { mDocument->SetStyleSheetDisabledState(this, mDisabled); } diff --git a/layout/xul/base/src/nsBrowserBoxObject.cpp b/layout/xul/base/src/nsBrowserBoxObject.cpp index 0bd87006df5..42a8661b11c 100644 --- a/layout/xul/base/src/nsBrowserBoxObject.cpp +++ b/layout/xul/base/src/nsBrowserBoxObject.cpp @@ -38,9 +38,9 @@ #include "nsCOMPtr.h" #include "nsIBrowserBoxObject.h" #include "nsBoxObject.h" -#include "nsIPresShell.h" #include "nsIFrame.h" #include "nsIDocShell.h" +#include "nsIDocument.h" #include "nsXPIDLString.h" class nsBrowserBoxObject : public nsIBrowserBoxObject, public nsBoxObject @@ -87,19 +87,31 @@ nsBrowserBoxObject::~nsBrowserBoxObject() delete mSrcURL; } -/* void openBrowser (in boolean openFlag); */ NS_IMETHODIMP nsBrowserBoxObject::GetDocShell(nsIDocShell** aResult) { *aResult = nsnull; - if (!mPresShell) - return NS_OK; - nsCOMPtr subShell; - mPresShell->GetSubShellFor(mContent, getter_AddRefs(subShell)); - if(!subShell) + if (!mPresShell) { return NS_OK; + } - return CallQueryInterface(subShell, aResult); //Addref happens here. + nsCOMPtr doc, sub_doc; + mPresShell->GetDocument(getter_AddRefs(doc)); + + doc->GetSubDocumentFor(mContent, getter_AddRefs(sub_doc)); + + if (!sub_doc) { + return NS_OK; + } + + nsCOMPtr container; + sub_doc->GetContainer(getter_AddRefs(container)); + + if (!container) { + return NS_OK; + } + + return CallQueryInterface(container, aResult); } // Creation Routine /////////////////////////////////////////////////////////////////////// diff --git a/layout/xul/base/src/nsEditorBoxObject.cpp b/layout/xul/base/src/nsEditorBoxObject.cpp index ff597efeb25..e2856ee6c86 100644 --- a/layout/xul/base/src/nsEditorBoxObject.cpp +++ b/layout/xul/base/src/nsEditorBoxObject.cpp @@ -38,7 +38,7 @@ #include "nsCOMPtr.h" #include "nsIEditorBoxObject.h" #include "nsBoxObject.h" -#include "nsIPresShell.h" +#include "nsIDocument.h" #include "nsIFrame.h" #include "nsIEditorShell.h" #include "nsIComponentManager.h" @@ -128,15 +128,28 @@ NS_IMETHODIMP nsEditorBoxObject::GetEditorShell(nsIEditorShell** aResult) NS_IMETHODIMP nsEditorBoxObject::GetDocShell(nsIDocShell** aResult) { *aResult = nsnull; - if (!mPresShell) - return NS_OK; - nsCOMPtr subShell; - mPresShell->GetSubShellFor(mContent, getter_AddRefs(subShell)); - if(!subShell) + if (!mPresShell) { return NS_OK; + } - return CallQueryInterface(subShell, aResult); //Addref happens here. + nsCOMPtr doc, sub_doc; + mPresShell->GetDocument(getter_AddRefs(doc)); + + doc->GetSubDocumentFor(mContent, getter_AddRefs(sub_doc)); + + if (!sub_doc) { + return NS_OK; + } + + nsCOMPtr container; + sub_doc->GetContainer(getter_AddRefs(container)); + + if (!container) { + return NS_OK; + } + + return CallQueryInterface(container, aResult); } // Creation Routine /////////////////////////////////////////////////////////////////////// diff --git a/layout/xul/base/src/nsIFrameBoxObject.cpp b/layout/xul/base/src/nsIFrameBoxObject.cpp index 4f8dbe35690..4473006aa76 100644 --- a/layout/xul/base/src/nsIFrameBoxObject.cpp +++ b/layout/xul/base/src/nsIFrameBoxObject.cpp @@ -38,6 +38,7 @@ #include "nsCOMPtr.h" #include "nsIIFrameBoxObject.h" #include "nsBoxObject.h" +#include "nsIDocument.h" #include "nsIPresShell.h" #include "nsIFrame.h" #include "nsIDocShell.h" @@ -87,15 +88,28 @@ nsIFrameBoxObject::~nsIFrameBoxObject() NS_IMETHODIMP nsIFrameBoxObject::GetDocShell(nsIDocShell** aResult) { *aResult = nsnull; - if (!mPresShell) - return NS_OK; - nsCOMPtr subShell; - mPresShell->GetSubShellFor(mContent, getter_AddRefs(subShell)); - if(!subShell) + if (!mPresShell) { return NS_OK; + } - return CallQueryInterface(subShell, aResult); //Addref happens here. + nsCOMPtr doc, sub_doc; + mPresShell->GetDocument(getter_AddRefs(doc)); + + doc->GetSubDocumentFor(mContent, getter_AddRefs(sub_doc)); + + if (!sub_doc) { + return NS_OK; + } + + nsCOMPtr container; + sub_doc->GetContainer(getter_AddRefs(container)); + + if (!container) { + return NS_OK; + } + + return CallQueryInterface(container, aResult); } // Creation Routine ///////////////////////////////////////////////////////////////////////