Skip to content

Commit

Permalink
Update input[type=*]'s step base handling to match spec
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=254761
rdar://problem/107721910

Reviewed by Aditya Keerthi.

This patch aligns WebKit with Gecko / Firefox and Blink / Chromium.

Merge [1]: https://chromium.googlesource.com/chromium/src.git/+/0f836e3f330abbd76df604090db47c6e8fccd5b1

Determine the step base for an input element per spec:

Spec: https://html.spec.whatwg.org/#concept-input-min-zero

That is, consult the 'value' attribute if 'min' is not present, and
then fallback to the default step base for the input type if that
isn't present either. Previously, 'value' was not considered.

Merge [2]: https://chromium.googlesource.com/chromium/src.git/+/f0af3d9cd0b5e0b05f20cd8c4f20103f572f14ef

The HTML spec recently shifted to using 'value' as the first fallback
option for an input element's "step base" (if no 'min' attribute):

Spec: https://html.spec.whatwg.org/#concept-input-min-zero

Also bring type=range elements into line with that, including using
that step base when clamping values to the supported range.

Merge [3]: https://chromium.googlesource.com/chromium/src.git/+/807ab32fd2e5accda8c5cef2678e0e0af23158b0

According to the specification, we should not resolve step-mismatch if there are
no step-matched values in the range. So, StepRange::clampValue() should return
the minimum value or the maximum value.

Spec: https://html.spec.whatwg.org/multipage/input.html#range-state-(type%3Drange)

Merge [4]: chromium/chromium@fb67b32

The spec for stepUp()/stepDown():

Spec: https://html.spec.whatwg.org/#dom-input-stepdown

requires that out-of-step values snap to step, just like the UI
implementation will do. Hence, bring the required clamping/snapping
handling into scope.

NOTE - It matches Blink from top of tree to avoid stack overflow issue:

Stack Overflow: https://source.chromium.org/chromium/chromium/src/+/ebc1f01b3fdba6c8b1b2b1075e029cd317c685ee

* Source/WebCore/html/InputType.cpp:
(InputType::findStepBase): Add Helping function
(InputType::applyStep): Update to spec
* Source/WebCore/html/InputType.h: Helper function definition
* Source/WebCore/html/MonthInputType.cpp:
(MonthInputType::defaultValueForStepUp): Use ’findStepBase’
* Source/WebCore/html/NumberInputType.cpp:
(NumberInputType::createStepRange): Use ’findStepBase’ and remove already covered ‘NaN’ handling
* Source/WebCore/html/TimeInputType.cpp:
(TimeInputType:: createStepRange): Use ’findStepBase’
* Source/WebCore/html/WeekInputType.cpp:
(WeekInputType:: createStepRange): Use ’findStepBase’
* Source/WebCore/html/RangeInputType.cpp:
(RangeInputType::createStepRange): Use 'findStepBase'
* Source/WebCore/html/StepRange.cpp:
(StepRange::clampValue): clampValue but respect 'stepBase'
* LayoutTests/fast/forms/week/week-stepup-stepdown.html:
* LayoutTests/fast/forms/time/time-stepup-stepdown.html:
* LayoutTests/fast/forms/range/range-stepup-stepdown.html: Removed duplicate tests as well
* LayoutTests/fast/forms/number/number-stepup-stepdown.html: Ditto
* LayoutTests/fast/forms/month/month-stepup-stepdown.html:
* LayoutTests/fast/forms/datetimelocal/datetimelocal-stepup-stepdown.html:
* LayoutTests/fast/forms/date/date-stepup-stepdown.html:
* LayoutTests/fast/forms/date/date-stepup-stepdown-expected.txt: Rebaselined
* LayoutTests/fast/forms/datetimelocal/datetimelocal-stepup-stepdown-expected.txt: Ditto
* LayoutTests/fast/forms/month/month-stepup-stepdown-expected.txt: Ditto
* LayoutTests/fast/forms/range/range-stepup-stepdown-expected.txt: Ditto
* LayoutTests/fast/forms/time/time-stepup-stepdown-expected.txt: Fail Tests also fail in Blink
* LayoutTests/fast/forms/week/week-stepup-stepdown-expected.txt: Rebaselined
* LayoutTests/fast/forms/number/number-stepup-stepdown-expected.txt: Rebaselined
* LayoutTests/fast/forms/date/input-date-validation-message.html: Rebaselined

Canonical link: https://commits.webkit.org/280127@main
  • Loading branch information
