[Datalist][iOS] Display suggestions for input[type=color]
authorakeerthi@apple.com <akeerthi@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 18 Aug 2018 00:43:23 +0000 (00:43 +0000)
committerakeerthi@apple.com <akeerthi@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 18 Aug 2018 00:43:23 +0000 (00:43 +0000)
https://bugs.webkit.org/show_bug.cgi?id=188669

Reviewed by Tim Horton.

Source/WebCore:

Expose suggestedColors() in HTMLInputElement in order to allow the UIProcess to
access the list of suggested colors from a <datalist> element.

* html/ColorInputType.cpp:
(WebCore::ColorInputType::suggestedColors const):
* html/ColorInputType.h:
* html/HTMLInputElement.cpp:
(WebCore::HTMLInputElement::suggestedColors const):
* html/HTMLInputElement.h:
* html/InputType.cpp:
(WebCore::InputType::suggestedColors const):
* html/InputType.h:
* platform/ColorChooserClient.h:

Source/WebKit:

An input[type=color] element that has an associated datalist element should
display the color values provided on iOS. Similar to macOS, we now support 1-12
suggested colors, that will be displayed at the top of the color picker.

Also ensured that we get rounded corners on both sides of a color swatch if it is
the only one in its row.

* Shared/AssistedNodeInformation.cpp: Added suggestedColors field.
(WebKit::AssistedNodeInformation::encode const):
(WebKit::AssistedNodeInformation::decode):
* Shared/AssistedNodeInformation.h:
* UIProcess/ios/forms/WKFormColorPicker.mm:
(+[WKColorPicker defaultTopColorMatrix]):
(-[WKColorPicker initWithView:]): Use the list of suggestedColors if it exists.
(-[WKColorPicker drawSelectionIndicatorForColorButton:]):
* WebProcess/WebCoreSupport/WebColorChooser.cpp:
(WebKit::WebColorChooser::WebColorChooser):
(WebKit::WebColorChooser::reattachColorChooser):
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::getAssistedNodeInformation):

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

14 files changed:
Source/WebCore/ChangeLog
Source/WebCore/html/ColorInputType.cpp
Source/WebCore/html/ColorInputType.h
Source/WebCore/html/HTMLInputElement.cpp
Source/WebCore/html/HTMLInputElement.h
Source/WebCore/html/InputType.cpp
Source/WebCore/html/InputType.h
Source/WebCore/platform/ColorChooserClient.h
Source/WebKit/ChangeLog
Source/WebKit/Shared/AssistedNodeInformation.cpp
Source/WebKit/Shared/AssistedNodeInformation.h
Source/WebKit/UIProcess/ios/forms/WKFormColorPicker.mm
Source/WebKit/WebProcess/WebCoreSupport/WebColorChooser.cpp
Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm

index d4d11ab..8fb2880 100644 (file)
@@ -1,3 +1,24 @@
+2018-08-17  Aditya Keerthi  <akeerthi@apple.com>
+
+        [Datalist][iOS] Display suggestions for input[type=color]
+        https://bugs.webkit.org/show_bug.cgi?id=188669
+
+        Reviewed by Tim Horton.
+
+        Expose suggestedColors() in HTMLInputElement in order to allow the UIProcess to
+        access the list of suggested colors from a <datalist> element.
+
+        * html/ColorInputType.cpp:
+        (WebCore::ColorInputType::suggestedColors const):
+        * html/ColorInputType.h:
+        * html/HTMLInputElement.cpp:
+        (WebCore::HTMLInputElement::suggestedColors const):
+        * html/HTMLInputElement.h:
+        * html/InputType.cpp:
+        (WebCore::InputType::suggestedColors const):
+        * html/InputType.h:
+        * platform/ColorChooserClient.h:
+
 2018-08-17  Alex Christensen  <achristensen@webkit.org>
 
         Clean up CSSSelectorList after r234825
index 1415782..3f8e20c 100644 (file)
@@ -281,7 +281,7 @@ bool ColorInputType::shouldShowSuggestions() const
 #endif
 }
 
