Title: [272368] trunk
Revision
272368
Author
akeer...@apple.com
Date
2021-02-04 06:59:24 -0800 (Thu, 04 Feb 2021)

Log Message

[macOS] Selecting a date on datetime-local inputs unexpectedly adds second and millisecond fields
https://bugs.webkit.org/show_bug.cgi?id=221350
<rdar://problem/73943517>

Reviewed by Devin Rousso.

Source/WebCore:

Currently, when setting the value of a datetime-local input using the
picker, the length of the current value of the input is used to determine
whether or not to return a value with second/millisecond precision.

This is approach is incorrect, since the value could be empty, while the
step attribute can specify second/millisecond precision. To fix, ensure
the DateTimeChooserParameters knows whether the input has second and
millisecond fields. That information can then be used by the UIProcess
to return a correctly formatted value to the WebProcess.

Test: fast/forms/datetimelocal/datetimelocal-editable-components/datetimelocal-choose-value-from-picker.html

* html/BaseDateAndTimeInputType.cpp:
(WebCore::BaseDateAndTimeInputType::handleDOMActivateEvent):
(WebCore::BaseDateAndTimeInputType::didChangeValueFromControl):
(WebCore::BaseDateAndTimeInputType::setupDateTimeChooserParameters):

Moved this method from HTMLInputElement to the input type, since it is
specific to date/time input types, and to leverage the existing
shouldHaveSecondField and shouldHaveMillisecondField methods when
building the DateTimeChooserParameters.

* html/BaseDateAndTimeInputType.h:
* html/HTMLInputElement.cpp:
* html/HTMLInputElement.h:
* platform/DateTimeChooserParameters.h:

Added hasSecondField and hasMillisecondField members, so that the UIProcess
knows whether or not to return a string that contains seconds/milliseconds.

(WebCore::DateTimeChooserParameters::encode const):
(WebCore::DateTimeChooserParameters::decode):

Source/WebKit:

* UIProcess/mac/WebDateTimePickerMac.mm:
(-[WKDateTimePicker updatePicker:]):
(-[WKDateTimePicker dateFormatStringForType:]):

Do not use the length of the value to determine whether or seconds and
milliseconds should be present, since the value can be empty.

Instead, use the new information in DateTimeChooserParameters, matching
the visual appearance of the input.

Tools:

Added a method to UIScriptController to simulate selecting a date using
the presented date picker.

* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.h:
(WTR::UIScriptController::chooseDateTimePickerValue):
* WebKitTestRunner/mac/UIScriptControllerMac.h:
* WebKitTestRunner/mac/UIScriptControllerMac.mm:
(WTR::UIScriptControllerMac::chooseDateTimePickerValue):

LayoutTests:

Added a test to to verify that the presence of seconds and milliseconds
in the value of a datetime-local input after selecting a date using the
picker matches the configuration.

* fast/forms/datetimelocal/datetimelocal-editable-components/datetimelocal-choose-value-from-picker-expected.txt: Added.
* fast/forms/datetimelocal/datetimelocal-editable-components/datetimelocal-choose-value-from-picker.html: Added.
* resources/ui-helper.js:
(window.UIHelper.chooseDateTimePickerValue):

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (272367 => 272368)


--- trunk/LayoutTests/ChangeLog	2021-02-04 12:48:46 UTC (rev 272367)
+++ trunk/LayoutTests/ChangeLog	2021-02-04 14:59:24 UTC (rev 272368)
@@ -1,3 +1,20 @@
+2021-02-04  Aditya Keerthi  <akeer...@apple.com>
+
+        [macOS] Selecting a date on datetime-local inputs unexpectedly adds second and millisecond fields
+        https://bugs.webkit.org/show_bug.cgi?id=221350
+        <rdar://problem/73943517>
+
+        Reviewed by Devin Rousso.
+
+        Added a test to to verify that the presence of seconds and milliseconds
+        in the value of a datetime-local input after selecting a date using the
+        picker matches the configuration.
+
+        * fast/forms/datetimelocal/datetimelocal-editable-components/datetimelocal-choose-value-from-picker-expected.txt: Added.
+        * fast/forms/datetimelocal/datetimelocal-editable-components/datetimelocal-choose-value-from-picker.html: Added.
+        * resources/ui-helper.js:
+        (window.UIHelper.chooseDateTimePickerValue):
+
 2021-02-04  Martin Robinson  <mrobin...@igalia.com>
 
         Improve the serialization of scroll-snap-type and scroll-snap-align