Ahmad-S792 authored and Ahmad Saleem committed Jun 18, 2024
1 parent 118f42b commit 5b73f8e
Show file tree
Hide file tree
Showing 26 changed files with 291 additions and 740 deletions.
5 changes: 3 additions & 2 deletions LayoutTests/fast/forms/date/date-stepup-stepdown-expected.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Check stepUp() and stepDown() bahevior for type=date.
Check stepUp() and stepDown() behavior for type=date.

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".

Expand All @@ -14,6 +14,7 @@ PASS stepDown("2010-02-10", null, null, "foo") is "2010-02-10"
PASS stepUp("2010-02-10", null, null, null) is "2010-02-10"
PASS stepDown("2010-02-10", null, null, null) is "2010-02-10"
Normal cases
PASS stepDown("1970-01-04", "2", null) is "1970-01-03"
PASS stepUp("2010-02-10", null, null) is "2010-02-11"
PASS stepDown("2010-02-10", null, null) is "2010-02-09"
PASS stepUp("2010-02-10", null, null, 10) is "2010-02-20"
Expand All @@ -24,7 +25,7 @@ Step=any
PASS stepUp("2010-02-10", "any", null) threw exception InvalidStateError: The object is in an invalid state..
PASS stepDown("2010-02-10", "any", null) threw exception InvalidStateError: The object is in an invalid state..
Overflow/underflow
PASS stepUp("2010-02-10", "3.40282346e+38", null) is "2010-02-10"
PASS stepUp("2010-02-10", "3.40282346e+38", null) is "1970-01-01"
PASS stepDown("2010-02-10", "3.40282346e+38", null) is "1970-01-01"
PASS stepUp("2010-02-10", "1", "2010-02-10") is "2010-02-10"
PASS stepDown("2010-02-10", "1", "2010-02-10") is "2010-02-10"
Expand Down
46 changes: 23 additions & 23 deletions LayoutTests/fast/forms/date/date-stepup-stepdown.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<script src="../../../resources/js-test-pre.js"></script>
<script src="../../../resources/js-test.js"></script>
</head>
<body>
<p id="description"></p>
<div id="console"></div>
<script>
description('Check stepUp() and stepDown() bahevior for type=date.');
description('Check stepUp() and stepDown() behavior for type=date.');

var input = document.createElement('input');

Expand Down Expand Up @@ -38,33 +38,33 @@

input.type = 'date';
debug('Invalid value');
shouldBe('stepUp("", null, null)', '"1970-01-02"');
shouldBe('stepDown("", null, null)', '"1969-12-31"');
shouldBeEqualToString('stepUp("", null, null)', '1970-01-02');
shouldBeEqualToString('stepDown("", null, null)', '1969-12-31');
debug('Non-number arguments');
shouldBe('stepUp("2010-02-10", null, null, "0")', '"2010-02-10"');
shouldBe('stepDown("2010-02-10", null, null, "0")', '"2010-02-10"');
shouldBe('stepUp("2010-02-10", null, null, "foo")', '"2010-02-10"');
shouldBe('stepDown("2010-02-10", null, null, "foo")', '"2010-02-10"');
shouldBe('stepUp("2010-02-10", null, null, null)', '"2010-02-10"');
shouldBe('stepDown("2010-02-10", null, null, null)', '"2010-02-10"');
shouldBeEqualToString('stepUp("2010-02-10", null, null, "0")', '2010-02-10');
shouldBeEqualToString('stepDown("2010-02-10", null, null, "0")', '2010-02-10');
shouldBeEqualToString('stepUp("2010-02-10", null, null, "foo")', '2010-02-10');
shouldBeEqualToString('stepDown("2010-02-10", null, null, "foo")', '2010-02-10');
shouldBeEqualToString('stepUp("2010-02-10", null, null, null)', '2010-02-10');
shouldBeEqualToString('stepDown("2010-02-10", null, null, null)', '2010-02-10');
debug('Normal cases');
shouldBe('stepUp("2010-02-10", null, null)', '"2010-02-11"');
shouldBe('stepDown("2010-02-10", null, null)', '"2010-02-09"');
shouldBe('stepUp("2010-02-10", null, null, 10)', '"2010-02-20"');
shouldBe('stepDown("2010-02-10", null, null, 11)', '"2010-01-30"');
shouldBe('stepUp("1970-01-01", "4", null, 2)', '"1970-01-09"');
shouldBe('stepDown("1970-01-01", "4", null, 3)', '"1969-12-20"');
shouldBeEqualToString('stepDown("1970-01-04", "2", null)', '1970-01-03');
shouldBeEqualToString('stepUp("2010-02-10", null, null)', '2010-02-11');
shouldBeEqualToString('stepDown("2010-02-10", null, null)', '2010-02-09');
shouldBeEqualToString('stepUp("2010-02-10", null, null, 10)', '2010-02-20');
shouldBeEqualToString('stepDown("2010-02-10", null, null, 11)', '2010-01-30');
shouldBeEqualToString('stepUp("1970-01-01", "4", null, 2)', '1970-01-09');
shouldBeEqualToString('stepDown("1970-01-01", "4", null, 3)', '1969-12-20');
debug('Step=any');
shouldThrowErrorName('stepUp("2010-02-10", "any", null)', "InvalidStateError");
shouldThrowErrorName('stepDown("2010-02-10", "any", null)', "InvalidStateError");
shouldThrow('stepUp("2010-02-10", "any", null)');
shouldThrow('stepDown("2010-02-10", "any", null)');
debug('Overflow/underflow');
shouldBe('stepUp("2010-02-10", "3.40282346e+38", null)', '"2010-02-10"');
shouldBe('stepDown("2010-02-10", "3.40282346e+38", null)', '"1970-01-01"');
shouldBe('stepUp("2010-02-10", "1", "2010-02-10")', '"2010-02-10"');
shouldBe('stepDown("2010-02-10", "1", "2010-02-10")', '"2010-02-10"');
shouldBeEqualToString('stepUp("2010-02-10", "3.40282346e+38", null)', '1970-01-01');
shouldBeEqualToString('stepDown("2010-02-10", "3.40282346e+38", null)', '1970-01-01');
shouldBeEqualToString('stepUp("2010-02-10", "1", "2010-02-10")', '2010-02-10');
shouldBeEqualToString('stepDown("2010-02-10", "1", "2010-02-10")', '2010-02-10');