-Vector<Color> ColorInputType::suggestions() const
+Vector<Color> ColorInputType::suggestedColors() const
 {
     Vector<Color> suggestions;
 #if ENABLE(DATALIST_ELEMENT)
index cdae3cb..d89236c 100644 (file)
@@ -50,7 +50,7 @@ private:
     IntRect elementRectRelativeToRootView() const final;
     Color currentColor() final;
     bool shouldShowSuggestions() const final;
-    Vector<Color> suggestions() const final;
+    Vector<Color> suggestedColors() const final;
     bool isMouseFocusable() const final;
     bool isKeyboardFocusable(KeyboardEvent*) const final;
     bool isColorControl() const final;
index 91bae95..bd102a5 100644 (file)
@@ -1601,6 +1601,11 @@ void HTMLInputElement::selectColor(StringView color)
     m_inputType->selectColor(color);
 }
 
+Vector<Color> HTMLInputElement::suggestedColors() const
+{
+    return m_inputType->suggestedColors();
+}
+
 #if ENABLE(DATALIST_ELEMENT)
 
 RefPtr<HTMLElement> HTMLInputElement::list() const
index fedb742..e32b389 100644 (file)
@@ -296,6 +296,7 @@ public:
 
     Color valueAsColor() const; // Returns transparent color if not type=color.
     WEBCORE_EXPORT void selectColor(StringView); // Does nothing if not type=color. Simulates user selection of color; intended for testing.
+    WEBCORE_EXPORT Vector<Color> suggestedColors() const;
 
     String defaultToolTip() const;
 
index 52317fa..dc1be9a 100644 (file)
@@ -1131,6 +1131,11 @@ void InputType::selectColor(StringView)
 {
 }
 
+Vector<Color> InputType::suggestedColors() const
+{
+    return { };
+}
+
 RefPtr<TextControlInnerTextElement> InputType::innerTextElement() const
 {
     return nullptr;
index 828b4c0..c7a9add 100644 (file)
@@ -270,6 +270,7 @@ public:
     virtual bool supportsSelectionAPI() const;
     virtual Color valueAsColor() const;
     virtual void selectColor(StringView);
+    virtual Vector<Color> suggestedColors() const;
 
     // Parses the specified string for the type, and return
     // the Decimal value for the parsing result if the parsing
index 48d4b27..9b3b898 100644 (file)
@@ -48,7 +48,7 @@ public:
     virtual IntRect elementRectRelativeToRootView() const = 0;
     virtual Color currentColor() = 0;
     virtual bool shouldShowSuggestions() const = 0;
-    virtual Vector<Color> suggestions() const = 0;
+    virtual Vector<Color> suggestedColors() const = 0;
 };
 
 } // namespace WebCore
index 5dc27b0..c89073c 100644 (file)
@@ -1,3 +1,31 @@
+2018-08-17  Aditya Keerthi  <akeerthi@apple.com>
+
+        [Datalist][iOS] Display suggestions for input[type=color]
+        https://bugs.webkit.org/show_bug.cgi?id=188669
+
+        Reviewed by Tim Horton.
+
+        An input[type=color] element that has an associated datalist element should
+        display the color values provided on iOS. Similar to macOS, we now support 1-12
+        suggested colors, that will be displayed at the top of the color picker.
+
+        Also ensured that we get rounded corners on both sides of a color swatch if it is
+        the only one in its row.
+
+        * Shared/AssistedNodeInformation.cpp: Added suggestedColors field.
+        (WebKit::AssistedNodeInformation::encode const):
+        (WebKit::AssistedNodeInformation::decode):
+        * Shared/AssistedNodeInformation.h:
+        * UIProcess/ios/forms/WKFormColorPicker.mm:
+        (+[WKColorPicker defaultTopColorMatrix]):
+        (-[WKColorPicker initWithView:]): Use the list of suggestedColors if it exists.
+        (-[WKColorPicker drawSelectionIndicatorForColorButton:]):
+        * WebProcess/WebCoreSupport/WebColorChooser.cpp:
+        (WebKit::WebColorChooser::WebColorChooser):
+        (WebKit::WebColorChooser::reattachColorChooser):
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::getAssistedNodeInformation):
+
 2018-08-17  Ryan Haddad  <ryanhaddad@apple.com>
 
         Unreviewed, rolling out r234991.