Added: trunk/LayoutTests/fast/forms/datetimelocal/datetimelocal-editable-components/datetimelocal-choose-value-from-picker-expected.txt (0 => 272368)


--- trunk/LayoutTests/fast/forms/datetimelocal/datetimelocal-editable-components/datetimelocal-choose-value-from-picker-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/forms/datetimelocal/datetimelocal-editable-components/datetimelocal-choose-value-from-picker-expected.txt	2021-02-04 14:59:24 UTC (rev 272368)
@@ -0,0 +1,29 @@
+Tests that choosing a value using the date/time picker does not unexpectedly add or remove second and millisecond fields.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Testing empty input with no step value.
+PASS valueHasSeconds is false
+PASS valueHasMillseconds is false
+
+Testing empty input with step attribute precise to seconds.
+PASS valueHasSeconds is true
+PASS valueHasMillseconds is false
+
+Testing empty input with step attribute precise to milliseconds.
+PASS valueHasSeconds is true
+PASS valueHasMillseconds is true
+
+Testing input with a value that contains seconds.
+PASS valueHasSeconds is true
+PASS valueHasMillseconds is false
+
+Testing input with a value that contains milliseconds.
+PASS valueHasSeconds is true
+PASS valueHasMillseconds is true
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/forms/datetimelocal/datetimelocal-editable-components/datetimelocal-choose-value-from-picker.html (0 => 272368)


--- trunk/LayoutTests/fast/forms/datetimelocal/datetimelocal-editable-components/datetimelocal-choose-value-from-picker.html	                        (rev 0)
+++ trunk/LayoutTests/fast/forms/datetimelocal/datetimelocal-editable-components/datetimelocal-choose-value-from-picker.html	2021-02-04 14:59:24 UTC (rev 272368)
@@ -0,0 +1,100 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+
+<input id="emptyInput" type="datetime-local" value=""/>
+<input id="emptyInputWithSecondStep" type="datetime-local" value="" step="2"/>
+<input id="emptyInputWithMillisecondStep" type="datetime-local" value="" step="0.5"/>
+<input id="inputWithSecondsValue" type="datetime-local" value="2021-02-03T10:30:40"/>
+<input id="inputWithMillisecondsValue" type="datetime-local" value="2021-02-03T10:30:00.100"/>
+
+<script>
+
+jsTestIsAsync = true;
+
+function hasSeconds(value) {
+    time = value.slice(value.lastIndexOf('T') + 1);
+    return time.length > 5;
+}
+
+function hasMilliseconds(value) {
+    time = value.slice(value.lastIndexOf('T') + 1);
+    return time.length > 8;
+}
+
+async function activateElementAndChooseDateUsingPicker(input) {
+    await UIHelper.activateElementAndWaitForInputSession(input);
+    await UIHelper.isShowingDateTimePicker();
+    await UIHelper.chooseDateTimePickerValue();
+}
+
+function expectNoSecondsOrMilliseconds(value) {
+    valueHasSeconds = hasSeconds(value);
+    shouldBeFalse("valueHasSeconds");
+    valueHasMillseconds = hasMilliseconds(value);
+    shouldBeFalse("valueHasMillseconds");
+}
+
+function expectSeconds(value) {
+    valueHasSeconds = hasSeconds(value);
+    shouldBeTrue("valueHasSeconds");
+    valueHasMillseconds = hasMilliseconds(value);
+    shouldBeFalse("valueHasMillseconds");
+}
+
+function expectMilliseconds(value) {
+    valueHasSeconds = hasSeconds(value);
+    shouldBeTrue("valueHasSeconds");
+    valueHasMillseconds = hasMilliseconds(value);
+    shouldBeTrue("valueHasMillseconds");
+}
+
+addEventListener("load", async () => {
+    description("Tests that choosing a value using the date/time picker does not unexpectedly add or remove second and millisecond fields.");
+
+    debug("Testing empty input with no step value.");
+    await activateElementAndChooseDateUsingPicker(emptyInput);
+    expectNoSecondsOrMilliseconds(emptyInput.value);
+    await UIHelper.deactivateFormControl(emptyInput);
+    await UIHelper.ensurePresentationUpdate();
+
+    debug("");
+    debug("Testing empty input with step attribute precise to seconds.");
+    await activateElementAndChooseDateUsingPicker(emptyInputWithSecondStep);
+    expectSeconds(emptyInputWithSecondStep.value);
+    await UIHelper.deactivateFormControl(emptyInputWithSecondStep);
+    await UIHelper.ensurePresentationUpdate();
+
+    debug("");
+    debug("Testing empty input with step attribute precise to milliseconds.");
+    await activateElementAndChooseDateUsingPicker(emptyInputWithMillisecondStep);
+    expectMilliseconds(emptyInputWithMillisecondStep.value);
+    await UIHelper.deactivateFormControl(emptyInputWithMillisecondStep);
+    await UIHelper.ensurePresentationUpdate();
+
+    debug("");
+    debug("Testing input with a value that contains seconds.");
+    await activateElementAndChooseDateUsingPicker(inputWithSecondsValue);
+    expectSeconds(inputWithSecondsValue.value);
+    await UIHelper.deactivateFormControl(inputWithSecondsValue);
+    await UIHelper.ensurePresentationUpdate();
+
+    debug("");
+    debug("Testing input with a value that contains milliseconds.");
+    await activateElementAndChooseDateUsingPicker(inputWithMillisecondsValue);
+    expectMilliseconds(inputWithMillisecondsValue.value);
+    await UIHelper.deactivateFormControl(inputWithMillisecondsValue);
+    await UIHelper.ensurePresentationUpdate();
+
+    debug("");
+    finishJSTest();
+});
+</script>
+
+<script src=""
+</body>
+</html>

