Diff
Modified: trunk/LayoutTests/ChangeLog (270874 => 270875)
--- trunk/LayoutTests/ChangeLog 2020-12-16 00:33:34 UTC (rev 270874)
+++ trunk/LayoutTests/ChangeLog 2020-12-16 01:05:20 UTC (rev 270875)
@@ -1,3 +1,17 @@
+2020-12-15 Aditya Keerthi <[email protected]>
+
+ [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.
+
+ 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.
+
2020-12-15 Alexey Shvayka <[email protected]>
Non-enumerable property fails to shadow inherited enumerable property from for-in
Added: trunk/LayoutTests/fast/forms/date/date-editable-components/date-editable-components-placeholder-color-expected.html (0 => 270875)
--- trunk/LayoutTests/fast/forms/date/date-editable-components/date-editable-components-placeholder-color-expected.html (rev 0)
+++ trunk/LayoutTests/fast/forms/date/date-editable-components/date-editable-components-placeholder-color-expected.html 2020-12-16 01:05:20 UTC (rev 270875)
@@ -0,0 +1,95 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+
+#black-on-white input {
+ background-color: white;
+ color: black;
+}
+
+#black-on-white input::-webkit-datetime-edit-day-field,
+#black-on-white input::-webkit-datetime-edit-month-field,
+#black-on-white input::-webkit-datetime-edit-year-field {
+ color: rgb(168, 168, 168);
+}
+
+#white-on-black input {
+ background-color: black;
+ color: white;
+}
+
+#white-on-black input::-webkit-datetime-edit-day-field,
+#white-on-black input::-webkit-datetime-edit-month-field,
+#white-on-black input::-webkit-datetime-edit-year-field {
+ color: rgb(168, 168, 168);
+}
+
+#red-on-white input {
+ background-color: white;
+ color: red;
+}
+
+#red-on-white input::-webkit-datetime-edit-day-field,
+#red-on-white input::-webkit-datetime-edit-month-field,
+#red-on-white input::-webkit-datetime-edit-year-field {
+ color: rgb(255, 168, 168);
+}
+
+#blue-on-orange input {
+ background-color: orange;
+ color: blue;
+}
+
+#blue-on-orange input::-webkit-datetime-edit-day-field,
+#blue-on-orange input::-webkit-datetime-edit-month-field,
+#blue-on-orange input::-webkit-datetime-edit-year-field {
+ color: rgb(168, 168, 255);
+}
+
+#transparent input {
+ color: transparent;
+}
+
+</style>
+</head>
+<body>
+ <div id="black-on-white">
+ <input type="date">
+ </div>
+ <div id="white-on-black">
+ <input type="date">
+ </div>
+ <div id="red-on-white">
+ <input type="date">
+ </div>
+ <div id="blue-on-orange">
+ <input type="date">
+ </div>
+ <div id="transparent">
+ <input type="date">
+ </div>
+</body>
+<script>
+
+function pad(number) {
+ if (number < 10) {
+ return '0' + number;
+ }
+ return number;
+}
+
+let now = new Date();
+let currentHTMLDateString = now.getFullYear() +
+ "-" +
+ pad(now.getMonth() + 1) +
+ "-" +
+ pad(now.getDate());
+
+let inputs = document.getElementsByTagName("input");
+Array.from(inputs).forEach(element => {
+ element.value = currentHTMLDateString;
+});
+
+</script>
+</html>
Added: trunk/LayoutTests/fast/forms/date/date-editable-components/date-editable-components-placeholder-color.html (0 => 270875)
--- trunk/LayoutTests/fast/forms/date/date-editable-components/date-editable-components-placeholder-color.html (rev 0)
+++ trunk/LayoutTests/fast/forms/date/date-editable-components/date-editable-components-placeholder-color.html 2020-12-16 01:05:20 UTC (rev 270875)
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+
+#black-on-white input {
+ background-color: white;
+ color: black;
+}
+
+#white-on-black input {
+ background-color: black;
+ color: white;
+}
+
+#red-on-white input {
+ background-color: white;
+ color: red;
+}
+
+#blue-on-orange input {
+ background-color: orange;
+ color: blue;
+}
+
+#transparent input {
+ color: transparent;
+}
+
+</style>
+</head>
+<body>
+ <div id="black-on-white">
+ <input type="date">
+ </div>
+ <div id="white-on-black">
+ <input type="date">
+ </div>
+ <div id="red-on-white">
+ <input type="date">
+ </div>
+ <div id="blue-on-orange">
+ <input type="date">
+ </div>
+ <div id="transparent">
+ <input type="date">
+ </div>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (270874 => 270875)
--- trunk/Source/WebCore/ChangeLog 2020-12-16 00:33:34 UTC (rev 270874)
+++ trunk/Source/WebCore/ChangeLog 2020-12-16 01:05:20 UTC (rev 270875)
@@ -1,3 +1,70 @@
+2020-12-15 Aditya Keerthi <[email protected]>
+
+ [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.
+
+ 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:
+
2020-12-15 Alexey Shvayka <[email protected]>
Non-enumerable property fails to shadow inherited enumerable property from for-in
Modified: trunk/Source/WebCore/html/shadow/DateTimeFieldElement.cpp (270874 => 270875)
--- trunk/Source/WebCore/html/shadow/DateTimeFieldElement.cpp 2020-12-16 00:33:34 UTC (rev 270874)
+++ trunk/Source/WebCore/html/shadow/DateTimeFieldElement.cpp 2020-12-16 01:05:20 UTC (rev 270875)
@@ -30,7 +30,6 @@
#if ENABLE(DATE_AND_TIME_INPUT_TYPES)
#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
#include "DateComponents.h"
#include "EventNames.h"
#include "HTMLNames.h"
@@ -37,6 +36,9 @@
#include "KeyboardEvent.h"
#include "LocalizedStrings.h"
#include "PlatformLocale.h"
+#include "RenderStyle.h"
+#include "RenderTheme.h"
+#include "StyleResolver.h"
#include "Text.h"
#include <wtf/IsoMallocInlines.h>
#include <wtf/text/WTFString.h>
@@ -61,6 +63,24 @@
setPseudo(pseudo);
}
+Optional<Style::ElementStyle> DateTimeFieldElement::resolveCustomStyle(const RenderStyle& parentStyle, const RenderStyle* shadowHostStyle)
+{
+ auto elementStyle = resolveStyle(&parentStyle);
+ if (!elementStyle.renderStyle)
+ return WTF::nullopt;
+
+ auto& style = *elementStyle.renderStyle;
+ adjustMinWidth(style);
+
+ if (!hasValue() && shadowHostStyle) {
+ auto textColor = shadowHostStyle->visitedDependentColorWithColorFilter(CSSPropertyColor);
+ auto backgroundColor = shadowHostStyle->visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor);
+ style.setColor(RenderTheme::singleton().datePlaceholderTextColor(textColor, backgroundColor));
+ }
+
+ return elementStyle;
+}
+
void DateTimeFieldElement::defaultEventHandler(Event& event)
{
if (event.type() == eventNames().blurEvent)
@@ -160,17 +180,6 @@
return m_fieldOwner ? m_fieldOwner->localeIdentifier() : nullAtom();
}
-void DateTimeFieldElement::setEmptyValue(EventBehavior)
-{
- setInlineStyleProperty(CSSPropertyColor, CSSValueDarkgray);
-}
-
-void DateTimeFieldElement::setValueAsInteger(int, EventBehavior)
-{
- if (!hasValue())
- removeInlineStyleProperty(CSSPropertyColor);
-}
-
String DateTimeFieldElement::visibleValue() const
{
return hasValue() ? value() : placeholderValue();
Modified: trunk/Source/WebCore/html/shadow/DateTimeFieldElement.h (270874 => 270875)
--- trunk/Source/WebCore/html/shadow/DateTimeFieldElement.h 2020-12-16 00:33:34 UTC (rev 270874)
+++ trunk/Source/WebCore/html/shadow/DateTimeFieldElement.h 2020-12-16 01:05:20 UTC (rev 270875)
@@ -36,6 +36,8 @@
namespace WebCore {
class DateComponents;
+class RenderStyle;
+
struct DateTimeFieldsState;
class DateTimeFieldElement : public HTMLDivElement {
@@ -61,12 +63,11 @@
String visibleValue() const;
- virtual void setEmptyValue(EventBehavior = DispatchNoEvent);
- virtual void setValueAsInteger(int, EventBehavior = DispatchNoEvent);
-
virtual bool hasValue() const = 0;
virtual void populateDateTimeFieldsState(DateTimeFieldsState&) = 0;
+ virtual void setEmptyValue(EventBehavior = DispatchNoEvent) = 0;
virtual void setValueAsDate(const DateComponents&) = 0;
+ virtual void setValueAsInteger(int, EventBehavior = DispatchNoEvent) = 0;
virtual void stepDown() = 0;
virtual void stepUp() = 0;
virtual String value() const = 0;
@@ -78,11 +79,14 @@
Locale& localeForOwner() const;
AtomString localeIdentifier() const;
void updateVisibleValue(EventBehavior);
+ virtual void adjustMinWidth(RenderStyle&) const = 0;
virtual int valueAsInteger() const = 0;
virtual void handleKeyboardEvent(KeyboardEvent&) = 0;
virtual void handleBlurEvent(Event&);
private:
+ Optional<Style::ElementStyle> resolveCustomStyle(const RenderStyle&, const RenderStyle*) final;
+
bool supportsFocus() const override;
void defaultKeyboardEventHandler(KeyboardEvent&);
Modified: trunk/Source/WebCore/html/shadow/DateTimeNumericFieldElement.cpp (270874 => 270875)
--- trunk/Source/WebCore/html/shadow/DateTimeNumericFieldElement.cpp 2020-12-16 00:33:34 UTC (rev 270874)
+++ trunk/Source/WebCore/html/shadow/DateTimeNumericFieldElement.cpp 2020-12-16 01:05:20 UTC (rev 270875)
@@ -35,7 +35,6 @@
#include "PlatformLocale.h"
#include "RenderBlock.h"
#include "RenderStyle.h"
-#include "StyleResolver.h"
#include <wtf/IsoMallocInlines.h>
namespace WebCore {
@@ -61,14 +60,10 @@
{
}
-Optional<Style::ElementStyle> DateTimeNumericFieldElement::resolveCustomStyle(const RenderStyle& parentStyle, const RenderStyle*)
+void DateTimeNumericFieldElement::adjustMinWidth(RenderStyle& style) const
{
- auto elementStyle = resolveStyle(&parentStyle);
- if (!elementStyle.renderStyle)
- return WTF::nullopt;
+ auto& font = style.fontCascade();
- auto& font = elementStyle.renderStyle->fontCascade();
-
unsigned length = 2;
if (m_range.maximum > 999)
length = 4;
@@ -80,11 +75,10 @@
float width = 0;
for (char c = '0'; c <= '9'; ++c) {
auto numberString = locale.convertToLocalizedNumber(makeString(pad(c, length, makeString(c))));
- width = std::max(width, font.width(RenderBlock::constructTextRun(numberString, *elementStyle.renderStyle)));
+ width = std::max(width, font.width(RenderBlock::constructTextRun(numberString, style)));
}
- elementStyle.renderStyle->setMinWidth({ width, Fixed });
- return elementStyle;
+ style.setMinWidth({ width, Fixed });
}
int DateTimeNumericFieldElement::maximum() const
@@ -115,8 +109,6 @@
void DateTimeNumericFieldElement::setEmptyValue(EventBehavior eventBehavior)
{
- DateTimeFieldElement::setEmptyValue(eventBehavior);
-
m_value = 0;
m_hasValue = false;
m_typeAheadBuffer.clear();
@@ -125,8 +117,6 @@
void DateTimeNumericFieldElement::setValueAsInteger(int value, EventBehavior eventBehavior)
{
- DateTimeFieldElement::setValueAsInteger(value, eventBehavior);
-
m_value = m_range.clampValue(value);
m_hasValue = true;
updateVisibleValue(eventBehavior);
Modified: trunk/Source/WebCore/html/shadow/DateTimeNumericFieldElement.h (270874 => 270875)
--- trunk/Source/WebCore/html/shadow/DateTimeNumericFieldElement.h 2020-12-16 00:33:34 UTC (rev 270874)
+++ trunk/Source/WebCore/html/shadow/DateTimeNumericFieldElement.h 2020-12-16 01:05:20 UTC (rev 270875)
@@ -62,9 +62,8 @@
int valueAsInteger() const final;
private:
- Optional<Style::ElementStyle> resolveCustomStyle(const RenderStyle&, const RenderStyle*) final;
-
// DateTimeFieldElement functions:
+ void adjustMinWidth(RenderStyle&) const final;
String value() const final;
String placeholderValue() const final;
void handleKeyboardEvent(KeyboardEvent&) final;
Modified: trunk/Source/WebCore/html/shadow/DateTimeSymbolicFieldElement.cpp (270874 => 270875)
--- trunk/Source/WebCore/html/shadow/DateTimeSymbolicFieldElement.cpp 2020-12-16 00:33:34 UTC (rev 270874)
+++ trunk/Source/WebCore/html/shadow/DateTimeSymbolicFieldElement.cpp 2020-12-16 01:05:20 UTC (rev 270875)
@@ -32,7 +32,6 @@
#include "FontCascade.h"
#include "RenderBlock.h"
#include "RenderStyle.h"
-#include "StyleResolver.h"
#include <wtf/IsoMallocInlines.h>
#include <wtf/text/StringBuilder.h>
#include <wtf/text/TextBreakIterator.h>
@@ -50,20 +49,15 @@
ASSERT(!m_symbols.isEmpty());
}
-Optional<Style::ElementStyle> DateTimeSymbolicFieldElement::resolveCustomStyle(const RenderStyle& parentStyle, const RenderStyle*)
+void DateTimeSymbolicFieldElement::adjustMinWidth(RenderStyle& style) const
{
- auto elementStyle = resolveStyle(&parentStyle);
- if (!elementStyle.renderStyle)
- return WTF::nullopt;
+ auto& font = style.fontCascade();
- auto& font = elementStyle.renderStyle->fontCascade();
-
float width = 0;
for (auto& symbol : m_symbols)
- width = std::max(width, font.width(RenderBlock::constructTextRun(symbol, *elementStyle.renderStyle)));
+ width = std::max(width, font.width(RenderBlock::constructTextRun(symbol, style)));
- elementStyle.renderStyle->setMinWidth({ width, Fixed });
- return elementStyle;
+ style.setMinWidth({ width, Fixed });
}
bool DateTimeSymbolicFieldElement::hasValue() const
@@ -78,8 +72,6 @@
void DateTimeSymbolicFieldElement::setEmptyValue(EventBehavior eventBehavior)
{
- DateTimeFieldElement::setEmptyValue(eventBehavior);
-
m_selectedIndex = invalidIndex;
updateVisibleValue(eventBehavior);
}
@@ -86,8 +78,6 @@
void DateTimeSymbolicFieldElement::setValueAsInteger(int newSelectedIndex, EventBehavior eventBehavior)
{
- DateTimeFieldElement::setValueAsInteger(newSelectedIndex, eventBehavior);
-
m_selectedIndex = std::max(0, std::min(newSelectedIndex, static_cast<int>(m_symbols.size() - 1)));
updateVisibleValue(eventBehavior);
}
Modified: trunk/Source/WebCore/html/shadow/DateTimeSymbolicFieldElement.h (270874 => 270875)
--- trunk/Source/WebCore/html/shadow/DateTimeSymbolicFieldElement.h 2020-12-16 00:33:34 UTC (rev 270874)
+++ trunk/Source/WebCore/html/shadow/DateTimeSymbolicFieldElement.h 2020-12-16 01:05:20 UTC (rev 270875)
@@ -47,9 +47,8 @@
private:
static constexpr int invalidIndex = -1;
- Optional<Style::ElementStyle> resolveCustomStyle(const RenderStyle&, const RenderStyle*) final;
-
// DateTimeFieldElement functions:
+ void adjustMinWidth(RenderStyle&) const final;
void stepDown() final;
void stepUp() final;
String value() const final;
Modified: trunk/Source/WebCore/rendering/RenderTheme.cpp (270874 => 270875)
--- trunk/Source/WebCore/rendering/RenderTheme.cpp 2020-12-16 00:33:34 UTC (rev 270874)
+++ trunk/Source/WebCore/rendering/RenderTheme.cpp 2020-12-16 01:05:20 UTC (rev 270875)
@@ -1428,6 +1428,20 @@
return disabledColor;
}
+// Value chosen to return dark gray for both white on black and black on white.
+constexpr float datePlaceholderColorLightnessAdjustmentFactor = 0.66f;
+
+Color RenderTheme::datePlaceholderTextColor(const Color& textColor, const Color& backgroundColor) const
+{
+ auto hsla = toHSLA(textColor.toSRGBALossy<float>());
+ if (textColor.luminance() < backgroundColor.luminance())
+ hsla.lightness += datePlaceholderColorLightnessAdjustmentFactor * (1.0f - hsla.lightness);
+ else
+ hsla.lightness *= datePlaceholderColorLightnessAdjustmentFactor;
+
+ return toSRGBA(hsla);
+}
+
void RenderTheme::setCustomFocusRingColor(const Color& color)
{
customFocusRingColor() = color;
Modified: trunk/Source/WebCore/rendering/RenderTheme.h (270874 => 270875)
--- trunk/Source/WebCore/rendering/RenderTheme.h 2020-12-16 00:33:34 UTC (rev 270874)
+++ trunk/Source/WebCore/rendering/RenderTheme.h 2020-12-16 01:05:20 UTC (rev 270875)
@@ -164,6 +164,8 @@
// Default highlighting color for app highlights.
Color appHighlightColor(OptionSet<StyleColor::Options>) const;
+ Color datePlaceholderTextColor(const Color& textColor, const Color& backgroundColor) const;
+
virtual Color disabledTextColor(const Color& textColor, const Color& backgroundColor) const;
WEBCORE_EXPORT Color focusRingColor(OptionSet<StyleColor::Options>) const;