[Datalist][macOS] Add suggestions UI for TextFieldInputTypes
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 16 Jul 2018 21:15:57 +0000 (21:15 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 16 Jul 2018 21:15:57 +0000 (21:15 +0000)
https://bugs.webkit.org/show_bug.cgi?id=186531

Patch by Aditya Keerthi <akeerthi@apple.com> on 2018-07-16
Reviewed by Tim Horton.

Source/WebCore:

Tests: fast/forms/datalist/datalist-show-hide.html
       fast/forms/datalist/datalist-textinput-keydown.html

* html/TextFieldInputType.cpp:
(WebCore::TextFieldInputType::handleKeydownEvent):
(WebCore::TextFieldInputType::handleKeydownEventForSpinButton): The suggestions view takes precedence when handling arrow key events.

Source/WebKit:

Created WebDataListSuggestionsDropdownMac as a wrapper around the suggestions
view. The suggestions for TextFieldInputTypes are displayed using an NSTableView
in it's own child window. This is done so that suggestions can be presented
outside of the page if the parent window's size is too small. The maximum number
of suggestions that are visible at one time is 6, with additional suggestions made
available by scrolling.

Suggestions in the view can be selected via click or by using arrow keys. If the
input element associated with the suggestions is blurred, or the page is moved in
any way, the suggestions view is hidden.

Added IPC messages to the UIProcess to enable the display of the suggestions view.
This required a new ArgumentCoder for DataListSuggestionInformation.

* Shared/WebCoreArgumentCoders.cpp:
(IPC::ArgumentCoder<DataListSuggestionInformation>::encode):
(IPC::ArgumentCoder<DataListSuggestionInformation>::decode):
* Shared/WebCoreArgumentCoders.h:
* UIProcess/PageClient.h:
* UIProcess/WebDataListSuggestionsDropdown.cpp: Copied from Source/WebKit/WebProcess/WebCoreSupport/WebDataListSuggestionPicker.h.
(WebKit::WebDataListSuggestionsDropdown::WebDataListSuggestionsDropdown):
(WebKit::WebDataListSuggestionsDropdown::~WebDataListSuggestionsDropdown):
(WebKit::WebDataListSuggestionsDropdown::close):
* UIProcess/WebDataListSuggestionsDropdown.h: Copied from Source/WebKit/WebProcess/WebCoreSupport/WebDataListSuggestionPicker.h.
(WebKit::WebDataListSuggestionsDropdown::Client::~Client):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::viewWillStartLiveResize):
(WebKit::WebPageProxy::viewDidLeaveWindow):
(WebKit::WebPageProxy::handleWheelEvent):
(WebKit::WebPageProxy::setPageZoomFactor):
(WebKit::WebPageProxy::setPageAndTextZoomFactors):
(WebKit::WebPageProxy::didStartProvisionalLoadForFrame):
(WebKit::WebPageProxy::pageDidScroll):
(WebKit::WebPageProxy::showDataListSuggestions):
(WebKit::WebPageProxy::handleKeydownInDataList):
(WebKit::WebPageProxy::endDataListSuggestions):
(WebKit::WebPageProxy::didCloseSuggestions):
(WebKit::WebPageProxy::didSelectOption):
(WebKit::WebPageProxy::resetState):
(WebKit::WebPageProxy::closeOverlayedViews):
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* UIProcess/ios/PageClientImplIOS.h:
* UIProcess/ios/PageClientImplIOS.mm:
(WebKit::PageClientImpl::createDataListSuggestionsDropdown):
* UIProcess/mac/PageClientImplMac.h:
* UIProcess/mac/PageClientImplMac.mm:
(WebKit::PageClientImpl::createDataListSuggestionsDropdown):
* UIProcess/mac/WebDataListSuggestionsDropdownMac.h: Copied from Source/WebKit/WebProcess/WebCoreSupport/WebDataListSuggestionPicker.h.
* UIProcess/mac/WebDataListSuggestionsDropdownMac.mm: Added.
(WebKit::WebDataListSuggestionsDropdownMac::create):
(WebKit::WebDataListSuggestionsDropdownMac::~WebDataListSuggestionsDropdownMac):
(WebKit::WebDataListSuggestionsDropdownMac::WebDataListSuggestionsDropdownMac):
(WebKit::WebDataListSuggestionsDropdownMac::show):
(WebKit::WebDataListSuggestionsDropdownMac::didSelectOption):
(WebKit::WebDataListSuggestionsDropdownMac::selectOption):
(WebKit::WebDataListSuggestionsDropdownMac::handleKeydownWithIdentifier):
(WebKit::WebDataListSuggestionsDropdownMac::close):
(-[WKDataListSuggestionCell initWithFrame:]):
(-[WKDataListSuggestionCell setText:]):
(-[WKDataListSuggestionCell setActive:]):
(-[WKDataListSuggestionCell drawRect:]):
(-[WKDataListSuggestionCell mouseEntered:]):
(-[WKDataListSuggestionCell mouseExited:]):
(-[WKDataListSuggestionCell acceptsFirstResponder]):
(-[WKDataListSuggestionTable initWithElementRect:]):
(-[WKDataListSuggestionTable setVisibleRect:]):
(-[WKDataListSuggestionTable currentActiveRow]):
(-[WKDataListSuggestionTable setActiveRow:]):
(-[WKDataListSuggestionTable reload]):
(-[WKDataListSuggestionTable acceptsFirstResponder]):
(-[WKDataListSuggestionTable enclosingScrollView]):
(-[WKDataListSuggestionTable removeFromSuperviewWithoutNeedingDisplay]):
(-[WKDataListSuggestionsView initWithInformation:inView:]):
(-[WKDataListSuggestionsView currentSelectedString]):
(-[WKDataListSuggestionsView updateWithInformation:]):
(-[WKDataListSuggestionsView moveSelectionByDirection:]):
(-[WKDataListSuggestionsView invalidate]):
(-[WKDataListSuggestionsView dropdownRectForElementRect:]):
(-[WKDataListSuggestionsView showSuggestionsDropdown:]):
(-[WKDataListSuggestionsView selectedRow:]):
(-[WKDataListSuggestionsView numberOfRowsInTableView:]):
(-[WKDataListSuggestionsView tableView:heightOfRow:]):
(-[WKDataListSuggestionsView tableView:viewForTableColumn:row:]):
* WebKit.xcodeproj/project.pbxproj:
* WebProcess/WebCoreSupport/WebDataListSuggestionPicker.cpp:
(WebKit::WebDataListSuggestionPicker::handleKeydownWithIdentifier):
(WebKit::WebDataListSuggestionPicker::didSelectOption):
(WebKit::WebDataListSuggestionPicker::didCloseSuggestions):
(WebKit::WebDataListSuggestionPicker::close):
(WebKit::WebDataListSuggestionPicker::displayWithActivationType):
* WebProcess/WebCoreSupport/WebDataListSuggestionPicker.h:

Tools:

Added isShowingDatalistSuggestions testing hook in order to enable testing of the
visibility of the suggestions view.

* DumpRenderTree/mac/UIScriptControllerMac.mm:
(WTR::UIScriptController::isShowingDataListSuggestions const):
* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.cpp:
(WTR::UIScriptController::isShowingDataListSuggestions const):
* TestRunnerShared/UIScriptContext/UIScriptController.h:
* WebKitTestRunner/mac/UIScriptControllerMac.mm:
(WTR::UIScriptController::isShowingDataListSuggestions const):

LayoutTests:

Added tests to verify that the suggestions are correctly shown and hidden, and that
suggestions can be selected and inserted into an input field.

* fast/forms/datalist/datalist-show-hide-expected.txt: Added.
* fast/forms/datalist/datalist-show-hide.html: Added.
* fast/forms/datalist/datalist-textinput-keydown-expected.txt: Added.
* fast/forms/datalist/datalist-textinput-keydown.html: Added.
* platform/ios/TestExpectations:
* resources/ui-helper.js:
(window.UIHelper.isShowingDataListSuggestions):

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

