Implement a new edit command to change the enclosing list type
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 12 Nov 2018 01:39:27 +0000 (01:39 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 12 Nov 2018 01:39:27 +0000 (01:39 +0000)
commitfffaff55f7277dddb8b35b85879651c3a93afc90
tree38e233024767f194965fda81a207eb02dafdc658
parent87374a008d2103e41a74294a8304b93a86a9e09f
Implement a new edit command to change the enclosing list type
https://bugs.webkit.org/show_bug.cgi?id=191487
<rdar://problem/45955922>

Reviewed by Ryosuke Niwa.

Source/WebCore:

Add support for a new edit command that changes the type of the enclosing list element around the selection from
unordered to ordered list and vice versa. This new edit command is exposed only to internal WebKit2 clients, via
SPI on WKWebView (`-_changeListType:`).

This is currently intended for use in Mail compose, but may also be adopted by legacy Notes in the future. As
such, the behavior of this editing command mostly matches shipping behavior in Mail compose (which is currently
implemented entirely by Mail). See below for more details.

Test:   editing/execCommand/change-list-type.html
        WKWebViewEditActions.ChangeListType

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* editing/ChangeListTypeCommand.cpp: Added.
(WebCore::listConversionTypeForSelection):
(WebCore::ChangeListTypeCommand::listConversionType):

Helper that returns a potential list conversion command that may be executed at the given document's selection,
if any exists. We also use existing logic from Mail here to determine which list to change, by walking up the
DOM from the lowest common ancestor container of the current selection until we hit the first list element.

(WebCore::ChangeListTypeCommand::createNewList):

Helper method to create a new list element to replace the given list, and then clone element data from the given
list to the new list. This addresses an existing bug in Mail, wherein changing list type for an enclosing list
which contains inline style properties drops the inline styles, because existing logic in Mail that implements
this editing command only copies the `class` attribute of the old list to the new list.

(WebCore::ChangeListTypeCommand::doApply):

Apply the edit command by running the following steps:
-   Find the enclosing list element, if any (see above).
-   Create a new list element of the opposite type as the enclosing list, and clone over element data from the
    list element being replaced.
-   Insert the new list next to the original list.
-   Move all children of the original list to the new list.
-   Remove the original list.
-   Set the selection to the end of the new list.

* editing/ChangeListTypeCommand.h: Added.
* editing/EditAction.h:

Add a pair of new edit actions for conversion from unordered list to ordered list and vice versa.

* editing/Editor.cpp:
(WebCore::Editor::changeSelectionListType):

Implement this by creating and applying a new ChangeListTypeCommand.

(WebCore::Editor::canChangeSelectionListType): Deleted.

Remove this for now, since there's no need for it until full support for edit command validation is implemented.

* editing/Editor.h:
* testing/Internals.cpp:
(WebCore::Internals::changeSelectionListType):
* testing/Internals.h:
* testing/Internals.idl:

Add internal hooks to change list type from layout tests.

Source/WebKit:

* UIProcess/WebEditCommandProxy.cpp:
(WebKit::WebEditCommandProxy::nameForEditAction):

Add undo/redo edit action strings for ConvertToOrderedList and ConvertToUnorderedList.

* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::increaseListLevel):
(WebKit::WebPage::decreaseListLevel):
(WebKit::WebPage::changeListType):

Remove preflight checks for these list editing commands. These are not necessary because these commands fall
back to being noops if these checks return false. This avoids an extraneous ancestor walk to determine the
enclosing list element when changing list type.

Source/WebKitLegacy/mac:

Add undo/redo edit action strings for ConvertToOrderedList and ConvertToUnorderedList.

* WebCoreSupport/WebEditorClient.mm:
(undoNameForEditAction):

Tools:

Add a new API test to verify that `-[WKWebView _changeListType:]` is hooked up to the corresponding editing
command in WebCore. See the new layout test for a test that exercises more nuanced corner cases.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKitCocoa/WKWebViewEditActions.mm:
(-[TestWKWebView setPosition:offset:]):
(-[TestWKWebView setBase:baseOffset:extent:extentOffset:]):
(TestWebKitAPI::webViewForEditActionTestingWithPageNamed):
(TestWebKitAPI::TEST):
* TestWebKitAPI/Tests/WebKitCocoa/editable-nested-lists.html: Added.

LayoutTests:

Add a new layout test to verify that the list change type editing command can be used to swap between enclosing
ordered and unordered lists. Also exercises undo, redo, changing list types under `pre` and `table` elements,
and handling selection within nested list elements.

* editing/execCommand/change-list-type-expected.txt: Added.
* editing/execCommand/change-list-type.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238080 268f45cc-cd09-0410-ab3c-d52691b4dbfc
23 files changed:
LayoutTests/ChangeLog
LayoutTests/editing/execCommand/change-list-type-expected.txt [new file with mode: 0644]
LayoutTests/editing/execCommand/change-list-type.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/Sources.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/editing/ChangeListTypeCommand.cpp [new file with mode: 0644]
Source/WebCore/editing/ChangeListTypeCommand.h [new file with mode: 0644]
Source/WebCore/editing/EditAction.h
Source/WebCore/editing/Editor.cpp
Source/WebCore/editing/Editor.h
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebCore/testing/Internals.idl
Source/WebKit/ChangeLog
Source/WebKit/UIProcess/WebEditCommandProxy.cpp
Source/WebKit/WebProcess/WebPage/WebPage.cpp
Source/WebKitLegacy/mac/ChangeLog
Source/WebKitLegacy/mac/WebCoreSupport/WebEditorClient.mm
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewEditActions.mm
Tools/TestWebKitAPI/Tests/WebKitCocoa/editable-nested-lists.html [new file with mode: 0644]