Changeset 259330 in webkit


Ignore:
Timestamp:
Mar 31, 2020, 6:22:59 PM (5 years ago)
Author:
Wenson Hsieh
Message:

Datalist option's label not used
https://bugs.webkit.org/show_bug.cgi?id=201768
<rdar://problem/55361186>

Reviewed by Darin Adler.

Source/WebCore:

Refactor DataListSuggestionInformation's suggestions to include label text as well as values, and then adjust
TextFieldInputType::suggestions() to match label text as well as values for ports that are capable of showing
label text in datalist suggestion UI.

Test: fast/forms/datalist/datalist-option-labels.html

  • html/DataListSuggestionInformation.h:

Introduce DataListSuggestion, a wrapper around a value and label. Currently, the list of datalist suggestions
is only a Vector<String>; change it to be a Vector<DataListSuggestion> instead.

(WebCore::DataListSuggestion::encode const):
(WebCore::DataListSuggestion::decode):
(WebCore::DataListSuggestionInformation::encode const):
(WebCore::DataListSuggestionInformation::decode):

Move encoding and decoding for DataListSuggestionInformation out of WebCoreArgumentCoders and into WebCore.

  • html/TextFieldInputType.cpp:

(WebCore::TextFieldInputType::listAttributeTargetChanged):
(WebCore::TextFieldInputType::suggestions):

When computing suggestions, match label text in addition to values on ports that display label text in the
chrome; for the time being, this is only the case for macOS, but will be extended to iOS as well in a future
patch. Note that we don't plumb label text if it is already the same as the value, to avoid duplicate strings
from showing up.

(WebCore::TextFieldInputType::didCloseSuggestions):

  • html/TextFieldInputType.h:
  • loader/EmptyClients.h:
  • page/ChromeClient.h:

Add a chrome client hook to return whether or not the client shows label text in its datalist UI.

  • platform/DataListSuggestionsClient.h:

Source/WebKit:

Add support on macOS for showing option labels in datalist suggestions.

  • Shared/WebCoreArgumentCoders.cpp:

(IPC::ArgumentCoder<DataListSuggestionInformation>::encode): Deleted.
(IPC::ArgumentCoder<DataListSuggestionInformation>::decode): Deleted.

  • Shared/WebCoreArgumentCoders.h:

Remove WebCoreArgumentCoders logic for encoding and decoding DataListSuggestionInformation. See
DataListSuggestionInformation.h in WebCore for more detail.

  • UIProcess/gtk/WebDataListSuggestionsDropdownGtk.cpp:

(WebKit::WebDataListSuggestionsDropdownGtk::show):

Tweak GTK code to adjust for the change from String to DataListSuggestion.

  • UIProcess/ios/WebDataListSuggestionsDropdownIOS.mm:

(-[WKDataListSuggestionsControl didSelectOptionAtIndex:]):
(-[WKDataListSuggestionsControl textSuggestions]):
(-[WKDataListSuggestionsControl suggestionAtIndex:]):

Adjust some iOS codepaths to use DataListSuggestion::value as the value string to display.

  • UIProcess/mac/WebDataListSuggestionsDropdownMac.mm:

Tweak several UI constants. A suggestion cell may now be either 20 or 40pt tall, depending on whether it has
label text to show.

Currently, the maximum combined height of the table view cells is 120 (not including spacing between cells and
vertical padding around the top and bottom of the table view), since the maximum number of cells to show is 6
and each cell is 20pt tall. Maintain this constant by making the maximum cell height 120, which accomodates
either three labeled cells, or 6 unlabeled cells (i.e. to match shipping behavior).

(-[WKDataListSuggestionView initWithFrame:]):
(-[WKDataListSuggestionView layout]):

Maintain two text fields or value and (optionally) label text: _valueField and _labelField. The value field
fills the bounds of the cell in the case where there is no label text, but fills only the top half of the cell
in the case where there is label text. The label field takes the bottom half of the cell in this case.

Additionally, add a divider view that may appear at the very bottom of each cell. This divider view is present
when one or more suggestions in the datalist are labeled.

(-[WKDataListSuggestionView setValue:label:]):

Renamed from -setText:. Add a label string argument as well.

(-[WKDataListSuggestionView setShouldShowBottomDivider:]):

Add getters and setters for the -shouldShowBottomDivider property, which can be used to make the divider view
visible or hidden.

(-[WKDataListSuggestionView shouldShowBottomDivider]):
(-[WKDataListSuggestionView setBackgroundStyle:]):

Use -[NSColor secondaryLabelColor] for the label text field.

(shouldShowDividersBetweenCells):

Add a helper method to determine whether the table view should be showing clear dividers between each item.
We only do so if there are one or more labels to be shown.