debug('');
</script>
<script src="../../../resources/js-test-post.js"></script>
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ PASS testIt("1982-11-02", "", "1970-12-31") is "Value must be less than or equal
Range underflow
PASS testIt("1982-11-02", "1990-05-25", "1990-12-24") is "Value must be greater than or equal to 1990-05-25"
Step mismatch
PASS testIt("1982-11-02", "", "", "123") is "Enter a valid value"
PASS testIt("1982-11-02", "", "", "123") is ""
PASS successfullyParsed is true

TEST COMPLETE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
shouldBeEqualToString('testIt("1982-11-02", "1990-05-25", "1990-12-24")', 'Value must be greater than or equal to 1990-05-25');

debug('Step mismatch')
shouldBeEqualToString('testIt("1982-11-02", "", "", "123")', 'Enter a valid value');
shouldBeEqualToString('testIt("1982-11-02", "", "", "123")', '');

</script>
</body>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Check stepUp() and stepDown() bahevior for type=datetime-local.
Check stepUp() and stepDown() behavior for type=datetime-local.

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".

Expand All @@ -24,7 +24,7 @@ Step=any
PASS stepUp("2010-02-10T20:13", "any", null) threw exception InvalidStateError: The object is in an invalid state..
PASS stepDown("2010-02-10T20:13", "any", null) threw exception InvalidStateError: The object is in an invalid state..
Overflow/underflow
PASS stepUp("2010-02-10T20:13", "3.40282346e+38", null) is "2010-02-10T20:13"
PASS stepUp("2010-02-10T20:13", "3.40282346e+38", null) is "1970-01-01T00:00"
PASS stepDown("2010-02-10T20:13", "3.40282346e+38", null) is "1970-01-01T00:00"
PASS stepUp("2010-02-10T20:13", "1", "2010-02-10T20:13") is "2010-02-10T20:13"
PASS stepDown("2010-02-10T20:13", "1", "2010-02-10T20:13") is "2010-02-10T20:13"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<script src="../../../resources/js-test-pre.js"></script>
<script src="../../../resources/js-test.js"></script>
</head>
<body>
<p id="description"></p>
<div id="console"></div>
<script>
description('Check stepUp() and stepDown() bahevior for type=datetime-local.');
description('Check stepUp() and stepDown() behavior for type=datetime-local.');

var input = document.createElement('input');

Expand Down Expand Up @@ -38,31 +38,30 @@

