Bug 1421553 - Part 1. OffsetEntry should use nsINode instead of nsIDOMNode. r?masayuki draft
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Wed, 29 Nov 2017 17:54:30 +0900
changeset 705000 53f2f09ce64a90af9202a0ad4339d8fac9fd50cd
parent 704807 cb9092a90f6ef501e6de8eb5fc6ce19e2717193f
child 705001 a23f3abc9b2ccb140b049282d216b12528940fc4
push id91311
push userbmo:m_kato@ga2.so-net.ne.jp
push dateWed, 29 Nov 2017 08:58:25 +0000
reviewersmasayuki
bugs1421553
milestone59.0a1
Bug 1421553 - Part 1. OffsetEntry should use nsINode instead of nsIDOMNode. r?masayuki nsTextServicesDocument still use nsIDOMNode, so we should replace with nsINode to reduce QI. MozReview-Commit-ID: 7G9w31dRFi9
editor/txtsvc/nsTextServicesDocument.cpp
editor/txtsvc/nsTextServicesDocument.h
--- a/editor/txtsvc/nsTextServicesDocument.cpp
+++ b/editor/txtsvc/nsTextServicesDocument.cpp
@@ -39,41 +39,36 @@
 #include "nscore.h"                     // for nsresult, NS_IMETHODIMP, etc
 
 #define LOCK_DOC(doc)
 #define UNLOCK_DOC(doc)
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
-class OffsetEntry
+class OffsetEntry final
 {
 public:
-  OffsetEntry(nsIDOMNode *aNode, int32_t aOffset, int32_t aLength)
+  OffsetEntry(nsINode *aNode, int32_t aOffset, int32_t aLength)
     : mNode(aNode), mNodeOffset(0), mStrOffset(aOffset), mLength(aLength),
       mIsInsertedText(false), mIsValid(true)
   {
     if (mStrOffset < 1) {
       mStrOffset = 0;
     }
     if (mLength < 1) {
       mLength = 0;
     }
   }
 
   virtual ~OffsetEntry()
   {
-    mNode       = 0;
-    mNodeOffset = 0;
-    mStrOffset  = 0;
-    mLength     = 0;
-    mIsValid    = false;
   }
 
-  nsIDOMNode *mNode;
+  nsINode* mNode;
   int32_t mNodeOffset;
   int32_t mStrOffset;
   int32_t mLength;
   bool    mIsInsertedText;
   bool    mIsValid;
 };
 
 nsTextServicesDocument::nsTextServicesDocument()
