diff --git a/content/base/public/nsIDocument.h b/content/base/public/nsIDocument.h index 9ff23835eec..057ef2d6a49 100644 --- a/content/base/public/nsIDocument.h +++ b/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/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index c7fcc8ae2d1..99d265ca8e9 100644 --- a/content/base/src/nsDocument.cpp +++ b/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/content/base/src/nsDocument.h b/content/base/src/nsDocument.h index 66921fef996..c0f7b7ed077 100644 --- a/content/base/src/nsDocument.h +++ b/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/content/html/document/src/nsHTMLContentSink.cpp b/content/html/document/src/nsHTMLContentSink.cpp index ca5a61a7ce1..e37ce917480 100644 --- a/content/html/document/src/nsHTMLContentSink.cpp +++ b/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/content/html/document/src/nsMediaDocument.cpp b/content/html/document/src/nsMediaDocument.cpp index 0ce97491b8c..0f04743ab19 100644 --- a/content/html/document/src/nsMediaDocument.cpp +++ b/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/content/xml/document/src/nsXMLContentSink.cpp b/content/xml/document/src/nsXMLContentSink.cpp index 48ba5268f0c..6019df59122 100644 --- a/content/xml/document/src/nsXMLContentSink.cpp +++ b/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/content/xul/document/src/nsXULDocument.cpp b/content/xul/document/src/nsXULDocument.cpp index dbafbc5abbc..bc30e033323 100644 --- a/content/xul/document/src/nsXULDocument.cpp +++ b/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/extensions/transformiix/source/xslt/txMozillaTextOutput.cpp b/extensions/transformiix/source/xslt/txMozillaTextOutput.cpp index b2818304c87..e69de29bb2d 100644 --- a/extensions/transformiix/source/xslt/txMozillaTextOutput.cpp +++ b/extensions/transformiix/source/xslt/txMozillaTextOutput.cpp @@ -1,337 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is TransforMiiX XSLT processor code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 2001 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Peter Van der Beken - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "txMozillaTextOutput.h" -#include "nsContentCID.h" -#include "nsIContent.h" -#include "nsIDocument.h" -#include "nsIDOMDocument.h" -#include "nsIDOMDocumentFragment.h" -#include "nsIDOMElement.h" -#include "nsIDOMHTMLElement.h" -#include "nsIDOMText.h" -#include "nsIDocumentTransformer.h" -#include "nsNetUtil.h" -#include "nsIDOMNSDocument.h" -#include "nsIParser.h" -#include "nsICharsetAlias.h" - -static NS_DEFINE_CID(kXMLDocumentCID, NS_XMLDOCUMENT_CID); - -txMozillaTextOutput::txMozillaTextOutput(nsIDOMDocument* aSourceDocument, - nsIDOMDocument* aResultDocument, - nsITransformObserver* aObserver) -{ - mObserver = do_GetWeakReference(aObserver); - createResultDocument(aSourceDocument, aResultDocument); -} - -txMozillaTextOutput::txMozillaTextOutput(nsIDOMDocumentFragment* aDest) -{ - nsCOMPtr doc; - aDest->GetOwnerDocument(getter_AddRefs(doc)); - NS_ASSERTION(doc, "unable to get ownerdocument"); - nsCOMPtr textNode; - nsresult rv = doc->CreateTextNode(EmptyString(), - getter_AddRefs(textNode)); - if (NS_FAILED(rv)) { - return; - } - nsCOMPtr dummy; - rv = aDest->AppendChild(textNode, getter_AddRefs(dummy)); - if (NS_FAILED(rv)) { - return; - } - - mTextNode = textNode; - return; -} - -txMozillaTextOutput::~txMozillaTextOutput() -{ -} - -void txMozillaTextOutput::attribute(const nsAString& aName, - const PRInt32 aNsID, - const nsAString& aValue) -{ -} - -void txMozillaTextOutput::characters(const nsAString& aData, PRBool aDOE) -{ - if (mTextNode) - mTextNode->AppendData(aData); -} - -void txMozillaTextOutput::comment(const nsAString& aData) -{ -} - -void txMozillaTextOutput::endDocument(nsresult aResult) -{ - if (NS_SUCCEEDED(aResult)) { - nsCOMPtr observer = do_QueryReferent(mObserver); - if (observer) { - observer->OnTransformDone(aResult, mDocument); - } - } -} - -void txMozillaTextOutput::endElement(const nsAString& aName, - const PRInt32 aNsID) -{ -} - -void txMozillaTextOutput::processingInstruction(const nsAString& aTarget, - const nsAString& aData) -{ -} - -void txMozillaTextOutput::startDocument() -{ -} - -void txMozillaTextOutput::createResultDocument(nsIDOMDocument* aSourceDocument, - nsIDOMDocument* aResultDocument) -{ - nsresult rv = NS_OK; - - /* - * Create an XHTML document to hold the text. - * - * - * - * - *
 * The text comes here * 
