[iOS] [WK2] Expose some more editing SPI on WKWebView
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 5 Oct 2018 03:03:21 +0000 (03:03 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 5 Oct 2018 03:03:21 +0000 (03:03 +0000)
https://bugs.webkit.org/show_bug.cgi?id=190232
<rdar://problem/44963368>

Reviewed by Tim Horton.

Source/WebKit:

Exposes a few additional editing commands as SPI on WKWebView, by defining a new extension on WKWebView that
also conforms to <UIResponderStandardEditActions>. This patch implements nearly all of the remaining
unimplemented methods on UIResponderStandardEditActions, and the new extension augments this set of editing
methods by adding additional editing helpers that don't currently exist on iOS (e.g. toggleStrikeThrough and
insertUnorderedList). The names of these new methods have been largely been borrowed from their counterparts on
macOS (see: `NSResponder.h`).

The new edit actions are added in this patch on iOS are:

```
- (void)alignCenter:(id)sender;
- (void)alignJustified:(id)sender;
- (void)alignLeft:(id)sender;
- (void)alignRight:(id)sender;
- (void)indent:(id)sender;
- (void)insertOrderedList:(id)sender;
- (void)insertUnorderedList:(id)sender;
- (void)outdent:(id)sender;
- (void)toggleStrikeThrough:(id)sender;
- (void)setFont:(UIFont *)font sender:(id)sender;
- (void)setFontSize:(CGFloat)fontSize sender:(id)sender;
- (void)setTextColor:(UIColor *)color sender:(id)sender;
```

Tests:  WKWebViewEditActions.ListInsertion
        WKWebViewEditActions.ChangeIndentation
        WKWebViewEditActions.SetAlignment
        WKWebViewEditActions.ToggleStrikeThrough
        WKWebViewEditActions.ChangeFontSize
        WKWebViewEditActions.SetTextColor
        WKWebViewEditActions.SetFontFamily

* Platform/spi/ios/UIKitSPI.h:
* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView canPerformAction:withSender:]):

Update this to handle the new editing actions. For now, we simply treat all of the new edit actions in the same
way as we currently treat bold, italic and underline: that is, they are enabled only when the user is in a
richly contenteditable element.

(-[WKWebView setFont:sender:]):
(-[WKWebView setFontSize:sender:]):

Construct and send a set of FontChanges.

(-[WKWebView setTextColor:sender:]):

Invoke "ForeColor" with the serialized color representation. This allows us to handle `rgba()` color values,
which hex format would not permit.

* UIProcess/API/Cocoa/WKWebViewPrivate.h:

Add the new SPI.

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::changeFontAttributes):
(WebKit::WebPageProxy::changeFont):

Pull logic for applying font and font attribute style changes out of macOS-specific code, and into
platform-agnostic code in WebPage and WebPageProxy.

* UIProcess/WebPageProxy.h:
* UIProcess/ios/WKContentViewInteraction.h:

Add the new supported editing commands as supported actions in WKWebView. The only new editing commands that
aren't present in this list are -setFont:sender:, -setColor:sender:, and -setFontSize:sender: which are manually
handled in places where the `FOR_EACH_WKCONTENTVIEW_ACTION` macro is otherwise used. In a followup, we could
consider augmenting `FOR_EACH_WKCONTENTVIEW_ACTION` to handle actions with multiple arguments.

* UIProcess/ios/WKContentViewInteraction.mm:

Define a new helper macro here to define boilerplate implementations of the -…ForWebView edit command
implementations that turn around and invoke `_page->executeEditCommand` with no additional arguments, and an
edit command name matching that of the WebCore edit command.

(-[WKContentView toggleStrikeThroughForWebView:]):
(-[WKContentView increaseSizeForWebView:]):
(-[WKContentView decreaseSizeForWebView:]):
(-[WKContentView setFontForWebView:sender:]):
(-[WKContentView setFontSizeForWebView:sender:]):
(-[WKContentView setTextColorForWebView:sender:]):
(-[WKContentView canPerformActionForWebView:sender:]):

Add …ForWebView plumbing for the new editing actions, so they turn around and call into WKContentView by
default, but behavior may be overridden in WKWebView.

* UIProcess/mac/WebPageProxyMac.mm:
(WebKit::WebPageProxy::changeFontAttributes): Deleted.
(WebKit::WebPageProxy::changeFont): Deleted.
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::changeFontAttributes):
(WebKit::WebPage::changeFont):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:
* WebProcess/WebPage/mac/WebPageMac.mm:
(WebKit::WebPage::changeFontAttributes): Deleted.
(WebKit::WebPage::changeFont): Deleted.

Tools:

Adds new API tests to exercise the new SPIs.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/ios/WKWebViewEditActions.mm: Added.
(-[TestWKWebView querySelectorExists:]):
(TestWebKitAPI::webViewForEditActionTesting):
(TestWebKitAPI::TEST):
* TestWebKitAPI/Tests/mac/FontManagerTests.mm:
(-[TestWKWebView collapseToStart]): Deleted.
(-[TestWKWebView collapseToEnd]): Deleted.
(-[TestWKWebView stylePropertyAtSelectionStart:]): Deleted.
(-[TestWKWebView stylePropertyAtSelectionEnd:]): Deleted.
* TestWebKitAPI/cocoa/TestWKWebView.h:
* TestWebKitAPI/cocoa/TestWKWebView.mm:
(-[TestWKWebView stylePropertyAtSelectionStart:]):
(-[TestWKWebView stylePropertyAtSelectionEnd:]):
(-[TestWKWebView collapseToStart]):
(-[TestWKWebView collapseToEnd]):

Pull some common testing helpers out of NSFontManager and into TestWKWebView.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@236867 268f45cc-cd09-0410-ab3c-d52691b4dbfc