(-[WKDataListSuggestionsController initWithInformation:inView:]):
(-[WKDataListSuggestionsController currentSelectedString]):
(-[WKDataListSuggestionsController updateWithInformation:]):
(-[WKDataListSuggestionsController moveSelectionByDirection:]):

Drive-by fix: scroll to reveal each selected row when using the arrow keys to navigate between items.

(-[WKDataListSuggestionsController dropdownRectForElementRect:]):
(-[WKDataListSuggestionsController tableView:heightOfRow:]):

Return either dropdownRowHeightWithoutLabel or dropdownRowHeightWithLabel, depending on whether there is
label text to be shown in that suggestion cell.

(-[WKDataListSuggestionsController tableView:viewForTableColumn:row:]):
(-[WKDataListSuggestionView setText:]): Deleted.

  • WebProcess/WebCoreSupport/WebChromeClient.cpp:

(WebKit::WebChromeClient::canShowDataListSuggestionLabels const):

  • WebProcess/WebCoreSupport/WebChromeClient.h:

Source/WebKitLegacy/mac:

See WebCore/ChangeLog and WebKit/ChangeLog for more details.

  • WebCoreSupport/WebChromeClient.h:

LayoutTests:

Add a test to verify that when datalist suggestions incorporate option labels into the displayed text
suggestions, they are matched against when changing the value of the input field, and can be selected. This is
expected to be the case on macOS, but not on other platforms (for the time being).

  • fast/forms/datalist/datalist-option-labels-expected.txt: Added.
  • fast/forms/datalist/datalist-option-labels.html: Added.
  • platform/gtk/fast/forms/datalist/datalist-option-labels-expected.txt: Added.
  • platform/ios/fast/forms/datalist/datalist-option-labels-expected.txt: Added.
