Bug 1574852 - part 88: Move `HTMLEditRules::FindNearEditableNode()` to `HTMLEditor` r=m_kato
authorMasayuki Nakano <masayuki@d-toybox.com>
Mon, 09 Sep 2019 10:09:38 +0000
changeset 492422 95684e6acbd31703b03fc986636e6ec0bf4843c4
parent 492421 8edfd974fc63dcd13bd0b501bebdba963e439da9
child 492423 1286d4b97efd3623db92b28472707c6fc4496d55
push id36555
push usermalexandru@mozilla.com
push dateTue, 10 Sep 2019 09:53:18 +0000
treeherdermozilla-central@07f1d247491f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersm_kato
bugs1574852
milestone71.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 1574852 - part 88: Move `HTMLEditRules::FindNearEditableNode()` to `HTMLEditor` r=m_kato Differential Revision: https://phabricator.services.mozilla.com/D44792
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/HTMLEditRules.h
editor/libeditor/HTMLEditor.h
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -218,16 +218,20 @@ template EditorDOMPoint HTMLEditor::GetC
 template EditorDOMPoint HTMLEditor::GetCurrentHardLineEndPoint(
     const RangeBoundary& aPoint);
 template EditorDOMPoint HTMLEditor::GetCurrentHardLineEndPoint(
     const RawRangeBoundary& aPoint);
 template Element* HTMLEditor::GetInvisibleBRElementAt(
     const EditorDOMPoint& aPoint);
 template Element* HTMLEditor::GetInvisibleBRElementAt(
     const EditorRawDOMPoint& aPoint);