19 files changed:
Source/WebKit/ChangeLog
Source/WebKit/Platform/spi/ios/UIKitSPI.h
Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h
Source/WebKit/UIProcess/WebPageProxy.cpp
Source/WebKit/UIProcess/WebPageProxy.h
Source/WebKit/UIProcess/ios/WKContentViewInteraction.h
Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm
Source/WebKit/UIProcess/mac/WebPageProxyMac.mm
Source/WebKit/WebProcess/WebPage/WebPage.cpp
Source/WebKit/WebProcess/WebPage/WebPage.h
Source/WebKit/WebProcess/WebPage/WebPage.messages.in
Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/ios/WKWebViewEditActions.mm [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/mac/FontManagerTests.mm
Tools/TestWebKitAPI/cocoa/TestWKWebView.h
Tools/TestWebKitAPI/cocoa/TestWKWebView.mm

index 2821cc5..acc1550 100644 (file)
@@ -1,3 +1,109 @@
+2018-10-04  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [iOS] [WK2] Expose some more editing SPI on WKWebView
+        https://bugs.webkit.org/show_bug.cgi?id=190232
+        <rdar://problem/44963368>
+
+        Reviewed by Tim Horton.
+
+        Exposes a few additional editing commands as SPI on WKWebView, by defining a new extension on WKWebView that
+        also conforms to <UIResponderStandardEditActions>. This patch implements nearly all of the remaining
+        unimplemented methods on UIResponderStandardEditActions, and the new extension augments this set of editing
+        methods by adding additional editing helpers that don't currently exist on iOS (e.g. toggleStrikeThrough and
+        insertUnorderedList). The names of these new methods have been largely been borrowed from their counterparts on
+        macOS (see: `NSResponder.h`).
+
+        The new edit actions are added in this patch on iOS are:
+
+        ```
+        - (void)alignCenter:(id)sender;
+        - (void)alignJustified:(id)sender;
+        - (void)alignLeft:(id)sender;
+        - (void)alignRight:(id)sender;
+        - (void)indent:(id)sender;
+        - (void)insertOrderedList:(id)sender;
+        - (void)insertUnorderedList:(id)sender;
+        - (void)outdent:(id)sender;
+        - (void)toggleStrikeThrough:(id)sender;
+        - (void)setFont:(UIFont *)font sender:(id)sender;
+        - (void)setFontSize:(CGFloat)fontSize sender:(id)sender;
+        - (void)setTextColor:(UIColor *)color sender:(id)sender;
+        ```
+
+        Tests:  WKWebViewEditActions.ListInsertion
+                WKWebViewEditActions.ChangeIndentation
+                WKWebViewEditActions.SetAlignment
+                WKWebViewEditActions.ToggleStrikeThrough
+                WKWebViewEditActions.ChangeFontSize
+                WKWebViewEditActions.SetTextColor
+                WKWebViewEditActions.SetFontFamily
+
+        * Platform/spi/ios/UIKitSPI.h:
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView canPerformAction:withSender:]):
+
+        Update this to handle the new editing actions. For now, we simply treat all of the new edit actions in the same
+        way as we currently treat bold, italic and underline: that is, they are enabled only when the user is in a
+        richly contenteditable element.
+
+        (-[WKWebView setFont:sender:]):
+        (-[WKWebView setFontSize:sender:]):
+
+        Construct and send a set of FontChanges.
+
+        (-[WKWebView setTextColor:sender:]):
+
+        Invoke "ForeColor" with the serialized color representation. This allows us to handle `rgba()` color values,
+        which hex format would not permit.
+
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+
+        Add the new SPI.
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::changeFontAttributes):
+        (WebKit::WebPageProxy::changeFont):
+
+        Pull logic for applying font and font attribute style changes out of macOS-specific code, and into
+        platform-agnostic code in WebPage and WebPageProxy.
+
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/ios/WKContentViewInteraction.h:
+
+        Add the new supported editing commands as supported actions in WKWebView. The only new editing commands that
+        aren't present in this list are -setFont:sender:, -setColor:sender:, and -setFontSize:sender: which are manually
+        handled in places where the `FOR_EACH_WKCONTENTVIEW_ACTION` macro is otherwise used. In a followup, we could
+        consider augmenting `FOR_EACH_WKCONTENTVIEW_ACTION` to handle actions with multiple arguments.
+
+        * UIProcess/ios/WKContentViewInteraction.mm:
+
+        Define a new helper macro here to define boilerplate implementations of the -…ForWebView edit command
+        implementations that turn around and invoke `_page->executeEditCommand` with no additional arguments, and an
+        edit command name matching that of the WebCore edit command.
+
+        (-[WKContentView toggleStrikeThroughForWebView:]):
+        (-[WKContentView increaseSizeForWebView:]):
+        (-[WKContentView decreaseSizeForWebView:]):
+        (-[WKContentView setFontForWebView:sender:]):
+        (-[WKContentView setFontSizeForWebView:sender:]):
+        (-[WKContentView setTextColorForWebView:sender:]):
+        (-[WKContentView canPerformActionForWebView:sender:]):
+
+        Add …ForWebView plumbing for the new editing actions, so they turn around and call into WKContentView by
+        default, but behavior may be overridden in WKWebView.
+
+        * UIProcess/mac/WebPageProxyMac.mm:
+        (WebKit::WebPageProxy::changeFontAttributes): Deleted.
+        (WebKit::WebPageProxy::changeFont): Deleted.
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::changeFontAttributes):
+        (WebKit::WebPage::changeFont):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+        * WebProcess/WebPage/mac/WebPageMac.mm:
+        (WebKit::WebPage::changeFontAttributes): Deleted.
+        (WebKit::WebPage::changeFont): Deleted.
+
 2018-10-04  Jer Noble  <jer.noble@apple.com>
 
         Add support for reporting "display composited video frames" through the VideoPlaybackQuality object.
