Title: [237976] trunk
Revision
237976
Author
[email protected]
Date
2018-11-07 19:14:37 -0800 (Wed, 07 Nov 2018)

Log Message

Add an editing command for creating and inserting child lists
https://bugs.webkit.org/show_bug.cgi?id=191335
<rdar://problem/45814050>

Reviewed by Ryosuke Niwa.

Source/WebCore:

Currently, insertOrderedList and insertUnorderedList only toggle or change list state (i.e. if the selection is
in an ordered or unordered list, reinserting the same list type removes the current list, and inserting a
different list type changes the enclosing list).

However, for certain internal clients (e.g. Mail), if the start of the selection is enclosed by a list item, we
instead create a new list item and insert it after the enclosing list item, and then create a new list within
that list item. Currently, this logic is implemented in Mail for legacy-WebKit-based Mail compose. This patch
brings this logic into WebKit in the form of a new editing command.

Tests: editing/execCommand/insert-nested-lists-in-table.html
       editing/execCommand/insert-nested-lists-with-pre.html
       editing/execCommand/insert-nested-lists.html

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* editing/Editor.cpp:
(WebCore::Editor::insertOrderedList):
(WebCore::Editor::insertUnorderedList):
* editing/EditorCommand.cpp:
(WebCore::executeInsertOrderedList):
(WebCore::executeInsertUnorderedList):
(WebCore::executeInsertNestedUnorderedList):
(WebCore::executeInsertNestedOrderedList):
(WebCore::createCommandMap):
* editing/IndentOutdentCommand.cpp:
(WebCore::IndentOutdentCommand::outdentParagraph):
* editing/InsertListCommand.cpp:
(WebCore::InsertListCommand::doApply):
(WebCore::InsertListCommand::editingAction const):
* editing/InsertListCommand.h:

Change a couple of `enum`s into `enum class`es.

* editing/InsertNestedListCommand.cpp: Added.
(WebCore::InsertNestedListCommand::insertUnorderedList):
(WebCore::InsertNestedListCommand::insertOrderedList):
(WebCore::InsertNestedListCommand::doApply):
* editing/InsertNestedListCommand.h: Added.

Add a new edit command to insert a new list (as a child of any containing list). If the start of the selection
is in a list item, we create a new list item, move the selection into the list item, and increment its list
level; otherwise, simply fall back to inserting a list.

* editing/ModifySelectionListLevel.cpp:
(WebCore::IncreaseSelectionListLevelCommand::doApply):
(WebCore::IncreaseSelectionListLevelCommand::increaseSelectionListLevel):
(WebCore::IncreaseSelectionListLevelCommand::increaseSelectionListLevelOrdered):
(WebCore::IncreaseSelectionListLevelCommand::increaseSelectionListLevelUnordered):
* editing/ModifySelectionListLevel.h:

Expose this constructor, allowing other edit commands to change selection list level as a composite edit
command. Also, change an `enum` into an `enum class`.

(WebCore::IncreaseSelectionListLevelCommand::create):

LayoutTests:

Add a new layout tests that exercise the "InsertNested(Un)orderedList" editing commands in several scenarios
including undo, redo, executing the edit command with a ranged selection, outdenting to decrease list level,
inserting lists in and around tables and table cells, and inserting lists in and around pre elements.

* editing/execCommand/insert-nested-lists-expected.txt: Added.
* editing/execCommand/insert-nested-lists-in-table-expected.txt: Added.
* editing/execCommand/insert-nested-lists-in-table.html: Added.
* editing/execCommand/insert-nested-lists-with-pre-expected.txt: Added.
* editing/execCommand/insert-nested-lists-with-pre.html: Added.
* editing/execCommand/insert-nested-lists.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (237975 => 237976)


--- trunk/LayoutTests/ChangeLog	2018-11-08 03:11:33 UTC (rev 237975)
+++ trunk/LayoutTests/ChangeLog	2018-11-08 03:14:37 UTC (rev 237976)
@@ -1,3 +1,22 @@
+2018-11-07  Wenson Hsieh  <[email protected]>
+
+        Add an editing command for creating and inserting child lists
+        https://bugs.webkit.org/show_bug.cgi?id=191335
+        <rdar://problem/45814050>
+
+        Reviewed by Ryosuke Niwa.
+
+        Add a new layout tests that exercise the "InsertNested(Un)orderedList" editing commands in several scenarios
+        including undo, redo, executing the edit command with a ranged selection, outdenting to decrease list level,
+        inserting lists in and around tables and table cells, and inserting lists in and around pre elements.
+
+        * editing/execCommand/insert-nested-lists-expected.txt: Added.
+        * editing/execCommand/insert-nested-lists-in-table-expected.txt: Added.
+        * editing/execCommand/insert-nested-lists-in-table.html: Added.
+        * editing/execCommand/insert-nested-lists-with-pre-expected.txt: Added.
+        * editing/execCommand/insert-nested-lists-with-pre.html: Added.
+        * editing/execCommand/insert-nested-lists.html: Added.
+
 2018-11-07  Chris Dumez  <[email protected]>
 
         ASSERT(renderer()) under HTMLTextAreaElement::updateValue()

Added: trunk/LayoutTests/editing/execCommand/insert-nested-lists-expected.txt (0 => 237976)