Modified: trunk/LayoutTests/resources/ui-helper.js (272367 => 272368)


--- trunk/LayoutTests/resources/ui-helper.js	2021-02-04 12:48:46 UTC (rev 272367)
+++ trunk/LayoutTests/resources/ui-helper.js	2021-02-04 14:59:24 UTC (rev 272368)
@@ -941,6 +941,16 @@
         });
     }
 
+    static chooseDateTimePickerValue()
+    {
+        return new Promise((resolve) => {
+            testRunner.runUIScript(`
+                uiController.chooseDateTimePickerValue();
+                uiController.uiScriptComplete();
+            `, resolve);
+        });
+    }
+
     static zoomScale()
     {
         return new Promise(resolve => {

Modified: trunk/Source/WebCore/ChangeLog (272367 => 272368)


--- trunk/Source/WebCore/ChangeLog	2021-02-04 12:48:46 UTC (rev 272367)
+++ trunk/Source/WebCore/ChangeLog	2021-02-04 14:59:24 UTC (rev 272368)
@@ -1,3 +1,44 @@
+2021-02-04  Aditya Keerthi  <akeer...@apple.com>
+
+        [macOS] Selecting a date on datetime-local inputs unexpectedly adds second and millisecond fields
+        https://bugs.webkit.org/show_bug.cgi?id=221350
+        <rdar://problem/73943517>
+
+        Reviewed by Devin Rousso.
+
+        Currently, when setting the value of a datetime-local input using the
+        picker, the length of the current value of the input is used to determine
+        whether or not to return a value with second/millisecond precision.
+
+        This is approach is incorrect, since the value could be empty, while the
+        step attribute can specify second/millisecond precision. To fix, ensure
+        the DateTimeChooserParameters knows whether the input has second and
+        millisecond fields. That information can then be used by the UIProcess
+        to return a correctly formatted value to the WebProcess.
+
+        Test: fast/forms/datetimelocal/datetimelocal-editable-components/datetimelocal-choose-value-from-picker.html
+
+        * html/BaseDateAndTimeInputType.cpp:
+        (WebCore::BaseDateAndTimeInputType::handleDOMActivateEvent):
+        (WebCore::BaseDateAndTimeInputType::didChangeValueFromControl):
+        (WebCore::BaseDateAndTimeInputType::setupDateTimeChooserParameters):
+
+        Moved this method from HTMLInputElement to the input type, since it is
+        specific to date/time input types, and to leverage the existing
+        shouldHaveSecondField and shouldHaveMillisecondField methods when
+        building the DateTimeChooserParameters.
+
+        * html/BaseDateAndTimeInputType.h:
+        * html/HTMLInputElement.cpp:
+        * html/HTMLInputElement.h:
+        * platform/DateTimeChooserParameters.h:
+
+        Added hasSecondField and hasMillisecondField members, so that the UIProcess
+        knows whether or not to return a string that contains seconds/milliseconds.
+
+        (WebCore::DateTimeChooserParameters::encode const):
+        (WebCore::DateTimeChooserParameters::decode):
+
 2021-02-04  Commit Queue  <commit-qu...@webkit.org>
 
         Unreviewed, reverting r272338.

Modified: trunk/Source/WebCore/html/BaseDateAndTimeInputType.cpp (272367 => 272368)


--- trunk/Source/WebCore/html/BaseDateAndTimeInputType.cpp	2021-02-04 12:48:46 UTC (rev 272367)
+++ trunk/Source/WebCore/html/BaseDateAndTimeInputType.cpp	2021-02-04 14:59:24 UTC (rev 272368)
@@ -40,9 +40,11 @@
 #include "DateTimeChooserParameters.h"
 #include "Decimal.h"
 #include "FocusController.h"
+#include "HTMLDataListElement.h"
 #include "HTMLDivElement.h"
 #include "HTMLInputElement.h"
 #include "HTMLNames.h"
+#include "HTMLOptionElement.h"
 #include "KeyboardEvent.h"
 #include "Page.h"
 #include "PlatformLocale.h"
@@ -292,7 +294,7 @@
         return;
 
     DateTimeChooserParameters parameters;
-    if (!element()->setupDateTimeChooserParameters(parameters))
+    if (!setupDateTimeChooserParameters(parameters))
         return;
 
     if (auto chrome = this->chrome()) {
@@ -460,7 +462,7 @@
     InputType::setValue(value, value != element()->value(), DispatchInputAndChangeEvent);
 
     DateTimeChooserParameters parameters;
-    if (!element()->setupDateTimeChooserParameters(parameters))
+    if (!setupDateTimeChooserParameters(parameters))
         return;
 
     if (m_dateTimeChooser)
@@ -496,6 +498,68 @@
     m_dateTimeChooser = nullptr;
 }
 
+bool BaseDateAndTimeInputType::setupDateTimeChooserParameters(DateTimeChooserParameters& parameters)
+{
+    ASSERT(element());
+
+    auto& element = *this->element();
+    auto& document = element.document();
+
+    if (!document.view())
+        return false;
+
+    parameters.type = element.type();
+    parameters.minimum = element.minimum();
+    parameters.maximum = element.maximum();
+    parameters.required = element.isRequired();
+
+    if (!document.settings().langAttributeAwareFormControlUIEnabled())
+        parameters.locale = defaultLanguage();
+    else {
+        AtomString computedLocale = element.computeInheritedLanguage();
+        parameters.locale = computedLocale.isEmpty() ? AtomString(defaultLanguage()) : computedLocale;
+    }
+
+    auto stepRange = createStepRange(AnyStepHandling::Reject);
+    if (stepRange.hasStep()) {
+        parameters.step = stepRange.step().toDouble();
+        parameters.stepBase = stepRange.stepBase().toDouble();
+    } else {
+        parameters.step = 1.0;
+        parameters.stepBase = 0;
+    }
+
+    if (RenderElement* renderer = element.renderer())
+        parameters.anchorRectInRootView = document.view()->contentsToRootView(renderer->absoluteBoundingBoxRect());
+    else
+        parameters.anchorRectInRootView = IntRect();
+    parameters.currentValue = element.value();
+
+    auto* computedStyle = element.computedStyle();
+    parameters.isAnchorElementRTL = computedStyle->direction() == TextDirection::RTL;
+    parameters.useDarkAppearance = document.useDarkAppearance(computedStyle);
+
+    auto date = parseToDateComponents(element.value()).valueOr(DateComponents());
+    parameters.hasSecondField = shouldHaveSecondField(date);
+    parameters.hasMillisecondField = shouldHaveMillisecondField(date);
+
+#if ENABLE(DATALIST_ELEMENT)
+    if (auto dataList = element.dataList()) {
+        for (auto& option : dataList->suggestions()) {
+            auto label = option.label();
+            auto value = option.value();
+            if (!element.isValidValue(value))
+                continue;
+            parameters.suggestionValues.append(element.sanitizeValue(value));
+            parameters.localizedSuggestionValues.append(element.localizeValue(value));
+            parameters.suggestionLabels.append(value == label ? String() : label);
+        }
+    }
+#endif
+
+    return true;
+}
+
 void BaseDateAndTimeInputType::closeDateTimeChooser()
 {
     if (m_dateTimeChooser)

Modified: trunk/Source/WebCore/html/BaseDateAndTimeInputType.h (272367 => 272368)


--- trunk/Source/WebCore/html/BaseDateAndTimeInputType.h	2021-02-04 12:48:46 UTC (rev 272367)
+++ trunk/Source/WebCore/html/BaseDateAndTimeInputType.h	2021-02-04 14:59:24 UTC (rev 272368)
@@ -44,6 +44,8 @@
 
 class DateComponents;
 
+struct DateTimeChooserParameters;
+
 // A super class of date, datetime, datetime-local, month, time, and week types.
 class BaseDateAndTimeInputType : public InputType, private DateTimeChooserClient, private DateTimeEditElement::EditControlOwner {
 protected:
@@ -133,6 +135,7 @@
     void didChooseValue(StringView) final;
     void didEndChooser() final;
 
+    bool setupDateTimeChooserParameters(DateTimeChooserParameters&);
     void closeDateTimeChooser();
 
     std::unique_ptr<DateTimeChooser> m_dateTimeChooser;

Modified: trunk/Source/WebCore/html/HTMLInputElement.cpp (272367 => 272368)


--- trunk/Source/WebCore/html/HTMLInputElement.cpp	2021-02-04 12:48:46 UTC (rev 272367)
+++ trunk/Source/WebCore/html/HTMLInputElement.cpp	2021-02-04 14:59:24 UTC (rev 272368)
@@ -38,7 +38,6 @@
 #include "ChromeClient.h"
 #include "DateComponents.h"
 #include "DateTimeChooser.h"
-#include "DateTimeChooserParameters.h"
 #include "Document.h"
 #include "Editor.h"
 #include "EventNames.h"
@@ -2102,63 +2101,6 @@
     return textBlockStyle;
 }
 
-#if ENABLE(DATE_AND_TIME_INPUT_TYPES)
-
-bool HTMLInputElement::setupDateTimeChooserParameters(DateTimeChooserParameters& parameters)
-{
-    if (!document().view())
-        return false;
-
-    parameters.type = type();
-    parameters.minimum = minimum();
-    parameters.maximum = maximum();
-    parameters.required = isRequired();
-
-    if (!document().settings().langAttributeAwareFormControlUIEnabled())
-        parameters.locale = defaultLanguage();
-    else {
-        AtomString computedLocale = computeInheritedLanguage();
-        parameters.locale = computedLocale.isEmpty() ? AtomString(defaultLanguage()) : computedLocale;
-    }
-
-    auto stepRange = createStepRange(AnyStepHandling::Reject);
-    if (stepRange.hasStep()) {
-        parameters.step = stepRange.step().toDouble();
-        parameters.stepBase = stepRange.stepBase().toDouble();
-    } else {
-        parameters.step = 1.0;
-        parameters.stepBase = 0;
-    }
-
-    if (RenderElement* renderer = this->renderer())
-        parameters.anchorRectInRootView = document().view()->contentsToRootView(renderer->absoluteBoundingBoxRect());
-    else
-        parameters.anchorRectInRootView = IntRect();
-    parameters.currentValue = value();
-
-    auto* computedStyle = this->computedStyle();
-    parameters.isAnchorElementRTL = computedStyle->direction() == TextDirection::RTL;
-    parameters.useDarkAppearance = document().useDarkAppearance(computedStyle);
-
-#if ENABLE(DATALIST_ELEMENT)
-    if (auto dataList = this->dataList()) {
-        for (auto& option : dataList->suggestions()) {
-            auto label = option.label();
-            auto value = option.value();
-            if (!isValidValue(value))
-                continue;
-            parameters.suggestionValues.append(sanitizeValue(value));
-            parameters.localizedSuggestionValues.append(localizeValue(value));
-            parameters.suggestionLabels.append(value == label ? String() : label);
-        }
-    }
-#endif
-
-    return true;
-}
-
-#endif
-
 void HTMLInputElement::capsLockStateMayHaveChanged()
 {
     m_inputType->capsLockStateMayHaveChanged();

Modified: trunk/Source/WebCore/html/HTMLInputElement.h (272367 => 272368)


--- trunk/Source/WebCore/html/HTMLInputElement.h	2021-02-04 12:48:46 UTC (rev 272367)
+++ trunk/Source/WebCore/html/HTMLInputElement.h	2021-02-04 14:59:24 UTC (rev 272368)
@@ -42,8 +42,6 @@
 class RadioButtonGroups;
 class StepRange;
 
-struct DateTimeChooserParameters;
-
 struct InputElementClickState {
     bool stateful { false };
     bool checked { false };
@@ -327,10 +325,6 @@
     HTMLImageLoader* imageLoader() { return m_imageLoader.get(); }
     HTMLImageLoader& ensureImageLoader();
 
-#if ENABLE(DATE_AND_TIME_INPUT_TYPES)
-    bool setupDateTimeChooserParameters(DateTimeChooserParameters&);
-#endif
-
     void capsLockStateMayHaveChanged();
 
     bool shouldTruncateText(const RenderStyle&) const;

Modified: trunk/Source/WebCore/platform/DateTimeChooserParameters.h (272367 => 272368)


--- trunk/Source/WebCore/platform/DateTimeChooserParameters.h	2021-02-04 12:48:46 UTC (rev 272367)
+++ trunk/Source/WebCore/platform/DateTimeChooserParameters.h	2021-02-04 14:59:24 UTC (rev 272368)
@@ -43,13 +43,15 @@
     Vector<String> suggestionValues;
     Vector<String> localizedSuggestionValues;
     Vector<String> suggestionLabels;
-    double minimum;
-    double maximum;
-    double step;
-    double stepBase;
-    bool required;
-    bool isAnchorElementRTL;
-    bool useDarkAppearance;
+    double minimum { 0 };
+    double maximum { 0 };
+    double step { 0 };
+    double stepBase { 0 };
+    bool required { false };
+    bool isAnchorElementRTL { false };
+    bool useDarkAppearance { false };
+    bool hasSecondField { false };
+    bool hasMillisecondField { false };
 
     template<class Encoder> void encode(Encoder&) const;
     template<class Decoder> static Optional<DateTimeChooserParameters> decode(Decoder&);
@@ -72,6 +74,8 @@
     encoder << required;
     encoder << isAnchorElementRTL;
     encoder << useDarkAppearance;
+    encoder << hasSecondField;
+    encoder << hasMillisecondField;
 }
 
 template<class Decoder>
@@ -133,7 +137,15 @@
     if (!decoder.decode(useDarkAppearance))
         return WTF::nullopt;
 
-    return {{ WTFMove(type), anchorRectInRootView, WTFMove(locale), WTFMove(currentValue), WTFMove(suggestionValues), WTFMove(localizedSuggestionValues), WTFMove(suggestionLabels), minimum, maximum, step, stepBase, required, isAnchorElementRTL, useDarkAppearance }};
+    bool hasSecondField;
+    if (!decoder.decode(hasSecondField))
+        return WTF::nullopt;
+
+    bool hasMillisecondField;
+    if (!decoder.decode(hasMillisecondField))
+        return WTF::nullopt;
+
+    return {{ WTFMove(type), anchorRectInRootView, WTFMove(locale), WTFMove(currentValue), WTFMove(suggestionValues), WTFMove(localizedSuggestionValues), WTFMove(suggestionLabels), minimum, maximum, step, stepBase, required, isAnchorElementRTL, useDarkAppearance, hasSecondField, hasMillisecondField }};
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebKit/ChangeLog (272367 => 272368)


--- trunk/Source/WebKit/ChangeLog	2021-02-04 12:48:46 UTC (rev 272367)
+++ trunk/Source/WebKit/ChangeLog	2021-02-04 14:59:24 UTC (rev 272368)
@@ -1,3 +1,21 @@
+2021-02-04  Aditya Keerthi  <akeer...@apple.com>
+
+        [macOS] Selecting a date on datetime-local inputs unexpectedly adds second and millisecond fields
+        https://bugs.webkit.org/show_bug.cgi?id=221350
+        <rdar://problem/73943517>
+
+        Reviewed by Devin Rousso.
+
+        * UIProcess/mac/WebDateTimePickerMac.mm:
+        (-[WKDateTimePicker updatePicker:]):
+        (-[WKDateTimePicker dateFormatStringForType:]):
+
+        Do not use the length of the value to determine whether or seconds and
+        milliseconds should be present, since the value can be empty.
+
+        Instead, use the new information in DateTimeChooserParameters, matching
+        the visual appearance of the input.
+
 2021-02-04  Lauro Moura  <lmo...@igalia.com>
 
         REGRESSION(r267763): [GTK][WPE] Broken main thread assertion in MemoryPressureMonitor

Modified: trunk/Source/WebKit/UIProcess/mac/WebDateTimePickerMac.mm (272367 => 272368)


--- trunk/Source/WebKit/UIProcess/mac/WebDateTimePickerMac.mm	2021-02-04 12:48:46 UTC (rev 272367)
+++ trunk/Source/WebKit/UIProcess/mac/WebDateTimePickerMac.mm	2021-02-04 14:59:24 UTC (rev 272368)
@@ -240,7 +240,7 @@
 
     NSString *currentDateValueString = _params.currentValue;
 
-    [_dateFormatter setDateFormat:[self dateFormatStringForType:_params.type value:currentDateValueString]];
+    [_dateFormatter setDateFormat:[self dateFormatStringForType:_params.type]];
 
     if (![currentDateValueString length])
         [_datePicker setDateValue:[self initialDateForEmptyValue]];
@@ -276,16 +276,14 @@
     _picker->didChooseDate(StringView(dateString));
 }
 
-- (NSString *)dateFormatStringForType:(NSString *)type value:(NSString *)value
+- (NSString *)dateFormatStringForType:(NSString *)type
 {
     if ([type isEqualToString:@"datetime-local"]) {
-        // Add two additional characters for the string delimiters in 'T'.
-        NSUInteger valueLengthForFormat = value.length + 2;
-        if (valueLengthForFormat == kDateTimeFormatString.length)
-            return kDateTimeFormatString;
-        if (valueLengthForFormat == kDateTimeWithSecondsFormatString.length)
+        if (_params.hasMillisecondField)
+            return kDateTimeWithMillisecondsFormatString;
+        if (_params.hasSecondField)
             return kDateTimeWithSecondsFormatString;
-        return kDateTimeWithMillisecondsFormatString;
+        return kDateTimeFormatString;
     }
 
     return kDateFormatString;

Modified: trunk/Tools/ChangeLog (272367 => 272368)


--- trunk/Tools/ChangeLog	2021-02-04 12:48:46 UTC (rev 272367)
+++ trunk/Tools/ChangeLog	2021-02-04 14:59:24 UTC (rev 272368)
@@ -1,3 +1,21 @@
+2021-02-04  Aditya Keerthi  <akeer...@apple.com>
+
+        [macOS] Selecting a date on datetime-local inputs unexpectedly adds second and millisecond fields
+        https://bugs.webkit.org/show_bug.cgi?id=221350
+        <rdar://problem/73943517>
+
+        Reviewed by Devin Rousso.
+
+        Added a method to UIScriptController to simulate selecting a date using
+        the presented date picker.
+
+        * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
+        * TestRunnerShared/UIScriptContext/UIScriptController.h:
+        (WTR::UIScriptController::chooseDateTimePickerValue):
+        * WebKitTestRunner/mac/UIScriptControllerMac.h:
+        * WebKitTestRunner/mac/UIScriptControllerMac.mm:
+        (WTR::UIScriptControllerMac::chooseDateTimePickerValue):
+
 2021-02-04  Eleni Maria Stea  <es...@igalia.com>
 
         Modifications to Tools/wpe/install-dependencies

Modified: trunk/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl (272367 => 272368)


--- trunk/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl	2021-02-04 12:48:46 UTC (rev 272367)
+++ trunk/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl	2021-02-04 14:59:24 UTC (rev 272368)
@@ -229,6 +229,7 @@
 
     readonly attribute boolean isShowingDateTimePicker;
     readonly attribute double dateTimePickerValue;
+    undefined chooseDateTimePickerValue();
 
     // <datalist>
     readonly attribute boolean isShowingDataListSuggestions;

Modified: trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h (272367 => 272368)


--- trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h	2021-02-04 12:48:46 UTC (rev 272367)
+++ trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h	2021-02-04 14:59:24 UTC (rev 272368)
@@ -223,6 +223,7 @@
     virtual double timePickerValueMinute() const { notImplemented(); return -1; }
     virtual bool isShowingDateTimePicker() const { notImplemented(); return false; }
     virtual double dateTimePickerValue() const { notImplemented(); return 0; }
+    virtual void chooseDateTimePickerValue() { notImplemented(); }
     virtual bool isShowingDataListSuggestions() const { notImplemented(); return false; }
     virtual JSObjectRef calendarType() const { notImplemented(); return nullptr; }
     virtual void setDefaultCalendarType(JSStringRef, JSStringRef) { notImplemented(); }

Modified: trunk/Tools/WebKitTestRunner/mac/UIScriptControllerMac.h (272367 => 272368)


--- trunk/Tools/WebKitTestRunner/mac/UIScriptControllerMac.h	2021-02-04 12:48:46 UTC (rev 272367)
+++ trunk/Tools/WebKitTestRunner/mac/UIScriptControllerMac.h	2021-02-04 14:59:24 UTC (rev 272368)
@@ -45,6 +45,7 @@
     void simulateAccessibilitySettingsChangeNotification(JSValueRef) override;
     bool isShowingDateTimePicker() const override;
     double dateTimePickerValue() const override;
+    void chooseDateTimePickerValue() override;
     bool isShowingDataListSuggestions() const override;
     void activateDataListSuggestion(unsigned index, JSValueRef callback) override;
     void beginBackSwipe(JSValueRef) override;

Modified: trunk/Tools/WebKitTestRunner/mac/UIScriptControllerMac.mm (272367 => 272368)


--- trunk/Tools/WebKitTestRunner/mac/UIScriptControllerMac.mm	2021-02-04 12:48:46 UTC (rev 272367)
+++ trunk/Tools/WebKitTestRunner/mac/UIScriptControllerMac.mm	2021-02-04 14:59:24 UTC (rev 272368)
@@ -119,6 +119,21 @@
     return 0;
 }
 
+void UIScriptControllerMac::chooseDateTimePickerValue()
+{
+    for (NSWindow *childWindow in webView().window.childWindows) {
+        if ([childWindow isKindOfClass:NSClassFromString(@"WKDateTimePickerWindow")]) {
+            for (NSView *subview in childWindow.contentView.subviews) {
+                if ([subview isKindOfClass:[NSDatePicker class]]) {
+                    NSDatePicker *datePicker = (NSDatePicker *)subview;
+                    [datePicker.target performSelector:datePicker.action withObject:datePicker];
+                    return;
+                }
+            }
+        }
+    }
+}
+
 bool UIScriptControllerMac::isShowingDataListSuggestions() const
 {
     return dataListSuggestionsTableView();
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to