index 00caa18..1893575 100644 (file)
@@ -195,11 +195,14 @@ typedef enum {
 @end
 
 typedef enum {
-    UIFontTraitPlain = 0x00000000,
+    UIFontTraitPlain = 0,
+    UIFontTraitItalic = 1 << 0,
+    UIFontTraitBold = 1 << 1,
 } UIFontTrait;
 
 @interface UIFont ()
 + (UIFont *)fontWithFamilyName:(NSString *)familyName traits:(UIFontTrait)traits size:(CGFloat)fontSize;
+- (UIFontTrait)traits;
 @end
 
 typedef enum {
index 0e7dccb..dd54dbb 100644 (file)
@@ -1398,6 +1398,9 @@ FOR_EACH_WKCONTENTVIEW_ACTION(FORWARD_ACTION_TO_WKCONTENTVIEW)
 
     #undef FORWARD_CANPERFORMACTION_TO_WKCONTENTVIEW
 
+    if (action == @selector(setTextColor:sender:) || action == @selector(setFontSize:sender:) || action == @selector(setFont:sender:))
+        return self.usesStandardContentView && [_contentView canPerformActionForWebView:action withSender:sender];
+
     return [super canPerformAction:action withSender:sender];
 }
 
@@ -1416,6 +1419,21 @@ FOR_EACH_WKCONTENTVIEW_ACTION(FORWARD_ACTION_TO_WKCONTENTVIEW)
     return [super targetForAction:action withSender:sender];
 }
 