input.type = 'datetime-local';
debug('Invalid value');
shouldBe('stepUp("", null, null)', '"1970-01-01T00:01"');
shouldBe('stepDown("", null, null)', '"1969-12-31T23:59"');
shouldBeEqualToString('stepUp("", null, null)', '1970-01-01T00:01');
shouldBeEqualToString('stepDown("", null, null)', '1969-12-31T23:59');
debug('Non-number arguments');
shouldBe('stepUp("2010-02-10T20:13", null, null, "0")', '"2010-02-10T20:13"');
shouldBe('stepDown("2010-02-10T20:13", null, null, "0")', '"2010-02-10T20:13"');
shouldBe('stepUp("2010-02-10T20:13", null, null, "foo")', '"2010-02-10T20:13"');
shouldBe('stepDown("2010-02-10T20:13", null, null, "foo")', '"2010-02-10T20:13"');
shouldBe('stepUp("2010-02-10T20:13", null, null, null)', '"2010-02-10T20:13"');
shouldBe('stepDown("2010-02-10T20:13", null, null, null)', '"2010-02-10T20:13"');
shouldBeEqualToString('stepUp("2010-02-10T20:13", null, null, "0")', '2010-02-10T20:13');
shouldBeEqualToString('stepDown("2010-02-10T20:13", null, null, "0")', '2010-02-10T20:13');
shouldBeEqualToString('stepUp("2010-02-10T20:13", null, null, "foo")', '2010-02-10T20:13');
shouldBeEqualToString('stepDown("2010-02-10T20:13", null, null, "foo")', '2010-02-10T20:13');
shouldBeEqualToString('stepUp("2010-02-10T20:13", null, null, null)', '2010-02-10T20:13');
shouldBeEqualToString('stepDown("2010-02-10T20:13", null, null, null)', '2010-02-10T20:13');
debug('Normal cases');
shouldBe('stepUp("2010-02-10T20:13", null, null)', '"2010-02-10T20:14"');
shouldBe('stepDown("2010-02-10T20:13", null, null)', '"2010-02-10T20:12"');
shouldBe('stepUp("2010-02-10T20:13", null, null, 10)', '"2010-02-10T20:23"');
shouldBe('stepDown("2010-02-10T20:13", null, null, 11)', '"2010-02-10T20:02"');
shouldBe('stepUp("1970-01-01T20:13", "4", null, 2)', '"1970-01-01T20:13:08"');
shouldBe('stepDown("1970-01-01T20:13", "4", null, 3)', '"1970-01-01T20:12:48"');
shouldBeEqualToString('stepUp("2010-02-10T20:13", null, null)', '2010-02-10T20:14');
shouldBeEqualToString('stepDown("2010-02-10T20:13", null, null)', '2010-02-10T20:12');
shouldBeEqualToString('stepUp("2010-02-10T20:13", null, null, 10)', '2010-02-10T20:23');
shouldBeEqualToString('stepDown("2010-02-10T20:13", null, null, 11)', '2010-02-10T20:02');
shouldBeEqualToString('stepUp("1970-01-01T20:13", "4", null, 2)', '1970-01-01T20:13:08');
shouldBeEqualToString('stepDown("1970-01-01T20:13", "4", null, 3)', '1970-01-01T20:12:48');
debug('Step=any');
shouldThrowErrorName('stepUp("2010-02-10T20:13", "any", null)', "InvalidStateError");
shouldThrowErrorName('stepDown("2010-02-10T20:13", "any", null)', "InvalidStateError");
shouldThrow('stepUp("2010-02-10T20:13", "any", null)');
shouldThrow('stepDown("2010-02-10T20:13", "any", null)');
debug('Overflow/underflow');
shouldBe('stepUp("2010-02-10T20:13", "3.40282346e+38", null)', '"2010-02-10T20:13"');
shouldBe('stepDown("2010-02-10T20:13", "3.40282346e+38", null)', '"1970-01-01T00:00"');
shouldBe('stepUp("2010-02-10T20:13", "1", "2010-02-10T20:13")', '"2010-02-10T20:13"');
shouldBe('stepDown("2010-02-10T20:13", "1", "2010-02-10T20:13")', '"2010-02-10T20:13"');
shouldBeEqualToString('stepUp("2010-02-10T20:13", "3.40282346e+38", null)', '1970-01-01T00:00');
shouldBeEqualToString('stepDown("2010-02-10T20:13", "3.40282346e+38", null)', '1970-01-01T00:00');
shouldBeEqualToString('stepUp("2010-02-10T20:13", "1", "2010-02-10T20:13")', '2010-02-10T20:13');
shouldBeEqualToString('stepDown("2010-02-10T20:13", "1", "2010-02-10T20:13")', '2010-02-10T20:13');
</script>
<script src="../../../resources/js-test-post.js"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Check stepUp() and stepDown() bahevior for type=month.
Check stepUp() and stepDown() behavior for type=month.

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".

