From 7e9ec005924160aee1271fd738f217c5f0d55a4e Mon Sep 17 00:00:00 2001 From: "neil%parkwaycc.co.uk" Date: Wed, 1 Sep 2004 16:18:31 +0000 Subject: [PATCH] Bug 135928 Range.surroundContents doesn't work on a single text node p=kin r=jfrancis sr=jst extracted from the otherwise bitrotted patch in bug 58974 git-svn-id: svn://10.0.0.236/trunk@161579 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/content/base/src/nsRange.cpp | 141 ++++++++------------------- 1 file changed, 38 insertions(+), 103 deletions(-) diff --git a/mozilla/content/base/src/nsRange.cpp b/mozilla/content/base/src/nsRange.cpp index 7a888f8d0e1..4c0497e5966 100644 --- a/mozilla/content/base/src/nsRange.cpp +++ b/mozilla/content/base/src/nsRange.cpp @@ -1995,124 +1995,59 @@ nsresult nsRange::InsertNode(nsIDOMNode* aN) return tStartContainer->InsertBefore(aN, tChildNode, getter_AddRefs(tResultNode)); } -nsresult nsRange::SurroundContents(nsIDOMNode* aN) +nsresult nsRange::SurroundContents(nsIDOMNode* aNewParent) { - VALIDATE_ACCESS(aN); + VALIDATE_ACCESS(aNewParent); - nsresult res; + // Extract the contents within the range. - //get start offset, and start container - PRInt32 tStartOffset; - this->GetStartOffset(&tStartOffset); - nsCOMPtr tStartContainer; - res = GetStartContainer(getter_AddRefs(tStartContainer)); - if(NS_FAILED(res)) return res; + nsCOMPtr docFrag; - //get end offset, and end container - PRInt32 tEndOffset; - this->GetEndOffset(&tEndOffset); - nsCOMPtr tEndContainer; - res = GetEndContainer(getter_AddRefs(tEndContainer)); - if(NS_FAILED(res)) return res; + nsresult res = ExtractContents(getter_AddRefs(docFrag)); - //prep start - PRUint16 tStartNodeType; - tStartContainer->GetNodeType(&tStartNodeType); - if( (nsIDOMNode::CDATA_SECTION_NODE == tStartNodeType) || - (nsIDOMNode::TEXT_NODE == tStartNodeType) ) + if (NS_FAILED(res)) return res; + if (!docFrag) return NS_ERROR_FAILURE; + + // Spec says we need to remove all of aNewParent's + // children prior to insertion. + + nsCOMPtr children; + res = aNewParent->GetChildNodes(getter_AddRefs(children)); + + if (NS_FAILED(res)) return res; + if (!children) return NS_ERROR_FAILURE; + + PRUint32 numChildren = 0; + res = children->GetLength(&numChildren); + if (NS_FAILED(res)) return res; + + nsCOMPtr tmpNode; + + while (numChildren) { - nsCOMPtr tStartContainerText = do_QueryInterface(tStartContainer); - nsCOMPtr tTempText; - res = tStartContainerText->SplitText(tStartOffset, getter_AddRefs(tTempText)); - if(NS_FAILED(res)) return res; - tStartOffset = 0; - tStartContainer = do_QueryInterface(tTempText); + nsCOMPtr child; + res = children->Item(--numChildren, getter_AddRefs(child)); + + if (NS_FAILED(res)) return res; + if (!child) return NS_ERROR_FAILURE; + + res = aNewParent->RemoveChild(child, getter_AddRefs(tmpNode)); + if (NS_FAILED(res)) return res; } - //prep end - PRUint16 tEndNodeType; - tEndContainer->GetNodeType(&tEndNodeType); - if( (nsIDOMNode::CDATA_SECTION_NODE == tEndNodeType) || - (nsIDOMNode::TEXT_NODE == tEndNodeType) ) - { - nsCOMPtr tEndContainerText = do_QueryInterface(tEndContainer); - nsCOMPtr tTempText; - res = tEndContainerText->SplitText(tEndOffset, getter_AddRefs(tTempText)); - if(NS_FAILED(res)) return res; + // Insert aNewParent at the range's start point. - tEndContainer = do_QueryInterface(tTempText); - } - - //get ancestor info - nsCOMPtr tAncestorContainer; - this->GetCommonAncestorContainer(getter_AddRefs(tAncestorContainer)); - - PRUint16 tCommonAncestorType; - tAncestorContainer->GetNodeType(&tCommonAncestorType); - - nsCOMPtrtempNode; - nsCOMPtrtRangeContentsNode; - nsCOMPtr document; - res = mStartParent->GetOwnerDocument(getter_AddRefs(document)); + res = InsertNode(aNewParent); if (NS_FAILED(res)) return res; - // Create a new document fragment in the context of this document, - // which might be null - nsCOMPtr docfrag; + // Append the content we extracted under aNewParent. - nsCOMPtr doc(do_QueryInterface(document)); - - res = NS_NewDocumentFragment(getter_AddRefs(docfrag), doc); + res = aNewParent->AppendChild(docFrag, getter_AddRefs(tmpNode)); if (NS_FAILED(res)) return res; - res = this->ExtractContents(getter_AddRefs(docfrag)); - if (NS_FAILED(res)) return res; + // Select aNewParent, and its contents. - tRangeContentsNode = do_QueryInterface(docfrag); - aN->AppendChild(tRangeContentsNode, getter_AddRefs(tempNode)); - - if( (nsIDOMNode::CDATA_SECTION_NODE == tCommonAncestorType) || - (nsIDOMNode::TEXT_NODE == tCommonAncestorType) ) - {//easy stuff here - this->InsertNode(aN); - } - else - {//hard stuff here - nsCOMPtrtChildList; - res = tAncestorContainer->GetChildNodes(getter_AddRefs(tChildList)); - PRUint32 i,tNumChildren; - tChildList->GetLength(&tNumChildren); - - PRBool tFound = PR_FALSE; - PRInt16 tResult; - for(i = 0; (i < tNumChildren && !tFound); i++) - { - ComparePoint(tAncestorContainer, i, &tResult); - if(tResult == 0) - { - tFound = PR_TRUE; - break; - } - } - - if(tFound) - { - nsCOMPtr tChild; - tChildList->Item(i, getter_AddRefs(tChild)); - tAncestorContainer->InsertBefore(aN, tChild, getter_AddRefs(tempNode)); - } - else // there is an error this may need to be updated later - this->InsertNode(aN); - - // re-define the range so that it contains the same content as it did before - tEndOffset = GetNodeLength(tEndContainer); - if (tEndOffset == -1) // failure code - return NS_ERROR_FAILURE; - - this->DoSetRange(tStartContainer, 0, tEndContainer, tEndOffset); - } - this->SelectNode(aN); - return NS_OK; + return SelectNode(aNewParent); } nsresult nsRange::ToString(nsAString& aReturn)