+- (void)setFont:(UIFont *)font sender:(id)sender
+{
+    [_contentView setFontForWebView:font sender:sender];
+}
+
+- (void)setTextColor:(UIColor *)color sender:(id)sender
+{
+    [_contentView setTextColorForWebView:color sender:sender];
+}
+
+- (void)setFontSize:(CGFloat)fontSize sender:(id)sender
+{
+    [_contentView setFontSizeForWebView:fontSize sender:sender];
+}
+
 static inline CGFloat floorToDevicePixel(CGFloat input, float deviceScaleFactor)
 {
     return CGFloor(input * deviceScaleFactor) / deviceScaleFactor;
index 062f15e..0837a61 100644 (file)
@@ -366,9 +366,28 @@ typedef NS_OPTIONS(NSUInteger, _WKRectEdge) {
 
 @end
 
-#if !TARGET_OS_IPHONE
+#if TARGET_OS_IPHONE
+
+@interface WKWebView () <UIResponderStandardEditActions>
+- (void)alignCenter:(id)sender WK_API_AVAILABLE(ios(WK_IOS_TBA));
+- (void)alignJustified:(id)sender WK_API_AVAILABLE(ios(WK_IOS_TBA));
+- (void)alignLeft:(id)sender WK_API_AVAILABLE(ios(WK_IOS_TBA));
+- (void)alignRight:(id)sender WK_API_AVAILABLE(ios(WK_IOS_TBA));
+- (void)indent:(id)sender WK_API_AVAILABLE(ios(WK_IOS_TBA));
+- (void)insertOrderedList:(id)sender WK_API_AVAILABLE(ios(WK_IOS_TBA));
+- (void)insertUnorderedList:(id)sender WK_API_AVAILABLE(ios(WK_IOS_TBA));
+- (void)outdent:(id)sender WK_API_AVAILABLE(ios(WK_IOS_TBA));
+- (void)toggleStrikeThrough:(id)sender WK_API_AVAILABLE(ios(WK_IOS_TBA));
+- (void)setFont:(UIFont *)font sender:(id)sender WK_API_AVAILABLE(ios(WK_IOS_TBA));
+- (void)setFontSize:(CGFloat)fontSize sender:(id)sender WK_API_AVAILABLE(ios(WK_IOS_TBA));
+- (void)setTextColor:(UIColor *)color sender:(id)sender WK_API_AVAILABLE(ios(WK_IOS_TBA));
+@end
+
+#else
+
 @interface WKWebView (WKNSTextFinderClient) <NSTextFinderClient>
 @end
+
 #endif
 
 @interface WKWebView (WKTesting)
index ea0f067..f467c17 100644 (file)
 #include <WebCore/EventNames.h>
 #include <WebCore/FloatRect.h>
 #include <WebCore/FocusDirection.h>
+#include <WebCore/FontAttributeChanges.h>
 #include <WebCore/FrameLoader.h>
 #include <WebCore/GlobalFrameIdentifier.h>
 #include <WebCore/GlobalWindowIdentifier.h>
@@ -7071,6 +7072,22 @@ void WebPageProxy::addMIMETypeWithCustomContentProvider(const String& mimeType)
     m_process->send(Messages::WebPage::AddMIMETypeWithCustomContentProvider(mimeType), m_pageID);
 }
 
+void WebPageProxy::changeFontAttributes(WebCore::FontAttributeChanges&& changes)
+{
+    if (!isValid())
+        return;
+
+    process().send(Messages::WebPage::ChangeFontAttributes(WTFMove(changes)), m_pageID);
+}
+
+void WebPageProxy::changeFont(WebCore::FontChanges&& changes)
+{
+    if (!isValid())
+        return;
+
+    process().send(Messages::WebPage::ChangeFont(WTFMove(changes)), m_pageID);
+}
+
 #if PLATFORM(COCOA)
 
 void WebPageProxy::setTextAsync(const String& text)
index 5b12c58..480d0ea 100644 (file)
@@ -698,11 +698,12 @@ public:
     RemoteLayerTreeScrollingPerformanceData* scrollingPerformanceData() { return m_scrollingPerformanceData.get(); }
 #endif // PLATFORM(COCOA)
 
+    void changeFontAttributes(WebCore::FontAttributeChanges&&);
+    void changeFont(WebCore::FontChanges&&);
+
 #if PLATFORM(MAC)
     void insertDictatedTextAsync(const String& text, const EditingRange& replacementRange, const Vector<WebCore::TextAlternativeWithRange>& dictationAlternatives, bool registerUndoGroup);
     void attributedSubstringForCharacterRangeAsync(const EditingRange&, WTF::Function<void (const AttributedString&, const EditingRange&, CallbackBase::Error)>&&);
-    void changeFontAttributes(WebCore::FontAttributeChanges&&);
-    void changeFont(WebCore::FontChanges&&);
     void fontAtSelection(WTF::Function<void (const String&, double, bool, CallbackBase::Error)>&&);
 
     void startWindowDrag();
index a239de9..9dec4d8 100644 (file)
@@ -121,7 +121,18 @@ typedef std::pair<WebKit::InteractionInformationRequest, InteractionInformationC
     M(selectAll) \
     M(toggleBoldface) \
     M(toggleItalics) \
-    M(toggleUnderline)
+    M(toggleUnderline) \
+    M(increaseSize) \
+    M(decreaseSize) \
+    M(toggleStrikeThrough) \
+    M(insertUnorderedList) \
+    M(insertOrderedList) \
+    M(indent) \
+    M(outdent) \
+    M(alignLeft) \
+    M(alignRight) \
+    M(alignCenter) \
+    M(alignJustified)
 
 namespace WebKit {
 
@@ -319,6 +330,10 @@ FOR_EACH_WKCONTENTVIEW_ACTION(DECLARE_WKCONTENTVIEW_ACTION_FOR_WEB_VIEW)
 DECLARE_WKCONTENTVIEW_ACTION_FOR_WEB_VIEW(_pasteAsQuotation)
 #undef DECLARE_WKCONTENTVIEW_ACTION_FOR_WEB_VIEW
 
+- (void)setFontForWebView:(UIFont *)fontFamily sender:(id)sender;
+- (void)setFontSizeForWebView:(CGFloat)fontSize sender:(id)sender;
+- (void)setTextColorForWebView:(UIColor *)color sender:(id)sender;
+
 #if ENABLE(TOUCH_EVENTS)
 - (void)_webTouchEvent:(const WebKit::NativeWebTouchEvent&)touchEvent preventsNativeGestures:(BOOL)preventsDefault;
 #endif
index b01c4f6..7f2f072 100644 (file)
@@ -75,6 +75,7 @@
 #import <WebCore/Color.h>
 #import <WebCore/DataDetection.h>
 #import <WebCore/FloatQuad.h>
+#import <WebCore/FontAttributeChanges.h>
 #import <WebCore/InputMode.h>
 #import <WebCore/LocalizedStrings.h>
 #import <WebCore/NotImplemented.h>
@@ -2279,6 +2280,57 @@ FORWARD_ACTION_TO_WKWEBVIEW(_pasteAsQuotation)
     [[UIKeyboardImpl sharedInstance] replaceText:sender];
 }
 
+#define WEBCORE_COMMAND_FOR_WEBVIEW(command) - (void)command ## ForWebView:(id)sender { _page->executeEditCommand(#command ## _s); }
+
+WEBCORE_COMMAND_FOR_WEBVIEW(insertOrderedList);
+WEBCORE_COMMAND_FOR_WEBVIEW(insertUnorderedList);
+WEBCORE_COMMAND_FOR_WEBVIEW(indent);
+WEBCORE_COMMAND_FOR_WEBVIEW(outdent);
+WEBCORE_COMMAND_FOR_WEBVIEW(alignLeft);
+WEBCORE_COMMAND_FOR_WEBVIEW(alignRight);
+WEBCORE_COMMAND_FOR_WEBVIEW(alignCenter);
+WEBCORE_COMMAND_FOR_WEBVIEW(alignJustified);
+
+- (void)toggleStrikeThroughForWebView:(id)sender
+{
+    _page->executeEditCommand("StrikeThrough"_s);
+}
+
+- (void)increaseSizeForWebView:(id)sender
+{
+    _page->executeEditCommand("FontSizeDelta"_s, "1"_s);
+}
+
+- (void)decreaseSizeForWebView:(id)sender
+{
+    _page->executeEditCommand("FontSizeDelta"_s, "-1"_s);
+}
+
+- (void)setFontForWebView:(UIFont *)font sender:(id)sender
+{
+    WebCore::FontChanges changes;
+    changes.setFontFamily(font.familyName);
+    changes.setFontName(font.fontName);
+    changes.setFontSize(font.pointSize);
+    changes.setBold(font.traits & UIFontTraitBold);
+    changes.setItalic(font.traits & UIFontTraitItalic);
+    _page->changeFont(WTFMove(changes));
+}
+
+- (void)setFontSizeForWebView:(CGFloat)fontSize sender:(id)sender
+{
+    WebCore::FontChanges changes;
+    changes.setFontSize(fontSize);
+    _page->changeFont(WTFMove(changes));
+}
+
+- (void)setTextColorForWebView:(UIColor *)color sender:(id)sender
+{
+    _page->executeEditCommand("ForeColor"_s, WebCore::Color(color.CGColor).serialized());
+}
+
+#undef WEBCORE_COMMAND_FOR_WEBVIEW
+
 - (NSDictionary *)textStylingAtPosition:(UITextPosition *)position inDirection:(UITextStorageDirection)direction
 {
     if (!position || !_page->editorState().isContentRichlyEditable)
@@ -2338,8 +2390,15 @@ FORWARD_ACTION_TO_WKWEBVIEW(_pasteAsQuotation)
         return editorState.isContentRichlyEditable && editorState.selectionIsRange && !_showingTextStyleOptions;
     if (_showingTextStyleOptions)
         return (action == @selector(toggleBoldface:) || action == @selector(toggleItalics:) || action == @selector(toggleUnderline:));
-    if (action == @selector(toggleBoldface:) || action == @selector(toggleItalics:) || action == @selector(toggleUnderline:))
+    if (action == @selector(toggleBoldface:) || action == @selector(toggleItalics:) || action == @selector(toggleUnderline:) || action == @selector(toggleStrikeThrough:)
+        || action == @selector(insertOrderedList:) || action == @selector(insertUnorderedList:) || action == @selector(indent:) || action == @selector(outdent:)
+        || action == @selector(alignLeft:) || action == @selector(alignRight:) || action == @selector(alignCenter:) || action == @selector(alignJustified:)
+        || action == @selector(increaseSize:) || action == @selector(decreaseSize:) || action == @selector(setTextColor:sender:)
+        || action == @selector(setFont:sender:) || action == @selector(setFontSize:sender:)) {
+        // FIXME: This should be more nuanced in the future, rather than returning YES for all richly editable areas. For instance, outdent: should be disabled when the selection is already
+        // at the outermost indentation level.
         return editorState.isContentRichlyEditable;
+    }
     if (action == @selector(cut:))
         return !editorState.isInPasswordField && editorState.isContentEditable && editorState.selectionIsRange;
     
index f312348..b55ce9e 100644 (file)
@@ -51,7 +51,6 @@
 #import <WebCore/DictationAlternative.h>
 #import <WebCore/DictionaryLookup.h>
 #import <WebCore/DragItem.h>
-#import <WebCore/FontAttributeChanges.h>
 #import <WebCore/GraphicsLayer.h>
 #import <WebCore/LegacyNSPasteboardTypes.h>
 #import <WebCore/RuntimeApplicationChecks.h>
@@ -629,22 +628,6 @@ bool WebPageProxy::appleMailLinesClampEnabled()
     return MacApplication::isAppleMail();
 }
 
-void WebPageProxy::changeFontAttributes(WebCore::FontAttributeChanges&& changes)
-{
-    if (!isValid())
-        return;
-
-    process().send(Messages::WebPage::ChangeFontAttributes(WTFMove(changes)), m_pageID);
-}
-    
-void WebPageProxy::changeFont(WebCore::FontChanges&& changes)
-{
-    if (!isValid())
-        return;
-
-    process().send(Messages::WebPage::ChangeFont(WTFMove(changes)), m_pageID);
-}
-
 void WebPageProxy::editorStateChanged(const EditorState& editorState)
 {
     bool couldChangeSecureInputState = m_editorState.isInPasswordField != editorState.isInPasswordField || m_editorState.selectionIsNone;
index 432dc89..c9d1724 100644 (file)
 #include <WebCore/EventNames.h>
 #include <WebCore/File.h>
 #include <WebCore/FocusController.h>
+#include <WebCore/FontAttributeChanges.h>
 #include <WebCore/FontAttributes.h>
 #include <WebCore/FormState.h>
 #include <WebCore/Frame.h>
@@ -1003,6 +1004,20 @@ EditorState WebPage::editorState(IncludePostLayoutDataHint shouldIncludePostLayo
     return result;
 }
 
+void WebPage::changeFontAttributes(WebCore::FontAttributeChanges&& changes)
+{
+    auto& frame = m_page->focusController().focusedOrMainFrame();
+    if (frame.selection().selection().isContentEditable())
+        frame.editor().applyStyleToSelection(changes.createEditingStyle(), changes.editAction(), Editor::ColorFilterMode::InvertColor);
+}
+
+void WebPage::changeFont(WebCore::FontChanges&& changes)
+{
+    auto& frame = m_page->focusController().focusedOrMainFrame();
+    if (frame.selection().selection().isContentEditable())
+        frame.editor().applyStyleToSelection(changes.createEditingStyle(), EditAction::SetFont, Editor::ColorFilterMode::InvertColor);
+}
+
 void WebPage::executeEditCommandWithCallback(const String& commandName, const String& argument, CallbackID callbackID)
 {
     executeEditCommand(commandName, argument);
index b12b063..d01c9ae 100644 (file)
@@ -1362,14 +1362,15 @@ private:
 
     void updateWebsitePolicies(WebsitePoliciesData&&);
 
+    void changeFont(WebCore::FontChanges&&);
+    void changeFontAttributes(WebCore::FontAttributeChanges&&);
+
 #if PLATFORM(MAC)
     void performImmediateActionHitTestAtLocation(WebCore::FloatPoint);
     std::tuple<RefPtr<WebCore::Range>, NSDictionary *> lookupTextAtLocation(WebCore::FloatPoint);
     void immediateActionDidUpdate();
     void immediateActionDidCancel();
     void immediateActionDidComplete();
-    void changeFont(WebCore::FontChanges&&);
-    void changeFontAttributes(WebCore::FontAttributeChanges&&);
 
     void dataDetectorsDidPresentUI(WebCore::PageOverlay::PageOverlayID);
     void dataDetectorsDidChangeUI(WebCore::PageOverlay::PageOverlayID);
index 94cafe6..a0a14ef 100644 (file)
@@ -190,9 +190,10 @@ messages -> WebPage LegacyReceiver {
 
 #if PLATFORM(MAC)
     PerformDictionaryLookupOfCurrentSelection()
+#endif
+
     ChangeFont(WebCore::FontChanges changes)
     ChangeFontAttributes(WebCore::FontAttributeChanges changes)
-#endif
 
     PreferencesDidChange(struct WebKit::WebPreferencesStore store)
 
index b781796..6233bf9 100644 (file)
@@ -63,7 +63,6 @@
 #import <WebCore/Editor.h>
 #import <WebCore/EventHandler.h>
 #import <WebCore/FocusController.h>
-#import <WebCore/FontAttributeChanges.h>
 #import <WebCore/Frame.h>
 #import <WebCore/FrameLoader.h>
 #import <WebCore/FrameView.h>
@@ -1113,20 +1112,6 @@ void WebPage::dataDetectorsDidHideUI(PageOverlay::PageOverlayID overlayID)
     }
 }
 
-void WebPage::changeFontAttributes(WebCore::FontAttributeChanges&& changes)
-{
-    auto& frame = m_page->focusController().focusedOrMainFrame();
-    if (frame.selection().selection().isContentEditable())
-        frame.editor().applyStyleToSelection(changes.createEditingStyle(), changes.editAction(), Editor::ColorFilterMode::InvertColor);
-}
-
-void WebPage::changeFont(WebCore::FontChanges&& changes)
-{
-    auto& frame = m_page->focusController().focusedOrMainFrame();
-    if (frame.selection().selection().isContentEditable())
-        frame.editor().applyStyleToSelection(changes.createEditingStyle(), EditAction::SetFont, Editor::ColorFilterMode::InvertColor);
-}
-
 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
 void WebPage::playbackTargetSelected(uint64_t contextId, const WebCore::MediaPlaybackTargetContext& targetContext) const
 {
index c55240b..908b9d1 100644 (file)
@@ -1,3 +1,32 @@
+2018-10-04  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [iOS] [WK2] Expose some more editing SPI on WKWebView
+        https://bugs.webkit.org/show_bug.cgi?id=190232
+        <rdar://problem/44963368>
+
+        Reviewed by Tim Horton.
+
+        Adds new API tests to exercise the new SPIs.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/ios/WKWebViewEditActions.mm: Added.
+        (-[TestWKWebView querySelectorExists:]):
+        (TestWebKitAPI::webViewForEditActionTesting):
+        (TestWebKitAPI::TEST):
+        * TestWebKitAPI/Tests/mac/FontManagerTests.mm:
+        (-[TestWKWebView collapseToStart]): Deleted.
+        (-[TestWKWebView collapseToEnd]): Deleted.
+        (-[TestWKWebView stylePropertyAtSelectionStart:]): Deleted.
+        (-[TestWKWebView stylePropertyAtSelectionEnd:]): Deleted.
+        * TestWebKitAPI/cocoa/TestWKWebView.h:
+        * TestWebKitAPI/cocoa/TestWKWebView.mm:
+        (-[TestWKWebView stylePropertyAtSelectionStart:]):
+        (-[TestWKWebView stylePropertyAtSelectionEnd:]):
+        (-[TestWKWebView collapseToStart]):
+        (-[TestWKWebView collapseToEnd]):
+
+        Pull some common testing helpers out of NSFontManager and into TestWKWebView.
+
 2018-10-04  Jer Noble  <jer.noble@apple.com>
 
         Add support for reporting "display composited video frames" through the VideoPlaybackQuality object.
index 2199d2d..eb31166 100644 (file)
                F4F5BB5221667BAA002D06B9 /* TestFontOptions.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4F5BB5121667BAA002D06B9 /* TestFontOptions.mm */; };
                F4FA91811E61849B007B8C1D /* WKWebViewMacEditingTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4FA917F1E61849B007B8C1D /* WKWebViewMacEditingTests.mm */; };
                F4FA91831E61857B007B8C1D /* double-click-does-not-select-trailing-space.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4FA91821E618566007B8C1D /* double-click-does-not-select-trailing-space.html */; };
