Changeset 270875 in webkit


Ignore:
Timestamp:
Dec 15, 2020 5:05:20 PM (19 months ago)
Author:
Aditya Keerthi
Message:

[macOS] Adjust date input placeholder color based on specified text color
https://bugs.webkit.org/show_bug.cgi?id=219875
<rdar://problem/72314705>

Reviewed by Darin Adler.

Source/WebCore:

Empty date inputs currently show the current date in dark gray text as
a placeholder.

The existing behavior results in an issue on Nike's membership registration
page, where their custom placeholder and the placeholder date are visible
at the same time. Nike uses "color: transparent" to hide the contents of
the date input and display their own placeholder. However, since the
placeholder date is always displayed in dark gray text, both placeholders
are visible.

To fix, the color of the placeholder should be adjusted based on the text
color specified by the site author. This will ensure that
"color: transparent" will hide the placeholder, and also ensures the
placeholder better matches the style of the rest of the input.

Test: fast/forms/date/date-editable-components/date-editable-components-placeholder-color.html

  • html/shadow/DateTimeFieldElement.cpp:

(WebCore::DateTimeFieldElement::resolveCustomStyle):

Moved custom style resolution out of the derived classes and into the
base class to reduce code duplication. The min-width adjustment is
preserved by calling the pure virtual method adjustMinWidth. The
new color resolution for placeholder dates is performed by obtaining
the text and background colors through the shadow host (the
HTMLInputElement) and calling into RenderTheme for the adjustment
algorithm.

  • html/shadow/DateTimeFieldElement.h:

Made setEmptyValue and setValueAsInteger pure virtual methods since
the base implementation is now empty.

Introduced adjustMinWidth as a pure virtual method to allow numeric
and symbolic field elements to set their minimum width. This replaces
the need to have the derived classes implement resolveCustomStyle.

  • html/shadow/DateTimeNumericFieldElement.cpp:

(WebCore::DateTimeNumericFieldElement::adjustMinWidth const):
(WebCore::DateTimeNumericFieldElement::setEmptyValue):
(WebCore::DateTimeNumericFieldElement::setValueAsInteger):

  • html/shadow/DateTimeNumericFieldElement.h:
  • html/shadow/DateTimeSymbolicFieldElement.cpp:

(WebCore::DateTimeSymbolicFieldElement::adjustMinWidth const):
(WebCore::DateTimeSymbolicFieldElement::setEmptyValue):
(WebCore::DateTimeSymbolicFieldElement::setValueAsInteger):

  • html/shadow/DateTimeSymbolicFieldElement.h:
  • rendering/RenderTheme.cpp:

(WebCore::RenderTheme::datePlaceholderTextColor const):

Adjust the placeholder text color based on the text and background color
specified. The adjustment is performed by changing the lightness of the
specified text color. The lightness is increased for dark text on a light
background, and is decreased for light text on a dark background. The
chosen adjustment factor ensures that a dark gray color is obtained for
both white on black, and black on white.

  • rendering/RenderTheme.h:

LayoutTests:

Added a test to verify that the color of the placeholder changes based
on the input's color property.

  • fast/forms/date/date-editable-components/date-editable-components-placeholder-color-expected.html: Added.
  • fast/forms/date/date-editable-components/date-editable-components-placeholder-color.html: Added.