@@ -234,17 +229,17 @@ nsTextServicesDocument::SetExtent(nsIDOM
 NS_IMETHODIMP
 nsTextServicesDocument::ExpandRangeToWordBoundaries(nsIDOMRange *aRange)
 {
   NS_ENSURE_ARG_POINTER(aRange);
   RefPtr<nsRange> range = static_cast<nsRange*>(aRange);
 
   // Get the end points of the range.
 
-  nsCOMPtr<nsIDOMNode> rngStartNode, rngEndNode;
+  nsCOMPtr<nsINode> rngStartNode, rngEndNode;
   int32_t rngStartOffset, rngEndOffset;
 
   nsresult rv = GetRangeEndPoints(range, getter_AddRefs(rngStartNode),
                                   &rngStartOffset,
                                   getter_AddRefs(rngEndNode),
                                   &rngEndOffset);
 
   NS_ENSURE_SUCCESS(rv, rv);
@@ -283,34 +278,26 @@ nsTextServicesDocument::ExpandRangeToWor
     return NS_ERROR_FAILURE;
   }
 
   nsINode *lastText = iter->GetCurrentNode();
   NS_ENSURE_TRUE(lastText, NS_ERROR_FAILURE);
 
   // Now make sure our end points are in terms of text nodes in the range!
 
-  nsCOMPtr<nsIDOMNode> firstTextNode = do_QueryInterface(firstText);
-  NS_ENSURE_TRUE(firstTextNode, NS_ERROR_FAILURE);
-
-  if (rngStartNode != firstTextNode) {
+  if (rngStartNode != firstText) {
     // The range includes the start of the first text node!
-    rngStartNode = firstTextNode;
+    rngStartNode = firstText;
     rngStartOffset = 0;
   }
 
-  nsCOMPtr<nsIDOMNode> lastTextNode = do_QueryInterface(lastText);
-  NS_ENSURE_TRUE(lastTextNode, NS_ERROR_FAILURE);
-
-  if (rngEndNode != lastTextNode) {
+  if (rngEndNode != lastText) {
     // The range includes the end of the last text node!
-    rngEndNode = lastTextNode;
-    nsAutoString str;
-    lastTextNode->GetNodeValue(str);
-    rngEndOffset = str.Length();
+    rngEndNode = lastText;
+    rngEndOffset = lastText->Length();
   }
 
   // Create a doc iterator so that we can scan beyond
   // the bounds of the extent range.
 
   nsCOMPtr<nsIContentIterator> docIter;
   rv = CreateDocumentContentIterator(getter_AddRefs(docIter));
   NS_ENSURE_SUCCESS(rv, rv);
@@ -328,17 +315,17 @@ nsTextServicesDocument::ExpandRangeToWor
 
   rv = CreateOffsetTable(&offsetTable, docIter, &iterStatus,
                          nullptr, &blockStr);
   if (NS_FAILED(rv)) {
     ClearOffsetTable(&offsetTable);
     return rv;
   }
 
-  nsCOMPtr<nsIDOMNode> wordStartNode, wordEndNode;
+  nsCOMPtr<nsINode> wordStartNode, wordEndNode;
   int32_t wordStartOffset, wordEndOffset;
 
   rv = FindWordBounds(&offsetTable, &blockStr,
                       rngStartNode, rngStartOffset,
                       getter_AddRefs(wordStartNode), &wordStartOffset,
                       getter_AddRefs(wordEndNode), &wordEndOffset);
 
   ClearOffsetTable(&offsetTable);
@@ -380,19 +367,18 @@ nsTextServicesDocument::ExpandRangeToWor
       rngEndOffset != wordStartOffset ||
       (rngEndNode == rngStartNode && rngEndOffset == rngStartOffset)) {
     rngEndNode = wordEndNode;
     rngEndOffset = wordEndOffset;
   }
 
   // Now adjust the range so that it uses our new
   // end points.
-  nsCOMPtr<nsINode> startNode = do_QueryInterface(rngStartNode);
-  nsCOMPtr<nsINode> endNode = do_QueryInterface(rngEndNode);
-  rv = range->SetStartAndEnd(startNode, rngStartOffset, endNode, rngEndOffset);
+  rv = range->SetStartAndEnd(rngStartNode, rngStartOffset,
+                             rngEndNode, rngEndOffset);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsTextServicesDocument::SetFilter(nsITextServicesFilter *aFilter)
@@ -478,56 +464,44 @@ nsTextServicesDocument::LastSelectedBloc
     mSelCon->GetDOMSelection(nsISelectionController::SELECTION_NORMAL);
   if (NS_WARN_IF(!selection)) {
     UNLOCK_DOC(this);
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<nsIContentIterator> iter;
   RefPtr<nsRange> range;
-  nsCOMPtr<nsIDOMNode>         parent;
+  nsCOMPtr<nsINode> parent;
 
   if (selection->IsCollapsed()) {
     // We have a caret. Check if the caret is in a text node.
     // If it is, make the text node's block the current block.
     // If the caret isn't in a text node, search forwards in
     // the document, till we find a text node.
 
     range = selection->GetRangeAt(0);
 
     if (!range) {
       UNLOCK_DOC(this);
       return NS_ERROR_FAILURE;
     }
 
-    nsresult rv = range->GetStartContainer(getter_AddRefs(parent));
-
-    if (NS_FAILED(rv)) {
-      UNLOCK_DOC(this);
-      return rv;
-    }
-
+    parent = range->GetStartContainer();
     if (!parent) {
       UNLOCK_DOC(this);
       return NS_ERROR_FAILURE;
     }
 
-    if (IsTextNode(parent)) {
+    nsresult rv;
+    if (parent->IsNodeOfType(nsINode::eTEXT)) {
       // The caret is in a text node. Find the beginning
       // of the text block containing this text node and
       // return.
 
-      nsCOMPtr<nsIContent> content(do_QueryInterface(parent));
-
-      if (!content) {
-        UNLOCK_DOC(this);
-        return NS_ERROR_FAILURE;
-      }
-
-      rv = mIterator->PositionAt(content);
+      rv = mIterator->PositionAt(parent);
 
       if (NS_FAILED(rv)) {
         UNLOCK_DOC(this);
         return rv;
       }
 
       rv = FirstTextNodeInCurrentBlock(mIterator);
 
@@ -557,23 +531,22 @@ nsTextServicesDocument::LastSelectedBloc
         rv = SetSelectionInternal(*aSelOffset, *aSelLength, false);
       }
     } else {
       // The caret isn't in a text node. Create an iterator
       // based on a range that extends from the current caret
       // position to the end of the document, then walk forwards
       // till you find a text node, then find the beginning of it's block.
 
-      rv = CreateDocumentContentRootToNodeOffsetRange(
-             parent, range->StartOffset(), false,
-             getter_AddRefs(range));
-
-      if (NS_FAILED(rv)) {
+      range = CreateDocumentContentRootToNodeOffsetRange(
+                parent, range->StartOffset(), false);
+
+      if (NS_WARN_IF(!range)) {
         UNLOCK_DOC(this);
-        return rv;
+        return NS_ERROR_FAILURE;
       }
 
       if (range->Collapsed()) {
         // If we get here, the range is collapsed because there is nothing after
         // the caret! Just return NS_OK;
 
         UNLOCK_DOC(this);
         return NS_OK;
@@ -583,26 +556,23 @@ nsTextServicesDocument::LastSelectedBloc
 
       if (NS_FAILED(rv)) {
         UNLOCK_DOC(this);
         return rv;
       }
 
       iter->First();
 
-      nsCOMPtr<nsIContent> content;
+      nsIContent* content = nullptr;
       while (!iter->IsDone()) {
-        content = do_QueryInterface(iter->GetCurrentNode());
-
-        if (IsTextNode(content)) {
+        nsINode* currentNode = iter->GetCurrentNode();
+        if (currentNode->IsNodeOfType(nsINode::eTEXT)) {
+          content = currentNode->AsContent();
           break;
         }
-
-        content = nullptr;
-
         iter->Next();
       }
 
       if (!content) {
         UNLOCK_DOC(this);
         return NS_OK;
       }
 
@@ -684,19 +654,18 @@ nsTextServicesDocument::LastSelectedBloc
 
     // Now walk through the range till we find a text node.
 
     while (!iter->IsDone()) {
       if (iter->GetCurrentNode()->NodeType() == nsIDOMNode::TEXT_NODE) {
         // We found a text node, so position the document's
         // iterator at the beginning of the block, then get
         // the selection in terms of the string offset.
-        nsCOMPtr<nsIContent> content = iter->GetCurrentNode()->AsContent();
-
-        rv = mIterator->PositionAt(content);
+
+        rv = mIterator->PositionAt(iter->GetCurrentNode());
 
         if (NS_FAILED(rv)) {
           UNLOCK_DOC(this);
           return rv;
         }
 
         rv = FirstTextNodeInCurrentBlock(mIterator);
 
@@ -734,61 +703,52 @@ nsTextServicesDocument::LastSelectedBloc
 
   range = selection->GetRangeAt(rangeCount - 1);
 
   if (!range) {
     UNLOCK_DOC(this);
     return NS_ERROR_FAILURE;
   }
 
-  nsresult rv = range->GetEndContainer(getter_AddRefs(parent));
-
-  if (NS_FAILED(rv)) {
-    UNLOCK_DOC(this);
-    return rv;
-  }
-
+  parent = range->GetEndContainer();
   if (!parent) {
     UNLOCK_DOC(this);
     return NS_ERROR_FAILURE;
   }
 
-  rv = CreateDocumentContentRootToNodeOffsetRange(
-         parent, range->EndOffset(), false,
-         getter_AddRefs(range));
-
-  if (NS_FAILED(rv)) {
+  range = CreateDocumentContentRootToNodeOffsetRange(
+            parent, range->EndOffset(), false);
+
+  if (NS_WARN_IF(!range)) {
     UNLOCK_DOC(this);
-    return rv;
+    return NS_ERROR_FAILURE;
   }
 
   if (range->Collapsed()) {
     // If we get here, the range is collapsed because there is nothing after
     // the current selection! Just return NS_OK;
 
     UNLOCK_DOC(this);
     return NS_OK;
   }
 
-  rv = CreateContentIterator(range, getter_AddRefs(iter));
+  nsresult rv = CreateContentIterator(range, getter_AddRefs(iter));
 
   if (NS_FAILED(rv)) {
     UNLOCK_DOC(this);
     return rv;
   }
 
   iter->First();
 
   while (!iter->IsDone()) {
     if (iter->GetCurrentNode()->NodeType() == nsIDOMNode::TEXT_NODE) {
       // We found a text node! Adjust the document's iterator to point
       // to the beginning of its text block, then get the current selection.
-      nsCOMPtr<nsIContent> content = iter->GetCurrentNode()->AsContent();
-
-      rv = mIterator->PositionAt(content);
+      rv = mIterator->PositionAt(iter->GetCurrentNode());
 
       if (NS_FAILED(rv)) {
         UNLOCK_DOC(this);
         return rv;
       }
 
       rv = FirstTextNodeInCurrentBlock(mIterator);
 
@@ -1039,17 +999,17 @@ nsTextServicesDocument::DeleteSelection(
   // printf("Sel: (%2d, %4d) (%2d, %4d)\n", mSelStartIndex, mSelStartOffset, mSelEndIndex, mSelEndOffset);
   // PrintOffsetTable();
   //**** KDEBUG ****
 
   // If we have an mExtent, save off its current set of
   // end points so we can compare them against mExtent's
   // set after the deletion of the content.
 
-  nsCOMPtr<nsIDOMNode> origStartNode, origEndNode;
+  nsCOMPtr<nsINode> origStartNode, origEndNode;
   int32_t origStartOffset = 0, origEndOffset = 0;
 
   if (mExtent) {
     nsresult rv =
       GetRangeEndPoints(mExtent,
                         getter_AddRefs(origStartNode), &origStartOffset,
                         getter_AddRefs(origEndNode), &origEndOffset);
 
@@ -1181,17 +1141,17 @@ nsTextServicesDocument::DeleteSelection(
     return rv;
   }
 
   // Now that we've actually deleted the selected content,
   // check to see if our mExtent has changed, if so, then
   // we have to create a new content iterator!
 
   if (origStartNode && origEndNode) {
-    nsCOMPtr<nsIDOMNode> curStartNode, curEndNode;
+    nsCOMPtr<nsINode> curStartNode, curEndNode;
     int32_t curStartOffset = 0, curEndOffset = 0;
 
     rv = GetRangeEndPoints(mExtent,
                            getter_AddRefs(curStartNode), &curStartOffset,
                            getter_AddRefs(curEndNode), &curEndOffset);
 
     if (NS_FAILED(rv)) {
       UNLOCK_DOC(this);
@@ -1349,17 +1309,16 @@ nsTextServicesDocument::InsertText(const
   //**** KDEBUG ****
   // printf("\n---- Before Insert\n");
   // printf("Sel: (%2d, %4d) (%2d, %4d)\n", mSelStartIndex, mSelStartOffset, mSelEndIndex, mSelEndOffset);
   // PrintOffsetTable();
   //**** KDEBUG ****
 
   int32_t strLength = aText->Length();
 
-  nsCOMPtr<nsISelection> selection;
   OffsetEntry *itEntry;
   OffsetEntry *entry = mOffsetTable[mSelStartIndex];
   void *node         = entry->mNode;
 
   NS_ASSERTION((entry->mIsValid), "Invalid insertion point!");
 
   if (entry->mStrOffset == mSelStartOffset) {
     if (entry->mIsInsertedText) {
@@ -1439,20 +1398,19 @@ nsTextServicesDocument::InsertText(const
     // We have a valid inserted text offset entry. Update its
     // length, adjust the selection indexes, and make sure the
     // caret is properly placed!
 
     itEntry->mLength += strLength;
 
     mSelStartIndex = mSelEndIndex = i;
 
-    rv = mSelCon->GetSelection(nsISelectionController::SELECTION_NORMAL,
-                               getter_AddRefs(selection));
-
-    if (NS_FAILED(rv)) {
+    RefPtr<Selection> selection =
+      mSelCon->GetDOMSelection(nsISelectionController::SELECTION_NORMAL);
+    if (NS_WARN_IF(!selection)) {
       editor->EndTransaction();
       UNLOCK_DOC(this);
       return rv;
     }
 
     rv = selection->Collapse(itEntry->mNode,
                              itEntry->mNodeOffset + itEntry->mLength);
 
@@ -1563,35 +1521,36 @@ nsTextServicesDocument::DidDeleteNode(ns
   // fflush(stdout);
   //**** KDEBUG ****
 
   LOCK_DOC(this);
 
   int32_t nodeIndex = 0;
   bool hasEntry = false;
   OffsetEntry *entry;
+  nsCOMPtr<nsINode> child = do_QueryInterface(aChild);
 
   nsresult rv =
-    NodeHasOffsetEntry(&mOffsetTable, aChild, &hasEntry, &nodeIndex);
+    NodeHasOffsetEntry(&mOffsetTable, child, &hasEntry, &nodeIndex);
 
   if (NS_FAILED(rv)) {
     UNLOCK_DOC(this);
     return rv;
   }
 
   if (!hasEntry) {
     // It's okay if the node isn't in the offset table, the
     // editor could be cleaning house.
     UNLOCK_DOC(this);
     return NS_OK;
   }
 
-  nsCOMPtr<nsIDOMNode> node = do_QueryInterface(mIterator->GetCurrentNode());
-
-  if (node && node == aChild &&
+  nsINode* node = mIterator->GetCurrentNode();
+
+  if (node && node == child &&
       mIteratorStatus != nsTextServicesDocument::eIsDone) {
     // XXX: This should never really happen because
     // AdjustContentIterator() should have been called prior
     // to the delete to try and position the iterator on the
     // next valid text node in the offset table, and if there
     // wasn't a next, it would've set mIteratorStatus to eIsDone.
 
     NS_ERROR("DeleteNode called for current iterator node.");
@@ -1602,17 +1561,17 @@ nsTextServicesDocument::DidDeleteNode(ns
   while (nodeIndex < tcount) {
     entry = mOffsetTable[nodeIndex];
 
     if (!entry) {
       UNLOCK_DOC(this);
       return NS_ERROR_FAILURE;
     }
 
-    if (entry->mNode == aChild) {
+    if (entry->mNode == child) {
       entry->mIsValid = false;
     }
 
     nodeIndex++;
   }
 
   UNLOCK_DOC(this);
 
@@ -1636,48 +1595,46 @@ nsTextServicesDocument::DidJoinNodes(nsI
 
   //**** KDEBUG ****
   // printf("** JoinNodes: 0x%.8x  0x%.8x  0x%.8x\n", aLeftNode, aRightNode, aParent);
   // fflush(stdout);
   //**** KDEBUG ****
 
   // Make sure that both nodes are text nodes -- otherwise we don't care.
 
-  uint16_t type;
-  nsresult rv = aLeftNode->GetNodeType(&type);
-  NS_ENSURE_SUCCESS(rv, NS_OK);
-  if (nsIDOMNode::TEXT_NODE != type) {
+  nsCOMPtr<nsINode> leftNode = do_QueryInterface(aLeftNode);
+  nsCOMPtr<nsINode> rightNode = do_QueryInterface(aRightNode);
+
+  if (!leftNode || !leftNode->IsNodeOfType(nsINode::eTEXT)) {
     return NS_OK;
   }
 
-  rv = aRightNode->GetNodeType(&type);
-  NS_ENSURE_SUCCESS(rv, NS_OK);
-  if (nsIDOMNode::TEXT_NODE != type) {
+  if (!rightNode || !rightNode->IsNodeOfType(nsINode::eTEXT)) {
     return NS_OK;
   }
 
   // Note: The editor merges the contents of the left node into the
   //       contents of the right.
 
   int32_t leftIndex = 0;
   int32_t rightIndex = 0;
   bool leftHasEntry = false;
   bool rightHasEntry = false;
 
-  rv = NodeHasOffsetEntry(&mOffsetTable, aLeftNode, &leftHasEntry, &leftIndex);
-
+  nsresult rv =
+    NodeHasOffsetEntry(&mOffsetTable, leftNode, &leftHasEntry, &leftIndex);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!leftHasEntry) {
     // It's okay if the node isn't in the offset table, the
     // editor could be cleaning house.
     return NS_OK;
   }
 
-  rv = NodeHasOffsetEntry(&mOffsetTable, aRightNode,
+  rv = NodeHasOffsetEntry(&mOffsetTable, rightNode,
                           &rightHasEntry, &rightIndex);
 
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!rightHasEntry) {
     // It's okay if the node isn't in the offset table, the
     // editor could be cleaning house.
     return NS_OK;
@@ -1693,57 +1650,47 @@ nsTextServicesDocument::DidJoinNodes(nsI
   LOCK_DOC(this);
 
   OffsetEntry *entry = mOffsetTable[rightIndex];
   NS_ASSERTION(entry->mNodeOffset == 0, "Unexpected offset value for rightIndex.");
 
   // Run through the table and change all entries referring to
   // the left node so that they now refer to the right node:
 
-  nsAutoString str;
-  aLeftNode->GetNodeValue(str);
-  int32_t nodeLength = str.Length();
+  uint32_t nodeLength = leftNode->Length();
 
   for (int32_t i = leftIndex; i < rightIndex; i++) {
     entry = mOffsetTable[i];
-    if (entry->mNode != aLeftNode) {
+    if (entry->mNode != leftNode) {
       break;
     }
     if (entry->mIsValid) {
-      entry->mNode = aRightNode;
+      entry->mNode = rightNode;
     }
   }
 
   // Run through the table and adjust the node offsets
   // for all entries referring to the right node.
 
   for (int32_t i = rightIndex;
        i < static_cast<int32_t>(mOffsetTable.Length()); i++) {
     entry = mOffsetTable[i];
-    if (entry->mNode != aRightNode) {
+    if (entry->mNode != rightNode) {
       break;
     }
     if (entry->mIsValid) {
       entry->mNodeOffset += nodeLength;
     }
   }
 
   // Now check to see if the iterator is pointing to the
   // left node. If it is, make it point to the right node!
 
-  nsCOMPtr<nsIContent> leftContent = do_QueryInterface(aLeftNode);
-  nsCOMPtr<nsIContent> rightContent = do_QueryInterface(aRightNode);
-
-  if (!leftContent || !rightContent) {
-    UNLOCK_DOC(this);
-    return NS_ERROR_FAILURE;
-  }
-
-  if (mIterator->GetCurrentNode() == leftContent) {
-    mIterator->PositionAt(rightContent);
+  if (mIterator->GetCurrentNode() == leftNode) {
+    mIterator->PositionAt(rightNode);
   }
 
   UNLOCK_DOC(this);
 
   return NS_OK;
 }
 
 nsresult
@@ -1763,156 +1710,149 @@ nsTextServicesDocument::CreateContentIte
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   filter.forget(aIterator);
   return NS_OK;
 }
 
-nsresult
-nsTextServicesDocument::GetDocumentContentRootNode(nsIDOMNode **aNode)
+already_AddRefed<nsINode>
+nsTextServicesDocument::GetDocumentContentRootNode()
 {
-  NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER);
-
-  *aNode = 0;
-
-  NS_ENSURE_TRUE(mDOMDocument, NS_ERROR_FAILURE);
+  if (NS_WARN_IF(!mDOMDocument)) {
+    return nullptr;
+  }
 
   nsCOMPtr<nsIDOMHTMLDocument> htmlDoc = do_QueryInterface(mDOMDocument);
 
   if (htmlDoc) {
     // For HTML documents, the content root node is the body.
 
     nsCOMPtr<nsIDOMHTMLElement> bodyElement;
 
     nsresult rv = htmlDoc->GetBody(getter_AddRefs(bodyElement));
-
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    NS_ENSURE_TRUE(bodyElement, NS_ERROR_FAILURE);
-
-    bodyElement.forget(aNode);
-  } else {
-    // For non-HTML documents, the content root node will be the document element.
-
-    nsCOMPtr<nsIDOMElement> docElement;
-
-    nsresult rv = mDOMDocument->GetDocumentElement(getter_AddRefs(docElement));
-
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    NS_ENSURE_TRUE(docElement, NS_ERROR_FAILURE);
-
-    docElement.forget(aNode);
+    if (NS_WARN_IF(NS_FAILED(rv)) || NS_WARN_IF(!bodyElement)) {
+      return nullptr;
+    }
+
+    nsCOMPtr<nsINode> node = do_QueryInterface(bodyElement);
+    return node.forget();
   }
-
-  return NS_OK;
+  // For non-HTML documents, the content root node will be the document element.
+
+  nsCOMPtr<nsIDOMElement> docElement;
+
+  nsresult rv = mDOMDocument->GetDocumentElement(getter_AddRefs(docElement));
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+   return nullptr;
+  }
+
+  nsCOMPtr<nsINode> node = do_QueryInterface(docElement);
+  return node.forget();
 }
 
-nsresult
-nsTextServicesDocument::CreateDocumentContentRange(nsRange** aRange)
+already_AddRefed<nsRange>
+nsTextServicesDocument::CreateDocumentContentRange()
 {
-  *aRange = nullptr;
-
-  nsCOMPtr<nsIDOMNode> node;
-  nsresult rv = GetDocumentContentRootNode(getter_AddRefs(node));
-  NS_ENSURE_SUCCESS(rv, rv);
-  NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
-
-  nsCOMPtr<nsINode> nativeNode = do_QueryInterface(node);
-  NS_ENSURE_STATE(nativeNode);
-
-  RefPtr<nsRange> range = new nsRange(nativeNode);
-
-  rv = range->SelectNodeContents(node);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  range.forget(aRange);
-  return NS_OK;
+  nsCOMPtr<nsINode> node = GetDocumentContentRootNode();
+  if (NS_WARN_IF(!node)) {
+    return nullptr;
+  }
+
+  RefPtr<nsRange> range = new nsRange(node);
+  ErrorResult errorResult;
+  range->SelectNodeContents(*node, errorResult);
+  if (NS_WARN_IF(errorResult.Failed())) {
+    errorResult.SuppressException();
+    return nullptr;
+  }
+
+  return range.forget();
 }
 
-nsresult
+already_AddRefed<nsRange>
 nsTextServicesDocument::CreateDocumentContentRootToNodeOffsetRange(
-    nsIDOMNode* aParent, uint32_t aOffset, bool aToStart, nsRange** aRange)
+    nsINode* aParent, uint32_t aOffset, bool aToStart)
 {
-  NS_ENSURE_TRUE(aParent && aRange, NS_ERROR_NULL_POINTER);
-
-  *aRange = nullptr;
-
-  nsCOMPtr<nsIDOMNode> bodyNode;
-  nsresult rv = GetDocumentContentRootNode(getter_AddRefs(bodyNode));
-  NS_ENSURE_SUCCESS(rv, rv);
-  NS_ENSURE_TRUE(bodyNode, NS_ERROR_NULL_POINTER);
-
-  nsCOMPtr<nsIDOMNode> startNode;
-  nsCOMPtr<nsIDOMNode> endNode;
+  if (NS_WARN_IF(!aParent)) {
+    return nullptr;
+  }
+
+  nsCOMPtr<nsINode> bodyNode = GetDocumentContentRootNode();
+  if (NS_WARN_IF(!bodyNode)) {
+    return nullptr;
+  }
+
+  nsCOMPtr<nsINode> startNode;
+  nsCOMPtr<nsINode> endNode;
   uint32_t startOffset, endOffset;
 
   if (aToStart) {
     // The range should begin at the start of the document
     // and extend up until (aParent, aOffset).
 
-    startNode   = bodyNode;
+    startNode = bodyNode;
     startOffset = 0;
     endNode     = aParent;
     endOffset   = aOffset;
   } else {
     // The range should begin at (aParent, aOffset) and
     // extend to the end of the document.
 
     startNode   = aParent;
     startOffset = aOffset;
-    endNode     = bodyNode;
-
-    nsCOMPtr<nsINode> body = do_QueryInterface(bodyNode);
-    endOffset = body ? body->GetChildCount() : 0;
+    endNode = bodyNode;
+    endOffset = endNode ? endNode->GetChildCount() : 0;
   }
 
-  return nsRange::CreateRange(startNode, startOffset, endNode, endOffset,
-                              aRange);
+  RefPtr<nsRange> range;
+  nsresult rv = nsRange::CreateRange(startNode, startOffset, endNode, endOffset,
+                                     getter_AddRefs(range));
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return nullptr;
+  }
+  return range.forget();
 }
 
 nsresult
 nsTextServicesDocument::CreateDocumentContentIterator(nsIContentIterator **aIterator)
 {
   NS_ENSURE_TRUE(aIterator, NS_ERROR_NULL_POINTER);
 
-  RefPtr<nsRange> range;
-
-  nsresult rv = CreateDocumentContentRange(getter_AddRefs(range));
-
-  NS_ENSURE_SUCCESS(rv, rv);
+  RefPtr<nsRange> range  = CreateDocumentContentRange();
+  if (NS_WARN_IF(!range)) {
+    *aIterator = nullptr;
+    return NS_ERROR_FAILURE;
+  }
 
   return CreateContentIterator(range, aIterator);
 }
 
 nsresult
 nsTextServicesDocument::AdjustContentIterator()
 {
   NS_ENSURE_TRUE(mIterator, NS_ERROR_FAILURE);
 
-  nsCOMPtr<nsIDOMNode> node(do_QueryInterface(mIterator->GetCurrentNode()));
-
+  nsCOMPtr<nsINode> node = mIterator->GetCurrentNode();
   NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
 
-  nsIDOMNode *nodePtr = node.get();
-  int32_t tcount      = mOffsetTable.Length();
-
-  nsIDOMNode *prevValidNode = 0;
-  nsIDOMNode *nextValidNode = 0;
+  size_t tcount = mOffsetTable.Length();
+
+  nsINode* prevValidNode = nullptr;
+  nsINode* nextValidNode = nullptr;
   bool foundEntry = false;
   OffsetEntry *entry;
 
-  for (int32_t i = 0; i < tcount && !nextValidNode; i++) {
+  for (size_t i = 0; i < tcount && !nextValidNode; i++) {
     entry = mOffsetTable[i];
 
     NS_ENSURE_TRUE(entry, NS_ERROR_FAILURE);
 
-    if (entry->mNode == nodePtr) {
+    if (entry->mNode == node) {
       if (entry->mIsValid) {
         // The iterator is still pointing to something valid!
         // Do nothing!
         return NS_OK;
       }
       // We found an invalid entry that points to
       // the current iterator node. Stop looking for
       // a previous valid node!
@@ -1926,19 +1866,23 @@ nsTextServicesDocument::AdjustContentIte
         nextValidNode = entry->mNode;
       }
     }
   }
 
   nsCOMPtr<nsIContent> content;
 
   if (prevValidNode) {
-    content = do_QueryInterface(prevValidNode);
+    if (prevValidNode->IsContent()) {
+      content = prevValidNode->AsContent();
+    }
   } else if (nextValidNode) {
-    content = do_QueryInterface(nextValidNode);
+    if (nextValidNode->IsContent()) {
+      content = nextValidNode->AsContent();
+    }
   }
 
   if (content) {
     nsresult rv = mIterator->PositionAt(content);
 
     if (NS_FAILED(rv)) {
       mIteratorStatus = eIsDone;
     } else {
@@ -2097,17 +2041,17 @@ nsTextServicesDocument::SetSelectionInte
     entry = mOffsetTable[i];
     if (entry->mIsValid) {
       if (entry->mIsInsertedText) {
         // Caret can only be placed at the end of an
         // inserted text offset entry, if the offsets
         // match exactly!
 
         if (entry->mStrOffset == aOffset) {
-          startNode = do_QueryInterface(entry->mNode);
+          startNode = entry->mNode;
           startNodeOffset = entry->mNodeOffset + entry->mLength;
         }
       } else if (aOffset >= entry->mStrOffset) {
         bool foundEntry = false;
         int32_t strEndOffset = entry->mStrOffset + entry->mLength;
 
         if (aOffset < strEndOffset) {
           foundEntry = true;
@@ -2124,17 +2068,17 @@ nsTextServicesDocument::SetSelectionInte
               // Next offset entry isn't an exact match, so we'll
               // just use the current entry.
               foundEntry = true;
             }
           }
         }
 
         if (foundEntry) {
-          startNode = do_QueryInterface(entry->mNode);
+          startNode = entry->mNode;
           startNodeOffset = entry->mNodeOffset + aOffset - entry->mStrOffset;
         }
       }
 
       if (startNode) {
         mSelStartIndex = static_cast<int32_t>(i);
         mSelStartOffset = aOffset;
       }
@@ -2181,22 +2125,22 @@ nsTextServicesDocument::SetSelectionInte
     entry = mOffsetTable[i];
 
     if (entry->mIsValid) {
       if (entry->mIsInsertedText) {
         if (entry->mStrOffset == endNodeOffset) {
           // If the selection ends on an inserted text offset entry,
           // the selection includes the entire entry!
 
-          endNode = do_QueryInterface(entry->mNode);
+          endNode = entry->mNode;
           endNodeOffset = entry->mNodeOffset + entry->mLength;
         }
       } else if (endOffset >= entry->mStrOffset &&
                  endOffset <= entry->mStrOffset + entry->mLength) {
-        endNode = do_QueryInterface(entry->mNode);
+        endNode = entry->mNode;
         endNodeOffset = entry->mNodeOffset + endOffset - entry->mStrOffset;
       }
 
       if (endNode) {
         mSelEndIndex = i;
         mSelEndOffset = endOffset;
       }
     }
@@ -2287,47 +2231,43 @@ nsTextServicesDocument::GetCollapsedSele
   }
 
   int32_t eStartOffset = eStart->mNodeOffset;
   int32_t eEndOffset   = eEnd->mNodeOffset + eEnd->mLength;
 
   RefPtr<nsRange> range = selection->GetRangeAt(0);
   NS_ENSURE_STATE(range);
 
-  nsCOMPtr<nsIDOMNode> domParent;
-  rv = range->GetStartContainer(getter_AddRefs(domParent));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsINode> parent = do_QueryInterface(domParent);
+  nsCOMPtr<nsINode> parent = range->GetStartContainer();
   MOZ_ASSERT(parent);
 
   uint32_t offset = range->StartOffset();
 
   int32_t e1s1 = nsContentUtils::ComparePoints(eStart->mNode, eStartOffset,
-                                               domParent,
+                                               parent,
                                                static_cast<int32_t>(offset));
   int32_t e2s1 = nsContentUtils::ComparePoints(eEnd->mNode, eEndOffset,
-                                               domParent,
+                                               parent,
                                                static_cast<int32_t>(offset));
 
   if (e1s1 > 0 || e2s1 < 0) {
     // We're done if the caret is outside the current text block.
     return NS_OK;
   }
 
   if (parent->NodeType() == nsIDOMNode::TEXT_NODE) {
     // Good news, the caret is in a text node. Look
     // through the offset table for the entry that
     // matches its parent and offset.
 
     for (int32_t i = 0; i < tableCount; i++) {
       OffsetEntry* entry = mOffsetTable[i];
       NS_ENSURE_TRUE(entry, NS_ERROR_FAILURE);
 
-      if (entry->mNode == domParent.get() &&
+      if (entry->mNode == parent &&
           entry->mNodeOffset <= static_cast<int32_t>(offset) &&
           static_cast<int32_t>(offset) <= entry->mNodeOffset + entry->mLength) {
         *aSelStatus = nsITextServicesDocument::eBlockContains;
         *aSelOffset = entry->mStrOffset + (offset - entry->mNodeOffset);
         *aSelLength = 0;
 
         return NS_OK;
       }
@@ -2341,18 +2281,18 @@ nsTextServicesDocument::GetCollapsedSele
 
   // The caret is in our text block, but it's positioned in some
   // non-text node (ex. <b>). Create a range based on the start
   // and end of the text block, then create an iterator based on
   // this range, with its initial position set to the closest
   // child of this non-text node. Then look for the closest text
   // node.
 
-  rv = CreateRange(eStart->mNode, eStartOffset, eEnd->mNode, eEndOffset,
-                   getter_AddRefs(range));
+  rv = nsRange::CreateRange(eStart->mNode, eStartOffset, eEnd->mNode,
+                            eEndOffset, getter_AddRefs(range));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIContentIterator> iter;
   rv = CreateContentIterator(range, getter_AddRefs(iter));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsIContent* saveNode;
   if (parent->HasChildren()) {
@@ -2387,17 +2327,17 @@ nsTextServicesDocument::GetCollapsedSele
   // Now iterate to the left, towards the beginning of
   // the text block, to find the first text node you
   // come across.
 
   nsIContent* node = nullptr;
   while (!iter->IsDone()) {
     nsINode* current = iter->GetCurrentNode();
     if (current->NodeType() == nsIDOMNode::TEXT_NODE) {
-      node = static_cast<nsIContent*>(current);
+      node = current->AsContent();
       break;
     }
 
     iter->Prev();
   }
 
   if (node) {
     // We found a node, now set the offset to the end
@@ -2413,17 +2353,17 @@ nsTextServicesDocument::GetCollapsedSele
     rv = iter->PositionAt(saveNode);
     NS_ENSURE_SUCCESS(rv, rv);
 
     node = nullptr;
     while (!iter->IsDone()) {
       nsINode* current = iter->GetCurrentNode();
 
       if (current->NodeType() == nsIDOMNode::TEXT_NODE) {
-        node = static_cast<nsIContent*>(current);
+        node = current->AsContent();
         break;
       }
 
       iter->Next();
     }
 
     NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
 
@@ -2432,17 +2372,17 @@ nsTextServicesDocument::GetCollapsedSele
 
     offset = 0;
   }
 
   for (int32_t i = 0; i < tableCount; i++) {
     OffsetEntry* entry = mOffsetTable[i];
     NS_ENSURE_TRUE(entry, NS_ERROR_FAILURE);
 
-    if (entry->mNode == node->AsDOMNode() &&
+    if (entry->mNode == node &&
         entry->mNodeOffset <= static_cast<int32_t>(offset) &&
         static_cast<int32_t>(offset) <= entry->mNodeOffset + entry->mLength) {
       *aSelStatus = nsITextServicesDocument::eBlockContains;
       *aSelOffset = entry->mStrOffset + (offset - entry->mNodeOffset);
       *aSelLength = 0;
 
       // Now move the caret so that it is actually in the text node.
       // We do this to keep things in sync.
@@ -2470,17 +2410,17 @@ nsTextServicesDocument::GetUncollapsedSe
   NS_ENSURE_TRUE(domSelection, NS_ERROR_FAILURE);
 
   RefPtr<Selection> selection = domSelection->AsSelection();
 
   // It is assumed that the calling function has made sure that the
   // selection is not collapsed, and that the input params to this
   // method are initialized to some defaults.
 
-  nsCOMPtr<nsIDOMNode> startContainer, endContainer;
+  nsCOMPtr<nsINode> startContainer, endContainer;
   int32_t startOffset, endOffset;
   int32_t tableCount;
   int32_t e1s1 = 0, e1s2 = 0, e2s1 = 0, e2s2 = 0;
 
   OffsetEntry *eStart, *eEnd;
   int32_t eStartOffset, eEndOffset;
 
   tableCount = mOffsetTable.Length();
@@ -2557,42 +2497,42 @@ nsTextServicesDocument::GetUncollapsedSe
   } else {
     // The range partially intersects the block.
     *aSelStatus = nsITextServicesDocument::eBlockPartial;
   }
 
   // Now create a range based on the intersection of the
   // text block and range:
 
-  nsCOMPtr<nsIDOMNode> p1, p2;
+  nsCOMPtr<nsINode> p1, p2;
   int32_t     o1,  o2;
 
   // The start of the range will be the rightmost
   // start node.
 
   if (e1s1 >= 0) {
-    p1 = do_QueryInterface(eStart->mNode);
+    p1 = eStart->mNode;
     o1 = eStartOffset;
   } else {
     p1 = startContainer;
     o1 = startOffset;
   }
 
   // The end of the range will be the leftmost
   // end node.
 
   if (e2s2 <= 0) {
-    p2 = do_QueryInterface(eEnd->mNode);
+    p2 = eEnd->mNode;
     o2 = eEndOffset;
   } else {
     p2 = endContainer;
     o2 = endOffset;
   }
 
-  rv = CreateRange(p1, o1, p2, o2, getter_AddRefs(range));
+  rv = nsRange::CreateRange(p1, o1, p2, o2, getter_AddRefs(range));
 
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Now iterate over this range to figure out the selection's
   // block offset and length.
 
   nsCOMPtr<nsIContentIterator> iter;
 
@@ -2602,59 +2542,47 @@ nsTextServicesDocument::GetUncollapsedSe
 
   // Find the first text node in the range.
 
   bool found;
   nsCOMPtr<nsIContent> content;
 
   iter->First();
 
-  if (!IsTextNode(p1)) {
+  if (!p1->IsNodeOfType(nsINode::eTEXT)) {
     found = false;
 
     while (!iter->IsDone()) {
-      content = do_QueryInterface(iter->GetCurrentNode());
-
-      if (IsTextNode(content)) {
-        p1 = do_QueryInterface(content);
-
-        NS_ENSURE_TRUE(p1, NS_ERROR_FAILURE);
-
+      nsINode* node = iter->GetCurrentNode();
+
+      if (node->IsNodeOfType(nsINode::eTEXT)) {
+        p1 = node;
         o1 = 0;
         found = true;
 
         break;
       }
 
       iter->Next();
     }
 
     NS_ENSURE_TRUE(found, NS_ERROR_FAILURE);
   }
 
   // Find the last text node in the range.
 
   iter->Last();
 
-  if (!IsTextNode(p2)) {
+  if (!p2->IsNodeOfType(nsINode::eTEXT)) {
     found = false;
     while (!iter->IsDone()) {
-      content = do_QueryInterface(iter->GetCurrentNode());
-      if (IsTextNode(content)) {
-        p2 = do_QueryInterface(content);
-
-        NS_ENSURE_TRUE(p2, NS_ERROR_FAILURE);
-
-        nsString str;
-
-        rv = p2->GetNodeValue(str);
-
-        NS_ENSURE_SUCCESS(rv, rv);
-
-        o2 = str.Length();
+      nsINode* node = iter->GetCurrentNode();
+      if (node->IsNodeOfType(nsINode::eTEXT)) {
+        p2 = node;
+        o2 = p2->Length();
         found = true;
 
         break;
       }
 
       iter->Prev();
     }
 
@@ -2711,54 +2639,37 @@ nsTextServicesDocument::SelectionIsColla
 bool
 nsTextServicesDocument::SelectionIsValid()
 {
   return(mSelStartIndex >= 0);
 }
 
 nsresult
 nsTextServicesDocument::GetRangeEndPoints(nsRange* aRange,
-                                          nsIDOMNode** aStartContainer,
+                                          nsINode** aStartContainer,
                                           int32_t* aStartOffset,
-                                          nsIDOMNode** aEndContainer,
+                                          nsINode** aEndContainer,
                                           int32_t* aEndOffset)
 {
   NS_ENSURE_TRUE(aRange && aStartContainer && aStartOffset &&
                  aEndContainer && aEndOffset, NS_ERROR_NULL_POINTER);
 
-  nsresult rv = aRange->GetStartContainer(aStartContainer);
-
-  NS_ENSURE_SUCCESS(rv, rv);
-
+  NS_IF_ADDREF(*aStartContainer = aRange->GetStartContainer());
   NS_ENSURE_TRUE(aStartContainer, NS_ERROR_FAILURE);
 
   *aStartOffset = static_cast<int32_t>(aRange->StartOffset());
 
-  rv = aRange->GetEndContainer(aEndContainer);
-
-  NS_ENSURE_SUCCESS(rv, rv);
-
+  NS_IF_ADDREF(*aEndContainer = aRange->GetEndContainer());
   NS_ENSURE_TRUE(aEndContainer, NS_ERROR_FAILURE);
 
   *aEndOffset = static_cast<int32_t>(aRange->EndOffset());
   return NS_OK;
 }
 
 nsresult
-nsTextServicesDocument::CreateRange(nsIDOMNode* aStartContainer,
-                                    int32_t aStartOffset,
-                                    nsIDOMNode* aEndContainer,
-                                    int32_t aEndOffset,
-                                    nsRange** aRange)
-{
-  return nsRange::CreateRange(aStartContainer, aStartOffset, aEndContainer,
-                              aEndOffset, aRange);
-}
-
-nsresult
 nsTextServicesDocument::FirstTextNode(nsIContentIterator *aIterator,
                                       TSDIteratorStatus *aIteratorStatus)
 {
   if (aIteratorStatus) {
     *aIteratorStatus = nsTextServicesDocument::eIsDone;
   }
 
   aIterator->First();
@@ -2988,17 +2899,17 @@ nsTextServicesDocument::CreateOffsetTabl
   if (*aIteratorStatus == nsTextServicesDocument::eIsDone) {
     return NS_OK;
   }
 
   // If we have an aIterRange, retrieve the endpoints so
   // they can be used in the while loop below to trim entries
   // for text nodes that are partially selected by aIterRange.
 
-  nsCOMPtr<nsIDOMNode> rngStartNode, rngEndNode;
+  nsCOMPtr<nsINode> rngStartNode, rngEndNode;
   int32_t rngStartOffset = 0, rngEndOffset = 0;
 
   if (aIterRange) {
     nsresult rv =
       GetRangeEndPoints(aIterRange,
                         getter_AddRefs(rngStartNode), &rngStartOffset,
                         getter_AddRefs(rngEndNode), &rngEndOffset);
 
@@ -3021,62 +2932,58 @@ nsTextServicesDocument::CreateOffsetTabl
     nsCOMPtr<nsIContent> content = aIterator->GetCurrentNode()->IsContent()
                                    ? aIterator->GetCurrentNode()->AsContent()
                                    : nullptr;
     if (IsTextNode(content)) {
       if (prev && !HasSameBlockNodeParent(prev, content)) {
         break;
       }
 
-      nsCOMPtr<nsIDOMNode> node = do_QueryInterface(content);
-      if (node) {
-        nsString str;
-
-        rv = node->GetNodeValue(str);
-
-        NS_ENSURE_SUCCESS(rv, rv);
-
-        // Add an entry for this text node into the offset table:
-
-        OffsetEntry *entry = new OffsetEntry(node, offset, str.Length());
-        aOffsetTable->AppendElement(entry);
-
-        // If one or both of the endpoints of the iteration range
-        // are in the text node for this entry, make sure the entry
-        // only accounts for the portion of the text node that is
-        // in the range.
-
-        int32_t startOffset = 0;
-        int32_t endOffset   = str.Length();
-        bool adjustStr    = false;
-
-        if (entry->mNode == rngStartNode) {
-          entry->mNodeOffset = startOffset = rngStartOffset;
-          adjustStr = true;
-        }
-
-        if (entry->mNode == rngEndNode) {
-          endOffset = rngEndOffset;
-          adjustStr = true;
-        }
-
-        if (adjustStr) {
-          entry->mLength = endOffset - startOffset;
-          str = Substring(str, startOffset, entry->mLength);
-        }
-
-        offset += str.Length();
-
-        if (aStr) {
-          // Append the text node's string to the output string:
-          if (!first) {
-            *aStr = str;
-          } else {
-            *aStr += str;
-          }
+      nsString str;
+      rv = content->AsDOMNode()->GetNodeValue(str);
+
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      // Add an entry for this text node into the offset table:
+
+      OffsetEntry *entry = new OffsetEntry(content, offset, str.Length());
+      aOffsetTable->AppendElement(entry);
+
+      // If one or both of the endpoints of the iteration range
+      // are in the text node for this entry, make sure the entry
+      // only accounts for the portion of the text node that is
+      // in the range.
+
+      int32_t startOffset = 0;
+      int32_t endOffset   = str.Length();
+      bool adjustStr    = false;
+
+      if (entry->mNode == rngStartNode) {
+        entry->mNodeOffset = startOffset = rngStartOffset;
+        adjustStr = true;
+      }
+
+      if (entry->mNode == rngEndNode) {
+        endOffset = rngEndOffset;
+        adjustStr = true;
+      }
+
+      if (adjustStr) {
+        entry->mLength = endOffset - startOffset;
+        str = Substring(str, startOffset, entry->mLength);
+      }
+
+      offset += str.Length();
+
+      if (aStr) {
+        // Append the text node's string to the output string:
+        if (!first) {
+          *aStr = str;
+        } else {
+          *aStr += str;
         }
       }
 
       prev = content;
 
       if (!first) {
         first = content;
       }
@@ -3173,17 +3080,19 @@ nsTextServicesDocument::SplitOffsetEntry
 
    entry->mLength        = oldLength;
    newEntry->mNodeOffset = entry->mNodeOffset + oldLength;
 
   return NS_OK;
 }
 
 nsresult
-nsTextServicesDocument::NodeHasOffsetEntry(nsTArray<OffsetEntry*> *aOffsetTable, nsIDOMNode *aNode, bool *aHasEntry, int32_t *aEntryIndex)
+nsTextServicesDocument::NodeHasOffsetEntry(
+                          nsTArray<OffsetEntry*> *aOffsetTable,
+                          nsINode *aNode, bool *aHasEntry, int32_t *aEntryIndex)
 {
   NS_ENSURE_TRUE(aNode && aHasEntry && aEntryIndex, NS_ERROR_NULL_POINTER);
 
   for (size_t i = 0; i < aOffsetTable->Length(); i++) {
     OffsetEntry* entry = (*aOffsetTable)[i];
 
     NS_ENSURE_TRUE(entry, NS_ERROR_FAILURE);
 
@@ -3200,21 +3109,21 @@ nsTextServicesDocument::NodeHasOffsetEnt
 }
 
 // Spellchecker code has this. See bug 211343
 #define IS_NBSP_CHAR(c) (((unsigned char)0xa0)==(c))
 
 nsresult
 nsTextServicesDocument::FindWordBounds(nsTArray<OffsetEntry*> *aOffsetTable,
                                        nsString *aBlockStr,
-                                       nsIDOMNode *aNode,
+                                       nsINode *aNode,
                                        int32_t aNodeOffset,
-                                       nsIDOMNode **aWordStartNode,
+                                       nsINode **aWordStartNode,
                                        int32_t *aWordStartOffset,
-                                       nsIDOMNode **aWordEndNode,
+                                       nsINode **aWordEndNode,
                                        int32_t *aWordEndOffset)
 {
   // Initialize return values.
 
   if (aWordStartNode) {
     *aWordStartNode = nullptr;
   }
   if (aWordStartOffset) {
--- a/editor/txtsvc/nsTextServicesDocument.h
+++ b/editor/txtsvc/nsTextServicesDocument.h
@@ -125,36 +125,33 @@ public:
   NS_IMETHOD DidInsertText(nsIDOMCharacterData *aTextNode, int32_t aOffset, const nsAString &aString, nsresult aResult) override;
   NS_IMETHOD WillDeleteText(nsIDOMCharacterData *aTextNode, int32_t aOffset, int32_t aLength) override;
   NS_IMETHOD DidDeleteText(nsIDOMCharacterData *aTextNode, int32_t aOffset, int32_t aLength, nsresult aResult) override;
   NS_IMETHOD WillDeleteSelection(nsISelection *aSelection) override;
   NS_IMETHOD DidDeleteSelection(nsISelection *aSelection) override;
 
   /* Helper functions */
   static nsresult GetRangeEndPoints(nsRange* aRange,
-                                    nsIDOMNode** aStartContainer,
+                                    nsINode** aStartContainer,
                                     int32_t* aStartOffset,
-                                    nsIDOMNode** aEndContainer,
+                                    nsINode** aEndContainer,
                                     int32_t* aEndOffset);
-  static nsresult CreateRange(nsIDOMNode* aStartContainer, int32_t aStartOffset,
-                              nsIDOMNode* aEndContainer, int32_t aEndOffset,
-                              nsRange** aRange);
 
 private:
   /* nsTextServicesDocument private methods. */
 
   nsresult CreateContentIterator(nsRange* aRange,
                                  nsIContentIterator** aIterator);
 
-  nsresult GetDocumentContentRootNode(nsIDOMNode **aNode);
-  nsresult CreateDocumentContentRange(nsRange** aRange);
-  nsresult CreateDocumentContentRootToNodeOffsetRange(nsIDOMNode* aParent,
-                                                      uint32_t aOffset,
-                                                      bool aToStart,
-                                                      nsRange** aRange);
+  already_AddRefed<nsINode> GetDocumentContentRootNode();
+  already_AddRefed<nsRange> CreateDocumentContentRange();
+  already_AddRefed<nsRange> CreateDocumentContentRootToNodeOffsetRange(
+                              nsINode* aParent,
+                              uint32_t aOffset,
+                              bool aToStart);
   nsresult CreateDocumentContentIterator(nsIContentIterator **aIterator);
 
   nsresult AdjustContentIterator();
 
   static nsresult FirstTextNode(nsIContentIterator *aIterator, TSDIteratorStatus *IteratorStatus);
   static nsresult LastTextNode(nsIContentIterator *aIterator, TSDIteratorStatus *IteratorStatus);
 
   static nsresult FirstTextNodeInCurrentBlock(nsIContentIterator *aIterator);
@@ -183,25 +180,25 @@ private:
 
   static nsresult CreateOffsetTable(nsTArray<OffsetEntry*> *aOffsetTable,
                              nsIContentIterator *aIterator,
                              TSDIteratorStatus *aIteratorStatus,
                              nsRange* aIterRange, nsString* aStr);
   static nsresult ClearOffsetTable(nsTArray<OffsetEntry*> *aOffsetTable);
 
   static nsresult NodeHasOffsetEntry(nsTArray<OffsetEntry*> *aOffsetTable,
-                                     nsIDOMNode *aNode,
+                                     nsINode *aNode,
                                      bool *aHasEntry,
                                      int32_t *aEntryIndex);
 
   nsresult RemoveInvalidOffsetEntries();
   nsresult SplitOffsetEntry(int32_t aTableIndex, int32_t aOffsetIntoEntry);
 
   static nsresult FindWordBounds(nsTArray<OffsetEntry*> *offsetTable,
                                  nsString *blockStr,
-                                 nsIDOMNode *aNode, int32_t aNodeOffset,
-                                 nsIDOMNode **aWordStartNode,
+                                 nsINode* aNode, int32_t aNodeOffset,
+                                 nsINode** aWordStartNode,
                                  int32_t *aWordStartOffset,
-                                 nsIDOMNode **aWordEndNode,
+                                 nsINode** aWordEndNode,
                                  int32_t *aWordEndOffset);
 };
 
 #endif // nsTextServicesDocument_h__