diff --git a/mozilla/content/base/public/nsContentUtils.h b/mozilla/content/base/public/nsContentUtils.h index 2548b3931da..4abe2184c0a 100644 --- a/mozilla/content/base/public/nsContentUtils.h +++ b/mozilla/content/base/public/nsContentUtils.h @@ -901,10 +901,13 @@ public: * * @param aContextNode the node which is used to resolve namespaces * @param aFragment the string which is parsed to a DocumentFragment + * @param aWillOwnFragment is PR_TRUE if ownership of the fragment should be + * transferred to the caller. * @param aReturn [out] the created DocumentFragment */ static nsresult CreateContextualFragment(nsIDOMNode* aContextNode, const nsAString& aFragment, + PRBool aWillOwnFragment, nsIDOMDocumentFragment** aReturn); /** diff --git a/mozilla/content/base/src/nsContentUtils.cpp b/mozilla/content/base/src/nsContentUtils.cpp index 8dcdb1562be..0f3bcb40aaf 100644 --- a/mozilla/content/base/src/nsContentUtils.cpp +++ b/mozilla/content/base/src/nsContentUtils.cpp @@ -3354,6 +3354,7 @@ nsContentUtils::IsValidNodeName(nsIAtom *aLocalName, nsIAtom *aPrefix, nsresult nsContentUtils::CreateContextualFragment(nsIDOMNode* aContextNode, const nsAString& aFragment, + PRBool aWillOwnFragment, nsIDOMDocumentFragment** aReturn) { NS_ENSURE_ARG(aContextNode); @@ -3499,7 +3500,7 @@ nsContentUtils::CreateContextualFragment(nsIDOMNode* aContextNode, rv = parser->ParseFragment(aFragment, nsnull, tagStack, !bHTML, contentType, mode); if (NS_SUCCEEDED(rv)) { - rv = sink->GetFragment(aReturn); + rv = sink->GetFragment(aWillOwnFragment, aReturn); } document->SetFragmentParser(parser); diff --git a/mozilla/content/base/src/nsRange.cpp b/mozilla/content/base/src/nsRange.cpp index a45aa8d1882..4973f2c4aff 100644 --- a/mozilla/content/base/src/nsRange.cpp +++ b/mozilla/content/base/src/nsRange.cpp @@ -1794,8 +1794,9 @@ nsRange::CreateContextualFragment(const nsAString& aFragment, nsIDOMDocumentFragment** aReturn) { nsCOMPtr start = do_QueryInterface(mStartParent); - return - mIsPositioned - ? nsContentUtils::CreateContextualFragment(start, aFragment, aReturn) - : NS_ERROR_FAILURE; + if (mIsPositioned) { + return nsContentUtils::CreateContextualFragment(start, aFragment, PR_TRUE, + aReturn); + } + return NS_ERROR_FAILURE; } diff --git a/mozilla/content/base/test/Makefile.in b/mozilla/content/base/test/Makefile.in index 5db9184ae7e..9a4757f03bd 100644 --- a/mozilla/content/base/test/Makefile.in +++ b/mozilla/content/base/test/Makefile.in @@ -175,6 +175,7 @@ _TEST_FILES = test_bug5141.html \ test_bug417384.html \ test_bug418214.html \ test_bug420609.xhtml \ + test_bug420700.html \ $(NULL) libs:: $(_TEST_FILES) diff --git a/mozilla/content/base/test/test_bug420700.html b/mozilla/content/base/test/test_bug420700.html new file mode 100644 index 00000000000..da36a69e944 --- /dev/null +++ b/mozilla/content/base/test/test_bug420700.html @@ -0,0 +1,36 @@ + + + + + Test for Bug 420700 + + + + + +Mozilla Bug 420700 +

+ +
+
+
+ + + diff --git a/mozilla/content/html/content/src/nsGenericHTMLElement.cpp b/mozilla/content/html/content/src/nsGenericHTMLElement.cpp index 35eba547343..990880c21f5 100644 --- a/mozilla/content/html/content/src/nsGenericHTMLElement.cpp +++ b/mozilla/content/html/content/src/nsGenericHTMLElement.cpp @@ -746,6 +746,7 @@ nsGenericHTMLElement::SetInnerHTML(const nsAString& aInnerHTML) nsCOMPtr thisNode(do_QueryInterface(static_cast (this))); nsresult rv = nsContentUtils::CreateContextualFragment(thisNode, aInnerHTML, + PR_FALSE, getter_AddRefs(df)); if (NS_SUCCEEDED(rv)) { nsCOMPtr tmpNode; diff --git a/mozilla/content/html/document/src/nsHTMLFragmentContentSink.cpp b/mozilla/content/html/document/src/nsHTMLFragmentContentSink.cpp index c11d436f5b8..8248631c70f 100644 --- a/mozilla/content/html/document/src/nsHTMLFragmentContentSink.cpp +++ b/mozilla/content/html/document/src/nsHTMLFragmentContentSink.cpp @@ -119,7 +119,8 @@ public: NS_IMETHOD AddDocTypeDecl(const nsIParserNode& aNode); // nsIFragmentContentSink - NS_IMETHOD GetFragment(nsIDOMDocumentFragment** aFragment); + NS_IMETHOD GetFragment(PRBool aWillOwnFragment, + nsIDOMDocumentFragment** aFragment); NS_IMETHOD SetTargetDocument(nsIDocument* aDocument); NS_IMETHOD WillBuildContent(); NS_IMETHOD DidBuildContent(); @@ -608,10 +609,15 @@ nsHTMLFragmentContentSink::AddDocTypeDecl(const nsIParserNode& aNode) } NS_IMETHODIMP -nsHTMLFragmentContentSink::GetFragment(nsIDOMDocumentFragment** aFragment) +nsHTMLFragmentContentSink::GetFragment(PRBool aWillOwnFragment, + nsIDOMDocumentFragment** aFragment) { if (mRoot) { - return CallQueryInterface(mRoot, aFragment); + nsresult rv = CallQueryInterface(mRoot, aFragment); + if (NS_SUCCEEDED(rv) && aWillOwnFragment) { + mRoot = nsnull; + } + return rv; } *aFragment = nsnull; diff --git a/mozilla/content/xml/document/src/nsXMLFragmentContentSink.cpp b/mozilla/content/xml/document/src/nsXMLFragmentContentSink.cpp index 3e66cbe8e27..463b5c4cf3f 100644 --- a/mozilla/content/xml/document/src/nsXMLFragmentContentSink.cpp +++ b/mozilla/content/xml/document/src/nsXMLFragmentContentSink.cpp @@ -102,7 +102,8 @@ public: // nsIXMLContentSink // nsIFragmentContentSink - NS_IMETHOD GetFragment(nsIDOMDocumentFragment** aFragment); + NS_IMETHOD GetFragment(PRBool aWillOwnFragment, + nsIDOMDocumentFragment** aFragment); NS_IMETHOD SetTargetDocument(nsIDocument* aDocument); NS_IMETHOD WillBuildContent(); NS_IMETHOD DidBuildContent(); @@ -400,14 +401,19 @@ nsXMLFragmentContentSink::StartLayout() //////////////////////////////////////////////////////////////////////// NS_IMETHODIMP -nsXMLFragmentContentSink::GetFragment(nsIDOMDocumentFragment** aFragment) +nsXMLFragmentContentSink::GetFragment(PRBool aWillOwnFragment, + nsIDOMDocumentFragment** aFragment) { *aFragment = nsnull; if (mParseError) { //XXX PARSE_ERR from DOM3 Load and Save would be more appropriate return NS_ERROR_DOM_SYNTAX_ERR; } else if (mRoot) { - return CallQueryInterface(mRoot, aFragment); + nsresult rv = CallQueryInterface(mRoot, aFragment); + if (NS_SUCCEEDED(rv) && aWillOwnFragment) { + mRoot = nsnull; + } + return rv; } else { return NS_OK; } diff --git a/mozilla/parser/htmlparser/public/nsIFragmentContentSink.h b/mozilla/parser/htmlparser/public/nsIFragmentContentSink.h index 17d723fa1c7..0255f12e894 100644 --- a/mozilla/parser/htmlparser/public/nsIFragmentContentSink.h +++ b/mozilla/parser/htmlparser/public/nsIFragmentContentSink.h @@ -43,8 +43,8 @@ class nsIDOMDocumentFragment; class nsIDocument; #define NS_I_FRAGMENT_CONTENT_SINK_IID \ - { 0x2cec7263, 0x9dd0, 0x4413, \ - { 0xb6, 0x68, 0x6f, 0xf0, 0xa1, 0x40, 0xc1, 0xbe } } + { 0x1ecdb30d, 0x1f10, 0x45d2, \ + { 0xa4, 0xf4, 0xec, 0xbc, 0x03, 0x52, 0x9a, 0x7e } } /** * The fragment sink allows a client to parse a fragment of sink, possibly @@ -60,8 +60,11 @@ public: * a fragment content sink. The value returned will be null * if the content sink hasn't yet received parser notifications. * + * If aWillOwnFragment is PR_TRUE then the sink should drop its + * ownership of the fragment. */ - NS_IMETHOD GetFragment(nsIDOMDocumentFragment** aFragment) = 0; + NS_IMETHOD GetFragment(PRBool aWillOwnFragment, + nsIDOMDocumentFragment** aFragment) = 0; /** * This method is used to set the target document for this fragment