Bug 1088054 part 2 - Reduce nsIDOMRange use in editor/; r=ehsan
authorAryeh Gregor <ayg@aryeh.name>
Sun, 02 Nov 2014 14:04:13 +0200
changeset 213506 e1d2814c9e7bd8af4f6df5ae143a71f850d16d94
parent 213505 311c0ed7a8d29f1e45414aa7424faad9fbd7d181
child 213507 658f4c23de2a33dcbb452d2320a0146461ab5b31
push id27753
push userphilringnalda@gmail.com
push dateSun, 02 Nov 2014 16:27:30 +0000
treeherdermozilla-central@443853a35898 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs1088054
milestone36.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1088054 part 2 - Reduce nsIDOMRange use in editor/; r=ehsan
editor/composer/nsEditorSpellCheck.cpp
editor/libeditor/DeleteRangeTxn.cpp
editor/libeditor/nsEditor.cpp
editor/libeditor/nsEditor.h
editor/libeditor/nsEditorEventListener.cpp
editor/libeditor/nsEditorUtils.cpp
editor/libeditor/nsEditorUtils.h
editor/libeditor/nsHTMLDataTransfer.cpp
editor/libeditor/nsHTMLEditRules.cpp
editor/libeditor/nsHTMLEditRules.h
editor/libeditor/nsHTMLEditor.cpp
editor/libeditor/nsHTMLEditor.h
editor/libeditor/nsHTMLEditorEventListener.cpp
editor/libeditor/nsHTMLEditorStyle.cpp
editor/libeditor/nsPlaintextDataTransfer.cpp
editor/libeditor/nsSelectionState.cpp
editor/libeditor/nsSelectionState.h
editor/libeditor/nsTableEditor.cpp
editor/txtsvc/nsFilteredContentIterator.cpp
editor/txtsvc/nsFilteredContentIterator.h
editor/txtsvc/nsTextServicesDocument.cpp
editor/txtsvc/nsTextServicesDocument.h
--- a/editor/composer/nsEditorSpellCheck.cpp
+++ b/editor/composer/nsEditorSpellCheck.cpp
@@ -5,52 +5,54 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <stdlib.h>                     // for getenv
 
 #include "mozilla/Attributes.h"         // for MOZ_FINAL
 #include "mozilla/Preferences.h"        // for Preferences
 #include "mozilla/Services.h"           // for GetXULChromeRegistryService
 #include "mozilla/dom/Element.h"        // for Element
+#include "mozilla/dom/Selection.h"
 #include "mozilla/mozalloc.h"           // for operator delete, etc
 #include "nsAString.h"                  // for nsAString_internal::IsEmpty, etc
 #include "nsComponentManagerUtils.h"    // for do_CreateInstance
 #include "nsDebug.h"                    // for NS_ENSURE_TRUE, etc
 #include "nsDependentSubstring.h"       // for Substring
 #include "nsEditorSpellCheck.h"
 #include "nsError.h"                    // for NS_ERROR_NOT_INITIALIZED, etc
 #include "nsIChromeRegistry.h"          // for nsIXULChromeRegistry
 #include "nsIContent.h"                 // for nsIContent
 #include "nsIContentPrefService.h"      // for nsIContentPrefService, etc
 #include "nsIContentPrefService2.h"     // for nsIContentPrefService2, etc
 #include "nsIDOMDocument.h"             // for nsIDOMDocument
 #include "nsIDOMElement.h"              // for nsIDOMElement
-#include "nsIDOMRange.h"                // for nsIDOMRange
 #include "nsIDocument.h"                // for nsIDocument
 #include "nsIEditor.h"                  // for nsIEditor
 #include "nsIHTMLEditor.h"              // for nsIHTMLEditor
 #include "nsILoadContext.h"
 #include "nsISelection.h"               // for nsISelection
 #include "nsISpellChecker.h"            // for nsISpellChecker, etc
 #include "nsISupportsBase.h"            // for nsISupports
 #include "nsISupportsUtils.h"           // for NS_ADDREF
 #include "nsITextServicesDocument.h"    // for nsITextServicesDocument
 #include "nsITextServicesFilter.h"      // for nsITextServicesFilter
 #include "nsIURI.h"                     // for nsIURI
 #include "nsIVariant.h"                 // for nsIWritableVariant, etc
 #include "nsLiteralString.h"            // for NS_LITERAL_STRING, etc
 #include "nsMemory.h"                   // for nsMemory
+#include "nsRange.h"
 #include "nsReadableUtils.h"            // for ToNewUnicode, EmptyString, etc
 #include "nsServiceManagerUtils.h"      // for do_GetService
 #include "nsString.h"                   // for nsAutoString, nsString, etc
 #include "nsStringFwd.h"                // for nsAFlatString
 #include "nsStyleUtil.h"                // for nsStyleUtil
 #include "nsXULAppAPI.h"                // for XRE_GetProcessType
 
 using namespace mozilla;