index 1cd7ac8..79adb68 100644 (file)
@@ -96,6 +96,9 @@ void AssistedNodeInformation::encode(IPC::Encoder& encoder) const
     encoder << label;
     encoder << ariaLabel;
     encoder << assistedNodeIdentifier;
+#if ENABLE(INPUT_TYPE_COLOR) && ENABLE(DATALIST_ELEMENT)
+    encoder << suggestedColors;
+#endif
 }
 
 bool AssistedNodeInformation::decode(IPC::Decoder& decoder, AssistedNodeInformation& result)
@@ -199,6 +202,11 @@ bool AssistedNodeInformation::decode(IPC::Decoder& decoder, AssistedNodeInformat
     if (!decoder.decode(result.assistedNodeIdentifier))
         return false;
 
+#if ENABLE(INPUT_TYPE_COLOR) && ENABLE(DATALIST_ELEMENT)
+    if (!decoder.decode(result.suggestedColors))
+        return false;
+#endif
+
     return true;
 }
 #endif
index 6b0ce17..1e7aac7 100644 (file)
@@ -28,6 +28,7 @@
 #include "ArgumentCoders.h"
 #include <WebCore/AutocapitalizeTypes.h>
 #include <WebCore/Autofill.h>
+#include <WebCore/Color.h>
 #include <WebCore/IntRect.h>
 #include <WebCore/URL.h>
 #include <wtf/text/WTFString.h>