--- trunk/LayoutTests/editing/execCommand/insert-nested-lists-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/editing/execCommand/insert-nested-lists-expected.txt	2018-11-08 03:14:37 UTC (rev 237976)
@@ -0,0 +1,94 @@
+Verifies that 'InsertNestedUnorderedList' and 'InsertNestedOrderedList' work as expected. This test requires WebKitTestRunner or DumpRenderTree.
+
+After unordered list insertion:
+| <ul>
+|   <li>
+|     "foo<#selection-caret>"
+|     <br>
+
+After typing and ordered sublist insertion:
+| <ul>
+|   <li>
+|     "foo"
+|     <br>
+|   <ol>
+|     <li>
+|       "bar<#selection-caret>"
+
+After the second unordered list insertion:
+| <ul>
+|   <li>
+|     "foo"
+|     <br>
+|   <ol>
+|     <li>
+|       "bar"
+|     <ul>
+|       <li>
+|         <#selection-caret>
+
+After undoing the last list insertion:
+| <ul>
+|   <li>
+|     "foo"
+|     <br>
+|   <ol>
+|     <li>
+|       "bar<#selection-caret>"
+
+After redoing the last list insertion:
+| <ul>
+|   <li>
+|     "foo"
+|     <br>
+|   <ol>
+|     <li>
+|       "bar"
+|     <ul>
+|       <li>
+|         <#selection-caret>
+
+After selecting a range and inserting another unordered list:
+| <ul>
+|   <li>
+|     "foo"
+|     <br>
+|   <ol>
+|     <li>
+|       "bar"
+|     <ul>
+|       <li>
+|         <#selection-caret>
+|       <ul>
+|         <li>
+
+After outdenting:
+| <ul>
+|   <li>
+|     "foo"
+|     <br>
+|   <ol>
+|     <li>
+|       "bar"
+|     <li>
+|       <#selection-caret>
+|       <br>
+|     <ul>
+|       <ul>
+|         <li>
+
+After outdenting again:
+| <ul>
+|   <li>
+|     "foo"
+|     <br>
+|   <ol>
+|     <li>
+|       "bar"
+|   <li>
+|     "baz<#selection-caret>"
+|     <br>
+|   <ol>
+|     <ul>
+|       <ul>
+|         <li>

Added: trunk/LayoutTests/editing/execCommand/insert-nested-lists-in-table-expected.txt (0 => 237976)


--- trunk/LayoutTests/editing/execCommand/insert-nested-lists-in-table-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/editing/execCommand/insert-nested-lists-in-table-expected.txt	2018-11-08 03:14:37 UTC (rev 237976)
@@ -0,0 +1,142 @@
+Verifies that 'InsertNestedUnorderedList' and 'InsertNestedOrderedList' work as expected in table cells. This test requires WebKitTestRunner or DumpRenderTree.
+
+After inserting a list in a table cell:
+| "
+    "
+| <table>
+|   "
+        "
+|   <tbody>
+|     "
+            "
+|     <tr>
+|       <th>
+|         "Left"
+|       <th>
+|         "Right"
+|     "
+            "
+|     <tr>
+|       <td>
+|         id="foo"
+|         "Foo"
+|       <td>
+|         "Bar"
+|     "
+            "
+|     <tr>
+|       <td>
+|         "Baz"
+|       <td>
+|         id="garply"
+|         <ol>
+|           <li>
+|             "<#selection-caret>Garply"
+|             <br>
+|       " "
+|     "
+        "
+|   "
+    "
+| "
+"
+
+After wrapping the table in a list:
+| "
+    "
+| <ul>
+|   <li>
+|     <#selection-anchor>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <th>
+|             "Left"
+|           <th>
+|             "Right"
+|         <tr>
+|           <td>
+|             id="foo"
+|             "Foo"
+|           <td>
+|             "Bar"
+|         <tr>
+|           <td>
+|             "Baz"
+|           <td>
+|             id="garply"
+|             <ol>
+|               <li>
+|                 "Garply"
+|                 <br>
+|     <#selection-focus>
+| "
+"
+
+After inserting a nested list below the outer list:
+| "
+    "
+| <ul>
+|   <li>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <th>
+|             "Left"
+|           <th>
+|             "Right"
+|         <tr>
+|           <td>
+|             id="foo"
+|             "Foo"
+|           <td>
+|             "Bar"
+|         <tr>
+|           <td>
+|             "Baz"
+|           <td>
+|             id="garply"
+|             <ol>
+|               <li>
+|                 "Garply"
+|                 <br>
+|   <ul>
+|     <li>
+|       <#selection-caret>
+| "
+"
+
+After inserting another list under a table cell:
+| "
+    "
+| <ul>
+|   <li>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <th>
+|             "Left"
+|           <th>
+|             "Right"
+|         <tr>
+|           <td>
+|             id="foo"
+|             "Foo"
+|           <td>
+|             "Bar"
+|         <tr>
+|           <td>
+|             "Baz"
+|           <td>
+|             id="garply"
+|             <ol>
+|               <li>
+|                 "Garply"
+|                 <br>
+|               <ol>
+|                 <li>
+|                   <#selection-caret>
+|   <ul>
+|     <li>
+| "
+"