Expand All @@ -24,7 +24,7 @@ Step=any
PASS stepUp("2010-02", "any", null) threw exception InvalidStateError: The object is in an invalid state..
PASS stepDown("2010-02", "any", null) threw exception InvalidStateError: The object is in an invalid state..
Overflow/underflow
PASS stepUp("2010-02", "3.40282346e+38", null) is "2010-02"
PASS stepUp("2010-02", "3.40282346e+38", null) is "1970-01"
PASS stepDown("2010-02", "3.40282346e+38", null) is "1970-01"
PASS stepUp("2010-02", "1", "2010-02") is "2010-02"
PASS stepDown("2010-02", "1", "2010-02") is "2010-02"
Expand Down
45 changes: 22 additions & 23 deletions LayoutTests/fast/forms/month/month-stepup-stepdown.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<script src="../../../resources/js-test-pre.js"></script>
<script src="../../../resources/js-test.js"></script>
</head>
<body>
<p id="description"></p>
<div id="console"></div>
<script>
description('Check stepUp() and stepDown() bahevior for type=month.');
description('Check stepUp() and stepDown() behavior for type=month.');

var input = document.createElement('input');

Expand Down Expand Up @@ -38,33 +38,32 @@

input.type = 'month';
debug('Invalid value');
shouldBe('stepUp("", null, null)', '"1970-02"');
shouldBe('stepDown("", null, null)', '"1969-12"');
shouldBeEqualToString('stepUp("", null, null)', '1970-02');
shouldBeEqualToString('stepDown("", null, null)', '1969-12');
debug('Non-number arguments');
shouldBe('stepUp("2010-02", null, null, "0")', '"2010-02"');
shouldBe('stepDown("2010-02", null, null, "0")', '"2010-02"');
shouldBe('stepUp("2010-02", null, null, "foo")', '"2010-02"');
shouldBe('stepDown("2010-02", null, null, "foo")', '"2010-02"');
shouldBe('stepUp("2010-02", null, null, null)', '"2010-02"');
shouldBe('stepDown("2010-02", null, null, null)', '"2010-02"');
shouldBeEqualToString('stepUp("2010-02", null, null, "0")', '2010-02');
shouldBeEqualToString('stepDown("2010-02", null, null, "0")', '2010-02');
shouldBeEqualToString('stepUp("2010-02", null, null, "foo")', '2010-02');
shouldBeEqualToString('stepDown("2010-02", null, null, "foo")', '2010-02');
shouldBeEqualToString('stepUp("2010-02", null, null, null)', '2010-02');
shouldBeEqualToString('stepDown("2010-02", null, null, null)', '2010-02');
debug('Normal cases');
shouldBe('stepUp("2010-02", null, null)', '"2010-03"');
shouldBe('stepDown("2010-02", null, null)', '"2010-01"');
shouldBe('stepUp("2010-02", null, null, 10)', '"2010-12"');
shouldBe('stepDown("2010-02", null, null, 11)', '"2009-03"');
shouldBe('stepUp("1970-01", "4", null, 2)', '"1970-09"');
shouldBe('stepDown("1970-01", "4", null, 3)', '"1969-01"');
shouldBeEqualToString('stepUp("2010-02", null, null)', '2010-03');
shouldBeEqualToString('stepDown("2010-02", null, null)', '2010-01');
shouldBeEqualToString('stepUp("2010-02", null, null, 10)', '2010-12');
shouldBeEqualToString('stepDown("2010-02", null, null, 11)', '2009-03');
shouldBeEqualToString('stepUp("1970-01", "4", null, 2)', '1970-09');
shouldBeEqualToString('stepDown("1970-01", "4", null, 3)', '1969-01');
debug('Step=any');
shouldThrowErrorName('stepUp("2010-02", "any", null)', "InvalidStateError");
shouldThrowErrorName('stepDown("2010-02", "any", null)', "InvalidStateError");
shouldThrow('stepUp("2010-02", "any", null)');
shouldThrow('stepDown("2010-02", "any", null)');
debug('Overflow/underflow');
shouldBe('stepUp("2010-02", "3.40282346e+38", null)', '"2010-02"');
shouldBe('stepDown("2010-02", "3.40282346e+38", null)', '"1970-01"');
shouldBe('stepUp("2010-02", "1", "2010-02")', '"2010-02"');
shouldBe('stepDown("2010-02", "1", "2010-02")', '"2010-02"');
shouldBeEqualToString('stepUp("2010-02", "3.40282346e+38", null)', '1970-01');
shouldBeEqualToString('stepDown("2010-02", "3.40282346e+38", null)', '1970-01');
shouldBeEqualToString('stepUp("2010-02", "1", "2010-02")', '2010-02');
shouldBeEqualToString('stepDown("2010-02", "1", "2010-02")', '2010-02');

debug('');
</script>
<script src="../../../resources/js-test-post.js"></script>
</body>
</html>
Loading

0 comments on commit 5b73f8e

Please sign in to comment.