Changeset 286869 in webkit


Ignore:
Timestamp:
Dec 10, 2021 12:37:40 PM (7 months ago)
Author:
Chris Dumez
Message:

Improve <type="datetime-local"> value parsing and sanitization
https://bugs.webkit.org/show_bug.cgi?id=234039

Reviewed by Darin Adler.

Source/WebCore:

Improve <type="datetime-local"> value parsing and sanitization.

Test: fast/forms/datetimelocal/datetime-local-value-sanitization.html

  • html/BaseDateAndTimeInputType.h:
  • html/DateTimeLocalInputType.cpp:

(WebCore::DateTimeLocalInputType::sanitizeValue const):
Implement value sanitization for <type="datetime-local"> so that:

  • html/DateTimeLocalInputType.h:
  • platform/DateComponents.cpp:

(WebCore::DateComponents::parseTime):
Fix bug where we would allow more than 3 digits for the millisecond part of the time (we
would silently ignore follow-up digits instead of failing parsing). This is as per:

This was covered by one of the subtests in imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/datetime-local.html

(WebCore::isDateTimeLocalSeparator):
(WebCore::DateComponents::parseDateTimeLocal):
Allow using a space as date / time separator in <type="datetime-local">, instead of simply allowing a 'T'.
This would align our behavior with Gecko and the specification:

Note that Blink still seems to only allow 'T' as separator.

(WebCore::DateComponents::toStringForTime const):
The output will use the shortest possible string, omitting seconds or milliseconds when 0, as per
https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-normalised-local-date-and-time-string

LayoutTests:

  • fast/forms/datetimelocal/ValidityState-typeMismatch-datetimelocal-expected.txt:
  • fast/forms/datetimelocal/ValidityState-typeMismatch-datetimelocal.html:
  • fast/forms/datetimelocal/input-valueasnumber-datetimelocal-expected.txt:
  • fast/forms/datetimelocal/input-valueasnumber-datetimelocal.html:

Update a couple of existing tests to reflect behavior change.

  • fast/forms/datetimelocal/datetime-local-value-sanitization-expected.txt: Added.
  • fast/forms/datetimelocal/datetime-local-value-sanitization.html: Added.

Improve test coverage for datetime-local value sanitization.

  • platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt:
  • platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/datetime-local-expected.txt:
  • platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/time-2-expected.txt:

Rebaseline WPT tests now that more checks are passing.