Added: trunk/LayoutTests/editing/execCommand/insert-nested-lists-in-table.html (0 => 237976)


--- trunk/LayoutTests/editing/execCommand/insert-nested-lists-in-table.html	                        (rev 0)
+++ trunk/LayoutTests/editing/execCommand/insert-nested-lists-in-table.html	2018-11-08 03:14:37 UTC (rev 237976)
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+<div contenteditable id="editor">
+    <table>
+        <tbody>
+            <tr><th>Left</th><th>Right</th></tr>
+            <tr><td id="foo">Foo</td><td>Bar</td></tr>
+            <tr><td>Baz</td><td id="garply">Garply</td> </tr>
+        </tbody>
+    </table>
+</div>
+</body>
+<script>
+Markup.description("Verifies that 'InsertNestedUnorderedList' and 'InsertNestedOrderedList' work as expected in table cells. This test requires WebKitTestRunner or DumpRenderTree.");
+
+editor.focus();
+getSelection().setPosition(garply.childNodes[0], 0);
+document.execCommand("InsertNestedOrderedList");
+Markup.dump("editor", "After inserting a list in a table cell");
+
+selectAllCommand();
+document.execCommand("InsertNestedUnorderedList");
+Markup.dump("editor", "After wrapping the table in a list");
+
+getSelection().setPosition(foo.childNodes[0], 0);
+document.execCommand("InsertNestedUnorderedList");
+Markup.dump("editor", "After inserting a nested list below the outer list");
+
+getSelection().setPosition(garply.childNodes[0], 3);
+document.execCommand("InsertNestedOrderedList");
+Markup.dump("editor", "After inserting another list under a table cell");
+</script>
+</html>

Added: trunk/LayoutTests/editing/execCommand/insert-nested-lists-with-pre-expected.txt (0 => 237976)


--- trunk/LayoutTests/editing/execCommand/insert-nested-lists-with-pre-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/editing/execCommand/insert-nested-lists-with-pre-expected.txt	2018-11-08 03:14:37 UTC (rev 237976)
@@ -0,0 +1,36 @@
+Verifies that 'InsertNestedUnorderedList' and 'InsertNestedOrderedList' work as expected with pre elements. This test requires WebKitTestRunner or DumpRenderTree.
+
+After inserting a list inside the pre:
+| "
+    "
+| <pre>
+|   id="pre"
+|   "Hello"
+|   <ul>
+|     <li>
+|       id="foo"
+|       "foo"
+|     <ol>
+|       <li>
+|         <#selection-caret>
+|   "world"
+| "
+"
+
+After inserting a list around the pre:
+| "
+    "
+| <pre>
+|   id="pre"
+|   <ul>
+|     <li>
+|       "<#selection-caret>Hello"
+|       <br>
+|     <li>
+|       id="foo"
+|       "foo"
+|     <ol>
+|       <li>
+|   "world"
+| "
+"

Added: trunk/LayoutTests/editing/execCommand/insert-nested-lists-with-pre.html (0 => 237976)


--- trunk/LayoutTests/editing/execCommand/insert-nested-lists-with-pre.html	                        (rev 0)
+++ trunk/LayoutTests/editing/execCommand/insert-nested-lists-with-pre.html	2018-11-08 03:14:37 UTC (rev 237976)
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+<div contenteditable id="editor">
+    <pre id="pre">Hello<ul><li id="foo">foo</li></ul>world</pre>
+</div>
+</body>
+<script>
+Markup.description("Verifies that 'InsertNestedUnorderedList' and 'InsertNestedOrderedList' work as expected with pre elements. This test requires WebKitTestRunner or DumpRenderTree.");
+
+editor.focus();
+getSelection().setPosition(foo.childNodes[0], 0);
+document.execCommand("InsertNestedOrderedList");
+Markup.dump("editor", "After inserting a list inside the pre");
+
+getSelection().setPosition(pre.childNodes[0], 0);
+document.execCommand("InsertNestedUnorderedList");
+Markup.dump("editor", "After inserting a list around the pre");
+</script>
+</html>

Added: trunk/LayoutTests/editing/execCommand/insert-nested-lists.html (0 => 237976)


--- trunk/LayoutTests/editing/execCommand/insert-nested-lists.html	                        (rev 0)
+++ trunk/LayoutTests/editing/execCommand/insert-nested-lists.html	2018-11-08 03:14:37 UTC (rev 237976)
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+<div contenteditable id="editor"></div>
+</body>
+<script>
+(async () => {
+    Markup.waitUntilDone();
+    Markup.description("Verifies that 'InsertNestedUnorderedList' and 'InsertNestedOrderedList' work as expected. This test requires WebKitTestRunner or DumpRenderTree.");
+    editor.focus();
+
+    [..."foo"].map(typeCharacterCommand);
+    document.execCommand("InsertNestedUnorderedList");
+    Markup.dump("editor", "After unordered list insertion");
+
+    document.execCommand("InsertNestedOrderedList");
+    [..."bar"].map(typeCharacterCommand);
+    Markup.dump("editor", "After typing and ordered sublist insertion");
+
+    // By default, AppKit on macOS coalesces undo operations that occur within the same runloop. Wait until the next
+    // runloop before inserting another unordered list to ensure that it gets its own entry in the undo stack.
+    await new Promise(resolve => requestAnimationFrame(resolve));
+
+    document.execCommand("InsertNestedUnorderedList");
+    Markup.dump("editor", "After the second unordered list insertion");
+
+    undoCommand();
+    Markup.dump("editor", "After undoing the last list insertion");
+
+    redoCommand();
+    Markup.dump("editor", "After redoing the last list insertion");
+
+    execExtendSelectionBackwardByLineCommand();
+    document.execCommand("InsertNestedUnorderedList");
+    Markup.dump("editor", "After selecting a range and inserting another unordered list");
+
+    document.execCommand("Outdent");
+    Markup.dump("editor", "After outdenting");
+
+    [..."baz"].map(typeCharacterCommand);
+    document.execCommand("Outdent");
+    Markup.dump("editor", "After outdenting again");
+    Markup.notifyDone();
+})();
+</script>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (237975 => 237976)