@@ -122,6 +123,9 @@ struct AssistedNodeInformation {
     String placeholder;
     String label;
     String ariaLabel;
+#if ENABLE(INPUT_TYPE_COLOR) && ENABLE(DATALIST_ELEMENT)
+    Vector<WebCore::Color> suggestedColors;
+#endif
 
     uint64_t assistedNodeIdentifier { 0 };
 
index 53fc009..48e7a79 100644 (file)
@@ -45,6 +45,9 @@ static const CGFloat colorSelectionIndicatorBorderWidth = 4;
 static const CGFloat colorSelectionIndicatorCornerRadius = 9;
 static const CGFloat pickerWidthForPopover = 280;
 static const CGFloat topColorMatrixPadding = 5;
+#if ENABLE(DATALIST_ELEMENT)
+static const size_t maxColorSuggestions = 12;
+#endif
 
 using namespace WebKit;
 
@@ -162,7 +165,7 @@ using namespace WebKit;
 
 + (NSArray<NSArray<UIColor *> *> *)defaultTopColorMatrix
 {
-    return @[@[[UIColor redColor], [UIColor orangeColor], [UIColor yellowColor], [UIColor greenColor], [UIColor cyanColor], [UIColor blueColor], [UIColor magentaColor], [UIColor purpleColor], [UIColor brownColor], [UIColor whiteColor], [UIColor grayColor], [UIColor blackColor]]];
+    return @[ @[ UIColor.redColor, UIColor.orangeColor, UIColor.yellowColor, UIColor.greenColor, UIColor.cyanColor, UIColor.blueColor, UIColor.magentaColor, UIColor.purpleColor, UIColor.brownColor, UIColor.whiteColor, UIColor.grayColor, UIColor.blackColor ] ];
 }
 
 - (instancetype)initWithView:(WKContentView *)view
@@ -190,7 +193,21 @@ using namespace WebKit;
     [_mainColorMatrix setDelegate:self];
     [_colorPicker addSubview:_mainColorMatrix.get()];
 
-    _topColorMatrix = adoptNS([[WKColorMatrixView alloc] initWithFrame:CGRectMake(0, 0, colorPickerSize.width, swatchHeight) colorMatrix:[[self class] defaultTopColorMatrix]]);
+    NSArray<NSArray<UIColor *> *> *topColorMatrix = [[self class] defaultTopColorMatrix];
+
+#if ENABLE(DATALIST_ELEMENT)
+    size_t numColorSuggestions = view.assistedNodeInformation.suggestedColors.size();
+    if (numColorSuggestions) {
+        NSMutableArray<UIColor *> *colors = [NSMutableArray array];
+        for (size_t i = 0; i < std::min(numColorSuggestions, maxColorSuggestions); i++) {
+            WebCore::Color color = view.assistedNodeInformation.suggestedColors[i];
+            [colors addObject:[UIColor colorWithCGColor:cachedCGColor(color)]];
+        }
+        topColorMatrix = @[ colors ];
+    }
+#endif
+
+    _topColorMatrix = adoptNS([[WKColorMatrixView alloc] initWithFrame:CGRectMake(0, 0, colorPickerSize.width, swatchHeight) colorMatrix:topColorMatrix]);
     [_topColorMatrix setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
     [_topColorMatrix setDelegate:self];
     [_colorPicker addSubview:_topColorMatrix.get()];
@@ -227,15 +244,15 @@ using namespace WebKit;
         bool maxXEqual = std::abs(CGRectGetMaxX(frame) - CGRectGetMaxX(colorPickerBounds)) < FLT_EPSILON;
         bool maxYEqual = std::abs(CGRectGetMaxY(frame) - CGRectGetMaxY(colorPickerBounds)) < FLT_EPSILON;
 
-        // On iPad, round one corner of the indicator if it's at the corner of the picker, to match the popover.
+        // On iPad, round the corners of the indicator that border the corners of the picker, to match the popover.
         if (minXEqual && minYEqual)
-            roundCorner = UIRectCornerTopLeft;
-        else if (maxXEqual && minYEqual)
-            roundCorner = UIRectCornerTopRight;
-        else if (minXEqual && maxYEqual)
-            roundCorner = UIRectCornerBottomLeft;
-        else if (maxXEqual && maxYEqual)
-            roundCorner = UIRectCornerBottomRight;
+            roundCorner |= UIRectCornerTopLeft;
+        if (maxXEqual && minYEqual)
+            roundCorner |= UIRectCornerTopRight;
+        if (minXEqual && maxYEqual)
+            roundCorner |= UIRectCornerBottomLeft;
+        if (maxXEqual && maxYEqual)
+            roundCorner |= UIRectCornerBottomRight;
     }
 
     UIBezierPath *cornerMaskPath = [UIBezierPath bezierPathWithRoundedRect:colorButton.bounds byRoundingCorners:roundCorner cornerRadii:CGSizeMake(colorSelectionIndicatorCornerRadius, colorSelectionIndicatorCornerRadius)];
index bd7f864..22371f2 100644 (file)
@@ -43,7 +43,7 @@ WebColorChooser::WebColorChooser(WebPage* page, ColorChooserClient* client, cons
     , m_page(page)
 {
     m_page->setActiveColorChooser(this);
-    WebProcess::singleton().parentProcessConnection()->send(Messages::WebPageProxy::ShowColorPicker(initialColor, client->elementRectRelativeToRootView(), client->suggestions()), m_page->pageID());
+    WebProcess::singleton().parentProcessConnection()->send(Messages::WebPageProxy::ShowColorPicker(initialColor, client->elementRectRelativeToRootView(), client->suggestedColors()), m_page->pageID());
 }
 
 WebColorChooser::~WebColorChooser()
@@ -75,7 +75,7 @@ void WebColorChooser::reattachColorChooser(const Color& color)
     m_page->setActiveColorChooser(this);
 
     ASSERT(m_colorChooserClient);
-    WebProcess::singleton().parentProcessConnection()->send(Messages::WebPageProxy::ShowColorPicker(color, m_colorChooserClient->elementRectRelativeToRootView(), m_colorChooserClient->suggestions()), m_page->pageID());
+    WebProcess::singleton().parentProcessConnection()->send(Messages::WebPageProxy::ShowColorPicker(color, m_colorChooserClient->elementRectRelativeToRootView(), m_colorChooserClient->suggestedColors()), m_page->pageID());
 }
 
 void WebColorChooser::setSelectedColor(const Color& color)
index a9cadce..26186fb 100644 (file)
@@ -2451,8 +2451,12 @@ void WebPage::getAssistedNodeInformation(AssistedNodeInformation& information)
             }
         }
 #if ENABLE(INPUT_TYPE_COLOR)
-        else if (element.isColorControl())
+        else if (element.isColorControl()) {
             information.elementType = InputType::Color;
+#if ENABLE(DATALIST_ELEMENT)
+            information.suggestedColors = element.suggestedColors();
+#endif
+        }
 #endif
 
         information.isReadOnly = element.isReadOnly();