static nsresult GenerateFlatTextContent(nsIRange* aRange, nsAFlatString& aString) { nsCOMPtr<nsIContentIterator> iter; nsresult rv = NS_NewContentIterator(getter_AddRefs(iter)); NS_ENSURE_SUCCESS(rv, rv); NS_ASSERTION(iter, "NS_NewContentIterator succeeded, but the result is null"); nsCOMPtr<nsIDOMRange> domRange(do_QueryInterface(aRange)); NS_ASSERTION(domRange, "aRange doesn't have nsIDOMRange!"); iter->Init(domRange); NS_ASSERTION(aString.IsEmpty(), "aString must be empty string"); nsINode* startNode = aRange->GetStartParent(); NS_ENSURE_TRUE(startNode, NS_ERROR_FAILURE); nsINode* endNode = aRange->GetEndParent(); NS_ENSURE_TRUE(endNode, NS_ERROR_FAILURE); if (startNode == endNode && startNode->IsNodeOfType(nsINode::eTEXT)) { nsIContent* content = static_cast<nsIContent*>(startNode); AppendSubString(aString, content, aRange->StartOffset(), aRange->EndOffset() - aRange->StartOffset()); ConvertToNativeNewlines(aString); return NS_OK; } nsAutoString tmpStr; for (; !iter->IsDone(); iter->Next()) { nsINode* node = iter->GetCurrentNode(); if (!node || !node->IsNodeOfType(nsINode::eCONTENT)) continue; nsIContent* content = static_cast<nsIContent*>(node); if (content->IsNodeOfType(nsINode::eTEXT)) { if (content == startNode) AppendSubString(aString, content, aRange->StartOffset(), content->TextLength() - aRange->StartOffset()); else if (content == endNode) AppendSubString(aString, content, 0, aRange->EndOffset()); else AppendString(aString, content); } else if (IsContentBR(content)) aString.Append(PRUnichar('\n')); } ConvertToNativeNewlines(aString); return NS_OK; }
//------------------------------------------------------------ nsresult nsFilteredContentIterator::Init(nsINode* aRoot) { NS_ENSURE_TRUE(mPreIterator, NS_ERROR_FAILURE); NS_ENSURE_TRUE(mIterator, NS_ERROR_FAILURE); mIsOutOfRange = PR_FALSE; mDirection = eForward; mCurrentIterator = mPreIterator; nsresult rv; mRange = do_CreateInstance("@mozilla.org/content/range;1", &rv); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIDOMRange> domRange(do_QueryInterface(mRange)); nsCOMPtr<nsIDOMNode> domNode(do_QueryInterface(aRoot)); if (domRange && domNode) { domRange->SelectNode(domNode); } rv = mPreIterator->Init(domRange); NS_ENSURE_SUCCESS(rv, rv); return mIterator->Init(domRange); }
nsresult nsContentEventHandler::SetRangeFromFlatTextOffset( nsIRange* aRange, PRUint32 aNativeOffset, PRUint32 aNativeLength, PRBool aExpandToClusterBoundaries) { nsCOMPtr<nsIContentIterator> iter; nsresult rv = NS_NewContentIterator(getter_AddRefs(iter)); NS_ENSURE_SUCCESS(rv, rv); NS_ASSERTION(iter, "NS_NewContentIterator succeeded, but the result is null"); rv = iter->Init(mRootContent); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIDOMRange> domRange(do_QueryInterface(aRange)); NS_ASSERTION(domRange, "aRange doesn't have nsIDOMRange!"); PRUint32 nativeOffset = 0; PRUint32 nativeEndOffset = aNativeOffset + aNativeLength; nsCOMPtr<nsIContent> content; for (; !iter->IsDone(); iter->Next()) { nsINode* node = iter->GetCurrentNode(); if (!node || !node->IsNodeOfType(nsINode::eCONTENT)) continue; nsIContent* content = static_cast<nsIContent*>(node); PRUint32 nativeTextLength; nativeTextLength = GetNativeTextLength(content); if (nativeTextLength == 0) continue; if (nativeOffset <= aNativeOffset && aNativeOffset < nativeOffset + nativeTextLength) { nsCOMPtr<nsIDOMNode> domNode(do_QueryInterface(content)); NS_ASSERTION(domNode, "aContent doesn't have nsIDOMNode!"); PRUint32 xpOffset = content->IsNodeOfType(nsINode::eTEXT) ? ConvertToXPOffset(content, aNativeOffset - nativeOffset) : 0; if (aExpandToClusterBoundaries) { rv = ExpandToClusterBoundary(content, PR_FALSE, &xpOffset); NS_ENSURE_SUCCESS(rv, rv); } rv = domRange->SetStart(domNode, PRInt32(xpOffset)); NS_ENSURE_SUCCESS(rv, rv); if (aNativeLength == 0) { // Ensure that the end offset and the start offset are same. rv = domRange->SetEnd(domNode, PRInt32(xpOffset)); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; } } if (nativeEndOffset <= nativeOffset + nativeTextLength) { nsCOMPtr<nsIDOMNode> domNode(do_QueryInterface(content)); NS_ASSERTION(domNode, "aContent doesn't have nsIDOMNode!"); PRUint32 xpOffset; if (content->IsNodeOfType(nsINode::eTEXT)) { xpOffset = ConvertToXPOffset(content, nativeEndOffset - nativeOffset); if (aExpandToClusterBoundaries) { rv = ExpandToClusterBoundary(content, PR_TRUE, &xpOffset); NS_ENSURE_SUCCESS(rv, rv); } } else { // Use first position of next node, because the end node is ignored // by ContentIterator when the offset is zero. xpOffset = 0; iter->Next(); if (iter->IsDone()) break; domNode = do_QueryInterface(iter->GetCurrentNode()); } rv = domRange->SetEnd(domNode, PRInt32(xpOffset)); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; } nativeOffset += nativeTextLength; } if (nativeOffset < aNativeOffset) return NS_ERROR_FAILURE; nsCOMPtr<nsIDOMNode> domNode(do_QueryInterface(mRootContent)); NS_ASSERTION(domNode, "lastContent doesn't have nsIDOMNode!"); if (!content) { rv = domRange->SetStart(domNode, 0); NS_ENSURE_SUCCESS(rv, rv); } rv = domRange->SetEnd(domNode, PRInt32(mRootContent->GetChildCount())); NS_ASSERTION(NS_SUCCEEDED(rv), "nsIDOMRange::SetEnd failed"); return rv; }