Location:
trunk
Files:
2 added
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r270874 r270875  
     12020-12-15  Aditya Keerthi  <akeerthi@apple.com>
     2
     3        [macOS] Adjust date input placeholder color based on specified text color
     4        https://bugs.webkit.org/show_bug.cgi?id=219875
     5        <rdar://problem/72314705>
     6
     7        Reviewed by Darin Adler.
     8
     9        Added a test to verify that the color of the placeholder changes based
     10        on the input's color property.
     11
     12        * fast/forms/date/date-editable-components/date-editable-components-placeholder-color-expected.html: Added.
     13        * fast/forms/date/date-editable-components/date-editable-components-placeholder-color.html: Added.
     14
    1152020-12-15  Alexey Shvayka  <shvaikalesh@gmail.com>
    216
  • trunk/Source/WebCore/ChangeLog

    r270874 r270875  
     12020-12-15  Aditya Keerthi  <akeerthi@apple.com>
     2
     3        [macOS] Adjust date input placeholder color based on specified text color
     4        https://bugs.webkit.org/show_bug.cgi?id=219875
     5        <rdar://problem/72314705>
     6
     7        Reviewed by Darin Adler.
     8
     9        Empty date inputs currently show the current date in dark gray text as
     10        a placeholder.
     11
     12        The existing behavior results in an issue on Nike's membership registration
     13        page, where their custom placeholder and the placeholder date are visible
     14        at the same time. Nike uses "color: transparent" to hide the contents of
     15        the date input and display their own placeholder. However, since the
     16        placeholder date is always displayed in dark gray text, both placeholders
     17        are visible.
     18
     19        To fix, the color of the placeholder should be adjusted based on the text
     20        color specified by the site author. This will ensure that
     21        "color: transparent" will hide the placeholder, and also ensures the
     22        placeholder better matches the style of the rest of the input.
     23
     24        Test: fast/forms/date/date-editable-components/date-editable-components-placeholder-color.html
     25
     26        * html/shadow/DateTimeFieldElement.cpp:
     27        (WebCore::DateTimeFieldElement::resolveCustomStyle):
     28
     29        Moved custom style resolution out of the derived classes and into the
     30        base class to reduce code duplication. The min-width adjustment is
     31        preserved by calling the pure virtual method adjustMinWidth. The
     32        new color resolution for placeholder dates is performed by obtaining
     33        the text and background colors through the shadow host (the
     34        HTMLInputElement) and calling into RenderTheme for the adjustment
     35        algorithm.
     36
     37        * html/shadow/DateTimeFieldElement.h:
     38
     39        Made setEmptyValue and setValueAsInteger pure virtual methods since
     40        the base implementation is now empty.
     41
     42        Introduced adjustMinWidth as a pure virtual method to allow numeric
     43        and symbolic field elements to set their minimum width. This replaces
     44        the need to have the derived classes implement resolveCustomStyle.
     45
     46        * html/shadow/DateTimeNumericFieldElement.cpp:
     47        (WebCore::DateTimeNumericFieldElement::adjustMinWidth const):
     48        (WebCore::DateTimeNumericFieldElement::setEmptyValue):
     49        (WebCore::DateTimeNumericFieldElement::setValueAsInteger):
     50        * html/shadow/DateTimeNumericFieldElement.h:
     51        * html/shadow/DateTimeSymbolicFieldElement.cpp:
     52        (WebCore::DateTimeSymbolicFieldElement::adjustMinWidth const):
     53        (WebCore::DateTimeSymbolicFieldElement::setEmptyValue):
     54        (WebCore::DateTimeSymbolicFieldElement::setValueAsInteger):
     55        * html/shadow/DateTimeSymbolicFieldElement.h:
     56        * rendering/RenderTheme.cpp:
     57        (WebCore::RenderTheme::datePlaceholderTextColor const):
     58
     59        Adjust the placeholder text color based on the text and background color
     60        specified. The adjustment is performed by changing the lightness of the
     61        specified text color. The lightness is increased for dark text on a light
     62        background, and is decreased for light text on a dark background. The
     63        chosen adjustment factor ensures that a dark gray color is obtained for
     64        both white on black, and black on white.
     65
     66        * rendering/RenderTheme.h:
     67
    1682020-12-15  Alexey Shvayka  <shvaikalesh@gmail.com>
    269
  • trunk/Source/WebCore/html/shadow/DateTimeFieldElement.cpp

    r270245 r270875  
    3131
    3232#include "CSSPropertyNames.h"
    33 #include "CSSValueKeywords.h"
    3433#include "DateComponents.h"
    3534#include "EventNames.h"
     
    3837#include "LocalizedStrings.h"
    3938#include "PlatformLocale.h"
     39#include "RenderStyle.h"
     40#include "RenderTheme.h"
     41#include "StyleResolver.h"
    4042#include "Text.h"
    4143#include <wtf/IsoMallocInlines.h>
     
    6062{
    6163    setPseudo(pseudo);
     64}
     65
     66Optional<Style::ElementStyle> DateTimeFieldElement::resolveCustomStyle(const RenderStyle& parentStyle, const RenderStyle* shadowHostStyle)
     67{
     68    auto elementStyle = resolveStyle(&parentStyle);
     69    if (!elementStyle.renderStyle)
     70        return WTF::nullopt;
     71
     72    auto& style = *elementStyle.renderStyle;
     73    adjustMinWidth(style);
     74
     75    if (!hasValue() && shadowHostStyle) {
     76        auto textColor = shadowHostStyle->visitedDependentColorWithColorFilter(CSSPropertyColor);
     77        auto backgroundColor = shadowHostStyle->visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor);
     78        style.setColor(RenderTheme::singleton().datePlaceholderTextColor(textColor, backgroundColor));
     79    }
     80
     81    return elementStyle;
    6282}
    6383
     
    161181}
    162182
    163 void DateTimeFieldElement::setEmptyValue(EventBehavior)
    164 {
    165     setInlineStyleProperty(CSSPropertyColor, CSSValueDarkgray);
    166 }
    167 
    168 void DateTimeFieldElement::setValueAsInteger(int, EventBehavior)
    169 {
    170     if (!hasValue())
    171         removeInlineStyleProperty(CSSPropertyColor);
    172 }
    173 
    174183String DateTimeFieldElement::visibleValue() const
    175184{
  • trunk/Source/WebCore/html/shadow/DateTimeFieldElement.h

    r270245 r270875  
    3737
    3838class DateComponents;
     39class RenderStyle;
     40
    3941struct DateTimeFieldsState;
    4042
     
    6264    String visibleValue() const;
    6365
    64     virtual void setEmptyValue(EventBehavior = DispatchNoEvent);
    65     virtual void setValueAsInteger(int, EventBehavior = DispatchNoEvent);
    66 
    6766    virtual bool hasValue() const = 0;
    6867    virtual void populateDateTimeFieldsState(DateTimeFieldsState&) = 0;
     68    virtual void setEmptyValue(EventBehavior = DispatchNoEvent) = 0;
    6969    virtual void setValueAsDate(const DateComponents&) = 0;
     70    virtual void setValueAsInteger(int, EventBehavior = DispatchNoEvent) = 0;
    7071    virtual void stepDown() = 0;
    7172    virtual void stepUp() = 0;
     
    7980    AtomString localeIdentifier() const;
    8081    void updateVisibleValue(EventBehavior);
     82    virtual void adjustMinWidth(RenderStyle&) const = 0;
    8183    virtual int valueAsInteger() const = 0;
    8284    virtual void handleKeyboardEvent(KeyboardEvent&) = 0;
     
    8486
    8587private:
     88    Optional<Style::ElementStyle> resolveCustomStyle(const RenderStyle&, const RenderStyle*) final;
     89
    8690    bool supportsFocus() const override;
    8791
  • trunk/Source/WebCore/html/shadow/DateTimeNumericFieldElement.cpp

    r270245 r270875  
    3636#include "RenderBlock.h"
    3737#include "RenderStyle.h"
    38 #include "StyleResolver.h"
    3938#include <wtf/IsoMallocInlines.h>
    4039
     
    6261}
    6362
    64 Optional<Style::ElementStyle> DateTimeNumericFieldElement::resolveCustomStyle(const RenderStyle& parentStyle, const RenderStyle*)
     63void DateTimeNumericFieldElement::adjustMinWidth(RenderStyle& style) const
    6564{
    66     auto elementStyle = resolveStyle(&parentStyle);
    67     if (!elementStyle.renderStyle)
    68         return WTF::nullopt;
    69 
    70     auto& font = elementStyle.renderStyle->fontCascade();
     65    auto& font = style.fontCascade();
    7166
    7267    unsigned length = 2;
     
    8176    for (char c = '0'; c <= '9'; ++c) {
    8277        auto numberString = locale.convertToLocalizedNumber(makeString(pad(c, length, makeString(c))));
    83         width = std::max(width, font.width(RenderBlock::constructTextRun(numberString, *elementStyle.renderStyle)));
     78        width = std::max(width, font.width(RenderBlock::constructTextRun(numberString, style)));
    8479    }
    8580
    86     elementStyle.renderStyle->setMinWidth({ width, Fixed });
    87     return elementStyle;
     81    style.setMinWidth({ width, Fixed });
    8882}
    8983
     
    116110void DateTimeNumericFieldElement::setEmptyValue(EventBehavior eventBehavior)
    117111{
    118     DateTimeFieldElement::setEmptyValue(eventBehavior);
    119 
    120112    m_value = 0;
    121113    m_hasValue = false;
     
    126118void DateTimeNumericFieldElement::setValueAsInteger(int value, EventBehavior eventBehavior)
    127119{
    128     DateTimeFieldElement::setValueAsInteger(value, eventBehavior);
    129 
    130120    m_value = m_range.clampValue(value);
    131121    m_hasValue = true;
  • trunk/Source/WebCore/html/shadow/DateTimeNumericFieldElement.h

    r270245 r270875  
    6363
    6464private:
    65     Optional<Style::ElementStyle> resolveCustomStyle(const RenderStyle&, const RenderStyle*) final;
    66 
    6765    // DateTimeFieldElement functions:
     66    void adjustMinWidth(RenderStyle&) const final;
    6867    String value() const final;
    6968    String placeholderValue() const final;
  • trunk/Source/WebCore/html/shadow/DateTimeSymbolicFieldElement.cpp

    r270245 r270875  
    3333#include "RenderBlock.h"
    3434#include "RenderStyle.h"
    35 #include "StyleResolver.h"
    3635#include <wtf/IsoMallocInlines.h>
    3736#include <wtf/text/StringBuilder.h>
     
    5150}
    5251
    53 Optional<Style::ElementStyle> DateTimeSymbolicFieldElement::resolveCustomStyle(const RenderStyle& parentStyle, const RenderStyle*)
     52void DateTimeSymbolicFieldElement::adjustMinWidth(RenderStyle& style) const
    5453{
    55     auto elementStyle = resolveStyle(&parentStyle);
    56     if (!elementStyle.renderStyle)
    57         return WTF::nullopt;
    58 
    59     auto& font = elementStyle.renderStyle->fontCascade();
     54    auto& font = style.fontCascade();
    6055
    6156    float width = 0;
    6257    for (auto& symbol : m_symbols)
    63         width = std::max(width, font.width(RenderBlock::constructTextRun(symbol, *elementStyle.renderStyle)));
     58        width = std::max(width, font.width(RenderBlock::constructTextRun(symbol, style)));
    6459
    65     elementStyle.renderStyle->setMinWidth({ width, Fixed });
    66     return elementStyle;
     60    style.setMinWidth({ width, Fixed });
    6761}
    6862
     
    7973void DateTimeSymbolicFieldElement::setEmptyValue(EventBehavior eventBehavior)
    8074{
    81     DateTimeFieldElement::setEmptyValue(eventBehavior);
    82 
    8375    m_selectedIndex = invalidIndex;
    8476    updateVisibleValue(eventBehavior);
     
    8779void DateTimeSymbolicFieldElement::setValueAsInteger(int newSelectedIndex, EventBehavior eventBehavior)
    8880{
    89     DateTimeFieldElement::setValueAsInteger(newSelectedIndex, eventBehavior);
    90 
    9181    m_selectedIndex = std::max(0, std::min(newSelectedIndex, static_cast<int>(m_symbols.size() - 1)));
    9282    updateVisibleValue(eventBehavior);
  • trunk/Source/WebCore/html/shadow/DateTimeSymbolicFieldElement.h

    r270245 r270875  
    4848    static constexpr int invalidIndex = -1;
    4949
    50     Optional<Style::ElementStyle> resolveCustomStyle(const RenderStyle&, const RenderStyle*) final;
    51 
    5250    // DateTimeFieldElement functions:
     51    void adjustMinWidth(RenderStyle&) const final;
    5352    void stepDown() final;
    5453    void stepUp() final;
  • trunk/Source/WebCore/rendering/RenderTheme.cpp

    r270678 r270875  
    14291429}
    14301430
     1431// Value chosen to return dark gray for both white on black and black on white.
     1432constexpr float datePlaceholderColorLightnessAdjustmentFactor = 0.66f;
     1433
     1434Color RenderTheme::datePlaceholderTextColor(const Color& textColor, const Color& backgroundColor) const
     1435{
     1436    auto hsla = toHSLA(textColor.toSRGBALossy<float>());
     1437    if (textColor.luminance() < backgroundColor.luminance())
     1438        hsla.lightness += datePlaceholderColorLightnessAdjustmentFactor * (1.0f - hsla.lightness);
     1439    else
     1440        hsla.lightness *= datePlaceholderColorLightnessAdjustmentFactor;
     1441
     1442    return toSRGBA(hsla);
     1443}
     1444
    14311445void RenderTheme::setCustomFocusRingColor(const Color& color)
    14321446{
  • trunk/Source/WebCore/rendering/RenderTheme.h

    r270713 r270875  
    164164    // Default highlighting color for app highlights.
    165165    Color appHighlightColor(OptionSet<StyleColor::Options>) const;
     166
     167    Color datePlaceholderTextColor(const Color& textColor, const Color& backgroundColor) const;
    166168
    167169    virtual Color disabledTextColor(const Color& textColor, const Color& backgroundColor) const;
Note: See TracChangeset for help on using the changeset viewer.