Location:
trunk
Files:
4 added
18 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r259328 r259330  
     12020-03-31  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        Datalist option's label not used
     4        https://bugs.webkit.org/show_bug.cgi?id=201768
     5        <rdar://problem/55361186>
     6
     7        Reviewed by Darin Adler.
     8
     9        Add a test to verify that when datalist suggestions incorporate option labels into the displayed text
     10        suggestions, they are matched against when changing the value of the input field, and can be selected. This is
     11        expected to be the case on macOS, but not on other platforms (for the time being).
     12
     13        * fast/forms/datalist/datalist-option-labels-expected.txt: Added.
     14        * fast/forms/datalist/datalist-option-labels.html: Added.
     15        * platform/gtk/fast/forms/datalist/datalist-option-labels-expected.txt: Added.
     16        * platform/ios/fast/forms/datalist/datalist-option-labels-expected.txt: Added.
     17
    1182020-03-31  Per Arne Vollan  <pvollan@apple.com>
    219
  • trunk/Source/WebCore/ChangeLog

    r259325 r259330  
     12020-03-31  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        Datalist option's label not used
     4        https://bugs.webkit.org/show_bug.cgi?id=201768
     5        <rdar://problem/55361186>
     6
     7        Reviewed by Darin Adler.
     8
     9        Refactor DataListSuggestionInformation's suggestions to include label text as well as values, and then adjust
     10        TextFieldInputType::suggestions() to match label text as well as values for ports that are capable of showing
     11        label text in datalist suggestion UI.
     12
     13        Test: fast/forms/datalist/datalist-option-labels.html
     14
     15        * html/DataListSuggestionInformation.h:
     16
     17        Introduce DataListSuggestion, a wrapper around a value and label. Currently, the list of datalist suggestions
     18        is only a `Vector<String>`; change it to be a `Vector<DataListSuggestion>` instead.
     19
     20        (WebCore::DataListSuggestion::encode const):
     21        (WebCore::DataListSuggestion::decode):
     22        (WebCore::DataListSuggestionInformation::encode const):
     23        (WebCore::DataListSuggestionInformation::decode):
     24
     25        Move encoding and decoding for DataListSuggestionInformation out of WebCoreArgumentCoders and into WebCore.
     26
     27        * html/TextFieldInputType.cpp:
     28        (WebCore::TextFieldInputType::listAttributeTargetChanged):
     29        (WebCore::TextFieldInputType::suggestions):
     30
     31        When computing suggestions, match label text in addition to values on ports that display label text in the
     32        chrome; for the time being, this is only the case for macOS, but will be extended to iOS as well in a future
     33        patch. Note that we don't plumb label text if it is already the same as the value, to avoid duplicate strings
     34        from showing up.
     35
     36        (WebCore::TextFieldInputType::didCloseSuggestions):
     37        * html/TextFieldInputType.h:
     38        * loader/EmptyClients.h:
     39        * page/ChromeClient.h:
     40
     41        Add a chrome client hook to return whether or not the client shows label text in its datalist UI.
     42
     43        * platform/DataListSuggestionsClient.h:
     44
    1452020-03-31  Don Olmstead  <don.olmstead@sony.com>
    246
  • trunk/Source/WebCore/html/DataListSuggestionInformation.h

    r235556 r259330  
    3030
    3131#if ENABLE(DATALIST_ELEMENT)
     32
    3233namespace WebCore {
    3334
    34 enum class DataListSuggestionActivationType {
     35enum class DataListSuggestionActivationType : uint8_t {
    3536    ControlClicked,
    3637    IndicatorClicked,
     
    3839};
    3940
     41struct DataListSuggestion {
     42    String value;
     43    String label;
     44
     45    template<class Encoder> void encode(Encoder&) const;
     46    template<class Decoder> static Optional<DataListSuggestion> decode(Decoder&);
     47};
     48
     49template<class Encoder>
     50void DataListSuggestion::encode(Encoder& encoder) const
     51{
     52    encoder << value;
     53    encoder << label;
     54}
     55
     56template<class Decoder>
     57Optional<DataListSuggestion> DataListSuggestion::decode(Decoder& decoder)
     58{
     59    Optional<String> value;
     60    decoder >> value;
     61    if (!value)
     62        return WTF::nullopt;
     63
     64    Optional<String> label;
     65    decoder >> label;
     66    if (!label)
     67        return WTF::nullopt;
     68
     69    return {{ *value, *label }};
     70}
     71
    4072struct DataListSuggestionInformation {
    4173    DataListSuggestionActivationType activationType;
    42     Vector<String> suggestions;
     74    Vector<DataListSuggestion> suggestions;
    4375    IntRect elementRect;
     76
     77    template<class Encoder> void encode(Encoder&) const;
     78    template<class Decoder> static Optional<DataListSuggestionInformation> decode(Decoder&);
    4479};
    4580
     81template<class Encoder>
     82void DataListSuggestionInformation::encode(Encoder& encoder) const
     83{
     84    encoder.encodeEnum(activationType);
     85    encoder << suggestions;
     86    encoder << elementRect;
    4687}
     88
     89template<class Decoder>
     90Optional<DataListSuggestionInformation> DataListSuggestionInformation::decode(Decoder& decoder)
     91{
     92    DataListSuggestionActivationType activationType;
     93    if (!decoder.decodeEnum(activationType))
     94        return WTF::nullopt;
     95
     96    Optional<Vector<DataListSuggestion>> suggestions;
     97    decoder >> suggestions;
     98    if (!suggestions)
     99        return WTF::nullopt;
     100
     101    Optional<IntRect> elementRect;
     102    decoder >> elementRect;
     103    if (!elementRect)
     104        return WTF::nullopt;
     105
     106    return {{ activationType, *suggestions, *elementRect }};
     107}
     108
     109} // namespace WebCore
     110
    47111#endif
  • trunk/Source/WebCore/html/TextFieldInputType.cpp

    r258181 r259330  
    829829void TextFieldInputType::listAttributeTargetChanged()
    830830{
    831     m_cachedSuggestions = std::make_pair(String(), Vector<String>());
     831    m_cachedSuggestions = { };
    832832
    833833    if (!m_dataListDropdownIndicator)
     
    857857}
    858858
    859 Vector<String> TextFieldInputType::suggestions()
     859Vector<DataListSuggestion> TextFieldInputType::suggestions()
    860860{
    861861    // FIXME: Suggestions are "typing completions" and so should probably use the findPlainText algorithm rather than the simplistic "ignoring ASCII case" rules.
    862862
    863     Vector<String> suggestions;
    864     Vector<String> matchesContainingValue;
     863    Vector<DataListSuggestion> suggestions;
     864    Vector<DataListSuggestion> matchesContainingValue;
    865865
    866866    String elementValue = element()->value();
     
    869869        return m_cachedSuggestions.second;
    870870
     871    auto* page = element()->document().page();
     872    bool canShowLabels = page && page->chrome().client().canShowDataListSuggestionLabels();
    871873    if (auto dataList = element()->dataList()) {
    872874        for (auto& option : dataList->suggestions()) {
    873             String value = option.value();
    874             if (!element()->isValidValue(value))
     875            DataListSuggestion suggestion;
     876            suggestion.value = option.value();
     877            if (!element()->isValidValue(suggestion.value))
    875878                continue;
    876             value = sanitizeValue(value);
    877             if (elementValue.isEmpty())
    878                 suggestions.append(value);
    879             else if (value.startsWithIgnoringASCIICase(elementValue))
    880                 suggestions.append(value);
    881             else if (value.containsIgnoringASCIICase(elementValue))
    882                 matchesContainingValue.append(value);
     879            suggestion.value = sanitizeValue(suggestion.value);
     880            suggestion.label = option.label();
     881            if (suggestion.value == suggestion.label)
     882                suggestion.label = { };
     883
     884            if (elementValue.isEmpty() || suggestion.value.startsWithIgnoringASCIICase(elementValue))
     885                suggestions.append(WTFMove(suggestion));
     886            else if (suggestion.value.containsIgnoringASCIICase(elementValue) || (canShowLabels && suggestion.label.containsIgnoringASCIICase(elementValue)))
     887                matchesContainingValue.append(WTFMove(suggestion));
    883888        }
    884889    }
    885890
    886     suggestions.appendVector(matchesContainingValue);
     891    suggestions.appendVector(WTFMove(matchesContainingValue));
    887892    m_cachedSuggestions = std::make_pair(elementValue, suggestions);
    888893
     
    897902void TextFieldInputType::didCloseSuggestions()
    898903{
    899     m_cachedSuggestions = std::make_pair(String(), Vector<String>());
     904    m_cachedSuggestions = { };
    900905    m_suggestionPicker = nullptr;
    901906    if (element()->renderer())
  • trunk/Source/WebCore/html/TextFieldInputType.h

    r242518 r259330  
    133133    // DataListSuggestionsClient
    134134    IntRect elementRectInRootViewCoordinates() const final;
    135     Vector<String> suggestions() final;
     135    Vector<DataListSuggestion> suggestions() final;
    136136    void didSelectDataListOption(const String&) final;
    137137    void didCloseSuggestions() final;
     
    140140    RefPtr<DataListButtonElement> m_dataListDropdownIndicator;
    141141
    142     std::pair<String, Vector<String>> m_cachedSuggestions;
     142    std::pair<String, Vector<DataListSuggestion>> m_cachedSuggestions;
    143143    std::unique_ptr<DataListSuggestionPicker> m_suggestionPicker;
    144144#endif
  • trunk/Source/WebCore/loader/EmptyClients.h

    r258487 r259330  
    134134#if ENABLE(DATALIST_ELEMENT)
    135135    std::unique_ptr<DataListSuggestionPicker> createDataListSuggestionPicker(DataListSuggestionsClient&) final;
     136    bool canShowDataListSuggestionLabels() const final { return false; }
    136137#endif
    137138
  • trunk/Source/WebCore/page/ChromeClient.h

    r258487 r259330  
    280280#if ENABLE(DATALIST_ELEMENT)
    281281    virtual std::unique_ptr<DataListSuggestionPicker> createDataListSuggestionPicker(DataListSuggestionsClient&) = 0;
     282    virtual bool canShowDataListSuggestionLabels() const = 0;
    282283#endif
    283284
  • trunk/Source/WebCore/platform/DataListSuggestionsClient.h

    r257196 r259330  
    3333
    3434class IntRect;
     35struct DataListSuggestion;
    3536
    3637class DataListSuggestionsClient {
     
    3940
    4041    virtual IntRect elementRectInRootViewCoordinates() const = 0;
    41     virtual Vector<String> suggestions() = 0;
     42    virtual Vector<DataListSuggestion> suggestions() = 0;
    4243
    4344    virtual void didSelectDataListOption(const String&) = 0;
  • trunk/Source/WebKit/ChangeLog

    r259328 r259330  
     12020-03-31  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        Datalist option's label not used
     4        https://bugs.webkit.org/show_bug.cgi?id=201768
     5        <rdar://problem/55361186>
     6
     7        Reviewed by Darin Adler.
     8
     9        Add support on macOS for showing option labels in datalist suggestions.
     10
     11        * Shared/WebCoreArgumentCoders.cpp:
     12        (IPC::ArgumentCoder<DataListSuggestionInformation>::encode): Deleted.
     13        (IPC::ArgumentCoder<DataListSuggestionInformation>::decode): Deleted.
     14        * Shared/WebCoreArgumentCoders.h:
     15
     16        Remove WebCoreArgumentCoders logic for encoding and decoding DataListSuggestionInformation. See
     17        DataListSuggestionInformation.h in WebCore for more detail.
     18
     19        * UIProcess/gtk/WebDataListSuggestionsDropdownGtk.cpp:
     20        (WebKit::WebDataListSuggestionsDropdownGtk::show):
     21
     22        Tweak GTK code to adjust for the change from `String` to `DataListSuggestion`.
     23
     24        * UIProcess/ios/WebDataListSuggestionsDropdownIOS.mm:
     25        (-[WKDataListSuggestionsControl didSelectOptionAtIndex:]):
     26        (-[WKDataListSuggestionsControl textSuggestions]):
     27        (-[WKDataListSuggestionsControl suggestionAtIndex:]):
     28
     29        Adjust some iOS codepaths to use DataListSuggestion::value as the value string to display.
     30
     31        * UIProcess/mac/WebDataListSuggestionsDropdownMac.mm:
     32
     33        Tweak several UI constants. A suggestion cell may now be either 20 or 40pt tall, depending on whether it has
     34        label text to show.
     35
     36        Currently, the maximum combined height of the table view cells is 120 (not including spacing between cells and
     37        vertical padding around the top and bottom of the table view), since the maximum number of cells to show is 6
     38        and each cell is 20pt tall. Maintain this constant by making the maximum cell height 120, which accomodates
     39        either three labeled cells, or 6 unlabeled cells (i.e. to match shipping behavior).
     40
     41        (-[WKDataListSuggestionView initWithFrame:]):
     42        (-[WKDataListSuggestionView layout]):
     43
     44        Maintain two text fields or value and (optionally) label text: `_valueField` and `_labelField`. The value field
     45        fills the bounds of the cell in the case where there is no label text, but fills only the top half of the cell
     46        in the case where there is label text. The label field takes the bottom half of the cell in this case.
     47
     48        Additionally, add a divider view that may appear at the very bottom of each cell. This divider view is present
     49        when one or more suggestions in the datalist are labeled.
     50
     51        (-[WKDataListSuggestionView setValue:label:]):
     52
     53        Renamed from -setText:. Add a label string argument as well.
     54
     55        (-[WKDataListSuggestionView setShouldShowBottomDivider:]):
     56
     57        Add getters and setters for the -shouldShowBottomDivider property, which can be used to make the divider view
     58        visible or hidden.
     59
     60        (-[WKDataListSuggestionView shouldShowBottomDivider]):
     61        (-[WKDataListSuggestionView setBackgroundStyle:]):
     62
     63        Use -[NSColor secondaryLabelColor] for the label text field.
     64
     65        (shouldShowDividersBetweenCells):
     66
     67        Add a helper method to determine whether the table view should be showing clear dividers between each item.
     68        We only do so if there are one or more labels to be shown.
     69
     70        (-[WKDataListSuggestionsController initWithInformation:inView:]):
     71        (-[WKDataListSuggestionsController currentSelectedString]):
     72        (-[WKDataListSuggestionsController updateWithInformation:]):
     73        (-[WKDataListSuggestionsController moveSelectionByDirection:]):
     74
     75        Drive-by fix: scroll to reveal each selected row when using the arrow keys to navigate between items.
     76
     77        (-[WKDataListSuggestionsController dropdownRectForElementRect:]):
     78        (-[WKDataListSuggestionsController tableView:heightOfRow:]):
     79
     80        Return either `dropdownRowHeightWithoutLabel` or `dropdownRowHeightWithLabel`, depending on whether there is
     81        label text to be shown in that suggestion cell.
     82
     83        (-[WKDataListSuggestionsController tableView:viewForTableColumn:row:]):
     84        (-[WKDataListSuggestionView setText:]): Deleted.
     85        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
     86        (WebKit::WebChromeClient::canShowDataListSuggestionLabels const):
     87        * WebProcess/WebCoreSupport/WebChromeClient.h:
     88
    1892020-03-31  Per Arne Vollan  <pvollan@apple.com>
    290
  • trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp

    r259184 r259330  
    4040#include <WebCore/Credential.h>
    4141#include <WebCore/Cursor.h>
    42 #include <WebCore/DataListSuggestionPicker.h>
    4342#include <WebCore/DatabaseDetails.h>
    4443#include <WebCore/DictationAlternative.h>
     
    17221721}
    17231722
    1724 #if ENABLE(DATALIST_ELEMENT)
    1725 void ArgumentCoder<DataListSuggestionInformation>::encode(Encoder& encoder, const WebCore::DataListSuggestionInformation& info)
    1726 {
    1727     encoder.encodeEnum(info.activationType);
    1728     encoder << info.suggestions;
    1729     encoder << info.elementRect;
    1730 }
    1731 
    1732 bool ArgumentCoder<DataListSuggestionInformation>::decode(Decoder& decoder, WebCore::DataListSuggestionInformation& info)
    1733 {
    1734     if (!decoder.decodeEnum(info.activationType))
    1735         return false;
    1736 
    1737     if (!decoder.decode(info.suggestions))
    1738         return false;
    1739 
    1740     if (!decoder.decode(info.elementRect))
    1741         return false;
    1742 
    1743     return true;
    1744 }
    1745 #endif
    1746 
    17471723template<> struct ArgumentCoder<PasteboardCustomData::Entry> {
    17481724    static void encode(Encoder&, const PasteboardCustomData::Entry&);
  • trunk/Source/WebKit/Shared/WebCoreArgumentCoders.h

    r259184 r259330  
    164164#endif
    165165
    166 #if ENABLE(DATALIST_ELEMENT)
    167 struct DataListSuggestionInformation;
    168 #endif
    169 
    170166#if USE(SOUP)
    171167struct SoupNetworkProxySettings;
     
    543539    static bool decode(Decoder&, WebCore::DatabaseDetails&);
    544540};
    545 
    546 #if ENABLE(DATALIST_ELEMENT)
    547 template<> struct ArgumentCoder<WebCore::DataListSuggestionInformation> {
    548     static void encode(Encoder&, const WebCore::DataListSuggestionInformation&);
    549     static bool decode(Decoder&, WebCore::DataListSuggestionInformation&);
    550 };
    551 #endif
    552541
    553542template<> struct ArgumentCoder<WebCore::DictationAlternative> {
  • trunk/Source/WebKit/UIProcess/gtk/WebDataListSuggestionsDropdownGtk.cpp

    r248547 r259330  
    121121        GtkTreeIter iter;
    122122        gtk_list_store_append(model, &iter);
    123         gtk_list_store_set(model, &iter, 0, suggestion.utf8().data(), -1);
     123        gtk_list_store_set(model, &iter, 0, suggestion.value.utf8().data(), -1);
    124124    }
    125125
  • trunk/Source/WebKit/UIProcess/ios/WebDataListSuggestionsDropdownIOS.mm

    r259207 r259330  
    4343@interface WKDataListSuggestionsControl : NSObject {
    4444    WeakPtr<WebKit::WebDataListSuggestionsDropdownIOS> _dropdown;
    45     Vector<String> _suggestions;
     45    Vector<WebCore::DataListSuggestion> _suggestions;
    4646}
    4747
     
    160160- (void)didSelectOptionAtIndex:(NSInteger)index
    161161{
    162     _dropdown->didSelectOption(_suggestions[index]);
     162    _dropdown->didSelectOption(_suggestions[index].value);
    163163}
    164164
     
    172172
    173173    for (const auto& suggestion : _suggestions) {
    174         [suggestions addObject:[WKDataListTextSuggestion textSuggestionWithInputText:suggestion]];
     174        [suggestions addObject:[WKDataListTextSuggestion textSuggestionWithInputText:suggestion.value]];
    175175        if (suggestions.count == 3)
    176176            break;
     
    187187- (String)suggestionAtIndex:(NSInteger)index
    188188{
    189     return _suggestions[index];
     189    return _suggestions[index].value;
    190190}
    191191
  • trunk/Source/WebKit/UIProcess/mac/WebDataListSuggestionsDropdownMac.mm

    r259207 r259330  
    3535#import <pal/spi/cocoa/NSColorSPI.h>
    3636
    37 static const CGFloat dropdownTopMargin = 3;
    38 static const CGFloat dropdownVerticalPadding = 4;
    39 static const CGFloat dropdownRowHeight = 20;
    40 static const size_t dropdownMaxSuggestions = 6;
     37constexpr CGFloat dropdownTopMargin = 3;
     38constexpr CGFloat dropdownVerticalPadding = 4;
     39constexpr CGFloat dropdownRowHeightWithoutLabel = 20;
     40constexpr CGFloat dropdownRowHeightWithLabel = 40;
     41constexpr CGFloat maximumTotalHeightForDropdownCells = 120;
    4142static NSString * const suggestionCellReuseIdentifier = @"WKDataListSuggestionView";
    4243
     
    4546
    4647@interface WKDataListSuggestionView : NSTableCellView
     48@property (nonatomic) BOOL shouldShowBottomDivider;
    4749@end
    4850
     
    170172
    171173@implementation WKDataListSuggestionView {
    172     RetainPtr<NSTextField> _textField;
     174    RetainPtr<NSTextField> _valueField;
     175    RetainPtr<NSTextField> _labelField;
     176    RetainPtr<NSView> _bottomDivider;
    173177}
    174178
     
    178182        return self;
    179183
    180     _textField = adoptNS([[NSTextField alloc] initWithFrame:frameRect]);
    181     self.textField = _textField.get();
    182 
    183     [self addSubview:self.textField];
    184 
     184    _valueField = adoptNS([[NSTextField alloc] init]);
     185    _labelField = adoptNS([[NSTextField alloc] init]);
     186    _bottomDivider = adoptNS([[NSView alloc] init]);
     187    [_bottomDivider setWantsLayer:YES];
     188    [_bottomDivider setHidden:YES];
     189    [_bottomDivider layer].backgroundColor = NSColor.separatorColor.CGColor;
     190    [self addSubview:_bottomDivider.get()];
     191
     192    auto setUpTextField = [&](NSTextField *textField) {
     193        textField.editable = NO;
     194        textField.bezeled = NO;
     195        textField.font = [NSFont menuFontOfSize:0];
     196        textField.drawsBackground = NO;
     197        [self addSubview:textField];
     198    };
     199
     200    setUpTextField(_valueField.get());
     201    setUpTextField(_labelField.get());
    185202    self.identifier = suggestionCellReuseIdentifier;
    186     self.textField.editable = NO;
    187     self.textField.bezeled = NO;
    188     self.textField.font = [NSFont menuFontOfSize:0];
    189     self.textField.drawsBackground = NO;
    190203
    191204    return self;
    192205}
    193206
    194 - (void)setText:(NSString *)text
    195 {
    196     self.textField.stringValue = text;
     207- (void)layout
     208{
     209    [super layout];
     210
     211    auto bounds = self.bounds;
     212    auto width = bounds.size.width;
     213    if (![_labelField isHidden]) {
     214        auto halfOfHeight = bounds.size.height / 2;
     215        [_valueField setFrame:NSMakeRect(0, halfOfHeight, width, halfOfHeight)];
     216        [_labelField setFrame:NSMakeRect(0, 0, width, halfOfHeight)];
     217    } else
     218        [_valueField setFrame:bounds];
     219
     220    if (![_bottomDivider isHidden])
     221        [_bottomDivider setFrame:NSMakeRect(0, 0, width, 0.5)];
     222}
     223
     224- (void)setValue:(NSString *)value label:(NSString *)label
     225{
     226    if ([[_valueField stringValue] isEqualToString:value] && [[_labelField stringValue] isEqualToString:label])
     227        return;
     228
     229    [_valueField setStringValue:value];
     230    [_labelField setStringValue:label];
     231    [_labelField setHidden:!label.length];
     232    self.needsLayout = YES;
     233}
     234
     235- (void)setShouldShowBottomDivider:(BOOL)showBottomDivider
     236{
     237    if ([_bottomDivider isHidden] == !showBottomDivider)
     238        return;
     239
     240    [_bottomDivider setHidden:!showBottomDivider];
     241    self.needsLayout = YES;
     242}
     243
     244- (BOOL)shouldShowBottomDivider
     245{
     246    return [_bottomDivider isHidden];
    197247}
    198248
     
    200250{
    201251    [super setBackgroundStyle:backgroundStyle];
    202     ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    203     self.textField.textColor = backgroundStyle == NSBackgroundStyleLight ? [NSColor textColor] : [NSColor alternateSelectedControlTextColor];
    204     ALLOW_DEPRECATED_DECLARATIONS_END
     252ALLOW_DEPRECATED_DECLARATIONS_BEGIN
     253    [_valueField setTextColor:backgroundStyle == NSBackgroundStyleLight ? NSColor.textColor : NSColor.alternateSelectedControlTextColor];
     254    [_labelField setTextColor:NSColor.secondaryLabelColor];
     255ALLOW_DEPRECATED_DECLARATIONS_END
    205256}
    206257
     
    252303@end
    253304
     305static BOOL shouldShowDividersBetweenCells(const Vector<WebCore::DataListSuggestion>& suggestions)
     306{
     307    return notFound != suggestions.findMatching([](auto& suggestion) {
     308        return !suggestion.label.isEmpty();
     309    });
     310}
     311
    254312@implementation WKDataListSuggestionsController {
    255313    WeakPtr<WebKit::WebDataListSuggestionsDropdownMac> _dropdown;
    256     Vector<String> _suggestions;
     314    Vector<WebCore::DataListSuggestion> _suggestions;
    257315    NSView *_presentingView;
    258316
     
    260318    RetainPtr<WKDataListSuggestionWindow> _enclosingWindow;
    261319    RetainPtr<WKDataListSuggestionTableView> _table;
     320    BOOL _showDividersBetweenCells;
    262321}
    263322
     
    269328    _presentingView = presentingView;
    270329    _suggestions = WTFMove(information.suggestions);
     330    _showDividersBetweenCells = shouldShowDividersBetweenCells(_suggestions);
    271331    _table = adoptNS([[WKDataListSuggestionTableView alloc] initWithElementRect:information.elementRect]);
    272332
     
    303363
    304364    if (selectedRow >= 0 && static_cast<size_t>(selectedRow) < _suggestions.size())
    305         return _suggestions.at(selectedRow);
     365        return _suggestions.at(selectedRow).value;
    306366
    307367    return String();
     
    311371{
    312372    _suggestions = WTFMove(information.suggestions);
     373    _showDividersBetweenCells = shouldShowDividersBetweenCells(_suggestions);
    313374    [_table reload];
    314375
     
    340401
    341402    [_table selectRowIndexes:[NSIndexSet indexSetWithIndex:newSelection] byExtendingSelection:NO];
     403    [_table scrollRowToVisible:newSelection];
    342404
    343405    // Notify accessibility clients of new selection.
     
    370432{
    371433    NSRect windowRect = [[_presentingView window] convertRectToScreen:[_presentingView convertRect:rect toView:nil]];
    372     auto visibleSuggestionCount = std::min(_suggestions.size(), dropdownMaxSuggestions);
    373     CGFloat height = visibleSuggestionCount * (dropdownRowHeight + [_table intercellSpacing].height) + (dropdownVerticalPadding * 2);
     434
     435    CGFloat totalCellHeight = 0;
     436    for (auto& suggestion : _suggestions)
     437        totalCellHeight += suggestion.label.isEmpty() ? dropdownRowHeightWithoutLabel : dropdownRowHeightWithLabel;
     438
     439    CGFloat totalIntercellSpacingAndPadding = dropdownVerticalPadding * 2;
     440    if (_suggestions.size() > 1)
     441        totalIntercellSpacingAndPadding += (_suggestions.size() - 1) * [_table intercellSpacing].height;
     442
     443    CGFloat height = totalIntercellSpacingAndPadding + std::min(totalCellHeight, maximumTotalHeightForDropdownCells);
    374444    return NSMakeRect(NSMinX(windowRect), NSMinY(windowRect) - height - dropdownTopMargin, rect.width(), height);
    375445}
     
    405475- (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row
    406476{
    407     return dropdownRowHeight;
     477    auto suggestionIndex = static_cast<size_t>(row);
     478    if (suggestionIndex >= _suggestions.size()) {
     479        ASSERT_NOT_REACHED();
     480        return 0;
     481    }
     482
     483    return _suggestions.at(suggestionIndex).label.isEmpty() ? dropdownRowHeightWithoutLabel : dropdownRowHeightWithLabel;
    408484}
    409485
     
    418494
    419495    if (!result) {
    420         result = [[[WKDataListSuggestionView alloc] initWithFrame:NSMakeRect(0, 0, tableView.frame.size.width, dropdownRowHeight)] autorelease];
     496        result = [[[WKDataListSuggestionView alloc] init] autorelease];
    421497        [result setIdentifier:suggestionCellReuseIdentifier];
    422498    }
    423499
    424     result.text = _suggestions.at(row);
     500    auto& suggestion = _suggestions.at(row);
     501    result.shouldShowBottomDivider = _showDividersBetweenCells && row < static_cast<NSInteger>(_suggestions.size() - 1);
     502    [result setValue:suggestion.value label:suggestion.label];
    425503
    426504    return result;
  • trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp

    r258663 r259330  
    797797}
    798798
     799bool WebChromeClient::canShowDataListSuggestionLabels() const
     800{
     801#if PLATFORM(MAC)
     802    return true;
     803#else
     804    return false;
     805#endif
     806}
     807
    799808#endif
    800809
  • trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h

    r258487 r259330  
    150150#if ENABLE(DATALIST_ELEMENT)
    151151    std::unique_ptr<WebCore::DataListSuggestionPicker> createDataListSuggestionPicker(WebCore::DataListSuggestionsClient&) final;
     152    bool canShowDataListSuggestionLabels() const final;
    152153#endif
    153154
  • trunk/Source/WebKitLegacy/mac/ChangeLog

    r259236 r259330  
     12020-03-31  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        Datalist option's label not used
     4        https://bugs.webkit.org/show_bug.cgi?id=201768
     5        <rdar://problem/55361186>
     6
     7        Reviewed by Darin Adler.
     8
     9        See WebCore/ChangeLog and WebKit/ChangeLog for more details.
     10
     11        * WebCoreSupport/WebChromeClient.h:
     12
    1132020-03-30  Devin Rousso  <drousso@apple.com>
    214
  • trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.h

    r258487 r259330  
    145145#if ENABLE(DATALIST_ELEMENT)
    146146    std::unique_ptr<WebCore::DataListSuggestionPicker> createDataListSuggestionPicker(WebCore::DataListSuggestionsClient&) final;
     147    bool canShowDataListSuggestionLabels() const final { return false; }
    147148#endif
    148149
Note: See TracChangeset for help on using the changeset viewer.