Bug 1447213 - Change editor methods which take |const EditorRawDOMPoint&| but called with EditorDOMPoint.AsRaw() to template methods r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Tue, 20 Mar 2018 14:05:47 +0900
changeset 770992 961de76ba3865c82339df5a982f8af6b03f0ce5a
parent 770928 b41c7c1ff91f49b1500b087ff23c288dd88f1fde
push id103548
push usermasayuki@d-toybox.com
push dateThu, 22 Mar 2018 08:16:26 +0000
reviewersm_kato
bugs1447213
milestone61.0a1
Bug 1447213 - Change editor methods which take |const EditorRawDOMPoint&| but called with EditorDOMPoint.AsRaw() to template methods r?m_kato A lot of methods take |const EditorRawDOMPoint&| as their argument. However, some of them are called with EditorDOMPoint::AsRaw(). This is not good for performance because: 1. Needs to create temporary instance of EditorRawDOMPoint. 2. EditorRawDOMPoint::AsRaw() may be used by simple mistake. 3. Such methods may call EditorRawDOMPoint::Offset(), however, it's not copied to the original EditorDOMPoint instance. So, callers may need to compute offset again. So, such methods should be changed to template methods if they are not virtual method and AsRaw() should be gotten rid of for prevent it looking not expensive. MozReview-Commit-ID: DAqqW4a2EMS
editor/libeditor/CreateElementTransaction.cpp
editor/libeditor/CreateElementTransaction.h
editor/libeditor/EditorBase.cpp
editor/libeditor/EditorBase.h
editor/libeditor/EditorDOMPoint.h
editor/libeditor/EditorUtils.h
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/HTMLEditRules.h
editor/libeditor/HTMLEditor.cpp
editor/libeditor/HTMLEditor.h
editor/libeditor/HTMLEditorDataTransfer.cpp
editor/libeditor/HTMLTableEditor.cpp
editor/libeditor/InsertNodeTransaction.cpp
editor/libeditor/InsertNodeTransaction.h
editor/libeditor/SelectionState.cpp
editor/libeditor/SelectionState.h
editor/libeditor/SplitNodeTransaction.cpp
editor/libeditor/SplitNodeTransaction.h
editor/libeditor/TextEditRules.h
editor/libeditor/TextEditor.cpp
editor/libeditor/TextEditor.h
editor/libeditor/WSRunObject.cpp
editor/libeditor/WSRunObject.h
--- a/editor/libeditor/CreateElementTransaction.cpp
+++ b/editor/libeditor/CreateElementTransaction.cpp
@@ -27,30 +27,44 @@
 #include "nsReadableUtils.h"
 #include "nsStringFwd.h"
 #include "nsString.h"
 
 namespace mozilla {
 
 using namespace dom;
 
+template already_AddRefed<CreateElementTransaction>
+CreateElementTransaction::Create(
+                            EditorBase& aEditorBase,
+                            nsAtom& aTag,
+                            const EditorDOMPoint& aPointToInsert);
+template already_AddRefed<CreateElementTransaction>
+CreateElementTransaction::Create(
+                            EditorBase& aEditorBase,
+                            nsAtom& aTag,
+                            const EditorRawDOMPoint& aPointToInsert);
+
+template<typename PT, typename CT>
 already_AddRefed<CreateElementTransaction>
-CreateElementTransaction::Create(EditorBase& aEditorBase,
-                                 nsAtom& aTag,
-                                 const EditorRawDOMPoint& aPointToInsert)
+CreateElementTransaction::Create(
+                            EditorBase& aEditorBase,
+                            nsAtom& aTag,
+                            const EditorDOMPointBase<PT, CT>& aPointToInsert)
 {
   RefPtr<CreateElementTransaction> transaction =
     new CreateElementTransaction(aEditorBase, aTag, aPointToInsert);
   return transaction.forget();
 }
 
+template<typename PT, typename CT>
 CreateElementTransaction::CreateElementTransaction(
                             EditorBase& aEditorBase,
                             nsAtom& aTag,
-                            const EditorRawDOMPoint& aPointToInsert)
+                            const EditorDOMPointBase<PT, CT>& aPointToInsert)
   : EditTransactionBase()
   , mEditorBase(&aEditorBase)
   , mTag(&aTag)
   , mPointToInsert(aPointToInsert)
 {
 }
 
 CreateElementTransaction::~CreateElementTransaction()
--- a/editor/libeditor/CreateElementTransaction.h
+++ b/editor/libeditor/CreateElementTransaction.h
@@ -24,36 +24,38 @@ namespace mozilla {
 class EditorBase;
 namespace dom {
 class Element;
 } // namespace dom
 
 class CreateElementTransaction final : public EditTransactionBase
 {
 protected:
+  template<typename PT, typename CT>
   CreateElementTransaction(EditorBase& aEditorBase,
                            nsAtom& aTag,
-                           const EditorRawDOMPoint& aPointToInsert);
+                           const EditorDOMPointBase<PT, CT>& aPointToInsert);
 
 public:
   /**
    * Create a transaction for creating a new child node of the container of
    * aPointToInsert of type aTag.
    *
    * @param aEditorBase     The editor which manages the transaction.
    * @param aTag            The tag (P, HR, TABLE, etc.) for the new element.
    * @param aPointToInsert  The new node will be inserted before the child at
    *                        aPointToInsert.  If this refers end of the container
    *                        or after, the new node will be appended to the
    *                        container.
    */
+  template<typename PT, typename CT>
   static already_AddRefed<CreateElementTransaction>
   Create(EditorBase& aEditorBase,
          nsAtom& aTag,
-         const EditorRawDOMPoint& aPointToInsert);
+         const EditorDOMPointBase<PT, CT>& aPointToInsert);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(CreateElementTransaction,
                                            EditTransactionBase)
 
   NS_DECL_EDITTRANSACTIONBASE
 
   NS_IMETHOD RedoTransaction() override;
--- a/editor/libeditor/EditorBase.cpp
+++ b/editor/libeditor/EditorBase.cpp
@@ -118,16 +118,41 @@ namespace mozilla {
 
 using namespace dom;
 using namespace widget;
 
 /*****************************************************************************
  * mozilla::EditorBase
  *****************************************************************************/
 
+template already_AddRefed<Element>
+EditorBase::CreateNode(nsAtom* aTag, const EditorDOMPoint& aPointToInsert);
+template already_AddRefed<Element>
+EditorBase::CreateNode(nsAtom* aTag, const EditorRawDOMPoint& aPointToInsert);
+template nsresult
+EditorBase::InsertNode(nsIContent& aContentToInsert,
+                       const EditorDOMPoint& aPointToInsert);
+template nsresult
+EditorBase::InsertNode(nsIContent& aContentToInsert,
+                       const EditorRawDOMPoint& aPointToInsert);
+template already_AddRefed<nsIContent>
+EditorBase::SplitNode(const EditorDOMPoint& aStartOfRightNode,
+                      ErrorResult& aError);
+template already_AddRefed<nsIContent>
+EditorBase::SplitNode(const EditorRawDOMPoint& aStartOfRightNode,
+                      ErrorResult& aError);
+template SplitNodeResult
+EditorBase::SplitNodeDeep(nsIContent& aMostAncestorToSplit,
+                          const EditorDOMPoint& aStartOfDeepestRightNode,
+                          SplitAtEdges aSplitAtEdges);
+template SplitNodeResult
+EditorBase::SplitNodeDeep(nsIContent& aMostAncestorToSplit,
+                          const EditorRawDOMPoint& aStartOfDeepestRightNode,
+                          SplitAtEdges aSplitAtEdges);
+
 EditorBase::EditorBase()
   : mPlaceholderName(nullptr)
   , mModCount(0)
   , mFlags(0)
   , mUpdateCount(0)
   , mPlaceholderBatch(0)
   , mAction(EditAction::none)
   , mDirection(eNone)
@@ -1412,19 +1437,20 @@ EditorBase::SyncRealTimeSpell()
 NS_IMETHODIMP
 EditorBase::SetSpellcheckUserOverride(bool enable)
 {
   mSpellcheckCheckboxState = enable ? eTriTrue : eTriFalse;
 
   return SyncRealTimeSpell();
 }
 
+template<typename PT, typename CT>
 already_AddRefed<Element>
 EditorBase::CreateNode(nsAtom* aTag,
-                       const EditorRawDOMPoint& aPointToInsert)
+                       const EditorDOMPointBase<PT, CT>& aPointToInsert)
 {
   MOZ_ASSERT(aTag);
   MOZ_ASSERT(aPointToInsert.IsSetAndValid());
 
   // XXX We need offset at new node for mRangeUpdater.  Therefore, we need
   //     to compute the offset now but this is expensive.  So, if it's possible,
   //     we need to redesign mRangeUpdater as avoiding using indices.
   Unused << aPointToInsert.Offset();
@@ -1484,32 +1510,33 @@ EditorBase::InsertNode(nsIDOMNode* aNode
     return NS_ERROR_NULL_POINTER;
   }
   int32_t offset =
     aOffset < 0 ? static_cast<int32_t>(container->Length()) :
                   std::min(aOffset, static_cast<int32_t>(container->Length()));
   return InsertNode(*contentToInsert, EditorRawDOMPoint(container, offset));
 }
 
+template<typename PT, typename CT>
 nsresult
 EditorBase::InsertNode(nsIContent& aContentToInsert,
-                       const EditorRawDOMPoint& aPointToInsert)
+                       const EditorDOMPointBase<PT, CT>& aPointToInsert)
 {
   if (NS_WARN_IF(!aPointToInsert.IsSet())) {
     return NS_ERROR_INVALID_ARG;
   }
   MOZ_ASSERT(aPointToInsert.IsSetAndValid());
 
   AutoRules beginRulesSniffing(this, EditAction::insertNode, nsIEditor::eNext);
 
   RefPtr<InsertNodeTransaction> transaction =
     InsertNodeTransaction::Create(*this, aContentToInsert, aPointToInsert);
   nsresult rv = DoTransaction(transaction);
 
-  mRangeUpdater.SelAdjInsertNode(aPointToInsert.AsRaw());
+  mRangeUpdater.SelAdjInsertNode(aPointToInsert);
 
   if (mRules && mRules->AsHTMLEditRules()) {
     RefPtr<HTMLEditRules> htmlEditRules = mRules->AsHTMLEditRules();
     htmlEditRules->DidInsertNode(aContentToInsert);
   }
 
   if (!mActionListeners.IsEmpty()) {
     AutoActionListenerArray listeners(mActionListeners);
@@ -1538,18 +1565,19 @@ EditorBase::SplitNode(nsIDOMNode* aNode,
     SplitNode(EditorRawDOMPoint(node, offset), error);
   *aNewLeftNode = GetAsDOMNode(newNode.forget().take());
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
   return NS_OK;
 }
 
+template<typename PT, typename CT>
 already_AddRefed<nsIContent>
-EditorBase::SplitNode(const EditorRawDOMPoint& aStartOfRightNode,
+EditorBase::SplitNode(const EditorDOMPointBase<PT, CT>& aStartOfRightNode,
                       ErrorResult& aError)
 {
   if (NS_WARN_IF(!aStartOfRightNode.IsSet()) ||
       NS_WARN_IF(!aStartOfRightNode.GetContainerAsContent())) {
     aError.Throw(NS_ERROR_INVALID_ARG);
     return nullptr;
   }
   MOZ_ASSERT(aStartOfRightNode.IsSetAndValid());
@@ -1770,17 +1798,17 @@ EditorBase::ReplaceContainer(Element* aO
         return nullptr;
       }
     }
   }
 
   // Insert new container into tree.
   NS_WARNING_ASSERTION(atOldContainer.IsSetAndValid(),
     "The old container might be moved by mutation observer");
-  nsresult rv = InsertNode(*newContainer, atOldContainer.AsRaw());
+  nsresult rv = InsertNode(*newContainer, atOldContainer);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return nullptr;
   }
 
   // Delete old container.
   rv = DeleteNode(aOldContainer);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return nullptr;
@@ -1884,17 +1912,17 @@ EditorBase::InsertContainerAbove(nsICont
     AutoTransactionsConserveSelection conserveSelection(this);
     rv = InsertNode(*aNode, EditorRawDOMPoint(newContainer, 0));
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return nullptr;
     }
   }
 
   // Put the new container where aNode was.
-  rv = InsertNode(*newContainer, pointToInsertNewContainer.AsRaw());
+  rv = InsertNode(*newContainer, pointToInsertNewContainer);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return nullptr;
   }
 
   return newContainer.forget();
 }
 
 /**
@@ -4127,20 +4155,22 @@ EditorBase::IsPreformatted(nsIDOMNode* a
   }
 
   const nsStyleText* styleText = elementStyle->StyleText();
 
   *aResult = styleText->WhiteSpaceIsSignificant();
   return NS_OK;
 }
 
+template<typename PT, typename CT>
 SplitNodeResult
-EditorBase::SplitNodeDeep(nsIContent& aMostAncestorToSplit,
-                          const EditorRawDOMPoint& aStartOfDeepestRightNode,
-                          SplitAtEdges aSplitAtEdges)
+EditorBase::SplitNodeDeep(
+              nsIContent& aMostAncestorToSplit,
+              const EditorDOMPointBase<PT, CT>& aStartOfDeepestRightNode,
+              SplitAtEdges aSplitAtEdges)
 {
   MOZ_ASSERT(aStartOfDeepestRightNode.IsSetAndValid());
   MOZ_ASSERT(aStartOfDeepestRightNode.GetContainer() == &aMostAncestorToSplit ||
              EditorUtils::IsDescendantOf(
                             *aStartOfDeepestRightNode.GetContainer(),
                             aMostAncestorToSplit));
 
   if (NS_WARN_IF(!aStartOfDeepestRightNode.IsSet())) {
@@ -4169,18 +4199,17 @@ EditorBase::SplitNodeDeep(nsIContent& aM
 
     // If the split point is middle of the node or the node is not a text node
     // and we're allowed to create empty element node, split it.
     if ((aSplitAtEdges == SplitAtEdges::eAllowToCreateEmptyContainer &&
          !atStartOfRightNode.GetContainerAsText()) ||
         (!atStartOfRightNode.IsStartOfContainer() &&
          !atStartOfRightNode.IsEndOfContainer())) {
       ErrorResult error;
-      nsCOMPtr<nsIContent> newLeftNode =
-        SplitNode(atStartOfRightNode.AsRaw(), error);
+      nsCOMPtr<nsIContent> newLeftNode = SplitNode(atStartOfRightNode, error);
       if (NS_WARN_IF(error.Failed())) {
         return SplitNodeResult(error.StealNSResult());
       }
 
       if (currentRightNode == &aMostAncestorToSplit) {
         // Actually, we split aMostAncestorToSplit.
         return SplitNodeResult(newLeftNode, &aMostAncestorToSplit);
       }
@@ -4517,17 +4546,17 @@ EditorBase::DeleteSelectionAndPrepareToC
     selection->Collapse(afterAnchorContainer, error);
     if (NS_WARN_IF(error.Failed())) {
       return error.StealNSResult();
     }
     return NS_OK;
   }
 
   ErrorResult error;
-  nsCOMPtr<nsIContent> newLeftNode = SplitNode(atAnchor.AsRaw(), error);
+  nsCOMPtr<nsIContent> newLeftNode = SplitNode(atAnchor, error);
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
 
   EditorRawDOMPoint atRightNode(atAnchor.GetContainer());
   if (NS_WARN_IF(!atRightNode.IsSet())) {
     return NS_ERROR_FAILURE;
   }
--- a/editor/libeditor/EditorBase.h
+++ b/editor/libeditor/EditorBase.h
@@ -345,18 +345,19 @@ public:
    *
    * @param aContentToInsert    The node to be inserted.
    * @param aPointToInsert      The insertion point of aContentToInsert.
    *                            If this refers end of the container, the
    *                            transaction will append the node to the
    *                            container.  Otherwise, will insert the node
    *                            before child node referred by this.
    */
+  template<typename PT, typename CT>
   nsresult InsertNode(nsIContent& aContentToInsert,
-                      const EditorRawDOMPoint& aPointToInsert);
+                      const EditorDOMPointBase<PT, CT>& aPointToInsert);
 
   enum ECloneAttributes { eDontCloneAttributes, eCloneAttributes };
   already_AddRefed<Element> ReplaceContainer(Element* aOldContainer,
                                              nsAtom* aNodeType,
                                              nsAtom* aAttribute = nullptr,
                                              const nsAString* aValue = nullptr,
                                              ECloneAttributes aCloneAttributes
                                              = eDontCloneAttributes);
@@ -376,18 +377,19 @@ public:
    *
    * @param aStartOfRightNode   The point to split.  Its container will be
    *                            the right node, i.e., become the new node's
    *                            next sibling.  And the point will be start
    *                            of the right node.
    * @param aError              If succeed, returns no error.  Otherwise, an
    *                            error.
    */
+  template<typename PT, typename CT>
   already_AddRefed<nsIContent>
