Add enterkeyhint support
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 29 Oct 2019 19:39:47 +0000 (19:39 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 29 Oct 2019 19:39:47 +0000 (19:39 +0000)
https://bugs.webkit.org/show_bug.cgi?id=189546
<rdar://problem/51021148>

Reviewed by Tim Horton.

Source/WebCore:

* Headers.cmake: Add EnterKeyHint.h.

Source/WebKit:

This patch adds support for the enterkeyhint HTML attribute on iOS.

Tests:  EnterKeyHintTests.EnterKeyHintInContentEditableElement
        EnterKeyHintTests.EnterKeyHintInTextInput
        EnterKeyHintTests.EnterKeyHintInTextArea

* Shared/FocusedElementInformation.cpp:
(WebKit::FocusedElementInformation::encode const):
(WebKit::FocusedElementInformation::decode):
* Shared/FocusedElementInformation.h:

Add a new flag to FocusedElementInformation to indicate the EnterKeyHint type that should be used when bringing
up an input view for the focused element.

* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView textInputTraits]):

Map the given EnterKeyHint type to a UIReturnKeyType. If an unsupported (i.e. "previous") or default
EnterKeyHint value is used, then we fall back to existing behavior which deduces the default enterkeyhint value
from the input type if the focused element is inside an actionable form; otherwise, we avoid setting any value
for the `returnKeyType`, defaulting to `UIReturnKeyDefault`.

* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::getFocusedElementInformation):

Tools:

Add new API tests to check the resulting UIReturnKeyType that gets set on text input traits in the UI process,
given the different values for "enterkeyhint". Also verifies that the default behaviors of search fields and
text input fields inside actionable form elements is to show "Search" or "Go" as the return key by default,
unless a different value for "enterkeyhint" is specified.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/ios/EnterKeyHintTests.mm: Added.
(-[TestWKWebView test:enterKeyHint:returnKeyType:]):
(TestWebKitAPI::enterKeyHintTestCases):
(TestWebKitAPI::createWebViewAndInputDelegateForTesting):
(TestWebKitAPI::TEST):

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

Source/WebCore/ChangeLog
Source/WebCore/Headers.cmake
Source/WebKit/ChangeLog
Source/WebKit/Shared/FocusedElementInformation.cpp
Source/WebKit/Shared/FocusedElementInformation.h
Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm
Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/ios/EnterKeyHintTests.mm [new file with mode: 0644]

index 4358db5..1e68802 100644 (file)
@@ -1,3 +1,13 @@
+2019-10-28  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        Add enterkeyhint support
+        https://bugs.webkit.org/show_bug.cgi?id=189546
+        <rdar://problem/51021148>
+
+        Reviewed by Tim Horton.
+
+        * Headers.cmake: Add EnterKeyHint.h.
+
 2019-10-29  Chris Dumez  <cdumez@apple.com>
 
         <input type="range">.setAttribute("value") does not update the value
index 55c0e0b..081651e 100644 (file)
@@ -541,6 +541,7 @@ set(WebCore_PRIVATE_FRAMEWORK_HEADERS
     html/CollectionType.h
     html/DOMTokenList.h
     html/DataListSuggestionInformation.h
+    html/EnterKeyHint.h
     html/FeaturePolicy.h
     html/FormAssociatedElement.h
     html/FormNamedItem.h
index 95e7e14..4558736 100644 (file)
@@ -1,3 +1,36 @@
+2019-10-27  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        Add enterkeyhint support
+        https://bugs.webkit.org/show_bug.cgi?id=189546
+        <rdar://problem/51021148>
+
+        Reviewed by Tim Horton.
+
+        This patch adds support for the enterkeyhint HTML attribute on iOS.
+
+        Tests:  EnterKeyHintTests.EnterKeyHintInContentEditableElement
+                EnterKeyHintTests.EnterKeyHintInTextInput
+                EnterKeyHintTests.EnterKeyHintInTextArea
+
+        * Shared/FocusedElementInformation.cpp:
+        (WebKit::FocusedElementInformation::encode const):
+        (WebKit::FocusedElementInformation::decode):
+        * Shared/FocusedElementInformation.h:
+
+        Add a new flag to FocusedElementInformation to indicate the EnterKeyHint type that should be used when bringing
+        up an input view for the focused element.
+
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView textInputTraits]):
+
+        Map the given EnterKeyHint type to a UIReturnKeyType. If an unsupported (i.e. "previous") or default
+        EnterKeyHint value is used, then we fall back to existing behavior which deduces the default enterkeyhint value
+        from the input type if the focused element is inside an actionable form; otherwise, we avoid setting any value
+        for the `returnKeyType`, defaulting to `UIReturnKeyDefault`.
+
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::getFocusedElementInformation):
+
 2019-10-29  Kate Cheney  <katherine_cheney@apple.com>
 
         Layout Test http/tests/resourceLoadStatistics/website-data-removal-for-site-navigated-to-with-link-decoration-database.html is a flaky failure
