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);