Eliminate nsIContent::SetDocument/SetParent/SetBindingParent in favor of
BindToTree and UnbindFromTree methods. Bug 286000, r=sicking, sr=jst
This commit is contained in:
Родитель
a8306ce1ab
Коммит
9b1db9f768
|
@ -60,8 +60,8 @@ class nsIURI;
|
|||
|
||||
// IID for the nsIContent interface
|
||||
#define NS_ICONTENT_IID \
|
||||
{ 0x38824dfc, 0x5a2d, 0x4b86, \
|
||||
{ 0x8c, 0x49, 0xcc, 0xbb, 0x70, 0x03, 0x47, 0x51 } }
|
||||
{ 0x10caf6a4, 0x8891, 0x46c9, \
|
||||
{ 0x9b, 0x6c, 0x6d, 0xc8, 0xdf, 0x01, 0x2d, 0x29 } }
|
||||
|
||||
/**
|
||||
* A node of content in a document's content model. This interface
|
||||
|
@ -82,16 +82,51 @@ public:
|
|||
virtual nsIDocument* GetDocument() const = 0;
|
||||
|
||||
/**
|
||||
* Set the document for this content.
|
||||
*
|
||||
* @param aDocument the new document to set (could be null)
|
||||
* @param aDeep whether to set the document on children
|
||||
* Bind this content node to a tree. If this method throws, the caller must
|
||||
* call UnbindFromTree() on the node. In the typical case of a node being
|
||||
* appended to a parent, this will be called after the node has been added to
|
||||
* the parent's child list and before nsIDocumentObserver notifications for
|
||||
* the addition are dispatched.
|
||||
* @param aDocument The new document for the content node. Must match the
|
||||
* current document of aParent, if aParent is not null.
|
||||
* May not be null if aParent is null.
|
||||
* @param aParent The new parent for the content node. May be null if the
|
||||
* node is being bound as a direct child of the document.
|
||||
* @param aBindingParent The new binding parent for the content node.
|
||||
* This is allowed to be null. In that case, the
|
||||
* binding parent of aParent, if any, will be used.
|
||||
* @param aCompileEventHandlers whether to initialize the event handlers in
|
||||
* the document (used by nsXULElement)
|
||||
* @note either aDocument or aParent must be non-null. If both are null,
|
||||
* this method _will_ crash.
|
||||
* @note This method must not be called by consumers of nsIContent on a node
|
||||
* that is already bound to a tree. Call UnbindFromTree first.
|
||||
* @note This method will handle rebinding descendants appropriately (eg
|
||||
* changing their binding parent as needed).
|
||||
* @note This method does not add the content node to aParent's child list
|
||||
* @throws NS_ERROR_OUT_OF_MEMORY if that happens
|
||||
*/
|
||||
virtual void SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers) = 0;
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers) = 0;
|
||||
|
||||
/**
|
||||
* Unbind this content node from a tree. This will set its current document
|
||||
* and binding parent to null. In the typical case of a node being removed
|
||||
* from a parent, this will be called after it has been removed from the
|
||||
* parent's child list and after the nsIDocumentObserver notifications for
|
||||
* the removal have been dispatched.
|
||||
* @param aDeep Whether to recursively unbind the entire subtree rooted at
|
||||
* this node. The only time PR_FALSE should be passed is when the
|
||||
* parent node of the content is being destroyed.
|
||||
* @param aNullParent Whether to null out the parent pointer as well. This
|
||||
* is usually desirable. This argument should only be false while
|
||||
* recursively calling UnbindFromTree when a subtree is detached.
|
||||
* @note This method is safe to call on nodes that are not bound to a tree.
|
||||
*/
|
||||
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
|
||||
PRBool aNullParent = PR_TRUE) = 0;
|
||||
|
||||
/**
|
||||
* Returns true if the content has an ancestor that is a document.
|
||||
*
|
||||
|
@ -128,14 +163,6 @@ public:
|
|||
return NS_REINTERPRET_CAST(nsIContent *, mParentPtrBits & ~kParentBitMask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the parent content for this content. (This does not add the child to
|
||||
* its parent's child list.) This clobbers the low 2 bits of the parent
|
||||
* pointer, so subclasses which use those bits should override this.
|
||||
* @param aParent the new parent content to set (could be null)
|
||||
*/
|
||||
virtual void SetParent(nsIContent* aParent) = 0;
|
||||
|
||||
/**
|
||||
* Get whether this content is C++-generated anonymous content
|
||||
* @see nsIAnonymousContentCreator
|
||||
|
@ -198,6 +225,7 @@ public:
|
|||
* @param aNotify whether to notify the document that the insert has
|
||||
* occurred
|
||||
* @param aDeepSetDocument whether to set document on all children of aKid
|
||||
* XXXbz aDeepSetDocument is now unused
|
||||
*/
|
||||
virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
|
||||
PRBool aNotify, PRBool aDeepSetDocument) = 0;
|
||||
|
@ -209,6 +237,7 @@ public:
|
|||
* @param aNotify whether to notify the document that the replace has
|
||||
* occurred
|
||||
* @param aDeepSetDocument whether to set document on all children of aKid
|
||||
* XXXbz aDeepSetDocument is now unused
|
||||
*/
|
||||
virtual nsresult AppendChildTo(nsIContent* aKid, PRBool aNotify,
|
||||
PRBool aDeepSetDocument) = 0;
|
||||
|
@ -480,15 +509,6 @@ public:
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets content node with the binding responsible for our construction (and
|
||||
* existence). Used by anonymous content (XBL-generated). null for all
|
||||
* explicit content.
|
||||
*
|
||||
* @param aContent the new binding parent
|
||||
*/
|
||||
virtual nsresult SetBindingParent(nsIContent* aContent) = 0;
|
||||
|
||||
/**
|
||||
* Gets content node with the binding responsible for our construction (and
|
||||
* existence). Used by anonymous content (XBL-generated). null for all
|
||||
|
|
|
@ -617,7 +617,9 @@ nsAttrAndChildArray::Clear()
|
|||
PRUint32 end = slotCount * ATTRSIZE + ChildCount();
|
||||
for (i = slotCount * ATTRSIZE; i < end; ++i) {
|
||||
nsIContent* child = NS_STATIC_CAST(nsIContent*, mImpl->mBuffer[i]);
|
||||
child->SetParent(nsnull); // XXX is it better to let the owner do this?
|
||||
// making this PR_FALSE so tree teardown doesn't end up being
|
||||
// O(N*D) (number of nodes times average depth of tree).
|
||||
child->UnbindFromTree(PR_FALSE); // XXX is it better to let the owner do this?
|
||||
NS_RELEASE(child);
|
||||
}
|
||||
|
||||
|
|
|
@ -543,13 +543,15 @@ nsDocument::~nsDocument()
|
|||
}
|
||||
|
||||
if (mRootContent) {
|
||||
if (mRootContent->GetDocument()) {
|
||||
if (mRootContent->GetCurrentDoc()) {
|
||||
NS_ASSERTION(mRootContent->GetCurrentDoc() == this,
|
||||
"Unexpected current doc in root content");
|
||||
// The root content still has a pointer back to the document,
|
||||
// clear the document pointer in all children.
|
||||
|
||||
PRInt32 count = mChildren.Count();
|
||||
for (indx = 0; indx < count; ++indx) {
|
||||
mChildren[indx]->SetDocument(nsnull, PR_TRUE, PR_FALSE);
|
||||
mChildren[indx]->UnbindFromTree();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -751,7 +753,7 @@ nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup)
|
|||
for (i = 0; i < count; i++) {
|
||||
nsCOMPtr<nsIContent> content = mChildren[i];
|
||||
|
||||
content->SetDocument(nsnull, PR_TRUE, PR_TRUE);
|
||||
content->UnbindFromTree();
|
||||
ContentRemoved(nsnull, content, i);
|
||||
}
|
||||
mChildren.Clear();
|
||||
|
@ -1837,7 +1839,7 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject)
|
|||
mIsGoingAway = PR_TRUE;
|
||||
|
||||
for (indx = 0; indx < count; ++indx) {
|
||||
mChildren[indx]->SetDocument(nsnull, PR_TRUE, PR_TRUE);
|
||||
mChildren[indx]->UnbindFromTree();
|
||||
}
|
||||
|
||||
// Propagate the out-of-band notification to each PresShell's
|
||||
|
@ -3291,7 +3293,9 @@ nsDocument::InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild,
|
|||
}
|
||||
|
||||
indx = mChildren.Count();
|
||||
mChildren.AppendObject(content);
|
||||
if (!mChildren.AppendObject(content)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIContent> refContent(do_QueryInterface(aRefChild));
|
||||
|
@ -3311,7 +3315,9 @@ nsDocument::InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild,
|
|||
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
|
||||
}
|
||||
|
||||
mChildren.InsertObjectAt(content, indx);
|
||||
if (!mChildren.InsertObjectAt(content, indx)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
// If we get here, we've succesfully inserted content into the
|
||||
|
@ -3320,7 +3326,16 @@ nsDocument::InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild,
|
|||
mRootContent = content;
|
||||
}
|
||||
|
||||
content->SetDocument(this, PR_TRUE, PR_TRUE);
|
||||
rv = content->BindToTree(this, nsnull, nsnull, PR_TRUE);
|
||||
if (NS_FAILED(rv)) {
|
||||
mChildren.RemoveObjectAt(indx);
|
||||
if (mRootContent == content) {
|
||||
mRootContent = nsnull;
|
||||
}
|
||||
content->UnbindFromTree();
|
||||
return rv;
|
||||
}
|
||||
|
||||
ContentInserted(nsnull, content, indx);
|
||||
|
||||
NS_ADDREF(*aReturn = aNewChild);
|
||||
|
@ -3371,16 +3386,28 @@ nsDocument::ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild,
|
|||
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
|
||||
}
|
||||
|
||||
ContentRemoved(nsnull, refContent, indx);
|
||||
refContent->SetDocument(nsnull, PR_TRUE, PR_TRUE);
|
||||
mChildren.RemoveObjectAt(indx);
|
||||
|
||||
ContentRemoved(nsnull, refContent, indx);
|
||||
refContent->UnbindFromTree();
|
||||
|
||||
mChildren.ReplaceObjectAt(content, indx);
|
||||
// This is OK because we checked above.
|
||||
if (nodeType == nsIDOMNode::ELEMENT_NODE) {
|
||||
mRootContent = content;
|
||||
}
|
||||
|
||||
content->SetDocument(this, PR_TRUE, PR_TRUE);
|
||||
mChildren.InsertObjectAt(content, indx);
|
||||
|
||||
rv = content->BindToTree(this, nsnull, nsnull, PR_TRUE);
|
||||
if (NS_FAILED(rv)) {
|
||||
mChildren.RemoveObjectAt(indx);
|
||||
if (mRootContent == content) {
|
||||
mRootContent = nsnull;
|
||||
}
|
||||
content->UnbindFromTree();
|
||||
return rv;
|
||||
}
|
||||
|
||||
ContentInserted(nsnull, content, indx);
|
||||
|
||||
NS_ADDREF(*aReturn = aNewChild);
|
||||
|
@ -3411,7 +3438,7 @@ nsDocument::RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
|
|||
if (content == mRootContent)
|
||||
mRootContent = nsnull;
|
||||
|
||||
content->SetDocument(nsnull, PR_TRUE, PR_TRUE);
|
||||
content->UnbindFromTree();
|
||||
|
||||
*aReturn = aOldChild;
|
||||
NS_ADDREF(aOldChild);
|
||||
|
|
|
@ -227,7 +227,11 @@ nsDocumentFragment::DisconnectChildren()
|
|||
PRUint32 i, count = GetChildCount();
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
GetChildAt(i)->SetParent(nsnull);
|
||||
NS_ASSERTION(GetChildAt(i)->GetCurrentDoc() == nsnull,
|
||||
"How did we get a child with a current doc?");
|
||||
// Safe to unbind PR_FALSE, since kids should never have a current document
|
||||
// or a binding parent
|
||||
GetChildAt(i)->UnbindFromTree(PR_FALSE);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -237,6 +241,8 @@ NS_IMETHODIMP
|
|||
nsDocumentFragment::ReconnectChildren()
|
||||
{
|
||||
PRUint32 i, count = GetChildCount();
|
||||
NS_PRECONDITION(GetCurrentDoc() == nsnull,
|
||||
"We really shouldn't have a current doc!");
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
nsIContent *child = GetChildAt(i);
|
||||
|
@ -246,6 +252,7 @@ nsDocumentFragment::ReconnectChildren()
|
|||
// This is potentially a O(n**2) operation, but it should only
|
||||
// happen in error cases (such as out of memory or something
|
||||
// similar) so we don't care for now.
|
||||
// XXXbz I don't think this is O(n**2) with our IndexOf cache, is it?
|
||||
|
||||
PRInt32 indx = parent->IndexOf(child);
|
||||
|
||||
|
@ -254,7 +261,15 @@ nsDocumentFragment::ReconnectChildren()
|
|||
}
|
||||
}
|
||||
|
||||
child->SetParent(this);
|
||||
nsresult rv = child->BindToTree(nsnull, this, nsnull, PR_FALSE);
|
||||
if (NS_FAILED(rv)) {
|
||||
// It's all bad now... Just forget about this kid, I guess
|
||||
child->UnbindFromTree();
|
||||
mAttrsAndChildren.RemoveChildAt(i);
|
||||
// Adjust count and iterator accordingly
|
||||
--count;
|
||||
--i;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -590,24 +590,64 @@ nsGenericDOMDataNode::GetDocument() const
|
|||
return GetCurrentDoc();
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericDOMDataNode::SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers)
|
||||
nsresult
|
||||
nsGenericDOMDataNode::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers)
|
||||
{
|
||||
NS_PRECONDITION(aParent || aDocument, "Must have document if no parent!");
|
||||
// XXXbz XUL elements are confused about their current doc when they're
|
||||
// cloned, so we don't assert if aParent is a XUL element and aDocument is
|
||||
// null, even if aParent->GetCurrentDoc() is non-null
|
||||
// NS_PRECONDITION(!aParent || aDocument == aParent->GetCurrentDoc(),
|
||||
// "aDocument must be current doc of aParent");
|
||||
NS_PRECONDITION(!aParent ||
|
||||
(aParent->IsContentOfType(eXUL) && aDocument == nsnull) ||
|
||||
aDocument == aParent->GetCurrentDoc(),
|
||||
"aDocument must be current doc of aParent");
|
||||
NS_PRECONDITION(!GetCurrentDoc(), "Already have a document. Unbind first!");
|
||||
// Note that as we recurse into the kids, they'll have a non-null parent. So
|
||||
// only assert if our parent is _changing_ while we have a parent.
|
||||
NS_PRECONDITION(!GetParent() || aParent == GetParent(),
|
||||
"Already have a parent. Unbind first!");
|
||||
// XXXbz GetBindingParent() is broken for us, so can't assert
|
||||
// anything about it yet.
|
||||
// NS_PRECONDITION(!GetBindingParent() ||
|
||||
// aBindingParent == GetBindingParent() ||
|
||||
// (aParent &&
|
||||
// aParent->GetBindingParent() == GetBindingParent()),
|
||||
// "Already have a binding parent. Unbind first!");
|
||||
|
||||
// XXXbz we don't keep track of the binding parent yet. We should.
|
||||
|
||||
// Set parent
|
||||
PtrBits new_bits = NS_REINTERPRET_CAST(PtrBits, aParent);
|
||||
new_bits |= mParentPtrBits & nsIContent::kParentBitMask;
|
||||
mParentPtrBits = new_bits;
|
||||
|
||||
// Set document
|
||||
mDocument = aDocument;
|
||||
if (mDocument && mText.IsBidi()) {
|
||||
aDocument->SetBidiEnabled(PR_TRUE);
|
||||
mDocument->SetBidiEnabled(PR_TRUE);
|
||||
}
|
||||
|
||||
NS_POSTCONDITION(aDocument == GetCurrentDoc(), "Bound to wrong document");
|
||||
NS_POSTCONDITION(aParent == GetParent(), "Bound to wrong parent");
|
||||
// XXXbz GetBindingParent() is broken for us, so can't assert
|
||||
// anything about it yet.
|
||||
// NS_POSTCONDITION(aBindingParent = GetBindingParent(),
|
||||
// "Bound to wrong binding parent");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericDOMDataNode::SetParent(nsIContent* aParent)
|
||||
nsGenericDOMDataNode::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
{
|
||||
PtrBits new_bits = NS_REINTERPRET_CAST(PtrBits, aParent);
|
||||
|
||||
new_bits |= mParentPtrBits & nsIContent::kParentBitMask;
|
||||
|
||||
mParentPtrBits = new_bits;
|
||||
mDocument = nsnull;
|
||||
if (aNullParent) {
|
||||
mParentPtrBits &= nsIContent::kParentBitMask;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -921,12 +961,6 @@ nsGenericDOMDataNode::GetBindingParent() const
|
|||
return parent ? parent->GetBindingParent() : nsnull;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericDOMDataNode::SetBindingParent(nsIContent* aParent)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsGenericDOMDataNode::IsContentOfType(PRUint32 aFlags) const
|
||||
{
|
||||
|
|
|
@ -166,8 +166,11 @@ public:
|
|||
|
||||
// Implementation for nsIContent
|
||||
nsIDocument* GetDocument() const;
|
||||
virtual void SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
|
||||
PRBool aNullParent = PR_TRUE);
|
||||
PRBool IsInDoc() const
|
||||
{
|
||||
return !!mDocument;
|
||||
|
@ -190,7 +193,6 @@ public:
|
|||
return parent ? parent->GetOwnerDoc() : nsnull;
|
||||
}
|
||||
|
||||
virtual void SetParent(nsIContent* aParent);
|
||||
virtual PRBool IsNativeAnonymous() const;
|
||||
virtual void SetNativeAnonymous(PRBool aAnonymous);
|
||||
virtual PRInt32 GetNameSpaceID() const;
|
||||
|
@ -226,7 +228,6 @@ public:
|
|||
virtual const nsVoidArray *GetRangeList() const;
|
||||
|
||||
virtual nsIContent *GetBindingParent() const;
|
||||
virtual nsresult SetBindingParent(nsIContent* aParent);
|
||||
virtual PRBool IsContentOfType(PRUint32 aFlags) const;
|
||||
|
||||
virtual nsresult GetListenerManager(nsIEventListenerManager **aResult);
|
||||
|
|
|
@ -1754,98 +1754,160 @@ nsGenericElement::Normalize()
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsGenericElement::SetDocumentInChildrenOf(nsIContent* aContent,
|
||||
nsIDocument* aDocument,
|
||||
PRBool aCompileEventHandlers)
|
||||
nsresult
|
||||
nsGenericElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers)
|
||||
{
|
||||
PRUint32 i, n = aContent->GetChildCount();
|
||||
NS_PRECONDITION(aParent || aDocument, "Must have document if no parent!");
|
||||
// XXXbz XUL elements are confused about their current doc when they're
|
||||
// cloned, so we don't assert if aParent is a XUL element and aDocument is
|
||||
// null, even if aParent->GetCurrentDoc() is non-null
|
||||
// NS_PRECONDITION(!aParent || aDocument == aParent->GetCurrentDoc(),
|
||||
// "aDocument must be current doc of aParent");
|
||||
NS_PRECONDITION(!aParent ||
|
||||
(aParent->IsContentOfType(eXUL) && aDocument == nsnull) ||
|
||||
aDocument == aParent->GetCurrentDoc(),
|
||||
"aDocument must be current doc of aParent");
|
||||
NS_PRECONDITION(!GetCurrentDoc(), "Already have a document. Unbind first!");
|
||||
// Note that as we recurse into the kids, they'll have a non-null parent. So
|
||||
// only assert if our parent is _changing_ while we have a parent.
|
||||
NS_PRECONDITION(!GetParent() || aParent == GetParent(),
|
||||
"Already have a parent. Unbind first!");
|
||||
NS_PRECONDITION(!GetBindingParent() ||
|
||||
aBindingParent == GetBindingParent() ||
|
||||
(!aBindingParent && aParent &&
|
||||
aParent->GetBindingParent() == GetBindingParent()),
|
||||
"Already have a binding parent. Unbind first!");
|
||||
|
||||
if (!aBindingParent && aParent) {
|
||||
aBindingParent = aParent->GetBindingParent();
|
||||
}
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
nsIContent *child = aContent->GetChildAt(i);
|
||||
// First set the binding parent
|
||||
if (aBindingParent) {
|
||||
nsDOMSlots *slots = GetDOMSlots();
|
||||
|
||||
if (child) {
|
||||
child->SetDocument(aDocument, PR_TRUE, aCompileEventHandlers);
|
||||
if (!slots) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
slots->mBindingParent = aBindingParent; // Weak, so no addref happens.
|
||||
}
|
||||
|
||||
// Now set the parent; make sure to preserve the bits we have stashed there
|
||||
// Note that checking whether aParent == GetParent() is probably not worth it
|
||||
// here.
|
||||
PtrBits new_bits = NS_REINTERPRET_CAST(PtrBits, aParent);
|
||||
new_bits |= mParentPtrBits & nsIContent::kParentBitMask;
|
||||
mParentPtrBits = new_bits;
|
||||
|
||||
nsresult rv;
|
||||
|
||||
// Finally, set the document
|
||||
if (aDocument) {
|
||||
// Notify XBL- & nsIAnonymousContentCreator-generated
|
||||
// anonymous content that the document is changing.
|
||||
// XXXbz ordering issues here? Probably not, since ChangeDocumentFor is
|
||||
// just pretty broken anyway.... Need to get it working.
|
||||
// XXXbz XBL doesn't handle this (asserts), and we don't really want
|
||||
// to be doing this during parsing anyway... sort this out.
|
||||
// aDocument->BindingManager()->ChangeDocumentFor(this, nsnull,
|
||||
// aDocument);
|
||||
|
||||
// Being added to a document.
|
||||
mParentPtrBits |= PARENT_BIT_INDOCUMENT;
|
||||
|
||||
// check the document on the nodeinfo to see whether we need a
|
||||
// new nodeinfo
|
||||
// XXXbz sXBL/XBL2 issue!
|
||||
nsIDocument *ownerDocument = GetOwnerDoc();
|
||||
if (aDocument != ownerDocument) {
|
||||
|
||||
if (HasProperties()) {
|
||||
ownerDocument->PropertyTable()->DeleteAllPropertiesFor(this);
|
||||
}
|
||||
|
||||
// get a new nodeinfo
|
||||
nsNodeInfoManager* nodeInfoManager = aDocument->NodeInfoManager();
|
||||
if (nodeInfoManager) {
|
||||
nsCOMPtr<nsINodeInfo> newNodeInfo;
|
||||
rv = nodeInfoManager->GetNodeInfo(mNodeInfo->NameAtom(),
|
||||
mNodeInfo->GetPrefixAtom(),
|
||||
mNodeInfo->NamespaceID(),
|
||||
getter_AddRefs(newNodeInfo));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ASSERTION(newNodeInfo, "GetNodeInfo lies");
|
||||
mNodeInfo.swap(newNodeInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now recurse into our kids
|
||||
PRUint32 i, n = GetChildCount();
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
rv = mAttrsAndChildren.ChildAt(i)->BindToTree(aDocument, this,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// XXXbz script execution during binding can trigger some of these
|
||||
// postcondition asserts.... But we do want that, since things will
|
||||
// generally be quite broken when that happens.
|
||||
NS_POSTCONDITION(aDocument == GetCurrentDoc(), "Bound to wrong document");
|
||||
NS_POSTCONDITION(aParent == GetParent(), "Bound to wrong parent");
|
||||
NS_POSTCONDITION(aBindingParent == GetBindingParent(),
|
||||
"Bound to wrong binding parent");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericElement::SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers)
|
||||
nsGenericElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
{
|
||||
NS_PRECONDITION(aDeep || (!GetCurrentDoc() && !GetBindingParent()),
|
||||
"Shallow unbind won't clear document and binding parent on "
|
||||
"kids!");
|
||||
// Make sure to unbind this node before doing the kids
|
||||
nsIDocument *document = GetCurrentDoc();
|
||||
if (aDocument != document) {
|
||||
// If we were part of a document, make sure we get rid of the
|
||||
// script context reference to our script object so that our
|
||||
// script object can be freed (or collected).
|
||||
if (document) {
|
||||
// Notify XBL- & nsIAnonymousContentCreator-generated
|
||||
// anonymous content that the document is changing.
|
||||
document->BindingManager()->ChangeDocumentFor(this, document, nsnull);
|
||||
|
||||
if (document && aDeep) {
|
||||
// Notify XBL- & nsIAnonymousContentCreator-generated
|
||||
// anonymous content that the document is changing.
|
||||
document->BindingManager()->ChangeDocumentFor(this, document, aDocument);
|
||||
nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(this);
|
||||
|
||||
nsCOMPtr<nsIDOMElement> domElement;
|
||||
QueryInterface(NS_GET_IID(nsIDOMElement), getter_AddRefs(domElement));
|
||||
|
||||
if (domElement) {
|
||||
nsCOMPtr<nsIDOMNSDocument> nsDoc(do_QueryInterface(document));
|
||||
nsDoc->SetBoxObjectFor(domElement, nsnull);
|
||||
}
|
||||
if (domElement) {
|
||||
nsCOMPtr<nsIDOMNSDocument> nsDoc = do_QueryInterface(document);
|
||||
nsDoc->SetBoxObjectFor(domElement, nsnull);
|
||||
}
|
||||
}
|
||||
|
||||
if (aDocument) {
|
||||
mParentPtrBits |= PARENT_BIT_INDOCUMENT;
|
||||
|
||||
// check the document on the nodeinfo to see whether we need a
|
||||
// new nodeinfo
|
||||
// XXXbz sXBL/XBL2 issue!
|
||||
nsIDocument *ownerDocument = GetOwnerDoc();
|
||||
if (aDocument != ownerDocument) {
|
||||
|
||||
if (HasProperties()) {
|
||||
ownerDocument->PropertyTable()->DeleteAllPropertiesFor(this);
|
||||
}
|
||||
|
||||
// get a new nodeinfo
|
||||
nsNodeInfoManager* nodeInfoManager = aDocument->NodeInfoManager();
|
||||
if (nodeInfoManager) {
|
||||
nsCOMPtr<nsINodeInfo> newNodeInfo;
|
||||
nodeInfoManager->GetNodeInfo(mNodeInfo->NameAtom(),
|
||||
mNodeInfo->GetPrefixAtom(),
|
||||
mNodeInfo->NamespaceID(),
|
||||
getter_AddRefs(newNodeInfo));
|
||||
if (newNodeInfo) {
|
||||
mNodeInfo.swap(newNodeInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
mParentPtrBits &= ~PARENT_BIT_INDOCUMENT;
|
||||
}
|
||||
// Unset things in the reverse order from how we set them in BindToTree
|
||||
mParentPtrBits &= ~PARENT_BIT_INDOCUMENT;
|
||||
|
||||
if (aNullParent) {
|
||||
// Just mask it out
|
||||
mParentPtrBits &= nsIContent::kParentBitMask;
|
||||
}
|
||||
|
||||
nsDOMSlots *slots = GetExistingDOMSlots();
|
||||
if (slots) {
|
||||
slots->mBindingParent = nsnull;
|
||||
}
|
||||
|
||||
if (aDeep) {
|
||||
SetDocumentInChildrenOf(this, aDocument, aCompileEventHandlers);
|
||||
}
|
||||
}
|
||||
// Do the kids
|
||||
PRUint32 i, n = GetChildCount();
|
||||
|
||||
|
||||
void
|
||||
nsGenericElement::SetParent(nsIContent* aParent)
|
||||
{
|
||||
PtrBits new_bits = NS_REINTERPRET_CAST(PtrBits, aParent);
|
||||
|
||||
new_bits |= mParentPtrBits & nsIContent::kParentBitMask;
|
||||
|
||||
mParentPtrBits = new_bits;
|
||||
|
||||
if (aParent) {
|
||||
nsIContent* bindingPar = aParent->GetBindingParent();
|
||||
if (bindingPar)
|
||||
SetBindingParent(bindingPar);
|
||||
for (i = 0; i < n; ++i) {
|
||||
// Note that we pass PR_FALSE for aNullParent here, since we don't want
|
||||
// the kids to forget us. We _do_ want them to forget their binding
|
||||
// parent, though, since this only walks non-anonymous kids.
|
||||
mAttrsAndChildren.ChildAt(i)->UnbindFromTree(PR_TRUE, PR_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2505,30 +2567,6 @@ nsGenericElement::GetBindingParent() const
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericElement::SetBindingParent(nsIContent* aParent)
|
||||
{
|
||||
nsDOMSlots *slots = GetDOMSlots();
|
||||
|
||||
if (!slots) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
slots->mBindingParent = aParent; // Weak, so no addref happens.
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (aParent) {
|
||||
PRUint32 count = GetChildCount();
|
||||
|
||||
for (PRUint32 i = 0; i < count; ++i) {
|
||||
rv |= GetChildAt(i)->SetBindingParent(aParent);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsGenericElement::IsContentOfType(PRUint32 aFlags) const
|
||||
{
|
||||
|
@ -2618,10 +2656,22 @@ nsGenericElement::InsertChildAt(nsIContent* aKid,
|
|||
nsresult rv = mAttrsAndChildren.InsertChildAt(aKid, aIndex);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aKid->SetParent(this);
|
||||
rv = aKid->BindToTree(document, this, nsnull, PR_TRUE);
|
||||
if (NS_FAILED(rv)) {
|
||||
mAttrsAndChildren.RemoveChildAt(aIndex);
|
||||
aKid->UnbindFromTree();
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsRange::OwnerChildInserted(this, aIndex);
|
||||
if (document) {
|
||||
aKid->SetDocument(document, aDeepSetDocument, PR_TRUE);
|
||||
// The kid may have removed us from the document, so recheck that we're still
|
||||
// in the document before proceeding. Also, the kid may have just removed
|
||||
// itself, in which case we don't really want to fire ContentAppended or a
|
||||
// mutation event.
|
||||
// XXXbz What if the kid just moved us in the document? Scripts suck. We
|
||||
// really need to stop running them while we're in the middle of modifying
|
||||
// the DOM....
|
||||
if (document && document == GetCurrentDoc() && aKid->GetParent() == this) {
|
||||
if (aNotify) {
|
||||
if (isAppend) {
|
||||
document->ContentAppended(this, aIndex);
|
||||
|
@ -2653,11 +2703,22 @@ nsGenericElement::AppendChildTo(nsIContent* aKid, PRBool aNotify,
|
|||
nsresult rv = mAttrsAndChildren.AppendChild(aKid);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aKid->SetParent(this);
|
||||
rv = aKid->BindToTree(document, this, nsnull, PR_TRUE);
|
||||
if (NS_FAILED(rv)) {
|
||||
mAttrsAndChildren.RemoveChildAt(GetChildCount() - 1);
|
||||
aKid->UnbindFromTree();
|
||||
return rv;
|
||||
}
|
||||
// ranges don't need adjustment since new child is at end of list
|
||||
|
||||
if (document) {
|
||||
aKid->SetDocument(document, aDeepSetDocument, PR_TRUE);
|
||||
// The kid may have removed us from the document, so recheck that we're still
|
||||
// in the document before proceeding. Also, the kid may have just removed
|
||||
// itself, in which case we don't really want to fire ContentAppended or a
|
||||
// mutation event.
|
||||
// XXXbz What if the kid just moved us in the document? Scripts suck. We
|
||||
// really need to stop running them while we're in the middle of modifying
|
||||
// the DOM....
|
||||
if (document && document == GetCurrentDoc() && aKid->GetParent() == this) {
|
||||
if (aNotify) {
|
||||
document->ContentAppended(this, GetChildCount() - 1);
|
||||
}
|
||||
|
@ -2699,8 +2760,7 @@ nsGenericElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
|
|||
document->ContentRemoved(this, oldKid, aIndex);
|
||||
}
|
||||
|
||||
oldKid->SetDocument(nsnull, PR_TRUE, PR_TRUE);
|
||||
oldKid->SetParent(nsnull);
|
||||
oldKid->UnbindFromTree();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -3267,7 +3327,9 @@ nsGenericElement::AddScriptEventListener(nsIAtom* aAttribute,
|
|||
|
||||
// If we have a document, and it has a script global, add the
|
||||
// event listener on the global. If not, proceed as normal.
|
||||
nsIDocument *document = GetCurrentDoc();
|
||||
// XXXbz should we instead use GetCurrentDoc() here, override
|
||||
// BindToTree for those classes and munge event listeners there?
|
||||
nsIDocument *document = GetOwnerDoc();
|
||||
if (document && (sgo = document->GetScriptGlobalObject())) {
|
||||
nsCOMPtr<nsIDOMEventReceiver> receiver(do_QueryInterface(sgo));
|
||||
NS_ENSURE_TRUE(receiver, NS_ERROR_FAILURE);
|
||||
|
|
|
@ -372,8 +372,11 @@ public:
|
|||
{
|
||||
return IsInDoc() ? GetOwnerDoc() : nsnull;
|
||||
}
|
||||
virtual void SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
|
||||
PRBool aNullParent = PR_TRUE);
|
||||
PRBool IsInDoc() const
|
||||
{
|
||||
return mParentPtrBits & PARENT_BIT_INDOCUMENT;
|
||||
|
@ -382,7 +385,6 @@ public:
|
|||
{
|
||||
return nsContentUtils::GetDocument(mNodeInfo);
|
||||
}
|
||||
virtual void SetParent(nsIContent* aParent);
|
||||
virtual PRBool IsNativeAnonymous() const;
|
||||
virtual void SetNativeAnonymous(PRBool aAnonymous);
|
||||
virtual PRInt32 GetNameSpaceID() const;
|
||||
|
@ -426,7 +428,6 @@ public:
|
|||
virtual void SetContentID(PRUint32 aID);
|
||||
virtual void SetFocus(nsPresContext* aContext);
|
||||
virtual nsIContent *GetBindingParent() const;
|
||||
virtual nsresult SetBindingParent(nsIContent* aParent);
|
||||
virtual PRBool IsContentOfType(PRUint32 aFlags) const;
|
||||
virtual nsresult GetListenerManager(nsIEventListenerManager** aResult);
|
||||
virtual already_AddRefed<nsIURI> GetBaseURI() const;
|
||||
|
|
|
@ -117,13 +117,12 @@ public:
|
|||
virtual ~nsAttributeTextNode() {
|
||||
DetachListener();
|
||||
}
|
||||
|
||||
virtual void SetParent(nsIContent* aParent) {
|
||||
if (!aParent) {
|
||||
DetachListener();
|
||||
}
|
||||
nsTextNode::SetParent(aParent);
|
||||
}
|
||||
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
|
||||
PRBool aNullParent = PR_TRUE);
|
||||
|
||||
nsRefPtr<nsAttrChangeListener> mListener; // our listener
|
||||
private:
|
||||
|
@ -305,10 +304,9 @@ nsAttributeTextNode::nsAttrChangeListener::HandleEvent(nsIDOMEvent* aEvent)
|
|||
}
|
||||
|
||||
nsresult
|
||||
NS_NewAttributeContent(nsIContent* aContent, PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttrName, nsIContent** aResult)
|
||||
NS_NewAttributeContent(PRInt32 aNameSpaceID, nsIAtom* aAttrName,
|
||||
nsIContent** aResult)
|
||||
{
|
||||
NS_PRECONDITION(aContent, "Must have parent content");
|
||||
NS_PRECONDITION(aAttrName, "Must have an attr name");
|
||||
NS_PRECONDITION(aNameSpaceID != kNameSpaceID_Unknown, "Must know namespace");
|
||||
|
||||
|
@ -317,47 +315,73 @@ NS_NewAttributeContent(nsIContent* aContent, PRInt32 aNameSpaceID,
|
|||
nsRefPtr<nsAttributeTextNode> textNode = new nsAttributeTextNode();
|
||||
NS_ENSURE_TRUE(textNode, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsCOMPtr<nsIDOMEventTarget> eventTarget(do_QueryInterface(aContent));
|
||||
NS_ENSURE_TRUE(eventTarget, NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsRefPtr<nsAttributeTextNode::nsAttrChangeListener> listener =
|
||||
textNode->mListener =
|
||||
new nsAttributeTextNode::nsAttrChangeListener(aNameSpaceID,
|
||||
aAttrName,
|
||||
textNode);
|
||||
NS_ENSURE_TRUE(listener, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = eventTarget->AddEventListener(NS_LITERAL_STRING("DOMAttrModified"),
|
||||
listener,
|
||||
PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoString attrValue;
|
||||
aContent->GetAttr(aNameSpaceID, aAttrName, attrValue);
|
||||
textNode->SetData(attrValue);
|
||||
|
||||
textNode->SetParent(aContent);
|
||||
textNode->mListener = listener; // Now textNode going away will detach the listener automatically.
|
||||
NS_ENSURE_TRUE(textNode->mListener, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
NS_ADDREF(*aResult = textNode);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAttributeTextNode::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers)
|
||||
{
|
||||
NS_PRECONDITION(aParent, "This node can't be a child of the document");
|
||||
|
||||
nsresult rv = nsTextNode::BindToTree(aDocument, aParent,
|
||||
aBindingParent, aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (mListener) {
|
||||
// Attach it to the new parent
|
||||
|
||||
nsCOMPtr<nsIDOMEventTarget> eventTarget(do_QueryInterface(aParent));
|
||||
NS_ENSURE_TRUE(eventTarget, NS_ERROR_UNEXPECTED);
|
||||
|
||||
rv = eventTarget->AddEventListener(NS_LITERAL_STRING("DOMAttrModified"),
|
||||
mListener,
|
||||
PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoString attrValue;
|
||||
aParent->GetAttr(mListener->mNameSpaceID, mListener->mAttrName,
|
||||
attrValue);
|
||||
SetData(attrValue);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsAttributeTextNode::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
{
|
||||
// Detach the listener while we know who our parent is!
|
||||
if (aNullParent) {
|
||||
DetachListener();
|
||||
}
|
||||
nsTextNode::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
void
|
||||
nsAttributeTextNode::DetachListener()
|
||||
{
|
||||
if (!mListener)
|
||||
return;
|
||||
|
||||
NS_ASSERTION(GetParent(), "How did our parent go away while we still have an observer?");
|
||||
|
||||
nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(GetParent()));
|
||||
if (target) {
|
||||
#ifdef DEBUG
|
||||
nsresult rv =
|
||||
nsresult rv =
|
||||
#endif
|
||||
target->RemoveEventListener(NS_LITERAL_STRING("DOMAttrModified"),
|
||||
mListener,
|
||||
PR_FALSE);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "'Leaking' listener for lifetime of this page");
|
||||
target->RemoveEventListener(NS_LITERAL_STRING("DOMAttrModified"),
|
||||
mListener,
|
||||
PR_FALSE);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "'Leaking' listener for lifetime of this page");
|
||||
}
|
||||
mListener->mContent = nsnull; // Make it forget us
|
||||
mListener = nsnull; // Goodbye, listener
|
||||
}
|
||||
|
|
|
@ -1317,22 +1317,30 @@ nsGenericHTMLElement::InNavQuirksMode(nsIDocument* aDoc)
|
|||
return doc->GetCompatibilityMode() == eCompatibility_NavQuirks;
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericHTMLElement::SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers)
|
||||
nsresult
|
||||
nsGenericHTMLElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers)
|
||||
{
|
||||
nsIDocument *document = GetCurrentDoc();
|
||||
PRBool doNothing = aDocument == document; // short circuit useless work
|
||||
|
||||
nsGenericElement::SetDocument(aDocument, aDeep, aCompileEventHandlers);
|
||||
nsresult rv = nsGenericElement::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// XXXbz if we already have a style attr parsed, this won't do
|
||||
// anything... need to fix that.
|
||||
ReparseStyleAttribute();
|
||||
if (!doNothing && aDocument) {
|
||||
|
||||
if (aDocument) {
|
||||
// If we're in a document now, let our mapped attrs know what their new
|
||||
// sheet is.
|
||||
nsHTMLStyleSheet* sheet = aDocument->GetAttributeStyleSheet();
|
||||
if (sheet) {
|
||||
mAttrsAndChildren.SetMappedAttrStyleSheet(sheet);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDOMHTMLFormElement>
|
||||
|
@ -1951,7 +1959,7 @@ nsGenericHTMLElement::GetInlineStyleRule()
|
|||
if (attrVal->Type() != nsAttrValue::eCSSStyleRule) {
|
||||
ReparseStyleAttribute();
|
||||
attrVal = mAttrsAndChildren.GetAttr(nsHTMLAtoms::style);
|
||||
// hopefully value.GetUnit() is now eHTMLUnit_CSSStyleRule
|
||||
// hopefully attrVal->Type() is now nsAttrValue::eCSSStyleRule
|
||||
}
|
||||
|
||||
if (attrVal->Type() == nsAttrValue::eCSSStyleRule) {
|
||||
|
@ -2597,11 +2605,7 @@ nsGenericHTMLElement::ParseStyleAttribute(nsIContent* aContent,
|
|||
nsresult result = NS_OK;
|
||||
NS_ASSERTION(aContent->GetNodeInfo(), "If we don't have a nodeinfo, we are very screwed");
|
||||
|
||||
// XXX GetOwnerDoc
|
||||
nsIDocument* doc = aContent->GetDocument();
|
||||
if (!doc) {
|
||||
doc = nsContentUtils::GetDocument(aContent->GetNodeInfo());
|
||||
}
|
||||
nsIDocument* doc = aContent->GetOwnerDoc();
|
||||
|
||||
if (doc) {
|
||||
PRBool isCSS = PR_TRUE; // assume CSS until proven otherwise
|
||||
|
@ -3240,56 +3244,53 @@ nsGenericHTMLFrameElement::IsFocusable(PRInt32 *aTabIndex)
|
|||
return isFocusable;
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericHTMLFormElement::SetParent(nsIContent* aParent)
|
||||
nsresult
|
||||
nsGenericHTMLFormElement::BindToTree(nsIDocument* aDocument,
|
||||
nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers)
|
||||
{
|
||||
// If we do any finding of the form, we need to do it after we've
|
||||
// called SetParent on the superclass.
|
||||
PRBool findForm = PR_FALSE;
|
||||
if (!aParent && mForm) {
|
||||
SetForm(nsnull);
|
||||
} else if (aParent && (GetParent() || !mForm)) {
|
||||
// If we have a new parent and either we had an old parent or we
|
||||
// don't have a form, search for a containing form. If we didn't
|
||||
// have an old parent, but we do have a form, we shouldn't do the
|
||||
// search. In this case, someone (possibly the content sink) has
|
||||
// already set the form for us.
|
||||
findForm = PR_TRUE;
|
||||
}
|
||||
nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsGenericHTMLElement::SetParent(aParent);
|
||||
|
||||
if (findForm) {
|
||||
if (!mForm && aParent) {
|
||||
// We now have a parent, so we may have picked up an ancestor form. Search
|
||||
// for it. Note that if mForm is already set we don't want to do this,
|
||||
// because that means someone (probably the content sink) has already set
|
||||
// it to the right value. Also note that even if being bound here didn't
|
||||
// change our parent, we still need to search, since our parent chain
|
||||
// probably changed _somewhere_.
|
||||
FindAndSetForm();
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericHTMLFormElement::SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers)
|
||||
nsGenericHTMLFormElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
{
|
||||
// Save state before doing anything if the document is being removed
|
||||
if (!aDocument) {
|
||||
SaveState();
|
||||
}
|
||||
// Save state before doing anything
|
||||
SaveState();
|
||||
|
||||
if (aDocument && GetParent() && !mForm) {
|
||||
FindAndSetForm();
|
||||
} else if (!aDocument && mForm) {
|
||||
// We got removed from document. We have a parent form. Check
|
||||
// that the form is still in the document, and if so remove
|
||||
// ourselves from the form. This keeps ghosts from appearing in
|
||||
// the form's |elements| array
|
||||
nsCOMPtr<nsIContent> formContent(do_QueryInterface(mForm));
|
||||
if (formContent && formContent->GetDocument()) {
|
||||
if (mForm) {
|
||||
// Might need to unset mForm
|
||||
if (aNullParent) {
|
||||
// No more parent means no more form
|
||||
SetForm(nsnull);
|
||||
} else {
|
||||
// Recheck whether we should still have an mForm.
|
||||
nsCOMPtr<nsIDOMHTMLFormElement> form = FindForm();
|
||||
if (!form) {
|
||||
SetForm(nsnull);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsGenericHTMLElement::SetDocument(aDocument, aDeep, aCompileEventHandlers);
|
||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLFormElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
|
@ -3464,30 +3465,29 @@ nsGenericHTMLFrameElement::LoadSrc()
|
|||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericHTMLFrameElement::SetParent(nsIContent *aParent)
|
||||
nsresult
|
||||
nsGenericHTMLFrameElement::BindToTree(nsIDocument* aDocument,
|
||||
nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers)
|
||||
{
|
||||
nsGenericHTMLElement::SetParent(aParent);
|
||||
nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// When parent is being set to null on the element's destruction, do not
|
||||
// call LoadSrc().
|
||||
if (!GetParent() || !IsInDoc()) {
|
||||
return;
|
||||
if (aDocument) {
|
||||
// We're in a document now. Kick off the frame load.
|
||||
LoadSrc();
|
||||
}
|
||||
|
||||
LoadSrc();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericHTMLFrameElement::SetDocument(nsIDocument *aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers)
|
||||
nsGenericHTMLFrameElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
{
|
||||
const nsIDocument *old_doc = GetCurrentDoc();
|
||||
|
||||
nsGenericHTMLElement::SetDocument(aDocument, aDeep,
|
||||
aCompileEventHandlers);
|
||||
|
||||
if (!aDocument && mFrameLoader) {
|
||||
if (mFrameLoader) {
|
||||
// This iframe is being taken out of the document, destroy the
|
||||
// iframe's frame loader (doing that will tear down the window in
|
||||
// this iframe).
|
||||
|
@ -3498,12 +3498,7 @@ nsGenericHTMLFrameElement::SetDocument(nsIDocument *aDocument, PRBool aDeep,
|
|||
mFrameLoader = nsnull;
|
||||
}
|
||||
|
||||
// When document is being set to null on the element's destruction,
|
||||
// or when the document is being set to what the document already
|
||||
// is, do not call LoadSrc().
|
||||
if (GetParent() && aDocument && aDocument != old_doc) {
|
||||
LoadSrc();
|
||||
}
|
||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -181,8 +181,9 @@ public:
|
|||
static const nsSize GetClientAreaSize(nsIFrame *aFrame);
|
||||
|
||||
// Implementation for nsIContent
|
||||
virtual void SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString& aValue, PRBool aNotify)
|
||||
{
|
||||
|
@ -829,10 +830,11 @@ public:
|
|||
}
|
||||
|
||||
// nsIContent
|
||||
virtual void SetParent(nsIContent *aParent);
|
||||
virtual void SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers);
|
||||
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
|
||||
PRBool aNullParent = PR_TRUE);
|
||||
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString& aValue, PRBool aNotify)
|
||||
{
|
||||
|
@ -887,9 +889,11 @@ public:
|
|||
|
||||
// nsIContent
|
||||
virtual PRBool IsFocusable(PRInt32 *aTabIndex = nsnull);
|
||||
virtual void SetParent(nsIContent *aParent);
|
||||
virtual void SetDocument(nsIDocument *aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
|
||||
PRBool aNullParent = PR_TRUE);
|
||||
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString& aValue, PRBool aNotify)
|
||||
{
|
||||
|
|
|
@ -98,8 +98,11 @@ public:
|
|||
NS_IMETHOD SetLinkState(nsLinkState aState);
|
||||
NS_IMETHOD GetHrefURI(nsIURI** aURI);
|
||||
|
||||
virtual void SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
|
||||
PRBool aNullParent = PR_TRUE);
|
||||
virtual void SetFocus(nsPresContext* aPresContext);
|
||||
virtual PRBool IsFocusable(PRBool *aTabIndex = nsnull);
|
||||
|
||||
|
@ -168,24 +171,31 @@ NS_IMPL_STRING_ATTR(nsHTMLAnchorElement, Type, type)
|
|||
NS_IMPL_STRING_ATTR(nsHTMLAnchorElement, AccessKey, accesskey)
|
||||
|
||||
|
||||
void
|
||||
nsHTMLAnchorElement::SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers)
|
||||
nsresult
|
||||
nsHTMLAnchorElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers)
|
||||
{
|
||||
nsIDocument *document = GetCurrentDoc();
|
||||
PRBool documentChanging = (aDocument != document);
|
||||
|
||||
// Unregister the access key for the old document.
|
||||
if (documentChanging && document) {
|
||||
nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (aDocument) {
|
||||
RegUnRegAccessKey(PR_TRUE);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLAnchorElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
{
|
||||
if (IsInDoc()) {
|
||||
RegUnRegAccessKey(PR_FALSE);
|
||||
}
|
||||
|
||||
nsGenericHTMLElement::SetDocument(aDocument, aDeep, aCompileEventHandlers);
|
||||
|
||||
// Register the access key for the new document.
|
||||
if (documentChanging && aDocument) {
|
||||
RegUnRegAccessKey(PR_TRUE);
|
||||
}
|
||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -245,7 +255,6 @@ nsHTMLAnchorElement::IsFocusable(PRInt32 *aTabIndex)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool isFocusable = PR_FALSE;
|
||||
if (!HasAttr(kNameSpaceID_None, nsHTMLAtoms::tabindex)) {
|
||||
// check whether we're actually a link
|
||||
nsCOMPtr<nsIURI> linkURI = nsContentUtils::GetLinkURI(this);
|
||||
|
|
|
@ -88,8 +88,11 @@ public:
|
|||
nsEventStatus* aEventStatus);
|
||||
virtual void SetFocus(nsPresContext* aPresContext);
|
||||
|
||||
virtual void SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
|
||||
PRBool aNullParent = PR_TRUE);
|
||||
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString& aValue, PRBool aNotify)
|
||||
{
|
||||
|
@ -201,24 +204,31 @@ nsHTMLAreaElement::SetFocus(nsPresContext* aPresContext)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLAreaElement::SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers)
|
||||
nsresult
|
||||
nsHTMLAreaElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers)
|
||||
{
|
||||
nsIDocument *document = GetCurrentDoc();
|
||||
PRBool documentChanging = (aDocument != document);
|
||||
|
||||
// Unregister the access key for the old document.
|
||||
if (documentChanging && document) {
|
||||
nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (aDocument) {
|
||||
RegUnRegAccessKey(PR_TRUE);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLAreaElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
{
|
||||
if (IsInDoc()) {
|
||||
RegUnRegAccessKey(PR_FALSE);
|
||||
}
|
||||
|
||||
nsGenericHTMLElement::SetDocument(aDocument, aDeep, aCompileEventHandlers);
|
||||
|
||||
// Register the access key for the new document.
|
||||
if (documentChanging && aDocument) {
|
||||
RegUnRegAccessKey(PR_TRUE);
|
||||
}
|
||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -109,8 +109,8 @@ public:
|
|||
virtual PRBool ParseAttribute(nsIAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsAttrValue& aResult);
|
||||
virtual void SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
|
||||
PRBool aNullParent = PR_TRUE);
|
||||
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const;
|
||||
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
|
||||
NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
|
||||
|
@ -413,17 +413,16 @@ nsHTMLBodyElement::ParseAttribute(nsIAtom* aAttribute,
|
|||
}
|
||||
|
||||
void
|
||||
nsHTMLBodyElement::SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers)
|
||||
nsHTMLBodyElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
{
|
||||
nsIDocument *document = GetCurrentDoc();
|
||||
if (aDocument != document && mContentStyleRule) {
|
||||
if (mContentStyleRule) {
|
||||
mContentStyleRule->mPart = nsnull;
|
||||
|
||||
// destroy old style rule since the sheet will probably change
|
||||
// destroy old style rule
|
||||
NS_RELEASE(mContentStyleRule);
|
||||
}
|
||||
nsGenericHTMLElement::SetDocument(aDocument, aDeep, aCompileEventHandlers);
|
||||
|
||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
static
|
||||
|
|
|
@ -171,8 +171,11 @@ public:
|
|||
nsEvent* aEvent, nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus);
|
||||
virtual void SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
|
||||
PRBool aNullParent = PR_TRUE);
|
||||
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString& aValue, PRBool aNotify)
|
||||
{
|
||||
|
@ -614,25 +617,36 @@ nsHTMLFormElement::ParseAttribute(nsIAtom* aAttribute,
|
|||
return nsGenericHTMLElement::ParseAttribute(aAttribute, aValue, aResult);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLFormElement::SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers)
|
||||
nsresult
|
||||
nsHTMLFormElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers)
|
||||
{
|
||||
nsCOMPtr<nsIHTMLDocument> oldDocument = do_QueryInterface(GetCurrentDoc());
|
||||
nsGenericHTMLElement::SetDocument(aDocument, aDeep, aCompileEventHandlers);
|
||||
|
||||
nsCOMPtr<nsIHTMLDocument> newDocument = do_QueryInterface(GetCurrentDoc());
|
||||
if (oldDocument != newDocument) {
|
||||
if (oldDocument) {
|
||||
oldDocument->RemovedForm();
|
||||
ForgetCurrentSubmission();
|
||||
}
|
||||
if (newDocument) {
|
||||
newDocument->AddedForm();
|
||||
}
|
||||
nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIHTMLDocument> htmlDoc(do_QueryInterface(aDocument));
|
||||
if (htmlDoc) {
|
||||
htmlDoc->AddedForm();
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLFormElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
{
|
||||
nsCOMPtr<nsIHTMLDocument> oldDocument = do_QueryInterface(GetCurrentDoc());
|
||||
|
||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||
|
||||
if (oldDocument) {
|
||||
oldDocument->RemovedForm();
|
||||
}
|
||||
ForgetCurrentSubmission();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLFormElement::HandleDOMEvent(nsPresContext* aPresContext,
|
||||
|
|
|
@ -141,9 +141,9 @@ public:
|
|||
// XXXbz What about UnsetAttr? We don't seem to unload images when
|
||||
// that happens...
|
||||
|
||||
virtual void SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual void SetParent(nsIContent* aParent);
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
|
||||
protected:
|
||||
void GetImageFrame(nsIImageFrame** aImageFrame);
|
||||
|
@ -581,37 +581,25 @@ nsHTMLImageElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
|||
aNotify);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLImageElement::SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers)
|
||||
nsresult
|
||||
nsHTMLImageElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers)
|
||||
{
|
||||
PRBool documentChanging = aDocument && aDocument != GetCurrentDoc();
|
||||
|
||||
nsGenericHTMLElement::SetDocument(aDocument, aDeep, aCompileEventHandlers);
|
||||
if (documentChanging && GetParent()) {
|
||||
// Our base URI may have changed; claim that our URI changed, and the
|
||||
// nsImageLoadingContent will decide whether a new image load is warranted.
|
||||
nsAutoString uri;
|
||||
nsresult result = GetAttr(kNameSpaceID_None, nsHTMLAtoms::src, uri);
|
||||
if (result == NS_CONTENT_ATTR_HAS_VALUE) {
|
||||
ImageURIChanged(uri);
|
||||
}
|
||||
}
|
||||
}
|
||||
nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
void
|
||||
nsHTMLImageElement::SetParent(nsIContent* aParent)
|
||||
{
|
||||
nsGenericHTMLElement::SetParent(aParent);
|
||||
if (aParent && IsInDoc()) {
|
||||
// Our base URI may have changed; claim that our URI changed, and the
|
||||
// nsImageLoadingContent will decide whether a new image load is warranted.
|
||||
nsAutoString uri;
|
||||
nsresult result = GetAttr(kNameSpaceID_None, nsHTMLAtoms::src, uri);
|
||||
if (result == NS_CONTENT_ATTR_HAS_VALUE) {
|
||||
ImageURIChanged(uri);
|
||||
}
|
||||
// Our base URI may have changed; claim that our URI changed, and the
|
||||
// nsImageLoadingContent will decide whether a new image load is warranted.
|
||||
nsAutoString uri;
|
||||
nsresult result = GetAttr(kNameSpaceID_None, nsHTMLAtoms::src, uri);
|
||||
if (result == NS_CONTENT_ATTR_HAS_VALUE) {
|
||||
ImageURIChanged(uri);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -187,10 +187,12 @@ public:
|
|||
nsEvent* aEvent, nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus);
|
||||
virtual void SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual void SetParent(nsIContent* aParent);
|
||||
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
|
||||
PRBool aNullParent = PR_TRUE);
|
||||
|
||||
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString& aValue, PRBool aNotify)
|
||||
{
|
||||
|
@ -896,9 +898,7 @@ nsHTMLInputElement::GetRadioGroupContainer()
|
|||
nsIRadioGroupContainer* retval = nsnull;
|
||||
if (mForm) {
|
||||
CallQueryInterface(mForm, &retval);
|
||||
} else if (GetParent()) {
|
||||
// XXXbz the GetParent() check is needed because we sometimes have a doc
|
||||
// when we're not really in one, I think... Need BindToTree!
|
||||
} else {
|
||||
nsIDocument* currentDoc = GetCurrentDoc();
|
||||
if (currentDoc) {
|
||||
CallQueryInterface(currentDoc, &retval);
|
||||
|
@ -1674,24 +1674,17 @@ nsHTMLInputElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
nsHTMLInputElement::SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers)
|
||||
nsresult
|
||||
nsHTMLInputElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers)
|
||||
{
|
||||
PRBool documentChanging = (aDocument != GetCurrentDoc());
|
||||
nsresult rv = nsGenericHTMLFormElement::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// SetDocument() sets the form and that takes care of form's WillRemove
|
||||
// so we just have to take care of the case where we're removing from the
|
||||
// document and we don't have a form
|
||||
if (documentChanging && !mForm && mType == NS_FORM_INPUT_RADIO) {
|
||||
WillRemoveFromRadioGroup();
|
||||
}
|
||||
|
||||
nsGenericHTMLFormElement::SetDocument(aDocument, aDeep,
|
||||
aCompileEventHandlers);
|
||||
|
||||
if (mType == NS_FORM_INPUT_IMAGE &&
|
||||
documentChanging && aDocument && GetParent()) {
|
||||
if (mType == NS_FORM_INPUT_IMAGE) {
|
||||
// Our base URI may have changed; claim that our URI changed, and the
|
||||
// nsImageLoadingContent will decide whether a new image load is warranted.
|
||||
nsAutoString uri;
|
||||
|
@ -1700,12 +1693,15 @@ nsHTMLInputElement::SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
|||
ImageURIChanged(uri);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If this is radio button which is in a form,
|
||||
// and the parser is still creating the element.
|
||||
// XXXbz hmmm Do we need this BF_PARSER_CREATING thing? I suspect
|
||||
// we don't and that it was a hackaround around the way-early
|
||||
// SetDocument call in the parser.
|
||||
if (mForm || mType != NS_FORM_INPUT_RADIO ||
|
||||
GET_BOOLBIT(mBitField, BF_PARSER_CREATING)) {
|
||||
return;
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Add radio to document if we don't have a form already (if we do it's
|
||||
|
@ -1713,21 +1709,23 @@ nsHTMLInputElement::SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
|||
if (aDocument && !mForm && mType == NS_FORM_INPUT_RADIO) {
|
||||
AddedToRadioGroup();
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLInputElement::SetParent(nsIContent* aParent)
|
||||
nsHTMLInputElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
{
|
||||
nsGenericHTMLFormElement::SetParent(aParent);
|
||||
if (mType == NS_FORM_INPUT_IMAGE && aParent && IsInDoc()) {
|
||||
// Our base URI may have changed; claim that our URI changed, and the
|
||||
// nsImageLoadingContent will decide whether a new image load is warranted.
|
||||
nsAutoString uri;
|
||||
nsresult result = GetAttr(kNameSpaceID_None, nsHTMLAtoms::src, uri);
|
||||
if (result == NS_CONTENT_ATTR_HAS_VALUE) {
|
||||
ImageURIChanged(uri);
|
||||
}
|
||||
// If we have a form and are unbound from it,
|
||||
// nsGenericHTMLFormElement::SetDocument() will unset the form and
|
||||
// that takes care of form's WillRemove so we just have to take care
|
||||
// of the case where we're removing from the document and we don't
|
||||
// have a form
|
||||
if (!mForm && mType == NS_FORM_INPUT_RADIO) {
|
||||
WillRemoveFromRadioGroup();
|
||||
}
|
||||
|
||||
nsGenericHTMLFormElement::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
static const nsAttrValue::EnumTable kInputTypeTable[] = {
|
||||
|
|
|
@ -82,8 +82,11 @@ public:
|
|||
nsIContent* aSubmitElement);
|
||||
|
||||
// nsIContent
|
||||
virtual void SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
|
||||
PRBool aNullParent = PR_TRUE);
|
||||
virtual nsresult HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent, nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
|
@ -155,25 +158,31 @@ nsHTMLLabelElement::GetForm(nsIDOMHTMLFormElement** aForm)
|
|||
NS_IMPL_STRING_ATTR(nsHTMLLabelElement, AccessKey, accesskey)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLLabelElement, HtmlFor, _for)
|
||||
|
||||
void
|
||||
nsHTMLLabelElement::SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers)
|
||||
nsresult
|
||||
nsHTMLLabelElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers)
|
||||
{
|
||||
nsIDocument *document = GetCurrentDoc();
|
||||
PRBool documentChanging = (aDocument != document);
|
||||
nsresult rv = nsGenericHTMLFormElement::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Unregister the access key for the old document.
|
||||
if (documentChanging && document) {
|
||||
if (aDocument) {
|
||||
RegUnRegAccessKey(PR_TRUE);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLLabelElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
{
|
||||
if (IsInDoc()) {
|
||||
RegUnRegAccessKey(PR_FALSE);
|
||||
}
|
||||
|
||||
nsGenericHTMLFormElement::SetDocument(aDocument, aDeep,
|
||||
aCompileEventHandlers);
|
||||
|
||||
// Register the access key for the new document.
|
||||
if (documentChanging && aDocument) {
|
||||
RegUnRegAccessKey(PR_TRUE);
|
||||
}
|
||||
nsGenericHTMLFormElement::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
static PRBool
|
||||
|
|
|
@ -79,8 +79,11 @@ public:
|
|||
nsIContent* aSubmitElement);
|
||||
|
||||
// nsIContent
|
||||
virtual void SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
|
||||
PRBool aNullParent = PR_TRUE);
|
||||
virtual void SetFocus(nsPresContext* aPresContext);
|
||||
virtual PRBool ParseAttribute(nsIAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
|
@ -214,25 +217,31 @@ nsHTMLLegendElement::Reset()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLLegendElement::SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers)
|
||||
nsresult
|
||||
nsHTMLLegendElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers)
|
||||
{
|
||||
nsIDocument *document = GetCurrentDoc();
|
||||
PRBool documentChanging = (aDocument != document);
|
||||
|
||||
// Unregister the access key for the old document.
|
||||
if (documentChanging && document) {
|
||||
nsresult rv = nsGenericHTMLFormElement::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (aDocument) {
|
||||
RegUnRegAccessKey(PR_TRUE);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLLegendElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
{
|
||||
if (IsInDoc()) {
|
||||
RegUnRegAccessKey(PR_FALSE);
|
||||
}
|
||||
|
||||
nsGenericHTMLFormElement::SetDocument(aDocument, aDeep,
|
||||
aCompileEventHandlers);
|
||||
|
||||
// Register the access key for the new document.
|
||||
if (documentChanging && document) {
|
||||
RegUnRegAccessKey(PR_TRUE);
|
||||
}
|
||||
nsGenericHTMLFormElement::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -86,11 +86,12 @@ public:
|
|||
NS_IMETHOD SetLinkState(nsLinkState aState);
|
||||
NS_IMETHOD GetHrefURI(nsIURI** aURI);
|
||||
|
||||
virtual void SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers);
|
||||
void CreateAndDispatchEvent(nsIDocument* aDoc, const nsString& aRel,
|
||||
const nsString& aRev,
|
||||
const nsAString& aEventName);
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
|
||||
PRBool aNullParent = PR_TRUE);
|
||||
void CreateAndDispatchEvent(nsIDocument* aDoc, const nsAString& aEventName);
|
||||
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString& aValue, PRBool aNotify)
|
||||
{
|
||||
|
@ -189,36 +190,52 @@ NS_IMPL_STRING_ATTR(nsHTMLLinkElement, Rev, rev)
|
|||
NS_IMPL_STRING_ATTR(nsHTMLLinkElement, Target, target)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLLinkElement, Type, type)
|
||||
|
||||
nsresult
|
||||
nsHTMLLinkElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers)
|
||||
{
|
||||
nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
UpdateStyleSheet(nsnull);
|
||||
|
||||
// XXXbz we really shouldn't fire the event until after we've finished with
|
||||
// the outermost BindToTree... In particular, this can effectively cause us
|
||||
// to reenter this code, or for some part of the document to become unbound
|
||||
// inside the event!
|
||||
CreateAndDispatchEvent(aDocument, NS_LITERAL_STRING("DOMLinkAdded"));
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLLinkElement::SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers)
|
||||
nsHTMLLinkElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> oldDoc = GetCurrentDoc();
|
||||
|
||||
// XXXbz we really shouldn't fire the event until after we've finished with
|
||||
// the outermost UnbindFromTree... In particular, this can effectively cause
|
||||
// us to reenter this code, or to be bound to a different tree inside the
|
||||
// event!
|
||||
CreateAndDispatchEvent(oldDoc, NS_LITERAL_STRING("DOMLinkRemoved"));
|
||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||
UpdateStyleSheet(oldDoc);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLLinkElement::CreateAndDispatchEvent(nsIDocument* aDoc,
|
||||
const nsAString& aEventName)
|
||||
{
|
||||
if (!aDoc)
|
||||
return;
|
||||
|
||||
nsAutoString rel;
|
||||
nsAutoString rev;
|
||||
GetAttr(kNameSpaceID_None, nsHTMLAtoms::rel, rel);
|
||||
GetAttr(kNameSpaceID_None, nsHTMLAtoms::rev, rev);
|
||||
|
||||
CreateAndDispatchEvent(oldDoc, rel, rev,
|
||||
NS_LITERAL_STRING("DOMLinkRemoved"));
|
||||
|
||||
// Do the removal and addition into the new doc.
|
||||
nsGenericHTMLElement::SetDocument(aDocument, aDeep, aCompileEventHandlers);
|
||||
UpdateStyleSheet(oldDoc);
|
||||
|
||||
CreateAndDispatchEvent(aDocument, rel, rev,
|
||||
NS_LITERAL_STRING("DOMLinkAdded"));
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLLinkElement::CreateAndDispatchEvent(nsIDocument* aDoc,
|
||||
const nsString& aRel,
|
||||
const nsString& aRev,
|
||||
const nsAString& aEventName)
|
||||
{
|
||||
if (!aDoc)
|
||||
return;
|
||||
|
||||
// In the unlikely case that both rev is specified *and* rel=stylesheet,
|
||||
// this code will cause the event to fire, on the principle that maybe the
|
||||
|
@ -226,8 +243,8 @@ nsHTMLLinkElement::CreateAndDispatchEvent(nsIDocument* aDoc,
|
|||
// this should never actually happen and the performance hit is minimal,
|
||||
// doing the "right" thing costs virtually nothing here, even if it doesn't
|
||||
// make much sense.
|
||||
if (aRev.IsEmpty() &&
|
||||
(aRel.IsEmpty() || aRel.LowerCaseEqualsLiteral("stylesheet")))
|
||||
if (rev.IsEmpty() &&
|
||||
(rel.IsEmpty() || rel.LowerCaseEqualsLiteral("stylesheet")))
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIDOMDocumentEvent> docEvent(do_QueryInterface(aDoc));
|
||||
|
|
|
@ -68,9 +68,11 @@ public:
|
|||
// nsIDOMHTMLMapElement
|
||||
NS_DECL_NSIDOMHTMLMAPELEMENT
|
||||
|
||||
virtual void SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers);
|
||||
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
|
||||
PRBool aNullParent = PR_TRUE);
|
||||
protected:
|
||||
nsRefPtr<nsContentList> mAreas;
|
||||
};
|
||||
|
@ -103,33 +105,36 @@ NS_HTML_CONTENT_INTERFACE_MAP_BEGIN(nsHTMLMapElement, nsGenericHTMLElement)
|
|||
NS_HTML_CONTENT_INTERFACE_MAP_END
|
||||
|
||||
|
||||
void
|
||||
nsHTMLMapElement::SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers)
|
||||
nsresult
|
||||
nsHTMLMapElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers)
|
||||
{
|
||||
nsIDocument *document = GetCurrentDoc();
|
||||
PRBool documentChanging = (aDocument != document);
|
||||
|
||||
if (documentChanging) {
|
||||
nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(document);
|
||||
nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (htmlDoc) {
|
||||
htmlDoc->RemoveImageMap(this);
|
||||
}
|
||||
nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(aDocument);
|
||||
|
||||
if (htmlDoc) {
|
||||
htmlDoc->AddImageMap(this);
|
||||
}
|
||||
|
||||
nsGenericHTMLElement::SetDocument(aDocument, aDeep, aCompileEventHandlers);
|
||||
|
||||
if (documentChanging) {
|
||||
// Since we changed the document, gotta re-QI
|
||||
nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(aDocument);
|
||||
|
||||
if (htmlDoc) {
|
||||
htmlDoc->AddImageMap(this);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLMapElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
{
|
||||
nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(GetCurrentDoc());
|
||||
|
||||
if (htmlDoc) {
|
||||
htmlDoc->RemoveImageMap(this);
|
||||
}
|
||||
|
||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
NS_IMPL_DOM_CLONENODE(nsHTMLMapElement)
|
||||
|
||||
|
|
|
@ -346,8 +346,10 @@ public:
|
|||
virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
PRBool aNotify);
|
||||
virtual void SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers);
|
||||
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
|
||||
PRBool aNotify, PRBool aDeepSetDocument);
|
||||
virtual nsresult AppendChildTo(nsIContent* aKid, PRBool aNotify,
|
||||
|
@ -437,14 +439,21 @@ nsHTMLScriptElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
|||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLScriptElement::SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers)
|
||||
nsresult
|
||||
nsHTMLScriptElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers)
|
||||
{
|
||||
nsGenericHTMLElement::SetDocument(aDocument, aDeep, aCompileEventHandlers);
|
||||
nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (aDocument) {
|
||||
MaybeProcessScript();
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -639,7 +648,7 @@ nsHTMLScriptElement::GetScriptLineNumber()
|
|||
void
|
||||
nsHTMLScriptElement::MaybeProcessScript()
|
||||
{
|
||||
if (mIsEvaluated || mEvaluating || !IsInDoc() || !GetParent()) {
|
||||
if (mIsEvaluated || mEvaluating || !IsInDoc()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -79,8 +79,11 @@ public:
|
|||
virtual nsresult AppendChildTo(nsIContent* aKid, PRBool aNotify,
|
||||
PRBool aDeepSetDocument);
|
||||
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
|
||||
virtual void SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
|
||||
PRBool aNullParent = PR_TRUE);
|
||||
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString& aValue, PRBool aNotify)
|
||||
{
|
||||
|
@ -210,17 +213,30 @@ nsHTMLStyleElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLStyleElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers)
|
||||
{
|
||||
nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
UpdateStyleSheet(nsnull);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLStyleElement::SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers)
|
||||
nsHTMLStyleElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> oldDoc = GetCurrentDoc();
|
||||
|
||||
nsGenericHTMLElement::SetDocument(aDocument, aDeep, aCompileEventHandlers);
|
||||
|
||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||
UpdateStyleSheet(oldDoc);
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsHTMLStyleElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
|
|
|
@ -703,6 +703,8 @@ public:
|
|||
// appended to it's parent until the container is closed. By setting
|
||||
// pre-append to true, the container will be appended when it is
|
||||
// created.
|
||||
// XXXbz why do we really need this "no pre-appending" thing? Seems
|
||||
// a little weird to me....
|
||||
void SetPreAppend(PRBool aPreAppend)
|
||||
{
|
||||
mPreAppend = aPreAppend;
|
||||
|
@ -1237,7 +1239,6 @@ SinkContext::OpenContainer(const nsIParserNode& aNode)
|
|||
mStack[mStackPos].mFlags = 0;
|
||||
mStack[mStackPos].mNumFlushed = 0;
|
||||
mStack[mStackPos].mInsertionPoint = -1;
|
||||
content->SetDocument(mSink->mDocument, PR_FALSE, PR_TRUE);
|
||||
|
||||
// Make sure to add base tag info, if needed, before setting any other
|
||||
// attributes -- what URI attrs do will depend on the base URI. Only do this
|
||||
|
@ -1477,9 +1478,6 @@ SinkContext::AddLeaf(const nsIParserNode& aNode)
|
|||
mSink->mCurrentForm, mSink->mDocShell);
|
||||
NS_ENSURE_TRUE(content, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// Set the content's document
|
||||
content->SetDocument(mSink->mDocument, PR_FALSE, PR_TRUE);
|
||||
|
||||
// Make sure to add base tag info, if needed, before setting any other
|
||||
// attributes -- what URI attrs do will depend on the base URI. Only do
|
||||
// this for elements that have useful URI attributes.
|
||||
|
@ -1607,8 +1605,6 @@ SinkContext::AddComment(const nsIParserNode& aNode)
|
|||
|
||||
domComment->AppendData(aNode.GetText());
|
||||
|
||||
comment->SetDocument(mSink->mDocument, PR_FALSE, PR_TRUE);
|
||||
|
||||
NS_ASSERTION(mStackPos > 0, "stack out of bounds");
|
||||
if (mStackPos <= 0) {
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -1875,9 +1871,6 @@ SinkContext::FlushText(PRBool* aDidFlush, PRBool aReleaseLast)
|
|||
|
||||
mLastTextNode = textContent;
|
||||
|
||||
// Set the content's document
|
||||
mLastTextNode->SetDocument(mSink->mDocument, PR_FALSE, PR_TRUE);
|
||||
|
||||
// Set the text in the text node
|
||||
mLastTextNode->SetText(mText, mTextLength, PR_FALSE);
|
||||
|
||||
|
@ -2176,7 +2169,11 @@ HTMLContentSink::Init(nsIDocument* aDoc,
|
|||
}
|
||||
NS_ADDREF(mRoot);
|
||||
|
||||
mRoot->SetDocument(mDocument, PR_FALSE, PR_TRUE);
|
||||
rv = mRoot->BindToTree(mDocument, nsnull, nsnull, PR_TRUE);
|
||||
if (NS_FAILED(rv)) {
|
||||
mRoot->UnbindFromTree();
|
||||
return rv;
|
||||
}
|
||||
mDocument->SetRootContent(mRoot);
|
||||
}
|
||||
|
||||
|
@ -3188,7 +3185,6 @@ HTMLContentSink::SetDocumentTitle(const nsAString& aTitle, const nsIParserNode*
|
|||
text->SetText(title, PR_TRUE);
|
||||
|
||||
it->AppendChildTo(text, PR_FALSE, PR_FALSE);
|
||||
text->SetDocument(mDocument, PR_FALSE, PR_TRUE);
|
||||
|
||||
mHead->AppendChildTo(it, PR_FALSE, PR_FALSE);
|
||||
|
||||
|
@ -3710,9 +3706,6 @@ HTMLContentSink::ProcessAREATag(const nsIParserNode& aNode)
|
|||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// Set the content's document
|
||||
area->SetDocument(mDocument, PR_FALSE, PR_TRUE);
|
||||
|
||||
// Make sure to add base tag info, if needed, before setting any other
|
||||
// attributes -- what URI attrs do will depend on the base URI. Only do this
|
||||
// for elements that have useful URI attributes.
|
||||
|
@ -3844,9 +3837,8 @@ HTMLContentSink::ProcessBASETag(const nsIParserNode& aNode)
|
|||
|
||||
element->SetContentID(mDocument->GetAndIncrementContentID());
|
||||
|
||||
// Add in the attributes and add the style content object to the
|
||||
// Add in the attributes and add the base content object to the
|
||||
// head container.
|
||||
element->SetDocument(mDocument, PR_FALSE, PR_TRUE);
|
||||
result = AddAttributes(aNode, element);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
|
@ -3904,7 +3896,6 @@ HTMLContentSink::ProcessLINKTag(const nsIParserNode& aNode)
|
|||
|
||||
// Add in the attributes and add the style content object to the
|
||||
// head container.
|
||||
element->SetDocument(mDocument, PR_FALSE, PR_TRUE);
|
||||
AddBaseTagInfo(element);
|
||||
result = AddAttributes(aNode, element);
|
||||
if (NS_FAILED(result)) {
|
||||
|
@ -3991,7 +3982,6 @@ HTMLContentSink::ProcessMETATag(const nsIParserNode& aNode)
|
|||
|
||||
// Add in the attributes and add the meta content object to the head
|
||||
// container.
|
||||
it->SetDocument(mDocument, PR_FALSE, PR_TRUE);
|
||||
AddBaseTagInfo(it);
|
||||
rv = AddAttributes(aNode, it);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -4180,9 +4170,8 @@ HTMLContentSink::ProcessSCRIPTTag(const nsIParserNode& aNode)
|
|||
|
||||
element->SetContentID(mDocument->GetAndIncrementContentID());
|
||||
|
||||
// Add in the attributes and add the style content object to the
|
||||
// Add in the attributes and add the script content object to the
|
||||
// head container.
|
||||
element->SetDocument(mDocument, PR_FALSE, PR_TRUE);
|
||||
AddBaseTagInfo(element);
|
||||
rv = AddAttributes(aNode, element);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -4214,7 +4203,6 @@ HTMLContentSink::ProcessSCRIPTTag(const nsIParserNode& aNode)
|
|||
text->SetText(script, PR_TRUE);
|
||||
|
||||
element->AppendChildTo(text, PR_FALSE, PR_FALSE);
|
||||
text->SetDocument(mDocument, PR_FALSE, PR_TRUE);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIScriptLoader> loader;
|
||||
|
@ -4241,6 +4229,13 @@ HTMLContentSink::ProcessSCRIPTTag(const nsIParserNode& aNode)
|
|||
mScriptElements.AppendObject(sele);
|
||||
}
|
||||
|
||||
// Now flush out tags so that the script will actually be bound to a
|
||||
// document and will evaluate as soon as it's appended.
|
||||
SINK_TRACE(SINK_TRACE_CALLS,
|
||||
("HTMLContentSink::ProcessSCRIPTTag: flushing tags before "
|
||||
"appending script"));
|
||||
mCurrentContext->FlushTags(PR_FALSE);
|
||||
|
||||
// Insert the child into the content tree. This will evaluate the
|
||||
// script as well.
|
||||
if (mCurrentContext->mStack[mCurrentContext->mStackPos - 1].mInsertionPoint != -1) {
|
||||
|
@ -4312,7 +4307,6 @@ HTMLContentSink::ProcessSTYLETag(const nsIParserNode& aNode)
|
|||
|
||||
// Add in the attributes and add the style content object to the
|
||||
// head container.
|
||||
element->SetDocument(mDocument, PR_FALSE, PR_TRUE);
|
||||
AddBaseTagInfo(element);
|
||||
rv = AddAttributes(aNode, element);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
|
|
@ -93,7 +93,7 @@ public:
|
|||
virtual already_AddRefed<nsContentList> GetFormControlElements() = 0;
|
||||
|
||||
/**
|
||||
* Called when form->SetDocument() is called so that document knows
|
||||
* Called when form->BindToTree() is called so that document knows
|
||||
* immediately when a form is added
|
||||
*/
|
||||
virtual void AddedForm() = 0;
|
||||
|
|
|
@ -587,7 +587,6 @@ nsImageDocument::CreateSyntheticDocument()
|
|||
if (!mImageContent) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
mImageContent->SetDocument(this, PR_FALSE, PR_TRUE);
|
||||
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mImageContent);
|
||||
NS_ENSURE_TRUE(imageLoader, NS_ERROR_UNEXPECTED);
|
||||
|
||||
|
|
|
@ -242,7 +242,11 @@ nsMediaDocument::CreateSyntheticDocument()
|
|||
if (!root) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
root->SetDocument(this, PR_FALSE, PR_TRUE);
|
||||
rv = root->BindToTree(this, nsnull, nsnull, PR_TRUE);
|
||||
if (NS_FAILED(rv)) {
|
||||
root->UnbindFromTree();
|
||||
return rv;
|
||||
}
|
||||
SetRootContent(root);
|
||||
|
||||
rv = mNodeInfoManager->GetNodeInfo(nsHTMLAtoms::body, nsnull,
|
||||
|
@ -254,7 +258,6 @@ nsMediaDocument::CreateSyntheticDocument()
|
|||
if (!body) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
body->SetDocument(this, PR_FALSE, PR_TRUE);
|
||||
mBodyContent = do_QueryInterface(body);
|
||||
|
||||
root->AppendChildTo(body, PR_FALSE, PR_FALSE);
|
||||
|
|
|
@ -180,7 +180,6 @@ nsPluginDocument::CreateSyntheticPluginDocument()
|
|||
if (!mPluginContent) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
mPluginContent->SetDocument(this, PR_FALSE, PR_TRUE);
|
||||
|
||||
// make it a named element
|
||||
mPluginContent->SetAttr(kNameSpaceID_None, nsHTMLAtoms::name,
|
||||
|
|
|
@ -102,12 +102,26 @@ NS_INTERFACE_MAP_END_INHERITING(nsGenericElement)
|
|||
//----------------------------------------------------------------------
|
||||
// nsIContent methods
|
||||
|
||||
void
|
||||
nsSVGElement::SetParent(nsIContent* aParent)
|
||||
nsresult
|
||||
nsSVGElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers)
|
||||
{
|
||||
nsGenericElement::SetParent(aParent);
|
||||
nsresult rv = nsGenericElement::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
ParentChainChanged();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
{
|
||||
nsGenericElement::UnbindFromTree(aDeep, aNullParent);
|
||||
ParentChainChanged();
|
||||
}
|
||||
|
||||
nsIAtom *
|
||||
|
@ -241,17 +255,6 @@ nsSVGElement::UnsetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
|||
return nsGenericElement::UnsetAttr(aNamespaceID, aName, aNotify);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGElement::SetBindingParent(nsIContent* aParent)
|
||||
{
|
||||
nsresult rv = nsGenericElement::SetBindingParent(aParent);
|
||||
|
||||
// XXX Are parent and bindingparent always in sync? (in which case
|
||||
// we don't have to call ParentChainChanged() here)
|
||||
ParentChainChanged();
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsSVGElement::IsContentOfType(PRUint32 aFlags) const
|
||||
{
|
||||
|
|
|
@ -69,7 +69,11 @@ public:
|
|||
|
||||
// nsIContent interface methods
|
||||
|
||||
virtual void SetParent(nsIContent* aParent);
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
|
||||
PRBool aNullParent = PR_TRUE);
|
||||
virtual nsIAtom *GetIDAttributeName() const;
|
||||
virtual nsIAtom *GetClassAttributeName() const;
|
||||
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
|
@ -83,7 +87,6 @@ public:
|
|||
virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
||||
PRBool aNotify);
|
||||
|
||||
virtual nsresult SetBindingParent(nsIContent* aParent);
|
||||
virtual PRBool IsContentOfType(PRUint32 aFlags) const;
|
||||
|
||||
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
|
||||
|
|
|
@ -95,8 +95,9 @@ public:
|
|||
nsISVGValue::modificationType aModType);
|
||||
|
||||
// nsIContent specializations:
|
||||
virtual void SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
|
||||
PRBool aNotify, PRBool aDeepSetDocument);
|
||||
virtual nsresult AppendChildTo(nsIContent* aKid, PRBool aNotify,
|
||||
|
@ -356,14 +357,21 @@ nsSVGScriptElement::DidModifySVGObservable(nsISVGValue* aObservable,
|
|||
//----------------------------------------------------------------------
|
||||
// nsIContent methods
|
||||
|
||||
void
|
||||
nsSVGScriptElement::SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers)
|
||||
nsresult
|
||||
nsSVGScriptElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers)
|
||||
{
|
||||
nsSVGScriptElementBase::SetDocument(aDocument, aDeep, aCompileEventHandlers);
|
||||
nsresult rv = nsSVGScriptElementBase::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (aDocument) {
|
||||
MaybeProcessScript();
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -400,7 +408,7 @@ nsSVGScriptElement::AppendChildTo(nsIContent* aKid, PRBool aNotify,
|
|||
void
|
||||
nsSVGScriptElement::MaybeProcessScript()
|
||||
{
|
||||
if (mIsEvaluated || mEvaluating || !IsInDoc() || !GetParent()) {
|
||||
if (mIsEvaluated || mEvaluating || !IsInDoc()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -70,8 +70,11 @@ public:
|
|||
virtual nsresult AppendChildTo(nsIContent* aKid, PRBool aNotify,
|
||||
PRBool aDeepSetDocument);
|
||||
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
|
||||
virtual void SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
|
||||
PRBool aNullParent = PR_TRUE);
|
||||
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString& aValue, PRBool aNotify)
|
||||
{
|
||||
|
@ -181,17 +184,30 @@ nsSVGStyleElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGStyleElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers)
|
||||
{
|
||||
nsresult rv = nsSVGStyleElementBase::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
UpdateStyleSheet(nsnull);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGStyleElement::SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers)
|
||||
nsSVGStyleElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> oldDoc = GetCurrentDoc();
|
||||
|
||||
nsSVGStyleElementBase::SetDocument(aDocument, aDeep, aCompileEventHandlers);
|
||||
|
||||
nsSVGStyleElementBase::UnbindFromTree(aDeep, aNullParent);
|
||||
UpdateStyleSheet(oldDoc);
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsSVGStyleElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
|
|
|
@ -407,7 +407,11 @@ NS_IMETHODIMP
|
|||
nsBindingManager::ChangeDocumentFor(nsIContent* aContent, nsIDocument* aOldDocument,
|
||||
nsIDocument* aNewDocument)
|
||||
{
|
||||
// XXXbz this code is pretty broken, since moving from one document
|
||||
// to another always passes through a null document!
|
||||
NS_PRECONDITION(aOldDocument != nsnull, "no old document");
|
||||
NS_PRECONDITION(!aNewDocument,
|
||||
"Changing to a non-null new document not supported yet");
|
||||
if (! aOldDocument)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
|
@ -432,6 +436,8 @@ nsBindingManager::ChangeDocumentFor(nsIContent* aContent, nsIDocument* aOldDocum
|
|||
|
||||
// See if the element has nsIAnonymousContentCreator-created
|
||||
// anonymous content...
|
||||
// XXXbz this really doesn't belong here, somehow... either that, or we
|
||||
// need to better define what sort of bindings we're managing.
|
||||
nsCOMPtr<nsISupportsArray> anonymousElements;
|
||||
shell->GetAnonymousContentFor(aContent, getter_AddRefs(anonymousElements));
|
||||
|
||||
|
@ -447,9 +453,12 @@ nsBindingManager::ChangeDocumentFor(nsIContent* aContent, nsIDocument* aOldDocum
|
|||
if (! content)
|
||||
continue;
|
||||
|
||||
content->SetDocument(aNewDocument, PR_TRUE, PR_TRUE);
|
||||
content->UnbindFromTree();
|
||||
}
|
||||
}
|
||||
|
||||
// now clear out the anonymous content for this node in the old presshell.
|
||||
shell->SetAnonymousContentFor(aContent, nsnull);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -191,19 +191,27 @@ nsXBLBinding::InstallAnonymousContent(nsIContent* aAnonParent, nsIContent* aElem
|
|||
// We need to ensure two things.
|
||||
// (1) The anonymous content should be fooled into thinking it's in the bound
|
||||
// element's document, assuming that the bound element is in a document
|
||||
nsIDocument* doc = aElement->GetCurrentDoc();
|
||||
|
||||
if (doc) {
|
||||
aAnonParent->SetDocument(doc, PR_TRUE, AllowScripts());
|
||||
}
|
||||
|
||||
// Note that we don't change the current doc of aAnonParent here, since that
|
||||
// quite simply does not matter. aAnonParent is just a way of keeping refs
|
||||
// to all its kids, which are anonymous content from the point of view of
|
||||
// aElement.
|
||||
// (2) The children's parent back pointer should not be to this synthetic root
|
||||
// but should instead point to the enclosing parent element.
|
||||
nsIDocument* doc = aElement->GetCurrentDoc();
|
||||
PRBool allowScripts = AllowScripts();
|
||||
|
||||
PRUint32 childCount = aAnonParent->GetChildCount();
|
||||
for (PRUint32 i = 0; i < childCount; i++) {
|
||||
nsIContent *child = aAnonParent->GetChildAt(i);
|
||||
child->SetParent(aElement);
|
||||
child->SetBindingParent(mBoundElement);
|
||||
child->UnbindFromTree();
|
||||
nsresult rv =
|
||||
child->BindToTree(doc, aElement, mBoundElement, allowScripts);
|
||||
if (NS_FAILED(rv)) {
|
||||
// Oh, well... Just give up.
|
||||
// XXXbz This really shouldn't be a void method!
|
||||
child->UnbindFromTree();
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
// To make XUL templates work (and other goodies that happen when
|
||||
|
@ -410,7 +418,7 @@ ChangeDocumentForDefaultContent(nsHashKey* aKey, void* aData, void* aClosure)
|
|||
nsCOMPtr<nsIContent> defContent = currPoint->GetDefaultContent();
|
||||
|
||||
if (defContent)
|
||||
defContent->SetDocument(nsnull, PR_TRUE, PR_TRUE);
|
||||
defContent->UnbindFromTree();
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
|
@ -909,7 +917,7 @@ nsXBLBinding::ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocumen
|
|||
nsCOMPtr<nsIXULDocument> xuldoc(do_QueryInterface(aOldDocument));
|
||||
#endif
|
||||
|
||||
anonymous->SetDocument(nsnull, PR_TRUE, PR_TRUE); // Kill it.
|
||||
anonymous->UnbindFromTree(); // Kill it.
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
// To make XUL templates work (and other XUL-specific stuff),
|
||||
|
|
|
@ -141,6 +141,15 @@ private:
|
|||
|
||||
class nsXBLInsertionPointEntry {
|
||||
public:
|
||||
~nsXBLInsertionPointEntry() {
|
||||
if (mDefaultContent) {
|
||||
// mDefaultContent is a sort of anonymous content within the XBL
|
||||
// document, and we own and manage it. Unhook it here, since we're going
|
||||
// away.
|
||||
mDefaultContent->UnbindFromTree();
|
||||
}
|
||||
}
|
||||
|
||||
nsIContent* GetInsertionParent() { return mInsertionParent; }
|
||||
PRUint32 GetInsertionIndex() { return mInsertionIndex; }
|
||||
void SetInsertionIndex(PRUint32 aIndex) { mInsertionIndex = aIndex; }
|
||||
|
@ -1186,7 +1195,14 @@ nsXBLPrototypeBinding::ConstructInsertionTable(nsIContent* aContent)
|
|||
// to work with on default content.
|
||||
// XXXbz this is somewhat screwed up, since it's sort of like anonymous
|
||||
// content... but not.
|
||||
child->SetParent(parent);
|
||||
nsresult rv =
|
||||
child->BindToTree(parent->GetCurrentDoc(), parent, nsnull, PR_FALSE);
|
||||
if (NS_FAILED(rv)) {
|
||||
// Well... now what? Just unbind and bail out, I guess...
|
||||
// XXXbz This really shouldn't be a void method!
|
||||
child->UnbindFromTree();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,9 +62,12 @@ public:
|
|||
NS_IMETHOD CloneNode(PRBool aDeep, nsIDOMNode** aReturn);
|
||||
|
||||
// nsIContent
|
||||
virtual void SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers);
|
||||
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
|
||||
PRBool aNullParent = PR_TRUE);
|
||||
|
||||
// nsStyleLinkElement
|
||||
NS_IMETHOD GetCharset(nsAString& aCharset);
|
||||
|
||||
|
@ -102,17 +105,29 @@ nsXMLStylesheetPI::~nsXMLStylesheetPI()
|
|||
|
||||
// nsIContent
|
||||
|
||||
void
|
||||
nsXMLStylesheetPI::SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers)
|
||||
nsresult
|
||||
nsXMLStylesheetPI::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> oldDoc = GetCurrentDoc();
|
||||
nsXMLProcessingInstruction::SetDocument(aDocument, aDeep,
|
||||
aCompileEventHandlers);
|
||||
nsresult rv = nsXMLProcessingInstruction::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
UpdateStyleSheet(oldDoc);
|
||||
UpdateStyleSheet(nsnull);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsXMLStylesheetPI::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> oldDoc = GetCurrentDoc();
|
||||
|
||||
nsXMLProcessingInstruction::UnbindFromTree(aDeep, aNullParent);
|
||||
UpdateStyleSheet(oldDoc);
|
||||
}
|
||||
|
||||
// nsIDOMNode
|
||||
|
||||
|
|
|
@ -743,9 +743,6 @@ nsXMLContentSink::FlushText(PRBool aCreateTextNode, PRBool* aDidFlush)
|
|||
rv = NS_NewTextNode(getter_AddRefs(textContent));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Set the content's document
|
||||
textContent->SetDocument(mDocument, PR_FALSE, PR_TRUE);
|
||||
|
||||
// Set the text in the text node
|
||||
textContent->SetText(mText, mTextLength, PR_FALSE);
|
||||
|
||||
|
@ -877,6 +874,13 @@ nsXMLContentSink::SetDocElement(PRInt32 aNameSpaceID,
|
|||
mDocElement = aContent;
|
||||
NS_ADDREF(mDocElement);
|
||||
|
||||
nsresult rv = mDocElement->BindToTree(mDocument, nsnull, nsnull, PR_TRUE);
|
||||
if (NS_FAILED(rv)) {
|
||||
mDocElement->UnbindFromTree();
|
||||
// If we return PR_FALSE here, the caller will bail out because it won't
|
||||
// find a parent content node to append to, which is fine.
|
||||
return PR_FALSE;
|
||||
}
|
||||
mDocument->SetRootContent(mDocElement);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
@ -927,7 +931,6 @@ nsXMLContentSink::HandleStartElement(const PRUnichar *aName,
|
|||
if (mDocument) {
|
||||
content->SetContentID(mDocument->GetAndIncrementContentID());
|
||||
}
|
||||
content->SetDocument(mDocument, PR_FALSE, PR_TRUE);
|
||||
|
||||
// Set the ID attribute atom on the node info object for this node
|
||||
// This must occur before the attributes are added so the name
|
||||
|
@ -1040,7 +1043,6 @@ nsXMLContentSink::HandleComment(const PRUnichar *aName)
|
|||
nsCOMPtr<nsIDOMComment> domComment = do_QueryInterface(comment, &result);
|
||||
if (domComment) {
|
||||
domComment->AppendData(nsDependentString(aName));
|
||||
comment->SetDocument(mDocument, PR_FALSE, PR_TRUE);
|
||||
result = AddContentAsLeaf(comment);
|
||||
}
|
||||
}
|
||||
|
@ -1064,7 +1066,6 @@ nsXMLContentSink::HandleCDataSection(const PRUnichar *aData,
|
|||
nsCOMPtr<nsIDOMCDATASection> domCDATA = do_QueryInterface(cdata);
|
||||
if (domCDATA) {
|
||||
domCDATA->SetData(nsDependentString(aData, aLength));
|
||||
cdata->SetDocument(mDocument, PR_FALSE, PR_TRUE);
|
||||
result = AddContentAsLeaf(cdata);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,46 +115,83 @@ nsXTFElementWrapper::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|||
//----------------------------------------------------------------------
|
||||
// nsIContent methods:
|
||||
|
||||
void
|
||||
nsXTFElementWrapper::SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers)
|
||||
nsresult
|
||||
nsXTFElementWrapper::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers)
|
||||
{
|
||||
// XXX For some reason we often get 2 SetDocument notifications with
|
||||
// identical aDocument (one when expat encounters the element and
|
||||
// another when the element is appended to its parent). We want to
|
||||
// make sure that we only route notifications if the document has
|
||||
// actually changed.
|
||||
bool docReallyChanged = false;
|
||||
if (aDocument!=GetCurrentDoc()) docReallyChanged = true;
|
||||
|
||||
// XXXbz making up random order for the notifications... Perhaps
|
||||
// this api should more closely match BindToTree/UnbindFromTree?
|
||||
nsCOMPtr<nsIDOMElement> domParent;
|
||||
if (aParent != GetParent()) {
|
||||
domParent = do_QueryInterface(aParent);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domDocument;
|
||||
if (docReallyChanged &&
|
||||
mNotificationMask & (nsIXTFElement::NOTIFY_WILL_CHANGE_DOCUMENT |
|
||||
nsIXTFElement::NOTIFY_DOCUMENT_CHANGED))
|
||||
if (aDocument &&
|
||||
(mNotificationMask & (nsIXTFElement::NOTIFY_WILL_CHANGE_DOCUMENT |
|
||||
nsIXTFElement::NOTIFY_DOCUMENT_CHANGED))) {
|
||||
domDocument = do_QueryInterface(aDocument);
|
||||
|
||||
if (docReallyChanged &&
|
||||
(mNotificationMask & nsIXTFElement::NOTIFY_WILL_CHANGE_DOCUMENT))
|
||||
}
|
||||
|
||||
if (domDocument &&
|
||||
(mNotificationMask & (nsIXTFElement::NOTIFY_WILL_CHANGE_DOCUMENT))) {
|
||||
GetXTFElement()->WillChangeDocument(domDocument);
|
||||
nsXTFElementWrapperBase::SetDocument(aDocument, aDeep, aCompileEventHandlers);
|
||||
if (docReallyChanged &&
|
||||
(mNotificationMask & nsIXTFElement::NOTIFY_DOCUMENT_CHANGED))
|
||||
}
|
||||
|
||||
if (domParent &&
|
||||
(mNotificationMask & (nsIXTFElement::NOTIFY_WILL_CHANGE_PARENT))) {
|
||||
GetXTFElement()->WillChangeParent(domParent);
|
||||
}
|
||||
|
||||
nsresult rv = nsXTFElementWrapperBase::BindToTree(aDocument, aParent,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (domDocument &&
|
||||
(mNotificationMask & (nsIXTFElement::NOTIFY_DOCUMENT_CHANGED))) {
|
||||
GetXTFElement()->DocumentChanged(domDocument);
|
||||
}
|
||||
|
||||
if (domParent &&
|
||||
(mNotificationMask & (nsIXTFElement::NOTIFY_PARENT_CHANGED))) {
|
||||
GetXTFElement()->ParentChanged(domParent);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsXTFElementWrapper::SetParent(nsIContent* aParent)
|
||||
nsXTFElementWrapper::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> domParent;
|
||||
if (mNotificationMask & (nsIXTFElement::NOTIFY_WILL_CHANGE_PARENT |
|
||||
nsIXTFElement::NOTIFY_PARENT_CHANGED))
|
||||
domParent = do_QueryInterface(aParent);
|
||||
|
||||
if (mNotificationMask & nsIXTFElement::NOTIFY_WILL_CHANGE_PARENT)
|
||||
GetXTFElement()->WillChangeParent(domParent);
|
||||
nsXTFElementWrapperBase::SetParent(aParent);
|
||||
if (mNotificationMask & nsIXTFElement::NOTIFY_PARENT_CHANGED)
|
||||
GetXTFElement()->ParentChanged(domParent);
|
||||
// XXXbz making up random order for the notifications... Perhaps
|
||||
// this api should more closely match BindToTree/UnbindFromTree?
|
||||
PRBool inDoc = IsInDoc();
|
||||
if (inDoc &&
|
||||
(mNotificationMask & nsIXTFElement::NOTIFY_WILL_CHANGE_DOCUMENT)) {
|
||||
GetXTFElement()->WillChangeDocument(nsnull);
|
||||
}
|
||||
|
||||
PRBool parentChanged = aNullParent && GetParent();
|
||||
|
||||
if (parentChanged &&
|
||||
(mNotificationMask & nsIXTFElement::NOTIFY_WILL_CHANGE_PARENT)) {
|
||||
GetXTFElement()->WillChangeParent(nsnull);
|
||||
}
|
||||
|
||||
nsXTFElementWrapperBase::UnbindFromTree(aDeep, aNullParent);
|
||||
|
||||
if (parentChanged &&
|
||||
(mNotificationMask & nsIXTFElement::NOTIFY_PARENT_CHANGED)) {
|
||||
GetXTFElement()->ParentChanged(nsnull);
|
||||
}
|
||||
|
||||
if (inDoc &&
|
||||
(mNotificationMask & nsIXTFElement::NOTIFY_DOCUMENT_CHANGED)) {
|
||||
GetXTFElement()->DocumentChanged(nsnull);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -76,9 +76,11 @@ public:
|
|||
// virtual PRUint32 GetElementType() = 0;
|
||||
|
||||
// nsIContent specializations:
|
||||
void SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers);
|
||||
void SetParent(nsIContent* aParent);
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
|
||||
PRBool aNullParent = PR_TRUE);
|
||||
nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
|
||||
PRBool aNotify, PRBool aDeepSetDocument);
|
||||
nsresult AppendChildTo(nsIContent* aKid, PRBool aNotify,
|
||||
|
|
|
@ -353,10 +353,12 @@ nsXULElement::nsXULElement(nsINodeInfo* aNodeInfo)
|
|||
|
||||
nsXULElement::~nsXULElement()
|
||||
{
|
||||
//XXX SetDocument(nsnull) is not called always before dtor.
|
||||
//XXX UnbindFromTree is not called always before dtor.
|
||||
//XXX Related to templates or overlays?
|
||||
if (IsInDoc())
|
||||
SetDocument(nsnull, PR_TRUE, PR_FALSE);
|
||||
//XXXbz probably related to the cloning thing!
|
||||
if (IsInDoc()) {
|
||||
UnbindFromTree();
|
||||
}
|
||||
|
||||
nsDOMSlots* slots = GetExistingDOMSlots();
|
||||
if (slots) {
|
||||
|
@ -512,24 +514,35 @@ nsXULElement::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
|
|||
|
||||
nsCOMPtr<nsIContent> result;
|
||||
|
||||
// XXX setting document on some nodes not in a document so XBL will bind
|
||||
// and chrome won't break. Make XBL bind to document-less nodes!
|
||||
// XXXbz Once this is fixed, fix up the asserts in all implementations of
|
||||
// BindToTree to assert what they would like to assert, and fix the
|
||||
// ChangeDocumentFor() call in nsXULElement::BindToTree as well. Also,
|
||||
// remove the UnbindFromTree call in ~nsXULElement, and add back in the
|
||||
// precondition in nsXULElement::UnbindFromTree.
|
||||
// Note: Make sure to do this witchery _after_ we've done any deep
|
||||
// cloning, so kids of the new node aren't confused about whether they're
|
||||
// in a document.
|
||||
|
||||
PRBool fakeBeingInDocument = PR_TRUE;
|
||||
|
||||
// If we have a prototype, so will our clone.
|
||||
if (mPrototype) {
|
||||
rv = nsXULElement::Create(mPrototype, GetOwnerDoc(), PR_TRUE,
|
||||
getter_AddRefs(result));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!IsInDoc()) {
|
||||
nsIContent* element = result;
|
||||
NS_STATIC_CAST(nsXULElement*, element)->
|
||||
mParentPtrBits &= ~PARENT_BIT_INDOCUMENT;
|
||||
}
|
||||
// Make sure to unset the "in document" bit we picked up in Create()
|
||||
// while we create our kids. We'll reset it as needed at the end of
|
||||
// this function.
|
||||
NS_STATIC_CAST(nsXULElement*,
|
||||
NS_STATIC_CAST(nsIContent*, result.get()))->
|
||||
mParentPtrBits &= ~PARENT_BIT_INDOCUMENT;
|
||||
fakeBeingInDocument = IsInDoc();
|
||||
} else {
|
||||
rv = NS_NewXULElement(getter_AddRefs(result), mNodeInfo);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// XXX setting document on nodes not in a document so XBL will bind
|
||||
// and chrome won't break. Make XBL bind to document-less nodes!
|
||||
result->SetDocument(GetCurrentDoc(), PR_TRUE, PR_TRUE);
|
||||
}
|
||||
|
||||
// Copy attributes
|
||||
|
@ -579,6 +592,14 @@ nsXULElement::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
|
|||
}
|
||||
}
|
||||
|
||||
if (fakeBeingInDocument) {
|
||||
// Don't use BindToTree here so we don't confuse the descendant
|
||||
// non-XUL nodes.
|
||||
NS_STATIC_CAST(nsXULElement*,
|
||||
NS_STATIC_CAST(nsIContent*, result.get()))->
|
||||
mParentPtrBits |= PARENT_BIT_INDOCUMENT;
|
||||
}
|
||||
|
||||
return CallQueryInterface(result, aReturn);
|
||||
}
|
||||
|
||||
|
@ -620,6 +641,8 @@ nsresult
|
|||
nsXULElement::AddScriptEventListener(nsIAtom* aName, const nsAString& aValue)
|
||||
{
|
||||
// XXX sXBL/XBL2 issue! Owner or current document?
|
||||
// Note that If it's current, then we need to hook up listeners on the root
|
||||
// when we BindToTree...
|
||||
nsIDocument* doc = GetOwnerDoc();
|
||||
if (!doc)
|
||||
return NS_OK; // XXX
|
||||
|
@ -854,102 +877,214 @@ nsXULElement::MaybeAddPopupListener(nsIAtom* aLocalName)
|
|||
// nsIContent interface
|
||||
//
|
||||
|
||||
void
|
||||
nsXULElement::SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers)
|
||||
nsresult
|
||||
nsXULElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers)
|
||||
{
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
if (aDocument != doc) {
|
||||
if (doc) {
|
||||
// Notify XBL- & nsIAnonymousContentCreator-generated
|
||||
// anonymous content that the document is changing.
|
||||
doc->BindingManager()->ChangeDocumentFor(this, doc, aDocument);
|
||||
NS_PRECONDITION(aParent || aDocument, "Must have document if no parent!");
|
||||
// XXXbz XUL elements are confused about their current doc when they're
|
||||
// cloned, so we don't assert if aParent is a XUL element and aDocument is
|
||||
// null, even if aParent->GetCurrentDoc() is non-null
|
||||
// NS_PRECONDITION(!aParent || aDocument == aParent->GetCurrentDoc(),
|
||||
// "aDocument must be current doc of aParent");
|
||||
NS_PRECONDITION(!aParent ||
|
||||
(aParent->IsContentOfType(eXUL) && aDocument == nsnull) ||
|
||||
aDocument == aParent->GetCurrentDoc(),
|
||||
"aDocument must be current doc of aParent");
|
||||
// XXXbz we'd like to assert that GetCurrentDoc() is null, but the cloning
|
||||
// mess makes that impossible. We can't even assert that aDocument ==
|
||||
// GetCurrentDoc() when GetCurrentDoc() is non-null, since we may be
|
||||
// getting inserted into a different document. :(
|
||||
// NS_PRECONDITION(!GetCurrentDoc(),
|
||||
// "Already have a document. Unbind first!");
|
||||
|
||||
nsCOMPtr<nsIDOMNSDocument> nsDoc(do_QueryInterface(doc));
|
||||
nsDoc->SetBoxObjectFor(this, nsnull);
|
||||
// Note that as we recurse into the kids, they'll have a non-null
|
||||
// parent. So only assert if our parent is _changing_ while we
|
||||
// have a parent.
|
||||
NS_PRECONDITION(!GetParent() || aParent == GetParent(),
|
||||
"Already have a parent. Unbind first!");
|
||||
NS_PRECONDITION(!GetBindingParent() ||
|
||||
aBindingParent == GetBindingParent() ||
|
||||
(!aBindingParent && aParent &&
|
||||
aParent->GetBindingParent() == GetBindingParent()),
|
||||
"Already have a binding parent. Unbind first!");
|
||||
|
||||
if (HasProperties()) {
|
||||
doc->PropertyTable()->DeleteAllPropertiesFor(this);
|
||||
}
|
||||
}
|
||||
if (!aBindingParent && aParent) {
|
||||
aBindingParent = aParent->GetBindingParent();
|
||||
}
|
||||
|
||||
// mControllers can own objects that are implemented
|
||||
// in JavaScript (such as some implementations of
|
||||
// nsIControllers. These objects prevent their global
|
||||
// object's script object from being garbage collected,
|
||||
// which means JS continues to hold an owning reference
|
||||
// to the nsGlobalWindow, which owns the document,
|
||||
// which owns this content. That's a cycle, so we break
|
||||
// it here. (It might be better to break this by releasing
|
||||
// mDocument in nsGlobalWindow::SetDocShell, but I'm not
|
||||
// sure whether that would fix all possible cycles through
|
||||
// mControllers.)
|
||||
nsDOMSlots* slots = GetExistingDOMSlots();
|
||||
if (!aDocument && slots) {
|
||||
NS_IF_RELEASE(slots->mControllers); // Forces release
|
||||
}
|
||||
// First set the binding parent
|
||||
mBindingParent = aBindingParent;
|
||||
|
||||
// Now set the parent; make sure to preserve the bits we have
|
||||
// stashed there Note that checking whether aParent == GetParent()
|
||||
// is probably not worth it here.
|
||||
PtrBits new_bits = NS_REINTERPRET_CAST(PtrBits, aParent);
|
||||
new_bits |= mParentPtrBits & nsIContent::kParentBitMask;
|
||||
mParentPtrBits = new_bits;
|
||||
|
||||
if (mListenerManager)
|
||||
mListenerManager->SetListenerTarget(nsnull);
|
||||
mListenerManager = nsnull;
|
||||
// Finally, set the document
|
||||
if (aDocument && aDocument != GetCurrentDoc()) {
|
||||
// Notify XBL- & nsIAnonymousContentCreator-generated
|
||||
// anonymous content that the document is changing.
|
||||
// XXXbz ordering issues here? Probably not, since ChangeDocumentFor
|
||||
// is just pretty broken anyway.... Need to get it working.
|
||||
// XXXbz XBL doesn't handle this (asserts), and we don't really want
|
||||
// to be doing this during parsing anyway... sort this out.
|
||||
// aDocument->BindingManager()->ChangeDocumentFor(this, nsnull,
|
||||
// aDocument);
|
||||
|
||||
// Being added to a document.
|
||||
mParentPtrBits |= PARENT_BIT_INDOCUMENT;
|
||||
|
||||
if (aDocument) {
|
||||
mParentPtrBits |= PARENT_BIT_INDOCUMENT;
|
||||
if (aDocument != mNodeInfo->GetDocument()) {
|
||||
// get a new nodeinfo
|
||||
nsNodeInfoManager* nodeInfoManager = aDocument->NodeInfoManager();
|
||||
if (nodeInfoManager) {
|
||||
// check the document on the nodeinfo to see whether we need a
|
||||
// new nodeinfo
|
||||
// XXXbz sXBL/XBL2 issue!
|
||||
nsIDocument *ownerDocument = GetOwnerDoc();
|
||||
if (aDocument != ownerDocument) {
|
||||
|
||||
if (HasProperties()) {
|
||||
ownerDocument->PropertyTable()->DeleteAllPropertiesFor(this);
|
||||
}
|
||||
|
||||
// get a new nodeinfo
|
||||
nsNodeInfoManager* nodeInfoManager = aDocument->NodeInfoManager();
|
||||
if (nodeInfoManager) {
|
||||
nsCOMPtr<nsINodeInfo> newNodeInfo;
|
||||
nodeInfoManager->GetNodeInfo(mNodeInfo->NameAtom(),
|
||||
mNodeInfo->GetPrefixAtom(),
|
||||
mNodeInfo->NamespaceID(),
|
||||
getter_AddRefs(newNodeInfo));
|
||||
if (newNodeInfo) {
|
||||
mNodeInfo.swap(newNodeInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
// When we SetDocument(), we're either adding an element
|
||||
// into the document that wasn't there before, or we're
|
||||
// moving the element from one document to
|
||||
// another. Regardless, we need to (re-)initialize several
|
||||
// attributes that are dependant on the document. Do that
|
||||
// now.
|
||||
PRInt32 count = mAttrsAndChildren.AttrCount();
|
||||
PRBool haveLocalAttributes = (count > 0);
|
||||
PRInt32 i;
|
||||
for (i = 0; i < count; i++) {
|
||||
AddListenerFor(*mAttrsAndChildren.GetSafeAttrNameAt(i),
|
||||
aCompileEventHandlers);
|
||||
}
|
||||
|
||||
if (mPrototype) {
|
||||
PRInt32 count = mPrototype->mNumAttributes;
|
||||
for (i = 0; i < count; i++) {
|
||||
nsXULPrototypeAttribute *protoattr =
|
||||
&mPrototype->mAttributes[i];
|
||||
|
||||
// Don't clobber a locally modified attribute.
|
||||
if (haveLocalAttributes &&
|
||||
mAttrsAndChildren.GetAttr(protoattr->mName.LocalName(),
|
||||
protoattr->mName.NamespaceID())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AddListenerFor(protoattr->mName, aCompileEventHandlers);
|
||||
}
|
||||
nsresult rv =
|
||||
nodeInfoManager->GetNodeInfo(mNodeInfo->NameAtom(),
|
||||
mNodeInfo->GetPrefixAtom(),
|
||||
mNodeInfo->NamespaceID(),
|
||||
getter_AddRefs(newNodeInfo));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ASSERTION(newNodeInfo, "GetNodeInfo lies");
|
||||
mNodeInfo.swap(newNodeInfo);
|
||||
}
|
||||
}
|
||||
else {
|
||||
mParentPtrBits &= ~PARENT_BIT_INDOCUMENT;
|
||||
|
||||
// we need to (re-)initialize several attributes that are dependant on
|
||||
// the document. Do that now.
|
||||
// XXXbz why do we have attributes depending on the current document?
|
||||
// Shouldn't they depend on the owner document? Or is this code just
|
||||
// misplaced, basically?
|
||||
|
||||
PRInt32 count = mAttrsAndChildren.AttrCount();
|
||||
PRBool haveLocalAttributes = (count > 0);
|
||||
PRInt32 i;
|
||||
for (i = 0; i < count; i++) {
|
||||
AddListenerFor(*mAttrsAndChildren.GetSafeAttrNameAt(i),
|
||||
aCompileEventHandlers);
|
||||
}
|
||||
|
||||
if (mPrototype) {
|
||||
PRInt32 count = mPrototype->mNumAttributes;
|
||||
for (i = 0; i < count; i++) {
|
||||
nsXULPrototypeAttribute *protoattr =
|
||||
&mPrototype->mAttributes[i];
|
||||
|
||||
// Don't clobber a locally modified attribute.
|
||||
if (haveLocalAttributes &&
|
||||
mAttrsAndChildren.GetAttr(protoattr->mName.LocalName(),
|
||||
protoattr->mName.NamespaceID())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AddListenerFor(protoattr->mName, aCompileEventHandlers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now recurse into our kids
|
||||
PRUint32 i, n = GetChildCount();
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
nsresult rv =
|
||||
mAttrsAndChildren.ChildAt(i)->BindToTree(aDocument, this,
|
||||
aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// XXXbz script execution during binding can trigger some of these
|
||||
// postcondition asserts.... But we do want that, since things will
|
||||
// generally be quite broken when that happens.
|
||||
// XXXbz we'd like to assert that we have the right GetCurrentDoc(), but
|
||||
// we may be being bound to a null document while we already have a
|
||||
// current doc, due to the cloneNode hack... So can't assert that yet.
|
||||
// NS_POSTCONDITION(aDocument == GetCurrentDoc(),
|
||||
// "Bound to wrong document");
|
||||
NS_POSTCONDITION(aParent == GetParent(), "Bound to wrong parent");
|
||||
NS_POSTCONDITION(aBindingParent == GetBindingParent(),
|
||||
"Bound to wrong binding parent");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsXULElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
{
|
||||
// XXXbz we'd like to assert that called didn't screw up aDeep, but I'm not
|
||||
// sure we can....
|
||||
// NS_PRECONDITION(aDeep || (!GetCurrentDoc() && !GetBindingParent()),
|
||||
// "Shallow unbind won't clear document and binding "
|
||||
// "parent on kids!");
|
||||
// Make sure to unbind this node before doing the kids
|
||||
nsIDocument *document = GetCurrentDoc();
|
||||
if (document) {
|
||||
// Notify XBL- & nsIAnonymousContentCreator-generated
|
||||
// anonymous content that the document is changing.
|
||||
document->BindingManager()->ChangeDocumentFor(this, document, nsnull);
|
||||
|
||||
nsCOMPtr<nsIDOMNSDocument> nsDoc(do_QueryInterface(document));
|
||||
nsDoc->SetBoxObjectFor(this, nsnull);
|
||||
}
|
||||
|
||||
// mControllers can own objects that are implemented
|
||||
// in JavaScript (such as some implementations of
|
||||
// nsIControllers. These objects prevent their global
|
||||
// object's script object from being garbage collected,
|
||||
// which means JS continues to hold an owning reference
|
||||
// to the nsGlobalWindow, which owns the document,
|
||||
// which owns this content. That's a cycle, so we break
|
||||
// it here. (It might be better to break this by releasing
|
||||
// mDocument in nsGlobalWindow::SetDocShell, but I'm not
|
||||
// sure whether that would fix all possible cycles through
|
||||
// mControllers.)
|
||||
nsDOMSlots* slots = GetExistingDOMSlots();
|
||||
if (slots) {
|
||||
NS_IF_RELEASE(slots->mControllers);
|
||||
}
|
||||
|
||||
// XXXbz why are we nuking our listener manager? We can get events while
|
||||
// not in a document!
|
||||
if (mListenerManager) {
|
||||
mListenerManager->SetListenerTarget(nsnull);
|
||||
mListenerManager = nsnull;
|
||||
}
|
||||
|
||||
// Unset things in the reverse order from how we set them in BindToTree
|
||||
mParentPtrBits &= ~PARENT_BIT_INDOCUMENT;
|
||||
|
||||
if (aNullParent) {
|
||||
// Just mask it out
|
||||
mParentPtrBits &= nsIContent::kParentBitMask;
|
||||
}
|
||||
|
||||
mBindingParent = nsnull;
|
||||
|
||||
if (aDeep) {
|
||||
PRInt32 i;
|
||||
for (i = mAttrsAndChildren.ChildCount() - 1; i >= 0; --i) {
|
||||
mAttrsAndChildren.ChildAt(i)->SetDocument(aDocument, aDeep,
|
||||
aCompileEventHandlers);
|
||||
// Do the kids. Note that we don't want to GetChildCount(), because
|
||||
// that will force content generation... if we never had to generate
|
||||
// the content, we shouldn't force it now!
|
||||
PRUint32 i, n = PeekChildCount();
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
// Note that we pass PR_FALSE for aNullParent here, since we don't
|
||||
// want the kids to forget us. We _do_ want them to forget their
|
||||
// binding parent, though, since this only walks non-anonymous
|
||||
// kids.
|
||||
mAttrsAndChildren.ChildAt(i)->UnbindFromTree(PR_TRUE, PR_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1014,12 +1149,25 @@ nsXULElement::InsertChildAt(nsIContent* aKid, PRUint32 aIndex, PRBool aNotify,
|
|||
rv = mAttrsAndChildren.InsertChildAt(aKid, aIndex);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aKid->SetParent(this);
|
||||
rv = aKid->BindToTree(doc, this, nsnull, PR_TRUE);
|
||||
if (NS_FAILED(rv)) {
|
||||
mAttrsAndChildren.RemoveChildAt(aIndex);
|
||||
aKid->UnbindFromTree();
|
||||
return rv;
|
||||
}
|
||||
|
||||
// XXXbz this screws up ranges, no? Need to figure out why this is
|
||||
// commented and uncomment....
|
||||
//nsRange::OwnerChildInserted(this, aIndex);
|
||||
|
||||
if (doc) {
|
||||
aKid->SetDocument(doc, aDeepSetDocument, PR_TRUE);
|
||||
|
||||
// The kid may have removed us from the document, so recheck that we're
|
||||
// still in the document before proceeding. Also, the kid may have just
|
||||
// removed itself, in which case we don't really want to fire
|
||||
// ContentAppended or a mutation event.
|
||||
// XXXbz What if the kid just moved us in the document? Scripts suck. We
|
||||
// really need to stop running them while we're in the middle of modifying
|
||||
// the DOM....
|
||||
if (doc && doc == GetCurrentDoc() && aKid->GetParent() == this) {
|
||||
if (aNotify) {
|
||||
if (isAppend) {
|
||||
doc->ContentAppended(this, aIndex);
|
||||
|
@ -1059,12 +1207,22 @@ nsXULElement::AppendChildTo(nsIContent* aKid, PRBool aNotify,
|
|||
rv = mAttrsAndChildren.AppendChild(aKid);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aKid->SetParent(this);
|
||||
rv = aKid->BindToTree(doc, this, nsnull, PR_TRUE);
|
||||
if (NS_FAILED(rv)) {
|
||||
mAttrsAndChildren.RemoveChildAt(GetChildCount() - 1);
|
||||
aKid->UnbindFromTree();
|
||||
return rv;
|
||||
}
|
||||
// ranges don't need adjustment since new child is at end of list
|
||||
|
||||
if (doc) {
|
||||
aKid->SetDocument(doc, aDeepSetDocument, PR_TRUE);
|
||||
|
||||
// The kid may have removed us from the document, so recheck that we're
|
||||
// still in the document before proceeding. Also, the kid may have just
|
||||
// removed itself, in which case we don't really want to fire
|
||||
// ContentAppended or a mutation event.
|
||||
// XXXbz What if the kid just moved us in the document? Scripts suck. We
|
||||
// really need to stop running them while we're in the middle of modifying
|
||||
// the DOM....
|
||||
if (doc && doc == GetCurrentDoc() && aKid->GetParent() == this) {
|
||||
if (aNotify) {
|
||||
doc->ContentAppended(this, mAttrsAndChildren.ChildCount() - 1);
|
||||
}
|
||||
|
@ -1205,10 +1363,7 @@ nsXULElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
|
|||
|
||||
// This will cause the script object to be unrooted for each
|
||||
// element in the subtree.
|
||||
oldKid->SetDocument(nsnull, PR_TRUE, PR_TRUE);
|
||||
|
||||
// We've got no mo' parent.
|
||||
oldKid->SetParent(nsnull);
|
||||
oldKid->UnbindFromTree();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -2655,22 +2810,6 @@ nsXULElement::GetBindingParent() const
|
|||
return mBindingParent;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXULElement::SetBindingParent(nsIContent* aParent)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
mBindingParent = aParent; // [Weak] no addref
|
||||
if (mBindingParent) {
|
||||
PRUint32 count = GetChildCount();
|
||||
for (PRUint32 i = 0; i < count; i++) {
|
||||
rv |= GetChildAt(i)->SetBindingParent(aParent);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsXULElement::IsContentOfType(PRUint32 aFlags) const
|
||||
{
|
||||
|
|
|
@ -461,8 +461,11 @@ public:
|
|||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIContent
|
||||
virtual void SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
|
||||
PRBool aNullParent = PR_TRUE);
|
||||
virtual PRBool IsNativeAnonymous() const;
|
||||
virtual PRUint32 GetChildCount() const;
|
||||
virtual nsIContent *GetChildAt(PRUint32 aIndex) const;
|
||||
|
@ -511,7 +514,6 @@ public:
|
|||
virtual void RemoveFocus(nsPresContext* aPresContext);
|
||||
|
||||
virtual nsIContent *GetBindingParent() const;
|
||||
virtual nsresult SetBindingParent(nsIContent* aParent);
|
||||
virtual PRBool IsContentOfType(PRUint32 aFlags) const;
|
||||
virtual nsresult GetListenerManager(nsIEventListenerManager** aResult);
|
||||
virtual PRBool IsFocusable(PRInt32 *aTabIndex = nsnull);
|
||||
|
|
|
@ -2573,6 +2573,9 @@ nsXULDocument::PrepareToWalk()
|
|||
rv = CreateElementFromPrototype(proto, getter_AddRefs(root));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = root->BindToTree(this, nsnull, nsnull, PR_TRUE);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
SetRootContent(root);
|
||||
|
||||
// Add the root element to the XUL document's ID-to-element map.
|
||||
|
@ -3545,8 +3548,6 @@ nsXULDocument::CreateElementFromPrototype(nsXULPrototypeElement* aPrototype,
|
|||
aPrototype->mNodeInfo);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
result->SetDocument(this, PR_FALSE, PR_TRUE);
|
||||
|
||||
rv = AddAttributes(aPrototype, result);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
|
|
@ -357,6 +357,7 @@ protected:
|
|||
|
||||
/**
|
||||
* Create a delegate content model element from a prototype.
|
||||
* Note that the resulting content node is not bound to any tree
|
||||
*/
|
||||
nsresult CreateElementFromPrototype(nsXULPrototypeElement* aPrototype,
|
||||
nsIContent** aResult);
|
||||
|
|
|
@ -1065,13 +1065,12 @@ nsXULContentBuilder::RemoveMember(nsIContent* aContainerElement,
|
|||
NS_ASSERTION(pos >= 0, "parent doesn't think this child has an index");
|
||||
if (pos < 0) continue;
|
||||
|
||||
// Note: RemoveChildAt sets |child|'s document to null so that
|
||||
// it'll get knocked out of the XUL doc's resource-to-element
|
||||
// map.
|
||||
rv = parent->RemoveChildAt(pos, aNotify);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Set its document to null so that it'll get knocked out of
|
||||
// the XUL doc's resource-to-element map.
|
||||
child->SetDocument(nsnull, PR_TRUE, PR_TRUE);
|
||||
|
||||
// Remove from the content support map.
|
||||
mContentSupportMap.Remove(child);
|
||||
|
||||
|
@ -1472,8 +1471,6 @@ nsXULContentBuilder::CreateElement(PRInt32 aNameSpaceID,
|
|||
rv = NS_NewElement(getter_AddRefs(result), aNameSpaceID, nodeInfo);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
result->SetDocument(doc, PR_FALSE, PR_TRUE);
|
||||
|
||||
*aResult = result;
|
||||
NS_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
|
|
|
@ -153,9 +153,12 @@ nsHTMLEditor::CreateAnonymousElement(const nsAString & aTag, nsIDOMNode * aPare
|
|||
|
||||
// establish parenthood of the element
|
||||
newContent->SetNativeAnonymous(PR_TRUE);
|
||||
newContent->SetParent(parentContent);
|
||||
newContent->SetDocument(doc, PR_TRUE, PR_TRUE);
|
||||
newContent->SetBindingParent(newContent);
|
||||
res = newContent->BindToTree(doc, parentContent, newContent, PR_TRUE);
|
||||
if (NS_FAILED(res)) {
|
||||
newContent->UnbindFromTree();
|
||||
return res;
|
||||
}
|
||||
|
||||
// display the element
|
||||
ps->RecreateFramesFor(newContent);
|
||||
|
||||
|
@ -178,10 +181,8 @@ nsHTMLEditor::DeleteRefToAnonymousNode(nsIDOMElement* aElement,
|
|||
nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
|
||||
if (content) {
|
||||
aDocObserver->ContentRemoved(content->GetCurrentDoc(),
|
||||
aParentContent, content, -1);
|
||||
content->SetParent(nsnull);
|
||||
content->SetBindingParent(nsnull);
|
||||
content->SetDocument(nsnull, PR_TRUE, PR_TRUE);
|
||||
aParentContent, content, -1);
|
||||
content->UnbindFromTree();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -249,7 +249,12 @@ void txMozillaTextOutput::createResultDocument(nsIDOMDocument* aSourceDocument,
|
|||
return;
|
||||
}
|
||||
|
||||
rootContent->SetDocument(doc, PR_FALSE, PR_TRUE);
|
||||
rv = rootContent->BindToTree(doc, nsnull, nsnull, PR_TRUE);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("Failed to bind root to tree");
|
||||
rootContent->UnbindFromTree();
|
||||
return rv;
|
||||
}
|
||||
|
||||
doc->SetRootContent(rootContent);
|
||||
|
||||
|
|
|
@ -296,12 +296,12 @@ void txMozillaXMLOutput::endElement(const nsAString& aName, const PRInt32 aNsID)
|
|||
// up the tree
|
||||
// we can't use GetParentNode to check if mCurrentNode is the
|
||||
// "non-added node" since that does strange things when we've called
|
||||
// SetDocument manually
|
||||
// BindToTree manually
|
||||
if (mCurrentNode == mNonAddedNode) {
|
||||
nsCOMPtr<nsIDocument> document = do_QueryInterface(mNonAddedParent);
|
||||
if (document && !mRootContent) {
|
||||
mRootContent = do_QueryInterface(mCurrentNode);
|
||||
mRootContent->SetDocument(document, PR_FALSE, PR_TRUE);
|
||||
mRootContent->BindToTree(document, nsnull, nsnull, PR_TRUE);
|
||||
document->SetRootContent(mRootContent);
|
||||
}
|
||||
else {
|
||||
|
@ -455,11 +455,6 @@ void txMozillaXMLOutput::startElement(const nsAString& aName,
|
|||
ssle->InitStyleLinkElement(nsnull, PR_FALSE);
|
||||
ssle->SetEnableUpdates(PR_FALSE);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> cont = do_QueryInterface(element);
|
||||
NS_ASSERTION(cont, "element doesn't implement nsIContent");
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(mDocument);
|
||||
cont->SetDocument(doc, PR_FALSE, PR_TRUE);
|
||||
}
|
||||
mParentNode = mCurrentNode;
|
||||
mCurrentNode = do_QueryInterface(element);
|
||||
|
@ -498,7 +493,7 @@ void txMozillaXMLOutput::closePrevious(PRInt8 aAction)
|
|||
|
||||
mParentNode = wrapper;
|
||||
mRootContent = do_QueryInterface(wrapper);
|
||||
mRootContent->SetDocument(document, PR_FALSE, PR_TRUE);
|
||||
mRootContent->BindToTree(document, nsnull, nsnull, PR_TRUE);
|
||||
document->SetRootContent(mRootContent);
|
||||
}
|
||||
|
||||
|
@ -509,7 +504,7 @@ void txMozillaXMLOutput::closePrevious(PRInt8 aAction)
|
|||
else {
|
||||
if (document && currentElement && !mRootContent) {
|
||||
mRootContent = do_QueryInterface(mCurrentNode);
|
||||
mRootContent->SetDocument(document, PR_FALSE, PR_TRUE);
|
||||
mRootContent->BindToTree(document, nsnull, nsnull, PR_TRUE);
|
||||
document->SetRootContent(mRootContent);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -712,7 +712,7 @@ txMozillaXSLTProcessor::notifyError()
|
|||
return;
|
||||
}
|
||||
|
||||
rootContent->SetDocument(document, PR_FALSE, PR_TRUE);
|
||||
rootContent->BindToTree(document, nsnull, nsnull, PR_TRUE);
|
||||
document->SetRootContent(rootContent);
|
||||
|
||||
nsCOMPtr<nsIDOMText> text;
|
||||
|
|
|
@ -2024,13 +2024,16 @@ nsCSSFrameConstructor::CreateGeneratedFrameFor(nsIFrame* aParentFram
|
|||
|
||||
// Set aContent as the parent content and set the document object. This
|
||||
// way event handling works
|
||||
content->SetParent(aContent);
|
||||
content->SetDocument(mDocument, PR_TRUE, PR_TRUE);
|
||||
// Hack the binding parent to make document rules not match (not
|
||||
// like it matters, since we already have a non-element style
|
||||
// context... which is totally wacky, but anyway).
|
||||
rv = content->BindToTree(mDocument, aContent, content, PR_TRUE);
|
||||
if (NS_FAILED(rv)) {
|
||||
content->UnbindFromTree();
|
||||
return rv;
|
||||
}
|
||||
|
||||
content->SetNativeAnonymous(PR_TRUE);
|
||||
// hack to make document rules not match (not like it matters, since we
|
||||
// already have a non-element style context... which is totally wacky, but
|
||||
// anyway).
|
||||
content->SetBindingParent(content);
|
||||
|
||||
// Create an image frame and initialize it
|
||||
nsIFrame* imageFrame = nsnull;
|
||||
|
@ -2086,15 +2089,18 @@ nsCSSFrameConstructor::CreateGeneratedFrameFor(nsIFrame* aParentFram
|
|||
nsresult rv = NS_ERROR_FAILURE;
|
||||
if (attrName) {
|
||||
nsIFrame* textFrame = nsnull;
|
||||
rv = NS_NewAttributeContent(aContent, attrNameSpace, attrName,
|
||||
rv = NS_NewAttributeContent(attrNameSpace, attrName,
|
||||
getter_AddRefs(content));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Set aContent as the parent content so that event handling works.
|
||||
content->SetParent(aContent);
|
||||
content->SetDocument(mDocument, PR_TRUE, PR_TRUE);
|
||||
rv = content->BindToTree(mDocument, aContent, content, PR_TRUE);
|
||||
if (NS_FAILED(rv)) {
|
||||
content->UnbindFromTree();
|
||||
return rv;
|
||||
}
|
||||
|
||||
content->SetNativeAnonymous(PR_TRUE);
|
||||
content->SetBindingParent(content);
|
||||
|
||||
// Create a text frame and initialize it
|
||||
NS_NewTextFrame(mPresShell, &textFrame);
|
||||
|
@ -2182,10 +2188,14 @@ nsCSSFrameConstructor::CreateGeneratedFrameFor(nsIFrame* aParentFram
|
|||
}
|
||||
|
||||
// Set aContent as the parent content so that event handling works.
|
||||
textContent->SetParent(aContent);
|
||||
textContent->SetDocument(mDocument, PR_TRUE, PR_TRUE);
|
||||
nsresult rv = textContent->BindToTree(mDocument, aContent, textContent,
|
||||
PR_TRUE);
|
||||
if (NS_FAILED(rv)) {
|
||||
textContent->UnbindFromTree();
|
||||
return rv;
|
||||
}
|
||||
|
||||
textContent->SetNativeAnonymous(PR_TRUE);
|
||||
textContent->SetBindingParent(textContent);
|
||||
|
||||
// Create a text frame and initialize it
|
||||
NS_NewTextFrame(mPresShell, &textFrame);
|
||||
|
@ -5615,10 +5625,9 @@ nsCSSFrameConstructor::CreateAnonymousFrames(nsFrameConstructorState& aState,
|
|||
continue;
|
||||
|
||||
content->SetNativeAnonymous(PR_TRUE);
|
||||
content->SetParent(aParent);
|
||||
content->SetDocument(aDocument, PR_TRUE, PR_TRUE);
|
||||
|
||||
nsresult rv;
|
||||
nsIContent* bindingParent = content;
|
||||
#ifdef MOZ_XUL
|
||||
// Only cut XUL scrollbars off if they're not in a XUL document.
|
||||
// This allows scrollbars to be styled from XUL (although not
|
||||
|
@ -5629,15 +5638,13 @@ nsCSSFrameConstructor::CreateAnonymousFrames(nsFrameConstructorState& aState,
|
|||
ni->Equals(nsXULAtoms::scrollcorner, kNameSpaceID_XUL))) {
|
||||
nsCOMPtr<nsIDOMXULDocument> xulDoc(do_QueryInterface(aDocument));
|
||||
if (xulDoc)
|
||||
rv = content->SetBindingParent(aParent);
|
||||
else
|
||||
rv = content->SetBindingParent(content);
|
||||
bindingParent = aParent;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef MOZ_XTF
|
||||
if (aForceBindingParent)
|
||||
rv = content->SetBindingParent(aParent);
|
||||
bindingParent = aParent;
|
||||
else
|
||||
#endif
|
||||
#ifdef MOZ_SVG
|
||||
|
@ -5646,12 +5653,14 @@ nsCSSFrameConstructor::CreateAnonymousFrames(nsFrameConstructorState& aState,
|
|||
if (aParent &&
|
||||
aParent->GetNodeInfo() &&
|
||||
aParent->GetNodeInfo()->Equals(nsSVGAtoms::use, kNameSpaceID_SVG))
|
||||
rv = content->SetBindingParent(aParent);
|
||||
else
|
||||
bindingParent = aParent;
|
||||
#endif
|
||||
rv = content->SetBindingParent(content);
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = content->BindToTree(aDocument, aParent, bindingParent, PR_TRUE);
|
||||
if (NS_FAILED(rv)) {
|
||||
content->UnbindFromTree();
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsIFrame * newFrame = nsnull;
|
||||
rv = creator->CreateFrameFor(aState.mPresContext, content, &newFrame);
|
||||
|
@ -10484,8 +10493,14 @@ nsCSSFrameConstructor::ConstructAlternateFrame(nsIContent* aContent,
|
|||
altTextContent->SetText(altText, PR_TRUE);
|
||||
|
||||
// Set aContent as the parent content.
|
||||
altTextContent->SetParent(aContent);
|
||||
altTextContent->SetDocument(mDocument, PR_TRUE, PR_TRUE);
|
||||
// XXXbz should this set the binding parent to |altTextContent|?
|
||||
rv = altTextContent->BindToTree(mDocument, aContent, nsnull, PR_TRUE);
|
||||
if (NS_FAILED(rv)) {
|
||||
altTextContent->UnbindFromTree();
|
||||
return rv;
|
||||
}
|
||||
|
||||
// XXXbz shouldn't it be set native anonymous too?
|
||||
|
||||
// Create either an inline frame, block frame, or area frame
|
||||
nsIFrame* containerFrame;
|
||||
|
|
|
@ -4904,7 +4904,7 @@ PresShell::SetAnonymousContentFor(nsIContent* aContent, nsISupportsArray* aAnony
|
|||
if (! content)
|
||||
continue;
|
||||
|
||||
content->SetDocument(nsnull, PR_TRUE, PR_TRUE);
|
||||
content->UnbindFromTree();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4943,7 +4943,7 @@ ClearDocumentEnumerator(nsHashKey* aKey, void* aData, void* aClosure)
|
|||
if (! content)
|
||||
continue;
|
||||
|
||||
content->SetDocument(nsnull, PR_TRUE, PR_TRUE);
|
||||
content->UnbindFromTree();
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
|
|
|
@ -362,15 +362,20 @@ nsContentDLF::CreateBlankDocument(nsILoadGroup *aLoadGroup, nsIDocument **aDocum
|
|||
|
||||
// blat in the structure
|
||||
if (htmlElement && headElement && bodyElement) {
|
||||
htmlElement->SetDocument(blankDoc, PR_FALSE, PR_TRUE);
|
||||
blankDoc->SetRootContent(htmlElement);
|
||||
rv = htmlElement->BindToTree(blankDoc, nsnull, nsnull, PR_TRUE);
|
||||
if (NS_FAILED(rv)) {
|
||||
htmlElement->UnbindFromTree();
|
||||
} else {
|
||||
blankDoc->SetRootContent(htmlElement);
|
||||
|
||||
htmlElement->AppendChildTo(headElement, PR_FALSE, PR_FALSE);
|
||||
htmlElement->AppendChildTo(headElement, PR_FALSE, PR_FALSE);
|
||||
|
||||
bodyElement->SetContentID(blankDoc->GetAndIncrementContentID());
|
||||
htmlElement->AppendChildTo(bodyElement, PR_FALSE, PR_FALSE);
|
||||
bodyElement->SetContentID(blankDoc->GetAndIncrementContentID());
|
||||
// XXXbz Why not notifying here?
|
||||
htmlElement->AppendChildTo(bodyElement, PR_FALSE, PR_FALSE);
|
||||
|
||||
rv = NS_OK;
|
||||
rv = NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -130,8 +130,7 @@ CleanupGeneratedContentIn(nsIContent* aRealContent, nsIFrame* aRoot) {
|
|||
while (child) {
|
||||
nsIContent* content = child->GetContent();
|
||||
if (content && content != aRealContent) {
|
||||
content->SetParent(nsnull);
|
||||
content->SetDocument(nsnull, PR_TRUE, PR_TRUE);
|
||||
content->UnbindFromTree();
|
||||
}
|
||||
::CleanupGeneratedContentIn(aRealContent, child);
|
||||
child = child->GetNextSibling();
|
||||
|
|
|
@ -89,8 +89,8 @@ NS_NewBlockFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame,
|
|||
|
||||
// Special Generated Content Frame
|
||||
nsresult
|
||||
NS_NewAttributeContent(nsIContent* aContent, PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttrName, nsIContent** aResult);
|
||||
NS_NewAttributeContent(PRInt32 aNameSpaceID, nsIAtom* aAttrName,
|
||||
nsIContent** aResult);
|
||||
|
||||
// Create a basic area frame but the GetFrameForPoint is overridden to always
|
||||
// return the option frame
|
||||
|
|
|
@ -1564,9 +1564,13 @@ nsObjectFrame::CreateDefaultFrames(nsPresContext *aPresContext,
|
|||
img->SetNativeAnonymous(PR_TRUE);
|
||||
text->SetNativeAnonymous(PR_TRUE);
|
||||
|
||||
// Set up the anonymous tree
|
||||
anchor->SetParent(mContent);
|
||||
anchor->SetDocument(doc, PR_TRUE, PR_TRUE);
|
||||
// Set up the anonymous tree. Note that the binding parent for the anchor is
|
||||
// used to cut off style rules from the page so they won't apply to it.
|
||||
rv = anchor->BindToTree(doc, mContent, anchor, PR_TRUE);
|
||||
if (NS_FAILED(rv)) {
|
||||
anchor->UnbindFromTree();
|
||||
return rv;
|
||||
}
|
||||
|
||||
anchor->AppendChildTo(img, PR_FALSE, PR_TRUE);
|
||||
anchor->AppendChildTo(text, PR_FALSE, PR_TRUE);
|
||||
|
|
|
@ -263,7 +263,12 @@ int main(int argc, char** argv)
|
|||
txt->AppendData(tmp);
|
||||
NS_RELEASE(txt);
|
||||
|
||||
text->SetDocument(myDoc, PR_FALSE, PR_TRUE);
|
||||
rv = text->BindToTree(myDoc, nsnull, nsnull, PR_FALSE);
|
||||
if (NS_FAILED(rv)) {
|
||||
printf("Could not bind text content to tree.\n");
|
||||
text->UnbindFromTree();
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Query ITextContent interface
|
||||
|
|
Загрузка…
Ссылка в новой задаче