Bug 1408227 - part 6: WSRunObject::CheckTrailingNBSP() should take |const EditorRawDOMPoint&| instead of a set of container node and offset in it r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Wed, 22 Nov 2017 02:45:08 +0900
changeset 706050 e0b5868929733077ae57bc84748f65901928a982
parent 706049 351b6588e59f2842e7eaced02c19395469e0e03f
child 742545 2376428c9abb38c2a1925acba480c89c494f36a9
push id91674
push usermasayuki@d-toybox.com
push dateFri, 01 Dec 2017 02:38:11 +0000
reviewersm_kato
bugs1408227
milestone59.0a1
Bug 1408227 - part 6: WSRunObject::CheckTrailingNBSP() should take |const EditorRawDOMPoint&| instead of a set of container node and offset in it r?m_kato The name, WSRunObject::CheckTrailingNBSP(), is unclear what it does. It replaces previous character of specified point with ASCII space if it is NBSP and it's not necessary. So, it should be renamed to ReplacePreviousNBSPIfUnncessary(). Additionally, it should take |const EditorRawDOMPoint&| instead of a set of container node and offset in it. MozReview-Commit-ID: 2vq46OiAzo6
editor/libeditor/WSRunObject.cpp
editor/libeditor/WSRunObject.h
--- a/editor/libeditor/WSRunObject.cpp
+++ b/editor/libeditor/WSRunObject.cpp
@@ -223,19 +223,20 @@ WSRunObject::InsertBreak(Selection& aSel
       // would become significant after break inserted.
       nsresult rv = DeleteRange(beforeRun->StartPoint(), pointToInsert.AsRaw());
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return nullptr;
       }
     } else if (beforeRun->mType == WSType::normalWS) {
       // Try to change an nbsp to a space, just to prevent nbsp proliferation
       nsresult rv =
-        CheckTrailingNBSP(beforeRun, pointToInsert.Container(),
-                          pointToInsert.Offset());
-      NS_ENSURE_SUCCESS(rv, nullptr);
+        ReplacePreviousNBSPIfUnncessary(beforeRun, pointToInsert.AsRaw());
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        return nullptr;
+      }
     }
   }
 
   RefPtr<Element> newBRElement =
     mHTMLEditor->CreateBRImpl(aSelection, pointToInsert.AsRaw(), aSelect);
   if (NS_WARN_IF(!newBRElement)) {
     return nullptr;
   }
@@ -305,19 +306,21 @@ WSRunObject::InsertText(nsIDocument& aDo
       // it would become significant after text inserted.
       nsresult rv = DeleteRange(beforeRun->StartPoint(), pointToInsert.AsRaw());
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
     } else if (beforeRun->mType == WSType::normalWS) {
       // Try to change an nbsp to a space, if possible, just to prevent nbsp
       // proliferation
-      nsresult rv = CheckTrailingNBSP(beforeRun, pointToInsert.Container(),
-                                      pointToInsert.Offset());
-      NS_ENSURE_SUCCESS(rv, rv);
+      nsresult rv =
+        ReplacePreviousNBSPIfUnncessary(beforeRun, pointToInsert.AsRaw());
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        return rv;
+      }
     }
 
     // After this block, pointToInsert is modified by AutoTrackDOMPoint.
   }
 
   // Next up, tweak head and tail of string as needed.  First the head: there
   // are a variety of circumstances that would require us to convert a leading
   // ws char into an nbsp:
@@ -1854,56 +1857,71 @@ WSRunObject::CheckTrailingNBSPOfRun(WSFr
                                                    startOffset, true);
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
   return NS_OK;
 }
 
 nsresult