33 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/forms/datalist/datalist-show-hide-expected.txt [new file with mode: 0644]
LayoutTests/fast/forms/datalist/datalist-show-hide.html [new file with mode: 0644]
LayoutTests/fast/forms/datalist/datalist-textinput-keydown-expected.txt [new file with mode: 0644]
LayoutTests/fast/forms/datalist/datalist-textinput-keydown.html [new file with mode: 0644]
LayoutTests/platform/ios/TestExpectations
LayoutTests/resources/ui-helper.js
Source/WebCore/ChangeLog
Source/WebCore/html/TextFieldInputType.cpp
Source/WebKit/ChangeLog
Source/WebKit/Shared/WebCoreArgumentCoders.cpp
Source/WebKit/Shared/WebCoreArgumentCoders.h
Source/WebKit/UIProcess/PageClient.h
Source/WebKit/UIProcess/WebDataListSuggestionsDropdown.cpp [new file with mode: 0644]
Source/WebKit/UIProcess/WebDataListSuggestionsDropdown.h [new file with mode: 0644]
Source/WebKit/UIProcess/WebPageProxy.cpp
Source/WebKit/UIProcess/WebPageProxy.h
Source/WebKit/UIProcess/WebPageProxy.messages.in
Source/WebKit/UIProcess/ios/PageClientImplIOS.h
Source/WebKit/UIProcess/ios/PageClientImplIOS.mm
Source/WebKit/UIProcess/mac/PageClientImplMac.h
Source/WebKit/UIProcess/mac/PageClientImplMac.mm
Source/WebKit/UIProcess/mac/WebDataListSuggestionsDropdownMac.h [new file with mode: 0644]
Source/WebKit/UIProcess/mac/WebDataListSuggestionsDropdownMac.mm [new file with mode: 0644]
Source/WebKit/WebKit.xcodeproj/project.pbxproj
Source/WebKit/WebProcess/WebCoreSupport/WebDataListSuggestionPicker.cpp
Source/WebKit/WebProcess/WebCoreSupport/WebDataListSuggestionPicker.h
Tools/ChangeLog
Tools/DumpRenderTree/mac/UIScriptControllerMac.mm
Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl
Tools/TestRunnerShared/UIScriptContext/UIScriptController.cpp
Tools/TestRunnerShared/UIScriptContext/UIScriptController.h
Tools/WebKitTestRunner/mac/UIScriptControllerMac.mm

index d9c121b..68358d3 100644 (file)
@@ -1,3 +1,21 @@
+2018-07-16  Aditya Keerthi  <akeerthi@apple.com>
+
+        [Datalist][macOS] Add suggestions UI for TextFieldInputTypes
+        https://bugs.webkit.org/show_bug.cgi?id=186531
+
+        Reviewed by Tim Horton.
+
+        Added tests to verify that the suggestions are correctly shown and hidden, and that
+        suggestions can be selected and inserted into an input field.
+
+        * fast/forms/datalist/datalist-show-hide-expected.txt: Added.
+        * fast/forms/datalist/datalist-show-hide.html: Added.
+        * fast/forms/datalist/datalist-textinput-keydown-expected.txt: Added.
+        * fast/forms/datalist/datalist-textinput-keydown.html: Added.
+        * platform/ios/TestExpectations:
+        * resources/ui-helper.js:
+        (window.UIHelper.isShowingDataListSuggestions):
+
 2018-07-16  Jeremy Jones  <jeremyj@apple.com>
 
         Fullscreen requires active document.
diff --git a/LayoutTests/fast/forms/datalist/datalist-show-hide-expected.txt b/LayoutTests/fast/forms/datalist/datalist-show-hide-expected.txt
new file mode 100644 (file)
index 0000000..536aa42
--- /dev/null
@@ -0,0 +1,8 @@
+CLICK
+PASS showingList is "true"
+BLUR
+PASS showingList is "false"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/forms/datalist/datalist-show-hide.html b/LayoutTests/fast/forms/datalist/datalist-show-hide.html
new file mode 100644 (file)
index 0000000..c25d6ef
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../../resources/js-test.js"></script>
+<script src="../../../resources/ui-helper.js"></script>
+<head>
+<body onload="runTest()">
+<input id="fruit" list="fruits" type="text"/>
+<datalist id="fruits">
+    <option>Apple</option>
+    <option>Orange</option>
+    <option>Pear</option>
+</datalist>
+</body>
+<script>
+jsTestIsAsync = true;
+
+async function runTest() {
+    let input = document.getElementById("fruit");
+
+    await UIHelper.activateElement(input);
+    UIHelper.isShowingDataListSuggestions().then(async (value) => {
+        showingList = value;
+        debug("CLICK");
+        shouldBe("showingList", '"true"');
+
+        await UIHelper.activateAt(0, 0);
+        UIHelper.isShowingDataListSuggestions().then((value) => {
+            showingList = value;
+            debug("BLUR");
+            shouldBe("showingList", '"false"');
+            finishJSTest();
+        });
+    });
+}
+
+</script>
+</html>
diff --git a/LayoutTests/fast/forms/datalist/datalist-textinput-keydown-expected.txt b/LayoutTests/fast/forms/datalist/datalist-textinput-keydown-expected.txt
new file mode 100644 (file)
index 0000000..4ac50d6
--- /dev/null
@@ -0,0 +1,11 @@
+Test for keyboard operations for <input type=text> with list attribute
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS input.value is "Apple"
+PASS input.value is "Pear"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/forms/datalist/datalist-textinput-keydown.html b/LayoutTests/fast/forms/datalist/datalist-textinput-keydown.html
new file mode 100644 (file)
index 0000000..3346892
--- /dev/null
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../../resources/js-test-pre.js"></script>
+<script src="../../../resources/ui-helper.js"></script>
+</head>
+<body>
+
+<input id="fruit" list="fruits" type="text"/>
+<datalist id="fruits">
+    <option>Apple</option>
+    <option>Orange</option>
+    <option>Pear</option>
+</datalist>
+
+<script>
+
+description('Test for keyboard operations for &lt;input type=text&gt; with list attribute');
+
+var input = document.getElementById("fruit");
+
+UIHelper.activateElement(input);
+eventSender.keyDown("downArrow");
+eventSender.keyDown("\r");
+
+shouldBe('input.value', '"Apple"');
+
+input.value = "";
+
+UIHelper.activateElement(input);
+eventSender.keyDown("upArrow");
+eventSender.keyDown("\r");
+
+shouldBe('input.value', '"Pear"');
+
+</script>
+
+<script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
index 1f6baa2..4f14561 100644 (file)
@@ -3329,3 +3329,7 @@ fast/block/block-only/margin-left-right-sizing-out-of-flow.html [ Failure ]
 fast/block/block-only/margin-left-right-sizing.html [ Failure ]
 fast/block/block-only/margin-sibling-collapse-propagated.html [ Failure ]
 fast/block/block-only/relative-auto-with-parent-offset.html [ Failure ]
+
+# Datalist
+webkit.org/b/186714 fast/forms/datalist/datalist-show-hide.html [ Skip ]
+webkit.org/b/186714 fast/forms/datalist/datalist-textinput-keydown.html [ Skip ]
index 90e9640..40ad82d 100644 (file)
@@ -229,6 +229,15 @@ window.UIHelper = class UIHelper {
         });
     }
 