Location:
trunk
Files:
2 added
22 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r286866 r286869  
     12021-12-10  Chris Dumez  <cdumez@apple.com>
     2
     3        Improve <type="datetime-local"> value parsing and sanitization
     4        https://bugs.webkit.org/show_bug.cgi?id=234039
     5
     6        Reviewed by Darin Adler.
     7
     8        * fast/forms/datetimelocal/ValidityState-typeMismatch-datetimelocal-expected.txt:
     9        * fast/forms/datetimelocal/ValidityState-typeMismatch-datetimelocal.html:
     10        * fast/forms/datetimelocal/input-valueasnumber-datetimelocal-expected.txt:
     11        * fast/forms/datetimelocal/input-valueasnumber-datetimelocal.html:
     12        Update a couple of existing tests to reflect behavior change.
     13
     14        * fast/forms/datetimelocal/datetime-local-value-sanitization-expected.txt: Added.
     15        * fast/forms/datetimelocal/datetime-local-value-sanitization.html: Added.
     16        Improve test coverage for datetime-local value sanitization.
     17
     18        * platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt:
     19        * platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/datetime-local-expected.txt:
     20        * platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/time-2-expected.txt:
     21        Rebaseline WPT tests now that more checks are passing.
     22
    1232021-12-10  Gabriel Nava Marino  <gnavamarino@apple.com>
    224
  • trunk/LayoutTests/fast/forms/datetimelocal/ValidityState-typeMismatch-datetimelocal-expected.txt

    r103957 r286869  
    1010PASS "2009-09-07T16:49:31.12" is a correct valid datetime-local string.
    1111PASS "2009-09-07T16:49:31.123" is a correct valid datetime-local string.
    12 PASS "2009-09-07T16:49:31.1234567890" is a correct valid datetime-local string.
    1312PASS "275760-09-13T00:00:00.000" is a correct valid datetime-local string.
    1413PASS "0001-01-01T00:00:00.000" is a correct valid datetime-local string.
     14PASS "2009-09-07 16:49" is a correct valid datetime-local string.
    1515PASS " 2009-09-07T16:49 " is an invalid datetime-local string and was sanitized.
    1616PASS "2009-09-07t16:49" is an invalid datetime-local string and was sanitized.
    17 PASS "2009-09-07 16:49" is an invalid datetime-local string and was sanitized.
    1817PASS "2009/09/07T16:49" is an invalid datetime-local string and was sanitized.
    1918PASS "a" is an invalid datetime-local string and was sanitized.
     
    2120PASS "0000-12-31T23:59:59.999" is an invalid datetime-local string and was sanitized.
    2221PASS "275760-09-13T00:00:00.001" is an invalid datetime-local string and was sanitized.
     22PASS "2009-09-07T16:49:31.1234567890" is an invalid datetime-local string and was sanitized.
    2323PASS "invalid" is an invalid datetime-local string and was sanitized while disabled.
    2424PASS successfullyParsed is true
  • trunk/LayoutTests/fast/forms/datetimelocal/ValidityState-typeMismatch-datetimelocal.html

    r155268 r286869  
    4646shouldBeValid('2009-09-07T16:49:31.12');
    4747shouldBeValid('2009-09-07T16:49:31.123');
    48 shouldBeValid('2009-09-07T16:49:31.1234567890');
    4948shouldBeValid('275760-09-13T00:00:00.000');
    5049shouldBeValid('0001-01-01T00:00:00.000');
     50shouldBeValid('2009-09-07 16:49');
    5151
    5252// Invalid values
    5353shouldBeInvalid(' 2009-09-07T16:49 ');
    5454shouldBeInvalid('2009-09-07t16:49');
    55 shouldBeInvalid('2009-09-07 16:49');
    5655shouldBeInvalid('2009/09/07T16:49');
    5756shouldBeInvalid('a');
     
    5958shouldBeInvalid('0000-12-31T23:59:59.999');
    6059shouldBeInvalid('275760-09-13T00:00:00.001');
     60shouldBeInvalid('2009-09-07T16:49:31.1234567890');
    6161
    6262// Disabled
  • trunk/LayoutTests/fast/forms/datetimelocal/input-valueasnumber-datetimelocal-expected.txt

    r219663 r286869  
    99PASS valueAsNumberFor("2009-12-22T11:32:11") is Date.UTC(2009, 11, 22, 11, 32, 11)
    1010PASS setValueAsNumberAndGetValue(1969, 11, 1, 0, 0, 0, 0) is "1969-12-01T00:00"
    11 PASS setValueAsNumberAndGetValue(1970, 0, 1, 10, 1, 0, 100) is "1970-01-01T10:01:00.100"
     11PASS setValueAsNumberAndGetValue(1970, 0, 1, 10, 1, 0, 100) is "1970-01-01T10:01:00.1"
    1212PASS setValueAsNumberAndGetValue(2009, 11, 31, 23, 59, 59, 999) is "2009-12-31T23:59:59.999"
    1313PASS setValueAsNumberAndGetValue(10000, 0, 1, 12, 0, 1, 0) is "10000-01-01T12:00:01"
     
    2727PASS input.valueAsNumber = Date.UTC(275760, 8, 13, 0, 0, 0, 1) threw exception NotSupportedError: The operation is not supported..
    2828Step attribute value and string representation:
    29 PASS input.step = "1"; setValueAsNumberAndGetValue(2010, 0, 21, 0, 0, 0, 0) is "2010-01-21T00:00:00"
    30 PASS input.step = "0.001"; setValueAsNumberAndGetValue(2010, 0, 21, 0, 0, 0, 0) is "2010-01-21T00:00:00.000"
     29PASS input.step = "1"; setValueAsNumberAndGetValue(2010, 0, 21, 0, 0, 0, 0) is "2010-01-21T00:00"
     30PASS input.step = "0.001"; setValueAsNumberAndGetValue(2010, 0, 21, 0, 0, 0, 0) is "2010-01-21T00:00"
    3131PASS successfullyParsed is true
    3232
  • trunk/LayoutTests/fast/forms/datetimelocal/input-valueasnumber-datetimelocal.html

    r219663 r286869  
    3333
    3434shouldBe('setValueAsNumberAndGetValue(1969, 11, 1, 0, 0, 0, 0)', '"1969-12-01T00:00"');
    35 shouldBe('setValueAsNumberAndGetValue(1970, 0, 1, 10, 1, 0, 100)', '"1970-01-01T10:01:00.100"');
     35shouldBe('setValueAsNumberAndGetValue(1970, 0, 1, 10, 1, 0, 100)', '"1970-01-01T10:01:00.1"');
    3636shouldBe('setValueAsNumberAndGetValue(2009, 11, 31, 23, 59, 59, 999)', '"2009-12-31T23:59:59.999"');
    3737shouldBe('setValueAsNumberAndGetValue(10000, 0, 1, 12, 0, 1, 0)', '"10000-01-01T12:00:01"');
     
    5555debug('Step attribute value and string representation:');
    5656// If the step attribute value is 1 second and the second part is 0, we should show the second part.
    57 shouldBe('input.step = "1"; setValueAsNumberAndGetValue(2010, 0, 21, 0, 0, 0, 0)', '"2010-01-21T00:00:00"');
     57shouldBe('input.step = "1"; setValueAsNumberAndGetValue(2010, 0, 21, 0, 0, 0, 0)', '"2010-01-21T00:00"');
    5858// If the step attribute value is 0.001 second and the millisecond part is 0, we should show the millisecond part.
    59 shouldBe('input.step = "0.001"; setValueAsNumberAndGetValue(2010, 0, 21, 0, 0, 0, 0)', '"2010-01-21T00:00:00.000"');
     59shouldBe('input.step = "0.001"; setValueAsNumberAndGetValue(2010, 0, 21, 0, 0, 0, 0)', '"2010-01-21T00:00"');
    6060</script>
    6161<script src="../../../resources/js-test-post.js"></script>
  • trunk/LayoutTests/fast/forms/time/time-validity-typemismatch-expected.txt

    r123836 r286869  
    1111PASS "23:59:59.12" is a correct valid time string.
    1212PASS "23:59:59.123" is a correct valid time string.
    13 PASS "23:59:59.1234567890" is a correct valid time string.
    14 PASS "00:00:00.0000000000" is a correct valid time string.
    1513PASS " 00:00 " is an invalid time string and was sanitized.
    1614PASS "1:23" is an invalid time string and was sanitized.
     
    3432PASS "23:45:06.abc" is an invalid time string and was sanitized.
    3533PASS "23:45:06.789abc" is an invalid time string and was sanitized.
     34PASS "23:59:59.1234567890" is an invalid time string and was sanitized.
     35PASS "00:00:00.0000000000" is an invalid time string and was sanitized.
    3636PASS "invalid" is an invalid time string and was sanitized while disabled.
    3737PASS successfullyParsed is true
  • trunk/LayoutTests/fast/forms/time/time-validity-typemismatch.html

    r155268 r286869  
    4747shouldBeValid('23:59:59.12');
    4848shouldBeValid('23:59:59.123');
    49 shouldBeValid('23:59:59.1234567890');
    50 shouldBeValid('00:00:00.0000000000');
    5149
    5250// Invalid values
     
    7270shouldBeInvalid('23:45:06.abc');
    7371shouldBeInvalid('23:45:06.789abc');
     72shouldBeInvalid('23:59:59.1234567890');
     73shouldBeInvalid('00:00:00.0000000000');
    7474
    7575// Disabled
  • trunk/LayoutTests/fast/forms/time/time-valueasdate-expected.txt

    r123422 r286869  
    2424Step attribute value and string representation:
    2525PASS input.step = "1"; setValueAsDateAndGetValue(0, 0, 0, 0) is "00:00:00"
    26 PASS input.step = "0.001"; setValueAsDateAndGetValue(0, 0, 0, 0) is "00:00:00.000"
     26PASS input.step = "0.001"; setValueAsDateAndGetValue(0, 0, 0, 0) is "00:00:00.0"
    2727PASS successfullyParsed is true
    2828
  • trunk/LayoutTests/fast/forms/time/time-valueasdate.html

    r155268 r286869  
    5151shouldBe('input.step = "1"; setValueAsDateAndGetValue(0, 0, 0, 0)', '"00:00:00"');
    5252// If the step attribute value is 0.001 second and the millisecond part is 0, we should show the millisecond part.
    53 shouldBe('input.step = "0.001"; setValueAsDateAndGetValue(0, 0, 0, 0)', '"00:00:00.000"');
     53shouldBe('input.step = "0.001"; setValueAsDateAndGetValue(0, 0, 0, 0)', '"00:00:00.0"');
    5454</script>
    5555<script src="../../../resources/js-test-post.js"></script>
  • trunk/LayoutTests/fast/forms/time/time-valueasnumber-expected.txt

    r219663 r286869  
    2727Step attribute value and string representation:
    2828PASS input.step = "1"; setValueAsNumberAndGetValue(0, 0, 0, 0) is "00:00:00"
    29 PASS input.step = "0.001"; setValueAsNumberAndGetValue(0, 0, 0, 0) is "00:00:00.000"
     29PASS input.step = "0.001"; setValueAsNumberAndGetValue(0, 0, 0, 0) is "00:00:00.0"
    3030PASS successfullyParsed is true
    3131
  • trunk/LayoutTests/fast/forms/time/time-valueasnumber.html

    r219663 r286869  
    5151shouldBe('input.step = "1"; setValueAsNumberAndGetValue(0, 0, 0, 0)', '"00:00:00"');
    5252// If the step attribute value is 0.001 second and the millisecond part is 0, we should show the millisecond part.
    53 shouldBe('input.step = "0.001"; setValueAsNumberAndGetValue(0, 0, 0, 0)', '"00:00:00.000"');
     53shouldBe('input.step = "0.001"; setValueAsNumberAndGetValue(0, 0, 0, 0)', '"00:00:00.0"');
    5454</script>
    5555<script src="../../../resources/js-test-post.js"></script>
  • trunk/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt

    r286855 r286869  
    2020PASS [INPUT in DATETIME-LOCAL status] The required attribute is not set
    2121PASS [INPUT in DATETIME-LOCAL status] Valid local date and time string(2000-12-10T12:00:00)
    22 FAIL [INPUT in DATETIME-LOCAL status] Valid local date and time string(2000-12-10 12:00) assert_false: The validity.valueMissing should be false. expected false got true
     22PASS [INPUT in DATETIME-LOCAL status] Valid local date and time string(2000-12-10 12:00)
    2323PASS [INPUT in DATETIME-LOCAL status] Valid local date and time string(1979-10-14T12:00:00.001)
    2424PASS [INPUT in DATETIME-LOCAL status] The value attribute is a number(1234567)
    2525PASS [INPUT in DATETIME-LOCAL status] The value attribute is a Date object
    2626PASS [INPUT in DATETIME-LOCAL status] Invalid local date and time string(1979-10-99 99:99)
    27 FAIL [INPUT in DATETIME-LOCAL status] Valid local date and time string(1979-10-14 12:00:00) assert_false: The validity.valueMissing should be false. expected false got true
     27PASS [INPUT in DATETIME-LOCAL status] Valid local date and time string(1979-10-14 12:00:00)
    2828PASS [INPUT in DATETIME-LOCAL status] Invalid local date and time string(2001-12-21  12:00)-two white space
    2929PASS [INPUT in DATETIME-LOCAL status] the value attribute is a string(abc)
  • trunk/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/datetime-local-expected.txt

    r267658 r286869  
    22PASS empty value
    33PASS datetime-local input value set to 2014-01-01T11:11:11.111 without min/max
    4 FAIL datetime-local input value set to 2014-01-01 11:11:11.111 without min/max assert_equals: expected "2014-01-01T11:11:11.111" but got ""
    5 FAIL datetime-local input value set to 2014-01-01 11:11 without min/max assert_equals: expected "2014-01-01T11:11" but got ""
    6 FAIL datetime-local input value set to 2014-01-01 00:00:00.000 without min/max assert_equals: expected "2014-01-01T00:00" but got ""
     4PASS datetime-local input value set to 2014-01-01 11:11:11.111 without min/max
     5PASS datetime-local input value set to 2014-01-01 11:11 without min/max
     6PASS datetime-local input value set to 2014-01-01 00:00:00.000 without min/max
    77PASS datetime-local input value set to 2014-01-0 11:11 without min/max
    88PASS datetime-local input value set to 2014-01-01 11:1 without min/max
     
    1313PASS invalid datetime-local input value 5
    1414PASS invalid datetime-local input value 6
    15 FAIL Value >= min attribute assert_equals: expected "2014-01-01T11:12" but got ""
    16 FAIL Value < min attribute assert_equals: expected "2014-01-01T11:11" but got ""
    17 FAIL Value <= max attribute assert_equals: expected "2014-01-01T11:10" but got ""
    18 FAIL Value > max attribute assert_equals: expected "2014-01-01T11:11" but got ""
     15PASS Value >= min attribute
     16FAIL Value < min attribute assert_equals: expected "2014-01-01T11:11" but got "2014-01-01T11:10"
     17PASS Value <= max attribute
     18FAIL Value > max attribute assert_equals: expected "2014-01-01T11:11" but got "2014-01-01T11:12"
    1919
  • trunk/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/time-2-expected.txt

    r267658 r286869  
    66PASS Valid value: value should be 00:00:00.00
    77PASS Valid value: value should be 00:00:00.000
    8 FAIL Invalid value: fraction should have one, two or three ASCII digits. Value should be empty assert_equals: expected "" but got "00:00:00.0000"
     8PASS Invalid value: fraction should have one, two or three ASCII digits. Value should be empty
    99PASS Invalid value: hour should have two ASCII digits. Value should be empty
    1010PASS Invalid value: minutes should have two ASCII digits. Value should be empty
  • trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt

    r286855 r286869  
    2020PASS [INPUT in DATETIME-LOCAL status] The required attribute is not set
    2121PASS [INPUT in DATETIME-LOCAL status] Valid local date and time string(2000-12-10T12:00:00)
    22 FAIL [INPUT in DATETIME-LOCAL status] Valid local date and time string(2000-12-10 12:00) assert_false: The validity.valueMissing should be false. expected false got true
     22PASS [INPUT in DATETIME-LOCAL status] Valid local date and time string(2000-12-10 12:00)
    2323PASS [INPUT in DATETIME-LOCAL status] Valid local date and time string(1979-10-14T12:00:00.001)
    2424PASS [INPUT in DATETIME-LOCAL status] The value attribute is a number(1234567)
    2525PASS [INPUT in DATETIME-LOCAL status] The value attribute is a Date object
    2626PASS [INPUT in DATETIME-LOCAL status] Invalid local date and time string(1979-10-99 99:99)
    27 FAIL [INPUT in DATETIME-LOCAL status] Valid local date and time string(1979-10-14 12:00:00) assert_false: The validity.valueMissing should be false. expected false got true
     27PASS [INPUT in DATETIME-LOCAL status] Valid local date and time string(1979-10-14 12:00:00)
    2828PASS [INPUT in DATETIME-LOCAL status] Invalid local date and time string(2001-12-21  12:00)-two white space
    2929PASS [INPUT in DATETIME-LOCAL status] the value attribute is a string(abc)
  • trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/datetime-local-expected.txt

    r267658 r286869  
    22PASS empty value
    33PASS datetime-local input value set to 2014-01-01T11:11:11.111 without min/max
    4 FAIL datetime-local input value set to 2014-01-01 11:11:11.111 without min/max assert_equals: expected "2014-01-01T11:11:11.111" but got ""
    5 FAIL datetime-local input value set to 2014-01-01 11:11 without min/max assert_equals: expected "2014-01-01T11:11" but got ""
    6 FAIL datetime-local input value set to 2014-01-01 00:00:00.000 without min/max assert_equals: expected "2014-01-01T00:00" but got ""
     4PASS datetime-local input value set to 2014-01-01 11:11:11.111 without min/max
     5PASS datetime-local input value set to 2014-01-01 11:11 without min/max
     6PASS datetime-local input value set to 2014-01-01 00:00:00.000 without min/max
    77PASS datetime-local input value set to 2014-01-0 11:11 without min/max
    88PASS datetime-local input value set to 2014-01-01 11:1 without min/max
     
    1313PASS invalid datetime-local input value 5
    1414PASS invalid datetime-local input value 6
    15 FAIL Value >= min attribute assert_equals: expected "2014-01-01T11:12" but got ""
    16 FAIL Value < min attribute assert_equals: expected "2014-01-01T11:11" but got ""
    17 FAIL Value <= max attribute assert_equals: expected "2014-01-01T11:10" but got ""
    18 FAIL Value > max attribute assert_equals: expected "2014-01-01T11:11" but got ""
     15PASS Value >= min attribute
     16FAIL Value < min attribute assert_equals: expected "2014-01-01T11:11" but got "2014-01-01T11:10"
     17PASS Value <= max attribute
     18FAIL Value > max attribute assert_equals: expected "2014-01-01T11:11" but got "2014-01-01T11:12"
    1919
  • trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/time-2-expected.txt

    r267658 r286869  
    66PASS Valid value: value should be 00:00:00.00
    77PASS Valid value: value should be 00:00:00.000
    8 FAIL Invalid value: fraction should have one, two or three ASCII digits. Value should be empty assert_equals: expected "" but got "00:00:00.0000"
     8PASS Invalid value: fraction should have one, two or three ASCII digits. Value should be empty
    99PASS Invalid value: hour should have two ASCII digits. Value should be empty
    1010PASS Invalid value: minutes should have two ASCII digits. Value should be empty
  • trunk/Source/WebCore/ChangeLog

    r286868 r286869  
     12021-12-10  Chris Dumez  <cdumez@apple.com>
     2
     3        Improve <type="datetime-local"> value parsing and sanitization
     4        https://bugs.webkit.org/show_bug.cgi?id=234039
     5
     6        Reviewed by Darin Adler.
     7
     8        Improve <type="datetime-local"> value parsing and sanitization.
     9
     10        Test: fast/forms/datetimelocal/datetime-local-value-sanitization.html
     11
     12        * html/BaseDateAndTimeInputType.h:
     13        * html/DateTimeLocalInputType.cpp:
     14        (WebCore::DateTimeLocalInputType::sanitizeValue const):
     15        Implement value sanitization for <type="datetime-local"> so that:
     16        - if the input uses a space as date / time separator, the sanitized value will use a 'T' instead.
     17        - The output will use the shortest possible string, omitting seconds or milliseconds when 0, as per
     18          https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-normalised-local-date-and-time-string
     19
     20        * html/DateTimeLocalInputType.h:
     21        * platform/DateComponents.cpp:
     22        (WebCore::DateComponents::parseTime):
     23        Fix bug where we would allow more than 3 digits for the millisecond part of the time (we
     24        would silently ignore follow-up digits instead of failing parsing). This is as per:
     25        - https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-time-string
     26        This was covered by one of the subtests in imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/datetime-local.html
     27
     28        (WebCore::isDateTimeLocalSeparator):
     29        (WebCore::DateComponents::parseDateTimeLocal):
     30        Allow using a space as date / time separator in <type="datetime-local">, instead of simply allowing a 'T'.
     31        This would align our behavior with Gecko and the specification:
     32        - https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-local-date-and-time-string
     33        Note that Blink still seems to only allow 'T' as separator.
     34
     35
     36        (WebCore::DateComponents::toStringForTime const):
     37        The output will use the shortest possible string, omitting seconds or milliseconds when 0, as per
     38        https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-normalised-local-date-and-time-string
     39
    1402021-12-10  Alex Christensen  <achristensen@webkit.org>
    241
  • trunk/Source/WebCore/html/BaseDateAndTimeInputType.h

    r286560 r286869  
    101101    // InputType functions:
    102102    String visibleValue() const final;
    103     String sanitizeValue(const String&) const final;
     103    String sanitizeValue(const String&) const override;
    104104    void setValue(const String&, bool valueChanged, TextFieldEventBehavior) final;
    105105    WallTime valueAsDate() const override;
  • trunk/Source/WebCore/html/DateTimeLocalInputType.cpp

    r286560 r286869  
    100100}
    101101
     102String DateTimeLocalInputType::sanitizeValue(const String& proposedValue) const
     103{
     104    if (proposedValue.isEmpty())
     105        return proposedValue;
     106
     107    auto components = DateComponents::fromParsingDateTimeLocal(proposedValue);
     108    return components ? components->toString() : emptyString();
     109}
     110
    102111String DateTimeLocalInputType::formatDateTimeFieldsState(const DateTimeFieldsState& state) const
    103112{
  • trunk/Source/WebCore/html/DateTimeLocalInputType.h

    r286560 r286869  
    5353    std::optional<DateComponents> parseToDateComponents(StringView) const final;
    5454    std::optional<DateComponents> setMillisecondToDateComponents(double) const final;
     55    String sanitizeValue(const String&) const final;
    5556
    5657    bool isValidFormat(OptionSet<DateTimeFormatValidationResults>) const final;
  • trunk/Source/WebCore/platform/DateComponents.cpp

    r281955 r286869  
    478478                        millisecond = parseInt(temporaryBuffer, 2);
    479479                        *millisecond *= 10;
    480                     } else {
    481                         // Regardless of the number of digits, we only ever parse at most 3. All other
    482                         // digits after that are ignored, but the buffer is incremented as if they were
    483                         // all parsed.
     480                    } else if (digitsLength == 3)
    484481                        millisecond = parseInt(temporaryBuffer, 3);
    485                     }
     482                    else
     483                        return false;
    486484
    487485                    // Due to the countDigits above, the parseInt calls should all be successful.
     
    503501}
    504502
     503// Gecko allows both 'T' and a space as datetime-local separator (see https://github.com/whatwg/html/issues/2276).
     504// WPT tests also expect this behavior.
     505template<typename CharacterType> static bool isDateTimeLocalSeparator(CharacterType c)
     506{
     507    return c == 'T' || c == ' ';
     508}
     509
    505510// https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#local-dates-and-times
    506511template<typename CharacterType> bool DateComponents::parseDateTimeLocal(StringParsingBuffer<CharacterType>& buffer)
     
    509514        return false;
    510515
    511     if (!skipExactly(buffer, 'T'))
     516    if (!skipExactly<isDateTimeLocalSeparator>(buffer))
    512517        return false;
    513518
     
    761766    case SecondFormat::Second:
    762767        return makeString(pad('0', 2, m_hour), ':', pad('0', 2, m_minute), ':', pad('0', 2, m_second));
    763     case SecondFormat::Millisecond:
    764         return makeString(pad('0', 2, m_hour), ':', pad('0', 2, m_minute), ':', pad('0', 2, m_second), '.', pad('0', 3, m_millisecond));
     768    case SecondFormat::Millisecond: {
     769        auto resultWithoutMilliseconds = makeString(pad('0', 2, m_hour), ':', pad('0', 2, m_minute), ':', pad('0', 2, m_second), '.');
     770        if (!(m_millisecond % 100))
     771            return makeString(resultWithoutMilliseconds, m_millisecond / 100);
     772        if (!(m_millisecond % 10))
     773            return makeString(resultWithoutMilliseconds, pad('0', 2, m_millisecond / 10));
     774        return makeString(resultWithoutMilliseconds, pad('0', 3, m_millisecond));
     775    }
    765776    }
    766777}
Note: See TracChangeset for help on using the changeset viewer.