+template nsIContent* HTMLEditor::FindNearEditableContent(
+    const EditorDOMPoint& aPoint, nsIEditor::EDirection aDirection);
+template nsIContent* HTMLEditor::FindNearEditableContent(
+    const EditorRawDOMPoint& aPoint, nsIEditor::EDirection aDirection);
 
 HTMLEditRules::HTMLEditRules() : mHTMLEditor(nullptr), mInitialized(false) {
   mIsHTMLEditRules = true;
 }
 
 nsresult HTMLEditRules::Init(TextEditor* aTextEditor) {
   if (NS_WARN_IF(!aTextEditor) || NS_WARN_IF(!aTextEditor->AsHTMLEditor())) {
     return NS_ERROR_INVALID_ARG;
@@ -9845,17 +9849,17 @@ nsresult HTMLEditRules::AdjustSelection(
   if (nearNode &&
       (TextEditUtils::IsBreak(nearNode) || EditorBase::IsTextNode(nearNode) ||
        nearNode->IsAnyOfHTMLElements(nsGkAtoms::img, nsGkAtoms::hr))) {
     return NS_OK;  // this is a good place for the caret to be
   }
 
   // look for a nearby text node.
   // prefer the correct direction.
-  nearNode = FindNearEditableNode(point, aAction);
+  nearNode = HTMLEditorRef().FindNearEditableContent(point, aAction);
   if (!nearNode) {
     return NS_OK;
   }
 
   EditorDOMPoint pt = HTMLEditorRef().GetGoodCaretPointFor(*nearNode, aAction);
   ErrorResult error;
   SelectionRefPtr()->Collapse(pt, error);
   if (NS_WARN_IF(!CanHandleEditAction())) {
@@ -9864,69 +9868,65 @@ nsresult HTMLEditRules::AdjustSelection(
   }
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
   return NS_OK;
 }
 
 template <typename PT, typename CT>
-nsIContent* HTMLEditRules::FindNearEditableNode(
+nsIContent* HTMLEditor::FindNearEditableContent(
     const EditorDOMPointBase<PT, CT>& aPoint,
     nsIEditor::EDirection aDirection) {
-  MOZ_ASSERT(IsEditorDataAvailable());
-
-  if (NS_WARN_IF(!aPoint.IsSet())) {
-    return nullptr;
-  }
+  MOZ_ASSERT(IsEditActionDataAvailable());
   MOZ_ASSERT(aPoint.IsSetAndValid());
 
-  nsIContent* nearNode = nullptr;
+  nsIContent* editableContent = nullptr;
   if (aDirection == nsIEditor::ePrevious) {
-    nearNode = HTMLEditorRef().GetPreviousEditableHTMLNode(aPoint);
-    if (!nearNode) {
+    editableContent = GetPreviousEditableHTMLNode(aPoint);
+    if (!editableContent) {
       return nullptr;  // Not illegal.
     }
   } else {
-    nearNode = HTMLEditorRef().GetNextEditableHTMLNode(aPoint);
-    if (NS_WARN_IF(!nearNode)) {
+    editableContent = GetNextEditableHTMLNode(aPoint);
+    if (NS_WARN_IF(!editableContent)) {
       // Perhaps, illegal because the node pointed by aPoint isn't editable
       // and nobody of previous nodes is editable.
       return nullptr;
     }
   }
 
   // scan in the right direction until we find an eligible text node,
   // but don't cross any breaks, images, or table elements.
-  // XXX This comment sounds odd.  |nearNode| may have already crossed breaks
-  //     and/or images.
-  while (nearNode && !(EditorBase::IsTextNode(nearNode) ||
-                       TextEditUtils::IsBreak(nearNode) ||
-                       HTMLEditUtils::IsImage(nearNode))) {
+  // XXX This comment sounds odd.  editableContent may have already crossed
+  //     breaks and/or images if they are non-editable.
+  while (editableContent && !EditorBase::IsTextNode(editableContent) &&
+         !TextEditUtils::IsBreak(editableContent) &&
+         !HTMLEditUtils::IsImage(editableContent)) {
     if (aDirection == nsIEditor::ePrevious) {
-      nearNode = HTMLEditorRef().GetPreviousEditableHTMLNode(*nearNode);
-      if (NS_WARN_IF(!nearNode)) {
+      editableContent = GetPreviousEditableHTMLNode(*editableContent);
+      if (NS_WARN_IF(!editableContent)) {
         return nullptr;
       }
     } else {
-      nearNode = HTMLEditorRef().GetNextEditableHTMLNode(*nearNode);
-      if (NS_WARN_IF(!nearNode)) {
+      editableContent = GetNextEditableHTMLNode(*editableContent);
+      if (NS_WARN_IF(!editableContent)) {
         return nullptr;
       }
     }
   }
 
   // don't cross any table elements
-  if (HTMLEditor::NodesInDifferentTableElements(*nearNode,
+  if (HTMLEditor::NodesInDifferentTableElements(*editableContent,
                                                 *aPoint.GetContainer())) {
     return nullptr;
   }
 
   // otherwise, ok, we have found a good spot to put the selection
-  return nearNode;
+  return editableContent;
 }
 
 // static
 bool HTMLEditor::NodesInDifferentTableElements(nsINode& aNode1,
                                                nsINode& aNode2) {
   nsINode* parentNode1;
   for (parentNode1 = &aNode1;
        parentNode1 && !HTMLEditUtils::IsTableElement(parentNode1);
--- a/editor/libeditor/HTMLEditRules.h
+++ b/editor/libeditor/HTMLEditRules.h
@@ -215,33 +215,16 @@ class HTMLEditRules : public TextEditRul
    * a <br> to put caret, this tries to create a <br> element.
    *
    * @param aAction     Maybe used to look for a good point to put caret.
    */
   MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult
   AdjustSelection(nsIEditor::EDirection aAction);
 
   /**
-   * FindNearEditableNode() tries to find an editable node near aPoint.
-   *
-   * @param aPoint      The DOM point where to start to search from.
-   * @param aDirection  If nsIEditor::ePrevious is set, this searches an
-   *                    editable node from next nodes.  Otherwise, from
-   *                    previous nodes.
-   * @return            If found, returns non-nullptr.  Otherwise, nullptr.
-   *                    Note that if found node is in different table element,
-   *                    this returns nullptr.
-   *                    And also if aDirection is not nsIEditor::ePrevious,
-   *                    the result may be the node pointed by aPoint.
-   */
-  template <typename PT, typename CT>
-  nsIContent* FindNearEditableNode(const EditorDOMPointBase<PT, CT>& aPoint,
-                                   nsIEditor::EDirection aDirection);
-
-  /**
    * RemoveEmptyNodesInChangedRange() removes all empty nodes in
    * TopLevelEditSubActionData::mChangedRange.  However, if mail-cite node has
    * only a <br> element, the node will be removed but <br> element is moved
    * to where the mail-cite node was.
    * XXX This method is expensive if TopLevelEditSubActionData::mChangedRange
    *     is too wide and may remove unexpected empty element, e.g., it was
    *     created by JS, but we haven't touched it.  Cannot we remove this
    *     method and make guarantee that empty nodes won't be created?
--- a/editor/libeditor/HTMLEditor.h
+++ b/editor/libeditor/HTMLEditor.h
@@ -2570,16 +2570,33 @@ class HTMLEditor final : public TextEdit
   AlignAsSubAction(const nsAString& aAlignType);
 
   /**
    * StartOrEndOfSelectionRangesIsIn() returns true if start or end of one
    * of selection ranges is in aContent.
    */
   bool StartOrEndOfSelectionRangesIsIn(nsIContent& aContent) const;
 
+  /**
+   * FindNearEditableContent() tries to find an editable node near aPoint.
+   *
+   * @param aPoint      The DOM point where to start to search from.
+   * @param aDirection  If nsIEditor::ePrevious is set, this searches an
+   *                    editable node from next nodes.  Otherwise, from
+   *                    previous nodes.
+   * @return            If found, returns non-nullptr.  Otherwise, nullptr.
+   *                    Note that if found node is in different table element,
+   *                    this returns nullptr.
+   *                    And also if aDirection is not nsIEditor::ePrevious,
+   *                    the result may be the node pointed by aPoint.
+   */
+  template <typename PT, typename CT>
+  nsIContent* FindNearEditableContent(const EditorDOMPointBase<PT, CT>& aPoint,
+                                      nsIEditor::EDirection aDirection);
+
  protected:  // Called by helper classes.
   virtual void OnStartToHandleTopLevelEditSubAction(
       EditSubAction aEditSubAction, nsIEditor::EDirection aDirection) override;
   MOZ_CAN_RUN_SCRIPT
   virtual void OnEndHandlingTopLevelEditSubAction() override;
 
  protected:  // Shouldn't be used by friend classes
   virtual ~HTMLEditor();