+               F4FB682521643EFC0034607A /* WKWebViewEditActions.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4FB682421643EFC0034607A /* WKWebViewEditActions.mm */; };
                F4FC077720F013B600CA043C /* significant-text-milestone.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4FC077620F0108100CA043C /* significant-text-milestone.html */; };
                F660AA1115A5F631003A1243 /* GetInjectedBundleInitializationUserDataCallback_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F660AA0F15A5F624003A1243 /* GetInjectedBundleInitializationUserDataCallback_Bundle.cpp */; };
                F660AA1515A61ABF003A1243 /* InjectedBundleInitializationUserDataCallbackWins_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F660AA1415A61ABF003A1243 /* InjectedBundleInitializationUserDataCallbackWins_Bundle.cpp */; };
                F4F5BB5121667BAA002D06B9 /* TestFontOptions.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = TestFontOptions.mm; sourceTree = "<group>"; };
                F4FA917F1E61849B007B8C1D /* WKWebViewMacEditingTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKWebViewMacEditingTests.mm; sourceTree = "<group>"; };
                F4FA91821E618566007B8C1D /* double-click-does-not-select-trailing-space.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = "double-click-does-not-select-trailing-space.html"; path = "Tests/WebKitCocoa/double-click-does-not-select-trailing-space.html"; sourceTree = SOURCE_ROOT; };
+               F4FB682421643EFC0034607A /* WKWebViewEditActions.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = WKWebViewEditActions.mm; sourceTree = "<group>"; };
                F4FC077620F0108100CA043C /* significant-text-milestone.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "significant-text-milestone.html"; sourceTree = "<group>"; };
                F660AA0C15A5F061003A1243 /* GetInjectedBundleInitializationUserDataCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GetInjectedBundleInitializationUserDataCallback.cpp; sourceTree = "<group>"; };
                F660AA0F15A5F624003A1243 /* GetInjectedBundleInitializationUserDataCallback_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GetInjectedBundleInitializationUserDataCallback_Bundle.cpp; sourceTree = "<group>"; };
                                F46849BD1EEF58E400B937FE /* UIPasteboardTests.mm */,
                                F43E3BBE20DADA1E00A4E7ED /* WKScrollViewTests.mm */,
                                514958BD1F7427AC00E87BAD /* WKWebViewAutofillTests.mm */,