+    static isShowingDataListSuggestions()
+    {
+        return new Promise(resolve => {
+            testRunner.runUIScript(`(() => {
+                uiController.uiScriptComplete(uiController.isShowingDataListSuggestions);
+            })()`, resolve);
+        });
+    }
+
     static zoomScale()
     {
         return new Promise(resolve => {
index 62cc913..c5a3868 100644 (file)
@@ -1,3 +1,17 @@
+2018-07-16  Aditya Keerthi  <akeerthi@apple.com>
+
+        [Datalist][macOS] Add suggestions UI for TextFieldInputTypes
+        https://bugs.webkit.org/show_bug.cgi?id=186531
+
+        Reviewed by Tim Horton.
+
+        Tests: fast/forms/datalist/datalist-show-hide.html
+               fast/forms/datalist/datalist-textinput-keydown.html
+
+        * html/TextFieldInputType.cpp:
+        (WebCore::TextFieldInputType::handleKeydownEvent):
+        (WebCore::TextFieldInputType::handleKeydownEventForSpinButton): The suggestions view takes precedence when handling arrow key events.
+
 2018-07-16  Jeremy Jones  <jeremyj@apple.com>
 
         Fullscreen requires active document.
index 6667cf6..6fefffd 100644 (file)
@@ -184,8 +184,10 @@ void TextFieldInputType::handleKeydownEvent(KeyboardEvent& event)
         return;
 #if ENABLE(DATALIST_ELEMENT)
     const String& key = event.keyIdentifier();
-    if (m_suggestionPicker && (key == "Enter" || key == "Up" || key == "Down"))
+    if (m_suggestionPicker && (key == "Enter" || key == "Up" || key == "Down")) {
         m_suggestionPicker->handleKeydownWithIdentifier(key);
+        event.setDefaultHandled();
+    }
 #endif
     RefPtr<Frame> frame = element()->document().frame();
     if (!frame || !frame->editor().doTextFieldCommandFromEvent(element(), &event))
@@ -198,6 +200,10 @@ void TextFieldInputType::handleKeydownEventForSpinButton(KeyboardEvent& event)
     ASSERT(element());
     if (element()->isDisabledOrReadOnly())
         return;
+#if ENABLE(DATALIST_ELEMENT)
+    if (m_suggestionPicker)
+        return;
+#endif
     const String& key = event.keyIdentifier();
     if (key == "Up")
         spinButtonStepUp();
index c1da58f..4427f8d 100644 (file)
@@ -1,3 +1,103 @@
+2018-07-16  Aditya Keerthi  <akeerthi@apple.com>
+
+        [Datalist][macOS] Add suggestions UI for TextFieldInputTypes
+        https://bugs.webkit.org/show_bug.cgi?id=186531
+
+        Reviewed by Tim Horton.
+
+        Created WebDataListSuggestionsDropdownMac as a wrapper around the suggestions
+        view. The suggestions for TextFieldInputTypes are displayed using an NSTableView
+        in it's own child window. This is done so that suggestions can be presented
+        outside of the page if the parent window's size is too small. The maximum number
+        of suggestions that are visible at one time is 6, with additional suggestions made
+        available by scrolling.
+
+        Suggestions in the view can be selected via click or by using arrow keys. If the
+        input element associated with the suggestions is blurred, or the page is moved in
+        any way, the suggestions view is hidden.
+
+        Added IPC messages to the UIProcess to enable the display of the suggestions view.
+        This required a new ArgumentCoder for DataListSuggestionInformation.
+
+        * Shared/WebCoreArgumentCoders.cpp:
+        (IPC::ArgumentCoder<DataListSuggestionInformation>::encode):
+        (IPC::ArgumentCoder<DataListSuggestionInformation>::decode):
+        * Shared/WebCoreArgumentCoders.h:
+        * UIProcess/PageClient.h:
+        * UIProcess/WebDataListSuggestionsDropdown.cpp: Copied from Source/WebKit/WebProcess/WebCoreSupport/WebDataListSuggestionPicker.h.
+        (WebKit::WebDataListSuggestionsDropdown::WebDataListSuggestionsDropdown):
+        (WebKit::WebDataListSuggestionsDropdown::~WebDataListSuggestionsDropdown):
+        (WebKit::WebDataListSuggestionsDropdown::close):
+        * UIProcess/WebDataListSuggestionsDropdown.h: Copied from Source/WebKit/WebProcess/WebCoreSupport/WebDataListSuggestionPicker.h.
+        (WebKit::WebDataListSuggestionsDropdown::Client::~Client):
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::viewWillStartLiveResize):
+        (WebKit::WebPageProxy::viewDidLeaveWindow):
+        (WebKit::WebPageProxy::handleWheelEvent):
+        (WebKit::WebPageProxy::setPageZoomFactor):
+        (WebKit::WebPageProxy::setPageAndTextZoomFactors):
+        (WebKit::WebPageProxy::didStartProvisionalLoadForFrame):
+        (WebKit::WebPageProxy::pageDidScroll):
+        (WebKit::WebPageProxy::showDataListSuggestions):
+        (WebKit::WebPageProxy::handleKeydownInDataList):
+        (WebKit::WebPageProxy::endDataListSuggestions):
+        (WebKit::WebPageProxy::didCloseSuggestions):
+        (WebKit::WebPageProxy::didSelectOption):
+        (WebKit::WebPageProxy::resetState):
+        (WebKit::WebPageProxy::closeOverlayedViews):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+        * UIProcess/ios/PageClientImplIOS.h:
+        * UIProcess/ios/PageClientImplIOS.mm:
+        (WebKit::PageClientImpl::createDataListSuggestionsDropdown):
+        * UIProcess/mac/PageClientImplMac.h:
+        * UIProcess/mac/PageClientImplMac.mm:
+        (WebKit::PageClientImpl::createDataListSuggestionsDropdown):
+        * UIProcess/mac/WebDataListSuggestionsDropdownMac.h: Copied from Source/WebKit/WebProcess/WebCoreSupport/WebDataListSuggestionPicker.h.
+        * UIProcess/mac/WebDataListSuggestionsDropdownMac.mm: Added.
+        (WebKit::WebDataListSuggestionsDropdownMac::create):
+        (WebKit::WebDataListSuggestionsDropdownMac::~WebDataListSuggestionsDropdownMac):
+        (WebKit::WebDataListSuggestionsDropdownMac::WebDataListSuggestionsDropdownMac):
+        (WebKit::WebDataListSuggestionsDropdownMac::show):
+        (WebKit::WebDataListSuggestionsDropdownMac::didSelectOption):
+        (WebKit::WebDataListSuggestionsDropdownMac::selectOption):
+        (WebKit::WebDataListSuggestionsDropdownMac::handleKeydownWithIdentifier):
+        (WebKit::WebDataListSuggestionsDropdownMac::close):
+        (-[WKDataListSuggestionCell initWithFrame:]):
+        (-[WKDataListSuggestionCell setText:]):
+        (-[WKDataListSuggestionCell setActive:]):
+        (-[WKDataListSuggestionCell drawRect:]):
+        (-[WKDataListSuggestionCell mouseEntered:]):
+        (-[WKDataListSuggestionCell mouseExited:]):
+        (-[WKDataListSuggestionCell acceptsFirstResponder]):
+        (-[WKDataListSuggestionTable initWithElementRect:]):
+        (-[WKDataListSuggestionTable setVisibleRect:]):
+        (-[WKDataListSuggestionTable currentActiveRow]):
+        (-[WKDataListSuggestionTable setActiveRow:]):
+        (-[WKDataListSuggestionTable reload]):
+        (-[WKDataListSuggestionTable acceptsFirstResponder]):
+        (-[WKDataListSuggestionTable enclosingScrollView]):
+        (-[WKDataListSuggestionTable removeFromSuperviewWithoutNeedingDisplay]):
+        (-[WKDataListSuggestionsView initWithInformation:inView:]):
+        (-[WKDataListSuggestionsView currentSelectedString]):
+        (-[WKDataListSuggestionsView updateWithInformation:]):
+        (-[WKDataListSuggestionsView moveSelectionByDirection:]):
+        (-[WKDataListSuggestionsView invalidate]):
+        (-[WKDataListSuggestionsView dropdownRectForElementRect:]):
+        (-[WKDataListSuggestionsView showSuggestionsDropdown:]):
+        (-[WKDataListSuggestionsView selectedRow:]):
+        (-[WKDataListSuggestionsView numberOfRowsInTableView:]):
+        (-[WKDataListSuggestionsView tableView:heightOfRow:]):
+        (-[WKDataListSuggestionsView tableView:viewForTableColumn:row:]):
+        * WebKit.xcodeproj/project.pbxproj:
+        * WebProcess/WebCoreSupport/WebDataListSuggestionPicker.cpp:
+        (WebKit::WebDataListSuggestionPicker::handleKeydownWithIdentifier):
+        (WebKit::WebDataListSuggestionPicker::didSelectOption):
+        (WebKit::WebDataListSuggestionPicker::didCloseSuggestions):
+        (WebKit::WebDataListSuggestionPicker::close):
+        (WebKit::WebDataListSuggestionPicker::displayWithActivationType):
+        * WebProcess/WebCoreSupport/WebDataListSuggestionPicker.h:
+
 2018-07-16  Jeremy Jones  <jeremyj@apple.com>
 
         Fullscreen requires active document.
index a2b4bf5..bc1b6cc 100644 (file)
@@ -36,6 +36,7 @@
 #include <WebCore/CompositionUnderline.h>
 #include <WebCore/Credential.h>
 #include <WebCore/Cursor.h>
+#include <WebCore/DataListSuggestionPicker.h>
 #include <WebCore/DatabaseDetails.h>
 #include <WebCore/DictationAlternative.h>
 #include <WebCore/DictionaryPopupInfo.h>
@@ -1631,6 +1632,29 @@ bool ArgumentCoder<DatabaseDetails>::decode(Decoder& decoder, DatabaseDetails& d
     return true;
 }
 
+#if ENABLE(DATALIST_ELEMENT)
+void ArgumentCoder<DataListSuggestionInformation>::encode(Encoder& encoder, const WebCore::DataListSuggestionInformation& info)
+{
+    encoder.encodeEnum(info.activationType);
+    encoder << info.suggestions;
+    encoder << info.elementRect;
+}
+
+bool ArgumentCoder<DataListSuggestionInformation>::decode(Decoder& decoder, WebCore::DataListSuggestionInformation& info)
+{
+    if (!decoder.decodeEnum(info.activationType))
+        return false;
+
+    if (!decoder.decode(info.suggestions))
+        return false;
+
+    if (!decoder.decode(info.elementRect))
+        return false;
+
+    return true;
+}
+#endif
+
 void ArgumentCoder<PasteboardCustomData>::encode(Encoder& encoder, const PasteboardCustomData& data)
 {
     encoder << data.origin;
index 030f337..45c7c01 100644 (file)
@@ -135,6 +135,10 @@ struct PasteboardWebContent;
 struct ViewportArguments;
 #endif
 
+#if ENABLE(DATALIST_ELEMENT)
+struct DataListSuggestionInformation;
+#endif
+
 #if USE(SOUP)
 struct SoupNetworkProxySettings;
 #endif
@@ -453,6 +457,13 @@ template<> struct ArgumentCoder<WebCore::DatabaseDetails> {
     static bool decode(Decoder&, WebCore::DatabaseDetails&);
 };
 
+#if ENABLE(DATALIST_ELEMENT)
+template<> struct ArgumentCoder<WebCore::DataListSuggestionInformation> {
+    static void encode(Encoder&, const WebCore::DataListSuggestionInformation&);
+    static bool decode(Decoder&, WebCore::DataListSuggestionInformation&);
+};
+#endif
+
 template<> struct ArgumentCoder<WebCore::DictationAlternative> {
     static void encode(Encoder&, const WebCore::DictationAlternative&);
     static std::optional<WebCore::DictationAlternative> decode(Decoder&);
index b658fbb..6205950 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "ShareableBitmap.h"
 #include "WebColorPicker.h"
+#include "WebDataListSuggestionsDropdown.h"
 #include "WebPageProxy.h"
 #include "WebPopupMenuProxy.h"
 #include <WebCore/AlternativeTextClient.h>
@@ -81,6 +82,10 @@ class NativeWebTouchEvent;
 class WebColorPicker;
 #endif
 
+#if ENABLE(DATALIST_ELEMENT)
+class WebDataListSuggestionsDropdown;
+#endif
+
 #if ENABLE(FULLSCREEN_API)
 class WebFullScreenManagerProxyClient;
 #endif
@@ -222,6 +227,10 @@ public:
     virtual RefPtr<WebColorPicker> createColorPicker(WebPageProxy*, const WebCore::Color& initialColor, const WebCore::IntRect&) = 0;
 #endif
 
+#if ENABLE(DATALIST_ELEMENT)
+    virtual RefPtr<WebDataListSuggestionsDropdown> createDataListSuggestionsDropdown(WebPageProxy&) = 0;
+#endif
+
 #if PLATFORM(COCOA)
     virtual Ref<WebCore::ValidationBubble> createValidationBubble(const String& message, const WebCore::ValidationBubble::Settings&) = 0;
 #endif
diff --git a/Source/WebKit/UIProcess/WebDataListSuggestionsDropdown.cpp b/Source/WebKit/UIProcess/WebDataListSuggestionsDropdown.cpp
new file mode 100644 (file)
index 0000000..2f5fac0
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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 "WebDataListSuggestionsDropdown.h"
+
+#if ENABLE(DATALIST_ELEMENT)
+
+namespace WebKit {
+
+WebDataListSuggestionsDropdown::WebDataListSuggestionsDropdown(Client& client)
+    : m_client(&client)
+{
+}
+
+WebDataListSuggestionsDropdown::~WebDataListSuggestionsDropdown()
+{
+}
+
+void WebDataListSuggestionsDropdown::close()
+{
+    m_client->didCloseSuggestions();
+    m_client = nullptr;
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(DATALIST_ELEMENT)
diff --git a/Source/WebKit/UIProcess/WebDataListSuggestionsDropdown.h b/Source/WebKit/UIProcess/WebDataListSuggestionsDropdown.h
new file mode 100644 (file)
index 0000000..f61cf6d
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * 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
+
+#if ENABLE(DATALIST_ELEMENT)
+
+#include <WebCore/DataListSuggestionPicker.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebKit {
+
+class WebDataListSuggestionsDropdown : public RefCounted<WebDataListSuggestionsDropdown> {
+public:
+    class Client {
+    protected:
+        virtual ~Client() { }
+
+    public:
+        virtual void didSelectOption(String&) = 0;
+        virtual void didCloseSuggestions() = 0;
+    };
+
+    virtual ~WebDataListSuggestionsDropdown();
+
+    virtual void show(WebCore::DataListSuggestionInformation&&) = 0;
+    virtual void handleKeydownWithIdentifier(const String&) = 0;
+    virtual void close();
+
+protected:
+    explicit WebDataListSuggestionsDropdown(Client&);
+
+    Client* m_client;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(DATALIST_ELEMENT)
index 30251d1..48cc400 100644 (file)
@@ -1446,10 +1446,8 @@ void WebPageProxy::viewWillStartLiveResize()
 {
     if (!isValid())
         return;
-#if ENABLE(INPUT_TYPE_COLOR_POPOVER) && ENABLE(INPUT_TYPE_COLOR)
-    if (m_colorPicker)
-        endColorPicker();
-#endif
+
+    closeOverlayedViews();
     m_process->send(Messages::WebPage::ViewWillStartLiveResize(), m_pageID);
 }
 
@@ -1536,11 +1534,7 @@ void WebPageProxy::activityStateDidChange(ActivityState::Flags mayHaveChanged, b
 
 void WebPageProxy::viewDidLeaveWindow()
 {
-#if ENABLE(INPUT_TYPE_COLOR_POPOVER) && ENABLE(INPUT_TYPE_COLOR)
-    // When leaving the current page, close the popover color well.
-    if (m_colorPicker)
-        endColorPicker();
-#endif
+    closeOverlayedViews();
 #if PLATFORM(IOS) && HAVE(AVKIT) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
     // When leaving the current page, close the video fullscreen.
     if (m_videoFullscreenManager)
@@ -2062,7 +2056,7 @@ void WebPageProxy::handleWheelEvent(const NativeWebWheelEvent& event)
     if (!isValid())
         return;
 
-    hideValidationMessage();
+    closeOverlayedViews();
 
     if (!m_currentlyProcessedWheelEvents.isEmpty()) {
         m_wheelEventQueue.append(event);
@@ -2692,7 +2686,7 @@ void WebPageProxy::setPageZoomFactor(double zoomFactor)
     if (m_pageZoomFactor == zoomFactor)
         return;
 
-    hideValidationMessage();
+    closeOverlayedViews();
 
     m_pageZoomFactor = zoomFactor;
     m_process->send(Messages::WebPage::SetPageZoomFactor(m_pageZoomFactor), m_pageID); 
@@ -2706,7 +2700,7 @@ void WebPageProxy::setPageAndTextZoomFactors(double pageZoomFactor, double textZ
     if (m_pageZoomFactor == pageZoomFactor && m_textZoomFactor == textZoomFactor)
         return;
 
-    hideValidationMessage();
+    closeOverlayedViews();
 
     m_pageZoomFactor = pageZoomFactor;
     m_textZoomFactor = textZoomFactor;
@@ -3464,7 +3458,7 @@ void WebPageProxy::didStartProvisionalLoadForFrame(uint64_t frameID, uint64_t na
         m_pageLoadStart = MonotonicTime::now();
         m_pageLoadState.didStartProvisionalLoad(transaction, url, unreachableURL);
         m_pageClient.didStartProvisionalLoadForMainFrame();
-        hideValidationMessage();
+        closeOverlayedViews();
     }
 
     frame->setUnreachableURL(unreachableURL);
@@ -4555,7 +4549,7 @@ void WebPageProxy::pageDidScroll()
     if (m_isKeyboardAnimatingIn)
         return;
 #endif
-    hideValidationMessage();
+    closeOverlayedViews();
 }
 
 void WebPageProxy::runOpenPanel(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, const FileChooserSettings& settings)
@@ -4751,6 +4745,49 @@ void WebPageProxy::didEndColorPicker()
 }
 #endif
 
+#if ENABLE(DATALIST_ELEMENT)
+
+void WebPageProxy::showDataListSuggestions(WebCore::DataListSuggestionInformation&& info)
+{
+    if (!m_dataListSuggestionsDropdown)
+        m_dataListSuggestionsDropdown = m_pageClient.createDataListSuggestionsDropdown(*this);
+
+    m_dataListSuggestionsDropdown->show(WTFMove(info));
+}
+
+void WebPageProxy::handleKeydownInDataList(const String& key)
+{
+    if (!m_dataListSuggestionsDropdown)
+        return;
+
+    m_dataListSuggestionsDropdown->handleKeydownWithIdentifier(key);
+}
+
+void WebPageProxy::endDataListSuggestions()
+{
+    if (m_dataListSuggestionsDropdown)
+        m_dataListSuggestionsDropdown->close();
+}
+
+void WebPageProxy::didCloseSuggestions()
+{
+    if (!m_dataListSuggestionsDropdown)
+        return;
+
+    m_dataListSuggestionsDropdown = nullptr;
+    m_process->send(Messages::WebPage::DidCloseSuggestions(), m_pageID);
+}
+
+void WebPageProxy::didSelectOption(String& selectedOption)
+{
+    if (!isValid())
+        return;
+
+    m_process->send(Messages::WebPage::DidSelectDataListOption(selectedOption), m_pageID);
+}
+
+#endif
+
 WebInspectorProxy* WebPageProxy::inspector() const
 {
     if (isClosed() || !isValid())
@@ -5977,7 +6014,7 @@ void WebPageProxy::resetState(ResetStateReason resetStateReason)
     m_scrollingPerformanceData = nullptr;
 #endif
     m_drawingArea = nullptr;
-    hideValidationMessage();
+    closeOverlayedViews();
 
     if (m_inspector) {
         m_inspector->invalidate();
@@ -7532,7 +7569,22 @@ void WebPageProxy::hideValidationMessage()
     m_validationBubble = nullptr;
 #endif
 }
-    
+
+// FIXME: Consolidate with dismissContentRelativeChildWindows
+void WebPageProxy::closeOverlayedViews()
+{
+    hideValidationMessage();
+
+#if ENABLE(DATALIST_ELEMENT)
+    endDataListSuggestions();
+#endif
+
+#if ENABLE(INPUT_TYPE_COLOR_POPOVER) && ENABLE(INPUT_TYPE_COLOR)
+    if (m_colorPicker)
+        endColorPicker();
+#endif
+}
+
 #if ENABLE(POINTER_LOCK)
 void WebPageProxy::requestPointerLock()
 {
index 86a2700..6095f28 100644 (file)
@@ -54,6 +54,7 @@
 #include "WebColorPicker.h"
 #include "WebContextMenuItemData.h"
 #include "WebCoreArgumentCoders.h"
+#include "WebDataListSuggestionsDropdown.h"
 #include "WebFrameProxy.h"
 #include "WebPageCreationParameters.h"
 #include "WebPageDiagnosticLoggingClient.h"
@@ -177,6 +178,7 @@ enum class ShouldTreatAsContinuingLoad;
 
 struct ApplicationManifest;
 struct BackForwardItemIdentifier;
+struct DataListSuggestionInformation;
 struct DictionaryPopupInfo;
 struct ExceptionDetails;
 struct FileChooserSettings;
@@ -322,6 +324,9 @@ class WebPageProxy : public API::ObjectImpl<API::Object::Type::Page>
 #if ENABLE(INPUT_TYPE_COLOR)
     , public WebColorPicker::Client
 #endif
+#if ENABLE(DATALIST_ELEMENT)
+    , public WebDataListSuggestionsDropdown::Client
+#endif
 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
     , public WebCore::WebMediaSessionManagerClient
 #endif
@@ -1515,6 +1520,16 @@ private:
     void didEndColorPicker() override;
 #endif
 
+#if ENABLE(DATALIST_ELEMENT)
+    void showDataListSuggestions(WebCore::DataListSuggestionInformation&&);
+    void handleKeydownInDataList(const String&);
+    void endDataListSuggestions();
+    void didSelectOption(String&) final;
+    void didCloseSuggestions() final;
+#endif
+
+    void closeOverlayedViews();
+
     void compositionWasCanceled();
     void setHasHadSelectionChangesFromUserInteraction(bool);
     void setNeedsHiddenContentEditableQuirk(bool);
@@ -2031,6 +2046,9 @@ private:
 #if ENABLE(INPUT_TYPE_COLOR)
     RefPtr<WebColorPicker> m_colorPicker;
 #endif
+#if ENABLE(DATALIST_ELEMENT)
+    RefPtr<WebDataListSuggestionsDropdown> m_dataListSuggestionsDropdown;
+#endif
 #if PLATFORM(COCOA)
     RefPtr<WebCore::ValidationBubble> m_validationBubble;
 #endif
index 93e9529..6cf61c3 100644 (file)
@@ -98,6 +98,12 @@ messages -> WebPageProxy {
     EndColorPicker();
 #endif
 
+#if ENABLE(DATALIST_ELEMENT)
+    ShowDataListSuggestions(struct WebCore::DataListSuggestionInformation suggestionInformation);
+    HandleKeydownInDataList(String key);
+    EndDataListSuggestions();
+#endif
+
     # Policy messages
     DecidePolicyForResponse(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, uint64_t navigationID, WebCore::ResourceResponse response, WebCore::ResourceRequest request, bool canShowMIMEType, uint64_t listenerID, WebKit::UserData userData)
     DecidePolicyForNavigationAction(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, uint64_t navigationID, struct WebKit::NavigationActionData navigationActionData, struct WebKit::FrameInfoData originatingFrameInfoData, uint64_t originatingPageID, WebCore::ResourceRequest originalRequest, WebCore::ResourceRequest request, WebCore::ResourceResponse redirectResponse, uint64_t listenerID, WebKit::UserData userData)
index 152ff30..77e05ce 100644 (file)
@@ -100,6 +100,10 @@ private:
     RefPtr<WebPopupMenuProxy> createPopupMenuProxy(WebPageProxy&) override;
     Ref<WebCore::ValidationBubble> createValidationBubble(const String& message, const WebCore::ValidationBubble::Settings&) final;
 
+#if ENABLE(DATALIST_ELEMENT)
+    RefPtr<WebDataListSuggestionsDropdown> createDataListSuggestionsDropdown(WebPageProxy&) final;
+#endif
+
     void setTextIndicator(Ref<WebCore::TextIndicator>, WebCore::TextIndicatorWindowLifetime) override;
     void clearTextIndicator(WebCore::TextIndicatorWindowDismissalAnimation) override;
     void setTextIndicatorAnimationProgress(float) override;
index 4e77459..e17d00f 100644 (file)
@@ -764,6 +764,13 @@ Ref<ValidationBubble> PageClientImpl::createValidationBubble(const String& messa
     return ValidationBubble::create(m_contentView, message, settings);
 }
 
+#if ENABLE(DATALIST_ELEMENT)
+RefPtr<WebDataListSuggestionsDropdown> PageClientImpl::createDataListSuggestionsDropdown(WebPageProxy& page)
+{
+    return nullptr;
+}
+#endif
+
 #if ENABLE(DATA_INTERACTION)
 void PageClientImpl::didPerformDataInteractionControllerOperation(bool handled)
 {
index 7f8301b..ed12a84 100644 (file)
@@ -132,6 +132,10 @@ private:
     RefPtr<WebColorPicker> createColorPicker(WebPageProxy*, const WebCore::Color& initialColor, const WebCore::IntRect&) override;
 #endif
 
+#if ENABLE(DATALIST_ELEMENT)
+    RefPtr<WebDataListSuggestionsDropdown> createDataListSuggestionsDropdown(WebPageProxy&) override;
+#endif
+
     Ref<WebCore::ValidationBubble> createValidationBubble(const String& message, const WebCore::ValidationBubble::Settings&) final;
 
     void setTextIndicator(Ref<WebCore::TextIndicator>, WebCore::TextIndicatorWindowLifetime) override;
index 549d7a3..8840bb5 100644 (file)
@@ -48,6 +48,7 @@
 #import "WKWebViewInternal.h"
 #import "WebColorPickerMac.h"
 #import "WebContextMenuProxyMac.h"
+#import "WebDataListSuggestionsDropdownMac.h"
 #import "WebEditCommandProxy.h"
 #import "WebPopupMenuProxyMac.h"
 #import "WebViewImpl.h"
@@ -458,6 +459,13 @@ RefPtr<WebColorPicker> PageClientImpl::createColorPicker(WebPageProxy* page, con
 }
 #endif
 
+#if ENABLE(DATALIST_ELEMENT)
+RefPtr<WebDataListSuggestionsDropdown> PageClientImpl::createDataListSuggestionsDropdown(WebPageProxy& page)
+{
+    return WebDataListSuggestionsDropdownMac::create(page, m_view);
+}
+#endif
+
 Ref<ValidationBubble> PageClientImpl::createValidationBubble(const String& message, const ValidationBubble::Settings& settings)
 {
     return ValidationBubble::create(m_view, message, settings);
diff --git a/Source/WebKit/UIProcess/mac/WebDataListSuggestionsDropdownMac.h b/Source/WebKit/UIProcess/mac/WebDataListSuggestionsDropdownMac.h
new file mode 100644 (file)
index 0000000..018cc6b
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 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
+
+#if ENABLE(DATALIST_ELEMENT) && USE(APPKIT)
+
+#import "WebDataListSuggestionsDropdown.h"
+#import <wtf/RetainPtr.h>
+
+OBJC_CLASS WKDataListSuggestionsView;
+
+namespace WebKit {
+
+class WebDataListSuggestionsDropdownMac final : public WebDataListSuggestionsDropdown {
+public:
+    static Ref<WebDataListSuggestionsDropdownMac> create(WebDataListSuggestionsDropdown::Client&, NSView *);
+    ~WebDataListSuggestionsDropdownMac();
+
+    void didSelectOption(String&);
+
+private:
+    WebDataListSuggestionsDropdownMac(WebDataListSuggestionsDropdown::Client&, NSView *);
+
+    void show(WebCore::DataListSuggestionInformation&&) final;
+    void handleKeydownWithIdentifier(const String&) final;
+    void close() final;
+
+    void selectOption();
+
+    NSView *m_view;
+    RetainPtr<WKDataListSuggestionsView> m_dropdownUI;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(DATALIST_ELEMENT) && USE(APPKIT)
diff --git a/Source/WebKit/UIProcess/mac/WebDataListSuggestionsDropdownMac.mm b/Source/WebKit/UIProcess/mac/WebDataListSuggestionsDropdownMac.mm
new file mode 100644 (file)
index 0000000..1a4f60a
--- /dev/null
@@ -0,0 +1,431 @@
+/*
+ * 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 "WebDataListSuggestionsDropdownMac.h"
+
+#include <WebCore/IntRect.h>
+
+#if ENABLE(DATALIST_ELEMENT) && USE(APPKIT)
+
+static const CGFloat dropdownTopMargin = 2;
+static const CGFloat dropdownRowHeight = 20;
+static const CGFloat dropdownShadowHeight = 5;
+static const CGFloat dropdownShadowBlurRadius = 3;
+static const size_t dropdownMaxSuggestions = 6;
+static NSString * const suggestionCellReuseIdentifier = @"WKDataListSuggestionCell";
+
+@interface WKDataListSuggestionWindow : NSWindow
+@end
+
+@interface WKDataListSuggestionCell : NSView {
+    RetainPtr<NSTextField> _textField;
+    BOOL _mouseIsOver;
+}
+
+@property (nonatomic, assign) BOOL active;
+
+- (void)setText:(NSString *)text;
+@end
+
+@interface WKDataListSuggestionTable : NSTableView {
+    RetainPtr<NSScrollView> _enclosingScrollView;
+    std::optional<size_t> _activeRow;
+}
+
+- (id)initWithElementRect:(const WebCore::IntRect&)rect;
+- (void)setVisibleRect:(NSRect)rect;
+- (void)setActiveRow:(size_t)row;
+- (std::optional<size_t>)currentActiveRow;
+- (void)reload;
+@end
+
+@interface WKDataListSuggestionsView : NSObject<NSTableViewDataSource, NSTableViewDelegate> {
+@private
+    RetainPtr<WKDataListSuggestionTable> _table;
+    WebKit::WebDataListSuggestionsDropdownMac* _dropdown;
+    Vector<String> _suggestions;
+    NSView *_view;
+    RetainPtr<NSWindow> _enclosingWindow;
+}
+
+- (id)initWithInformation:(WebCore::DataListSuggestionInformation&&)information inView:(NSView *)view;
+- (void)showSuggestionsDropdown:(WebKit::WebDataListSuggestionsDropdownMac*)dropdown;
+- (void)updateWithInformation:(WebCore::DataListSuggestionInformation&&)information;
+- (void)moveSelectionByDirection:(const String&)direction;
+- (void)invalidate;
+
+- (String)currentSelectedString;
+@end
+
+namespace WebKit {
+
+Ref<WebDataListSuggestionsDropdownMac> WebDataListSuggestionsDropdownMac::create(WebDataListSuggestionsDropdown::Client& client, NSView *view)
+{
+    return adoptRef(*new WebDataListSuggestionsDropdownMac(client, view));
+}
+
+WebDataListSuggestionsDropdownMac::~WebDataListSuggestionsDropdownMac() { }
+
+WebDataListSuggestionsDropdownMac::WebDataListSuggestionsDropdownMac(WebDataListSuggestionsDropdown::Client& client, NSView *view)
+    : WebDataListSuggestionsDropdown(client)
+    , m_view(view)
+{
+}
+
+void WebDataListSuggestionsDropdownMac::show(WebCore::DataListSuggestionInformation&& information)
+{
+    if (m_dropdownUI) {
+        [m_dropdownUI updateWithInformation:WTFMove(information)];
+        return;
+    }
+
+    m_dropdownUI = adoptNS([[WKDataListSuggestionsView alloc] initWithInformation:WTFMove(information) inView:m_view]);
+    [m_dropdownUI showSuggestionsDropdown:this];
+}
+
+void WebDataListSuggestionsDropdownMac::didSelectOption(String& selectedOption)
+{
+    if (!m_client)
+        return;
+
+    m_client->didSelectOption(selectedOption);
+    close();
+}
+
+void WebDataListSuggestionsDropdownMac::selectOption()
+{
+    if (!m_client)
+        return;
+
+    String selectedOption = [m_dropdownUI currentSelectedString];
+    m_client->didSelectOption(selectedOption);
+    close();
+}
+
+void WebDataListSuggestionsDropdownMac::handleKeydownWithIdentifier(const String& key)
+{
+    if (key == "Enter")
+        selectOption();
+    else if (key == "Up" || key == "Down")
+        [m_dropdownUI moveSelectionByDirection:key];
+}
+
+void WebDataListSuggestionsDropdownMac::close()
+{
+    [m_dropdownUI invalidate];
+    m_dropdownUI = nil;
+    WebDataListSuggestionsDropdown::close();
+}
+
+} // namespace WebKit
+
+@implementation WKDataListSuggestionWindow
+@end
+
+@implementation WKDataListSuggestionCell
+
+- (id)initWithFrame:(NSRect)frameRect
+{
+    if (!(self = [super initWithFrame:frameRect]))
+        return self;
+
+    _textField = adoptNS([[NSTextField alloc] init]);
+    [_textField setEditable:NO];
+    [_textField setBezeled:NO];
+    [_textField setBackgroundColor:[NSColor clearColor]];
+    [self addSubview:_textField.get()];
+
+    [self setIdentifier:@"WKDataListSuggestionCell"];
+
+    [self addTrackingRect:self.bounds owner:self userData:nil assumeInside:NO];
+
+    return self;
+}
+
+- (void)setText:(NSString *)text
+{
+    [_textField setStringValue:text];
+    [_textField sizeToFit];
+
+    NSRect textFieldFrame = [_textField frame];
+    [_textField setFrame:CGRectMake(0, (CGRectGetHeight(self.frame) - CGRectGetHeight(textFieldFrame)) / 2, CGRectGetWidth(textFieldFrame), CGRectGetHeight(textFieldFrame))];
+
+    _mouseIsOver = NO;
+    self.active = NO;
+}
+
+- (void)setActive:(BOOL)shouldActivate
+{
+    _active = shouldActivate;
+    [self setNeedsDisplay:YES];
+}
+
+- (void)drawRect:(NSRect)dirtyRect
+{
+    if (self.active) {
+        [[NSColor alternateSelectedControlColor] setFill];
+        [_textField setTextColor:[NSColor alternateSelectedControlTextColor]];
+    } else if (_mouseIsOver) {
+        [[NSColor controlColor] setFill];
+        [_textField setTextColor:[NSColor textColor]];
+    } else {
+        [[NSColor controlBackgroundColor] setFill];
+        [_textField setTextColor:[NSColor textColor]];
+    }
+
+    NSRectFill(dirtyRect);
+    [super drawRect:dirtyRect];
+}
+
+- (void)mouseEntered:(NSEvent *)event
+{
+    [super mouseEntered:event];
+    _mouseIsOver = YES;
+    [self setNeedsDisplay:YES];
+}
+
+- (void)mouseExited:(NSEvent *)event
+{
+    [super mouseExited:event];
+    _mouseIsOver = NO;
+    [self setNeedsDisplay:YES];
+}
+
+- (BOOL)acceptsFirstResponder
+{
+    return NO;
+}
+
+@end
+
+@implementation WKDataListSuggestionTable
+
+- (id)initWithElementRect:(const WebCore::IntRect&)rect
+{
+    if (!(self = [super initWithFrame:NSMakeRect(0, 0, rect.width(), 0)]))
+        return self;
+
+    [self setIntercellSpacing:CGSizeZero];
+    [self setHeaderView:nil];
+    [self setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleNone];
+
+    auto column = adoptNS([[NSTableColumn alloc] init]);
+    [column setWidth:rect.width()];
+    [self addTableColumn:column.get()];
+
+    _enclosingScrollView = adoptNS([[NSScrollView alloc] init]);
+    [_enclosingScrollView setHasVerticalScroller:YES];
+    [_enclosingScrollView setVerticalScrollElasticity:NSScrollElasticityNone];
+    [_enclosingScrollView setHorizontalScrollElasticity:NSScrollElasticityNone];
+    [_enclosingScrollView setDocumentView:self];
+
+    auto dropShadow = adoptNS([[NSShadow alloc] init]);
+    [dropShadow setShadowColor:[NSColor systemGrayColor]];
+    [dropShadow setShadowOffset:NSMakeSize(0, dropdownShadowHeight)];
+    [dropShadow setShadowBlurRadius:dropdownShadowBlurRadius];
+    [_enclosingScrollView setWantsLayer:YES];
+    [_enclosingScrollView setShadow:dropShadow.get()];
+
+    return self;
+}
+
+- (void)setVisibleRect:(NSRect)rect
+{
+    [self setFrame:NSMakeRect(0, 0, NSWidth(rect) - dropdownShadowHeight * 2, 0)];
+    [_enclosingScrollView setFrame:NSMakeRect(dropdownShadowHeight, dropdownShadowHeight, NSWidth(rect) - dropdownShadowHeight * 2, NSHeight(rect) - dropdownShadowHeight)];
+}
+
+- (std::optional<size_t>)currentActiveRow
+{
+    return _activeRow;
+}
+
+- (void)setActiveRow:(size_t)row
+{
+    if (_activeRow) {
+        WKDataListSuggestionCell *oldCell = (WKDataListSuggestionCell *)[self viewAtColumn:0 row:_activeRow.value() makeIfNecessary:NO];
+        oldCell.active = NO;
+    }
+
+    [self scrollRowToVisible:row];
+    WKDataListSuggestionCell *newCell = (WKDataListSuggestionCell *)[self viewAtColumn:0 row:row makeIfNecessary:NO];
+    newCell.active = YES;
+
+    _activeRow = row;
+}
+
+- (void)reload
+{
+    _activeRow = std::nullopt;
+    [self reloadData];
+}
+
+- (BOOL)acceptsFirstResponder
+{
+    return NO;
+}
+
+- (NSScrollView *)enclosingScrollView
+{
+    return _enclosingScrollView.get();
+}
+
+- (void)removeFromSuperviewWithoutNeedingDisplay
+{
+    [super removeFromSuperviewWithoutNeedingDisplay];
+    [_enclosingScrollView removeFromSuperviewWithoutNeedingDisplay];
+}
+
+@end
+
+@implementation WKDataListSuggestionsView
+
+- (id)initWithInformation:(WebCore::DataListSuggestionInformation&&)information inView:(NSView *)view
+{
+    if (!(self = [super init]))
+        return self;
+
+    _view = view;
+    _suggestions = WTFMove(information.suggestions);
+    _table = adoptNS([[WKDataListSuggestionTable alloc] initWithElementRect:information.elementRect]);
+
+    _enclosingWindow = adoptNS([[WKDataListSuggestionWindow alloc] initWithContentRect:NSZeroRect styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:NO]);
+    [_enclosingWindow setReleasedWhenClosed:NO];
+    [_enclosingWindow setFrame:[self dropdownRectForElementRect:information.elementRect] display:YES];
+    [_enclosingWindow setBackgroundColor:[NSColor clearColor]];
+    [_enclosingWindow setOpaque:NO];
+
+    [_table setVisibleRect:[_enclosingWindow frame]];
+    [_table setDelegate:self];
+    [_table setDataSource:self];
+    [_table setAction:@selector(selectedRow:)];
+    [_table setTarget:self];
+
+    return self;
+}
+
+- (String)currentSelectedString
+{
+    std::optional<size_t> selectedRow = [_table currentActiveRow];
+    if (selectedRow && selectedRow.value() < _suggestions.size())
+        return _suggestions.at(selectedRow.value());
+
+    return emptyString();
+}
+
+- (void)updateWithInformation:(WebCore::DataListSuggestionInformation&&)information
+{
+    _suggestions = WTFMove(information.suggestions);
+    [_enclosingWindow setFrame:[self dropdownRectForElementRect:information.elementRect] display:YES];
+    [_table setVisibleRect:[_enclosingWindow frame]];
+    [_table reload];
+}
+
+- (void)moveSelectionByDirection:(const String&)direction
+{
+    size_t size = _suggestions.size();
+    std::optional<size_t> oldSelection = [_table currentActiveRow];
+
+    size_t newSelection;
+    if (oldSelection) {
+        size_t oldValue = oldSelection.value();
+        if (direction == "Up")
+            newSelection = oldValue ? (oldValue - 1) : (size - 1);
+        else
+            newSelection = (oldValue + 1) % size;
+    } else
+        newSelection = (direction == "Up") ? (size - 1) : 0;
+
+    [_table setActiveRow:newSelection];
+}
+
+- (void)invalidate
+{
+    [_table removeFromSuperviewWithoutNeedingDisplay];
+
+    [_table setDelegate:nil];
+    [_table setDataSource:nil];
+    [_table setTarget:nil];
+
+    _table = nil;
+
+    [[_view window] removeChildWindow:_enclosingWindow.get()];
+    [_enclosingWindow close];
+    _enclosingWindow = nil;
+}
+
+- (NSRect)dropdownRectForElementRect:(const WebCore::IntRect&)rect
+{
+    NSRect windowRect = [[_view window] convertRectToScreen:[_view convertRect:rect toView:nil]];
+    CGFloat height = std::min(_suggestions.size(), dropdownMaxSuggestions) * dropdownRowHeight;
+    return NSMakeRect(NSMinX(windowRect) - dropdownShadowHeight, NSMinY(windowRect) - height - dropdownShadowHeight - dropdownTopMargin, rect.width() + dropdownShadowHeight * 2, height + dropdownShadowHeight);
+}
+
+- (void)showSuggestionsDropdown:(WebKit::WebDataListSuggestionsDropdownMac*)dropdown
+{
+    _dropdown = dropdown;
+    [[_enclosingWindow contentView] addSubview:[_table enclosingScrollView]];
+    [_table reload];
+    [[_view window] addChildWindow:_enclosingWindow.get() ordered:NSWindowAbove];
+    [[_table enclosingScrollView] flashScrollers];
+}
+
+- (void)selectedRow:(NSTableView *)sender
+{
+    _dropdown->didSelectOption(_suggestions.at([sender selectedRow]));
+}
+
+- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
+{
+    return _suggestions.size();
+}
+
+- (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row
+{
+    return dropdownRowHeight;
+}
+
+- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
+{
+    WKDataListSuggestionCell *result = [tableView makeViewWithIdentifier:suggestionCellReuseIdentifier owner:self];
+
+    if (!result) {
+        result = [[[WKDataListSuggestionCell alloc] initWithFrame:NSMakeRect(0, 0, tableView.frame.size.width, dropdownRowHeight)] autorelease];
+        [result setIdentifier:suggestionCellReuseIdentifier];
+    }
+
+    [result setText:_suggestions.at(row)];
+
+    std::optional<size_t> currentActiveRow = [_table currentActiveRow];
+    if (currentActiveRow && static_cast<size_t>(row) == currentActiveRow.value())
+        result.active = YES;
+
+    return result;
+}
+
+@end
+
+#endif // ENABLE(DATALIST_ELEMENT) && USE(APPKIT)
index d71dac0..464d2e5 100644 (file)
                E4E864931B16750700C82F40 /* VersionChecks.h in Headers */ = {isa = PBXBuildFile; fileRef = E4E8648E1B1673FB00C82F40 /* VersionChecks.h */; };
                E52CF55220A35C3A00DADA27 /* WebDataListSuggestionPicker.h in Headers */ = {isa = PBXBuildFile; fileRef = E52CF55020A35C3A00DADA27 /* WebDataListSuggestionPicker.h */; };
                E52CF55320A35C3A00DADA27 /* WebDataListSuggestionPicker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E52CF55120A35C3A00DADA27 /* WebDataListSuggestionPicker.cpp */; };
+               E54A14CF20FCFB7B007E13D8 /* WebDataListSuggestionsDropdown.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E54A14CE20FCFB7B007E13D8 /* WebDataListSuggestionsDropdown.cpp */; };
+               E568B91F20A3AB2F00E3C856 /* WebDataListSuggestionsDropdown.h in Headers */ = {isa = PBXBuildFile; fileRef = E568B91E20A3AB2F00E3C856 /* WebDataListSuggestionsDropdown.h */; };
+               E568B92220A3AC6A00E3C856 /* WebDataListSuggestionsDropdownMac.h in Headers */ = {isa = PBXBuildFile; fileRef = E568B92020A3AC6A00E3C856 /* WebDataListSuggestionsDropdownMac.h */; };
+               E568B92320A3AC6A00E3C856 /* WebDataListSuggestionsDropdownMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = E568B92120A3AC6A00E3C856 /* WebDataListSuggestionsDropdownMac.mm */; };
                ECA680D81E690E2500731D20 /* WebProcessCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = ECA680D71E690DF800731D20 /* WebProcessCocoa.h */; settings = {ATTRIBUTES = (Private, ); }; };
                ED82A7F2128C6FAF004477B3 /* WKBundlePageOverlay.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A22F0FF1289FCD90085E74F /* WKBundlePageOverlay.h */; settings = {ATTRIBUTES = (Private, ); }; };
                EDCA71B7128DDA8C00201B26 /* WKBundlePageOverlay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A22F1001289FCD90085E74F /* WKBundlePageOverlay.cpp */; };
                E4E8648F1B1673FB00C82F40 /* VersionChecks.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = VersionChecks.mm; sourceTree = "<group>"; };
                E52CF55020A35C3A00DADA27 /* WebDataListSuggestionPicker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebDataListSuggestionPicker.h; sourceTree = "<group>"; };
                E52CF55120A35C3A00DADA27 /* WebDataListSuggestionPicker.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WebDataListSuggestionPicker.cpp; sourceTree = "<group>"; };
+               E54A14CE20FCFB7B007E13D8 /* WebDataListSuggestionsDropdown.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WebDataListSuggestionsDropdown.cpp; sourceTree = "<group>"; };
+               E568B91E20A3AB2F00E3C856 /* WebDataListSuggestionsDropdown.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebDataListSuggestionsDropdown.h; sourceTree = "<group>"; };
+               E568B92020A3AC6A00E3C856 /* WebDataListSuggestionsDropdownMac.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebDataListSuggestionsDropdownMac.h; sourceTree = "<group>"; };
+               E568B92120A3AC6A00E3C856 /* WebDataListSuggestionsDropdownMac.mm */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; path = WebDataListSuggestionsDropdownMac.mm; sourceTree = "<group>"; };
                ECA680D31E6904B500731D20 /* ExtraPrivateSymbolsForTAPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExtraPrivateSymbolsForTAPI.h; sourceTree = "<group>"; };
                ECA680D71E690DF800731D20 /* WebProcessCocoa.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebProcessCocoa.h; sourceTree = "<group>"; };
                ECBFC1DB1E6A4D66000300C7 /* ExtraPublicSymbolsForTAPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ExtraPublicSymbolsForTAPI.h; sourceTree = "<group>"; };
                                330934541315B9750097A7BC /* WebCookieManagerProxy.messages.in */,
                                33AA1064131F060000D4A575 /* WebCookieManagerProxyClient.cpp */,
                                33AA1065131F060000D4A575 /* WebCookieManagerProxyClient.h */,
+                               E54A14CE20FCFB7B007E13D8 /* WebDataListSuggestionsDropdown.cpp */,
+                               E568B91E20A3AB2F00E3C856 /* WebDataListSuggestionsDropdown.h */,
                                BCA0EF9E12332642007D3CFB /* WebEditCommandProxy.cpp */,
                                BCA0EF9D12332642007D3CFB /* WebEditCommandProxy.h */,
                                BCE4694F1214E6CB000B98EB /* WebFormClient.cpp */,
                                51ACBB9E127A8F2C00D203B9 /* WebContextMenuProxyMac.h */,
                                51ACBB9F127A8F2C00D203B9 /* WebContextMenuProxyMac.mm */,
                                F6D632BA133D181B00743D77 /* WebCookieManagerProxyMac.mm */,
+                               E568B92020A3AC6A00E3C856 /* WebDataListSuggestionsDropdownMac.h */,
+                               E568B92120A3AC6A00E3C856 /* WebDataListSuggestionsDropdownMac.mm */,
                                1CA8B935127C774E00576C2B /* WebInspectorProxyMac.mm */,
                                BC857E8512B71EBB00EDEB2E /* WebPageProxyMac.mm */,
                                BC5750951268F3C6006F0F12 /* WebPopupMenuProxyMac.h */,
                                5760829F202D2C4600116678 /* WebCredentialsMessengerProxyMessages.h in Headers */,
                                1AA83F6D1A5B63FF00026EC6 /* WebDatabaseProvider.h in Headers */,
                                E52CF55220A35C3A00DADA27 /* WebDataListSuggestionPicker.h in Headers */,
+                               E568B91F20A3AB2F00E3C856 /* WebDataListSuggestionsDropdown.h in Headers */,
+                               E568B92220A3AC6A00E3C856 /* WebDataListSuggestionsDropdownMac.h in Headers */,
                                CD19A26E1A13E834008D650E /* WebDiagnosticLoggingClient.h in Headers */,
                                1A5B1C5518987EDF004FCF9B /* WebDocumentLoader.h in Headers */,
                                BC032D7B10F4378D0058C15A /* WebDragClient.h in Headers */,
                                5760829E202D2C4300116678 /* WebCredentialsMessengerProxyMessageReceiver.cpp in Sources */,
                                1AA83F6C1A5B63FF00026EC6 /* WebDatabaseProvider.cpp in Sources */,
                                E52CF55320A35C3A00DADA27 /* WebDataListSuggestionPicker.cpp in Sources */,
+                               E54A14CF20FCFB7B007E13D8 /* WebDataListSuggestionsDropdown.cpp in Sources */,
+                               E568B92320A3AC6A00E3C856 /* WebDataListSuggestionsDropdownMac.mm in Sources */,
                                CD19A26D1A13E82A008D650E /* WebDiagnosticLoggingClient.cpp in Sources */,
                                1A5B1C5418987EDF004FCF9B /* WebDocumentLoader.cpp in Sources */,
                                BC111A5D112F4FBB00337BAB /* WebDragClient.cpp in Sources */,
index 6844527..0d2d5e9 100644 (file)
@@ -28,6 +28,7 @@
 
 #if ENABLE(DATALIST_ELEMENT)
 
+#include "WebCoreArgumentCoders.h"
 #include "WebPage.h"
 #include "WebPageProxyMessages.h"
 #include "WebProcess.h"
@@ -47,27 +48,35 @@ WebDataListSuggestionPicker::~WebDataListSuggestionPicker() { }
 
 void WebDataListSuggestionPicker::handleKeydownWithIdentifier(const WTF::String& key)
 {
-
+    WebProcess::singleton().parentProcessConnection()->send(Messages::WebPageProxy::HandleKeydownInDataList(key), m_page->pageID());
 }
 
 void WebDataListSuggestionPicker::didSelectOption(const WTF::String& selectedOption)
 {
-
+    m_dataListSuggestionsClient->didSelectDataListOption(selectedOption);
 }
 
 void WebDataListSuggestionPicker::didCloseSuggestions()
 {
-
+    m_dataListSuggestionsClient->didCloseSuggestions();
 }
 
 void WebDataListSuggestionPicker::close()
 {
-
+    WebProcess::singleton().parentProcessConnection()->send(Messages::WebPageProxy::EndDataListSuggestions(), m_page->pageID());
 }
 
 void WebDataListSuggestionPicker::displayWithActivationType(DataListSuggestionActivationType type)
 {
+    if (!m_dataListSuggestionsClient->suggestions().size()) {
+        close();
+        return;
+    }
+
+    m_page->setActiveDataListSuggestionPicker(this);
 
+    DataListSuggestionInformation info = { type, m_dataListSuggestionsClient->suggestions(), m_dataListSuggestionsClient->elementRectInRootViewCoordinates() };
+    WebProcess::singleton().parentProcessConnection()->send(Messages::WebPageProxy::ShowDataListSuggestions(info), m_page->pageID());
 }
 
 } // namespace WebKit
index e5b3818..9705359 100644 (file)
@@ -49,8 +49,8 @@ public:
     void close() override;
     void displayWithActivationType(WebCore::DataListSuggestionActivationType) override;
 private:
-    __unused WebCore::DataListSuggestionsClient* m_dataListSuggestionsClient;
-    __unused WebPage* m_page;
+    WebCore::DataListSuggestionsClient* m_dataListSuggestionsClient;
+    WebPage* m_page;
 };
 
 } // namespace WebKit
index 050e251..b6c2c57 100644 (file)
@@ -1,3 +1,22 @@
+2018-07-16  Aditya Keerthi  <akeerthi@apple.com>
+
+        [Datalist][macOS] Add suggestions UI for TextFieldInputTypes
+        https://bugs.webkit.org/show_bug.cgi?id=186531
+
+        Reviewed by Tim Horton.
+
+        Added isShowingDatalistSuggestions testing hook in order to enable testing of the
+        visibility of the suggestions view.
+
+        * DumpRenderTree/mac/UIScriptControllerMac.mm:
+        (WTR::UIScriptController::isShowingDataListSuggestions const):
+        * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
+        * TestRunnerShared/UIScriptContext/UIScriptController.cpp:
+        (WTR::UIScriptController::isShowingDataListSuggestions const):
+        * TestRunnerShared/UIScriptContext/UIScriptController.h:
+        * WebKitTestRunner/mac/UIScriptControllerMac.mm:
+        (WTR::UIScriptController::isShowingDataListSuggestions const):
+
 2018-07-16  Yusuke Suzuki  <utatane.tea@gmail.com>
 
         Add --target-path option to dump-class-layout
index b3ac6ae..ec22359 100644 (file)
@@ -180,6 +180,11 @@ bool UIScriptController::isWindowContentViewFirstResponder() const
     return false;
 }
 
+bool UIScriptController::isShowingDataListSuggestions() const
+{
+    return false;
+}
+
 }
 
 #endif // PLATFORM(MAC)
index 582e4f8..809e475 100644 (file)
@@ -195,6 +195,9 @@ interface UIScriptController {
 
     void setTimePickerValue(long hour, long minute);
 
+    // <datalist>
+    readonly attribute boolean isShowingDataListSuggestions;
+
     void keyboardAccessoryBarNext();
     void keyboardAccessoryBarPrevious();
 
index eb86fb8..42c12ce 100644 (file)
@@ -517,6 +517,11 @@ bool UIScriptController::isWindowContentViewFirstResponder() const
     return false;
 }
 
+bool UIScriptController::isShowingDataListSuggestions() const
+{
+    return false;
+}
+
 #endif
 
 void UIScriptController::uiScriptComplete(JSStringRef result)
index 70b29cc..b2e1ade 100644 (file)
@@ -102,7 +102,9 @@ public:
     JSRetainPtr<JSStringRef> selectFormPopoverTitle() const;
     JSRetainPtr<JSStringRef> formInputLabel() const;
     void setTimePickerValue(long hour, long minute);
-    
+
+    bool isShowingDataListSuggestions() const;
+
     JSObjectRef contentsOfUserInterfaceItem(JSStringRef) const;
     void overridePreference(JSStringRef preference, JSStringRef value);
     
index 1f4eed4..7d90010 100644 (file)
@@ -168,6 +168,18 @@ void UIScriptController::findString(JSStringRef, unsigned long options, unsigned
 {
 }
 
+bool UIScriptController::isShowingDataListSuggestions() const
+{
+#if WK_API_ENABLED
+    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
+    for (NSWindow *childWindow in webView.window.childWindows) {
+        if ([childWindow isKindOfClass:NSClassFromString(@"WKDataListSuggestionWindow")])
+            return true;
+    }
+#endif
+    return false;
+}
+
 void UIScriptController::removeViewFromWindow(JSValueRef callback)
 {
 #if WK_API_ENABLED