diff --git a/mozilla/content/base/src/nsDocument.cpp b/mozilla/content/base/src/nsDocument.cpp index 9219fd19193..9181741f8bb 100644 --- a/mozilla/content/base/src/nsDocument.cpp +++ b/mozilla/content/base/src/nsDocument.cpp @@ -106,7 +106,6 @@ #include "nsIDOMWindowInternal.h" #include "nsIDOMElement.h" -#include "nsIAnonymousContentCreator.h" static NS_DEFINE_CID(kCRangeCID, NS_RANGE_CID); static NS_DEFINE_CID(kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID); @@ -1696,26 +1695,17 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject) } } - // XXX You thought that was a hack? Let's unroot the scrollbars - // around the root element. The frame that created the anonymous - // content for them isn't the primary frame for any element, so - // we do it here. This tries not to have too much knowledge of - // how scrollbars are implemented today by actually checking all - // the frames up to the top. - nsCOMPtr shell( dont_AddRef(GetShellAt(0)) ); - if (shell) { - nsIFrame *kidFrame = nsnull; - shell->GetPrimaryFrameFor(mRootContent, &kidFrame); - while (kidFrame) { - // XXX Don't release a frame! - nsCOMPtr acc( do_QueryInterface(kidFrame) ); - if (acc) { - acc->SetDocumentForAnonymousContent(nsnull, PR_TRUE, PR_TRUE); - } - nsIFrame *parentFrame; - kidFrame->GetParent(&parentFrame); - kidFrame = parentFrame; - } + // Propagate the out-of-band notification to each PresShell's + // anonymous content as well. This ensures that there aren't any + // accidental script references left in anonymous content keeping + // the document alive. (While not strictly necessary -- the + // PresShell owns us -- it's tidy.) + for (count = mPresShells.Count() - 1; count >= 0; --count) { + nsIPresShell* shell = NS_STATIC_CAST(nsIPresShell*, mPresShells[count]); + if (! shell) + continue; + + shell->ReleaseAnonymousContent(); } } diff --git a/mozilla/content/base/src/nsGenericElement.cpp b/mozilla/content/base/src/nsGenericElement.cpp index 709c5f082f2..45807a46aae 100644 --- a/mozilla/content/base/src/nsGenericElement.cpp +++ b/mozilla/content/base/src/nsGenericElement.cpp @@ -68,8 +68,6 @@ #include "nsIDOMViewCSS.h" #include "nsIXBLService.h" -#include "nsIAnonymousContentCreator.h" - #include "nsLayoutAtoms.h" #include "nsHTMLAtoms.h" #include "nsLayoutUtils.h" diff --git a/mozilla/content/xbl/public/nsIBindingManager.h b/mozilla/content/xbl/public/nsIBindingManager.h index 13e28e6435d..9fee326cfb4 100644 --- a/mozilla/content/xbl/public/nsIBindingManager.h +++ b/mozilla/content/xbl/public/nsIBindingManager.h @@ -73,18 +73,6 @@ public: nsIDocument* aNewDocument) = 0; - /** - * Notify the binding manager that an element has - * nsIAnonymousContentCreator-generated anonymous - * content associated with it. - * @param aContent the element with which the anonymous - * content is to be associated with. - * @param aAnonymousElements an array of nsIContent - * objects, or null to indicate that any anonymous - * content should be dissociated from the aContent. - */ - NS_IMETHOD SetAnonymousContentFor(nsIContent* aContent, nsISupportsArray* aAnonymousElements) = 0; - NS_IMETHOD ResolveTag(nsIContent* aContent, PRInt32* aNameSpaceID, nsIAtom** aResult) = 0; NS_IMETHOD GetInsertionPoint(nsIContent* aParent, nsIContent* aChild, nsIContent** aResult) = 0; diff --git a/mozilla/content/xbl/src/nsBindingManager.cpp b/mozilla/content/xbl/src/nsBindingManager.cpp index 9eeac3e2b5b..e1ec4d7598a 100644 --- a/mozilla/content/xbl/src/nsBindingManager.cpp +++ b/mozilla/content/xbl/src/nsBindingManager.cpp @@ -38,6 +38,7 @@ #include "nsIContent.h" #include "nsIDOMElement.h" #include "nsIDocument.h" +#include "nsIPresShell.h" #include "nsIXMLContentSink.h" #include "nsLayoutCID.h" #include "nsXMLDocument.h" @@ -203,8 +204,6 @@ public: NS_IMETHOD ChangeDocumentFor(nsIContent* aContent, nsIDocument* aOldDocument, nsIDocument* aNewDocument); - NS_IMETHOD SetAnonymousContentFor(nsIContent* aContent, nsISupportsArray* aAnonymousElements); - NS_IMETHOD ResolveTag(nsIContent* aContent, PRInt32* aNameSpaceID, nsIAtom** aResult); NS_IMETHOD GetInsertionPoint(nsIContent* aParent, nsIContent* aChild, nsIContent** aResult); @@ -251,7 +250,6 @@ protected: nsSupportsHashtable* mBindingTable; nsSupportsHashtable* mDocumentTable; nsSupportsHashtable* mLoadingDocTable; - nsSupportsHashtable* mAnonymousContentTable; nsCOMPtr mAttachedQueue; }; @@ -272,7 +270,6 @@ nsBindingManager::nsBindingManager(void) mDocumentTable = nsnull; mLoadingDocTable = nsnull; - mAnonymousContentTable = nsnull; mAttachedQueue = nsnull; } @@ -282,7 +279,6 @@ nsBindingManager::~nsBindingManager(void) delete mBindingTable; delete mDocumentTable; delete mLoadingDocTable; - delete mAnonymousContentTable; } NS_IMETHODIMP @@ -324,6 +320,10 @@ NS_IMETHODIMP nsBindingManager::ChangeDocumentFor(nsIContent* aContent, nsIDocument* aOldDocument, nsIDocument* aNewDocument) { + NS_PRECONDITION(aOldDocument != nsnull, "no old document"); + if (! aOldDocument) + return NS_ERROR_NULL_POINTER; + nsCOMPtr binding; GetBinding(aContent, getter_AddRefs(binding)); if (binding) { @@ -336,13 +336,14 @@ nsBindingManager::ChangeDocumentFor(nsIContent* aContent, nsIDocument* aOldDocum } } - if (mAnonymousContentTable) { + for (PRInt32 i = aOldDocument->GetNumberOfShells() - 1; i >= 0; --i) { + nsCOMPtr shell = dont_AddRef( aOldDocument->GetShellAt(i) ); + NS_ASSERTION(shell != nsnull, "Zoiks! nsIPresShell::ShellAt() broke"); + // See if the element has nsIAnonymousContentCreator-created // anonymous content... - nsISupportsKey key(aContent); - - nsCOMPtr anonymousElements = - getter_AddRefs(NS_REINTERPRET_CAST(nsISupportsArray*, mAnonymousContentTable->Get(&key))); + nsCOMPtr anonymousElements; + shell->GetAnonymousContentFor(aContent, getter_AddRefs(anonymousElements)); if (anonymousElements) { // ...yep, so be sure to update the doc pointer in those @@ -365,48 +366,6 @@ nsBindingManager::ChangeDocumentFor(nsIContent* aContent, nsIDocument* aOldDocum return NS_OK; } -NS_IMETHODIMP -nsBindingManager::SetAnonymousContentFor(nsIContent* aContent, nsISupportsArray* aAnonymousElements) -{ - NS_PRECONDITION(aContent != nsnull, "null ptr"); - if (! aContent) - return NS_ERROR_NULL_POINTER; - - if (!mAnonymousContentTable) - mAnonymousContentTable = new nsSupportsHashtable; - - nsISupportsKey key(aContent); - - nsCOMPtr oldAnonymousElements = - getter_AddRefs(NS_STATIC_CAST(nsISupportsArray*, mAnonymousContentTable->Get(&key))); - - if (oldAnonymousElements && aAnonymousElements) { - // If we're trying to set anonymous content for an element that - // already had anonymous content, then we need to be sure to clean - // up after the old content. (This can happen, for example, when a - // reframe occurs.) - PRUint32 count; - oldAnonymousElements->Count(&count); - - while (PRInt32(--count) >= 0) { - nsCOMPtr isupports( getter_AddRefs(oldAnonymousElements->ElementAt(count)) ); - nsCOMPtr content( do_QueryInterface(isupports) ); - NS_ASSERTION(content != nsnull, "not an nsIContent"); - if (! content) - continue; - - content->SetDocument(nsnull, PR_TRUE, PR_TRUE); - } - } - - if (aAnonymousElements) - mAnonymousContentTable->Put(&key, aAnonymousElements); - else - mAnonymousContentTable->Remove(&key); - - return NS_OK; -} - NS_IMETHODIMP nsBindingManager::ResolveTag(nsIContent* aContent, PRInt32* aNameSpaceID, nsIAtom** aResult) { diff --git a/mozilla/content/xul/document/src/nsXULDocument.cpp b/mozilla/content/xul/document/src/nsXULDocument.cpp index 1b5bde4e0c5..af8a20678de 100644 --- a/mozilla/content/xul/document/src/nsXULDocument.cpp +++ b/mozilla/content/xul/document/src/nsXULDocument.cpp @@ -1442,6 +1442,19 @@ nsXULDocument::SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject) NS_RELEASE(builder); } } + + // Propagate the out-of-band notification to each PresShell's + // anonymous content as well. This ensures that there aren't + // any accidental script references left in anonymous content + // keeping the document alive. (While not strictly necessary + // -- the PresShell owns us -- it's tidy.) + for (PRInt32 count = mPresShells.Count() - 1; count >= 0; --count) { + nsIPresShell* shell = NS_STATIC_CAST(nsIPresShell*, mPresShells[count]); + if (! shell) + continue; + + shell->ReleaseAnonymousContent(); + } } mScriptGlobalObject = aScriptGlobalObject; diff --git a/mozilla/layout/base/nsCSSFrameConstructor.cpp b/mozilla/layout/base/nsCSSFrameConstructor.cpp index 9855b5d44e2..eec1e0eb14f 100644 --- a/mozilla/layout/base/nsCSSFrameConstructor.cpp +++ b/mozilla/layout/base/nsCSSFrameConstructor.cpp @@ -5479,13 +5479,8 @@ nsCSSFrameConstructor::CreateAnonymousFrames(nsIPresShell* aPresShell, anonymousItems->Count(&count); if (count) { - // Inform the binding manager about the anonymous content - nsCOMPtr bindingManager; - aDocument->GetBindingManager(getter_AddRefs(bindingManager)); - NS_ASSERTION(bindingManager, "no binding manager"); - if (bindingManager) { - bindingManager->SetAnonymousContentFor(aParent, anonymousItems); - } + // Inform the pres shell about the anonymous content + aPresShell->SetAnonymousContentFor(aParent, anonymousItems); for (PRUint32 i=0; i < count; i++) { // get our child's content and set its parent to our content diff --git a/mozilla/layout/base/nsIPresShell.h b/mozilla/layout/base/nsIPresShell.h index c7f7a1d4057..04aa6754189 100644 --- a/mozilla/layout/base/nsIPresShell.h +++ b/mozilla/layout/base/nsIPresShell.h @@ -66,6 +66,7 @@ class nsIFrameManager; class nsILayoutHistoryState; class nsIArena; class nsIReflowCallback; +class nsISupportsArray; #define NS_IPRESSHELL_IID \ { 0x76e79c60, 0x944e, 0x11d1, \ @@ -429,6 +430,35 @@ public: GeneratedContentType aType, nsIContentIterator** aIterator) const = 0; + + /** + * Store the nsIAnonymousContentCreator-generated anonymous + * content that's associated with an element. + * @param aContent the element with which the anonymous + * content is to be associated with + * @param aAnonymousElements an array of nsIContent + * objects, or null to indicate that any anonymous + * content should be dissociated from the aContent + */ + NS_IMETHOD SetAnonymousContentFor(nsIContent* aContent, nsISupportsArray* aAnonymousElements) = 0; + + /** + * Retrieve the nsIAnonymousContentCreator-generated anonymous + * content that's associated with an element. + * @param aContent the element for which to retrieve the + * associated anonymous content + * @param aAnonymousElements an array of nsIContent objects, + * or null to indicate that there are no anonymous elements + * associated with aContent + */ + NS_IMETHOD GetAnonymousContentFor(nsIContent* aContent, nsISupportsArray** aAnonymousElements) = 0; + + /** + * Release all nsIAnonymousContentCreator-generated + * anonymous content associated with the shell. + */ + NS_IMETHOD ReleaseAnonymousContent() = 0; + /** * See if reflow verification is enabled. To enable reflow verification add * "verifyreflow:1" to your NSPR_LOG_MODULES environment variable diff --git a/mozilla/layout/base/nsPresShell.cpp b/mozilla/layout/base/nsPresShell.cpp index cd52ec1f59a..2aba9405bd3 100644 --- a/mozilla/layout/base/nsPresShell.cpp +++ b/mozilla/layout/base/nsPresShell.cpp @@ -53,6 +53,7 @@ #include "prmem.h" #include "prinrval.h" #include "nsVoidArray.h" +#include "nsHashtable.h" #include "nsIPref.h" #include "nsIViewObserver.h" #include "nsContainerFrame.h" @@ -839,6 +840,10 @@ public: GeneratedContentType aType, nsIContentIterator** aIterator) const; + NS_IMETHOD SetAnonymousContentFor(nsIContent* aContent, nsISupportsArray* aAnonymousElements); + NS_IMETHOD GetAnonymousContentFor(nsIContent* aContent, nsISupportsArray** aAnonymousElements); + NS_IMETHOD ReleaseAnonymousContent(); + NS_IMETHOD HandleEventWithTarget(nsEvent* aEvent, nsIFrame* aFrame, nsIContent* aContent, PRUint32 aFlags, nsEventStatus* aStatus); NS_IMETHOD GetEventTargetFrame(nsIFrame** aFrame); @@ -1005,6 +1010,7 @@ protected: nsIContent* mCurrentEventContent; nsVoidArray mCurrentEventFrameStack; nsVoidArray mCurrentEventContentStack; + nsSupportsHashtable* mAnonymousContentTable; #ifdef NS_DEBUG nsRect mCurrentTargetRect; @@ -1164,7 +1170,8 @@ PresShell::PresShell():mStackArena(nsnull), mFirstAttributeRequest(nsnull), mLastAttributeRequest(nsnull), mFirstCallbackEventRequest(nsnull), - mLastCallbackEventRequest(nsnull) + mLastCallbackEventRequest(nsnull), + mAnonymousContentTable(nsnull) { NS_INIT_REFCNT(); mIsDestroying = PR_FALSE; @@ -1244,6 +1251,9 @@ PresShell::~PresShell() // if we allocated any stack memory free it. FreeDynamicStack(); + // free our table of anonymous content + ReleaseAnonymousContent(); + mIsDestroying = PR_TRUE; // Clobber weak leaks in case of re-entrancy during tear down @@ -3409,6 +3419,103 @@ PresShell::GetGeneratedContentIterator(nsIContent* aContent, return rv; } + +NS_IMETHODIMP +PresShell::SetAnonymousContentFor(nsIContent* aContent, nsISupportsArray* aAnonymousElements) +{ + NS_PRECONDITION(aContent != nsnull, "null ptr"); + if (! aContent) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aAnonymousElements != nsnull, "null ptr"); + if (! aAnonymousElements) + return NS_ERROR_NULL_POINTER; + + if (! mAnonymousContentTable) { + mAnonymousContentTable = new nsSupportsHashtable; + if (! mAnonymousContentTable) + return NS_ERROR_OUT_OF_MEMORY; + } + + nsISupportsKey key(aContent); + + nsCOMPtr oldAnonymousElements = + getter_AddRefs(NS_STATIC_CAST(nsISupportsArray*, mAnonymousContentTable->Get(&key))); + + if (oldAnonymousElements) { + // If we're trying to set anonymous content for an element that + // already had anonymous content, then we need to be sure to clean + // up after the old content. (This can happen, for example, when a + // reframe occurs.) + PRUint32 count; + oldAnonymousElements->Count(&count); + + while (PRInt32(--count) >= 0) { + nsCOMPtr isupports( getter_AddRefs(oldAnonymousElements->ElementAt(count)) ); + nsCOMPtr content( do_QueryInterface(isupports) ); + NS_ASSERTION(content != nsnull, "not an nsIContent"); + if (! content) + continue; + + content->SetDocument(nsnull, PR_TRUE, PR_TRUE); + } + } + + mAnonymousContentTable->Put(&key, aAnonymousElements); + return NS_OK; +} + + +NS_IMETHODIMP +PresShell::GetAnonymousContentFor(nsIContent* aContent, nsISupportsArray** aAnonymousElements) +{ + if (! mAnonymousContentTable) { + *aAnonymousElements = nsnull; + return NS_OK; + } + + nsISupportsKey key(aContent); + *aAnonymousElements = + NS_REINTERPRET_CAST(nsISupportsArray*, mAnonymousContentTable->Get(&key)); // addrefs + + return NS_OK; +} + + +static PRBool PR_CALLBACK +ClearDocumentEnumerator(nsHashKey* aKey, void* aData, void* aClosure) +{ + nsISupportsArray* anonymousElements = + NS_STATIC_CAST(nsISupportsArray*, aData); + + PRUint32 count; + anonymousElements->Count(&count); + while (PRInt32(--count) >= 0) { + nsCOMPtr isupports( getter_AddRefs(anonymousElements->ElementAt(count)) ); + nsCOMPtr content( do_QueryInterface(isupports) ); + NS_ASSERTION(content != nsnull, "not an nsIContent"); + if (! content) + continue; + + content->SetDocument(nsnull, PR_TRUE, PR_TRUE); + } + + return PR_TRUE; +} + + +NS_IMETHODIMP +PresShell::ReleaseAnonymousContent() +{ + if (mAnonymousContentTable) { + mAnonymousContentTable->Enumerate(ClearDocumentEnumerator); + delete mAnonymousContentTable; + mAnonymousContentTable = nsnull; + } + return NS_OK; +} + + // Post a request to handle an arbitrary callback after reflow has finished. NS_IMETHODIMP PresShell::PostReflowCallback(nsIReflowCallback* aCallback) diff --git a/mozilla/layout/base/public/nsIPresShell.h b/mozilla/layout/base/public/nsIPresShell.h index c7f7a1d4057..04aa6754189 100644 --- a/mozilla/layout/base/public/nsIPresShell.h +++ b/mozilla/layout/base/public/nsIPresShell.h @@ -66,6 +66,7 @@ class nsIFrameManager; class nsILayoutHistoryState; class nsIArena; class nsIReflowCallback; +class nsISupportsArray; #define NS_IPRESSHELL_IID \ { 0x76e79c60, 0x944e, 0x11d1, \ @@ -429,6 +430,35 @@ public: GeneratedContentType aType, nsIContentIterator** aIterator) const = 0; + + /** + * Store the nsIAnonymousContentCreator-generated anonymous + * content that's associated with an element. + * @param aContent the element with which the anonymous + * content is to be associated with + * @param aAnonymousElements an array of nsIContent + * objects, or null to indicate that any anonymous + * content should be dissociated from the aContent + */ + NS_IMETHOD SetAnonymousContentFor(nsIContent* aContent, nsISupportsArray* aAnonymousElements) = 0; + + /** + * Retrieve the nsIAnonymousContentCreator-generated anonymous + * content that's associated with an element. + * @param aContent the element for which to retrieve the + * associated anonymous content + * @param aAnonymousElements an array of nsIContent objects, + * or null to indicate that there are no anonymous elements + * associated with aContent + */ + NS_IMETHOD GetAnonymousContentFor(nsIContent* aContent, nsISupportsArray** aAnonymousElements) = 0; + + /** + * Release all nsIAnonymousContentCreator-generated + * anonymous content associated with the shell. + */ + NS_IMETHOD ReleaseAnonymousContent() = 0; + /** * See if reflow verification is enabled. To enable reflow verification add * "verifyreflow:1" to your NSPR_LOG_MODULES environment variable diff --git a/mozilla/layout/base/src/nsDocument.cpp b/mozilla/layout/base/src/nsDocument.cpp index 9219fd19193..9181741f8bb 100644 --- a/mozilla/layout/base/src/nsDocument.cpp +++ b/mozilla/layout/base/src/nsDocument.cpp @@ -106,7 +106,6 @@ #include "nsIDOMWindowInternal.h" #include "nsIDOMElement.h" -#include "nsIAnonymousContentCreator.h" static NS_DEFINE_CID(kCRangeCID, NS_RANGE_CID); static NS_DEFINE_CID(kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID); @@ -1696,26 +1695,17 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject) } } - // XXX You thought that was a hack? Let's unroot the scrollbars - // around the root element. The frame that created the anonymous - // content for them isn't the primary frame for any element, so - // we do it here. This tries not to have too much knowledge of - // how scrollbars are implemented today by actually checking all - // the frames up to the top. - nsCOMPtr shell( dont_AddRef(GetShellAt(0)) ); - if (shell) { - nsIFrame *kidFrame = nsnull; - shell->GetPrimaryFrameFor(mRootContent, &kidFrame); - while (kidFrame) { - // XXX Don't release a frame! - nsCOMPtr acc( do_QueryInterface(kidFrame) ); - if (acc) { - acc->SetDocumentForAnonymousContent(nsnull, PR_TRUE, PR_TRUE); - } - nsIFrame *parentFrame; - kidFrame->GetParent(&parentFrame); - kidFrame = parentFrame; - } + // Propagate the out-of-band notification to each PresShell's + // anonymous content as well. This ensures that there aren't any + // accidental script references left in anonymous content keeping + // the document alive. (While not strictly necessary -- the + // PresShell owns us -- it's tidy.) + for (count = mPresShells.Count() - 1; count >= 0; --count) { + nsIPresShell* shell = NS_STATIC_CAST(nsIPresShell*, mPresShells[count]); + if (! shell) + continue; + + shell->ReleaseAnonymousContent(); } } diff --git a/mozilla/layout/base/src/nsGenericElement.cpp b/mozilla/layout/base/src/nsGenericElement.cpp index 709c5f082f2..45807a46aae 100644 --- a/mozilla/layout/base/src/nsGenericElement.cpp +++ b/mozilla/layout/base/src/nsGenericElement.cpp @@ -68,8 +68,6 @@ #include "nsIDOMViewCSS.h" #include "nsIXBLService.h" -#include "nsIAnonymousContentCreator.h" - #include "nsLayoutAtoms.h" #include "nsHTMLAtoms.h" #include "nsLayoutUtils.h" diff --git a/mozilla/layout/forms/nsComboboxControlFrame.cpp b/mozilla/layout/forms/nsComboboxControlFrame.cpp index db5ad3962cc..4460a44522c 100644 --- a/mozilla/layout/forms/nsComboboxControlFrame.cpp +++ b/mozilla/layout/forms/nsComboboxControlFrame.cpp @@ -2168,16 +2168,6 @@ nsComboboxControlFrame::CreateAnonymousContent(nsIPresContext* aPresContext, return NS_OK; } -NS_IMETHODIMP -nsComboboxControlFrame::SetDocumentForAnonymousContent(nsIDocument* aDocument, - PRBool aDeep, - PRBool aCompileEventHandlers) -{ - // XXX WRITE ME - return NS_OK; -} - - NS_IMETHODIMP nsComboboxControlFrame::CreateFrameFor(nsIPresContext* aPresContext, nsIContent * aContent, diff --git a/mozilla/layout/forms/nsComboboxControlFrame.h b/mozilla/layout/forms/nsComboboxControlFrame.h index 765b8d55160..53cf8f6f24a 100644 --- a/mozilla/layout/forms/nsComboboxControlFrame.h +++ b/mozilla/layout/forms/nsComboboxControlFrame.h @@ -79,9 +79,6 @@ public: // nsIAnonymousContentCreator NS_IMETHOD CreateAnonymousContent(nsIPresContext* aPresContext, nsISupportsArray& aChildList); - NS_IMETHOD SetDocumentForAnonymousContent(nsIDocument* aDocument, - PRBool aDeep, - PRBool aCompileEventHandlers); NS_IMETHOD CreateFrameFor(nsIPresContext* aPresContext, nsIContent * aContent, nsIFrame** aFrame); diff --git a/mozilla/layout/forms/nsFileControlFrame.cpp b/mozilla/layout/forms/nsFileControlFrame.cpp index 9925e68e092..7b3443524c6 100644 --- a/mozilla/layout/forms/nsFileControlFrame.cpp +++ b/mozilla/layout/forms/nsFileControlFrame.cpp @@ -154,15 +154,6 @@ nsFileControlFrame::CreateAnonymousContent(nsIPresContext* aPresContext, return NS_OK; } -NS_IMETHODIMP -nsFileControlFrame::SetDocumentForAnonymousContent(nsIDocument* aDocument, - PRBool aDeep, - PRBool aCompileEventHandlers) -{ - // XXX WRITE ME - return NS_OK; -} - // Frames are not refcounted, no need to AddRef NS_IMETHODIMP nsFileControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) diff --git a/mozilla/layout/forms/nsFileControlFrame.h b/mozilla/layout/forms/nsFileControlFrame.h index 955b5987daa..73eeb5bf685 100644 --- a/mozilla/layout/forms/nsFileControlFrame.h +++ b/mozilla/layout/forms/nsFileControlFrame.h @@ -125,9 +125,6 @@ public: // from nsIAnonymousContentCreator NS_IMETHOD CreateAnonymousContent(nsIPresContext* aPresContext, nsISupportsArray& aChildList); - NS_IMETHOD SetDocumentForAnonymousContent(nsIDocument* aDocument, - PRBool aDeep, - PRBool aCompileEventHandlers); NS_IMETHOD CreateFrameFor(nsIPresContext* aPresContext, nsIContent * aContent, nsIFrame** aFrame) { if (aFrame) *aFrame = nsnull; return NS_ERROR_FAILURE; } diff --git a/mozilla/layout/forms/nsGfxButtonControlFrame.cpp b/mozilla/layout/forms/nsGfxButtonControlFrame.cpp index 8807df59ce0..4f80fdd9b77 100644 --- a/mozilla/layout/forms/nsGfxButtonControlFrame.cpp +++ b/mozilla/layout/forms/nsGfxButtonControlFrame.cpp @@ -445,15 +445,6 @@ nsGfxButtonControlFrame::CreateFrameFor(nsIPresContext* aPresContext, return rv; } -NS_IMETHODIMP -nsGfxButtonControlFrame::SetDocumentForAnonymousContent(nsIDocument* aDocument, - PRBool aDeep, - PRBool aCompileEventHandlers) -{ - // XXX WRITE ME - return NS_OK; -} - // Frames are not refcounted, no need to AddRef NS_IMETHODIMP nsGfxButtonControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) diff --git a/mozilla/layout/forms/nsGfxButtonControlFrame.h b/mozilla/layout/forms/nsGfxButtonControlFrame.h index 8bec39b52be..299eafa9192 100644 --- a/mozilla/layout/forms/nsGfxButtonControlFrame.h +++ b/mozilla/layout/forms/nsGfxButtonControlFrame.h @@ -68,9 +68,6 @@ public: // nsIAnonymousContentCreator NS_IMETHOD CreateAnonymousContent(nsIPresContext* aPresContext, nsISupportsArray& aChildList); - NS_IMETHOD SetDocumentForAnonymousContent(nsIDocument* aDocument, - PRBool aDeep, - PRBool aCompileEventHandlers); NS_IMETHOD CreateFrameFor(nsIPresContext* aPresContext, nsIContent * aContent, nsIFrame** aFrame); diff --git a/mozilla/layout/forms/nsIsIndexFrame.cpp b/mozilla/layout/forms/nsIsIndexFrame.cpp index 2ef2900831d..19675cb4a53 100644 --- a/mozilla/layout/forms/nsIsIndexFrame.cpp +++ b/mozilla/layout/forms/nsIsIndexFrame.cpp @@ -241,15 +241,6 @@ nsIsIndexFrame::CreateAnonymousContent(nsIPresContext* aPresContext, return result; } -NS_IMETHODIMP -nsIsIndexFrame::SetDocumentForAnonymousContent(nsIDocument* aDocument, - PRBool aDeep, - PRBool aCompileEventHandlers) -{ - // XXX WRITE ME - return NS_OK; -} - // Frames are not refcounted, no need to AddRef NS_IMETHODIMP nsIsIndexFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) diff --git a/mozilla/layout/forms/nsIsIndexFrame.h b/mozilla/layout/forms/nsIsIndexFrame.h index bde7d9eb277..37eb142bb5c 100644 --- a/mozilla/layout/forms/nsIsIndexFrame.h +++ b/mozilla/layout/forms/nsIsIndexFrame.h @@ -107,9 +107,6 @@ public: // from nsIAnonymousContentCreator NS_IMETHOD CreateAnonymousContent(nsIPresContext* aPresContext, nsISupportsArray& aChildList); - NS_IMETHOD SetDocumentForAnonymousContent(nsIDocument* aDocument, - PRBool aDeep, - PRBool aCompileEventHandlers); NS_IMETHOD CreateFrameFor(nsIPresContext* aPresContext, nsIContent * aContent, nsIFrame** aFrame) { if (aFrame) *aFrame = nsnull; return NS_ERROR_FAILURE; } diff --git a/mozilla/layout/generic/nsGfxScrollFrame.cpp b/mozilla/layout/generic/nsGfxScrollFrame.cpp index 9cba2aff08a..34e76d5670a 100644 --- a/mozilla/layout/generic/nsGfxScrollFrame.cpp +++ b/mozilla/layout/generic/nsGfxScrollFrame.cpp @@ -444,40 +444,6 @@ nsGfxScrollFrame::CreateAnonymousContent(nsIPresContext* aPresContext, return NS_OK; } -NS_IMETHODIMP -nsGfxScrollFrame::SetDocumentForAnonymousContent(nsIDocument* aDocument, - PRBool aDeep, - PRBool aCompileEventHandlers) -{ - // XXX Propogate return values?? (but don't stop part way through) - - if (mInner->mHScrollbarBox) { - nsIFrame* hframe = nsnull; - mInner->mHScrollbarBox->GetFrame(&hframe); - if (hframe) { - nsCOMPtr hcontent; - hframe->GetContent(getter_AddRefs(hcontent)); - if (hcontent) { - hcontent->SetDocument(aDocument, aDeep, aCompileEventHandlers); - } - } - } - - if (mInner->mHScrollbarBox) { - nsIFrame* vframe = nsnull; - mInner->mVScrollbarBox->GetFrame(&vframe); - if (vframe) { - nsCOMPtr vcontent; - vframe->GetContent(getter_AddRefs(vcontent)); - if (vcontent) { - vcontent->SetDocument(aDocument, aDeep, aCompileEventHandlers); - } - } - } - - return NS_OK; -} - NS_IMETHODIMP nsGfxScrollFrame::Destroy(nsIPresContext* aPresContext) diff --git a/mozilla/layout/generic/nsGfxScrollFrame.h b/mozilla/layout/generic/nsGfxScrollFrame.h index 34122b8c127..c1c59e02a0e 100644 --- a/mozilla/layout/generic/nsGfxScrollFrame.h +++ b/mozilla/layout/generic/nsGfxScrollFrame.h @@ -109,9 +109,6 @@ public: // nsIAnonymousContentCreator NS_IMETHOD CreateAnonymousContent(nsIPresContext* aPresContext, nsISupportsArray& aAnonymousItems); - NS_IMETHOD SetDocumentForAnonymousContent(nsIDocument* aDocument, - PRBool aDeep, - PRBool aCompileEventHandlers); NS_IMETHOD CreateFrameFor(nsIPresContext* aPresContext, nsIContent * aContent, nsIFrame** aFrame) { if (aFrame) *aFrame = nsnull; return NS_ERROR_FAILURE; } diff --git a/mozilla/layout/generic/nsIAnonymousContentCreator.h b/mozilla/layout/generic/nsIAnonymousContentCreator.h index e48c6bb4275..feb843496e0 100644 --- a/mozilla/layout/generic/nsIAnonymousContentCreator.h +++ b/mozilla/layout/generic/nsIAnonymousContentCreator.h @@ -50,11 +50,6 @@ public: NS_IMETHOD CreateAnonymousContent(nsIPresContext* aPresContext, nsISupportsArray& aAnonymousItems)=0; - // Needed to unroot script objects in anonymous content - NS_IMETHOD SetDocumentForAnonymousContent(nsIDocument* aDocument, - PRBool aDeep, - PRBool aCompileEventHandlers) = 0; - // If the creator doesn't want to create special fframe ro frame hierarchy // then it should null out the style content arg and return NS_ERROR_FAILURE NS_IMETHOD CreateFrameFor(nsIPresContext* aPresContext, diff --git a/mozilla/layout/html/base/src/nsGfxScrollFrame.cpp b/mozilla/layout/html/base/src/nsGfxScrollFrame.cpp index 9cba2aff08a..34e76d5670a 100644 --- a/mozilla/layout/html/base/src/nsGfxScrollFrame.cpp +++ b/mozilla/layout/html/base/src/nsGfxScrollFrame.cpp @@ -444,40 +444,6 @@ nsGfxScrollFrame::CreateAnonymousContent(nsIPresContext* aPresContext, return NS_OK; } -NS_IMETHODIMP -nsGfxScrollFrame::SetDocumentForAnonymousContent(nsIDocument* aDocument, - PRBool aDeep, - PRBool aCompileEventHandlers) -{ - // XXX Propogate return values?? (but don't stop part way through) - - if (mInner->mHScrollbarBox) { - nsIFrame* hframe = nsnull; - mInner->mHScrollbarBox->GetFrame(&hframe); - if (hframe) { - nsCOMPtr hcontent; - hframe->GetContent(getter_AddRefs(hcontent)); - if (hcontent) { - hcontent->SetDocument(aDocument, aDeep, aCompileEventHandlers); - } - } - } - - if (mInner->mHScrollbarBox) { - nsIFrame* vframe = nsnull; - mInner->mVScrollbarBox->GetFrame(&vframe); - if (vframe) { - nsCOMPtr vcontent; - vframe->GetContent(getter_AddRefs(vcontent)); - if (vcontent) { - vcontent->SetDocument(aDocument, aDeep, aCompileEventHandlers); - } - } - } - - return NS_OK; -} - NS_IMETHODIMP nsGfxScrollFrame::Destroy(nsIPresContext* aPresContext) diff --git a/mozilla/layout/html/base/src/nsGfxScrollFrame.h b/mozilla/layout/html/base/src/nsGfxScrollFrame.h index 34122b8c127..c1c59e02a0e 100644 --- a/mozilla/layout/html/base/src/nsGfxScrollFrame.h +++ b/mozilla/layout/html/base/src/nsGfxScrollFrame.h @@ -109,9 +109,6 @@ public: // nsIAnonymousContentCreator NS_IMETHOD CreateAnonymousContent(nsIPresContext* aPresContext, nsISupportsArray& aAnonymousItems); - NS_IMETHOD SetDocumentForAnonymousContent(nsIDocument* aDocument, - PRBool aDeep, - PRBool aCompileEventHandlers); NS_IMETHOD CreateFrameFor(nsIPresContext* aPresContext, nsIContent * aContent, nsIFrame** aFrame) { if (aFrame) *aFrame = nsnull; return NS_ERROR_FAILURE; } diff --git a/mozilla/layout/html/base/src/nsIAnonymousContentCreator.h b/mozilla/layout/html/base/src/nsIAnonymousContentCreator.h index e48c6bb4275..feb843496e0 100644 --- a/mozilla/layout/html/base/src/nsIAnonymousContentCreator.h +++ b/mozilla/layout/html/base/src/nsIAnonymousContentCreator.h @@ -50,11 +50,6 @@ public: NS_IMETHOD CreateAnonymousContent(nsIPresContext* aPresContext, nsISupportsArray& aAnonymousItems)=0; - // Needed to unroot script objects in anonymous content - NS_IMETHOD SetDocumentForAnonymousContent(nsIDocument* aDocument, - PRBool aDeep, - PRBool aCompileEventHandlers) = 0; - // If the creator doesn't want to create special fframe ro frame hierarchy // then it should null out the style content arg and return NS_ERROR_FAILURE NS_IMETHOD CreateFrameFor(nsIPresContext* aPresContext, diff --git a/mozilla/layout/html/base/src/nsPresShell.cpp b/mozilla/layout/html/base/src/nsPresShell.cpp index cd52ec1f59a..2aba9405bd3 100644 --- a/mozilla/layout/html/base/src/nsPresShell.cpp +++ b/mozilla/layout/html/base/src/nsPresShell.cpp @@ -53,6 +53,7 @@ #include "prmem.h" #include "prinrval.h" #include "nsVoidArray.h" +#include "nsHashtable.h" #include "nsIPref.h" #include "nsIViewObserver.h" #include "nsContainerFrame.h" @@ -839,6 +840,10 @@ public: GeneratedContentType aType, nsIContentIterator** aIterator) const; + NS_IMETHOD SetAnonymousContentFor(nsIContent* aContent, nsISupportsArray* aAnonymousElements); + NS_IMETHOD GetAnonymousContentFor(nsIContent* aContent, nsISupportsArray** aAnonymousElements); + NS_IMETHOD ReleaseAnonymousContent(); + NS_IMETHOD HandleEventWithTarget(nsEvent* aEvent, nsIFrame* aFrame, nsIContent* aContent, PRUint32 aFlags, nsEventStatus* aStatus); NS_IMETHOD GetEventTargetFrame(nsIFrame** aFrame); @@ -1005,6 +1010,7 @@ protected: nsIContent* mCurrentEventContent; nsVoidArray mCurrentEventFrameStack; nsVoidArray mCurrentEventContentStack; + nsSupportsHashtable* mAnonymousContentTable; #ifdef NS_DEBUG nsRect mCurrentTargetRect; @@ -1164,7 +1170,8 @@ PresShell::PresShell():mStackArena(nsnull), mFirstAttributeRequest(nsnull), mLastAttributeRequest(nsnull), mFirstCallbackEventRequest(nsnull), - mLastCallbackEventRequest(nsnull) + mLastCallbackEventRequest(nsnull), + mAnonymousContentTable(nsnull) { NS_INIT_REFCNT(); mIsDestroying = PR_FALSE; @@ -1244,6 +1251,9 @@ PresShell::~PresShell() // if we allocated any stack memory free it. FreeDynamicStack(); + // free our table of anonymous content + ReleaseAnonymousContent(); + mIsDestroying = PR_TRUE; // Clobber weak leaks in case of re-entrancy during tear down @@ -3409,6 +3419,103 @@ PresShell::GetGeneratedContentIterator(nsIContent* aContent, return rv; } + +NS_IMETHODIMP +PresShell::SetAnonymousContentFor(nsIContent* aContent, nsISupportsArray* aAnonymousElements) +{ + NS_PRECONDITION(aContent != nsnull, "null ptr"); + if (! aContent) + return NS_ERROR_NULL_POINTER; + + NS_PRECONDITION(aAnonymousElements != nsnull, "null ptr"); + if (! aAnonymousElements) + return NS_ERROR_NULL_POINTER; + + if (! mAnonymousContentTable) { + mAnonymousContentTable = new nsSupportsHashtable; + if (! mAnonymousContentTable) + return NS_ERROR_OUT_OF_MEMORY; + } + + nsISupportsKey key(aContent); + + nsCOMPtr oldAnonymousElements = + getter_AddRefs(NS_STATIC_CAST(nsISupportsArray*, mAnonymousContentTable->Get(&key))); + + if (oldAnonymousElements) { + // If we're trying to set anonymous content for an element that + // already had anonymous content, then we need to be sure to clean + // up after the old content. (This can happen, for example, when a + // reframe occurs.) + PRUint32 count; + oldAnonymousElements->Count(&count); + + while (PRInt32(--count) >= 0) { + nsCOMPtr isupports( getter_AddRefs(oldAnonymousElements->ElementAt(count)) ); + nsCOMPtr content( do_QueryInterface(isupports) ); + NS_ASSERTION(content != nsnull, "not an nsIContent"); + if (! content) + continue; + + content->SetDocument(nsnull, PR_TRUE, PR_TRUE); + } + } + + mAnonymousContentTable->Put(&key, aAnonymousElements); + return NS_OK; +} + + +NS_IMETHODIMP +PresShell::GetAnonymousContentFor(nsIContent* aContent, nsISupportsArray** aAnonymousElements) +{ + if (! mAnonymousContentTable) { + *aAnonymousElements = nsnull; + return NS_OK; + } + + nsISupportsKey key(aContent); + *aAnonymousElements = + NS_REINTERPRET_CAST(nsISupportsArray*, mAnonymousContentTable->Get(&key)); // addrefs + + return NS_OK; +} + + +static PRBool PR_CALLBACK +ClearDocumentEnumerator(nsHashKey* aKey, void* aData, void* aClosure) +{ + nsISupportsArray* anonymousElements = + NS_STATIC_CAST(nsISupportsArray*, aData); + + PRUint32 count; + anonymousElements->Count(&count); + while (PRInt32(--count) >= 0) { + nsCOMPtr isupports( getter_AddRefs(anonymousElements->ElementAt(count)) ); + nsCOMPtr content( do_QueryInterface(isupports) ); + NS_ASSERTION(content != nsnull, "not an nsIContent"); + if (! content) + continue; + + content->SetDocument(nsnull, PR_TRUE, PR_TRUE); + } + + return PR_TRUE; +} + + +NS_IMETHODIMP +PresShell::ReleaseAnonymousContent() +{ + if (mAnonymousContentTable) { + mAnonymousContentTable->Enumerate(ClearDocumentEnumerator); + delete mAnonymousContentTable; + mAnonymousContentTable = nsnull; + } + return NS_OK; +} + + // Post a request to handle an arbitrary callback after reflow has finished. NS_IMETHODIMP PresShell::PostReflowCallback(nsIReflowCallback* aCallback) diff --git a/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp b/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp index db5ad3962cc..4460a44522c 100644 --- a/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp @@ -2168,16 +2168,6 @@ nsComboboxControlFrame::CreateAnonymousContent(nsIPresContext* aPresContext, return NS_OK; } -NS_IMETHODIMP -nsComboboxControlFrame::SetDocumentForAnonymousContent(nsIDocument* aDocument, - PRBool aDeep, - PRBool aCompileEventHandlers) -{ - // XXX WRITE ME - return NS_OK; -} - - NS_IMETHODIMP nsComboboxControlFrame::CreateFrameFor(nsIPresContext* aPresContext, nsIContent * aContent, diff --git a/mozilla/layout/html/forms/src/nsComboboxControlFrame.h b/mozilla/layout/html/forms/src/nsComboboxControlFrame.h index 765b8d55160..53cf8f6f24a 100644 --- a/mozilla/layout/html/forms/src/nsComboboxControlFrame.h +++ b/mozilla/layout/html/forms/src/nsComboboxControlFrame.h @@ -79,9 +79,6 @@ public: // nsIAnonymousContentCreator NS_IMETHOD CreateAnonymousContent(nsIPresContext* aPresContext, nsISupportsArray& aChildList); - NS_IMETHOD SetDocumentForAnonymousContent(nsIDocument* aDocument, - PRBool aDeep, - PRBool aCompileEventHandlers); NS_IMETHOD CreateFrameFor(nsIPresContext* aPresContext, nsIContent * aContent, nsIFrame** aFrame); diff --git a/mozilla/layout/html/forms/src/nsFileControlFrame.cpp b/mozilla/layout/html/forms/src/nsFileControlFrame.cpp index 9925e68e092..7b3443524c6 100644 --- a/mozilla/layout/html/forms/src/nsFileControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsFileControlFrame.cpp @@ -154,15 +154,6 @@ nsFileControlFrame::CreateAnonymousContent(nsIPresContext* aPresContext, return NS_OK; } -NS_IMETHODIMP -nsFileControlFrame::SetDocumentForAnonymousContent(nsIDocument* aDocument, - PRBool aDeep, - PRBool aCompileEventHandlers) -{ - // XXX WRITE ME - return NS_OK; -} - // Frames are not refcounted, no need to AddRef NS_IMETHODIMP nsFileControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) diff --git a/mozilla/layout/html/forms/src/nsFileControlFrame.h b/mozilla/layout/html/forms/src/nsFileControlFrame.h index 955b5987daa..73eeb5bf685 100644 --- a/mozilla/layout/html/forms/src/nsFileControlFrame.h +++ b/mozilla/layout/html/forms/src/nsFileControlFrame.h @@ -125,9 +125,6 @@ public: // from nsIAnonymousContentCreator NS_IMETHOD CreateAnonymousContent(nsIPresContext* aPresContext, nsISupportsArray& aChildList); - NS_IMETHOD SetDocumentForAnonymousContent(nsIDocument* aDocument, - PRBool aDeep, - PRBool aCompileEventHandlers); NS_IMETHOD CreateFrameFor(nsIPresContext* aPresContext, nsIContent * aContent, nsIFrame** aFrame) { if (aFrame) *aFrame = nsnull; return NS_ERROR_FAILURE; } diff --git a/mozilla/layout/html/forms/src/nsGfxButtonControlFrame.cpp b/mozilla/layout/html/forms/src/nsGfxButtonControlFrame.cpp index 8807df59ce0..4f80fdd9b77 100644 --- a/mozilla/layout/html/forms/src/nsGfxButtonControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsGfxButtonControlFrame.cpp @@ -445,15 +445,6 @@ nsGfxButtonControlFrame::CreateFrameFor(nsIPresContext* aPresContext, return rv; } -NS_IMETHODIMP -nsGfxButtonControlFrame::SetDocumentForAnonymousContent(nsIDocument* aDocument, - PRBool aDeep, - PRBool aCompileEventHandlers) -{ - // XXX WRITE ME - return NS_OK; -} - // Frames are not refcounted, no need to AddRef NS_IMETHODIMP nsGfxButtonControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) diff --git a/mozilla/layout/html/forms/src/nsGfxButtonControlFrame.h b/mozilla/layout/html/forms/src/nsGfxButtonControlFrame.h index 8bec39b52be..299eafa9192 100644 --- a/mozilla/layout/html/forms/src/nsGfxButtonControlFrame.h +++ b/mozilla/layout/html/forms/src/nsGfxButtonControlFrame.h @@ -68,9 +68,6 @@ public: // nsIAnonymousContentCreator NS_IMETHOD CreateAnonymousContent(nsIPresContext* aPresContext, nsISupportsArray& aChildList); - NS_IMETHOD SetDocumentForAnonymousContent(nsIDocument* aDocument, - PRBool aDeep, - PRBool aCompileEventHandlers); NS_IMETHOD CreateFrameFor(nsIPresContext* aPresContext, nsIContent * aContent, nsIFrame** aFrame); diff --git a/mozilla/layout/html/forms/src/nsGfxTextControlFrame2.cpp b/mozilla/layout/html/forms/src/nsGfxTextControlFrame2.cpp index 8801cfed6b0..85ef35b7d0e 100644 --- a/mozilla/layout/html/forms/src/nsGfxTextControlFrame2.cpp +++ b/mozilla/layout/html/forms/src/nsGfxTextControlFrame2.cpp @@ -1976,22 +1976,6 @@ nsGfxTextControlFrame2::CreateAnonymousContent(nsIPresContext* aPresContext, return NS_OK; } -NS_IMETHODIMP -nsGfxTextControlFrame2::SetDocumentForAnonymousContent(nsIDocument* aDocument, - PRBool aDeep, - PRBool aCompileEventHandlers) -{ - if (mEditor) { - nsCOMPtr root; - mEditor->GetRootElement(getter_AddRefs(root)); - if (root) { - nsCOMPtr rootContent( do_QueryInterface(root) ); - rootContent->SetDocument(aDocument, aDeep, aCompileEventHandlers); - } - } - return NS_OK; -} - NS_IMETHODIMP nsGfxTextControlFrame2::Reflow(nsIPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, diff --git a/mozilla/layout/html/forms/src/nsGfxTextControlFrame2.h b/mozilla/layout/html/forms/src/nsGfxTextControlFrame2.h index 0613ccf85d5..33a6382561e 100644 --- a/mozilla/layout/html/forms/src/nsGfxTextControlFrame2.h +++ b/mozilla/layout/html/forms/src/nsGfxTextControlFrame2.h @@ -83,9 +83,6 @@ public: // from nsIAnonymousContentCreator NS_IMETHOD CreateAnonymousContent(nsIPresContext* aPresContext, nsISupportsArray& aChildList); - NS_IMETHOD SetDocumentForAnonymousContent(nsIDocument* aDocument, - PRBool aDeep, - PRBool aCompileEventHandlers); // Utility methods to get and set current widget state void GetTextControlFrameState(nsAWritableString& aValue); diff --git a/mozilla/layout/html/forms/src/nsIsIndexFrame.cpp b/mozilla/layout/html/forms/src/nsIsIndexFrame.cpp index 2ef2900831d..19675cb4a53 100644 --- a/mozilla/layout/html/forms/src/nsIsIndexFrame.cpp +++ b/mozilla/layout/html/forms/src/nsIsIndexFrame.cpp @@ -241,15 +241,6 @@ nsIsIndexFrame::CreateAnonymousContent(nsIPresContext* aPresContext, return result; } -NS_IMETHODIMP -nsIsIndexFrame::SetDocumentForAnonymousContent(nsIDocument* aDocument, - PRBool aDeep, - PRBool aCompileEventHandlers) -{ - // XXX WRITE ME - return NS_OK; -} - // Frames are not refcounted, no need to AddRef NS_IMETHODIMP nsIsIndexFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) diff --git a/mozilla/layout/html/forms/src/nsIsIndexFrame.h b/mozilla/layout/html/forms/src/nsIsIndexFrame.h index bde7d9eb277..37eb142bb5c 100644 --- a/mozilla/layout/html/forms/src/nsIsIndexFrame.h +++ b/mozilla/layout/html/forms/src/nsIsIndexFrame.h @@ -107,9 +107,6 @@ public: // from nsIAnonymousContentCreator NS_IMETHOD CreateAnonymousContent(nsIPresContext* aPresContext, nsISupportsArray& aChildList); - NS_IMETHOD SetDocumentForAnonymousContent(nsIDocument* aDocument, - PRBool aDeep, - PRBool aCompileEventHandlers); NS_IMETHOD CreateFrameFor(nsIPresContext* aPresContext, nsIContent * aContent, nsIFrame** aFrame) { if (aFrame) *aFrame = nsnull; return NS_ERROR_FAILURE; } diff --git a/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp b/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp index 9855b5d44e2..eec1e0eb14f 100644 --- a/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp +++ b/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp @@ -5479,13 +5479,8 @@ nsCSSFrameConstructor::CreateAnonymousFrames(nsIPresShell* aPresShell, anonymousItems->Count(&count); if (count) { - // Inform the binding manager about the anonymous content - nsCOMPtr bindingManager; - aDocument->GetBindingManager(getter_AddRefs(bindingManager)); - NS_ASSERTION(bindingManager, "no binding manager"); - if (bindingManager) { - bindingManager->SetAnonymousContentFor(aParent, anonymousItems); - } + // Inform the pres shell about the anonymous content + aPresShell->SetAnonymousContentFor(aParent, anonymousItems); for (PRUint32 i=0; i < count; i++) { // get our child's content and set its parent to our content diff --git a/mozilla/layout/xbl/public/nsIBindingManager.h b/mozilla/layout/xbl/public/nsIBindingManager.h index 13e28e6435d..9fee326cfb4 100644 --- a/mozilla/layout/xbl/public/nsIBindingManager.h +++ b/mozilla/layout/xbl/public/nsIBindingManager.h @@ -73,18 +73,6 @@ public: nsIDocument* aNewDocument) = 0; - /** - * Notify the binding manager that an element has - * nsIAnonymousContentCreator-generated anonymous - * content associated with it. - * @param aContent the element with which the anonymous - * content is to be associated with. - * @param aAnonymousElements an array of nsIContent - * objects, or null to indicate that any anonymous - * content should be dissociated from the aContent. - */ - NS_IMETHOD SetAnonymousContentFor(nsIContent* aContent, nsISupportsArray* aAnonymousElements) = 0; - NS_IMETHOD ResolveTag(nsIContent* aContent, PRInt32* aNameSpaceID, nsIAtom** aResult) = 0; NS_IMETHOD GetInsertionPoint(nsIContent* aParent, nsIContent* aChild, nsIContent** aResult) = 0; diff --git a/mozilla/layout/xbl/src/nsBindingManager.cpp b/mozilla/layout/xbl/src/nsBindingManager.cpp index 9eeac3e2b5b..e1ec4d7598a 100644 --- a/mozilla/layout/xbl/src/nsBindingManager.cpp +++ b/mozilla/layout/xbl/src/nsBindingManager.cpp @@ -38,6 +38,7 @@ #include "nsIContent.h" #include "nsIDOMElement.h" #include "nsIDocument.h" +#include "nsIPresShell.h" #include "nsIXMLContentSink.h" #include "nsLayoutCID.h" #include "nsXMLDocument.h" @@ -203,8 +204,6 @@ public: NS_IMETHOD ChangeDocumentFor(nsIContent* aContent, nsIDocument* aOldDocument, nsIDocument* aNewDocument); - NS_IMETHOD SetAnonymousContentFor(nsIContent* aContent, nsISupportsArray* aAnonymousElements); - NS_IMETHOD ResolveTag(nsIContent* aContent, PRInt32* aNameSpaceID, nsIAtom** aResult); NS_IMETHOD GetInsertionPoint(nsIContent* aParent, nsIContent* aChild, nsIContent** aResult); @@ -251,7 +250,6 @@ protected: nsSupportsHashtable* mBindingTable; nsSupportsHashtable* mDocumentTable; nsSupportsHashtable* mLoadingDocTable; - nsSupportsHashtable* mAnonymousContentTable; nsCOMPtr mAttachedQueue; }; @@ -272,7 +270,6 @@ nsBindingManager::nsBindingManager(void) mDocumentTable = nsnull; mLoadingDocTable = nsnull; - mAnonymousContentTable = nsnull; mAttachedQueue = nsnull; } @@ -282,7 +279,6 @@ nsBindingManager::~nsBindingManager(void) delete mBindingTable; delete mDocumentTable; delete mLoadingDocTable; - delete mAnonymousContentTable; } NS_IMETHODIMP @@ -324,6 +320,10 @@ NS_IMETHODIMP nsBindingManager::ChangeDocumentFor(nsIContent* aContent, nsIDocument* aOldDocument, nsIDocument* aNewDocument) { + NS_PRECONDITION(aOldDocument != nsnull, "no old document"); + if (! aOldDocument) + return NS_ERROR_NULL_POINTER; + nsCOMPtr binding; GetBinding(aContent, getter_AddRefs(binding)); if (binding) { @@ -336,13 +336,14 @@ nsBindingManager::ChangeDocumentFor(nsIContent* aContent, nsIDocument* aOldDocum } } - if (mAnonymousContentTable) { + for (PRInt32 i = aOldDocument->GetNumberOfShells() - 1; i >= 0; --i) { + nsCOMPtr shell = dont_AddRef( aOldDocument->GetShellAt(i) ); + NS_ASSERTION(shell != nsnull, "Zoiks! nsIPresShell::ShellAt() broke"); + // See if the element has nsIAnonymousContentCreator-created // anonymous content... - nsISupportsKey key(aContent); - - nsCOMPtr anonymousElements = - getter_AddRefs(NS_REINTERPRET_CAST(nsISupportsArray*, mAnonymousContentTable->Get(&key))); + nsCOMPtr anonymousElements; + shell->GetAnonymousContentFor(aContent, getter_AddRefs(anonymousElements)); if (anonymousElements) { // ...yep, so be sure to update the doc pointer in those @@ -365,48 +366,6 @@ nsBindingManager::ChangeDocumentFor(nsIContent* aContent, nsIDocument* aOldDocum return NS_OK; } -NS_IMETHODIMP -nsBindingManager::SetAnonymousContentFor(nsIContent* aContent, nsISupportsArray* aAnonymousElements) -{ - NS_PRECONDITION(aContent != nsnull, "null ptr"); - if (! aContent) - return NS_ERROR_NULL_POINTER; - - if (!mAnonymousContentTable) - mAnonymousContentTable = new nsSupportsHashtable; - - nsISupportsKey key(aContent); - - nsCOMPtr oldAnonymousElements = - getter_AddRefs(NS_STATIC_CAST(nsISupportsArray*, mAnonymousContentTable->Get(&key))); - - if (oldAnonymousElements && aAnonymousElements) { - // If we're trying to set anonymous content for an element that - // already had anonymous content, then we need to be sure to clean - // up after the old content. (This can happen, for example, when a - // reframe occurs.) - PRUint32 count; - oldAnonymousElements->Count(&count); - - while (PRInt32(--count) >= 0) { - nsCOMPtr isupports( getter_AddRefs(oldAnonymousElements->ElementAt(count)) ); - nsCOMPtr content( do_QueryInterface(isupports) ); - NS_ASSERTION(content != nsnull, "not an nsIContent"); - if (! content) - continue; - - content->SetDocument(nsnull, PR_TRUE, PR_TRUE); - } - } - - if (aAnonymousElements) - mAnonymousContentTable->Put(&key, aAnonymousElements); - else - mAnonymousContentTable->Remove(&key); - - return NS_OK; -} - NS_IMETHODIMP nsBindingManager::ResolveTag(nsIContent* aContent, PRInt32* aNameSpaceID, nsIAtom** aResult) { diff --git a/mozilla/layout/xul/base/src/nsSplitterFrame.cpp b/mozilla/layout/xul/base/src/nsSplitterFrame.cpp index 695b28e64fb..63ababf015f 100644 --- a/mozilla/layout/xul/base/src/nsSplitterFrame.cpp +++ b/mozilla/layout/xul/base/src/nsSplitterFrame.cpp @@ -298,15 +298,6 @@ nsSplitterFrame::CreateAnonymousContent(nsIPresContext* aPresContext, return NS_OK; } -NS_IMETHODIMP -nsSplitterFrame::SetDocumentForAnonymousContent(nsIDocument* aDocument, - PRBool aDeep, - PRBool aCompileEventHandlers) -{ - // XXX WRITE ME - return NS_OK; -} - NS_IMETHODIMP nsSplitterFrame::GetCursor(nsIPresContext* aPresContext, nsPoint& aPoint, diff --git a/mozilla/layout/xul/base/src/nsSplitterFrame.h b/mozilla/layout/xul/base/src/nsSplitterFrame.h index 7009a267a18..9a851167be6 100644 --- a/mozilla/layout/xul/base/src/nsSplitterFrame.h +++ b/mozilla/layout/xul/base/src/nsSplitterFrame.h @@ -71,9 +71,6 @@ public: // nsIAnonymousContentCreator NS_IMETHOD CreateAnonymousContent(nsIPresContext* aPresContext, nsISupportsArray& aAnonymousItems); - NS_IMETHOD SetDocumentForAnonymousContent(nsIDocument* aDocument, - PRBool aDeep, - PRBool aCompileEventHandlers); NS_IMETHOD CreateFrameFor(nsIPresContext* aPresContext, nsIContent * aContent, nsIFrame** aFrame) { if (aFrame) *aFrame = nsnull; return NS_ERROR_FAILURE; } diff --git a/mozilla/rdf/content/src/nsXULDocument.cpp b/mozilla/rdf/content/src/nsXULDocument.cpp index 1b5bde4e0c5..af8a20678de 100644 --- a/mozilla/rdf/content/src/nsXULDocument.cpp +++ b/mozilla/rdf/content/src/nsXULDocument.cpp @@ -1442,6 +1442,19 @@ nsXULDocument::SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject) NS_RELEASE(builder); } } + + // Propagate the out-of-band notification to each PresShell's + // anonymous content as well. This ensures that there aren't + // any accidental script references left in anonymous content + // keeping the document alive. (While not strictly necessary + // -- the PresShell owns us -- it's tidy.) + for (PRInt32 count = mPresShells.Count() - 1; count >= 0; --count) { + nsIPresShell* shell = NS_STATIC_CAST(nsIPresShell*, mPresShells[count]); + if (! shell) + continue; + + shell->ReleaseAnonymousContent(); + } } mScriptGlobalObject = aScriptGlobalObject;