Bug 1503231 - Make TextEditor::DeleteSelectionAsAction() removes removing range information from EditAction when Selection is NOT collapsed r=m_kato
authorMasayuki Nakano <masayuki@d-toybox.com>
Wed, 07 Nov 2018 08:38:15 +0000
changeset 444811 b631af71b7ba4ccdff840db112ec9c519382f161
parent 444810 dc0584144f761bd0e10df867a59d66419ccd62ea
child 444812 4de987e47323c74954cef79540e5a0bbe887c232
push id35003
push userncsoregi@mozilla.com
push dateWed, 07 Nov 2018 16:16:52 +0000
treeherdermozilla-central@4407a6d3e374 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersm_kato
bugs1503231
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 1503231 - Make TextEditor::DeleteSelectionAsAction() removes removing range information from EditAction when Selection is NOT collapsed r=m_kato When Selection is NOT collapsed, we remove selected content. Therefore, web apps don't need to know range information of user operation. However, web apps may want to know direction of the operation (backward or forward). E.g., web apps may just mark selected range as "deleted" and move caret before or after the range. Therefore, when computed EditAction is eDeleteWordBackward or eDeleteToBeginningOfSoftLine, we should use eDeleteBackward instead. When it is eDeleteWordForward or eDeleteToEndOfSoftLine, we should use eDeleteForward instead. Note that only on Windows, we follow behavior of richtext control (and Word). That is, Ctrl + Backspace/Delete collapse from start of selected range to start/end of current word. I.e., collapsing Selection to start first and removing to start or end of current word is Windows's standard behavior. Currently, we do this in DeleteSelectionAsSubAction() but every caller specifies eNone to aDirection except DeleteSelectionAsAction(). So, we can move this before re-computing EditAction in DeleteSelectionAsAction(). Differential Revision: https://phabricator.services.mozilla.com/D10992
editor/libeditor/TextEditor.cpp
--- a/editor/libeditor/TextEditor.cpp
+++ b/editor/libeditor/TextEditor.cpp
@@ -707,16 +707,66 @@ TextEditor::DeleteSelectionAsAction(EDir
       break;
   }
 
   AutoEditActionDataSetter editActionData(*this, editAction);
   if (NS_WARN_IF(!editActionData.CanHandle())) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
+  // If there is an existing selection when an extended delete is requested,
+  // platforms that use "caret-style" caret positioning collapse the
+  // selection to the  start and then create a new selection.
+  // Platforms that use "selection-style" caret positioning just delete the
+  // existing selection without extending it.
+  if (!SelectionRefPtr()->IsCollapsed()) {
+    switch (aDirection) {
+      case eNextWord:
+      case ePreviousWord:
+      case eToBeginningOfLine:
+      case eToEndOfLine: {
+        if (mCaretStyle != 1) {
+          aDirection = eNone;
+          break;
+        }
+        ErrorResult error;
+        SelectionRefPtr()->CollapseToStart(error);
+        if (NS_WARN_IF(error.Failed())) {
+          return error.StealNSResult();
+        }
+        break;
+      }
+      default:
+        break;
+    }
+  }
+
+  // If Selection is still NOT collapsed, it does not important removing
+  // range of the operation since we'll remove the selected content.  However,
+  // information of direction (backward or forward) may be important for
+  // web apps.  E.g., web apps may want to mark selected range as "deleted"
+  // and move caret before or after the range.  Therefore, we should forget
+  // only the range information but keep range information.  See discussion
+  // of the spec issue for the detail:
+  // https://github.com/w3c/input-events/issues/82
+  if (!SelectionRefPtr()->IsCollapsed()) {
+    switch (editAction) {
+      case EditAction::eDeleteWordBackward:
+      case EditAction::eDeleteToBeginningOfSoftLine:
+        editActionData.UpdateEditAction(EditAction::eDeleteBackward);
+        break;
+      case EditAction::eDeleteWordForward:
+      case EditAction::eDeleteToEndOfSoftLine:
+        editActionData.UpdateEditAction(EditAction::eDeleteForward);
+        break;
+      default:
+        break;
+    }
+  }
+
   // delete placeholder txns merge.
   AutoPlaceholderBatch treatAsOneTransaction(*this, *nsGkAtoms::DeleteTxnName);
   nsresult rv = DeleteSelectionAsSubAction(aDirection, aStripWrappers);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   return NS_OK;
 }
@@ -732,43 +782,16 @@ TextEditor::DeleteSelectionAsSubAction(E
 
   if (!mRules) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
   // Protect the edit rules object from dying
   RefPtr<TextEditRules> rules(mRules);
 
-  // If there is an existing selection when an extended delete is requested,
-  //  platforms that use "caret-style" caret positioning collapse the
-  //  selection to the  start and then create a new selection.
-  //  Platforms that use "selection-style" caret positioning just delete the
-  //  existing selection without extending it.
-  if (!SelectionRefPtr()->IsCollapsed()) {
-    switch (aDirection) {
-      case eNextWord:
-      case ePreviousWord:
-      case eToBeginningOfLine:
-      case eToEndOfLine: {
-        if (mCaretStyle != 1) {
-          aDirection = eNone;
-          break;
-        }
-        ErrorResult error;
-        SelectionRefPtr()->CollapseToStart(error);
-        if (NS_WARN_IF(error.Failed())) {
-          return error.StealNSResult();
-        }
-        break;
-      }
-      default:
-        break;
-    }
-  }
-
   AutoTopLevelEditSubActionNotifier maybeTopLevelEditSubAction(
                                       *this,
                                       EditSubAction::eDeleteSelectedContent,
                                       aDirection);
   EditSubActionInfo subActionInfo(EditSubAction::eDeleteSelectedContent);
   subActionInfo.collapsedAction = aDirection;
   subActionInfo.stripWrappers = aStripWrappers;
   bool cancel, handled;