-WSRunObject::CheckTrailingNBSP(WSFragment* aRun,
-                               nsINode* aNode,
-                               int32_t aOffset)
+WSRunObject::ReplacePreviousNBSPIfUnncessary(WSFragment* aRun,
+                                             const EditorRawDOMPoint& aPoint)
 {
-  // Try to change an nbsp to a space, if possible, just to prevent nbsp
+  if (NS_WARN_IF(!aRun) ||
+      NS_WARN_IF(!aPoint.IsSet())) {
+    return NS_ERROR_INVALID_ARG;
+  }
+  MOZ_ASSERT(aPoint.IsSetAndValid());
+
+  // Try to change an NBSP to a space, if possible, just to prevent NBSP
   // proliferation.  This routine is called when we are about to make this
   // point in the ws abut an inserted break or text, so we don't have to worry
   // about what is after it.  What is after it now will end up after the
   // inserted object.
-  NS_ENSURE_TRUE(aRun && aNode, NS_ERROR_NULL_POINTER);
   bool canConvert = false;
-  WSPoint thePoint = GetPreviousCharPoint(EditorRawDOMPoint(aNode, aOffset));
+  WSPoint thePoint = GetPreviousCharPoint(aPoint);
   if (thePoint.mTextNode && thePoint.mChar == nbsp) {
     WSPoint prevPoint = GetPreviousCharPoint(thePoint);
     if (prevPoint.mTextNode) {
       if (!nsCRT::IsAsciiSpace(prevPoint.mChar)) {
+        // If previous character is a NBSP and its previous character isn't
+        // ASCII space, we can replace the NBSP with ASCII space.
         canConvert = true;
       }
     } else if (aRun->mLeftType == WSType::text ||
                aRun->mLeftType == WSType::special) {
+      // If previous character is a NBSP and it's the first character of the
+      // text node, additionally, if its previous node is a text node including
+      // non-whitespace characters or <img> node or something inline
+      // non-container element node, we can replace the NBSP with ASCII space.
       canConvert = true;
     }
   }
-  if (canConvert) {
-    // First, insert a space
-    AutoTransactionsConserveSelection dontChangeMySelection(mHTMLEditor);
-    nsAutoString spaceStr(char16_t(32));
-    nsresult rv =
-      mHTMLEditor->InsertTextIntoTextNodeImpl(spaceStr, *thePoint.mTextNode,
-                                              thePoint.mOffset, true);
-    NS_ENSURE_SUCCESS(rv, rv);
+
+  if (!canConvert) {
+    return NS_OK;
+  }
 
-    // Finally, delete that nbsp
-    rv = DeleteRange(EditorRawDOMPoint(thePoint.mTextNode,
-                                       thePoint.mOffset + 1),
-                     EditorRawDOMPoint(thePoint.mTextNode,
-                                       thePoint.mOffset + 2));
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
+  // First, insert a space before the previous NBSP.
+  AutoTransactionsConserveSelection dontChangeMySelection(mHTMLEditor);
+  nsAutoString spaceStr(char16_t(32));
+  nsresult rv =
+    mHTMLEditor->InsertTextIntoTextNodeImpl(spaceStr, *thePoint.mTextNode,
+                                            thePoint.mOffset, true);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  // Finally, delete the previous NBSP.
+  rv = DeleteRange(EditorRawDOMPoint(thePoint.mTextNode,
+                                     thePoint.mOffset + 1),
+                   EditorRawDOMPoint(thePoint.mTextNode,
+                                     thePoint.mOffset + 2));
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
   }
   return NS_OK;
 }
 
 nsresult
 WSRunObject::CheckLeadingNBSP(WSFragment* aRun,
                               nsINode* aNode,
                               int32_t aOffset)
--- a/editor/libeditor/WSRunObject.h
+++ b/editor/libeditor/WSRunObject.h
@@ -435,18 +435,28 @@ protected:
    *                      if aPoint is start of a run, returns its next run.
    *                      if aPoint is before the first run, returns nullptr.
    *                      if aPoint is after the last run, returns the last run.
    */
   WSFragment* FindNearestRun(const EditorRawDOMPoint& aPoint, bool aForward);
 
   char16_t GetCharAt(dom::Text* aTextNode, int32_t aOffset);
   nsresult CheckTrailingNBSPOfRun(WSFragment *aRun);
-  nsresult CheckTrailingNBSP(WSFragment* aRun, nsINode* aNode,
-                             int32_t aOffset);
+
+  /**
+   * ReplacePreviousNBSPIfUnncessary() replaces previous character of aPoint
+   * if it's a NBSP and it's unnecessary.
+   *
+   * @param aRun        Current text run.  aPoint must be in this run.
+   * @param aPoint      Current insertion point.  Its previous character is
+   *                    unnecessary NBSP will be checked.
+   */
+  nsresult ReplacePreviousNBSPIfUnncessary(WSFragment* aRun,
+                                           const EditorRawDOMPoint& aPoint);
+
   nsresult CheckLeadingNBSP(WSFragment* aRun, nsINode* aNode,
                             int32_t aOffset);
 
   nsresult Scrub();
   bool IsBlockNode(nsINode* aNode);
 
   EditorRawDOMPoint Point() const
   {