Bug 1627175 - part 68: Move `HTMLEditor::StartOrEndOfSelectionRangesIsIn()` to `AutoRangeArray` r=m_kato
authorMasayuki Nakano <masayuki@d-toybox.com>
Tue, 18 May 2021 09:06:13 +0000
changeset 579877 e72cd321bbaf0723d8f13bbc69278b1853273c62
parent 579876 e7942f7307ab789ec63cf4f2262200082310042e
child 579878 9dc679970296c93353800f9765d023b24fbfc423
push id38472
push userimoraru@mozilla.com
push dateTue, 18 May 2021 21:36:28 +0000
treeherdermozilla-central@4cc4cb51f18d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersm_kato
bugs1627175
milestone90.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 1627175 - part 68: Move `HTMLEditor::StartOrEndOfSelectionRangesIsIn()` to `AutoRangeArray` r=m_kato Differential Revision: https://phabricator.services.mozilla.com/D115180
editor/libeditor/EditorUtils.h
editor/libeditor/HTMLEditSubActionHandler.cpp
editor/libeditor/HTMLEditor.h
--- a/editor/libeditor/EditorUtils.h
+++ b/editor/libeditor/EditorUtils.h
@@ -757,16 +757,40 @@ class MOZ_STACK_CLASS AutoRangeArray fin
    * EnsureOnlyEditableRanges() removes ranges which cannot modify.
    * Note that this is designed only for `HTMLEditor` because this must not
    * be required by `TextEditor`.
    */
   void EnsureOnlyEditableRanges(const dom::Element& aEditingHost);
   static bool IsEditableRange(const dom::AbstractRange& aRange,
                               const dom::Element& aEditingHost);
 
+  /**
+   * IsAtLeastOneContainerOfRangeBoundariesInclusiveDescendantOf() returns true
+   * if at least one of the containers of the range boundaries is an inclusive
+   * descendant of aContent.
+   */
+  bool IsAtLeastOneContainerOfRangeBoundariesInclusiveDescendantOf(
+      const nsIContent& aContent) const {
+    for (const OwningNonNull<nsRange>& range : mRanges) {
+      nsINode* startContainer = range->GetStartContainer();
+      if (startContainer &&
+          startContainer->IsInclusiveDescendantOf(&aContent)) {
+        return true;
+      }
+      nsINode* endContainer = range->GetEndContainer();
+      if (startContainer == endContainer) {
+        continue;
+      }
+      if (endContainer && endContainer->IsInclusiveDescendantOf(&aContent)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
   auto& Ranges() { return mRanges; }
   const auto& Ranges() const { return mRanges; }
   auto& FirstRangeRef() { return mRanges[0]; }
   const auto& FirstRangeRef() const { return mRanges[0]; }
 
   template <template <typename> typename StrongPtrType>
   AutoTArray<StrongPtrType<nsRange>, 8> CloneRanges() const {
     AutoTArray<StrongPtrType<nsRange>, 8> ranges;
--- a/editor/libeditor/HTMLEditSubActionHandler.cpp
+++ b/editor/libeditor/HTMLEditSubActionHandler.cpp
@@ -8288,17 +8288,21 @@ nsresult HTMLEditor::RemoveEmptyNodesIn(
         // Only consider certain nodes to be empty for purposes of removal
         isCandidate = true;
       } else if (HTMLEditUtils::IsFormatNode(content) ||
                  HTMLEditUtils::IsListItem(content) ||
                  content->IsHTMLElement(nsGkAtoms::blockquote)) {
         // These node types are candidates if selection is not in them.  If
         // it is one of these, don't delete if selection inside.  This is so
         // we can create empty headings, etc., for the user to type into.
-        isCandidate = !StartOrEndOfSelectionRangesIsIn(*content);
+        AutoRangeArray selectionRanges(SelectionRef());
+        isCandidate =
+            !selectionRanges
+                 .IsAtLeastOneContainerOfRangeBoundariesInclusiveDescendantOf(
+                     *content);
       }
     }
 
     bool isEmptyNode = false;
     if (isCandidate) {
       // We delete mailcites even if they have a solo br in them.  Other
       // nodes we require to be empty.
       HTMLEditUtils::EmptyCheckOptions options{
@@ -8367,46 +8371,16 @@ nsresult HTMLEditor::RemoveEmptyNodesIn(
       NS_WARNING("HTMLEditor::DeleteNodeWithTransaction() failed");
       return rv;
     }
   }
 
   return NS_OK;
 }
 
-bool HTMLEditor::StartOrEndOfSelectionRangesIsIn(nsIContent& aContent) const {
-  MOZ_ASSERT(IsEditActionDataAvailable());
-
-  for (uint32_t i = 0; i < SelectionRef().RangeCount(); ++i) {
-    const nsRange* range = SelectionRef().GetRangeAt(i);
-    nsINode* startContainer = range->GetStartContainer();
-    if (startContainer) {
-      if (&aContent == startContainer) {
-        return true;
-      }
-      if (EditorUtils::IsDescendantOf(*startContainer, aContent)) {
-        return true;
-      }
-    }
-    nsINode* endContainer = range->GetEndContainer();
-    if (startContainer == endContainer) {
-      continue;
-    }
-    if (endContainer) {
-      if (&aContent == endContainer) {
-        return true;
-      }
-      if (EditorUtils::IsDescendantOf(*endContainer, aContent)) {
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
 nsresult HTMLEditor::LiftUpListItemElement(
     Element& aListItemElement,
     LiftUpFromAllParentListElements aLiftUpFromAllParentListElements) {
   MOZ_ASSERT(IsEditActionDataAvailable());
 
   if (!HTMLEditUtils::IsListItem(&aListItemElement)) {
     return NS_ERROR_INVALID_ARG;
   }
--- a/editor/libeditor/HTMLEditor.h
+++ b/editor/libeditor/HTMLEditor.h
@@ -2547,22 +2547,16 @@ class HTMLEditor final : public TextEdit
    *
    * @param aAlignType          New align attribute value where the contents
    *                            should be aligned to.
    */
   [[nodiscard]] MOZ_CAN_RUN_SCRIPT EditActionResult
   AlignAsSubAction(const nsAString& aAlignType);
 
   /**
-   * StartOrEndOfSelectionRangesIsIn() returns true if start or end of one
-   * of selection ranges is in aContent.
-   */
-  bool StartOrEndOfSelectionRangesIsIn(nsIContent& aContent) const;
-
-  /**
    * AdjustCaretPositionAndEnsurePaddingBRElement() may adjust caret
    * position to nearest editable content and if padding `<br>` element is
    * necessary at caret position, this creates it.
    *
    * @param aDirectionAndAmount Direction of the edit action.
    */
   [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
   AdjustCaretPositionAndEnsurePaddingBRElement(