From a457ebeec50081686cb59a335bbf2e9f34cfcda6 Mon Sep 17 00:00:00 2001 From: Shannon Booth Date: Wed, 19 Mar 2025 01:47:23 +1300 Subject: [PATCH] LibWeb/HTML: Implement 'convert string to number' for datetime-local --- Libraries/LibWeb/HTML/HTMLInputElement.cpp | 26 +++++++++++++++++++ .../the-input-element/input-valueasnumber.txt | 8 +++--- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Libraries/LibWeb/HTML/HTMLInputElement.cpp index ac12a592431..8e02be0eb50 100644 --- a/Libraries/LibWeb/HTML/HTMLInputElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLInputElement.cpp @@ -2308,6 +2308,29 @@ static String convert_number_to_time_string(double input) return MUST(String::formatted("{:02d}:{:02d}", JS::hour_from_time(input), JS::min_from_time(input))); } +// https://html.spec.whatwg.org/multipage/input.html#local-date-and-time-state-(type=datetime-local):concept-input-value-number-string +static String convert_number_to_local_date_and_time_string(double input) +{ + // The algorithm to convert a number to a string, given a number input, is as follows: Return a valid + // normalized local date and time string that represents the date and time that is input milliseconds + // after midnight on the morning of 1970-01-01 (the time represented by the value "1970-01-01T00:00:00.0"). + auto year = JS::year_from_time(input); + auto month = JS::month_from_time(input) + 1; // Adjust for zero-based month + auto day = JS::date_from_time(input); + auto hour = JS::hour_from_time(input); + auto minutes = JS::min_from_time(input); + auto seconds = JS::sec_from_time(input); + auto milliseconds = JS::ms_from_time(input); + + if (seconds > 0) { + if (milliseconds > 0) + return MUST(String::formatted("{:04d}-{:02d}-{:02d}T{:02d}:{:02d}:{:02d}.{:03d}", year, month, day, hour, minutes, seconds, milliseconds)); + return MUST(String::formatted("{:04d}-{:02d}-{:02d}T{:02d}:{:02d}:{:02d}", year, month, day, hour, minutes, seconds)); + } + + return MUST(String::formatted("{:04d}-{:02d}-{:02d}T{:02d}:{:02d}", year, month, day, hour, minutes)); +} + // https://html.spec.whatwg.org/multipage/input.html#concept-input-value-string-number String HTMLInputElement::convert_number_to_string(double input) const { @@ -2331,6 +2354,9 @@ String HTMLInputElement::convert_number_to_string(double input) const if (type_state() == TypeAttributeState::Time) return convert_number_to_time_string(input); + if (type_state() == TypeAttributeState::LocalDateAndTime) + return convert_number_to_local_date_and_time_string(input); + dbgln("HTMLInputElement::convert_number_to_string() not implemented for input type {}", type()); return {}; } diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-input-element/input-valueasnumber.txt b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-input-element/input-valueasnumber.txt index 34d9e60bbfb..edde99ed0dc 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-input-element/input-valueasnumber.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/forms/the-input-element/input-valueasnumber.txt @@ -2,8 +2,8 @@ Harness status: OK Found 60 tests -54 Pass -6 Fail +56 Pass +4 Fail Pass valueAsNumber getter on type date (actual value: , expected valueAsNumber: NaN) Pass valueAsNumber getter on type date (actual value: 0000-12-10, expected valueAsNumber: NaN) Pass valueAsNumber getter on type date (actual value: 2019-00-12, expected valueAsNumber: NaN) @@ -43,8 +43,8 @@ Pass valueAsNumber setter on type time (actual valueAsNumber: 86340000, expected Pass valueAsNumber getter on type datetime-local (actual value: , expected valueAsNumber: NaN) Fail valueAsNumber getter on type datetime-local (actual value: 2019-12-10T00:00, expected valueAsNumber: 1575936000000) Fail valueAsNumber getter on type datetime-local (actual value: 2019-12-10T12:00, expected valueAsNumber: 1575979200000) -Fail valueAsNumber setter on type datetime-local (actual valueAsNumber: 1575936000000, expected value: 2019-12-10T00:00) -Fail valueAsNumber setter on type datetime-local (actual valueAsNumber: 1575979200000, expected value: 2019-12-10T12:00) +Pass valueAsNumber setter on type datetime-local (actual valueAsNumber: 1575936000000, expected value: 2019-12-10T00:00) +Pass valueAsNumber setter on type datetime-local (actual valueAsNumber: 1575979200000, expected value: 2019-12-10T12:00) Pass valueAsNumber getter on type number (actual value: , expected valueAsNumber: NaN) Pass valueAsNumber getter on type number (actual value: 123, expected valueAsNumber: 123) Pass valueAsNumber getter on type number (actual value: 123.456, expected valueAsNumber: 123.456)