- * - * - * - * Except if we are transforming into a non-displayed document we create - * the following DOM - * - * * The text comes here * - */ - - nsCOMPtr doc; - if (!aResultDocument) { - // Create the document - doc = do_CreateInstance(kXMLDocumentCID, &rv); - NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't create document"); - mDocument = do_QueryInterface(doc); - } - else { - mDocument = aResultDocument; - doc = do_QueryInterface(aResultDocument); - NS_ASSERTION(doc, "Couldn't QI to nsIDocument"); - } - - if (!doc) { - return; - } - - NS_ASSERTION(mDocument, "Need document"); - - nsCOMPtr nsDoc = do_QueryInterface(mDocument); - if (nsDoc) { - nsDoc->SetTitle(EmptyString()); - } - - // Reset and set up document - nsCOMPtr channel; - nsCOMPtr sourceDoc = do_QueryInterface(aSourceDocument); - nsCOMPtr loadGroup = sourceDoc->GetDocumentLoadGroup(); - nsCOMPtr serv = do_GetService(NS_IOSERVICE_CONTRACTID); - if (serv) { - // Create a temporary channel to get nsIDocument->Reset to - // do the right thing. We want the output document to get - // much of the input document's characteristics. - serv->NewChannelFromURI(sourceDoc->GetDocumentURI(), - getter_AddRefs(channel)); - } - doc->Reset(channel, loadGroup); - doc->SetBaseURI(sourceDoc->GetBaseURI()); - - // Set the charset - if (!mOutputFormat.mEncoding.IsEmpty()) { - NS_LossyConvertUTF16toASCII charset(mOutputFormat.mEncoding); - nsCAutoString canonicalCharset; - nsCOMPtr calias = - do_GetService("@mozilla.org/intl/charsetalias;1"); - - if (calias && - NS_SUCCEEDED(calias->GetPreferred(charset, canonicalCharset))) { - doc->SetDocumentCharacterSet(canonicalCharset); - doc->SetDocumentCharacterSetSource(kCharsetFromOtherComponent); - } - } - else { - doc->SetDocumentCharacterSet(sourceDoc->GetDocumentCharacterSet()); - doc->SetDocumentCharacterSetSource( - sourceDoc->GetDocumentCharacterSetSource()); - } - - // Notify the contentsink that the document is created - nsCOMPtr observer = do_QueryReferent(mObserver); - if (observer) { - observer->OnDocumentCreated(mDocument); - } - - // Create the content - - // When transforming into a non-displayed document (i.e. when there is no - // observer) we only create a transformiix:result root element. - // Don't do this when called through nsIXSLTProcessorObsolete (i.e. when - // aResultDocument is set) for compability reasons - nsCOMPtr textContainer; - if (!aResultDocument && !observer) { - nsCOMPtr docElement; - mDocument->CreateElementNS(NS_LITERAL_STRING(kTXNameSpaceURI), - NS_LITERAL_STRING(kTXWrapper), - getter_AddRefs(docElement)); - NS_ASSERTION(docElement, "Failed to create wrapper element"); - if (!docElement) { - return; - } - - rv = mDocument->AppendChild(docElement, getter_AddRefs(textContainer)); - NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to append the wrapper element"); - if (NS_FAILED(rv)) { - return; - } - } - else { - nsCOMPtr element, docElement; - nsCOMPtr parent, pre; - - NS_NAMED_LITERAL_STRING(XHTML_NSURI, "http://www.w3.org/1999/xhtml"); - - mDocument->CreateElementNS(XHTML_NSURI, - NS_LITERAL_STRING("html"), - getter_AddRefs(docElement)); - nsCOMPtr rootContent = do_QueryInterface(docElement); - NS_ASSERTION(rootContent, "Need root element"); - if (!rootContent) { - return; - } - - rv = rootContent->BindToTree(doc, nsnull, nsnull, PR_TRUE); - if (NS_FAILED(rv)) { - NS_ERROR("Failed to bind root to tree"); - rootContent->UnbindFromTree(); - return; - } - - doc->SetRootContent(rootContent); - - mDocument->CreateElementNS(XHTML_NSURI, - NS_LITERAL_STRING("head"), - getter_AddRefs(element)); - NS_ASSERTION(element, "Failed to create head element"); - if (!element) { - return; - } - - rv = docElement->AppendChild(element, getter_AddRefs(parent)); - NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to append the head element"); - if (NS_FAILED(rv)) { - return; - } - - mDocument->CreateElementNS(XHTML_NSURI, - NS_LITERAL_STRING("body"), - getter_AddRefs(element)); - NS_ASSERTION(element, "Failed to create body element"); - if (!element) { - return; - } - - rv = docElement->AppendChild(element, getter_AddRefs(parent)); - NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to append the body element"); - if (NS_FAILED(rv)) { - return; - } - - mDocument->CreateElementNS(XHTML_NSURI, - NS_LITERAL_STRING("pre"), - getter_AddRefs(element)); - NS_ASSERTION(element, "Failed to create pre element"); - if (!element) { - return; - } - - rv = parent->AppendChild(element, getter_AddRefs(pre)); - NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to append the pre element"); - if (NS_FAILED(rv)) { - return; - } - - nsCOMPtr htmlElement = do_QueryInterface(pre); - htmlElement->SetId(NS_LITERAL_STRING("transformiixResult")); - NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to append the id"); - - textContainer = pre; - } - - nsCOMPtr textNode; - mDocument->CreateTextNode(EmptyString(), - getter_AddRefs(textNode)); - NS_ASSERTION(textNode, "Failed to create the text node"); - if (!textNode) { - return; - } - - nsCOMPtr dummy; - rv = textContainer->AppendChild(textNode, getter_AddRefs(dummy)); - NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to append the text node"); - if (NS_FAILED(rv)) { - return; - } - - mTextNode = textNode; -} - -void txMozillaTextOutput::startElement(const nsAString& aName, - const PRInt32 aNsID) -{ -} - -void txMozillaTextOutput::getOutputDocument(nsIDOMDocument** aDocument) -{ - *aDocument = mDocument; - NS_IF_ADDREF(*aDocument); -} diff --git a/extensions/transformiix/source/xslt/txMozillaXMLOutput.cpp b/extensions/transformiix/source/xslt/txMozillaXMLOutput.cpp index 3f8875d96cd..a262d57993f 100644 --- a/extensions/transformiix/source/xslt/txMozillaXMLOutput.cpp +++ b/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/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.cpp b/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.cpp index ddc743c8f0f..2625308a24d 100644 --- a/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.cpp +++ b/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/layout/build/nsContentDLF.cpp b/layout/build/nsContentDLF.cpp index b3f3a735922..5e76cde9d55 100644 --- a/layout/build/nsContentDLF.cpp +++ b/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); + } } } }