+                               F4FB682421643EFC0034607A /* WKWebViewEditActions.mm */,
                        );
                        path = ios;
                        sourceTree = "<group>";
                                7C417F331D19E14800B8EF53 /* WKWebViewDefaultNavigationDelegate.mm in Sources */,
                                46E66A901F0D75590026D83C /* WKWebViewDiagnosticLogging.mm in Sources */,
                                2DB647881F4163D60051A89E /* WKWebViewDoesNotLogDuringInitialization.mm in Sources */,
+                               F4FB682521643EFC0034607A /* WKWebViewEditActions.mm in Sources */,
                                0F3B94A71A77267400DE3272 /* WKWebViewEvaluateJavaScript.mm in Sources */,
                                D34E08761E4E42E1005FF14A /* WKWebViewGetContents.mm in Sources */,
                                F4FA91811E61849B007B8C1D /* WKWebViewMacEditingTests.mm in Sources */,
diff --git a/Tools/TestWebKitAPI/Tests/ios/WKWebViewEditActions.mm b/Tools/TestWebKitAPI/Tests/ios/WKWebViewEditActions.mm
new file mode 100644 (file)
index 0000000..55ee609
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * 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.
+ */
+
+#import "config.h"
+
+#if PLATFORM(IOS) && WK_API_ENABLED
+
+#import "PlatformUtilities.h"
+#import "TestWKWebView.h"
+#import "UIKitSPI.h"
+#import <UIKit/UIFontDescriptor.h>
+#import <WebKit/WKWebViewPrivate.h>
+
+@interface TestWKWebView (EditActionTesting)
+- (BOOL)querySelectorExists:(NSString *)querySelector;
+@end
+
+@implementation TestWKWebView (EditActionTesting)
+
+- (BOOL)querySelectorExists:(NSString *)querySelector
+{
+    return [[self objectByEvaluatingJavaScript:[NSString stringWithFormat:@"!!document.querySelector(`%@`)", querySelector]] boolValue];
+}
+
+@end
+
+namespace TestWebKitAPI {
+
+static RetainPtr<TestWKWebView> webViewForEditActionTesting()
+{
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
+    [webView synchronouslyLoadHTMLString:@"<div>WebKit</div>"];
+    [webView _setEditable:YES];
+    [webView stringByEvaluatingJavaScript:@"getSelection().setPosition(document.body, 1)"];
+    return webView;
+}
+
+TEST(WKWebViewEditActions, ListInsertion)
+{
+    auto webView = webViewForEditActionTesting();
+
+    [webView insertOrderedList:nil];
+    EXPECT_TRUE([webView querySelectorExists:@"ol"]);
+    [webView insertOrderedList:nil];
+    EXPECT_FALSE([webView querySelectorExists:@"ol"]);
+
+    [webView insertUnorderedList:nil];
+    EXPECT_TRUE([webView querySelectorExists:@"ul"]);
+    [webView insertUnorderedList:nil];
+    EXPECT_FALSE([webView querySelectorExists:@"ul"]);
+}
+
+TEST(WKWebViewEditActions, ChangeIndentation)
+{
+    auto webView = webViewForEditActionTesting();
+
+    [webView indent:nil];
+    EXPECT_TRUE([webView querySelectorExists:@"blockquote"]);
+    [webView indent:nil];
+    EXPECT_TRUE([webView querySelectorExists:@"blockquote > blockquote"]);
+
+    [webView outdent:nil];
+    EXPECT_TRUE([webView querySelectorExists:@"blockquote"]);
+    [webView outdent:nil];
+    EXPECT_FALSE([webView querySelectorExists:@"blockquote"]);
+}
+
+TEST(WKWebViewEditActions, SetAlignment)
+{
+    auto webView = webViewForEditActionTesting();
+    auto runTest = [webView] {
+        [webView alignCenter:nil];
+        EXPECT_WK_STREQ("center", [webView stylePropertyAtSelectionStart:@"text-align"]);
+        [webView alignLeft:nil];
+        EXPECT_WK_STREQ("left", [webView stylePropertyAtSelectionStart:@"text-align"]);
+        [webView alignRight:nil];
+        EXPECT_WK_STREQ("right", [webView stylePropertyAtSelectionStart:@"text-align"]);
+        [webView alignJustified:nil];
+        EXPECT_WK_STREQ("justify", [webView stylePropertyAtSelectionStart:@"text-align"]);
+    };
+
+    [webView evaluateJavaScript:@"document.body.dir = 'rtl'" completionHandler:nil];
+    runTest();
+
+    [webView evaluateJavaScript:@"document.body.dir = 'ltr'" completionHandler:nil];
+    runTest();
+}
+
+TEST(WKWebViewEditActions, ToggleStrikeThrough)
+{
+    auto webView = webViewForEditActionTesting();
+    [webView selectAll:nil];
+    [webView toggleStrikeThrough:nil];
+    EXPECT_WK_STREQ("line-through", [webView stylePropertyAtSelectionStart:@"-webkit-text-decorations-in-effect"]);
+    EXPECT_WK_STREQ("line-through", [webView stylePropertyAtSelectionEnd:@"-webkit-text-decorations-in-effect"]);
+
+    [webView toggleStrikeThrough:nil];
+    EXPECT_WK_STREQ("none", [webView stylePropertyAtSelectionStart:@"-webkit-text-decorations-in-effect"]);
+    EXPECT_WK_STREQ("none", [webView stylePropertyAtSelectionEnd:@"-webkit-text-decorations-in-effect"]);
+
+    [webView collapseToEnd];
+    [webView toggleStrikeThrough:nil];
+    [[webView textInputContentView] insertText:@"Hello"];
+    EXPECT_WK_STREQ("line-through", [webView stylePropertyAtSelectionStart:@"-webkit-text-decorations-in-effect"]);
+
+    [webView toggleStrikeThrough:nil];
+    [[webView textInputContentView] insertText:@"Hello"];
+    EXPECT_WK_STREQ("none", [webView stylePropertyAtSelectionStart:@"-webkit-text-decorations-in-effect"]);
+}
+
+TEST(WKWebViewEditActions, ChangeFontSize)
+{
+    auto webView = webViewForEditActionTesting();
+    [webView selectAll:nil];
+    EXPECT_EQ(16, [[webView stylePropertyAtSelectionStart:@"font-size"] floatValue]);
+
+    [webView increaseSize:nil];
+    EXPECT_EQ(17, [[webView stylePropertyAtSelectionStart:@"font-size"] floatValue]);
+    [webView increaseSize:nil];
+    EXPECT_EQ(18, [[webView stylePropertyAtSelectionStart:@"font-size"] floatValue]);
+
+    [webView decreaseSize:nil];
+    EXPECT_EQ(17, [[webView stylePropertyAtSelectionStart:@"font-size"] floatValue]);
+    [webView decreaseSize:nil];
+    EXPECT_EQ(16, [[webView stylePropertyAtSelectionStart:@"font-size"] floatValue]);
+
+    [webView setFontSize:20 sender:nil];
+    EXPECT_EQ(20, [[webView stylePropertyAtSelectionStart:@"font-size"] floatValue]);
+}
+
+TEST(WKWebViewEditActions, SetTextColor)
+{
+    auto webView = webViewForEditActionTesting();
+    [webView selectAll:nil];
+
+    [webView setTextColor:[UIColor colorWithRed:1 green:0 blue:0 alpha:1] sender:nil];
+    EXPECT_WK_STREQ("rgb(255, 0, 0)", [webView stylePropertyAtSelectionStart:@"color"]);
+    EXPECT_TRUE([webView querySelectorExists:@"font"]);
+
+    [webView setTextColor:[UIColor colorWithRed:0 green:1 blue:0 alpha:0.2] sender:nil];
+    EXPECT_WK_STREQ("rgba(0, 255, 0, 0.2)", [webView stylePropertyAtSelectionStart:@"color"]);
+    EXPECT_FALSE([webView querySelectorExists:@"font"]);
+}
+
+TEST(WKWebViewEditActions, SetFontFamily)
+{
+    auto webView = webViewForEditActionTesting();
+    [webView selectAll:nil];
+
+    UIFontDescriptor *fontDescriptor = [UIFontDescriptor fontDescriptorWithFontAttributes:@{ UIFontDescriptorFamilyAttribute: @"Helvetica" }];
+    [webView setFont:[UIFont fontWithDescriptor:fontDescriptor size:24] sender:nil];
+    EXPECT_WK_STREQ("Helvetica", [webView stylePropertyAtSelectionStart:@"font-family"]);
+    EXPECT_WK_STREQ("24px", [webView stylePropertyAtSelectionStart:@"font-size"]);
+    EXPECT_WK_STREQ("normal", [webView stylePropertyAtSelectionStart:@"font-weight"]);
+    EXPECT_WK_STREQ("normal", [webView stylePropertyAtSelectionStart:@"font-style"]);
+
+    [webView setFont:[UIFont fontWithName:@"TimesNewRomanPS-BoldMT" size:12] sender:nil];
+    EXPECT_WK_STREQ("\"Times New Roman\"", [webView stylePropertyAtSelectionStart:@"font-family"]);
+    EXPECT_WK_STREQ("12px", [webView stylePropertyAtSelectionStart:@"font-size"]);
+    EXPECT_WK_STREQ("bold", [webView stylePropertyAtSelectionStart:@"font-weight"]);
+    EXPECT_WK_STREQ("normal", [webView stylePropertyAtSelectionStart:@"font-style"]);
+
+    fontDescriptor = [fontDescriptor fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitItalic | UIFontDescriptorTraitBold];
+    [webView setFont:[UIFont fontWithDescriptor:fontDescriptor size:20] sender:nil];
+    EXPECT_WK_STREQ("Helvetica", [webView stylePropertyAtSelectionStart:@"font-family"]);
+    EXPECT_WK_STREQ("20px", [webView stylePropertyAtSelectionStart:@"font-size"]);
+    EXPECT_WK_STREQ("bold", [webView stylePropertyAtSelectionStart:@"font-weight"]);
+    EXPECT_WK_STREQ("italic", [webView stylePropertyAtSelectionStart:@"font-style"]);
+}
+
+} // namespace TestWebKitAPI
+
+#endif // PLATFORM(IOS) && WK_API_ENABLED
index 6a44679..4bcbec4 100644 (file)
 @property (nonatomic, readonly) NSString *selectedText;
 
 - (NSDictionary<NSString *, id> *)typingAttributes;
