timeless%mac.com 2002-04-05 05:42:10 +00:00
Родитель 85b4b37772
Коммит a84a7e233f
55 изменённых файлов: 3006 добавлений и 3603 удалений

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

@ -27,4 +27,3 @@ nsIStyleSheet.h
nsIStyleSheetLinkingElement.h nsIStyleSheetLinkingElement.h
nsITextContent.h nsITextContent.h
nsIContentList.h nsIContentList.h
nsIFrameLoader.h

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

@ -56,7 +56,6 @@ nsIPrivateDOMImplementation.h \
nsIContentSerializer.h \ nsIContentSerializer.h \
nsIHTMLToTextSink.h \ nsIHTMLToTextSink.h \
nsIContentList.h \ nsIContentList.h \
nsIFrameLoader.h \
$(NULL) $(NULL)
XPIDLSRCS = \ XPIDLSRCS = \

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

@ -48,7 +48,6 @@ EXPORTS = \
nsIContentSerializer.h \ nsIContentSerializer.h \
nsIHTMLToTextSink.h \ nsIHTMLToTextSink.h \
nsIContentList.h \ nsIContentList.h \
nsIFrameLoader.h \
$(NULL) $(NULL)
MODULE=content MODULE=content

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

@ -227,32 +227,13 @@ public:
/** /**
* Return the parent document of this document. Will return null * Return the parent document of this document. Will return null
* unless this document is within a compound document and has a * unless this document is within a compound document and has a parent.
* parent. Note that this parent chain may cross chrome boundaries.
*/ */
NS_IMETHOD GetParentDocument(nsIDocument** aParent) = 0; NS_IMETHOD GetParentDocument(nsIDocument** aParent) = 0;
/**
* Set the parent document of this document.
*/
NS_IMETHOD SetParentDocument(nsIDocument* aParent) = 0; NS_IMETHOD SetParentDocument(nsIDocument* aParent) = 0;
NS_IMETHOD AddSubDocument(nsIDocument* aSubDoc) = 0;
/** NS_IMETHOD GetNumberOfSubDocuments(PRInt32* aCount) = 0;
* Set the sub document for aContent to aSubDoc. NS_IMETHOD GetSubDocumentAt(PRInt32 aIndex, nsIDocument** aSubDoc) = 0;
*/
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. * Return the root content object for this document.
@ -392,16 +373,6 @@ public:
NS_IMETHOD AddReference(void *aKey, nsISupports *aReference) = 0; NS_IMETHOD AddReference(void *aKey, nsISupports *aReference) = 0;
NS_IMETHOD RemoveReference(void *aKey, nsISupports **aOldReference) = 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;
}; };

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

@ -43,7 +43,7 @@
#include "nsAString.h" #include "nsAString.h"
// Forward declarations // Forward declarations
class nsIContent; class nsIDOMElement;
class nsIDocShell; class nsIDocShell;
class nsIURI; class nsIURI;
@ -57,42 +57,18 @@ class nsIURI;
{ 0x0080d493, 0x96b4, 0x4606, \ { 0x0080d493, 0x96b4, 0x4606, \
{0xa7, 0x43, 0x0f, 0x47, 0xee, 0x87, 0x14, 0xd1} } {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 class nsIFrameLoader : public nsISupports
{ {
public: public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IFRAMELOADER_IID) 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; NS_IMETHOD GetDocShell(nsIDocShell **aDocShell) = 0;
/**
* Destroy the frame loader and everything inside it. This will
* clear the weak owner content reference.
*/
NS_IMETHOD Destroy() = 0; NS_IMETHOD Destroy() = 0;
}; };
@ -102,9 +78,6 @@ class nsIFrameLoaderOwner : public nsISupports
public: public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IFRAMELOADEROWNER_IID) NS_DEFINE_STATIC_IID_ACCESSOR(NS_IFRAMELOADEROWNER_IID)
/**
* Get the frame loader from the frame loader owner.
*/
NS_IMETHOD GetFrameLoader(nsIFrameLoader **aFrameLoader) = 0; NS_IMETHOD GetFrameLoader(nsIFrameLoader **aFrameLoader) = 0;
}; };

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

@ -55,8 +55,8 @@ REQUIRES = xpcom \
imglib2 \ imglib2 \
gfx2 \ gfx2 \
uriloader \ uriloader \
webbrwsr \ webbrwsr \
webBrowser_core \ webBrowser_core \
$(NULL) $(NULL)
CPPSRCS = \ CPPSRCS = \
@ -97,11 +97,9 @@ CPPSRCS = \
nsScriptLoader.cpp \ nsScriptLoader.cpp \
nsStyleLinkElement.cpp \ nsStyleLinkElement.cpp \
nsContentAreaDragDrop.cpp \ nsContentAreaDragDrop.cpp \
nsFrameLoader.cpp \
$(NULL) $(NULL)
# we don't want the shared lib, but we want to force the creation of a # we don't want the shared lib, but we want to force the creation of a static lib.
# static lib.
FORCE_STATIC_LIB = 1 FORCE_STATIC_LIB = 1
include $(topsrcdir)/config/rules.mk include $(topsrcdir)/config/rules.mk

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

@ -43,7 +43,6 @@ REQUIRES = xpcom \
uconv \ uconv \
chrome \ chrome \
docshell \ docshell \
uriloader \
pref \ pref \
xpconnect \ xpconnect \
util \ util \
@ -69,10 +68,10 @@ CPP_OBJS= \
.\$(OBJDIR)\nsCommentNode.obj \ .\$(OBJDIR)\nsCommentNode.obj \
.\$(OBJDIR)\nsGenericDOMDataNode.obj \ .\$(OBJDIR)\nsGenericDOMDataNode.obj \
.\$(OBJDIR)\nsGenericDOMNodeList.obj \ .\$(OBJDIR)\nsGenericDOMNodeList.obj \
.\$(OBJDIR)\nsGenericElement.obj \ .\$(OBJDIR)\nsGenericElement.obj \
.\$(OBJDIR)\nsContentList.obj \ .\$(OBJDIR)\nsContentList.obj \
.\$(OBJDIR)\nsContentIterator.obj \ .\$(OBJDIR)\nsContentIterator.obj \
.\$(OBJDIR)\nsContentPolicy.obj \ .\$(OBJDIR)\nsContentPolicy.obj \
.\$(OBJDIR)\nsDocument.obj \ .\$(OBJDIR)\nsDocument.obj \
.\$(OBJDIR)\nsDocumentEncoder.obj \ .\$(OBJDIR)\nsDocumentEncoder.obj \
.\$(OBJDIR)\nsDocumentFragment.obj \ .\$(OBJDIR)\nsDocumentFragment.obj \
@ -80,7 +79,7 @@ CPP_OBJS= \
.\$(OBJDIR)\nsDOMAttribute.obj \ .\$(OBJDIR)\nsDOMAttribute.obj \
.\$(OBJDIR)\nsDOMAttributeMap.obj \ .\$(OBJDIR)\nsDOMAttributeMap.obj \
.\$(OBJDIR)\nsDOMDocumentType.obj \ .\$(OBJDIR)\nsDOMDocumentType.obj \
.\$(OBJDIR)\nsGeneratedIterator.obj \ .\$(OBJDIR)\nsGeneratedIterator.obj \
.\$(OBJDIR)\nsNameSpaceManager.obj \ .\$(OBJDIR)\nsNameSpaceManager.obj \
.\$(OBJDIR)\nsNodeInfo.obj \ .\$(OBJDIR)\nsNodeInfo.obj \
.\$(OBJDIR)\nsNodeInfoManager.obj \ .\$(OBJDIR)\nsNodeInfoManager.obj \
@ -92,13 +91,12 @@ CPP_OBJS= \
.\$(OBJDIR)\nsTreeWalker.obj \ .\$(OBJDIR)\nsTreeWalker.obj \
.\$(OBJDIR)\nsXMLContentSerializer.obj \ .\$(OBJDIR)\nsXMLContentSerializer.obj \
.\$(OBJDIR)\nsHTMLContentSerializer.obj \ .\$(OBJDIR)\nsHTMLContentSerializer.obj \
.\$(OBJDIR)\nsParserUtils.obj \ .\$(OBJDIR)\nsParserUtils.obj \
.\$(OBJDIR)\nsPlainTextSerializer.obj \ .\$(OBJDIR)\nsPlainTextSerializer.obj \
.\$(OBJDIR)\nsContentUtils.obj \ .\$(OBJDIR)\nsContentUtils.obj \
.\$(OBJDIR)\nsScriptLoader.obj \ .\$(OBJDIR)\nsScriptLoader.obj \
.\$(OBJDIR)\nsStyleLinkElement.obj \ .\$(OBJDIR)\nsStyleLinkElement.obj \
.\$(OBJDIR)\nsContentAreaDragDrop.obj \ .\$(OBJDIR)\nsContentAreaDragDrop.obj \
.\$(OBJDIR)\nsFrameLoader.obj \
$(NULL) $(NULL)
LINCS=-I..\..\html\base\src -I..\..\html\style\src \ LINCS=-I..\..\html\base\src -I..\..\html\style\src \

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

