Bug 1694255 - Allow delete previous block element. r=masayuki
☠☠ backed out by 711e7a52d4f9 ☠ ☠
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Thu, 20 May 2021 08:52:00 +0000
changeset 580197 8707a9007c1768ace636d3b16bfffd27143f110d
parent 580196 274924028c4ccd2814dc55540843b147b92447eb
child 580198 df784a865e380e5245a8bca699384eab7a533242
push id38479
push usermalexandru@mozilla.com
push dateFri, 21 May 2021 09:57:54 +0000
treeherdermozilla-central@9d30cff8f9d4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmasayuki
bugs1694255
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 1694255 - Allow delete previous block element. r=masayuki This fix allows that we can remove previous div block that isn't editable. ``` <div contenteditable>foo<div contenteditable=false>bar</div><[]baz</div> ``` Our text scanner can reach previous text node in other block when deleting text even if text node is read-only. In this situation, we try joining each block. But since target element/node isn't editable, this operation is failure. So we should use atomic deletion instead for this case. Differential Revision: https://phabricator.services.mozilla.com/D115341
editor/libeditor/HTMLEditorDeleteHandler.cpp
editor/libeditor/WSRunObject.h
editor/libeditor/tests/browserscope/lib/richtext2/currentStatus.js
testing/web-platform/meta/editing/run/delete.html.ini
--- a/editor/libeditor/HTMLEditorDeleteHandler.cpp
+++ b/editor/libeditor/HTMLEditorDeleteHandler.cpp
@@ -1671,17 +1671,18 @@ HTMLEditor::AutoDeleteRangesHandler::Com
     NS_WARNING_ASSERTION(
         NS_SUCCEEDED(rv),
         "AutoDeleteRangesHandler::"
         "ComputeRangesToDeleteTextAroundCollapsedRanges() failed");
     return rv;
   }
 
   if (aScanFromCaretPointResult.ReachedSpecialContent() ||
-      aScanFromCaretPointResult.ReachedBRElement()) {
+      aScanFromCaretPointResult.ReachedBRElement() ||
+      aScanFromCaretPointResult.ReachedNonEditableOtherBlockElement()) {
     if (aScanFromCaretPointResult.GetContent() ==
         aWSRunScannerAtCaret.GetEditingHost()) {
       return NS_OK;
     }
     nsIContent* atomicContent = GetAtomicContentToDelete(
         aDirectionAndAmount, aWSRunScannerAtCaret, aScanFromCaretPointResult);
     if (!HTMLEditUtils::IsRemovableNode(*atomicContent)) {
       NS_WARNING(
@@ -1712,20 +1713,16 @@ HTMLEditor::AutoDeleteRangesHandler::Com
         "AutoDeleteRangesHandler::ComputeRangesToDeleteHRElement() failed");
     return rv;
   }
 
   if (aScanFromCaretPointResult.ReachedOtherBlockElement()) {
     if (NS_WARN_IF(!aScanFromCaretPointResult.GetContent()->IsElement())) {
       return NS_ERROR_FAILURE;
     }
-    // TODO(m_kato):
-    // When aScanFromCaretPointResult.GetContent isn't editable and is
-    // removable, PrepareToDeleteAtOtherBlockBoundary will return false.
-    // But this should be removed.
     AutoBlockElementsJoiner joiner(*this);
     if (!joiner.PrepareToDeleteAtOtherBlockBoundary(
             aHTMLEditor, aDirectionAndAmount,
             *aScanFromCaretPointResult.ElementPtr(),
             aWSRunScannerAtCaret.ScanStartRef(), aWSRunScannerAtCaret)) {
       return NS_SUCCESS_DOM_NO_OPERATION;
     }
     nsresult rv = joiner.ComputeRangesToDelete(
@@ -1810,17 +1807,18 @@ HTMLEditor::AutoDeleteRangesHandler::Han
     NS_WARNING_ASSERTION(result.Succeeded(),
                          "AutoDeleteRangesHandler::"
                          "HandleDeleteCollapsedSelectionAtVisibleChar() "
                          "failed");
     return result;
   }
 
   if (aScanFromCaretPointResult.ReachedSpecialContent() ||
-      aScanFromCaretPointResult.ReachedBRElement()) {
+      aScanFromCaretPointResult.ReachedBRElement() ||
+      aScanFromCaretPointResult.ReachedNonEditableOtherBlockElement()) {
     if (aScanFromCaretPointResult.GetContent() ==
         aWSRunScannerAtCaret.GetEditingHost()) {
       return EditActionHandled();
     }
     nsCOMPtr<nsIContent> atomicContent = GetAtomicContentToDelete(
         aDirectionAndAmount, aWSRunScannerAtCaret, aScanFromCaretPointResult);
     if (!HTMLEditUtils::IsRemovableNode(*atomicContent)) {
       NS_WARNING(
--- a/editor/libeditor/WSRunObject.h
+++ b/editor/libeditor/WSRunObject.h
@@ -261,16 +261,23 @@ class MOZ_STACK_CLASS WSScanResult final
   /**
    * The scanner reached other block element.
    */
   bool ReachedOtherBlockElement() const {
     return mReason == WSType::OtherBlockBoundary;
   }
 
   /**
+   * The scanner reached other block element that isn't editable
+   */
+  bool ReachedNonEditableOtherBlockElement() const {
+    return ReachedOtherBlockElement() && !GetContent()->IsEditable();
+  }
+
+  /**
    * The scanner reached something non-text node.
    */
   bool ReachedSomething() const { return !InNormalWhiteSpacesOrText(); }
 
  private:
   nsCOMPtr<nsIContent> mContent;
   Maybe<uint32_t> mOffset;
   WSType mReason;
--- a/editor/libeditor/tests/browserscope/lib/richtext2/currentStatus.js
+++ b/editor/libeditor/tests/browserscope/lib/richtext2/currentStatus.js
@@ -214,18 +214,16 @@ const knownFailures = {
     "D-Proposed-TR3rs:3-1_SO1-div": true,
     "D-Proposed-TR3rs:3-1_SO2-dM": true,
     "D-Proposed-TR3rs:3-1_SO2-body": true,
     "D-Proposed-TR3rs:3-1_SO2-div": true,
     "D-Proposed-TR3rs:3-1_SO3-dM": true,
     "D-Proposed-TR3rs:3-1_SO3-body": true,
     "D-Proposed-TR3rs:3-1_SO3-div": true,
     "D-Proposed-DIV:ce:false-1_SB-dM": true,
-    "D-Proposed-DIV:ce:false-1_SB-body": true,
-    "D-Proposed-DIV:ce:false-1_SB-div": true,
     "D-Proposed-DIV:ce:false-1_SL-dM": true,
     "D-Proposed-DIV:ce:false-1_SL-body": true,
     "D-Proposed-DIV:ce:false-1_SL-div": true,
     "D-Proposed-DIV:ce:false-1_SR-dM": true,
     "D-Proposed-DIV:ce:false-1_SR-body": true,
     "D-Proposed-DIV:ce:false-1_SR-div": true,
     "D-Proposed-DIV:ce:false-1_SI-dM": true,
     "FD-Proposed-OL-LI-1_SW-dM": true,
@@ -856,18 +854,16 @@ const knownFailures = {
     "D-Proposed-TR3rs:3-1_SO1-div": true,
     "D-Proposed-TR3rs:3-1_SO2-dM": true,
     "D-Proposed-TR3rs:3-1_SO2-body": true,
     "D-Proposed-TR3rs:3-1_SO2-div": true,
     "D-Proposed-TR3rs:3-1_SO3-dM": true,
     "D-Proposed-TR3rs:3-1_SO3-body": true,
     "D-Proposed-TR3rs:3-1_SO3-div": true,
     "D-Proposed-DIV:ce:false-1_SB-dM": true,
-    "D-Proposed-DIV:ce:false-1_SB-body": true,
-    "D-Proposed-DIV:ce:false-1_SB-div": true,
     "D-Proposed-DIV:ce:false-1_SL-dM": true,
     "D-Proposed-DIV:ce:false-1_SL-body": true,
     "D-Proposed-DIV:ce:false-1_SL-div": true,
     "D-Proposed-DIV:ce:false-1_SR-dM": true,
     "D-Proposed-DIV:ce:false-1_SR-body": true,
     "D-Proposed-DIV:ce:false-1_SR-div": true,
     "D-Proposed-DIV:ce:false-1_SI-dM": true,
     "D-Proposed-SPAN:d:ib-2_SL-dM": true,
--- a/testing/web-platform/meta/editing/run/delete.html.ini
+++ b/testing/web-platform/meta/editing/run/delete.html.ini
@@ -692,13 +692,10 @@
     expected: FAIL
 
   [[["delete",""\]\] "<div>abc  </div> <div>  [\]def</div>" compare innerHTML]
     expected: FAIL
 
   [[["delete",""\]\] "<div>  a[\]bc</div>" compare innerHTML]
     expected: FAIL
 
-  [[["delete",""\]\] "foo<div contenteditable=false>bar</div>[\]baz" compare innerHTML]
-    expected: FAIL
-
   [[["delete",""\]\] "foo<span contenteditable=false>bar</span><span contenteditable=false>baz</span>[\]qux" compare innerHTML]
     expected: FAIL