--- trunk/Source/WebCore/ChangeLog	2018-11-08 03:11:33 UTC (rev 237975)
+++ trunk/Source/WebCore/ChangeLog	2018-11-08 03:14:37 UTC (rev 237976)
@@ -1,3 +1,66 @@
+2018-11-07  Wenson Hsieh  <[email protected]>
+
+        Add an editing command for creating and inserting child lists
+        https://bugs.webkit.org/show_bug.cgi?id=191335
+        <rdar://problem/45814050>
+
+        Reviewed by Ryosuke Niwa.
+
+        Currently, insertOrderedList and insertUnorderedList only toggle or change list state (i.e. if the selection is
+        in an ordered or unordered list, reinserting the same list type removes the current list, and inserting a
+        different list type changes the enclosing list).
+
+        However, for certain internal clients (e.g. Mail), if the start of the selection is enclosed by a list item, we
+        instead create a new list item and insert it after the enclosing list item, and then create a new list within
+        that list item. Currently, this logic is implemented in Mail for legacy-WebKit-based Mail compose. This patch
+        brings this logic into WebKit in the form of a new editing command.
+
+        Tests: editing/execCommand/insert-nested-lists-in-table.html
+               editing/execCommand/insert-nested-lists-with-pre.html
+               editing/execCommand/insert-nested-lists.html
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * editing/Editor.cpp:
+        (WebCore::Editor::insertOrderedList):
+        (WebCore::Editor::insertUnorderedList):
+        * editing/EditorCommand.cpp:
+        (WebCore::executeInsertOrderedList):
+        (WebCore::executeInsertUnorderedList):
+        (WebCore::executeInsertNestedUnorderedList):
+        (WebCore::executeInsertNestedOrderedList):
+        (WebCore::createCommandMap):
+        * editing/IndentOutdentCommand.cpp:
+        (WebCore::IndentOutdentCommand::outdentParagraph):
+        * editing/InsertListCommand.cpp:
+        (WebCore::InsertListCommand::doApply):
+        (WebCore::InsertListCommand::editingAction const):
+        * editing/InsertListCommand.h:
+
+        Change a couple of `enum`s into `enum class`es.
+
+        * editing/InsertNestedListCommand.cpp: Added.
+        (WebCore::InsertNestedListCommand::insertUnorderedList):
+        (WebCore::InsertNestedListCommand::insertOrderedList):
+        (WebCore::InsertNestedListCommand::doApply):
+        * editing/InsertNestedListCommand.h: Added.
+
+        Add a new edit command to insert a new list (as a child of any containing list). If the start of the selection
+        is in a list item, we create a new list item, move the selection into the list item, and increment its list
+        level; otherwise, simply fall back to inserting a list.
+
+        * editing/ModifySelectionListLevel.cpp:
+        (WebCore::IncreaseSelectionListLevelCommand::doApply):
+        (WebCore::IncreaseSelectionListLevelCommand::increaseSelectionListLevel):
+        (WebCore::IncreaseSelectionListLevelCommand::increaseSelectionListLevelOrdered):
+        (WebCore::IncreaseSelectionListLevelCommand::increaseSelectionListLevelUnordered):
+        * editing/ModifySelectionListLevel.h:
+
+        Expose this constructor, allowing other edit commands to change selection list level as a composite edit
+        command. Also, change an `enum` into an `enum class`.
+
+        (WebCore::IncreaseSelectionListLevelCommand::create):
+
 2018-11-07  Chris Dumez  <[email protected]>
 
         ASSERT(renderer()) under HTMLTextAreaElement::updateValue()

Modified: trunk/Source/WebCore/Sources.txt (237975 => 237976)


--- trunk/Source/WebCore/Sources.txt	2018-11-08 03:11:33 UTC (rev 237975)
+++ trunk/Source/WebCore/Sources.txt	2018-11-08 03:14:37 UTC (rev 237976)
@@ -903,6 +903,7 @@
 editing/FormatBlockCommand.cpp
 editing/FrameSelection.cpp
 editing/HTMLInterchange.cpp
+editing/InsertNestedListCommand.cpp
 editing/IndentOutdentCommand.cpp
 editing/InsertIntoTextNodeCommand.cpp
 editing/InsertLineBreakCommand.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (237975 => 237976)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2018-11-08 03:11:33 UTC (rev 237975)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2018-11-08 03:14:37 UTC (rev 237976)
