Bug 1465702 - part 5: Remove unnecessary Selection argument from editor module r=m_kato
authorMasayuki Nakano <masayuki@d-toybox.com>
Tue, 30 Oct 2018 10:01:38 +0000
changeset 502708 1945bfc27c6d9bbd6797df4aa2117b787907a525
parent 502707 986f21f1f5d5757812f6956aa9b8722c6a043842
child 502709 258672244b3e879b464788d7e054e9f72bd67655
push id1905
push userffxbld-merge
push dateMon, 21 Jan 2019 12:33:13 +0000
treeherdermozilla-release@c2fca1944d8c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersm_kato
bugs1465702
milestone65.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 1465702 - part 5: Remove unnecessary Selection argument from editor module r=m_kato EditorBase::SelectionRefPtr() is now safe to use in editor and really fast to retrieve Selection than EditorBase::GetSelection(). Therefore, we can get rid of all Selection pointer/reference argument of each method which always take normal Selection. Note that this changes nsIHTMLEditor.checkSelectionStateForAnonymousButtons() because its argument is only Selection. So, BlueGriffon should work even though it calls the method with nsIEditor.selection. Differential Revision: https://phabricator.services.mozilla.com/D10009
editor/libeditor/CSSEditUtils.cpp
editor/libeditor/EditorBase.cpp
editor/libeditor/EditorBase.h
editor/libeditor/HTMLAbsPositionEditor.cpp
editor/libeditor/HTMLAnonymousNodeEditor.cpp
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/HTMLEditor.cpp
editor/libeditor/HTMLEditor.h
editor/libeditor/HTMLEditorDataTransfer.cpp
editor/libeditor/HTMLEditorEventListener.cpp
editor/libeditor/HTMLStyleEditor.cpp
editor/libeditor/HTMLTableEditor.cpp
editor/libeditor/TextEditRules.cpp
editor/libeditor/TextEditor.cpp
editor/libeditor/TextEditor.h
editor/libeditor/TypeInState.cpp
editor/libeditor/WSRunObject.cpp
editor/nsIHTMLEditor.idl
--- a/editor/libeditor/CSSEditUtils.cpp
+++ b/editor/libeditor/CSSEditUtils.cpp
@@ -448,17 +448,17 @@ CSSEditUtils::SetCSSProperty(Element& aE
     ChangeStyleTransaction::Create(aElement, aProperty, aValue);
   if (aSuppressTxn) {
     return transaction->DoTransaction();
   }
   if (NS_WARN_IF(!mHTMLEditor)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
   RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
-  return htmlEditor->DoTransaction(transaction);
+  return htmlEditor->DoTransactionInternal(transaction);
 }
 
 nsresult
 CSSEditUtils::SetCSSPropertyPixels(Element& aElement,
                                    nsAtom& aProperty,
                                    int32_t aIntValue)
 {
   nsAutoString s;
@@ -480,17 +480,17 @@ CSSEditUtils::RemoveCSSProperty(Element&
     ChangeStyleTransaction::CreateToRemove(aElement, aProperty, aValue);
   if (aSuppressTxn) {
     return transaction->DoTransaction();
   }
   if (NS_WARN_IF(!mHTMLEditor)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
   RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
-  return htmlEditor->DoTransaction(transaction);
+  return htmlEditor->DoTransactionInternal(transaction);
 }
 
 // static
 nsresult
 CSSEditUtils::GetSpecifiedProperty(nsINode& aNode,
                                    nsAtom& aProperty,
                                    nsAString& aValue)
 {
--- a/editor/libeditor/EditorBase.cpp
+++ b/editor/libeditor/EditorBase.cpp
@@ -747,29 +747,29 @@ EditorBase::GetSelection(SelectionType a
 NS_IMETHODIMP
 EditorBase::DoTransaction(nsITransaction* aTxn)
 {
   AutoEditActionDataSetter editActionData(*this, EditAction::eUnknown);
   if (NS_WARN_IF(!editActionData.CanHandle())) {
     return NS_ERROR_FAILURE;
   }
 
-  return DoTransaction(nullptr, aTxn);
+  return DoTransactionInternal(aTxn);
 }
 
 nsresult
-EditorBase::DoTransaction(Selection* aSelection, nsITransaction* aTxn)
+EditorBase::DoTransactionInternal(nsITransaction* aTxn)
 {
   if (mPlaceholderBatch && !mPlaceholderTransaction) {
     mPlaceholderTransaction =
       PlaceholderTransaction::Create(*this, mPlaceholderName, std::move(mSelState));
     MOZ_ASSERT(mSelState.isNothing());
 
     // We will recurse, but will not hit this case in the nested call
-    DoTransaction(mPlaceholderTransaction);
+    DoTransactionInternal(mPlaceholderTransaction);
 
     if (mTransactionManager) {
       nsCOMPtr<nsITransaction> topTransaction =
         mTransactionManager->PeekUndoStack();
       nsCOMPtr<nsIAbsorbingTransaction> topAbsorbingTransaction =
         do_QueryInterface(topTransaction);
       if (topAbsorbingTransaction) {
         RefPtr<PlaceholderTransaction> topPlaceholderTransaction =
@@ -801,20 +801,17 @@ EditorBase::DoTransaction(Selection* aSe
     // XXX: selection listeners have access to accurate frame data?
     // XXX:
     // XXX: Note that if we did add Begin/EndUpdateViewBatch() calls
     // XXX: we will need to make sure that they are disabled during
     // XXX: the init of the editor for text widgets to avoid layout
     // XXX: re-entry during initial reflow. - kin
 
     // get the selection and start a batch change
-    RefPtr<Selection> selection = aSelection ? aSelection : GetSelection();
-    NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
-
-    SelectionBatcher selectionBatcher(selection);
+    SelectionBatcher selectionBatcher(SelectionRefPtr());
 
     nsresult rv;
     if (mTransactionManager) {
       RefPtr<TransactionManager> transactionManager(mTransactionManager);
       rv = transactionManager->DoTransaction(aTxn);
     } else {
       rv = aTxn->DoTransaction();
     }
@@ -1060,21 +1057,17 @@ EditorBase::SelectAllInternal()
   if (NS_WARN_IF(Destroyed())) {
     return NS_ERROR_EDITOR_DESTROYED;
   }
 
   // XXX Do we need to keep handling after committing composition causes moving
   //     focus to different element?  Although TextEditor has independent
   //     selection, so, we may not see any odd behavior even in such case.
 
-  RefPtr<Selection> selection = GetSelection();
-  if (NS_WARN_IF(!selection)) {
-    return NS_ERROR_FAILURE;
-  }
-  nsresult rv = SelectEntireDocument(selection);
+  nsresult rv = SelectEntireDocument();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 EditorBase::BeginningOfDocument()
@@ -1113,45 +1106,43 @@ EditorBase::BeginningOfDocument()
 
 NS_IMETHODIMP
 EditorBase::EndOfDocument()
 {
   AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing);
   if (NS_WARN_IF(!editActionData.CanHandle())) {
     return NS_ERROR_NOT_INITIALIZED;
   }
-  return CollapseSelectionToEnd(SelectionRefPtr());
+  return CollapseSelectionToEnd();
 }
 
 nsresult
-EditorBase::CollapseSelectionToEnd(Selection* aSelection)
-{
+EditorBase::CollapseSelectionToEnd()
+{
+  MOZ_ASSERT(IsEditActionDataAvailable());
+
   // XXX Why doesn't this check if the document is alive?
   if (NS_WARN_IF(!IsInitialized())) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
-  if (NS_WARN_IF(!aSelection)) {
-    return NS_ERROR_NULL_POINTER;
-  }
-
   // get the root element
   nsINode* node = GetRoot();
   if (NS_WARN_IF(!node)) {
     return NS_ERROR_NULL_POINTER;
   }
 
   nsINode* child = node->GetLastChild();
   while (child && IsContainer(child)) {
     node = child;
     child = node->GetLastChild();
   }
 
   uint32_t length = node->Length();
-  return aSelection->Collapse(node, static_cast<int32_t>(length));
+  return SelectionRefPtr()->Collapse(node, static_cast<int32_t>(length));
 }
 
 NS_IMETHODIMP
 EditorBase::GetDocumentModified(bool* outDocModified)
 {
   NS_ENSURE_TRUE(outDocModified, NS_ERROR_NULL_POINTER);
 
   int32_t  modCount = 0;
@@ -1270,17 +1261,17 @@ EditorBase::SetAttribute(Element* aEleme
 
 nsresult
 EditorBase::SetAttributeWithTransaction(Element& aElement,
                                         nsAtom& aAttribute,
                                         const nsAString& aValue)
 {
   RefPtr<ChangeAttributeTransaction> transaction =
     ChangeAttributeTransaction::Create(aElement, aAttribute, aValue);
-  return DoTransaction(transaction);
+  return DoTransactionInternal(transaction);
 }
 
 NS_IMETHODIMP
 EditorBase::GetAttributeValue(Element* aElement,
                               const nsAString& aAttribute,
                               nsAString& aResultValue,
                               bool* aResultIsSet)
 {
@@ -1322,17 +1313,17 @@ nsresult
 EditorBase::RemoveAttributeWithTransaction(Element& aElement,
                                            nsAtom& aAttribute)
 {
   // XXX If aElement doesn't have aAttribute, shouldn't we stop creating
   //     the transaction?  Otherwise, there will be added a transaction
   //     which does nothing at doing undo/redo.
   RefPtr<ChangeAttributeTransaction> transaction =
     ChangeAttributeTransaction::CreateToRemove(aElement, aAttribute);
-  return DoTransaction(transaction);
+  return DoTransactionInternal(transaction);
 }
 
 NS_IMETHODIMP
 EditorBase::MarkNodeDirty(nsINode* aNode)
 {
   // Mark the node dirty, but not for webpages (bug 599983)
   if (!OutputsMozDirty()) {
     return NS_OK;
@@ -1434,17 +1425,17 @@ EditorBase::CreateNodeWithTransaction(
   AutoTopLevelEditSubActionNotifier maybeTopLevelEditSubAction(
                                       *this, EditSubAction::eCreateNode,
                                       nsIEditor::eNext);
 
   RefPtr<Element> newElement;
 
   RefPtr<CreateElementTransaction> transaction =
     CreateElementTransaction::Create(*this, aTagName, aPointToInsert);
-  nsresult rv = DoTransaction(transaction);
+  nsresult rv = DoTransactionInternal(transaction);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     // XXX Why do we do this even when DoTransaction() returned error?
     mRangeUpdater.SelAdjCreateNode(aPointToInsert);
   } else {
     newElement = transaction->GetNewNode();
     MOZ_ASSERT(newElement);
 
     // If we succeeded to create and insert new element, we need to adjust
@@ -1516,17 +1507,17 @@ EditorBase::InsertNodeWithTransaction(
   MOZ_ASSERT(aPointToInsert.IsSetAndValid());
 
   AutoTopLevelEditSubActionNotifier maybeTopLevelEditSubAction(
                                       *this, EditSubAction::eInsertNode,
                                       nsIEditor::eNext);
 
   RefPtr<InsertNodeTransaction> transaction =
     InsertNodeTransaction::Create(*this, aContentToInsert, aPointToInsert);
-  nsresult rv = DoTransaction(transaction);
+  nsresult rv = DoTransactionInternal(transaction);
 
   mRangeUpdater.SelAdjInsertNode(aPointToInsert);
 
   if (mRules && mRules->AsHTMLEditRules()) {
     Selection* selection = GetSelection();
     if (selection) {
       RefPtr<HTMLEditRules> htmlEditRules = mRules->AsHTMLEditRules();
       htmlEditRules->DidInsertNode(*selection, aContentToInsert);
@@ -1590,17 +1581,17 @@ EditorBase::SplitNodeWithTransaction(
 
   // XXX Unfortunately, storing offset of the split point in
   //     SplitNodeTransaction is necessary for now.  We should fix this
   //     in a follow up bug.
   Unused << aStartOfRightNode.Offset();
 
   RefPtr<SplitNodeTransaction> transaction =
     SplitNodeTransaction::Create(*this, aStartOfRightNode);
-  aError = DoTransaction(transaction);
+  aError = DoTransactionInternal(transaction);
 
   nsCOMPtr<nsIContent> newNode = transaction->GetNewNode();
   NS_WARNING_ASSERTION(newNode, "Failed to create a new left node");
 
   // XXX Some other transactions manage range updater by themselves.
   //     Why doesn't SplitNodeTransaction do it?
   mRangeUpdater.SelAdjSplitNode(*aStartOfRightNode.GetContainerAsContent(),
                                 newNode);
@@ -1675,17 +1666,17 @@ EditorBase::JoinNodesWithTransaction(nsI
     RefPtr<HTMLEditRules> htmlEditRules = mRules->AsHTMLEditRules();
     htmlEditRules->WillJoinNodes(aLeftNode, aRightNode);
   }
 
   nsresult rv = NS_OK;
   RefPtr<JoinNodeTransaction> transaction =
     JoinNodeTransaction::MaybeCreate(*this, aLeftNode, aRightNode);
   if (transaction)  {
-    rv = DoTransaction(transaction);
+    rv = DoTransactionInternal(transaction);
   }
 
   // XXX Some other transactions manage range updater by themselves.
   //     Why doesn't JoinNodeTransaction do it?
   mRangeUpdater.SelAdjJoinNodes(aLeftNode, aRightNode, *parent, offset,
                                 (int32_t)oldLeftNodeLen);
 
   if (mRules && mRules->AsHTMLEditRules()) {
@@ -1749,18 +1740,19 @@ EditorBase::DeleteNodeWithTransaction(ns
       NS_WARNING("Selection has gone");
     }
   }
 
   // FYI: DeleteNodeTransaction grabs aNode while it's alive.  So, it's safe
   //      to refer aNode even after calling DoTransaction().
   RefPtr<DeleteNodeTransaction> deleteNodeTransaction =
     DeleteNodeTransaction::MaybeCreate(*this, aNode);
-  nsresult rv = deleteNodeTransaction ? DoTransaction(deleteNodeTransaction) :
-                                        NS_ERROR_FAILURE;
+  nsresult rv =
+    deleteNodeTransaction ? DoTransactionInternal(deleteNodeTransaction) :
+                            NS_ERROR_FAILURE;
 
   if (mTextServicesDocument && NS_SUCCEEDED(rv)) {
     RefPtr<TextServicesDocument> textServicesDocument = mTextServicesDocument;
     textServicesDocument->DidDeleteNode(&aNode);
   }
 
   if (!mActionListeners.IsEmpty()) {
     AutoActionListenerArray listeners(mActionListeners);
@@ -2380,29 +2372,33 @@ EditorBase::OutputToString(const nsAStri
 
 bool
 EditorBase::ArePreservingSelection()
 {
   return !(mSavedSel.IsEmpty());
 }
 
 void
-EditorBase::PreserveSelectionAcrossActions(Selection* aSel)
-{
-  mSavedSel.SaveSelection(aSel);
+EditorBase::PreserveSelectionAcrossActions()
+{
+  MOZ_ASSERT(IsEditActionDataAvailable());
+
+  mSavedSel.SaveSelection(SelectionRefPtr());
   mRangeUpdater.RegisterSelectionState(mSavedSel);
 }
 
 nsresult
-EditorBase::RestorePreservedSelection(Selection* aSel)
-{
+EditorBase::RestorePreservedSelection()
+{
+  MOZ_ASSERT(IsEditActionDataAvailable());
+
   if (mSavedSel.IsEmpty()) {
     return NS_ERROR_FAILURE;
   }
-  mSavedSel.RestoreSelection(aSel);
+  mSavedSel.RestoreSelection(SelectionRefPtr());
   StopPreservingSelection();
   return NS_OK;
 }
 
 void
 EditorBase::StopPreservingSelection()
 {
   mRangeUpdater.DropSelectionState(mSavedSel);
@@ -2846,17 +2842,17 @@ EditorBase::InsertTextIntoTextNodeWithTr
   } else {
     transaction =
       InsertTextTransaction::Create(*this, aStringToInsert, aTextNode, aOffset);
   }
 
   // XXX We may not need these view batches anymore.  This is handled at a
   // higher level now I believe.
   BeginUpdateViewBatch();
-  nsresult rv = DoTransaction(transaction);
+  nsresult rv = DoTransactionInternal(transaction);
   EndUpdateViewBatch();
 
   if (mRules && mRules->AsHTMLEditRules() && insertedTextNode) {
     Selection* selection = GetSelection();
     if (selection) {
       RefPtr<HTMLEditRules> htmlEditRules = mRules->AsHTMLEditRules();
       htmlEditRules->DidInsertText(*selection, *insertedTextNode,
                                    insertedOffset, aStringToInsert);
@@ -2892,29 +2888,27 @@ EditorBase::InsertTextIntoTextNodeWithTr
       static_cast<CompositionTransaction*>(transaction.get())->MarkFixed();
     }
   }
 
   return rv;
 }
 
 nsresult
-EditorBase::SelectEntireDocument(Selection* aSelection)
-{
-  if (!aSelection) {
-    return NS_ERROR_NULL_POINTER;
-  }
+EditorBase::SelectEntireDocument()
+{
+  MOZ_ASSERT(IsEditActionDataAvailable());
 
   Element* rootElement = GetRoot();
   if (!rootElement) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
   ErrorResult errorResult;
-  aSelection->SelectAllChildren(*rootElement, errorResult);
+  SelectionRefPtr()->SelectAllChildren(*rootElement, errorResult);
   return errorResult.StealNSResult();
 }
 
 nsINode*
 EditorBase::GetFirstEditableNode(nsINode* aRoot)
 {
   MOZ_ASSERT(aRoot);
 
@@ -2979,19 +2973,21 @@ EditorBase::NotifyDocumentListeners(
     default:
       MOZ_ASSERT_UNREACHABLE("Unknown notification");
   }
 
   return rv;
 }
 
 nsresult
-EditorBase::SetTextImpl(Selection& aSelection, const nsAString& aString,
+EditorBase::SetTextImpl(const nsAString& aString,
                         Text& aCharData)
 {
+  MOZ_ASSERT(IsEditActionDataAvailable());
+
   const uint32_t length = aCharData.Length();
 
   AutoTopLevelEditSubActionNotifier maybeTopLevelEditSubAction(
                                       *this, EditSubAction::eSetText,
                                       nsIEditor::eNext);
 
   // Let listeners know what's up
   if (!mActionListeners.IsEmpty() && length) {
@@ -3006,38 +3002,34 @@ EditorBase::SetTextImpl(Selection& aSele
   // the rules!
   ErrorResult res;
   aCharData.SetData(aString, res);
   nsresult rv = res.StealNSResult();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-  RefPtr<Selection> selection = GetSelection();
-  if (NS_WARN_IF(!selection)) {
-    return NS_ERROR_FAILURE;
-  }
-
   {
     // Create a nested scope to not overwrite rv from the outer scope.
-    DebugOnly<nsresult> rv = selection->Collapse(&aCharData, aString.Length());
+    DebugOnly<nsresult> rv =
+      SelectionRefPtr()->Collapse(&aCharData, aString.Length());
     NS_ASSERTION(NS_SUCCEEDED(rv),
                  "Selection could not be collapsed after insert");
   }
 
   mRangeUpdater.SelAdjDeleteText(&aCharData, 0, length);
   mRangeUpdater.SelAdjInsertText(aCharData, 0, aString);
 
   if (mRules && mRules->AsHTMLEditRules()) {
     RefPtr<HTMLEditRules> htmlEditRules = mRules->AsHTMLEditRules();
     if (length) {
-      htmlEditRules->DidDeleteText(*selection, aCharData, 0, length);
+      htmlEditRules->DidDeleteText(*SelectionRefPtr(), aCharData, 0, length);
     }
     if (!aString.IsEmpty()) {
-      htmlEditRules->DidInsertText(*selection, aCharData, 0, aString);
+      htmlEditRules->DidInsertText(*SelectionRefPtr(), aCharData, 0, aString);
     }
   }
 
   // Let listeners know what happened
   if (!mActionListeners.IsEmpty()) {
     AutoActionListenerArray listeners(mActionListeners);
     for (auto& listener : listeners) {
       if (length) {
@@ -3070,17 +3062,17 @@ EditorBase::DeleteTextWithTransaction(Ch
   // Let listeners know what's up
   if (!mActionListeners.IsEmpty()) {
     AutoActionListenerArray listeners(mActionListeners);
     for (auto& listener : listeners) {
       listener->WillDeleteText(&aCharData, aOffset, aLength);
     }
   }
 
-  nsresult rv = DoTransaction(transaction);
+  nsresult rv = DoTransactionInternal(transaction);
 
   if (mRules && mRules->AsHTMLEditRules()) {
     RefPtr<Selection> selection = GetSelection();
     if (selection) {
       RefPtr<HTMLEditRules> htmlEditRules = mRules->AsHTMLEditRules();
       htmlEditRules->DidDeleteText(*selection, aCharData, aOffset, aLength);
     } else {
       NS_WARNING("Selection has gone");
@@ -3945,66 +3937,62 @@ EditorBase::GetNodeAtRangeOffsetPoint(co
   if (aPoint.Container()->GetAsText()) {
     return aPoint.Container()->AsContent();
   }
   return aPoint.GetChildAtOffset();
 }
 
 // static
 EditorRawDOMPoint
-EditorBase::GetStartPoint(Selection* aSelection)
-{
-  MOZ_ASSERT(aSelection);
-
-  if (NS_WARN_IF(!aSelection->RangeCount())) {
+EditorBase::GetStartPoint(const Selection& aSelection)
+{
+  if (NS_WARN_IF(!aSelection.RangeCount())) {
     return EditorRawDOMPoint();
   }
 
-  const nsRange* range = aSelection->GetRangeAt(0);
+  const nsRange* range = aSelection.GetRangeAt(0);
   if (NS_WARN_IF(!range) ||
       NS_WARN_IF(!range->IsPositioned())) {
     return EditorRawDOMPoint();
   }
 
   return EditorRawDOMPoint(range->StartRef());
 }
 
 // static
 EditorRawDOMPoint
-EditorBase::GetEndPoint(Selection* aSelection)
-{
-  MOZ_ASSERT(aSelection);
-
-  if (NS_WARN_IF(!aSelection->RangeCount())) {
+EditorBase::GetEndPoint(const Selection& aSelection)
+{
+  if (NS_WARN_IF(!aSelection.RangeCount())) {
     return EditorRawDOMPoint();
   }
 
-  const nsRange* range = aSelection->GetRangeAt(0);
+  const nsRange* range = aSelection.GetRangeAt(0);
   if (NS_WARN_IF(!range) ||
       NS_WARN_IF(!range->IsPositioned())) {
     return EditorRawDOMPoint();
   }
 
   return EditorRawDOMPoint(range->EndRef());
 }
 
+// static
 nsresult
-EditorBase::GetEndChildNode(Selection* aSelection,
+EditorBase::GetEndChildNode(const Selection& aSelection,
                             nsIContent** aEndNode)
 {
-  MOZ_ASSERT(aSelection);
   MOZ_ASSERT(aEndNode);
 
   *aEndNode = nullptr;
 
-  if (NS_WARN_IF(!aSelection->RangeCount())) {
+  if (NS_WARN_IF(!aSelection.RangeCount())) {
     return NS_ERROR_FAILURE;
   }
 
-  const nsRange* range = aSelection->GetRangeAt(0);
+  const nsRange* range = aSelection.GetRangeAt(0);
   if (NS_WARN_IF(!range)) {
     return NS_ERROR_FAILURE;
   }
 
   if (NS_WARN_IF(!range->IsPositioned())) {
     return NS_ERROR_FAILURE;
   }
 
@@ -4240,17 +4228,17 @@ EditorBase::EndUpdateViewBatch()
   // mutation events listeners because all the changes the user can apply
   // to a document may result in multiple events, some of them quite hard
   // to listen too (in particular when an ancestor of the selection is
   // changed but the selection itself is not changed).
   if (NS_WARN_IF(!selection)) {
     return;
   }
 
-  DebugOnly<nsresult> rv = htmlEditor->RefereshEditingUI(*selection);
+  DebugOnly<nsresult> rv = htmlEditor->RefereshEditingUI();
   NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "RefereshEditingUI() failed");
 }
 
 TextComposition*
 EditorBase::GetComposition() const
 {
   return mComposition;
 }
@@ -4701,45 +4689,47 @@ EditorBase::HandleKeyPressEvent(WidgetKe
       aKeyboardEvent->PreventDefault(); // consumed
       return NS_OK;
   }
   return NS_OK;
 }
 
 nsresult
 EditorBase::HandleInlineSpellCheck(EditSubAction aEditSubAction,
-                                   Selection& aSelection,
                                    nsINode* previousSelectedNode,
                                    uint32_t previousSelectedOffset,
                                    nsINode* aStartContainer,
                                    uint32_t aStartOffset,
                                    nsINode* aEndContainer,
                                    uint32_t aEndOffset)
 {
+  MOZ_ASSERT(IsEditActionDataAvailable());
+
   if (!mInlineSpellChecker) {
     return NS_OK;
   }
   return mInlineSpellChecker->SpellCheckAfterEditorChange(
-                                aEditSubAction, aSelection,
+                                aEditSubAction, *SelectionRefPtr(),
                                 previousSelectedNode, previousSelectedOffset,
                                 aStartContainer, aStartOffset, aEndContainer,
                                 aEndOffset);
 }
 
 Element*
 EditorBase::FindSelectionRoot(nsINode* aNode) const
 {
   return GetRoot();
 }
 
 void
-EditorBase::InitializeSelectionAncestorLimit(Selection& aSelection,
-                                             nsIContent& aAncestorLimit)
-{
-  aSelection.SetAncestorLimiter(&aAncestorLimit);
+EditorBase::InitializeSelectionAncestorLimit(nsIContent& aAncestorLimit)
+{
+  MOZ_ASSERT(IsEditActionDataAvailable());
+
+  SelectionRefPtr()->SetAncestorLimiter(&aAncestorLimit);
 }
 
 nsresult
 EditorBase::InitializeSelection(EventTarget* aFocusEventTarget)
 {
   nsCOMPtr<nsINode> targetNode = do_QueryInterface(aFocusEventTarget);
   NS_ENSURE_TRUE(targetNode, NS_ERROR_INVALID_ARG);
   nsCOMPtr<nsIContent> selectionRootContent = FindSelectionRoot(targetNode);
@@ -4776,17 +4766,17 @@ EditorBase::InitializeSelection(EventTar
                          nsISelectionController::SELECTION_NORMAL);
 
   // If the computed selection root isn't root content, we should set it
   // as selection ancestor limit.  However, if that is root element, it means
   // there is not limitation of the selection, then, we must set nullptr.
   // NOTE: If we set a root element to the ancestor limit, some selection
   // methods don't work fine.
   if (selectionRootContent->GetParent()) {
-    InitializeSelectionAncestorLimit(*selection, *selectionRootContent);
+    InitializeSelectionAncestorLimit(*selectionRootContent);
   } else {
     selection->SetAncestorLimiter(nullptr);
   }
 
   // If there is composition when this is called, we may need to restore IME
   // selection because if the editor is reframed, this already forgot IME
   // selection and the transaction.
   if (mComposition && mComposition->IsMovingToNewTextNode()) {
@@ -5261,47 +5251,41 @@ EditorBase::HideCaret(bool aHide)
   }
 }
 
 /******************************************************************************
  * EditorBase::AutoSelectionRestorer
  *****************************************************************************/
 
 EditorBase::AutoSelectionRestorer::AutoSelectionRestorer(
-                                     Selection& aSelection,
                                      EditorBase& aEditorBase
                                      MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
   : mEditorBase(nullptr)
 {
   MOZ_GUARD_OBJECT_NOTIFIER_INIT;
   if (aEditorBase.ArePreservingSelection()) {
     // We already have initialized mSavedSel, so this must be nested call.
     return;
   }
-  mSelection = &aSelection;
+  MOZ_ASSERT(aEditorBase.IsEditActionDataAvailable());
   mEditorBase = &aEditorBase;
-  mEditorBase->PreserveSelectionAcrossActions(mSelection);
+  mEditorBase->PreserveSelectionAcrossActions();
 }
 
 EditorBase::AutoSelectionRestorer::~AutoSelectionRestorer()
 {
-  NS_ASSERTION(!mSelection || mEditorBase,
-               "mEditorBase should be non-null when mSelection is");
-  // mSelection will be null if this was nested call.
-  if (mSelection && mEditorBase->ArePreservingSelection()) {
-    mEditorBase->RestorePreservedSelection(mSelection);
+  if (mEditorBase && mEditorBase->ArePreservingSelection()) {
+    mEditorBase->RestorePreservedSelection();
   }
 }
 
 void
 EditorBase::AutoSelectionRestorer::Abort()
 {
-  NS_ASSERTION(!mSelection || mEditorBase,
-               "mEditorBase should be non-null when mSelection is");
-  if (mSelection) {
+  if (mEditorBase) {
     mEditorBase->StopPreservingSelection();
   }
 }
 
 /*****************************************************************************
  * mozilla::EditorBase::AutoEditActionDataSetter
  *****************************************************************************/
 
--- a/editor/libeditor/EditorBase.h
+++ b/editor/libeditor/EditorBase.h
@@ -798,18 +798,17 @@ protected: // May be called by friends.
    *                            E.g., adjusting whitespaces during composition.
    *                            false, otherwise.
    */
   nsresult
   InsertTextIntoTextNodeWithTransaction(const nsAString& aStringToInsert,
                                         Text& aTextNode, int32_t aOffset,
                                         bool aSuppressIME = false);
 
-  nsresult SetTextImpl(Selection& aSelection,
-                       const nsAString& aString,
+  nsresult SetTextImpl(const nsAString& aString,
                        Text& aTextNode);
 
   /**
    * DeleteNodeWithTransaction() removes aNode from the DOM tree.
    *
    * @param aNode       The node which will be removed form the DOM tree.
    */
   nsresult DeleteNodeWithTransaction(nsINode& aNode);
@@ -1311,21 +1310,17 @@ protected: // May be called by friends.
    * @param aLeftNode   The node which will be removed form the tree.
    * @param aRightNode  The node which will be inserted the contents of
    *                    aLeftNode.
    * @return            The point of the first child of the last right node.
    */
   EditorDOMPoint JoinNodesDeepWithTransaction(nsIContent& aLeftNode,
                                               nsIContent& aRightNode);
 
-  /**
-   * Note that aSelection is optional and can be nullptr.
-   */
-  nsresult DoTransaction(Selection* aSelection,
-                         nsITransaction* aTxn);
+  nsresult DoTransactionInternal(nsITransaction* aTxn);
 
   virtual bool IsBlockNode(nsINode* aNode);
 
   /**
    * Set outOffset to the offset of aChild in the parent.
    * Returns the parent of aChild.
    */
   static nsINode* GetNodeLocation(nsINode* aChild, int32_t* aOffset);
@@ -1597,26 +1592,26 @@ protected: // May be called by friends.
    */
   static nsIContent* GetNodeAtRangeOffsetPoint(nsINode* aContainer,
                                                int32_t aOffset)
   {
     return GetNodeAtRangeOffsetPoint(RawRangeBoundary(aContainer, aOffset));
   }
   static nsIContent* GetNodeAtRangeOffsetPoint(const RawRangeBoundary& aPoint);
 
-  static EditorRawDOMPoint GetStartPoint(Selection* aSelection);
-  static EditorRawDOMPoint GetEndPoint(Selection* aSelection);
+  static EditorRawDOMPoint GetStartPoint(const Selection& aSelection);
+  static EditorRawDOMPoint GetEndPoint(const Selection& aSelection);
 
-  static nsresult GetEndChildNode(Selection* aSelection,
+  static nsresult GetEndChildNode(const Selection& aSelection,
                                   nsIContent** aEndNode);
 
   /**
    * CollapseSelectionToEnd() collapses the selection to the end of the editor.
    */
-  nsresult CollapseSelectionToEnd(Selection* aSelection);
+  nsresult CollapseSelectionToEnd();
 
   /**
    * Helpers to add a node to the selection.
    * Used by table cell selection methods.
    */
   nsresult CreateRange(nsINode* aStartContainer, int32_t aStartOffset,
                        nsINode* aEndContainer, int32_t aEndOffset,
                        nsRange** aRange);
@@ -1639,17 +1634,16 @@ protected: // May be called by friends.
    * makes this editor not allow transactions to change Selection.
    */
   inline void MakeThisAllowTransactionsToChangeSelection(bool aAllow)
   {
     mAllowsTransactionsToChangeSelection = aAllow;
   }
 
   nsresult HandleInlineSpellCheck(EditSubAction aEditSubAction,
-                                  Selection& aSelection,
                                   nsINode* previousSelectedNode,
                                   uint32_t previousSelectedOffset,
                                   nsINode* aStartContainer,
                                   uint32_t aStartOffset,
                                   nsINode* aEndContainer,
                                   uint32_t aEndOffset);
 
   /**
@@ -1715,18 +1709,18 @@ protected: // Called by helper classes.
    */
   virtual void OnEndHandlingTopLevelEditSubAction();
 
   /**
    * Routines for managing the preservation of selection across
    * various editor actions.
    */
   bool ArePreservingSelection();
-  void PreserveSelectionAcrossActions(Selection* aSel);
-  nsresult RestorePreservedSelection(Selection* aSel);
+  void PreserveSelectionAcrossActions();
+  nsresult RestorePreservedSelection();
   void StopPreservingSelection();
 
   /**
    * (Begin|End)PlaceholderTransaction() are called by AutoPlaceholderBatch.
    * This set of methods are similar to the (Begin|End)Transaction(), but do
    * not use the transaction managers batching feature.  Instead we use a
    * placeholder transaction to wrap up any further transaction while the
    * batch is open.  The advantage of this is that placeholder transactions
@@ -1797,17 +1791,17 @@ protected: // Shouldn't be used by frien
     eDocumentStateChanged
   };
   nsresult NotifyDocumentListeners(
              TDocumentListenerNotification aNotificationType);
 
   /**
    * Make the given selection span the entire document.
    */
-  virtual nsresult SelectEntireDocument(Selection* aSelection);
+  virtual nsresult SelectEntireDocument();
 
   /**
    * Helper method for scrolling the selection into view after
    * an edit operation. aScrollToAnchor should be true if you
    * want to scroll to the point where the selection was started.
    * If false, it attempts to scroll the end of the selection into view.
    *
    * Editor methods *should* call this method instead of the versions
@@ -1903,25 +1897,23 @@ protected: // Shouldn't be used by frien
     // or not.
     return !IsPasswordEditor() && !IsReadonly() && !IsDisabled() &&
            !ShouldSkipSpellCheck();
   }
 
   /**
    * InitializeSelectionAncestorLimit() is called by InitializeSelection().
    * When this is called, each implementation has to call
-   * aSelection.SetAncestorLimiter() with aAnotherLimit.
+   * Selection::SetAncestorLimiter() with aAnotherLimit.
    *
-   * @param aSelection          The selection.
-   * @param aAncestorLimit      New ancestor limit of aSelection.  This always
+   * @param aAncestorLimit      New ancestor limit of Selection.  This always
    *                            has parent node.  So, it's always safe to
    *                            call SetAncestorLimit() with this node.
    */
-  virtual void InitializeSelectionAncestorLimit(Selection& aSelection,
-                                                nsIContent& aAncestorLimit);
+  virtual void InitializeSelectionAncestorLimit(nsIContent& aAncestorLimit);
 
   /**
    * Return the offset of aChild in aParent.  Asserts fatally if parent or
    * child is null, or parent is not child's parent.
    * FYI: aChild must not be being removed from aParent.  In such case, these
    *      methods may return wrong index if aChild doesn't have previous
    *      sibling or next sibling.
    */
@@ -2046,32 +2038,30 @@ protected: // helper classes which may b
    */
   class MOZ_RAII AutoSelectionRestorer final
   {
   public:
     /**
      * Constructor responsible for remembering all state needed to restore
      * aSelection.
      */
-    AutoSelectionRestorer(Selection& aSelection,
-                          EditorBase& aEditorBase
-                          MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
+    explicit AutoSelectionRestorer(EditorBase& aEditorBase
+                                   MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
 
     /**
      * Destructor restores mSelection to its former state
      */
     ~AutoSelectionRestorer();
 
     /**
      * Abort() cancels to restore the selection.
      */
     void Abort();
 
   protected:
-    RefPtr<Selection> mSelection;
     EditorBase* mEditorBase;
     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
   };
 
   /**
    * AutoTopLevelEditSubActionNotifier notifies editor of start to handle
    * top level edit sub-action and end handling top level edit sub-action.
    */
--- a/editor/libeditor/HTMLAbsPositionEditor.cpp
+++ b/editor/libeditor/HTMLAbsPositionEditor.cpp
@@ -85,17 +85,17 @@ HTMLEditor::SetSelectionToAbsoluteOrStat
 already_AddRefed<Element>
 HTMLEditor::GetAbsolutelyPositionedSelectionContainer()
 {
   AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing);
   if (NS_WARN_IF(!editActionData.CanHandle())) {
     return nullptr;
   }
 
-  RefPtr<Element> element = GetSelectionContainerElement(*SelectionRefPtr());
+  RefPtr<Element> element = GetSelectionContainerElement();
   if (NS_WARN_IF(!element)) {
     return nullptr;
   }
 
   nsAutoString positionStr;
   while (element && !element->IsHTMLElement(nsGkAtoms::html)) {
     nsresult rv =
       CSSEditUtils::GetComputedProperty(*element, *nsGkAtoms::position,
@@ -468,21 +468,17 @@ HTMLEditor::EndMoving()
                             mMouseMotionListenerP,
                             NS_LITERAL_STRING("mousemove"),
                             TrustedEventsAtSystemGroupBubble());
   }
   mMouseMotionListenerP = nullptr;
 
   mGrabberClicked = false;
   mIsMoving = false;
-  RefPtr<Selection> selection = GetSelection();
-  if (!selection) {
-    return NS_ERROR_NOT_INITIALIZED;
-  }
-  nsresult rv = RefereshEditingUI(*selection);
+  nsresult rv = RefereshEditingUI();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   return NS_OK;
 }
 nsresult
 HTMLEditor::SetFinalPosition(int32_t aX,
                              int32_t aY)
@@ -577,18 +573,17 @@ HTMLEditor::SetPositionToAbsolute(Elemen
   // container
   nsINode* parentNode = aElement.GetParentNode();
   if (parentNode->GetChildCount() == 1) {
     RefPtr<Selection> selection = GetSelection();
     if (NS_WARN_IF(!selection)) {
       return NS_ERROR_FAILURE;
     }
     RefPtr<Element> newBrElement =
-      InsertBrElementWithTransaction(*selection,
-                                     EditorRawDOMPoint(parentNode, 0));
+      InsertBrElementWithTransaction(EditorRawDOMPoint(parentNode, 0));
     if (NS_WARN_IF(!newBrElement)) {
       return NS_ERROR_FAILURE;
     }
   }
   return NS_OK;
 }
 
 nsresult
--- a/editor/libeditor/HTMLAnonymousNodeEditor.cpp
+++ b/editor/libeditor/HTMLAnonymousNodeEditor.cpp
@@ -323,37 +323,35 @@ HTMLEditor::HideAnonymousEditingUIsIfUnn
     //     operation now.
     DebugOnly<nsresult> rv = HideResizersInternal();
     NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "HideResizersInternal() failed");
     NS_ASSERTION(!mResizedObject, "HideResizersInternal() failed");
   }
 }
 
 NS_IMETHODIMP
-HTMLEditor::CheckSelectionStateForAnonymousButtons(Selection* aSelection)
+HTMLEditor::CheckSelectionStateForAnonymousButtons()
 {
-  if (NS_WARN_IF(!aSelection)) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
   AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing);
   if (NS_WARN_IF(!editActionData.CanHandle())) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
-  nsresult rv = RefereshEditingUI(*aSelection);
+  nsresult rv = RefereshEditingUI();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   return NS_OK;
 }
 
 nsresult
-HTMLEditor::RefereshEditingUI(Selection& aSelection)
+HTMLEditor::RefereshEditingUI()
 {
+  MOZ_ASSERT(IsEditActionDataAvailable());
+
   // First, we need to remove unnecessary editing UI now since some of them
   // may be disabled while them are visible.
   HideAnonymousEditingUIsIfUnnecessary();
 
   // early way out if all contextual UI extensions are disabled
   if (!IsObjectResizerEnabled() &&
       !IsAbsolutePositionEditorEnabled() &&
       !IsInlineTableEditorEnabled()) {
@@ -361,17 +359,17 @@ HTMLEditor::RefereshEditingUI(Selection&
   }
 
   // Don't change selection state if we're moving.
   if (mIsMoving) {
     return NS_OK;
   }
 
   // let's get the containing element of the selection
-  RefPtr<Element> focusElement = GetSelectionContainerElement(aSelection);
+  RefPtr<Element> focusElement = GetSelectionContainerElement();
   if (NS_WARN_IF(!focusElement)) {
     return NS_OK;
   }
 
   // If we're not in a document, don't try to add resizers
   if (!focusElement->IsInUncomposedDoc()) {
     return NS_OK;
   }
@@ -385,18 +383,17 @@ HTMLEditor::RefereshEditingUI(Selection&
     // in an absolutely positioned element ?
     absPosElement = GetAbsolutelyPositionedSelectionContainer();
   }
 
   RefPtr<Element> cellElement;
   if (IsObjectResizerEnabled() || IsInlineTableEditorEnabled()) {
     // Resizing or Inline Table Editing is enabled, we need to check if the
     // selection is contained in a table cell
-    cellElement =
-      GetElementOrParentByTagNameAtSelection(aSelection, *nsGkAtoms::td);
+    cellElement = GetElementOrParentByTagNameAtSelection(*nsGkAtoms::td);
   }
 
   if (IsObjectResizerEnabled() && cellElement) {
     // we are here because Resizing is enabled AND selection is contained in
     // a cell
 
     // get the enclosing table
     if (nsGkAtoms::img != focusTagAtom) {
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -176,17 +176,17 @@ public:
     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
 
     if (aSelection.GetAncestorLimiter()) {
       return;
     }
 
     Element* root = aHTMLEditor.FindSelectionRoot(&aStartPointNode);
     if (root) {
-      aHTMLEditor.InitializeSelectionAncestorLimit(aSelection, *root);
+      aHTMLEditor.InitializeSelectionAncestorLimit(*root);
       mSelection = &aSelection;
     }
   }
 
   ~AutoSetTemporaryAncestorLimiter()
   {
     if (mSelection) {
       mSelection->SetAncestorLimiter(nullptr);
@@ -629,17 +629,17 @@ HTMLEditRules::AfterEditInner(EditSubAct
       rv = ReapplyCachedStyles();
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
       ClearCachedStyles();
     }
   }
 
-  rv = HTMLEditorRef().HandleInlineSpellCheck(aEditSubAction, SelectionRef(),
+  rv = HTMLEditorRef().HandleInlineSpellCheck(aEditSubAction,
                                               mRangeItem->mStartContainer,
                                               mRangeItem->mStartOffset,
                                               rangeStartContainer,
                                               rangeStartOffset,
                                               rangeEndContainer,
                                               rangeEndOffset);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
@@ -1194,17 +1194,17 @@ HTMLEditRules::GetParagraphState(bool* a
       }
     }
   }
 
   // we might have an empty node list.  if so, find selection parent
   // and put that on the list
   if (arrayOfNodes.IsEmpty()) {
     EditorRawDOMPoint selectionStartPoint(
-                        EditorBase::GetStartPoint(&SelectionRef()));
+                        EditorBase::GetStartPoint(SelectionRef()));
     if (NS_WARN_IF(!selectionStartPoint.IsSet())) {
       return NS_ERROR_FAILURE;
     }
     arrayOfNodes.AppendElement(*selectionStartPoint.GetContainer());
   }
 
   // remember root node
   Element* rootElement = HTMLEditorRef().GetRoot();
@@ -1523,18 +1523,17 @@ HTMLEditRules::WillInsertText(EditSubAct
           pos = tString.Length();
         }
 
         nsDependentSubstring subStr(tString, oldPos, subStrLen);
 
         // is it a return?
         if (subStr.Equals(newlineStr)) {
           RefPtr<Element> brElement =
-            HTMLEditorRef().InsertBrElementWithTransaction(SelectionRef(),
-                                                           currentPoint,
+            HTMLEditorRef().InsertBrElementWithTransaction(currentPoint,
                                                            nsIEditor::eNone);
           if (NS_WARN_IF(!CanHandleEditAction())) {
             return NS_ERROR_EDITOR_DESTROYED;
           }
           if (NS_WARN_IF(!brElement)) {
             return NS_ERROR_FAILURE;
           }
           pos++;
@@ -1911,18 +1910,17 @@ HTMLEditRules::WillInsertBreak(bool* aCa
   // contains the word "text".  The user selects "text" and types return.
   // "Text" is deleted leaving an empty block.  We want to put in one br to
   // make block have a line.  Then code further below will put in a second br.)
   if (IsEmptyBlockElement(*blockParent, IgnoreSingleBR::eNo)) {
     AutoEditorDOMPointChildInvalidator lockOffset(atStartOfSelection);
     EditorRawDOMPoint endOfBlockParent;
     endOfBlockParent.SetToEndOf(blockParent);
     RefPtr<Element> brElement =
-      HTMLEditorRef().InsertBrElementWithTransaction(SelectionRef(),
-                                                     endOfBlockParent);
+      HTMLEditorRef().InsertBrElementWithTransaction(endOfBlockParent);
     if (NS_WARN_IF(!CanHandleEditAction())) {
       return NS_ERROR_EDITOR_DESTROYED;
     }
     if (NS_WARN_IF(!brElement)) {
       return NS_ERROR_FAILURE;
     }
   }
 
@@ -2007,18 +2005,17 @@ HTMLEditRules::InsertBRElement(const Edi
 
   bool brElementIsAfterBlock = false;
   bool brElementIsBeforeBlock = false;
 
   // First, insert a <br> element.
   RefPtr<Element> brElement;
   if (IsPlaintextEditor()) {
     brElement =
-      HTMLEditorRef().InsertBrElementWithTransaction(SelectionRef(),
-                                                     aPointToBreak);
+      HTMLEditorRef().InsertBrElementWithTransaction(aPointToBreak);
     if (NS_WARN_IF(!CanHandleEditAction())) {
       return NS_ERROR_EDITOR_DESTROYED;
     }
     if (NS_WARN_IF(!brElement)) {
       return NS_ERROR_FAILURE;
     }
   } else {
     EditorDOMPoint pointToBreak(aPointToBreak);
@@ -2148,17 +2145,17 @@ nsresult
 HTMLEditRules::SplitMailCites(bool* aHandled)
 {
   MOZ_ASSERT(IsEditorDataAvailable());
 
   if (NS_WARN_IF(!aHandled)) {
     return NS_ERROR_INVALID_ARG;
   }
 
-  EditorRawDOMPoint pointToSplit(EditorBase::GetStartPoint(&SelectionRef()));
+  EditorRawDOMPoint pointToSplit(EditorBase::GetStartPoint(SelectionRef()));
   if (NS_WARN_IF(!pointToSplit.IsSet())) {
     return NS_ERROR_FAILURE;
   }
 
   RefPtr<Element> citeNode =
     GetTopEnclosingMailCite(*pointToSplit.GetContainer());
   if (!citeNode) {
     return NS_OK;
@@ -2222,33 +2219,31 @@ HTMLEditRules::SplitMailCites(bool* aHan
     nsCOMPtr<nsINode> lastChild =
       previousNodeOfSplitPoint->GetLastChild();
     if (lastChild && !lastChild->IsHTMLElement(nsGkAtoms::br)) {
       // We ignore the result here.
       EditorRawDOMPoint endOfPreviousNodeOfSplitPoint;
       endOfPreviousNodeOfSplitPoint.SetToEndOf(previousNodeOfSplitPoint);
       RefPtr<Element> invisibleBrElement =
         HTMLEditorRef().InsertBrElementWithTransaction(
-                          SelectionRef(),
                           endOfPreviousNodeOfSplitPoint);
       if (NS_WARN_IF(!CanHandleEditAction())) {
         return NS_ERROR_EDITOR_DESTROYED;
       }
       NS_WARNING_ASSERTION(invisibleBrElement,
         "Failed to create an invisible <br> element");
     }
   }
 
   // In most cases, <br> should be inserted after current cite.  However, if
   // left cite hasn't been created because the split point was start of the
   // cite node, <br> should be inserted before the current cite.
   EditorRawDOMPoint pointToInsertBrNode(splitCiteNodeResult.SplitPoint());
   RefPtr<Element> brElement =
-    HTMLEditorRef().InsertBrElementWithTransaction(SelectionRef(),
-                                                   pointToInsertBrNode);
+    HTMLEditorRef().InsertBrElementWithTransaction(pointToInsertBrNode);
   if (NS_WARN_IF(!CanHandleEditAction())) {
     return NS_ERROR_EDITOR_DESTROYED;
   }
   if (NS_WARN_IF(!brElement)) {
     return NS_ERROR_FAILURE;
   }
   // Now, offset of pointToInsertBrNode is invalid.  Let's clear it.
   pointToInsertBrNode.Clear();
@@ -2292,17 +2287,17 @@ HTMLEditRules::SplitMailCites(bool* aHan
       WSRunObject wsObjAfterBR(&HTMLEditorRef(), pointAfterNewBrNode);
       wsObjAfterBR.NextVisibleNode(pointAfterNewBrNode, &wsType);
       if (wsType == WSType::normalWS || wsType == WSType::text ||
           wsType == WSType::special ||
           // In case we're at the very end.
           wsType == WSType::thisBlock) {
         brElement =
           HTMLEditorRef().InsertBrElementWithTransaction(
-                            SelectionRef(), pointToCreateNewBrNode);
+                            pointToCreateNewBrNode);
         if (NS_WARN_IF(!CanHandleEditAction())) {
           return NS_ERROR_EDITOR_DESTROYED;
         }
         if (NS_WARN_IF(!brElement)) {
           return NS_ERROR_FAILURE;
         }
         // Now, those points may be invalid.
         pointToCreateNewBrNode.Clear();
@@ -2378,18 +2373,17 @@ HTMLEditRules::WillDeleteSelection(nsIEd
   if (mBogusNode) {
     *aCancel = true;
     return NS_OK;
   }
 
   // First check for table selection mode.  If so, hand off to table editor.
   ErrorResult error;
   RefPtr<Element> cellElement =
-    HTMLEditorRef().GetFirstSelectedTableCellElement(SelectionRef(),
-                                                     error);
+    HTMLEditorRef().GetFirstSelectedTableCellElement(error);
   if (cellElement) {
     error.SuppressException();
     nsresult rv = HTMLEditorRef().DeleteTableCellContentsWithTransaction();
     if (NS_WARN_IF(!CanHandleEditAction())) {
       return NS_ERROR_EDITOR_DESTROYED;
     }
     *aHandled = true;
     return rv;
@@ -2402,17 +2396,17 @@ HTMLEditRules::WillDeleteSelection(nsIEd
   // ExtendSelectionForDelete later. TryToJoinBlocksWithTransaction() should
   // happen if the original selection is collapsed and the cursor is at the end
   // of a block element, in which case ExtendSelectionForDelete would always
   // make the selection not collapsed.
   bool join = false;
   bool origCollapsed = SelectionRef().IsCollapsed();
 
   if (origCollapsed) {
-    EditorDOMPoint startPoint(EditorBase::GetStartPoint(&SelectionRef()));
+    EditorDOMPoint startPoint(EditorBase::GetStartPoint(SelectionRef()));
     if (NS_WARN_IF(!startPoint.IsSet())) {
       return NS_ERROR_FAILURE;
     }
 
     // If we are inside an empty block, delete it.
     RefPtr<Element> host = HTMLEditorRef().GetActiveEditingHost();
     if (NS_WARN_IF(!host)) {
       return NS_ERROR_FAILURE;
@@ -2442,31 +2436,31 @@ HTMLEditRules::WillDeleteSelection(nsIEd
 
     // ExtendSelectionForDelete will use selection controller to set
     // selection for delete.  But if focus event doesn't receive yet,
     // ancestor isn't set.  So we must set root eleement of editor to
     // ancestor.
     AutoSetTemporaryAncestorLimiter autoSetter(HTMLEditorRef(), SelectionRef(),
                                                *startPoint.GetContainer());
 
-    rv = HTMLEditorRef().ExtendSelectionForDelete(&SelectionRef(), &aAction);
+    rv = HTMLEditorRef().ExtendSelectionForDelete(&aAction);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
     // We should delete nothing.
     if (aAction == nsIEditor::eNone) {
       return NS_OK;
     }
   }
 
   if (SelectionRef().IsCollapsed()) {
     // ExtendSelectionForDelete() won't change the selection.
 
-    EditorDOMPoint startPoint(EditorBase::GetStartPoint(&SelectionRef()));
+    EditorDOMPoint startPoint(EditorBase::GetStartPoint(SelectionRef()));
     if (NS_WARN_IF(!startPoint.IsSet())) {
       return NS_ERROR_FAILURE;
     }
 
     // What's in the direction we are deleting?
     WSRunObject wsObj(&HTMLEditorRef(), startPoint);
     nsCOMPtr<nsINode> visNode;
     int32_t visOffset;
@@ -3271,17 +3265,17 @@ HTMLEditRules::DeleteNodeIfCollapsedText
 }
 
 nsresult
 HTMLEditRules::InsertBRIfNeeded()
 {
   MOZ_ASSERT(IsEditorDataAvailable());
 
   EditorRawDOMPoint atStartOfSelection(
-                      EditorBase::GetStartPoint(&SelectionRef()));
+                      EditorBase::GetStartPoint(SelectionRef()));
   if (NS_WARN_IF(!atStartOfSelection.IsSet())) {
     return NS_ERROR_FAILURE;
   }
 
   // inline elements don't need any br
   if (!IsBlockNode(*atStartOfSelection.GetContainer())) {
     return NS_OK;
   }
@@ -3291,18 +3285,17 @@ HTMLEditRules::InsertBRIfNeeded()
   if (((wsObj.mStartReason & WSType::block) ||
        (wsObj.mStartReason & WSType::br)) &&
       (wsObj.mEndReason & WSType::block)) {
     // if we are tucked between block boundaries then insert a br
     // first check that we are allowed to
     if (HTMLEditorRef().CanContainTag(*atStartOfSelection.GetContainer(),
                                       *nsGkAtoms::br)) {
       RefPtr<Element> brElement =
-        HTMLEditorRef().InsertBrElementWithTransaction(SelectionRef(),
-                                                       atStartOfSelection,
+        HTMLEditorRef().InsertBrElementWithTransaction(atStartOfSelection,
                                                        nsIEditor::ePrevious);
       if (NS_WARN_IF(!CanHandleEditAction())) {
         return NS_ERROR_EDITOR_DESTROYED;
       }
       if (NS_WARN_IF(!brElement)) {
         return NS_ERROR_FAILURE;
       }
       return NS_OK;
@@ -3895,17 +3888,17 @@ HTMLEditRules::DeleteElementsExceptTable
 }
 
 nsresult
 HTMLEditRules::DidDeleteSelection()
 {
   MOZ_ASSERT(IsEditorDataAvailable());
 
   // find where we are
-  EditorDOMPoint atStartOfSelection(EditorBase::GetStartPoint(&SelectionRef()));
+  EditorDOMPoint atStartOfSelection(EditorBase::GetStartPoint(SelectionRef()));
   if (NS_WARN_IF(!atStartOfSelection.IsSet())) {
     return NS_ERROR_FAILURE;
   }
 
   // find any enclosing mailcite
   RefPtr<Element> citeNode =
     GetTopEnclosingMailCite(*atStartOfSelection.GetContainer());
   if (citeNode) {
@@ -3921,18 +3914,17 @@ HTMLEditRules::DidDeleteSelection()
           return NS_ERROR_EDITOR_DESTROYED;
         }
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return rv;
         }
       }
       if (atCiteNode.IsSet() && seenBR) {
         RefPtr<Element> brElement =
-          HTMLEditorRef().InsertBrElementWithTransaction(SelectionRef(),
-                                                         atCiteNode);
+          HTMLEditorRef().InsertBrElementWithTransaction(atCiteNode);
         if (NS_WARN_IF(!CanHandleEditAction())) {
           return NS_ERROR_EDITOR_DESTROYED;
         }
         if (NS_WARN_IF(!brElement)) {
           return NS_ERROR_FAILURE;
         }
         IgnoredErrorResult error;
         SelectionRef().Collapse(EditorRawDOMPoint(brElement), error);
@@ -4017,17 +4009,17 @@ HTMLEditRules::WillMakeList(const nsAStr
 
 nsresult
 HTMLEditRules::MakeList(nsAtom& aListType,
                         bool aEntireList,
                         const nsAString* aBulletType,
                         bool* aCancel,
                         nsAtom& aItemType)
 {
-  AutoSelectionRestorer restoreSelectionLater(SelectionRef(), HTMLEditorRef());
+  AutoSelectionRestorer restoreSelectionLater(HTMLEditorRef());
 
   nsTArray<OwningNonNull<nsINode>> arrayOfNodes;
   nsresult rv =
     GetListActionNodes(arrayOfNodes,
                        aEntireList ? EntireList::yes : EntireList::no,
                        TouchContent::yes);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
@@ -4432,17 +4424,17 @@ HTMLEditRules::WillRemoveList(bool* aCan
   *aCancel = false;
   *aHandled = true;
 
   nsresult rv = NormalizeSelection();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-  AutoSelectionRestorer restoreSelectionLater(SelectionRef(), HTMLEditorRef());
+  AutoSelectionRestorer restoreSelectionLater(HTMLEditorRef());
 
   nsTArray<RefPtr<nsRange>> arrayOfRanges;
   GetPromotedRanges(arrayOfRanges, EditSubAction::eCreateOrChangeList);
 
   // use these ranges to contruct a list of nodes to act on.
   nsTArray<OwningNonNull<nsINode>> arrayOfNodes;
   rv = GetListActionNodes(arrayOfNodes, EntireList::no, TouchContent::yes);
   if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -4536,17 +4528,17 @@ HTMLEditRules::MakeBasicBlock(nsAtom& bl
 {
   MOZ_ASSERT(IsEditorDataAvailable());
 
   nsresult rv = NormalizeSelection();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-  AutoSelectionRestorer restoreSelectionLater(SelectionRef(), HTMLEditorRef());
+  AutoSelectionRestorer restoreSelectionLater(HTMLEditorRef());
   AutoTransactionsConserveSelection dontChangeMySelection(HTMLEditorRef());
 
   // Contruct a list of nodes to act on.
   nsTArray<OwningNonNull<nsINode>> arrayOfNodes;
   rv = GetNodesFromSelection(EditSubAction::eCreateOrRemoveBlock, arrayOfNodes,
                              TouchContent::yes);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
@@ -4596,18 +4588,17 @@ HTMLEditRules::MakeBasicBlock(nsAtom& bl
         return NS_ERROR_EDITOR_DESTROYED;
       }
       if (NS_WARN_IF(splitNodeResult.Failed())) {
         return splitNodeResult.Rv();
       }
       EditorRawDOMPoint pointToInsertBrNode(splitNodeResult.SplitPoint());
       // Put a <br> element at the split point
       brContent =
-        HTMLEditorRef().InsertBrElementWithTransaction(SelectionRef(),
-                                                       pointToInsertBrNode);
+        HTMLEditorRef().InsertBrElementWithTransaction(pointToInsertBrNode);
       if (NS_WARN_IF(!CanHandleEditAction())) {
         return NS_ERROR_EDITOR_DESTROYED;
       }
       if (NS_WARN_IF(!brContent)) {
         return NS_ERROR_FAILURE;
       }
       // Put selection at the split point
       EditorRawDOMPoint atBrNode(brContent);
@@ -4788,27 +4779,27 @@ HTMLEditRules::WillCSSIndent(bool* aCanc
   return NS_OK;
 }
 
 nsresult
 HTMLEditRules::IndentAroundSelectionWithCSS()
 {
   MOZ_ASSERT(IsEditorDataAvailable());
 
-  AutoSelectionRestorer restoreSelectionLater(SelectionRef(), HTMLEditorRef());
+  AutoSelectionRestorer restoreSelectionLater(HTMLEditorRef());
   nsTArray<OwningNonNull<nsRange>> arrayOfRanges;
   nsTArray<OwningNonNull<nsINode>> arrayOfNodes;
 
   // short circuit: detect case of collapsed selection inside an <li>.
   // just sublist that <li>.  This prevents bug 97797.
 
   nsCOMPtr<Element> liNode;
   if (SelectionRef().IsCollapsed()) {
     EditorRawDOMPoint selectionStartPoint(
-                        EditorBase::GetStartPoint(&SelectionRef()));
+                        EditorBase::GetStartPoint(SelectionRef()));
     if (NS_WARN_IF(!selectionStartPoint.IsSet())) {
       return NS_ERROR_FAILURE;
     }
     Element* block =
       HTMLEditorRef().GetBlock(*selectionStartPoint.GetContainer());
     if (block && HTMLEditUtils::IsListItem(block)) {
       liNode = block;
     }
@@ -5092,17 +5083,17 @@ HTMLEditRules::WillHTMLIndent(bool* aCan
   return NS_OK;
 }
 
 nsresult
 HTMLEditRules::IndentAroundSelectionWithHTML()
 {
   MOZ_ASSERT(IsEditorDataAvailable());
 
-  AutoSelectionRestorer restoreSelectionLater(SelectionRef(), HTMLEditorRef());
+  AutoSelectionRestorer restoreSelectionLater(HTMLEditorRef());
 
   // 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
 
   nsTArray<RefPtr<nsRange>> arrayOfRanges;
   GetPromotedRanges(arrayOfRanges, EditSubAction::eIndent);
@@ -5472,17 +5463,17 @@ HTMLEditRules::WillOutdent(bool* aCancel
   return NS_OK;
 }
 
 SplitRangeOffFromNodeResult
 HTMLEditRules::OutdentAroundSelection()
 {
   MOZ_ASSERT(IsEditorDataAvailable());
 
-  AutoSelectionRestorer restoreSelectionLater(SelectionRef(), HTMLEditorRef());
+  AutoSelectionRestorer restoreSelectionLater(HTMLEditorRef());
 
   bool useCSS = HTMLEditorRef().IsCSSEnabled();
 
   // 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
   nsTArray<OwningNonNull<nsINode>> arrayOfNodes;
@@ -6112,17 +6103,17 @@ HTMLEditRules::WillAlign(const nsAString
     return rv;
   }
   return NS_OK;
 }
 
 nsresult
 HTMLEditRules::AlignContentsAtSelection(const nsAString& aAlignType)
 {
-  AutoSelectionRestorer restoreSelectionLater(SelectionRef(), HTMLEditorRef());
+  AutoSelectionRestorer restoreSelectionLater(HTMLEditorRef());
 
   // 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
   nsTArray<OwningNonNull<nsINode>> nodeArray;
   nsresult rv =
     GetNodesFromSelection(EditSubAction::eSetOrClearAlignment, nodeArray,
@@ -6542,18 +6533,17 @@ HTMLEditRules::MaybeDeleteTopMostEmptyAn
       EditorDOMPoint atBlockParent(blockParent);
       if (NS_WARN_IF(!atBlockParent.IsSet())) {
         return NS_ERROR_FAILURE;
       }
       // If the grand parent IS a list element, we'll adjust Selection in
       // AfterEdit().
       if (!HTMLEditUtils::IsList(atBlockParent.GetContainer())) {
         RefPtr<Element> brElement =
-          HTMLEditorRef().InsertBrElementWithTransaction(SelectionRef(),
-                                                         atBlockParent);
+          HTMLEditorRef().InsertBrElementWithTransaction(atBlockParent);
         if (NS_WARN_IF(!CanHandleEditAction())) {
           return NS_ERROR_EDITOR_DESTROYED;
         }
         if (NS_WARN_IF(!brElement)) {
           return NS_ERROR_FAILURE;
         }
         ErrorResult error;
         SelectionRef().Collapse(EditorRawDOMPoint(brElement), error);
@@ -8087,17 +8077,17 @@ HTMLEditRules::ReturnInHeader(Element& a
       }
       if (NS_WARN_IF(!pNode)) {
         return NS_ERROR_FAILURE;
       }
 
       // Append a <br> to it
       RefPtr<Element> brElement =
         HTMLEditorRef().InsertBrElementWithTransaction(
-                          SelectionRef(), EditorRawDOMPoint(pNode, 0));
+                          EditorRawDOMPoint(pNode, 0));
       if (NS_WARN_IF(!CanHandleEditAction())) {
         return NS_ERROR_EDITOR_DESTROYED;
       }
       if (NS_WARN_IF(!brElement)) {
         return NS_ERROR_FAILURE;
       }
 
       // Set selection to before the break
@@ -8305,18 +8295,17 @@ HTMLEditRules::ReturnInParagraph(Element
   }
   if (pointToInsertBR.IsSet()) {
     // if CR does not create a new P, default to BR creation
     if (NS_WARN_IF(!doesCRCreateNewP)) {
       return EditActionResult(NS_OK);
     }
 
     brContent =
-      HTMLEditorRef().InsertBrElementWithTransaction(SelectionRef(),
-                                                     pointToInsertBR);
+      HTMLEditorRef().InsertBrElementWithTransaction(pointToInsertBR);
     if (NS_WARN_IF(!CanHandleEditAction())) {
       return EditActionResult(NS_ERROR_EDITOR_DESTROYED);
     }
     NS_WARNING_ASSERTION(brContent, "Failed to create a <br> element");
     if (splitAfterNewBR) {
       // We split the parent after the br we've just inserted.
       pointToSplitParentDivOrP.Set(brContent);
       DebugOnly<bool> advanced = pointToSplitParentDivOrP.AdvanceOffset();
@@ -8518,17 +8507,17 @@ HTMLEditRules::ReturnInListItem(Element&
       }
       if (NS_WARN_IF(!pNode)) {
         return NS_ERROR_FAILURE;
       }
 
       // Append a <br> to it
       RefPtr<Element> brElement =
         HTMLEditorRef().InsertBrElementWithTransaction(
-                          SelectionRef(), EditorRawDOMPoint(pNode, 0));
+                          EditorRawDOMPoint(pNode, 0));
       if (NS_WARN_IF(!CanHandleEditAction())) {
         return NS_ERROR_EDITOR_DESTROYED;
       }
       if (NS_WARN_IF(!brElement)) {
         return NS_ERROR_FAILURE;
       }
 
       // Set selection to before the break
@@ -9459,17 +9448,17 @@ HTMLEditRules::InsertBRElementToEmptyLis
 }
 
 nsresult
 HTMLEditRules::AdjustWhitespace()
 {
   MOZ_ASSERT(IsEditorDataAvailable());
 
   EditorRawDOMPoint selectionStartPoint(
-                      EditorBase::GetStartPoint(&SelectionRef()));
+                      EditorBase::GetStartPoint(SelectionRef()));
   if (NS_WARN_IF(!selectionStartPoint.IsSet())) {
     return NS_ERROR_FAILURE;
   }
 
   // Ask whitespace object to tweak nbsp's
   nsresult rv =
     WSRunObject(&HTMLEditorRef(), selectionStartPoint).AdjustWhitespace();
   if (NS_WARN_IF(!CanHandleEditAction())) {
@@ -9490,17 +9479,17 @@ HTMLEditRules::PinSelectionToNewBlock()
     return NS_OK;
   }
 
   if (NS_WARN_IF(!mNewBlock)) {
     return NS_ERROR_NULL_POINTER;
   }
 
   EditorRawDOMPoint selectionStartPoint(
-                      EditorBase::GetStartPoint(&SelectionRef()));
+                      EditorBase::GetStartPoint(SelectionRef()));
   if (NS_WARN_IF(!selectionStartPoint.IsSet())) {
     return NS_ERROR_FAILURE;
   }
 
   // Use ranges and nsRange::CompareNodeToRange() to compare selection start
   // to new block.
   // XXX It's too expensive to use nsRange and set it only for comparing a
   //     DOM point with a node.
@@ -9643,17 +9632,17 @@ HTMLEditRules::AdjustSelection(nsIEditor
   // if the selection isn't collapsed, do nothing.
   // moose: one thing to do instead is check for the case of
   // only a single break selected, and collapse it.  Good thing?  Beats me.
   if (!SelectionRef().IsCollapsed()) {
     return NS_OK;
   }
 
   // get the (collapsed) selection location
-  EditorDOMPoint point(EditorBase::GetStartPoint(&SelectionRef()));
+  EditorDOMPoint point(EditorBase::GetStartPoint(SelectionRef()));
   if (NS_WARN_IF(!point.IsSet())) {
     return NS_ERROR_FAILURE;
   }
 
   // are we in an editable node?
   while (!HTMLEditorRef().IsEditable(point.GetContainer())) {
     // scan up the tree until we find an editable place to be
     point.Set(point.GetContainer());
@@ -10002,17 +9991,17 @@ HTMLEditRules::RemoveEmptyNodesInChanged
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
     if (!isEmptyNode) {
       // We are deleting a cite that has just a br.  We want to delete cite,
       // but preserve br.
       RefPtr<Element> brElement =
         HTMLEditorRef().InsertBrElementWithTransaction(
-                          SelectionRef(), EditorRawDOMPoint(delNode));
+                          EditorRawDOMPoint(delNode));
       if (NS_WARN_IF(!CanHandleEditAction())) {
         return NS_ERROR_EDITOR_DESTROYED;
       }
       if (NS_WARN_IF(!brElement)) {
         return NS_ERROR_FAILURE;
       }
     }
     rv = HTMLEditorRef().DeleteNodeWithTransaction(*delNode);
@@ -10278,17 +10267,17 @@ HTMLEditRules::ConfirmSelectionInBody()
   MOZ_ASSERT(IsEditorDataAvailable());
 
   Element* rootElement = HTMLEditorRef().GetRoot();
   if (NS_WARN_IF(!rootElement)) {
     return NS_ERROR_UNEXPECTED;
   }
 
   EditorRawDOMPoint selectionStartPoint(
-                      EditorBase::GetStartPoint(&SelectionRef()));
+                      EditorBase::GetStartPoint(SelectionRef()));
   if (NS_WARN_IF(!selectionStartPoint.IsSet())) {
     return NS_ERROR_FAILURE;
   }
 
   // Check that selection start container is inside the <body> element.
   //XXXsmaug this code is insane.
   nsINode* temp = selectionStartPoint.GetContainer();
   while (temp && !temp->IsHTMLElement(nsGkAtoms::body)) {
@@ -10302,17 +10291,17 @@ HTMLEditRules::ConfirmSelectionInBody()
     if (NS_WARN_IF(!CanHandleEditAction())) {
       return NS_ERROR_EDITOR_DESTROYED;
     }
     NS_WARNING_ASSERTION(!ignoredError.Failed(),
       "Failed to collapse selection at start of the root element");
     return NS_OK;
   }
 
-  EditorRawDOMPoint selectionEndPoint(EditorBase::GetEndPoint(&SelectionRef()));
+  EditorRawDOMPoint selectionEndPoint(EditorBase::GetEndPoint(SelectionRef()));
   if (NS_WARN_IF(!selectionEndPoint.IsSet())) {
     return NS_ERROR_FAILURE;
   }
 
   // check that selNode is inside body
   //XXXsmaug this code is insane.
   temp = selectionEndPoint.GetContainer();
   while (temp && !temp->IsHTMLElement(nsGkAtoms::body)) {
@@ -10616,21 +10605,21 @@ HTMLEditRules::WillDeleteSelection(Selec
   }
 
   if (NS_WARN_IF(!CanHandleEditAction())) {
     return;
   }
 
   AutoSafeEditorData setData(*this, *mHTMLEditor, aSelection);
 
-  EditorRawDOMPoint startPoint = EditorBase::GetStartPoint(&SelectionRef());
+  EditorRawDOMPoint startPoint = EditorBase::GetStartPoint(SelectionRef());
   if (NS_WARN_IF(!startPoint.IsSet())) {
     return;
   }
-  EditorRawDOMPoint endPoint = EditorBase::GetEndPoint(&SelectionRef());
+  EditorRawDOMPoint endPoint = EditorBase::GetEndPoint(SelectionRef());
   if (NS_WARN_IF(!endPoint.IsSet())) {
     return;
   }
   nsresult rv = mUtilRange->SetStartAndEnd(startPoint, endPoint);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return;
   }
   UpdateDocChangeRange(mUtilRange);
@@ -10775,18 +10764,17 @@ HTMLEditRules::MakeSureElemStartsOrEndsO
   if (!foundCR) {
     EditorRawDOMPoint pointToInsert;
     if (!aStarts) {
       pointToInsert.SetToEndOf(&aNode);
     } else {
       pointToInsert.Set(&aNode, 0);
     }
     RefPtr<Element> brElement =
-      HTMLEditorRef().InsertBrElementWithTransaction(SelectionRef(),
-                                                     pointToInsert);
+      HTMLEditorRef().InsertBrElementWithTransaction(pointToInsert);
     if (NS_WARN_IF(!CanHandleEditAction())) {
       return NS_ERROR_EDITOR_DESTROYED;
     }
     if (NS_WARN_IF(!brElement)) {
       return NS_ERROR_FAILURE;
     }
   }
   return NS_OK;
@@ -10958,18 +10946,17 @@ HTMLEditRules::WillAbsolutePosition(bool
   if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
     return NS_ERROR_EDITOR_DESTROYED;
   }
   NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "WillInsert() failed");
 
   *aCancel = false;
   *aHandled = true;
 
-  RefPtr<Element> focusElement =
-    HTMLEditorRef().GetSelectionContainerElement(SelectionRef());
+  RefPtr<Element> focusElement = HTMLEditorRef().GetSelectionContainerElement();
   if (focusElement && HTMLEditUtils::IsImage(focusElement)) {
     mNewBlock = focusElement;
     return NS_OK;
   }
 
   rv = NormalizeSelection();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
@@ -10993,17 +10980,17 @@ HTMLEditRules::PrepareToMakeElementAbsol
                  bool* aHandled,
                  RefPtr<Element>* aTargetElement)
 {
   MOZ_ASSERT(IsEditorDataAvailable());
 
   MOZ_ASSERT(aHandled);
   MOZ_ASSERT(aTargetElement);
 
-  AutoSelectionRestorer restoreSelectionLater(SelectionRef(), HTMLEditorRef());
+  AutoSelectionRestorer restoreSelectionLater(HTMLEditorRef());
 
   // 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.
 
   nsTArray<RefPtr<nsRange>> arrayOfRanges;
   GetPromotedRanges(arrayOfRanges, EditSubAction::eSetPositionToAbsolute);
@@ -11298,17 +11285,17 @@ HTMLEditRules::WillRemoveAbsolutePositio
 
   RefPtr<Element> element =
     HTMLEditorRef().GetAbsolutelyPositionedSelectionContainer();
   if (NS_WARN_IF(!element)) {
     return NS_ERROR_FAILURE;
   }
 
   {
-    AutoSelectionRestorer restoreSelectionLater(SelectionRef(), HTMLEditorRef());
+    AutoSelectionRestorer restoreSelectionLater(HTMLEditorRef());
 
     nsresult rv = HTMLEditorRef().SetPositionToAbsoluteOrStatic(*element, false);
     if (NS_WARN_IF(!CanHandleEditAction())) {
       return NS_ERROR_EDITOR_DESTROYED;
     }
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
@@ -11344,17 +11331,17 @@ HTMLEditRules::WillRelativeChangeZIndex(
 
   RefPtr<Element> element =
     HTMLEditorRef().GetAbsolutelyPositionedSelectionContainer();
   if (NS_WARN_IF(!element)) {
     return NS_ERROR_FAILURE;
   }
 
   {
-    AutoSelectionRestorer restoreSelectionLater(SelectionRef(), HTMLEditorRef());
+    AutoSelectionRestorer restoreSelectionLater(HTMLEditorRef());
 
     int32_t zIndex;
     nsresult rv = HTMLEditorRef().RelativeChangeElementZIndex(*element, aChange,
                                                               &zIndex);
     if (NS_WARN_IF(!CanHandleEditAction())) {
       return NS_ERROR_EDITOR_DESTROYED;
     }
     if (NS_WARN_IF(NS_FAILED(rv))) {
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -433,17 +433,17 @@ HTMLEditor::NotifySelectionChanged(nsIDo
     if ((aReason & (nsISelectionListener::MOUSEDOWN_REASON |
                     nsISelectionListener::KEYPRESS_REASON |
                     nsISelectionListener::SELECTALL_REASON)) && aSelection) {
       // the selection changed and we need to check if we have to
       // hide and/or redisplay resizing handles
       // FYI: This is an XPCOM method.  So, the caller, Selection, guarantees
       //      the lifetime of this instance.  So, don't need to grab this with
       //      local variable.
-      DebugOnly<nsresult> rv = RefereshEditingUI(*aSelection);
+      DebugOnly<nsresult> rv = RefereshEditingUI();
       NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "RefereshEditingUI() failed");
     }
   }
 
   if (mComposerCommandsUpdater) {
     RefPtr<ComposerCommandsUpdater> updater = mComposerCommandsUpdater;
     updater->OnSelectionChange();
   }
@@ -606,19 +606,20 @@ HTMLEditor::BeginningOfDocument()
   if (NS_WARN_IF(!editActionData.CanHandle())) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
   return MaybeCollapseSelectionAtFirstEditableNode(false);
 }
 
 void
-HTMLEditor::InitializeSelectionAncestorLimit(Selection& aSelection,
-                                             nsIContent& aAncestorLimit)
+HTMLEditor::InitializeSelectionAncestorLimit(nsIContent& aAncestorLimit)
 {
+  MOZ_ASSERT(IsEditActionDataAvailable());
+
   // Hack for initializing selection.
   // HTMLEditor::MaybeCollapseSelectionAtFirstEditableNode() will try to
   // collapse selection at first editable text node or inline element which
   // cannot have text nodes as its children.  However, selection has already
   // set into the new editing host by user, we should not change it.  For
   // solving this issue, we should do nothing if selection range is in active
   // editing host except it's not collapsed at start of the editing host since
   // aSelection.SetAncestorLimiter(aAncestorLimit) will collapse selection
@@ -626,29 +627,30 @@ HTMLEditor::InitializeSelectionAncestorL
   // editing host.  However, we need to check here if selection is already
   // collapsed at start of the editing host because it's possible JS to do it.
   // In such case, we should not modify selection with calling
   // MaybeCollapseSelectionAtFirstEditableNode().
 
   // Basically, we should try to collapse selection at first editable node
   // in HTMLEditor.
   bool tryToCollapseSelectionAtFirstEditableNode = true;
-  if (aSelection.RangeCount() == 1 && aSelection.IsCollapsed()) {
+  if (SelectionRefPtr()->RangeCount() == 1 &&
+      SelectionRefPtr()->IsCollapsed()) {
     Element* editingHost = GetActiveEditingHost();
-    nsRange* range = aSelection.GetRangeAt(0);
+    nsRange* range = SelectionRefPtr()->GetRangeAt(0);
     if (range->GetStartContainer() == editingHost &&
         !range->StartOffset()) {
       // JS or user operation has already collapsed selection at start of
       // the editing host.  So, we don't need to try to change selection
       // in this case.
       tryToCollapseSelectionAtFirstEditableNode = false;
     }
   }
 
-  EditorBase::InitializeSelectionAncestorLimit(aSelection, aAncestorLimit);
+  EditorBase::InitializeSelectionAncestorLimit(aAncestorLimit);
 
   // XXX Do we need to check if we still need to change selection?  E.g.,
   //     we could have already lost focus while we're changing the ancestor
   //     limiter because it may causes "selectionchange" event.
   if (tryToCollapseSelectionAtFirstEditableNode) {
     MaybeCollapseSelectionAtFirstEditableNode(true);
   }
 }
@@ -1144,18 +1146,17 @@ HTMLEditor::TabInTable(bool inIsShift,
 
   AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing);
   if (NS_WARN_IF(!editActionData.CanHandle())) {
     // Do nothing if we didn't find a table cell.
     return NS_OK;
   }
 
   // Find enclosing table cell from selection (cell may be selected element)
-  Element* cellElement =
-    GetElementOrParentByTagNameAtSelection(*SelectionRefPtr(), *nsGkAtoms::td);
+  Element* cellElement = GetElementOrParentByTagNameAtSelection(*nsGkAtoms::td);
   if (NS_WARN_IF(!cellElement)) {
     // Do nothing if we didn't find a table cell.
     return NS_OK;
   }
 
   // find enclosing table
   RefPtr<Element> table = GetEnclosingTable(cellElement);
   if (NS_WARN_IF(!table)) {
@@ -1182,17 +1183,17 @@ HTMLEditor::TabInTable(bool inIsShift,
     } else {
       iter->Next();
     }
 
     node = iter->GetCurrentNode();
 
     if (node && HTMLEditUtils::IsTableCell(node) &&
         GetEnclosingTable(node) == table) {
-      CollapseSelectionToDeepestNonTableFirstChild(nullptr, node);
+      CollapseSelectionToDeepestNonTableFirstChild(node);
       *outHandled = true;
       return NS_OK;
     }
   } while (!iter->IsDone());
 
   if (!(*outHandled) && !inIsShift) {
     // If we haven't handled it yet, then we must have run off the end of the
     // table.  Insert a new row.
@@ -1207,18 +1208,17 @@ HTMLEditor::TabInTable(bool inIsShift,
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
     *outHandled = true;
     // Put selection in right place.  Use table code to get selection and index
     // to new row...
     RefPtr<Element> tblElement, cell;
     int32_t row;
-    rv = GetCellContext(nullptr,
-                        getter_AddRefs(tblElement),
+    rv = GetCellContext(getter_AddRefs(tblElement),
                         getter_AddRefs(cell),
                         nullptr, nullptr,
                         &row, nullptr);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
     if (NS_WARN_IF(!tblElement)) {
       return NS_ERROR_FAILURE;
@@ -1252,59 +1252,51 @@ HTMLEditor::InsertBrElementAtSelectionWi
 
   if (!selection->IsCollapsed()) {
     nsresult rv = DeleteSelectionAsSubAction(eNone, eStrip);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
   }
 
-  EditorRawDOMPoint atStartOfSelection(GetStartPoint(selection));
+  EditorRawDOMPoint atStartOfSelection(EditorBase::GetStartPoint(*selection));
   if (NS_WARN_IF(!atStartOfSelection.IsSet())) {
     return NS_ERROR_FAILURE;
   }
 
   // InsertBrElementWithTransaction() will set selection after the new <br>
   // element.
   RefPtr<Element> newBrElement =
-    InsertBrElementWithTransaction(*selection, atStartOfSelection, eNext);
+    InsertBrElementWithTransaction(atStartOfSelection, eNext);
   if (NS_WARN_IF(!newBrElement)) {
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
 void
-HTMLEditor::CollapseSelectionToDeepestNonTableFirstChild(Selection* aSelection,
-                                                         nsINode* aNode)
+HTMLEditor::CollapseSelectionToDeepestNonTableFirstChild(nsINode* aNode)
 {
+  MOZ_ASSERT(IsEditActionDataAvailable());
+
   MOZ_ASSERT(aNode);
 
-  RefPtr<Selection> selection = aSelection;
-  if (!selection) {
-    selection = GetSelection();
-  }
-  if (!selection) {
-    // Nothing to do
-    return;
-  }
-
   nsCOMPtr<nsINode> node = aNode;
 
   for (nsCOMPtr<nsIContent> child = node->GetFirstChild();
        child;
        child = child->GetFirstChild()) {
     // Stop if we find a table, don't want to go into nested tables
     if (HTMLEditUtils::IsTable(child) || !IsContainer(child)) {
       break;
     }
     node = child;
   }
 
-  selection->Collapse(node, 0);
+  SelectionRefPtr()->Collapse(node, 0);
 }
 
 nsresult
 HTMLEditor::ReplaceHeadContentsWithSourceWithTransaction(
               const nsAString& aSourceToInsert)
 {
   // don't do any post processing, rules get confused
   AutoTopLevelEditSubActionNotifier
@@ -1724,32 +1716,31 @@ HTMLEditor::InsertElementAtSelection(Ele
         InsertNodeIntoProperAncestorWithTransaction(
           *aElement, pointToInsert, SplitAtEdges::eAllowToCreateEmptyContainer);
       if (NS_WARN_IF(!insertedPoint.IsSet())) {
         return NS_ERROR_FAILURE;
       }
       // Set caret after element, but check for special case
       //  of inserting table-related elements: set in first cell instead
       if (!SetCaretInTableCell(aElement)) {
-        rv = CollapseSelectionAfter(*SelectionRefPtr(), *aElement);
+        rv = CollapseSelectionAfter(*aElement);
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return rv;
         }
       }
       // check for inserting a whole table at the end of a block. If so insert
       // a br after it.
       if (HTMLEditUtils::IsTable(aElement) &&
           IsLastEditableChild(aElement)) {
         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 =
-          InsertBrElementWithTransaction(*SelectionRefPtr(), insertedPoint,
-                                         ePrevious);
+          InsertBrElementWithTransaction(insertedPoint, ePrevious);
         if (NS_WARN_IF(!newBrElement)) {
           return NS_ERROR_FAILURE;
         }
       }
     }
   }
   rv = rules->DidDoAction(SelectionRefPtr(), subActionInfo, rv);
   return rv;
@@ -1830,27 +1821,28 @@ HTMLEditor::SelectElement(Element* aElem
     return NS_ERROR_INVALID_ARG;
   }
 
   AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing);
   if (NS_WARN_IF(!editActionData.CanHandle())) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
-  nsresult rv = SelectContentInternal(*SelectionRefPtr(), *aElement);
+  nsresult rv = SelectContentInternal(*aElement);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   return NS_OK;
 }
 
 nsresult
-HTMLEditor::SelectContentInternal(Selection& aSelection,
-                                  nsIContent& aContentToSelect)
+HTMLEditor::SelectContentInternal(nsIContent& aContentToSelect)
 {
+  MOZ_ASSERT(IsEditActionDataAvailable());
+
   // Must be sure that element is contained in the document body
   if (!IsDescendantOfEditorRoot(&aContentToSelect)) {
     return NS_ERROR_FAILURE;
   }
 
   nsINode* parent = aContentToSelect.GetParentNode();
   if (NS_WARN_IF(!parent)) {
     return NS_ERROR_FAILURE;
@@ -1858,22 +1850,22 @@ HTMLEditor::SelectContentInternal(Select
 
   // Don't notify selection change at collapse.
   AutoUpdateViewBatch notifySelectionChangeOnce(*this);
 
   // XXX Perhaps, Selection should have SelectNode(nsIContent&).
   int32_t offsetInParent = parent->ComputeIndexOf(&aContentToSelect);
 
   // Collapse selection to just before desired element,
-  nsresult rv = aSelection.Collapse(parent, offsetInParent);
+  nsresult rv = SelectionRefPtr()->Collapse(parent, offsetInParent);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   // then extend it to just after
-  rv = aSelection.Extend(parent, offsetInParent + 1);
+  rv = SelectionRefPtr()->Extend(parent, offsetInParent + 1);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLEditor::SetCaretAfterElement(Element* aElement)
@@ -1882,42 +1874,43 @@ HTMLEditor::SetCaretAfterElement(Element
     return NS_ERROR_INVALID_ARG;
   }
 
   AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing);
   if (NS_WARN_IF(!editActionData.CanHandle())) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
-  nsresult rv = CollapseSelectionAfter(*SelectionRefPtr(), *aElement);
+  nsresult rv = CollapseSelectionAfter(*aElement);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   return NS_OK;
 }
 
 nsresult
-HTMLEditor::CollapseSelectionAfter(Selection& aSelection,
-                                   Element& aElement)
+HTMLEditor::CollapseSelectionAfter(Element& aElement)
 {
+  MOZ_ASSERT(IsEditActionDataAvailable());
+
   // Be sure the element is contained in the document body
   if (NS_WARN_IF(!IsDescendantOfEditorRoot(&aElement))) {
     return NS_ERROR_INVALID_ARG;
   }
   nsINode* parent = aElement.GetParentNode();
   if (NS_WARN_IF(!parent)) {
     return NS_ERROR_FAILURE;
   }
   // Collapse selection to just after desired element,
   EditorRawDOMPoint afterElement(&aElement);
   if (NS_WARN_IF(!afterElement.AdvanceOffset())) {
     return NS_ERROR_FAILURE;
   }
   ErrorResult error;
-  aSelection.Collapse(afterElement, error);
+  SelectionRefPtr()->Collapse(afterElement, error);
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLEditor::SetParagraphFormat(const nsAString& aParagraphFormat)
@@ -2103,17 +2096,17 @@ HTMLEditor::GetHTMLBackgroundColorState(
 
   RefPtr<Selection> selection = GetSelection();
   if (NS_WARN_IF(!selection)) {
     return NS_ERROR_FAILURE;
   }
 
   ErrorResult error;
   RefPtr<Element> cellOrRowOrTableElement =
-    GetSelectedOrParentTableElement(*selection, error);
+    GetSelectedOrParentTableElement(error);
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
 
   for (RefPtr<Element> element = std::move(cellOrRowOrTableElement);
        element;
        element = element->GetParentElement()) {
     // We are in a cell or selected table
@@ -2306,17 +2299,21 @@ HTMLEditor::MakeOrChangeList(const nsASt
     }
     ErrorResult error;
     SelectionRefPtr()->Collapse(RawRangeBoundary(newItem, 0), error);
     if (NS_WARN_IF(error.Failed())) {
       return error.StealNSResult();
     }
   }
 
-  return rules->DidDoAction(SelectionRefPtr(), subActionInfo, rv);
+  rv = rules->DidDoAction(SelectionRefPtr(), subActionInfo, rv);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLEditor::RemoveList(const nsAString&)
 {
   if (!mRules) {
     return NS_ERROR_NOT_INITIALIZED;
   }
@@ -2340,17 +2337,21 @@ HTMLEditor::RemoveList(const nsAString&)
   nsresult rv =
     rules->WillDoAction(SelectionRefPtr(), subActionInfo, &cancel, &handled);
   if (cancel || NS_FAILED(rv)) {
     return rv;
   }
 
   // no default behavior for this yet.  what would it mean?
 
-  return rules->DidDoAction(SelectionRefPtr(), subActionInfo, rv);
+  rv = rules->DidDoAction(SelectionRefPtr(), subActionInfo, rv);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+  return NS_OK;
 }
 
 nsresult
 HTMLEditor::MakeDefinitionListItemWithTransaction(nsAtom& aTagName)
 {
   if (!mRules) {
     return NS_ERROR_NOT_INITIALIZED;
   }
@@ -2674,48 +2675,49 @@ HTMLEditor::Align(const nsAString& aAlig
   EditSubActionInfo subActionInfo(EditSubAction::eSetOrClearAlignment);
   subActionInfo.alignType = &aAlignType;
   nsresult rv =
    rules->WillDoAction(SelectionRefPtr(), subActionInfo, &cancel, &handled);
   if (cancel || NS_FAILED(rv)) {
     return rv;
   }
 
-  return rules->DidDoAction(SelectionRefPtr(), subActionInfo, rv);
+  rv = rules->DidDoAction(SelectionRefPtr(), subActionInfo, rv);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+  return NS_OK;
 }
 
 Element*
 HTMLEditor::GetElementOrParentByTagName(const nsAtom& aTagName,
                                         nsINode* aNode) const
 {
   MOZ_ASSERT(&aTagName != nsGkAtoms::_empty);
 
   AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing);
   if (NS_WARN_IF(!editActionData.CanHandle())) {
     return nullptr;
   }
 
   if (aNode) {
     return GetElementOrParentByTagNameInternal(aTagName, *aNode);
   }
-  RefPtr<Selection> selection = GetSelection();
-  if (NS_WARN_IF(!selection)) {
-    return nullptr;
-  }
-  return GetElementOrParentByTagNameAtSelection(*selection, aTagName);
+  return GetElementOrParentByTagNameAtSelection(aTagName);
 }
 
 Element*
-HTMLEditor::GetElementOrParentByTagNameAtSelection(Selection& aSelection,
-                                                   const nsAtom& aTagName) const
+HTMLEditor::GetElementOrParentByTagNameAtSelection(const nsAtom& aTagName) const
 {
+  MOZ_ASSERT(IsEditActionDataAvailable());
+
   MOZ_ASSERT(&aTagName != nsGkAtoms::_empty);
 
   // If no node supplied, get it from anchor node of current selection
-  const EditorRawDOMPoint atAnchor(aSelection.AnchorRef());
+  const EditorRawDOMPoint atAnchor(SelectionRefPtr()->AnchorRef());
   if (NS_WARN_IF(!atAnchor.IsSet())) {
     return nullptr;
   }
 
   // Try to get the actual selected node
   nsCOMPtr<nsINode> node;
   if (atAnchor.GetContainer()->HasChildNodes() &&
       atAnchor.GetContainerAsContent()) {
@@ -2815,36 +2817,36 @@ HTMLEditor::GetSelectedElement(const nsA
 
   AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing);
   if (NS_WARN_IF(!editActionData.CanHandle())) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
   ErrorResult error;
   RefPtr<nsAtom> tagName = GetLowerCaseNameAtom(aTagName);
-  RefPtr<nsINode> selectedNode =
-    GetSelectedElement(*SelectionRefPtr(), tagName, error);
+  RefPtr<nsINode> selectedNode = GetSelectedElement(tagName, error);
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
   selectedNode.forget(aReturn);
   return NS_OK;
 }
 
 already_AddRefed<Element>
-HTMLEditor::GetSelectedElement(Selection& aSelection,
-                               const nsAtom* aTagName,
+HTMLEditor::GetSelectedElement(const nsAtom* aTagName,
                                ErrorResult& aRv)
 {
+  MOZ_ASSERT(IsEditActionDataAvailable());
+
   MOZ_ASSERT(!aRv.Failed());
 
   bool isLinkTag = aTagName && IsLinkTag(*aTagName);
   bool isNamedAnchorTag = aTagName && IsNamedAnchorTag(*aTagName);
 
-  RefPtr<nsRange> firstRange = aSelection.GetRangeAt(0);
+  RefPtr<nsRange> firstRange = SelectionRefPtr()->GetRangeAt(0);
   if (NS_WARN_IF(!firstRange)) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   nsCOMPtr<nsINode> startContainer = firstRange->GetStartContainer();
   nsIContent* startNode = firstRange->GetChildAtStartOffset();
 
@@ -2873,26 +2875,26 @@ HTMLEditor::GetSelectedElement(Selection
     }
   }
 
   RefPtr<Element> selectedElement;
   if (isLinkTag) {
     // Link tag is a special case - we return the anchor node
     //  found for any selection that is totally within a link,
     //  included a collapsed selection (just a caret in a link)
-    const RangeBoundary& anchor = aSelection.AnchorRef();
-    const RangeBoundary& focus = aSelection.FocusRef();
+    const RangeBoundary& anchor = SelectionRefPtr()->AnchorRef();
+    const RangeBoundary& focus = SelectionRefPtr()->FocusRef();
     // Link node must be the same for both ends of selection
     if (anchor.IsSet()) {
       Element* parentLinkOfAnchor =
         GetElementOrParentByTagNameInternal(*nsGkAtoms::href,
                                             *anchor.Container());
       // XXX: ERROR_HANDLING  can parentLinkOfAnchor be null?
       if (parentLinkOfAnchor) {
-        if (aSelection.IsCollapsed()) {
+        if (SelectionRefPtr()->IsCollapsed()) {
           // We have just a caret in the link.
           return do_AddRef(parentLinkOfAnchor);
         }
         if (focus.IsSet()) {
           // Link node must be the same for both ends of selection.
           Element* parentLinkOfFocus =
             GetElementOrParentByTagNameInternal(*nsGkAtoms::href,
                                                 *focus.Container());
@@ -2907,17 +2909,17 @@ HTMLEditor::GetSelectedElement(Selection
             focus.GetChildAtOffset() ==
               anchor.GetChildAtOffset()->GetNextSibling()) {
           selectedElement = Element::FromNodeOrNull(anchor.GetChildAtOffset());
         }
       }
     }
   }
 
-  if (aSelection.IsCollapsed()) {
+  if (SelectionRefPtr()->IsCollapsed()) {
     return selectedElement.forget();
   }
 
   nsCOMPtr<nsIContentIterator> iter = NS_NewContentIterator();
 
   bool found = !!selectedElement;
   const nsAtom* tagNameLookingFor = aTagName;
   iter->Init(firstRange);
@@ -3130,17 +3132,17 @@ HTMLEditor::SetHTMLBackgroundColorWithTr
   if (NS_WARN_IF(!selection)) {
     return NS_ERROR_FAILURE;
   }
 
   // Find a selected or enclosing table element to set background on
   ErrorResult error;
   bool isCellSelected = false;
   RefPtr<Element> cellOrRowOrTableElement =
-    GetSelectedOrParentTableElement(*selection, error, &isCellSelected);
+    GetSelectedOrParentTableElement(error, &isCellSelected);
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
 
   bool setColor = !aColor.IsEmpty();
   RefPtr<Element> rootElementOfBackgroundColor;
   if (cellOrRowOrTableElement) {
     rootElementOfBackgroundColor = std::move(cellOrRowOrTableElement);
@@ -3149,39 +3151,37 @@ HTMLEditor::SetHTMLBackgroundColorWithTr
     // do this.  Note that users can select each cell, but with Selection API,
     // web apps can select <tr> and <td> at same time. With <table>, looks
     // odd, though.
     if (isCellSelected ||
         cellOrRowOrTableElement->IsAnyOfHTMLElements(nsGkAtoms::table,
                                                     nsGkAtoms::tr)) {
       IgnoredErrorResult ignoredError;
       RefPtr<Element> cellElement =
-        GetFirstSelectedTableCellElement(*selection, ignoredError);
+        GetFirstSelectedTableCellElement(ignoredError);
       if (cellElement) {
         if (setColor) {
           while (cellElement) {
             nsresult rv =
               SetAttributeWithTransaction(*cellElement, *nsGkAtoms::bgcolor,
                                           aColor);
             if (NS_WARN_IF(NS_FAILED(rv))) {
               return rv;
             }
-            cellElement =
-              GetNextSelectedTableCellElement(*selection, ignoredError);
+            cellElement = GetNextSelectedTableCellElement(ignoredError);
           }
           return NS_OK;
         }
         while (cellElement) {
           nsresult rv =
             RemoveAttributeWithTransaction(*cellElement, *nsGkAtoms::bgcolor);
           if (NS_FAILED(rv)) {
             return rv;
           }
-          cellElement =
-            GetNextSelectedTableCellElement(*selection, ignoredError);
+          cellElement = GetNextSelectedTableCellElement(ignoredError);
         }
         return NS_OK;
       }
     }
     // If we failed to find a cell, fall through to use originally-found element
   } else {
     // No table element -- set the background color on the body tag
     rootElementOfBackgroundColor = GetRoot();
@@ -3811,35 +3811,41 @@ HTMLEditor::IsContainer(nsINode* aNode)
   } else {
     tagEnum = nsHTMLTags::StringTagToId(aNode->NodeName());
   }
 
   return HTMLEditUtils::IsContainer(tagEnum);
 }
 
 nsresult
-HTMLEditor::SelectEntireDocument(Selection* aSelection)
+HTMLEditor::SelectEntireDocument()
 {
-  if (!aSelection || !mRules) {
+  MOZ_ASSERT(IsEditActionDataAvailable());
+
+  if (!mRules) {
     return NS_ERROR_NULL_POINTER;
   }
 
   // Protect the edit rules object from dying
   RefPtr<TextEditRules> rules(mRules);
 
   // is doc empty?
   if (rules->DocumentIsEmpty()) {
     // get editor root node
     Element* rootElement = GetRoot();
 
     // if its empty dont select entire doc - that would select the bogus node
-    return aSelection->Collapse(rootElement, 0);
-  }
-
-  return EditorBase::SelectEntireDocument(aSelection);
+    nsresult rv = SelectionRefPtr()->Collapse(rootElement, 0);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+    return NS_OK;
+  }
+
+  return EditorBase::SelectEntireDocument();
 }
 
 nsresult
 HTMLEditor::SelectAllInternal()
 {
   CommitComposition();
   if (NS_WARN_IF(Destroyed())) {
     return NS_ERROR_EDITOR_DESTROYED;
@@ -4017,22 +4023,28 @@ HTMLEditor::CollapseAdjacentTextNodes(ns
 
     textNodes.RemoveElementAt(0); // remove the leftmost text node from the list
   }
 
   return NS_OK;
 }
 
 nsresult
-HTMLEditor::SetSelectionAtDocumentStart(Selection* aSelection)
+HTMLEditor::SetSelectionAtDocumentStart()
 {
+  MOZ_ASSERT(IsEditActionDataAvailable());
+
   dom::Element* rootElement = GetRoot();
   NS_ENSURE_TRUE(rootElement, NS_ERROR_NULL_POINTER);
 
-  return aSelection->Collapse(rootElement, 0);
+  nsresult rv = SelectionRefPtr()->Collapse(rootElement, 0);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+  return NS_OK;
 }
 
 /**
  * Remove aNode, reparenting any children into the parent of aNode.  In
  * addition, insert any br's needed to preserve identity of removed block.
  */
 nsresult
 HTMLEditor::RemoveBlockContainerWithTransaction(Element& aElement)
@@ -4059,18 +4071,17 @@ HTMLEditor::RemoveBlockContainerWithTran
     // 3) first child of aNode is a block OR
     // 4) either is null
 
     nsCOMPtr<nsIContent> sibling = GetPriorHTMLSibling(&aElement);
     if (sibling && !IsBlockNode(sibling) &&
         !sibling->IsHTMLElement(nsGkAtoms::br) && !IsBlockNode(child)) {
       // Insert br node
       RefPtr<Element> brElement =
-        InsertBrElementWithTransaction(*selection,
-                                       EditorRawDOMPoint(&aElement, 0));
+        InsertBrElementWithTransaction(EditorRawDOMPoint(&aElement, 0));
       if (NS_WARN_IF(!brElement)) {
         return NS_ERROR_FAILURE;
       }
     }
 
     // We need a br at end unless:
     // 1) following sibling of aNode is a block, OR
     // 2) last child of aNode is a block, OR
@@ -4080,18 +4091,17 @@ HTMLEditor::RemoveBlockContainerWithTran
     sibling = GetNextHTMLSibling(&aElement);
     if (sibling && !IsBlockNode(sibling)) {
       child = GetLastEditableChild(aElement);
       MOZ_ASSERT(child, "aNode has first editable child but not last?");
       if (!IsBlockNode(child) && !child->IsHTMLElement(nsGkAtoms::br)) {
         // Insert br node
         EditorRawDOMPoint endOfNode;
         endOfNode.SetToEndOf(&aElement);
-        RefPtr<Element> brElement =
-          InsertBrElementWithTransaction(*selection, endOfNode);
+        RefPtr<Element> brElement = InsertBrElementWithTransaction(endOfNode);
         if (NS_WARN_IF(!brElement)) {
           return NS_ERROR_FAILURE;
         }
       }
     }
   } else {
     // The case of aNode being empty.  We need a br at start unless:
     // 1) previous sibling of aNode is a block, OR
@@ -4102,18 +4112,17 @@ HTMLEditor::RemoveBlockContainerWithTran
     nsCOMPtr<nsIContent> sibling = GetPriorHTMLSibling(&aElement);
     if (sibling && !IsBlockNode(sibling) &&
         !sibling->IsHTMLElement(nsGkAtoms::br)) {
       sibling = GetNextHTMLSibling(&aElement);
       if (sibling && !IsBlockNode(sibling) &&
           !sibling->IsHTMLElement(nsGkAtoms::br)) {
         // Insert br node
         RefPtr<Element> brElement =
-          InsertBrElementWithTransaction(*selection,
-                                         EditorRawDOMPoint(&aElement, 0));
+          InsertBrElementWithTransaction(EditorRawDOMPoint(&aElement, 0));
         if (NS_WARN_IF(!brElement)) {
           return NS_ERROR_FAILURE;
         }
       }
     }
   }
 
   // Now remove container
@@ -4636,17 +4645,17 @@ HTMLEditor::SetCSSBackgroundColorWithTra
   NS_ENSURE_STATE(selection);
 
   bool isCollapsed = selection->IsCollapsed();
 
   AutoPlaceholderBatch treatAsOneTransaction(*this);
   AutoTopLevelEditSubActionNotifier maybeTopLevelEditSubAction(
                                       *this, EditSubAction::eInsertElement,
                                       nsIEditor::eNext);
-  AutoSelectionRestorer restoreSelectionLater(*selection, *this);
+  AutoSelectionRestorer restoreSelectionLater(*this);
   AutoTransactionsConserveSelection dontChangeMySelection(*this);
 
   // XXX Although, this method may set background color of ancestor block
   //     element, using EditSubAction::eSetTextProperty.
   bool cancel, handled;
   EditSubActionInfo subActionInfo(EditSubAction::eSetTextProperty);
   nsresult rv =
     rules->WillDoAction(selection, subActionInfo, &cancel, &handled);
@@ -4892,18 +4901,17 @@ HTMLEditor::CopyLastEditableChildStylesW
     return NS_OK;
   }
 
   RefPtr<Selection> selection = GetSelection();
   if (NS_WARN_IF(!selection)) {
     return NS_ERROR_FAILURE;
   }
   RefPtr<Element> brElement =
-    InsertBrElementWithTransaction(*selection,
-                                   EditorRawDOMPoint(firstClonsedElement, 0));
+    InsertBrElementWithTransaction(EditorRawDOMPoint(firstClonsedElement, 0));
   if (NS_WARN_IF(!brElement)) {
     return NS_ERROR_FAILURE;
   }
   *aNewBrElement = brElement.forget();
   return NS_OK;
 }
 
 nsresult
@@ -4928,30 +4936,32 @@ HTMLEditor::GetElementOrigin(Element& aE
   nsPoint off = frame->GetOffsetTo(container);
   aX = nsPresContext::AppUnitsToIntCSSPixels(off.x);
   aY = nsPresContext::AppUnitsToIntCSSPixels(off.y);
 
   return NS_OK;
 }
 
 Element*
-HTMLEditor::GetSelectionContainerElement(Selection& aSelection) const
+HTMLEditor::GetSelectionContainerElement() const
 {
+  MOZ_ASSERT(IsEditActionDataAvailable());
+
   nsINode* focusNode = nullptr;
-  if (aSelection.IsCollapsed()) {
-    focusNode = aSelection.GetFocusNode();
+  if (SelectionRefPtr()->IsCollapsed()) {
+    focusNode = SelectionRefPtr()->GetFocusNode();
     if (NS_WARN_IF(!focusNode)) {
       return nullptr;
     }
   } else {
-    uint32_t rangeCount = aSelection.RangeCount();
+    uint32_t rangeCount = SelectionRefPtr()->RangeCount();
     MOZ_ASSERT(rangeCount, "If 0, Selection::IsCollapsed() should return true");
 
     if (rangeCount == 1) {
-      nsRange* range = aSelection.GetRangeAt(0);
+      nsRange* range = SelectionRefPtr()->GetRangeAt(0);
 
       const RangeBoundary& startRef = range->StartRef();
       const RangeBoundary& endRef = range->EndRef();
 
       // This method called GetSelectedElement() to retrieve proper container
       // when only one node is selected.  However, it simply returns start
       // node of Selection with additional cost.  So, we do not need to call
       // it anymore.
@@ -4965,17 +4975,17 @@ HTMLEditor::GetSelectionContainerElement
       } else {
         focusNode = range->GetCommonAncestor();
         if (NS_WARN_IF(!focusNode)) {
           return nullptr;
         }
       }
     } else {
       for (uint32_t i = 0; i < rangeCount; i++) {
-        nsRange* range = aSelection.GetRangeAt(i);
+        nsRange* range = SelectionRefPtr()->GetRangeAt(i);
         nsINode* startContainer = range->GetStartContainer();
         if (!focusNode) {
           focusNode = startContainer;
         } else if (focusNode != startContainer) {
           // XXX Looks odd to use parent of startContainer because previous
           //     range may not be in the parent node of current startContainer.
           focusNode = startContainer->GetParentNode();
           // XXX Looks odd to break the for-loop here because we refer only
--- a/editor/libeditor/HTMLEditor.h
+++ b/editor/libeditor/HTMLEditor.h
@@ -247,21 +247,17 @@ public:
 
     AutoEditActionDataSetter editActionData(
       *this, EditAction::eEnableOrDisableResizer);
     if (NS_WARN_IF(!editActionData.CanHandle())) {
       return;
     }
 
     mIsObjectResizingEnabled = aEnable;
-    RefPtr<Selection> selection = GetSelection();
-    if (NS_WARN_IF(!selection)) {
-      return;
-    }
-    RefereshEditingUI(*selection);
+    RefereshEditingUI();
   }
   bool IsObjectResizerEnabled() const
   {
     return mIsObjectResizingEnabled;
   }
 
   /**
    * Enable/disable inline table editor, e.g., adding new row or column,
@@ -275,21 +271,17 @@ public:
 
     AutoEditActionDataSetter editActionData(
       *this, EditAction::eEnableOrDisableInlineTableEditingUI);
     if (NS_WARN_IF(!editActionData.CanHandle())) {
       return;
     }
 
     mIsInlineTableEditingEnabled = aEnable;
-    RefPtr<Selection> selection = GetSelection();
-    if (NS_WARN_IF(!selection)) {
-      return;
-    }
-    RefereshEditingUI(*selection);
+    RefereshEditingUI();
   }
   bool IsInlineTableEditorEnabled() const
   {
     return mIsInlineTableEditingEnabled;
   }
 
   /**
    * Enable/disable absolute position editor, resizing absolute positioned
@@ -304,21 +296,17 @@ public:
 
     AutoEditActionDataSetter editActionData(
       *this, EditAction::eEnableOrDisableAbsolutePositionEditor);
     if (NS_WARN_IF(!editActionData.CanHandle())) {
       return;
     }
 
     mIsAbsolutelyPositioningEnabled = aEnable;
-    RefPtr<Selection> selection = GetSelection();
-    if (NS_WARN_IF(!selection)) {
-      return;
-    }
-    RefereshEditingUI(*selection);
+    RefereshEditingUI();
   }
   bool IsAbsolutePositionEditorEnabled() const
   {
     return mIsAbsolutelyPositioningEnabled;
   }
 
   // non-virtual methods of interface methods
 
@@ -604,66 +592,62 @@ protected: // May be called by friends.
    * Returns container element of ranges in Selection.  If Selection is
    * collapsed, returns focus container node (or its parent element).
    * If Selection selects only one element node, returns the element node.
    * If Selection is only one range, returns common ancestor of the range.
    * XXX If there are two or more Selection ranges, this returns parent node
    *     of start container of a range which starts with different node from
    *     start container of the first range.
    */
-  Element* GetSelectionContainerElement(Selection& aSelection) const;
+  Element* GetSelectionContainerElement() const;
 
   /**
    * GetFirstSelectedTableCellElement() returns a <td> or <th> element if
    * first range of Selection (i.e., result of Selection::GetRangeAt(0))
    * selects a <td> element or <th> element.  Even if Selection is in
    * a cell element, this returns nullptr.  And even if 2nd or later
    * range of Selection selects a cell element, also returns nullptr.
    * Note that when this looks for a cell element, this resets the internal
    * index of ranges of Selection.  When you call
    * GetNextSelectedTableCellElement() after a call of this, it'll return 2nd
    * selected cell if there is.
    *
-   * @param aSelection          Selection for this editor.
    * @param aRv                 Returns error if there is no selection or
    *                            first range of Selection is unexpected.
    * @return                    A <td> or <th> element is selected by first
    *                            range of Selection.  Note that the range must
    *                            be: startContaienr and endContainer are same
    *                            <tr> element, startOffset + 1 equals endOffset.
    */
   already_AddRefed<Element>
-  GetFirstSelectedTableCellElement(Selection& aSelection,
-                                   ErrorResult& aRv) const;
+  GetFirstSelectedTableCellElement(ErrorResult& aRv) const;
 
   /**
    * GetNextSelectedTableCellElement() is a stateful method to retrieve
    * selected table cell elements which are selected by 2nd or later ranges
    * of Selection.  When you call GetFirstSelectedTableCellElement(), it
    * resets internal counter of this method.  Then, following calls of
    * GetNextSelectedTableCellElement() scans the remaining ranges of Selection.
    * If a range selects a <td> or <th> element, returns the cell element.
    * If a range selects an element but neither <td> nor <th> element, this
    * ignores the range.  If a range is in a text node, returns null without
    * throwing exception, but stops scanning the remaining ranges even you
    * call this again.
    * Note that this may cross <table> boundaries since this method just
    * scans all ranges of Selection.  Therefore, returning cells which
    * belong to different <table> elements.
    *
-   * @param Selection           Selection for this editor.
    * @param aRv                 Returns error if Selection doesn't have
    *                            range properly.
    * @return                    A <td> or <th> element if one of remaining
    *                            ranges selects a <td> or <th> element unless
    *                            this does not meet a range in a text node.
    */
   already_AddRefed<Element>
-  GetNextSelectedTableCellElement(Selection& aSelection,
-                                  ErrorResult& aRv) const;
+  GetNextSelectedTableCellElement(ErrorResult& aRv) const;
 
   /**
    * DeleteTableCellContentsWithTransaction() removes any contents in cell
    * elements.  If two or more cell elements are selected, this removes
    * all selected cells' contents.  Otherwise, this removes contents of
    * a cell which contains first selection range.  This does not return
    * error even if selection is not in cell element, just does nothing.
    */
@@ -1015,50 +999,44 @@ protected: // Shouldn't be used by frien
   virtual ~HTMLEditor();
 
   virtual nsresult SelectAllInternal() override;
 
   /**
    * SelectContentInternal() sets Selection to aContentToSelect to
    * aContentToSelect + 1 in parent of aContentToSelect.
    *
-   * @param aSelection          The Selection, callers have to guarantee the
-   *                            lifetime.
    * @param aContentToSelect    The content which should be selected.
    */
-  nsresult SelectContentInternal(Selection& aSelection,
-                                 nsIContent& aContentToSelect);
+  nsresult SelectContentInternal(nsIContent& aContentToSelect);
 
   /**
    * CollapseSelectionAfter() collapses Selection after aElement.
    * If aElement is an orphan node or not in editing host, returns error.
    */
-  nsresult CollapseSelectionAfter(Selection& aSelection,
-                                  Element& aElement);
+  nsresult CollapseSelectionAfter(Element& aElement);
 
   /**
    * GetElementOrParentByTagNameAtSelection() looks for an element node whose
    * name matches aTagName from anchor node of Selection to <body> element.
    *
-   * @param aSelection      The Selection for this editor.
    * @param aTagName        The tag name which you want to look for.
    *                        Must not be nsGkAtoms::_empty.
    *                        If nsGkAtoms::list, the result may be <ul>, <ol> or
    *                        <dl> element.
    *                        If nsGkAtoms::td, the result may be <td> or <th>.
    *                        If nsGkAtoms::href, the result may be <a> element
    *                        which has "href" attribute with non-empty value.
    *                        If nsGkAtoms::anchor, the result may be <a> which
    *                        has "name" attribute with non-empty value.
    * @return                If an element which matches aTagName, returns
    *                        an Element.  Otherwise, nullptr.
    */
   Element*
-  GetElementOrParentByTagNameAtSelection(Selection& aSelection,
-                                         const nsAtom& aTagName) const;
+  GetElementOrParentByTagNameAtSelection(const nsAtom& aTagName) const;
 
   /**
    * GetElementOrParentByTagNameInternal() looks for an element node whose
    * name matches aTagName from aNode to <body> element.
    *
    * @param aTagName        The tag name which you want to look for.
    *                        Must not be nsGkAtoms::_empty.
    *                        If nsGkAtoms::list, the result may be <ul>, <ol> or
@@ -1073,17 +1051,17 @@ protected: // Shouldn't be used by frien
    *                        an Element.  Otherwise, nullptr.
    */
   Element*
   GetElementOrParentByTagNameInternal(const nsAtom& aTagName,
                                       nsINode& aNode) const;
 
   /**
    * GetSelectedElement() returns an element node which is in first range of
-   * aSelection.  The rule is a little bit complicated and the rules do not
+   * Selection.  The rule is a little bit complicated and the rules do not
    * make sense except in a few cases.  If you want to use this newly,
    * you should create new method instead.  This needs to be here for
    * comm-central.
    * The rules are:
    *   1. If Selection selects an element node, i.e., both containers are
    *      same node and start offset and end offset is start offset + 1.
    *      (XXX However, if last child is selected, this path is not used.)
    *   2. If the argument is "href", look for anchor elements whose href
@@ -1092,30 +1070,28 @@ protected: // Shouldn't be used by frien
    *      (i.e., this allows collapsed selection.)
    *   3. If the Selection is collapsed, returns null.
    *   4. Otherwise, listing up all nodes with content iterator (post-order).
    *     4-1. When first element node does *not* match with the argument,
    *          *returns* the element.
    *     4-2. When first element node matches with the argument, returns
    *          *next* element node.
    *
-   * @param aSelection          The Selection.
    * @param aTagName            The atom of tag name in lower case.
    *                            If nullptr, look for any element node.
    *                            If nsGkAtoms::href, look for an <a> element
    *                            which has non-empty href attribute.
    *                            If nsGkAtoms::anchor or atomized "namedanchor",
    *                            look for an <a> element which has non-empty
    *                            name attribute.
    * @param aRv                 Returns error code.
-   * @return                    An element in first range of aSelection.
+   * @return                    An element in first range of Selection.
    */
   already_AddRefed<Element>
-  GetSelectedElement(Selection& aSelection,
-                     const nsAtom* aTagName,
+  GetSelectedElement(const nsAtom* aTagName,
                      ErrorResult& aRv);
 
   /**
    * GetFirstTableRowElement() returns the first <tr> element in the most
    * nearest ancestor of aTableOrElementInTable or itself.
    *
    * @param aTableOrElementInTable      <table> element or another element.
    *                                    If this is a <table> element, returns
@@ -1520,18 +1496,17 @@ protected: // Shouldn't be used by frien
    *   #4 if the first selection range does not select a cell and
    *      the selection anchor refers a <td>, returns it.
    *   #5 otherwise, nearest ancestor <td> or <th> element of the
    *      selection anchor if there is.
    * In #1 and #4, *aIsCellSelected will be set to true (i.e,, when
    * a selection range selects a cell element).
    */
   already_AddRefed<Element>
-  GetSelectedOrParentTableElement(Selection& aSelection,
-                                  ErrorResult& aRv,
+  GetSelectedOrParentTableElement(ErrorResult& aRv,
                                   bool* aIsCellSelected = nullptr) const;
 
   /**
    * PasteInternal() pasts text with replacing selected content.
    * This tries to dispatch ePaste event first.  If its defaultPrevent() is
    * called, this does nothing but returns NS_OK.
    *
    * @param aClipboardType      nsIClipboard::kGlobalClipboard or
@@ -1644,34 +1619,31 @@ protected: // Shouldn't be used by frien
   /**
    * This sets background on the appropriate container element (table, cell,)
    * or calls into nsTextEditor to set the page background.
    */
   nsresult SetCSSBackgroundColorWithTransaction(const nsAString& aColor);
   nsresult SetHTMLBackgroundColorWithTransaction(const nsAString& aColor);
 
   virtual void
-  InitializeSelectionAncestorLimit(Selection& aSelection,
-                                   nsIContent& aAncestorLimit) override;
+  InitializeSelectionAncestorLimit(nsIContent& aAncestorLimit) override;
 
   /**
    * Make the given selection span the entire document.
    */
-  virtual nsresult SelectEntireDocument(Selection* aSelection) override;
+  virtual nsresult SelectEntireDocument() override;
 
   /**
    * 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.
-   * @param aSelection      Optional. If null, we get current selection.
    */
-  void CollapseSelectionToDeepestNonTableFirstChild(Selection* aSelection,
-                                                    nsINode* aNode);
+  void CollapseSelectionToDeepestNonTableFirstChild(nsINode* aNode);
 
   /**
    * Returns TRUE if sheet was loaded, false if it wasn't.
    */
   bool EnableExistingStyleSheet(const nsAString& aURL);
 
   /**
    * GetStyleSheetForURL() returns a pointer to StyleSheet which was added
@@ -1975,22 +1947,20 @@ protected: // Shouldn't be used by frien
   nsresult MergeCells(RefPtr<Element> aTargetCell,
                       RefPtr<Element> aCellToMerge,
                       bool aDeleteCellToMerge);
 
   /**
    * DeleteTableElementAndChildren() removes aTableElement (and its children)
    * from the DOM tree with transaction.
    *
-   * @param aSelection      The normal Selection for the editor.
    * @param aTableElement   The <table> element which you want to remove.
    */
   nsresult
-  DeleteTableElementAndChildrenWithTransaction(Selection& aSelection,
-                                               Element& aTableElement);
+  DeleteTableElementAndChildrenWithTransaction(Element& aTableElement);
 
   nsresult SetColSpan(Element* aCell, int32_t aColSpan);
   nsresult SetRowSpan(Element* aCell, int32_t aRowSpan);
 
   /**
    * Helper used to get nsTableWrapperFrame for a table.
    */
   static nsTableWrapperFrame* GetTableFrame(Element* aTable);
@@ -2021,17 +1991,17 @@ protected: // Shouldn't be used by frien
    * Most insert methods need to get the same basic context data.
    * Any of the pointers may be null if you don't need that datum (for more
    * efficiency).
    * Input: *aCell is a known cell,
    *        if null, cell is obtained from the anchor node of the selection.
    * Returns NS_EDITOR_ELEMENT_NOT_FOUND if cell is not found even if aCell is
    * null.
    */
-  nsresult GetCellContext(Selection** aSelection, Element** aTable,
+  nsresult GetCellContext(Element** aTable,
                           Element** aCell, nsINode** aCellParent,
                           int32_t* aCellOffset, int32_t* aRowIndex,
                           int32_t* aColIndex);
 
   nsresult GetCellSpansAt(Element* aTable, int32_t aRowIndex,
                           int32_t aColIndex, int32_t& aActualRowSpan,
                           int32_t& aActualColSpan);
 
@@ -2051,34 +2021,32 @@ protected: // Shouldn't be used by frien
    * Reduce rowspan/colspan when cells span into nonexistent rows/columns.
    */
   nsresult FixBadRowSpan(Element* aTable, int32_t aRowIndex,
                          int32_t& aNewRowCount);
   nsresult FixBadColSpan(Element* aTable, int32_t aColIndex,
                          int32_t& aNewColCount);
 
   /**
-   * XXX NormalizeTable() is broken.  If it meets a cell which has bigger or
-   *     smaller rowspan or colspan than actual number of cells, this always
-   *     failed to scan the table.  Therefore, this does nothing when the
-   *     table should be normalized.
+   * XXX NormalizeTableInternal() is broken.  If it meets a cell which has
+   *     bigger or smaller rowspan or colspan than actual number of cells,
+   *     this always failed to scan the table.  Therefore, this does nothing
+   *     when the table should be normalized.
    *
-   * @param aSelection              The Selection for the editor.
    * @param aTableOrElementInTable  An element which is in a <table> element
    *                                or <table> element itself.  Otherwise,
    *                                this returns NS_OK but does nothing.
    */
-  nsresult NormalizeTable(Selection& aSelection,
-                          Element& aTableOrElementInTable);
+  nsresult NormalizeTableInternal(Element& aTableOrElementInTable);
 
   /**
    * Fallback method: Call this after using ClearSelection() and you
    * failed to set selection to some other content in the document.
    */
-  nsresult SetSelectionAtDocumentStart(Selection* aSelection);
+  nsresult SetSelectionAtDocumentStart();
 
   static Element* GetEnclosingTable(nsINode* aNode);
 
   // Methods for handling plaintext quotations
   nsresult PasteAsPlaintextQuotation(int32_t aSelectionType);
 
   /**
    * Insert a string as quoted text, replacing the selected text (if any).
@@ -2294,17 +2262,17 @@ protected: // Shouldn't be used by frien
   void DeleteRefToAnonymousNode(ManualNACPtr aContent,
                                 nsIPresShell* aShell);
 
   /**
    * RefereshEditingUI() may refresh editing UIs for current Selection, focus,
    * etc.  If this shows or hides some UIs, it causes reflow.  So, this is
    * not safe method.
    */
-  nsresult RefereshEditingUI(Selection& aSelection);
+  nsresult RefereshEditingUI();
 
   /**
    * Returns the offset of an element's frame to its absolute containing block.
    */
   nsresult GetElementOrigin(Element& aElement,
                             int32_t& aX, int32_t& aY);
   nsresult GetPositionAndDimensions(Element& aElement,
                                     int32_t& aX, int32_t& aY,
--- a/editor/libeditor/HTMLEditorDataTransfer.cpp
+++ b/editor/libeditor/HTMLEditorDataTransfer.cpp
@@ -227,17 +227,17 @@ HTMLEditor::DoInsertHTMLWithContext(cons
                                            &streamEndOffset,
                                            aTrustedInput);
   NS_ENSURE_SUCCESS(rv, rv);
 
   EditorDOMPoint targetPoint;
   if (!aDestNode) {
     // if caller didn't provide the destination/target node,
     // fetch the paste insertion point from our selection
-    targetPoint = EditorBase::GetStartPoint(selection);
+    targetPoint = EditorBase::GetStartPoint(*selection);
     if (NS_WARN_IF(!targetPoint.IsSet()) ||
         !IsEditable(targetPoint.GetContainer())) {
       return NS_ERROR_FAILURE;
     }
   } else {
     targetPoint.Set(aDestNode, aDestOffset);
   }
 
@@ -288,18 +288,17 @@ HTMLEditor::DoInsertHTMLWithContext(cons
     }
     return NS_OK;
   }
 
   // Are there any table elements in the list?
   // check for table cell selection mode
   bool cellSelectionMode = false;
   IgnoredErrorResult ignoredError;
-  RefPtr<Element> cellElement =
-    GetFirstSelectedTableCellElement(*selection, ignoredError);
+  RefPtr<Element> cellElement = GetFirstSelectedTableCellElement(ignoredError);
   if (cellElement) {
     cellSelectionMode = true;
   }
 
   if (cellSelectionMode) {
     // do we have table content to paste?  If so, we want to delete
     // the selected table cells and replace with new table elements;
     // but if not we want to delete _contents_ of cells and replace
@@ -323,17 +322,17 @@ HTMLEditor::DoInsertHTMLWithContext(cons
     }
   } else {
     // Delete whole cells: we will replace with new table content.
 
     // Braces for artificial block to scope AutoSelectionRestorer.
     // Save current selection since DeleteTableCellWithTransaction() perturbs
     // it.
     {
-      AutoSelectionRestorer restoreSelectionLater(*selection, *this);
+      AutoSelectionRestorer restoreSelectionLater(*this);
       rv = DeleteTableCellWithTransaction(1);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
     }
     // collapse selection to beginning of deleted table content
     selection->CollapseToStart(IgnoreErrors());
   }
@@ -346,17 +345,18 @@ HTMLEditor::DoInsertHTMLWithContext(cons
   if (cancel) {
     return NS_OK; // rules canceled the operation
   }
 
   if (!handled) {
     // Adjust position based on the first node we are going to insert.
     // FYI: WillDoAction() above might have changed the selection.
     EditorDOMPoint pointToInsert =
-      GetBetterInsertionPointFor(nodeList[0], GetStartPoint(selection));
+      GetBetterInsertionPointFor(nodeList[0],
+                                 EditorBase::GetStartPoint(*selection));
     if (NS_WARN_IF(!pointToInsert.IsSet())) {
       return NS_ERROR_FAILURE;
     }
 
     // if there are any invisible br's after our insertion point, remove them.
     // this is because if there is a br at end of what we paste, it will make
     // the invisible br visible.
     WSRunObject wsObj(this, pointToInsert);
--- a/editor/libeditor/HTMLEditorEventListener.cpp
+++ b/editor/libeditor/HTMLEditorEventListener.cpp
@@ -159,17 +159,17 @@ HTMLEditorEventListener::MouseDown(Mouse
         }
         if (DetachedFromEditor()) {
           return NS_OK;
         }
       }
     }
     // HACK !!! Context click places the caret but the context menu consumes
     // the event; so we need to check resizing state ourselves
-    htmlEditor->CheckSelectionStateForAnonymousButtons(selection);
+    htmlEditor->CheckSelectionStateForAnonymousButtons();
 
     // Prevent bubbling if we changed selection or
     //   for all context clicks
     if (element || isContextClick) {
       aMouseEvent->PreventDefault();
       return NS_OK;
     }
   } else if (!isContextClick && buttonNumber == 0 && clickCount == 1) {
--- a/editor/libeditor/HTMLStyleEditor.cpp
+++ b/editor/libeditor/HTMLStyleEditor.cpp
@@ -130,17 +130,17 @@ HTMLEditor::SetInlinePropertyInternal(ns
     mTypeInState->SetProp(&aProperty, aAttribute, aValue);
     return NS_OK;
   }
 
   AutoPlaceholderBatch treatAsOneTransaction(*this);
   AutoTopLevelEditSubActionNotifier maybeTopLevelEditSubAction(
                                       *this, EditSubAction::eInsertElement,
                                       nsIEditor::eNext);
-  AutoSelectionRestorer restoreSelectionLater(*selection, *this);
+  AutoSelectionRestorer restoreSelectionLater(*this);
   AutoTransactionsConserveSelection dontChangeMySelection(*this);
 
   bool cancel, handled;
   EditSubActionInfo subActionInfo(EditSubAction::eSetTextProperty);
   // Protect the edit rules object from dying
   nsresult rv =
     rules->WillDoAction(selection, subActionInfo, &cancel, &handled);
   if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -1361,17 +1361,17 @@ HTMLEditor::RemoveInlinePropertyInternal
     }
     return NS_OK;
   }
 
   AutoPlaceholderBatch treatAsOneTransaction(*this);
   AutoTopLevelEditSubActionNotifier maybeTopLevelEditSubAction(
                                       *this, EditSubAction::eRemoveTextProperty,
                                       nsIEditor::eNext);
-  AutoSelectionRestorer restoreSelectionLater(*selection, *this);
+  AutoSelectionRestorer restoreSelectionLater(*this);
   AutoTransactionsConserveSelection dontChangeMySelection(*this);
 
   bool cancel, handled;
   EditSubActionInfo subActionInfo(EditSubAction::eRemoveTextProperty);
   // Protect the edit rules object from dying
   RefPtr<TextEditRules> rules(mRules);
   nsresult rv =
     rules->WillDoAction(selection, subActionInfo, &cancel, &handled);
@@ -1543,17 +1543,17 @@ HTMLEditor::RelativeFontChange(FontSize 
     return NS_OK;
   }
 
   // Wrap with txn batching, rules sniffing, and selection preservation code
   AutoPlaceholderBatch treatAsOneTransaction(*this);
   AutoTopLevelEditSubActionNotifier maybeTopLevelEditSubAction(
                                       *this, EditSubAction::eSetTextProperty,
                                       nsIEditor::eNext);
-  AutoSelectionRestorer restoreSelectionLater(*selection, *this);
+  AutoSelectionRestorer restoreSelectionLater(*this);
   AutoTransactionsConserveSelection dontChangeMySelection(*this);
 
   // Loop through the ranges in the selection
   AutoRangeArray arrayOfRanges(selection);
   for (auto& range : arrayOfRanges.mRanges) {
     // Adjust range to include any ancestors with entirely selected children
     nsresult rv = PromoteInlineRange(*range);
     NS_ENSURE_SUCCESS(rv, rv);
--- a/editor/libeditor/HTMLTableEditor.cpp
+++ b/editor/libeditor/HTMLTableEditor.cpp
@@ -189,18 +189,17 @@ HTMLEditor::InsertTableCell(int32_t aNum
 nsresult
 HTMLEditor::InsertTableCellsWithTransaction(int32_t aNumberOfCellsToInsert,
                                             InsertPosition aInsertPosition)
 {
   RefPtr<Element> table;
   RefPtr<Element> curCell;
   nsCOMPtr<nsINode> cellParent;
   int32_t cellOffset, startRowIndex, startColIndex;
-  nsresult rv = GetCellContext(nullptr,
-                               getter_AddRefs(table),
+  nsresult rv = GetCellContext(getter_AddRefs(table),
                                getter_AddRefs(curCell),
                                getter_AddRefs(cellParent), &cellOffset,
                                &startRowIndex, &startColIndex);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   if (NS_WARN_IF(!table) || NS_WARN_IF(!curCell)) {
     // Don't fail if no cell found.
@@ -430,22 +429,22 @@ HTMLEditor::InsertTableColumn(int32_t aN
   }
   return NS_OK;
 }
 
 nsresult
 HTMLEditor::InsertTableColumnsWithTransaction(int32_t aNumberOfColumnsToInsert,
                                               InsertPosition aInsertPosition)
 {
-  RefPtr<Selection> selection;
+  MOZ_ASSERT(IsEditActionDataAvailable());
+
   RefPtr<Element> table;
   RefPtr<Element> curCell;
   int32_t startRowIndex, startColIndex;
-  nsresult rv = GetCellContext(getter_AddRefs(selection),
-                               getter_AddRefs(table),
+  nsresult rv = GetCellContext(getter_AddRefs(table),
                                getter_AddRefs(curCell),
                                nullptr, nullptr,
                                &startRowIndex, &startColIndex);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   if (NS_WARN_IF(!table) || NS_WARN_IF(!curCell)) {
     // Don't fail if no cell found.
@@ -499,24 +498,21 @@ HTMLEditor::InsertTableColumnsWithTransa
                                              cellDataAtSelection.mCurrent.mRow,
                                              startColIndex, ePreviousRow,
                                              false);
   // Suppress Rules System selection munging.
   AutoTransactionsConserveSelection dontChangeSelection(*this);
 
   // If we are inserting after all existing columns, make sure table is
   // "well formed" before appending new column.
-  // XXX As far as I've tested, NormalizeTable() always fails to normalize
-  //     non-rectangular table.  So, the following CellData will fail if
-  //     the table is not rectangle.
+  // XXX As far as I've tested, NormalizeTableInternal() always fails to
+  //     normalize non-rectangular table.  So, the following CellData will
+  //     fail if the table is not rectangle.
   if (startColIndex >= tableSize.mColumnCount) {
-    if (NS_WARN_IF(!selection)) {
-      return NS_ERROR_FAILURE;
-    }
-    DebugOnly<nsresult> rv = NormalizeTable(*selection, *table);
+    DebugOnly<nsresult> rv = NormalizeTableInternal(*table);
     NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to normalize the table");
   }
 
   RefPtr<Element> rowElement;
   for (int32_t rowIndex = 0; rowIndex < tableSize.mRowCount; rowIndex++) {
     if (startColIndex < tableSize.mColumnCount) {
       // We are inserting before an existing column.
       CellData cellData(*this, *table, rowIndex, startColIndex, ignoredError);
@@ -542,17 +538,18 @@ HTMLEditor::InsertTableColumnsWithTransa
                      cellData.mColSpan + aNumberOfColumnsToInsert);
         }
         continue;
       }
 
       // Simply set selection to the current cell. So, we can let
       // InsertTableCellsWithTransaction() do the work.  Insert a new cell
       // before current one.
-      selection->Collapse(RawRangeBoundary(cellData.mElement, 0), ignoredError);
+      SelectionRefPtr()->Collapse(RawRangeBoundary(cellData.mElement, 0),
+                                  ignoredError);
       NS_WARNING_ASSERTION(!ignoredError.Failed(),
         "Failed to collapse Selection into the cell");
       rv = InsertTableCellsWithTransaction(aNumberOfColumnsToInsert,
                                            InsertPosition::eBeforeSelectedCell);
       NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to insert a cell element");
       continue;
     }
 
@@ -586,19 +583,20 @@ HTMLEditor::InsertTableColumnsWithTransa
       return rv;
     }
     if (NS_WARN_IF(!lastCellNode)) {
       return NS_ERROR_FAILURE;
     }
 
     // Simply add same number of cells to each row.  Although tempted to check
     // cell indexes for current cell, the effects of colspan > 1 in some cells
-    // makes this futile.  We must use NormalizeTable first to assure that
-    // there are cells in each cellmap location.
-    selection->Collapse(RawRangeBoundary(lastCellNode, 0), ignoredError);
+    // makes this futile.  We must use NormalizeTableInternal() first to assure
+    // that there are cells in each cellmap location.
+    SelectionRefPtr()->Collapse(RawRangeBoundary(lastCellNode, 0),
+                                ignoredError);
     NS_WARNING_ASSERTION(!ignoredError.Failed(),
       "Failed to collapse Selection into the cell");
     rv = InsertTableCellsWithTransaction(aNumberOfColumnsToInsert,
                                          InsertPosition::eAfterSelectedCell);
     NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to insert a cell element");
   }
   // XXX This is perhaps the result of the last call of
   //     InsertTableCellsWithTransaction().
@@ -628,18 +626,17 @@ HTMLEditor::InsertTableRow(int32_t aNumb
 nsresult
 HTMLEditor::InsertTableRowsWithTransaction(int32_t aNumberOfRowsToInsert,
                                            InsertPosition aInsertPosition)
 {
   RefPtr<Element> table;
   RefPtr<Element> curCell;
 
   int32_t startRowIndex, startColIndex;
-  nsresult rv = GetCellContext(nullptr,
-                               getter_AddRefs(table),
+  nsresult rv = GetCellContext(getter_AddRefs(table),
                                getter_AddRefs(curCell),
                                nullptr, nullptr,
                                &startRowIndex, &startColIndex);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   if (NS_WARN_IF(!table) || NS_WARN_IF(!curCell)) {
     // Don't fail if no cell found.
@@ -823,45 +820,46 @@ HTMLEditor::InsertTableRowsWithTransacti
   if (presShell) {
     presShell->FlushPendingNotifications(FlushType::Frames);
   }
 
   return NS_OK;
 }
 
 nsresult
-HTMLEditor::DeleteTableElementAndChildrenWithTransaction(Selection& aSelection,
-                                                         Element& aTableElement)
+HTMLEditor::DeleteTableElementAndChildrenWithTransaction(Element& aTableElement)
 {
+  MOZ_ASSERT(IsEditActionDataAvailable());
+
   // Block selectionchange event.  It's enough to dispatch selectionchange
   // event immediately after removing the table element.
   {
-    AutoHideSelectionChanges hideSelection(&aSelection);
+    AutoHideSelectionChanges hideSelection(SelectionRefPtr());
 
     // Select the <table> element after clear current selection.
-    if (aSelection.RangeCount()) {
-      nsresult rv = aSelection.RemoveAllRangesTemporarily();
+    if (SelectionRefPtr()->RangeCount()) {
+      nsresult rv = SelectionRefPtr()->RemoveAllRangesTemporarily();
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
     }
 
     RefPtr<nsRange> range = new nsRange(&aTableElement);
     ErrorResult error;
     range->SelectNode(aTableElement, error);
     if (NS_WARN_IF(error.Failed())) {
       return error.StealNSResult();
     }
-    aSelection.AddRange(*range, error);
+    SelectionRefPtr()->AddRange(*range, error);
     if (NS_WARN_IF(error.Failed())) {
       return error.StealNSResult();
     }
 
 #ifdef DEBUG
-    range = aSelection.GetRangeAt(0);
+    range = SelectionRefPtr()->GetRangeAt(0);
     MOZ_ASSERT(range);
     MOZ_ASSERT(range->GetStartContainer() == aTableElement.GetParent());
     MOZ_ASSERT(range->GetEndContainer() == aTableElement.GetParent());
     MOZ_ASSERT(range->GetChildAtStartOffset() == &aTableElement);
     MOZ_ASSERT(range->GetChildAtEndOffset() == aTableElement.GetNextSibling());
 #endif // #ifdef DEBUG
   }
 
@@ -877,28 +875,27 @@ HTMLEditor::DeleteTable()
 {
   AutoEditActionDataSetter editActionData(*this,
                                           EditAction::eRemoveTableElement);
   if (NS_WARN_IF(!editActionData.CanHandle())) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
   RefPtr<Element> table;
-  nsresult rv = GetCellContext(nullptr,
-                               getter_AddRefs(table),
+  nsresult rv = GetCellContext(getter_AddRefs(table),
                                nullptr, nullptr, nullptr, nullptr, nullptr);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   if (NS_WARN_IF(!table)) {
     return NS_ERROR_FAILURE;
   }
 
   AutoPlaceholderBatch treateAsOneTransaction(*this);
-  rv = DeleteTableElementAndChildrenWithTransaction(*SelectionRefPtr(), *table);
+  rv = DeleteTableElementAndChildrenWithTransaction(*table);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLEditor::DeleteTableCell(int32_t aNumberOfCellsToDelete)
@@ -914,24 +911,24 @@ HTMLEditor::DeleteTableCell(int32_t aNum
     return rv;
   }
   return NS_OK;
 }
 
 nsresult
 HTMLEditor::DeleteTableCellWithTransaction(int32_t aNumberOfCellsToDelete)
 {
-  RefPtr<Selection> selection;
+  MOZ_ASSERT(IsEditActionDataAvailable());
+
   RefPtr<Element> table;
   RefPtr<Element> cell;
   int32_t startRowIndex, startColIndex;
 
 
-  nsresult rv = GetCellContext(getter_AddRefs(selection),
-                               getter_AddRefs(table),
+  nsresult rv = GetCellContext(getter_AddRefs(table),
                                getter_AddRefs(cell),
                                nullptr, nullptr,
                                &startRowIndex, &startColIndex);
 
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   if (NS_WARN_IF(!table) || NS_WARN_IF(!cell)) {
@@ -942,37 +939,36 @@ HTMLEditor::DeleteTableCellWithTransacti
   AutoPlaceholderBatch treateAsOneTransaction(*this);
   // Prevent rules testing until we're done
   AutoTopLevelEditSubActionNotifier maybeTopLevelEditSubAction(
                                       *this, EditSubAction::eDeleteNode,
                                       nsIEditor::eNext);
 
   ErrorResult error;
   RefPtr<Element> firstSelectedCellElement =
-    GetFirstSelectedTableCellElement(*selection, error);
+    GetFirstSelectedTableCellElement(error);
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
 
-  MOZ_ASSERT(selection->RangeCount());
+  MOZ_ASSERT(SelectionRefPtr()->RangeCount());
 
   TableSize tableSize(*this, *table, error);
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
 
   MOZ_ASSERT(!tableSize.IsEmpty());
 
   // If only one cell is selected or no cell is selected, remove cells
   // starting from the first selected cell or a cell containing first
   // selection range.
-  if (!firstSelectedCellElement || selection->RangeCount() == 1) {
+  if (!firstSelectedCellElement || SelectionRefPtr()->RangeCount() == 1) {
     for (int32_t i = 0; i < aNumberOfCellsToDelete; i++) {
-      rv = GetCellContext(getter_AddRefs(selection),
-                          getter_AddRefs(table),
+      rv = GetCellContext(getter_AddRefs(table),
                           getter_AddRefs(cell),
                           nullptr, nullptr,
                           &startRowIndex, &startColIndex);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
       if (NS_WARN_IF(!table) || NS_WARN_IF(!cell)) {
         // Don't fail if no cell found
@@ -982,17 +978,17 @@ HTMLEditor::DeleteTableCellWithTransacti
       int32_t numberOfCellsInRow = GetNumberOfCellsInRow(*table, startRowIndex);
       NS_WARNING_ASSERTION(numberOfCellsInRow >= 0,
         "Failed to count number of cells in the row");
 
       if (numberOfCellsInRow == 1) {
         // Remove <tr> or <table> if we're removing all cells in the row or
         // the table.
         if (tableSize.mRowCount == 1) {
-          rv = DeleteTableElementAndChildrenWithTransaction(*selection, *table);
+          rv = DeleteTableElementAndChildrenWithTransaction(*table);
           if (NS_WARN_IF(NS_FAILED(rv))) {
             return rv;
           }
           return NS_OK;
         }
 
         // We need to call DeleteSelectedTableRowsWithTransaction() to handle
         // cells with rowspan attribute.
@@ -1055,32 +1051,32 @@ HTMLEditor::DeleteTableCellWithTransacti
       // Optimize to delete an entire row
       // Clear so we don't repeat AllCellsInRowSelected within the same row
       checkToDeleteRow = false;
       if (AllCellsInRowSelected(table, startRowIndex, tableSize.mColumnCount)) {
         // First, find the next cell in a different row to continue after we
         // delete this row.
         int32_t nextRow = startRowIndex;
         while (nextRow == startRowIndex) {
-          cell = GetNextSelectedTableCellElement(*selection, error);
+          cell = GetNextSelectedTableCellElement(error);
           if (NS_WARN_IF(error.Failed())) {
             return error.StealNSResult();
           }
           if (!cell) {
             break;
           }
           CellIndexes nextSelectedCellIndexes(*cell, error);
           if (NS_WARN_IF(error.Failed())) {
             return error.StealNSResult();
           }
           nextRow = nextSelectedCellIndexes.mRow;
           startColIndex = nextSelectedCellIndexes.mColumn;
         }
         if (tableSize.mRowCount == 1) {
-          rv = DeleteTableElementAndChildrenWithTransaction(*selection, *table);
+          rv = DeleteTableElementAndChildrenWithTransaction(*table);
           if (NS_WARN_IF(NS_FAILED(rv))) {
             return rv;
           }
           return NS_OK;
         }
         rv = DeleteTableRowWithTransaction(*table, startRowIndex);
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return rv;
@@ -1108,17 +1104,17 @@ HTMLEditor::DeleteTableCellWithTransacti
       // Clear this so we don't repeat AllCellsInColSelected within the same Col
       checkToDeleteColumn = false;
       if (AllCellsInColumnSelected(table, startColIndex,
                                    tableSize.mColumnCount)) {
         // First, find the next cell in a different column to continue after
         // we delete this column.
         int32_t nextCol = startColIndex;
         while (nextCol == startColIndex) {
-          cell = GetNextSelectedTableCellElement(*selection, error);
+          cell = GetNextSelectedTableCellElement(error);
           if (NS_WARN_IF(error.Failed())) {
             return error.StealNSResult();
           }
           if (!cell) {
             break;
           }
           CellIndexes nextSelectedCellIndexes(*cell, error);
           if (NS_WARN_IF(error.Failed())) {
@@ -1146,18 +1142,17 @@ HTMLEditor::DeleteTableCellWithTransacti
         startColIndex = nextCol - 1;
         // Set true since we know we will look at a new column next
         checkToDeleteColumn = true;
         continue;
       }
     }
 
     // First get the next cell to delete
-    RefPtr<Element> nextCell =
-      GetNextSelectedTableCellElement(*selection, error);
+    RefPtr<Element> nextCell = GetNextSelectedTableCellElement(error);
     if (NS_WARN_IF(error.Failed())) {
       return error.StealNSResult();
     }
 
     // Then delete the cell
     rv = DeleteNodeWithTransaction(*cell);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
@@ -1197,45 +1192,45 @@ HTMLEditor::DeleteTableCellContents()
     return rv;
   }
   return NS_OK;
 }
 
 nsresult
 HTMLEditor::DeleteTableCellContentsWithTransaction()
 {
-  RefPtr<Selection> selection;
+  MOZ_ASSERT(IsEditActionDataAvailable());
+
   RefPtr<Element> table;
   RefPtr<Element> cell;
   int32_t startRowIndex, startColIndex;
-  nsresult rv = GetCellContext(getter_AddRefs(selection),
-                               getter_AddRefs(table),
+  nsresult rv = GetCellContext(getter_AddRefs(table),
                                getter_AddRefs(cell),
                                nullptr, nullptr,
                                &startRowIndex, &startColIndex);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
-  if (NS_WARN_IF(!selection) || NS_WARN_IF(!cell)) {
+  if (NS_WARN_IF(!cell)) {
     // Don't fail if no cell found.
     return NS_OK;
   }
 
 
   AutoPlaceholderBatch treateAsOneTransaction(*this);
   // Prevent rules testing until we're done
   AutoTopLevelEditSubActionNotifier maybeTopLevelEditSubAction(
                                       *this, EditSubAction::eDeleteNode,
                                       nsIEditor::eNext);
   // Don't let Rules System change the selection
   AutoTransactionsConserveSelection dontChangeSelection(*this);
 
   ErrorResult error;
   RefPtr<Element> firstSelectedCellElement =
-    GetFirstSelectedTableCellElement(*selection, error);
+    GetFirstSelectedTableCellElement(error);
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
 
   if (firstSelectedCellElement) {
     CellIndexes firstCellIndexes(*firstSelectedCellElement, error);
     if (NS_WARN_IF(error.Failed())) {
       return error.StealNSResult();
@@ -1255,17 +1250,17 @@ HTMLEditor::DeleteTableCellContentsWithT
       "Failed to remove all children of the cell element");
     // If selection is not in cell-select mode, we should remove only the cell
     // which contains first selection range.
     if (!firstSelectedCellElement) {
       return NS_OK;
     }
     // If there are 2 or more selected cells, keep handling the other selected
     // cells.
-    cell = GetNextSelectedTableCellElement(*selection, error);
+    cell = GetNextSelectedTableCellElement(error);
     if (NS_WARN_IF(error.Failed())) {
       return error.StealNSResult();
     }
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -1284,29 +1279,27 @@ HTMLEditor::DeleteTableColumn(int32_t aN
   }
   return NS_OK;
 }
 
 nsresult
 HTMLEditor::DeleteSelectedTableColumnsWithTransaction(
               int32_t aNumberOfColumnsToDelete)
 {
-  RefPtr<Selection> selection;
   RefPtr<Element> table;
   RefPtr<Element> cell;
   int32_t startRowIndex, startColIndex;
-  nsresult rv = GetCellContext(getter_AddRefs(selection),
-                               getter_AddRefs(table),
+  nsresult rv = GetCellContext(getter_AddRefs(table),
                                getter_AddRefs(cell),
                                nullptr, nullptr,
                                &startRowIndex, &startColIndex);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
-  if (NS_WARN_IF(!selection) || NS_WARN_IF(!table) || NS_WARN_IF(!cell)) {
+  if (NS_WARN_IF(!table) || NS_WARN_IF(!cell)) {
     // Don't fail if no cell found.
     return NS_OK;
   }
 
   ErrorResult error;
   TableSize tableSize(*this, *table, error);
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
@@ -1316,50 +1309,50 @@ HTMLEditor::DeleteSelectedTableColumnsWi
 
   // Prevent rules testing until we're done
   AutoTopLevelEditSubActionNotifier maybeTopLevelEditSubAction(
                                       *this, EditSubAction::eDeleteNode,
                                       nsIEditor::eNext);
 
   // Shortcut the case of deleting all columns in table
   if (!startColIndex && aNumberOfColumnsToDelete >= tableSize.mColumnCount) {
-    rv = DeleteTableElementAndChildrenWithTransaction(*selection, *table);
+    rv = DeleteTableElementAndChildrenWithTransaction(*table);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
     return NS_OK;
   }
 
 
   // Test if deletion is controlled by selected cells
   RefPtr<Element> firstSelectedCellElement =
-    GetFirstSelectedTableCellElement(*selection, error);
+    GetFirstSelectedTableCellElement(error);
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
 
-  MOZ_ASSERT(selection->RangeCount());
-
-  if (firstSelectedCellElement && selection->RangeCount() > 1) {
+  MOZ_ASSERT(SelectionRefPtr()->RangeCount());
+
+  if (firstSelectedCellElement && SelectionRefPtr()->RangeCount() > 1) {
     CellIndexes firstCellIndexes(*firstSelectedCellElement, error);
     if (NS_WARN_IF(error.Failed())) {
       return error.StealNSResult();
     }
     startRowIndex = firstCellIndexes.mRow;
     startColIndex = firstCellIndexes.mColumn;
   }
 
   // We control selection resetting after the insert...
   AutoSelectionSetterAfterTableEdit setCaret(*this, table, startRowIndex,
                                              startColIndex, ePreviousRow,
                                              false);
 
   // If 2 or more cells are not selected, removing columns starting from
   // a column which contains first selection range.
-  if (!firstSelectedCellElement || selection->RangeCount() == 1) {
+  if (!firstSelectedCellElement || SelectionRefPtr()->RangeCount() == 1) {
     int32_t columnCountToRemove =
       std::min(aNumberOfColumnsToDelete,
                tableSize.mColumnCount - startColIndex);
     for (int32_t i = 0; i < columnCountToRemove; i++) {
       rv = DeleteTableColumnWithTransaction(*table, startColIndex);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
@@ -1377,17 +1370,17 @@ HTMLEditor::DeleteSelectedTableColumnsWi
       }
       startRowIndex = cellIndexes.mRow;
       startColIndex = cellIndexes.mColumn;
     }
     // Find the next cell in a different column
     // to continue after we delete this column
     int32_t nextCol = startColIndex;
     while (nextCol == startColIndex) {
-      cell = GetNextSelectedTableCellElement(*selection, error);
+      cell = GetNextSelectedTableCellElement(error);
       if (NS_WARN_IF(error.Failed())) {
         return error.StealNSResult();
       }
       if (!cell) {
         break;
       }
       CellIndexes cellIndexes(*cell, error);
       if (NS_WARN_IF(error.Failed())) {
@@ -1479,18 +1472,17 @@ HTMLEditor::DeleteTableColumnWithTransac
     }
 
     if (tableSize.mRowCount == 1) {
       // We're deleting the last row.  So, let's remove the <table> now.
       RefPtr<Selection> selection = GetSelection();
       if (NS_WARN_IF(!selection)) {
         return NS_ERROR_FAILURE;
       }
-      nsresult rv =
-        DeleteTableElementAndChildrenWithTransaction(*selection, aTableElement);
+      nsresult rv = DeleteTableElementAndChildrenWithTransaction(aTableElement);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
       return NS_OK;
     }
 
     // Delete the row by placing caret in cell we were to delete.  We need
     // to call DeleteTableRowWithTransaction() to handle cells with rowspan.
@@ -1520,29 +1512,29 @@ HTMLEditor::DeleteTableRow(int32_t aNumb
   }
   return NS_OK;
 }
 
 nsresult
 HTMLEditor::DeleteSelectedTableRowsWithTransaction(
               int32_t aNumberOfRowsToDelete)
 {
-  RefPtr<Selection> selection;
+  MOZ_ASSERT(IsEditActionDataAvailable());
+
   RefPtr<Element> table;
   RefPtr<Element> cell;
   int32_t startRowIndex, startColIndex;
-  nsresult rv =  GetCellContext(getter_AddRefs(selection),
-                                getter_AddRefs(table),
+  nsresult rv =  GetCellContext(getter_AddRefs(table),
                                 getter_AddRefs(cell),
                                 nullptr, nullptr,
                                 &startRowIndex, &startColIndex);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
-  if (NS_WARN_IF(!selection) || NS_WARN_IF(!table) || NS_WARN_IF(!cell)) {
+  if (NS_WARN_IF(!table) || NS_WARN_IF(!cell)) {
     // Don't fail if no cell found.
     return NS_OK;
   }
 
   ErrorResult error;
   TableSize tableSize(*this, *table, error);
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
@@ -1552,32 +1544,32 @@ HTMLEditor::DeleteSelectedTableRowsWithT
 
   // Prevent rules testing until we're done
   AutoTopLevelEditSubActionNotifier maybeTopLevelEditSubAction(
                                       *this, EditSubAction::eDeleteNode,
                                       nsIEditor::eNext);
 
   // Shortcut the case of deleting all rows in table
   if (!startRowIndex && aNumberOfRowsToDelete >= tableSize.mRowCount) {
-    rv = DeleteTableElementAndChildrenWithTransaction(*selection, *table);
+    rv = DeleteTableElementAndChildrenWithTransaction(*table);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return NS_ERROR_FAILURE;
     }
     return NS_OK;
   }
 
   RefPtr<Element> firstSelectedCellElement =
-    GetFirstSelectedTableCellElement(*selection, error);
+    GetFirstSelectedTableCellElement(error);
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
 
-  MOZ_ASSERT(selection->RangeCount());
-
-  if (firstSelectedCellElement && selection->RangeCount() > 1) {
+  MOZ_ASSERT(SelectionRefPtr()->RangeCount());
+
+  if (firstSelectedCellElement && SelectionRefPtr()->RangeCount() > 1) {
     // Fetch indexes again - may be different for selected cells
     CellIndexes firstCellIndexes(*firstSelectedCellElement, error);
     if (NS_WARN_IF(error.Failed())) {
       return error.StealNSResult();
     }
     startRowIndex = firstCellIndexes.mRow;
     startColIndex = firstCellIndexes.mColumn;
   }
@@ -1590,17 +1582,17 @@ HTMLEditor::DeleteSelectedTableRowsWithT
   AutoTransactionsConserveSelection dontChangeSelection(*this);
 
   // XXX Perhaps, the following loops should collect <tr> elements to remove
   //     first, then, remove them from the DOM tree since mutation event
   //     listener may change the DOM tree during the loops.
 
   // If 2 or more cells are not selected, removing rows starting from
   // a row which contains first selection range.
-  if (!firstSelectedCellElement || selection->RangeCount() == 1) {
+  if (!firstSelectedCellElement || SelectionRefPtr()->RangeCount() == 1) {
     int32_t rowCountToRemove =
       std::min(aNumberOfRowsToDelete, tableSize.mRowCount - startRowIndex);
     for (int32_t i = 0; i < rowCountToRemove; i++) {
       nsresult rv = DeleteTableRowWithTransaction(*table, startRowIndex);
       // If failed in current row, try the next
       if (NS_WARN_IF(NS_FAILED(rv))) {
         startRowIndex++;
       }
@@ -1623,17 +1615,17 @@ HTMLEditor::DeleteSelectedTableRowsWithT
       }
       startRowIndex = cellIndexes.mRow;
       startColIndex = cellIndexes.mColumn;
     }
     // Find the next cell in a different row
     // to continue after we delete this row
     int32_t nextRow = startRowIndex;
     while (nextRow == startRowIndex) {
-      cell = GetNextSelectedTableCellElement(*selection, error);
+      cell = GetNextSelectedTableCellElement(error);
       if (NS_WARN_IF(error.Failed())) {
         return error.StealNSResult();
       }
       if (!cell) {
         break;
       }
       CellIndexes cellIndexes(*cell, error);
       if (NS_WARN_IF(error.Failed())) {
@@ -1776,18 +1768,17 @@ NS_IMETHODIMP
 HTMLEditor::SelectTable()
 {
   AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing);
   if (NS_WARN_IF(!editActionData.CanHandle())) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
   RefPtr<Element> table =
-    GetElementOrParentByTagNameAtSelection(*SelectionRefPtr(),
-                                           *nsGkAtoms::table);
+    GetElementOrParentByTagNameAtSelection(*nsGkAtoms::table);
   if (NS_WARN_IF(!table)) {
     return NS_OK; // Don't fail if we didn't find a table.
   }
 
   nsresult rv = ClearSelection();
   if (NS_FAILED(rv)) {
     return rv;
   }
@@ -1797,18 +1788,17 @@ HTMLEditor::SelectTable()
 NS_IMETHODIMP
 HTMLEditor::SelectTableCell()
 {
   AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing);
   if (NS_WARN_IF(!editActionData.CanHandle())) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
-  RefPtr<Element> cell =
-    GetElementOrParentByTagNameAtSelection(*SelectionRefPtr(), *nsGkAtoms::td);
+  RefPtr<Element> cell = GetElementOrParentByTagNameAtSelection(*nsGkAtoms::td);
   if (NS_WARN_IF(!cell)) {
     return NS_SUCCESS_EDITOR_ELEMENT_NOT_FOUND;
   }
 
   nsresult rv = ClearSelection();
   if (NS_FAILED(rv)) {
     return rv;
   }
@@ -1866,18 +1856,17 @@ HTMLEditor::SelectBlockOfCells(Element* 
     std::min(startCellIndexes.mColumn, endCellIndexes.mColumn);
   int32_t minRow =
     std::min(startCellIndexes.mRow, endCellIndexes.mRow);
   int32_t maxColumn =
     std::max(startCellIndexes.mColumn, endCellIndexes.mColumn);
   int32_t maxRow =
     std::max(startCellIndexes.mRow, endCellIndexes.mRow);
 
-  RefPtr<Element> cell;
-  cell = GetFirstSelectedTableCellElement(*SelectionRefPtr(), error);
+  RefPtr<Element> cell = GetFirstSelectedTableCellElement(error);
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
   if (!cell) {
     return NS_OK;
   }
   RefPtr<nsRange> range = SelectionRefPtr()->GetRangeAt(0);
   MOZ_ASSERT(range);
@@ -1890,17 +1879,17 @@ HTMLEditor::SelectBlockOfCells(Element* 
         currentCellIndexes.mRow > maxRow ||
         currentCellIndexes.mColumn < maxColumn ||
         currentCellIndexes.mColumn > maxColumn) {
       SelectionRefPtr()->RemoveRange(*range, IgnoreErrors());
       // Since we've removed the range, decrement pointer to next range
       MOZ_ASSERT(mSelectedCellIndex > 0);
       mSelectedCellIndex--;
     }
-    cell = GetNextSelectedTableCellElement(*SelectionRefPtr(), error);
+    cell = GetNextSelectedTableCellElement(error);
     if (NS_WARN_IF(error.Failed())) {
       return error.StealNSResult();
     }
     if (cell) {
       MOZ_ASSERT(mSelectedCellIndex > 0);
       range = SelectionRefPtr()->GetRangeAt(mSelectedCellIndex - 1);
     }
   }
@@ -1938,17 +1927,17 @@ NS_IMETHODIMP
 HTMLEditor::SelectAllTableCells()
 {
   AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing);
   if (NS_WARN_IF(!editActionData.CanHandle())) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
   RefPtr<Element> cell =
-    GetElementOrParentByTagNameAtSelection(*SelectionRefPtr(), *nsGkAtoms::td);
+    GetElementOrParentByTagNameAtSelection(*nsGkAtoms::td);
   if (NS_WARN_IF(!cell)) {
     // Don't fail if we didn't find a cell.
     return NS_SUCCESS_EDITOR_ELEMENT_NOT_FOUND;
   }
 
   RefPtr<Element> startCell = cell;
 
   // Get parent table
@@ -2013,30 +2002,29 @@ NS_IMETHODIMP
 HTMLEditor::SelectTableRow()
 {
   AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing);
   if (NS_WARN_IF(!editActionData.CanHandle())) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
   RefPtr<Element> cell =
-    GetElementOrParentByTagNameAtSelection(*SelectionRefPtr(), *nsGkAtoms::td);
+    GetElementOrParentByTagNameAtSelection(*nsGkAtoms::td);
   if (NS_WARN_IF(!cell)) {
     // Don't fail if we didn't find a cell.
     return NS_SUCCESS_EDITOR_ELEMENT_NOT_FOUND;
   }
 
   RefPtr<Element> startCell = cell;
 
   // Get table and location of cell:
   RefPtr<Element> table;
   int32_t startRowIndex, startColIndex;
 
-  nsresult rv = GetCellContext(nullptr,
-                               getter_AddRefs(table),
+  nsresult rv = GetCellContext(getter_AddRefs(table),
                                getter_AddRefs(cell),
                                nullptr, nullptr,
                                &startRowIndex, &startColIndex);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   if (NS_WARN_IF(!table)) {
     return NS_ERROR_FAILURE;
@@ -2098,31 +2086,29 @@ HTMLEditor::SelectTableRow()
 NS_IMETHODIMP
 HTMLEditor::SelectTableColumn()
 {
   AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing);
   if (NS_WARN_IF(!editActionData.CanHandle())) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
-  RefPtr<Element> cell =
-    GetElementOrParentByTagNameAtSelection(*SelectionRefPtr(), *nsGkAtoms::td);
+  RefPtr<Element> cell = GetElementOrParentByTagNameAtSelection(*nsGkAtoms::td);
   if (NS_WARN_IF(!cell)) {
     // Don't fail if we didn't find a cell.
     return NS_SUCCESS_EDITOR_ELEMENT_NOT_FOUND;
   }
 
   RefPtr<Element> startCell = cell;
 
   // Get location of cell:
   RefPtr<Element> table;
   int32_t startRowIndex, startColIndex;
 
-  nsresult rv = GetCellContext(nullptr,
-                               getter_AddRefs(table),
+  nsresult rv = GetCellContext(getter_AddRefs(table),
                                getter_AddRefs(cell),
                                nullptr, nullptr,
                                &startRowIndex, &startColIndex);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   if (NS_WARN_IF(!table)) {
     return NS_ERROR_FAILURE;
@@ -2185,18 +2171,17 @@ HTMLEditor::SplitTableCell()
   if (NS_WARN_IF(!editActionData.CanHandle())) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
   RefPtr<Element> table;
   RefPtr<Element> cell;
   int32_t startRowIndex, startColIndex, actualRowSpan, actualColSpan;
   // Get cell, table, etc. at selection anchor node
-  nsresult rv = GetCellContext(nullptr,
-                               getter_AddRefs(table),
+  nsresult rv = GetCellContext(getter_AddRefs(table),
                                getter_AddRefs(cell),
                                nullptr, nullptr,
                                &startRowIndex, &startColIndex);
   NS_ENSURE_SUCCESS(rv, rv);
   if (!table || !cell) {
     return NS_SUCCESS_EDITOR_ELEMENT_NOT_FOUND;
   }
 
@@ -2475,17 +2460,17 @@ HTMLEditor::SwitchTableCellHeaderType(El
   // ReplaceContainerAndCloneAttributesWithTransaction().
   AutoTopLevelEditSubActionNotifier maybeTopLevelEditSubAction(
                                       *this, EditSubAction::eInsertNode,
                                       nsIEditor::eNext);
 
   // Save current selection to restore when done.
   // This is needed so ReplaceContainerAndCloneAttributesWithTransaction()
   // can monitor selection when replacing nodes.
-  AutoSelectionRestorer restoreSelectionLater(*SelectionRefPtr(), *this);
+  AutoSelectionRestorer restoreSelectionLater(*this);
 
   // Set to the opposite of current type
   nsAtom* newCellName =
     aSourceCell->IsHTMLElement(nsGkAtoms::td) ? nsGkAtoms::th : nsGkAtoms::td;
 
   // This creates new node, moves children, copies attributes (true)
   //   and manages the selection!
   RefPtr<Element> newCell =
@@ -2512,18 +2497,17 @@ HTMLEditor::JoinTableCells(bool aMergeNo
     return NS_ERROR_NOT_INITIALIZED;
   }
 
   RefPtr<Element> table;
   RefPtr<Element> targetCell;
   int32_t startRowIndex, startColIndex;
 
   // Get cell, table, etc. at selection anchor node
-  nsresult rv = GetCellContext(nullptr,
-                               getter_AddRefs(table),
+  nsresult rv = GetCellContext(getter_AddRefs(table),
                                getter_AddRefs(targetCell),
                                nullptr, nullptr,
                                &startRowIndex, &startColIndex);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   if (!table || !targetCell) {
     return NS_OK;
@@ -2540,18 +2524,17 @@ HTMLEditor::JoinTableCells(bool aMergeNo
   ErrorResult error;
   CellAndIndexes firstSelectedCell(*this, *SelectionRefPtr(), error);
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
 
   bool joinSelectedCells = false;
   if (firstSelectedCell.mElement) {
-    RefPtr<Element> secondCell =
-      GetNextSelectedTableCellElement(*SelectionRefPtr(), error);
+    RefPtr<Element> secondCell = GetNextSelectedTableCellElement(error);
     if (NS_WARN_IF(error.Failed())) {
       return error.StealNSResult();
     }
 
     // If only one cell is selected, join with cell to the right
     joinSelectedCells = (secondCell != nullptr);
   }
 
@@ -2786,17 +2769,17 @@ HTMLEditor::JoinTableCells(bool aMergeNo
     }
     rv = SetColSpan(firstSelectedCell.mElement,
                     lastColIndex - firstSelectedCell.mIndexes.mColumn + 1);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
     // Fixup disturbances in table layout
-    DebugOnly<nsresult> rv = NormalizeTable(*SelectionRefPtr(), *table);
+    DebugOnly<nsresult> rv = NormalizeTableInternal(*table);
     NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to normalize the table");
   } else {
     // Joining with cell to the right -- get rowspan and colspan data of target
     // cell.
     IgnoredErrorResult ignoredError;
     CellData leftCellData(*this, *table, startRowIndex, startColIndex,
                           ignoredError);
     if (NS_WARN_IF(leftCellData.FailedOrNotFound())) {
@@ -3113,33 +3096,32 @@ HTMLEditor::NormalizeTable(Element* aTab
 {
   AutoEditActionDataSetter editActionData(*this, EditAction::eNormalizeTable);
   if (NS_WARN_IF(!editActionData.CanHandle())) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
   if (!aTableOrElementInTable) {
     aTableOrElementInTable =
-      GetElementOrParentByTagNameAtSelection(*SelectionRefPtr(),
-                                             *nsGkAtoms::table);
+      GetElementOrParentByTagNameAtSelection(*nsGkAtoms::table);
     if (!aTableOrElementInTable) {
       return NS_OK; // Don't throw error even if the element is not in <table>.
     }
   }
-  nsresult rv = NormalizeTable(*SelectionRefPtr(), *aTableOrElementInTable);
+  nsresult rv = NormalizeTableInternal(*aTableOrElementInTable);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   return NS_OK;
 }
 
 nsresult
-HTMLEditor::NormalizeTable(Selection& aSelection,
-                           Element& aTableOrElementInTable)
+HTMLEditor::NormalizeTableInternal(Element& aTableOrElementInTable)
 {
+  MOZ_ASSERT(IsEditActionDataAvailable());
 
   RefPtr<Element> tableElement;
   if (aTableOrElementInTable.NodeInfo()->NameAtom() == nsGkAtoms::table) {
     tableElement = &aTableOrElementInTable;
   } else {
     tableElement =
       GetElementOrParentByTagNameInternal(*nsGkAtoms::table,
                                           aTableOrElementInTable);
@@ -3150,17 +3132,17 @@ HTMLEditor::NormalizeTable(Selection& aS
 
   ErrorResult error;
   TableSize tableSize(*this, *tableElement, error);
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
 
   // Save current selection
-  AutoSelectionRestorer restoreSelectionLater(aSelection, *this);
+  AutoSelectionRestorer restoreSelectionLater(*this);
 
   AutoPlaceholderBatch treateAsOneTransaction(*this);
   // Prevent auto insertion of BR in new cell until we're done
   AutoTopLevelEditSubActionNotifier maybeTopLevelEditSubAction(
                                       *this, EditSubAction::eInsertNode,
                                       nsIEditor::eNext);
 
   // XXX If there is a cell which has bigger or smaller "rowspan" or "colspan"
@@ -3272,18 +3254,17 @@ HTMLEditor::CellIndexes::Update(HTMLEdit
                                 Selection& aSelection,
                                 ErrorResult& aRv)
 {
   MOZ_ASSERT(!aRv.Failed());
 
   // Guarantee the life time of the cell element since Init() will access
   // layout methods.
   RefPtr<Element> cellElement =
-    aHTMLEditor.GetElementOrParentByTagNameAtSelection(aSelection,
-                                                       *nsGkAtoms::td);
+    aHTMLEditor.GetElementOrParentByTagNameAtSelection(*nsGkAtoms::td);
   if (!cellElement) {
     aRv.Throw(NS_ERROR_FAILURE);
     return;
   }
   Update(*cellElement, aRv);
 }
 
 void
@@ -3370,18 +3351,17 @@ HTMLEditor::GetTableSize(Element* aTable
   }
 
   *aRowCount = 0;
   *aColumnCount = 0;
 
   Element* tableOrElementInTable = aTableOrElementInTable;
   if (!tableOrElementInTable) {
     tableOrElementInTable =
-      GetElementOrParentByTagNameAtSelection(*SelectionRefPtr(),
-                                             *nsGkAtoms::table);
+      GetElementOrParentByTagNameAtSelection(*nsGkAtoms::table);
     if (NS_WARN_IF(!tableOrElementInTable)) {
       return NS_ERROR_FAILURE;
     }
   }
 
   ErrorResult error;
   TableSize tableSize(*this, *tableOrElementInTable, error);
   if (NS_WARN_IF(error.Failed())) {
@@ -3456,19 +3436,17 @@ HTMLEditor::GetCellDataAt(Element* aTabl
   *aCellElement = nullptr;
 
   // Let's keep the table element with strong pointer since editor developers
   // may not handle layout code of <table>, however, this method depends on
   // them.
   RefPtr<Element> table = aTableElement;
   if (!table) {
     // Get the selected table or the table enclosing the selection anchor.
-    table =
-      GetElementOrParentByTagNameAtSelection(*SelectionRefPtr(),
-                                             *nsGkAtoms::table);
+    table = GetElementOrParentByTagNameAtSelection(*nsGkAtoms::table);
     if (NS_WARN_IF(!table)) {
       return NS_ERROR_FAILURE;
     }
   }
 
   IgnoredErrorResult ignoredError;
   CellData cellData(*this, *table, aRowIndex, aColumnIndex, ignoredError);
   if (NS_WARN_IF(cellData.FailedOrNotFound())) {
@@ -3547,19 +3525,17 @@ HTMLEditor::GetCellAt(Element* aTableEle
     return NS_ERROR_NOT_INITIALIZED;
   }
 
   *aCellElement = nullptr;
 
   Element* tableElement = aTableElement;
   if (!tableElement) {
     // Get the selected table or the table enclosing the selection anchor.
-    tableElement =
-      GetElementOrParentByTagNameAtSelection(*SelectionRefPtr(),
-                                             *nsGkAtoms::table);
+    tableElement = GetElementOrParentByTagNameAtSelection(*nsGkAtoms::table);
     if (NS_WARN_IF(!tableElement)) {
       return NS_ERROR_FAILURE;
     }
   }
 
   RefPtr<Element> cellElement =
     GetTableCellElementAt(*tableElement, aRowIndex, aColumnIndex);
   cellElement.forget(aCellElement);
@@ -3597,28 +3573,26 @@ HTMLEditor::GetCellSpansAt(Element* aTab
   }
   aActualRowSpan = tableFrame->GetEffectiveRowSpanAt(aRowIndex, aColIndex);
   aActualColSpan = tableFrame->GetEffectiveColSpanAt(aRowIndex, aColIndex);
 
   return NS_OK;
 }
 
 nsresult
-HTMLEditor::GetCellContext(Selection** aSelection,
-                           Element** aTable,
+HTMLEditor::GetCellContext(Element** aTable,
                            Element** aCell,
                            nsINode** aCellParent,
                            int32_t* aCellOffset,
                            int32_t* aRowIndex,
                            int32_t* aColumnIndex)
 {
+  MOZ_ASSERT(IsEditActionDataAvailable());
+
   // Initialize return pointers
-  if (aSelection) {
-    *aSelection = nullptr;
-  }
   if (aTable) {
     *aTable = nullptr;
   }
   if (aCell) {
     *aCell = nullptr;
   }
   if (aCellParent) {
     *aCellParent = nullptr;
@@ -3628,41 +3602,32 @@ HTMLEditor::GetCellContext(Selection** a
   }
   if (aRowIndex) {
     *aRowIndex = 0;
   }
   if (aColumnIndex) {
     *aColumnIndex = 0;
   }
 
-  RefPtr<Selection> selection = GetSelection();
-  if (NS_WARN_IF(!selection)) {
-    return NS_ERROR_FAILURE;
-  }
-
-  if (aSelection) {
-    *aSelection = selection.get();
-    NS_ADDREF(*aSelection);
-  }
   RefPtr<Element> table;
   RefPtr<Element> cell;
 
   // Caller may supply the cell...
   if (aCell && *aCell) {
     cell = *aCell;
   }
 
   // ...but if not supplied,
   //    get cell if it's the child of selection anchor node,
   //    or get the enclosing by a cell
   if (!cell) {
     // Find a selected or enclosing table element
     ErrorResult error;
     RefPtr<Element> cellOrRowOrTableElement =
-      GetSelectedOrParentTableElement(*selection, error);
+      GetSelectedOrParentTableElement(error);
     if (NS_WARN_IF(error.Failed())) {
       return error.StealNSResult();
     }
     if (!cellOrRowOrTableElement) {
       return NS_SUCCESS_EDITOR_ELEMENT_NOT_FOUND;
     }
     if (cellOrRowOrTableElement->IsHTMLElement(nsGkAtoms::table)) {
       // We have a selected table, not a cell
@@ -3785,17 +3750,17 @@ HTMLEditor::GetFirstSelectedCell(nsRange
 
   *aFirstSelectedCellElement = nullptr;
   if (aFirstSelectedRange) {
     *aFirstSelectedRange = nullptr;
   }
 
   ErrorResult error;
   RefPtr<Element> firstSelectedCellElement =
-    GetFirstSelectedTableCellElement(*SelectionRefPtr(), error);
+    GetFirstSelectedTableCellElement(error);
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
 
   if (!firstSelectedCellElement) {
     // Just not found.  Don't return error.
     return NS_OK;
   }
@@ -3807,22 +3772,23 @@ HTMLEditor::GetFirstSelectedCell(nsRange
     MOZ_ASSERT(firstRange);
     firstRange.forget(aFirstSelectedRange);
   }
 
   return NS_OK;
 }
 
 already_AddRefed<Element>
-HTMLEditor::GetFirstSelectedTableCellElement(Selection& aSelection,
-                                             ErrorResult& aRv) const
+HTMLEditor::GetFirstSelectedTableCellElement(ErrorResult& aRv) const
 {
+  MOZ_ASSERT(IsEditActionDataAvailable());
+
   MOZ_ASSERT(!aRv.Failed());
 
-  nsRange* firstRange = aSelection.GetRangeAt(0);
+  nsRange* firstRange = SelectionRefPtr()->GetRangeAt(0);
   if (NS_WARN_IF(!firstRange)) {
     // XXX Why don't we treat "not found" in this case?
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   // XXX It must be unclear when this is reset...
   mSelectedCellIndex = 0;
@@ -3864,17 +3830,17 @@ HTMLEditor::GetNextSelectedCell(nsRange*
 
   *aNextSelectedCellElement = nullptr;
   if (aNextSelectedCellRange) {
     *aNextSelectedCellRange = nullptr;
   }
 
   ErrorResult error;
   RefPtr<Element> nextSelectedCellElement =
-    GetNextSelectedTableCellElement(*SelectionRefPtr(), error);
+    GetNextSelectedTableCellElement(error);
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
 
   if (!nextSelectedCellElement) {
     // not more range, or met a range which does not select <td> nor <th>.
     return NS_OK;
   }
@@ -3884,29 +3850,32 @@ HTMLEditor::GetNextSelectedCell(nsRange*
     *aNextSelectedCellRange =
       do_AddRef(SelectionRefPtr()->GetRangeAt(mSelectedCellIndex - 1)).take();
   }
   nextSelectedCellElement.forget(aNextSelectedCellElement);
   return NS_OK;
 }
 
 already_AddRefed<Element>
-HTMLEditor::GetNextSelectedTableCellElement(Selection& aSelection,
-                                            ErrorResult& aRv) const
+HTMLEditor::GetNextSelectedTableCellElement(ErrorResult& aRv) const
 {
+  MOZ_ASSERT(IsEditActionDataAvailable());
+
   MOZ_ASSERT(!aRv.Failed());
 
-  if (mSelectedCellIndex >= aSelection.RangeCount()) {
+  if (mSelectedCellIndex >= SelectionRefPtr()->RangeCount()) {
     // We've already returned all selected cells.
     return nullptr;
   }
 
   MOZ_ASSERT(mSelectedCellIndex > 0);
-  for (; mSelectedCellIndex < aSelection.RangeCount(); mSelectedCellIndex++) {
-    nsRange* range = aSelection.GetRangeAt(mSelectedCellIndex);
+  for (;
+       mSelectedCellIndex < SelectionRefPtr()->RangeCount();
+       mSelectedCellIndex++) {
+    nsRange* range = SelectionRefPtr()->GetRangeAt(mSelectedCellIndex);
     if (NS_WARN_IF(!range)) {
       aRv.Throw(NS_ERROR_FAILURE);
       return nullptr;
     }
 
     RefPtr<Element> nextSelectedCellElement;
     nsresult rv =
       HTMLEditor::GetCellFromRange(range,
@@ -3964,17 +3933,17 @@ HTMLEditor::CellAndIndexes::Update(HTMLE
                                    Selection& aSelection,
                                    ErrorResult& aRv)
 {
   MOZ_ASSERT(!aRv.Failed());
 
   mIndexes.mRow = -1;
   mIndexes.mColumn = -1;
 
-  mElement = aHTMLEditor.GetFirstSelectedTableCellElement(aSelection, aRv);
+  mElement = aHTMLEditor.GetFirstSelectedTableCellElement(aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return;
   }
   if (!mElement) {
     return;
   }
 
   mIndexes.Update(*mElement, aRv);
@@ -4000,27 +3969,27 @@ HTMLEditor::SetSelectionAfterTableEdit(E
 
   RefPtr<Element> cell;
   bool done = false;
   do {
     cell = GetTableCellElementAt(*aTable, aRow, aCol);
     if (cell) {
       if (aSelected) {
         // Reselect the cell
-        DebugOnly<nsresult> rv = SelectContentInternal(*selection, *cell);
+        DebugOnly<nsresult> rv = SelectContentInternal(*cell);
         NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
           "Failed to select the cell");
         return;
       }
 
       // Set the caret to deepest first child
       //   but don't go into nested tables
       // TODO: Should we really be placing the caret at the END
       //  of the cell content?
-      CollapseSelectionToDeepestNonTableFirstChild(selection, cell);
+      CollapseSelectionToDeepestNonTableFirstChild(cell);
       return;
     }
 
     // Setup index to find another cell in the
     //   direction requested, but move in other direction if already at
     //   beginning of row or column
     switch (aDirection) {
       case ePreviousColumn:
@@ -4057,17 +4026,17 @@ HTMLEditor::SetSelectionAfterTableEdit(E
     if (NS_WARN_IF(!atTable.IsSetAndValid())) {
       return;
     }
     selection->Collapse(atTable);
     return;
   }
   // Last resort: Set selection to start of doc
   // (it's very bad to not have a valid selection!)
-  SetSelectionAtDocumentStart(selection);
+  SetSelectionAtDocumentStart();
 }
 
 NS_IMETHODIMP
 HTMLEditor::GetSelectedOrParentTableElement(nsAString& aTagName,
                                             int32_t* aSelectedCount,
                                             Element** aCellOrRowOrTableElement)
 {
   if (NS_WARN_IF(!aSelectedCount) || NS_WARN_IF(!aCellOrRowOrTableElement)) {
@@ -4081,17 +4050,17 @@ HTMLEditor::GetSelectedOrParentTableElem
   AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing);
   if (NS_WARN_IF(!editActionData.CanHandle())) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
   bool isCellSelected = false;
   ErrorResult aRv;
   RefPtr<Element> cellOrRowOrTableElement =
-    GetSelectedOrParentTableElement(*SelectionRefPtr(), aRv, &isCellSelected);
+    GetSelectedOrParentTableElement(aRv, &isCellSelected);
   if (NS_WARN_IF(aRv.Failed())) {
     return aRv.StealNSResult();
   }
   if (!cellOrRowOrTableElement) {
     return NS_OK;
   }
 
   if (isCellSelected) {
@@ -4124,41 +4093,41 @@ HTMLEditor::GetSelectedOrParentTableElem
   }
 
   MOZ_ASSERT_UNREACHABLE("Which element was returned?");
   return NS_ERROR_UNEXPECTED;
 }
 
 already_AddRefed<Element>
 HTMLEditor::GetSelectedOrParentTableElement(
-              Selection& aSelection,
               ErrorResult& aRv,
               bool* aIsCellSelected /* = nullptr */) const
 {
+  MOZ_ASSERT(IsEditActionDataAvailable());
+
   MOZ_ASSERT(!aRv.Failed());
 
   if (aIsCellSelected) {
     *aIsCellSelected = false;
   }
 
   // Try to get the first selected cell, first.
-  RefPtr<Element> cellElement =
-    GetFirstSelectedTableCellElement(aSelection, aRv);
+  RefPtr<Element> cellElement = GetFirstSelectedTableCellElement(aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
   if (cellElement) {
     if (aIsCellSelected) {
       *aIsCellSelected = true;
     }
     return cellElement.forget();
   }
 
-  const RangeBoundary& anchorRef = aSelection.AnchorRef();
+  const RangeBoundary& anchorRef = SelectionRefPtr()->AnchorRef();
   if (NS_WARN_IF(!anchorRef.IsSet())) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   // If anchor selects a <td>, <table> or <tr>, return it.
   if (anchorRef.Container()->HasChildNodes()) {
     nsIContent* selectedContent = anchorRef.GetChildAtOffset();
@@ -4209,33 +4178,30 @@ HTMLEditor::GetSelectedCellsType(Element
   //  (if aElement is null, this uses selection's anchor node)
   RefPtr<Element> table;
   if (aElement) {
     table = GetElementOrParentByTagNameInternal(*nsGkAtoms::table, *aElement);
     if (NS_WARN_IF(!table)) {
       return NS_ERROR_FAILURE;
     }
   } else {
-    table =
-      GetElementOrParentByTagNameAtSelection(*SelectionRefPtr(),
-                                             *nsGkAtoms::table);
+    table = GetElementOrParentByTagNameAtSelection(*nsGkAtoms::table);
     if (NS_WARN_IF(!table)) {
       return NS_ERROR_FAILURE;
     }
   }
 
   ErrorResult error;
   TableSize tableSize(*this, *table, error);
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
 
   // Traverse all selected cells
-  RefPtr<Element> selectedCell =
-    GetFirstSelectedTableCellElement(*SelectionRefPtr(), error);
+  RefPtr<Element> selectedCell = GetFirstSelectedTableCellElement(error);
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
   if (!selectedCell) {
     return NS_OK;
   }
 
   // We have at least one selected cell, so set return value
@@ -4258,51 +4224,49 @@ HTMLEditor::GetSelectedCellsType(Element
         AllCellsInRowSelected(table, selectedCellIndexes.mRow,
                               tableSize.mColumnCount);
       // We're done as soon as we fail for any row
       if (!allCellsInRowAreSelected) {
         break;
       }
     }
     selectedCell =
-      GetNextSelectedTableCellElement(*SelectionRefPtr(), ignoredError);
+      GetNextSelectedTableCellElement(ignoredError);
     NS_WARNING_ASSERTION(!ignoredError.Failed(),
       "Failed to get next selected table cell element");
   }
 
   if (allCellsInRowAreSelected) {
     *aSelectionType = static_cast<uint32_t>(TableSelection::Row);
     return NS_OK;
   }
   // Test for columns
 
   // Empty the indexArray
   indexArray.Clear();
 
   // Start at first cell again
-  selectedCell = GetFirstSelectedTableCellElement(*SelectionRefPtr(),
-                                                  ignoredError);
+  selectedCell = GetFirstSelectedTableCellElement(ignoredError);
   while (selectedCell) {
     CellIndexes selectedCellIndexes(*selectedCell, error);
     if (NS_WARN_IF(error.Failed())) {
       return error.StealNSResult();
     }
 
     if (!indexArray.Contains(selectedCellIndexes.mRow)) {
       indexArray.AppendElement(selectedCellIndexes.mColumn);
       allCellsInColAreSelected =
         AllCellsInColumnSelected(table, selectedCellIndexes.mColumn,
                                  tableSize.mRowCount);
       // We're done as soon as we fail for any column
       if (!allCellsInRowAreSelected) {
         break;
       }
     }
-    selectedCell =
-      GetNextSelectedTableCellElement(*SelectionRefPtr(), ignoredError);
+    selectedCell = GetNextSelectedTableCellElement(ignoredError);
     NS_WARNING_ASSERTION(!ignoredError.Failed(),
       "Failed to get next selected table cell element");
   }
   if (allCellsInColAreSelected) {
     *aSelectionType = static_cast<uint32_t>(TableSelection::Column);
   }
 
   return NS_OK;
--- a/editor/libeditor/TextEditRules.cpp
+++ b/editor/libeditor/TextEditRules.cpp
@@ -155,17 +155,17 @@ TextEditRules::Init(TextEditor* aTextEdi
   nsresult rv = CreateBogusNodeIfNeeded();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   // If the selection hasn't been set up yet, set it up collapsed to the end of
   // our editable content.
   if (!SelectionRef().RangeCount()) {
-    rv = TextEditorRef().CollapseSelectionToEnd(&SelectionRef());
+    rv = TextEditorRef().CollapseSelectionToEnd();
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
   }
 
   if (IsPlaintextEditor()) {
     // ensure trailing br node
     rv = CreateTrailingBRIfNeeded();
@@ -258,17 +258,17 @@ TextEditRules::AfterEdit(EditSubAction a
     Selection* selection = mTextEditor->GetSelection();
     if (NS_WARN_IF(!selection)) {
       return NS_ERROR_FAILURE;
     }
 
     AutoSafeEditorData setData(*this, *mTextEditor, *selection);
 
     nsresult rv =
-      TextEditorRef().HandleInlineSpellCheck(aEditSubAction, *selection,
+      TextEditorRef().HandleInlineSpellCheck(aEditSubAction,
                                              mCachedSelectionNode,
                                              mCachedSelectionOffset,
                                              nullptr, 0, nullptr, 0);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
     // no longer uses mCachedSelectionNode, so release it.
@@ -500,26 +500,26 @@ TextEditRules::CollapseSelectionToTraili
   if (!IsPlaintextEditor()) {
     return NS_OK;
   }
 
   // If there is no selection ranges, we should set to the end of the editor.
   // This is usually performed in TextEditRules::Init(), however, if the
   // editor is reframed, this may be called by AfterEdit().
   if (!SelectionRef().RangeCount()) {
-    TextEditorRef().CollapseSelectionToEnd(&SelectionRef());
+    TextEditorRef().CollapseSelectionToEnd();
     if (NS_WARN_IF(!CanHandleEditAction())) {
       return NS_ERROR_EDITOR_DESTROYED;
     }
   }
 
   // If we are at the end of the <textarea> element, we need to set the
   // selection to stick to the moz-<br> at the end of the <textarea>.
   EditorRawDOMPoint selectionStartPoint(
-                      EditorBase::GetStartPoint(&SelectionRef()));
+                      EditorBase::GetStartPoint(SelectionRef()));
   if (NS_WARN_IF(!selectionStartPoint.IsSet())) {
     return NS_ERROR_FAILURE;
   }
 
   // Nothing to do if we're not at the end of the text node.
   if (!selectionStartPoint.IsInTextNode() ||
       !selectionStartPoint.IsEndOfContainer()) {
     return NS_OK;
@@ -556,17 +556,17 @@ TextEditRules::CollapseSelectionToTraili
 }
 
 already_AddRefed<nsINode>
 TextEditRules::GetTextNodeAroundSelectionStartContainer()
 {
   MOZ_ASSERT(IsEditorDataAvailable());
 
   EditorRawDOMPoint selectionStartPoint(
-                      EditorBase::GetStartPoint(&SelectionRef()));
+                      EditorBase::GetStartPoint(SelectionRef()));
   if (NS_WARN_IF(!selectionStartPoint.IsSet())) {
     return nullptr;
   }
   if (selectionStartPoint.IsInTextNode()) {
     nsCOMPtr<nsINode> node = selectionStartPoint.GetContainer();
     return node.forget();
   }
   // This should be the root node, walk the tree looking for text nodes.
@@ -974,18 +974,17 @@ TextEditRules::WillSetText(bool* aCancel
 
   nsINode* curNode = rootElement->GetFirstChild();
   if (NS_WARN_IF(!EditorBase::IsTextNode(curNode))) {
     return NS_OK;
   }
 
   // Even if empty text, we don't remove text node and set empty text
   // for performance
-  rv = TextEditorRef().SetTextImpl(SelectionRef(), tString,
-                                   *curNode->GetAsText());
+  rv = TextEditorRef().SetTextImpl(tString, *curNode->GetAsText());
   if (NS_WARN_IF(!CanHandleEditAction())) {
     return NS_ERROR_EDITOR_DESTROYED;
   }
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   *aHandled = true;
@@ -1075,19 +1074,17 @@ TextEditRules::DeleteSelectionWithTransa
   // want to send a single selectionchange event to the document, so we
   // batch the selectionchange events, such that a single event fires after
   // the AutoHideSelectionChanges destructor has been run.
   SelectionBatcher selectionBatcher(&SelectionRef());
   AutoHideSelectionChanges hideSelection(&SelectionRef());
   nsAutoScriptBlocker scriptBlocker;
 
   if (IsPasswordEditor()) {
-    nsresult rv =
-      TextEditorRef().ExtendSelectionForDelete(&SelectionRef(),
-                                               &aCollapsedAction);
+    nsresult rv = TextEditorRef().ExtendSelectionForDelete(&aCollapsedAction);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
     // manage the password buffer
     uint32_t start, end;
     nsContentUtils::GetSelectionInTextControl(&SelectionRef(),
                                               TextEditorRef().GetRoot(),
@@ -1118,17 +1115,17 @@ TextEditRules::DeleteSelectionWithTransa
       // Otherwise nothing to do for this collapsed selection.
     }
     // Extended selection.
     else {
       mPasswordText.Cut(start, end-start);
     }
   } else {
     EditorRawDOMPoint selectionStartPoint(
-                        EditorBase::GetStartPoint(&SelectionRef()));
+                        EditorBase::GetStartPoint(SelectionRef()));
     if (NS_WARN_IF(!selectionStartPoint.IsSet())) {
       return NS_ERROR_FAILURE;
     }
 
     if (!SelectionRef().IsCollapsed()) {
       return NS_OK;
     }
 
@@ -1137,18 +1134,17 @@ TextEditRules::DeleteSelectionWithTransa
       CheckBidiLevelForDeletion(selectionStartPoint, aCollapsedAction, aCancel);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
     if (*aCancel) {
       return NS_OK;
     }
 
-    rv = TextEditorRef().ExtendSelectionForDelete(&SelectionRef(),
-                                                  &aCollapsedAction);
+    rv = TextEditorRef().ExtendSelectionForDelete(&aCollapsedAction);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
   }
 
   nsresult rv =
     TextEditorRef().DeleteSelectionWithTransaction(aCollapsedAction,
                                                    nsIEditor::eStrip);
@@ -1165,17 +1161,17 @@ TextEditRules::DeleteSelectionWithTransa
 }
 
 nsresult
 TextEditRules::DidDeleteSelection()
 {
   MOZ_ASSERT(IsEditorDataAvailable());
 
   EditorRawDOMPoint selectionStartPoint(
-                      EditorBase::GetStartPoint(&SelectionRef()));
+                      EditorBase::GetStartPoint(SelectionRef()));
   if (NS_WARN_IF(!selectionStartPoint.IsSet())) {
     return NS_ERROR_FAILURE;
   }
 
   // Delete empty text nodes at selection.
   if (selectionStartPoint.IsInTextNode() &&
       !selectionStartPoint.GetContainer()->Length()) {
     nsresult rv =
@@ -1812,18 +1808,17 @@ TextEditRules::CreateBRInternal(
 {
   MOZ_ASSERT(IsEditorDataAvailable());
 
   if (NS_WARN_IF(!aPointToInsert.IsSet())) {
     return CreateElementResult(NS_ERROR_FAILURE);
   }
 
   RefPtr<Element> brElement =
-    TextEditorRef().InsertBrElementWithTransaction(SelectionRef(),
-                                                   aPointToInsert);
+    TextEditorRef().InsertBrElementWithTransaction(aPointToInsert);
   if (NS_WARN_IF(!CanHandleEditAction())) {
     return CreateElementResult(NS_ERROR_EDITOR_DESTROYED);
   }
   if (NS_WARN_IF(!brElement)) {
     return CreateElementResult(NS_ERROR_FAILURE);
   }
 
   // give it special moz attr
--- a/editor/libeditor/TextEditor.cpp
+++ b/editor/libeditor/TextEditor.cpp
@@ -61,22 +61,20 @@ class nsIOutputStream;
 class nsISupports;
 
 namespace mozilla {
 
 using namespace dom;
 
 template already_AddRefed<Element>
 TextEditor::InsertBrElementWithTransaction(
-              Selection& aSelection,
               const EditorDOMPoint& aPointToInsert,
               EDirection aSelect);
 template already_AddRefed<Element>
 TextEditor::InsertBrElementWithTransaction(
-              Selection& aSelection,
               const EditorRawDOMPoint& aPointToInsert,
               EDirection aSelect);
 
 TextEditor::TextEditor()
   : mWrapColumn(0)
   , mMaxTextLength(-1)
   , mInitTriggerCounter(0)
   , mNewlineHandling(nsIPlaintextEditor::eNewlinesPasteToFirst)
@@ -458,20 +456,21 @@ TextEditor::OnInputParagraphSeparator()
     return rv;
   }
   return NS_OK;
 }
 
 template<typename PT, typename CT>
 already_AddRefed<Element>
 TextEditor::InsertBrElementWithTransaction(
-              Selection& aSelection,
               const EditorDOMPointBase<PT, CT>& aPointToInsert,
               EDirection aSelect /* = eNone */)
 {
+  MOZ_ASSERT(IsEditActionDataAvailable());
+
   if (NS_WARN_IF(!aPointToInsert.IsSet())) {
     return nullptr;
   }
 
   // We need to insert a <br> node.
   RefPtr<Element> newBRElement;
   if (aPointToInsert.IsInTextNode()) {
     EditorDOMPoint pointInContainer;
@@ -515,39 +514,39 @@ TextEditor::InsertBrElementWithTransacti
       return nullptr;
     }
   }
 
   switch (aSelect) {
     case eNone:
       break;
     case eNext: {
-      aSelection.SetInterlinePosition(true, IgnoreErrors());
+      SelectionRefPtr()->SetInterlinePosition(true, IgnoreErrors());
       // Collapse selection after the <br> node.
       EditorRawDOMPoint afterBRElement(newBRElement);
       if (afterBRElement.IsSet()) {
         DebugOnly<bool> advanced = afterBRElement.AdvanceOffset();
         NS_WARNING_ASSERTION(advanced,
           "Failed to advance offset after the <br> element");
         ErrorResult error;
-        aSelection.Collapse(afterBRElement, error);
+        SelectionRefPtr()->Collapse(afterBRElement, error);
         NS_WARNING_ASSERTION(!error.Failed(),
           "Failed to collapse selection after the <br> element");
       } else {
         NS_WARNING("The <br> node is not in the DOM tree?");
       }
       break;
     }
     case ePrevious: {
-      aSelection.SetInterlinePosition(true, IgnoreErrors());
+      SelectionRefPtr()->SetInterlinePosition(true, IgnoreErrors());
       // Collapse selection at the <br> node.
       EditorRawDOMPoint atBRElement(newBRElement);
       if (atBRElement.IsSet()) {
         ErrorResult error;
-        aSelection.Collapse(atBRElement, error);
+        SelectionRefPtr()->Collapse(atBRElement, error);
         NS_WARNING_ASSERTION(!error.Failed(),
           "Failed to collapse selection at the <br> element");
       } else {
         NS_WARNING("The <br> node is not in the DOM tree?");
       }
       break;
     }
     default:
@@ -555,20 +554,21 @@ TextEditor::InsertBrElementWithTransacti
                  "by itself");
       break;
   }
 
   return newBRElement.forget();
 }
 
 nsresult
-TextEditor::ExtendSelectionForDelete(Selection* aSelection,
-                                     nsIEditor::EDirection* aAction)
+TextEditor::ExtendSelectionForDelete(nsIEditor::EDirection* aAction)
 {
-  bool bCollapsed = aSelection->IsCollapsed();
+  MOZ_ASSERT(IsEditActionDataAvailable());
+
+  bool bCollapsed = SelectionRefPtr()->IsCollapsed();
 
   if (*aAction == eNextWord ||
       *aAction == ePreviousWord ||
       (*aAction == eNext && bCollapsed) ||
       (*aAction == ePrevious && bCollapsed) ||
       *aAction == eToBeginningOfLine ||
       *aAction == eToEndOfLine) {
     nsCOMPtr<nsISelectionController> selCont;
@@ -604,17 +604,17 @@ TextEditor::ExtendSelectionForDelete(Sel
       }
       case ePrevious: {
         // Only extend the selection where the selection is after a UTF-16
         // surrogate pair or a variation selector.
         // For other cases we don't want to do that, in order
         // to make sure that pressing backspace will only delete the last
         // typed character.
         EditorRawDOMPoint atStartOfSelection =
-          EditorBase::GetStartPoint(aSelection);
+          EditorBase::GetStartPoint(*SelectionRefPtr());
         if (NS_WARN_IF(!atStartOfSelection.IsSet())) {
           return NS_ERROR_FAILURE;
         }
 
         // node might be anonymous DIV, so we find better text node
         EditorRawDOMPoint insertionPoint =
           FindBetterInsertionPoint(atStartOfSelection);
 
@@ -842,17 +842,17 @@ TextEditor::DeleteSelectionWithTransacti
       AutoActionListenerArray listeners(mActionListeners);
       for (auto& listener : listeners) {
         listener->WillDeleteText(deleteCharData, deleteCharOffset, 1);
       }
     }
   }
 
   // Delete the specified amount
-  nsresult rv = DoTransaction(deleteSelectionTransaction);
+  nsresult rv = DoTransactionInternal(deleteSelectionTransaction);
 
   if (mRules && mRules->AsHTMLEditRules() && deleteCharData) {
     MOZ_ASSERT(deleteNode);
     RefPtr<HTMLEditRules> htmlEditRules = mRules->AsHTMLEditRules();
     htmlEditRules->DidDeleteText(*selection, *deleteNode, deleteCharOffset, 1);
   }
 
   if (mTextServicesDocument && NS_SUCCEEDED(rv) &&
@@ -1167,17 +1167,17 @@ TextEditor::InsertParagraphSeparatorAsAc
     if (NS_SUCCEEDED(rv)) {
       // set the selection to the correct location
       MOZ_ASSERT(!pointAfterInsertedLineBreak.GetChild(),
         "After inserting text into a text node, pointAfterInsertedLineBreak."
         "GetChild() should be nullptr");
       rv = selection->Collapse(pointAfterInsertedLineBreak);
       if (NS_SUCCEEDED(rv)) {
         // see if we're at the end of the editor range
-        EditorRawDOMPoint endPoint = GetEndPoint(selection);
+        EditorRawDOMPoint endPoint = EditorBase::GetEndPoint(*selection);
         if (endPoint == pointAfterInsertedLineBreak) {
           // SetInterlinePosition(true) means we want the caret to stick to the
           // content on the "right".  We want the caret to stick to whatever is
           // past the break.  This is because the break is on the same line we
           // were on, but the next content will be on the following line.
           selection->SetInterlinePosition(true, IgnoreErrors());
         }
       }
@@ -1308,17 +1308,17 @@ TextEditor::SetTextAsSubAction(const nsA
       // if it's empty, don't select entire doc - that would select
       // the bogus node
       Element* rootElement = GetRoot();
       if (NS_WARN_IF(!rootElement)) {
         return NS_ERROR_FAILURE;
       }
       rv = selection->Collapse(rootElement, 0);
     } else {
-      rv = EditorBase::SelectEntireDocument(selection);
+      rv = EditorBase::SelectEntireDocument();
     }
     if (NS_SUCCEEDED(rv)) {
       rv = ReplaceSelectionAsSubAction(aString);
       NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
         "Failed to replace selection with new string");
     }
   }
   // post-process
@@ -2234,56 +2234,61 @@ TextEditor::OnEndHandlingTopLevelEditSub
   NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
     "TextEditRules::AfterEdit() failed to handle something");
   EditorBase::OnEndHandlingTopLevelEditSubAction();
   MOZ_ASSERT(!mTopLevelEditSubAction);
   MOZ_ASSERT(mDirection == eNone);
 }
 
 nsresult
-TextEditor::SelectEntireDocument(Selection* aSelection)
+TextEditor::SelectEntireDocument()
 {
-  if (!aSelection || !mRules) {
+  MOZ_ASSERT(IsEditActionDataAvailable());
+
+  if (!mRules) {
     return NS_ERROR_NULL_POINTER;
   }
 
   // Protect the edit rules object from dying
   RefPtr<TextEditRules> rules(mRules);
 
   // is doc empty?
   if (rules->DocumentIsEmpty()) {
     // get root node
     Element* rootElement = GetRoot();
     if (NS_WARN_IF(!rootElement)) {
       return NS_ERROR_FAILURE;
     }
 
     // if it's empty don't select entire doc - that would select the bogus node
-    return aSelection->Collapse(rootElement, 0);
+    return SelectionRefPtr()->Collapse(rootElement, 0);
   }
 
-  SelectionBatcher selectionBatcher(aSelection);
-  nsresult rv = EditorBase::SelectEntireDocument(aSelection);
-  NS_ENSURE_SUCCESS(rv, rv);
+  SelectionBatcher selectionBatcher(SelectionRefPtr());
+  nsresult rv = EditorBase::SelectEntireDocument();
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
 
   // Don't select the trailing BR node if we have one
   nsCOMPtr<nsIContent> childNode;
-  rv = GetEndChildNode(aSelection, getter_AddRefs(childNode));
+  rv = EditorBase::GetEndChildNode(*SelectionRefPtr(),
+                                   getter_AddRefs(childNode));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   if (childNode) {
     childNode = childNode->GetPreviousSibling();
   }
 
   if (childNode && TextEditUtils::IsMozBR(childNode)) {
     int32_t parentOffset;
     nsINode* parentNode = GetNodeLocation(childNode, &parentOffset);
 
-    return aSelection->Extend(parentNode, parentOffset);
+    return SelectionRefPtr()->Extend(parentNode, parentOffset);
   }
 
   return NS_OK;
 }
 
 EventTarget*
 TextEditor::GetDOMEventTarget()
 {
--- a/editor/libeditor/TextEditor.h
+++ b/editor/libeditor/TextEditor.h
@@ -309,41 +309,38 @@ protected: // May be called by friends.
    */
   nsresult ReplaceSelectionAsSubAction(const nsAString& aString);
 
   /**
    * InsertBrElementWithTransaction() 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.
    *
-   * @param aSelection          The selection of this editor.
    * @param aPointToInsert      The DOM point where should be <br> node inserted
    *                            before.
    * @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>
   InsertBrElementWithTransaction(
-    Selection& aSelection,
     const EditorDOMPointBase<PT, CT>& aPointToInsert,
     EDirection aSelect = eNone);
 
   /**
    * Extends the selection for given deletion operation
    * If done, also update aAction to what's actually left to do after the
    * extension.
    */
-  nsresult ExtendSelectionForDelete(Selection* aSelection,
-                                    nsIEditor::EDirection* aAction);
+  nsresult ExtendSelectionForDelete(nsIEditor::EDirection* aAction);
 
   /**
    * HideLastPasswordInput() is called by timer callback of TextEditRules.
    * This should be called only by TextEditRules::Notify().
    * When this is called, the TextEditRules wants to call its
    * HideLastPasswordInput() with AutoEditActionDataSetter instance.
    */
   MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult HideLastPasswordInput();
@@ -364,17 +361,17 @@ protected: // Called by helper classes.
 protected: // Shouldn't be used by friend classes
   virtual ~TextEditor();
 
   int32_t WrapWidth() const { return mWrapColumn; }
 
   /**
    * Make the given selection span the entire document.
    */
-  virtual nsresult SelectEntireDocument(Selection* aSelection) override;
+  virtual nsresult SelectEntireDocument() override;
 
   /**
    * OnInputText() is called when user inputs text with keyboard or something.
    *
    * @param aStringToInsert     The string to insert.
    */
   nsresult OnInputText(const nsAString& aStringToInsert);
 
--- a/editor/libeditor/TypeInState.cpp
+++ b/editor/libeditor/TypeInState.cpp
@@ -68,17 +68,17 @@ TypeInState::UpdateSelState(Selection* a
   if (NS_WARN_IF(!aSelection)) {
     return NS_ERROR_INVALID_ARG;
   }
 
   if (!aSelection->IsCollapsed()) {
     return NS_OK;
   }
 
-  mLastSelectionPoint = EditorBase::GetStartPoint(aSelection);
+  mLastSelectionPoint = EditorBase::GetStartPoint(*aSelection);
   if (!mLastSelectionPoint.IsSet()) {
     return NS_ERROR_FAILURE;
   }
   // We need to store only offset because referring child may be removed by
   // we'll check the point later.
   AutoEditorDOMPointChildInvalidator saveOnlyOffset(mLastSelectionPoint);
   return NS_OK;
 }
@@ -93,17 +93,17 @@ TypeInState::OnSelectionChange(Selection
   // XXX: The following code attempts to work around the bogus notifications,
   // XXX: and should probably be removed once bug 140303 is fixed.
   // XXX:
   // XXX: This code temporarily fixes the problem where clicking the mouse in
   // XXX: the same location clears the type-in-state.
 
   if (aSelection.IsCollapsed() && aSelection.RangeCount()) {
     EditorRawDOMPoint selectionStartPoint(
-                        EditorBase::GetStartPoint(&aSelection));
+                        EditorBase::GetStartPoint(aSelection));
     if (NS_WARN_IF(!selectionStartPoint.IsSet())) {
       return;
     }
 
     if (mLastSelectionPoint == selectionStartPoint) {
       // We got a bogus selection changed notification!
       return;
     }
--- a/editor/libeditor/WSRunObject.cpp
+++ b/editor/libeditor/WSRunObject.cpp
@@ -260,18 +260,17 @@ WSRunObject::InsertBreak(Selection& aSel
         ReplacePreviousNBSPIfUnncessary(beforeRun, pointToInsert);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return nullptr;
       }
     }
   }
 
   RefPtr<Element> newBrElement =
-    mHTMLEditor->InsertBrElementWithTransaction(aSelection, pointToInsert,
-                                                aSelect);
+    mHTMLEditor->InsertBrElementWithTransaction(pointToInsert, aSelect);
   if (NS_WARN_IF(!newBrElement)) {
     return nullptr;
   }
   return newBrElement.forget();
 }
 
 template<typename PT, typename CT>
 nsresult
@@ -1893,18 +1892,17 @@ WSRunObject::CheckTrailingNBSPOfRun(WSFr
         // space, and then "foo  " jumps down to the next line.  Ugh.  The best
         // way I can find out of this is to throw in a harmless <br> here,
         // which allows us to do: |<body>foo.&nbsp <br></body>|, which doesn't
         // cause foo to jump lines, doesn't cause spaces to show up at the
         // beginning of soft wrapped lines, and lets the user see 2 spaces when
         // they type 2 spaces.
 
         RefPtr<Element> brElement =
-          htmlEditor->InsertBrElementWithTransaction(*selection,
-                                                     aRun->EndPoint());
+          htmlEditor->InsertBrElementWithTransaction(aRun->EndPoint());
         if (NS_WARN_IF(!brElement)) {
           return NS_ERROR_FAILURE;
         }
 
         // Refresh thePoint, prevPoint
         thePoint = GetPreviousCharPoint(aRun->EndPoint());
         prevPoint = GetPreviousCharPoint(thePoint);
         rightCheck = true;
--- a/editor/nsIHTMLEditor.idl
+++ b/editor/nsIHTMLEditor.idl
@@ -392,21 +392,18 @@ interface nsIHTMLEditor : nsISupports
   attribute boolean isCSSEnabled;
 
   /**
    * checkSelectionStateForAnonymousButtons() may refresh editing UI such as
    * resizers, inline-table-editing UI, absolute positioning UI for current
    * Selection and focus state.  When this method shows or hides UI, the
    * editor (and/or its document/window) could be broken by mutation observers.
    * FYI: Current user in script is only BlueGriffon.
-   *
-   * @param aSelection  Selection instance for the normal selection of the
-   *                    document.
    */
-  void checkSelectionStateForAnonymousButtons(in Selection aSelection);
+  void checkSelectionStateForAnonymousButtons();
 
   boolean isAnonymousElement(in Element aElement);
 
   /**
    * A boolean indicating if a return key pressed in a paragraph creates
    * another paragraph or just inserts a <br> at the caret
    *
    * @return    true if CR in a paragraph creates a new paragraph