-- (NSString *)stylePropertyAtSelectionStart:(NSString *)propertyName;
-- (NSString *)stylePropertyAtSelectionEnd:(NSString *)propertyName;
 - (void)selectNextWord;
-- (void)collapseToStart;
-- (void)collapseToEnd;
 
 @end
 
     [self selectWord:nil];
 }
 
-- (void)collapseToStart
-{
-    [self evaluateJavaScript:@"getSelection().collapseToStart()" completionHandler:nil];
-}
-
-- (void)collapseToEnd
-{
-    [self evaluateJavaScript:@"getSelection().collapseToEnd()" completionHandler:nil];
-}
-
-- (NSString *)stylePropertyAtSelectionStart:(NSString *)propertyName
-{
-    NSString *script = [NSString stringWithFormat:@"getComputedStyle(getSelection().getRangeAt(0).startContainer.parentElement)['%@']", propertyName];
-    return [self stringByEvaluatingJavaScript:script];
-}
-
-- (NSString *)stylePropertyAtSelectionEnd:(NSString *)propertyName
-{
-    NSString *script = [NSString stringWithFormat:@"getComputedStyle(getSelection().getRangeAt(0).endContainer.parentElement)['%@']", propertyName];
-    return [self stringByEvaluatingJavaScript:script];
-}
-
 @end
 
 static RetainPtr<FontManagerTestWKWebView> webViewForFontManagerTesting(NSFontManager *fontManager, NSString *markup)