-  SplitNode(const EditorRawDOMPoint& aStartOfRightNode,
+  SplitNode(const EditorDOMPointBase<PT, CT>& aStartOfRightNode,
             ErrorResult& aResult);
 
   nsresult JoinNodes(nsINode& aLeftNode, nsINode& aRightNode);
   nsresult MoveNode(nsIContent* aNode, nsINode* aParent, int32_t aOffset);
 
   /**
    * MoveAllChildren() moves all children of aContainer to before
    * aPointToInsert.GetChild().
@@ -515,18 +517,20 @@ protected:
    * @param aTag            The element name to create.
    * @param aPointToInsert  The insertion point of new element.  If this refers
    *                        end of the container or after, the transaction
    *                        will append the element to the container.
    *                        Otherwise, will insert the element before the
    *                        child node referred by this.
    * @return                The created new element node.
    */
-  already_AddRefed<Element> CreateNode(nsAtom* aTag,
-                                       const EditorRawDOMPoint& aPointToInsert);
+  template<typename PT, typename CT>
+  already_AddRefed<Element>
+  CreateNode(nsAtom* aTag,
+             const EditorDOMPointBase<PT, CT>& aPointToInsert);
 
   /**
    * Create an aggregate transaction for delete selection.  The result may
    * include DeleteNodeTransactions and/or DeleteTextTransactions as its
    * children.
    *
    * @param aAction             The action caused removing the selection.
    * @param aRemovingNode       The node to be removed.
@@ -900,38 +904,45 @@ public:
    *   MOZ_ASSERT(advanced);
    *   point.Set(point.GetChild());
    * }
    *
    * On the other hand, the methods taking nsINode behavior must be what
    * you want.  They start to search the result from next node of the given
    * node.
    */
-  nsIContent* GetNextNode(const EditorRawDOMPoint& aPoint)
+  template<typename PT, typename CT>
+  nsIContent* GetNextNode(const EditorDOMPointBase<PT, CT>& aPoint)
   {
     return GetNextNodeInternal(aPoint, false, true, false);
   }
-  nsIContent* GetNextElementOrText(const EditorRawDOMPoint& aPoint)
+  template<typename PT, typename CT>
+  nsIContent* GetNextElementOrText(const EditorDOMPointBase<PT, CT>& aPoint)
   {
     return GetNextNodeInternal(aPoint, false, false, false);
   }
-  nsIContent* GetNextEditableNode(const EditorRawDOMPoint& aPoint)
+  template<typename PT, typename CT>
+  nsIContent* GetNextEditableNode(const EditorDOMPointBase<PT, CT>& aPoint)
   {
     return GetNextNodeInternal(aPoint, true, true, false);
   }
-  nsIContent* GetNextNodeInBlock(const EditorRawDOMPoint& aPoint)
+  template<typename PT, typename CT>
+  nsIContent* GetNextNodeInBlock(const EditorDOMPointBase<PT, CT>& aPoint)
   {
     return GetNextNodeInternal(aPoint, false, true, true);
   }
-  nsIContent* GetNextElementOrTextInBlock(const EditorRawDOMPoint& aPoint)
+  template<typename PT, typename CT>
+  nsIContent* GetNextElementOrTextInBlock(
+                const EditorDOMPointBase<PT, CT>& aPoint)
   {
     return GetNextNodeInternal(aPoint, false, false, true);
   }
+  template<typename PT, typename CT>
   nsIContent* GetNextEditableNodeInBlock(
-                const EditorRawDOMPoint& aPoint)
+                const EditorDOMPointBase<PT, CT>& aPoint)
   {
     return GetNextNodeInternal(aPoint, true, true, true);
   }
   nsIContent* GetNextNode(nsINode& aNode)
   {
     return GetNextNodeInternal(aNode, false, true, false);
   }
   nsIContent* GetNextElementOrText(nsINode& aNode)
@@ -1177,19 +1188,20 @@ public:
    *                                    create empty container element when
    *                                    split point is start or end of an
    *                                    element.
    * @return                            SplitPoint() returns split point in
    *                                    aMostAncestorToSplit.  The point must
    *                                    be good to insert something if the
    *                                    caller want to do it.
    */
+  template<typename PT, typename CT>
   SplitNodeResult
   SplitNodeDeep(nsIContent& aMostAncestorToSplit,
-                const EditorRawDOMPoint& aDeepestStartOfRightNode,
+                const EditorDOMPointBase<PT, CT>& aDeepestStartOfRightNode,
                 SplitAtEdges aSplitAtEdges);
 
   EditorDOMPoint JoinNodeDeep(nsIContent& aLeftNode,
                               nsIContent& aRightNode);
 
   nsresult GetString(const nsAString& name, nsAString& value);
 
   void BeginUpdateViewBatch();
--- a/editor/libeditor/EditorDOMPoint.h
+++ b/editor/libeditor/EditorDOMPoint.h
@@ -624,24 +624,16 @@ public:
     const_cast<SelfType*>(this)->EnsureChild();
     if (!mChild ||
         mChild->GetNextSibling()) {
       return false;
     }
     return mChild->IsHTMLElement(nsGkAtoms::br);
   }
 