@ -445,7 +445,7 @@ nsDocumentChildNodes::DropReference()
// ================================================================== // ==================================================================
nsDocument::nsDocument() : mIsGoingAway(PR_FALSE), nsDocument::nsDocument() : mIsGoingAway(PR_FALSE),
mCSSLoader(nsnull), mSubDocuments(nsnull) mCSSLoader(nsnull)
{ {
NS_INIT_REFCNT(); NS_INIT_REFCNT();
@ -476,7 +476,6 @@ nsDocument::nsDocument() : mIsGoingAway(PR_FALSE),
mObservers.InsertElementAt(observer, 0); mObservers.InsertElementAt(observer, 0);
} }
nsDocument::~nsDocument() nsDocument::~nsDocument()
{ {
// XXX Inform any remaining observers that we are going away. // XXX Inform any remaining observers that we are going away.
@ -502,12 +501,11 @@ nsDocument::~nsDocument()
mParentDocument = nsnull; mParentDocument = nsnull;
// Kill the subdocument map, doing this will release its strong // Delete references to sub-documents
// references, if any. indx = mSubDocuments.Count();
if (mSubDocuments) { while (--indx >= 0) {
PL_DHashTableDestroy(mSubDocuments); nsIDocument* subdoc = (nsIDocument*) mSubDocuments.ElementAt(indx);
NS_RELEASE(subdoc);
mSubDocuments = nsnull;
} }
if (mRootContent) { if (mRootContent) {
@ -673,28 +671,25 @@ nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup)
NS_IF_RELEASE(mPrincipal); NS_IF_RELEASE(mPrincipal);
mDocumentLoadGroup = nsnull; mDocumentLoadGroup = nsnull;
// Delete references to sub-documents and kill the subdocument map, // Delete references to sub-documents
// if any. It holds strong references PRInt32 indx = mSubDocuments.Count();
if (mSubDocuments) { while (--indx >= 0) {
PL_DHashTableDestroy(mSubDocuments); nsIDocument* subdoc = (nsIDocument*) mSubDocuments.ElementAt(indx);
NS_RELEASE(subdoc);
mSubDocuments = nsnull;
} }
mRootContent = nsnull; mRootContent = nsnull;
PRUint32 count, i; PRUint32 count, i;
mChildren->Count(&count); mChildren->Count(&count);
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
nsCOMPtr<nsIContent> content = nsCOMPtr<nsIContent> content(dont_AddRef(NS_STATIC_CAST(nsIContent*,mChildren->ElementAt(i))));
dont_AddRef(NS_STATIC_CAST(nsIContent *, mChildren->ElementAt(i)));
content->SetDocument(nsnull, PR_TRUE, PR_TRUE); content->SetDocument(nsnull, PR_TRUE, PR_TRUE);
ContentRemoved(nsnull, content, i); ContentRemoved(nsnull, content, indx);
} }
mChildren->Clear(); mChildren->Clear();
// Delete references to style sheets // Delete references to style sheets
PRInt32 indx = mStyleSheets.Count(); indx = mStyleSheets.Count();
while (--indx >= 0) { while (--indx >= 0) {
nsIStyleSheet* sheet = (nsIStyleSheet*) mStyleSheets.ElementAt(indx); nsIStyleSheet* sheet = (nsIStyleSheet*) mStyleSheets.ElementAt(indx);
sheet->SetOwningDocument(nsnull); sheet->SetOwningDocument(nsnull);
@ -728,9 +723,8 @@ nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup)
if (aLoadGroup) { if (aLoadGroup) {
mDocumentLoadGroup = getter_AddRefs(NS_GetWeakReference(aLoadGroup)); mDocumentLoadGroup = getter_AddRefs(NS_GetWeakReference(aLoadGroup));
// there was an assertion here that aLoadGroup was not null. This // there was an assertion here that aLoadGroup was not null. This is no longer valid
// is no longer valid nsWebShell::SetDocument does not create a // nsWebShell::SetDocument does not create a load group, and it works just fine.
// load group, and it works just fine.
} }
if (NS_OK == rv) if (NS_OK == rv)
@ -1165,151 +1159,26 @@ nsDocument::SetParentDocument(nsIDocument* aParent)
return NS_OK; return NS_OK;
} }
PR_STATIC_CALLBACK(void)
SubDocClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
{
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 NS_IMETHODIMP
nsDocument::SetSubDocumentFor(nsIContent *aContent, nsIDocument* aSubDoc) nsDocument::AddSubDocument(nsIDocument* aSubDoc)
{ {
NS_ENSURE_TRUE(aContent, NS_ERROR_UNEXPECTED); NS_ADDREF(aSubDoc);
mSubDocuments.AppendElement(aSubDoc);
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; return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
nsDocument::GetSubDocumentFor(nsIContent *aContent, nsIDocument** aSubDoc) nsDocument::GetNumberOfSubDocuments(PRInt32* aCount)
{ {
*aSubDoc = nsnull; *aCount = mSubDocuments.Count();
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; 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 = entry->mKey;
return PL_DHASH_STOP;
}
return PL_DHASH_NEXT;
}
NS_IMETHODIMP NS_IMETHODIMP
nsDocument::FindContentForSubDocument(nsIDocument *aDocument, nsDocument::GetSubDocumentAt(PRInt32 aIndex, nsIDocument** aSubDoc)
nsIContent **aContent)
{ {
NS_ENSURE_ARG_POINTER(aDocument); *aSubDoc = (nsIDocument*) mSubDocuments.SafeElementAt(aIndex);
NS_IF_ADDREF(*aSubDoc);
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; return NS_OK;
} }
@ -1871,18 +1740,23 @@ nsDocument::EndLoad()
if (docShellAsItem) { if (docShellAsItem) {
docShellAsItem->GetSameTypeParent(getter_AddRefs(docShellParent)); docShellAsItem->GetSameTypeParent(getter_AddRefs(docShellParent));
nsCOMPtr<nsIDocument> parent_doc; nsCOMPtr<nsIDocument> doc;
GetDocumentFromDocShellTreeItem(docShellParent, GetDocumentFromDocShellTreeItem(docShellParent, getter_AddRefs(doc));
getter_AddRefs(parent_doc));
if (parent_doc) { if (doc) {
nsCOMPtr<nsIContent> target_content; nsCOMPtr<nsIPresShell> shell;
doc->GetShellAt(0, getter_AddRefs(shell));
parent_doc->FindContentForSubDocument(this, if (shell) {
getter_AddRefs(target_content)); nsCOMPtr<nsIContent> target_content;
target_frame = do_QueryInterface(target_content); nsCOMPtr<nsISupports> docshell_identity(docShell);
shell->FindContentForShell(docshell_identity,
getter_AddRefs(target_content));
target_frame = do_QueryInterface(target_content);
}
} }
} }
} }
@ -2271,8 +2145,8 @@ nsDocument::GetDocumentElement(nsIDOMElement** aDocumentElement)
nsresult res = NS_OK; nsresult res = NS_OK;
if (mRootContent) { if (nsnull != mRootContent) {
res = CallQueryInterface(mRootContent, aDocumentElement); res = mRootContent->QueryInterface(NS_GET_IID(nsIDOMElement), (void**)aDocumentElement);
NS_ASSERTION(NS_OK == res, "Must be a DOM Element"); NS_ASSERTION(NS_OK == res, "Must be a DOM Element");
} else { } else {
*aDocumentElement = nsnull; *aDocumentElement = nsnull;
@ -3597,25 +3471,6 @@ nsDocument::RemoveReference(void *aKey, nsISupports **aOldReference)
return NS_OK; 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<nsISupports> container = do_QueryReferent(mDocumentContainer);
*aContainer = container;
NS_IF_ADDREF(*aContainer);
return NS_OK;
}
#ifdef IBMBIDI #ifdef IBMBIDI
/** /**
* Check if bidi enabled (set depending on the presence of RTL * Check if bidi enabled (set depending on the presence of RTL

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

@ -69,8 +69,6 @@
#include "nsScriptLoader.h" #include "nsScriptLoader.h"
#include "nsICSSLoader.h" #include "nsICSSLoader.h"
#include "pldhash.h"
class nsIEventListenerManager; class nsIEventListenerManager;
class nsDOMStyleSheetList; class nsDOMStyleSheetList;
class nsIOutputStream; class nsIOutputStream;
@ -214,29 +212,6 @@ protected:
void* mScriptObject; 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. // Base class for our document implementations.
// //
// Note that this class *implements* nsIDOMXMLDocument, but it's not // Note that this class *implements* nsIDOMXMLDocument, but it's not
@ -392,11 +367,9 @@ public:
*/ */
NS_IMETHOD GetParentDocument(nsIDocument** aParent); NS_IMETHOD GetParentDocument(nsIDocument** aParent);
NS_IMETHOD SetParentDocument(nsIDocument* aParent); 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);
/** /**
* Return the root content object for this document. * Return the root content object for this document.
@ -519,8 +492,6 @@ public:
NS_IMETHOD GetNodeInfoManager(nsINodeInfoManager*& aNodeInfoManager); NS_IMETHOD GetNodeInfoManager(nsINodeInfoManager*& aNodeInfoManager);
NS_IMETHOD AddReference(void *aKey, nsISupports *aReference); NS_IMETHOD AddReference(void *aKey, nsISupports *aReference);
NS_IMETHOD RemoveReference(void *aKey, nsISupports **aOldReference); NS_IMETHOD RemoveReference(void *aKey, nsISupports **aOldReference);
NS_IMETHOD SetContainer(nsISupports *aContainer);
NS_IMETHOD GetContainer(nsISupports **aContainer);
// nsIDOMNode // nsIDOMNode
NS_DECL_NSIDOMNODE NS_DECL_NSIDOMNODE
@ -602,16 +573,13 @@ protected:
nsCOMPtr<nsIURI> mDocumentBaseURL; nsCOMPtr<nsIURI> mDocumentBaseURL;
nsIPrincipal* mPrincipal; nsIPrincipal* mPrincipal;
nsWeakPtr mDocumentLoadGroup; nsWeakPtr mDocumentLoadGroup;
nsWeakPtr mDocumentContainer;
nsString mCharacterSet; nsString mCharacterSet;
PRInt32 mCharacterSetSource; PRInt32 mCharacterSetSource;
nsVoidArray mCharSetObservers; nsVoidArray mCharSetObservers;
nsIDocument* mParentDocument; nsIDocument* mParentDocument;
nsVoidArray mSubDocuments;
PLDHashTable *mSubDocuments;
nsVoidArray mPresShells; nsVoidArray mPresShells;
nsCOMPtr<nsISupportsArray> mChildren; // contains owning references nsCOMPtr<nsISupportsArray> mChildren; // contains owning references
nsIContent* mRootContent; // a weak reference to the only element in nsIContent* mRootContent; // a weak reference to the only element in

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -40,14 +40,13 @@
#include "nsIFrameLoader.h" #include "nsIFrameLoader.h"
#include "nsIDOMHTMLIFrameElement.h" #include "nsIDOMHTMLIFrameElement.h"
#include "nsIDOMHTMLFrameElement.h" #include "nsIDOMHTMLFrameElement.h"
#include "nsIDOMEventListener.h"
#include "nsIDOMEventTarget.h"
#include "nsIDOMWindow.h" #include "nsIDOMWindow.h"
#include "nsIPresContext.h" #include "nsIPresContext.h"
#include "nsIPresShell.h" #include "nsIPresShell.h"
#include "nsIContent.h"
#include "nsIDocument.h" #include "nsIDocument.h"
#include "nsIDOMDocument.h" #include "nsIDOMDocument.h"
#include "nsIDOMWindow.h"
#include "nsPIDOMWindow.h"
#include "nsIWebNavigation.h" #include "nsIWebNavigation.h"
#include "nsIChromeEventHandler.h" #include "nsIChromeEventHandler.h"
#include "nsIDocShell.h" #include "nsIDocShell.h"
@ -57,6 +56,9 @@
#include "nsIDocShellLoadInfo.h" #include "nsIDocShellLoadInfo.h"
#include "nsIBaseWindow.h" #include "nsIBaseWindow.h"
#include "nsIWebShell.h" #include "nsIWebShell.h"
#include "nsIWebProgressListener.h"
#include "nsIWebProgress.h"
#include "nsWeakReference.h"
#include "nsIScriptSecurityManager.h" #include "nsIScriptSecurityManager.h"
#include "nsICodebasePrincipal.h" #include "nsICodebasePrincipal.h"
@ -64,17 +66,10 @@
#include "nsIURI.h" #include "nsIURI.h"
#include "nsNetUtil.h" #include "nsNetUtil.h"
#include "nsHTMLAtoms.h" class nsFrameLoader : public nsIFrameLoader,
#include "nsINameSpaceManager.h" public nsIDOMEventListener,
public nsIWebProgressListener,
public nsSupportsWeakReference
// 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 25
class nsFrameLoader : public nsIFrameLoader
{ {
public: public:
nsFrameLoader(); nsFrameLoader();
@ -84,19 +79,26 @@ public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
// nsIFrameLoader // nsIFrameLoader
NS_IMETHOD Init(nsIContent *aOwner); NS_IMETHOD Init(nsIDOMElement *aOwner);
NS_IMETHOD LoadFrame(); NS_IMETHOD LoadURI(nsIURI *aURI);
NS_IMETHOD GetDocShell(nsIDocShell **aDocShell); NS_IMETHOD GetDocShell(nsIDocShell **aDocShell);
NS_IMETHOD Destroy(); NS_IMETHOD Destroy();
// nsIDOMEventListener
NS_DECL_NSIDOMEVENTLISTENER
// nsIWebProgressListener
NS_DECL_NSIWEBPROGRESSLISTENER
protected: protected:
nsresult GetPresContext(nsIPresContext **aPresContext); nsresult GetPresContext(nsIPresContext **aPresContext);
nsresult EnsureDocShell(); nsresult EnsureDocShell();
void GetURL(nsAString& aURL);
nsCOMPtr<nsIDocShell> mDocShell; nsCOMPtr<nsIDocShell> mDocShell;
nsIContent *mOwnerContent; // WEAK nsCOMPtr<nsIDOMElement> mOwnerElement;
nsCOMPtr<nsIURI> mURI;
}; };
nsresult nsresult
@ -110,22 +112,26 @@ NS_NewFrameLoader(nsIFrameLoader **aFrameLoader)
return NS_OK; return NS_OK;
} }
nsFrameLoader::nsFrameLoader() nsFrameLoader::nsFrameLoader()
: mOwnerContent(nsnull)
{ {
NS_INIT_ISUPPORTS(); NS_INIT_ISUPPORTS();
} }
nsFrameLoader::~nsFrameLoader() nsFrameLoader::~nsFrameLoader()
{ {
Destroy(); nsCOMPtr<nsIBaseWindow> treeOwnerAsWin(do_QueryInterface(mDocShell));
if (treeOwnerAsWin) {
treeOwnerAsWin->Destroy();
}
} }
// QueryInterface implementation for nsFrameLoader // QueryInterface implementation for nsFrameLoader
NS_INTERFACE_MAP_BEGIN(nsFrameLoader) NS_INTERFACE_MAP_BEGIN(nsFrameLoader)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY(nsIFrameLoader) NS_INTERFACE_MAP_ENTRY(nsIFrameLoader)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END NS_INTERFACE_MAP_END
@ -133,49 +139,27 @@ NS_IMPL_ADDREF(nsFrameLoader);
NS_IMPL_RELEASE(nsFrameLoader); NS_IMPL_RELEASE(nsFrameLoader);
NS_IMETHODIMP NS_IMETHODIMP
nsFrameLoader::Init(nsIContent *aOwner) nsFrameLoader::Init(nsIDOMElement *aOwner)
{ {
mOwnerContent = aOwner; // WEAK mOwnerElement = aOwner;
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
nsFrameLoader::LoadFrame() nsFrameLoader::LoadURI(nsIURI *aURI)
{ {
NS_ENSURE_TRUE(mOwnerContent, NS_ERROR_NOT_INITIALIZED); mURI = aURI;
nsresult rv = EnsureDocShell(); nsresult rv = EnsureDocShell();
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDocument> doc;
mOwnerContent->GetDocument(*getter_AddRefs(doc));
NS_ENSURE_TRUE(doc, NS_ERROR_UNEXPECTED);
nsAutoString src; // Prevent recursion
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)
return NS_OK; // mCreatingViewer=PR_TRUE;
}
// Make an absolute URI
nsCOMPtr<nsIURI> base_uri;
doc->GetBaseURL(*getter_AddRefs(base_uri));
nsAutoString doc_charset;
doc->GetDocumentCharacterSet(doc_charset);
nsCOMPtr<nsIURI> 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 // Check for security
nsCOMPtr<nsIScriptSecurityManager> secMan = nsCOMPtr<nsIScriptSecurityManager> secMan =
@ -213,21 +197,31 @@ nsFrameLoader::LoadFrame()
loadInfo->SetInheritOwner(PR_TRUE); loadInfo->SetInheritOwner(PR_TRUE);
referrer = base_uri; nsCOMPtr<nsIDOMDocument> dom_doc;
mOwnerElement->GetOwnerDocument(getter_AddRefs(dom_doc));
nsCOMPtr<nsIDocument> doc(do_QueryInterface(dom_doc));
if (doc) {
doc->GetBaseURL(*getter_AddRefs(referrer));
}
} }
loadInfo->SetReferrer(referrer); loadInfo->SetReferrer(referrer);
// Check if we are allowed to load absURL // Check if we are allowed to load absURL
rv = secMan->CheckLoadURI(referrer, uri, rv = secMan->CheckLoadURI(referrer, mURI,
nsIScriptSecurityManager::STANDARD); nsIScriptSecurityManager::STANDARD);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; // We're not return rv; // We're not
} }
// Kick off the load... nsCOMPtr<nsIWebProgress> webProgress(do_GetInterface(mDocShell));
rv = mDocShell->LoadURI(uri, loadInfo, nsIWebNavigation::LOAD_FLAGS_NONE,
PR_FALSE); if (webProgress) {
webProgress->AddProgressListener(this);
}
rv = mDocShell->LoadURI(mURI, loadInfo, nsIWebNavigation::LOAD_FLAGS_NONE);
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to load URL"); NS_ASSERTION(NS_SUCCEEDED(rv), "failed to load URL");
return rv; return rv;
@ -247,25 +241,12 @@ nsFrameLoader::GetDocShell(nsIDocShell **aDocShell)
NS_IMETHODIMP NS_IMETHODIMP
nsFrameLoader::Destroy() nsFrameLoader::Destroy()
{ {
if (mOwnerContent) { return NS_OK;
nsCOMPtr<nsIDocument> doc; }
mOwnerContent->GetDocument(*getter_AddRefs(doc)); NS_IMETHODIMP
nsFrameLoader::HandleEvent(nsIDOMEvent *aEvent)
if (doc) { {
doc->SetSubDocumentFor(mOwnerContent, nsnull);
}
mOwnerContent = nsnull;
}
nsCOMPtr<nsIBaseWindow> base_win(do_QueryInterface(mDocShell));
if (base_win) {
base_win->Destroy();
}
mDocShell = nsnull;
return NS_OK; return NS_OK;
} }
@ -275,8 +256,10 @@ nsFrameLoader::GetPresContext(nsIPresContext **aPresContext)
{ {
*aPresContext = nsnull; *aPresContext = nsnull;
nsCOMPtr<nsIDocument> doc; nsCOMPtr<nsIDOMDocument> dom_doc;
mOwnerContent->GetDocument(*getter_AddRefs(doc)); mOwnerElement->GetOwnerDocument(getter_AddRefs(dom_doc));
nsCOMPtr<nsIDocument> doc(do_QueryInterface(dom_doc));
while (doc) { while (doc) {
nsCOMPtr<nsIPresShell> presShell; nsCOMPtr<nsIPresShell> presShell;
@ -304,15 +287,16 @@ nsFrameLoader::EnsureDocShell()
return NS_OK; return NS_OK;
} }
nsCOMPtr<nsIPresContext> presContext; #if 0
GetPresContext(getter_AddRefs(presContext));
NS_ENSURE_TRUE(presContext, NS_ERROR_UNEXPECTED);
// Bug 8065: Don't exceed some maximum depth in content frames // Bug 8065: Don't exceed some maximum depth in content frames
// (MAX_DEPTH_CONTENT_FRAMES) // (MAX_DEPTH_CONTENT_FRAMES)
PRInt32 depth = 0; PRInt32 depth = 0;
nsCOMPtr<nsISupports> parentAsSupports; nsCOMPtr<nsISupports> parentAsSupports;
presContext->GetContainer(getter_AddRefs(parentAsSupports)); aPresContext->GetContainer(getter_AddRefs(parentAsSupports));
if (parentAsSupports) { if (parentAsSupports) {
nsCOMPtr<nsIDocShellTreeItem> parentAsItem = nsCOMPtr<nsIDocShellTreeItem> parentAsItem =
@ -337,16 +321,32 @@ nsFrameLoader::EnsureDocShell()
} }
} }
} }
#endif
// Create the docshell...
mDocShell = do_CreateInstance("@mozilla.org/webshell;1"); mDocShell = do_CreateInstance("@mozilla.org/webshell;1");
NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE); NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
// Get the frame name and tell the docshell about it. #if 0
// notify the pres shell that a docshell has been created
nsCOMPtr<nsIPresShell> presShell;
aPresContext->GetShell(getter_AddRefs(presShell));
if (presShell) {
nsCOMPtr<nsISupports> 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
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mDocShell)); nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mDocShell));
NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE); NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE);
nsAutoString frameName; nsAutoString frameName;
mOwnerContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::name, frameName); mOwnerElement->GetAttribute(NS_LITERAL_STRING("name"), frameName);
if (!frameName.IsEmpty()) { if (!frameName.IsEmpty()) {
docShellAsItem->SetName(frameName.get()); docShellAsItem->SetName(frameName.get());
@ -356,148 +356,178 @@ nsFrameLoader::EnsureDocShell()
// child. If it's not a web-shell then some things will not operate // child. If it's not a web-shell then some things will not operate
// properly. // properly.
nsCOMPtr<nsIPresContext> presContext;
GetPresContext(getter_AddRefs(presContext));
// what if !presContext ?
nsCOMPtr<nsISupports> container; nsCOMPtr<nsISupports> container;
presContext->GetContainer(getter_AddRefs(container)); presContext->GetContainer(getter_AddRefs(container));
nsCOMPtr<nsIDocShellTreeNode> parentAsNode(do_QueryInterface(container)); if (container) {
if (parentAsNode) { nsCOMPtr<nsIDocShellTreeNode> parentAsNode(do_QueryInterface(container));
nsCOMPtr<nsIDocShellTreeItem> parentAsItem = if (parentAsNode) {
do_QueryInterface(parentAsNode); nsCOMPtr<nsIDocShellTreeItem> parentAsItem =
do_QueryInterface(parentAsNode);
PRInt32 parentType; PRInt32 parentType;
parentAsItem->GetItemType(&parentType); parentAsItem->GetItemType(&parentType);
nsAutoString value; nsAutoString value, valuePiece;
PRBool isContent; PRBool isContent;
isContent = PR_FALSE; isContent = PR_FALSE;
mOwnerElement->GetAttribute(NS_LITERAL_STRING("type"), value);
if (mOwnerContent->IsContentOfType(nsIContent::eXUL)) { if (!value.IsEmpty()) {
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.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
if (value.Length() >= 7) {
ToLowerCase(value);
nsAutoString::const_iterator start, end;
value.BeginReading(start);
value.EndReading(end);
nsAutoString::const_iterator iter(start); // string iterators!
iter.advance(7);
const nsAString& valuePiece = Substring(start, iter);
if (valuePiece.Equals(NS_LITERAL_STRING("content")) && value.Left(valuePiece, 7);
(iter == end || *iter == '-')) { if (valuePiece.EqualsIgnoreCase("content") &&
(value.Length() == 7 ||
value.Mid(valuePiece, 7, 1) == 1 &&
valuePiece.EqualsWithConversion("-"))) {
isContent = PR_TRUE; isContent = PR_TRUE;
} }
} }
}
if (isContent) { if (isContent) {
// The web shell's type is content. // The web shell's type is content.
docShellAsItem->SetItemType(nsIDocShellTreeItem::typeContent);
docShellAsItem->SetItemType(nsIDocShellTreeItem::typeContent); } else {
} else { // Inherit our type from our parent webshell. If it is
// Inherit our type from our parent webshell. If it is // chrome, we'll be chrome. If it is content, we'll be
// chrome, we'll be chrome. If it is content, we'll be // content.
// content. docShellAsItem->SetItemType(parentType);
docShellAsItem->SetItemType(parentType);
}
parentAsNode->AddChild(docShellAsItem);
if (isContent) {
nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner;
parentAsItem->GetTreeOwner(getter_AddRefs(parentTreeOwner));
if(parentTreeOwner) {
// value is lowercased above.
PRBool is_primary = value.Equals(NS_LITERAL_STRING("content-primary"));
parentTreeOwner->ContentShellAdded(docShellAsItem, is_primary,
value.get());
} }
parentAsNode->AddChild(docShellAsItem);
if (isContent) {
nsCOMPtr<nsIDocShellTreeOwner> 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<nsIWebShell> webShell(do_QueryInterface(mDocShell));
nsCOMPtr<nsIWebShellContainer> 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<nsIChromeEventHandler> 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<nsIDocShell> 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);
} }
// connect the container...
nsCOMPtr<nsIWebShell> webShell(do_QueryInterface(mDocShell));
nsCOMPtr<nsIWebShellContainer> 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<nsIChromeEventHandler> 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<nsIDocShell> 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<nsIDOMElement> frame_element(do_QueryInterface(mOwnerContent));
NS_ASSERTION(frame_element, "frame loader owner element not a DOM element!");
nsCOMPtr<nsIDOMWindow> win(do_GetInterface(mDocShell));
nsCOMPtr<nsPIDOMWindow> win_private(do_QueryInterface(win));
NS_ENSURE_TRUE(win_private, NS_ERROR_UNEXPECTED);
win_private->SetFrameElementInternal(frame_element);
nsCOMPtr<nsIBaseWindow> 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; return NS_OK;
} }
void NS_IMETHODIMP
nsFrameLoader::GetURL(nsAString& aURI) nsFrameLoader::OnStateChange(nsIWebProgress *aWebProgress,
nsIRequest *aRequest,
PRInt32 aStateFlags, PRUint32 aStatus)
{ {
aURI.Truncate(); if (!((~aStateFlags) & (nsIWebProgressListener::STATE_IS_DOCUMENT |
nsIWebProgressListener::STATE_TRANSFERRING))) {
nsCOMPtr<nsIDOMWindow> win(do_GetInterface(mDocShell));
nsCOMPtr<nsIDOMEventTarget> eventTarget(do_QueryInterface(win));
nsCOMPtr<nsIAtom> type; if (eventTarget) {
mOwnerContent->GetTag(*getter_AddRefs(type)); eventTarget->AddEventListener(NS_LITERAL_STRING("load"), this,
PR_FALSE);
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;
} }

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

@ -1620,8 +1620,8 @@ nsGenericElement::HandleDOMEvent(nsIPresContext* aPresContext,
PRBool intermediateCapture = PR_FALSE; PRBool intermediateCapture = PR_FALSE;
//Capturing stage evaluation //Capturing stage evaluation
if (NS_EVENT_FLAG_BUBBLE != aFlags && aEvent->message != NS_PAGE_LOAD && if (NS_EVENT_FLAG_BUBBLE != aFlags && aEvent->message != NS_PAGE_LOAD
aEvent->message != NS_SCRIPT_LOAD && && aEvent->message != NS_SCRIPT_LOAD &&
aEvent->message != NS_IMAGE_ERROR && aEvent->message != NS_IMAGE_LOAD) { aEvent->message != NS_IMAGE_ERROR && aEvent->message != NS_IMAGE_LOAD) {
//Initiate capturing phase. Special case first call to document //Initiate capturing phase. Special case first call to document
if (parent) { if (parent) {

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

@ -91,16 +91,15 @@ private:
// objects for each of these instance variables, we put them off // objects for each of these instance variables, we put them off
// in a side structure that's only allocated when the content is // in a side structure that's only allocated when the content is
// accessed through the DOM. // accessed through the DOM.
struct nsDOMSlots typedef struct {
{
nsChildContentList *mChildNodes; nsChildContentList *mChildNodes;
nsDOMCSSDeclaration *mStyle; nsDOMCSSDeclaration *mStyle;
nsDOMAttributeMap* mAttributeMap; nsDOMAttributeMap* mAttributeMap;
nsVoidArray *mRangeList; nsVoidArray *mRangeList;
nsIEventListenerManager* mListenerManager; nsIEventListenerManager* mListenerManager;
nsIContent* mBindingParent; // The nearest enclosing content node with a nsIContent* mBindingParent; // The nearest enclosing content node with a binding
// binding that created us. [Weak] // that created us. [Weak]
}; } nsDOMSlots;
class nsNode3Tearoff : public nsIDOM3Node class nsNode3Tearoff : public nsIDOM3Node

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

@ -416,8 +416,6 @@ nsContentDLF::CreateDocument(const char* aCommand,
break; break;
docv->SetUAStyleSheet(gUAStyleSheet); docv->SetUAStyleSheet(gUAStyleSheet);
doc->SetContainer(aContainer);
// Initialize the document to begin loading the data. An // Initialize the document to begin loading the data. An
// nsIStreamListener connected to the parser is returned in // nsIStreamListener connected to the parser is returned in
// aDocListener. // aDocListener.
@ -514,9 +512,6 @@ nsContentDLF::CreateRDFDocument(const char* aCommand,
* An nsIStreamListener connected to the parser is returned in * An nsIStreamListener connected to the parser is returned in
* aDocListener. * aDocListener.
*/ */
doc->SetContainer(aContainer);
rv = doc->StartDocumentLoad(aCommand, aChannel, aLoadGroup, aContainer, aDocListener, PR_TRUE); rv = doc->StartDocumentLoad(aCommand, aChannel, aLoadGroup, aContainer, aDocListener, PR_TRUE);
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
/* /*

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

@ -97,7 +97,6 @@
#include "nsISelection.h" #include "nsISelection.h"
#include "nsITextContent.h" #include "nsITextContent.h"
#include "nsIXBLService.h" #include "nsIXBLService.h"
#include "nsIFrameLoader.h"
#include "nsLayoutAtoms.h" #include "nsLayoutAtoms.h"
#include "nsPlainTextSerializer.h" #include "nsPlainTextSerializer.h"
#include "nsRange.h" #include "nsRange.h"
@ -276,7 +275,6 @@ extern nsresult NS_NewXBLService(nsIXBLService** aResult);
extern nsresult NS_NewBindingManager(nsIBindingManager** aResult); extern nsresult NS_NewBindingManager(nsIBindingManager** aResult);
extern nsresult NS_NewNodeInfoManager(nsINodeInfoManager** aResult); extern nsresult NS_NewNodeInfoManager(nsINodeInfoManager** aResult);
extern nsresult NS_NewContentPolicy(nsIContentPolicy** aResult); extern nsresult NS_NewContentPolicy(nsIContentPolicy** aResult);
extern nsresult NS_NewFrameLoader(nsIFrameLoader** aResult);
#ifdef MOZ_XUL #ifdef MOZ_XUL
extern nsresult NS_NewXULElementFactory(nsIElementFactory** aResult); extern nsresult NS_NewXULElementFactory(nsIElementFactory** aResult);
@ -348,7 +346,6 @@ MAKE_CTOR(CreatePlainTextSerializer, nsIContentSerializer, NS_NewPla
MAKE_CTOR(CreateXBLService, nsIXBLService, NS_NewXBLService) MAKE_CTOR(CreateXBLService, nsIXBLService, NS_NewXBLService)
MAKE_CTOR(CreateBindingManager, nsIBindingManager, NS_NewBindingManager) MAKE_CTOR(CreateBindingManager, nsIBindingManager, NS_NewBindingManager)
MAKE_CTOR(CreateContentPolicy, nsIContentPolicy, NS_NewContentPolicy) MAKE_CTOR(CreateContentPolicy, nsIContentPolicy, NS_NewContentPolicy)
MAKE_CTOR(CreateFrameLoader, nsIFrameLoader, NS_NewFrameLoader)
MAKE_CTOR(CreateNodeInfoManager, nsINodeInfoManager, NS_NewNodeInfoManager) MAKE_CTOR(CreateNodeInfoManager, nsINodeInfoManager, NS_NewNodeInfoManager)
MAKE_CTOR(CreateComputedDOMStyle, nsIComputedDOMStyle, NS_NewComputedDOMStyle) MAKE_CTOR(CreateComputedDOMStyle, nsIComputedDOMStyle, NS_NewComputedDOMStyle)
#ifdef MOZ_XUL #ifdef MOZ_XUL
@ -738,11 +735,6 @@ static const nsModuleComponentInfo gComponents[] = {
NS_CONTENTPOLICY_CONTRACTID, NS_CONTENTPOLICY_CONTRACTID,
CreateContentPolicy }, CreateContentPolicy },
{ "Frame Loader",
NS_FRAMELOADER_CID,
NS_FRAMELOADER_CONTRACTID,
CreateFrameLoader },
{ "NodeInfoManager", { "NodeInfoManager",
NS_NODEINFOMANAGER_CID, NS_NODEINFOMANAGER_CID,
NS_NODEINFOMANAGER_CONTRACTID, NS_NODEINFOMANAGER_CONTRACTID,

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

@ -1513,7 +1513,7 @@ nsEventStateManager::DoWheelScroll(nsIPresContext* aPresContext,
rv = GetParentScrollingView(msEvent, aPresContext, newFrame, rv = GetParentScrollingView(msEvent, aPresContext, newFrame,
*getter_AddRefs(newPresContext)); *getter_AddRefs(newPresContext));
if (NS_SUCCEEDED(rv) && newFrame) if (NS_SUCCEEDED(rv))
return DoWheelScroll(newPresContext, newFrame, msEvent, numLines, return DoWheelScroll(newPresContext, newFrame, msEvent, numLines,
scrollPage, PR_TRUE); scrollPage, PR_TRUE);
else else
@ -1529,40 +1529,41 @@ nsEventStateManager::GetParentScrollingView(nsMouseScrollEvent *aEvent,
nsIFrame* &targetOuterFrame, nsIFrame* &targetOuterFrame,
nsIPresContext* &presCtxOuter) nsIPresContext* &presCtxOuter)
{ {
targetOuterFrame = nsnull;
if (!aEvent) return NS_ERROR_FAILURE; if (!aEvent) return NS_ERROR_FAILURE;
if (!aPresContext) return NS_ERROR_FAILURE; if (!aPresContext) return NS_ERROR_FAILURE;
nsCOMPtr<nsIDocument> doc; nsCOMPtr<nsISupports> shell;
aPresContext->GetContainer(getter_AddRefs(shell));
if (!shell) return NS_ERROR_FAILURE;
{ nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryInterface(shell);
nsCOMPtr<nsIPresShell> presShell; if (!treeItem) return NS_ERROR_FAILURE;
aPresContext->GetShell(getter_AddRefs(presShell));
NS_ASSERTION(presShell, "No presshell in prescontext!");
presShell->GetDocument(getter_AddRefs(doc)); /* get our docshell's parent */
} nsCOMPtr<nsIDocShellTreeItem> parent;
treeItem->GetParent(getter_AddRefs(parent));
if (!parent) return NS_ERROR_FAILURE;
NS_ASSERTION(doc, "No document in prescontext!"); nsCOMPtr<nsIDocShell> pDocShell = do_QueryInterface(parent);
if (!pDocShell) return NS_ERROR_FAILURE;
nsCOMPtr<nsIDocument> parentDoc;
doc->GetParentDocument(getter_AddRefs(parentDoc));
if (!parentDoc) {
return NS_OK;
}
nsCOMPtr<nsIPresShell> pPresShell; nsCOMPtr<nsIPresShell> pPresShell;
parentDoc->GetShellAt(0, getter_AddRefs(pPresShell)); pDocShell->GetPresShell(getter_AddRefs(pPresShell));
NS_ENSURE_TRUE(pPresShell, NS_ERROR_FAILURE); if (!pPresShell) return NS_ERROR_FAILURE;
/* now find the content node in our parent docshell's document that nsCOMPtr<nsIDocument> parentDoc;
corresponds to our docshell */ pPresShell->GetDocument(getter_AddRefs(parentDoc));
nsCOMPtr<nsIContent> rootContent;
parentDoc->GetRootContent(getter_AddRefs(rootContent));
nsCOMPtr<nsIDocShell> ourDS = do_QueryInterface(shell);
/* now find the content node in our parent docshell's document that corresponds
to our docshell */
nsCOMPtr<nsIContent> frameContent; nsCOMPtr<nsIContent> frameContent;
pPresShell->FindContentForShell(ourDS, getter_AddRefs(frameContent));
parentDoc->FindContentForSubDocument(doc, getter_AddRefs(frameContent)); if (!frameContent) return NS_ERROR_FAILURE;
NS_ENSURE_TRUE(frameContent, NS_ERROR_FAILURE);
/* /*
get this content node's frame, and use it as the new event target, get this content node's frame, and use it as the new event target,
@ -1570,7 +1571,6 @@ nsEventStateManager::GetParentScrollingView(nsMouseScrollEvent *aEvent,
Note that we don't actually need to translate the event coordinates Note that we don't actually need to translate the event coordinates
because they are not used by DoWheelScroll(). because they are not used by DoWheelScroll().
*/ */
nsIFrame* frameFrame = nsnull; nsIFrame* frameFrame = nsnull;
pPresShell->GetPrimaryFrameFor(frameContent, &frameFrame); pPresShell->GetPrimaryFrameFor(frameContent, &frameFrame);
if (!frameFrame) return NS_ERROR_FAILURE; if (!frameFrame) return NS_ERROR_FAILURE;
@ -2838,32 +2838,19 @@ nsEventStateManager::ShiftFocusInternal(PRBool aForward, nsIContent* aStart)
// Check to see if the next focused element has a subshell. // Check to see if the next focused element has a subshell.
// This is the case for an IFRAME or FRAME element. If it // This is the case for an IFRAME or FRAME element. If it
// does, we send focus into the subshell. // does, we send focus into the subshell.
nsCOMPtr<nsISupports> shellObject;
presShell->GetSubShellFor(nextFocus, getter_AddRefs(shellObject));
if (shellObject) {
nsCOMPtr<nsIDocShell> subShell = do_QueryInterface(shellObject);
if (subShell) {
SetContentState(nsnull, NS_EVENT_STATE_FOCUS);
nsCOMPtr<nsIDocShell> sub_shell; nsIFrame* nextFocusFrame = nsnull;
presShell->GetPrimaryFrameFor(nextFocus, &nextFocusFrame);
nsCOMPtr<nsIDocument> doc, sub_doc; presShell->ScrollFrameIntoView(nextFocusFrame, NS_PRESSHELL_SCROLL_ANYWHERE,
nextFocus->GetDocument(*getter_AddRefs(doc)); NS_PRESSHELL_SCROLL_ANYWHERE);
TabIntoDocument(subShell, aForward);
if (doc) {
doc->GetSubDocumentFor(nextFocus, getter_AddRefs(sub_doc));
if (sub_doc) {
nsCOMPtr<nsISupports> 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 { } else {
// there is no subshell, so just focus nextFocus // there is no subshell, so just focus nextFocus
#ifdef DEBUG_DOCSHELL_FOCUS #ifdef DEBUG_DOCSHELL_FOCUS
@ -2941,13 +2928,8 @@ nsEventStateManager::ShiftFocusInternal(PRBool aForward, nsIContent* aStart)
nsCOMPtr<nsIPresShell> parentShell; nsCOMPtr<nsIPresShell> parentShell;
parentDS->GetPresShell(getter_AddRefs(parentShell)); parentDS->GetPresShell(getter_AddRefs(parentShell));
nsCOMPtr<nsIContent> docContent; nsCOMPtr<nsIContent> shellContent;
nsCOMPtr<nsIDocument> parent_doc; parentShell->FindContentForShell(docShell, getter_AddRefs(shellContent));
parentShell->GetDocument(getter_AddRefs(parent_doc));
parent_doc->FindContentForSubDocument(mDocument,
getter_AddRefs(docContent));
nsCOMPtr<nsIPresContext> parentPC; nsCOMPtr<nsIPresContext> parentPC;
parentShell->GetPresContext(getter_AddRefs(parentPC)); parentShell->GetPresContext(getter_AddRefs(parentPC));
@ -2961,7 +2943,7 @@ nsEventStateManager::ShiftFocusInternal(PRBool aForward, nsIContent* aStart)
printf("popping out focus to parent docshell\n"); printf("popping out focus to parent docshell\n");
#endif #endif
parentESM->MoveCaretToFocus(); parentESM->MoveCaretToFocus();
parentESM->ShiftFocus(aForward, docContent); parentESM->ShiftFocus(aForward, shellContent);
} }
} else { } else {
PRBool tookFocus = PR_FALSE; PRBool tookFocus = PR_FALSE;
@ -4665,14 +4647,6 @@ PRBool
nsEventStateManager::IsIFrameDoc(nsIDocShell* aDocShell) nsEventStateManager::IsIFrameDoc(nsIDocShell* aDocShell)
{ {
NS_ASSERTION(aDocShell, "docshell is null"); NS_ASSERTION(aDocShell, "docshell is null");
nsCOMPtr<nsIPresShell> presShell;
aDocShell->GetPresShell(getter_AddRefs(presShell));
nsCOMPtr<nsIDocument> doc;
presShell->GetDocument(getter_AddRefs(doc));
NS_ASSERTION(doc, "No document in presshell!");
nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryInterface(aDocShell); nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryInterface(aDocShell);
nsCOMPtr<nsIDocShellTreeItem> parentItem; nsCOMPtr<nsIDocShellTreeItem> parentItem;
treeItem->GetParent(getter_AddRefs(parentItem)); treeItem->GetParent(getter_AddRefs(parentItem));
@ -4680,17 +4654,12 @@ nsEventStateManager::IsIFrameDoc(nsIDocShell* aDocShell)
return PR_FALSE; return PR_FALSE;
nsCOMPtr<nsIDocShell> parentDS = do_QueryInterface(parentItem); nsCOMPtr<nsIDocShell> parentDS = do_QueryInterface(parentItem);
nsCOMPtr<nsIPresShell> parentPresShell; nsCOMPtr<nsIPresShell> parentShell;
parentDS->GetPresShell(getter_AddRefs(parentPresShell)); parentDS->GetPresShell(getter_AddRefs(parentShell));
NS_ASSERTION(parentPresShell, "presshell is null"); NS_ASSERTION(parentShell, "presshell is null");
nsCOMPtr<nsIDocument> parentDoc;
parentPresShell->GetDocument(getter_AddRefs(parentDoc));
nsCOMPtr<nsIContent> docContent; nsCOMPtr<nsIContent> docContent;
parentShell->FindContentForShell(aDocShell, getter_AddRefs(docContent));
parentDoc->FindContentForSubDocument(doc, getter_AddRefs(docContent));
if (!docContent) if (!docContent)
return PR_FALSE; return PR_FALSE;

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

@ -32,10 +32,10 @@ REQUIRES = xpcom \
webshell \ webshell \
htmlparser \ htmlparser \
necko \ necko \
uriloader \
view \ view \
pref \ pref \
docshell \ docshell \
uriloader \
xpconnect \ xpconnect \
caps \ caps \
editor \ editor \

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

@ -2331,12 +2331,12 @@ nsGenericHTMLElement::GetBaseURL(const nsHTMLValue& aBaseHref,
baseHref.Trim(" \t\n\r"); baseHref.Trim(" \t\n\r");
nsIURI* url = nsnull; nsIURI* url = nsnull;
result = NS_NewURI(&url, baseHref, nsnull, docBaseURL); {
result = NS_NewURI(&url, baseHref, nsnull, docBaseURL);
}
NS_IF_RELEASE(docBaseURL); NS_IF_RELEASE(docBaseURL);
*aBaseURL = url; *aBaseURL = url;
} }
return result; return result;
} }
@ -4571,6 +4571,32 @@ nsGenericHTMLElement::SetElementFocus(PRBool aDoFocus)
return RemoveFocus(presContext); 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<nsIPresContext> 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 // static
nsresult nsresult
nsGenericHTMLElement::SetProtocolInHrefString(const nsAString &aHref, nsGenericHTMLElement::SetProtocolInHrefString(const nsAString &aHref,

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

@ -465,6 +465,8 @@ public:
protected: protected:
nsresult SetElementFocus(PRBool aDoFocus); nsresult SetElementFocus(PRBool aDoFocus);
nsresult HandleFrameOnloadEvent(nsIDOMEvent* aEvent);
PRBool IsEventName(nsIAtom* aName); PRBool IsEventName(nsIAtom* aName);
}; };

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

@ -37,6 +37,7 @@
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#include "nsIDOMHTMLFrameElement.h" #include "nsIDOMHTMLFrameElement.h"
#include "nsIDOMNSHTMLFrameElement.h" #include "nsIDOMNSHTMLFrameElement.h"
#include "nsIDOMEventListener.h"
#include "nsIDOMEventReceiver.h" #include "nsIDOMEventReceiver.h"
#include "nsIDOMWindow.h" #include "nsIDOMWindow.h"
#include "nsIScriptGlobalObject.h" #include "nsIScriptGlobalObject.h"
@ -48,14 +49,14 @@
#include "nsIDOMDocument.h" #include "nsIDOMDocument.h"
#include "nsIWebNavigation.h" #include "nsIWebNavigation.h"
#include "nsIChromeEventHandler.h" #include "nsIChromeEventHandler.h"
#include "nsIDocShell.h"
#include "nsDOMError.h" #include "nsDOMError.h"
class nsHTMLFrameElement : public nsGenericHTMLLeafElement, class nsHTMLFrameElement : public nsGenericHTMLLeafElement,
public nsIDOMHTMLFrameElement, public nsIDOMHTMLFrameElement,
public nsIDOMNSHTMLFrameElement, public nsIDOMNSHTMLFrameElement,
public nsIChromeEventHandler public nsIChromeEventHandler,
public nsIDOMEventListener
{ {
public: public:
nsHTMLFrameElement(); nsHTMLFrameElement();
@ -82,6 +83,9 @@ public:
// nsIChromeEventHandler // nsIChromeEventHandler
NS_DECL_NSICHROMEEVENTHANDLER NS_DECL_NSICHROMEEVENTHANDLER
// nsIDOMEventListener
NS_DECL_NSIDOMEVENTLISTENER
NS_IMETHOD StringToAttribute(nsIAtom* aAttribute, NS_IMETHOD StringToAttribute(nsIAtom* aAttribute,
const nsAString& aValue, const nsAString& aValue,
nsHTMLValue& aResult); nsHTMLValue& aResult);
@ -139,6 +143,7 @@ NS_HTML_CONTENT_INTERFACE_MAP_BEGIN(nsHTMLFrameElement,
NS_INTERFACE_MAP_ENTRY(nsIDOMHTMLFrameElement) NS_INTERFACE_MAP_ENTRY(nsIDOMHTMLFrameElement)
NS_INTERFACE_MAP_ENTRY(nsIDOMNSHTMLFrameElement) NS_INTERFACE_MAP_ENTRY(nsIDOMNSHTMLFrameElement)
NS_INTERFACE_MAP_ENTRY(nsIChromeEventHandler) NS_INTERFACE_MAP_ENTRY(nsIChromeEventHandler)
NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(HTMLFrameElement) NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(HTMLFrameElement)
NS_HTML_CONTENT_INTERFACE_MAP_END NS_HTML_CONTENT_INTERFACE_MAP_END
@ -186,21 +191,33 @@ NS_IMETHODIMP
nsHTMLFrameElement::GetContentDocument(nsIDOMDocument** aContentDocument) nsHTMLFrameElement::GetContentDocument(nsIDOMDocument** aContentDocument)
{ {
NS_ENSURE_ARG_POINTER(aContentDocument); NS_ENSURE_ARG_POINTER(aContentDocument);
*aContentDocument = nsnull; *aContentDocument = nsnull;
if (!mDocument) { NS_ENSURE_TRUE(mDocument, NS_OK);
return NS_OK;
}
nsCOMPtr<nsIDocument> content_document; nsCOMPtr<nsIPresShell> presShell;
mDocument->GetSubDocumentFor(this, getter_AddRefs(content_document)); mDocument->GetShellAt(0, getter_AddRefs(presShell));
NS_ENSURE_TRUE(presShell, NS_OK);
if (!content_document) { nsCOMPtr<nsISupports> tmp;
return NS_OK;
}
return CallQueryInterface(content_document, aContentDocument); presShell->GetSubShellFor(this, getter_AddRefs(tmp));
NS_ENSURE_TRUE(tmp, NS_OK);
nsCOMPtr<nsIWebNavigation> webNav = do_QueryInterface(tmp);
NS_ENSURE_TRUE(webNav, NS_OK);
nsCOMPtr<nsIDOMDocument> domDoc;
webNav->GetDocument(getter_AddRefs(domDoc));
*aContentDocument = domDoc;
NS_IF_ADDREF(*aContentDocument);
return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -312,3 +329,8 @@ nsHTMLFrameElement::HandleChromeEvent(nsIPresContext* aPresContext,
return HandleDOMEvent(aPresContext, aEvent, aDOMEvent, aFlags,aEventStatus); return HandleDOMEvent(aPresContext, aEvent, aDOMEvent, aFlags,aEventStatus);
} }
nsresult
nsHTMLFrameElement::HandleEvent(nsIDOMEvent *aEvent)
{
return HandleFrameOnloadEvent(aEvent);
}

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

@ -37,10 +37,11 @@
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#include "nsIDOMHTMLIFrameElement.h" #include "nsIDOMHTMLIFrameElement.h"
#include "nsIDOMNSHTMLFrameElement.h" #include "nsIDOMNSHTMLFrameElement.h"
#include "nsIDOMEventListener.h"
#include "nsIDOMEventReceiver.h" #include "nsIDOMEventReceiver.h"
#include "nsIDOMWindow.h" #include "nsIDOMWindow.h"
#include "nsIScriptGlobalObject.h" #include "nsIScriptGlobalObject.h"
#include "nsIFrameLoader.h" #include "nsIHTMLContent.h"
#include "nsGenericHTMLElement.h" #include "nsGenericHTMLElement.h"
#include "nsHTMLAtoms.h" #include "nsHTMLAtoms.h"
#include "nsIStyleContext.h" #include "nsIStyleContext.h"
@ -53,14 +54,12 @@
#include "nsIChromeEventHandler.h" #include "nsIChromeEventHandler.h"
#include "nsDOMError.h" #include "nsDOMError.h"
#include "nsRuleNode.h" #include "nsRuleNode.h"
#include "nsIDocShell.h"
#include "nsIInterfaceRequestorUtils.h"
class nsHTMLIFrameElement : public nsGenericHTMLContainerElement, class nsHTMLIFrameElement : public nsGenericHTMLContainerElement,
public nsIDOMHTMLIFrameElement, public nsIDOMHTMLIFrameElement,
public nsIDOMNSHTMLFrameElement, public nsIDOMNSHTMLFrameElement,
public nsIChromeEventHandler, public nsIChromeEventHandler,
public nsIFrameLoaderOwner public nsIDOMEventListener
{ {
public: public:
nsHTMLIFrameElement(); nsHTMLIFrameElement();
@ -87,11 +86,8 @@ public:
// nsIChromeEventHandler // nsIChromeEventHandler
NS_DECL_NSICHROMEEVENTHANDLER NS_DECL_NSICHROMEEVENTHANDLER
// nsIFrameLoaderOwner // nsIDOMEventListener
NS_IMETHOD GetFrameLoader(nsIFrameLoader **aFrameLoader); NS_DECL_NSIDOMEVENTLISTENER
// nsIContent
NS_IMETHOD SetParent(nsIContent *aParent);
NS_IMETHOD StringToAttribute(nsIAtom* aAttribute, NS_IMETHOD StringToAttribute(nsIAtom* aAttribute,
const nsAString& aValue, const nsAString& aValue,
@ -105,14 +101,6 @@ public:
#ifdef DEBUG #ifdef DEBUG
NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const; NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const;
#endif #endif
protected:
// This doesn't really ensure a frame loade in all cases, only when
// it makes sense.
nsresult EnsureFrameLoader();
nsresult LoadSrc();
nsCOMPtr<nsIFrameLoader> mFrameLoader;
}; };
nsresult nsresult
@ -148,9 +136,6 @@ nsHTMLIFrameElement::nsHTMLIFrameElement()
nsHTMLIFrameElement::~nsHTMLIFrameElement() nsHTMLIFrameElement::~nsHTMLIFrameElement()
{ {
if (mFrameLoader) {
mFrameLoader->Destroy();
}
} }
@ -163,7 +148,7 @@ NS_HTML_CONTENT_INTERFACE_MAP_BEGIN(nsHTMLIFrameElement,
NS_INTERFACE_MAP_ENTRY(nsIDOMHTMLIFrameElement) NS_INTERFACE_MAP_ENTRY(nsIDOMHTMLIFrameElement)
NS_INTERFACE_MAP_ENTRY(nsIDOMNSHTMLFrameElement) NS_INTERFACE_MAP_ENTRY(nsIDOMNSHTMLFrameElement)
NS_INTERFACE_MAP_ENTRY(nsIChromeEventHandler) NS_INTERFACE_MAP_ENTRY(nsIChromeEventHandler)
NS_INTERFACE_MAP_ENTRY(nsIFrameLoaderOwner) NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(HTMLIFrameElement) NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(HTMLIFrameElement)
NS_HTML_CONTENT_INTERFACE_MAP_END NS_HTML_CONTENT_INTERFACE_MAP_END
@ -204,123 +189,71 @@ NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, MarginHeight, marginheight)
NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, MarginWidth, marginwidth) NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, MarginWidth, marginwidth)
NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, Name, name) NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, Name, name)
NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, Scrolling, scrolling) NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, Scrolling, scrolling)
NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, Src, src)
NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, Width, width) 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 NS_IMETHODIMP
nsHTMLIFrameElement::GetContentDocument(nsIDOMDocument** aContentDocument) nsHTMLIFrameElement::GetContentDocument(nsIDOMDocument** aContentDocument)
{ {
NS_ENSURE_ARG_POINTER(aContentDocument); NS_ENSURE_ARG_POINTER(aContentDocument);
*aContentDocument = nsnull; *aContentDocument = nsnull;
nsresult rv = EnsureFrameLoader(); NS_ENSURE_TRUE(mDocument, NS_OK);
NS_ENSURE_SUCCESS(rv, rv);
if (!mFrameLoader) { nsCOMPtr<nsIPresShell> presShell;
return NS_OK;
}
nsCOMPtr<nsIDocShell> doc_shell; mDocument->GetShellAt(0, getter_AddRefs(presShell));
mFrameLoader->GetDocShell(getter_AddRefs(doc_shell)); NS_ENSURE_TRUE(presShell, NS_OK);
nsCOMPtr<nsIDOMWindow> win(do_GetInterface(doc_shell)); nsCOMPtr<nsISupports> tmp;
if (!win) { presShell->GetSubShellFor(this, getter_AddRefs(tmp));
return NS_OK; NS_ENSURE_TRUE(tmp, NS_OK);
}
return win->GetDocument(aContentDocument); nsCOMPtr<nsIWebNavigation> webNav = do_QueryInterface(tmp);
NS_ENSURE_TRUE(webNav, NS_OK);
nsCOMPtr<nsIDOMDocument> domDoc;
webNav->GetDocument(getter_AddRefs(domDoc));
*aContentDocument = domDoc;
NS_IF_ADDREF(*aContentDocument);
return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
nsHTMLIFrameElement::GetContentWindow(nsIDOMWindow** aContentWindow) nsHTMLIFrameElement::GetContentWindow(nsIDOMWindow** aContentWindow)
{ {
NS_ENSURE_ARG_POINTER(aContentWindow); NS_ENSURE_ARG_POINTER(aContentWindow);
*aContentWindow = nsnull;
nsresult rv = EnsureFrameLoader(); nsCOMPtr<nsIDOMDocument> content_doc;
nsresult rv = GetContentDocument(getter_AddRefs(content_doc));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (!mFrameLoader) { nsCOMPtr<nsIDocument> doc(do_QueryInterface(content_doc));
if (!doc) {
return NS_OK; return NS_OK;
} }
nsCOMPtr<nsIDocShell> doc_shell; nsCOMPtr<nsIScriptGlobalObject> globalObj;
mFrameLoader->GetDocShell(getter_AddRefs(doc_shell)); doc->GetScriptGlobalObject(getter_AddRefs(globalObj));
nsCOMPtr<nsIDOMWindow> win(do_GetInterface(doc_shell)); nsCOMPtr<nsIDOMWindow> window (do_QueryInterface(globalObj));
*aContentWindow = win; *aContentWindow = window;
NS_IF_ADDREF(*aContentWindow); NS_IF_ADDREF(*aContentWindow);
return NS_OK; 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 NS_IMETHODIMP
nsHTMLIFrameElement::StringToAttribute(nsIAtom* aAttribute, nsHTMLIFrameElement::StringToAttribute(nsIAtom* aAttribute,
const nsAString& aValue, const nsAString& aValue,
@ -444,8 +377,7 @@ MapAttributesIntoRule(const nsIHTMLMappedAttributes* aAttributes,
} }
NS_IMETHODIMP NS_IMETHODIMP
nsHTMLIFrameElement::GetMappedAttributeImpact(const nsIAtom* aAttribute, nsHTMLIFrameElement::GetMappedAttributeImpact(const nsIAtom* aAttribute, PRInt32 aModType,
PRInt32 aModType,
PRInt32& aHint) const PRInt32& aHint) const
{ {
if ((aAttribute == nsHTMLAtoms::width) || if ((aAttribute == nsHTMLAtoms::width) ||
@ -499,3 +431,8 @@ nsHTMLIFrameElement::HandleChromeEvent(nsIPresContext* aPresContext,
return HandleDOMEvent(aPresContext, aEvent, aDOMEvent, aFlags,aEventStatus); return HandleDOMEvent(aPresContext, aEvent, aDOMEvent, aFlags,aEventStatus);
} }
nsresult
nsHTMLIFrameElement::HandleEvent(nsIDOMEvent *aEvent)
{
return HandleFrameOnloadEvent(aEvent);
}

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

@ -190,18 +190,30 @@ nsHTMLObjectElement::GetContentDocument(nsIDOMDocument** aContentDocument)
*aContentDocument = nsnull; *aContentDocument = nsnull;
if (!mDocument) { NS_ENSURE_TRUE(mDocument, NS_OK);
return NS_OK;
}
nsCOMPtr<nsIDocument> sub_doc; nsCOMPtr<nsIPresShell> presShell;
mDocument->GetSubDocumentFor(this, getter_AddRefs(sub_doc));
if (!sub_doc) { mDocument->GetShellAt(0, getter_AddRefs(presShell));
return NS_OK; NS_ENSURE_TRUE(presShell, NS_OK);
}
return CallQueryInterface(sub_doc, aContentDocument); nsCOMPtr<nsISupports> tmp;
presShell->GetSubShellFor(this, getter_AddRefs(tmp));
if (!tmp) return NS_OK;
nsCOMPtr<nsIWebNavigation> webNav = do_QueryInterface(tmp);
NS_ENSURE_TRUE(webNav, NS_OK);
nsCOMPtr<nsIDOMDocument> domDoc;
webNav->GetDocument(getter_AddRefs(domDoc));
*aContentDocument = domDoc;
NS_IF_ADDREF(*aContentDocument);
return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP

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

@ -190,18 +190,30 @@ nsHTMLObjectElement::GetContentDocument(nsIDOMDocument** aContentDocument)
*aContentDocument = nsnull; *aContentDocument = nsnull;
if (!mDocument) { NS_ENSURE_TRUE(mDocument, NS_OK);
return NS_OK;
}
nsCOMPtr<nsIDocument> sub_doc; nsCOMPtr<nsIPresShell> presShell;
mDocument->GetSubDocumentFor(this, getter_AddRefs(sub_doc));
if (!sub_doc) { mDocument->GetShellAt(0, getter_AddRefs(presShell));
return NS_OK; NS_ENSURE_TRUE(presShell, NS_OK);
}
return CallQueryInterface(sub_doc, aContentDocument); nsCOMPtr<nsISupports> tmp;
presShell->GetSubShellFor(this, getter_AddRefs(tmp));
if (!tmp) return NS_OK;
nsCOMPtr<nsIWebNavigation> webNav = do_QueryInterface(tmp);
NS_ENSURE_TRUE(webNav, NS_OK);
nsCOMPtr<nsIDOMDocument> domDoc;
webNav->GetDocument(getter_AddRefs(domDoc));
*aContentDocument = domDoc;
NS_IF_ADDREF(*aContentDocument);
return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP

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

@ -1604,8 +1604,7 @@ SinkContext::CloseContainer(const nsIParserNode& aNode)
case eHTMLTag_select: case eHTMLTag_select:
{ {
nsCOMPtr<nsISelectElement> select = do_QueryInterface(content); nsCOMPtr<nsISelectElement> select = do_QueryInterface(content, &result);
if (select) { if (select) {
result = select->DoneAddingChildren(); result = select->DoneAddingChildren();
} }
@ -3825,29 +3824,20 @@ HTMLContentSink::DidProcessAToken(void)
PRInt32 oldMaxTokenProcessingTime = GetMaxTokenProcessingTime(); PRInt32 oldMaxTokenProcessingTime = GetMaxTokenProcessingTime();
#endif #endif
// There is both a high frequency interrupt mode and a low // There is both a high frequency interrupt mode and a low frequency
// frequency interupt mode controlled by the flag // interupt mode controlled by the flag NS_SINK_FLAG_DYNAMIC_LOWER_VALUE
// NS_SINK_FLAG_DYNAMIC_LOWER_VALUE The high frequency mode // The high frequency mode interupts the parser frequently to provide
// interupts the parser frequently to provide UI responsiveness at // UI responsiveness at the expense of page load time. The low frequency mode
// the expense of page load time. The low frequency mode // interrupts the parser and samples the system clock infrequently to provide fast
// interrupts the parser and samples the system clock infrequently // page load time. When the user moves the mouse, clicks or types the mode switches
// to provide fast page load time. When the user moves the mouse, // to the high frequency interrupt mode. If the user stops moving the mouse or typing
// clicks or types the mode switches to the high frequency // for a duration of time (mDynamicIntervalSwitchThreshold) it switches to low
// interrupt mode. If the user stops moving the mouse or typing // frequency interrupt mode.
// for a duration of time (mDynamicIntervalSwitchThreshold) it
// switches to low frequency interrupt mode.
// Get the current user event time // Get the current user event time
nsCOMPtr<nsIPresShell> shell; nsCOMPtr<nsIPresShell> shell;
mDocument->GetShellAt(0, getter_AddRefs(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<nsIViewManager> vm; nsCOMPtr<nsIViewManager> vm;
shell->GetViewManager(getter_AddRefs(vm)); shell->GetViewManager(getter_AddRefs(vm));
NS_ENSURE_TRUE(vm, NS_ERROR_FAILURE); NS_ENSURE_TRUE(vm, NS_ERROR_FAILURE);
@ -3855,27 +3845,22 @@ PRInt32 oldMaxTokenProcessingTime = GetMaxTokenProcessingTime();
nsresult rv = vm->GetLastUserEventTime(eventTime); nsresult rv = vm->GetLastUserEventTime(eventTime);
NS_ENSURE_TRUE(NS_SUCCEEDED(rv), NS_ERROR_FAILURE); NS_ENSURE_TRUE(NS_SUCCEEDED(rv), NS_ERROR_FAILURE);
if ((!(mFlags & NS_SINK_FLAG_DYNAMIC_LOWER_VALUE)) && if ((!(mFlags & NS_SINK_FLAG_DYNAMIC_LOWER_VALUE)) &&
(mLastSampledUserEventTime == eventTime)) { (mLastSampledUserEventTime == eventTime)) {
// The magic value of NS_MAX_TOKENS_DEFLECTED_IN_LOW_FREQ_MODE // The magic value of NS_MAX_TOKENS_DEFLECTED_IN_LOW_FREQ_MODE was selected by
// was selected by empirical testing. It provides reasonable // empirical testing. It provides reasonable
// user response and prevents us from sampling the clock too // user response and prevents us from sampling the clock too frequently.
// frequently.
if (mDeflectedCount < NS_MAX_TOKENS_DEFLECTED_IN_LOW_FREQ_MODE) { if (mDeflectedCount < NS_MAX_TOKENS_DEFLECTED_IN_LOW_FREQ_MODE) {
mDeflectedCount++; mDeflectedCount++;
return NS_OK; // return early to prevent sampling the clock. Note: This prevents
// return early to prevent sampling the clock. Note: This // us from switching to higher frequency (better UI responsive) mode, so
// prevents us from switching to higher frequency (better UI // limit ourselves to doing for no more than
// responsive) mode, so limit ourselves to doing for no more // NS_MAX_TOKENS_DEFLECTED_IN_LOW_FREQ_MODE tokens.
// than NS_MAX_TOKENS_DEFLECTED_IN_LOW_FREQ_MODE tokens.
return NS_OK;
} else { } else {
// reset count and drop through to the code which samples the mDeflectedCount = 0; // reset count and drop through to the code which samples the clock and
// clock and does the dynamic switch between the high // does the dynamic switch between the high frequency and low frequency
// frequency and low frequency interruption of the parser. // interruption of the parser.
mDeflectedCount = 0;
} }
} }
@ -3883,49 +3868,48 @@ PRInt32 oldMaxTokenProcessingTime = GetMaxTokenProcessingTime();
PRUint32 currentTime = PR_IntervalToMicroseconds(PR_IntervalNow()); PRUint32 currentTime = PR_IntervalToMicroseconds(PR_IntervalNow());
// Get the last user event time and compare it with the current // Get the last user event time and compare it with
// time to determine if the lower value for content notification // the current time to determine if the lower value
// and max token processing should be used. But only consider // for content notification and max token processing
// using the lower value if the document has already been loading // should be used. But only consider using the lower
// for 2 seconds. 2 seconds was chosen because it is greater than // value if the document has already been loading
// the default 3/4 of second that is used to determine when to // for 2 seconds. 2 seconds was chosen because it is
// switch between the modes and it gives the document a little // greater than the default 3/4 of second that is used
// time to create windows. This is important because on some // to determine when to switch between the modes and it
// systems (Windows, for example) when a window is created and the // gives the document a little time to create windows.
// mouse is over it, a mouse move event is sent, which will kick // This is important because on some systems (Windows,
// us into interactive mode otherwise. It also supresses reaction // for example) when a window is created and the mouse
// to pressing the ENTER key in the URL bar... // 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)); PRUint32 delayBeforeLoweringThreshold = NS_STATIC_CAST(PRUint32, ((2 * mDynamicIntervalSwitchThreshold) + NS_DELAY_FOR_WINDOW_CREATION));
if (((currentTime - mBeginLoadTime) > delayBeforeLoweringThreshold) && mDocument) {
if ((currentTime - mBeginLoadTime) > delayBeforeLoweringThreshold) { if ((currentTime - eventTime) < NS_STATIC_CAST(PRUint32, mDynamicIntervalSwitchThreshold)) {
if ((currentTime - eventTime) < // lower the dynamic values to favor
NS_STATIC_CAST(PRUint32, mDynamicIntervalSwitchThreshold)) { // application responsiveness over page load
// lower the dynamic values to favor application // time.
// responsiveness over page load time. mFlags |= NS_SINK_FLAG_DYNAMIC_LOWER_VALUE;
}
mFlags |= NS_SINK_FLAG_DYNAMIC_LOWER_VALUE; else {
} else { // raise the content notification and
// raise the content notification and MaxTokenProcessing time // MaxTokenProcessing time to favor overall
// to favor overall page load speed over responsiveness // page load speed over responsiveness
mFlags &= ~NS_SINK_FLAG_DYNAMIC_LOWER_VALUE;
mFlags &= ~NS_SINK_FLAG_DYNAMIC_LOWER_VALUE;
} }
} }
#ifdef NS_DEBUG #ifdef NS_DEBUG
PRInt32 newMaxTokenProcessingTime = GetMaxTokenProcessingTime(); PRInt32 newMaxTokenProcessingTime = GetMaxTokenProcessingTime();
if (newMaxTokenProcessingTime != oldMaxTokenProcessingTime) { if (newMaxTokenProcessingTime != oldMaxTokenProcessingTime) {
// printf("Changed dynamic interval : MaxTokenProcessingTime %d\n", // printf("Changed dynamic interval : MaxTokenProcessingTime %d\n", GetMaxTokenProcessingTime());
// GetMaxTokenProcessingTime()); }
}
#endif #endif
if ((currentTime - mDelayTimerStart) > if ((currentTime - mDelayTimerStart) > NS_STATIC_CAST(PRUint32, GetMaxTokenProcessingTime())) {
NS_STATIC_CAST(PRUint32, GetMaxTokenProcessingTime())) { return NS_ERROR_HTMLPARSER_INTERRUPTED;
return NS_ERROR_HTMLPARSER_INTERRUPTED; }
}
} }
return NS_OK; return NS_OK;
@ -4172,7 +4156,7 @@ nsresult
HTMLContentSink::ProcessAREATag(const nsIParserNode& aNode) HTMLContentSink::ProcessAREATag(const nsIParserNode& aNode)
{ {
nsresult rv = NS_OK; nsresult rv = NS_OK;
if (mCurrentMap) { if (nsnull != mCurrentMap) {
nsHTMLTag nodeType = nsHTMLTag(aNode.GetNodeType()); nsHTMLTag nodeType = nsHTMLTag(aNode.GetNodeType());
nsIHTMLContent* area; nsIHTMLContent* area;
rv = CreateContentObject(aNode, nodeType, nsnull, nsnull, &area); rv = CreateContentObject(aNode, nodeType, nsnull, nsnull, &area);

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

@ -1477,7 +1477,7 @@ nsHTMLDocument::FlushPendingNotifications(PRBool aFlushReflows,
} }
} }
if (isSafeToFlush && mParser) { if ((isSafeToFlush) && (mParser)) {
nsCOMPtr<nsIContentSink> sink; nsCOMPtr<nsIContentSink> sink;
// XXX Ack! Parser doesn't addref sink before passing it back // XXX Ack! Parser doesn't addref sink before passing it back
@ -3750,33 +3750,34 @@ nsHTMLDocument::ResolveName(const nsAString& aName,
PRBool PRBool
nsHTMLDocument::GetBodyContent() nsHTMLDocument::GetBodyContent()
{ {
nsCOMPtr<nsIContent> root; nsCOMPtr<nsIDOMElement> root;
GetRootContent(getter_AddRefs(root)); GetDocumentElement(getter_AddRefs(root));
if (!root) { if (!root) {
return PR_FALSE; return PR_FALSE;
} }
PRInt32 i, child_count; NS_NAMED_LITERAL_STRING(bodyStr, "BODY");
root->ChildCount(child_count); nsCOMPtr<nsIDOMNode> child;
root->GetFirstChild(getter_AddRefs(child));
for (i = 0; i < child_count; i++) { while (child) {
nsCOMPtr<nsIContent> child; nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(child));
root->ChildAt(i, *getter_AddRefs(child)); if (domElement) {
NS_ENSURE_TRUE(child, NS_ERROR_UNEXPECTED); nsAutoString tagName;
domElement->GetTagName(tagName);
nsCOMPtr<nsINodeInfo> ni; ToUpperCase(tagName);
child->GetNodeInfo(*getter_AddRefs(ni)); if (bodyStr.Equals(tagName)) {
mBodyContent = child;
if (ni && ni->Equals(nsHTMLAtoms::body) && return PR_TRUE;
(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; return PR_FALSE;

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

@ -2657,7 +2657,7 @@ CSSStyleSheetImpl::SetDisabled(PRBool aDisabled)
PRBool oldState = mDisabled; PRBool oldState = mDisabled;
mDisabled = aDisabled; mDisabled = aDisabled;
if (mDocument && (mDisabled != oldState)) { if ((nsnull != mDocument) && (mDisabled != oldState)) {
mDocument->SetStyleSheetDisabledState(this, mDisabled); mDocument->SetStyleSheetDisabledState(this, mDisabled);
} }

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

@ -2310,13 +2310,6 @@
<FILEKIND>Text</FILEKIND> <FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS> <FILEFLAGS>Debug</FILEFLAGS>
</FILE> </FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsFrameLoader.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE> <FILE>
<PATHTYPE>Name</PATHTYPE> <PATHTYPE>Name</PATHTYPE>
<PATH>UnicharUtilsStatic.o</PATH> <PATH>UnicharUtilsStatic.o</PATH>
@ -3452,11 +3445,6 @@
<PATH>nsContentAreaDragDrop.cpp</PATH> <PATH>nsContentAreaDragDrop.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT> <PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF> </FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsFrameLoader.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF> <FILEREF>
<PATHTYPE>Name</PATHTYPE> <PATHTYPE>Name</PATHTYPE>
<PATH>UnicharUtilsStatic.o</PATH> <PATH>UnicharUtilsStatic.o</PATH>
@ -5811,13 +5799,6 @@
<FILEKIND>Text</FILEKIND> <FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS> <FILEFLAGS>Debug</FILEFLAGS>
</FILE> </FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsFrameLoader.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE> <FILE>
<PATHTYPE>Name</PATHTYPE> <PATHTYPE>Name</PATHTYPE>
<PATH>UnicharUtilsStaticDebug.o</PATH> <PATH>UnicharUtilsStaticDebug.o</PATH>
@ -6953,11 +6934,6 @@
<PATH>nsContentAreaDragDrop.cpp</PATH> <PATH>nsContentAreaDragDrop.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT> <PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF> </FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsFrameLoader.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF> <FILEREF>
<PATHTYPE>Name</PATHTYPE> <PATHTYPE>Name</PATHTYPE>
<PATH>UnicharUtilsStaticDebug.o</PATH> <PATH>UnicharUtilsStaticDebug.o</PATH>
@ -7286,12 +7262,6 @@
<PATH>nsContentAreaDragDrop.cpp</PATH> <PATH>nsContentAreaDragDrop.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT> <PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF> </FILEREF>
<FILEREF>
<TARGETNAME>content.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsFrameLoader.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
</GROUP> </GROUP>
<GROUP><NAME>build</NAME> <GROUP><NAME>build</NAME>
<FILEREF> <FILEREF>

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

@ -445,8 +445,6 @@ nsXULDocument::nsXULDocument(void)
#ifdef IBMBIDI #ifdef IBMBIDI
mBidiEnabled = PR_FALSE; mBidiEnabled = PR_FALSE;
#endif // IBMBIDI #endif // IBMBIDI
mSubDocuments = nsnull;
} }
nsIFastLoadService* nsXULDocument::gFastLoadService = nsnull; nsIFastLoadService* nsXULDocument::gFastLoadService = nsnull;
@ -474,11 +472,14 @@ nsXULDocument::~nsXULDocument()
observer->DocumentWillBeDestroyed(this); observer->DocumentWillBeDestroyed(this);
} }
// Delete references to sub-documents and kill the subdocument map, // mParentDocument is never refcounted
// if any. It holds strong references // Delete references to sub-documents
if (mSubDocuments) { {
PL_DHashTableDestroy(mSubDocuments); i = mSubDocuments.Count();
mSubDocuments = nsnull; while (--i >= 0) {
nsIDocument* subdoc = (nsIDocument*) mSubDocuments.ElementAt(i);
NS_RELEASE(subdoc);
}
} }
// Delete references to style sheets but only if we aren't a popup document. // Delete references to style sheets but only if we aren't a popup document.
@ -525,8 +526,7 @@ nsXULDocument::~nsXULDocument()
NS_IF_RELEASE(gXMLElementFactory); NS_IF_RELEASE(gXMLElementFactory);
if (gNameSpaceManager) { if (gNameSpaceManager) {
nsServiceManager::ReleaseService(kNameSpaceManagerCID, nsServiceManager::ReleaseService(kNameSpaceManagerCID, gNameSpaceManager);
gNameSpaceManager);
gNameSpaceManager = nsnull; gNameSpaceManager = nsnull;
} }
@ -1122,154 +1122,27 @@ nsXULDocument::SetParentDocument(nsIDocument* aParent)
return NS_OK; return NS_OK;
} }
PR_STATIC_CALLBACK(void)
SubDocClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
{
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 NS_IMETHODIMP
nsXULDocument::SetSubDocumentFor(nsIContent *aContent, nsIDocument* aSubDoc) nsXULDocument::AddSubDocument(nsIDocument* aSubDoc)
{ {
NS_ENSURE_TRUE(aContent, NS_ERROR_UNEXPECTED); NS_ADDREF(aSubDoc);
mSubDocuments.AppendElement(aSubDoc);
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::GetSubDocumentFor(nsIContent *aContent, nsIDocument** 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; return NS_OK;
} }
FindContentData data(aDocument); NS_IMETHODIMP
PL_DHashTableEnumerate(mSubDocuments, FindContentEnumerator, &data); nsXULDocument::GetNumberOfSubDocuments(PRInt32 *aCount)
{
*aCount = mSubDocuments.Count();
return NS_OK;
}
*aContent = data.mResult; NS_IMETHODIMP
NS_IF_ADDREF(*aContent); nsXULDocument::GetSubDocumentAt(PRInt32 aIndex, nsIDocument** aSubDoc)
{
return NS_OK; *aSubDoc = (nsIDocument*) mSubDocuments.SafeElementAt(aIndex);
NS_IF_ADDREF(*aSubDoc);
return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -2531,25 +2404,6 @@ nsXULDocument::RemoveReference(void *aKey, nsISupports **aOldReference)
return NS_OK; 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<nsISupports> container = do_QueryReferent(mDocumentContainer);
*aContainer = container;
NS_IF_ADDREF(*aContainer);
return NS_OK;
}
void void
nsXULDocument::SetDisplaySelection(PRInt8 aToggle) nsXULDocument::SetDisplaySelection(PRInt8 aToggle)
{ {

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

@ -222,12 +222,11 @@ public:
NS_IMETHOD SetParentDocument(nsIDocument* aParent); NS_IMETHOD SetParentDocument(nsIDocument* aParent);
NS_IMETHOD SetSubDocumentFor(nsIContent *aContent, nsIDocument* aSubDoc); NS_IMETHOD AddSubDocument(nsIDocument* aSubDoc);
NS_IMETHOD GetSubDocumentFor(nsIContent *aContent, nsIDocument** aSubDoc); NS_IMETHOD GetNumberOfSubDocuments(PRInt32* aCount);
NS_IMETHOD FindContentForSubDocument(nsIDocument *aDocument, NS_IMETHOD GetSubDocumentAt(PRInt32 aIndex, nsIDocument** aSubDoc);
nsIContent **aContent);
NS_IMETHOD GetRootContent(nsIContent** aRoot); NS_IMETHOD GetRootContent(nsIContent** aRoot);
@ -334,8 +333,6 @@ public:
NS_IMETHOD AddReference(void *aKey, nsISupports *aReference); NS_IMETHOD AddReference(void *aKey, nsISupports *aReference);
NS_IMETHOD RemoveReference(void *aKey, nsISupports **aOldReference); NS_IMETHOD RemoveReference(void *aKey, nsISupports **aOldReference);
NS_IMETHOD SetContainer(nsISupports *aContainer);
NS_IMETHOD GetContainer(nsISupports **aContainer);
virtual void SetDisplaySelection(PRInt8 aToggle); virtual void SetDisplaySelection(PRInt8 aToggle);
@ -565,7 +562,6 @@ protected:
nsCOMPtr<nsIURI> mDocumentURL; // [OWNER] ??? compare with loader nsCOMPtr<nsIURI> mDocumentURL; // [OWNER] ??? compare with loader
nsCOMPtr<nsIURI> mDocumentBaseURL; nsCOMPtr<nsIURI> mDocumentBaseURL;
nsWeakPtr mDocumentLoadGroup; // [WEAK] leads to loader nsWeakPtr mDocumentLoadGroup; // [WEAK] leads to loader
nsWeakPtr mDocumentContainer; // [WEAK] leads to container
nsCOMPtr<nsIPrincipal> mDocumentPrincipal; // [OWNER] nsCOMPtr<nsIPrincipal> mDocumentPrincipal; // [OWNER]
nsCOMPtr<nsIContent> mRootContent; // [OWNER] nsCOMPtr<nsIContent> mRootContent; // [OWNER]
nsIDocument* mParentDocument; // [WEAK] nsIDocument* mParentDocument; // [WEAK]
@ -594,7 +590,7 @@ protected:
nsCOMPtr<nsIRDFDataSource> mLocalStore; nsCOMPtr<nsIRDFDataSource> mLocalStore;
nsCOMPtr<nsILineBreaker> mLineBreaker; // [OWNER] nsCOMPtr<nsILineBreaker> mLineBreaker; // [OWNER]
nsCOMPtr<nsIWordBreaker> mWordBreaker; // [OWNER] nsCOMPtr<nsIWordBreaker> mWordBreaker; // [OWNER]
PLDHashTable *mSubDocuments; // [OWNER] of subelements nsVoidArray mSubDocuments; // [OWNER] of subelements
PRPackedBool mIsPopup; PRPackedBool mIsPopup;
PRPackedBool mIsFastLoad; PRPackedBool mIsFastLoad;
PRPackedBool mApplyingPersistedAttrs; PRPackedBool mApplyingPersistedAttrs;

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

@ -1158,14 +1158,6 @@ nsDocShell::SetChromeEventHandler(nsIChromeEventHandler * aChromeEventHandler)
{ {
// Weak reference. Don't addref. // Weak reference. Don't addref.
mChromeEventHandler = aChromeEventHandler; 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; return NS_OK;
} }
@ -2449,6 +2441,7 @@ nsDocShell::Stop(PRUint32 aStopFlags)
if (nsIWebNavigation::STOP_CONTENT & aStopFlags) { if (nsIWebNavigation::STOP_CONTENT & aStopFlags) {
if (mContentViewer) if (mContentViewer)
mContentViewer->Stop(); mContentViewer->Stop();
} }
if (nsIWebNavigation::STOP_NETWORK & aStopFlags) { if (nsIWebNavigation::STOP_NETWORK & aStopFlags) {
@ -2657,6 +2650,7 @@ nsDocShell::InitWindow(nativeWindow parentNativeWindow,
NS_IMETHODIMP NS_IMETHODIMP
nsDocShell::Create() nsDocShell::Create()
{ {
NS_ENSURE_STATE(!mContentViewer);
mPrefs = do_GetService(NS_PREF_CONTRACTID); mPrefs = do_GetService(NS_PREF_CONTRACTID);
//GlobalHistory is now set in SetGlobalHistory //GlobalHistory is now set in SetGlobalHistory
// mGlobalHistory = do_GetService(NS_GLOBALHISTORY_CONTRACTID); // mGlobalHistory = do_GetService(NS_GLOBALHISTORY_CONTRACTID);
@ -2841,6 +2835,8 @@ nsDocShell::GetParentWidget(nsIWidget ** parentWidget)
NS_IMETHODIMP NS_IMETHODIMP
nsDocShell::SetParentWidget(nsIWidget * aParentWidget) nsDocShell::SetParentWidget(nsIWidget * aParentWidget)
{ {
NS_ENSURE_STATE(!mContentViewer);
mParentWidget = aParentWidget; mParentWidget = aParentWidget;
return NS_OK; return NS_OK;
@ -3964,7 +3960,6 @@ nsDocShell::CreateAboutBlankContentViewer()
// generate (about:blank) document to load // generate (about:blank) document to load
docFactory->CreateBlankDocument(loadGroup, getter_AddRefs(blankDoc)); docFactory->CreateBlankDocument(loadGroup, getter_AddRefs(blankDoc));
if (blankDoc) { if (blankDoc) {
blankDoc->SetContainer(NS_STATIC_CAST(nsIDocShell *, this));
// create a content viewer for us and the new document // create a content viewer for us and the new document
docFactory->CreateInstanceForDocument(NS_ISUPPORTS_CAST(nsIDocShell *, this), docFactory->CreateInstanceForDocument(NS_ISUPPORTS_CAST(nsIDocShell *, this),
@ -4306,13 +4301,13 @@ nsDocShell::SetupNewViewer(nsIContentViewer * aNewViewer)
nsCOMPtr<nsIWidget> widget; nsCOMPtr<nsIWidget> widget;
NS_ENSURE_SUCCESS(GetMainWidget(getter_AddRefs(widget)), NS_ERROR_FAILURE); NS_ENSURE_SUCCESS(GetMainWidget(getter_AddRefs(widget)), NS_ERROR_FAILURE);
if (!widget) {
if (widget) { NS_ERROR("GetMainWidget coughed up a null widget");
NS_ENSURE_SUCCESS(EnsureDeviceContext(), NS_ERROR_FAILURE); return NS_ERROR_FAILURE;
} }
nsRect bounds(x, y, cx, cy); nsRect bounds(x, y, cx, cy);
NS_ENSURE_SUCCESS(EnsureDeviceContext(), NS_ERROR_FAILURE);
if (NS_FAILED(mContentViewer->Init(widget, mDeviceContext, bounds))) { if (NS_FAILED(mContentViewer->Init(widget, mDeviceContext, bounds))) {
mContentViewer = nsnull; mContentViewer = nsnull;
NS_ERROR("ContentViewer Initialization failed"); NS_ERROR("ContentViewer Initialization failed");
@ -4335,7 +4330,7 @@ nsDocShell::SetupNewViewer(nsIContentViewer * aNewViewer)
focusController->SetSuppressFocus(PR_FALSE, focusController->SetSuppressFocus(PR_FALSE,
"Win32-Only Link Traversal Issue"); "Win32-Only Link Traversal Issue");
if (bgSet && widget) { if (bgSet) {
// Stuff the bgcolor from the last view manager into the new // Stuff the bgcolor from the last view manager into the new
// view manager. This improves page load continuity. // view manager. This improves page load continuity.
nsCOMPtr<nsIDocumentViewer> docviewer = nsCOMPtr<nsIDocumentViewer> docviewer =

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

@ -1254,7 +1254,7 @@ NS_IMETHODIMP nsWebShell::Create()
// Set the webshell as the default IContentViewerContainer for the loader... // Set the webshell as the default IContentViewerContainer for the loader...
mDocLoader->SetContainer(shellAsContainer); mDocLoader->SetContainer(shellAsContainer);
return nsDocShell::Create(); return nsDocShell::Create();
} }
NS_IMETHODIMP nsWebShell::Destroy() NS_IMETHODIMP nsWebShell::Destroy()

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

@ -46,7 +46,6 @@
#include "nsIDOMLocation.h" #include "nsIDOMLocation.h"
#include "nsIDOMXULCommandDispatcher.h" #include "nsIDOMXULCommandDispatcher.h"
#include "nsIDocument.h" #include "nsIDocument.h"
#include "nsIDOMElement.h"
class nsIDocShell; class nsIDocShell;
class nsIDOMWindowInternal; class nsIDOMWindowInternal;
@ -85,12 +84,6 @@ public:
NS_IMETHOD GetExtantDocument(nsIDOMDocument** aDocument) = 0; NS_IMETHOD GetExtantDocument(nsIDOMDocument** aDocument) = 0;
NS_IMETHOD ReallyCloseWindow() = 0; 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;
}; };
#endif // nsPIDOMWindow_h__ #endif // nsPIDOMWindow_h__

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

@ -185,6 +185,4 @@ interface nsIDOMWindowInternal : nsIDOMWindow
// Ascii base64 data to binary data and vice versa... // Ascii base64 data to binary data and vice versa...
DOMString atob(in DOMString aAsciiString); DOMString atob(in DOMString aAsciiString);
DOMString btoa(in DOMString aBase64Data); DOMString btoa(in DOMString aBase64Data);
readonly attribute nsIDOMElement frameElement;
}; };

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

@ -185,8 +185,7 @@ GlobalWindowImpl::GlobalWindowImpl() :
mLastMouseButtonAction(LL_ZERO), mFullScreen(PR_FALSE), mLastMouseButtonAction(LL_ZERO), mFullScreen(PR_FALSE),
mOriginalPos(nsnull), mOriginalSize(nsnull), mOriginalPos(nsnull), mOriginalSize(nsnull),
mGlobalObjectOwner(nsnull), mGlobalObjectOwner(nsnull),
mDocShell(nsnull), mMutationBits(0), mChromeEventHandler(nsnull), mDocShell(nsnull), mMutationBits(0), mChromeEventHandler(nsnull)
mFrameElement(nsnull)
{ {
NS_INIT_REFCNT(); NS_INIT_REFCNT();
// We could have failed the first time through trying // We could have failed the first time through trying
@ -717,38 +716,6 @@ GlobalWindowImpl::HandleDOMEvent(nsIPresContext* aPresContext,
} }
} }
if (aEvent->message == NS_PAGE_LOAD) {
nsCOMPtr<nsIContent> content(do_QueryInterface(mFrameElement));
nsCOMPtr<nsIDOMWindowInternal> parent;
GetParentInternal(getter_AddRefs(parent));
nsCOMPtr<nsIDocShellTreeItem> 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<nsIPresContext> 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) { if (NS_EVENT_FLAG_INIT & aFlags) {
// We're leaving the DOM event loop so if we created an event, // We're leaving the DOM event loop so if we created an event,
@ -2846,53 +2813,6 @@ GlobalWindowImpl::ReallyCloseWindow()
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
GlobalWindowImpl::GetFrameElement(nsIDOMElement** aFrameElement)
{
*aFrameElement = nsnull;
nsCOMPtr<nsIDocShell> docShell;
GetDocShell(getter_AddRefs(docShell));
nsCOMPtr<nsIDocShellTreeItem> docShellTI(do_QueryInterface(docShell));
if (!docShellTI) {
return NS_OK;
}
nsCOMPtr<nsIDocShellTreeItem> 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 NS_IMETHODIMP
GlobalWindowImpl::UpdateCommands(const nsAString& anAction) GlobalWindowImpl::UpdateCommands(const nsAString& anAction)
{ {
@ -4852,7 +4772,6 @@ nsGlobalChromeWindow::GetWindowState(PRUint16* aWindowState)
break; break;
case nsSizeMode_Normal: case nsSizeMode_Normal:
*aWindowState = nsIDOMChromeWindow::STATE_NORMAL; *aWindowState = nsIDOMChromeWindow::STATE_NORMAL;
break;
default: default:
NS_WARNING("Illegal window state for this chrome window"); NS_WARNING("Illegal window state for this chrome window");
break; break;

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

@ -188,9 +188,6 @@ public:
NS_IMETHOD ReallyCloseWindow(); NS_IMETHOD ReallyCloseWindow();
NS_IMETHOD GetFrameElementInternal(nsIDOMElement** aFrameElement);
NS_IMETHOD SetFrameElementInternal(nsIDOMElement* aFrameElement);
// nsIDOMViewCSS // nsIDOMViewCSS
NS_DECL_NSIDOMVIEWCSS NS_DECL_NSIDOMVIEWCSS
@ -305,8 +302,6 @@ protected:
nsCOMPtr<nsIDOMPkcs11> mPkcs11; nsCOMPtr<nsIDOMPkcs11> mPkcs11;
nsCOMPtr<nsIPrincipal> mDocumentPrincipal; nsCOMPtr<nsIPrincipal> mDocumentPrincipal;
nsIDOMElement* mFrameElement; // WEAK
friend class nsDOMScriptableHelper; friend class nsDOMScriptableHelper;
static nsIXPConnect *sXPConnect; static nsIXPConnect *sXPConnect;
}; };

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

@ -151,11 +151,9 @@ nsresult nsJSEventListener::HandleEvent(nsIDOMEvent* aEvent)
nsEvent* event; nsEvent* event;
priv->GetInternalNSEvent(&event); priv->GetInternalNSEvent(&event);
if (event->message == NS_SCRIPT_ERROR) { if (event->message == NS_SCRIPT_ERROR) {
nsScriptErrorEvent *scriptEvent = nsScriptErrorEvent *scriptEvent = NS_STATIC_CAST(nsScriptErrorEvent*, event);
NS_STATIC_CAST(nsScriptErrorEvent*, event);
argv = ::JS_PushArguments(cx, &stackPtr, "WWi", scriptEvent->errorMsg, 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); NS_ENSURE_TRUE(argv, NS_ERROR_OUT_OF_MEMORY);
argc = 3; argc = 3;
handledScriptError = PR_TRUE; handledScriptError = PR_TRUE;

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

@ -261,8 +261,6 @@ nsEditor::~nsEditor()
IMETextTxn::ClassShutdown(); IMETextTxn::ClassShutdown();
PR_AtomicDecrement(&gInstanceCount); PR_AtomicDecrement(&gInstanceCount);
NS_IF_RELEASE(mViewManager);
} }
@ -306,6 +304,7 @@ nsEditor::Init(nsIDOMDocument *aDoc, nsIPresShell* aPresShell, nsIContent *aRoot
ps->GetViewManager(&mViewManager); ps->GetViewManager(&mViewManager);
if (!mViewManager) {return NS_ERROR_NULL_POINTER;} if (!mViewManager) {return NS_ERROR_NULL_POINTER;}
mViewManager->Release(); //we want a weak link
mUpdateCount=0; mUpdateCount=0;
InsertTextTxn::ClassInit(); InsertTextTxn::ClassInit();

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

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK ***** /* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
* *
@ -253,12 +253,22 @@ inLayoutUtils::GetSubDocumentFor(nsIDOMNode* aNode)
nsCOMPtr<nsIDocument> doc; nsCOMPtr<nsIDocument> doc;
content->GetDocument(*getter_AddRefs(doc)); content->GetDocument(*getter_AddRefs(doc));
if (doc) { if (doc) {
nsCOMPtr<nsIDocument> sub_doc; nsCOMPtr<nsIPresShell> shell;
doc->GetSubDocumentFor(content, getter_AddRefs(sub_doc)); doc->GetShellAt(0, getter_AddRefs(shell));
if (shell) {
nsCOMPtr<nsIDOMDocument> domdoc(do_QueryInterface(sub_doc)); nsCOMPtr<nsISupports> supports;
shell->GetSubShellFor(content, getter_AddRefs(supports));
return domdoc; nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(supports);
if (docShell) {
nsCOMPtr<nsIContentViewer> contentViewer;
docShell->GetContentViewer(getter_AddRefs(contentViewer));
if (contentViewer) {
nsCOMPtr<nsIDOMDocument> domdoc;
contentViewer->GetDOMDocument(getter_AddRefs(domdoc));
return domdoc;
}
}
}
} }
} }
@ -269,7 +279,6 @@ nsIDOMNode*
inLayoutUtils::GetContainerFor(nsIDOMDocument* aDoc) inLayoutUtils::GetContainerFor(nsIDOMDocument* aDoc)
{ {
nsCOMPtr<nsIDOMNode> container; nsCOMPtr<nsIDOMNode> container;
nsCOMPtr<nsIDocument> doc(do_QueryInterface(aDoc));
// get the doc shell for this document and look for the parent doc shell // get the doc shell for this document and look for the parent doc shell
nsCOMPtr<nsIDOMWindowInternal> win = inLayoutUtils::GetWindowFor(aDoc); nsCOMPtr<nsIDOMWindowInternal> win = inLayoutUtils::GetWindowFor(aDoc);
@ -288,17 +297,9 @@ inLayoutUtils::GetContainerFor(nsIDOMDocument* aDoc)
nsCOMPtr<nsIPresShell> presShell; nsCOMPtr<nsIPresShell> presShell;
parentDocShell->GetPresShell(getter_AddRefs(presShell)); parentDocShell->GetPresShell(getter_AddRefs(presShell));
nsCOMPtr<nsIDocument> parent_doc; nsCOMPtr<nsIContent> content;
presShell->GetDocument(getter_AddRefs(parent_doc)); presShell->FindContentForShell(docShell, getter_AddRefs(content));
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(content);
nsCOMPtr<nsIDOMNode> node;
if (parent_doc) {
nsCOMPtr<nsIContent> content;
parent_doc->FindContentForSubDocument(doc, getter_AddRefs(content));
node = do_QueryInterface(content);
}
return node; return node;
} }

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -265,6 +265,28 @@ public:
NS_IMETHOD GetLayoutObjectFor(nsIContent* aContent, NS_IMETHOD GetLayoutObjectFor(nsIContent* aContent,
nsISupports** aResult) const = 0; 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 * Gets the placeholder frame associated with the specified frame. This is
* a helper frame that forwards the request to the frame manager. * a helper frame that forwards the request to the frame manager.

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

@ -166,6 +166,9 @@
#include "nsIContentViewer.h" #include "nsIContentViewer.h"
#include "nsIDocumentViewer.h" #include "nsIDocumentViewer.h"
// SubShell map
#include "pldhash.h"
#ifdef IBMBIDI #ifdef IBMBIDI
#include "nsIBidiKeyboard.h" #include "nsIBidiKeyboard.h"
#endif // IBMBIDI #endif // IBMBIDI
@ -806,6 +809,14 @@ 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, class PresShell : public nsIPresShell, public nsIViewObserver,
private nsIDocumentObserver, public nsIFocusTracker, private nsIDocumentObserver, public nsIFocusTracker,
public nsISelectionController, public nsISelectionController,
@ -866,6 +877,12 @@ public:
nsIStyleContext** aStyleContext) const; nsIStyleContext** aStyleContext) const;
NS_IMETHOD GetLayoutObjectFor(nsIContent* aContent, NS_IMETHOD GetLayoutObjectFor(nsIContent* aContent,
nsISupports** aResult) const; 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, NS_IMETHOD GetPlaceholderFrameFor(nsIFrame* aFrame,
nsIFrame** aPlaceholderFrame) const; nsIFrame** aPlaceholderFrame) const;
NS_IMETHOD AppendReflowCommand(nsHTMLReflowCommand* aReflowCommand); NS_IMETHOD AppendReflowCommand(nsHTMLReflowCommand* aReflowCommand);
@ -1218,6 +1235,9 @@ protected:
static void sPaintSuppressionCallback(nsITimer* aTimer, void* aPresShell); // A callback for the timer. 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(mReflowWatch) // Used for measuring time spent in reflow
MOZ_TIMER_DECLARE(mFrameCreationWatch) // Used for measuring time spent in frame creation MOZ_TIMER_DECLARE(mFrameCreationWatch) // Used for measuring time spent in frame creation
@ -1655,6 +1675,13 @@ PresShell::Destroy()
// Clobber weak leaks in case of re-entrancy during tear down // Clobber weak leaks in case of re-entrancy during tear down
mHistoryState = nsnull; 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 // release current event content and any content on event stack
NS_IF_RELEASE(mCurrentEventContent); NS_IF_RELEASE(mCurrentEventContent);
@ -5502,6 +5529,94 @@ PresShell::GetLayoutObjectFor(nsIContent* aContent,
return result; 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 NS_IMETHODIMP
PresShell::GetPlaceholderFrameFor(nsIFrame* aFrame, PresShell::GetPlaceholderFrameFor(nsIFrame* aFrame,
nsIFrame** aResult) const nsIFrame** aResult) const

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

@ -265,6 +265,28 @@ public:
NS_IMETHOD GetLayoutObjectFor(nsIContent* aContent, NS_IMETHOD GetLayoutObjectFor(nsIContent* aContent,
nsISupports** aResult) const = 0; 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 * Gets the placeholder frame associated with the specified frame. This is
* a helper frame that forwards the request to the frame manager. * a helper frame that forwards the request to the frame manager.

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

@ -416,8 +416,6 @@ nsContentDLF::CreateDocument(const char* aCommand,
break; break;
docv->SetUAStyleSheet(gUAStyleSheet); docv->SetUAStyleSheet(gUAStyleSheet);
doc->SetContainer(aContainer);
// Initialize the document to begin loading the data. An // Initialize the document to begin loading the data. An
// nsIStreamListener connected to the parser is returned in // nsIStreamListener connected to the parser is returned in
// aDocListener. // aDocListener.
@ -514,9 +512,6 @@ nsContentDLF::CreateRDFDocument(const char* aCommand,
* An nsIStreamListener connected to the parser is returned in * An nsIStreamListener connected to the parser is returned in
* aDocListener. * aDocListener.
*/ */
doc->SetContainer(aContainer);
rv = doc->StartDocumentLoad(aCommand, aChannel, aLoadGroup, aContainer, aDocListener, PR_TRUE); rv = doc->StartDocumentLoad(aCommand, aChannel, aLoadGroup, aContainer, aDocListener, PR_TRUE);
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
/* /*

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

@ -72,7 +72,6 @@
#include "nsFrameSetFrame.h" #include "nsFrameSetFrame.h"
#include "nsIDOMHTMLFrameElement.h" #include "nsIDOMHTMLFrameElement.h"
#include "nsIDOMHTMLIFrameElement.h" #include "nsIDOMHTMLIFrameElement.h"
#include "nsIFrameLoader.h"
#include "nsLayoutAtoms.h" #include "nsLayoutAtoms.h"
#include "nsIChromeEventHandler.h" #include "nsIChromeEventHandler.h"
#include "nsIScriptSecurityManager.h" #include "nsIScriptSecurityManager.h"
@ -89,7 +88,6 @@
#include "nsIDOMEventTarget.h" #include "nsIDOMEventTarget.h"
#include "nsIDOMEventListener.h" #include "nsIDOMEventListener.h"
#include "nsIDOMWindow.h" #include "nsIDOMWindow.h"
#include "nsIDOMDocument.h"
#include "nsIRenderingContext.h" #include "nsIRenderingContext.h"
// For Accessibility // For Accessibility
@ -100,12 +98,19 @@
class nsHTMLFrame; 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(kCViewCID, NS_VIEW_CID);
static NS_DEFINE_CID(kCChildCID, NS_CHILD_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.
#define MAX_DEPTH_CONTENT_FRAMES 25
/*******************************************************************************
* FrameLoadingInfo * FrameLoadingInfo
*****************************************************************************/ ******************************************************************************/
class FrameLoadingInfo : public nsISupports class FrameLoadingInfo : public nsISupports
{ {
public: public:
@ -122,9 +127,9 @@ public:
}; };
/****************************************************************************** /*******************************************************************************
* nsHTMLFrameOuterFrame * nsHTMLFrameOuterFrame
*****************************************************************************/ ******************************************************************************/
#define nsHTMLFrameOuterFrameSuper nsHTMLContainerFrame #define nsHTMLFrameOuterFrameSuper nsHTMLContainerFrame
class nsHTMLFrameOuterFrame : public nsHTMLFrameOuterFrameSuper { class nsHTMLFrameOuterFrame : public nsHTMLFrameOuterFrameSuper {
@ -182,10 +187,11 @@ protected:
nsCOMPtr<nsIPresContext> mPresContext; nsCOMPtr<nsIPresContext> mPresContext;
}; };
/****************************************************************************** /*******************************************************************************
* nsHTMLFrameInnerFrame * nsHTMLFrameInnerFrame
*****************************************************************************/ ******************************************************************************/
class nsHTMLFrameInnerFrame : public nsLeafFrame, class nsHTMLFrameInnerFrame : public nsLeafFrame,
public nsIWebProgressListener,
public nsSupportsWeakReference public nsSupportsWeakReference
{ {
public: public:
@ -195,6 +201,8 @@ public:
NS_IMETHOD_(nsrefcnt) AddRef(void) { return 2; } NS_IMETHOD_(nsrefcnt) AddRef(void) { return 2; }
NS_IMETHOD_(nsrefcnt) Release(void) { return 1; } NS_IMETHOD_(nsrefcnt) Release(void) { return 1; }
NS_DECL_NSIWEBPROGRESSLISTENER
#ifdef DEBUG #ifdef DEBUG
NS_IMETHOD GetFrameName(nsAString& aResult) const; NS_IMETHOD GetFrameName(nsAString& aResult) const;
#endif #endif
@ -228,9 +236,7 @@ public:
nsIStyleContext* aContext, nsIStyleContext* aContext,
nsIFrame* aPrevInFlow); nsIFrame* aPrevInFlow);
void GetParentContent(nsIContent** aContent); NS_IMETHOD GetParentContent(nsIContent*& aContent);
nsresult GetDocShell(nsIDocShell **aDocShell);
PRBool GetURL(nsIContent* aContent, nsString& aResult); PRBool GetURL(nsIContent* aContent, nsString& aResult);
PRBool GetName(nsIContent* aContent, nsString& aResult); PRBool GetName(nsIContent* aContent, nsString& aResult);
PRInt32 GetScrolling(nsIContent* aContent); PRInt32 GetScrolling(nsIContent* aContent);
@ -238,10 +244,13 @@ public:
PRInt32 GetMarginWidth(nsIPresContext* aPresContext, nsIContent* aContent); PRInt32 GetMarginWidth(nsIPresContext* aPresContext, nsIContent* aContent);
PRInt32 GetMarginHeight(nsIPresContext* aPresContext, nsIContent* aContent); PRInt32 GetMarginHeight(nsIPresContext* aPresContext, nsIContent* aContent);
nsresult ReloadURL(nsIPresContext* aPresContext);
friend class nsHTMLFrameOuterFrame; friend class nsHTMLFrameOuterFrame;
protected: protected:
nsresult ShowDocShell(nsIPresContext* aPresContext); nsresult CreateDocShell(nsIPresContext* aPresContext);
nsresult DoLoadURL(nsIPresContext* aPresContext);
nsresult CreateViewAndWidget(nsIPresContext* aPresContext, nsresult CreateViewAndWidget(nsIPresContext* aPresContext,
nsIWidget** aWidget); nsIWidget** aWidget);
@ -251,18 +260,15 @@ protected:
const nsHTMLReflowState& aReflowState, const nsHTMLReflowState& aReflowState,
nsHTMLReflowMetrics& aDesiredSize); nsHTMLReflowMetrics& aDesiredSize);
nsresult ReloadURL(); nsCOMPtr<nsIBaseWindow> mSubShell;
nsWeakPtr mPresShellWeak; // weak reference to the nsIPresShell
nsCOMPtr<nsIFrameLoader> mFrameLoader; PRBool mCreatingViewer;
PRPackedBool mOwnsFrameLoader;
PRPackedBool mCreatingViewer;
}; };
/****************************************************************************** /*******************************************************************************
* nsHTMLFrameOuterFrame * nsHTMLFrameOuterFrame
*****************************************************************************/ ******************************************************************************/
nsHTMLFrameOuterFrame::nsHTMLFrameOuterFrame() nsHTMLFrameOuterFrame::nsHTMLFrameOuterFrame()
: nsHTMLContainerFrame() : nsHTMLContainerFrame()
{ {
@ -550,34 +556,31 @@ nsHTMLFrameOuterFrame::AttributeChanged(nsIPresContext* aPresContext,
nsCOMPtr<nsIAtom> type; nsCOMPtr<nsIAtom> type;
aChild->GetTag(*getter_AddRefs(type)); aChild->GetTag(*getter_AddRefs(type));
if ((type != nsHTMLAtoms::object && aAttribute == nsHTMLAtoms::src) || if (((nsHTMLAtoms::src == aAttribute) && (nsHTMLAtoms::object != type)) ||
(type == nsHTMLAtoms::object && aAttribute == nsHTMLAtoms::data)) { ((nsHTMLAtoms::data == aAttribute) && (nsHTMLAtoms::object == type))) {
nsHTMLFrameInnerFrame* firstChild = nsHTMLFrameInnerFrame* firstChild = NS_STATIC_CAST(nsHTMLFrameInnerFrame*,
NS_STATIC_CAST(nsHTMLFrameInnerFrame*, mFrames.FirstChild()); mFrames.FirstChild());
if (firstChild) { if (firstChild) {
firstChild->ReloadURL(); firstChild->ReloadURL(aPresContext);
} }
} }
// If the noResize attribute changes, dis/allow frame to be resized // If the noResize attribute changes, dis/allow frame to be resized
else if (aAttribute == nsHTMLAtoms::noresize) { else if (nsHTMLAtoms::noresize == aAttribute) {
nsCOMPtr<nsIContent> parentContent; nsCOMPtr<nsIContent> parentContent;
mContent->GetParent(*getter_AddRefs(parentContent)); mContent->GetParent(*getter_AddRefs(parentContent));
nsCOMPtr<nsIAtom> parentTag; nsCOMPtr<nsIAtom> parentTag;
parentContent->GetTag(*getter_AddRefs(parentTag)); parentContent->GetTag(*getter_AddRefs(parentTag));
if (parentTag == nsHTMLAtoms::frameset) { if (nsHTMLAtoms::frameset == parentTag) {
nsIFrame* parentFrame = nsnull; nsIFrame* parentFrame = nsnull;
GetParent(&parentFrame); GetParent(&parentFrame);
if (parentFrame) { if (parentFrame) {
// There is no interface for nsHTMLFramesetFrame so QI'ing to // There is no interface for kIFramesetFrameIID
// concrete class, yay! // so QI'ing to concrete class, yay!
nsHTMLFramesetFrame* framesetFrame = nsnull; nsHTMLFramesetFrame* framesetFrame = nsnull;
parentFrame->QueryInterface(NS_GET_IID(nsHTMLFramesetFrame), parentFrame->QueryInterface(kIFramesetFrameIID, (void **)&framesetFrame);
(void **)&framesetFrame);
if (framesetFrame) { if (framesetFrame) {
framesetFrame->RecalculateBorderResize(); framesetFrame->RecalculateBorderResize();
} }
@ -586,8 +589,8 @@ nsHTMLFrameOuterFrame::AttributeChanged(nsIPresContext* aPresContext,
} }
else if (aAttribute == nsHTMLAtoms::type) { else if (aAttribute == nsHTMLAtoms::type) {
nsHTMLFrameInnerFrame* firstChild = NS_STATIC_CAST(nsHTMLFrameInnerFrame*, nsHTMLFrameInnerFrame* firstChild = NS_STATIC_CAST(nsHTMLFrameInnerFrame*,
mFrames.FirstChild()); mFrames.FirstChild());
if (!firstChild || !firstChild->mFrameLoader) if (!firstChild)
return NS_OK; return NS_OK;
nsAutoString value; nsAutoString value;
@ -595,36 +598,28 @@ nsHTMLFrameOuterFrame::AttributeChanged(nsIPresContext* aPresContext,
// Notify our enclosing chrome that the primary content shell // Notify our enclosing chrome that the primary content shell
// has changed. // has changed.
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(firstChild->mSubShell));
nsCOMPtr<nsIDocShell> docShell; nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(firstChild->mSubShell));
firstChild->mFrameLoader->GetDocShell(getter_AddRefs(docShell));
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(docShell));
// If our container is a web-shell, inform it that it has a new // 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 // child. If it's not a web-shell then some things will not operate
// properly. // properly.
nsCOMPtr<nsISupports> container; nsCOMPtr<nsISupports> container;
aPresContext->GetContainer(getter_AddRefs(container)); aPresContext->GetContainer(getter_AddRefs(container));
if (container) {
nsCOMPtr<nsIDocShellTreeNode> parentAsNode(do_QueryInterface(container));
if (parentAsNode) {
nsCOMPtr<nsIDocShellTreeItem> parentAsItem(do_QueryInterface(parentAsNode));
nsCOMPtr<nsIDocShellTreeNode> parentAsNode(do_QueryInterface(container)); nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner;
parentAsItem->GetTreeOwner(getter_AddRefs(parentTreeOwner));
if (parentAsNode) { if (parentTreeOwner)
nsCOMPtr<nsIDocShellTreeItem> parentAsItem = parentTreeOwner->ContentShellAdded(docShellAsItem,
do_QueryInterface(parentAsNode); value.EqualsIgnoreCase("content-primary") ? PR_TRUE : PR_FALSE,
value.get());
nsCOMPtr<nsIDocShellTreeOwner> 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; return NS_OK;
} }
@ -643,42 +638,41 @@ NS_NewHTMLFrameOuterFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
return NS_OK; return NS_OK;
} }
/****************************************************************************** /*******************************************************************************
* nsHTMLFrameInnerFrame * nsHTMLFrameInnerFrame
*****************************************************************************/ ******************************************************************************/
nsHTMLFrameInnerFrame::nsHTMLFrameInnerFrame() nsHTMLFrameInnerFrame::nsHTMLFrameInnerFrame()
: nsLeafFrame(), mOwnsFrameLoader(PR_FALSE), mCreatingViewer(PR_FALSE) : nsLeafFrame()
{ {
mCreatingViewer = PR_FALSE;
mPresShellWeak = nsnull;
} }
nsHTMLFrameInnerFrame::~nsHTMLFrameInnerFrame() nsHTMLFrameInnerFrame::~nsHTMLFrameInnerFrame()
{ {
//printf("nsHTMLFrameInnerFrame destructor %X \n", this); //printf("nsHTMLFrameInnerFrame destructor %X \n", this);
if (mFrameLoader) { nsCOMPtr<nsIDOMWindow> win(do_GetInterface(mSubShell));
// Get the content viewer through the docshell, but don't call nsCOMPtr<nsIDOMEventTarget> eventTarget(do_QueryInterface(win));
// GetDocShell() since we don't want to create one if we don't nsCOMPtr<nsIDOMEventListener> eventListener(do_QueryInterface(mContent));
// have one.
nsCOMPtr<nsIDocShell> docShell; if (eventTarget && eventListener) {
mFrameLoader->GetDocShell(getter_AddRefs(docShell)); eventTarget->RemoveEventListener(NS_LITERAL_STRING("load"), eventListener,
PR_FALSE);
}
nsCOMPtr<nsIContentViewer> content_viewer; if(mSubShell) {
docShell->GetContentViewer(getter_AddRefs(content_viewer)); // notify the pres shell that a docshell has been destroyed
if (mPresShellWeak) {
if (content_viewer) { nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
// Hide the content viewer now that the frame is going away... if (ps) {
ps->SetSubShellFor(mContent, nsnull);
content_viewer->Hide(); }
} }
mSubShell->Destroy();
} }
mSubShell = nsnull; // This is the location it was released before...
if (mFrameLoader && mOwnsFrameLoader) { // Not sure if there is ordering depending on this.
// We own this frame loader, and we're going away, so destroy our
// frame loader.
mFrameLoader->Destroy();
}
} }
PRBool nsHTMLFrameInnerFrame::GetURL(nsIContent* aContent, nsString& aResult) PRBool nsHTMLFrameInnerFrame::GetURL(nsIContent* aContent, nsString& aResult)
@ -814,6 +808,12 @@ nsHTMLFrameInnerFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{ {
NS_ENSURE_ARG_POINTER(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))) { if (aIID.Equals(NS_GET_IID(nsISupportsWeakReference))) {
nsISupports *tmp = NS_STATIC_CAST(nsISupportsWeakReference *, this); nsISupports *tmp = NS_STATIC_CAST(nsISupportsWeakReference *, this);
*aInstancePtr = tmp; *aInstancePtr = tmp;
@ -823,6 +823,60 @@ nsHTMLFrameInnerFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr)
return nsLeafFrame::QueryInterface(aIID, 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<nsIDOMWindow> win(do_GetInterface(mSubShell));
nsCOMPtr<nsIDOMEventTarget> eventTarget(do_QueryInterface(win));
nsCOMPtr<nsIDOMEventListener> 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 #ifdef DEBUG
NS_IMETHODIMP nsHTMLFrameInnerFrame::GetFrameName(nsAString& aResult) const NS_IMETHODIMP nsHTMLFrameInnerFrame::GetFrameName(nsAString& aResult) const
{ {
@ -846,90 +900,33 @@ nsHTMLFrameInnerFrame::Paint(nsIPresContext* aPresContext,
nsFramePaintLayer aWhichLayer, nsFramePaintLayer aWhichLayer,
PRUint32 aFlags) PRUint32 aFlags)
{ {
//printf("inner paint %X (%d,%d,%d,%d) \n", this, aDirtyRect.x, //printf("inner paint %X (%d,%d,%d,%d) \n", this, aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height);
//aDirtyRect.y, aDirtyRect.width, aDirtyRect.height); if there is // if there is not web shell paint based on our background color,
//not web shell paint based on our background color, otherwise let // otherwise let the web shell paint the sub document
//the web shell paint the sub document
// isPaginated is a temporary fix for Bug 75737 and this should all // isPaginated is a temporary fix for Bug 75737
// be fixed correctly by Bug 75739 // and this should all be fixed correctly by Bug 75739
PRBool isPaginated; PRBool isPaginated;
aPresContext->IsPaginated(&isPaginated); aPresContext->IsPaginated(&isPaginated);
if (!mSubShell && !isPaginated) {
if (!isPaginated) { const nsStyleBackground* color =
nsCOMPtr<nsIDocShell> docShell; (const nsStyleBackground*)mStyleContext->GetStyleData(eStyleStruct_Background);
GetDocShell(getter_AddRefs(docShell)); aRenderingContext.SetColor(color->mBackgroundColor);
aRenderingContext.FillRect(mRect);
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); DO_GLOBAL_REFLOW_COUNT_DSP("nsHTMLFrameInnerFrame", &aRenderingContext);
return NS_OK; return NS_OK;
} }
void NS_IMETHODIMP
nsHTMLFrameInnerFrame::GetParentContent(nsIContent** aContent) nsHTMLFrameInnerFrame::GetParentContent(nsIContent*& aContent)
{ {
*aContent = nsnull; nsHTMLFrameOuterFrame* parent;
nsresult rv = GetParent((nsIFrame**)&parent);
nsIFrame* parent = nsnull; if (NS_SUCCEEDED(rv) && parent) {
GetParent(&parent); rv = parent->GetContent(&aContent);
if (parent) {
parent->GetContent(aContent);
} }
} return rv;
nsresult
nsHTMLFrameInnerFrame::GetDocShell(nsIDocShell **aDocShell)
{
*aDocShell = nsnull;
nsCOMPtr<nsIContent> 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<nsIFrameLoaderOwner> 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 NS_IMETHODIMP
@ -955,7 +952,7 @@ nsHTMLFrameInnerFrame::DidReflow(nsIPresContext* aPresContext,
if (newVis != oldVis) { if (newVis != oldVis) {
nsCOMPtr<nsIViewManager> vm; nsCOMPtr<nsIViewManager> vm;
view->GetViewManager(*getter_AddRefs(vm)); view->GetViewManager(*getter_AddRefs(vm));
if (vm) { if (vm != nsnull) {
vm->SetViewVisibility(view, newVis); vm->SetViewVisibility(view, newVis);
} }
} }
@ -966,91 +963,276 @@ nsHTMLFrameInnerFrame::DidReflow(nsIPresContext* aPresContext,
} }
nsresult nsresult
nsHTMLFrameInnerFrame::ShowDocShell(nsIPresContext* aPresContext) nsHTMLFrameInnerFrame::CreateDocShell(nsIPresContext* aPresContext)
{ {
nsCOMPtr<nsIDocShell> docShell; nsresult rv;
nsresult rv = GetDocShell(getter_AddRefs(docShell)); nsCOMPtr<nsIContent> parentContent;
NS_ENSURE_SUCCESS(rv, rv); GetParentContent(*getter_AddRefs(parentContent));
// Make sure there's a document in the docshell. // Bug 8065: Don't exceed some maximum depth in content frames (MAX_DEPTH_CONTENT_FRAMES)
nsCOMPtr<nsIDOMWindow> win(do_GetInterface(docShell)); PRInt32 depth = 0;
NS_ENSURE_TRUE(win, NS_ERROR_UNEXPECTED); nsCOMPtr<nsISupports> parentAsSupports;
aPresContext->GetContainer(getter_AddRefs(parentAsSupports));
if (parentAsSupports) {
nsCOMPtr<nsIDocShellTreeItem> parentAsItem(do_QueryInterface(parentAsSupports));
while (parentAsItem) {
depth++;
if (MAX_DEPTH_CONTENT_FRAMES < depth)
return NS_ERROR_UNEXPECTED; // Too deep, give up! (silently?)
{ // Only count depth on content, not chrome.
nsCOMPtr<nsIDOMDocument> dom_doc; // If we wanted to limit total depth, skip the following check:
PRInt32 parentType;
// This will synchronously create a document if there is no parentAsItem->GetItemType(&parentType);
// document in the window yet. if (nsIDocShellTreeItem::typeContent == parentType) {
nsIDocShellTreeItem* temp = parentAsItem;
win->GetDocument(getter_AddRefs(dom_doc)); temp->GetParent(getter_AddRefs(parentAsItem));
} else {
break; // we have exited content, stop counting, depth is OK!
}
}
} }
mSubShell = do_CreateInstance(kWebShellCID);
NS_ENSURE_TRUE(mSubShell, NS_ERROR_FAILURE);
// notify the pres shell that a docshell has been created
nsCOMPtr<nsIPresShell> presShell; nsCOMPtr<nsIPresShell> presShell;
docShell->GetPresShell(getter_AddRefs(presShell)); aPresContext->GetShell(getter_AddRefs(presShell));
if (presShell)
if (presShell) { {
// The docshell is already showing, nothing left to do... nsCOMPtr<nsISupports> subShellAsSupports(do_QueryInterface(mSubShell));
NS_ENSURE_TRUE(subShellAsSupports, NS_ERROR_FAILURE);
return NS_OK; 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));
} }
nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem(do_QueryInterface(docShell)); nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(mSubShell));
NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
nsCOMPtr<nsIDocShellTreeItem> parentDocShellTreeItem; // pass along marginwidth, marginheight, scrolling so sub document can use it
docShellTreeItem->GetParent(getter_AddRefs(parentDocShellTreeItem)); docShell->SetMarginWidth(GetMarginWidth(aPresContext, parentContent));
docShell->SetMarginHeight(GetMarginHeight(aPresContext, parentContent));
nsCOMPtr<nsIDocShell> parentDocShell =
do_QueryInterface(parentDocShellTreeItem);
nsCOMPtr<nsIPresShell> parentPresShell;
parentDocShell->GetPresShell(getter_AddRefs(parentPresShell));
nsCOMPtr<nsIContent> 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 // Current and initial scrolling is set so that all succeeding docs
// will use the scrolling value set here, regardless if scrolling is // will use the scrolling value set here, regardless if scrolling is
// set by viewing a particular document (e.g. XUL turns off scrolling) // set by viewing a particular document (e.g. XUL turns off scrolling)
nsCOMPtr<nsIScrollable> scrollableContainer(do_QueryInterface(docShell)); nsCOMPtr<nsIScrollable> scrollableContainer(do_QueryInterface(mSubShell));
if (scrollableContainer) { if (scrollableContainer) {
scrollableContainer->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_Y, scrollableContainer->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_Y,
GetScrolling(content)); GetScrolling(parentContent));
scrollableContainer->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X, scrollableContainer->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X,
GetScrolling(content)); GetScrolling(parentContent));
} }
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(docShell)); nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mSubShell));
NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE); 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<nsISupports> container;
aPresContext->GetContainer(getter_AddRefs(container));
if (container) {
nsCOMPtr<nsIDocShellTreeNode> parentAsNode(do_QueryInterface(container));
if (parentAsNode) {
nsCOMPtr<nsIDocShellTreeItem> 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<nsIDocShellTreeOwner> 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<nsIWebShell> webShell(do_QueryInterface(mSubShell));
nsCOMPtr<nsIWebShellContainer> 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<nsIDocShell> parentShell(do_QueryInterface(parentAsNode));
nsCOMPtr<nsIChromeEventHandler> 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<nsIWidget> widget; nsCOMPtr<nsIWidget> widget;
rv = CreateViewAndWidget(aPresContext, getter_AddRefs(widget)); rv = CreateViewAndWidget(aPresContext, getter_AddRefs(widget));
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; return rv;
} }
nsCOMPtr<nsIBaseWindow> baseWindow(do_QueryInterface(docShell)); mSubShell->InitWindow(nsnull, widget, 0, 0, 10, 10);
mSubShell->Create();
if (baseWindow) { mSubShell->SetVisibility(PR_TRUE);
baseWindow->InitWindow(nsnull, widget, 0, 0, 10, 10);
// This is kinda whacky, this "Create()" calldoesn't really create
// anything, one starts to wonder why this was named "Create"...
baseWindow->Create();
baseWindow->SetVisibility(PR_TRUE);
}
return NS_OK; 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<nsIContent> 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<nsIURI> baseURL;
nsCOMPtr<nsIHTMLContent> htmlContent = do_QueryInterface(parentContent, &rv);
nsCOMPtr<nsIDocument> 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<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), absURL,
docCharset.IsEmpty() ? nsnull : NS_ConvertUCS2toUTF8(docCharset).get());
// Check for security
nsCOMPtr<nsIScriptSecurityManager> secMan =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
// Get base URL
nsCOMPtr<nsIURI> baseURI;
rv = aPresContext->GetBaseURL(getter_AddRefs(baseURI));
// Get docshell and create load info
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(mSubShell));
NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
docShell->CreateLoadInfo(getter_AddRefs(loadInfo));
NS_ENSURE_TRUE(loadInfo, NS_ERROR_FAILURE);
// Get referring URL
nsCOMPtr<nsIURI> referrer;
nsCOMPtr<nsIPrincipal> 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<nsICodebasePrincipal> 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<nsISupports> 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<nsIURI> 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<nsIWebProgress> 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 nsresult
nsHTMLFrameInnerFrame::CreateViewAndWidget(nsIPresContext* aPresContext, nsHTMLFrameInnerFrame::CreateViewAndWidget(nsIPresContext* aPresContext,
nsIWidget** aWidget) nsIWidget** aWidget)
@ -1060,19 +1242,18 @@ nsHTMLFrameInnerFrame::CreateViewAndWidget(nsIPresContext* aPresContext,
nsCOMPtr<nsIPresShell> presShell; nsCOMPtr<nsIPresShell> presShell;
aPresContext->GetShell(getter_AddRefs(presShell)); aPresContext->GetShell(getter_AddRefs(presShell));
NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE); if (!presShell) return NS_ERROR_FAILURE;
float t2p; float t2p;
aPresContext->GetTwipsToPixels(&t2p); aPresContext->GetTwipsToPixels(&t2p);
// create, init, set the parent of the view // create, init, set the parent of the view
nsIView* view; nsIView* view;
nsresult rv = nsComponentManager::CreateInstance(kCViewCID, nsnull, nsresult rv = nsComponentManager::CreateInstance(kCViewCID, nsnull, NS_GET_IID(nsIView),
NS_GET_IID(nsIView), (void **)&view);
(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; return rv;
} }
@ -1111,39 +1292,41 @@ nsHTMLFrameInnerFrame::Init(nsIPresContext* aPresContext,
nsIStyleContext* aContext, nsIStyleContext* aContext,
nsIFrame* aPrevInFlow) nsIFrame* aPrevInFlow)
{ {
nsresult rv = nsLeafFrame::Init(aPresContext, aContent, aParent, aContext, nsresult rv = nsLeafFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
aPrevInFlow);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return rv; return rv;
// determine if we are a printcontext // determine if we are a printcontext
PRBool shouldCreateDoc = PR_TRUE; PRBool shouldCreateDoc = PR_TRUE;
nsCOMPtr<nsIPrintContext> thePrinterContext(do_QueryInterface(aPresContext)); nsCOMPtr<nsIPrintContext> thePrinterContext = do_QueryInterface(aPresContext);
if (thePrinterContext) {
if (thePrinterContext) {
// we are printing // we are printing
shouldCreateDoc = PR_FALSE; 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. // we do not want to load the document, it is alerady loaded.
nsCOMPtr<nsIPrintPreviewContext> thePrintPreviewContext = nsCOMPtr<nsIPrintPreviewContext> thePrintPreviewContext = do_QueryInterface(aPresContext);
do_QueryInterface(aPresContext); if (thePrintPreviewContext) {
if (thePrintPreviewContext) {
nsCOMPtr<nsIWidget> widget; nsCOMPtr<nsIWidget> widget;
rv = CreateViewAndWidget(aPresContext, getter_AddRefs(widget)); rv = CreateViewAndWidget(aPresContext, getter_AddRefs(widget));
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; return rv;
} }
// we are in PrintPreview // we are in PrintPreview
shouldCreateDoc = PR_FALSE; shouldCreateDoc = PR_FALSE;
} }
if (shouldCreateDoc) { if (!mCreatingViewer && shouldCreateDoc) {
ShowDocShell(aPresContext); // 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);
}
} }
return NS_OK; return NS_OK;
@ -1164,34 +1347,28 @@ nsHTMLFrameInnerFrame::Reflow(nsIPresContext* aPresContext,
nsresult rv = NS_OK; nsresult rv = NS_OK;
// use the max size set in aReflowState by the nsHTMLFrameOuterFrame // use the max size set in aReflowState by the nsHTMLFrameOuterFrame as our size
// as our size
GetDesiredSize(aPresContext, aReflowState, aDesiredSize); GetDesiredSize(aPresContext, aReflowState, aDesiredSize);
aStatus = NS_FRAME_COMPLETE; aStatus = NS_FRAME_COMPLETE;
nsCOMPtr<nsIDocShell> docShell;
GetDocShell(getter_AddRefs(docShell));
nsCOMPtr<nsIBaseWindow> baseWindow(do_QueryInterface(docShell));
// resize the sub document // resize the sub document
if (baseWindow) { if(mSubShell) {
float t2p; float t2p;
aPresContext->GetTwipsToPixels(&t2p); aPresContext->GetTwipsToPixels(&t2p);
PRInt32 x = 0; PRInt32 x = 0;
PRInt32 y = 0; PRInt32 y = 0;
baseWindow->GetPositionAndSize(&x, &y, nsnull, nsnull); mSubShell->GetPositionAndSize(&x, &y, nsnull, nsnull);
PRInt32 cx = NSToCoordRound(aDesiredSize.width * t2p); PRInt32 cx = NSToCoordRound(aDesiredSize.width * t2p);
PRInt32 cy = NSToCoordRound(aDesiredSize.height * t2p); PRInt32 cy = NSToCoordRound(aDesiredSize.height * t2p);
baseWindow->SetPositionAndSize(x, y, cx, cy, PR_FALSE); mSubShell->SetPositionAndSize(x, y, cx, cy, PR_FALSE);
NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS, NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
("exit nsHTMLFrameInnerFrame::Reflow: size=%d,%d rv=%x", ("exit nsHTMLFrameInnerFrame::Reflow: size=%d,%d rv=%x",
aDesiredSize.width, aDesiredSize.height, aStatus)); aDesiredSize.width, aDesiredSize.height, aStatus));
} }
return rv; return rv;
@ -1199,19 +1376,11 @@ nsHTMLFrameInnerFrame::Reflow(nsIPresContext* aPresContext,
// load a new url // load a new url
nsresult nsresult
nsHTMLFrameInnerFrame::ReloadURL() nsHTMLFrameInnerFrame::ReloadURL(nsIPresContext* aPresContext)
{ {
if (!mOwnsFrameLoader || !mFrameLoader) { return DoLoadURL(aPresContext);
// 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, nsHTMLFrameInnerFrame::GetDesiredSize(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState, const nsHTMLReflowState& aReflowState,
@ -1222,28 +1391,19 @@ nsHTMLFrameInnerFrame::GetDesiredSize(nsIPresContext* aPresContext,
aDesiredSize.ascent = aDesiredSize.height; aDesiredSize.ascent = aDesiredSize.height;
aDesiredSize.descent = 0; aDesiredSize.descent = 0;
// For unknown reasons, the maxElementSize for the InnerFrame is // For unknown reasons, the maxElementSize for the InnerFrame is used, but the
// used, but the maxElementSize for the OuterFrame is ignored, make // maxElementSize for the OuterFrame is ignored, make sure to get it right here!
// sure to get it right here!
if (aDesiredSize.maxElementSize) { if (aDesiredSize.maxElementSize) {
if ((NS_UNCONSTRAINEDSIZE == aReflowState.availableWidth) || if ((NS_UNCONSTRAINEDSIZE == aReflowState.availableWidth) ||
(eStyleUnit_Percent == (eStyleUnit_Percent == aReflowState.mStylePosition->mWidth.GetUnit())) {
aReflowState.mStylePosition->mWidth.GetUnit())) { aDesiredSize.maxElementSize->width = 0; // percent width springy down to 0 px
// percent width springy down to 0 px
aDesiredSize.maxElementSize->width = 0;
} }
else { else {
aDesiredSize.maxElementSize->width = aDesiredSize.width; aDesiredSize.maxElementSize->width = aDesiredSize.width;
} }
if ((NS_UNCONSTRAINEDSIZE == aReflowState.availableHeight) || if ((NS_UNCONSTRAINEDSIZE == aReflowState.availableHeight) ||
(eStyleUnit_Percent == (eStyleUnit_Percent == aReflowState.mStylePosition->mHeight.GetUnit())) {
aReflowState.mStylePosition->mHeight.GetUnit())) { aDesiredSize.maxElementSize->height = 0; // percent height springy down to 0px
// percent height springy down to 0px
aDesiredSize.maxElementSize->height = 0;
} }
else { else {
aDesiredSize.maxElementSize->height = aDesiredSize.height; aDesiredSize.maxElementSize->height = aDesiredSize.height;
@ -1251,9 +1411,9 @@ nsHTMLFrameInnerFrame::GetDesiredSize(nsIPresContext* aPresContext,
} }
} }
/****************************************************************************** /*******************************************************************************
* FrameLoadingInfo * FrameLoadingInfo
*****************************************************************************/ ******************************************************************************/
FrameLoadingInfo::FrameLoadingInfo(const nsSize& aSize) FrameLoadingInfo::FrameLoadingInfo(const nsSize& aSize)
{ {
NS_INIT_REFCNT(); NS_INIT_REFCNT();

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

@ -63,6 +63,7 @@
#define ALL_VIS 0x000F #define ALL_VIS 0x000F
#define NONE_VIS 0x0000 #define NONE_VIS 0x0000
static NS_DEFINE_IID(kIFramesetFrameIID, NS_IFRAMESETFRAME_IID);
static NS_DEFINE_IID(kLookAndFeelCID, NS_LOOKANDFEEL_CID); static NS_DEFINE_IID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
/******************************************************************************* /*******************************************************************************
@ -251,7 +252,7 @@ nsresult nsHTMLFramesetFrame::QueryInterface(const nsIID& aIID,
{ {
if (NULL == aInstancePtr) { if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER; return NS_ERROR_NULL_POINTER;
} else if (aIID.Equals(NS_GET_IID(nsHTMLFramesetFrame))) { } else if (aIID.Equals(kIFramesetFrameIID)) {
*aInstancePtr = (void*)this; *aInstancePtr = (void*)this;
return NS_OK; return NS_OK;
} else if (aIID.Equals(NS_GET_IID(nsIObserver))) { } else if (aIID.Equals(NS_GET_IID(nsIObserver))) {
@ -326,8 +327,7 @@ nsHTMLFramesetFrame::Init(nsIPresContext* aPresContext,
mTopLevelFrameset = (nsHTMLFramesetFrame*)this; mTopLevelFrameset = (nsHTMLFramesetFrame*)this;
while (parentFrame) { while (parentFrame) {
nsHTMLFramesetFrame* frameset; nsHTMLFramesetFrame* frameset;
rv = parentFrame->QueryInterface(NS_GET_IID(nsHTMLFramesetFrame), rv = parentFrame->QueryInterface(kIFramesetFrameIID, (void**)&frameset);
(void**)&frameset);
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
mTopLevelFrameset = frameset; mTopLevelFrameset = frameset;
parentFrame->GetParent((nsIFrame**)&parentFrame); parentFrame->GetParent((nsIFrame**)&parentFrame);
@ -1404,7 +1404,7 @@ PRBool
nsHTMLFramesetFrame::ChildIsFrameset(nsIFrame* aChild) nsHTMLFramesetFrame::ChildIsFrameset(nsIFrame* aChild)
{ {
nsIFrame* childFrame = nsnull; nsIFrame* childFrame = nsnull;
aChild->QueryInterface(NS_GET_IID(nsHTMLFramesetFrame), (void**)&childFrame); aChild->QueryInterface(kIFramesetFrameIID, (void**)&childFrame);
if (childFrame) { if (childFrame) {
return PR_TRUE; return PR_TRUE;
} }

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

@ -57,8 +57,7 @@ struct nsGUIEvent;
class nsHTMLFramesetFrame; class nsHTMLFramesetFrame;
#define NS_IFRAMESETFRAME_IID \ #define NS_IFRAMESETFRAME_IID \
{ 0xf47deac0, 0x4200, 0x11d2, \ { 0xf47deac0, 0x4200, 0x11d2, { 0x80, 0x3c, 0x0, 0x60, 0x8, 0x15, 0xa7, 0x91 } }
{ 0x80, 0x3c, 0x0, 0x60, 0x8, 0x15, 0xa7, 0x91 } }
#define NO_COLOR 0xFFFFFFFA #define NO_COLOR 0xFFFFFFFA
@ -116,10 +115,8 @@ struct nsFramesetDrag {
class nsHTMLFramesetFrame : public nsHTMLContainerFrame, class nsHTMLFramesetFrame : public nsHTMLContainerFrame,
public nsIObserver public nsIObserver
{ {
public:
// Woohoo, concrete class with an IID!
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IFRAMESETFRAME_IID)
public:
nsHTMLFramesetFrame(); nsHTMLFramesetFrame();
virtual ~nsHTMLFramesetFrame(); virtual ~nsHTMLFramesetFrame();

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

@ -166,6 +166,9 @@
#include "nsIContentViewer.h" #include "nsIContentViewer.h"
#include "nsIDocumentViewer.h" #include "nsIDocumentViewer.h"
// SubShell map
#include "pldhash.h"
#ifdef IBMBIDI #ifdef IBMBIDI
#include "nsIBidiKeyboard.h" #include "nsIBidiKeyboard.h"
#endif // IBMBIDI #endif // IBMBIDI
@ -806,6 +809,14 @@ 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, class PresShell : public nsIPresShell, public nsIViewObserver,
private nsIDocumentObserver, public nsIFocusTracker, private nsIDocumentObserver, public nsIFocusTracker,
public nsISelectionController, public nsISelectionController,
@ -866,6 +877,12 @@ public:
nsIStyleContext** aStyleContext) const; nsIStyleContext** aStyleContext) const;
NS_IMETHOD GetLayoutObjectFor(nsIContent* aContent, NS_IMETHOD GetLayoutObjectFor(nsIContent* aContent,
nsISupports** aResult) const; 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, NS_IMETHOD GetPlaceholderFrameFor(nsIFrame* aFrame,
nsIFrame** aPlaceholderFrame) const; nsIFrame** aPlaceholderFrame) const;
NS_IMETHOD AppendReflowCommand(nsHTMLReflowCommand* aReflowCommand); NS_IMETHOD AppendReflowCommand(nsHTMLReflowCommand* aReflowCommand);
@ -1218,6 +1235,9 @@ protected:
static void sPaintSuppressionCallback(nsITimer* aTimer, void* aPresShell); // A callback for the timer. 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(mReflowWatch) // Used for measuring time spent in reflow
MOZ_TIMER_DECLARE(mFrameCreationWatch) // Used for measuring time spent in frame creation MOZ_TIMER_DECLARE(mFrameCreationWatch) // Used for measuring time spent in frame creation
@ -1655,6 +1675,13 @@ PresShell::Destroy()
// Clobber weak leaks in case of re-entrancy during tear down // Clobber weak leaks in case of re-entrancy during tear down
mHistoryState = nsnull; 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 // release current event content and any content on event stack
NS_IF_RELEASE(mCurrentEventContent); NS_IF_RELEASE(mCurrentEventContent);
@ -5502,6 +5529,94 @@ PresShell::GetLayoutObjectFor(nsIContent* aContent,
return result; 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 NS_IMETHODIMP
PresShell::GetPlaceholderFrameFor(nsIFrame* aFrame, PresShell::GetPlaceholderFrameFor(nsIFrame* aFrame,
nsIFrame** aResult) const nsIFrame** aResult) const

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

@ -72,7 +72,6 @@
#include "nsFrameSetFrame.h" #include "nsFrameSetFrame.h"
#include "nsIDOMHTMLFrameElement.h" #include "nsIDOMHTMLFrameElement.h"
#include "nsIDOMHTMLIFrameElement.h" #include "nsIDOMHTMLIFrameElement.h"
#include "nsIFrameLoader.h"
#include "nsLayoutAtoms.h" #include "nsLayoutAtoms.h"
#include "nsIChromeEventHandler.h" #include "nsIChromeEventHandler.h"
#include "nsIScriptSecurityManager.h" #include "nsIScriptSecurityManager.h"
@ -89,7 +88,6 @@
#include "nsIDOMEventTarget.h" #include "nsIDOMEventTarget.h"
#include "nsIDOMEventListener.h" #include "nsIDOMEventListener.h"
#include "nsIDOMWindow.h" #include "nsIDOMWindow.h"
#include "nsIDOMDocument.h"
#include "nsIRenderingContext.h" #include "nsIRenderingContext.h"
// For Accessibility // For Accessibility
@ -100,12 +98,19 @@
class nsHTMLFrame; 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(kCViewCID, NS_VIEW_CID);
static NS_DEFINE_CID(kCChildCID, NS_CHILD_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.
#define MAX_DEPTH_CONTENT_FRAMES 25
/*******************************************************************************
* FrameLoadingInfo * FrameLoadingInfo
*****************************************************************************/ ******************************************************************************/
class FrameLoadingInfo : public nsISupports class FrameLoadingInfo : public nsISupports
{ {
public: public:
@ -122,9 +127,9 @@ public:
}; };
/****************************************************************************** /*******************************************************************************
* nsHTMLFrameOuterFrame * nsHTMLFrameOuterFrame
*****************************************************************************/ ******************************************************************************/
#define nsHTMLFrameOuterFrameSuper nsHTMLContainerFrame #define nsHTMLFrameOuterFrameSuper nsHTMLContainerFrame
class nsHTMLFrameOuterFrame : public nsHTMLFrameOuterFrameSuper { class nsHTMLFrameOuterFrame : public nsHTMLFrameOuterFrameSuper {
@ -182,10 +187,11 @@ protected:
nsCOMPtr<nsIPresContext> mPresContext; nsCOMPtr<nsIPresContext> mPresContext;
}; };
/****************************************************************************** /*******************************************************************************
* nsHTMLFrameInnerFrame * nsHTMLFrameInnerFrame
*****************************************************************************/ ******************************************************************************/
class nsHTMLFrameInnerFrame : public nsLeafFrame, class nsHTMLFrameInnerFrame : public nsLeafFrame,
public nsIWebProgressListener,
public nsSupportsWeakReference public nsSupportsWeakReference
{ {
public: public:
@ -195,6 +201,8 @@ public:
NS_IMETHOD_(nsrefcnt) AddRef(void) { return 2; } NS_IMETHOD_(nsrefcnt) AddRef(void) { return 2; }
NS_IMETHOD_(nsrefcnt) Release(void) { return 1; } NS_IMETHOD_(nsrefcnt) Release(void) { return 1; }
NS_DECL_NSIWEBPROGRESSLISTENER
#ifdef DEBUG #ifdef DEBUG
NS_IMETHOD GetFrameName(nsAString& aResult) const; NS_IMETHOD GetFrameName(nsAString& aResult) const;
#endif #endif
@ -228,9 +236,7 @@ public:
nsIStyleContext* aContext, nsIStyleContext* aContext,
nsIFrame* aPrevInFlow); nsIFrame* aPrevInFlow);
void GetParentContent(nsIContent** aContent); NS_IMETHOD GetParentContent(nsIContent*& aContent);
nsresult GetDocShell(nsIDocShell **aDocShell);
PRBool GetURL(nsIContent* aContent, nsString& aResult); PRBool GetURL(nsIContent* aContent, nsString& aResult);
PRBool GetName(nsIContent* aContent, nsString& aResult); PRBool GetName(nsIContent* aContent, nsString& aResult);
PRInt32 GetScrolling(nsIContent* aContent); PRInt32 GetScrolling(nsIContent* aContent);
@ -238,10 +244,13 @@ public:
PRInt32 GetMarginWidth(nsIPresContext* aPresContext, nsIContent* aContent); PRInt32 GetMarginWidth(nsIPresContext* aPresContext, nsIContent* aContent);
PRInt32 GetMarginHeight(nsIPresContext* aPresContext, nsIContent* aContent); PRInt32 GetMarginHeight(nsIPresContext* aPresContext, nsIContent* aContent);
nsresult ReloadURL(nsIPresContext* aPresContext);
friend class nsHTMLFrameOuterFrame; friend class nsHTMLFrameOuterFrame;
protected: protected:
nsresult ShowDocShell(nsIPresContext* aPresContext); nsresult CreateDocShell(nsIPresContext* aPresContext);
nsresult DoLoadURL(nsIPresContext* aPresContext);
nsresult CreateViewAndWidget(nsIPresContext* aPresContext, nsresult CreateViewAndWidget(nsIPresContext* aPresContext,
nsIWidget** aWidget); nsIWidget** aWidget);
@ -251,18 +260,15 @@ protected:
const nsHTMLReflowState& aReflowState, const nsHTMLReflowState& aReflowState,
nsHTMLReflowMetrics& aDesiredSize); nsHTMLReflowMetrics& aDesiredSize);
nsresult ReloadURL(); nsCOMPtr<nsIBaseWindow> mSubShell;
nsWeakPtr mPresShellWeak; // weak reference to the nsIPresShell
nsCOMPtr<nsIFrameLoader> mFrameLoader; PRBool mCreatingViewer;
PRPackedBool mOwnsFrameLoader;
PRPackedBool mCreatingViewer;
}; };
/****************************************************************************** /*******************************************************************************
* nsHTMLFrameOuterFrame * nsHTMLFrameOuterFrame
*****************************************************************************/ ******************************************************************************/
nsHTMLFrameOuterFrame::nsHTMLFrameOuterFrame() nsHTMLFrameOuterFrame::nsHTMLFrameOuterFrame()
: nsHTMLContainerFrame() : nsHTMLContainerFrame()
{ {
@ -550,34 +556,31 @@ nsHTMLFrameOuterFrame::AttributeChanged(nsIPresContext* aPresContext,
nsCOMPtr<nsIAtom> type; nsCOMPtr<nsIAtom> type;
aChild->GetTag(*getter_AddRefs(type)); aChild->GetTag(*getter_AddRefs(type));
if ((type != nsHTMLAtoms::object && aAttribute == nsHTMLAtoms::src) || if (((nsHTMLAtoms::src == aAttribute) && (nsHTMLAtoms::object != type)) ||
(type == nsHTMLAtoms::object && aAttribute == nsHTMLAtoms::data)) { ((nsHTMLAtoms::data == aAttribute) && (nsHTMLAtoms::object == type))) {
nsHTMLFrameInnerFrame* firstChild = nsHTMLFrameInnerFrame* firstChild = NS_STATIC_CAST(nsHTMLFrameInnerFrame*,
NS_STATIC_CAST(nsHTMLFrameInnerFrame*, mFrames.FirstChild()); mFrames.FirstChild());
if (firstChild) { if (firstChild) {
firstChild->ReloadURL(); firstChild->ReloadURL(aPresContext);
} }
} }
// If the noResize attribute changes, dis/allow frame to be resized // If the noResize attribute changes, dis/allow frame to be resized
else if (aAttribute == nsHTMLAtoms::noresize) { else if (nsHTMLAtoms::noresize == aAttribute) {
nsCOMPtr<nsIContent> parentContent; nsCOMPtr<nsIContent> parentContent;
mContent->GetParent(*getter_AddRefs(parentContent)); mContent->GetParent(*getter_AddRefs(parentContent));
nsCOMPtr<nsIAtom> parentTag; nsCOMPtr<nsIAtom> parentTag;
parentContent->GetTag(*getter_AddRefs(parentTag)); parentContent->GetTag(*getter_AddRefs(parentTag));
if (parentTag == nsHTMLAtoms::frameset) { if (nsHTMLAtoms::frameset == parentTag) {
nsIFrame* parentFrame = nsnull; nsIFrame* parentFrame = nsnull;
GetParent(&parentFrame); GetParent(&parentFrame);
if (parentFrame) { if (parentFrame) {
// There is no interface for nsHTMLFramesetFrame so QI'ing to // There is no interface for kIFramesetFrameIID
// concrete class, yay! // so QI'ing to concrete class, yay!
nsHTMLFramesetFrame* framesetFrame = nsnull; nsHTMLFramesetFrame* framesetFrame = nsnull;
parentFrame->QueryInterface(NS_GET_IID(nsHTMLFramesetFrame), parentFrame->QueryInterface(kIFramesetFrameIID, (void **)&framesetFrame);
(void **)&framesetFrame);
if (framesetFrame) { if (framesetFrame) {
framesetFrame->RecalculateBorderResize(); framesetFrame->RecalculateBorderResize();
} }
@ -586,8 +589,8 @@ nsHTMLFrameOuterFrame::AttributeChanged(nsIPresContext* aPresContext,
} }
else if (aAttribute == nsHTMLAtoms::type) { else if (aAttribute == nsHTMLAtoms::type) {
nsHTMLFrameInnerFrame* firstChild = NS_STATIC_CAST(nsHTMLFrameInnerFrame*, nsHTMLFrameInnerFrame* firstChild = NS_STATIC_CAST(nsHTMLFrameInnerFrame*,
mFrames.FirstChild()); mFrames.FirstChild());
if (!firstChild || !firstChild->mFrameLoader) if (!firstChild)
return NS_OK; return NS_OK;
nsAutoString value; nsAutoString value;
@ -595,36 +598,28 @@ nsHTMLFrameOuterFrame::AttributeChanged(nsIPresContext* aPresContext,
// Notify our enclosing chrome that the primary content shell // Notify our enclosing chrome that the primary content shell
// has changed. // has changed.
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(firstChild->mSubShell));
nsCOMPtr<nsIDocShell> docShell; nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(firstChild->mSubShell));
firstChild->mFrameLoader->GetDocShell(getter_AddRefs(docShell));
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(docShell));
// If our container is a web-shell, inform it that it has a new // 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 // child. If it's not a web-shell then some things will not operate
// properly. // properly.
nsCOMPtr<nsISupports> container; nsCOMPtr<nsISupports> container;
aPresContext->GetContainer(getter_AddRefs(container)); aPresContext->GetContainer(getter_AddRefs(container));
if (container) {
nsCOMPtr<nsIDocShellTreeNode> parentAsNode(do_QueryInterface(container));
if (parentAsNode) {
nsCOMPtr<nsIDocShellTreeItem> parentAsItem(do_QueryInterface(parentAsNode));
nsCOMPtr<nsIDocShellTreeNode> parentAsNode(do_QueryInterface(container)); nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner;
parentAsItem->GetTreeOwner(getter_AddRefs(parentTreeOwner));
if (parentAsNode) { if (parentTreeOwner)
nsCOMPtr<nsIDocShellTreeItem> parentAsItem = parentTreeOwner->ContentShellAdded(docShellAsItem,
do_QueryInterface(parentAsNode); value.EqualsIgnoreCase("content-primary") ? PR_TRUE : PR_FALSE,
value.get());
nsCOMPtr<nsIDocShellTreeOwner> 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; return NS_OK;
} }
@ -643,42 +638,41 @@ NS_NewHTMLFrameOuterFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
return NS_OK; return NS_OK;
} }
/****************************************************************************** /*******************************************************************************
* nsHTMLFrameInnerFrame * nsHTMLFrameInnerFrame
*****************************************************************************/ ******************************************************************************/
nsHTMLFrameInnerFrame::nsHTMLFrameInnerFrame() nsHTMLFrameInnerFrame::nsHTMLFrameInnerFrame()
: nsLeafFrame(), mOwnsFrameLoader(PR_FALSE), mCreatingViewer(PR_FALSE) : nsLeafFrame()
{ {
mCreatingViewer = PR_FALSE;
mPresShellWeak = nsnull;
} }
nsHTMLFrameInnerFrame::~nsHTMLFrameInnerFrame() nsHTMLFrameInnerFrame::~nsHTMLFrameInnerFrame()
{ {
//printf("nsHTMLFrameInnerFrame destructor %X \n", this); //printf("nsHTMLFrameInnerFrame destructor %X \n", this);
if (mFrameLoader) { nsCOMPtr<nsIDOMWindow> win(do_GetInterface(mSubShell));
// Get the content viewer through the docshell, but don't call nsCOMPtr<nsIDOMEventTarget> eventTarget(do_QueryInterface(win));
// GetDocShell() since we don't want to create one if we don't nsCOMPtr<nsIDOMEventListener> eventListener(do_QueryInterface(mContent));
// have one.
nsCOMPtr<nsIDocShell> docShell; if (eventTarget && eventListener) {
mFrameLoader->GetDocShell(getter_AddRefs(docShell)); eventTarget->RemoveEventListener(NS_LITERAL_STRING("load"), eventListener,
PR_FALSE);
}
nsCOMPtr<nsIContentViewer> content_viewer; if(mSubShell) {
docShell->GetContentViewer(getter_AddRefs(content_viewer)); // notify the pres shell that a docshell has been destroyed
if (mPresShellWeak) {
if (content_viewer) { nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
// Hide the content viewer now that the frame is going away... if (ps) {
ps->SetSubShellFor(mContent, nsnull);
content_viewer->Hide(); }
} }
mSubShell->Destroy();
} }
mSubShell = nsnull; // This is the location it was released before...
if (mFrameLoader && mOwnsFrameLoader) { // Not sure if there is ordering depending on this.
// We own this frame loader, and we're going away, so destroy our
// frame loader.
mFrameLoader->Destroy();
}
} }
PRBool nsHTMLFrameInnerFrame::GetURL(nsIContent* aContent, nsString& aResult) PRBool nsHTMLFrameInnerFrame::GetURL(nsIContent* aContent, nsString& aResult)
@ -814,6 +808,12 @@ nsHTMLFrameInnerFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{ {
NS_ENSURE_ARG_POINTER(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))) { if (aIID.Equals(NS_GET_IID(nsISupportsWeakReference))) {
nsISupports *tmp = NS_STATIC_CAST(nsISupportsWeakReference *, this); nsISupports *tmp = NS_STATIC_CAST(nsISupportsWeakReference *, this);
*aInstancePtr = tmp; *aInstancePtr = tmp;
@ -823,6 +823,60 @@ nsHTMLFrameInnerFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr)
return nsLeafFrame::QueryInterface(aIID, 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<nsIDOMWindow> win(do_GetInterface(mSubShell));
nsCOMPtr<nsIDOMEventTarget> eventTarget(do_QueryInterface(win));
nsCOMPtr<nsIDOMEventListener> 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 #ifdef DEBUG
NS_IMETHODIMP nsHTMLFrameInnerFrame::GetFrameName(nsAString& aResult) const NS_IMETHODIMP nsHTMLFrameInnerFrame::GetFrameName(nsAString& aResult) const
{ {
@ -846,90 +900,33 @@ nsHTMLFrameInnerFrame::Paint(nsIPresContext* aPresContext,
nsFramePaintLayer aWhichLayer, nsFramePaintLayer aWhichLayer,
PRUint32 aFlags) PRUint32 aFlags)
{ {
//printf("inner paint %X (%d,%d,%d,%d) \n", this, aDirtyRect.x, //printf("inner paint %X (%d,%d,%d,%d) \n", this, aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height);
//aDirtyRect.y, aDirtyRect.width, aDirtyRect.height); if there is // if there is not web shell paint based on our background color,
//not web shell paint based on our background color, otherwise let // otherwise let the web shell paint the sub document
//the web shell paint the sub document
// isPaginated is a temporary fix for Bug 75737 and this should all // isPaginated is a temporary fix for Bug 75737
// be fixed correctly by Bug 75739 // and this should all be fixed correctly by Bug 75739
PRBool isPaginated; PRBool isPaginated;
aPresContext->IsPaginated(&isPaginated); aPresContext->IsPaginated(&isPaginated);
if (!mSubShell && !isPaginated) {
if (!isPaginated) { const nsStyleBackground* color =
nsCOMPtr<nsIDocShell> docShell; (const nsStyleBackground*)mStyleContext->GetStyleData(eStyleStruct_Background);
GetDocShell(getter_AddRefs(docShell)); aRenderingContext.SetColor(color->mBackgroundColor);
aRenderingContext.FillRect(mRect);
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); DO_GLOBAL_REFLOW_COUNT_DSP("nsHTMLFrameInnerFrame", &aRenderingContext);
return NS_OK; return NS_OK;
} }
void NS_IMETHODIMP
nsHTMLFrameInnerFrame::GetParentContent(nsIContent** aContent) nsHTMLFrameInnerFrame::GetParentContent(nsIContent*& aContent)
{ {
*aContent = nsnull; nsHTMLFrameOuterFrame* parent;
nsresult rv = GetParent((nsIFrame**)&parent);
nsIFrame* parent = nsnull; if (NS_SUCCEEDED(rv) && parent) {
GetParent(&parent); rv = parent->GetContent(&aContent);
if (parent) {
parent->GetContent(aContent);
} }
} return rv;
nsresult
nsHTMLFrameInnerFrame::GetDocShell(nsIDocShell **aDocShell)
{
*aDocShell = nsnull;
nsCOMPtr<nsIContent> 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<nsIFrameLoaderOwner> 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 NS_IMETHODIMP
@ -955,7 +952,7 @@ nsHTMLFrameInnerFrame::DidReflow(nsIPresContext* aPresContext,
if (newVis != oldVis) { if (newVis != oldVis) {
nsCOMPtr<nsIViewManager> vm; nsCOMPtr<nsIViewManager> vm;
view->GetViewManager(*getter_AddRefs(vm)); view->GetViewManager(*getter_AddRefs(vm));
if (vm) { if (vm != nsnull) {
vm->SetViewVisibility(view, newVis); vm->SetViewVisibility(view, newVis);
} }
} }
@ -966,91 +963,276 @@ nsHTMLFrameInnerFrame::DidReflow(nsIPresContext* aPresContext,
} }
nsresult nsresult
nsHTMLFrameInnerFrame::ShowDocShell(nsIPresContext* aPresContext) nsHTMLFrameInnerFrame::CreateDocShell(nsIPresContext* aPresContext)
{ {
nsCOMPtr<nsIDocShell> docShell; nsresult rv;
nsresult rv = GetDocShell(getter_AddRefs(docShell)); nsCOMPtr<nsIContent> parentContent;
NS_ENSURE_SUCCESS(rv, rv); GetParentContent(*getter_AddRefs(parentContent));
// Make sure there's a document in the docshell. // Bug 8065: Don't exceed some maximum depth in content frames (MAX_DEPTH_CONTENT_FRAMES)
nsCOMPtr<nsIDOMWindow> win(do_GetInterface(docShell)); PRInt32 depth = 0;
NS_ENSURE_TRUE(win, NS_ERROR_UNEXPECTED); nsCOMPtr<nsISupports> parentAsSupports;
aPresContext->GetContainer(getter_AddRefs(parentAsSupports));
if (parentAsSupports) {
nsCOMPtr<nsIDocShellTreeItem> parentAsItem(do_QueryInterface(parentAsSupports));
while (parentAsItem) {
depth++;
if (MAX_DEPTH_CONTENT_FRAMES < depth)
return NS_ERROR_UNEXPECTED; // Too deep, give up! (silently?)
{ // Only count depth on content, not chrome.
nsCOMPtr<nsIDOMDocument> dom_doc; // If we wanted to limit total depth, skip the following check:
PRInt32 parentType;
// This will synchronously create a document if there is no parentAsItem->GetItemType(&parentType);
// document in the window yet. if (nsIDocShellTreeItem::typeContent == parentType) {
nsIDocShellTreeItem* temp = parentAsItem;
win->GetDocument(getter_AddRefs(dom_doc)); temp->GetParent(getter_AddRefs(parentAsItem));
} else {
break; // we have exited content, stop counting, depth is OK!
}
}
} }
mSubShell = do_CreateInstance(kWebShellCID);
NS_ENSURE_TRUE(mSubShell, NS_ERROR_FAILURE);
// notify the pres shell that a docshell has been created
nsCOMPtr<nsIPresShell> presShell; nsCOMPtr<nsIPresShell> presShell;
docShell->GetPresShell(getter_AddRefs(presShell)); aPresContext->GetShell(getter_AddRefs(presShell));
if (presShell)
if (presShell) { {
// The docshell is already showing, nothing left to do... nsCOMPtr<nsISupports> subShellAsSupports(do_QueryInterface(mSubShell));
NS_ENSURE_TRUE(subShellAsSupports, NS_ERROR_FAILURE);
return NS_OK; 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));
} }
nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem(do_QueryInterface(docShell)); nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(mSubShell));
NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
nsCOMPtr<nsIDocShellTreeItem> parentDocShellTreeItem; // pass along marginwidth, marginheight, scrolling so sub document can use it
docShellTreeItem->GetParent(getter_AddRefs(parentDocShellTreeItem)); docShell->SetMarginWidth(GetMarginWidth(aPresContext, parentContent));
docShell->SetMarginHeight(GetMarginHeight(aPresContext, parentContent));
nsCOMPtr<nsIDocShell> parentDocShell =
do_QueryInterface(parentDocShellTreeItem);
nsCOMPtr<nsIPresShell> parentPresShell;
parentDocShell->GetPresShell(getter_AddRefs(parentPresShell));
nsCOMPtr<nsIContent> 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 // Current and initial scrolling is set so that all succeeding docs
// will use the scrolling value set here, regardless if scrolling is // will use the scrolling value set here, regardless if scrolling is
// set by viewing a particular document (e.g. XUL turns off scrolling) // set by viewing a particular document (e.g. XUL turns off scrolling)
nsCOMPtr<nsIScrollable> scrollableContainer(do_QueryInterface(docShell)); nsCOMPtr<nsIScrollable> scrollableContainer(do_QueryInterface(mSubShell));
if (scrollableContainer) { if (scrollableContainer) {
scrollableContainer->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_Y, scrollableContainer->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_Y,
GetScrolling(content)); GetScrolling(parentContent));
scrollableContainer->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X, scrollableContainer->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X,
GetScrolling(content)); GetScrolling(parentContent));
} }
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(docShell)); nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mSubShell));
NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE); 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<nsISupports> container;
aPresContext->GetContainer(getter_AddRefs(container));
if (container) {
nsCOMPtr<nsIDocShellTreeNode> parentAsNode(do_QueryInterface(container));
if (parentAsNode) {
nsCOMPtr<nsIDocShellTreeItem> 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<nsIDocShellTreeOwner> 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<nsIWebShell> webShell(do_QueryInterface(mSubShell));
nsCOMPtr<nsIWebShellContainer> 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<nsIDocShell> parentShell(do_QueryInterface(parentAsNode));
nsCOMPtr<nsIChromeEventHandler> 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<nsIWidget> widget; nsCOMPtr<nsIWidget> widget;
rv = CreateViewAndWidget(aPresContext, getter_AddRefs(widget)); rv = CreateViewAndWidget(aPresContext, getter_AddRefs(widget));
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; return rv;
} }
nsCOMPtr<nsIBaseWindow> baseWindow(do_QueryInterface(docShell)); mSubShell->InitWindow(nsnull, widget, 0, 0, 10, 10);
mSubShell->Create();
if (baseWindow) { mSubShell->SetVisibility(PR_TRUE);
baseWindow->InitWindow(nsnull, widget, 0, 0, 10, 10);
// This is kinda whacky, this "Create()" calldoesn't really create
// anything, one starts to wonder why this was named "Create"...
baseWindow->Create();
baseWindow->SetVisibility(PR_TRUE);
}
return NS_OK; 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<nsIContent> 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<nsIURI> baseURL;
nsCOMPtr<nsIHTMLContent> htmlContent = do_QueryInterface(parentContent, &rv);
nsCOMPtr<nsIDocument> 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<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), absURL,
docCharset.IsEmpty() ? nsnull : NS_ConvertUCS2toUTF8(docCharset).get());
// Check for security
nsCOMPtr<nsIScriptSecurityManager> secMan =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
// Get base URL
nsCOMPtr<nsIURI> baseURI;
rv = aPresContext->GetBaseURL(getter_AddRefs(baseURI));
// Get docshell and create load info
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(mSubShell));
NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
docShell->CreateLoadInfo(getter_AddRefs(loadInfo));
NS_ENSURE_TRUE(loadInfo, NS_ERROR_FAILURE);
// Get referring URL
nsCOMPtr<nsIURI> referrer;
nsCOMPtr<nsIPrincipal> 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<nsICodebasePrincipal> 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<nsISupports> 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<nsIURI> 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<nsIWebProgress> 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 nsresult
nsHTMLFrameInnerFrame::CreateViewAndWidget(nsIPresContext* aPresContext, nsHTMLFrameInnerFrame::CreateViewAndWidget(nsIPresContext* aPresContext,
nsIWidget** aWidget) nsIWidget** aWidget)
@ -1060,19 +1242,18 @@ nsHTMLFrameInnerFrame::CreateViewAndWidget(nsIPresContext* aPresContext,
nsCOMPtr<nsIPresShell> presShell; nsCOMPtr<nsIPresShell> presShell;
aPresContext->GetShell(getter_AddRefs(presShell)); aPresContext->GetShell(getter_AddRefs(presShell));
NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE); if (!presShell) return NS_ERROR_FAILURE;
float t2p; float t2p;
aPresContext->GetTwipsToPixels(&t2p); aPresContext->GetTwipsToPixels(&t2p);
// create, init, set the parent of the view // create, init, set the parent of the view
nsIView* view; nsIView* view;
nsresult rv = nsComponentManager::CreateInstance(kCViewCID, nsnull, nsresult rv = nsComponentManager::CreateInstance(kCViewCID, nsnull, NS_GET_IID(nsIView),
NS_GET_IID(nsIView), (void **)&view);
(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; return rv;
} }
@ -1111,39 +1292,41 @@ nsHTMLFrameInnerFrame::Init(nsIPresContext* aPresContext,
nsIStyleContext* aContext, nsIStyleContext* aContext,
nsIFrame* aPrevInFlow) nsIFrame* aPrevInFlow)
{ {
nsresult rv = nsLeafFrame::Init(aPresContext, aContent, aParent, aContext, nsresult rv = nsLeafFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
aPrevInFlow);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return rv; return rv;
// determine if we are a printcontext // determine if we are a printcontext
PRBool shouldCreateDoc = PR_TRUE; PRBool shouldCreateDoc = PR_TRUE;
nsCOMPtr<nsIPrintContext> thePrinterContext(do_QueryInterface(aPresContext)); nsCOMPtr<nsIPrintContext> thePrinterContext = do_QueryInterface(aPresContext);
if (thePrinterContext) {
if (thePrinterContext) {
// we are printing // we are printing
shouldCreateDoc = PR_FALSE; 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. // we do not want to load the document, it is alerady loaded.
nsCOMPtr<nsIPrintPreviewContext> thePrintPreviewContext = nsCOMPtr<nsIPrintPreviewContext> thePrintPreviewContext = do_QueryInterface(aPresContext);
do_QueryInterface(aPresContext); if (thePrintPreviewContext) {
if (thePrintPreviewContext) {
nsCOMPtr<nsIWidget> widget; nsCOMPtr<nsIWidget> widget;
rv = CreateViewAndWidget(aPresContext, getter_AddRefs(widget)); rv = CreateViewAndWidget(aPresContext, getter_AddRefs(widget));
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; return rv;
} }
// we are in PrintPreview // we are in PrintPreview
shouldCreateDoc = PR_FALSE; shouldCreateDoc = PR_FALSE;
} }
if (shouldCreateDoc) { if (!mCreatingViewer && shouldCreateDoc) {
ShowDocShell(aPresContext); // 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);
}
} }
return NS_OK; return NS_OK;
@ -1164,34 +1347,28 @@ nsHTMLFrameInnerFrame::Reflow(nsIPresContext* aPresContext,
nsresult rv = NS_OK; nsresult rv = NS_OK;
// use the max size set in aReflowState by the nsHTMLFrameOuterFrame // use the max size set in aReflowState by the nsHTMLFrameOuterFrame as our size
// as our size
GetDesiredSize(aPresContext, aReflowState, aDesiredSize); GetDesiredSize(aPresContext, aReflowState, aDesiredSize);
aStatus = NS_FRAME_COMPLETE; aStatus = NS_FRAME_COMPLETE;
nsCOMPtr<nsIDocShell> docShell;
GetDocShell(getter_AddRefs(docShell));
nsCOMPtr<nsIBaseWindow> baseWindow(do_QueryInterface(docShell));
// resize the sub document // resize the sub document
if (baseWindow) { if(mSubShell) {
float t2p; float t2p;
aPresContext->GetTwipsToPixels(&t2p); aPresContext->GetTwipsToPixels(&t2p);
PRInt32 x = 0; PRInt32 x = 0;
PRInt32 y = 0; PRInt32 y = 0;
baseWindow->GetPositionAndSize(&x, &y, nsnull, nsnull); mSubShell->GetPositionAndSize(&x, &y, nsnull, nsnull);
PRInt32 cx = NSToCoordRound(aDesiredSize.width * t2p); PRInt32 cx = NSToCoordRound(aDesiredSize.width * t2p);
PRInt32 cy = NSToCoordRound(aDesiredSize.height * t2p); PRInt32 cy = NSToCoordRound(aDesiredSize.height * t2p);
baseWindow->SetPositionAndSize(x, y, cx, cy, PR_FALSE); mSubShell->SetPositionAndSize(x, y, cx, cy, PR_FALSE);
NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS, NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
("exit nsHTMLFrameInnerFrame::Reflow: size=%d,%d rv=%x", ("exit nsHTMLFrameInnerFrame::Reflow: size=%d,%d rv=%x",
aDesiredSize.width, aDesiredSize.height, aStatus)); aDesiredSize.width, aDesiredSize.height, aStatus));
} }
return rv; return rv;
@ -1199,19 +1376,11 @@ nsHTMLFrameInnerFrame::Reflow(nsIPresContext* aPresContext,
// load a new url // load a new url
nsresult nsresult
nsHTMLFrameInnerFrame::ReloadURL() nsHTMLFrameInnerFrame::ReloadURL(nsIPresContext* aPresContext)
{ {
if (!mOwnsFrameLoader || !mFrameLoader) { return DoLoadURL(aPresContext);
// 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, nsHTMLFrameInnerFrame::GetDesiredSize(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState, const nsHTMLReflowState& aReflowState,
@ -1222,28 +1391,19 @@ nsHTMLFrameInnerFrame::GetDesiredSize(nsIPresContext* aPresContext,
aDesiredSize.ascent = aDesiredSize.height; aDesiredSize.ascent = aDesiredSize.height;
aDesiredSize.descent = 0; aDesiredSize.descent = 0;
// For unknown reasons, the maxElementSize for the InnerFrame is // For unknown reasons, the maxElementSize for the InnerFrame is used, but the
// used, but the maxElementSize for the OuterFrame is ignored, make // maxElementSize for the OuterFrame is ignored, make sure to get it right here!
// sure to get it right here!
if (aDesiredSize.maxElementSize) { if (aDesiredSize.maxElementSize) {
if ((NS_UNCONSTRAINEDSIZE == aReflowState.availableWidth) || if ((NS_UNCONSTRAINEDSIZE == aReflowState.availableWidth) ||
(eStyleUnit_Percent == (eStyleUnit_Percent == aReflowState.mStylePosition->mWidth.GetUnit())) {
aReflowState.mStylePosition->mWidth.GetUnit())) { aDesiredSize.maxElementSize->width = 0; // percent width springy down to 0 px
// percent width springy down to 0 px
aDesiredSize.maxElementSize->width = 0;
} }
else { else {
aDesiredSize.maxElementSize->width = aDesiredSize.width; aDesiredSize.maxElementSize->width = aDesiredSize.width;
} }
if ((NS_UNCONSTRAINEDSIZE == aReflowState.availableHeight) || if ((NS_UNCONSTRAINEDSIZE == aReflowState.availableHeight) ||
(eStyleUnit_Percent == (eStyleUnit_Percent == aReflowState.mStylePosition->mHeight.GetUnit())) {
aReflowState.mStylePosition->mHeight.GetUnit())) { aDesiredSize.maxElementSize->height = 0; // percent height springy down to 0px
// percent height springy down to 0px
aDesiredSize.maxElementSize->height = 0;
} }
else { else {
aDesiredSize.maxElementSize->height = aDesiredSize.height; aDesiredSize.maxElementSize->height = aDesiredSize.height;
@ -1251,9 +1411,9 @@ nsHTMLFrameInnerFrame::GetDesiredSize(nsIPresContext* aPresContext,
} }
} }
/****************************************************************************** /*******************************************************************************
* FrameLoadingInfo * FrameLoadingInfo
*****************************************************************************/ ******************************************************************************/
FrameLoadingInfo::FrameLoadingInfo(const nsSize& aSize) FrameLoadingInfo::FrameLoadingInfo(const nsSize& aSize)
{ {
NS_INIT_REFCNT(); NS_INIT_REFCNT();

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

@ -63,6 +63,7 @@
#define ALL_VIS 0x000F #define ALL_VIS 0x000F
#define NONE_VIS 0x0000 #define NONE_VIS 0x0000
static NS_DEFINE_IID(kIFramesetFrameIID, NS_IFRAMESETFRAME_IID);
static NS_DEFINE_IID(kLookAndFeelCID, NS_LOOKANDFEEL_CID); static NS_DEFINE_IID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
/******************************************************************************* /*******************************************************************************
@ -251,7 +252,7 @@ nsresult nsHTMLFramesetFrame::QueryInterface(const nsIID& aIID,
{ {
if (NULL == aInstancePtr) { if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER; return NS_ERROR_NULL_POINTER;
} else if (aIID.Equals(NS_GET_IID(nsHTMLFramesetFrame))) { } else if (aIID.Equals(kIFramesetFrameIID)) {
*aInstancePtr = (void*)this; *aInstancePtr = (void*)this;
return NS_OK; return NS_OK;
} else if (aIID.Equals(NS_GET_IID(nsIObserver))) { } else if (aIID.Equals(NS_GET_IID(nsIObserver))) {
@ -326,8 +327,7 @@ nsHTMLFramesetFrame::Init(nsIPresContext* aPresContext,
mTopLevelFrameset = (nsHTMLFramesetFrame*)this; mTopLevelFrameset = (nsHTMLFramesetFrame*)this;
while (parentFrame) { while (parentFrame) {
nsHTMLFramesetFrame* frameset; nsHTMLFramesetFrame* frameset;
rv = parentFrame->QueryInterface(NS_GET_IID(nsHTMLFramesetFrame), rv = parentFrame->QueryInterface(kIFramesetFrameIID, (void**)&frameset);
(void**)&frameset);
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
mTopLevelFrameset = frameset; mTopLevelFrameset = frameset;
parentFrame->GetParent((nsIFrame**)&parentFrame); parentFrame->GetParent((nsIFrame**)&parentFrame);
@ -1404,7 +1404,7 @@ PRBool
nsHTMLFramesetFrame::ChildIsFrameset(nsIFrame* aChild) nsHTMLFramesetFrame::ChildIsFrameset(nsIFrame* aChild)
{ {
nsIFrame* childFrame = nsnull; nsIFrame* childFrame = nsnull;
aChild->QueryInterface(NS_GET_IID(nsHTMLFramesetFrame), (void**)&childFrame); aChild->QueryInterface(kIFramesetFrameIID, (void**)&childFrame);
if (childFrame) { if (childFrame) {
return PR_TRUE; return PR_TRUE;
} }

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

@ -57,8 +57,7 @@ struct nsGUIEvent;
class nsHTMLFramesetFrame; class nsHTMLFramesetFrame;
#define NS_IFRAMESETFRAME_IID \ #define NS_IFRAMESETFRAME_IID \
{ 0xf47deac0, 0x4200, 0x11d2, \ { 0xf47deac0, 0x4200, 0x11d2, { 0x80, 0x3c, 0x0, 0x60, 0x8, 0x15, 0xa7, 0x91 } }
{ 0x80, 0x3c, 0x0, 0x60, 0x8, 0x15, 0xa7, 0x91 } }
#define NO_COLOR 0xFFFFFFFA #define NO_COLOR 0xFFFFFFFA
@ -116,10 +115,8 @@ struct nsFramesetDrag {
class nsHTMLFramesetFrame : public nsHTMLContainerFrame, class nsHTMLFramesetFrame : public nsHTMLContainerFrame,
public nsIObserver public nsIObserver
{ {
public:
// Woohoo, concrete class with an IID!
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IFRAMESETFRAME_IID)
public:
nsHTMLFramesetFrame(); nsHTMLFramesetFrame();
virtual ~nsHTMLFramesetFrame(); virtual ~nsHTMLFramesetFrame();

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

@ -2657,7 +2657,7 @@ CSSStyleSheetImpl::SetDisabled(PRBool aDisabled)
PRBool oldState = mDisabled; PRBool oldState = mDisabled;
mDisabled = aDisabled; mDisabled = aDisabled;
if (mDocument && (mDisabled != oldState)) { if ((nsnull != mDocument) && (mDisabled != oldState)) {
mDocument->SetStyleSheetDisabledState(this, mDisabled); mDocument->SetStyleSheetDisabledState(this, mDisabled);
} }

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

@ -38,9 +38,9 @@
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsIBrowserBoxObject.h" #include "nsIBrowserBoxObject.h"
#include "nsBoxObject.h" #include "nsBoxObject.h"
#include "nsIPresShell.h"
#include "nsIFrame.h" #include "nsIFrame.h"
#include "nsIDocShell.h" #include "nsIDocShell.h"
#include "nsIDocument.h"
#include "nsXPIDLString.h" #include "nsXPIDLString.h"
class nsBrowserBoxObject : public nsIBrowserBoxObject, public nsBoxObject class nsBrowserBoxObject : public nsIBrowserBoxObject, public nsBoxObject
@ -91,27 +91,15 @@ nsBrowserBoxObject::~nsBrowserBoxObject()
NS_IMETHODIMP nsBrowserBoxObject::GetDocShell(nsIDocShell** aResult) NS_IMETHODIMP nsBrowserBoxObject::GetDocShell(nsIDocShell** aResult)
{ {
*aResult = nsnull; *aResult = nsnull;
if (!mPresShell) if (!mPresShell)
return NS_OK; return NS_OK;
nsCOMPtr<nsIDocument> doc, sub_doc; nsCOMPtr<nsISupports> subShell;
mPresShell->GetDocument(getter_AddRefs(doc)); mPresShell->GetSubShellFor(mContent, getter_AddRefs(subShell));
if(!subShell)
doc->GetSubDocumentFor(mContent, getter_AddRefs(sub_doc));
if (!sub_doc) {
return NS_OK; return NS_OK;
}
nsCOMPtr<nsISupports> container; return CallQueryInterface(subShell, aResult); //Addref happens here.
sub_doc->GetContainer(getter_AddRefs(container));
if (!container) {
return NS_OK;
}
return CallQueryInterface(container, aResult);
} }
// Creation Routine /////////////////////////////////////////////////////////////////////// // Creation Routine ///////////////////////////////////////////////////////////////////////

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

@ -38,7 +38,7 @@
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsIEditorBoxObject.h" #include "nsIEditorBoxObject.h"
#include "nsBoxObject.h" #include "nsBoxObject.h"
#include "nsIDocument.h" #include "nsIPresShell.h"
#include "nsIFrame.h" #include "nsIFrame.h"
#include "nsIEditorShell.h" #include "nsIEditorShell.h"
#include "nsIComponentManager.h" #include "nsIComponentManager.h"
@ -128,27 +128,15 @@ NS_IMETHODIMP nsEditorBoxObject::GetEditorShell(nsIEditorShell** aResult)
NS_IMETHODIMP nsEditorBoxObject::GetDocShell(nsIDocShell** aResult) NS_IMETHODIMP nsEditorBoxObject::GetDocShell(nsIDocShell** aResult)
{ {
*aResult = nsnull; *aResult = nsnull;
if (!mPresShell) if (!mPresShell)
return NS_OK; return NS_OK;
nsCOMPtr<nsIDocument> doc, sub_doc; nsCOMPtr<nsISupports> subShell;
mPresShell->GetDocument(getter_AddRefs(doc)); mPresShell->GetSubShellFor(mContent, getter_AddRefs(subShell));
if(!subShell)
doc->GetSubDocumentFor(mContent, getter_AddRefs(sub_doc));
if (!sub_doc) {
return NS_OK; return NS_OK;
}
nsCOMPtr<nsISupports> container; return CallQueryInterface(subShell, aResult); //Addref happens here.
sub_doc->GetContainer(getter_AddRefs(container));
if (!container) {
return NS_OK;
}
return CallQueryInterface(container, aResult);
} }
// Creation Routine /////////////////////////////////////////////////////////////////////// // Creation Routine ///////////////////////////////////////////////////////////////////////

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

@ -38,7 +38,6 @@
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsIIFrameBoxObject.h" #include "nsIIFrameBoxObject.h"
#include "nsBoxObject.h" #include "nsBoxObject.h"
#include "nsIDocument.h"
#include "nsIPresShell.h" #include "nsIPresShell.h"
#include "nsIFrame.h" #include "nsIFrame.h"
#include "nsIDocShell.h" #include "nsIDocShell.h"
@ -88,27 +87,15 @@ nsIFrameBoxObject::~nsIFrameBoxObject()
NS_IMETHODIMP nsIFrameBoxObject::GetDocShell(nsIDocShell** aResult) NS_IMETHODIMP nsIFrameBoxObject::GetDocShell(nsIDocShell** aResult)
{ {
*aResult = nsnull; *aResult = nsnull;
if (!mPresShell) if (!mPresShell)
return NS_OK; return NS_OK;
nsCOMPtr<nsIDocument> doc, sub_doc; nsCOMPtr<nsISupports> subShell;
mPresShell->GetDocument(getter_AddRefs(doc)); mPresShell->GetSubShellFor(mContent, getter_AddRefs(subShell));
if(!subShell)
doc->GetSubDocumentFor(mContent, getter_AddRefs(sub_doc));
if (!sub_doc) {
return NS_OK; return NS_OK;
}
nsCOMPtr<nsISupports> container; return CallQueryInterface(subShell, aResult); //Addref happens here.
sub_doc->GetContainer(getter_AddRefs(container));
if (!container) {
return NS_OK;
}
return CallQueryInterface(container, aResult);
} }
// Creation Routine /////////////////////////////////////////////////////////////////////// // Creation Routine ///////////////////////////////////////////////////////////////////////

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

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK ***** /* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
* *
@ -804,7 +804,7 @@ nsDocLoaderImpl::GetDOMWindow(nsIDOMWindow **aResult)
*aResult = window; *aResult = window;
NS_IF_ADDREF(*aResult); NS_IF_ADDREF(*aResult);
} else { } else {
rv = NS_ERROR_FAILURE; rv = NS_ERROR_FAILURE;
} }
return rv; return rv;