diff --git a/mozilla/content/base/public/nsIDocument.h b/mozilla/content/base/public/nsIDocument.h index 9ff23835eec..057ef2d6a49 100644 --- a/mozilla/content/base/public/nsIDocument.h +++ b/mozilla/content/base/public/nsIDocument.h @@ -338,7 +338,18 @@ public: { return mRootContent; } - virtual void SetRootContent(nsIContent* aRoot) = 0; + + /** + * Set aRoot as the root content object for this document. If aRoot is + * non-null, this should not be called on documents that currently have a + * root content without first clearing out the document's children. Passing + * in null to unbind the existing root content is allowed. This method will + * bind aRoot to the document; the caller need not call BindToTree on aRoot. + * + * Note that this method never sends out nsIDocumentObserver notifications; + * doing that is the caller's responsibility. + */ + virtual nsresult SetRootContent(nsIContent* aRoot) = 0; /** * Get the direct children of the document - content in diff --git a/mozilla/content/base/src/nsDocument.cpp b/mozilla/content/base/src/nsDocument.cpp index c7fcc8ae2d1..99d265ca8e9 100644 --- a/mozilla/content/base/src/nsDocument.cpp +++ b/mozilla/content/base/src/nsDocument.cpp @@ -1490,21 +1490,34 @@ nsDocument::FindContentForSubDocument(nsIDocument *aDocument) const return data.mResult; } -void +nsresult nsDocument::SetRootContent(nsIContent* aRoot) { - if (mRootContent) { - PRInt32 indx = mChildren.IndexOf(mRootContent); - if (aRoot) { - mChildren.ReplaceObjectAt(aRoot, indx); - } else { - mChildren.RemoveObjectAt(indx); + if (aRoot) { + NS_ASSERTION(!mRootContent, + "Already have a root content! Clear out first!"); + nsresult rv = aRoot->BindToTree(this, nsnull, nsnull, PR_TRUE); + + if (NS_SUCCEEDED(rv) && !mChildren.AppendObject(aRoot)) { + rv = NS_ERROR_OUT_OF_MEMORY; } - } else if (aRoot) { - mChildren.AppendObject(aRoot); + + if (NS_FAILED(rv)) { + aRoot->UnbindFromTree(); + } else { + mRootContent = aRoot; + } + + return rv; } - mRootContent = aRoot; + if (mRootContent) { + mRootContent->UnbindFromTree(); + mChildren.RemoveObject(mRootContent); + mRootContent = nsnull; + } + + return NS_OK; } nsIContent * diff --git a/mozilla/content/base/src/nsDocument.h b/mozilla/content/base/src/nsDocument.h index 66921fef996..c0f7b7ed077 100644 --- a/mozilla/content/base/src/nsDocument.h +++ b/mozilla/content/base/src/nsDocument.h @@ -291,7 +291,7 @@ public: virtual nsIDocument* GetSubDocumentFor(nsIContent *aContent) const; virtual nsIContent* FindContentForSubDocument(nsIDocument *aDocument) const; - virtual void SetRootContent(nsIContent* aRoot); + virtual nsresult SetRootContent(nsIContent* aRoot); /** * Get the direct children of the document - content in diff --git a/mozilla/content/html/document/src/nsHTMLContentSink.cpp b/mozilla/content/html/document/src/nsHTMLContentSink.cpp index ca5a61a7ce1..e37ce917480 100644 --- a/mozilla/content/html/document/src/nsHTMLContentSink.cpp +++ b/mozilla/content/html/document/src/nsHTMLContentSink.cpp @@ -2104,12 +2104,8 @@ HTMLContentSink::Init(nsIDocument* aDoc, } NS_ADDREF(mRoot); - rv = mRoot->BindToTree(mDocument, nsnull, nsnull, PR_TRUE); - if (NS_FAILED(rv)) { - mRoot->UnbindFromTree(); - return rv; - } - mDocument->SetRootContent(mRoot); + rv = mDocument->SetRootContent(mRoot); + NS_ENSURE_SUCCESS(rv, rv); } // Make head part diff --git a/mozilla/content/html/document/src/nsMediaDocument.cpp b/mozilla/content/html/document/src/nsMediaDocument.cpp index 0ce97491b8c..0f04743ab19 100644 --- a/mozilla/content/html/document/src/nsMediaDocument.cpp +++ b/mozilla/content/html/document/src/nsMediaDocument.cpp @@ -242,12 +242,9 @@ nsMediaDocument::CreateSyntheticDocument() if (!root) { return NS_ERROR_OUT_OF_MEMORY; } - rv = root->BindToTree(this, nsnull, nsnull, PR_TRUE); - if (NS_FAILED(rv)) { - root->UnbindFromTree(); - return rv; - } - SetRootContent(root); + + rv = SetRootContent(root); + NS_ENSURE_SUCCESS(rv, rv); rv = mNodeInfoManager->GetNodeInfo(nsHTMLAtoms::body, nsnull, kNameSpaceID_None, diff --git a/mozilla/content/xml/document/src/nsXMLContentSink.cpp b/mozilla/content/xml/document/src/nsXMLContentSink.cpp index 48ba5268f0c..6019df59122 100644 --- a/mozilla/content/xml/document/src/nsXMLContentSink.cpp +++ b/mozilla/content/xml/document/src/nsXMLContentSink.cpp @@ -857,14 +857,12 @@ nsXMLContentSink::SetDocElement(PRInt32 aNameSpaceID, mDocElement = aContent; NS_ADDREF(mDocElement); - nsresult rv = mDocElement->BindToTree(mDocument, nsnull, nsnull, PR_TRUE); + nsresult rv = mDocument->SetRootContent(mDocElement); 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; } diff --git a/mozilla/content/xul/document/src/nsXULDocument.cpp b/mozilla/content/xul/document/src/nsXULDocument.cpp index dbafbc5abbc..bc30e033323 100644 --- a/mozilla/content/xul/document/src/nsXULDocument.cpp +++ b/mozilla/content/xul/document/src/nsXULDocument.cpp @@ -2573,11 +2573,9 @@ nsXULDocument::PrepareToWalk() rv = CreateElementFromPrototype(proto, getter_AddRefs(root)); if (NS_FAILED(rv)) return rv; - rv = root->BindToTree(this, nsnull, nsnull, PR_TRUE); + rv = SetRootContent(root); if (NS_FAILED(rv)) return rv; - SetRootContent(root); - // Add the root element to the XUL document's ID-to-element map. rv = AddElementToMap(root); if (NS_FAILED(rv)) return rv; diff --git a/mozilla/extensions/transformiix/source/xslt/txMozillaTextOutput.cpp b/mozilla/extensions/transformiix/source/xslt/txMozillaTextOutput.cpp index b2818304c87..ad081e691bd 100644 --- a/mozilla/extensions/transformiix/source/xslt/txMozillaTextOutput.cpp +++ b/mozilla/extensions/transformiix/source/xslt/txMozillaTextOutput.cpp @@ -249,14 +249,13 @@ void txMozillaTextOutput::createResultDocument(nsIDOMDocument* aSourceDocument, return; } - rv = rootContent->BindToTree(doc, nsnull, nsnull, PR_TRUE); + // XXXbz what to do on failure here? + rv = doc->SetRootContent(rootContent); if (NS_FAILED(rv)) { - NS_ERROR("Failed to bind root to tree"); - rootContent->UnbindFromTree(); + NS_ERROR("Failed to set root content"); return; } - - doc->SetRootContent(rootContent); + mDocument->CreateElementNS(XHTML_NSURI, NS_LITERAL_STRING("head"), diff --git a/mozilla/extensions/transformiix/source/xslt/txMozillaXMLOutput.cpp b/mozilla/extensions/transformiix/source/xslt/txMozillaXMLOutput.cpp index 3f8875d96cd..a262d57993f 100644 --- a/mozilla/extensions/transformiix/source/xslt/txMozillaXMLOutput.cpp +++ b/mozilla/extensions/transformiix/source/xslt/txMozillaXMLOutput.cpp @@ -301,7 +301,7 @@ void txMozillaXMLOutput::endElement(const nsAString& aName, const PRInt32 aNsID) nsCOMPtr document = do_QueryInterface(mNonAddedParent); if (document && !mRootContent) { mRootContent = do_QueryInterface(mCurrentNode); - mRootContent->BindToTree(document, nsnull, nsnull, PR_TRUE); + // XXXbz what to do on failure here? document->SetRootContent(mRootContent); } else { @@ -493,7 +493,7 @@ void txMozillaXMLOutput::closePrevious(PRInt8 aAction) mParentNode = wrapper; mRootContent = do_QueryInterface(wrapper); - mRootContent->BindToTree(document, nsnull, nsnull, PR_TRUE); + // XXXbz what to do on failure here? document->SetRootContent(mRootContent); } @@ -504,7 +504,7 @@ void txMozillaXMLOutput::closePrevious(PRInt8 aAction) else { if (document && currentElement && !mRootContent) { mRootContent = do_QueryInterface(mCurrentNode); - mRootContent->BindToTree(document, nsnull, nsnull, PR_TRUE); + // XXXbz what to do on failure here? document->SetRootContent(mRootContent); } else { diff --git a/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.cpp b/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.cpp index ddc743c8f0f..2625308a24d 100644 --- a/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.cpp +++ b/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.cpp @@ -712,8 +712,10 @@ txMozillaXSLTProcessor::notifyError() return; } - rootContent->BindToTree(document, nsnull, nsnull, PR_TRUE); - document->SetRootContent(rootContent); + rv = document->SetRootContent(rootContent); + if (NS_FAILED(rv)) { + return; + } nsCOMPtr text; rv = errorDocument->CreateTextNode(mErrorText, getter_AddRefs(text)); diff --git a/mozilla/layout/build/nsContentDLF.cpp b/mozilla/layout/build/nsContentDLF.cpp index b3f3a735922..5e76cde9d55 100644 --- a/mozilla/layout/build/nsContentDLF.cpp +++ b/mozilla/layout/build/nsContentDLF.cpp @@ -362,19 +362,15 @@ nsContentDLF::CreateBlankDocument(nsILoadGroup *aLoadGroup, nsIDocument **aDocum // blat in the structure if (htmlElement && headElement && bodyElement) { - rv = htmlElement->BindToTree(blankDoc, nsnull, nsnull, PR_TRUE); - if (NS_FAILED(rv)) { - htmlElement->UnbindFromTree(); - } else { - blankDoc->SetRootContent(htmlElement); + rv = blankDoc->SetRootContent(htmlElement); + if (NS_SUCCEEDED(rv)) { + rv = htmlElement->AppendChildTo(headElement, PR_FALSE, PR_FALSE); - htmlElement->AppendChildTo(headElement, PR_FALSE, PR_FALSE); - - bodyElement->SetContentID(blankDoc->GetAndIncrementContentID()); - // XXXbz Why not notifying here? - htmlElement->AppendChildTo(bodyElement, PR_FALSE, PR_FALSE); - - rv = NS_OK; + if (NS_SUCCEEDED(rv)) { + bodyElement->SetContentID(blankDoc->GetAndIncrementContentID()); + // XXXbz Why not notifying here? + htmlElement->AppendChildTo(bodyElement, PR_FALSE, PR_FALSE); + } } } }