Merge mozilla-inbound to mozilla-central. a=merge
authorCosmin Sabou <csabou@mozilla.com>
Wed, 03 Jul 2019 19:20:05 +0300
changeset 540788 5f0961efaa1c01e5b4bc449ee5d58260393291ef
parent 540739 02fa74d45af5412d2d6cf4581fd9f0c437c6c0e0 (current diff)
parent 540787 c5ee16e71ed41d54344797dddbc7dfc49de2b1f6 (diff)
child 540789 7eff60789f10b2766615d486b8e9c1568b7efcbd
child 540902 ffe069e332c2da5054bd54fdd14af31a2a89b9ec
push id11529
push userarchaeopteryx@coole-files.de
push dateThu, 04 Jul 2019 15:22:33 +0000
treeherdermozilla-beta@ebb510a784b8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone69.0a1
first release with
nightly linux32
5f0961efaa1c / 69.0a1 / 20190703162038 / files
nightly linux64
5f0961efaa1c / 69.0a1 / 20190703162038 / files
nightly mac
5f0961efaa1c / 69.0a1 / 20190703162038 / files
nightly win32
5f0961efaa1c / 69.0a1 / 20190703162038 / files
nightly win64
5f0961efaa1c / 69.0a1 / 20190703162038 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-inbound to mozilla-central. a=merge
dom/base/nsFocusManager.cpp
--- a/accessible/base/nsCoreUtils.cpp
+++ b/accessible/base/nsCoreUtils.cpp
@@ -229,17 +229,17 @@ nsresult nsCoreUtils::ScrollSubstringTo(
   nsCOMPtr<nsISelectionController> selCon;
   aFrame->GetSelectionController(presContext, getter_AddRefs(selCon));
   NS_ENSURE_TRUE(selCon, NS_ERROR_FAILURE);
 
   RefPtr<dom::Selection> selection =
       selCon->GetSelection(nsISelectionController::SELECTION_ACCESSIBILITY);
 
   selection->RemoveAllRanges(IgnoreErrors());
-  selection->AddRange(*aRange, IgnoreErrors());
+  selection->AddRangeAndSelectFramesAndNotifyListeners(*aRange, IgnoreErrors());
 
   selection->ScrollIntoView(nsISelectionController::SELECTION_ANCHOR_REGION,
                             aVertical, aHorizontal,
                             Selection::SCROLL_SYNCHRONOUS);
 
   selection->CollapseToStart(IgnoreErrors());
 
   return NS_OK;
--- a/accessible/generic/HyperTextAccessible.cpp
+++ b/accessible/generic/HyperTextAccessible.cpp
@@ -1267,17 +1267,18 @@ nsresult HyperTextAccessible::SetSelecti
   // some input controls
   if (isFocusable) TakeFocus();
 
   dom::Selection* domSel = DOMSelection();
   NS_ENSURE_STATE(domSel);
 
   // Set up the selection.
   for (int32_t idx = domSel->RangeCount() - 1; idx > 0; idx--)
-    domSel->RemoveRange(*domSel->GetRangeAt(idx), IgnoreErrors());
+    domSel->RemoveRangeAndUnselectFramesAndNotifyListeners(
+        *domSel->GetRangeAt(idx), IgnoreErrors());
   SetSelectionBoundsAt(0, aStartPos, aEndPos);
 
   // Make sure it is visible
   domSel->ScrollIntoView(nsISelectionController::SELECTION_FOCUS_REGION,
                          ScrollAxis(), ScrollAxis(),
                          dom::Selection::SCROLL_FOR_CARET_MOVE |
                              dom::Selection::SCROLL_OVERFLOW_HIDDEN);
 
@@ -1566,21 +1567,22 @@ bool HyperTextAccessible::SetSelectionBo
 
   if (!OffsetsToDOMRange(std::min(startOffset, endOffset),
                          std::max(startOffset, endOffset), range))
     return false;
 
   // If this is not a new range, notify selection listeners that the existing
   // selection range has changed. Otherwise, just add the new range.
   if (aSelectionNum != static_cast<int32_t>(rangeCount)) {
-    domSel->RemoveRange(*range, IgnoreErrors());
+    domSel->RemoveRangeAndUnselectFramesAndNotifyListeners(*range,
+                                                           IgnoreErrors());
   }
 
   IgnoredErrorResult err;
-  domSel->AddRange(*range, err);
+  domSel->AddRangeAndSelectFramesAndNotifyListeners(*range, err);
 
   if (!err.Failed()) {
     // Changing the direction of the selection assures that the caret
     // will be at the logical end of the selection.
     domSel->SetDirection(startOffset < endOffset ? eDirNext : eDirPrevious);
     return true;
   }
 
@@ -1590,17 +1592,18 @@ bool HyperTextAccessible::SetSelectionBo
 bool HyperTextAccessible::RemoveFromSelection(int32_t aSelectionNum) {
   dom::Selection* domSel = DOMSelection();
   if (!domSel) return false;
 
   if (aSelectionNum < 0 ||
       aSelectionNum >= static_cast<int32_t>(domSel->RangeCount()))
     return false;
 
-  domSel->RemoveRange(*domSel->GetRangeAt(aSelectionNum), IgnoreErrors());
+  domSel->RemoveRangeAndUnselectFramesAndNotifyListeners(
+      *domSel->GetRangeAt(aSelectionNum), IgnoreErrors());
   return true;
 }
 
 void HyperTextAccessible::ScrollSubstringTo(int32_t aStartOffset,
                                             int32_t aEndOffset,
                                             uint32_t aScrollType) {
   RefPtr<nsRange> range = new nsRange(mContent);
   if (OffsetsToDOMRange(aStartOffset, aEndOffset, range))
--- a/dom/base/Selection.cpp
+++ b/dom/base/Selection.cpp
@@ -933,17 +933,17 @@ nsresult Selection::AddItem(nsRange* aIt
   if (!aItem->IsPositioned()) return NS_ERROR_UNEXPECTED;
 
   NS_ASSERTION(aOutIndex, "aOutIndex can't be null");
 
   if (mUserInitiated) {
     AutoTArray<RefPtr<nsRange>, 4> rangesToAdd;
     *aOutIndex = int32_t(mRanges.Length()) - 1;
 
-    Document* doc = GetParentObject();
+    Document* doc = GetDocument();
     bool selectEventsEnabled =
         StaticPrefs::dom_select_events_enabled() ||
         (doc && nsContentUtils::IsSystemPrincipal(doc->NodePrincipal()));
 
     if (!aNoStartSelect && mSelectionType == SelectionType::eNormal &&
         selectEventsEnabled && IsCollapsed() &&
         !IsBlockingSelectionChangeEvents()) {
       // First, we generate the ranges to add with a scratch range, which is a
@@ -979,17 +979,17 @@ nsresult Selection::AddItem(nsRange* aIt
             // This is a selection under a text control, so don't dispatch the
             // event.
             dispatchEvent = false;
           }
         }
 
         if (dispatchEvent) {
           nsContentUtils::DispatchTrustedEvent(
-              GetParentObject(), target, NS_LITERAL_STRING("selectstart"),
+              GetDocument(), target, NS_LITERAL_STRING("selectstart"),
               CanBubble::eYes, Cancelable::eYes, &defaultAction);
 
           if (!defaultAction) {
             return NS_OK;
           }
 
           // As we just dispatched an event to the DOM, something could have
           // changed under our feet. Re-generate the rangesToAdd array, and
@@ -1973,26 +1973,28 @@ nsresult Selection::RemoveAllRangesTempo
     mCachedRange->ResetTemporarily();
   }
   return result.StealNSResult();
 }
 
 void Selection::AddRangeJS(nsRange& aRange, ErrorResult& aRv) {
   AutoRestore<bool> calledFromJSRestorer(mCalledByJS);
   mCalledByJS = true;
-  AddRange(aRange, aRv);
+  AddRangeAndSelectFramesAndNotifyListeners(aRange, aRv);
 }
 
-void Selection::AddRange(nsRange& aRange, ErrorResult& aRv) {
-  RefPtr<Document> document(GetParentObject());
-  return AddRangeInternal(aRange, document, aRv);
+void Selection::AddRangeAndSelectFramesAndNotifyListeners(nsRange& aRange,
+                                                          ErrorResult& aRv) {
+  RefPtr<Document> document(GetDocument());
+  return AddRangeAndSelectFramesAndNotifyListeners(aRange, document, aRv);
 }
 
-void Selection::AddRangeInternal(nsRange& aRange, Document* aDocument,
-                                 ErrorResult& aRv) {
+void Selection::AddRangeAndSelectFramesAndNotifyListeners(nsRange& aRange,
+                                                          Document* aDocument,
+                                                          ErrorResult& aRv) {
   // If the given range is part of another Selection, we need to clone the
   // range first.
   RefPtr<nsRange> range;
   if (aRange.IsInSelection() && aRange.GetSelection() != this) {
     // Because of performance reason, when there is a cached range, let's use
     // it.  Otherwise, clone the range.
     if (mCachedRange) {
       range = std::move(mCachedRange);
@@ -2062,29 +2064,30 @@ void Selection::AddRangeInternal(nsRange
   // XXX Why doesn't this call Selection::NotifySelectionListener() directly?
   RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
   result = frameSelection->NotifySelectionListeners(GetType());
   if (NS_FAILED(result)) {
     aRv.Throw(result);
   }
 }
 
-// Selection::RemoveRange
+// Selection::RemoveRangeAndUnselectFramesAndNotifyListeners
 //
 //    Removes the given range from the selection. The tricky part is updating
 //    the flags on the frames that indicate whether they have a selection or
 //    not. There could be several selection ranges on the frame, and clearing
 //    the bit would cause the selection to not be drawn, even when there is
 //    another range on the frame (bug 346185).
 //
 //    We therefore find any ranges that intersect the same nodes as the range
 //    being removed, and cause them to set the selected bits back on their
 //    selected frames after we've cleared the bit from ours.
 
-void Selection::RemoveRange(nsRange& aRange, ErrorResult& aRv) {
+void Selection::RemoveRangeAndUnselectFramesAndNotifyListeners(
+    nsRange& aRange, ErrorResult& aRv) {
   nsresult rv = RemoveItem(&aRange);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return;
   }
 
   nsINode* beginNode = aRange.GetStartContainer();
   nsINode* endNode = aRange.GetEndContainer();
@@ -3482,17 +3485,17 @@ void Selection::SetStartAndEndInternal(I
     }
   }
 
   RemoveAllRanges(aRv);
   if (aRv.Failed()) {
     return;
   }
 
-  AddRange(*newRange, aRv);
+  AddRangeAndSelectFramesAndNotifyListeners(*newRange, aRv);
   if (aRv.Failed()) {
     return;
   }
 
   // Adding a range may set 2 or more ranges if there are non-selectable
   // contents only when this change is caused by a user operation.  Therefore,
   // we need to select frames with the result in such case.
   if (mUserInitiated) {
@@ -3667,11 +3670,11 @@ JSObject* Selection::WrapObject(JSContex
 // AutoHideSelectionChanges
 AutoHideSelectionChanges::AutoHideSelectionChanges(
     const nsFrameSelection* aFrame)
     : AutoHideSelectionChanges(
           aFrame ? aFrame->GetSelection(SelectionType::eNormal) : nullptr) {}
 
 bool Selection::HasSameRootOrSameComposedDoc(const nsINode& aNode) {
   nsINode* root = aNode.SubtreeRoot();
-  Document* doc = GetParentObject();
+  Document* doc = GetDocument();
   return doc == root || (root && doc == root->GetComposedDoc());
 }
--- a/dom/base/Selection.h
+++ b/dom/base/Selection.h
@@ -112,17 +112,20 @@ class Selection final : public nsSupport
    * selectionchange event at every selection change.
    */
   void EnableSelectionChangeEvent() {
     if (!mSelectionChangeEventDispatcher) {
       mSelectionChangeEventDispatcher = new SelectionChangeEventDispatcher();
     }
   }
 
+  // Required for WebIDL bindings, see
+  // https://developer.mozilla.org/en-US/docs/Mozilla/WebIDL_bindings#Adding_WebIDL_bindings_to_a_class.
   Document* GetParentObject() const;
+
   DocGroup* GetDocGroup() const;
 
   // utility methods for scrolling the selection into view
   nsPresContext* GetPresContext() const;
   PresShell* GetPresShell() const;
   nsFrameSelection* GetFrameSelection() const { return mFrameSelection; }
   // Returns a rect containing the selection region, and frame that that
   // position is relative to. For SELECTION_ANCHOR_REGION or
@@ -287,17 +290,18 @@ class Selection final : public nsSupport
   uint32_t RangeCount() const { return mRanges.Length(); }
 
   void GetType(nsAString& aOutType) const;
 
   nsRange* GetRangeAt(uint32_t aIndex, mozilla::ErrorResult& aRv);
   void AddRangeJS(nsRange& aRange, mozilla::ErrorResult& aRv);
 
   MOZ_CAN_RUN_SCRIPT_BOUNDARY
-  void RemoveRange(nsRange& aRange, mozilla::ErrorResult& aRv);
+  void RemoveRangeAndUnselectFramesAndNotifyListeners(
+      nsRange& aRange, mozilla::ErrorResult& aRv);
 
   MOZ_CAN_RUN_SCRIPT_BOUNDARY void RemoveAllRanges(mozilla::ErrorResult& aRv);
 
   /**
    * RemoveAllRangesTemporarily() is useful if the caller will add one or more
    * ranges later.  This tries to cache a removing range if it's possible.
    * If a range is not referred by anything else this selection, the range
    * can be reused later.  Otherwise, this works as same as RemoveAllRanges().
@@ -433,17 +437,18 @@ class Selection final : public nsSupport
    * @param aContainer The node where the selection will be extended to
    * @param aOffset    Where in aContainer to place the offset of the new
    *                   selection end.
    */
   MOZ_CAN_RUN_SCRIPT_BOUNDARY
   void Extend(nsINode& aContainer, uint32_t aOffset, ErrorResult& aRv);
 
   MOZ_CAN_RUN_SCRIPT_BOUNDARY
-  void AddRange(nsRange& aRange, mozilla::ErrorResult& aRv);
+  void AddRangeAndSelectFramesAndNotifyListeners(nsRange& aRange,
+                                                 mozilla::ErrorResult& aRv);
 
   /**
    * Adds all children of the specified node to the selection.
    * @param aNode the parent of the children to be added to the selection.
    */
   MOZ_CAN_RUN_SCRIPT_BOUNDARY
   void SelectAllChildren(nsINode& aNode, mozilla::ErrorResult& aRv);
 
@@ -592,17 +597,19 @@ class Selection final : public nsSupport
 
   bool HasSameRootOrSameComposedDoc(const nsINode& aNode);
 
   // XXX Please don't add additional uses of this method, it's only for
   // XXX supporting broken code (bug 1245883) in the following classes:
   friend class ::nsCopySupport;
   friend class ::nsHTMLCopyEncoder;
   MOZ_CAN_RUN_SCRIPT
-  void AddRangeInternal(nsRange& aRange, Document* aDocument, ErrorResult&);
+  void AddRangeAndSelectFramesAndNotifyListeners(nsRange& aRange,
+                                                 Document* aDocument,
+                                                 ErrorResult&);
 
   // This is helper method for GetPrimaryFrameForFocusNode.
   // If aVisual is true, this returns caret frame.
   // If false, this returns primary frame.
   nsresult GetPrimaryOrCaretFrameForNodeOffset(nsIContent* aContent,
                                                uint32_t aOffset,
                                                nsIFrame** aReturnFrame,
                                                int32_t* aOffsetUsed,
--- a/dom/base/nsCopySupport.cpp
+++ b/dom/base/nsCopySupport.cpp
@@ -420,17 +420,17 @@ nsresult nsCopySupport::GetTransferableF
   // XXX bug 1245883
   RefPtr<Selection> selection = new Selection();
   RefPtr<nsRange> range = new nsRange(aNode);
   ErrorResult result;
   range->SelectNode(*aNode, result);
   if (NS_WARN_IF(result.Failed())) {
     return result.StealNSResult();
   }
-  selection->AddRangeInternal(*range, aDoc, result);
+  selection->AddRangeAndSelectFramesAndNotifyListeners(*range, aDoc, result);
   if (NS_WARN_IF(result.Failed())) {
     return result.StealNSResult();
   }
   // It's not the primary selection - so don't skip invisible content.
   uint32_t additionalFlags = 0;
   return EncodeDocumentWithContextAndCreateTransferable(
       *aDoc, selection, additionalFlags, aTransferable);
 }
--- a/dom/base/nsDocumentEncoder.cpp
+++ b/dom/base/nsDocumentEncoder.cpp
@@ -1371,17 +1371,18 @@ nsHTMLCopyEncoder::SetSelection(Selectio
     // adjust range to include any ancestors who's children are entirely
     // selected
     nsresult rv = PromoteRange(myRange);
     NS_ENSURE_SUCCESS(rv, rv);
 
     ErrorResult result;
     RefPtr<Selection> selection(mEncodingScope.mSelection);
     RefPtr<Document> document(mDocument);
-    selection->AddRangeInternal(*myRange, document, result);
+    selection->AddRangeAndSelectFramesAndNotifyListeners(*myRange, document,
+                                                         result);
     rv = result.StealNSResult();
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -2308,17 +2308,18 @@ void nsFocusManager::MoveCaretToFocus(Pr
         if (!aContent->GetFirstChild() ||
             aContent->IsNodeOfType(nsINode::eHTML_FORM_CONTROL)) {
           // If current focus node is a leaf, set range to before the
           // node by using the parent as a container.
           // This prevents it from appearing as selected.
           newRange->SetStartBefore(*aContent, IgnoreErrors());
           newRange->SetEndBefore(*aContent, IgnoreErrors());
         }
-        domSelection->AddRange(*newRange, IgnoreErrors());
+        domSelection->AddRangeAndSelectFramesAndNotifyListeners(*newRange,
+                                                                IgnoreErrors());
         domSelection->CollapseToStart(IgnoreErrors());
       }
     }
   }
 }
 
 nsresult nsFocusManager::SetCaretVisible(PresShell* aPresShell, bool aVisible,
                                          nsIContent* aContent) {
--- a/dom/base/nsRange.cpp
+++ b/dom/base/nsRange.cpp
@@ -969,17 +969,18 @@ void nsRange::SetSelection(mozilla::dom:
   // aSelection will be null when we are removing from a selection
   // and a range can't be in more than one selection at a time,
   // thus mSelection must be null too.
   MOZ_ASSERT(!aSelection || !mSelection);
 
   // Extra step in case our parent failed to ensure the above
   // invariant.
   if (aSelection && mSelection) {
-    mSelection->RemoveRange(*this, IgnoreErrors());
+    mSelection->RemoveRangeAndUnselectFramesAndNotifyListeners(*this,
+                                                               IgnoreErrors());
   }
 
   mSelection = aSelection;
   if (mSelection) {
     nsINode* commonAncestor = GetCommonAncestor();
     NS_ASSERTION(commonAncestor, "unexpected disconnected nodes");
     RegisterCommonAncestor(commonAncestor);
   } else if (mRegisteredCommonAncestor) {
--- a/dom/html/nsTextEditorState.cpp
+++ b/dom/html/nsTextEditorState.cpp
@@ -94,18 +94,20 @@ class RestoreSelectionState : public Run
     if (!mTextEditorState) {
       return NS_OK;
     }
 
     AutoHideSelectionChanges hideSelectionChanges(
         mFrame->GetConstFrameSelection());
 
     if (mFrame) {
-      // SetSelectionRange leads to Selection::AddRange which flushes Layout -
-      // need to block script to avoid nested PrepareEditor calls (bug 642800).
+      // SetSelectionRange leads to
+      // Selection::AddRangeAndSelectFramesAndNotifyListeners which flushes
+      // Layout - need to block script to avoid nested PrepareEditor calls (bug
+      // 642800).
       nsAutoScriptBlocker scriptBlocker;
       nsTextEditorState::SelectionProperties& properties =
           mTextEditorState->GetSelectionProperties();
       if (properties.IsDirty()) {
         mFrame->SetSelectionRange(properties.GetStart(), properties.GetEnd(),
                                   properties.GetDirection());
       }
       if (!mTextEditorState->mSelectionRestoreEagerInit) {
--- a/dom/webidl/Selection.webidl
+++ b/dom/webidl/Selection.webidl
@@ -30,17 +30,17 @@ interface Selection {
   /**
    * Adds a range to the current selection.
    */
   [Throws, BinaryName="addRangeJS"]
   void      addRange(Range range);
   /**
    * Removes a range from the current selection.
    */
-  [Throws]
+  [Throws, BinaryName="removeRangeAndUnselectFramesAndNotifyListeners"]
   void      removeRange(Range range);
   /**
    * Removes all ranges from the current selection.
    */
   [Throws]
   void      removeAllRanges();
   [Throws, BinaryName="RemoveAllRanges"]
   void      empty();
--- a/editor/libeditor/CompositionTransaction.cpp
+++ b/editor/libeditor/CompositionTransaction.cpp
@@ -292,17 +292,18 @@ nsresult CompositionTransaction::SetIMES
     RefPtr<Selection> selectionOfIME =
         selCon->GetSelection(ToRawSelectionType(textRange.mRangeType));
     if (!selectionOfIME) {
       NS_WARNING("Failed to get IME selection");
       break;
     }
 
     IgnoredErrorResult err;
-    selectionOfIME->AddRange(*clauseRange, err);
+    selectionOfIME->AddRangeAndSelectFramesAndNotifyListeners(*clauseRange,
+                                                              err);
     if (err.Failed()) {
       NS_WARNING("Failed to add selection range for a clause of composition");
       break;
     }
 
     // Set the style of the clause.
     rv = selectionOfIME->SetTextRangeStyle(clauseRange, textRange.mRangeStyle);
     if (NS_FAILED(rv)) {
--- a/editor/libeditor/EditorBase.cpp
+++ b/editor/libeditor/EditorBase.cpp
@@ -2994,17 +2994,18 @@ void EditorBase::DoSplitNode(const Edito
     }
 
     RefPtr<nsRange> newRange =
         nsRange::Create(range.mStartContainer, range.mStartOffset,
                         range.mEndContainer, range.mEndOffset, aError);
     if (NS_WARN_IF(aError.Failed())) {
       return;
     }
-    range.mSelection->AddRange(*newRange, aError);
+    range.mSelection->AddRangeAndSelectFramesAndNotifyListeners(*newRange,
+                                                                aError);
     if (NS_WARN_IF(aError.Failed())) {
       return;
     }
   }
 
   // We don't need to set selection here because the caller should do that
   // in any case.
 
@@ -3160,17 +3161,17 @@ nsresult EditorBase::DoJoinNodes(nsINode
     RefPtr<nsRange> newRange =
         nsRange::Create(range.mStartContainer, range.mStartOffset,
                         range.mEndContainer, range.mEndOffset, IgnoreErrors());
     if (NS_WARN_IF(!newRange)) {
       return NS_ERROR_FAILURE;
     }
 
     ErrorResult err;
-    range.mSelection->AddRange(*newRange, err);
+    range.mSelection->AddRangeAndSelectFramesAndNotifyListeners(*newRange, err);
     if (NS_WARN_IF(err.Failed())) {
       return err.StealNSResult();
     }
   }
 
   if (allowedTransactionsToChangeSelection) {
     // Editor wants us to set selection at join point.
     DebugOnly<nsresult> rv = SelectionRefPtr()->Collapse(
@@ -4214,17 +4215,17 @@ nsresult EditorBase::AppendNodeToSelecti
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   if (NS_WARN_IF(!range)) {
     return NS_ERROR_FAILURE;
   }
 
   ErrorResult err;
-  SelectionRefPtr()->AddRange(*range, err);
+  SelectionRefPtr()->AddRangeAndSelectFramesAndNotifyListeners(*range, err);
   NS_WARNING_ASSERTION(!err.Failed(), "Failed to add range to Selection");
   return err.StealNSResult();
 }
 
 nsresult EditorBase::ClearSelection() {
   MOZ_ASSERT(IsEditActionDataAvailable());
 
   ErrorResult rv;
--- a/editor/libeditor/HTMLTableEditor.cpp
+++ b/editor/libeditor/HTMLTableEditor.cpp
@@ -799,17 +799,17 @@ nsresult HTMLEditor::DeleteTableElementA
     }
 
     RefPtr<nsRange> range = new nsRange(&aTableElement);
     ErrorResult error;
     range->SelectNode(aTableElement, error);
     if (NS_WARN_IF(error.Failed())) {
       return error.StealNSResult();
     }
-    SelectionRefPtr()->AddRange(*range, error);
+    SelectionRefPtr()->AddRangeAndSelectFramesAndNotifyListeners(*range, error);
     if (NS_WARN_IF(error.Failed())) {
       return error.StealNSResult();
     }
 
 #ifdef DEBUG
     range = SelectionRefPtr()->GetRangeAt(0);
     MOZ_ASSERT(range);
     MOZ_ASSERT(range->GetStartContainer() == aTableElement.GetParent());
@@ -1788,17 +1788,18 @@ HTMLEditor::SelectBlockOfCells(Element* 
   while (cell) {
     CellIndexes currentCellIndexes(*cell, error);
     if (NS_WARN_IF(error.Failed())) {
       return EditorBase::ToGenericNSResult(error.StealNSResult());
     }
     if (currentCellIndexes.mRow < maxRow || currentCellIndexes.mRow > maxRow ||
         currentCellIndexes.mColumn < maxColumn ||
         currentCellIndexes.mColumn > maxColumn) {
-      SelectionRefPtr()->RemoveRange(*range, IgnoreErrors());
+      SelectionRefPtr()->RemoveRangeAndUnselectFramesAndNotifyListeners(
+          *range, IgnoreErrors());
       // Since we've removed the range, decrement pointer to next range
       MOZ_ASSERT(mSelectedCellIndex > 0);
       mSelectedCellIndex--;
     }
     cell = GetNextSelectedTableCellElement(error);
     if (NS_WARN_IF(error.Failed())) {
       return EditorBase::ToGenericNSResult(error.StealNSResult());
     }
@@ -2644,17 +2645,18 @@ HTMLEditor::JoinTableCells(bool aMergeNo
       range = SelectionRefPtr()->GetRangeAt(i);
       if (NS_WARN_IF(!range)) {
         return NS_ERROR_FAILURE;
       }
 
       RefPtr<Element> deletedCell;
       HTMLEditor::GetCellFromRange(range, getter_AddRefs(deletedCell));
       if (!deletedCell) {
-        SelectionRefPtr()->RemoveRange(*range, IgnoreErrors());
+        SelectionRefPtr()->RemoveRangeAndUnselectFramesAndNotifyListeners(
+            *range, IgnoreErrors());
         rangeCount--;
         i--;
       }
     }
 
     // Set spans for the cell everything merged into
     rv = SetRowSpan(MOZ_KnownLive(firstSelectedCell.mElement),
                     lastRowIndex - firstSelectedCell.mIndexes.mRow + 1);
--- a/editor/libeditor/SelectionState.cpp
+++ b/editor/libeditor/SelectionState.cpp
@@ -76,17 +76,17 @@ nsresult SelectionState::RestoreSelectio
 
   // set the selection ranges anew
   size_t arrayCount = mArray.Length();
   for (size_t i = 0; i < arrayCount; i++) {
     RefPtr<nsRange> range = mArray[i]->GetRange();
     NS_ENSURE_TRUE(range, NS_ERROR_UNEXPECTED);
 
     ErrorResult rv;
-    aSel->AddRange(*range, rv);
+    aSel->AddRangeAndSelectFramesAndNotifyListeners(*range, rv);
     if (rv.Failed()) {
       return rv.StealNSResult();
     }
   }
   return NS_OK;
 }
 
 bool SelectionState::IsCollapsed() {
--- a/editor/libeditor/TextEditor.cpp
+++ b/editor/libeditor/TextEditor.cpp
@@ -1148,17 +1148,18 @@ nsresult TextEditor::ReplaceTextAsAction
 
   // Select the range but as far as possible, we should not create new range
   // even if it's part of special Selection.
   nsresult rv = SelectionRefPtr()->RemoveAllRangesTemporarily();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   ErrorResult error;
-  SelectionRefPtr()->AddRange(*aReplaceRange, error);
+  SelectionRefPtr()->AddRangeAndSelectFramesAndNotifyListeners(*aReplaceRange,
+                                                               error);
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
 
   rv = ReplaceSelectionAsSubAction(aString);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return EditorBase::ToGenericNSResult(rv);
   }
--- a/extensions/spellcheck/src/mozInlineSpellChecker.cpp
+++ b/extensions/spellcheck/src/mozInlineSpellChecker.cpp
@@ -1599,17 +1599,18 @@ nsresult mozInlineSpellChecker::CleanupR
 //    selection, we need to decrement mNumWordsInSpellSelection
 
 nsresult mozInlineSpellChecker::RemoveRange(Selection* aSpellCheckSelection,
                                             nsRange* aRange) {
   NS_ENSURE_ARG_POINTER(aSpellCheckSelection);
   NS_ENSURE_ARG_POINTER(aRange);
 
   ErrorResult rv;
-  aSpellCheckSelection->RemoveRange(*aRange, rv);
+  aSpellCheckSelection->RemoveRangeAndUnselectFramesAndNotifyListeners(*aRange,
+                                                                       rv);
   if (!rv.Failed() && mNumWordsInSpellSelection) mNumWordsInSpellSelection--;
 
   return rv.StealNSResult();
 }
 
 // mozInlineSpellChecker::AddRange
 //
 //    For performance reasons, we have an upper bound on the number of word
@@ -1620,17 +1621,18 @@ nsresult mozInlineSpellChecker::AddRange
                                          nsRange* aRange) {
   NS_ENSURE_ARG_POINTER(aSpellCheckSelection);
   NS_ENSURE_ARG_POINTER(aRange);
 
   nsresult rv = NS_OK;
 
   if (!SpellCheckSelectionIsFull()) {
     IgnoredErrorResult err;
-    aSpellCheckSelection->AddRange(*aRange, err);
+    aSpellCheckSelection->AddRangeAndSelectFramesAndNotifyListeners(*aRange,
+        err);
     if (err.Failed()) {
       rv = err.StealNSResult();
     } else {
       mNumWordsInSpellSelection++;
     }
   }
 
   return rv;
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -3121,17 +3121,18 @@ nsresult PresShell::GoToAnchor(const nsA
     while (content && content->GetFirstChild()) {
       content = content->GetFirstChild();
     }
     jumpToRange->SelectNodeContents(*content, IgnoreErrors());
     // Select the anchor
     RefPtr<Selection> sel = mSelection->GetSelection(SelectionType::eNormal);
     if (sel) {
       sel->RemoveAllRanges(IgnoreErrors());
-      sel->AddRange(*jumpToRange, IgnoreErrors());
+      sel->AddRangeAndSelectFramesAndNotifyListeners(*jumpToRange,
+                                                     IgnoreErrors());
       if (!selectAnchor) {
         // Use a caret (collapsed selection) at the start of the anchor
         sel->CollapseToStart(IgnoreErrors());
       }
     }
     // Selection is at anchor.
     // Now focus the document itself if focus is on an element within it.
     nsPIDOMWindowOuter* win = mDocument->GetWindow();
--- a/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -833,17 +833,18 @@ nsresult nsTextControlFrame::SetSelectio
   }
 
   ErrorResult err;
   selection->RemoveAllRanges(err);
   if (NS_WARN_IF(err.Failed())) {
     return err.StealNSResult();
   }
 
-  selection->AddRange(*range, err);  // NOTE: can destroy the world
+  selection->AddRangeAndSelectFramesAndNotifyListeners(
+      *range, err);  // NOTE: can destroy the world
   if (NS_WARN_IF(err.Failed())) {
     return err.StealNSResult();
   }
 
   selection->SetDirection(direction);
   return rv;
 }
 
--- a/layout/generic/nsFrameSelection.cpp
+++ b/layout/generic/nsFrameSelection.cpp
@@ -1240,17 +1240,18 @@ nsresult nsFrameSelection::TakeFocus(nsI
     if (aMultipleSelection) {
       // Remove existing collapsed ranges as there's no point in having
       // non-anchor/focus collapsed ranges.
       mDomSelections[index]->RemoveCollapsedRanges();
 
       RefPtr<nsRange> newRange = new nsRange(aNewFocus);
 
       newRange->CollapseTo(aNewFocus, aContentOffset);
-      mDomSelections[index]->AddRange(*newRange, IgnoreErrors());
+      mDomSelections[index]->AddRangeAndSelectFramesAndNotifyListeners(
+          *newRange, IgnoreErrors());
       mBatching = batching;
       mChangesDuringBatching = changes;
     } else {
       bool oldDesiredPosSet = mDesiredPosSet;  // need to keep old desired
                                                // position if it was set.
       mDomSelections[index]->Collapse(aNewFocus, aContentOffset);
       mDesiredPosSet = oldDesiredPosSet;  // now reset desired pos back.
       mBatching = batching;
@@ -2238,17 +2239,18 @@ nsresult nsFrameSelection::HandleTableSe
 #endif
             // Unselecting the start of previous block
             // XXX What do we use now!
             if (childContent == mAppendStartSelectedCell)
               mAppendStartSelectedCell = nullptr;
 
             // Deselect cell by removing its range from selection
             ErrorResult err;
-            mDomSelections[index]->RemoveRange(*range, err);
+            mDomSelections[index]
+                ->RemoveRangeAndUnselectFramesAndNotifyListeners(*range, err);
             return err.StealNSResult();
           }
         }
         mUnselectCellOnMouseUp = nullptr;
       }
     }
   }
   return result;
@@ -2318,17 +2320,18 @@ nsresult nsFrameSelection::UnselectCells
 #ifdef DEBUG_TABLE_SELECTION
     if (!range) printf("RemoveCellsToSelection -- range is null\n");
 #endif
 
     if (range) {
       if (aRemoveOutsideOfCellRange) {
         if (curRowIndex < minRowIndex || curRowIndex > maxRowIndex ||
             curColIndex < minColIndex || curColIndex > maxColIndex) {
-          mDomSelections[index]->RemoveRange(*range, IgnoreErrors());
+          mDomSelections[index]->RemoveRangeAndUnselectFramesAndNotifyListeners(
+              *range, IgnoreErrors());
           // Since we've removed the range, decrement pointer to next range
           mSelectedCellIndex--;
         }
 
       } else {
         // Remove cell from selection if it belongs to the given cells range or
         // it is spanned onto the cells range.
         nsTableCellFrame* cellFrame =
@@ -2343,17 +2346,18 @@ nsresult nsFrameSelection::UnselectCells
         if (origRowIndex <= static_cast<uint32_t>(maxRowIndex) &&
             maxRowIndex >= 0 &&
             origRowIndex + actualRowSpan - 1 >=
                 static_cast<uint32_t>(minRowIndex) &&
             origColIndex <= static_cast<uint32_t>(maxColIndex) &&
             maxColIndex >= 0 &&
             origColIndex + actualColSpan - 1 >=
                 static_cast<uint32_t>(minColIndex)) {
-          mDomSelections[index]->RemoveRange(*range, IgnoreErrors());
+          mDomSelections[index]->RemoveRangeAndUnselectFramesAndNotifyListeners(
+              *range, IgnoreErrors());
           // Since we've removed the range, decrement pointer to next range
           mSelectedCellIndex--;
         }
       }
     }
 
     range = GetNextCellRange();
     cellNode = GetFirstSelectedContent(range);
@@ -2633,17 +2637,17 @@ nsresult nsFrameSelection::CreateAndAddR
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   int8_t index = GetIndexFromSelectionType(SelectionType::eNormal);
   if (!mDomSelections[index]) return NS_ERROR_NULL_POINTER;
 
   ErrorResult err;
-  mDomSelections[index]->AddRange(*range, err);
+  mDomSelections[index]->AddRangeAndSelectFramesAndNotifyListeners(*range, err);
   return err.StealNSResult();
 }
 
 // End of Table Selection
 
 void nsFrameSelection::SetAncestorLimiter(nsIContent* aLimiter) {
   if (mAncestorLimiter != aLimiter) {
     mAncestorLimiter = aLimiter;
--- a/layout/printing/nsPrintJob.cpp
+++ b/layout/printing/nsPrintJob.cpp
@@ -1904,17 +1904,18 @@ nsresult nsPrintJob::UpdateSelectionAndS
   // this function before.
   if (selectionPS) {
     selectionPS->RemoveAllRanges(IgnoreErrors());
   }
   if (selection && selectionPS) {
     int32_t cnt = selection->RangeCount();
     int32_t inx;
     for (inx = 0; inx < cnt; ++inx) {
-      selectionPS->AddRange(*selection->GetRangeAt(inx), IgnoreErrors());
+      selectionPS->AddRangeAndSelectFramesAndNotifyListeners(
+          *selection->GetRangeAt(inx), IgnoreErrors());
     }
   }
 
   // If we are trying to shrink the contents to fit on the page
   // we must first locate the "pageContent" frame
   // Then we walk the frame tree and look for the "xmost" frame
   // this is the frame where the right-hand side of the frame extends
   // the furthest
@@ -2293,17 +2294,18 @@ static nsresult DeleteUnselectedNodes(Do
 
     // Create the range that we want to remove. Note that if startNode or
     // endNode are null nsRange::Create() will fail and we won't remove
     // that section.
     RefPtr<nsRange> range = nsRange::Create(startNode, startOffset, endNode,
                                             endOffset, IgnoreErrors());
 
     if (range && !range->Collapsed()) {
-      selection->AddRange(*range, IgnoreErrors());
+      selection->AddRangeAndSelectFramesAndNotifyListeners(*range,
+                                                           IgnoreErrors());
 
       // Unless we've already added an ellipsis at the start, if we ended mid
       // text node then add ellipsis.
       Text* text = endNode->GetAsText();
       if (!ellipsisOffset && text && endOffset && endOffset < text->Length()) {
         text->InsertData(endOffset, kEllipsis, IgnoreErrors());
         ellipsisOffset += kEllipsis.Length();
       }
@@ -2328,17 +2330,18 @@ static nsresult DeleteUnselectedNodes(Do
     }
   }
 
   // Add in the last range to the end of the body.
   RefPtr<nsRange> lastRange =
       nsRange::Create(startNode, startOffset, bodyNode,
                       bodyNode->GetChildCount(), IgnoreErrors());
   if (lastRange && !lastRange->Collapsed()) {
-    selection->AddRange(*lastRange, IgnoreErrors());
+    selection->AddRangeAndSelectFramesAndNotifyListeners(*lastRange,
+                                                         IgnoreErrors());
   }
 
   selection->DeleteFromDocument(IgnoreErrors());
   return NS_OK;
 }
 
 //-------------------------------------------------------
 nsresult nsPrintJob::DoPrint(const UniquePtr<nsPrintObject>& aPO) {
--- a/toolkit/components/find/nsWebBrowserFind.cpp
+++ b/toolkit/components/find/nsWebBrowserFind.cpp
@@ -353,17 +353,18 @@ void nsWebBrowserFind::SetSelectionAndSc
     }
   }
 
   selCon->SetDisplaySelection(nsISelectionController::SELECTION_ON);
   RefPtr<Selection> selection =
       selCon->GetSelection(nsISelectionController::SELECTION_NORMAL);
   if (selection) {
     selection->RemoveAllRanges(IgnoreErrors());
-    selection->AddRange(*aRange, IgnoreErrors());
+    selection->AddRangeAndSelectFramesAndNotifyListeners(*aRange,
+                                                         IgnoreErrors());
 
     nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
     if (fm) {
       if (tcFrame) {
         RefPtr<Element> newFocusedElement = Element::FromNode(content);
         fm->SetFocus(newFocusedElement, nsIFocusManager::FLAG_NOSCROLL);
       } else {
         RefPtr<Element> result;
--- a/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp
+++ b/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp
@@ -593,17 +593,18 @@ nsresult nsTypeAheadFind::FindItNow(bool
         GetSelection(presShell, getter_AddRefs(selectionController),
                      getter_AddRefs(selection));
       }
       mSelectionController = do_GetWeakReference(selectionController);
 
       // Select the found text
       if (selection) {
         selection->RemoveAllRanges(IgnoreErrors());
-        selection->AddRange(*returnRange, IgnoreErrors());
+        selection->AddRangeAndSelectFramesAndNotifyListeners(*returnRange,
+                                                             IgnoreErrors());
       }
 
       if (!mFoundEditable && fm) {
         fm->MoveFocus(window->GetOuterWindow(), nullptr,
                       nsIFocusManager::MOVEFOCUS_CARET,
                       nsIFocusManager::FLAG_NOSCROLL |
                           nsIFocusManager::FLAG_NOSWITCHFRAME,
                       getter_AddRefs(mFoundLink));
--- a/toolkit/modules/subprocess/subprocess_unix.jsm
+++ b/toolkit/modules/subprocess/subprocess_unix.jsm
@@ -107,17 +107,17 @@ var SubprocessUnix = {
     function decode(array) {
       try {
         return decoder.decode(array);
       } catch (e) {
         return array;
       }
     }
 
-    for (let envp = environ; !envp.contents.isNull(); envp = envp.increment()) {
+    for (let envp = environ; !envp.isNull() && !envp.contents.isNull(); envp = envp.increment()) {
       let buf = ptrToUint8Array(envp.contents);
 
       for (let i = 0; i < buf.length; i++) {
         if (buf[i] == EQUAL) {
           yield [decode(buf.subarray(0, i)),
                  decode(buf.subarray(i + 1))];
           break;
         }