+using namespace mozilla::dom;
 
 class UpdateDictionaryHolder {
   private:
     nsEditorSpellCheck* mSpellCheck;
   public:
     explicit UpdateDictionaryHolder(nsEditorSpellCheck* esc): mSpellCheck(esc) {
       if (mSpellCheck) {
         mSpellCheck->BeginUpdateDictionary();
@@ -338,45 +340,39 @@ nsEditorSpellCheck::InitSpellChecker(nsI
   // Pass the editor to the text services document
   rv = tsDoc->InitWithEditor(aEditor);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (aEnableSelectionChecking) {
     // Find out if the section is collapsed or not.
     // If it isn't, we want to spellcheck just the selection.
 
-    nsCOMPtr<nsISelection> selection;
-
-    rv = aEditor->GetSelection(getter_AddRefs(selection));
-    NS_ENSURE_SUCCESS(rv, rv);
+    nsCOMPtr<nsISelection> domSelection;
+    aEditor->GetSelection(getter_AddRefs(domSelection));
+    nsRefPtr<Selection> selection = static_cast<Selection*>(domSelection.get());
     NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
 
     int32_t count = 0;
 
     rv = selection->GetRangeCount(&count);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (count > 0) {
-      nsCOMPtr<nsIDOMRange> range;
-
-      rv = selection->GetRangeAt(0, getter_AddRefs(range));
-      NS_ENSURE_SUCCESS(rv, rv);
+      nsRefPtr<nsRange> range = selection->GetRangeAt(0);
+      NS_ENSURE_STATE(range);
 
       bool collapsed = false;
       rv = range->GetCollapsed(&collapsed);
       NS_ENSURE_SUCCESS(rv, rv);
 
       if (!collapsed) {
         // We don't want to touch the range in the selection,
         // so create a new copy of it.
 
-        nsCOMPtr<nsIDOMRange> rangeBounds;
-        rv =  range->CloneRange(getter_AddRefs(rangeBounds));
-        NS_ENSURE_SUCCESS(rv, rv);
-        NS_ENSURE_TRUE(rangeBounds, NS_ERROR_FAILURE);
+        nsRefPtr<nsRange> rangeBounds = range->CloneRange();
 
         // Make sure the new range spans complete words.
 
         rv = tsDoc->ExpandRangeToWordBoundaries(rangeBounds);
         NS_ENSURE_SUCCESS(rv, rv);
 
         // Now tell the text services that you only want
         // to iterate over the text in this range.
--- a/editor/libeditor/DeleteRangeTxn.cpp
+++ b/editor/libeditor/DeleteRangeTxn.cpp
@@ -14,18 +14,16 @@
 #include "nsEditor.h"
 #include "nsError.h"
 #include "nsIContent.h"
 #include "nsIContentIterator.h"
 #include "nsIDOMCharacterData.h"
 #include "nsINode.h"
 #include "nsAString.h"
 
-class nsIDOMRange;
-
 using namespace mozilla;
 using namespace mozilla::dom;
 
 // note that aEditor is not refcounted
 DeleteRangeTxn::DeleteRangeTxn()
   : EditAggregateTxn(),
     mRange(),
     mEditor(nullptr),
--- a/editor/libeditor/nsEditor.cpp
+++ b/editor/libeditor/nsEditor.cpp
@@ -61,17 +61,16 @@
 #include "nsIDOMEventListener.h"        // for nsIDOMEventListener
 #include "nsIDOMEventTarget.h"          // for nsIDOMEventTarget
 #include "nsIDOMHTMLElement.h"          // for nsIDOMHTMLElement
 #include "nsIDOMKeyEvent.h"             // for nsIDOMKeyEvent, etc
 #include "nsIDOMMozNamedAttrMap.h"      // for nsIDOMMozNamedAttrMap
 #include "nsIDOMMouseEvent.h"           // for nsIDOMMouseEvent
 #include "nsIDOMNode.h"                 // for nsIDOMNode, etc
 #include "nsIDOMNodeList.h"             // for nsIDOMNodeList
-#include "nsIDOMRange.h"                // for nsIDOMRange
 #include "nsIDOMText.h"                 // for nsIDOMText
 #include "nsIDocument.h"                // for nsIDocument
 #include "nsIDocumentStateListener.h"   // for nsIDocumentStateListener
 #include "nsIEditActionListener.h"      // for nsIEditActionListener
 #include "nsIEditorObserver.h"          // for nsIEditorObserver
 #include "nsIEditorSpellCheck.h"        // for nsIEditorSpellCheck
 #include "nsIFrame.h"                   // for nsIFrame
 #include "nsIHTMLDocument.h"            // for nsIHTMLDocument
@@ -4388,17 +4387,17 @@ nsEditor::CreateTxnForDeleteInsertionPoi
   }
 
   return NS_OK;
 }
 
 nsresult 
 nsEditor::CreateRange(nsIDOMNode *aStartParent, int32_t aStartOffset,
                       nsIDOMNode *aEndParent, int32_t aEndOffset,
-                      nsIDOMRange **aRange)
+                      nsRange** aRange)
 {
   return nsRange::CreateRange(aStartParent, aStartOffset, aEndParent,
                               aEndOffset, aRange);
 }
 
 nsresult 
 nsEditor::AppendNodeToSelectionAsRange(nsIDOMNode *aNode)
 {
@@ -4408,17 +4407,17 @@ nsEditor::AppendNodeToSelectionAsRange(n
 
   nsCOMPtr<nsIDOMNode> parentNode;
   nsresult res = aNode->GetParentNode(getter_AddRefs(parentNode));
   NS_ENSURE_SUCCESS(res, res);
   NS_ENSURE_TRUE(parentNode, NS_ERROR_NULL_POINTER);
   
   int32_t offset = GetChildOffset(aNode, parentNode);
   
-  nsCOMPtr<nsIDOMRange> range;
+  nsRefPtr<nsRange> range;
   res = CreateRange(parentNode, offset, parentNode, offset+1, getter_AddRefs(range));
   NS_ENSURE_SUCCESS(res, res);
   NS_ENSURE_TRUE(range, NS_ERROR_NULL_POINTER);
 
   return selection->AddRange(range);
 }
 
 nsresult nsEditor::ClearSelection()
--- a/editor/libeditor/nsEditor.h
+++ b/editor/libeditor/nsEditor.h
@@ -37,17 +37,16 @@ class nsIDOMCharacterData;
 class nsIDOMDataTransfer;
 class nsIDOMDocument;
 class nsIDOMElement;
 class nsIDOMEvent;
 class nsIDOMEventListener;
 class nsIDOMEventTarget;
 class nsIDOMKeyEvent;
 class nsIDOMNode;
-class nsIDOMRange;
 class nsIDocument;
 class nsIDocumentStateListener;
 class nsIEditActionListener;
 class nsIEditorObserver;
 class nsIInlineSpellChecker;
 class nsINode;
 class nsIPresShell;
 class nsISupports;
@@ -620,17 +619,17 @@ public:
   static void DumpNode(nsIDOMNode *aNode, int32_t indent=0);
 #endif
   mozilla::dom::Selection* GetSelection();
 
   // Helpers to add a node to the selection. 
   // Used by table cell selection methods
   nsresult CreateRange(nsIDOMNode *aStartParent, int32_t aStartOffset,
                        nsIDOMNode *aEndParent, int32_t aEndOffset,
-                       nsIDOMRange **aRange);
+                       nsRange** aRange);
 
   // Creates a range with just the supplied node and appends that to the selection
   nsresult AppendNodeToSelectionAsRange(nsIDOMNode *aNode);
   // When you are using AppendNodeToSelectionAsRange, call this first to start a new selection
   nsresult ClearSelection();
 
   nsresult IsPreformatted(nsIDOMNode *aNode, bool *aResult);
 
--- a/editor/libeditor/nsEditorEventListener.cpp
+++ b/editor/libeditor/nsEditorEventListener.cpp
@@ -27,33 +27,33 @@
 #include "nsIDOMDocument.h"             // for nsIDOMDocument
 #include "nsIDOMDragEvent.h"            // for nsIDOMDragEvent
 #include "nsIDOMElement.h"              // for nsIDOMElement
 #include "nsIDOMEvent.h"                // for nsIDOMEvent
 #include "nsIDOMEventTarget.h"          // for nsIDOMEventTarget
 #include "nsIDOMKeyEvent.h"             // for nsIDOMKeyEvent
 #include "nsIDOMMouseEvent.h"           // for nsIDOMMouseEvent
 #include "nsIDOMNode.h"                 // for nsIDOMNode
-#include "nsIDOMRange.h"                // for nsIDOMRange
 #include "nsIDocument.h"                // for nsIDocument
 #include "nsIEditor.h"                  // for nsEditor::GetSelection, etc
 #include "nsIEditorIMESupport.h"
 #include "nsIEditorMailSupport.h"       // for nsIEditorMailSupport
 #include "nsIFocusManager.h"            // for nsIFocusManager
 #include "nsIFormControl.h"             // for nsIFormControl, etc
 #include "nsIHTMLEditor.h"              // for nsIHTMLEditor
 #include "nsINode.h"                    // for nsINode, ::NODE_IS_EDITABLE, etc
 #include "nsIPlaintextEditor.h"         // for nsIPlaintextEditor, etc
 #include "nsIPresShell.h"               // for nsIPresShell
 #include "nsISelectionController.h"     // for nsISelectionController, etc
 #include "nsITransferable.h"            // for kFileMime, kHTMLMime, etc
 #include "nsIWidget.h"                  // for nsIWidget
 #include "nsLiteralString.h"            // for NS_LITERAL_STRING
 #include "nsPIWindowRoot.h"             // for nsPIWindowRoot
 #include "nsPrintfCString.h"            // for nsPrintfCString
+#include "nsRange.h"
 #include "nsServiceManagerUtils.h"      // for do_GetService
 #include "nsString.h"                   // for nsAutoString
 #ifdef HANDLE_NATIVE_TEXT_DIRECTION_SWITCH
 #include "nsContentUtils.h"             // for nsContentUtils, etc
 #include "nsIBidiKeyboard.h"            // for nsIBidiKeyboard
 #endif
 
 class nsPresContext;
@@ -1002,19 +1002,18 @@ nsEditorEventListener::CanDrop(nsIDOMDra
   rv = aEvent->GetRangeOffset(&offset);
   NS_ENSURE_SUCCESS(rv, false);
 
   int32_t rangeCount;
   rv = selection->GetRangeCount(&rangeCount);
   NS_ENSURE_SUCCESS(rv, false);
 
   for (int32_t i = 0; i < rangeCount; i++) {
-    nsCOMPtr<nsIDOMRange> range;
-    rv = selection->GetRangeAt(i, getter_AddRefs(range));
-    if (NS_FAILED(rv) || !range) {
+    nsRefPtr<nsRange> range = selection->GetRangeAt(i);
+    if (!range) {
       // Don't bail yet, iterate through them all
       continue;
     }
 
     bool inRange = true;
     range->IsPointInRange(parent, offset, &inRange);
     if (inRange) {
       // Okay, now you can bail, we are over the orginal selection
--- a/editor/libeditor/nsEditorUtils.cpp
+++ b/editor/libeditor/nsEditorUtils.cpp
@@ -15,18 +15,18 @@
 #include "nsIContentIterator.h"
 #include "nsIDOMDocument.h"
 #include "nsIDocShell.h"
 #include "nsIDocument.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsINode.h"
 #include "nsISimpleEnumerator.h"
 
-class nsIDOMRange;
 class nsISupports;
+class nsRange;
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 /******************************************************************************
  * nsAutoSelectionReset
  *****************************************************************************/
 
@@ -70,17 +70,17 @@ mIter(nullptr)
 {
 }
     
 nsDOMIterator::~nsDOMIterator()
 {
 }
     
 nsresult
-nsDOMIterator::Init(nsIDOMRange* aRange)
+nsDOMIterator::Init(nsRange* aRange)
 {
   nsresult res;
   mIter = do_CreateInstance("@mozilla.org/content/post-content-iterator;1", &res);
   NS_ENSURE_SUCCESS(res, res);
   NS_ENSURE_TRUE(mIter, NS_ERROR_FAILURE);
   return mIter->Init(aRange);
 }
 
@@ -120,17 +120,17 @@ nsDOMSubtreeIterator::nsDOMSubtreeIterat
 {
 }
     
 nsDOMSubtreeIterator::~nsDOMSubtreeIterator()
 {
 }
     
 nsresult
-nsDOMSubtreeIterator::Init(nsIDOMRange* aRange)
+nsDOMSubtreeIterator::Init(nsRange* aRange)
 {
   nsresult res;
   mIter = do_CreateInstance("@mozilla.org/content/subtree-content-iterator;1", &res);
   NS_ENSURE_SUCCESS(res, res);
   NS_ENSURE_TRUE(mIter, NS_ERROR_FAILURE);
   return mIter->Init(aRange);
 }
 
--- a/editor/libeditor/nsEditorUtils.h
+++ b/editor/libeditor/nsEditorUtils.h
@@ -13,17 +13,17 @@
 #include "nsEditor.h"
 #include "nsIDOMNode.h"
 #include "nsIEditor.h"
 #include "nscore.h"
 
 class nsIAtom;
 class nsIContentIterator;
 class nsIDOMDocument;
-class nsIDOMRange;
+class nsRange;
 template <class E> class nsCOMArray;
 namespace mozilla {
 namespace dom {
 class Selection;
 }
 }
 
 /***************************************************************************
@@ -171,31 +171,31 @@ class nsBoolDomIterFunctor
 };
 
 class MOZ_STACK_CLASS nsDOMIterator
 {
   public:
     nsDOMIterator();
     virtual ~nsDOMIterator();
     
-    nsresult Init(nsIDOMRange* aRange);
+    nsresult Init(nsRange* aRange);
     nsresult Init(nsIDOMNode* aNode);
     nsresult AppendList(nsBoolDomIterFunctor& functor,
                         nsCOMArray<nsIDOMNode>& arrayOfNodes) const;
   protected:
     nsCOMPtr<nsIContentIterator> mIter;
 };
 
 class MOZ_STACK_CLASS nsDOMSubtreeIterator : public nsDOMIterator
 {
   public:
     nsDOMSubtreeIterator();
     virtual ~nsDOMSubtreeIterator();
 
-    nsresult Init(nsIDOMRange* aRange);
+    nsresult Init(nsRange* aRange);
 };
 
 class nsTrivialFunctor : public nsBoolDomIterFunctor
 {
   public:
     virtual bool operator()(nsIDOMNode* aNode)  // used to build list of all nodes iterator covers
     {
       return true;
--- a/editor/libeditor/nsHTMLDataTransfer.cpp
+++ b/editor/libeditor/nsHTMLDataTransfer.cpp
@@ -43,17 +43,16 @@
 #include "nsIDOMHTMLFrameElement.h"
 #include "nsIDOMHTMLIFrameElement.h"
 #include "nsIDOMHTMLImageElement.h"
 #include "nsIDOMHTMLInputElement.h"
 #include "nsIDOMHTMLLinkElement.h"
 #include "nsIDOMHTMLObjectElement.h"
 #include "nsIDOMHTMLScriptElement.h"
 #include "nsIDOMNode.h"
-#include "nsIDOMRange.h"
 #include "nsIDocument.h"
 #include "nsIEditor.h"
 #include "nsIEditorIMESupport.h"
 #include "nsIEditorMailSupport.h"
 #include "nsIFile.h"
 #include "nsIInputStream.h"
 #include "nsIMIMEService.h"
 #include "nsNameSpaceManager.h"
@@ -163,19 +162,17 @@ NS_IMETHODIMP nsHTMLEditor::LoadHTML(con
   {
     // Delete Selection, but only if it isn't collapsed, see bug #106269
     if (!selection->Collapsed()) {
       rv = DeleteSelection(eNone, eStrip);
       NS_ENSURE_SUCCESS(rv, rv);
     }
 
     // Get the first range in the selection, for context:
-    nsCOMPtr<nsIDOMRange> range;
-    rv = selection->GetRangeAt(0, getter_AddRefs(range));
-    NS_ENSURE_SUCCESS(rv, rv);
+    nsRefPtr<nsRange> range = selection->GetRangeAt(0);
     NS_ENSURE_TRUE(range, NS_ERROR_NULL_POINTER);
 
     // create fragment for pasted html
     nsCOMPtr<nsIDOMDocumentFragment> docfrag;
     {
       rv = range->CreateContextualFragment(aInputString, getter_AddRefs(docfrag));
       NS_ENSURE_SUCCESS(rv, rv);
     }
--- a/editor/libeditor/nsHTMLEditRules.cpp
+++ b/editor/libeditor/nsHTMLEditRules.cpp
@@ -31,17 +31,16 @@
 #include "nsIAtom.h"
 #include "nsIContent.h"
 #include "nsIContentIterator.h"
 #include "nsID.h"
 #include "nsIDOMCharacterData.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMNode.h"
-#include "nsIDOMRange.h"
 #include "nsIDOMText.h"
 #include "nsIHTMLAbsPosEditor.h"
 #include "nsIHTMLDocument.h"
 #include "nsINode.h"
 #include "nsLiteralString.h"
 #include "nsPlaintextEditor.h"
 #include "nsRange.h"
 #include "nsReadableUtils.h"
@@ -828,17 +827,17 @@ nsHTMLEditRules::GetAlignment(bool *aMix
   } else if (parent->Tag() == nsGkAtoms::html && offset == rootOffset) {
     // if we have selected the body, let's look at the first editable node
     NS_ENSURE_STATE(mHTMLEditor);
     nodeToExamine =
       GetAsDOMNode(mHTMLEditor->GetNextNode(parent, offset, true));
   }
   else
   {
-    nsCOMArray<nsIDOMRange> arrayOfRanges;
+    nsTArray<nsRefPtr<nsRange>> arrayOfRanges;
     res = GetPromotedRanges(selection, arrayOfRanges, EditAction::align);
     NS_ENSURE_SUCCESS(res, res);
 
     // use these ranges to construct a list of nodes to act on.
     nsCOMArray<nsIDOMNode> arrayOfNodes;
     res = GetNodesForOperation(arrayOfRanges, arrayOfNodes,
                                EditAction::align, true);
     NS_ENSURE_SUCCESS(res, res);                                 
@@ -2015,36 +2014,26 @@ nsHTMLEditRules::WillDeleteSelection(Sel
           if (NS_IS_LOW_SURROGATE(text->CharAt(so)) &&
               NS_IS_HIGH_SURROGATE(text->CharAt(so - 1))) {
             so--;
           }
         }
       }
       else
       {
-        nsCOMPtr<nsIDOMRange> range;
-        res = aSelection->GetRangeAt(0, getter_AddRefs(range));
-        NS_ENSURE_SUCCESS(res, res);
-
-#ifdef DEBUG
-        nsIDOMNode *container;
-
-        res = range->GetStartContainer(&container);
-        NS_ENSURE_SUCCESS(res, res);
-        NS_ASSERTION(container == visNode, "selection start not in visNode");
-
-        res = range->GetEndContainer(&container);
-        NS_ENSURE_SUCCESS(res, res);
-        NS_ASSERTION(container == visNode, "selection end not in visNode");
-#endif
-
-        res = range->GetStartOffset(&so);
-        NS_ENSURE_SUCCESS(res, res);
-        res = range->GetEndOffset(&eo);
-        NS_ENSURE_SUCCESS(res, res);
+        nsRefPtr<nsRange> range = aSelection->GetRangeAt(0);
+        NS_ENSURE_STATE(range);
+
+        NS_ASSERTION(GetAsDOMNode(range->GetStartParent()) == visNode,
+                     "selection start not in visNode");
+        NS_ASSERTION(GetAsDOMNode(range->GetEndParent()) == visNode,
+                     "selection end not in visNode");
+
+        so = range->StartOffset();
+        eo = range->EndOffset();
       }
       NS_ENSURE_STATE(mHTMLEditor);
       res = nsWSRunObject::PrepareToDeleteRange(mHTMLEditor,
           address_of(visNode_), &so, address_of(visNode_), &eo);
       NS_ENSURE_SUCCESS(res, res);
       visNode = GetAsDOMNode(visNode_);
       NS_ENSURE_STATE(mHTMLEditor);
       res = mHTMLEditor->DeleteText(*nodeAsText, std::min(so, eo),
@@ -3446,17 +3435,17 @@ nsHTMLEditRules::WillRemoveList(Selectio
   *aCancel = false;
   *aHandled = true;
   
   nsresult res = NormalizeSelection(aSelection);
   NS_ENSURE_SUCCESS(res, res);
   NS_ENSURE_STATE(mHTMLEditor);
   nsAutoSelectionReset selectionResetter(aSelection, mHTMLEditor);
   
-  nsCOMArray<nsIDOMRange> arrayOfRanges;
+  nsTArray<nsRefPtr<nsRange>> arrayOfRanges;
   res = GetPromotedRanges(aSelection, arrayOfRanges, EditAction::makeList);
   NS_ENSURE_SUCCESS(res, res);
   
   // use these ranges to contruct a list of nodes to act on.
   nsCOMArray<nsIDOMNode> arrayOfNodes;
   res = GetListActionNodes(arrayOfNodes, false);
   NS_ENSURE_SUCCESS(res, res);                                 
                                      
@@ -3720,17 +3709,17 @@ nsHTMLEditRules::WillCSSIndent(Selection
   // we want to ignore result of WillInsert()
   *aCancel = false;
   *aHandled = true;
 
   res = NormalizeSelection(aSelection);
   NS_ENSURE_SUCCESS(res, res);
   NS_ENSURE_STATE(mHTMLEditor);
   nsAutoSelectionReset selectionResetter(aSelection, mHTMLEditor);
-  nsCOMArray<nsIDOMRange>  arrayOfRanges;
+  nsTArray<nsRefPtr<nsRange>> arrayOfRanges;
   nsCOMArray<nsIDOMNode> arrayOfNodes;
   
   // short circuit: detect case of collapsed selection inside an <li>.
   // just sublist that <li>.  This prevents bug 97797.
   
   nsCOMPtr<nsIDOMNode> liNode;
   if (aSelection->Collapsed()) {
     nsCOMPtr<nsIDOMNode> node, block;
@@ -3932,17 +3921,17 @@ nsHTMLEditRules::WillHTMLIndent(Selectio
   NS_ENSURE_STATE(mHTMLEditor);
   nsAutoSelectionReset selectionResetter(aSelection, mHTMLEditor);
   
   // convert the selection ranges into "promoted" selection ranges:
   // this basically just expands the range to include the immediate
   // block parent, and then further expands to include any ancestors
   // whose children are all in the range
   
-  nsCOMArray<nsIDOMRange> arrayOfRanges;
+  nsTArray<nsRefPtr<nsRange>> arrayOfRanges;
   res = GetPromotedRanges(aSelection, arrayOfRanges, EditAction::indent);
   NS_ENSURE_SUCCESS(res, res);
   
   // use these ranges to contruct a list of nodes to act on.
   nsCOMArray<nsIDOMNode> arrayOfNodes;
   res = GetNodesForOperation(arrayOfRanges, arrayOfNodes, EditAction::indent);
   NS_ENSURE_SUCCESS(res, res);                                 
                                      
@@ -5287,19 +5276,17 @@ nsHTMLEditRules::ExpandSelectionForDelet
   int32_t rangeCount;
   nsresult res = aSelection->GetRangeCount(&rangeCount);
   NS_ENSURE_SUCCESS(res, res);
   
   // we don't need to mess with cell selections, and we assume multirange selections are those.
   if (rangeCount != 1) return NS_OK;
   
   // find current sel start and end
-  nsCOMPtr<nsIDOMRange> range;
-  res = aSelection->GetRangeAt(0, getter_AddRefs(range));
-  NS_ENSURE_SUCCESS(res, res);
+  nsRefPtr<nsRange> range = aSelection->GetRangeAt(0);
   NS_ENSURE_TRUE(range, NS_ERROR_NULL_POINTER);
   nsCOMPtr<nsIDOMNode> selStartNode, selEndNode, selCommon;
   int32_t selStartOffset, selEndOffset;
   
   res = range->GetStartContainer(getter_AddRefs(selStartNode));
   NS_ENSURE_SUCCESS(res, res);
   res = range->GetStartOffset(&selStartOffset);
   NS_ENSURE_SUCCESS(res, res);
@@ -5468,19 +5455,17 @@ nsHTMLEditRules::NormalizeSelection(Sele
 
   int32_t rangeCount;
   nsresult res = inSelection->GetRangeCount(&rangeCount);
   NS_ENSURE_SUCCESS(res, res);
   
   // we don't need to mess with cell selections, and we assume multirange selections are those.
   if (rangeCount != 1) return NS_OK;
   
-  nsCOMPtr<nsIDOMRange> range;
-  res = inSelection->GetRangeAt(0, getter_AddRefs(range));
-  NS_ENSURE_SUCCESS(res, res);
+  nsRefPtr<nsRange> range = inSelection->GetRangeAt(0);
   NS_ENSURE_TRUE(range, NS_ERROR_NULL_POINTER);
   nsCOMPtr<nsIDOMNode> startNode, endNode;
   int32_t startOffset, endOffset;
   nsCOMPtr<nsIDOMNode> newStartNode, newEndNode;
   int32_t newStartOffset, newEndOffset;
   
   res = range->GetStartContainer(getter_AddRefs(startNode));
   NS_ENSURE_SUCCESS(res, res);
@@ -5795,59 +5780,57 @@ nsHTMLEditRules::GetPromotedPoint(RulesE
 
 
 ///////////////////////////////////////////////////////////////////////////
 // GetPromotedRanges: run all the selection range endpoint through 
 //                    GetPromotedPoint()
 //                       
 nsresult 
 nsHTMLEditRules::GetPromotedRanges(Selection* inSelection, 
-                                   nsCOMArray<nsIDOMRange> &outArrayOfRanges, 
+                                   nsTArray<nsRefPtr<nsRange>>& outArrayOfRanges, 
                                    EditAction inOperationType)
 {
   NS_ENSURE_TRUE(inSelection, NS_ERROR_NULL_POINTER);
 
   int32_t rangeCount;
   nsresult res = inSelection->GetRangeCount(&rangeCount);
   NS_ENSURE_SUCCESS(res, res);
   
   int32_t i;
-  nsCOMPtr<nsIDOMRange> selectionRange;
-  nsCOMPtr<nsIDOMRange> opRange;
+  nsRefPtr<nsRange> selectionRange;
+  nsRefPtr<nsRange> opRange;
 
   for (i = 0; i < rangeCount; i++)
   {
-    res = inSelection->GetRangeAt(i, getter_AddRefs(selectionRange));
-    NS_ENSURE_SUCCESS(res, res);
+    selectionRange = inSelection->GetRangeAt(i);
+    NS_ENSURE_STATE(selectionRange);
 
     // clone range so we don't muck with actual selection ranges
-    res = selectionRange->CloneRange(getter_AddRefs(opRange));
-    NS_ENSURE_SUCCESS(res, res);
+    opRange = selectionRange->CloneRange();
 
     // make a new adjusted range to represent the appropriate block content.
     // The basic idea is to push out the range endpoints
     // to truly enclose the blocks that we will affect.
     // This call alters opRange.
     res = PromoteRange(opRange, inOperationType);
     NS_ENSURE_SUCCESS(res, res);
       
     // stuff new opRange into array
-    outArrayOfRanges.AppendObject(opRange);
+    outArrayOfRanges.AppendElement(opRange);
   }
   return res;
 }
 
 
 ///////////////////////////////////////////////////////////////////////////
 // PromoteRange: expand a range to include any parents for which all
 //               editable children are already in range. 
 //                       
 nsresult 
-nsHTMLEditRules::PromoteRange(nsIDOMRange *inRange, 
-                              EditAction inOperationType)
+nsHTMLEditRules::PromoteRange(nsRange* inRange, EditAction inOperationType)
 {
   NS_ENSURE_TRUE(inRange, NS_ERROR_NULL_POINTER);
   nsresult res;
   nsCOMPtr<nsIDOMNode> startNode, endNode;
   int32_t startOffset, endOffset;
   
   res = inRange->GetStartContainer(getter_AddRefs(startNode));
   NS_ENSURE_SUCCESS(res, res);
@@ -5900,17 +5883,17 @@ nsHTMLEditRules::PromoteRange(nsIDOMRang
 
   // make a new adjusted range to represent the appropriate block content.
   // this is tricky.  the basic idea is to push out the range endpoints
   // to truly enclose the blocks that we will affect
   
   nsCOMPtr<nsIDOMNode> opStartNode;
   nsCOMPtr<nsIDOMNode> opEndNode;
   int32_t opStartOffset, opEndOffset;
-  nsCOMPtr<nsIDOMRange> opRange;
+  nsRefPtr<nsRange> opRange;
   
   GetPromotedPoint(kStart, startNode, startOffset, inOperationType,
                    address_of(opStartNode), &opStartOffset);
   GetPromotedPoint(kEnd, endNode, endOffset, inOperationType,
                    address_of(opEndNode), &opEndOffset);
 
   // Make sure that the new range ends up to be in the editable section.
   NS_ENSURE_STATE(mHTMLEditor);
@@ -5942,65 +5925,63 @@ private:
   nsCOMArray<nsIDOMNode> &mArray;
 };
 
 ///////////////////////////////////////////////////////////////////////////
 // GetNodesForOperation: run through the ranges in the array and construct 
 //                       a new array of nodes to be acted on.
 //                       
 nsresult 
-nsHTMLEditRules::GetNodesForOperation(nsCOMArray<nsIDOMRange>& inArrayOfRanges, 
+nsHTMLEditRules::GetNodesForOperation(nsTArray<nsRefPtr<nsRange>>& inArrayOfRanges, 
                                       nsCOMArray<nsIDOMNode>& outArrayOfNodes, 
                                       EditAction inOperationType,
                                       bool aDontTouchContent)
 {
-  int32_t rangeCount = inArrayOfRanges.Count();
+  int32_t rangeCount = inArrayOfRanges.Length();
   
   int32_t i;
-  nsCOMPtr<nsIDOMRange> opRange;
+  nsRefPtr<nsRange> opRange;
 
   nsresult res = NS_OK;
   
   // bust up any inlines that cross our range endpoints,
   // but only if we are allowed to touch content.
   
   if (!aDontTouchContent)
   {
-    nsTArray<nsRefPtr<nsRangeStore> > rangeItemArray;
-    if (!rangeItemArray.AppendElements(rangeCount)) {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
+    nsTArray<nsRefPtr<nsRangeStore>> rangeItemArray;
+    rangeItemArray.AppendElements(rangeCount);
 
     NS_ASSERTION(static_cast<uint32_t>(rangeCount) == rangeItemArray.Length(),
                  "How did that happen?");
 
     // first register ranges for special editor gravity
     for (i = 0; i < rangeCount; i++)
     {
       opRange = inArrayOfRanges[0];
       rangeItemArray[i] = new nsRangeStore();
-      rangeItemArray[i]->StoreRange(static_cast<nsRange*>(opRange.get()));
+      rangeItemArray[i]->StoreRange(opRange);
       NS_ENSURE_STATE(mHTMLEditor);
       mHTMLEditor->mRangeUpdater.RegisterRangeItem(rangeItemArray[i]);
-      inArrayOfRanges.RemoveObjectAt(0);
+      inArrayOfRanges.RemoveElementAt(0);
     }    
     // now bust up inlines.  Safe to start at rangeCount-1, since we
     // asserted we have enough items above.
     for (i = rangeCount-1; i >= 0 && NS_SUCCEEDED(res); i--)
     {
       res = BustUpInlinesAtRangeEndpoints(*rangeItemArray[i]);
     } 
     // then unregister the ranges
     for (i = 0; i < rangeCount; i++)
     {
       nsRangeStore* item = rangeItemArray[i];
       NS_ENSURE_STATE(mHTMLEditor);
       mHTMLEditor->mRangeUpdater.DropRangeItem(item);
       opRange = item->GetRange();
-      inArrayOfRanges.AppendObject(opRange);
+      inArrayOfRanges.AppendElement(opRange);
     }
     NS_ENSURE_SUCCESS(res, res);
   }
   // gather up a list of all the nodes
   for (i = 0; i < rangeCount; i++)
   {
     opRange = inArrayOfRanges[i];
     
@@ -6505,20 +6486,20 @@ nsHTMLEditRules::GetNodesFromPoint(::DOM
   nsresult res = range->SetStart(point.node, point.offset);
   NS_ENSURE_SUCCESS(res, res);
   
   // expand the range to include adjacent inlines
   res = PromoteRange(range, operation);
   NS_ENSURE_SUCCESS(res, res);
       
   // make array of ranges
-  nsCOMArray<nsIDOMRange> arrayOfRanges;
+  nsTArray<nsRefPtr<nsRange>> arrayOfRanges;
   
   // stuff new opRange into array
-  arrayOfRanges.AppendObject(range);
+  arrayOfRanges.AppendElement(range);
   
   // use these ranges to contruct a list of nodes to act on.
   res = GetNodesForOperation(arrayOfRanges, arrayOfNodes, operation, dontTouchContent); 
   return res;
 }
 
 
 ///////////////////////////////////////////////////////////////////////////
@@ -6530,17 +6511,17 @@ nsHTMLEditRules::GetNodesFromSelection(S
                                        EditAction operation,
                                        nsCOMArray<nsIDOMNode>& arrayOfNodes,
                                        bool dontTouchContent)
 {
   NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
   nsresult res;
   
   // promote selection ranges
-  nsCOMArray<nsIDOMRange> arrayOfRanges;
+  nsTArray<nsRefPtr<nsRange>> arrayOfRanges;
   res = GetPromotedRanges(selection, arrayOfRanges, operation);
   NS_ENSURE_SUCCESS(res, res);
   
   // use these ranges to contruct a list of nodes to act on.
   res = GetNodesForOperation(arrayOfRanges, arrayOfNodes, operation, dontTouchContent); 
   return res;
 }
 
@@ -8551,17 +8532,17 @@ nsHTMLEditRules::ConfirmSelectionInBody(
     selection->Collapse(rootElement, 0);
   }
   
   return res;
 }
 
 
 nsresult 
-nsHTMLEditRules::UpdateDocChangeRange(nsIDOMRange *aRange)
+nsHTMLEditRules::UpdateDocChangeRange(nsRange* aRange)
 {
   nsresult res = NS_OK;
 
   // first make sure aRange is in the document.  It might not be if
   // portions of our editting action involved manipulating nodes
   // prior to placing them in the document (e.g., populating a list item
   // before placing it in its list)
   nsCOMPtr<nsIDOMNode> startNode;
@@ -8571,19 +8552,17 @@ nsHTMLEditRules::UpdateDocChangeRange(ns
   if (!mHTMLEditor->IsDescendantOfRoot(startNode)) {
     // just return - we don't need to adjust mDocChangeRange in this case
     return NS_OK;
   }
   
   if (!mDocChangeRange)
   {
     // clone aRange.
-    nsCOMPtr<nsIDOMRange> range;
-    res = aRange->CloneRange(getter_AddRefs(range));
-    mDocChangeRange = static_cast<nsRange*>(range.get());
+    mDocChangeRange = aRange->CloneRange();
   }
   else
   {
     int16_t result;
     
     // compare starts of ranges
     res = mDocChangeRange->CompareBoundaryPoints(nsIDOMRange::START_TO_START, aRange, &result);
     if (res == NS_ERROR_NOT_INITIALIZED) {
@@ -9179,17 +9158,17 @@ nsHTMLEditRules::WillAbsolutePosition(Se
   NS_ENSURE_STATE(mHTMLEditor);
   nsAutoSelectionReset selectionResetter(aSelection, mHTMLEditor);
   
   // convert the selection ranges into "promoted" selection ranges:
   // this basically just expands the range to include the immediate
   // block parent, and then further expands to include any ancestors
   // whose children are all in the range
   
-  nsCOMArray<nsIDOMRange> arrayOfRanges;
+  nsTArray<nsRefPtr<nsRange>> arrayOfRanges;
   res = GetPromotedRanges(aSelection, arrayOfRanges,
                           EditAction::setAbsolutePosition);
   NS_ENSURE_SUCCESS(res, res);
   
   // use these ranges to contruct a list of nodes to act on.
   nsCOMArray<nsIDOMNode> arrayOfNodes;
   res = GetNodesForOperation(arrayOfRanges, arrayOfNodes,
                              EditAction::setAbsolutePosition);
--- a/editor/libeditor/nsHTMLEditRules.h
+++ b/editor/libeditor/nsHTMLEditRules.h
@@ -20,17 +20,16 @@
 #include "nscore.h"
 
 class nsHTMLEditor;
 class nsIAtom;
 class nsIDOMCharacterData;
 class nsIDOMDocument;
 class nsIDOMElement;
 class nsIDOMNode;
-class nsIDOMRange;
 class nsIEditor;
 class nsINode;
 class nsPlaintextEditor;
 class nsRange;
 class nsRulesInfo;
 namespace mozilla {
 namespace dom {
 class Element;
@@ -261,21 +260,20 @@ protected:
   nsresult ExpandSelectionForDeletion(mozilla::dom::Selection* aSelection);
   bool IsFirstNode(nsIDOMNode *aNode);
   bool IsLastNode(nsIDOMNode *aNode);
   nsresult NormalizeSelection(mozilla::dom::Selection* aSelection);
   void GetPromotedPoint(RulesEndpoint aWhere, nsIDOMNode* aNode,
                         int32_t aOffset, EditAction actionID,
                         nsCOMPtr<nsIDOMNode>* outNode, int32_t* outOffset);
   nsresult GetPromotedRanges(mozilla::dom::Selection* aSelection, 
-                             nsCOMArray<nsIDOMRange> &outArrayOfRanges, 
+                             nsTArray<nsRefPtr<nsRange>>& outArrayOfRanges,
                              EditAction inOperationType);
-  nsresult PromoteRange(nsIDOMRange *inRange,
-                        EditAction inOperationType);
-  nsresult GetNodesForOperation(nsCOMArray<nsIDOMRange>& inArrayOfRanges, 
+  nsresult PromoteRange(nsRange* inRange, EditAction inOperationType);
+  nsresult GetNodesForOperation(nsTArray<nsRefPtr<nsRange>>& inArrayOfRanges, 
                                 nsCOMArray<nsIDOMNode>& outArrayOfNodes, 
                                 EditAction inOperationType,
                                 bool aDontTouchContent=false);
   nsresult GetChildNodesForOperation(nsIDOMNode *inNode, 
                                      nsCOMArray<nsIDOMNode>& outArrayOfNodes);
   nsresult GetNodesFromPoint(::DOMPoint point,
                              EditAction operation,
                              nsCOMArray<nsIDOMNode>& arrayOfNodes,
@@ -326,17 +324,17 @@ protected:
    * 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.
    */
   bool     InDifferentTableElements(nsIDOMNode* aNode1, nsIDOMNode* aNode2);
   bool     InDifferentTableElements(nsINode* aNode1, nsINode* aNode2);
   nsresult RemoveEmptyNodes();
   nsresult SelectionEndpointInNode(nsINode *aNode, bool *aResult);
-  nsresult UpdateDocChangeRange(nsIDOMRange *aRange);
+  nsresult UpdateDocChangeRange(nsRange* aRange);
   nsresult ConfirmSelectionInBody();
   nsresult InsertMozBRIfNeeded(nsIDOMNode *aNode);
   bool     IsEmptyInline(nsIDOMNode *aNode);
   bool     ListIsEmptyLine(nsCOMArray<nsIDOMNode> &arrayOfNodes);
   nsresult RemoveAlignment(nsIDOMNode * aNode, const nsAString & aAlignType, bool aChildrenOnly);
   nsresult MakeSureElemStartsOrEndsOnCR(nsIDOMNode *aNode, bool aStarts);
   nsresult AlignBlock(nsIDOMElement * aElement, const nsAString * aAlignType, bool aContentsOnly);
   nsresult RelativeChangeIndentationOfElementNode(nsIDOMNode *aNode, int8_t aRelativeChange);
--- a/editor/libeditor/nsHTMLEditor.cpp
+++ b/editor/libeditor/nsHTMLEditor.cpp
@@ -37,17 +37,16 @@
 #include "nsIInlineSpellChecker.h"
 
 #include "mozilla/CSSStyleSheet.h"
 #include "mozilla/css/Loader.h"
 #include "nsIDOMStyleSheet.h"
 
 #include "nsIContent.h"
 #include "nsIContentIterator.h"
-#include "nsIDOMRange.h"
 #include "nsISupportsArray.h"
 #include "nsContentUtils.h"
 #include "nsIDocumentEncoder.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "SetDocTitleTxn.h"
 #include "nsFocusManager.h"
 #include "nsPIDOMWindow.h"
@@ -2355,23 +2354,22 @@ nsHTMLEditor::GetSelectedElement(const n
   nsAutoString TagName(aTagName);
   ToLowerCase(TagName);
   // Empty string indicates we should match any element tag
   bool anyTag = (TagName.IsEmpty());
   bool isLinkTag = IsLinkTag(TagName);
   bool isNamedAnchorTag = IsNamedAnchorTag(TagName);
   
   nsCOMPtr<nsIDOMElement> selectedElement;
-  nsCOMPtr<nsIDOMRange> range;
-  nsresult res = selection->GetRangeAt(0, getter_AddRefs(range));
-  NS_ENSURE_SUCCESS(res, res);
+  nsRefPtr<nsRange> range = selection->GetRangeAt(0);
+  NS_ENSURE_STATE(range);
 
   nsCOMPtr<nsIDOMNode> startParent;
   int32_t startOffset, endOffset;
-  res = range->GetStartContainer(getter_AddRefs(startParent));
+  nsresult res = range->GetStartContainer(getter_AddRefs(startParent));
   NS_ENSURE_SUCCESS(res, res);
   res = range->GetStartOffset(&startOffset);
   NS_ENSURE_SUCCESS(res, res);
 
   nsCOMPtr<nsIDOMNode> endParent;
   res = range->GetEndContainer(getter_AddRefs(endParent));
   NS_ENSURE_SUCCESS(res, res);
   res = range->GetEndOffset(&endOffset);
@@ -3706,18 +3704,18 @@ nsHTMLEditor::GetEnclosingTable(nsIDOMNo
 
 
 /* this method scans the selection for adjacent text nodes
  * and collapses them into a single text node.
  * "adjacent" means literally adjacent siblings of the same parent.
  * Uses nsEditor::JoinNodes so action is undoable. 
  * Should be called within the context of a batch transaction.
  */
-NS_IMETHODIMP
-nsHTMLEditor::CollapseAdjacentTextNodes(nsIDOMRange *aInRange)
+nsresult
+nsHTMLEditor::CollapseAdjacentTextNodes(nsRange* aInRange)
 {
   NS_ENSURE_TRUE(aInRange, NS_ERROR_NULL_POINTER);
   nsAutoTxnsConserveSelection dontSpazMySelection(this);
   nsTArray<nsCOMPtr<nsIDOMNode> > textNodes;
   // we can't actually do anything during iteration, so store the text nodes in an array
   // don't bother ref counting them because we know we can hold them for the 
   // lifetime of this method
 
@@ -4966,19 +4964,17 @@ nsHTMLEditor::GetSelectionContainer(nsID
   } else {
 
     int32_t rangeCount;
     res = selection->GetRangeCount(&rangeCount);
     NS_ENSURE_SUCCESS(res, res);
 
     if (rangeCount == 1) {
 
-      nsCOMPtr<nsIDOMRange> range;
-      res = selection->GetRangeAt(0, getter_AddRefs(range));
-      NS_ENSURE_SUCCESS(res, res);
+      nsRefPtr<nsRange> range = selection->GetRangeAt(0);
       NS_ENSURE_TRUE(range, NS_ERROR_NULL_POINTER);
 
       nsCOMPtr<nsIDOMNode> startContainer, endContainer;
       res = range->GetStartContainer(getter_AddRefs(startContainer));
       NS_ENSURE_SUCCESS(res, res);
       res = range->GetEndContainer(getter_AddRefs(endContainer));
       NS_ENSURE_SUCCESS(res, res);
       int32_t startOffset, endOffset;
@@ -4996,21 +4992,21 @@ nsHTMLEditor::GetSelectionContainer(nsID
       }
       if (!focusNode) {
         res = range->GetCommonAncestorContainer(getter_AddRefs(focusNode));
         NS_ENSURE_SUCCESS(res, res);
       }
     }
     else {
       int32_t i;
-      nsCOMPtr<nsIDOMRange> range;
+      nsRefPtr<nsRange> range;
       for (i = 0; i < rangeCount; i++)
       {
-        res = selection->GetRangeAt(i, getter_AddRefs(range));
-        NS_ENSURE_SUCCESS(res, res);
+        range = selection->GetRangeAt(i);
+        NS_ENSURE_STATE(range);
         nsCOMPtr<nsIDOMNode> startContainer;
         res = range->GetStartContainer(getter_AddRefs(startContainer));
         if (NS_FAILED(res)) continue;
         if (!focusNode)
           focusNode = startContainer;
         else if (focusNode != startContainer) {
           res = startContainer->GetParentNode(getter_AddRefs(focusNode));
           NS_ENSURE_SUCCESS(res, res);
--- a/editor/libeditor/nsHTMLEditor.h
+++ b/editor/libeditor/nsHTMLEditor.h
@@ -45,16 +45,18 @@ class nsIDOMKeyEvent;
 class nsITransferable;
 class nsIDocumentEncoder;
 class nsIClipboard;
 class TypeInState;
 class nsIContentFilter;
 class nsIURL;
 class nsILinkHandler;
 class nsTableOuterFrame;
+class nsIDOMRange;
+class nsRange;
 struct PropItem;
 
 namespace mozilla {
 namespace widget {
 struct IMEState;
 } // namespace widget
 } // namespace mozilla
 
@@ -200,17 +202,17 @@ public:
 
   NS_IMETHOD SetSelectionAfterTableEdit(nsIDOMElement* aTable, int32_t aRow, int32_t aCol, 
                                         int32_t aDirection, bool aSelected);
   NS_IMETHOD GetSelectedOrParentTableElement(nsAString& aTagName,
                                              int32_t *aSelectedCount,
                                              nsIDOMElement** aTableElement);
   NS_IMETHOD GetSelectedCellsType(nsIDOMElement *aElement, uint32_t *aSelectionType);
 
-  nsresult GetCellFromRange(nsIDOMRange *aRange, nsIDOMElement **aCell);
+  nsresult GetCellFromRange(nsRange* aRange, nsIDOMElement** aCell);
 
   // Finds the first selected cell in first range of selection
   // This is in the *order of selection*, not order in the table
   // (i.e., each cell added to selection is added in another range 
   //  in the selection's rangelist, independent of location in table)
   // aRange is optional: returns the range around the cell
   NS_IMETHOD GetFirstSelectedCell(nsIDOMRange **aRange, nsIDOMElement **aCell);
   // Get next cell until no more are found. Always use GetFirstSelected cell first
@@ -298,17 +300,17 @@ public:
                                       const nsAString & aAttribute,
                                       const nsAString & aValue,
                                       bool aSuppressTransaction);
   NS_IMETHOD RemoveAttributeOrEquivalent(nsIDOMElement * aElement,
                                          const nsAString & aAttribute,
                                          bool aSuppressTransaction);
 
   /** join together any adjacent editable text nodes in the range */
-  NS_IMETHOD CollapseAdjacentTextNodes(nsIDOMRange *aInRange);
+  nsresult CollapseAdjacentTextNodes(nsRange* aRange);
 
   virtual bool AreNodesSameType(nsIContent* aNode1, nsIContent* aNode2)
     MOZ_OVERRIDE;
 
   NS_IMETHOD DeleteSelectionImpl(EDirection aAction,
                                  EStripWrappers aStripWrappers);
   nsresult DeleteNode(nsINode* aNode);
   NS_IMETHODIMP DeleteNode(nsIDOMNode * aNode);
@@ -654,19 +656,19 @@ protected:
                                     nsIAtom *aProperty, 
                                     const nsAString *aAttribute,
                                     const nsAString *aValue);
   nsresult SetInlinePropertyOnNode(nsIContent* aNode,
                                    nsIAtom* aProperty,
                                    const nsAString* aAttribute,
                                    const nsAString* aValue);
 
-  nsresult PromoteInlineRange(nsIDOMRange *inRange);
-  nsresult PromoteRangeIfStartsOrEndsInNamedAnchor(nsIDOMRange *inRange);
-  nsresult SplitStyleAboveRange(nsIDOMRange *aRange, 
+  nsresult PromoteInlineRange(nsRange* aRange);
+  nsresult PromoteRangeIfStartsOrEndsInNamedAnchor(nsRange* aRange);
+  nsresult SplitStyleAboveRange(nsRange* aRange,
                                 nsIAtom *aProperty, 
                                 const nsAString *aAttribute);
   nsresult SplitStyleAbovePoint(nsCOMPtr<nsIDOMNode> *aNode,
                                 int32_t *aOffset,
                                 nsIAtom *aProperty, 
                                 const nsAString *aAttribute,
                                 nsCOMPtr<nsIDOMNode> *outLeftNode = nullptr,
                                 nsCOMPtr<nsIDOMNode> *outRightNode = nullptr);
--- a/editor/libeditor/nsHTMLEditorEventListener.cpp
+++ b/editor/libeditor/nsHTMLEditorEventListener.cpp
@@ -11,23 +11,23 @@
 #include "nsHTMLEditUtils.h"
 #include "nsHTMLEditor.h"
 #include "nsHTMLEditorEventListener.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIDOMMouseEvent.h"
 #include "nsIDOMNode.h"
-#include "nsIDOMRange.h"
 #include "nsIEditor.h"
 #include "nsIHTMLEditor.h"
 #include "nsIHTMLInlineTableEditor.h"
 #include "nsIHTMLObjectResizer.h"
 #include "nsISupportsImpl.h"
 #include "nsLiteralString.h"
+#include "nsRange.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 /*
  * nsHTMLEditorEventListener implementation
  *
  */
@@ -118,20 +118,18 @@ nsHTMLEditorEventListener::MouseDown(nsI
     // Detect if mouse point is within current selection for context click
     bool nodeIsInSelection = false;
     if (isContextClick && !selection->Collapsed()) {
       int32_t rangeCount;
       rv = selection->GetRangeCount(&rangeCount);
       NS_ENSURE_SUCCESS(rv, rv);
 
       for (int32_t i = 0; i < rangeCount; i++) {
-        nsCOMPtr<nsIDOMRange> range;
-
-        rv = selection->GetRangeAt(i, getter_AddRefs(range));
-        if (NS_FAILED(rv) || !range) {
+        nsRefPtr<nsRange> range = selection->GetRangeAt(i);
+        if (!range) {
           // Don't bail yet, iterate through them all
           continue;
         }
 
         range->IsPointInRange(parent, offset, &nodeIsInSelection);
 
         // Done when we find a range that we are in
         if (nodeIsInSelection) {
--- a/editor/libeditor/nsHTMLEditorStyle.cpp
+++ b/editor/libeditor/nsHTMLEditorStyle.cpp
@@ -24,23 +24,23 @@
 #include "nsHTMLEditUtils.h"
 #include "nsHTMLEditor.h"
 #include "nsIAtom.h"
 #include "nsIContent.h"
 #include "nsIContentIterator.h"
 #include "nsIDOMCharacterData.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMNode.h"
-#include "nsIDOMRange.h"
 #include "nsIEditor.h"
 #include "nsIEditorIMESupport.h"
 #include "nsNameSpaceManager.h"
 #include "nsINode.h"
 #include "nsISupportsImpl.h"
 #include "nsLiteralString.h"
+#include "nsRange.h"
 #include "nsReadableUtils.h"
 #include "nsSelectionState.h"
 #include "nsString.h"
 #include "nsStringFwd.h"
 #include "nsTArray.h"
 #include "nsTextEditRules.h"
 #include "nsTextEditUtils.h"
 #include "nsUnicharUtils.h"
@@ -573,19 +573,19 @@ nsHTMLEditor::SetInlinePropertyOnNode(ns
                                       aAttribute, aValue);
     NS_ENSURE_SUCCESS(res, res);
   }
 
   return NS_OK;
 }
 
 
-nsresult nsHTMLEditor::SplitStyleAboveRange(nsIDOMRange *inRange, 
-                                            nsIAtom *aProperty, 
-                                            const nsAString *aAttribute)
+nsresult
+nsHTMLEditor::SplitStyleAboveRange(nsRange* inRange, nsIAtom* aProperty,
+                                   const nsAString* aAttribute)
 {
   NS_ENSURE_TRUE(inRange, NS_ERROR_NULL_POINTER);
   nsresult res;
   nsCOMPtr<nsIDOMNode> startNode, endNode, origStartNode;
   int32_t startOffset, endOffset;
 
   res = inRange->GetStartContainer(getter_AddRefs(startNode));
   NS_ENSURE_SUCCESS(res, res);
@@ -943,17 +943,18 @@ bool nsHTMLEditor::HasAttr(nsIDOMNode* a
 
   nsCOMPtr<nsIAtom> atom = do_GetAtom(*aAttribute);
   NS_ENSURE_TRUE(atom, false);
 
   return element->HasAttr(kNameSpaceID_None, atom);
 }
 
 
-nsresult nsHTMLEditor::PromoteRangeIfStartsOrEndsInNamedAnchor(nsIDOMRange *inRange)
+nsresult
+nsHTMLEditor::PromoteRangeIfStartsOrEndsInNamedAnchor(nsRange* inRange)
 {
   NS_ENSURE_TRUE(inRange, NS_ERROR_NULL_POINTER);
   nsresult res;
   nsCOMPtr<nsIDOMNode> startNode, endNode, parent, tmp;
   int32_t startOffset, endOffset, tmpOffset;
   
   res = inRange->GetStartContainer(getter_AddRefs(startNode));
   NS_ENSURE_SUCCESS(res, res);
@@ -997,17 +998,18 @@ nsresult nsHTMLEditor::PromoteRangeIfSta
   }
 
   res = inRange->SetStart(startNode, startOffset);
   NS_ENSURE_SUCCESS(res, res);
   res = inRange->SetEnd(endNode, endOffset);
   return res;
 }
 
-nsresult nsHTMLEditor::PromoteInlineRange(nsIDOMRange *inRange)
+nsresult
+nsHTMLEditor::PromoteInlineRange(nsRange* inRange)
 {
   NS_ENSURE_TRUE(inRange, NS_ERROR_NULL_POINTER);
   nsresult res;
   nsCOMPtr<nsIDOMNode> startNode, endNode, parent;
   int32_t startOffset, endOffset;
   
   res = inRange->GetStartContainer(getter_AddRefs(startNode));
   NS_ENSURE_SUCCESS(res, res);
--- a/editor/libeditor/nsPlaintextDataTransfer.cpp
+++ b/editor/libeditor/nsPlaintextDataTransfer.cpp
@@ -17,33 +17,33 @@
 #include "nsError.h"
 #include "nsIClipboard.h"
 #include "nsIContent.h"
 #include "nsIDOMDataTransfer.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMDragEvent.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMNode.h"
-#include "nsIDOMRange.h"
 #include "nsIDOMUIEvent.h"
 #include "nsIDocument.h"
 #include "nsIDragService.h"
 #include "nsIDragSession.h"
 #include "nsIEditor.h"
 #include "nsIEditorIMESupport.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIPrincipal.h"
 #include "nsIFormControl.h"
 #include "nsIPlaintextEditor.h"
 #include "nsISupportsPrimitives.h"
 #include "nsITransferable.h"
 #include "nsIVariant.h"
 #include "nsLiteralString.h"
 #include "nsPlaintextEditor.h"
+#include "nsRange.h"
 #include "nsSelectionState.h"
 #include "nsServiceManagerUtils.h"
 #include "nsString.h"
 #include "nsXPCOM.h"
 #include "nscore.h"
 
 class nsILoadContext;
 class nsISupports;
@@ -251,20 +251,21 @@ nsresult nsPlaintextEditor::InsertFromDr
     bool cursorIsInSelection = false;
 
     int32_t rangeCount;
     rv = selection->GetRangeCount(&rangeCount);
     NS_ENSURE_SUCCESS(rv, rv);
 
     for (int32_t j = 0; j < rangeCount; j++)
     {
-      nsCOMPtr<nsIDOMRange> range;
-      rv = selection->GetRangeAt(j, getter_AddRefs(range));
-      if (NS_FAILED(rv) || !range) 
-        continue;  // don't bail yet, iterate through them all
+      nsRefPtr<nsRange> range = selection->GetRangeAt(j);
+      if (!range) {
+        // don't bail yet, iterate through them all
+        continue;
+      }
 
       rv = range->IsPointInRange(newSelectionParent, newSelectionOffset, &cursorIsInSelection);
       if (cursorIsInSelection)
         break;
     }
 
     if (cursorIsInSelection)
     {
--- a/editor/libeditor/nsSelectionState.cpp
+++ b/editor/libeditor/nsSelectionState.cpp
@@ -10,17 +10,16 @@
 #include "nsCycleCollectionParticipant.h"
 #include "nsDebug.h"                    // for NS_ENSURE_TRUE, etc
 #include "nsEditor.h"                   // for nsEditor
 #include "nsEditorUtils.h"              // for nsEditorUtils
 #include "nsError.h"                    // for NS_OK, etc
 #include "nsIContent.h"                 // for nsIContent
 #include "nsIDOMCharacterData.h"        // for nsIDOMCharacterData
 #include "nsIDOMNode.h"                 // for nsIDOMNode
-#include "nsIDOMRange.h"                // for nsIDOMRange, etc
 #include "nsISupportsImpl.h"            // for nsRange::Release
 #include "nsRange.h"                    // for nsRange
 #include "nsSelectionState.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 /***************************************************************************
@@ -144,17 +143,17 @@ nsSelectionState::MakeEmpty()
 
 bool     
 nsSelectionState::IsEmpty()
 {
   return mArray.IsEmpty();
 }
 
 /***************************************************************************
- * nsRangeUpdater:  class for updating nsIDOMRanges in response to editor actions.
+ * nsRangeUpdater:  class for updating nsRanges in response to editor actions.
  */
 
 nsRangeUpdater::nsRangeUpdater() : mArray(), mLock(false) {}
 
 nsRangeUpdater::~nsRangeUpdater()
 {
   // nothing to do, we don't own the items in our array.
 }
--- a/editor/libeditor/nsSelectionState.h
+++ b/editor/libeditor/nsSelectionState.h
@@ -9,17 +9,16 @@
 #include "nsCOMPtr.h"
 #include "nsIDOMNode.h"
 #include "nsINode.h"
 #include "nsTArray.h"
 #include "nscore.h"
 
 class nsCycleCollectionTraversalCallback;
 class nsIDOMCharacterData;
-class nsIDOMRange;
 class nsRange;
 namespace mozilla {
 namespace dom {
 class Selection;
 class Text;
 }
 }
 
--- a/editor/libeditor/nsTableEditor.cpp
+++ b/editor/libeditor/nsTableEditor.cpp
@@ -17,27 +17,27 @@
 #include "nsError.h"
 #include "nsGkAtoms.h"
 #include "nsHTMLEditUtils.h"
 #include "nsHTMLEditor.h"
 #include "nsIAtom.h"
 #include "nsIContent.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMNode.h"
-#include "nsIDOMRange.h"
 #include "nsIEditor.h"
 #include "nsIFrame.h"
 #include "nsIHTMLEditor.h"
 #include "nsINode.h"
 #include "nsIPresShell.h"
 #include "nsISupportsUtils.h"
 #include "nsITableCellLayout.h" // For efficient access to table cell
 #include "nsITableEditor.h"
 #include "nsLiteralString.h"
 #include "nsQueryFrame.h"
+#include "nsRange.h"
 #include "nsString.h"
 #include "nsTArray.h"
 #include "nsTableCellFrame.h"
 #include "nsTableOuterFrame.h"
 #include "nscore.h"
 #include <algorithm>
 
 using namespace mozilla;
@@ -2209,22 +2209,21 @@ nsHTMLEditor::JoinTableCells(bool aMerge
     // Cleanup selection: remove ranges where cells were deleted
     nsRefPtr<Selection> selection = GetSelection();
     NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
 
     int32_t rangeCount;
     res = selection->GetRangeCount(&rangeCount);
     NS_ENSURE_SUCCESS(res, res);
 
-    nsCOMPtr<nsIDOMRange> range;
+    nsRefPtr<nsRange> range;
     int32_t i;
     for (i = 0; i < rangeCount; i++)
     {
-      res = selection->GetRangeAt(i, getter_AddRefs(range));
-      NS_ENSURE_SUCCESS(res, res);
+      range = selection->GetRangeAt(i);
       NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
 
       nsCOMPtr<nsIDOMElement> deletedCell;
       res = GetCellFromRange(range, getter_AddRefs(deletedCell));
       if (!deletedCell)
       {
         selection->RemoveRange(range);
         rangeCount--;
@@ -2872,17 +2871,17 @@ nsHTMLEditor::GetCellContext(Selection**
       *aCellOffset = GetChildOffset(cell, cellParent);
     }
   }
 
   return res;
 }
 
 nsresult 
-nsHTMLEditor::GetCellFromRange(nsIDOMRange *aRange, nsIDOMElement **aCell)
+nsHTMLEditor::GetCellFromRange(nsRange* aRange, nsIDOMElement** aCell)
 {
   // Note: this might return a node that is outside of the range.
   // Use carefully.
   NS_ENSURE_TRUE(aRange && aCell, NS_ERROR_NULL_POINTER);
 
   *aCell = nullptr;
 
   nsCOMPtr<nsIDOMNode> startParent;
@@ -2931,24 +2930,22 @@ nsHTMLEditor::GetFirstSelectedCell(nsIDO
 {
   NS_ENSURE_TRUE(aCell, NS_ERROR_NULL_POINTER);
   *aCell = nullptr;
   if (aRange) *aRange = nullptr;
 
   nsRefPtr<Selection> selection = GetSelection();
   NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
 
-  nsCOMPtr<nsIDOMRange> range;
-  nsresult res = selection->GetRangeAt(0, getter_AddRefs(range));
-  NS_ENSURE_SUCCESS(res, res);
+  nsRefPtr<nsRange> range = selection->GetRangeAt(0);
   NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
 
   mSelectedCellIndex = 0;
 
-  res = GetCellFromRange(range, aCell);
+  nsresult res = GetCellFromRange(range, aCell);
   // Failure here probably means selection is in a text node,
   //  so there's no selected cell
   if (NS_FAILED(res)) {
     return NS_EDITOR_ELEMENT_NOT_FOUND;
   }
   // No cell means range was collapsed (cell was deleted)
   if (!*aCell) {
     return NS_EDITOR_ELEMENT_NOT_FOUND;
@@ -2978,22 +2975,21 @@ nsHTMLEditor::GetNextSelectedCell(nsIDOM
 
   int32_t rangeCount = selection->GetRangeCount();
 
   // Don't even try if index exceeds range count
   if (mSelectedCellIndex >= rangeCount) 
     return NS_EDITOR_ELEMENT_NOT_FOUND;
 
   // Scan through ranges to find next valid selected cell
-  nsCOMPtr<nsIDOMRange> range;
+  nsRefPtr<nsRange> range;
   nsresult res;
   for (; mSelectedCellIndex < rangeCount; mSelectedCellIndex++)
   {
-    res = selection->GetRangeAt(mSelectedCellIndex, getter_AddRefs(range));
-    NS_ENSURE_SUCCESS(res, res);
+    range = selection->GetRangeAt(mSelectedCellIndex);
     NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
 
     res = GetCellFromRange(range, aCell);
     // Failure here means the range doesn't contain a cell
     NS_ENSURE_SUCCESS(res, NS_EDITOR_ELEMENT_NOT_FOUND);
     
     // We found a selected cell
     if (*aCell) break;
--- a/editor/txtsvc/nsFilteredContentIterator.cpp
+++ b/editor/txtsvc/nsFilteredContentIterator.cpp
@@ -8,17 +8,16 @@
 #include "nsContentUtils.h"
 #include "nsDebug.h"
 #include "nsError.h"
 #include "nsFilteredContentIterator.h"
 #include "nsIAtom.h"
 #include "nsIContent.h"
 #include "nsIContentIterator.h"
 #include "nsIDOMNode.h"
-#include "nsIDOMRange.h"
 #include "nsINode.h"
 #include "nsISupportsBase.h"
 #include "nsISupportsUtils.h"
 #include "nsITextServicesFilter.h"
 #include "nsRange.h"
 
 //------------------------------------------------------------
 nsFilteredContentIterator::nsFilteredContentIterator(nsITextServicesFilter* aFilter) :
@@ -81,24 +80,21 @@ nsFilteredContentIterator::Init(nsIDOMRa
 {
   NS_ENSURE_TRUE(mPreIterator, NS_ERROR_FAILURE);
   NS_ENSURE_TRUE(mIterator, NS_ERROR_FAILURE);
   NS_ENSURE_ARG_POINTER(aRange);
   mIsOutOfRange    = false;
   mDirection       = eForward;
   mCurrentIterator = mPreIterator;
 
-  nsCOMPtr<nsIDOMRange> domRange;
-  nsresult rv = aRange->CloneRange(getter_AddRefs(domRange));
+  mRange = static_cast<nsRange*>(aRange)->CloneRange();
+
+  nsresult rv = mPreIterator->Init(mRange);
   NS_ENSURE_SUCCESS(rv, rv);
-  mRange = do_QueryInterface(domRange);
-
-  rv = mPreIterator->Init(domRange);
-  NS_ENSURE_SUCCESS(rv, rv);
-  return mIterator->Init(domRange);
+  return mIterator->Init(mRange);
 }
 
 //------------------------------------------------------------
 nsresult 
 nsFilteredContentIterator::SwitchDirections(bool aChangeToForward)
 {
   nsINode *node = mCurrentIterator->GetCurrentNode();
 
@@ -232,17 +228,17 @@ ContentIsInTraversalRange(nsIContent *aC
   int32_t startRes = nsContentUtils::ComparePoints(aStartNode, aStartOffset,
                                                    parentNode, indx);
   int32_t endRes = nsContentUtils::ComparePoints(aEndNode, aEndOffset,
                                                  parentNode, indx);
   return (startRes <= 0) && (endRes >= 0);
 }
 
 static bool
-ContentIsInTraversalRange(nsIDOMRange *aRange, nsIDOMNode* aNextNode, bool aIsPreMode)
+ContentIsInTraversalRange(nsRange* aRange, nsIDOMNode* aNextNode, bool aIsPreMode)
 {
   nsCOMPtr<nsIContent> content(do_QueryInterface(aNextNode));
   NS_ENSURE_TRUE(content && aRange, false);
 
   nsCOMPtr<nsIDOMNode> sNode;
   nsCOMPtr<nsIDOMNode> eNode;
   int32_t sOffset;
   int32_t eOffset;
--- a/editor/txtsvc/nsFilteredContentIterator.h
+++ b/editor/txtsvc/nsFilteredContentIterator.h
@@ -12,16 +12,17 @@
 #include "nsISupportsImpl.h"
 #include "nscore.h"
 
 class nsIAtom;
 class nsIDOMNode;
 class nsIDOMRange;
 class nsINode;
 class nsITextServicesFilter;
+class nsRange;
 
 class nsFilteredContentIterator MOZ_FINAL : public nsIContentIterator
 {
 public:
 
   // nsISupports interface...
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(nsFilteredContentIterator)
@@ -60,15 +61,15 @@ protected:
 
   nsCOMPtr<nsIAtom> mBlockQuoteAtom;
   nsCOMPtr<nsIAtom> mScriptAtom;
   nsCOMPtr<nsIAtom> mTextAreaAtom;
   nsCOMPtr<nsIAtom> mSelectAreaAtom;
   nsCOMPtr<nsIAtom> mMapAtom;
 
   nsCOMPtr<nsITextServicesFilter> mFilter;
-  nsCOMPtr<nsIDOMRange>           mRange;
+  nsRefPtr<nsRange>               mRange;
   bool                            mDidSkip;
   bool                            mIsOutOfRange;
   eDirectionType                  mDirection;
 };
 
 #endif
--- a/editor/txtsvc/nsTextServicesDocument.cpp
+++ b/editor/txtsvc/nsTextServicesDocument.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <stddef.h>                     // for nullptr
 
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
+#include "mozilla/dom/Selection.h"
 #include "mozilla/mozalloc.h"           // for operator new, etc
 #include "nsAString.h"                  // for nsAString_internal::Length, etc
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsContentUtils.h"             // for nsContentUtils
 #include "nsDebug.h"                    // for NS_ENSURE_TRUE, etc
 #include "nsDependentSubstring.h"       // for Substring
 #include "nsError.h"                    // for NS_OK, NS_ERROR_FAILURE, etc
 #include "nsFilteredContentIterator.h"  // for nsFilteredContentIterator
@@ -37,16 +38,17 @@
 #include "nsString.h"                   // for nsString, nsAutoString
 #include "nsTextServicesDocument.h"
 #include "nscore.h"                     // for nsresult, NS_IMETHODIMP, etc
 
 #define LOCK_DOC(doc)
 #define UNLOCK_DOC(doc)
 
 using namespace mozilla;
+using namespace mozilla::dom;
 
 class OffsetEntry
 {
 public:
   OffsetEntry(nsIDOMNode *aNode, int32_t aOffset, int32_t aLength)
     : mNode(aNode), mNodeOffset(0), mStrOffset(aOffset), mLength(aLength),
       mIsInsertedText(false), mIsValid(true)
   {
@@ -229,27 +231,21 @@ nsTextServicesDocument::SetExtent(nsIDOM
   NS_ENSURE_ARG_POINTER(aDOMRange);
   NS_ENSURE_TRUE(mDOMDocument, NS_ERROR_FAILURE);
 
   LOCK_DOC(this);
 
   // We need to store a copy of aDOMRange since we don't
   // know where it came from.
 
-  nsresult result = aDOMRange->CloneRange(getter_AddRefs(mExtent));
-
-  if (NS_FAILED(result))
-  {
-    UNLOCK_DOC(this);
-    return result;
-  }
+  mExtent = static_cast<nsRange*>(aDOMRange)->CloneRange();
 
   // Create a new iterator based on our new extent range.
 
-  result = CreateContentIterator(mExtent, getter_AddRefs(mIterator));
+  nsresult result = CreateContentIterator(mExtent, getter_AddRefs(mIterator));
 
   if (NS_FAILED(result))
   {
     UNLOCK_DOC(this);
     return result;
   }
 
   // Now position the iterator at the start of the first block
@@ -263,34 +259,34 @@ nsTextServicesDocument::SetExtent(nsIDOM
 
   return result;
 }
 
 NS_IMETHODIMP
 nsTextServicesDocument::ExpandRangeToWordBoundaries(nsIDOMRange *aRange)
 {
   NS_ENSURE_ARG_POINTER(aRange);
+  nsRefPtr<nsRange> range = static_cast<nsRange*>(aRange);
 
   // Get the end points of the range.
 
   nsCOMPtr<nsIDOMNode> rngStartNode, rngEndNode;
   int32_t rngStartOffset, rngEndOffset;
 
-  nsresult result =  GetRangeEndPoints(aRange,
-                                       getter_AddRefs(rngStartNode),
+  nsresult result =  GetRangeEndPoints(range, getter_AddRefs(rngStartNode),
                                        &rngStartOffset,
                                        getter_AddRefs(rngEndNode),
                                        &rngEndOffset);
 
   NS_ENSURE_SUCCESS(result, result);
 
   // Create a content iterator based on the range.
 
   nsCOMPtr<nsIContentIterator> iter;
-  result = CreateContentIterator(aRange, getter_AddRefs(iter));
+  result = CreateContentIterator(range, getter_AddRefs(iter));
 
   NS_ENSURE_SUCCESS(result, result);
 
   // Find the first text node in the range.
 
   TSDIteratorStatus iterStatus;
 
   result = FirstTextNode(iter, &iterStatus);
@@ -420,20 +416,20 @@ nsTextServicesDocument::ExpandRangeToWor
   {
     rngEndNode = wordEndNode;
     rngEndOffset = wordEndOffset;
   }
 
   // Now adjust the range so that it uses our new
   // end points.
 
-  result = aRange->SetEnd(rngEndNode, rngEndOffset);
+  result = range->SetEnd(rngEndNode, rngEndOffset);
   NS_ENSURE_SUCCESS(result, result);
 
-  return aRange->SetStart(rngStartNode, rngStartOffset);
+  return range->SetStart(rngStartNode, rngStartOffset);
 }
 
 NS_IMETHODIMP
 nsTextServicesDocument::SetFilter(nsITextServicesFilter *aFilter)
 {
   // Hang on to the filter so we can set it into the filtered iterator.
   mTxtSvcFilter = aFilter;
 
@@ -514,54 +510,42 @@ nsTextServicesDocument::LastSelectedBloc
   *aSelOffset = *aSelLength = -1;
 
   if (!mSelCon || !mIterator)
   {
     UNLOCK_DOC(this);
     return NS_ERROR_FAILURE;
   }
 
-  nsCOMPtr<nsISelection> selection;
-  bool isCollapsed = false;
-
-  result = mSelCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));
-
+  nsCOMPtr<nsISelection> domSelection;
+  result = mSelCon->GetSelection(nsISelectionController::SELECTION_NORMAL,
+                                 getter_AddRefs(domSelection));
   if (NS_FAILED(result))
   {
     UNLOCK_DOC(this);
     return result;
   }
 
-  result = selection->GetIsCollapsed(&isCollapsed);
-
-  if (NS_FAILED(result))
-  {
-    UNLOCK_DOC(this);
-    return result;
-  }
+  nsRefPtr<Selection> selection = static_cast<Selection*>(domSelection.get());
+
+  bool isCollapsed = selection->IsCollapsed();
 
   nsCOMPtr<nsIContentIterator> iter;
-  nsCOMPtr<nsIDOMRange>        range;
+  nsRefPtr<nsRange> range;
   nsCOMPtr<nsIDOMNode>         parent;
   int32_t                      i, rangeCount, offset;
 
   if (isCollapsed)
   {
     // We have a caret. Check if the caret is in a text node.
     // If it is, make the text node's block the current block.
     // If the caret isn't in a text node, search forwards in
     // the document, till we find a text node.
 
-    result = selection->GetRangeAt(0, getter_AddRefs(range));
-
-    if (NS_FAILED(result))
-    {
-      UNLOCK_DOC(this);
-      return result;
-    }
+    range = selection->GetRangeAt(0);
 
     if (!range)
     {
       UNLOCK_DOC(this);
       return NS_ERROR_FAILURE;
     }
 
     result = range->GetStartContainer(getter_AddRefs(parent));
@@ -764,20 +748,19 @@ nsTextServicesDocument::LastSelectedBloc
 
   // XXX: We may need to add some code here to make sure
   //      the ranges are sorted in document appearance order!
 
   for (i = rangeCount - 1; i >= 0; i--)
   {
     // Get the i'th range from the selection.
 
-    result = selection->GetRangeAt(i, getter_AddRefs(range));
-
-    if (NS_FAILED(result))
-    {
+    range = selection->GetRangeAt(i);
+
+    if (!range) {
       UNLOCK_DOC(this);
       return result;
     }
 
     // Create an iterator for the range.
 
     result = CreateContentIterator(range, getter_AddRefs(iter));
 
@@ -838,23 +821,17 @@ nsTextServicesDocument::LastSelectedBloc
     }
   }
 
   // If we get here, we didn't find any text node in the selection!
   // Create a range that extends from the end of the selection,
   // to the end of the document, then iterate forwards through
   // it till you find a text node!
 
-  result = selection->GetRangeAt(rangeCount - 1, getter_AddRefs(range));
-
-  if (NS_FAILED(result))
-  {
-    UNLOCK_DOC(this);
-    return result;
-  }
+  range = selection->GetRangeAt(rangeCount - 1);
 
   if (!range)
   {
     UNLOCK_DOC(this);
     return NS_ERROR_FAILURE;
   }
 
   result = range->GetEndContainer(getter_AddRefs(parent));
@@ -1972,17 +1949,18 @@ nsTextServicesDocument::DidJoinNodes(nsI
     result = mIterator->PositionAt(rightContent);
 
   UNLOCK_DOC(this);
 
   return NS_OK;
 }
 
 nsresult
-nsTextServicesDocument::CreateContentIterator(nsIDOMRange *aRange, nsIContentIterator **aIterator)
+nsTextServicesDocument::CreateContentIterator(nsRange* aRange,
+                                              nsIContentIterator** aIterator)
 {
   NS_ENSURE_TRUE(aRange && aIterator, NS_ERROR_NULL_POINTER);
 
   *aIterator = nullptr;
 
   // Create a nsFilteredContentIterator
   // This class wraps the ContentIterator in order to give itself a chance
   // to filter out certain content nodes
@@ -2038,17 +2016,17 @@ nsTextServicesDocument::GetDocumentConte
 
     result = docElement->QueryInterface(NS_GET_IID(nsIDOMNode), (void **)aNode);
   }
 
   return result;
 }
 
 nsresult
-nsTextServicesDocument::CreateDocumentContentRange(nsIDOMRange **aRange)
+nsTextServicesDocument::CreateDocumentContentRange(nsRange** aRange)
 {
   *aRange = nullptr;
 
   nsCOMPtr<nsIDOMNode> node;
   nsresult rv = GetDocumentContentRootNode(getter_AddRefs(node));
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
 
@@ -2060,17 +2038,18 @@ nsTextServicesDocument::CreateDocumentCo
   rv = range->SelectNodeContents(node);
   NS_ENSURE_SUCCESS(rv, rv);
 
   range.forget(aRange);
   return NS_OK;
 }
 
 nsresult
-nsTextServicesDocument::CreateDocumentContentRootToNodeOffsetRange(nsIDOMNode *aParent, int32_t aOffset, bool aToStart, nsIDOMRange **aRange)
+nsTextServicesDocument::CreateDocumentContentRootToNodeOffsetRange(
+    nsIDOMNode* aParent, int32_t aOffset, bool aToStart, nsRange** aRange)
 {
   NS_ENSURE_TRUE(aParent && aRange, NS_ERROR_NULL_POINTER);
 
   *aRange = 0;
 
   NS_ASSERTION(aOffset >= 0, "Invalid offset!");
 
   if (aOffset < 0)
@@ -2111,17 +2090,17 @@ nsTextServicesDocument::CreateDocumentCo
 
 nsresult
 nsTextServicesDocument::CreateDocumentContentIterator(nsIContentIterator **aIterator)
 {
   nsresult result;
 
   NS_ENSURE_TRUE(aIterator, NS_ERROR_NULL_POINTER);
 
-  nsCOMPtr<nsIDOMRange> range;
+  nsRefPtr<nsRange> range;
 
   result = CreateDocumentContentRange(getter_AddRefs(range));
 
   NS_ENSURE_SUCCESS(result, result);
 
   result = CreateContentIterator(range, aIterator);
 
   return result;
@@ -2536,20 +2515,24 @@ nsTextServicesDocument::GetSelection(nsI
   // UNLOCK_DOC(this);
 
   return result;
 }
 
 nsresult
 nsTextServicesDocument::GetCollapsedSelection(nsITextServicesDocument::TSDBlockSelectionStatus *aSelStatus, int32_t *aSelOffset, int32_t *aSelLength)
 {
-  nsCOMPtr<nsISelection> selection;
-  nsresult result = mSelCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));
+  nsCOMPtr<nsISelection> domSelection;
+  nsresult result =
+    mSelCon->GetSelection(nsISelectionController::SELECTION_NORMAL,
+                          getter_AddRefs(domSelection));
   NS_ENSURE_SUCCESS(result, result);
-  NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
+  NS_ENSURE_TRUE(domSelection, NS_ERROR_FAILURE);
+
+  nsRefPtr<Selection> selection = static_cast<Selection*>(domSelection.get());
 
   // The calling function should have done the GetIsCollapsed()
   // check already. Just assume it's collapsed!
   *aSelStatus = nsITextServicesDocument::eBlockOutside;
   *aSelOffset = *aSelLength = -1;
 
   int32_t tableCount = mOffsetTable.Length();
 
@@ -2564,19 +2547,18 @@ nsTextServicesDocument::GetCollapsedSele
   if (tableCount > 1)
     eEnd = mOffsetTable[tableCount - 1];
   else
     eEnd = eStart;
 
   int32_t eStartOffset = eStart->mNodeOffset;
   int32_t eEndOffset   = eEnd->mNodeOffset + eEnd->mLength;
 
-  nsCOMPtr<nsIDOMRange> range;
-  result = selection->GetRangeAt(0, getter_AddRefs(range));
-  NS_ENSURE_SUCCESS(result, result);
+  nsRefPtr<nsRange> range = selection->GetRangeAt(0);
+  NS_ENSURE_STATE(range);
 
   nsCOMPtr<nsIDOMNode> domParent;
   result = range->GetStartContainer(getter_AddRefs(domParent));
   NS_ENSURE_SUCCESS(result, result);
 
   nsCOMPtr<nsINode> parent = do_QueryInterface(domParent);
   MOZ_ASSERT(parent);
 
@@ -2749,25 +2731,26 @@ nsTextServicesDocument::GetCollapsedSele
   return NS_ERROR_FAILURE;
 }
 
 nsresult
 nsTextServicesDocument::GetUncollapsedSelection(nsITextServicesDocument::TSDBlockSelectionStatus *aSelStatus, int32_t *aSelOffset, int32_t *aSelLength)
 {
   nsresult result;
 
-  nsCOMPtr<nsISelection> selection;
-  nsCOMPtr<nsIDOMRange> range;
+  nsRefPtr<nsRange> range;
   OffsetEntry *entry;
 
-  result = mSelCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));
-
+  nsCOMPtr<nsISelection> domSelection;
+  result = mSelCon->GetSelection(nsISelectionController::SELECTION_NORMAL,
+                                 getter_AddRefs(domSelection));
   NS_ENSURE_SUCCESS(result, result);
-
-  NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
+  NS_ENSURE_TRUE(domSelection, NS_ERROR_FAILURE);
+
+  nsRefPtr<Selection> selection = static_cast<Selection*>(domSelection.get());
 
   // It is assumed that the calling function has made sure that the
   // selection is not collapsed, and that the input params to this
   // method are initialized to some defaults.
 
   nsCOMPtr<nsIDOMNode> startParent, endParent;
   int32_t startOffset, endOffset;
   int32_t rangeCount, tableCount, i;
@@ -2795,19 +2778,18 @@ nsTextServicesDocument::GetUncollapsedSe
 
   NS_ENSURE_SUCCESS(result, result);
 
   // Find the first range in the selection that intersects
   // the current text block.
 
   for (i = 0; i < rangeCount; i++)
   {
-    result = selection->GetRangeAt(i, getter_AddRefs(range));
-
-    NS_ENSURE_SUCCESS(result, result);
+    range = selection->GetRangeAt(i);
+    NS_ENSURE_STATE(range);
 
     result = GetRangeEndPoints(range,
                                getter_AddRefs(startParent), &startOffset,
                                getter_AddRefs(endParent), &endOffset);
 
     NS_ENSURE_SUCCESS(result, result);
 
     e1s2 = nsContentUtils::ComparePoints(eStart->mNode, eStartOffset,
@@ -3049,17 +3031,17 @@ nsTextServicesDocument::SelectionIsColla
 
 bool
 nsTextServicesDocument::SelectionIsValid()
 {
   return(mSelStartIndex >= 0);
 }
 
 nsresult
-nsTextServicesDocument::GetRangeEndPoints(nsIDOMRange *aRange,
+nsTextServicesDocument::GetRangeEndPoints(nsRange* aRange,
                                           nsIDOMNode **aStartParent, int32_t *aStartOffset,
                                           nsIDOMNode **aEndParent, int32_t *aEndOffset)
 {
   nsresult result;
 
   NS_ENSURE_TRUE(aRange && aStartParent && aStartOffset && aEndParent && aEndOffset, NS_ERROR_NULL_POINTER);
 
   result = aRange->GetStartContainer(aStartParent);
@@ -3082,17 +3064,17 @@ nsTextServicesDocument::GetRangeEndPoint
 
   return result;
 }
 
 
 nsresult
 nsTextServicesDocument::CreateRange(nsIDOMNode *aStartParent, int32_t aStartOffset,
                                     nsIDOMNode *aEndParent, int32_t aEndOffset,
-                                    nsIDOMRange **aRange)
+                                    nsRange** aRange)
 {
   return nsRange::CreateRange(aStartParent, aStartOffset, aEndParent,
                               aEndOffset, aRange);
 }
 
 nsresult
 nsTextServicesDocument::FirstTextNode(nsIContentIterator *aIterator,
                                       TSDIteratorStatus *aIteratorStatus)
@@ -3317,18 +3299,17 @@ nsTextServicesDocument::GetFirstTextNode
   // Restore the iterator:
   return mIterator->PositionAt(node);
 }
 
 nsresult
 nsTextServicesDocument::CreateOffsetTable(nsTArray<OffsetEntry*> *aOffsetTable,
                                           nsIContentIterator *aIterator,
                                           TSDIteratorStatus *aIteratorStatus,
-                                          nsIDOMRange *aIterRange,
-                                          nsString *aStr)
+                                          nsRange* aIterRange, nsString* aStr)
 {
   nsresult result = NS_OK;
 
   nsCOMPtr<nsIContent> first;
   nsCOMPtr<nsIContent> prev;
 
   NS_ENSURE_TRUE(aIterator, NS_ERROR_NULL_POINTER);
 
--- a/editor/txtsvc/nsTextServicesDocument.h
+++ b/editor/txtsvc/nsTextServicesDocument.h
@@ -78,17 +78,17 @@ private:
   nsCOMPtr<nsIContent>            mNextTextBlock;
   nsTArray<OffsetEntry*>          mOffsetTable;
 
   int32_t                         mSelStartIndex;
   int32_t                         mSelStartOffset;
   int32_t                         mSelEndIndex;
   int32_t                         mSelEndOffset;
 
-  nsCOMPtr<nsIDOMRange>           mExtent;
+  nsRefPtr<nsRange>               mExtent;
 
   nsCOMPtr<nsITextServicesFilter> mTxtSvcFilter;
 
 protected:
   /** The default destructor.
    */
   virtual ~nsTextServicesDocument();
 
@@ -155,27 +155,35 @@ public:
   NS_IMETHOD WillInsertText(nsIDOMCharacterData *aTextNode, int32_t aOffset, const nsAString &aString);
   NS_IMETHOD DidInsertText(nsIDOMCharacterData *aTextNode, int32_t aOffset, const nsAString &aString, nsresult aResult);
   NS_IMETHOD WillDeleteText(nsIDOMCharacterData *aTextNode, int32_t aOffset, int32_t aLength);
   NS_IMETHOD DidDeleteText(nsIDOMCharacterData *aTextNode, int32_t aOffset, int32_t aLength, nsresult aResult);
   NS_IMETHOD WillDeleteSelection(nsISelection *aSelection);
   NS_IMETHOD DidDeleteSelection(nsISelection *aSelection);
 
   /* Helper functions */
-  static nsresult GetRangeEndPoints(nsIDOMRange *aRange, nsIDOMNode **aParent1, int32_t *aOffset1, nsIDOMNode **aParent2, int32_t *aOffset2);
-  static nsresult CreateRange(nsIDOMNode *aStartParent, int32_t aStartOffset, nsIDOMNode *aEndParent, int32_t aEndOffset, nsIDOMRange **aRange);
+  static nsresult GetRangeEndPoints(nsRange* aRange, nsIDOMNode** aParent1,
+                                    int32_t* aOffset1, nsIDOMNode** aParent2,
+                                    int32_t* aOffset2);
+  static nsresult CreateRange(nsIDOMNode* aStartParent, int32_t aStartOffset,
+                              nsIDOMNode* aEndParent, int32_t aEndOffset,
+                              nsRange** aRange);
 
 private:
   /* nsTextServicesDocument private methods. */
 
-  nsresult CreateContentIterator(nsIDOMRange *aRange, nsIContentIterator **aIterator);
+  nsresult CreateContentIterator(nsRange* aRange,
+                                 nsIContentIterator** aIterator);
 
   nsresult GetDocumentContentRootNode(nsIDOMNode **aNode);
-  nsresult CreateDocumentContentRange(nsIDOMRange **aRange);
-  nsresult CreateDocumentContentRootToNodeOffsetRange(nsIDOMNode *aParent, int32_t aOffset, bool aToStart, nsIDOMRange **aRange);
+  nsresult CreateDocumentContentRange(nsRange** aRange);
+  nsresult CreateDocumentContentRootToNodeOffsetRange(nsIDOMNode* aParent,
+                                                      int32_t aOffset,
+                                                      bool aToStart,
+                                                      nsRange** aRange);
   nsresult CreateDocumentContentIterator(nsIContentIterator **aIterator);
 
   nsresult AdjustContentIterator();
 
   static nsresult FirstTextNode(nsIContentIterator *aIterator, TSDIteratorStatus *IteratorStatus);
   static nsresult LastTextNode(nsIContentIterator *aIterator, TSDIteratorStatus *IteratorStatus);
 
   static nsresult FirstTextNodeInCurrentBlock(nsIContentIterator *aIterator);
@@ -200,18 +208,17 @@ private:
   nsresult GetUncollapsedSelection(TSDBlockSelectionStatus *aSelStatus, int32_t *aSelOffset, int32_t *aSelLength);
 
   bool SelectionIsCollapsed();
   bool SelectionIsValid();
 
   static nsresult CreateOffsetTable(nsTArray<OffsetEntry*> *aOffsetTable,
                              nsIContentIterator *aIterator,
                              TSDIteratorStatus *aIteratorStatus,
-                             nsIDOMRange *aIterRange,
-                             nsString *aStr);
+                             nsRange* aIterRange, nsString* aStr);
   static nsresult ClearOffsetTable(nsTArray<OffsetEntry*> *aOffsetTable);
 
   static nsresult NodeHasOffsetEntry(nsTArray<OffsetEntry*> *aOffsetTable,
                                      nsIDOMNode *aNode,
                                      bool *aHasEntry,
                                      int32_t *aEntryIndex);
 
   nsresult RemoveInvalidOffsetEntries();