index d5aa31d..19f4375 100644 (file)
@@ -79,6 +79,7 @@ void FocusedElementInformation::encode(IPC::Encoder& encoder) const
     encoder.encodeEnum(autocapitalizeType);
     encoder.encodeEnum(elementType);
     encoder.encodeEnum(inputMode);
+    encoder.encodeEnum(enterKeyHint);
     encoder << formAction;
     encoder << selectOptions;
     encoder << selectedIndex;
@@ -162,6 +163,9 @@ bool FocusedElementInformation::decode(IPC::Decoder& decoder, FocusedElementInfo
     if (!decoder.decodeEnum(result.inputMode))
         return false;
 
+    if (!decoder.decodeEnum(result.enterKeyHint))
+        return false;
+
     if (!decoder.decode(result.formAction))
         return false;
 
index 5facfe1..b853cd1 100644 (file)
@@ -30,6 +30,7 @@
 #include <WebCore/Autofill.h>
 #include <WebCore/Color.h>
 #include <WebCore/ElementContext.h>
+#include <WebCore/EnterKeyHint.h>
 #include <WebCore/GraphicsLayer.h>
 #include <WebCore/InputMode.h>
 #include <WebCore/IntRect.h>
@@ -118,6 +119,7 @@ struct FocusedElementInformation {
     AutocapitalizeType autocapitalizeType { AutocapitalizeTypeDefault };
     InputType elementType { InputType::None };
     WebCore::InputMode inputMode { WebCore::InputMode::Unspecified };
+    WebCore::EnterKeyHint enterKeyHint { WebCore::EnterKeyHint::Unspecified };
     String formAction;
     Vector<OptionItem> selectOptions;
     int selectedIndex { -1 };
index 8957227..9ba3758 100644 (file)
@@ -4709,8 +4709,30 @@ static NSString *contentTypeFromFieldName(WebCore::AutofillFieldName fieldName)
     [_traits setSecureTextEntry:_focusedElementInformation.elementType == WebKit::InputType::Password || [_formInputSession forceSecureTextEntry]];
     [_traits setShortcutConversionType:_focusedElementInformation.elementType == WebKit::InputType::Password ? UITextShortcutConversionTypeNo : UITextShortcutConversionTypeDefault];
 
-    if (!_focusedElementInformation.formAction.isEmpty())
-        [_traits setReturnKeyType:(_focusedElementInformation.elementType == WebKit::InputType::Search) ? UIReturnKeySearch : UIReturnKeyGo];
+    switch (_focusedElementInformation.enterKeyHint) {
+    case WebCore::EnterKeyHint::Enter:
+        [_traits setReturnKeyType:UIReturnKeyDefault];
+        break;
+    case WebCore::EnterKeyHint::Done:
+        [_traits setReturnKeyType:UIReturnKeyDone];
+        break;
+    case WebCore::EnterKeyHint::Go:
+        [_traits setReturnKeyType:UIReturnKeyGo];
+        break;
+    case WebCore::EnterKeyHint::Next:
+        [_traits setReturnKeyType:UIReturnKeyNext];
+        break;
+    case WebCore::EnterKeyHint::Search:
+        [_traits setReturnKeyType:UIReturnKeySearch];
+        break;
+    case WebCore::EnterKeyHint::Send:
+        [_traits setReturnKeyType:UIReturnKeySend];
+        break;
+    default: {
+        if (!_focusedElementInformation.formAction.isEmpty())
+            [_traits setReturnKeyType:_focusedElementInformation.elementType == WebKit::InputType::Search ? UIReturnKeySearch : UIReturnKeyGo];
+    }
+    }
 
     if (_focusedElementInformation.elementType == WebKit::InputType::Password || _focusedElementInformation.elementType == WebKit::InputType::Email || _focusedElementInformation.elementType == WebKit::InputType::URL || _focusedElementInformation.formAction.contains("login")) {
         [_traits setAutocapitalizationType:UITextAutocapitalizationTypeNone];
index d623810..1c02adb 100644 (file)
@@ -2987,6 +2987,7 @@ void WebPage::getFocusedElementInformation(FocusedElementInformation& informatio
         information.autofillFieldName = WebCore::toAutofillFieldName(element.autofillData().fieldName);
         information.placeholder = element.attributeWithoutSynchronization(HTMLNames::placeholderAttr);
         information.inputMode = element.canonicalInputMode();
+        information.enterKeyHint = element.canonicalEnterKeyHint();
     } else if (is<HTMLInputElement>(*m_focusedElement)) {
         HTMLInputElement& element = downcast<HTMLInputElement>(*m_focusedElement);
         HTMLFormElement* form = element.form();
@@ -3048,6 +3049,7 @@ void WebPage::getFocusedElementInformation(FocusedElementInformation& informatio
         information.hasSuggestions = !!element.list();
 #endif
         information.inputMode = element.canonicalInputMode();
+        information.enterKeyHint = element.canonicalEnterKeyHint();
         information.isReadOnly = element.isReadOnly();
         information.value = element.value();
         information.valueAsNumber = element.valueAsNumber();
@@ -3062,6 +3064,7 @@ void WebPage::getFocusedElementInformation(FocusedElementInformation& informatio
             information.isAutocorrect = focusedElement.shouldAutocorrect();
             information.autocapitalizeType = focusedElement.autocapitalizeType();
             information.inputMode = focusedElement.canonicalInputMode();
+            information.enterKeyHint = focusedElement.canonicalEnterKeyHint();
             information.shouldSynthesizeKeyEventsForEditing = focusedElement.document().settings().syntheticEditingCommandsEnabled();
         } else {
             information.isAutocorrect = true;
index 10bd45b..cf6d33e 100644 (file)
@@ -1,3 +1,23 @@
+2019-10-27  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        Add enterkeyhint support
+        https://bugs.webkit.org/show_bug.cgi?id=189546
+        <rdar://problem/51021148>
+
+        Reviewed by Tim Horton.
+
+        Add new API tests to check the resulting UIReturnKeyType that gets set on text input traits in the UI process,
+        given the different values for "enterkeyhint". Also verifies that the default behaviors of search fields and
+        text input fields inside actionable form elements is to show "Search" or "Go" as the return key by default,
+        unless a different value for "enterkeyhint" is specified.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/ios/EnterKeyHintTests.mm: Added.
+        (-[TestWKWebView test:enterKeyHint:returnKeyType:]):
+        (TestWebKitAPI::enterKeyHintTestCases):
+        (TestWebKitAPI::createWebViewAndInputDelegateForTesting):
+        (TestWebKitAPI::TEST):
+
 2019-10-29  Truitt Savell  <tsavell@apple.com>
 
         Unreviewed, rolling out r251639.
index 160c3a5..ed9c3f9 100644 (file)
                F4C8797F2059D8D3009CD00B /* ScrollViewInsetTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4C8797E2059D8D3009CD00B /* ScrollViewInsetTests.mm */; };
                F4CD74C620FDACFA00DE3794 /* text-with-async-script.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4CD74C520FDACF500DE3794 /* text-with-async-script.html */; };
                F4CD74C920FDB49600DE3794 /* TestURLSchemeHandler.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4CD74C820FDB49600DE3794 /* TestURLSchemeHandler.mm */; };
+               F4CF32802366552200D3AD07 /* EnterKeyHintTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4CF327F2366552200D3AD07 /* EnterKeyHintTests.mm */; };
                F4D2986E20FEE7370092D636 /* RunScriptAfterDocumentLoad.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4D2986D20FEE7370092D636 /* RunScriptAfterDocumentLoad.mm */; };
                F4D4F3B61E4E2BCB00BB2767 /* DragAndDropSimulatorIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4D4F3B41E4E2BCB00BB2767 /* DragAndDropSimulatorIOS.mm */; };
                F4D4F3B91E4E36E400BB2767 /* DragAndDropTestsIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4D4F3B71E4E36E400BB2767 /* DragAndDropTestsIOS.mm */; };
                F4CD74C720FDB49600DE3794 /* TestURLSchemeHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestURLSchemeHandler.h; sourceTree = "<group>"; };
                F4CD74C820FDB49600DE3794 /* TestURLSchemeHandler.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = TestURLSchemeHandler.mm; sourceTree = "<group>"; };
                F4CDAB3322489FE10057A2D9 /* IPadUserInterfaceSwizzler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IPadUserInterfaceSwizzler.h; sourceTree = "<group>"; };
+               F4CF327F2366552200D3AD07 /* EnterKeyHintTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = EnterKeyHintTests.mm; sourceTree = "<group>"; };
                F4D2986D20FEE7370092D636 /* RunScriptAfterDocumentLoad.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = RunScriptAfterDocumentLoad.mm; sourceTree = "<group>"; };
                F4D4F3B41E4E2BCB00BB2767 /* DragAndDropSimulatorIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DragAndDropSimulatorIOS.mm; sourceTree = "<group>"; };
                F4D4F3B71E4E36E400BB2767 /* DragAndDropTestsIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DragAndDropTestsIOS.mm; sourceTree = "<group>"; };
                                F42D634322A1729F00D2FB3A /* AutocorrectionTestsIOS.mm */,
                                44077BB0231449D200179E2D /* DataDetectorsTestIOS.mm */,
                                F4D4F3B71E4E36E400BB2767 /* DragAndDropTestsIOS.mm */,
