Bug 1574852 - part 29: Merge `HTMLEditRules::GetListActionNodes()` with `HTMLEditor::CollectEditTargetNodes()` r=m_kato
authorMasayuki Nakano <masayuki@d-toybox.com>
Sun, 25 Aug 2019 04:20:34 +0000
changeset 553543 65a9f716e652ba5d0a261727aafa7ac96f9c17ff
parent 553542 65b324e800761e957ac3c523040a51b39fb3a835
child 553544 8804f2b110be1ab158487f1c3e19c72c5354a2a9
push id2165
push userffxbld-merge
push dateMon, 14 Oct 2019 16:30:58 +0000
treeherdermozilla-release@0eae18af659f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersm_kato
bugs1574852
milestone70.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 29: Merge `HTMLEditRules::GetListActionNodes()` with `HTMLEditor::CollectEditTargetNodes()` r=m_kato This patch fixes an existing bug with this clean up. Except `HTMLEditRules::MoveBlock()`, `GetListActionNodes()` is called after calling `SplitInlinesAndCollectEditTargetNodesInExtendedSelectionRanges()` or `CollectEditTargetNodesInExtendedSelectionRanges()` **with** `EditSubAction::eCreateOrChangeList`. I think that `HTMLEditRules::MoveBlock()` using the edit sub-action is a simple mistake. Perhaps, it should be `EditSubAction::eCreateOrRemvoeBlock`. However, I'm not 100% sure because `HTMLEditor::CollectEditTargetNodes()` does special handling for `EditSubAction::eCreateOrRemvoeBlock` but not so for `EditSubAction::eCreateOrChangeList`. The behavior of difference between those edit sub-actions are only here. Therefore, this patch creates new `EditSubAction` `eMergeBlockContents` for `MoveBlock()`. Then, this patch makes `HTMLEditor::CollectEditTargetNodes()` handle `EditSubAction::eCreateOrChangeList` insead of `GetListActionNodes()`. This causes one logic change in `SplitInlinesAndCollectEditTargetNodes()`. It calls `MaybeSplitElementsAtEveryBRElement()` after `CollectEditTargetNodes()` so that this change makes calling `MaybeSplitElementsAtEveryBRElement()` at last. According to my tests, new behavior must be expected since `<br>` elements outside and in `<table>` should be handled consistently. Therefore, this patch adds some simple testcases into WPT. Differential Revision: https://phabricator.services.mozilla.com/D43190
editor/libeditor/EditAction.h
editor/libeditor/EditorBase.h
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/HTMLEditRules.h
editor/libeditor/HTMLEditor.h
testing/web-platform/meta/editing/run/insert-list-items-in-table-cell.html.ini
testing/web-platform/tests/editing/data/insert-list-items-in-table-cells.js
--- a/editor/libeditor/EditAction.h
+++ b/editor/libeditor/EditAction.h
@@ -431,16 +431,21 @@ enum class EditSubAction : int32_t {
   // eSetOrClearAlignment aligns content or clears alignment with align
   // attribute or text-align.
   eSetOrClearAlignment,
 
   // eCreateOrRemoveBlock creates new block or removes existing block and
   // move its descendants to where the block was.
   eCreateOrRemoveBlock,
 
+  // eMergeBlockContents is not an actual sub-action, but this is used by
+  // HTMLEditor::MoveBlock() to request special handling in
+  // HTMLEditor::SplitInlinesAndCollectEditTargetNodesInOneHardLine().
+  eMergeBlockContents,
+
   // eRemoveList removes specific type of list but keep its content.
   eRemoveList,
 
   // eCreateOrChangeDefinitionList indicates to create new definition list or
   // change existing list to a definition list.
   eCreateOrChangeDefinitionList,
 
   // eInsertElement indicates to insert an element.
--- a/editor/libeditor/EditorBase.h
+++ b/editor/libeditor/EditorBase.h
@@ -813,16 +813,17 @@ class EditorBase : public nsIEditor,
         case EditSubAction::eSetText:
         case EditSubAction::eInsertLineBreak:
         case EditSubAction::eInsertParagraphSeparator:
         case EditSubAction::eCreateOrChangeList:
         case EditSubAction::eIndent:
         case EditSubAction::eOutdent:
         case EditSubAction::eSetOrClearAlignment:
         case EditSubAction::eCreateOrRemoveBlock:
+        case EditSubAction::eMergeBlockContents:
         case EditSubAction::eRemoveList:
         case EditSubAction::eCreateOrChangeDefinitionList:
         case EditSubAction::eInsertElement:
         case EditSubAction::eInsertQuotation:
         case EditSubAction::eInsertQuotedText:
         case EditSubAction::ePasteHTMLContent:
         case EditSubAction::eInsertHTMLSource:
         case EditSubAction::eSetPositionToAbsolute:
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -81,16 +81,17 @@ static bool IsStyleCachePreservingSubAct
     case EditSubAction::eDeleteSelectedContent:
     case EditSubAction::eInsertLineBreak:
     case EditSubAction::eInsertParagraphSeparator:
     case EditSubAction::eCreateOrChangeList:
     case EditSubAction::eIndent:
     case EditSubAction::eOutdent:
     case EditSubAction::eSetOrClearAlignment:
     case EditSubAction::eCreateOrRemoveBlock:
+    case EditSubAction::eMergeBlockContents:
     case EditSubAction::eRemoveList:
     case EditSubAction::eCreateOrChangeDefinitionList:
     case EditSubAction::eInsertElement:
     case EditSubAction::eInsertQuotation:
     case EditSubAction::eInsertQuotedText:
       return true;
     default:
       return false;
@@ -890,20 +891,16 @@ nsresult HTMLEditRules::GetListState(boo
 
   AutoTArray<OwningNonNull<nsINode>, 64> arrayOfNodes;
   nsresult rv = HTMLEditorRef().CollectEditTargetNodesInExtendedSelectionRanges(
       arrayOfNodes, EditSubAction::eCreateOrChangeList,
       HTMLEditor::CollectNonEditableNodes::No);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
-  rv = GetListActionNodes(arrayOfNodes);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
 
   // Examine list type for nodes in selection.
   for (const auto& curNode : arrayOfNodes) {
     if (!curNode->IsElement()) {
       bNonList = true;
     } else if (curNode->IsHTMLElement(nsGkAtoms::ul)) {
       *aUL = true;
     } else if (curNode->IsHTMLElement(nsGkAtoms::ol)) {
@@ -949,20 +946,16 @@ nsresult HTMLEditRules::GetListItemState
 
   AutoTArray<OwningNonNull<nsINode>, 64> arrayOfNodes;
   nsresult rv = HTMLEditorRef().CollectEditTargetNodesInExtendedSelectionRanges(
       arrayOfNodes, EditSubAction::eCreateOrChangeList,
       HTMLEditor::CollectNonEditableNodes::No);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
-  rv = GetListActionNodes(arrayOfNodes);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
 
   // examine list type for nodes in selection
   for (const auto& node : arrayOfNodes) {
     if (!node->IsElement()) {
       bNonList = true;
     } else if (node->IsAnyOfHTMLElements(nsGkAtoms::ul, nsGkAtoms::ol,
                                          nsGkAtoms::li)) {
       *aLI = true;
@@ -3729,17 +3722,17 @@ EditActionResult HTMLEditRules::MoveBloc
                                           int32_t aLeftOffset,
                                           int32_t aRightOffset) {
   MOZ_ASSERT(IsEditorDataAvailable());
 
   AutoTArray<OwningNonNull<nsINode>, 64> arrayOfNodes;
   nsresult rv = MOZ_KnownLive(HTMLEditorRef())
                     .SplitInlinesAndCollectEditTargetNodesInOneHardLine(
                         EditorDOMPoint(&aRightBlock, aRightOffset),
-                        arrayOfNodes, EditSubAction::eCreateOrChangeList,
+                        arrayOfNodes, EditSubAction::eMergeBlockContents,
                         HTMLEditor::CollectNonEditableNodes::Yes);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return EditActionIgnored(rv);
   }
 
   EditActionResult ret(NS_OK);
   for (uint32_t i = 0; i < arrayOfNodes.Length(); i++) {
     // get the node to act on
@@ -4013,28 +4006,22 @@ nsresult HTMLEditRules::MakeList(nsAtom&
   AutoSelectionRestorer restoreSelectionLater(HTMLEditorRef());
 
   AutoTArray<OwningNonNull<nsINode>, 64> arrayOfNodes;
   Element* parentListElement =
       aEntireList ? HTMLEditorRef().GetParentListElementAtSelection() : nullptr;
   if (parentListElement) {
     arrayOfNodes.AppendElement(OwningNonNull<nsINode>(*parentListElement));
   } else {
-    {
-      AutoTransactionsConserveSelection dontChangeMySelection(HTMLEditorRef());
-      nsresult rv =
-          MOZ_KnownLive(HTMLEditorRef())
-              .SplitInlinesAndCollectEditTargetNodesInExtendedSelectionRanges(
-                  arrayOfNodes, EditSubAction::eCreateOrChangeList,
-                  HTMLEditor::CollectNonEditableNodes::No);
-      if (NS_WARN_IF(NS_FAILED(rv))) {
-        return rv;
-      }
-    }
-    nsresult rv = GetListActionNodes(arrayOfNodes);
+    AutoTransactionsConserveSelection dontChangeMySelection(HTMLEditorRef());
+    nsresult rv =
+        MOZ_KnownLive(HTMLEditorRef())
+            .SplitInlinesAndCollectEditTargetNodesInExtendedSelectionRanges(
+                arrayOfNodes, EditSubAction::eCreateOrChangeList,
+                HTMLEditor::CollectNonEditableNodes::No);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
   }
 
   // check if all our nodes are <br>s, or empty inlines
   bool bOnlyBreaks = true;
   for (auto& curNode : arrayOfNodes) {
@@ -4475,20 +4462,16 @@ nsresult HTMLEditRules::WillRemoveList(b
         MOZ_KnownLive(HTMLEditorRef())
             .SplitInlinesAndCollectEditTargetNodesInExtendedSelectionRanges(
                 arrayOfNodes, EditSubAction::eCreateOrChangeList,
                 HTMLEditor::CollectNonEditableNodes::No);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
   }
-  rv = GetListActionNodes(arrayOfNodes);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
 
   // Remove all non-editable nodes.  Leave them be.
   for (int32_t i = arrayOfNodes.Length() - 1; i >= 0; i--) {
     OwningNonNull<nsINode> testNode = arrayOfNodes[i];
     if (!HTMLEditorRef().IsEditable(testNode)) {
       arrayOfNodes.RemoveElementAt(i);
     }
   }
@@ -7516,17 +7499,17 @@ nsresult HTMLEditor::SplitParentInlineEl
   }
   return NS_OK;
 }
 
 nsresult HTMLEditor::CollectEditTargetNodes(
     nsTArray<RefPtr<nsRange>>& aArrayOfRanges,
     nsTArray<OwningNonNull<nsINode>>& aOutArrayOfNodes,
     EditSubAction aEditSubAction,
-    CollectNonEditableNodes aCollectNonEditableNodes) const {
+    CollectNonEditableNodes aCollectNonEditableNodes) {
   MOZ_ASSERT(IsEditActionDataAvailable());
 
   // Gather up a list of all the nodes
   for (auto& range : aArrayOfRanges) {
     DOMSubtreeIterator iter;
     nsresult rv = iter.Init(*range);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
@@ -7567,16 +7550,58 @@ nsresult HTMLEditor::CollectEditTargetNo
         if (Text* text = aOutArrayOfNodes[i]->GetAsText()) {
           // Don't select empty text except to empty block
           if (!IsVisibleTextNode(*text)) {
             aOutArrayOfNodes.RemoveElementAt(i);
           }
         }
       }
       break;
+    case EditSubAction::eCreateOrChangeList: {
+      for (size_t i = aOutArrayOfNodes.Length(); i > 0; i--) {
+        // Scan for table elements.  If we find table elements other than
+        // table, replace it with a list of any editable non-table content
+        // because if a selection range starts from end in a table-cell and
+        // ends at or starts from outside the `<table>`, we need to make
+        // lists in each selected table-cells.
+        OwningNonNull<nsINode> node = aOutArrayOfNodes[i - 1];
+        if (HTMLEditUtils::IsTableElementButNotTable(node)) {
+          // XXX aCollectNonEditableNodes is ignored here.  Maybe a bug.
+          aOutArrayOfNodes.RemoveElementAt(i - 1);
+          CollectChildren(node, aOutArrayOfNodes, i - 1,
+                          CollectListChildren::No, CollectTableChildren::Yes,
+                          CollectNonEditableNodes::Yes);
+        }
+      }
+      // If there is only one node in the array, and it is a `<div>`,
+      // `<blockquote>` or a list element, then look inside of it until we
+      // find inner list or content.
+      if (aOutArrayOfNodes.Length() != 1) {
+        break;
+      }
+      Element* deepestDivBlockquoteOrListElement =
+          GetDeepestEditableOnlyChildDivBlockquoteOrListElement(
+              aOutArrayOfNodes[0]);
+      if (!deepestDivBlockquoteOrListElement) {
+        break;
+      }
+      if (deepestDivBlockquoteOrListElement->IsAnyOfHTMLElements(
+              nsGkAtoms::div, nsGkAtoms::blockquote)) {
+        aOutArrayOfNodes.Clear();
+        // XXX Before we're called, non-editable nodes are ignored.  However,
+        //     we may append non-editable nodes here.
+        CollectChildren(*deepestDivBlockquoteOrListElement, aOutArrayOfNodes, 0,
+                        CollectListChildren::No, CollectTableChildren::No,
+                        CollectNonEditableNodes::Yes);
+        break;
+      }
+      aOutArrayOfNodes.ReplaceElementAt(
+          0, OwningNonNull<nsINode>(*deepestDivBlockquoteOrListElement));
+      break;
+    }
     case EditSubAction::eOutdent:
     case EditSubAction::eIndent:
     case EditSubAction::eSetPositionToAbsolute:
       // Indent/outdent already do something special for list items, but we
       // still need to make sure we don't act on table elements
       for (int32_t i = aOutArrayOfNodes.Length() - 1; i >= 0; i--) {
         OwningNonNull<nsINode> node = aOutArrayOfNodes[i];
         if (HTMLEditUtils::IsTableElementButNotTable(node)) {
@@ -7607,16 +7632,17 @@ nsresult HTMLEditor::CollectEditTargetNo
 
 nsresult HTMLEditor::MaybeSplitElementsAtEveryBRElement(
     nsTArray<OwningNonNull<nsINode>>& aArrayOfNodes,
     EditSubAction aEditSubAction) {
   // Post-process the list to break up inline containers that contain br's, but
   // only for operations that might care, like making lists or paragraphs
   switch (aEditSubAction) {
     case EditSubAction::eCreateOrRemoveBlock:
+    case EditSubAction::eMergeBlockContents:
     case EditSubAction::eCreateOrChangeList:
     case EditSubAction::eSetOrClearAlignment:
     case EditSubAction::eSetPositionToAbsolute:
     case EditSubAction::eIndent:
     case EditSubAction::eOutdent:
       for (int32_t i = aArrayOfNodes.Length() - 1; i >= 0; i--) {
         OwningNonNull<nsINode> node = aArrayOfNodes[i];
         if (HTMLEditor::NodeIsInlineStatic(node) && IsContainer(node) &&
@@ -7649,68 +7675,16 @@ Element* HTMLEditor::GetParentListElemen
       if (HTMLEditUtils::IsList(parent)) {
         return parent->AsElement();
       }
     }
   }
   return nullptr;
 }
 
-nsresult HTMLEditRules::GetListActionNodes(
-    nsTArray<OwningNonNull<nsINode>>& aOutArrayOfNodes) const {
-  MOZ_ASSERT(IsEditorDataAvailable());
-
-  // Pre-process our list of nodes
-  for (int32_t i = aOutArrayOfNodes.Length() - 1; i >= 0; i--) {
-    OwningNonNull<nsINode> testNode = aOutArrayOfNodes[i];
-
-    // Scan for table elements and divs.  If we find table elements other than
-    // table, replace it with a list of any editable non-table content.
-    if (HTMLEditUtils::IsTableElementButNotTable(testNode)) {
-      // XXX Before we're called, non-editable nodes are ignored.  However,
-      //     we may append non-editable nodes in table elements here.
-      aOutArrayOfNodes.RemoveElementAt(i);
-      HTMLEditorRef().CollectChildren(*testNode, aOutArrayOfNodes, i,
-                                      HTMLEditor::CollectListChildren::No,
-                                      HTMLEditor::CollectTableChildren::Yes,
-                                      HTMLEditor::CollectNonEditableNodes::Yes);
-    }
-  }
-
-  // If there is only one node in the array, and it is a list, div, or
-  // blockquote, then look inside of it until we find inner list or content.
-  if (aOutArrayOfNodes.Length() != 1) {
-    return NS_OK;
-  }
-
-  Element* deepestDivBlockquoteOrListElement =
-      HTMLEditorRef().GetDeepestEditableOnlyChildDivBlockquoteOrListElement(
-          aOutArrayOfNodes[0]);
-  if (!deepestDivBlockquoteOrListElement) {
-    return NS_OK;
-  }
-
-  if (deepestDivBlockquoteOrListElement->IsAnyOfHTMLElements(
-          nsGkAtoms::div, nsGkAtoms::blockquote)) {
-    aOutArrayOfNodes.Clear();
-    // XXX Before we're called, non-editable nodes are ignored.  However,
-    //     we may append non-editable nodes here.
-    HTMLEditorRef().CollectChildren(*deepestDivBlockquoteOrListElement,
-                                    aOutArrayOfNodes, 0,
-                                    HTMLEditor::CollectListChildren::No,
-                                    HTMLEditor::CollectTableChildren::No,
-                                    HTMLEditor::CollectNonEditableNodes::Yes);
-    return NS_OK;
-  }
-
-  aOutArrayOfNodes.ReplaceElementAt(
-      0, OwningNonNull<nsINode>(*deepestDivBlockquoteOrListElement));
-  return NS_OK;
-}
-
 Element* HTMLEditor::GetDeepestEditableOnlyChildDivBlockquoteOrListElement(
     nsINode& aNode) {
   if (!aNode.IsElement()) {
     return nullptr;
   }
   // XXX If aNode is non-editable, shouldn't we return nullptr here?
   Element* parentElement = nullptr;
   for (nsIContent* content = aNode.AsContent();
--- a/editor/libeditor/HTMLEditRules.h
+++ b/editor/libeditor/HTMLEditRules.h
@@ -781,18 +781,16 @@ class HTMLEditRules : public TextEditRul
    * NormalizeSelection() adjust Selection if it's not collapsed and there is
    * only one range.  If range start and/or end point is <br> node or something
    * non-editable point, they should be moved to nearest text node or something
    * where the other methods easier to handle edit action.
    */
   MOZ_CAN_RUN_SCRIPT
   MOZ_MUST_USE nsresult NormalizeSelection();
 
-  MOZ_MUST_USE nsresult
-  GetListActionNodes(nsTArray<OwningNonNull<nsINode>>& aOutArrayOfNodes) const;
   void GetDefinitionListItemTypes(Element* aElement, bool* aDT,
                                   bool* aDD) const;
   MOZ_CAN_RUN_SCRIPT
   nsresult GetParagraphFormatNodes(
       nsTArray<OwningNonNull<nsINode>>& outArrayOfNodes);
 
   /**
    * MakeTransitionList() detects all the transitions in the array, where a
--- a/editor/libeditor/HTMLEditor.h
+++ b/editor/libeditor/HTMLEditor.h
@@ -1323,17 +1323,17 @@ class HTMLEditor final : public TextEdit
    * result for specific edit sub-actions.
    * FYI: You can use CollectEditTargetNodesInExtendedSelectionRanges() instead
    *      if you want to call this with extended selection ranges.
    */
   nsresult CollectEditTargetNodes(
       nsTArray<RefPtr<nsRange>>& aArrayOfRanges,
       nsTArray<OwningNonNull<nsINode>>& aOutArrayOfNodes,
       EditSubAction aEditSubAction,
-      CollectNonEditableNodes aCollectNonEditableNodes) const;
+      CollectNonEditableNodes aCollectNonEditableNodes);
 
   /**
    * GetWhiteSpaceEndPoint() returns point at first or last ASCII whitespace
    * or non-breakable space starting from aPoint.  I.e., this returns next or
    * previous point whether the character is neither ASCII whitespace nor
    * non-brekable space.
    */
   enum class ScanDirection { Backward, Forward };
--- a/testing/web-platform/meta/editing/run/insert-list-items-in-table-cell.html.ini
+++ b/testing/web-platform/meta/editing/run/insert-list-items-in-table-cell.html.ini
@@ -1,15 +1,39 @@
 [insert-list-items-in-table-cell.html]
   [[["insertOrderedList",""\]\] "<div contenteditable=\\"true\\"><table><tr><td>[fsdf\]</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>" queryCommandValue("insertOrderedList") before]
     expected: FAIL
 
   [[["insertOrderedList",""\]\] "<div contenteditable=\\"true\\"><table><tr><td>[fsdf\]</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>" queryCommandValue("insertOrderedList") after]
     expected: FAIL
 
+  [[["insertOrderedList",""\]\] "<div contenteditable=\\"true\\"><table><tr><td>[fs<br>df\]</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>" queryCommandValue("insertOrderedList") before]
+    expected: FAIL
+
+  [[["insertOrderedList",""\]\] "<div contenteditable=\\"true\\"><table><tr><td>[fs<br>df\]</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>" queryCommandValue("insertOrderedList") after]
+    expected: FAIL
+
+  [[["insertOrderedList",""\]\] "<div contenteditable=\\"true\\"><table><tr><td>[f<b>s<br>d</b>f\]</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>" queryCommandValue("insertOrderedList") before]
+    expected: FAIL
+
+  [[["insertOrderedList",""\]\] "<div contenteditable=\\"true\\"><table><tr><td>[f<b>s<br>d</b>f\]</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>" queryCommandValue("insertOrderedList") after]
+    expected: FAIL
+
+  [[["insertOrderedList",""\]\] "<div contenteditable=\\"true\\"><table><tr><td>[fs\]<br>df</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>" queryCommandValue("insertOrderedList") before]
+    expected: FAIL
+
+  [[["insertOrderedList",""\]\] "<div contenteditable=\\"true\\"><table><tr><td>[fs\]<br>df</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>" queryCommandValue("insertOrderedList") after]
+    expected: FAIL
+
+  [[["insertOrderedList",""\]\] "<div contenteditable=\\"true\\"><table><tr><td>[f<b>s\]<br>d</b>f</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>" queryCommandValue("insertOrderedList") before]
+    expected: FAIL
+
+  [[["insertOrderedList",""\]\] "<div contenteditable=\\"true\\"><table><tr><td>[f<b>s\]<br>d</b>f</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>" queryCommandValue("insertOrderedList") after]
+    expected: FAIL
+
   [[["insertOrderedList",""\]\] "<div contenteditable=\\"true\\"><table><tr data-start=0 data-end=2><td>fsdf</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>" queryCommandValue("insertOrderedList") before]
     expected: FAIL
 
   [[["insertOrderedList",""\]\] "<div contenteditable=\\"true\\"><table><tr data-start=0 data-end=2><td>fsdf</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>" queryCommandState("insertOrderedList") after]
     expected: FAIL
 
   [[["insertOrderedList",""\]\] "<div contenteditable=\\"true\\"><table><tr data-start=0 data-end=2><td>fsdf</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>" queryCommandValue("insertOrderedList") after]
     expected: FAIL
--- a/testing/web-platform/tests/editing/data/insert-list-items-in-table-cells.js
+++ b/testing/web-platform/tests/editing/data/insert-list-items-in-table-cells.js
@@ -1,15 +1,35 @@
 // For documentation of the format, see README in this directory.
 var browserTests = [
 ['<div contenteditable="true"><table><tr><td>[fsdf]</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>',
     [["insertOrderedList",""]],
     '<div contenteditable="true"><table><tbody><tr><td><ol><li>fsdf</li></ol></td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></tbody></table></div>',
     [true],
     {"insertOrderedList":[false,false,"false",false,true,"true"]}],
+['<div contenteditable="true"><table><tr><td>[fs<br>df]</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>',
+    [["insertOrderedList",""]],
+    '<div contenteditable="true"><table><tbody><tr><td><ol><li>fs</li><li>df</li></ol></td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></tbody></table></div>',
+    [true],
+    {"insertOrderedList":[false,false,"false",false,true,"true"]}],
+['<div contenteditable="true"><table><tr><td>[f<b>s<br>d</b>f]</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>',
+    [["insertOrderedList",""]],
+    '<div contenteditable="true"><table><tbody><tr><td><ol><li>f<b>s</b></li><li><b>d</b>f</li></ol></td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></tbody></table></div>',
+    [true],
+    {"insertOrderedList":[false,false,"false",false,true,"true"]}],
+['<div contenteditable="true"><table><tr><td>[fs]<br>df</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>',
+    [["insertOrderedList",""]],
+    '<div contenteditable="true"><table><tbody><tr><td><ol><li>fs</li></ol>df</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></tbody></table></div>',
+    [true],
+    {"insertOrderedList":[false,false,"false",false,true,"true"]}],
+['<div contenteditable="true"><table><tr><td>[f<b>s]<br>d</b>f</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>',
+    [["insertOrderedList",""]],
+    '<div contenteditable="true"><table><tbody><tr><td><ol><li>f<b>s</b></li></ol><b>d</b>f</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></tbody></table></div>',
+    [true],
+    {"insertOrderedList":[false,false,"false",false,true,"true"]}],
 ['<div contenteditable="true"><table><tr data-start=0 data-end=2><td>fsdf</td><td>fsdf</td></tr><tr><td>gghfg</td><td>fsfg</td></tr></table></div>',
     [["insertOrderedList",""]],
     '<div contenteditable="true"><table><tbody><tr><td><ol><li>fsdf</li></ol></td><td><ol><li>fsdf</li></ol></td></tr><tr><td>gghfg</td><td>fsfg</td></tr></tbody></table></div>',
     [true],
     {"insertOrderedList":[false,false,"false",false,false,"false"]}],
 ['<div contenteditable="true"><table><tr data-start=0><td>fsdf</td><td>fsdf</td></tr><tr data-end=2><td>gghfg</td><td>fsfg</td></tr></table></div>',
     [["insertOrderedList",""]],
     '<div contenteditable="true"><table><tbody><tr><td><ol><li>fsdf</li></ol></td><td><ol><li>fsdf</li></ol></td></tr><tr><td><ol><li>gghfg</li></ol></td><td><ol><li>fsfg</li></ol></td></tr></tbody></table></div>',