Bug 53969. Move anonymous content storage to pres shell; remove obsolete methods from nsIAnonymousContentCreator. r=dbaron, a=hyatt

This commit is contained in:
waterson%netscape.com 2000-10-09 03:08:41 +00:00
parent cf24862cb3
commit 883ea58a61
42 changed files with 350 additions and 403 deletions

View File

@ -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<nsIPresShell> shell( dont_AddRef(GetShellAt(0)) );
if (shell) {
nsIFrame *kidFrame = nsnull;
shell->GetPrimaryFrameFor(mRootContent, &kidFrame);
while (kidFrame) {
// XXX Don't release a frame!
nsCOMPtr<nsIAnonymousContentCreator> 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();
}
}

View File

@ -68,8 +68,6 @@
#include "nsIDOMViewCSS.h"
#include "nsIXBLService.h"
#include "nsIAnonymousContentCreator.h"
#include "nsLayoutAtoms.h"
#include "nsHTMLAtoms.h"
#include "nsLayoutUtils.h"

View File

@ -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;

View File

@ -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<nsISupportsArray> 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<nsIXBLBinding> 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<nsIPresShell> 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<nsISupportsArray> anonymousElements =
getter_AddRefs(NS_REINTERPRET_CAST(nsISupportsArray*, mAnonymousContentTable->Get(&key)));
nsCOMPtr<nsISupportsArray> 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<nsISupportsArray> 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<nsISupports> isupports( getter_AddRefs(oldAnonymousElements->ElementAt(count)) );
nsCOMPtr<nsIContent> 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)
{

View File

@ -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;

View File

@ -5479,13 +5479,8 @@ nsCSSFrameConstructor::CreateAnonymousFrames(nsIPresShell* aPresShell,
anonymousItems->Count(&count);
if (count) {
// Inform the binding manager about the anonymous content
nsCOMPtr<nsIBindingManager> 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

View File

@ -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

View File

@ -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<nsISupportsArray> 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<nsISupports> isupports( getter_AddRefs(oldAnonymousElements->ElementAt(count)) );
nsCOMPtr<nsIContent> 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<nsISupports> isupports( getter_AddRefs(anonymousElements->ElementAt(count)) );
nsCOMPtr<nsIContent> 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)

View File

@ -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

View File

@ -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<nsIPresShell> shell( dont_AddRef(GetShellAt(0)) );
if (shell) {
nsIFrame *kidFrame = nsnull;
shell->GetPrimaryFrameFor(mRootContent, &kidFrame);
while (kidFrame) {
// XXX Don't release a frame!
nsCOMPtr<nsIAnonymousContentCreator> 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();
}
}

View File

@ -68,8 +68,6 @@
#include "nsIDOMViewCSS.h"
#include "nsIXBLService.h"
#include "nsIAnonymousContentCreator.h"
#include "nsLayoutAtoms.h"
#include "nsHTMLAtoms.h"
#include "nsLayoutUtils.h"

View File

@ -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,

View File

@ -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);

View File

@ -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)

View File

@ -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; }

View File

@ -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)

View File

@ -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);

View File

@ -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)

View File

@ -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; }

View File

@ -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<nsIContent> 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<nsIContent> vcontent;
vframe->GetContent(getter_AddRefs(vcontent));
if (vcontent) {
vcontent->SetDocument(aDocument, aDeep, aCompileEventHandlers);
}
}
}
return NS_OK;
}
NS_IMETHODIMP
nsGfxScrollFrame::Destroy(nsIPresContext* aPresContext)

View File

@ -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; }

View File

@ -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,

View File

@ -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<nsIContent> 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<nsIContent> vcontent;
vframe->GetContent(getter_AddRefs(vcontent));
if (vcontent) {
vcontent->SetDocument(aDocument, aDeep, aCompileEventHandlers);
}
}
}
return NS_OK;
}
NS_IMETHODIMP
nsGfxScrollFrame::Destroy(nsIPresContext* aPresContext)

View File

@ -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; }

View File

@ -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,

View File

@ -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<nsISupportsArray> 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<nsISupports> isupports( getter_AddRefs(oldAnonymousElements->ElementAt(count)) );
nsCOMPtr<nsIContent> 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<nsISupports> isupports( getter_AddRefs(anonymousElements->ElementAt(count)) );
nsCOMPtr<nsIContent> 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)

View File

@ -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,

View File

@ -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);

View File

@ -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)

View File

@ -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; }

View File

@ -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)

View File

@ -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);

View File

@ -1976,22 +1976,6 @@ nsGfxTextControlFrame2::CreateAnonymousContent(nsIPresContext* aPresContext,
return NS_OK;
}
NS_IMETHODIMP
nsGfxTextControlFrame2::SetDocumentForAnonymousContent(nsIDocument* aDocument,
PRBool aDeep,
PRBool aCompileEventHandlers)
{
if (mEditor) {
nsCOMPtr<nsIDOMElement> root;
mEditor->GetRootElement(getter_AddRefs(root));
if (root) {
nsCOMPtr<nsIContent> rootContent( do_QueryInterface(root) );
rootContent->SetDocument(aDocument, aDeep, aCompileEventHandlers);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsGfxTextControlFrame2::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,

View File

@ -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);

View File

@ -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)

View File

@ -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; }

View File

@ -5479,13 +5479,8 @@ nsCSSFrameConstructor::CreateAnonymousFrames(nsIPresShell* aPresShell,
anonymousItems->Count(&count);
if (count) {
// Inform the binding manager about the anonymous content
nsCOMPtr<nsIBindingManager> 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

View File

@ -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;

View File

@ -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<nsISupportsArray> 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<nsIXBLBinding> 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<nsIPresShell> 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<nsISupportsArray> anonymousElements =
getter_AddRefs(NS_REINTERPRET_CAST(nsISupportsArray*, mAnonymousContentTable->Get(&key)));
nsCOMPtr<nsISupportsArray> 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<nsISupportsArray> 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<nsISupports> isupports( getter_AddRefs(oldAnonymousElements->ElementAt(count)) );
nsCOMPtr<nsIContent> 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)
{

View File

@ -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,

View File

@ -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; }

View File

@ -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;