+                               F4CF327F2366552200D3AD07 /* EnterKeyHintTests.mm */,
                                F4BC0B132146C849002A0478 /* FocusPreservationTests.mm */,
                                CDA93DAC22F4EC2200490A69 /* FullscreenTouchSecheuristicTests.cpp */,
                                F45E15722112CE2900307E82 /* KeyboardInputTestsIOS.mm */,
                                7CCE7EE01A411A9A00447C4C /* EditorCommands.mm in Sources */,
                                F44D06471F39627A001A0E29 /* EditorStateTests.mm in Sources */,
                                7CCE7EBF1A411A7E00447C4C /* ElementAtPointInWebFrame.mm in Sources */,
+                               F4CF32802366552200D3AD07 /* EnterKeyHintTests.mm in Sources */,
                                07492B3B1DF8B14C00633DE1 /* EnumerateMediaDevices.cpp in Sources */,
                                448D7E471EA6C55500ECC756 /* EnvironmentUtilitiesTest.cpp in Sources */,
                                7CCE7EEF1A411AE600447C4C /* EphemeralSessionPushStateNoHistoryCallback.cpp in Sources */,
diff --git a/Tools/TestWebKitAPI/Tests/ios/EnterKeyHintTests.mm b/Tools/TestWebKitAPI/Tests/ios/EnterKeyHintTests.mm
new file mode 100644 (file)
index 0000000..396334a
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2019 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_FAMILY)
+
+#import "TestInputDelegate.h"
+#import "TestWKWebView.h"
+#import "UIKitSPI.h"
+#import <WebKit/WKWebViewPrivate.h>
+#import <WebKit/_WKInputDelegate.h>
+#import <wtf/text/WTFString.h>
+
+@interface TestWKWebView (EnterKeyHintTests)
+- (void)test:(NSString *)querySelector enterKeyHint:(NSString *)enterKeyHint returnKeyType:(UIReturnKeyType)returnKeyType;
+@end
+
+@implementation TestWKWebView (EnterKeyHintTests)
+
+- (void)test:(NSString *)querySelector enterKeyHint:(NSString *)enterKeyHint returnKeyType:(UIReturnKeyType)returnKeyType
+{
+    [self stringByEvaluatingJavaScript:[NSString stringWithFormat:@"document.querySelector('%@').enterKeyHint = '%@'", querySelector, enterKeyHint]];
+    [self evaluateJavaScriptAndWaitForInputSessionToChange:[NSString stringWithFormat:@"document.querySelector('%@').focus()", querySelector]];
+    EXPECT_EQ(returnKeyType, [self textInputContentView].textInputTraits.returnKeyType);
+    [self evaluateJavaScriptAndWaitForInputSessionToChange:@"document.activeElement.blur()"];
+}
+
+@end
+
+namespace TestWebKitAPI {
+
+using EnterKeyHintTestCase = std::pair<RetainPtr<NSString>, UIReturnKeyType>;
+
+Vector<EnterKeyHintTestCase> enterKeyHintTestCases(UIReturnKeyType fallbackReturnKeyType = UIReturnKeyDefault)
+{
+    return {
+        { @"", fallbackReturnKeyType },
+        { @"enter", UIReturnKeyDefault },
+        { @"done", UIReturnKeyDone },
+        { @"go", UIReturnKeyGo },
+        { @"next", UIReturnKeyNext },
+        { @"previous", fallbackReturnKeyType },
+        { @"search", UIReturnKeySearch },
+        { @"send", UIReturnKeySend }
+    };
+}
+
+static std::pair<RetainPtr<TestWKWebView>, RetainPtr<TestInputDelegate>> createWebViewAndInputDelegateForTesting()
+{
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+    auto inputDelegate = adoptNS([[TestInputDelegate alloc] init]);
+    [inputDelegate setFocusStartsInputSessionPolicyHandler:[&] (WKWebView *, id <_WKFocusedElementInfo>) -> _WKFocusStartsInputSessionPolicy {
+        return _WKFocusStartsInputSessionPolicyAllow;
+    }];
+    [webView _setInputDelegate:inputDelegate.get()];
+    return { WTFMove(webView), WTFMove(inputDelegate) };
+}
+
+TEST(EnterKeyHintTests, EnterKeyHintInContentEditableElement)
+{
+    RetainPtr<TestWKWebView> webView;
+    RetainPtr<TestInputDelegate> inputDelegate;
+    std::tie(webView, inputDelegate) = createWebViewAndInputDelegateForTesting();
+    [webView synchronouslyLoadHTMLString:@"<div contenteditable></div>"];
+    for (auto& test : enterKeyHintTestCases())
+        [webView test:@"div" enterKeyHint:test.first.get() returnKeyType:test.second];
+}
+
+TEST(EnterKeyHintTests, EnterKeyHintInTextInput)
+{
+    RetainPtr<TestWKWebView> webView;
+    RetainPtr<TestInputDelegate> inputDelegate;
+    std::tie(webView, inputDelegate) = createWebViewAndInputDelegateForTesting();
+    [webView synchronouslyLoadHTMLString:@""
+        "<form action='#' method='post'>"
+        "    <input id='one' name='foo' />"
+        "    <input id='two' type='search' name='bar' />"
+        "    <input type='submit' value='test' />"
+        "</form>"
+        "<input id='three' />"];
+
+    for (auto& test : enterKeyHintTestCases(UIReturnKeyGo))
+        [webView test:@"#one" enterKeyHint:test.first.get() returnKeyType:test.second];
+
+    for (auto& test : enterKeyHintTestCases(UIReturnKeySearch))
+        [webView test:@"#two" enterKeyHint:test.first.get() returnKeyType:test.second];
+
+    for (auto& test : enterKeyHintTestCases())
+        [webView test:@"#three" enterKeyHint:test.first.get() returnKeyType:test.second];
+}
+
+TEST(EnterKeyHintTests, EnterKeyHintInTextArea)
+{
+    RetainPtr<TestWKWebView> webView;
+    RetainPtr<TestInputDelegate> inputDelegate;
+    std::tie(webView, inputDelegate) = createWebViewAndInputDelegateForTesting();
+    [webView synchronouslyLoadHTMLString:@"<textarea></textarea>"];
+    for (auto& test : enterKeyHintTestCases())
+        [webView test:@"textarea" enterKeyHint:test.first.get() returnKeyType:test.second];
+}
+
+} // namespace TestWebKitAPI
+
+#endif // PLATFORM(IOS_FAMILY)