-  // Convenience methods for switching between the two types
-  // of EditorDOMPointBase.
-  EditorDOMPointBase<nsINode*, nsIContent*>
-  AsRaw() const
-  {
-    return EditorRawDOMPoint(*this);
-  }
-
   template<typename A, typename B>
   EditorDOMPointBase& operator=(const RangeBoundaryBase<A,B>& aOther)
   {
     mParent = aOther.mParent;
     mChild =
       aOther.mRef ? aOther.mRef->GetNextSibling() :
                     (aOther.mParent && aOther.mParent->IsContainerNode() ?
                        aOther.mParent->GetFirstChild() : nullptr);
--- a/editor/libeditor/EditorUtils.h
+++ b/editor/libeditor/EditorUtils.h
@@ -216,17 +216,17 @@ public:
    * and child node are guaranteed while using the result temporarily.
    */
   EditorRawDOMPoint SplitPoint() const
   {
     if (Failed()) {
       return EditorRawDOMPoint();
     }
     if (mGivenSplitPoint.IsSet()) {
-      return mGivenSplitPoint.AsRaw();
+      return EditorRawDOMPoint(mGivenSplitPoint);
     }
     if (!mPreviousNode) {
       return EditorRawDOMPoint(mNextNode);
     }
     EditorRawDOMPoint point(mPreviousNode);
     DebugOnly<bool> advanced = point.AdvanceOffset();
     NS_WARNING_ASSERTION(advanced,
       "Failed to advance offset to after previous node");
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -1253,18 +1253,21 @@ HTMLEditRules::WillInsert(Selection& aSe
       htmlEditor->GetBlock(*atStartOfSelection.GetContainer());
     RefPtr<Element> block2 = htmlEditor->GetBlockNodeParent(priorNode);
 
     if (block1 && block1 == block2) {
       // If we are here then the selection is right after a mozBR that is in
       // the same block as the selection.  We need to move the selection start
       // to be before the mozBR.
       EditorRawDOMPoint point(priorNode);
-      nsresult rv = aSelection.Collapse(point.AsRaw());
-      NS_ENSURE_SUCCESS_VOID(rv);
+      IgnoredErrorResult error;
+      aSelection.Collapse(point, error);
+      if (NS_WARN_IF(error.Failed())) {
+        return;
+      }
     }
   }
 
   if (mDidDeleteSelection &&
       (mTheAction == EditAction::insertText ||
        mTheAction == EditAction::insertIMEText ||
        mTheAction == EditAction::deleteSelection)) {
     nsresult rv = ReapplyCachedStyles();
@@ -1344,25 +1347,26 @@ HTMLEditRules::WillInsertText(EditAction
     // the insertion point.
     int32_t IMESelectionOffset =
       mHTMLEditor->GetIMESelectionStartOffsetIn(pointToInsert.GetContainer());
     if (IMESelectionOffset >= 0) {
       pointToInsert.Set(pointToInsert.GetContainer(), IMESelectionOffset);
     }
 
     if (inString->IsEmpty()) {
-      rv = mHTMLEditor->InsertTextImpl(*doc, *inString, pointToInsert.AsRaw());
+      rv = mHTMLEditor->InsertTextImpl(*doc, *inString,
+                                       EditorRawDOMPoint(pointToInsert));
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
       return NS_OK;
     }
 
     WSRunObject wsObj(mHTMLEditor, pointToInsert);
-    rv = wsObj.InsertText(*doc, *inString, pointToInsert.AsRaw());
+    rv = wsObj.InsertText(*doc, *inString, pointToInsert);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
     return NS_OK;
   }
 
   // aAction == kInsertText
 
@@ -1417,17 +1421,17 @@ HTMLEditRules::WillInsertText(EditAction
         }
 
         nsDependentSubstring subStr(tString, oldPos, subStrLen);
 
         // is it a return?
         if (subStr.Equals(newlineStr)) {
           NS_ENSURE_STATE(mHTMLEditor);
           nsCOMPtr<Element> br =
-            mHTMLEditor->CreateBRImpl(*aSelection, currentPoint.AsRaw(),
+            mHTMLEditor->CreateBRImpl(*aSelection, currentPoint,
                                       nsIEditor::eNone);
           NS_ENSURE_STATE(br);
           pos++;
           if (br->GetNextSibling()) {
             pointToInsert.Set(br->GetNextSibling());
           } else {
             pointToInsert.SetToEndOf(currentPoint.GetContainer());
           }
@@ -1439,17 +1443,18 @@ HTMLEditRules::WillInsertText(EditAction
           NS_WARNING_ASSERTION(advanced,
             "Failed to advance offset after the new <br> element");
           NS_WARNING_ASSERTION(currentPoint == pointToInsert,
             "Perhaps, <br> element position has been moved to different point "
             "by mutation observer");
         } else {
           NS_ENSURE_STATE(mHTMLEditor);
           EditorRawDOMPoint pointAfterInsertedString;
-          rv = mHTMLEditor->InsertTextImpl(*doc, subStr, currentPoint.AsRaw(),
+          rv = mHTMLEditor->InsertTextImpl(*doc, subStr,
+                                           EditorRawDOMPoint(currentPoint),
                                            &pointAfterInsertedString);
           NS_ENSURE_SUCCESS(rv, rv);
           currentPoint = pointAfterInsertedString;
           pointToInsert = pointAfterInsertedString;
         }
       }
     } else {
       NS_NAMED_LITERAL_STRING(tabStr, "\t");
@@ -1474,30 +1479,29 @@ HTMLEditRules::WillInsertText(EditAction
 
         nsDependentSubstring subStr(tString, oldPos, subStrLen);
         NS_ENSURE_STATE(mHTMLEditor);
         WSRunObject wsObj(mHTMLEditor, currentPoint);
 
         // is it a tab?
         if (subStr.Equals(tabStr)) {
           EditorRawDOMPoint pointAfterInsertedSpaces;
-          rv = wsObj.InsertText(*doc, spacesStr, currentPoint.AsRaw(),
+          rv = wsObj.InsertText(*doc, spacesStr, currentPoint,
                                 &pointAfterInsertedSpaces);
           if (NS_WARN_IF(NS_FAILED(rv))) {
             return rv;
           }
           pos++;
           currentPoint = pointAfterInsertedSpaces;
           pointToInsert = pointAfterInsertedSpaces;
         }
         // is it a return?
         else if (subStr.Equals(newlineStr)) {
           RefPtr<Element> newBRElement =
-            wsObj.InsertBreak(*aSelection, currentPoint.AsRaw(),
-                              nsIEditor::eNone);
+            wsObj.InsertBreak(*aSelection, currentPoint, nsIEditor::eNone);
           if (NS_WARN_IF(!newBRElement)) {
             return NS_ERROR_FAILURE;
           }
           pos++;
           if (newBRElement->GetNextSibling()) {
             pointToInsert.Set(newBRElement->GetNextSibling());
           } else {
             pointToInsert.SetToEndOf(currentPoint.GetContainer());
@@ -1509,17 +1513,17 @@ HTMLEditRules::WillInsertText(EditAction
           // XXX If the newBRElement has been moved or removed by mutation
           //     observer, we hit this assert.  We need to check if
           //     newBRElement is in expected point, though, we must have
           //     a lot of same bugs...
           NS_WARNING_ASSERTION(currentPoint == pointToInsert,
             "Perhaps, newBRElement has been moved or removed unexpectedly");
         } else {
           EditorRawDOMPoint pointAfterInsertedString;
-          rv = wsObj.InsertText(*doc, subStr, currentPoint.AsRaw(),
+          rv = wsObj.InsertText(*doc, subStr, currentPoint,
                                 &pointAfterInsertedString);
           if (NS_WARN_IF(NS_FAILED(rv))) {
             return rv;
           }
           currentPoint = pointAfterInsertedString;
           pointToInsert = pointAfterInsertedString;
         }
       }
@@ -1527,39 +1531,38 @@ HTMLEditRules::WillInsertText(EditAction
 
     // After this block, pointToInsert is updated by AutoTrackDOMPoint.
   }
 
   aSelection->SetInterlinePosition(false);
 
   if (currentPoint.IsSet()) {
     ErrorResult error;
-    aSelection->Collapse(currentPoint.AsRaw(), error);
+    aSelection->Collapse(currentPoint, error);
     if (error.Failed()) {
       NS_WARNING("Failed to collapse at current point");
       error.SuppressException();
     }
   }
 
   // manually update the doc changed range so that AfterEdit will clean up
   // the correct portion of the document.
   if (!mDocChangeRange) {
     mDocChangeRange = new nsRange(pointToInsert.GetContainer());
   }
 
   if (currentPoint.IsSet()) {
-    rv = mDocChangeRange->SetStartAndEnd(pointToInsert.AsRaw(),
-                                         currentPoint.AsRaw());
+    rv = mDocChangeRange->SetStartAndEnd(pointToInsert, currentPoint);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
     return NS_OK;
   }
 
-  rv = mDocChangeRange->CollapseTo(pointToInsert.AsRaw());
+  rv = mDocChangeRange->CollapseTo(pointToInsert);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   return NS_OK;
 }
 
 nsresult
 HTMLEditRules::WillLoadHTML(Selection* aSelection,
@@ -1851,17 +1854,17 @@ HTMLEditRules::InsertBRElement(Selection
   RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
 
   bool brElementIsAfterBlock = false;
   bool brElementIsBeforeBlock = false;
 
   // First, insert a <br> element.
   RefPtr<Element> brElement;
   if (IsPlaintextEditor()) {
-    brElement = htmlEditor->CreateBR(aPointToBreak.AsRaw());
+    brElement = htmlEditor->CreateBR(aPointToBreak);
     if (NS_WARN_IF(!brElement)) {
       return NS_ERROR_FAILURE;
     }
   } else {
     EditorDOMPoint pointToBreak(aPointToBreak);
     WSRunObject wsObj(htmlEditor, pointToBreak);
     int32_t visOffset = 0;
     WSType wsType;
@@ -1881,25 +1884,24 @@ HTMLEditRules::InsertBRElement(Selection
     nsCOMPtr<nsINode> linkDOMNode;
     if (htmlEditor->IsInLink(pointToBreak.GetContainer(),
                              address_of(linkDOMNode))) {
       nsCOMPtr<Element> linkNode = do_QueryInterface(linkDOMNode);
       if (NS_WARN_IF(!linkNode)) {
         return NS_ERROR_FAILURE;
       }
       SplitNodeResult splitLinkNodeResult =
-        htmlEditor->SplitNodeDeep(*linkNode, pointToBreak.AsRaw(),
+        htmlEditor->SplitNodeDeep(*linkNode, pointToBreak,
                                   SplitAtEdges::eDoNotCreateEmptyContainer);
       if (NS_WARN_IF(splitLinkNodeResult.Failed())) {
         return splitLinkNodeResult.Rv();
       }
       pointToBreak = splitLinkNodeResult.SplitPoint();
     }
-    brElement =
-      wsObj.InsertBreak(aSelection, pointToBreak.AsRaw(), nsIEditor::eNone);
+    brElement = wsObj.InsertBreak(aSelection, pointToBreak, nsIEditor::eNone);
     if (NS_WARN_IF(!brElement)) {
       return NS_ERROR_FAILURE;
     }
   }
 
   // If the <br> element has already been removed from the DOM tree by a
   // mutation observer, don't continue handling this.
   if (NS_WARN_IF(!brElement->GetParentNode())) {
@@ -1958,17 +1960,17 @@ HTMLEditRules::InsertBRElement(Selection
   // but the next content will be on the following line.
 
   // An exception to this is if the break has a next sibling that is a block
   // node.  Then we stick to the left to avoid an uber caret.
   nsIContent* nextSiblingOfBRElement = brElement->GetNextSibling();
   aSelection.SetInterlinePosition(!(nextSiblingOfBRElement &&
                                     IsBlockNode(*nextSiblingOfBRElement)));
   ErrorResult error;
-  aSelection.Collapse(afterBRElement.AsRaw(), error);
+  aSelection.Collapse(afterBRElement, error);
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
   return NS_OK;
 }
 
 nsresult
 HTMLEditRules::DidInsertBreak(Selection* aSelection,
@@ -2469,18 +2471,21 @@ HTMLEditRules::WillDeleteSelection(Selec
       // Are they both text nodes?  If so, join them!
       if (startNode == stepbrother && startNode->GetAsText() &&
           sibling->GetAsText()) {
         EditorDOMPoint pt = JoinNodesSmart(*sibling, *startNode->AsContent());
         if (NS_WARN_IF(!pt.IsSet())) {
           return NS_ERROR_FAILURE;
         }
         // Fix up selection
-        rv = aSelection->Collapse(pt.AsRaw());
-        NS_ENSURE_SUCCESS(rv, rv);
+        ErrorResult error;
+        aSelection->Collapse(pt, error);
+        if (NS_WARN_IF(error.Failed())) {
+          return error.StealNSResult();
+        }
       }
       rv = InsertBRIfNeeded(aSelection);
       NS_ENSURE_SUCCESS(rv, rv);
       return NS_OK;
     }
 
     if (wsType == WSType::otherBlock) {
       // Make sure it's not a table element.  If so, cancel the operation
@@ -2542,17 +2547,17 @@ HTMLEditRules::WillDeleteSelection(Selec
 
       if (bDeletedBR) {
         // Put selection at edge of block and we are done.
         NS_ENSURE_STATE(leafNode);
         EditorDOMPoint newSel = GetGoodSelPointForNode(*leafNode, aAction);
         if (NS_WARN_IF(!newSel.IsSet())) {
           return NS_ERROR_FAILURE;
         }
-        aSelection->Collapse(newSel.AsRaw());
+        aSelection->Collapse(newSel);
         return NS_OK;
       }
 
       // Else we are joining content to block
 
       nsCOMPtr<nsINode> selPointNode = startNode;
       int32_t selPointOffset = startOffset;
       {
@@ -2734,18 +2739,21 @@ HTMLEditRules::WillDeleteSelection(Selec
           // Join blocks
           NS_ENSURE_STATE(mHTMLEditor);
           EditorDOMPoint pt =
             mHTMLEditor->JoinNodeDeep(*leftParent, *rightParent);
           if (NS_WARN_IF(!pt.IsSet())) {
             return NS_ERROR_FAILURE;
           }
           // Fix up selection
-          rv = aSelection->Collapse(pt.AsRaw());
-          NS_ENSURE_SUCCESS(rv, rv);
+          ErrorResult error;
+          aSelection->Collapse(pt, error);
+          if (NS_WARN_IF(error.Failed())) {
+            return error.StealNSResult();
+          }
           return NS_OK;
         }
 
         // Else blocks not same type, or not siblings.  Delete everything
         // except table elements.
         join = true;
 
         AutoRangeArray arrayOfRanges(aSelection);
@@ -3469,17 +3477,17 @@ HTMLEditRules::DidDeleteSelection(Select
       {
         AutoEditorDOMPointChildInvalidator lockOffset(atCiteNode);
         nsresult rv = htmlEditor->DeleteNode(citeNode);
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return rv;
         }
       }
       if (atCiteNode.IsSet() && seenBR) {
-        RefPtr<Element> brNode = htmlEditor->CreateBR(atCiteNode.AsRaw());
+        RefPtr<Element> brNode = htmlEditor->CreateBR(atCiteNode);
         if (NS_WARN_IF(!brNode)) {
           return NS_ERROR_FAILURE;
         }
         IgnoredErrorResult error;
         aSelection->Collapse(EditorRawDOMPoint(brNode), error);
         NS_WARNING_ASSERTION(!error.Failed(),
           "Failed to collapse selection at the new <br> element");
       }
@@ -3579,17 +3587,17 @@ HTMLEditRules::WillMakeList(Selection* a
     // Make sure we can put a list here.
     if (!htmlEditor->CanContainTag(*atStartOfSelection.GetContainer(),
                                    listType)) {
       *aCancel = true;
       return NS_OK;
     }
 
     SplitNodeResult splitAtSelectionStartResult =
-      MaybeSplitAncestorsForInsert(listType, atStartOfSelection.AsRaw());
+      MaybeSplitAncestorsForInsert(listType, atStartOfSelection);
     if (NS_WARN_IF(splitAtSelectionStartResult.Failed())) {
       return splitAtSelectionStartResult.Rv();
     }
     RefPtr<Element> theList =
       htmlEditor->CreateNode(listType,
                              splitAtSelectionStartResult.SplitPoint());
     NS_ENSURE_STATE(theList);
 
@@ -3936,25 +3944,25 @@ HTMLEditRules::MakeBasicBlock(Selection&
       if (!HTMLEditUtils::IsFormatNode(curBlock)) {
         return NS_OK;
       }
 
       // If the first editable node after selection is a br, consume it.
       // Otherwise it gets pushed into a following block after the split,
       // which is visually bad.
       nsCOMPtr<nsIContent> brNode =
-        htmlEditor->GetNextEditableHTMLNode(pointToInsertBlock.AsRaw());
+        htmlEditor->GetNextEditableHTMLNode(pointToInsertBlock);
       if (brNode && brNode->IsHTMLElement(nsGkAtoms::br)) {
         AutoEditorDOMPointChildInvalidator lockOffset(pointToInsertBlock);
         rv = htmlEditor->DeleteNode(brNode);
         NS_ENSURE_SUCCESS(rv, rv);
       }
       // Do the splits!
       SplitNodeResult splitNodeResult =
-        htmlEditor->SplitNodeDeep(*curBlock, pointToInsertBlock.AsRaw(),
+        htmlEditor->SplitNodeDeep(*curBlock, pointToInsertBlock,
                                   SplitAtEdges::eDoNotCreateEmptyContainer);
       if (NS_WARN_IF(splitNodeResult.Failed())) {
         return splitNodeResult.Rv();
       }
       EditorRawDOMPoint pointToInsertBrNode(splitNodeResult.SplitPoint());
       // Put a br at the split point
       brNode = htmlEditor->CreateBR(pointToInsertBrNode);
       NS_ENSURE_STATE(brNode);
@@ -3967,27 +3975,27 @@ HTMLEditRules::MakeBasicBlock(Selection&
       if (NS_WARN_IF(error.Failed())) {
         return error.StealNSResult();
       }
       return NS_OK;
     }
 
     // We are making a block.  Consume a br, if needed.
     nsCOMPtr<nsIContent> brNode =
-      htmlEditor->GetNextEditableHTMLNodeInBlock(pointToInsertBlock.AsRaw());
+      htmlEditor->GetNextEditableHTMLNodeInBlock(pointToInsertBlock);
     if (brNode && brNode->IsHTMLElement(nsGkAtoms::br)) {
       AutoEditorDOMPointChildInvalidator lockOffset(pointToInsertBlock);
       rv = htmlEditor->DeleteNode(brNode);
       NS_ENSURE_SUCCESS(rv, rv);
       // We don't need to act on this node any more
       arrayOfNodes.RemoveElement(brNode);
     }
     // Make sure we can put a block here.
     SplitNodeResult splitNodeResult =
-      MaybeSplitAncestorsForInsert(blockType, pointToInsertBlock.AsRaw());
+      MaybeSplitAncestorsForInsert(blockType, pointToInsertBlock);
     if (NS_WARN_IF(splitNodeResult.Failed())) {
       return splitNodeResult.Rv();
     }
     RefPtr<Element> block =
       htmlEditor->CreateNode(&blockType, splitNodeResult.SplitPoint());
     NS_ENSURE_STATE(block);
     // Remember our new block for postprocessing
     mNewBlock = block;
@@ -4126,17 +4134,17 @@ HTMLEditRules::WillCSSIndent(Selection* 
 
     EditorDOMPoint atStartOfSelection(firstRange->StartRef());
     if (NS_WARN_IF(!atStartOfSelection.IsSet())) {
       return NS_ERROR_FAILURE;
     }
 
     // make sure we can put a block here
     SplitNodeResult splitNodeResult =
-      MaybeSplitAncestorsForInsert(*nsGkAtoms::div, atStartOfSelection.AsRaw());
+      MaybeSplitAncestorsForInsert(*nsGkAtoms::div, atStartOfSelection);
     if (NS_WARN_IF(splitNodeResult.Failed())) {
       return splitNodeResult.Rv();
     }
     RefPtr<Element> theBlock =
       htmlEditor->CreateNode(nsGkAtoms::div, splitNodeResult.SplitPoint());
     NS_ENSURE_STATE(theBlock);
     // remember our new block for postprocessing
     mNewBlock = theBlock;
@@ -4214,17 +4222,17 @@ HTMLEditRules::WillCSSIndent(Selection* 
         sibling = htmlEditor->GetPriorHTMLSibling(curNode);
       }
 
       if (!curList || (sibling && sibling != curList)) {
         nsAtom* containerName =
           atCurNode.GetContainer()->NodeInfo()->NameAtom();
         // Create a new nested list of correct type.
         SplitNodeResult splitNodeResult =
-          MaybeSplitAncestorsForInsert(*containerName, atCurNode.AsRaw());
+          MaybeSplitAncestorsForInsert(*containerName, atCurNode);
         if (NS_WARN_IF(splitNodeResult.Failed())) {
           return splitNodeResult.Rv();
         }
         curList = htmlEditor->CreateNode(containerName,
                                          splitNodeResult.SplitPoint());
         NS_ENSURE_STATE(curList);
         // curList is now the correct thing to put curNode in
         // remember our new block for postprocessing
@@ -4249,17 +4257,17 @@ HTMLEditRules::WillCSSIndent(Selection* 
     if (!curQuote) {
       // First, check that our element can contain a div.
       if (!htmlEditor->CanContainTag(*atCurNode.GetContainer(),
                                      *nsGkAtoms::div)) {
         return NS_OK; // cancelled
       }
 
       SplitNodeResult splitNodeResult =
-        MaybeSplitAncestorsForInsert(*nsGkAtoms::div, atCurNode.AsRaw());
+        MaybeSplitAncestorsForInsert(*nsGkAtoms::div, atCurNode);
       if (NS_WARN_IF(splitNodeResult.Failed())) {
         return splitNodeResult.Rv();
       }
       curQuote =
         htmlEditor->CreateNode(nsGkAtoms::div, splitNodeResult.SplitPoint());
       NS_ENSURE_STATE(curQuote);
       ChangeIndentation(*curQuote, Change::plus);
       // remember our new block for postprocessing
@@ -4324,17 +4332,17 @@ HTMLEditRules::WillHTMLIndent(Selection*
     EditorDOMPoint atStartOfSelection(firstRange->StartRef());
     if (NS_WARN_IF(!atStartOfSelection.IsSet())) {
       return NS_ERROR_FAILURE;
     }
 
     // Make sure we can put a block here.
     SplitNodeResult splitNodeResult =
       MaybeSplitAncestorsForInsert(*nsGkAtoms::blockquote,
-                              atStartOfSelection.AsRaw());
+                                   atStartOfSelection);
     if (NS_WARN_IF(splitNodeResult.Failed())) {
       return splitNodeResult.Rv();
     }
     RefPtr<Element> theBlock =
       htmlEditor->CreateNode(nsGkAtoms::blockquote,
                              splitNodeResult.SplitPoint());
     NS_ENSURE_STATE(theBlock);
     // remember our new block for postprocessing
@@ -4412,17 +4420,17 @@ HTMLEditRules::WillHTMLIndent(Selection*
         sibling = htmlEditor->GetPriorHTMLSibling(curNode);
       }
 
       if (!curList || (sibling && sibling != curList)) {
         nsAtom* containerName =
           atCurNode.GetContainer()->NodeInfo()->NameAtom();
         // Create a new nested list of correct type.
         SplitNodeResult splitNodeResult =
-          MaybeSplitAncestorsForInsert(*containerName, atCurNode.AsRaw());
+          MaybeSplitAncestorsForInsert(*containerName, atCurNode);
         if (NS_WARN_IF(splitNodeResult.Failed())) {
           return splitNodeResult.Rv();
         }
         curList =
           htmlEditor->CreateNode(containerName, splitNodeResult.SplitPoint());
         NS_ENSURE_STATE(curList);
         // curList is now the correct thing to put curNode in
         // remember our new block for postprocessing
@@ -4461,17 +4469,17 @@ HTMLEditRules::WillHTMLIndent(Selection*
         EditorDOMPoint atListItem(listItem);
         if (NS_WARN_IF(!listItem)) {
           return NS_ERROR_FAILURE;
         }
         nsAtom* containerName =
           atListItem.GetContainer()->NodeInfo()->NameAtom();
         // Create a new nested list of correct type.
         SplitNodeResult splitNodeResult =
-          MaybeSplitAncestorsForInsert(*containerName, atListItem.AsRaw());
+          MaybeSplitAncestorsForInsert(*containerName, atListItem);
         if (NS_WARN_IF(splitNodeResult.Failed())) {
           return splitNodeResult.Rv();
         }
         curList = htmlEditor->CreateNode(containerName,
                                          splitNodeResult.SplitPoint());
         NS_ENSURE_STATE(curList);
       }
 
@@ -4495,17 +4503,17 @@ HTMLEditRules::WillHTMLIndent(Selection*
     if (!curQuote) {
       // First, check that our element can contain a blockquote.
       if (!htmlEditor->CanContainTag(*atCurNode.GetContainer(),
                                      *nsGkAtoms::blockquote)) {
         return NS_OK; // cancelled
       }
 
       SplitNodeResult splitNodeResult =
-        MaybeSplitAncestorsForInsert(*nsGkAtoms::blockquote, atCurNode.AsRaw());
+        MaybeSplitAncestorsForInsert(*nsGkAtoms::blockquote, atCurNode);
       if (NS_WARN_IF(splitNodeResult.Failed())) {
         return splitNodeResult.Rv();
       }
       curQuote =
         htmlEditor->CreateNode(nsGkAtoms::blockquote,
                                splitNodeResult.SplitPoint());
       NS_ENSURE_STATE(curQuote);
       // remember our new block for postprocessing
@@ -5099,17 +5107,17 @@ HTMLEditRules::WillAlign(Selection& aSel
     }
 
     EditorDOMPoint atStartOfSelection(firstRange->StartRef());
     if (NS_WARN_IF(!atStartOfSelection.IsSet())) {
       return NS_ERROR_FAILURE;
     }
 
     SplitNodeResult splitNodeResult =
-      MaybeSplitAncestorsForInsert(*nsGkAtoms::div, atStartOfSelection.AsRaw());
+      MaybeSplitAncestorsForInsert(*nsGkAtoms::div, atStartOfSelection);
     if (NS_WARN_IF(splitNodeResult.Failed())) {
       return splitNodeResult.Rv();
     }
 
     // Consume a trailing br, if any.  This is to keep an alignment from
     // creating extra lines, if possible.
     nsCOMPtr<nsIContent> brContent =
       htmlEditor->GetNextEditableHTMLNodeInBlock(splitNodeResult.SplitPoint());
@@ -5124,17 +5132,17 @@ HTMLEditRules::WillAlign(Selection& aSel
       }
       if (sibling && !IsBlockNode(*sibling)) {
         AutoEditorDOMPointChildInvalidator lockOffset(pointToInsertDiv);
         rv = htmlEditor->DeleteNode(brContent);
         NS_ENSURE_SUCCESS(rv, rv);
       }
     }
     RefPtr<Element> div =
-      htmlEditor->CreateNode(nsGkAtoms::div, pointToInsertDiv.AsRaw());
+      htmlEditor->CreateNode(nsGkAtoms::div, pointToInsertDiv);
     NS_ENSURE_STATE(div);
     // Remember our new block for postprocessing
     mNewBlock = div;
     // Set up the alignment on the div, using HTML or CSS
     rv = AlignBlock(*div, aAlignType, ContentsOnly::yes);
     NS_ENSURE_SUCCESS(rv, rv);
     *aHandled = true;
     // Put in a moz-br so that it won't get deleted
@@ -5233,17 +5241,17 @@ HTMLEditRules::WillAlign(Selection& aSel
       // First, check that our element can contain a div.
       if (!htmlEditor->CanContainTag(*atCurNode.GetContainer(),
                                      *nsGkAtoms::div)) {
         // Cancelled
         return NS_OK;
       }
 
       SplitNodeResult splitNodeResult =
-        MaybeSplitAncestorsForInsert(*nsGkAtoms::div, atCurNode.AsRaw());
+        MaybeSplitAncestorsForInsert(*nsGkAtoms::div, atCurNode);
       if (NS_WARN_IF(splitNodeResult.Failed())) {
         return splitNodeResult.Rv();
       }
       curDiv =
         htmlEditor->CreateNode(nsGkAtoms::div, splitNodeResult.SplitPoint());
       NS_ENSURE_STATE(curDiv);
       // Remember our new block for postprocessing
       mNewBlock = curDiv;
@@ -5391,17 +5399,17 @@ HTMLEditRules::CheckForEmptyBlock(nsINod
       if (htmlEditor->IsFirstEditableChild(emptyBlock)) {
         EditorDOMPoint atBlockParent(blockParent);
         if (NS_WARN_IF(!atBlockParent.IsSet())) {
           return NS_ERROR_FAILURE;
         }
         // If we are a sublist, skip the br creation
         if (!HTMLEditUtils::IsList(atBlockParent.GetContainer())) {
           // Create a br before list
-          RefPtr<Element> br = htmlEditor->CreateBR(atBlockParent.AsRaw());
+          RefPtr<Element> br = htmlEditor->CreateBR(atBlockParent);
           if (NS_WARN_IF(!br)) {
             return NS_ERROR_FAILURE;
           }
           // Adjust selection to be right before it
           ErrorResult error;
           aSelection->Collapse(EditorRawDOMPoint(br), error);
           if (NS_WARN_IF(error.Failed())) {
             return error.StealNSResult();
@@ -5417,37 +5425,43 @@ HTMLEditRules::CheckForEmptyBlock(nsINod
         EditorRawDOMPoint afterEmptyBlock(emptyBlock);
         DebugOnly<bool> advanced = afterEmptyBlock.AdvanceOffset();
         NS_WARNING_ASSERTION(advanced,
           "Failed to set selection to the after the empty block");
         nsCOMPtr<nsIContent> nextNode =
           htmlEditor->GetNextNode(afterEmptyBlock);
         if (nextNode) {
           EditorDOMPoint pt = GetGoodSelPointForNode(*nextNode, aAction);
-          nsresult rv = aSelection->Collapse(pt.AsRaw());
-          NS_ENSURE_SUCCESS(rv, rv);
+          ErrorResult error;
+          aSelection->Collapse(pt, error);
+          if (NS_WARN_IF(error.Failed())) {
+            return error.StealNSResult();
+          }
         } else {
           // Adjust selection to be right after it.
           EditorRawDOMPoint afterEmptyBlock(emptyBlock);
           if (NS_WARN_IF(!afterEmptyBlock.AdvanceOffset())) {
             return NS_ERROR_FAILURE;
           }
-          nsresult rv = aSelection->Collapse(afterEmptyBlock);
-          NS_ENSURE_SUCCESS(rv, rv);
+          ErrorResult error;
+          aSelection->Collapse(afterEmptyBlock, error);
+          if (NS_WARN_IF(error.Failed())) {
+            return error.StealNSResult();
+          }
         }
       } else if (aAction == nsIEditor::ePrevious ||
                  aAction == nsIEditor::ePreviousWord ||
                  aAction == nsIEditor::eToBeginningOfLine) {
         // Move to the end of the previous node
         EditorRawDOMPoint atEmptyBlock(emptyBlock);
         nsCOMPtr<nsIContent> priorNode =
           htmlEditor->GetPreviousEditableNode(atEmptyBlock);
         if (priorNode) {
           EditorDOMPoint pt = GetGoodSelPointForNode(*priorNode, aAction);
-          nsresult rv = aSelection->Collapse(pt.AsRaw());
+          nsresult rv = aSelection->Collapse(pt);
           NS_ENSURE_SUCCESS(rv, rv);
         } else {
           EditorRawDOMPoint afterEmptyBlock(emptyBlock);
           if (NS_WARN_IF(!afterEmptyBlock.AdvanceOffset())) {
             return NS_ERROR_FAILURE;
           }
           nsresult rv = aSelection->Collapse(afterEmptyBlock);
           NS_ENSURE_SUCCESS(rv, rv);
@@ -5894,30 +5908,30 @@ HTMLEditRules::GetPromotedPoint(RulesEnd
         return point;
       }
       point.Set(point.GetContainer());
     }
 
     // look back through any further inline nodes that aren't across a <br>
     // from us, and that are enclosed in the same block.
     nsCOMPtr<nsINode> priorNode =
-      htmlEditor->GetPreviousEditableHTMLNodeInBlock(point.AsRaw());
+      htmlEditor->GetPreviousEditableHTMLNodeInBlock(point);
 
     while (priorNode && priorNode->GetParentNode() &&
            !htmlEditor->IsVisibleBRElement(priorNode) &&
            !IsBlockNode(*priorNode)) {
       point.Set(priorNode);
-      priorNode = htmlEditor->GetPreviousEditableHTMLNodeInBlock(point.AsRaw());
+      priorNode = htmlEditor->GetPreviousEditableHTMLNodeInBlock(point);
     }
 
     // finding the real start for this point.  look up the tree for as long as
     // we are the first node in the container, and as long as we haven't hit
     // the body node.
     nsCOMPtr<nsIContent> nearNode =
-      htmlEditor->GetPreviousEditableHTMLNodeInBlock(point.AsRaw());
+      htmlEditor->GetPreviousEditableHTMLNodeInBlock(point);
     while (!nearNode &&
            !point.IsContainerHTMLElement(nsGkAtoms::body) &&
            point.GetContainer()->GetParentNode()) {
       // some cutoffs are here: we don't need to also include them in the
       // aWhere == kEnd case.  as long as they are in one or the other it will
       // work.  special case for outdent: don't keep looking up if we have
       // found a blockquote element to act on
       if (actionID == EditAction::outdent &&
@@ -5936,17 +5950,17 @@ HTMLEditRules::GetPromotedPoint(RulesEnd
       if (!htmlEditor->IsDescendantOfEditorRoot(
                          point.GetContainer()->GetParentNode()) &&
           (blockLevelAction ||
            !htmlEditor->IsDescendantOfEditorRoot(point.GetContainer()))) {
         break;
       }
 
       point.Set(point.GetContainer());
-      nearNode = htmlEditor->GetPreviousEditableHTMLNodeInBlock(point.AsRaw());
+      nearNode = htmlEditor->GetPreviousEditableHTMLNodeInBlock(point);
     }
     return point;
   }
 
   // aWhere == kEnd
   // some special casing for text nodes
   if (point.IsInTextNode()) {
     if (!point.GetContainer()->GetParentNode()) {
@@ -5970,17 +5984,17 @@ HTMLEditRules::GetPromotedPoint(RulesEnd
   //     inline elements even if it's non-editable.  For example, following
   //     examples with insertParagraph causes different result:
   //     * <div contenteditable>foo[]<b contenteditable="false">bar</b></div>
   //     * <div contenteditable>foo[]<b>bar</b></div>
   //     * <div contenteditable>foo[]<b contenteditable="false">bar</b>baz</div>
   //     Only in the first case, after the caret position isn't wrapped with
   //     new <div> element.
   nsCOMPtr<nsIContent> nextNode =
-    htmlEditor->GetNextEditableHTMLNodeInBlock(point.AsRaw());
+    htmlEditor->GetNextEditableHTMLNodeInBlock(point);
 
   while (nextNode && !IsBlockNode(*nextNode) && nextNode->GetParentNode()) {
     point.Set(nextNode);
     if (NS_WARN_IF(!point.AdvanceOffset())) {
       break;
     }
     if (htmlEditor->IsVisibleBRElement(nextNode)) {
       break;
@@ -5998,41 +6012,41 @@ HTMLEditRules::GetPromotedPoint(RulesEnd
           if (static_cast<uint32_t>(newlinePos) + 1 == tempString.Length()) {
             // No need for special processing if the newline is at the end.
             break;
           }
           return EditorDOMPoint(nextNode, newlinePos + 1);
         }
       }
     }
-    nextNode = htmlEditor->GetNextEditableHTMLNodeInBlock(point.AsRaw());
+    nextNode = htmlEditor->GetNextEditableHTMLNodeInBlock(point);
   }
 
   // finding the real end for this point.  look up the tree for as long as we
   // are the last node in the container, and as long as we haven't hit the body
   // node.
   nsCOMPtr<nsIContent> nearNode =
-    htmlEditor->GetNextEditableHTMLNodeInBlock(point.AsRaw());
+    htmlEditor->GetNextEditableHTMLNodeInBlock(point);
   while (!nearNode &&
          !point.IsContainerHTMLElement(nsGkAtoms::body) &&
          point.GetContainer()->GetParentNode()) {
     // Don't walk past the editable section. Note that we need to check before
     // walking up to a parent because we need to return the parent object, so
     // the parent itself might not be in the editable area, but it's OK.
     if (!htmlEditor->IsDescendantOfEditorRoot(point.GetContainer()) &&
         !htmlEditor->IsDescendantOfEditorRoot(
                        point.GetContainer()->GetParentNode())) {
       break;
     }
 
     point.Set(point.GetContainer());
     if (NS_WARN_IF(!point.AdvanceOffset())) {
       break;
     }
-    nearNode = htmlEditor->GetNextEditableHTMLNodeInBlock(point.AsRaw());
+    nearNode = htmlEditor->GetNextEditableHTMLNodeInBlock(point);
   }
   return point;
 }
 
 /**
  * GetPromotedRanges() runs all the selection range endpoint through
  * GetPromotedPoint().
  */
@@ -6121,30 +6135,29 @@ HTMLEditRules::PromoteRange(nsRange& aRa
 
   // Make sure that the new range ends up to be in the editable section.
   // XXX Looks like that this check wastes the time.  Perhaps, we should
   //     implement a method which checks both two DOM points in the editor
   //     root.
   EditorDOMPoint startPoint =
     GetPromotedPoint(kStart, *startNode, startOffset, aOperationType);
   if (!htmlEditor->IsDescendantOfEditorRoot(
-         EditorBase::GetNodeAtRangeOffsetPoint(startPoint.AsRaw()))) {
+         EditorBase::GetNodeAtRangeOffsetPoint(startPoint))) {
     return;
   }
   EditorDOMPoint endPoint =
     GetPromotedPoint(kEnd, *endNode, endOffset, aOperationType);
-  EditorRawDOMPoint lastRawPoint(endPoint.AsRaw());
+  EditorRawDOMPoint lastRawPoint(endPoint);
   lastRawPoint.RewindOffset();
   if (!htmlEditor->IsDescendantOfEditorRoot(
          EditorBase::GetNodeAtRangeOffsetPoint(lastRawPoint))) {
     return;
   }
 
-  DebugOnly<nsresult> rv =
-    aRange.SetStartAndEnd(startPoint.AsRaw(), endPoint.AsRaw());
+  DebugOnly<nsresult> rv = aRange.SetStartAndEnd(startPoint, endPoint);
   MOZ_ASSERT(NS_SUCCEEDED(rv));
 }
 
 class UniqueFunctor final : public BoolDomIterFunctor
 {
 public:
   explicit UniqueFunctor(nsTArray<OwningNonNull<nsINode>>& aArray)
     : mArray(aArray)
@@ -6184,17 +6197,17 @@ HTMLEditRules::GetNodesForOperation(
       if (NS_WARN_IF(!atEnd.IsSet()) || !atEnd.IsInTextNode()) {
         continue;
       }
 
       if (!atEnd.IsStartOfContainer() && !atEnd.IsEndOfContainer()) {
         // Split the text node.
         ErrorResult error;
         nsCOMPtr<nsIContent> newLeftNode =
-          htmlEditor->SplitNode(atEnd.AsRaw(), error);
+          htmlEditor->SplitNode(atEnd, error);
         if (NS_WARN_IF(error.Failed())) {
           return error.StealNSResult();
         }
 
         // Correct the range.
         // The new end parent becomes the parent node of the text.
         // XXX We want nsRange::SetEnd(const RawRangeBoundary&)
         EditorRawDOMPoint atContainerOfSplitNode(atEnd.GetContainer());
@@ -7029,17 +7042,17 @@ HTMLEditRules::ReturnInParagraph(Selecti
         NS_WARNING_ASSERTION(advanced,
           "Failed to advance offset to after the container of selection start");
         brNode = nullptr;
       }
     } else {
       if (doesCRCreateNewP) {
         ErrorResult error;
         nsCOMPtr<nsIContent> newLeftDivOrP =
-          htmlEditor->SplitNode(pointToSplitParentDivOrP.AsRaw(), error);
+          htmlEditor->SplitNode(pointToSplitParentDivOrP, error);
         if (NS_WARN_IF(error.Failed())) {
           return EditActionResult(error.StealNSResult());
         }
         pointToSplitParentDivOrP.SetToEndOf(newLeftDivOrP);
       }
 
       // We need to put new <br> after the left node if given node was split
       // above.
@@ -7048,22 +7061,22 @@ HTMLEditRules::ReturnInParagraph(Selecti
       NS_WARNING_ASSERTION(advanced,
         "Failed to advance offset to after the container of selection start");
     }
   } else {
     // not in a text node.
     // is there a BR prior to it?
     nsCOMPtr<nsIContent> nearNode;
     nearNode =
-      htmlEditor->GetPreviousEditableHTMLNode(atStartOfSelection.AsRaw());
+      htmlEditor->GetPreviousEditableHTMLNode(atStartOfSelection);
     if (!nearNode || !htmlEditor->IsVisibleBRElement(nearNode) ||
         TextEditUtils::HasMozAttr(GetAsDOMNode(nearNode))) {
       // is there a BR after it?
       nearNode =
-        htmlEditor->GetNextEditableHTMLNode(atStartOfSelection.AsRaw());
+        htmlEditor->GetNextEditableHTMLNode(atStartOfSelection);
       if (!nearNode || !htmlEditor->IsVisibleBRElement(nearNode) ||
           TextEditUtils::HasMozAttr(GetAsDOMNode(nearNode))) {
         pointToInsertBR = atStartOfSelection;
         splitAfterNewBR = true;
       }
     }
     if (!pointToInsertBR.IsSet() && TextEditUtils::IsBreak(nearNode)) {
       brNode = nearNode;
@@ -7085,30 +7098,32 @@ HTMLEditRules::ReturnInParagraph(Selecti
       // We split the parent after the br we've just inserted.
       pointToSplitParentDivOrP.Set(brNode);
       DebugOnly<bool> advanced = pointToSplitParentDivOrP.AdvanceOffset();
       NS_WARNING_ASSERTION(advanced,
         "Failed to advance offset after the new <br>");
     }
   }
   EditActionResult result(
-    SplitParagraph(aSelection, aParentDivOrP, pointToSplitParentDivOrP.AsRaw(),
+    SplitParagraph(aSelection, aParentDivOrP, pointToSplitParentDivOrP,
                    brNode));
   result.MarkAsHandled();
   if (NS_WARN_IF(result.Failed())) {
     return result;
   }
   return result;
 }
 
+template<typename PT, typename CT>
 nsresult
-HTMLEditRules::SplitParagraph(Selection& aSelection,
-                              Element& aParentDivOrP,
-                              const EditorRawDOMPoint& aStartOfRightNode,
-                              nsIContent* aNextBRNode)
+HTMLEditRules::SplitParagraph(
+                 Selection& aSelection,
+                 Element& aParentDivOrP,
+                 const EditorDOMPointBase<PT, CT>& aStartOfRightNode,
+                 nsIContent* aNextBRNode)
 {
   if (NS_WARN_IF(!mHTMLEditor)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   RefPtr<HTMLEditor> htmlEditor = mHTMLEditor;
 
   // split para
@@ -7412,17 +7427,17 @@ HTMLEditRules::MakeBlockquote(nsTArray<O
     } else {
       prevParent = curNode->GetParentNode();
     }
 
     // If no curBlock, make one
     if (!curBlock) {
       EditorDOMPoint atCurNode(curNode);
       SplitNodeResult splitNodeResult =
-        MaybeSplitAncestorsForInsert(*nsGkAtoms::blockquote, atCurNode.AsRaw());
+        MaybeSplitAncestorsForInsert(*nsGkAtoms::blockquote, atCurNode);
       if (NS_WARN_IF(splitNodeResult.Failed())) {
         return splitNodeResult.Rv();
       }
       curBlock = htmlEditor->CreateNode(nsGkAtoms::blockquote,
                                         splitNodeResult.SplitPoint());
       NS_ENSURE_STATE(curBlock);
       // remember our new block for postprocessing
       mNewBlock = curBlock;
@@ -7589,17 +7604,17 @@ HTMLEditRules::ApplyBlockStyle(nsTArray<
       if (!childArray.IsEmpty()) {
         nsresult rv = ApplyBlockStyle(childArray, aBlockTag);
         NS_ENSURE_SUCCESS(rv, rv);
         continue;
       }
 
       // Make sure we can put a block here
       SplitNodeResult splitNodeResult =
-        MaybeSplitAncestorsForInsert(aBlockTag, atCurNode.AsRaw());
+        MaybeSplitAncestorsForInsert(aBlockTag, atCurNode);
       if (NS_WARN_IF(splitNodeResult.Failed())) {
         return splitNodeResult.Rv();
       }
       RefPtr<Element> theBlock =
         htmlEditor->CreateNode(&aBlockTag, splitNodeResult.SplitPoint());
       NS_ENSURE_STATE(theBlock);
       // Remember our new block for postprocessing
       mNewBlock = theBlock;
@@ -7615,17 +7630,17 @@ HTMLEditRules::ApplyBlockStyle(nsTArray<
         nsresult rv = htmlEditor->DeleteNode(curNode);
         NS_ENSURE_SUCCESS(rv, rv);
         continue;
       }
 
       // The break is the first (or even only) node we encountered.  Create a
       // block for it.
       SplitNodeResult splitNodeResult =
-        MaybeSplitAncestorsForInsert(aBlockTag, atCurNode.AsRaw());
+        MaybeSplitAncestorsForInsert(aBlockTag, atCurNode);
       if (NS_WARN_IF(splitNodeResult.Failed())) {
         return splitNodeResult.Rv();
       }
       curBlock =
         htmlEditor->CreateNode(&aBlockTag, splitNodeResult.SplitPoint());
       NS_ENSURE_STATE(curBlock);
       // Remember our new block for postprocessing
       mNewBlock = curBlock;
@@ -7648,17 +7663,17 @@ HTMLEditRules::ApplyBlockStyle(nsTArray<
         continue;
       }
 
       // If no curBlock, make one
       if (!curBlock) {
         AutoEditorDOMPointOffsetInvalidator lockChild(atCurNode);
 
         SplitNodeResult splitNodeResult =
-          MaybeSplitAncestorsForInsert(aBlockTag, atCurNode.AsRaw());
+          MaybeSplitAncestorsForInsert(aBlockTag, atCurNode);
         if (NS_WARN_IF(splitNodeResult.Failed())) {
           return splitNodeResult.Rv();
         }
         curBlock =
           htmlEditor->CreateNode(&aBlockTag, splitNodeResult.SplitPoint());
         NS_ENSURE_STATE(curBlock);
         // Remember our new block for postprocessing
         mNewBlock = curBlock;
@@ -7676,20 +7691,21 @@ HTMLEditRules::ApplyBlockStyle(nsTArray<
       // the same block item.  Use curBlock.
       nsresult rv = htmlEditor->MoveNode(curNode->AsContent(), curBlock, -1);
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
   return NS_OK;
 }
 
+template<typename PT, typename CT>
 SplitNodeResult
 HTMLEditRules::MaybeSplitAncestorsForInsert(
                  nsAtom& aTag,
-                 const EditorRawDOMPoint& aStartOfDeepestRightNode)
+                 const EditorDOMPointBase<PT, CT>& aStartOfDeepestRightNode)
 {
   if (NS_WARN_IF(!aStartOfDeepestRightNode.IsSet())) {
     return SplitNodeResult(NS_ERROR_INVALID_ARG);
   }
   MOZ_ASSERT(aStartOfDeepestRightNode.IsSetAndValid());
 
   if (NS_WARN_IF(!mHTMLEditor)) {
     return SplitNodeResult(NS_ERROR_NOT_AVAILABLE);
@@ -8126,17 +8142,17 @@ HTMLEditRules::CheckInterlinePosition(Se
     return;
   }
   MOZ_ASSERT(atStartOfSelection.IsSetAndValid());
 
   // First, let's check to see if we are after a <br>.  We take care of this
   // special-case first so that we don't accidentally fall through into one of
   // the other conditionals.
   nsCOMPtr<nsIContent> node =
-    htmlEditor->GetPreviousEditableHTMLNodeInBlock(atStartOfSelection.AsRaw());
+    htmlEditor->GetPreviousEditableHTMLNodeInBlock(atStartOfSelection);
   if (node && node->IsHTMLElement(nsGkAtoms::br)) {
     aSelection.SetInterlinePosition(true);
     return;
   }
 
   // Are we after a block?  If so try set caret to following content
   if (atStartOfSelection.GetChild()) {
     node = htmlEditor->GetPriorHTMLSibling(atStartOfSelection.GetChild());
@@ -8213,17 +8229,17 @@ HTMLEditRules::AdjustSelection(Selection
       if (point.GetContainer() == rootElement) {
         // Our root node is completely empty. Don't add a <br> here.
         // AfterEditInner() will add one for us when it calls
         // CreateBogusNodeIfNeeded()!
         return NS_OK;
       }
 
       // we know we can skip the rest of this routine given the cirumstance
-      RefPtr<Element> brElement = CreateMozBR(point.AsRaw());
+      RefPtr<Element> brElement = CreateMozBR(point);
       if (NS_WARN_IF(!brElement)) {
         return NS_ERROR_FAILURE;
       }
       return NS_OK;
     }
   }
 
   // are we in a text node?
@@ -8232,36 +8248,36 @@ HTMLEditRules::AdjustSelection(Selection
   }
 
   // do we need to insert a special mozBR?  We do if we are:
   // 1) prior node is in same block where selection is AND
   // 2) prior node is a br AND
   // 3) that br is not visible
 
   nsCOMPtr<nsIContent> nearNode =
-    htmlEditor->GetPreviousEditableHTMLNode(point.AsRaw());
+    htmlEditor->GetPreviousEditableHTMLNode(point);
   if (nearNode) {
     // is nearNode also a descendant of same block?
     RefPtr<Element> block = htmlEditor->GetBlock(*point.GetContainer());
     RefPtr<Element> nearBlock = htmlEditor->GetBlockNodeParent(nearNode);
     if (block && block == nearBlock) {
       if (nearNode && TextEditUtils::IsBreak(nearNode)) {
         if (!htmlEditor->IsVisibleBRElement(nearNode)) {
           // need to insert special moz BR. Why?  Because if we don't
           // the user will see no new line for the break.  Also, things
           // like table cells won't grow in height.
-          RefPtr<Element> brElement = CreateMozBR(point.AsRaw());
+          RefPtr<Element> brElement = CreateMozBR(point);
           if (NS_WARN_IF(!brElement)) {
             return NS_ERROR_FAILURE;
           }
           point.Set(brElement);
           // selection stays *before* moz-br, sticking to it
           aSelection->SetInterlinePosition(true);
           ErrorResult error;
-          aSelection->Collapse(point.AsRaw(), error);
+          aSelection->Collapse(point, error);
           if (NS_WARN_IF(error.Failed())) {
             return error.StealNSResult();
           }
         } else {
           nsCOMPtr<nsIContent> nextNode =
             htmlEditor->GetNextEditableHTMLNodeInBlock(*nearNode);
           if (nextNode && TextEditUtils::IsMozBR(nextNode)) {
             // selection between br and mozbr.  make it stick to mozbr
@@ -8269,50 +8285,51 @@ HTMLEditRules::AdjustSelection(Selection
             aSelection->SetInterlinePosition(true);
           }
         }
       }
     }
   }
 
   // we aren't in a textnode: are we adjacent to text or a break or an image?
-  nearNode = htmlEditor->GetPreviousEditableHTMLNodeInBlock(point.AsRaw());
+  nearNode = htmlEditor->GetPreviousEditableHTMLNodeInBlock(point);
   if (nearNode && (TextEditUtils::IsBreak(nearNode) ||
                    EditorBase::IsTextNode(nearNode) ||
                    HTMLEditUtils::IsImage(nearNode) ||
                    nearNode->IsHTMLElement(nsGkAtoms::hr))) {
     // this is a good place for the caret to be
     return NS_OK;
   }
-  nearNode = htmlEditor->GetNextEditableHTMLNodeInBlock(point.AsRaw());
+  nearNode = htmlEditor->GetNextEditableHTMLNodeInBlock(point);
   if (nearNode && (TextEditUtils::IsBreak(nearNode) ||
                    EditorBase::IsTextNode(nearNode) ||
                    nearNode->IsAnyOfHTMLElements(nsGkAtoms::img,
                                                  nsGkAtoms::hr))) {
     return NS_OK; // this is a good place for the caret to be
   }
 
   // look for a nearby text node.
   // prefer the correct direction.
-  nearNode = FindNearEditableNode(point.AsRaw(), aAction);
+  nearNode = FindNearEditableNode(point, aAction);
   if (!nearNode) {
     return NS_OK;
   }
 
   EditorDOMPoint pt = GetGoodSelPointForNode(*nearNode, aAction);
   ErrorResult error;
-  aSelection->Collapse(pt.AsRaw(), error);
+  aSelection->Collapse(pt, error);
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
   return NS_OK;
 }
 
+template<typename PT, typename CT>
 nsIContent*
-HTMLEditRules::FindNearEditableNode(const EditorRawDOMPoint& aPoint,
+HTMLEditRules::FindNearEditableNode(const EditorDOMPointBase<PT, CT>& aPoint,
                                     nsIEditor::EDirection aDirection)
 {
   if (NS_WARN_IF(!aPoint.IsSet()) ||
       NS_WARN_IF(!mHTMLEditor)) {
     return nullptr;
   }
   MOZ_ASSERT(aPoint.IsSetAndValid());
 
@@ -8657,17 +8674,17 @@ HTMLEditRules::PopListItem(nsIContent& a
     EditorDOMPoint atListItem(&aListItem);
     if (NS_WARN_IF(!atListItem.IsSet())) {
       return NS_ERROR_INVALID_ARG;
     }
     MOZ_ASSERT(atListItem.IsSetAndValid());
 
     // split the list
     ErrorResult error;
-    leftListNode = mHTMLEditor->SplitNode(atListItem.AsRaw(), error);
+    leftListNode = mHTMLEditor->SplitNode(atListItem, error);
     if (NS_WARN_IF(error.Failed())) {
       return error.StealNSResult();
     }
     if (NS_WARN_IF(!mHTMLEditor)) {
       return NS_ERROR_FAILURE;
     }
   }
 
@@ -9330,17 +9347,17 @@ HTMLEditRules::WillAbsolutePosition(Sele
 
     EditorDOMPoint atStartOfSelection(firstRange->StartRef());
     if (NS_WARN_IF(!atStartOfSelection.IsSet())) {
       return NS_ERROR_FAILURE;
     }
 
     // Make sure we can put a block here.
     SplitNodeResult splitNodeResult =
-      MaybeSplitAncestorsForInsert(*nsGkAtoms::div, atStartOfSelection.AsRaw());
+      MaybeSplitAncestorsForInsert(*nsGkAtoms::div, atStartOfSelection);
     if (NS_WARN_IF(splitNodeResult.Failed())) {
       return splitNodeResult.Rv();
     }
     RefPtr<Element> positionedDiv =
       htmlEditor->CreateNode(nsGkAtoms::div, splitNodeResult.SplitPoint());
     NS_ENSURE_STATE(positionedDiv);
     // Remember our new block for postprocessing
     mNewBlock = positionedDiv;
@@ -9385,17 +9402,17 @@ HTMLEditRules::WillAbsolutePosition(Sele
         sibling = htmlEditor->GetPriorHTMLSibling(curNode);
       }
 
       if (!curList || (sibling && sibling != curList)) {
         nsAtom* containerName =
           atCurNode.GetContainer()->NodeInfo()->NameAtom();
         // Create a new nested list of correct type.
         SplitNodeResult splitNodeResult =
-          MaybeSplitAncestorsForInsert(*containerName, atCurNode.AsRaw());
+          MaybeSplitAncestorsForInsert(*containerName, atCurNode);
         if (NS_WARN_IF(splitNodeResult.Failed())) {
           return splitNodeResult.Rv();
         }
         if (!curPositionedDiv) {
           curPositionedDiv =
             htmlEditor->CreateNode(nsGkAtoms::div,
                                    splitNodeResult.SplitPoint());
           mNewBlock = curPositionedDiv;
@@ -9436,17 +9453,17 @@ HTMLEditRules::WillAbsolutePosition(Sele
         EditorDOMPoint atListItem(listItem);
         if (NS_WARN_IF(!atListItem.IsSet())) {
           return NS_ERROR_FAILURE;
         }
         nsAtom* containerName =
           atListItem.GetContainer()->NodeInfo()->NameAtom();
         // Create a new nested list of correct type
         SplitNodeResult splitNodeResult =
-          MaybeSplitAncestorsForInsert(*containerName, atListItem.AsRaw());
+          MaybeSplitAncestorsForInsert(*containerName, atListItem);
         if (NS_WARN_IF(splitNodeResult.Failed())) {
           return splitNodeResult.Rv();
         }
         if (!curPositionedDiv) {
           EditorRawDOMPoint atListItemParent(atListItem.GetContainer());
           curPositionedDiv =
             htmlEditor->CreateNode(nsGkAtoms::div, atListItemParent);
           mNewBlock = curPositionedDiv;
@@ -9468,17 +9485,17 @@ HTMLEditRules::WillAbsolutePosition(Sele
     if (!curPositionedDiv) {
       if (curNode->IsHTMLElement(nsGkAtoms::div)) {
         curPositionedDiv = curNode->AsElement();
         mNewBlock = curPositionedDiv;
         curList = nullptr;
         continue;
       }
       SplitNodeResult splitNodeResult =
-        MaybeSplitAncestorsForInsert(*nsGkAtoms::div, atCurNode.AsRaw());
+        MaybeSplitAncestorsForInsert(*nsGkAtoms::div, atCurNode);
       if (NS_WARN_IF(splitNodeResult.Failed())) {
         return splitNodeResult.Rv();
       }
       curPositionedDiv =
         htmlEditor->CreateNode(nsGkAtoms::div, splitNodeResult.SplitPoint());
       NS_ENSURE_STATE(curPositionedDiv);
       // Remember our new block for postprocessing
       mNewBlock = curPositionedDiv;
--- a/editor/libeditor/HTMLEditRules.h
+++ b/editor/libeditor/HTMLEditRules.h
@@ -315,19 +315,20 @@ protected:
    *                            or <div> element.
    * @param aStartOfRightNode   The point to be start of right node after
    *                            split.  This must be descendant of
    *                            aParentDivOrP.
    * @param aNextBRNode         Next <br> node if there is.  Otherwise, nullptr.
    *                            If this is not nullptr, the <br> node may be
    *                            removed.
    */
+  template<typename PT, typename CT>
   nsresult SplitParagraph(Selection& aSelection,
                           Element& aParentDivOrP,
-                          const EditorRawDOMPoint& aStartOfRightNode,
+                          const EditorDOMPointBase<PT, CT>& aStartOfRightNode,
                           nsIContent* aBRNode);
 
   nsresult ReturnInListItem(Selection& aSelection, Element& aHeader,
                             nsINode& aNode, int32_t aOffset);
   nsresult AfterEditInner(EditAction action,
                           nsIEditor::EDirection aDirection);
   nsresult RemovePartOfBlock(Element& aBlock, nsIContent& aStartChild,
                              nsIContent& aEndChild);
@@ -452,19 +453,20 @@ protected:
    * @param aTag                        The name of element to be inserted
    *                                    after calling this method.
    * @param aStartOfDeepestRightNode    The start point of deepest right node.
    *                                    This point must be descendant of
    *                                    active editing host.
    * @return                            When succeeded, SplitPoint() returns
    *                                    the point to insert the element.
    */
+  template<typename PT, typename CT>
   SplitNodeResult MaybeSplitAncestorsForInsert(
                     nsAtom& aTag,
-                    const EditorRawDOMPoint& aStartOfDeepestRightNode);
+                    const EditorDOMPointBase<PT, CT>& aStartOfDeepestRightNode);
 
   nsresult AddTerminatingBR(nsIDOMNode *aBlock);
   EditorDOMPoint JoinNodesSmart(nsIContent& aNodeLeft,
                                 nsIContent& aNodeRight);
   Element* GetTopEnclosingMailCite(nsINode& aNode);
   nsresult PopListItem(nsIContent& aListItem, bool* aOutOfList = nullptr);
   nsresult RemoveListStructure(Element& aList);
   nsresult CacheInlineStyles(nsINode* aNode);
@@ -485,17 +487,18 @@ protected:
    *                    editable node from next nodes.  Otherwise, from
    *                    previous nodes.
    * @return            If found, returns non-nullptr.  Otherwise, nullptr.
    *                    Note that if found node is in different table element,
    *                    this returns nullptr.
    *                    And also if aDirection is not nsIEditor::ePrevious,
    *                    the result may be the node pointed by aPoint.
    */
-  nsIContent* FindNearEditableNode(const EditorRawDOMPoint& aPoint,
+  template<typename PT, typename CT>
+  nsIContent* FindNearEditableNode(const EditorDOMPointBase<PT, CT>& aPoint,
                                    nsIEditor::EDirection aDirection);
   /**
    * Returns true if aNode1 or aNode2 or both is the descendant of some type of
    * table element, but their nearest table element ancestors differ.  "Table
    * element" here includes not just <table> but also <td>, <tbody>, <tr>, etc.
    * The nodes count as being their own descendants for this purpose, so a
    * table element is its own nearest table element ancestor.
    */
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -83,16 +83,27 @@ IsLinkTag(const nsString& s)
 }
 
 static bool
 IsNamedAnchorTag(const nsString& s)
 {
   return s.EqualsIgnoreCase("anchor") || s.EqualsIgnoreCase("namedanchor");
 }
 
+template EditorDOMPoint
+HTMLEditor::InsertNodeIntoProperAncestor(
+              nsIContent& aNode,
+              const EditorDOMPoint& aPointToInsert,
+              SplitAtEdges aSplitAtEdges);
+template EditorDOMPoint
+HTMLEditor::InsertNodeIntoProperAncestor(
+              nsIContent& aNode,
+              const EditorRawDOMPoint& aPointToInsert,
+              SplitAtEdges aSplitAtEdges);
+
 HTMLEditor::HTMLEditor()
   : mCRInParagraphCreatesParagraph(false)
   , mCSSAware(false)
   , mSelectedCellIndex(0)
   , mIsObjectResizingEnabled(true)
   , mIsResizing(false)
   , mPreserveRatio(false)
   , mResizedObjectIsAnImage(false)
@@ -1595,31 +1606,32 @@ HTMLEditor::InsertElementAtSelection(nsI
       // a br after it.
       if (HTMLEditUtils::IsTable(element) &&
           IsLastEditableChild(element)) {
         DebugOnly<bool> advanced = insertedPoint.AdvanceOffset();
         NS_WARNING_ASSERTION(advanced,
           "Failed to advance offset from inserted point");
         // Collapse selection to the new <br> element node after creating it.
         RefPtr<Element> newBRElement =
-          CreateBRImpl(*selection, insertedPoint.AsRaw(), ePrevious);
+          CreateBRImpl(*selection, insertedPoint, ePrevious);
         if (NS_WARN_IF(!newBRElement)) {
           return NS_ERROR_FAILURE;
         }
       }
     }
   }
   rv = rules->DidDoAction(selection, &ruleInfo, rv);
   return rv;
 }
 
+template<typename PT, typename CT>
 EditorDOMPoint
 HTMLEditor::InsertNodeIntoProperAncestor(
               nsIContent& aNode,
-              const EditorRawDOMPoint& aPointToInsert,
+              const EditorDOMPointBase<PT, CT>& aPointToInsert,
               SplitAtEdges aSplitAtEdges)
 {
   if (NS_WARN_IF(!aPointToInsert.IsSet())) {
     return EditorDOMPoint();
   }
   MOZ_ASSERT(aPointToInsert.IsSetAndValid());
 
   // Search up the parent chain to find a suitable container.
@@ -1665,17 +1677,17 @@ HTMLEditor::InsertNodeIntoProperAncestor
     // After inserting a node, pointToInsert will refer next sibling of
     // the new node but keep referring the new node's offset.
     // This method's result should be the point at insertion, it's useful
     // even if the new node is moved by mutation observer immediately.
     // So, let's lock only the offset and child node should be recomputed
     // when it's necessary.
     AutoEditorDOMPointChildInvalidator lockOffset(pointToInsert);
     // Now we can insert the new node.
-    nsresult rv = InsertNode(aNode, pointToInsert.AsRaw());
+    nsresult rv = InsertNode(aNode, pointToInsert);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return EditorDOMPoint();
     }
   }
   return pointToInsert;
 }
 
 NS_IMETHODIMP
@@ -2037,17 +2049,17 @@ HTMLEditor::MakeOrChangeList(const nsASt
       if (NS_WARN_IF(!pointToInsertList.IsSet())) {
         return NS_ERROR_FAILURE;
       }
     }
 
     // Create a list and insert it before the right node if we split some
     // parents of start of selection above, or just start of selection
     // otherwise.
-    RefPtr<Element> newList = CreateNode(listAtom, pointToInsertList.AsRaw());
+    RefPtr<Element> newList = CreateNode(listAtom, pointToInsertList);
     NS_ENSURE_STATE(newList);
     // make a list item
     EditorRawDOMPoint atStartOfNewList(newList, 0);
     RefPtr<Element> newItem = CreateNode(nsGkAtoms::li, atStartOfNewList);
     NS_ENSURE_STATE(newItem);
     rv = selection->Collapse(newItem, 0);
     NS_ENSURE_SUCCESS(rv, rv);
   }
@@ -2187,18 +2199,17 @@ HTMLEditor::InsertBasicBlock(const nsASt
       if (NS_WARN_IF(!pointToInsertBlock.IsSet())) {
         return NS_ERROR_FAILURE;
       }
     }
 
     // Create a block and insert it before the right node if we split some
     // parents of start of selection above, or just start of selection
     // otherwise.
-    RefPtr<Element> newBlock =
-      CreateNode(blockAtom, pointToInsertBlock.AsRaw());
+    RefPtr<Element> newBlock = CreateNode(blockAtom, pointToInsertBlock);
     NS_ENSURE_STATE(newBlock);
 
     // reposition selection to inside the block
     rv = selection->Collapse(newBlock, 0);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return rules->DidDoAction(selection, &ruleInfo, rv);
@@ -2271,17 +2282,17 @@ HTMLEditor::Indent(const nsAString& aInd
         return NS_ERROR_FAILURE;
       }
     }
 
     // Create a list and insert it before the right node if we split some
     // parents of start of selection above, or just start of selection
     // otherwise.
     RefPtr<Element> newBQ =
-      CreateNode(nsGkAtoms::blockquote, pointToInsertBlockquote.AsRaw());
+      CreateNode(nsGkAtoms::blockquote, pointToInsertBlockquote);
     NS_ENSURE_STATE(newBQ);
     // put a space in it so layout will draw the list item
     rv = selection->Collapse(newBQ, 0);
     NS_ENSURE_SUCCESS(rv, rv);
     rv = InsertText(NS_LITERAL_STRING(" "));
     NS_ENSURE_SUCCESS(rv, rv);
     // reposition selection to before the space character
     NS_ENSURE_STATE(selection->GetRangeAt(0));
@@ -3796,19 +3807,20 @@ HTMLEditor::GetPreviousHTMLElementOrText
 {
   if (!GetActiveEditingHost()) {
     return nullptr;
   }
   return aNoBlockCrossing ? GetPreviousElementOrTextInBlock(aNode) :
                             GetPreviousElementOrText(aNode);
 }
 
+template<typename PT, typename CT>
 nsIContent*
 HTMLEditor::GetPreviousHTMLElementOrTextInternal(
-              const EditorRawDOMPoint& aPoint,
+              const EditorDOMPointBase<PT, CT>& aPoint,
               bool aNoBlockCrossing)
 {
   if (!GetActiveEditingHost()) {
     return nullptr;
   }
   return aNoBlockCrossing ? GetPreviousElementOrTextInBlock(aPoint) :
                             GetPreviousElementOrText(aPoint);
 }
@@ -3819,19 +3831,21 @@ HTMLEditor::GetPreviousEditableHTMLNodeI
 {
   if (!GetActiveEditingHost()) {
     return nullptr;
   }
   return aNoBlockCrossing ? GetPreviousEditableNodeInBlock(aNode) :
                             GetPreviousEditableNode(aNode);
 }
 
+template<typename PT, typename CT>
 nsIContent*
-HTMLEditor::GetPreviousEditableHTMLNodeInternal(const EditorRawDOMPoint& aPoint,
-                                                bool aNoBlockCrossing)
+HTMLEditor::GetPreviousEditableHTMLNodeInternal(
+              const EditorDOMPointBase<PT, CT>& aPoint,
+              bool aNoBlockCrossing)
 {
   if (!GetActiveEditingHost()) {
     return nullptr;
   }
   return aNoBlockCrossing ? GetPreviousEditableNodeInBlock(aPoint) :
                             GetPreviousEditableNode(aPoint);
 }
 
@@ -3841,19 +3855,21 @@ HTMLEditor::GetNextHTMLElementOrTextInte
 {
   if (!GetActiveEditingHost()) {
     return nullptr;
   }
   return aNoBlockCrossing ? GetNextElementOrTextInBlock(aNode) :
                             GetNextElementOrText(aNode);
 }
 
+template<typename PT, typename CT>
 nsIContent*
-HTMLEditor::GetNextHTMLElementOrTextInternal(const EditorRawDOMPoint& aPoint,
-                                             bool aNoBlockCrossing)
+HTMLEditor::GetNextHTMLElementOrTextInternal(
+              const EditorDOMPointBase<PT, CT>& aPoint,
+              bool aNoBlockCrossing)
 {
   if (!GetActiveEditingHost()) {
     return nullptr;
   }
   return aNoBlockCrossing ? GetNextElementOrTextInBlock(aPoint) :
                             GetNextElementOrText(aPoint);
 }
 
@@ -3863,19 +3879,21 @@ HTMLEditor::GetNextEditableHTMLNodeInter
 {
   if (!GetActiveEditingHost()) {
     return nullptr;
   }
   return aNoBlockCrossing ? GetNextEditableNodeInBlock(aNode) :
                             GetNextEditableNode(aNode);
 }
 
+template<typename PT, typename CT>
 nsIContent*
-HTMLEditor::GetNextEditableHTMLNodeInternal(const EditorRawDOMPoint& aPoint,
-                                            bool aNoBlockCrossing)
+HTMLEditor::GetNextEditableHTMLNodeInternal(
+              const EditorDOMPointBase<PT, CT>& aPoint,
+              bool aNoBlockCrossing)
 {
   if (!GetActiveEditingHost()) {
     return nullptr;
   }
   return aNoBlockCrossing ? GetNextEditableNodeInBlock(aPoint) :
                             GetNextEditableNode(aPoint);
 }
 
--- a/editor/libeditor/HTMLEditor.h
+++ b/editor/libeditor/HTMLEditor.h
@@ -418,19 +418,20 @@ public:
    * empty nodes.
    *
    * @param aNode             Node to insert.
    * @param aPointToInsert    Insertion point.
    * @param aSplitAtEdges     Splitting can result in empty nodes?
    * @return                  Returns inserted point if succeeded.
    *                          Otherwise, the result is not set.
    */
+  template<typename PT, typename CT>
   EditorDOMPoint
   InsertNodeIntoProperAncestor(nsIContent& aNode,
-                               const EditorRawDOMPoint& aPointToInsert,
+                               const EditorDOMPointBase<PT, CT>& aPointToInsert,
                                SplitAtEdges aSplitAtEdges);
 
   /**
    * Use this to assure that selection is set after attribute nodes when
    * trying to collapse selection at begining of a block node
    * e.g., when setting at beginning of a table cell
    * This will stop at a table, however, since we don't want to
    * "drill down" into nested tables.
@@ -929,67 +930,75 @@ protected:
   nsIContent* GetPreviousHTMLElementOrText(nsINode& aNode)
   {
     return GetPreviousHTMLElementOrTextInternal(aNode, false);
   }
   nsIContent* GetPreviousHTMLElementOrTextInBlock(nsINode& aNode)
   {
     return GetPreviousHTMLElementOrTextInternal(aNode, true);
   }
-  nsIContent* GetPreviousHTMLElementOrText(const EditorRawDOMPoint& aPoint)
+  template<typename PT, typename CT>
+  nsIContent*
+  GetPreviousHTMLElementOrText(const EditorDOMPointBase<PT, CT>& aPoint)
   {
     return GetPreviousHTMLElementOrTextInternal(aPoint, false);
   }
+  template<typename PT, typename CT>
   nsIContent*
-  GetPreviousHTMLElementOrTextInBlock(const EditorRawDOMPoint& aPoint)
+  GetPreviousHTMLElementOrTextInBlock(const EditorDOMPointBase<PT, CT>& aPoint)
   {
     return GetPreviousHTMLElementOrTextInternal(aPoint, true);
   }
 
   /**
    * GetPreviousHTMLElementOrTextInternal() methods are common implementation
    * of above methods.  Please don't use this method directly.
    */
   nsIContent* GetPreviousHTMLElementOrTextInternal(nsINode& aNode,
                                                    bool aNoBlockCrossing);
+  template<typename PT, typename CT>
   nsIContent*
-  GetPreviousHTMLElementOrTextInternal(const EditorRawDOMPoint& aPoint,
+  GetPreviousHTMLElementOrTextInternal(const EditorDOMPointBase<PT, CT>& aPoint,
                                        bool aNoBlockCrossing);
 
   /**
    * GetPreviousEditableHTMLNode*() methods are similar to
    * EditorBase::GetPreviousEditableNode() but this won't return nodes outside
    * active editing host.
    */
   nsIContent* GetPreviousEditableHTMLNode(nsINode& aNode)
   {
     return GetPreviousEditableHTMLNodeInternal(aNode, false);
   }
   nsIContent* GetPreviousEditableHTMLNodeInBlock(nsINode& aNode)
   {
     return GetPreviousEditableHTMLNodeInternal(aNode, true);
   }
-  nsIContent* GetPreviousEditableHTMLNode(const EditorRawDOMPoint& aPoint)
+  template<typename PT, typename CT>
+  nsIContent*
+  GetPreviousEditableHTMLNode(const EditorDOMPointBase<PT, CT>& aPoint)
   {
     return GetPreviousEditableHTMLNodeInternal(aPoint, false);
   }
+  template<typename PT, typename CT>
   nsIContent* GetPreviousEditableHTMLNodeInBlock(
-                const EditorRawDOMPoint& aPoint)
+                const EditorDOMPointBase<PT, CT>& aPoint)
   {
     return GetPreviousEditableHTMLNodeInternal(aPoint, true);
   }
 
   /**
    * GetPreviousEditableHTMLNodeInternal() methods are common implementation
    * of above methods.  Please don't use this method directly.
    */
   nsIContent* GetPreviousEditableHTMLNodeInternal(nsINode& aNode,
                                                   bool aNoBlockCrossing);
+  template<typename PT, typename CT>
   nsIContent* GetPreviousEditableHTMLNodeInternal(
-                const EditorRawDOMPoint& aPoint,
+                const EditorDOMPointBase<PT, CT>& aPoint,
                 bool aNoBlockCrossing);
 
   /**
    * GetNextHTMLElementOrText*() methods are similar to
    * EditorBase::GetNextElementOrText*() but this won't return nodes outside
    * active editing host.
    *
    * Note that same as EditorBase::GetTextEditableNode(), methods which take
@@ -1000,33 +1009,39 @@ protected:
   nsIContent* GetNextHTMLElementOrText(nsINode& aNode)
   {
     return GetNextHTMLElementOrTextInternal(aNode, false);
   }
   nsIContent* GetNextHTMLElementOrTextInBlock(nsINode& aNode)
   {
     return GetNextHTMLElementOrTextInternal(aNode, true);
   }
-  nsIContent* GetNextHTMLElementOrText(const EditorRawDOMPoint& aPoint)
+  template<typename PT, typename CT>
+  nsIContent*
+  GetNextHTMLElementOrText(const EditorDOMPointBase<PT, CT>& aPoint)
   {
     return GetNextHTMLElementOrTextInternal(aPoint, false);
   }
-  nsIContent* GetNextHTMLElementOrTextInBlock(const EditorRawDOMPoint& aPoint)
+  template<typename PT, typename CT>
+  nsIContent*
+  GetNextHTMLElementOrTextInBlock(const EditorDOMPointBase<PT, CT>& aPoint)
   {
     return GetNextHTMLElementOrTextInternal(aPoint, true);
   }
 
   /**
    * GetNextHTMLNodeInternal() methods are common implementation
    * of above methods.  Please don't use this method directly.
    */
   nsIContent* GetNextHTMLElementOrTextInternal(nsINode& aNode,
                                                bool aNoBlockCrossing);
-  nsIContent* GetNextHTMLElementOrTextInternal(const EditorRawDOMPoint& aPoint,
-                                               bool aNoBlockCrossing);
+  template<typename PT, typename CT>
+  nsIContent*
+  GetNextHTMLElementOrTextInternal(const EditorDOMPointBase<PT, CT>& aPoint,
+                                   bool aNoBlockCrossing);
 
   /**
    * GetNextEditableHTMLNode*() methods are similar to
    * EditorBase::GetNextEditableNode() but this won't return nodes outside
    * active editing host.
    *
    * Note that same as EditorBase::GetTextEditableNode(), methods which take
    * |const EditorRawDOMPoint&| start to search from the node pointed by it.
@@ -1036,34 +1051,37 @@ protected:
   nsIContent* GetNextEditableHTMLNode(nsINode& aNode)
   {
     return GetNextEditableHTMLNodeInternal(aNode, false);
   }
   nsIContent* GetNextEditableHTMLNodeInBlock(nsINode& aNode)
   {
     return GetNextEditableHTMLNodeInternal(aNode, true);
   }
-  nsIContent* GetNextEditableHTMLNode(const EditorRawDOMPoint& aPoint)
+  template<typename PT, typename CT>
+  nsIContent* GetNextEditableHTMLNode(const EditorDOMPointBase<PT, CT>& aPoint)
   {
     return GetNextEditableHTMLNodeInternal(aPoint, false);
   }
+  template<typename PT, typename CT>
   nsIContent* GetNextEditableHTMLNodeInBlock(
-                const EditorRawDOMPoint& aPoint)
+                const EditorDOMPointBase<PT, CT>& aPoint)
   {
     return GetNextEditableHTMLNodeInternal(aPoint, true);
   }
 
   /**
    * GetNextEditableHTMLNodeInternal() methods are common implementation
    * of above methods.  Please don't use this method directly.
    */
   nsIContent* GetNextEditableHTMLNodeInternal(nsINode& aNode,
-                                                  bool aNoBlockCrossing);
+                                              bool aNoBlockCrossing);
+  template<typename PT, typename CT>
   nsIContent* GetNextEditableHTMLNodeInternal(
-                const EditorRawDOMPoint& aPoint,
+                const EditorDOMPointBase<PT, CT>& aPoint,
                 bool aNoBlockCrossing);
 
   bool IsFirstEditableChild(nsINode* aNode);
   bool IsLastEditableChild(nsINode* aNode);
   nsIContent* GetFirstEditableChild(nsINode& aNode);
   nsIContent* GetLastEditableChild(nsINode& aNode);
 
   nsIContent* GetFirstEditableLeaf(nsINode& aNode);
--- a/editor/libeditor/HTMLEditorDataTransfer.cpp
+++ b/editor/libeditor/HTMLEditorDataTransfer.cpp
@@ -137,17 +137,17 @@ HTMLEditor::LoadHTML(const nsAString& aI
     //     behavior since using only child node to pointing insertion point
     //     changes the behavior when inserted child is moved by mutation
     //     observer.  We need to investigate what we should do here.
     Unused << pointToInsert.Offset();
     for (nsCOMPtr<nsIContent> contentToInsert =
            documentFragment->GetFirstChild();
          contentToInsert;
          contentToInsert = documentFragment->GetFirstChild()) {
-      rv = InsertNode(*contentToInsert, pointToInsert.AsRaw());
+      rv = InsertNode(*contentToInsert, pointToInsert);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
       // XXX If the inserted node has been moved by mutation observer,
       //     incrementing offset will cause odd result.  Next new node
       //     will be inserted after existing node and the offset will be
       //     overflown from the container node.
       pointToInsert.Set(pointToInsert.GetContainer(),
@@ -357,18 +357,17 @@ HTMLEditor::DoInsertHTMLWithContext(cons
     }
 
     // Remember if we are in a link.
     bool bStartedInLink = IsInLink(pointToInsert.GetContainer());
 
     // Are we in a text node? If so, split it.
     if (pointToInsert.IsInTextNode()) {
       SplitNodeResult splitNodeResult =
-        SplitNodeDeep(*pointToInsert.GetContainerAsContent(),
-                      pointToInsert.AsRaw(),
+        SplitNodeDeep(*pointToInsert.GetContainerAsContent(), pointToInsert,
                       SplitAtEdges::eAllowToCreateEmptyContainer);
       if (NS_WARN_IF(splitNodeResult.Failed())) {
         return splitNodeResult.Rv();
       }
       pointToInsert = splitNodeResult.SplitPoint();
       if (NS_WARN_IF(!pointToInsert.IsSet())) {
         return NS_ERROR_FAILURE;
       }
@@ -447,17 +446,17 @@ HTMLEditor::DoInsertHTMLWithContext(cons
           HTMLEditUtils::IsTableRow(pointToInsert.GetContainer()) &&
           (HTMLEditUtils::IsTable(curNode) ||
            HTMLEditUtils::IsTable(pointToInsert.GetContainer()))) {
         for (nsCOMPtr<nsIContent> firstChild = curNode->GetFirstChild();
              firstChild;
              firstChild = curNode->GetFirstChild()) {
           EditorDOMPoint insertedPoint =
             InsertNodeIntoProperAncestor(
-              *firstChild, pointToInsert.AsRaw(),
+              *firstChild, pointToInsert,
               SplitAtEdges::eDoNotCreateEmptyContainer);
           if (NS_WARN_IF(!insertedPoint.IsSet())) {
             break;
           }
           bDidInsert = true;
           lastInsertNode = firstChild;
           pointToInsert = insertedPoint;
           DebugOnly<bool> advanced = pointToInsert.AdvanceOffset();
@@ -489,17 +488,17 @@ HTMLEditor::DoInsertHTMLWithContext(cons
                 } else {
                   DeleteNode(pointToInsert.GetContainer());
                   pointToInsert.Set(pointToInsert.GetContainer());
                 }
               }
             }
             EditorDOMPoint insertedPoint =
               InsertNodeIntoProperAncestor(
-                *firstChild, pointToInsert.AsRaw(),
+                *firstChild, pointToInsert,
                 SplitAtEdges::eDoNotCreateEmptyContainer);
             if (NS_WARN_IF(!insertedPoint.IsSet())) {
               break;
             }
 
             bDidInsert = true;
             lastInsertNode = firstChild;
             pointToInsert = insertedPoint;
@@ -518,17 +517,17 @@ HTMLEditor::DoInsertHTMLWithContext(cons
       } else if (parentBlock && HTMLEditUtils::IsPre(parentBlock) &&
                  HTMLEditUtils::IsPre(curNode)) {
         // Check for pre's going into pre's.
         for (nsCOMPtr<nsIContent> firstChild = curNode->GetFirstChild();
              firstChild;
              firstChild = curNode->GetFirstChild()) {
           EditorDOMPoint insertedPoint =
             InsertNodeIntoProperAncestor(
-              *firstChild, pointToInsert.AsRaw(),
+              *firstChild, pointToInsert,
               SplitAtEdges::eDoNotCreateEmptyContainer);
           if (NS_WARN_IF(!insertedPoint.IsSet())) {
             break;
           }
 
           bDidInsert = true;
           lastInsertNode = firstChild;
           pointToInsert = insertedPoint;
@@ -537,17 +536,17 @@ HTMLEditor::DoInsertHTMLWithContext(cons
             "Failed to advance offset from inserted point");
         }
       }
 
       if (!bDidInsert || NS_FAILED(rv)) {
         // Try to insert.
         EditorDOMPoint insertedPoint =
           InsertNodeIntoProperAncestor(
-            *curNode->AsContent(), pointToInsert.AsRaw(),
+            *curNode->AsContent(), pointToInsert,
             SplitAtEdges::eDoNotCreateEmptyContainer);
         if (insertedPoint.IsSet()) {
           lastInsertNode = curNode->AsContent();
           pointToInsert = insertedPoint;
         }
 
         // Assume failure means no legal parent in the document hierarchy,
         // try again with the parent of curNode in the paste hierarchy.
@@ -557,17 +556,17 @@ HTMLEditor::DoInsertHTMLWithContext(cons
              content = content->GetParent()) {
           if (NS_WARN_IF(!content->GetParent()) ||
               NS_WARN_IF(TextEditUtils::IsBody(content->GetParent()))) {
             continue;
           }
           nsCOMPtr<nsINode> oldParent = content->GetParentNode();
           insertedPoint =
             InsertNodeIntoProperAncestor(
-              *content->GetParent(), pointToInsert.AsRaw(),
+              *content->GetParent(), pointToInsert,
               SplitAtEdges::eDoNotCreateEmptyContainer);
           if (insertedPoint.IsSet()) {
             insertedContextParent = oldParent;
             pointToInsert = insertedPoint;
           }
         }
       }
       if (lastInsertNode) {
--- a/editor/libeditor/HTMLTableEditor.cpp
+++ b/editor/libeditor/HTMLTableEditor.cpp
@@ -146,17 +146,17 @@ HTMLEditor::InsertCell(nsIDOMElement* aD
   if (aAfter) {
     DebugOnly<bool> advanced = pointToInsert.AdvanceOffset();
     NS_WARNING_ASSERTION(advanced,
       "Failed to advance offset to after the old cell");
   }
 
   // Don't let Rules System change the selection.
   AutoTransactionsConserveSelection dontChangeSelection(this);
-  return InsertNode(*newCell, pointToInsert.AsRaw());
+  return InsertNode(*newCell, pointToInsert);
 }
 
 nsresult
 HTMLEditor::SetColSpan(nsIDOMElement* aCell,
                        int32_t aColSpan)
 {
   NS_ENSURE_TRUE(aCell, NS_ERROR_NULL_POINTER);
   nsAutoString newSpan;
--- a/editor/libeditor/InsertNodeTransaction.cpp
+++ b/editor/libeditor/InsertNodeTransaction.cpp
@@ -17,31 +17,42 @@
 #include "nsMemory.h"                   // for nsMemory
 #include "nsReadableUtils.h"            // for ToNewCString
 #include "nsString.h"                   // for nsString
 
 namespace mozilla {
 
 using namespace dom;
 
+template already_AddRefed<InsertNodeTransaction>
+InsertNodeTransaction::Create(EditorBase& aEditorBase,
+                              nsIContent& aContentToInsert,
+                              const EditorDOMPoint& aPointToInsert);
+template already_AddRefed<InsertNodeTransaction>
+InsertNodeTransaction::Create(EditorBase& aEditorBase,
+                              nsIContent& aContentToInsert,
+                              const EditorRawDOMPoint& aPointToInsert);
+
 // static
+template<typename PT, typename CT>
 already_AddRefed<InsertNodeTransaction>
 InsertNodeTransaction::Create(EditorBase& aEditorBase,
                               nsIContent& aContentToInsert,
-                              const EditorRawDOMPoint& aPointToInsert)
+                              const EditorDOMPointBase<PT, CT>& aPointToInsert)
 {
   RefPtr<InsertNodeTransaction> transaction =
     new InsertNodeTransaction(aEditorBase, aContentToInsert, aPointToInsert);
   return transaction.forget();
 }
 
+template<typename PT, typename CT>
 InsertNodeTransaction::InsertNodeTransaction(
                          EditorBase& aEditorBase,
                          nsIContent& aContentToInsert,
-                         const EditorRawDOMPoint& aPointToInsert)
+                         const EditorDOMPointBase<PT, CT>& aPointToInsert)
   : mContentToInsert(&aContentToInsert)
   , mPointToInsert(aPointToInsert)
   , mEditorBase(&aEditorBase)
 {
   MOZ_ASSERT(mPointToInsert.IsSetAndValid());
   // Ensure mPointToInsert stores child at offset.
   Unused << mPointToInsert.GetChild();
 }
--- a/editor/libeditor/InsertNodeTransaction.h
+++ b/editor/libeditor/InsertNodeTransaction.h
@@ -18,39 +18,41 @@ namespace mozilla {
 class EditorBase;
 
 /**
  * A transaction that inserts a single element
  */
 class InsertNodeTransaction final : public EditTransactionBase
 {
 protected:
+  template<typename PT, typename CT>
   InsertNodeTransaction(EditorBase& aEditorBase,
                         nsIContent& aContentToInsert,
-                        const EditorRawDOMPoint& aPointToInsert);
+                        const EditorDOMPointBase<PT, CT>& aPointToInsert);
 
 public:
   /**
    * Create a transaction for inserting aContentToInsert before the child
    * at aPointToInsert.
    *
    * @param aEditorBase         The editor which manages the transaction.
    * @param aContentToInsert    The node to be inserted.
    * @param aPointToInsert      The insertion point of aContentToInsert.
    *                            If this refers end of the container, the
    *                            transaction will append the node to the
    *                            container.  Otherwise, will insert the node
    *                            before child node referred by this.
    * @return                    A InsertNodeTranaction which was initialized
    *                            with the arguments.
    */
+  template<typename PT, typename CT>
   static already_AddRefed<InsertNodeTransaction>
   Create(EditorBase& aEditorBase,
          nsIContent& aContentToInsert,
-         const EditorRawDOMPoint& aPointToInsert);
+         const EditorDOMPointBase<PT, CT>& aPointToInsert);
 
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(InsertNodeTransaction,
                                            EditTransactionBase)
 
   NS_DECL_EDITTRANSACTIONBASE
 
--- a/editor/libeditor/SelectionState.cpp
+++ b/editor/libeditor/SelectionState.cpp
@@ -23,16 +23,26 @@ using namespace dom;
 
 /******************************************************************************
  * mozilla::SelectionState
  *
  * Class for recording selection info.  Stores selection as collection of
  * { {startnode, startoffset} , {endnode, endoffset} } tuples.  Can't store
  * ranges since dom gravity will possibly change the ranges.
  ******************************************************************************/
+
+template nsresult
+RangeUpdater::SelAdjCreateNode(const EditorDOMPoint& aPoint);
+template nsresult
+RangeUpdater::SelAdjCreateNode(const EditorRawDOMPoint& aPoint);
+template nsresult
+RangeUpdater::SelAdjInsertNode(const EditorDOMPoint& aPoint);
+template nsresult
+RangeUpdater::SelAdjInsertNode(const EditorRawDOMPoint& aPoint);
+
 SelectionState::SelectionState()
 {
 }
 
 SelectionState::~SelectionState()
 {
   MakeEmpty();
 }
@@ -206,18 +216,19 @@ RangeUpdater::DropSelectionState(Selecti
     DropRangeItem(aSelState.mArray[i]);
   }
 
   return NS_OK;
 }
 
 // gravity methods:
 
+template<typename PT, typename CT>
 nsresult
-RangeUpdater::SelAdjCreateNode(const EditorRawDOMPoint& aPoint)
+RangeUpdater::SelAdjCreateNode(const EditorDOMPointBase<PT, CT>& aPoint)
 {
   if (mLock) {
     // lock set by Will/DidReplaceParent, etc...
     return NS_OK;
   }
   size_t count = mArray.Length();
   if (!count) {
     return NS_OK;
@@ -238,18 +249,19 @@ RangeUpdater::SelAdjCreateNode(const Edi
     if (item->mEndContainer == aPoint.GetContainer() &&
         item->mEndOffset > static_cast<int32_t>(aPoint.Offset())) {
       item->mEndOffset++;
     }
   }
   return NS_OK;
 }
 
+template<typename PT, typename CT>
 nsresult
-RangeUpdater::SelAdjInsertNode(const EditorRawDOMPoint& aPoint)
+RangeUpdater::SelAdjInsertNode(const EditorDOMPointBase<PT, CT>& aPoint)
 {
   return SelAdjCreateNode(aPoint);
 }
 
 void
 RangeUpdater::SelAdjDeleteNode(nsINode* aNode)
 {
   if (mLock) {
--- a/editor/libeditor/SelectionState.h
+++ b/editor/libeditor/SelectionState.h
@@ -103,18 +103,20 @@ public:
   nsresult RegisterSelectionState(SelectionState& aSelState);
   nsresult DropSelectionState(SelectionState& aSelState);
 
   // editor selection gravity routines.  Note that we can't always depend on
   // DOM Range gravity to do what we want to the "real" selection.  For instance,
   // if you move a node, that corresponds to deleting it and reinserting it.
   // DOM Range gravity will promote the selection out of the node on deletion,
   // which is not what you want if you know you are reinserting it.
-  nsresult SelAdjCreateNode(const EditorRawDOMPoint& aPoint);
-  nsresult SelAdjInsertNode(const EditorRawDOMPoint& aPoint);
+  template<typename PT, typename CT>
+  nsresult SelAdjCreateNode(const EditorDOMPointBase<PT, CT>& aPoint);
+  template<typename PT, typename CT>
+  nsresult SelAdjInsertNode(const EditorDOMPointBase<PT, CT>& aPoint);
   void SelAdjDeleteNode(nsINode* aNode);
   nsresult SelAdjSplitNode(nsIContent& aRightNode, nsIContent* aNewLeftNode);
   nsresult SelAdjJoinNodes(nsINode& aLeftNode,
                            nsINode& aRightNode,
                            nsINode& aParent,
                            int32_t aOffset,
                            int32_t aOldLeftNodeLength);
   void SelAdjInsertText(dom::Text& aTextNode, int32_t aOffset,
--- a/editor/libeditor/SplitNodeTransaction.cpp
+++ b/editor/libeditor/SplitNodeTransaction.cpp
@@ -12,29 +12,41 @@
 #include "nsDebug.h"                    // for NS_ASSERTION, etc.
 #include "nsError.h"                    // for NS_ERROR_NOT_INITIALIZED, etc.
 #include "nsIContent.h"                 // for nsIContent
 
 namespace mozilla {
 
 using namespace dom;
 
+template already_AddRefed<SplitNodeTransaction>
+SplitNodeTransaction::Create(
+                        EditorBase& aEditorBase,
+                        const EditorDOMPoint& aStartOfRightNode);
+template already_AddRefed<SplitNodeTransaction>
+SplitNodeTransaction::Create(
+                        EditorBase& aEditorBase,
+                        const EditorRawDOMPoint& aStartOfRightNode);
+
 // static
+template<typename PT, typename CT>
 already_AddRefed<SplitNodeTransaction>
-SplitNodeTransaction::Create(EditorBase& aEditorBase,
-                             const EditorRawDOMPoint& aStartOfRightNode)
+SplitNodeTransaction::Create(
+                        EditorBase& aEditorBase,
+                        const EditorDOMPointBase<PT, CT>& aStartOfRightNode)
 {
   RefPtr<SplitNodeTransaction> transaction =
     new SplitNodeTransaction(aEditorBase, aStartOfRightNode);
   return transaction.forget();
 }
 
+template<typename PT, typename CT>
 SplitNodeTransaction::SplitNodeTransaction(
                         EditorBase& aEditorBase,
-                        const EditorRawDOMPoint& aStartOfRightNode)
+                        const EditorDOMPointBase<PT, CT>& aStartOfRightNode)
   : mEditorBase(&aEditorBase)
   , mStartOfRightNode(aStartOfRightNode)
 {
   MOZ_DIAGNOSTIC_ASSERT(aStartOfRightNode.IsSet());
   MOZ_DIAGNOSTIC_ASSERT(aStartOfRightNode.GetContainerAsContent());
 }
 
 SplitNodeTransaction::~SplitNodeTransaction()
--- a/editor/libeditor/SplitNodeTransaction.h
+++ b/editor/libeditor/SplitNodeTransaction.h
@@ -22,34 +22,36 @@ class EditorBase;
 
 /**
  * A transaction that splits a node into two identical nodes, with the children
  * divided between the new nodes.
  */
 class SplitNodeTransaction final : public EditTransactionBase
 {
 private:
+  template<typename PT, typename CT>
   SplitNodeTransaction(EditorBase& aEditorBase,
-                       const EditorRawDOMPoint& aStartOfRightNode);
+                       const EditorDOMPointBase<PT, CT>& aStartOfRightNode);
 
 public:
   /**
    * Creates a transaction to create a new node (left node) identical to an
    * existing node (right node), and split the contents between the same point
    * in both nodes.
    *
    * @param aEditorBase         The provider of core editing operations.
    * @param aStartOfRightNode   The point to split.  Its container will be
    *                            the right node, i.e., become the new node's
    *                            next sibling.  And the point will be start
    *                            of the right node.
    */
+  template<typename PT, typename CT>
   static already_AddRefed<SplitNodeTransaction>
   Create(EditorBase& aEditorBase,
-         const EditorRawDOMPoint& aStartOfRightNode);
+         const EditorDOMPointBase<PT, CT>& aStartOfRightNode);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SplitNodeTransaction,
                                            EditTransactionBase)
 
   NS_DECL_EDITTRANSACTIONBASE
 
   NS_IMETHOD RedoTransaction() override;
--- a/editor/libeditor/TextEditRules.h
+++ b/editor/libeditor/TextEditRules.h
@@ -223,29 +223,33 @@ protected:
 
   /**
    * Create a normal <br> element and insert it to aPointToInsert.
    *
    * @param aPointToInsert  The point where the new <br> element will be
    *                        inserted.
    * @return                Returns created <br> element.
    */
-  already_AddRefed<Element> CreateBR(const EditorRawDOMPoint& aPointToInsert)
+  template<typename PT, typename CT>
+  already_AddRefed<Element>
+  CreateBR(const EditorDOMPointBase<PT, CT>& aPointToInsert)
   {
     return CreateBRInternal(aPointToInsert, false);
   }
 
   /**
    * Create a moz-<br> element and insert it to aPointToInsert.
    *
    * @param aPointToInsert  The point where the new moz-<br> element will be
    *                        inserted.
    * @return                Returns created moz-<br> element.
    */
-  already_AddRefed<Element> CreateMozBR(const EditorRawDOMPoint& aPointToInsert)
+  template<typename PT, typename CT>
+  already_AddRefed<Element>
+  CreateMozBR(const EditorDOMPointBase<PT, CT>& aPointToInsert)
   {
     return CreateBRInternal(aPointToInsert, true);
   }
 
   /**
    * Create a normal <br> element or a moz-<br> element and insert it to
    * aPointToInsert.
    *
--- a/editor/libeditor/TextEditor.cpp
+++ b/editor/libeditor/TextEditor.cpp
@@ -58,16 +58,23 @@
 
 class nsIOutputStream;
 class nsISupports;
 
 namespace mozilla {
 
 using namespace dom;
 
+template already_AddRefed<Element>
+TextEditor::CreateBR(const EditorDOMPoint& aPointToInsert,
+                     EDirection aSelect);
+template already_AddRefed<Element>
+TextEditor::CreateBR(const EditorRawDOMPoint& aPointToInsert,
+                     EDirection aSelect);
+
 TextEditor::TextEditor()
   : mWrapColumn(0)
   , mMaxTextLength(-1)
   , mInitTriggerCounter(0)
   , mNewlineHandling(nsIPlaintextEditor::eNewlinesPasteToFirst)
 #ifdef XP_WIN
   , mCaretStyle(1)
 #else
@@ -403,31 +410,33 @@ TextEditor::TypedText(const nsAString& a
     case eTypedBreak:
       return InsertLineBreak();
     default:
       // eTypedBR is only for HTML
       return NS_ERROR_FAILURE;
   }
 }
 
+template<typename PT, typename CT>
 already_AddRefed<Element>
-TextEditor::CreateBR(const EditorRawDOMPoint& aPointToInsert,
+TextEditor::CreateBR(const EditorDOMPointBase<PT, CT>& aPointToInsert,
                      EDirection aSelect /* = eNone */)
 {
   RefPtr<Selection> selection = GetSelection();
   if (NS_WARN_IF(!selection)) {
     return nullptr;
   }
   // We assume everything is fine if newBRElement is not null.
   return CreateBRImpl(*selection, aPointToInsert, aSelect);
 }
 
+template<typename PT, typename CT>
 already_AddRefed<Element>
 TextEditor::CreateBRImpl(Selection& aSelection,
-                         const EditorRawDOMPoint& aPointToInsert,
+                         const EditorDOMPointBase<PT, CT>& aPointToInsert,
                          EDirection aSelect)
 {
   if (NS_WARN_IF(!aPointToInsert.IsSet())) {
     return nullptr;
   }
 
   // We need to insert a <br> node.
   RefPtr<Element> newBRElement;
@@ -457,17 +466,17 @@ TextEditor::CreateBRImpl(Selection& aSel
         error.SuppressException();
         return nullptr;
       }
       Unused << newLeftNode;
       // Insert new <br> before the right node.
       pointInContainer.Set(aPointToInsert.GetContainer());
     }
     // Create a <br> node.
-    newBRElement = CreateNode(nsGkAtoms::br, pointInContainer.AsRaw());
+    newBRElement = CreateNode(nsGkAtoms::br, pointInContainer);
     if (NS_WARN_IF(!newBRElement)) {
       return nullptr;
     }
   } else {
     newBRElement = CreateNode(nsGkAtoms::br, aPointToInsert);
     if (NS_WARN_IF(!newBRElement)) {
       return nullptr;
     }
--- a/editor/libeditor/TextEditor.h
+++ b/editor/libeditor/TextEditor.h
@@ -208,18 +208,20 @@ protected:
    * @param aSelect         If eNone, this won't change selection.
    *                        If eNext, selection will be collapsed after the
    *                        <br> element.
    *                        If ePrevious, selection will be collapsed at the
    *                        <br> element.
    * @return                The new <br> node.  If failed to create new <br>
    *                        node, returns nullptr.
    */
-  already_AddRefed<Element> CreateBR(const EditorRawDOMPoint& aPointToInsert,
-                                     EDirection aSelect = eNone);
+  template<typename PT, typename CT>
+  already_AddRefed<Element>
+  CreateBR(const EditorDOMPointBase<PT, CT>& aPointToInsert,
+           EDirection aSelect = eNone);
 
   /**
    * CreateBRImpl() creates a <br> element and inserts it before aPointToInsert.
    * Then, tries to collapse selection at or after the new <br> node if
    * aSelect is not eNone.
    * XXX Perhaps, this should be merged with CreateBR().
    *
    * @param aSelection          The selection of this editor.
@@ -228,19 +230,20 @@ protected:
    * @param aSelect             If eNone, this won't change selection.
    *                            If eNext, selection will be collapsed after
    *                            the <br> element.
    *                            If ePrevious, selection will be collapsed at
    *                            the <br> element.
    * @return                    The new <br> node.  If failed to create new
    *                            <br> node, returns nullptr.
    */
+  template<typename PT, typename CT>
   already_AddRefed<Element>
   CreateBRImpl(Selection& aSelection,
-               const EditorRawDOMPoint& aPointToInsert,
+               const EditorDOMPointBase<PT, CT>& aPointToInsert,
                EDirection aSelect);
 
   /**
    * Factored methods for handling insertion of data from transferables
    * (drag&drop or clipboard).
    */
   NS_IMETHOD PrepareTransferable(nsITransferable** transferable);
   nsresult InsertTextFromTransferable(nsITransferable* transferable,
--- a/editor/libeditor/WSRunObject.cpp
+++ b/editor/libeditor/WSRunObject.cpp
@@ -49,16 +49,34 @@ template void WSRunObject::PriorVisibleN
 template void WSRunObject::NextVisibleNode(const EditorDOMPoint& aPoint,
                                            nsCOMPtr<nsINode>* outVisNode,
                                            int32_t* outVisOffset,
                                            WSType* outType);
 template void WSRunObject::NextVisibleNode(const EditorRawDOMPoint& aPoint,
                                            nsCOMPtr<nsINode>* outVisNode,
                                            int32_t* outVisOffset,
                                            WSType* outType);
+template already_AddRefed<Element>
+WSRunObject::InsertBreak(Selection& aSelection,
+                         const EditorDOMPoint& aPointToInsert,
+                         nsIEditor::EDirection aSelect);
+template already_AddRefed<Element>
+WSRunObject::InsertBreak(Selection& aSelection,
+                         const EditorRawDOMPoint& aPointToInsert,
+                         nsIEditor::EDirection aSelect);
+template nsresult
+WSRunObject::InsertText(nsIDocument& aDocument,
+                        const nsAString& aStringToInsert,
+                        const EditorDOMPoint& aPointToInsert,
+                        EditorRawDOMPoint* aPointAfterInsertedString);
+template nsresult
+WSRunObject::InsertText(nsIDocument& aDocument,
+                        const nsAString& aStringToInsert,
+                        const EditorRawDOMPoint& aPointToInsert,
+                        EditorRawDOMPoint* aPointAfterInsertedString);
 
 template<typename PT, typename CT>
 WSRunObject::WSRunObject(HTMLEditor* aHTMLEditor,
                          const EditorDOMPointBase<PT, CT>& aPoint)
   : WSRunObject(aHTMLEditor, aPoint.GetContainer(), aPoint.Offset())
 {
 }
 
@@ -171,19 +189,20 @@ WSRunObject::PrepareToSplitAcrossBlocks(
   AutoTrackDOMPoint tracker(aHTMLEditor->mRangeUpdater,
                             aSplitNode, aSplitOffset);
 
   WSRunObject wsObj(aHTMLEditor, *aSplitNode, *aSplitOffset);
 
   return wsObj.PrepareToSplitAcrossBlocksPriv();
 }
 
+template<typename PT, typename CT>
 already_AddRefed<Element>
 WSRunObject::InsertBreak(Selection& aSelection,
-                         const EditorRawDOMPoint& aPointToInsert,
+                         const EditorDOMPointBase<PT, CT>& aPointToInsert,
                          nsIEditor::EDirection aSelect)
 {
   if (NS_WARN_IF(!aPointToInsert.IsSet())) {
     return nullptr;
   }
 
   // MOOSE: for now, we always assume non-PRE formatting.  Fix this later.
   // meanwhile, the pre case is handled in WillInsertText in
@@ -200,24 +219,24 @@ WSRunObject::InsertBreak(Selection& aSel
 
     // Handle any changes needed to ws run after inserted br
     if (!afterRun || (afterRun->mType & WSType::trailingWS)) {
       // Don't need to do anything.  Just insert break.  ws won't change.
     } else if (afterRun->mType & WSType::leadingWS) {
       // Delete the leading ws that is after insertion point.  We don't
       // have to (it would still not be significant after br), but it's
       // just more aesthetically pleasing to.
-      nsresult rv = DeleteRange(pointToInsert.AsRaw(), afterRun->EndPoint());
+      nsresult rv = DeleteRange(pointToInsert, afterRun->EndPoint());
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return nullptr;
       }
     } else if (afterRun->mType == WSType::normalWS) {
       // Need to determine if break at front of non-nbsp run.  If so, convert
       // run to nbsp.
-      WSPoint thePoint = GetNextCharPoint(pointToInsert.AsRaw());
+      WSPoint thePoint = GetNextCharPoint(pointToInsert);
       if (thePoint.mTextNode && nsCRT::IsAsciiSpace(thePoint.mChar)) {
         WSPoint prevPoint = GetPreviousCharPoint(thePoint);
         if (!prevPoint.mTextNode ||
             (prevPoint.mTextNode && !nsCRT::IsAsciiSpace(prevPoint.mChar))) {
           // We are at start of non-nbsps.  Convert to a single nbsp.
           nsresult rv = InsertNBSPAndRemoveFollowingASCIIWhitespaces(thePoint);
           if (NS_WARN_IF(NS_FAILED(rv))) {
             return nullptr;
@@ -227,42 +246,43 @@ WSRunObject::InsertBreak(Selection& aSel
     }
 
     // Handle any changes needed to ws run before inserted br
     if (!beforeRun || (beforeRun->mType & WSType::leadingWS)) {
       // Don't need to do anything.  Just insert break.  ws won't change.
     } else if (beforeRun->mType & WSType::trailingWS) {
       // Need to delete the trailing ws that is before insertion point, because it
       // would become significant after break inserted.
-      nsresult rv = DeleteRange(beforeRun->StartPoint(), pointToInsert.AsRaw());
+      nsresult rv = DeleteRange(beforeRun->StartPoint(), pointToInsert);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return nullptr;
       }
     } else if (beforeRun->mType == WSType::normalWS) {
       // Try to change an nbsp to a space, just to prevent nbsp proliferation
       nsresult rv =
-        ReplacePreviousNBSPIfUnncessary(beforeRun, pointToInsert.AsRaw());
+        ReplacePreviousNBSPIfUnncessary(beforeRun, pointToInsert);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return nullptr;
       }
     }
   }
 
   RefPtr<Element> newBRElement =
-    mHTMLEditor->CreateBRImpl(aSelection, pointToInsert.AsRaw(), aSelect);
+    mHTMLEditor->CreateBRImpl(aSelection, pointToInsert, aSelect);
   if (NS_WARN_IF(!newBRElement)) {
     return nullptr;
   }
   return newBRElement.forget();
 }
 
+template<typename PT, typename CT>
 nsresult
 WSRunObject::InsertText(nsIDocument& aDocument,
                         const nsAString& aStringToInsert,
-                        const EditorRawDOMPoint& aPointToInsert,
+                        const EditorDOMPointBase<PT, CT>& aPointToInsert,
                         EditorRawDOMPoint* aPointAfterInsertedString)
 {
   // MOOSE: for now, we always assume non-PRE formatting.  Fix this later.
   // meanwhile, the pre case is handled in WillInsertText in
   // HTMLEditRules.cpp
 
   // MOOSE: for now, just getting the ws logic straight.  This implementation
   // is very slow.  Will need to replace edit rules impl with a more efficient
@@ -292,17 +312,17 @@ WSRunObject::InsertText(nsIDocument& aDo
     AutoTrackDOMPoint tracker(mHTMLEditor->mRangeUpdater, &pointToInsert);
 
     // Handle any changes needed to ws run after inserted text
     if (!afterRun || afterRun->mType & WSType::trailingWS) {
       // Don't need to do anything.  Just insert text.  ws won't change.
     } else if (afterRun->mType & WSType::leadingWS) {
       // Delete the leading ws that is after insertion point, because it
       // would become significant after text inserted.
-      nsresult rv = DeleteRange(pointToInsert.AsRaw(), afterRun->EndPoint());
+      nsresult rv = DeleteRange(pointToInsert, afterRun->EndPoint());
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
     } else if (afterRun->mType == WSType::normalWS) {
       // Try to change an nbsp to a space, if possible, just to prevent nbsp
       // proliferation
       nsresult rv = CheckLeadingNBSP(afterRun, pointToInsert.GetContainer(),
                                      pointToInsert.Offset());
@@ -310,25 +330,25 @@ WSRunObject::InsertText(nsIDocument& aDo
     }
 
     // Handle any changes needed to ws run before inserted text
     if (!beforeRun || beforeRun->mType & WSType::leadingWS) {
       // Don't need to do anything.  Just insert text.  ws won't change.
     } else if (beforeRun->mType & WSType::trailingWS) {
       // Need to delete the trailing ws that is before insertion point, because
       // it would become significant after text inserted.
-      nsresult rv = DeleteRange(beforeRun->StartPoint(), pointToInsert.AsRaw());
+      nsresult rv = DeleteRange(beforeRun->StartPoint(), pointToInsert);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
     } else if (beforeRun->mType == WSType::normalWS) {
       // Try to change an nbsp to a space, if possible, just to prevent nbsp
       // proliferation
       nsresult rv =
-        ReplacePreviousNBSPIfUnncessary(beforeRun, pointToInsert.AsRaw());
+        ReplacePreviousNBSPIfUnncessary(beforeRun, pointToInsert);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
     }
 
     // After this block, pointToInsert is modified by AutoTrackDOMPoint.
   }
 
@@ -337,17 +357,17 @@ WSRunObject::InsertText(nsIDocument& aDo
   // ws char into an nbsp:
 
   if (nsCRT::IsAsciiSpace(theString[0])) {
     // We have a leading space
     if (beforeRun) {
       if (beforeRun->mType & WSType::leadingWS) {
         theString.SetCharAt(kNBSP, 0);
       } else if (beforeRun->mType & WSType::normalWS) {
-        WSPoint wspoint = GetPreviousCharPoint(pointToInsert.AsRaw());
+        WSPoint wspoint = GetPreviousCharPoint(pointToInsert);
         if (wspoint.mTextNode && nsCRT::IsAsciiSpace(wspoint.mChar)) {
           theString.SetCharAt(kNBSP, 0);
         }
       }
     } else if (mStartReason & WSType::block || mStartReason == WSType::br) {
       theString.SetCharAt(kNBSP, 0);
     }
   }
@@ -356,17 +376,17 @@ WSRunObject::InsertText(nsIDocument& aDo
   uint32_t lastCharIndex = theString.Length() - 1;
 
   if (nsCRT::IsAsciiSpace(theString[lastCharIndex])) {
     // We have a leading space
     if (afterRun) {
       if (afterRun->mType & WSType::trailingWS) {
         theString.SetCharAt(kNBSP, lastCharIndex);
       } else if (afterRun->mType & WSType::normalWS) {
-        WSPoint wspoint = GetNextCharPoint(pointToInsert.AsRaw());
+        WSPoint wspoint = GetNextCharPoint(pointToInsert);
         if (wspoint.mTextNode && nsCRT::IsAsciiSpace(wspoint.mChar)) {
           theString.SetCharAt(kNBSP, lastCharIndex);
         }
       }
     } else if (mEndReason & WSType::block) {
       theString.SetCharAt(kNBSP, lastCharIndex);
     }
   }
@@ -386,17 +406,17 @@ WSRunObject::InsertText(nsIDocument& aDo
       }
     } else {
       prevWS = false;
     }
   }
 
   // Ready, aim, fire!
   nsresult rv =
-    mHTMLEditor->InsertTextImpl(aDocument, theString, pointToInsert.AsRaw(),
+    mHTMLEditor->InsertTextImpl(aDocument, theString, pointToInsert,
                                 aPointAfterInsertedString);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return NS_OK;
   }
   return NS_OK;
 }
 
 nsresult
@@ -1320,19 +1340,20 @@ WSRunObject::PrepareToSplitAcrossBlocksP
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
     }
   }
   return NS_OK;
 }
 
+template<typename PT1, typename CT1, typename PT2, typename CT2>
 nsresult
-WSRunObject::DeleteRange(const EditorRawDOMPoint& aStartPoint,
-                         const EditorRawDOMPoint& aEndPoint)
+WSRunObject::DeleteRange(const EditorDOMPointBase<PT1, CT1>& aStartPoint,
+                         const EditorDOMPointBase<PT2, CT2>& aEndPoint)
 {
   if (NS_WARN_IF(!aStartPoint.IsSet()) ||
       NS_WARN_IF(!aEndPoint.IsSet())) {
     return NS_ERROR_INVALID_ARG;
   }
   MOZ_ASSERT(aStartPoint.IsSetAndValid());
   MOZ_ASSERT(aEndPoint.IsSetAndValid());
 
@@ -1903,19 +1924,21 @@ WSRunObject::CheckTrailingNBSPOfRun(WSFr
         htmlEditor->InsertTextIntoTextNodeImpl(nsDependentSubstring(&kNBSP, 1),
                                                *startNode, startOffset, true);
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
   return NS_OK;
 }
 
+template<typename PT, typename CT>
 nsresult
-WSRunObject::ReplacePreviousNBSPIfUnncessary(WSFragment* aRun,
-                                             const EditorRawDOMPoint& aPoint)
+WSRunObject::ReplacePreviousNBSPIfUnncessary(
+               WSFragment* aRun,
+               const EditorDOMPointBase<PT, CT>& aPoint)
 {
   if (NS_WARN_IF(!aRun) ||
       NS_WARN_IF(!aPoint.IsSet())) {
     return NS_ERROR_INVALID_ARG;
   }
   MOZ_ASSERT(aPoint.IsSetAndValid());
 
   // Try to change an NBSP to a space, if possible, just to prevent NBSP
--- a/editor/libeditor/WSRunObject.h
+++ b/editor/libeditor/WSRunObject.h
@@ -225,19 +225,20 @@ public:
    * @param aSelect         If eNone, this won't change selection.
    *                        If eNext, selection will be collapsed after the
    *                        <br> element.
    *                        If ePrevious, selection will be collapsed at the
    *                        <br> element.
    * @return                The new <br> node.  If failed to create new <br>
    *                        node, returns nullptr.
    */
+  template<typename PT, typename CT>
   already_AddRefed<dom::Element>
   InsertBreak(Selection& aSelection,
-              const EditorRawDOMPoint& aPointToInsert,
+              const EditorDOMPointBase<PT, CT>& aPointToInsert,
               nsIEditor::EDirection aSelect);
 
   /**
    * InsertTextImpl() inserts aStringToInsert to aPointToInsert and makes any
    * needed adjustments to white spaces around that point. E.g., trailing white
    * spaces before aPointToInsert needs to be removed.
    * This calls EditorBase::InsertTextImpl() after adjusting white spaces.
    * So, please refer the method's explanation to know what this method exactly
@@ -251,19 +252,20 @@ public:
    *                        The point after inserted aStringToInsert.
    *                        So, when this method actually inserts string,
    *                        this is set to a point in the text node.
    *                        Otherwise, this may be set to aPointToInsert.
    * @return                When this succeeds to insert the string or
    *                        does nothing during composition, returns NS_OK.
    *                        Otherwise, an error code.
    */
+  template<typename PT, typename CT>
   nsresult InsertText(nsIDocument& aDocument,
                       const nsAString& aStringToInsert,
-                      const EditorRawDOMPoint& aPointToInsert,
+                      const EditorDOMPointBase<PT, CT>& aPointToInsert,
                       EditorRawDOMPoint* aPointAfterInsertedString = nullptr);
 
   // DeleteWSBackward deletes a single visible piece of ws before the ws
   // point (the point to create the wsRunObject, passed to its constructor).
   // It makes any needed conversion to adjacent ws to retain its
   // significance.
   nsresult DeleteWSBackward();
 
@@ -376,18 +378,19 @@ protected:
    * DeleteRange() removes the range between aStartPoint and aEndPoint.
    * When aStartPoint and aEndPoint are same point, does nothing.
    * When aStartPoint and aEndPoint are in same text node, removes characters
    * between them.
    * When aStartPoint is in a text node, removes the text data after the point.
    * When aEndPoint is in a text node, removes the text data before the point.
    * Removes any nodes between them.
    */
-  nsresult DeleteRange(const EditorRawDOMPoint& aStartPoint,
-                       const EditorRawDOMPoint& aEndPoint);
+  template<typename PT1, typename CT1, typename PT2, typename CT2>
+  nsresult DeleteRange(const EditorDOMPointBase<PT1, CT1>& aStartPoint,
+                       const EditorDOMPointBase<PT2, CT2>& aEndPoint);
 
   /**
    * GetNextCharPoint() returns next character's point of aPoint.  If there is
    * no character after aPoint, mTextNode is set to nullptr.
    */
   template<typename PT, typename CT>
   WSPoint GetNextCharPoint(const EditorDOMPointBase<PT, CT>& aPoint);
   WSPoint GetNextCharPoint(const WSPoint& aPoint);
@@ -481,18 +484,20 @@ protected:
   /**
    * ReplacePreviousNBSPIfUnncessary() replaces previous character of aPoint
    * if it's a NBSP and it's unnecessary.
    *
    * @param aRun        Current text run.  aPoint must be in this run.
    * @param aPoint      Current insertion point.  Its previous character is
    *                    unnecessary NBSP will be checked.
    */
-  nsresult ReplacePreviousNBSPIfUnncessary(WSFragment* aRun,
-                                           const EditorRawDOMPoint& aPoint);
+  template<typename PT, typename CT>
+  nsresult
+  ReplacePreviousNBSPIfUnncessary(WSFragment* aRun,
+                                  const EditorDOMPointBase<PT, CT>& aPoint);
 
   nsresult CheckLeadingNBSP(WSFragment* aRun, nsINode* aNode,
                             int32_t aOffset);
 
   nsresult Scrub();
   bool IsBlockNode(nsINode* aNode);
 
   EditorRawDOMPoint Point() const