Changeset 234281 in webkit


Ignore:
Timestamp:
Jul 26, 2018 4:12:23 PM (6 years ago)
Author:
commit-queue@webkit.org
Message:

[Datalist] Add button to TextFieldInputs with a datalist
https://bugs.webkit.org/show_bug.cgi?id=187741

Patch by Aditya Keerthi <Aditya Keerthi> on 2018-07-26
Reviewed by Tim Horton.

Source/WebCore:

TextFieldInputs that have an associated datalist element should be drawn as
combo boxes. However, we cannot use NSComboBox for this control, as NSComboBox
is not height-resizable. Furthermore, the input should also be able to contain
additional elements, such as the stepper for type=number and the cancel button
for type=search. For these reasons, we draw a button at the end of the input,
mimicking appearance of a combo box.

The list-button -webkit-appearance value was added to display the new button.

Tests: fast/forms/datalist/datalist-searchinput-appearance.html

fast/forms/datalist/datalist-textinput-appearance.html

  • Resources/ListButtonArrow.png: Added.
  • Resources/ListButtonArrow@2x.png: Added.
  • WebCore.xcodeproj/project.pbxproj:
  • css/CSSPrimitiveValueMappings.h:

(WebCore::CSSPrimitiveValue::CSSPrimitiveValue):

  • css/CSSProperties.json:
  • css/CSSValueKeywords.in:
  • css/html.css:

(input::-webkit-list-button):

  • html/HTMLInputElement.cpp:

(WebCore::HTMLInputElement::dataListButtonElement const):
(WebCore::HTMLInputElement::isShowingList const):

  • html/HTMLInputElement.h:
  • html/InputType.h:

(WebCore::InputType::dataListButtonElement const):
(WebCore::InputType::isShowingList const):

  • html/TextFieldInputType.cpp:

(WebCore::TextFieldInputType::needsContainer const):
(WebCore::TextFieldInputType::createShadowSubtree):
(WebCore::TextFieldInputType::destroyShadowSubtree):
(WebCore::TextFieldInputType::listAttributeTargetChanged):
(WebCore::TextFieldInputType::dataListButtonElement const):
(WebCore::TextFieldInputType::dataListButtonElementWasClicked):
(WebCore::TextFieldInputType::didCloseSuggestions):
(WebCore::TextFieldInputType::isShowingList const):

  • html/TextFieldInputType.h:
  • html/shadow/DataListButtonElement.cpp: Added.

(WebCore::DataListButtonElement::create):
(WebCore::DataListButtonElement::DataListButtonElement):
(WebCore::DataListButtonElement::~DataListButtonElement):
(WebCore::DataListButtonElement::defaultEventHandler):

  • html/shadow/DataListButtonElement.h: Added.
  • platform/ThemeTypes.h:
  • rendering/RenderTheme.cpp:

(WebCore::RenderTheme::adjustStyle):
(WebCore::RenderTheme::adjustListButtonStyle const):

  • rendering/RenderTheme.h:
  • rendering/RenderThemeMac.h:
  • rendering/RenderThemeMac.mm:

(-[WebListButtonCell drawWithFrame:inView:]):
(WebCore::RenderThemeMac::paintListButtonForInput):
(WebCore::RenderThemeMac::adjustListButtonStyle const):
(WebCore::RenderThemeMac::paintTextField):
(WebCore::RenderThemeMac::paintSearchField):
(WebCore::RenderThemeMac::paintSearchFieldCancelButton):
(WebCore::RenderThemeMac::listButton const):

Source/WebCore/PAL:

  • pal/spi/cocoa/NSColorSPI.h: Added NSColorGetUserAccentColor().

Source/WebInspectorUI:

Add keyword completion for 'list-button'.

  • UserInterface/External/CodeMirror/css.js:
  • UserInterface/Models/CSSKeywordCompletions.js:

LayoutTests:

Added tests to verify appearance of TextFieldInputs with a datalist.

  • fast/forms/datalist/datalist-searchinput-appearance.html: Added.
  • fast/forms/datalist/datalist-textinput-appearance.html: Added.
  • platform/mac/fast/forms/datalist/datalist-searchinput-appearance-expected.png: Added.
  • platform/mac/fast/forms/datalist/datalist-searchinput-appearance-expected.txt: Added.
  • platform/mac/fast/forms/datalist/datalist-textinput-appearance-expected.png: Added.
  • platform/mac/fast/forms/datalist/datalist-textinput-appearance-expected.txt: Added.