@@ -4885,6 +4885,7 @@
 		F47A09D120A93A9700240FAE /* DisabledAdaptations.h in Headers */ = {isa = PBXBuildFile; fileRef = F47A09CF20A939F600240FAE /* DisabledAdaptations.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		F47A5E3E195B8C8A00483100 /* StyleScrollSnapPoints.h in Headers */ = {isa = PBXBuildFile; fileRef = F47A5E3B195B8C8A00483100 /* StyleScrollSnapPoints.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		F47A633D1FF6FD500081B3CC /* PromisedAttachmentInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = F47A633C1FF6FD500081B3CC /* PromisedAttachmentInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		F47AD23B21934FF40051DD0B /* InsertNestedListCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = F47AD2382193499A0051DD0B /* InsertNestedListCommand.h */; };
 		F48223101E3869B80066FC79 /* WebItemProviderPasteboard.mm in Sources */ = {isa = PBXBuildFile; fileRef = F482230E1E3869B80066FC79 /* WebItemProviderPasteboard.mm */; };
 		F48223111E3869B80066FC79 /* WebItemProviderPasteboard.h in Headers */ = {isa = PBXBuildFile; fileRef = F482230F1E3869B80066FC79 /* WebItemProviderPasteboard.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		F48223131E386E240066FC79 /* AbstractPasteboard.h in Headers */ = {isa = PBXBuildFile; fileRef = F48223121E386E240066FC79 /* AbstractPasteboard.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -14830,6 +14831,8 @@
 		F47A5E3A195B8C8A00483100 /* StyleScrollSnapPoints.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleScrollSnapPoints.cpp; sourceTree = "<group>"; };
 		F47A5E3B195B8C8A00483100 /* StyleScrollSnapPoints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleScrollSnapPoints.h; sourceTree = "<group>"; };
 		F47A633C1FF6FD500081B3CC /* PromisedAttachmentInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PromisedAttachmentInfo.h; sourceTree = "<group>"; };
+		F47AD2382193499A0051DD0B /* InsertNestedListCommand.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InsertNestedListCommand.h; sourceTree = "<group>"; };
+		F47AD2392193499A0051DD0B /* InsertNestedListCommand.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InsertNestedListCommand.cpp; sourceTree = "<group>"; };
 		F482230E1E3869B80066FC79 /* WebItemProviderPasteboard.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebItemProviderPasteboard.mm; sourceTree = "<group>"; };
 		F482230F1E3869B80066FC79 /* WebItemProviderPasteboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebItemProviderPasteboard.h; sourceTree = "<group>"; };
 		F48223121E386E240066FC79 /* AbstractPasteboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AbstractPasteboard.h; sourceTree = "<group>"; };
@@ -20658,6 +20661,8 @@
 				93309D9D099E64910056E581 /* InsertLineBreakCommand.h */,
 				D07DEAB70A36554A00CA30F8 /* InsertListCommand.cpp */,
 				D07DEAB80A36554A00CA30F8 /* InsertListCommand.h */,
+				F47AD2392193499A0051DD0B /* InsertNestedListCommand.cpp */,
+				F47AD2382193499A0051DD0B /* InsertNestedListCommand.h */,
 				93309D9E099E64910056E581 /* InsertNodeBeforeCommand.cpp */,
 				93309D9F099E64910056E581 /* InsertNodeBeforeCommand.h */,
 				93309DA0099E64910056E581 /* InsertParagraphSeparatorCommand.cpp */,
@@ -28631,7 +28636,6 @@
 				51E399021D6E4750009C8831 /* GameControllerGamepadProvider.h in Headers */,
 				516C62211950D48700337E75 /* GamepadEvent.h in Headers */,
 				51A9D9EA195B931F001B2B5C /* GamepadManager.h in Headers */,
-				412DE4B8219285C00075F3A7 /* RTCRtpCapabilities.h in Headers */,
 				515BE1921D54F5FB00DD7C68 /* GamepadProvider.h in Headers */,
 				515BE1931D54F5FB00DD7C68 /* GamepadProviderClient.h in Headers */,
 				8EC6C963201A251600FBFA53 /* GapLength.h in Headers */,
@@ -28982,6 +28986,7 @@
 				93309DEA099E64920056E581 /* InsertIntoTextNodeCommand.h in Headers */,
 				93309DEC099E64920056E581 /* InsertLineBreakCommand.h in Headers */,
 				D07DEABA0A36554A00CA30F8 /* InsertListCommand.h in Headers */,
+				F47AD23B21934FF40051DD0B /* InsertNestedListCommand.h in Headers */,
 				93309DEE099E64920056E581 /* InsertNodeBeforeCommand.h in Headers */,
 				93309DF0099E64920056E581 /* InsertParagraphSeparatorCommand.h in Headers */,
 				93309DF2099E64920056E581 /* InsertTextCommand.h in Headers */,
@@ -30698,6 +30703,7 @@
 				078E094217D16E1C00420AA1 /* RTCPeerConnectionHandlerClient.h in Headers */,
 				078E092417D14D1C00420AA1 /* RTCPeerConnectionIceEvent.h in Headers */,
 				5E2C437C1BCF9A840001E2BC /* RTCPeerConnectionInternalsBuiltins.h in Headers */,
+				412DE4B8219285C00075F3A7 /* RTCRtpCapabilities.h in Headers */,
 				5E2C43631BCEE32B0001E2BC /* RTCRtpReceiver.h in Headers */,
 				5E2C43611BCEE3230001E2BC /* RTCRtpSender.h in Headers */,
 				5E5E2B141CFC3E75000C0D85 /* RTCRtpTransceiver.h in Headers */,

Modified: trunk/Source/WebCore/editing/Editor.cpp (237975 => 237976)


--- trunk/Source/WebCore/editing/Editor.cpp	2018-11-08 03:11:33 UTC (rev 237975)
+++ trunk/Source/WebCore/editing/Editor.cpp	2018-11-08 03:14:37 UTC (rev 237976)
@@ -804,7 +804,7 @@
     if (!canEditRichly())
         return nullptr;
         
-    RefPtr<Node> newList = InsertListCommand::insertList(document(), InsertListCommand::OrderedList);
+    auto newList = InsertListCommand::insertList(document(), InsertListCommand::Type::OrderedList);
     revealSelectionAfterEditingOperation();
     return newList;
 }
@@ -814,7 +814,7 @@
     if (!canEditRichly())
         return nullptr;
         
-    RefPtr<Node> newList = InsertListCommand::insertList(document(), InsertListCommand::UnorderedList);
+    auto newList = InsertListCommand::insertList(document(), InsertListCommand::Type::UnorderedList);
     revealSelectionAfterEditingOperation();
     return newList;
 }

Modified: trunk/Source/WebCore/editing/EditorCommand.cpp (237975 => 237976)


--- trunk/Source/WebCore/editing/EditorCommand.cpp	2018-11-08 03:11:33 UTC (rev 237975)
+++ trunk/Source/WebCore/editing/EditorCommand.cpp	2018-11-08 03:14:37 UTC (rev 237976)
@@ -47,6 +47,7 @@
 #include "HTMLNames.h"
 #include "IndentOutdentCommand.h"
 #include "InsertListCommand.h"
+#include "InsertNestedListCommand.h"
 #include "Page.h"
 #include "Pasteboard.h"
 #include "RenderBox.h"
@@ -509,7 +510,7 @@
 static bool executeInsertOrderedList(Frame& frame, Event*, EditorCommandSource, const String&)
 {
     ASSERT(frame.document());
-    InsertListCommand::create(*frame.document(), InsertListCommand::OrderedList)->apply();
+    InsertListCommand::create(*frame.document(), InsertListCommand::Type::OrderedList)->apply();
     return true;
 }
 
@@ -533,10 +534,24 @@
 static bool executeInsertUnorderedList(Frame& frame, Event*, EditorCommandSource, const String&)
 {
     ASSERT(frame.document());
-    InsertListCommand::create(*frame.document(), InsertListCommand::UnorderedList)->apply();
+    InsertListCommand::create(*frame.document(), InsertListCommand::Type::UnorderedList)->apply();
     return true;
 }
 
+static bool executeInsertNestedUnorderedList(Frame& frame, Event*, EditorCommandSource, const String&)
+{
+    ASSERT(frame.document());
+    InsertNestedListCommand::insertUnorderedList(*frame.document());
+    return true;
+}
+
+static bool executeInsertNestedOrderedList(Frame& frame, Event*, EditorCommandSource, const String&)
+{
+    ASSERT(frame.document());
+    InsertNestedListCommand::insertOrderedList(*frame.document());
+    return true;
+}
+
 static bool executeJustifyCenter(Frame& frame, Event*, EditorCommandSource source, const String&)
 {
     return executeApplyParagraphStyle(frame, source, EditAction::Center, CSSPropertyTextAlign, "center"_s);
@@ -1582,10 +1597,12 @@
         { "InsertNewline", { executeInsertNewline, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, isTextInsertion, doNotAllowExecutionWhenDisabled } },    
         { "InsertNewlineInQuotedContent", { executeInsertNewlineInQuotedContent, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
         { "InsertOrderedList", { executeInsertOrderedList, supported, enabledInRichlyEditableText, stateOrderedList, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+        { "InsertNestedOrderedList", { executeInsertNestedOrderedList, supported, enabledInRichlyEditableText, stateOrderedList, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
         { "InsertParagraph", { executeInsertParagraph, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
         { "InsertTab", { executeInsertTab, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, isTextInsertion, doNotAllowExecutionWhenDisabled } },
         { "InsertText", { executeInsertText, supported, enabledInEditableText, stateNone, valueNull, isTextInsertion, doNotAllowExecutionWhenDisabled } },
         { "InsertUnorderedList", { executeInsertUnorderedList, supported, enabledInRichlyEditableText, stateUnorderedList, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+        { "InsertNestedUnorderedList", { executeInsertNestedUnorderedList, supported, enabledInRichlyEditableText, stateUnorderedList, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
         { "Italic", { executeToggleItalic, supported, enabledInRichlyEditableText, stateItalic, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
         { "JustifyCenter", { executeJustifyCenter, supported, enabledInRichlyEditableText, stateJustifyCenter, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
         { "JustifyFull", { executeJustifyFull, supported, enabledInRichlyEditableText, stateJustifyFull, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },

Modified: trunk/Source/WebCore/editing/IndentOutdentCommand.cpp (237975 => 237976)


--- trunk/Source/WebCore/editing/IndentOutdentCommand.cpp	2018-11-08 03:11:33 UTC (rev 237975)
+++ trunk/Source/WebCore/editing/IndentOutdentCommand.cpp	2018-11-08 03:14:37 UTC (rev 237976)
@@ -133,11 +133,11 @@
 
     // Use InsertListCommand to remove the selection from the list
     if (enclosingNode->hasTagName(olTag)) {
-        applyCommandToComposite(InsertListCommand::create(document(), InsertListCommand::OrderedList));
+        applyCommandToComposite(InsertListCommand::create(document(), InsertListCommand::Type::OrderedList));
         return;        
     }
     if (enclosingNode->hasTagName(ulTag)) {
-        applyCommandToComposite(InsertListCommand::create(document(), InsertListCommand::UnorderedList));
+        applyCommandToComposite(InsertListCommand::create(document(), InsertListCommand::Type::UnorderedList));
         return;
     }
     

Modified: trunk/Source/WebCore/editing/InsertListCommand.cpp (237975 => 237976)


--- trunk/Source/WebCore/editing/InsertListCommand.cpp	2018-11-08 03:11:33 UTC (rev 237975)
+++ trunk/Source/WebCore/editing/InsertListCommand.cpp	2018-11-08 03:14:37 UTC (rev 237976)
@@ -128,7 +128,7 @@
             return;
     }
 
-    auto& listTag = (m_type == OrderedList) ? olTag : ulTag;
+    auto& listTag = (m_type == Type::OrderedList) ? olTag : ulTag;
     if (endingSelection().isRange()) {
         VisibleSelection selection = selectionForParagraphIteration(endingSelection());
         ASSERT(selection.isRange());
@@ -192,7 +192,7 @@
 
 EditAction InsertListCommand::editingAction() const
 {
-    return m_type == OrderedList ? EditAction::InsertOrderedList : EditAction::InsertUnorderedList;
+    return m_type == Type::OrderedList ? EditAction::InsertOrderedList : EditAction::InsertUnorderedList;
 }
 
 void InsertListCommand::doApplyForSingleParagraph(bool forceCreateList, const HTMLQualifiedName& listTag, Range* currentSelection)

Modified: trunk/Source/WebCore/editing/InsertListCommand.h (237975 => 237976)


--- trunk/Source/WebCore/editing/InsertListCommand.h	2018-11-08 03:11:33 UTC (rev 237975)
+++ trunk/Source/WebCore/editing/InsertListCommand.h	2018-11-08 03:14:37 UTC (rev 237976)
@@ -34,7 +34,7 @@
 
 class InsertListCommand final : public CompositeEditCommand {
 public:
-    enum Type { OrderedList, UnorderedList };
+    enum class Type : uint8_t { OrderedList, UnorderedList };
 
     static Ref<InsertListCommand> create(Document& document, Type listType)
     {

Added: trunk/Source/WebCore/editing/InsertNestedListCommand.cpp (0 => 237976)


--- trunk/Source/WebCore/editing/InsertNestedListCommand.cpp	                        (rev 0)
+++ trunk/Source/WebCore/editing/InsertNestedListCommand.cpp	2018-11-08 03:14:37 UTC (rev 237976)
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "InsertNestedListCommand.h"
+
+#include "Editing.h"
+#include "HTMLLIElement.h"
+#include "HTMLNames.h"
+#include "InsertListCommand.h"
+#include "ModifySelectionListLevel.h"
+
+namespace WebCore {
+
+void InsertNestedListCommand::insertUnorderedList(Document& document)
+{
+    InsertNestedListCommand::create(document, Type::UnorderedList)->apply();
+}
+
+void InsertNestedListCommand::insertOrderedList(Document& document)
+{
+    InsertNestedListCommand::create(document, Type::OrderedList)->apply();
+}
+
+void InsertNestedListCommand::doApply()
+{
+    if (endingSelection().isNoneOrOrphaned() || !endingSelection().isContentRichlyEditable())
+        return;
+
+    if (auto enclosingItem = makeRefPtr(enclosingElementWithTag(endingSelection().visibleStart().deepEquivalent(), HTMLNames::liTag))) {
+        auto newListItem = HTMLLIElement::create(document());
+        insertNodeAfter(newListItem.copyRef(), *enclosingItem);
+        setEndingSelection({ Position { newListItem.ptr(), Position::PositionIsBeforeChildren }, DOWNSTREAM });
+
+        auto commandType = m_type == Type::OrderedList ? IncreaseSelectionListLevelCommand::Type::OrderedList : IncreaseSelectionListLevelCommand::Type::UnorderedList;
+        applyCommandToComposite(IncreaseSelectionListLevelCommand::create(document(), commandType));
+        return;
+    }
+
+    auto commandType = m_type == Type::OrderedList ? InsertListCommand::Type::OrderedList : InsertListCommand::Type::UnorderedList;
+    applyCommandToComposite(InsertListCommand::create(document(), commandType));
+}
+
+} // namespace WebCore

Added: trunk/Source/WebCore/editing/InsertNestedListCommand.h (0 => 237976)


--- trunk/Source/WebCore/editing/InsertNestedListCommand.h	                        (rev 0)
+++ trunk/Source/WebCore/editing/InsertNestedListCommand.h	2018-11-08 03:14:37 UTC (rev 237976)
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CompositeEditCommand.h"
+#include "EditAction.h"
+
+namespace WebCore {
+
+class InsertNestedListCommand final : public CompositeEditCommand {
+public:
+    static void insertUnorderedList(Document&);
+    static void insertOrderedList(Document&);
+
+private:
+    enum class Type : uint8_t { OrderedList, UnorderedList };
+
+    static Ref<InsertNestedListCommand> create(Document& document, Type type)
+    {
+        return adoptRef(*new InsertNestedListCommand(document, type));
+    }
+
+    InsertNestedListCommand(Document& document, Type type)
+        : CompositeEditCommand(document)
+        , m_type(type)
+    {
+    }
+
+    EditAction editingAction() const final
+    {
+        if (m_type == Type::OrderedList)
+            return EditAction::InsertOrderedList;
+
+        return EditAction::InsertUnorderedList;
+    }
+
+    bool preservesTypingStyle() const final { return true; }
+    void doApply() final;
+
+    Type m_type;
+};
+
+} // namespace WebCore

Modified: trunk/Source/WebCore/editing/ModifySelectionListLevel.cpp (237975 => 237976)


--- trunk/Source/WebCore/editing/ModifySelectionListLevel.cpp	2018-11-08 03:11:33 UTC (rev 237975)
+++ trunk/Source/WebCore/editing/ModifySelectionListLevel.cpp	2018-11-08 03:14:37 UTC (rev 237976)
@@ -185,17 +185,17 @@
         // create a sublist for the preceding element and move nodes there
         RefPtr<Element> newParent;
         switch (m_listType) {
-            case InheritedListType:
-                newParent = startListChild->parentElement();
-                if (newParent)
-                    newParent = newParent->cloneElementWithoutChildren(document());
-                break;
-            case OrderedList:
-                newParent = HTMLOListElement::create(document());
-                break;
-            case UnorderedList:
-                newParent = HTMLUListElement::create(document());
-                break;
+        case Type::InheritedListType:
+            newParent = startListChild->parentElement();
+            if (newParent)
+                newParent = newParent->cloneElementWithoutChildren(document());
+            break;
+        case Type::OrderedList:
+            newParent = HTMLOListElement::create(document());
+            break;
+        case Type::UnorderedList:
+            newParent = HTMLUListElement::create(document());
+            break;
         }
         insertNodeBefore(*newParent, *startListChild);
         appendSiblingNodeRange(startListChild, endListChild, newParent.get());
@@ -221,17 +221,17 @@
 
 RefPtr<Node> IncreaseSelectionListLevelCommand::increaseSelectionListLevel(Document* document)
 {
-    return increaseSelectionListLevel(document, InheritedListType);
+    return increaseSelectionListLevel(document, Type::InheritedListType);
 }
 
 RefPtr<Node> IncreaseSelectionListLevelCommand::increaseSelectionListLevelOrdered(Document* document)
 {
-    return increaseSelectionListLevel(document, OrderedList);
+    return increaseSelectionListLevel(document, Type::OrderedList);
 }
 
 RefPtr<Node> IncreaseSelectionListLevelCommand::increaseSelectionListLevelUnordered(Document* document)
 {
-    return increaseSelectionListLevel(document, UnorderedList);
+    return increaseSelectionListLevel(document, Type::UnorderedList);
 }
 
 DecreaseSelectionListLevelCommand::DecreaseSelectionListLevelCommand(Document& document)

Modified: trunk/Source/WebCore/editing/ModifySelectionListLevel.h (237975 => 237976)


--- trunk/Source/WebCore/editing/ModifySelectionListLevel.h	2018-11-08 03:11:33 UTC (rev 237975)
+++ trunk/Source/WebCore/editing/ModifySelectionListLevel.h	2018-11-08 03:14:37 UTC (rev 237976)
@@ -47,6 +47,12 @@
 // IncreaseSelectionListLevelCommand moves the selected list items one level deeper.
 class IncreaseSelectionListLevelCommand : public ModifySelectionListLevelCommand {
 public:
+    enum class Type : uint8_t { InheritedListType, OrderedList, UnorderedList };
+    static Ref<IncreaseSelectionListLevelCommand> create(Document& document, Type type)
+    {
+        return adoptRef(*new IncreaseSelectionListLevelCommand(document, type));
+    }
+
     static bool canIncreaseSelectionListLevel(Document*);
     static RefPtr<Node> increaseSelectionListLevel(Document*);
     static RefPtr<Node> increaseSelectionListLevelOrdered(Document*);
@@ -53,13 +59,7 @@
     static RefPtr<Node> increaseSelectionListLevelUnordered(Document*);
 
 private:
-    enum Type { InheritedListType, OrderedList, UnorderedList };
     static RefPtr<Node> increaseSelectionListLevel(Document*, Type);
-
-    static Ref<IncreaseSelectionListLevelCommand> create(Document& document, Type type)
-    {
-        return adoptRef(*new IncreaseSelectionListLevelCommand(document, type));
-    }
     
     IncreaseSelectionListLevelCommand(Document&, Type);
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to