index fe91add..13269cf 100644 (file)
 - (void)waitForMessage:(NSString *)message;
 - (void)performAfterLoading:(dispatch_block_t)actions;
 - (void)waitForNextPresentationUpdate;
+- (NSString *)stylePropertyAtSelectionStart:(NSString *)propertyName;
+- (NSString *)stylePropertyAtSelectionEnd:(NSString *)propertyName;
+- (void)collapseToStart;
+- (void)collapseToEnd;
 @end
 
 #if PLATFORM(IOS)
index add013f..98f4f09 100644 (file)
@@ -315,6 +315,28 @@ NSEventMask __simulated_forceClickAssociatedEventsMask(id self, SEL _cmd)
     TestWebKitAPI::Util::run(&done);
 }
 
+- (NSString *)stylePropertyAtSelectionStart:(NSString *)propertyName
+{
+    NSString *script = [NSString stringWithFormat:@"getComputedStyle(getSelection().getRangeAt(0).startContainer.parentElement)['%@']", propertyName];
+    return [self stringByEvaluatingJavaScript:script];
+}
+
+- (NSString *)stylePropertyAtSelectionEnd:(NSString *)propertyName
+{
+    NSString *script = [NSString stringWithFormat:@"getComputedStyle(getSelection().getRangeAt(0).endContainer.parentElement)['%@']", propertyName];
+    return [self stringByEvaluatingJavaScript:script];
+}
+
+- (void)collapseToStart
+{
+    [self evaluateJavaScript:@"getSelection().collapseToStart()" completionHandler:nil];
+}
+
+- (void)collapseToEnd
+{
+    [self evaluateJavaScript:@"getSelection().collapseToEnd()" completionHandler:nil];
+}
+
 @end
 
 #if PLATFORM(IOS)