Location:
trunk
Files:
10 added
22 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r234279 r234281  
     12018-07-26  Aditya Keerthi  <akeerthi@apple.com>
     2
     3        [Datalist] Add button to TextFieldInputs with a datalist
     4        https://bugs.webkit.org/show_bug.cgi?id=187741
     5
     6        Reviewed by Tim Horton.
     7
     8        Added tests to verify appearance of TextFieldInputs with a datalist.
     9
     10        * fast/forms/datalist/datalist-searchinput-appearance.html: Added.
     11        * fast/forms/datalist/datalist-textinput-appearance.html: Added.
     12        * platform/mac/fast/forms/datalist/datalist-searchinput-appearance-expected.png: Added.
     13        * platform/mac/fast/forms/datalist/datalist-searchinput-appearance-expected.txt: Added.
     14        * platform/mac/fast/forms/datalist/datalist-textinput-appearance-expected.png: Added.
     15        * platform/mac/fast/forms/datalist/datalist-textinput-appearance-expected.txt: Added.
     16
    1172018-07-26  Antoine Quint  <graouts@apple.com>
    218
  • trunk/Source/WebCore/ChangeLog

    r234279 r234281  
     12018-07-26  Aditya Keerthi  <akeerthi@apple.com>
     2
     3        [Datalist] Add button to TextFieldInputs with a datalist
     4        https://bugs.webkit.org/show_bug.cgi?id=187741
     5
     6        Reviewed by Tim Horton.
     7
     8        TextFieldInputs that have an associated datalist element should be drawn as
     9        combo boxes. However, we cannot use NSComboBox for this control, as NSComboBox
     10        is not height-resizable. Furthermore, the input should also be able to contain
     11        additional elements, such as the stepper for type=number and the cancel button
     12        for type=search. For these reasons, we draw a button at the end of the input,
     13        mimicking appearance of a combo box.
     14
     15        The list-button -webkit-appearance value was added to display the new button.
     16
     17        Tests: fast/forms/datalist/datalist-searchinput-appearance.html
     18               fast/forms/datalist/datalist-textinput-appearance.html
     19
     20        * Resources/ListButtonArrow.png: Added.
     21        * Resources/ListButtonArrow@2x.png: Added.
     22        * WebCore.xcodeproj/project.pbxproj:
     23        * css/CSSPrimitiveValueMappings.h:
     24        (WebCore::CSSPrimitiveValue::CSSPrimitiveValue):
     25        * css/CSSProperties.json:
     26        * css/CSSValueKeywords.in:
     27        * css/html.css:
     28        (input::-webkit-list-button):
     29        * html/HTMLInputElement.cpp:
     30        (WebCore::HTMLInputElement::dataListButtonElement const):
     31        (WebCore::HTMLInputElement::isShowingList const):
     32        * html/HTMLInputElement.h:
     33        * html/InputType.h:
     34        (WebCore::InputType::dataListButtonElement const):
     35        (WebCore::InputType::isShowingList const):
     36        * html/TextFieldInputType.cpp:
     37        (WebCore::TextFieldInputType::needsContainer const):
     38        (WebCore::TextFieldInputType::createShadowSubtree):
     39        (WebCore::TextFieldInputType::destroyShadowSubtree):
     40        (WebCore::TextFieldInputType::listAttributeTargetChanged):
     41        (WebCore::TextFieldInputType::dataListButtonElement const):
     42        (WebCore::TextFieldInputType::dataListButtonElementWasClicked):
     43        (WebCore::TextFieldInputType::didCloseSuggestions):
     44        (WebCore::TextFieldInputType::isShowingList const):
     45        * html/TextFieldInputType.h:
     46        * html/shadow/DataListButtonElement.cpp: Added.
     47        (WebCore::DataListButtonElement::create):
     48        (WebCore::DataListButtonElement::DataListButtonElement):
     49        (WebCore::DataListButtonElement::~DataListButtonElement):
     50        (WebCore::DataListButtonElement::defaultEventHandler):
     51        * html/shadow/DataListButtonElement.h: Added.
     52        * platform/ThemeTypes.h:
     53        * rendering/RenderTheme.cpp:
     54        (WebCore::RenderTheme::adjustStyle):
     55        (WebCore::RenderTheme::adjustListButtonStyle const):
     56        * rendering/RenderTheme.h:
     57        * rendering/RenderThemeMac.h:
     58        * rendering/RenderThemeMac.mm:
     59        (-[WebListButtonCell drawWithFrame:inView:]):
     60        (WebCore::RenderThemeMac::paintListButtonForInput):
     61        (WebCore::RenderThemeMac::adjustListButtonStyle const):
     62        (WebCore::RenderThemeMac::paintTextField):
     63        (WebCore::RenderThemeMac::paintSearchField):
     64        (WebCore::RenderThemeMac::paintSearchFieldCancelButton):
     65        (WebCore::RenderThemeMac::listButton const):
     66
    1672018-07-26  Antoine Quint  <graouts@apple.com>
    268
  • trunk/Source/WebCore/PAL/ChangeLog

    r234272 r234281  
     12018-07-26  Aditya Keerthi  <akeerthi@apple.com>
     2
     3        [Datalist] Add button to TextFieldInputs with a datalist
     4        https://bugs.webkit.org/show_bug.cgi?id=187741
     5
     6        Reviewed by Tim Horton.
     7
     8        * pal/spi/cocoa/NSColorSPI.h: Added NSColorGetUserAccentColor().
     9
    1102018-07-26  Commit Queue  <commit-queue@webkit.org>
    211
  • trunk/Source/WebCore/PAL/pal/spi/cocoa/NSColorSPI.h

    r232847 r234281  
    2929
    3030#import <AppKit/NSColor_Private.h>
     31#import <AppKit/NSColor_UserAccent.h>
    3132
    3233#else
     
    4748@end
    4849
     50typedef NS_ENUM(NSInteger, NSUserAccentColor) {
     51    NSUserAccentColorRed = 0,
     52    NSUserAccentColorOrange,
     53    NSUserAccentColorYellow,
     54    NSUserAccentColorGreen,
     55    NSUserAccentColorBlue,
     56    NSUserAccentColorPurple,
     57    NSUserAccentColorPink,
     58
     59    NSUserAccentColorNoColor = -1,
     60};
     61
     62extern "C" NSUserAccentColor NSColorGetUserAccentColor(void);
     63
    4964#endif
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r234258 r234281  
    47824782                E4E9B11D1814569C003ACCDF /* SimpleLineLayoutFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = E4E9B11C1814569C003ACCDF /* SimpleLineLayoutFunctions.h */; };
    47834783                E4F9EEF3156DA00700D23E7E /* StyleSheetContents.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F9EEF1156D84C400D23E7E /* StyleSheetContents.h */; settings = {ATTRIBUTES = (Private, ); }; };
     4784                E59DD4B821098287003C8B47 /* ListButtonArrow.png in Resources */ = {isa = PBXBuildFile; fileRef = E59DD4B721098285003C8B47 /* ListButtonArrow.png */; };
     4785                E516699120FF9918009D2C27 /* ListButtonArrow@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E516698F20FF9916009D2C27 /* ListButtonArrow@2x.png */; };
    47844786                E517670320B88C1400D41167 /* DataListSuggestionInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = E517670220B88C1400D41167 /* DataListSuggestionInformation.h */; settings = {ATTRIBUTES = (Private, ); }; };
    47854787                E52CF54D20A268AC00DADA27 /* DataListSuggestionsClient.h in Headers */ = {isa = PBXBuildFile; fileRef = E52CF54C20A268AC00DADA27 /* DataListSuggestionsClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
    47864788                E52CF54F20A35A2800DADA27 /* DataListSuggestionPicker.h in Headers */ = {isa = PBXBuildFile; fileRef = E52CF54E20A35A2800DADA27 /* DataListSuggestionPicker.h */; settings = {ATTRIBUTES = (Private, ); }; };
     4789                E58B45BA20AD07DD00991025 /* DataListButtonElement.h in Headers */ = {isa = PBXBuildFile; fileRef = E58B45B820AD07DD00991025 /* DataListButtonElement.h */; };
     4790                E58B45BB20AD07DD00991025 /* DataListButtonElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E58B45B920AD07DD00991025 /* DataListButtonElement.cpp */; };
    47874791                E5BA7D63151437CA00FE1E3F /* LengthFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = E5BA7D62151437CA00FE1E3F /* LengthFunctions.h */; settings = {ATTRIBUTES = (Private, ); }; };
    47884792                EBF5121C1696496C0056BD25 /* JSTypeConversions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EBF5121A1696496C0056BD25 /* JSTypeConversions.cpp */; };
     
    1449014494                E4F9EEF0156D84C400D23E7E /* StyleSheetContents.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleSheetContents.cpp; sourceTree = "<group>"; };
    1449114495                E4F9EEF1156D84C400D23E7E /* StyleSheetContents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleSheetContents.h; sourceTree = "<group>"; };
     14496                E59DD4B721098285003C8B47 /* ListButtonArrow.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = ListButtonArrow.png; sourceTree = "<group>"; };
     14497                E516698F20FF9916009D2C27 /* ListButtonArrow@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "ListButtonArrow@2x.png"; sourceTree = "<group>"; };
    1449214498                E517670220B88C1400D41167 /* DataListSuggestionInformation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DataListSuggestionInformation.h; sourceTree = "<group>"; };
    1449314499                E51A81DE17298D7700BFCA61 /* JSPerformance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPerformance.cpp; sourceTree = "<group>"; };
     
    1449614502                E52CF54E20A35A2800DADA27 /* DataListSuggestionPicker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DataListSuggestionPicker.h; sourceTree = "<group>"; };
    1449714503                E55F4979151B888000BB67DB /* LengthFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LengthFunctions.cpp; sourceTree = "<group>"; };
     14504                E58B45B820AD07DD00991025 /* DataListButtonElement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DataListButtonElement.h; sourceTree = "<group>"; };
     14505                E58B45B920AD07DD00991025 /* DataListButtonElement.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DataListButtonElement.cpp; sourceTree = "<group>"; };
    1449814506                E5BA7D62151437CA00FE1E3F /* LengthFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LengthFunctions.h; sourceTree = "<group>"; };
    1449914507                EB081CD81696084400553730 /* TypeConversions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TypeConversions.h; sourceTree = "<group>"; };
     
    1684316851                                7C1E97251A9F9834007BF0FB /* AutoFillButtonElement.cpp */,
    1684416852                                7C1E97261A9F9834007BF0FB /* AutoFillButtonElement.h */,
     16853                                E58B45B920AD07DD00991025 /* DataListButtonElement.cpp */,
     16854                                E58B45B820AD07DD00991025 /* DataListButtonElement.h */,
    1684516855                                A7C9ABF61357A3BF00F5503F /* DetailsMarkerControl.cpp */,
    1684616856                                A7C9ABF71357A3BF00F5503F /* DetailsMarkerControl.h */,
     
    1922219232                                D02B64B014089E56006EFA21 /* DictationPhraseWithAlternativesDot.png */,
    1922319233                                D02B64B114089E56006EFA21 /* DictationPhraseWithAlternativesDot@2x.png */,
     19234                                E59DD4B721098285003C8B47 /* ListButtonArrow.png */,
     19235                                E516698F20FF9916009D2C27 /* ListButtonArrow@2x.png */,
    1922419236                                BE8C753010681324001E93F5 /* SpellingDot.png */,
    1922519237                                01E6C2E31194B2820050821C /* SpellingDot@2x.png */,
     
    2766827680                                C5227DF11C3C6DF100F5ED54 /* DataDetection.h in Headers */,
    2766927681                                7C7941E51C56C29300A4C58E /* DataDetectorsCoreSoftLink.h in Headers */,
     27682                                E58B45BA20AD07DD00991025 /* DataListButtonElement.h in Headers */,
    2767027683                                E517670320B88C1400D41167 /* DataListSuggestionInformation.h in Headers */,
    2767127684                                E52CF54F20A35A2800DADA27 /* DataListSuggestionPicker.h in Headers */,
     
    3123131244                                7CC7E3D717208C0F003C5277 /* IDNScriptWhiteList.txt in Resources */,
    3123231245                                2D9F0E1314FF1CBF00BA0FF7 /* linearSRGB.icc in Resources */,
     31246                                E59DD4B821098287003C8B47 /* ListButtonArrow.png in Resources */,
     31247                                E516699120FF9918009D2C27 /* ListButtonArrow@2x.png in Resources */,
    3123331248                                BCAD180A131C7A0D00990406 /* Localizable.strings in Resources */,
    3123431249                                837A80131E1E127300026B9F /* Localizable.stringsdict in Resources */,
     
    3147331488                                1ABA76CA11D20E50004C201C /* CSSPropertyNames.cpp in Sources */,
    3147431489                                BE23480C18A9870B00E4B6E8 /* DataCue.cpp in Sources */,
     31490                                E58B45BB20AD07DD00991025 /* DataListButtonElement.cpp in Sources */,
    3147531491                                515BE18F1D54F5FB00DD7C68 /* EmptyGamepadProvider.cpp in Sources */,
    3147631492                                724ED32C1A3A7E5400F5F13C /* EXTBlendMinMax.cpp in Sources */,
  • trunk/Source/WebCore/css/CSSPrimitiveValueMappings.h

    r233916 r234281  
    620620    case ApplePayButtonPart:
    621621        m_value.valueID = CSSValueApplePayButton;
     622        break;
     623#endif
     624#if ENABLE(DATALIST_ELEMENT)
     625    case ListButtonPart:
     626        m_value.valueID = CSSValueListButton;
    622627        break;
    623628#endif
  • trunk/Source/WebCore/css/CSSProperties.json

    r234215 r234281  
    37943794                "attachment",
    37953795                "caps-lock-indicator",
     3796                "list-button",
    37963797                "none"
    37973798            ],
  • trunk/Source/WebCore/css/CSSValueKeywords.in

    r233877 r234281  
    837837-apple-pay-button
    838838#endif
     839#if defined(ENABLE_DATALIST_ELEMENT) && ENABLE_DATALIST_ELEMENT
     840list-button
     841#endif
    839842textarea
    840843#if defined(ENABLE_ATTACHMENT_ELEMENT) && ENABLE_ATTACHMENT_ELEMENT
  • trunk/Source/WebCore/css/html.css

    r234126 r234281  
    617617}
    618618
     619#if defined(ENABLE_DATALIST_ELEMENT) && ENABLE_DATALIST_ELEMENT
     620input::-webkit-list-button {
     621    -webkit-appearance: list-button;
     622    display: block;
     623    position: relative;
     624    cursor: default;
     625    align-self: stretch;
     626    flex: none;
     627    -webkit-user-select: none;
     628    width: 16px;
     629    height: 100%;
     630}
     631#endif
     632
    619633keygen, select {
    620634    border-radius: 5px;
  • trunk/Source/WebCore/html/HTMLInputElement.cpp

    r234278 r234281  
    242242}
    243243
     244#if ENABLE(DATALIST_ELEMENT)
     245HTMLElement* HTMLInputElement::dataListButtonElement() const
     246{
     247    return m_inputType->dataListButtonElement();
     248}
     249#endif
     250
    244251bool HTMLInputElement::shouldAutocomplete() const
    245252{
     
    16291636}
    16301637
     1638bool HTMLInputElement::isShowingList() const
     1639{
     1640    return m_inputType->isShowingList();
     1641}
     1642
    16311643#endif // ENABLE(DATALIST_ELEMENT)
    16321644
  • trunk/Source/WebCore/html/HTMLInputElement.h

    r234105 r234281  
    149149    HTMLElement* placeholderElement() const final;
    150150    WEBCORE_EXPORT HTMLElement* autoFillButtonElement() const;
     151#if ENABLE(DATALIST_ELEMENT)
     152    HTMLElement* dataListButtonElement() const;
     153#endif
    151154
    152155    bool checked() const { return m_isChecked; }
     
    273276    RefPtr<HTMLDataListElement> dataList() const;
    274277    void listAttributeTargetChanged();
     278    bool isShowingList() const;
    275279#endif
    276280
  • trunk/Source/WebCore/html/InputType.h

    r232496 r234281  
    227227    virtual HTMLElement* sliderTrackElement() const { return nullptr; }
    228228    virtual HTMLElement* placeholderElement() const;
     229#if ENABLE(DATALIST_ELEMENT)
     230    virtual HTMLElement* dataListButtonElement() const { return nullptr; }
     231#endif
    229232
    230233    // Miscellaneous functions.
     
    291294
    292295#if ENABLE(DATALIST_ELEMENT)
     296    virtual bool isShowingList() const { return false; };
    293297    virtual void listAttributeTargetChanged();
    294298    virtual std::optional<Decimal> findClosestTickMarkValue(const Decimal&);
  • trunk/Source/WebCore/html/TextFieldInputType.cpp

    r233866 r234281  
    286286bool TextFieldInputType::needsContainer() const
    287287{
     288#if ENABLE(DATALIST_ELEMENT)
     289    return element()->hasAttributeWithoutSynchronization(listAttr);
     290#endif
    288291    return false;
    289292}
     
    344347
    345348    updateAutoFillButton();
     349
     350#if ENABLE(DATALIST_ELEMENT)
     351    m_dataListDropdownIndicator = DataListButtonElement::create(element()->document(), *this);
     352    m_dataListDropdownIndicator->setInlineStyleProperty(CSSPropertyDisplay, CSSValueNone, true);
     353    m_container->appendChild(*m_dataListDropdownIndicator);
     354#endif
    346355}
    347356
     
    393402    m_capsLockIndicator = nullptr;
    394403    m_autoFillButton = nullptr;
     404#if ENABLE(DATALIST)
     405    m_dataListDropdownIndicator = nullptr;
     406#endif
    395407    m_container = nullptr;
    396408}
     
    786798#if ENABLE(DATALIST_ELEMENT)
    787799
     800void TextFieldInputType::listAttributeTargetChanged()
     801{
     802    if (!m_dataListDropdownIndicator)
     803        return;
     804
     805    m_dataListDropdownIndicator->setInlineStyleProperty(CSSPropertyDisplay, element()->list() ? CSSValueBlock : CSSValueNone, true);
     806}
     807
     808HTMLElement* TextFieldInputType::dataListButtonElement() const
     809{
     810    return m_dataListDropdownIndicator.get();
     811}
     812
     813void TextFieldInputType::dataListButtonElementWasClicked()
     814{
     815    if (element()->list())
     816        displaySuggestions(DataListSuggestionActivationType::IndicatorClicked);
     817}
     818
    788819IntRect TextFieldInputType::elementRectInRootViewCoordinates() const
    789820{
     
    820851{
    821852    m_suggestionPicker = nullptr;
     853    element()->renderer()->repaint();
    822854}
    823855
     
    845877}
    846878
     879bool TextFieldInputType::isShowingList() const
     880{
     881    return !!m_suggestionPicker;
     882}
     883
    847884#endif
    848885
  • trunk/Source/WebCore/html/TextFieldInputType.h

    r232640 r234281  
    3333
    3434#include "AutoFillButtonElement.h"
     35#include "DataListButtonElement.h"
    3536#include "DataListSuggestionPicker.h"
    3637#include "DataListSuggestionsClient.h"
     
    4748class TextFieldInputType : public InputType, protected SpinButtonElement::SpinButtonOwner, protected AutoFillButtonElement::AutoFillButtonOwner
    4849#if ENABLE(DATALIST_ELEMENT)
    49     , private DataListSuggestionsClient
     50    , private DataListSuggestionsClient, protected DataListButtonElement::DataListButtonOwner
    5051#endif
    5152{
     
    6566    HTMLElement* capsLockIndicatorElement() const final;
    6667    HTMLElement* autoFillButtonElement() const final;
     68#if ENABLE(DATALIST_ELEMENT)
     69    HTMLElement* dataListButtonElement() const final;
     70#endif
    6771
    6872    virtual bool needsContainer() const;
     
    121125
    122126#if ENABLE(DATALIST_ELEMENT)
     127    bool isShowingList() const override;
     128    void listAttributeTargetChanged() final;
    123129    void displaySuggestions(DataListSuggestionActivationType);
    124130    void closeSuggestions();
     
    129135    void didSelectDataListOption(const String&) final;
    130136    void didCloseSuggestions() final;
     137
     138    void dataListButtonElementWasClicked() final;
     139    RefPtr<DataListButtonElement> m_dataListDropdownIndicator;
    131140
    132141    std::unique_ptr<DataListSuggestionPicker> m_suggestionPicker;
  • trunk/Source/WebCore/html/shadow/DataListButtonElement.h

    r234280 r234281  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2018 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 #import <AppKit/NSColor.h>
     26#pragma once
    2727
    28 #if PLATFORM(MAC) && USE(APPLE_INTERNAL_SDK)
     28#if ENABLE(DATALIST_ELEMENT)
    2929
    30 #import <AppKit/NSColor_Private.h>
     30#include "HTMLDivElement.h"
    3131
    32 #else
     32namespace WebCore {
    3333
    34 @interface NSColor ()
    35 + (NSColor *)systemRedColor;
    36 + (NSColor *)systemGreenColor;
    37 + (NSColor *)systemBlueColor;
    38 + (NSColor *)systemOrangeColor;
    39 + (NSColor *)systemYellowColor;
    40 + (NSColor *)systemBrownColor;
    41 + (NSColor *)systemPinkColor;
    42 + (NSColor *)systemPurpleColor;
    43 + (NSColor *)systemGrayColor;
    44 + (NSColor *)linkColor;
    45 + (NSColor *)findHighlightColor;
    46 + (NSColor *)placeholderTextColor;
    47 @end
     34class TextFieldInputType;
    4835
    49 #endif
     36class DataListButtonElement final : public HTMLDivElement {
     37    WTF_MAKE_ISO_ALLOCATED(DataListButtonElement);
     38public:
     39    class DataListButtonOwner {
     40    public:
     41        virtual ~DataListButtonOwner() = default;
     42        virtual void dataListButtonElementWasClicked() = 0;
     43    };
     44
     45    ~DataListButtonElement();
     46
     47    static Ref<DataListButtonElement> create(Document&, DataListButtonOwner&);
     48
     49private:
     50    explicit DataListButtonElement(Document&, DataListButtonOwner&);
     51
     52    void defaultEventHandler(Event&) override;
     53
     54    DataListButtonOwner& m_owner;
     55};
     56
     57} // namespace WebCore
     58
     59#endif // ENABLE(DATALIST_ELEMENT)
  • trunk/Source/WebCore/platform/ThemeTypes.h

    r217937 r234281  
    5252    ApplePayButtonPart,
    5353#endif
     54#if ENABLE(DATALIST_ELEMENT)
     55    ListButtonPart,
     56#endif
    5457    TextAreaPart,
    5558#if ENABLE(ATTACHMENT_ELEMENT)
  • trunk/Source/WebCore/rendering/RenderTheme.cpp

    r234222 r234281  
    266266    case BorderlessAttachmentPart:
    267267        return adjustAttachmentStyle(styleResolver, style, element);
     268#endif
     269#if ENABLE(DATALIST_ELEMENT)
     270    case ListButtonPart:
     271        return adjustListButtonStyle(styleResolver, style, element);
    268272#endif
    269273    default:
     
    9991003#if ENABLE(DATALIST_ELEMENT)
    10001004
     1005void RenderTheme::adjustListButtonStyle(StyleResolver&, RenderStyle&, const Element*) const
     1006{
     1007}
     1008
    10011009LayoutUnit RenderTheme::sliderTickSnappingThreshold() const
    10021010{
  • trunk/Source/WebCore/rendering/RenderTheme.h

    r233869 r234281  
    337337    virtual void adjustAttachmentStyle(StyleResolver&, RenderStyle&, const Element*) const;
    338338    virtual bool paintAttachment(const RenderObject&, const PaintInfo&, const IntRect&);
     339#endif
     340
     341#if ENABLE(DATALIST_ELEMENT)
     342    virtual void adjustListButtonStyle(StyleResolver&, RenderStyle&, const Element*) const;
    339343#endif
    340344
  • trunk/Source/WebCore/rendering/RenderThemeMac.h

    r233869 r234281  
    155155    bool paintSearchFieldResultsButton(const RenderBox&, const PaintInfo&, const IntRect&) final;
    156156
     157#if ENABLE(DATALIST_ELEMENT)
     158    void paintListButtonForInput(const RenderObject&, GraphicsContext&, const FloatRect&);
     159    void adjustListButtonStyle(StyleResolver&, RenderStyle&, const Element*) const;
     160#endif
     161
    157162#if ENABLE(VIDEO)
    158163    bool supportsClosedCaptioning() const final { return true; }
     
    219224    NSSliderCell *sliderThumbVertical() const;
    220225    NSTextFieldCell *textField() const;
     226#if ENABLE(DATALIST_ELEMENT)
     227    NSCell *listButton() const;
     228#endif
    221229
    222230#if ENABLE(METER_ELEMENT)
     
    247255    mutable RetainPtr<NSServicesRolloverButtonCell> m_servicesRolloverButton;
    248256#endif
     257#if ENABLE(DATALIST_ELEMENT)
     258    mutable RetainPtr<NSCell> m_listButton;
     259#endif
    249260
    250261    bool m_isSliderThumbHorizontalPressed { false };
  • trunk/Source/WebCore/rendering/RenderThemeMac.mm

    r233870 r234281  
    197197@implementation WebCoreRenderThemeBundle
    198198@end
     199
     200#if ENABLE(DATALIST_ELEMENT)
     201
     202static const CGFloat listButtonWidth = 16.0f;
     203static const CGFloat listButtonCornerRadius = 5.0f;
     204
     205@interface WebListButtonCell : NSCell
     206@end
     207
     208@implementation WebListButtonCell
     209- (void)drawWithFrame:(NSRect)cellFrame inView:(__unused NSView *)controlView
     210{
     211    CGFloat listButtonCornerRadius = 5.0f;
     212    NSPoint topLeft = NSMakePoint(NSMinX(cellFrame), NSMinY(cellFrame));
     213    NSPoint topRight = NSMakePoint(NSMaxX(cellFrame), NSMinY(cellFrame));
     214    NSPoint bottomRight = NSMakePoint(NSMaxX(cellFrame), NSMaxY(cellFrame));
     215    NSPoint bottomLeft = NSMakePoint(NSMinX(cellFrame), NSMaxY(cellFrame));
     216
     217    NSBezierPath *path = [NSBezierPath bezierPath];
     218    [path moveToPoint:topLeft];
     219
     220    [path lineToPoint:NSMakePoint(topRight.x - listButtonCornerRadius, topRight.y)];
     221    [path curveToPoint:NSMakePoint(topRight.x, topRight.y + listButtonCornerRadius) controlPoint1:topRight controlPoint2:topRight];
     222
     223    [path lineToPoint:NSMakePoint(bottomRight.x, bottomRight.y - listButtonCornerRadius)];
     224    [path curveToPoint:NSMakePoint(bottomRight.x - listButtonCornerRadius, bottomRight.y) controlPoint1:bottomRight controlPoint2:bottomRight];
     225
     226    [path lineToPoint:bottomLeft];
     227    [path lineToPoint:topLeft];
     228
     229    if ([self userInterfaceLayoutDirection] == NSUserInterfaceLayoutDirectionRightToLeft) {
     230        NSAffineTransform *transform = [NSAffineTransform transform];
     231        [transform translateXBy:NSMidX(cellFrame) yBy:NSMidY(cellFrame)];
     232        [transform rotateByDegrees:180];
     233        [transform translateXBy:-1 * NSMidX(cellFrame) yBy:-1 * NSMidY(cellFrame)];
     234        [path transformUsingAffineTransform:transform];
     235    }
     236
     237    // FIXME: Obtain the gradient colors from CoreUI or AppKit
     238    RetainPtr<NSGradient> gradient;
     239    NSUserAccentColor accentColor = NSColorGetUserAccentColor();
     240    if (accentColor == NSUserAccentColorRed)
     241        gradient = adoptNS([[NSGradient alloc] initWithStartingColor:[NSColor colorWithRed:(212.0 / 255) green:(122.0 / 255) blue:(117.0 / 255) alpha:1.0] endingColor:[NSColor colorWithRed:(189.0 / 255) green:(34.0 / 255) blue:(23.0 / 255) alpha:1.0]]);
     242    else if (accentColor == NSUserAccentColorOrange)
     243        gradient = adoptNS([[NSGradient alloc] initWithStartingColor:[NSColor colorWithRed:(242.0 / 255) green:(185.0 / 255) blue:(113.0 / 255) alpha:1.0] endingColor:[NSColor colorWithRed:(242.0 / 255) green:(145.0 / 255) blue:(17.0 / 255) alpha:1.0]]);
     244    else if (accentColor == NSUserAccentColorYellow)
     245        gradient = adoptNS([[NSGradient alloc] initWithStartingColor:[NSColor colorWithRed:(241.0 / 255) green:(212.0 / 255) blue:(119.0 / 255) alpha:1.0] endingColor:[NSColor colorWithRed:(239.0 / 255) green:(193.0 / 255) blue:(27.0 / 255) alpha:1.0]]);
     246    else if (accentColor == NSUserAccentColorGreen)
     247        gradient = adoptNS([[NSGradient alloc] initWithStartingColor:[NSColor colorWithRed:(132.0 / 255) green:(186.0 / 255) blue:(120.0 / 255) alpha:1.0] endingColor:[NSColor colorWithRed:(46.0 / 255) green:(145.0 / 255) blue:(30.0 / 255) alpha:1.0]]);
     248    else if (accentColor == NSUserAccentColorPurple)
     249        gradient = adoptNS([[NSGradient alloc] initWithStartingColor:[NSColor colorWithRed:(178.0 / 255) green:(128.0 / 255) blue:(175.0 / 255) alpha:1.0] endingColor:[NSColor colorWithRed:(130.0 / 255) green:(43.0 / 255) blue:(123.0 / 255) alpha:1.0]]);
     250    else if (accentColor == NSUserAccentColorPink)
     251        gradient = adoptNS([[NSGradient alloc] initWithStartingColor:[NSColor colorWithRed:(225.0 / 255) green:(126.0 / 255) blue:(165.0 / 255) alpha:1.0] endingColor:[NSColor colorWithRed:(211.0 / 255) green:(42.0 / 255) blue:(105.0 / 255) alpha:1.0]]);
     252    else if (accentColor == NSUserAccentColorNoColor)
     253        gradient = adoptNS([[NSGradient alloc] initWithStartingColor:[NSColor colorWithRed:(177.0 / 255) green:(177.0 / 255) blue:(182.0 / 255) alpha:1.0] endingColor:[NSColor colorWithRed:(145.0 / 255) green:(145.0 / 255) blue:(150.0 / 255) alpha:1.0]]);
     254    else
     255        gradient = adoptNS([[NSGradient alloc] initWithStartingColor:[NSColor colorWithRed:(114.0 / 255) green:(164.0 / 255) blue:(243.0 / 255) alpha:1.0] endingColor:[NSColor colorWithRed:(45.0 / 255) green:(117.0 / 255) blue:(246.0 / 255) alpha:1.0]]);
     256
     257    [gradient drawInBezierPath:path angle:90];
     258    if ([self isHighlighted]) {
     259        NSColor *overlay = [NSColor colorWithWhite:0 alpha:0.1];
     260        [overlay setFill];
     261        [path fill];
     262    }
     263}
     264@end
     265
     266#endif // ENABLE(DATALIST_ELEMENT)
    199267
    200268namespace WebCore {
     
    10061074}
    10071075
     1076#if ENABLE(DATALIST_ELEMENT)
     1077
     1078void RenderThemeMac::paintListButtonForInput(const RenderObject& o, GraphicsContext& context, const FloatRect& r)
     1079{
     1080    // We can't paint an NSComboBoxCell since they are not height-resizable.
     1081    const auto& input = downcast<HTMLInputElement>(*(o.generatingNode()));
     1082    NSCell *listButton = this->listButton();
     1083
     1084    NSRect listButtonFrame = NSMakeRect(r.maxX() - listButtonWidth, r.y(), listButtonWidth, r.height());
     1085    if (!o.style().isLeftToRightDirection()) {
     1086        listButtonFrame.origin.x = r.x();
     1087        [listButton setUserInterfaceLayoutDirection:NSUserInterfaceLayoutDirectionRightToLeft];
     1088    } else
     1089        [listButton setUserInterfaceLayoutDirection:NSUserInterfaceLayoutDirectionLeftToRight];
     1090
     1091    [listButton setHighlighted:input.isShowingList()];
     1092    if (!input.isShowingList())
     1093        updatePressedState(listButton, *(input.dataListButtonElement()->renderer()));
     1094
     1095    [listButton drawWithFrame:listButtonFrame inView:documentViewFor(o)];
     1096    [listButton setControlView:nil];
     1097
     1098    RefPtr<Image> image;
     1099    float imageScale = 1;
     1100    if (o.document().deviceScaleFactor() >= 2) {
     1101        image = Image::loadPlatformResource("ListButtonArrow@2x");
     1102        imageScale = 2;
     1103    } else
     1104        image = Image::loadPlatformResource("ListButtonArrow");
     1105
     1106    FloatRect imageRect(0, 0, image->width() / imageScale, image->height() / imageScale);
     1107    imageRect.setX(NSMidX(listButtonFrame) - imageRect.width() / 2);
     1108    imageRect.setY(NSMidY(listButtonFrame) - imageRect.height() / 2);
     1109
     1110    context.drawImage(*image, imageRect);
     1111}
     1112
     1113void RenderThemeMac::adjustListButtonStyle(StyleResolver&, RenderStyle& style, const Element*) const
     1114{
     1115    // Add a margin to place the button at end of the input field.
     1116    if (style.isLeftToRightDirection())
     1117        style.setMarginRight(Length(-4, Fixed));
     1118    else
     1119        style.setMarginLeft(Length(-4, Fixed));
     1120}
     1121
     1122#endif
     1123
    10081124bool RenderThemeMac::paintTextField(const RenderObject& o, const PaintInfo& paintInfo, const FloatRect& r)
    10091125{
     
    10311147
    10321148    [textField setControlView:nil];
     1149
     1150#if ENABLE(DATALIST_ELEMENT)
     1151    if (!is<HTMLInputElement>(o.generatingNode()))
     1152        return false;
     1153
     1154    const auto& input = downcast<HTMLInputElement>(*(o.generatingNode()));
     1155    if (input.list())
     1156        paintListButtonForInput(o, paintInfo.context(), adjustedPaintRect);
     1157#endif
    10331158
    10341159    return false;
     
    17891914    [search resetSearchButtonCell];
    17901915
     1916#if ENABLE(DATALIST_ELEMENT)
     1917    if (!is<HTMLInputElement>(o.generatingNode()))
     1918        return false;
     1919
     1920    const auto& input = downcast<HTMLInputElement>(*(o.generatingNode()));
     1921    if (input.list())
     1922        paintListButtonForInput(o, paintInfo.context(), FloatRect(unzoomedRect.x(), unzoomedRect.y() + 1, unzoomedRect.width(), unzoomedRect.height() - 2));
     1923#endif
     1924
    17911925    return false;
    17921926}
     
    18912025
    18922026    FloatRect localBounds = adjustedCancelButtonRect([search cancelButtonRectForBounds:NSRect(snappedIntRect(inputBox.contentBoxRect()))]);
     2027
    18932028    // Adjust position based on the content direction.
    18942029    float adjustedXPosition;
    1895     if (box.style().direction() == RTL)
    1896         adjustedXPosition = inputBox.contentBoxRect().x();
    1897     else
    1898         adjustedXPosition = inputBox.contentBoxRect().maxX() - localBounds.size().width();
    1899    
     2030
     2031    if (is<HTMLInputElement>(*input)) {
     2032        RenderBox* cancelButtonBox = downcast<RenderBox>(downcast<HTMLInputElement>(*input).cancelButtonElement()->renderer());
     2033        // The cancel button won't always be the rightmost element
     2034        adjustedXPosition = inputBox.contentBoxRect().x() + (cancelButtonBox->absoluteContentBox().x() - inputBox.absoluteContentBox().x());
     2035    } else {
     2036        if (box.style().direction() == RTL)
     2037            adjustedXPosition = inputBox.contentBoxRect().x();
     2038        else
     2039            adjustedXPosition = inputBox.contentBoxRect().maxX() - localBounds.size().width();
     2040    }
     2041
    19002042    localBounds.setX(adjustedXPosition);
    19012043    FloatPoint paintingPos = convertToPaintingPosition(inputBox, box, localBounds.location(), r.location());
     
    22282370}
    22292371
     2372#if ENABLE(DATALIST_ELEMENT)
     2373NSCell *RenderThemeMac::listButton() const
     2374{
     2375    if (!m_listButton)
     2376        m_listButton = adoptNS([[WebListButtonCell alloc] init]);
     2377
     2378    return m_listButton.get();
     2379}
     2380#endif
     2381
    22302382String RenderThemeMac::fileListNameForWidth(const FileList* fileList, const FontCascade& font, int width, bool multipleFilesAllowed) const
    22312383{
  • trunk/Source/WebInspectorUI/ChangeLog

    r234219 r234281  
     12018-07-26  Aditya Keerthi  <akeerthi@apple.com>
     2
     3        [Datalist] Add button to TextFieldInputs with a datalist
     4        https://bugs.webkit.org/show_bug.cgi?id=187741
     5
     6        Reviewed by Tim Horton.
     7
     8        Add keyword completion for 'list-button'.
     9
     10        * UserInterface/External/CodeMirror/css.js:
     11        * UserInterface/Models/CSSKeywordCompletions.js:
     12
    1132018-07-25  Nikita Vasilyev  <nvasilyev@apple.com>
    214
  • trunk/Source/WebInspectorUI/UserInterface/External/CodeMirror/css.js

    r217236 r234281  
    627627    "korean-hangul-formal", "korean-hanja-formal", "korean-hanja-informal",
    628628    "landscape", "lao", "large", "larger", "left", "level", "lighter", "lighten",
    629     "line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "listitem",
     629    "line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "list-button", "listitem",
    630630    "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
    631631    "lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
  • trunk/Source/WebInspectorUI/UserInterface/Models/CSSKeywordCompletions.js

    r223308 r234281  
    10411041    /*
    10421042    "-webkit-appearance": [
    1043         "none", "checkbox", "radio", "push-button", "square-button", "button", "button-bevel", "default-button", "inner-spin-button", "listbox", "listitem", "media-enter-fullscreen-button", "media-exit-fullscreen-button", "media-fullscreen-volume-slider", "media-fullscreen-volume-slider-thumb", "media-mute-button", "media-play-button", "media-overlay-play-button", "media-seek-back-button", "media-seek-forward-button", "media-rewind-button", "media-return-to-realtime-button", "media-toggle-closed-captions-button", "media-slider", "media-sliderthumb", "media-volume-slider-container", "media-volume-slider", "media-volume-sliderthumb", "media-volume-slider-mute-button", "media-controls-background", "media-controls-fullscreen-background", "media-current-time-display", "media-time-remaining-display", "menulist", "menulist-button", "menulist-text", "menulist-textfield", "meter", "progress-bar", "progress-bar-value", "slider-horizontal", "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "caret", "searchfield", "searchfield-decoration", "searchfield-results-decoration", "searchfield-results-button", "searchfield-cancel-button", "snapshotted-plugin-overlay", "textfield", "relevancy-level-indicator", "continuous-capacity-level-indicator", "discrete-capacity-level-indicator", "rating-level-indicator", "textarea", "attachment", "caps-lock-indicator"
     1043        "none", "checkbox", "radio", "push-button", "square-button", "button", "button-bevel", "default-button", "inner-spin-button", "listbox", "listitem", "media-enter-fullscreen-button", "media-exit-fullscreen-button", "media-fullscreen-volume-slider", "media-fullscreen-volume-slider-thumb", "media-mute-button", "media-play-button", "media-overlay-play-button", "media-seek-back-button", "media-seek-forward-button", "media-rewind-button", "media-return-to-realtime-button", "media-toggle-closed-captions-button", "media-slider", "media-sliderthumb", "media-volume-slider-container", "media-volume-slider", "media-volume-sliderthumb", "media-volume-slider-mute-button", "media-controls-background", "media-controls-fullscreen-background", "media-current-time-display", "media-time-remaining-display", "menulist", "menulist-button", "menulist-text", "menulist-textfield", "meter", "progress-bar", "progress-bar-value", "slider-horizontal", "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "caret", "searchfield", "searchfield-decoration", "searchfield-results-decoration", "searchfield-results-button", "searchfield-cancel-button", "snapshotted-plugin-overlay", "textfield", "relevancy-level-indicator", "continuous-capacity-level-indicator", "discrete-capacity-level-indicator", "rating-level-indicator", "textarea", "attachment", "caps-lock-indicator", "list-button"
    10441044    ],
    10451045    */
Note: See TracChangeset for help on using the changeset viewer.