input[type=number] does not increment/decrement integers with trailing decimal characters
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Nov 2015 07:21:41 +0000 (07:21 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Nov 2015 07:21:41 +0000 (07:21 +0000)
https://bugs.webkit.org/show_bug.cgi?id=148867
rdar://problem/22589693

Patch by Keith Rollin <krollin@apple.com> on 2015-11-02
Reviewed by Chris Dumez.

Source/WebCore:

Support input[type=number].value attributes of the form "###." (that
is, leading digits with a decimal but no trailing digits). This form
was supported in the setting of the attribute, but not when changing
it through stepUp/Down.

Testing turned up similarly incorrect processing of -.###, so
addressed that, too.

Test: fast/forms/range/input-appearance-range-decimals.html

Updated the following tests:
- fast/forms/number/number-stepup-stepdown-from-renderer.html
- fast/forms/number/number-stepup-stepdown.html
- fast/forms/range/range-stepup-stepdown-from-renderer.html
- fast/forms/range/range-stepup-stepdown.html

* html/InputType.cpp:
(WebCore::InputType::stepUpFromRenderer):
* platform/Decimal.cpp:
(WebCore::Decimal::fromString):

LayoutTests:

New tests for input[type=number].skipUp/Down when .value ends in a
decimal point (with no additional trailing digits). Also some coverage
for input[type=range] which shares some same code.

* fast/forms/number/number-stepup-stepdown-expected.txt:
* fast/forms/number/number-stepup-stepdown-from-renderer-expected.txt:
* fast/forms/number/number-stepup-stepdown-from-renderer.html:
* fast/forms/number/number-stepup-stepdown.html:
* fast/forms/range/range-stepup-stepdown-expected.txt:
* fast/forms/range/range-stepup-stepdown-from-renderer-expected.txt:
* fast/forms/range/range-stepup-stepdown-from-renderer.html:
* fast/forms/range/range-stepup-stepdown.html:
* fast/forms/range/input-appearance-range-decimals-expected.html: Added
* fast/forms/range/input-appearance-range-decimals.html: Added

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@191940 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/forms/number/number-stepup-stepdown-expected.txt
LayoutTests/fast/forms/number/number-stepup-stepdown-from-renderer-expected.txt
LayoutTests/fast/forms/number/number-stepup-stepdown-from-renderer.html
LayoutTests/fast/forms/number/number-stepup-stepdown.html
LayoutTests/fast/forms/range/input-appearance-range-decimals-expected.html [new file with mode: 0644]
LayoutTests/fast/forms/range/input-appearance-range-decimals.html [new file with mode: 0644]
LayoutTests/fast/forms/range/range-stepup-stepdown-expected.txt
LayoutTests/fast/forms/range/range-stepup-stepdown-from-renderer-expected.txt
LayoutTests/fast/forms/range/range-stepup-stepdown-from-renderer.html
LayoutTests/fast/forms/range/range-stepup-stepdown.html
Source/WebCore/ChangeLog
Source/WebCore/html/InputType.cpp
Source/WebCore/platform/Decimal.cpp

index 12006cc..6f244e1 100644 (file)
@@ -1,3 +1,26 @@
+2015-11-02  Keith Rollin  <krollin@apple.com>
+
+        input[type=number] does not increment/decrement integers with trailing decimal characters
+        https://bugs.webkit.org/show_bug.cgi?id=148867
+        rdar://problem/22589693
+
+        Reviewed by Chris Dumez.
+
+        New tests for input[type=number].skipUp/Down when .value ends in a
+        decimal point (with no additional trailing digits). Also some coverage
+        for input[type=range] which shares some same code.
+
+        * fast/forms/number/number-stepup-stepdown-expected.txt:
+        * fast/forms/number/number-stepup-stepdown-from-renderer-expected.txt:
+        * fast/forms/number/number-stepup-stepdown-from-renderer.html:
+        * fast/forms/number/number-stepup-stepdown.html:
+        * fast/forms/range/range-stepup-stepdown-expected.txt:
+        * fast/forms/range/range-stepup-stepdown-from-renderer-expected.txt:
+        * fast/forms/range/range-stepup-stepdown-from-renderer.html:
+        * fast/forms/range/range-stepup-stepdown.html:
+        * fast/forms/range/input-appearance-range-decimals-expected.html: Added
+        * fast/forms/range/input-appearance-range-decimals.html: Added
+
 2015-11-02  Myles C. Maxfield  <mmaxfield@apple.com>
 
         [Cocoa] Fix tests
index 6141c36..c7b153d 100644 (file)
@@ -4,9 +4,11 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 
 
 Number type
+
 Invalid value
 PASS stepUp("", null, null) threw exception Error: InvalidStateError: DOM Exception 11.
 PASS stepDown("", null, null) threw exception Error: InvalidStateError: DOM Exception 11.
+
 Non-number arguments
 PASS stepUp("0", null, null, "0") is "0"
 PASS stepDown("0", null, null, "0") is "0"
@@ -14,6 +16,7 @@ PASS stepUp("0", null, null, "foo") is "0"
 PASS stepDown("0", null, null, "foo") is "0"
 PASS stepUp("0", null, null, null) is "0"
 PASS stepDown("0", null, null, null) is "0"
+
 Normal cases
 PASS stepUp("0", null, null) is "1"
 PASS stepUp("1", null, null, 2) is "3"
@@ -21,19 +24,121 @@ PASS stepUp("3", null, null, -1) is "2"
 PASS stepDown("2", null, null) is "1"
 PASS stepDown("1", null, null, 2) is "-1"
 PASS stepDown("-1", null, null, -1) is "0"
+
+Fractional cases
+PASS stepUp("0.1", 1, null) is "1.1"
+PASS stepUp("0.2", 1, null) is "1.2"
+PASS stepUp("1.0", 1, null) is "2"
+PASS stepUp("1.1", 1, null) is "2.1"
+PASS stepUp("1.2", 1, null) is "2.2"
+PASS stepUp("2.0", 1, null) is "3"
+
+PASS stepUp("-0.1", 1, null) is "0.9"
+PASS stepUp("-0.2", 1, null) is "0.8"
+PASS stepUp("-1.0", 1, null) is "0"
+PASS stepUp("-1.1", 1, null) is "-0.1"
+PASS stepUp("-1.2", 1, null) is "-0.2"
+PASS stepUp("-2.0", 1, null) is "-1"
+
+PASS stepDown("0.1", 1, null) is "-0.9"
+PASS stepDown("0.2", 1, null) is "-0.8"
+PASS stepDown("1.0", 1, null) is "0"
+PASS stepDown("1.1", 1, null) is "0.1"
+PASS stepDown("1.2", 1, null) is "0.2"
+PASS stepDown("2.0", 1, null) is "1"
+
+PASS stepDown("-0.1", 1, null) is "-1.1"
+PASS stepDown("-0.2", 1, null) is "-1.2"
+PASS stepDown("-1.0", 1, null) is "-2"
+PASS stepDown("-1.1", 1, null) is "-2.1"
+PASS stepDown("-1.2", 1, null) is "-2.2"
+PASS stepDown("-2.0", 1, null) is "-3"
+
+PASS stepUp(".1", 1, null) is "1.1"
+PASS stepUp(".2", 1, null) is "1.2"
+PASS stepUp("1.", 1, null) is "2"
+PASS stepUp("2.", 1, null) is "3"
+
+PASS stepUp("-.1", 1, null) is "0.9"
+PASS stepUp("-.2", 1, null) is "0.8"
+PASS stepUp("-1.", 1, null) is "0"
+PASS stepUp("-2.", 1, null) is "-1"
+
+PASS stepDown(".1", 1, null) is "-0.9"
+PASS stepDown(".2", 1, null) is "-0.8"
+PASS stepDown("1.", 1, null) is "0"
+PASS stepDown("2.", 1, null) is "1"
+
+PASS stepDown("-.1", 1, null) is "-1.1"
+PASS stepDown("-.2", 1, null) is "-1.2"
+PASS stepDown("-1.", 1, null) is "-2"
+PASS stepDown("-2.", 1, null) is "-3"
+
+PASS stepUp("0.1", .1, null) is "0.2"
+PASS stepUp("0.2", .1, null) is "0.3"
+PASS stepUp("1.0", .1, null) is "1.1"
+PASS stepUp("1.1", .1, null) is "1.2"
+PASS stepUp("1.2", .1, null) is "1.3"
+PASS stepUp("2.0", .1, null) is "2.1"
+
+PASS stepUp("-0.1", .1, null) is "0"
+PASS stepUp("-0.2", .1, null) is "-0.1"
+PASS stepUp("-1.0", .1, null) is "-0.9"
+PASS stepUp("-1.1", .1, null) is "-1"
+PASS stepUp("-1.2", .1, null) is "-1.1"
+PASS stepUp("-2.0", .1, null) is "-1.9"
+
+PASS stepDown("0.1", .1, null) is "0"
+PASS stepDown("0.2", .1, null) is "0.1"
+PASS stepDown("1.0", .1, null) is "0.9"
+PASS stepDown("1.1", .1, null) is "1"
+PASS stepDown("1.2", .1, null) is "1.1"
+PASS stepDown("2.0", .1, null) is "1.9"
+
+PASS stepDown("-0.1", .1, null) is "-0.2"
+PASS stepDown("-0.2", .1, null) is "-0.3"
+PASS stepDown("-1.0", .1, null) is "-1.1"
+PASS stepDown("-1.1", .1, null) is "-1.2"
+PASS stepDown("-1.2", .1, null) is "-1.3"
+PASS stepDown("-2.0", .1, null) is "-2.1"
+
+PASS stepUp(".1", .1, null) is "0.2"
+PASS stepUp(".2", .1, null) is "0.3"
+PASS stepUp("1.", .1, null) is "1.1"
+PASS stepUp("2.", .1, null) is "2.1"
+
+PASS stepUp("-.1", .1, null) is "0"
+PASS stepUp("-.2", .1, null) is "-0.1"
+PASS stepUp("-1.", .1, null) is "-0.9"
+PASS stepUp("-2.", .1, null) is "-1.9"
+
+PASS stepDown(".1", .1, null) is "0"
+PASS stepDown(".2", .1, null) is "0.1"
+PASS stepDown("1.", .1, null) is "0.9"
+PASS stepDown("2.", .1, null) is "1.9"
+
+PASS stepDown("-.1", .1, null) is "-0.2"
+PASS stepDown("-.2", .1, null) is "-0.3"
+PASS stepDown("-1.", .1, null) is "-1.1"
+PASS stepDown("-2.", .1, null) is "-2.1"
+
 Extra arguments
 PASS input.value = "0"; input.min = null; input.step = null; input.stepUp(1, 2); input.value is "1"
 PASS input.value = "1"; input.stepDown(1, 3); input.value is "0"
+
 Invalid step value
 PASS stepUp("0", "foo", null) is "1"
 PASS stepUp("1", "0", null) is "2"
 PASS stepUp("2", "-1", null) is "3"
+
 Step=any
 PASS stepUp("0", "any", null) threw exception Error: InvalidStateError: DOM Exception 11.
 PASS stepDown("0", "any", null) threw exception Error: InvalidStateError: DOM Exception 11.
+
 Step=any corner case
 PASS stepUpExplicitBounds("0", "100", "any", "1.5", "1") threw exception Error: InvalidStateError: DOM Exception 11.
 PASS stepDownExplicitBounds("0", "100", "any", "1.5", "1") threw exception Error: InvalidStateError: DOM Exception 11.
+
 Overflow/underflow
 PASS stepDown("1", "1", "0") is "0"
 PASS stepDown("0", "1", "0") threw exception Error: InvalidStateError: DOM Exception 11.
@@ -45,21 +150,25 @@ PASS stepUp("0", "1", "0") threw exception Error: InvalidStateError: DOM Excepti
 PASS stepUp("-1", "1", "0", 2) threw exception Error: InvalidStateError: DOM Exception 11.
 PASS input.value is "-1"
 PASS stepUp("1", "3.40282346e+38", "", 2) threw exception Error: InvalidStateError: DOM Exception 11.
+
 stepDown()/stepUp() for stepMismatch values
 PASS stepUp("1", "2", "") is "3"
 PASS input.stepDown(); input.value is "1"
 PASS input.min = "0"; stepUp("9", "10", "", 9) is "99"
 PASS stepDown("19", "10", "0") is "9"
 PASS stepUp("89", "10", "99") is "99"
+
 Huge value and small step
 PASS input.min = ""; stepUp("1e+38", "1", "", 999999) is "1e+38"
 PASS input.max = ""; stepDown("1e+38", "1", "", 999999) is "1e+38"
+
 Fractional numbers
 PASS input.min = ""; stepUp("0", "0.33333333333333333", "", 3) is "1"
 PASS stepUp("1", "0.1", "", 10) is "2"
 PASS input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.value is "3"
 PASS input.min = "0"; stepUp("0", "0.003921568627450980", "1", 255) is "1"
 PASS for (var i = 0; i < 255; i++) { input.stepDown(); }; input.value is "0"
+
 Rounding
 PASS stepUp("5.005", "0.005", "", 2) is "5.015"
 PASS stepUp("5.005", "0.005", "", 11) is "5.06"
@@ -67,6 +176,7 @@ PASS stepUp("5.005", "0.005", "", 12) is "5.065"
 PASS stepUpExplicitBounds("4", "9", "0.005", "5.005", 2) is "5.015"
 PASS stepUpExplicitBounds("4", "9", "0.005", "5.005", 11) is "5.06"
 PASS stepUpExplicitBounds("4", "9", "0.005", "5.005", 12) is "5.065"
+
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 28f0c9a..dddb10e 100644 (file)
@@ -5,6 +5,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 
 Number type
 Function arguments are (value, step, {min or max}, [stepCount]).
+
 Invalid value
 PASS stepUp("", null, null) is "1"
 PASS stepDown("", null, null) is "-1"
@@ -18,6 +19,7 @@ PASS stepUp("foo", "any", null) is "1"
 PASS stepDown("foo", "any", null) is "-1"
 PASS stepUp("foo", "foo", null) is "1"
 PASS stepDown("foo", "foo", null) is "-1"
+
 Normal cases
 PASS stepUp("0", null, null) is "1"
 PASS stepUp("1", null, null, 2) is "3"
@@ -25,16 +27,116 @@ PASS stepUp("3", null, null, -1) is "2"
 PASS stepDown("2", null, null) is "1"
 PASS stepDown("1", null, null, 2) is "-1"
 PASS stepDown("-1", null, null, -1) is "0"
+
+Fractional cases
+PASS stepUp("0.1", 1, null) is "1"
+PASS stepUp("0.2", 1, null) is "1"
+PASS stepUp("1.0", 1, null) is "2"
+PASS stepUp("1.1", 1, null) is "2"
+PASS stepUp("1.2", 1, null) is "2"
+PASS stepUp("2.0", 1, null) is "3"
+
+PASS stepUp("-0.1", 1, null) is "0"
+PASS stepUp("-0.2", 1, null) is "0"
+PASS stepUp("-1.0", 1, null) is "0"
+PASS stepUp("-1.1", 1, null) is "-1"
+PASS stepUp("-1.2", 1, null) is "-1"
+PASS stepUp("-2.0", 1, null) is "-1"
+
+PASS stepDown("0.1", 1, null) is "0"
+PASS stepDown("0.2", 1, null) is "0"
+PASS stepDown("1.0", 1, null) is "0"
+PASS stepDown("1.1", 1, null) is "1"
+PASS stepDown("1.2", 1, null) is "1"
+PASS stepDown("2.0", 1, null) is "1"
+
+PASS stepDown("-0.1", 1, null) is "-1"
+PASS stepDown("-0.2", 1, null) is "-1"
+PASS stepDown("-1.0", 1, null) is "-2"
+PASS stepDown("-1.1", 1, null) is "-2"
+PASS stepDown("-1.2", 1, null) is "-2"
+PASS stepDown("-2.0", 1, null) is "-3"
+
+PASS stepUp(".1", 1, null) is "1"
+PASS stepUp(".2", 1, null) is "1"
+PASS stepUp("1.", 1, null) is "2"
+PASS stepUp("2.", 1, null) is "3"
+
+PASS stepUp("-.1", 1, null) is "0"
+PASS stepUp("-.2", 1, null) is "0"
+PASS stepUp("-1.", 1, null) is "0"
+PASS stepUp("-2.", 1, null) is "-1"
+
+PASS stepDown(".1", 1, null) is "0"
+PASS stepDown(".2", 1, null) is "0"
+PASS stepDown("1.", 1, null) is "0"
+PASS stepDown("2.", 1, null) is "1"
+
+PASS stepDown("-.1", 1, null) is "-1"
+PASS stepDown("-.2", 1, null) is "-1"
+PASS stepDown("-1.", 1, null) is "-2"
+PASS stepDown("-2.", 1, null) is "-3"
+
+PASS stepUp("0.1", .1, null) is "0.2"
+PASS stepUp("0.2", .1, null) is "0.3"
+PASS stepUp("1.0", .1, null) is "1.1"
+PASS stepUp("1.1", .1, null) is "1.2"
+PASS stepUp("1.2", .1, null) is "1.3"
+PASS stepUp("2.0", .1, null) is "2.1"
+
+PASS stepUp("-0.1", .1, null) is "0"
+PASS stepUp("-0.2", .1, null) is "-0.1"
+PASS stepUp("-1.0", .1, null) is "-0.9"
+PASS stepUp("-1.1", .1, null) is "-1"
+PASS stepUp("-1.2", .1, null) is "-1.1"
+PASS stepUp("-2.0", .1, null) is "-1.9"
+
+PASS stepDown("0.1", .1, null) is "0"
+PASS stepDown("0.2", .1, null) is "0.1"
+PASS stepDown("1.0", .1, null) is "0.9"
+PASS stepDown("1.1", .1, null) is "1"
+PASS stepDown("1.2", .1, null) is "1.1"
+PASS stepDown("2.0", .1, null) is "1.9"
+
+PASS stepDown("-0.1", .1, null) is "-0.2"
+PASS stepDown("-0.2", .1, null) is "-0.3"
+PASS stepDown("-1.0", .1, null) is "-1.1"
+PASS stepDown("-1.1", .1, null) is "-1.2"
+PASS stepDown("-1.2", .1, null) is "-1.3"
+PASS stepDown("-2.0", .1, null) is "-2.1"
+
+PASS stepUp(".1", .1, null) is "0.2"
+PASS stepUp(".2", .1, null) is "0.3"
+PASS stepUp("1.", .1, null) is "1.1"
+PASS stepUp("2.", .1, null) is "2.1"
+
+PASS stepUp("-.1", .1, null) is "0"
+PASS stepUp("-.2", .1, null) is "-0.1"
+PASS stepUp("-1.", .1, null) is "-0.9"
+PASS stepUp("-2.", .1, null) is "-1.9"
+PASS stepDown(".1", .1, null) is "0"
+PASS stepDown(".2", .1, null) is "0.1"
+PASS stepDown("1.", .1, null) is "0.9"
+PASS stepDown("2.", .1, null) is "1.9"
+
+PASS stepDown("-.1", .1, null) is "-0.2"
+PASS stepDown("-.2", .1, null) is "-0.3"
+PASS stepDown("-1.", .1, null) is "-1.1"
+PASS stepDown("-2.", .1, null) is "-2.1"
+
 Invalid step value
 PASS stepUp("0", "foo", null) is "1"
 PASS stepUp("1", "0", null) is "2"
 PASS stepUp("2", "-1", null) is "3"
+
 Step=any
 PASS stepUp("0", "any", null) is "1"
 PASS stepDown("0", "any", null) is "-1"
+
 Step=any corner case
 PASS stepUpExplicitBounds("0", "100", "any", "1.5", "1") is "2.5"
 PASS stepDownExplicitBounds("0", "100", "any", "1.5", "1") is "0.5"
+
 Overflow/underflow
 PASS stepDown("1", "1", "0") is "0"
 PASS stepDown("0", "1", "0") is "0"
@@ -44,6 +146,7 @@ PASS stepUp("-1", "1", "0") is "0"
 PASS stepUp("0", "1", "0") is "0"
 PASS stepUp("-1", "1", "0", 2) is "0"
 PASS stepUp("1", "3.40282346e+38", "", 2) is "3.40282346e+38"
+
 stepDown()/stepUp() for stepMismatch values
 PASS stepUp("1", "2", "") is "2"
 PASS input.min = "0"; stepUp("9", "10", "") is "10"
@@ -53,13 +156,16 @@ PASS stepUp("7", "300", "") is "300"
 PASS stepUp("-7", "300", "") is "0"
 PASS stepDown("7", "300", "") is "0"
 PASS stepDown("-7", "300", "") is "-300"
+
 Huge value and small step
 PASS input.min = ""; stepUp("1e+38", "1", "", 999) is "1e+38"
 PASS input.max = ""; stepDown("1e+38", "1", "", 999) is "1e+38"
+
 Fractional numbers
 PASS input.min = ""; stepUp("0", "0.33333333333333333", "", 3) is "1"
 PASS stepUp("1", "0.1", "", 10) is "2"
 PASS input.min = "0"; stepUp("0", "0.003921568627450980", "1", 255) is "1"
+
 Rounding
 PASS stepUp("5.005", "0.005", "", 2) is "5.015"
 PASS stepUp("5.005", "0.005", "", 11) is "5.06"
index 64b7d60..7d9940b 100644 (file)
@@ -87,6 +87,8 @@ function stepDownExplicitBounds(min, max, step, value, stepCount) {
 debug('Number type');
 input.type = 'number';
 debug('Function arguments are (value, step, {min or max}, [stepCount]).');
+
+debug('');
 debug('Invalid value');
 shouldBe('stepUp("", null, null)', '"1"');
 shouldBe('stepDown("", null, null)', '"-1"');
@@ -100,6 +102,8 @@ shouldBe('stepUp("foo", "any", null)', '"1"');
 shouldBe('stepDown("foo", "any", null)', '"-1"');
 shouldBe('stepUp("foo", "foo", null)', '"1"');
 shouldBe('stepDown("foo", "foo", null)', '"-1"');
+
+debug('');
 debug('Normal cases');
 shouldBe('stepUp("0", null, null)', '"1"');
 shouldBe('stepUp("1", null, null, 2)', '"3"');
@@ -107,16 +111,160 @@ shouldBe('stepUp("3", null, null, -1)', '"2"');
 shouldBe('stepDown("2", null, null)', '"1"');
 shouldBe('stepDown("1", null, null, 2)', '"-1"');
 shouldBe('stepDown("-1", null, null, -1)', '"0"');
+
+debug('');
+debug('Fractional cases')
+
+// Note: these tests also appear in number-stepup-stepdown.html. However, the
+// results here differ from the results there. According to:
+//
+//      https://html.spec.whatwg.org/multipage/forms.html#number-state-(type=number)
+//
+// The browser is allowed to clamp resulting values to the nearest multiple of
+// the [step] value:
+//
+//      When the element is suffering from a step mismatch, the user agent may
+//      round the element's value to the nearest number for which the element
+//      would not suffer from a step mismatch. If there are two such numbers,
+//      user agents are encouraged to pick the one nearest positive infinity.
+//
+// WebKit seesm to perform this clamping when stepping from the UI, but not
+// from the API.
+//
+// See also the function comment for InputType::stepUpFromRenderer.
+
+// Base/model/template tests
+shouldBe('stepUp("0.1", 1, null)', '"1"')       // Is 1.1 in non-render test
+shouldBe('stepUp("0.2", 1, null)', '"1"');      // Is 1.1 in non-render test
+shouldBe('stepUp("1.0", 1, null)', '"2"');
+shouldBe('stepUp("1.1", 1, null)', '"2"');      // Is 2.1 in non-render test
+shouldBe('stepUp("1.2", 1, null)', '"2"');      // Is 2.2 in non-render test
+shouldBe('stepUp("2.0", 1, null)', '"3"');
+
+debug('');
+// Same as above, but with negative numbers.
+shouldBe('stepUp("-0.1", 1, null)', '"0"');     // Is 0.9 in non-render test
+shouldBe('stepUp("-0.2", 1, null)', '"0"');     // Is 0.8 in non-render test
+shouldBe('stepUp("-1.0", 1, null)', '"0"');
+shouldBe('stepUp("-1.1", 1, null)', '"-1"');    // Is -0.1 in non-render test
+shouldBe('stepUp("-1.2", 1, null)', '"-1"');    // Is -0.2 in non-render test
+shouldBe('stepUp("-2.0", 1, null)', '"-1"');
+
+debug('');
+// Same as above, but stepping down rather than up.
+shouldBe('stepDown("0.1", 1, null)', '"0"');    // Is -0.9 in non-render test
+shouldBe('stepDown("0.2", 1, null)', '"0"');    // Is -0.8 in non-render test
+shouldBe('stepDown("1.0", 1, null)', '"0"');
+shouldBe('stepDown("1.1", 1, null)', '"1"');    // Is 0.1 in non-render test
+shouldBe('stepDown("1.2", 1, null)', '"1"');    // Is 0.2 in non-render test
+shouldBe('stepDown("2.0", 1, null)', '"1"');
+
+debug('');
+shouldBe('stepDown("-0.1", 1, null)', '"-1"');  // Is -1.1 in non-render test
+shouldBe('stepDown("-0.2", 1, null)', '"-1"');  // Is -1.2 in non-render test
+shouldBe('stepDown("-1.0", 1, null)', '"-2"');
+shouldBe('stepDown("-1.1", 1, null)', '"-2"');  // Is -2.1 in non-render test
+shouldBe('stepDown("-1.2", 1, null)', '"-2"');  // Is -2.2 in non-render test
+shouldBe('stepDown("-2.0", 1, null)', '"-3"');
+
+// Same as above, but with leading/trailing zeros removed.
+debug('');
+shouldBe('stepUp(".1", 1, null)', '"1"');       // Is 1.1 in non-render test
+shouldBe('stepUp(".2", 1, null)', '"1"');       // Is 1.2 in non-render test
+shouldBe('stepUp("1.", 1, null)', '"2"');
+shouldBe('stepUp("2.", 1, null)', '"3"');
+
+debug('');
+shouldBe('stepUp("-.1", 1, null)', '"0"');      // Is 0.9 in non-render test
+shouldBe('stepUp("-.2", 1, null)', '"0"');      // Is 0.8 in non-render test
+shouldBe('stepUp("-1.", 1, null)', '"0"');
+shouldBe('stepUp("-2.", 1, null)', '"-1"');
+
+debug('');
+shouldBe('stepDown(".1", 1, null)', '"0"');     // Is -0.9 in non-render test
+shouldBe('stepDown(".2", 1, null)', '"0"');     // Is -0.8 in non-render test
+shouldBe('stepDown("1.", 1, null)', '"0"');
+shouldBe('stepDown("2.", 1, null)', '"1"');
+
+debug('');
+shouldBe('stepDown("-.1", 1, null)', '"-1"');   // Is -1.1 in non-render test
+shouldBe('stepDown("-.2", 1, null)', '"-1"');   // Is -1.2 in non-render test
+shouldBe('stepDown("-1.", 1, null)', '"-2"');
+shouldBe('stepDown("-2.", 1, null)', '"-3"');
+
+// Same as above, but stepping by .1 rather than 1.
+debug('');
+shouldBe('stepUp("0.1", .1, null)', '"0.2"');
+shouldBe('stepUp("0.2", .1, null)', '"0.3"');
+shouldBe('stepUp("1.0", .1, null)', '"1.1"');
+shouldBe('stepUp("1.1", .1, null)', '"1.2"');
+shouldBe('stepUp("1.2", .1, null)', '"1.3"');
+shouldBe('stepUp("2.0", .1, null)', '"2.1"');
+
+debug('');
+shouldBe('stepUp("-0.1", .1, null)', '"0"');
+shouldBe('stepUp("-0.2", .1, null)', '"-0.1"');
+shouldBe('stepUp("-1.0", .1, null)', '"-0.9"');
+shouldBe('stepUp("-1.1", .1, null)', '"-1"');
+shouldBe('stepUp("-1.2", .1, null)', '"-1.1"');
+shouldBe('stepUp("-2.0", .1, null)', '"-1.9"');
+
+debug('');
+shouldBe('stepDown("0.1", .1, null)', '"0"');
+shouldBe('stepDown("0.2", .1, null)', '"0.1"');
+shouldBe('stepDown("1.0", .1, null)', '"0.9"');
+shouldBe('stepDown("1.1", .1, null)', '"1"');
+shouldBe('stepDown("1.2", .1, null)', '"1.1"');
+shouldBe('stepDown("2.0", .1, null)', '"1.9"');
+
+debug('');
+shouldBe('stepDown("-0.1", .1, null)', '"-0.2"');
+shouldBe('stepDown("-0.2", .1, null)', '"-0.3"');
+shouldBe('stepDown("-1.0", .1, null)', '"-1.1"');
+shouldBe('stepDown("-1.1", .1, null)', '"-1.2"');
+shouldBe('stepDown("-1.2", .1, null)', '"-1.3"');
+shouldBe('stepDown("-2.0", .1, null)', '"-2.1"');
+
+debug('');
+shouldBe('stepUp(".1", .1, null)', '"0.2"');
+shouldBe('stepUp(".2", .1, null)', '"0.3"');
+shouldBe('stepUp("1.", .1, null)', '"1.1"');
+shouldBe('stepUp("2.", .1, null)', '"2.1"');
+
+debug('');
+shouldBe('stepUp("-.1", .1, null)', '"0"');
+shouldBe('stepUp("-.2", .1, null)', '"-0.1"');
+shouldBe('stepUp("-1.", .1, null)', '"-0.9"');
+shouldBe('stepUp("-2.", .1, null)', '"-1.9"');
+
+shouldBe('stepDown(".1", .1, null)', '"0"');
+shouldBe('stepDown(".2", .1, null)', '"0.1"');
+shouldBe('stepDown("1.", .1, null)', '"0.9"');
+shouldBe('stepDown("2.", .1, null)', '"1.9"');
+
+debug('');
+shouldBe('stepDown("-.1", .1, null)', '"-0.2"');
+shouldBe('stepDown("-.2", .1, null)', '"-0.3"');
+shouldBe('stepDown("-1.", .1, null)', '"-1.1"');
+shouldBe('stepDown("-2.", .1, null)', '"-2.1"');
+
+debug('');
 debug('Invalid step value');
 shouldBe('stepUp("0", "foo", null)', '"1"');
 shouldBe('stepUp("1", "0", null)', '"2"');
 shouldBe('stepUp("2", "-1", null)', '"3"');
+
+debug('');
 debug('Step=any');
 shouldBe('stepUp("0", "any", null)', '"1"');
 shouldBe('stepDown("0", "any", null)', '"-1"');
+
+debug('');
 debug('Step=any corner case');
 shouldBe('stepUpExplicitBounds("0", "100", "any", "1.5", "1")', '"2.5"');
 shouldBe('stepDownExplicitBounds("0", "100", "any", "1.5", "1")', '"0.5"');
+
+debug('');
 debug('Overflow/underflow');
 shouldBe('stepDown("1", "1", "0")', '"0"');
 shouldBe('stepDown("0", "1", "0")', '"0"');
@@ -126,6 +274,8 @@ shouldBe('stepUp("-1", "1", "0")', '"0"');
 shouldBe('stepUp("0", "1", "0")', '"0"');
 shouldBe('stepUp("-1", "1", "0", 2)', '"0"');
 shouldBe('stepUp("1", "3.40282346e+38", "", 2)', '"3.40282346e+38"');
+
+debug('');
 debug('stepDown()/stepUp() for stepMismatch values');
 shouldBe('stepUp("1", "2", "")', '"2"');
 shouldBe('input.min = "0"; stepUp("9", "10", "")', '"10"');
@@ -135,13 +285,19 @@ shouldBe('stepUp("7", "300", "")', '"300"');
 shouldBe('stepUp("-7", "300", "")', '"0"');
 shouldBe('stepDown("7", "300", "")', '"0"');
 shouldBe('stepDown("-7", "300", "")', '"-300"');
+
+debug('');
 debug('Huge value and small step');
 shouldBe('input.min = ""; stepUp("1e+38", "1", "", 999)', '"1e+38"');
 shouldBe('input.max = ""; stepDown("1e+38", "1", "", 999)', '"1e+38"');
+
+debug('');
 debug('Fractional numbers');
 shouldBe('input.min = ""; stepUp("0", "0.33333333333333333", "", 3)', '"1"');
 shouldBe('stepUp("1", "0.1", "", 10)', '"2"');
 shouldBe('input.min = "0"; stepUp("0", "0.003921568627450980", "1", 255)', '"1"');
+
+debug('');
 debug('Rounding');
 shouldBe('stepUp("5.005", "0.005", "", 2)', '"5.015"');
 shouldBe('stepUp("5.005", "0.005", "", 11)', '"5.06"');
index 64cfd8f..c4b7067 100644 (file)
@@ -55,9 +55,13 @@ function stepDownExplicitBounds(min, max, step, value, stepCount) {
 
 debug('Number type');
 input.type = 'number';
+
+debug('');
 debug('Invalid value');
 shouldThrow('stepUp("", null, null)', invalidStateErr);
 shouldThrow('stepDown("", null, null)', invalidStateErr);
+
+debug('');
 debug('Non-number arguments');
 shouldBe('stepUp("0", null, null, "0")', '"0"');
 shouldBe('stepDown("0", null, null, "0")', '"0"');
@@ -65,6 +69,8 @@ shouldBe('stepUp("0", null, null, "foo")', '"0"');
 shouldBe('stepDown("0", null, null, "foo")', '"0"');
 shouldBe('stepUp("0", null, null, null)', '"0"');
 shouldBe('stepDown("0", null, null, null)', '"0"');
+
+debug('');
 debug('Normal cases');
 shouldBe('stepUp("0", null, null)', '"1"');
 shouldBe('stepUp("1", null, null, 2)', '"3"');
@@ -72,19 +78,147 @@ shouldBe('stepUp("3", null, null, -1)', '"2"');
 shouldBe('stepDown("2", null, null)', '"1"');
 shouldBe('stepDown("1", null, null, 2)', '"-1"');
 shouldBe('stepDown("-1", null, null, -1)', '"0"');
+
+debug('');
+debug('Fractional cases')
+// Base/model/template tests
+shouldBe('stepUp("0.1", 1, null)', '"1.1"');
+shouldBe('stepUp("0.2", 1, null)', '"1.2"');
+shouldBe('stepUp("1.0", 1, null)', '"2"');
+shouldBe('stepUp("1.1", 1, null)', '"2.1"');
+shouldBe('stepUp("1.2", 1, null)', '"2.2"');
+shouldBe('stepUp("2.0", 1, null)', '"3"');
+
+// Same as above, but with negative numbers.
+debug('');
+shouldBe('stepUp("-0.1", 1, null)', '"0.9"');
+shouldBe('stepUp("-0.2", 1, null)', '"0.8"');
+shouldBe('stepUp("-1.0", 1, null)', '"0"');
+shouldBe('stepUp("-1.1", 1, null)', '"-0.1"');
+shouldBe('stepUp("-1.2", 1, null)', '"-0.2"');
+shouldBe('stepUp("-2.0", 1, null)', '"-1"');
+
+// Same as above, but stepping down rather than up.
+debug('');
+shouldBe('stepDown("0.1", 1, null)', '"-0.9"');
+shouldBe('stepDown("0.2", 1, null)', '"-0.8"');
+shouldBe('stepDown("1.0", 1, null)', '"0"');
+shouldBe('stepDown("1.1", 1, null)', '"0.1"');
+shouldBe('stepDown("1.2", 1, null)', '"0.2"');
+shouldBe('stepDown("2.0", 1, null)', '"1"');
+
+debug('');
+shouldBe('stepDown("-0.1", 1, null)', '"-1.1"');
+shouldBe('stepDown("-0.2", 1, null)', '"-1.2"');
+shouldBe('stepDown("-1.0", 1, null)', '"-2"');
+shouldBe('stepDown("-1.1", 1, null)', '"-2.1"');
+shouldBe('stepDown("-1.2", 1, null)', '"-2.2"');
+shouldBe('stepDown("-2.0", 1, null)', '"-3"');
+
+// Same as above, but with leading/trailing zeros removed.
+debug('');
+shouldBe('stepUp(".1", 1, null)', '"1.1"');
+shouldBe('stepUp(".2", 1, null)', '"1.2"');
+shouldBe('stepUp("1.", 1, null)', '"2"');
+shouldBe('stepUp("2.", 1, null)', '"3"');
+
+debug('');
+shouldBe('stepUp("-.1", 1, null)', '"0.9"');
+shouldBe('stepUp("-.2", 1, null)', '"0.8"');
+shouldBe('stepUp("-1.", 1, null)', '"0"');
+shouldBe('stepUp("-2.", 1, null)', '"-1"');
+
+debug('');
+shouldBe('stepDown(".1", 1, null)', '"-0.9"');
+shouldBe('stepDown(".2", 1, null)', '"-0.8"');
+shouldBe('stepDown("1.", 1, null)', '"0"');
+shouldBe('stepDown("2.", 1, null)', '"1"');
+
+debug('');
+shouldBe('stepDown("-.1", 1, null)', '"-1.1"');
+shouldBe('stepDown("-.2", 1, null)', '"-1.2"');
+shouldBe('stepDown("-1.", 1, null)', '"-2"');
+shouldBe('stepDown("-2.", 1, null)', '"-3"');
+
+// Same as above, but stepping by .1 rather than 1.
+debug('');
+shouldBe('stepUp("0.1", .1, null)', '"0.2"');
+shouldBe('stepUp("0.2", .1, null)', '"0.3"');
+shouldBe('stepUp("1.0", .1, null)', '"1.1"');
+shouldBe('stepUp("1.1", .1, null)', '"1.2"');
+shouldBe('stepUp("1.2", .1, null)', '"1.3"');
+shouldBe('stepUp("2.0", .1, null)', '"2.1"');
+
+debug('');
+shouldBe('stepUp("-0.1", .1, null)', '"0"');
+shouldBe('stepUp("-0.2", .1, null)', '"-0.1"');
+shouldBe('stepUp("-1.0", .1, null)', '"-0.9"');
+shouldBe('stepUp("-1.1", .1, null)', '"-1"');
+shouldBe('stepUp("-1.2", .1, null)', '"-1.1"');
+shouldBe('stepUp("-2.0", .1, null)', '"-1.9"');
+
+debug('');
+shouldBe('stepDown("0.1", .1, null)', '"0"');
+shouldBe('stepDown("0.2", .1, null)', '"0.1"');
+shouldBe('stepDown("1.0", .1, null)', '"0.9"');
+shouldBe('stepDown("1.1", .1, null)', '"1"');
+shouldBe('stepDown("1.2", .1, null)', '"1.1"');
+shouldBe('stepDown("2.0", .1, null)', '"1.9"');
+
+debug('');
+shouldBe('stepDown("-0.1", .1, null)', '"-0.2"');
+shouldBe('stepDown("-0.2", .1, null)', '"-0.3"');
+shouldBe('stepDown("-1.0", .1, null)', '"-1.1"');
+shouldBe('stepDown("-1.1", .1, null)', '"-1.2"');
+shouldBe('stepDown("-1.2", .1, null)', '"-1.3"');
+shouldBe('stepDown("-2.0", .1, null)', '"-2.1"');
+
+debug('');
+shouldBe('stepUp(".1", .1, null)', '"0.2"');
+shouldBe('stepUp(".2", .1, null)', '"0.3"');
+shouldBe('stepUp("1.", .1, null)', '"1.1"');
+shouldBe('stepUp("2.", .1, null)', '"2.1"');
+
+debug('');
+shouldBe('stepUp("-.1", .1, null)', '"0"');
+shouldBe('stepUp("-.2", .1, null)', '"-0.1"');
+shouldBe('stepUp("-1.", .1, null)', '"-0.9"');
+shouldBe('stepUp("-2.", .1, null)', '"-1.9"');
+
+debug('');
+shouldBe('stepDown(".1", .1, null)', '"0"');
+shouldBe('stepDown(".2", .1, null)', '"0.1"');
+shouldBe('stepDown("1.", .1, null)', '"0.9"');
+shouldBe('stepDown("2.", .1, null)', '"1.9"');
+
+debug('');
+shouldBe('stepDown("-.1", .1, null)', '"-0.2"');
+shouldBe('stepDown("-.2", .1, null)', '"-0.3"');
+shouldBe('stepDown("-1.", .1, null)', '"-1.1"');
+shouldBe('stepDown("-2.", .1, null)', '"-2.1"');
+
+debug('');
 debug('Extra arguments');
 shouldBe('input.value = "0"; input.min = null; input.step = null; input.stepUp(1, 2); input.value', '"1"');
 shouldBe('input.value = "1"; input.stepDown(1, 3); input.value', '"0"');
+
+debug('');
 debug('Invalid step value');
 shouldBe('stepUp("0", "foo", null)', '"1"');
 shouldBe('stepUp("1", "0", null)', '"2"');
 shouldBe('stepUp("2", "-1", null)', '"3"');
+
+debug('');
 debug('Step=any');
 shouldThrow('stepUp("0", "any", null)', invalidStateErr);
 shouldThrow('stepDown("0", "any", null)', invalidStateErr);
+
+debug('');
 debug('Step=any corner case');
 shouldThrow('stepUpExplicitBounds("0", "100", "any", "1.5", "1")', invalidStateErr);
 shouldThrow('stepDownExplicitBounds("0", "100", "any", "1.5", "1")', invalidStateErr);
+
+debug('');
 debug('Overflow/underflow');
 shouldBe('stepDown("1", "1", "0")', '"0"');
 shouldThrow('stepDown("0", "1", "0")', invalidStateErr);
@@ -96,21 +230,29 @@ shouldThrow('stepUp("0", "1", "0")', invalidStateErr);
 shouldThrow('stepUp("-1", "1", "0", 2)', invalidStateErr);
 shouldBe('input.value', '"-1"');
 shouldThrow('stepUp("1", "3.40282346e+38", "", 2)', invalidStateErr);
+
+debug('');
 debug('stepDown()/stepUp() for stepMismatch values');
 shouldBe('stepUp("1", "2", "")', '"3"');
 shouldBe('input.stepDown(); input.value', '"1"');
 shouldBe('input.min = "0"; stepUp("9", "10", "", 9)', '"99"');
 shouldBe('stepDown("19", "10", "0")', '"9"');
 shouldBe('stepUp("89", "10", "99")', '"99"');
+
+debug('');
 debug('Huge value and small step');
 shouldBe('input.min = ""; stepUp("1e+38", "1", "", 999999)', '"1e+38"');
 shouldBe('input.max = ""; stepDown("1e+38", "1", "", 999999)', '"1e+38"');
+
+debug('');
 debug('Fractional numbers');
 shouldBe('input.min = ""; stepUp("0", "0.33333333333333333", "", 3)', '"1"');
 shouldBe('stepUp("1", "0.1", "", 10)', '"2"');
 shouldBe('input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.value', '"3"');
 shouldBe('input.min = "0"; stepUp("0", "0.003921568627450980", "1", 255)', '"1"');
 shouldBe('for (var i = 0; i < 255; i++) { input.stepDown(); }; input.value', '"0"');
+
+debug('');
 debug('Rounding');
 shouldBe('stepUp("5.005", "0.005", "", 2)', '"5.015"');
 shouldBe('stepUp("5.005", "0.005", "", 11)', '"5.06"');
@@ -118,6 +260,8 @@ shouldBe('stepUp("5.005", "0.005", "", 12)', '"5.065"');
 shouldBe('stepUpExplicitBounds("4", "9", "0.005", "5.005", 2)', '"5.015"');
 shouldBe('stepUpExplicitBounds("4", "9", "0.005", "5.005", 11)', '"5.06"');
 shouldBe('stepUpExplicitBounds("4", "9", "0.005", "5.005", 12)', '"5.065"');
+
+debug('');
 </script>
 <script src="../../../resources/js-test-post.js"></script>
 </body>
diff --git a/LayoutTests/fast/forms/range/input-appearance-range-decimals-expected.html b/LayoutTests/fast/forms/range/input-appearance-range-decimals-expected.html
new file mode 100644 (file)
index 0000000..ab8b90e
--- /dev/null
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<body>
+<input type=range value="0.4" min="-0.4" max="1.0">
+<body>
+
diff --git a/LayoutTests/fast/forms/range/input-appearance-range-decimals.html b/LayoutTests/fast/forms/range/input-appearance-range-decimals.html
new file mode 100644 (file)
index 0000000..0dcfc73
--- /dev/null
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<body>
+<!-- These numbers should parse the same as 0.4, -0.4, and 1.0 -->
+<input type=range value=".4" min="-.4" max="1.">
+<body>
+
index 0dd22d0..897b8a4 100644 (file)
@@ -7,6 +7,7 @@ function arguments are (min, max, step, value, [stepCount])
 Using the default values
 PASS stepUpExplicitBounds(null, null, null, "") is "51"
 PASS stepDownExplicitBounds(null, null, null, "") is "49"
+
 Non-number arguments (stepCount)
 PASS stepUpExplicitBounds(null, null, null, "0", "0") is "0"
 PASS stepDownExplicitBounds(null, null, null, "0", "0") is "0"
@@ -14,6 +15,7 @@ PASS stepUpExplicitBounds(null, null, null, "0", "foo") is "0"
 PASS stepDownExplicitBounds(null, null, null, "0", "foo") is "0"
 PASS stepUpExplicitBounds(null, null, null, "0", null) is "0"
 PASS stepDownExplicitBounds(null, null, null, "0", null) is "0"
+
 Normal cases
 PASS stepUpExplicitBounds(null, null, null, "0") is "1"
 PASS stepUpExplicitBounds(null, null, null, "1", 2) is "3"
@@ -21,9 +23,108 @@ PASS stepUpExplicitBounds(null, null, null, "3", -1) is "2"
 PASS stepDownExplicitBounds("-100", null, null, "2") is "1"
 PASS stepDownExplicitBounds("-100", null, null, "1", 2) is "-1"
 PASS stepDownExplicitBounds("-100", null, null, "-1", -1) is "0"
+
+Fractional cases
+PASS stepUpExplicitBounds(-10, 10, 1, "0.1") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, "0.2") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, "1.0") is "2"
+PASS stepUpExplicitBounds(-10, 10, 1, "1.1") is "2"
+PASS stepUpExplicitBounds(-10, 10, 1, "1.2") is "2"
+PASS stepUpExplicitBounds(-10, 10, 1, "2.0") is "3"
+
+PASS stepUpExplicitBounds(-10, 10, 1, "-0.1") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, "-0.2") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, "-1.0") is "0"
+PASS stepUpExplicitBounds(-10, 10, 1, "-1.1") is "0"
+PASS stepUpExplicitBounds(-10, 10, 1, "-1.2") is "0"
+PASS stepUpExplicitBounds(-10, 10, 1, "-2.0") is "-1"
+
+PASS stepDownExplicitBounds(-10, 10, 1, "0.1") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, "0.2") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, "1.0") is "0"
+PASS stepDownExplicitBounds(-10, 10, 1, "1.1") is "0"
+PASS stepDownExplicitBounds(-10, 10, 1, "1.2") is "0"
+PASS stepDownExplicitBounds(-10, 10, 1, "2.0") is "1"
+
+PASS stepDownExplicitBounds(-10, 10, 1, "-0.1") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, "-0.2") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, "-1.0") is "-2"
+PASS stepDownExplicitBounds(-10, 10, 1, "-1.1") is "-2"
+PASS stepDownExplicitBounds(-10, 10, 1, "-1.2") is "-2"
+PASS stepDownExplicitBounds(-10, 10, 1, "-2.0") is "-3"
+
+PASS stepUpExplicitBounds(-10, 10, 1, ".1") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, ".2") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, "1.") is "2"
+PASS stepUpExplicitBounds(-10, 10, 1, "2.") is "3"
+
+PASS stepUpExplicitBounds(-10, 10, 1, "-.1") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, "-.2") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, "-1.") is "0"
+PASS stepUpExplicitBounds(-10, 10, 1, "-2.") is "-1"
+
+PASS stepDownExplicitBounds(-10, 10, 1, ".1") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, ".2") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, "1.") is "0"
+PASS stepDownExplicitBounds(-10, 10, 1, "2.") is "1"
+
+PASS stepDownExplicitBounds(-10, 10, 1, "-.1") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, "-.2") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, "-1.") is "-2"
+PASS stepDownExplicitBounds(-10, 10, 1, "-2.") is "-3"
+
+PASS stepUpExplicitBounds(-10, 10, .1, "0.1") is "0.2"
+PASS stepUpExplicitBounds(-10, 10, .1, "0.2") is "0.3"
+PASS stepUpExplicitBounds(-10, 10, .1, "1.0") is "1.1"
+PASS stepUpExplicitBounds(-10, 10, .1, "1.1") is "1.2"
+PASS stepUpExplicitBounds(-10, 10, .1, "1.2") is "1.3"
+PASS stepUpExplicitBounds(-10, 10, .1, "2.0") is "2.1"
+
+PASS stepUpExplicitBounds(-10, 10, .1, "-0.1") is "0"
+PASS stepUpExplicitBounds(-10, 10, .1, "-0.2") is "-0.1"
+PASS stepUpExplicitBounds(-10, 10, .1, "-1.0") is "-0.9"
+PASS stepUpExplicitBounds(-10, 10, .1, "-1.1") is "-1"
+PASS stepUpExplicitBounds(-10, 10, .1, "-1.2") is "-1.1"
+PASS stepUpExplicitBounds(-10, 10, .1, "-2.0") is "-1.9"
+
+PASS stepDownExplicitBounds(-10, 10, .1, "0.1") is "0"
+PASS stepDownExplicitBounds(-10, 10, .1, "0.2") is "0.1"
+PASS stepDownExplicitBounds(-10, 10, .1, "1.0") is "0.9"
+PASS stepDownExplicitBounds(-10, 10, .1, "1.1") is "1"
+PASS stepDownExplicitBounds(-10, 10, .1, "1.2") is "1.1"
+PASS stepDownExplicitBounds(-10, 10, .1, "2.0") is "1.9"
+
+PASS stepDownExplicitBounds(-10, 10, .1, "-0.1") is "-0.2"
+PASS stepDownExplicitBounds(-10, 10, .1, "-0.2") is "-0.3"
+PASS stepDownExplicitBounds(-10, 10, .1, "-1.0") is "-1.1"
+PASS stepDownExplicitBounds(-10, 10, .1, "-1.1") is "-1.2"
+PASS stepDownExplicitBounds(-10, 10, .1, "-1.2") is "-1.3"
+PASS stepDownExplicitBounds(-10, 10, .1, "-2.0") is "-2.1"
+
+PASS stepUpExplicitBounds(-10, 10, .1, ".1") is "0.2"
+PASS stepUpExplicitBounds(-10, 10, .1, ".2") is "0.3"
+PASS stepUpExplicitBounds(-10, 10, .1, "1.") is "1.1"
+PASS stepUpExplicitBounds(-10, 10, .1, "2.") is "2.1"
+
+PASS stepUpExplicitBounds(-10, 10, .1, "-.1") is "0"
+PASS stepUpExplicitBounds(-10, 10, .1, "-.2") is "-0.1"
+PASS stepUpExplicitBounds(-10, 10, .1, "-1.") is "-0.9"
+PASS stepUpExplicitBounds(-10, 10, .1, "-2.") is "-1.9"
+
+PASS stepDownExplicitBounds(-10, 10, .1, ".1") is "0"
+PASS stepDownExplicitBounds(-10, 10, .1, ".2") is "0.1"
+PASS stepDownExplicitBounds(-10, 10, .1, "1.") is "0.9"
+PASS stepDownExplicitBounds(-10, 10, .1, "2.") is "1.9"
+
+PASS stepDownExplicitBounds(-10, 10, .1, "-.1") is "-0.2"
+PASS stepDownExplicitBounds(-10, 10, .1, "-.2") is "-0.3"
+PASS stepDownExplicitBounds(-10, 10, .1, "-1.") is "-1.1"
+PASS stepDownExplicitBounds(-10, 10, .1, "-2.") is "-2.1"
+
 Extra arguments
 PASS setInputAttributes(null, null, null, "0"); input.stepUp(1,2); input.value is "1"
 PASS setInputAttributes(null, null, null, "1"); input.stepDown(1,3); input.value is "0"
+
 Invalid step value
 PASS stepUpExplicitBounds(null, null, "foo", "0") is "1"
 PASS stepUpExplicitBounds(null, null, "0", "1") is "2"
@@ -31,9 +132,11 @@ PASS stepUpExplicitBounds(null, null, "-1", "2") is "3"
 PASS stepDownExplicitBounds(null, null, "foo", "1") is "0"
 PASS stepDownExplicitBounds(null, null, "0", "2") is "1"
 PASS stepDownExplicitBounds(null, null, "-1", "3") is "2"
+
 Step=any
 PASS stepUpExplicitBounds(null, null, "any", "1") threw exception Error: InvalidStateError: DOM Exception 11.
 PASS stepDownExplicitBounds(null, null, "any", "1") threw exception Error: InvalidStateError: DOM Exception 11.
+
 Overflow/underflow
 PASS stepUpExplicitBounds(null, "100", "1", "99") is "100"
 PASS stepUpExplicitBounds(null, "100", "1", "100") threw exception Error: InvalidStateError: DOM Exception 11.
@@ -51,16 +154,20 @@ PASS stepUpExplicitBounds(null, 0, 1, 0) threw exception Error: InvalidStateErro
 PASS stepUpExplicitBounds(-100, 0, 1, -1, 2) threw exception Error: InvalidStateError: DOM Exception 11.
 PASS input.value is "-1"
 PASS stepUpExplicitBounds(null, null, "3.40282346e+38", "1", "2") threw exception Error: InvalidStateError: DOM Exception 11.
+
 stepDown()/stepUp() for stepMismatch values
 PASS stepUpExplicitBounds(null, null, 2, 1) is "4"
 PASS input.stepDown(); input.value is "2"
 PASS stepUpExplicitBounds(0, null, 10, 9, 9) is "100"
 PASS stepDownExplicitBounds(0, null, 10, 19) is "10"
+
 value + step is <= max, but rounded result would be > max.
 PASS stepUpExplicitBounds(null, 99, 10, 89) threw exception Error: InvalidStateError: DOM Exception 11.
+
 Huge value and small step
 PASS stepUpExplicitBounds(0, 1e38, 1, 1e38, 999999) is "1e+38"
 PASS stepDownExplicitBounds(0, 1e38, 1, 1e38, 999999) is "1e+38"
+
 Fractional numbers
 PASS stepUpExplicitBounds(null, null, 0.33333333333333333, 0, 3) is "1"
 PASS stepUpExplicitBounds(null, null, 0.1, 1) is "1.1"
@@ -71,6 +178,7 @@ PASS stepUpExplicitBounds(0, 1, 0.003921568627450980, 0, 255) is "1"
 PASS for (var i = 0; i < 255; i++) { input.stepDown(); }; input.value is "0"
 PASS stepDownExplicitBounds(null, null, 0.1, 1, 8) is "0.2"
 PASS stepDownExplicitBounds(null, null, 0.1, 1) is "0.9"
+
 PASS successfullyParsed is true
 
 TEST COMPLETE
index afa32da..d7b7d19 100644 (file)
@@ -17,6 +17,7 @@ PASS stepUpExplicitBounds(null, null, "any", "foo") is "51"
 PASS stepDownExplicitBounds(null, null, "any", "foo") is "49"
 PASS stepUpExplicitBounds(null, null, "foo", "foo") is "51"
 PASS stepDownExplicitBounds(null, null, "foo", "foo") is "49"
+
 Normal cases
 PASS stepUpExplicitBounds(null, null, null, "0") is "1"
 PASS stepUpExplicitBounds(null, null, null, "1", 2) is "3"
@@ -24,6 +25,103 @@ PASS stepUpExplicitBounds(null, null, null, "3", -1) is "2"
 PASS stepDownExplicitBounds("-100", null, null, "2") is "1"
 PASS stepDownExplicitBounds("-100", null, null, "1", 2) is "-1"
 PASS stepDownExplicitBounds("-100", null, null, "-1", -1) is "0"
+
+Fractional cases
+PASS stepUpExplicitBounds(-10, 10, 1, "0.1") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, "0.2") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, "1.0") is "2"
+PASS stepUpExplicitBounds(-10, 10, 1, "1.1") is "2"
+PASS stepUpExplicitBounds(-10, 10, 1, "1.2") is "2"
+PASS stepUpExplicitBounds(-10, 10, 1, "2.0") is "3"
+
+PASS stepUpExplicitBounds(-10, 10, 1, "-0.1") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, "-0.2") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, "-1.0") is "0"
+PASS stepUpExplicitBounds(-10, 10, 1, "-1.1") is "0"
+PASS stepUpExplicitBounds(-10, 10, 1, "-1.2") is "0"
+PASS stepUpExplicitBounds(-10, 10, 1, "-2.0") is "-1"
+
+PASS stepDownExplicitBounds(-10, 10, 1, "0.1") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, "0.2") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, "1.0") is "0"
+PASS stepDownExplicitBounds(-10, 10, 1, "1.1") is "0"
+PASS stepDownExplicitBounds(-10, 10, 1, "1.2") is "0"
+PASS stepDownExplicitBounds(-10, 10, 1, "2.0") is "1"
+
+PASS stepDownExplicitBounds(-10, 10, 1, "-0.1") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, "-0.2") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, "-1.0") is "-2"
+PASS stepDownExplicitBounds(-10, 10, 1, "-1.1") is "-2"
+PASS stepDownExplicitBounds(-10, 10, 1, "-1.2") is "-2"
+PASS stepDownExplicitBounds(-10, 10, 1, "-2.0") is "-3"
+
+PASS stepUpExplicitBounds(-10, 10, 1, ".1") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, ".2") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, "1.") is "2"
+PASS stepUpExplicitBounds(-10, 10, 1, "2.") is "3"
+
+PASS stepUpExplicitBounds(-10, 10, 1, "-.1") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, "-.2") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, "-1.") is "0"
+PASS stepUpExplicitBounds(-10, 10, 1, "-2.") is "-1"
+
+PASS stepDownExplicitBounds(-10, 10, 1, ".1") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, ".2") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, "1.") is "0"
+PASS stepDownExplicitBounds(-10, 10, 1, "2.") is "1"
+
+PASS stepDownExplicitBounds(-10, 10, 1, "-.1") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, "-.2") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, "-1.") is "-2"
+PASS stepDownExplicitBounds(-10, 10, 1, "-2.") is "-3"
+
+PASS stepUpExplicitBounds(-10, 10, .1, "0.1") is "0.2"
+PASS stepUpExplicitBounds(-10, 10, .1, "0.2") is "0.3"
+PASS stepUpExplicitBounds(-10, 10, .1, "1.0") is "1.1"
+PASS stepUpExplicitBounds(-10, 10, .1, "1.1") is "1.2"
+PASS stepUpExplicitBounds(-10, 10, .1, "1.2") is "1.3"
+PASS stepUpExplicitBounds(-10, 10, .1, "2.0") is "2.1"
+
+PASS stepUpExplicitBounds(-10, 10, .1, "-0.1") is "0"
+PASS stepUpExplicitBounds(-10, 10, .1, "-0.2") is "-0.1"
+PASS stepUpExplicitBounds(-10, 10, .1, "-1.0") is "-0.9"
+PASS stepUpExplicitBounds(-10, 10, .1, "-1.1") is "-1"
+PASS stepUpExplicitBounds(-10, 10, .1, "-1.2") is "-1.1"
+PASS stepUpExplicitBounds(-10, 10, .1, "-2.0") is "-1.9"
+
+PASS stepDownExplicitBounds(-10, 10, .1, "0.1") is "0"
+PASS stepDownExplicitBounds(-10, 10, .1, "0.2") is "0.1"
+PASS stepDownExplicitBounds(-10, 10, .1, "1.0") is "0.9"
+PASS stepDownExplicitBounds(-10, 10, .1, "1.1") is "1"
+PASS stepDownExplicitBounds(-10, 10, .1, "1.2") is "1.1"
+PASS stepDownExplicitBounds(-10, 10, .1, "2.0") is "1.9"
+
+PASS stepDownExplicitBounds(-10, 10, .1, "-0.1") is "-0.2"
+PASS stepDownExplicitBounds(-10, 10, .1, "-0.2") is "-0.3"
+PASS stepDownExplicitBounds(-10, 10, .1, "-1.0") is "-1.1"
+PASS stepDownExplicitBounds(-10, 10, .1, "-1.1") is "-1.2"
+PASS stepDownExplicitBounds(-10, 10, .1, "-1.2") is "-1.3"
+PASS stepDownExplicitBounds(-10, 10, .1, "-2.0") is "-2.1"
+
+PASS stepUpExplicitBounds(-10, 10, .1, ".1") is "0.2"
+PASS stepUpExplicitBounds(-10, 10, .1, ".2") is "0.3"
+PASS stepUpExplicitBounds(-10, 10, .1, "1.") is "1.1"
+PASS stepUpExplicitBounds(-10, 10, .1, "2.") is "2.1"
+
+PASS stepUpExplicitBounds(-10, 10, .1, "-.1") is "0"
+PASS stepUpExplicitBounds(-10, 10, .1, "-.2") is "-0.1"
+PASS stepUpExplicitBounds(-10, 10, .1, "-1.") is "-0.9"
+PASS stepUpExplicitBounds(-10, 10, .1, "-2.") is "-1.9"
+PASS stepDownExplicitBounds(-10, 10, .1, ".1") is "0"
+PASS stepDownExplicitBounds(-10, 10, .1, ".2") is "0.1"
+PASS stepDownExplicitBounds(-10, 10, .1, "1.") is "0.9"
+PASS stepDownExplicitBounds(-10, 10, .1, "2.") is "1.9"
+
+PASS stepDownExplicitBounds(-10, 10, .1, "-.1") is "-0.2"
+PASS stepDownExplicitBounds(-10, 10, .1, "-.2") is "-0.3"
+PASS stepDownExplicitBounds(-10, 10, .1, "-1.") is "-1.1"
+PASS stepDownExplicitBounds(-10, 10, .1, "-2.") is "-2.1"
+
 Invalid step value
 PASS stepUpExplicitBounds(null, null, "foo", "0") is "1"
 PASS stepUpExplicitBounds(null, null, "0", "1") is "2"
@@ -31,9 +129,11 @@ PASS stepUpExplicitBounds(null, null, "-1", "2") is "3"
 PASS stepDownExplicitBounds(null, null, "foo", "1") is "0"
 PASS stepDownExplicitBounds(null, null, "0", "2") is "1"
 PASS stepDownExplicitBounds(null, null, "-1", "3") is "2"
+
 Step=any
 PASS stepUpExplicitBounds(null, null, "any", "1") is "2"
 PASS stepDownExplicitBounds(null, null, "any", "1") is "0"
+
 Overflow/underflow
 PASS stepUpExplicitBounds(null, "100", "1", "99") is "100"
 PASS stepUpExplicitBounds(null, "100", "1", "100") is "100"
@@ -46,15 +146,19 @@ PASS stepUpExplicitBounds(-100, 0, 1, -1) is "0"
 PASS stepUpExplicitBounds(null, 0, 1, 0) is "0"
 PASS stepUpExplicitBounds(-100, 0, 1, -1, 2) is "0"
 PASS stepUpExplicitBounds(null, null, "3.40282346e+38", "1", 2) is "0"
+
 stepDown()/stepUp() for stepMismatch values
 PASS stepUpExplicitBounds(null, null, 2, 1) is "4"
 PASS stepUpExplicitBounds(0, null, 10, 9, 9) is "100"
 PASS stepDownExplicitBounds(0, null, 10, 19) is "10"
+
 value + step is <= max, but rounded result would be > max.
 PASS stepUpExplicitBounds(null, 99, 10, 89) is "90"
+
 Huge value and small step
 PASS stepUpExplicitBounds(0, 1e38, 1, 1e38, 999) is "1e+38"
 PASS stepDownExplicitBounds(0, 1e38, 1, 1e38, 999) is "1e+38"
+
 Fractional numbers
 PASS stepUpExplicitBounds(null, null, 0.33333333333333333, 0, 3) is "1"
 PASS stepUpExplicitBounds(null, null, 0.1, 1) is "1.1"
index ce9f145..de09c39 100644 (file)
@@ -101,6 +101,8 @@ shouldBe('stepUpExplicitBounds(null, null, "any", "foo")', '"51"');
 shouldBe('stepDownExplicitBounds(null, null, "any", "foo")', '"49"');
 shouldBe('stepUpExplicitBounds(null, null, "foo", "foo")', '"51"');
 shouldBe('stepDownExplicitBounds(null, null, "foo", "foo")', '"49"');
+
+debug('');
 debug('Normal cases');
 shouldBe('stepUpExplicitBounds(null, null, null, "0")', '"1"');
 shouldBe('stepUpExplicitBounds(null, null, null, "1", 2)', '"3"');
@@ -108,6 +110,134 @@ shouldBe('stepUpExplicitBounds(null, null, null, "3", -1)', '"2"');
 shouldBe('stepDownExplicitBounds("-100", null, null, "2")', '"1"');
 shouldBe('stepDownExplicitBounds("-100", null, null, "1", 2)', '"-1"');
 shouldBe('stepDownExplicitBounds("-100", null, null, "-1", -1)', '"0"');
+
+
+debug('');
+debug('Fractional cases')
+// "When the element is suffering from a step mismatch, the user agent must
+// round the element's value to the nearest number for which the element would
+// not suffer from a step mismatch, and which is greater than or equal to the
+// minimum, and, if the maximum is not less than the minimum, which is less
+// than or equal to the maximum, if there is a number that matches these
+// constraints. If two numbers match these constraints, then user agents must
+// use the one nearest to positive infinity.""
+
+// Base/model/template tests
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "0.1")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "0.2")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "1.0")', '"2"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "1.1")', '"2"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "1.2")', '"2"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "2.0")', '"3"');
+
+// Same as above, but with negative numbers.
+debug('');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-0.1")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-0.2")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-1.0")', '"0"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-1.1")', '"0"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-1.2")', '"0"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-2.0")', '"-1"');
+
+// Same as above, but stepping down rather than up.
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "0.1")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "0.2")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "1.0")', '"0"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "1.1")', '"0"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "1.2")', '"0"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "2.0")', '"1"');
+
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-0.1")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-0.2")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-1.0")', '"-2"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-1.1")', '"-2"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-1.2")', '"-2"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-2.0")', '"-3"');
+
+// Same as above, but with leading/trailing zeros removed.
+debug('');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, ".1")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, ".2")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "1.")', '"2"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "2.")', '"3"');
+
+debug('');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-.1")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-.2")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-1.")', '"0"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-2.")', '"-1"');
+
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, ".1")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, ".2")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "1.")', '"0"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "2.")', '"1"');
+
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-.1")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-.2")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-1.")', '"-2"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-2.")', '"-3"');
+
+// Same as above, but stepping by .1 rather than 1.
+debug('');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "0.1")', '"0.2"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "0.2")', '"0.3"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "1.0")', '"1.1"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "1.1")', '"1.2"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "1.2")', '"1.3"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "2.0")', '"2.1"');
+
+debug('');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-0.1")', '"0"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-0.2")', '"-0.1"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-1.0")', '"-0.9"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-1.1")', '"-1"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-1.2")', '"-1.1"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-2.0")', '"-1.9"');
+
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "0.1")', '"0"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "0.2")', '"0.1"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "1.0")', '"0.9"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "1.1")', '"1"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "1.2")', '"1.1"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "2.0")', '"1.9"');
+
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-0.1")', '"-0.2"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-0.2")', '"-0.3"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-1.0")', '"-1.1"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-1.1")', '"-1.2"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-1.2")', '"-1.3"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-2.0")', '"-2.1"');
+
+debug('');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, ".1")', '"0.2"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, ".2")', '"0.3"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "1.")', '"1.1"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "2.")', '"2.1"');
+
+debug('');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-.1")', '"0"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-.2")', '"-0.1"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-1.")', '"-0.9"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-2.")', '"-1.9"');
+
+shouldBe('stepDownExplicitBounds(-10, 10, .1, ".1")', '"0"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, ".2")', '"0.1"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "1.")', '"0.9"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "2.")', '"1.9"');
+
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-.1")', '"-0.2"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-.2")', '"-0.3"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-1.")', '"-1.1"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-2.")', '"-2.1"');
+
+debug('');
 debug('Invalid step value');
 shouldBe('stepUpExplicitBounds(null, null, "foo", "0")', '"1"');
 shouldBe('stepUpExplicitBounds(null, null, "0", "1")', '"2"');
@@ -115,9 +245,13 @@ shouldBe('stepUpExplicitBounds(null, null, "-1", "2")', '"3"');
 shouldBe('stepDownExplicitBounds(null, null, "foo", "1")', '"0"');
 shouldBe('stepDownExplicitBounds(null, null, "0", "2")', '"1"');
 shouldBe('stepDownExplicitBounds(null, null, "-1", "3")', '"2"');
+
+debug('');
 debug('Step=any');
 shouldBe('stepUpExplicitBounds(null, null, "any", "1")', '"2"');
 shouldBe('stepDownExplicitBounds(null, null, "any", "1")', '"0"');
+
+debug('');
 debug('Overflow/underflow');
 shouldBe('stepUpExplicitBounds(null, "100", "1", "99")', '"100"');
 shouldBe('stepUpExplicitBounds(null, "100", "1", "100")', '"100"');
@@ -130,15 +264,23 @@ shouldBe('stepUpExplicitBounds(-100, 0, 1, -1)', '"0"');
 shouldBe('stepUpExplicitBounds(null, 0, 1, 0)', '"0"');
 shouldBe('stepUpExplicitBounds(-100, 0, 1, -1, 2)', '"0"');
 shouldBe('stepUpExplicitBounds(null, null, "3.40282346e+38", "1", 2)', '"0"');
+
+debug('');
 debug('stepDown()/stepUp() for stepMismatch values');
 shouldBe('stepUpExplicitBounds(null, null, 2, 1)', '"4"');
 shouldBe('stepUpExplicitBounds(0, null, 10, 9, 9)', '"100"');
 shouldBe('stepDownExplicitBounds(0, null, 10, 19)', '"10"');
+
+debug('');
 debug('value + step is <= max, but rounded result would be > max.');
 shouldBe('stepUpExplicitBounds(null, 99, 10, 89)', '"90"');
+
+debug('');
 debug('Huge value and small step');
 shouldBe('stepUpExplicitBounds(0, 1e38, 1, 1e38, 999)', '"1e+38"');
 shouldBe('stepDownExplicitBounds(0, 1e38, 1, 1e38, 999)', '"1e+38"');
+
+debug('');
 debug('Fractional numbers');
 shouldBe('stepUpExplicitBounds(null, null, 0.33333333333333333, 0, 3)', '"1"');
 shouldBe('stepUpExplicitBounds(null, null, 0.1, 1)', '"1.1"');
index 2dbf2fc..3e647cb 100644 (file)
@@ -63,6 +63,8 @@ debug('function arguments are (min, max, step, value, [stepCount])');
 debug('Using the default values');
 shouldBe('stepUpExplicitBounds(null, null, null, "")', '"51"');
 shouldBe('stepDownExplicitBounds(null, null, null, "")', '"49"');
+
+debug('');
 debug('Non-number arguments (stepCount)');
 shouldBe('stepUpExplicitBounds(null, null, null, "0", "0")', '"0"');
 shouldBe('stepDownExplicitBounds(null, null, null, "0", "0")', '"0"');
@@ -70,6 +72,8 @@ shouldBe('stepUpExplicitBounds(null, null, null, "0", "foo")', '"0"');
 shouldBe('stepDownExplicitBounds(null, null, null, "0", "foo")', '"0"');
 shouldBe('stepUpExplicitBounds(null, null, null, "0", null)', '"0"');
 shouldBe('stepDownExplicitBounds(null, null, null, "0", null)', '"0"');
+
+debug('');
 debug('Normal cases');
 shouldBe('stepUpExplicitBounds(null, null, null, "0")', '"1"');
 shouldBe('stepUpExplicitBounds(null, null, null, "1", 2)', '"3"');
@@ -77,9 +81,139 @@ shouldBe('stepUpExplicitBounds(null, null, null, "3", -1)', '"2"');
 shouldBe('stepDownExplicitBounds("-100", null, null, "2")', '"1"');
 shouldBe('stepDownExplicitBounds("-100", null, null, "1", 2)', '"-1"');
 shouldBe('stepDownExplicitBounds("-100", null, null, "-1", -1)', '"0"');
+
+debug('');
+debug('Fractional cases')
+// "When the element is suffering from a step mismatch, the user agent must
+// round the element's value to the nearest number for which the element would
+// not suffer from a step mismatch, and which is greater than or equal to the
+// minimum, and, if the maximum is not less than the minimum, which is less
+// than or equal to the maximum, if there is a number that matches these
+// constraints. If two numbers match these constraints, then user agents must
+// use the one nearest to positive infinity.""
+
+// Base/model/template tests
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "0.1")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "0.2")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "1.0")', '"2"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "1.1")', '"2"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "1.2")', '"2"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "2.0")', '"3"');
+
+// Same as above, but with negative numbers.
+debug('');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-0.1")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-0.2")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-1.0")', '"0"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-1.1")', '"0"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-1.2")', '"0"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-2.0")', '"-1"');
+
+// Same as above, but stepping down rather than up.
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "0.1")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "0.2")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "1.0")', '"0"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "1.1")', '"0"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "1.2")', '"0"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "2.0")', '"1"');
+
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-0.1")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-0.2")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-1.0")', '"-2"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-1.1")', '"-2"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-1.2")', '"-2"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-2.0")', '"-3"');
+
+// Same as above, but with leading/trailing zeros removed.
+debug('');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, ".1")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, ".2")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "1.")', '"2"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "2.")', '"3"');
+
+debug('');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-.1")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-.2")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-1.")', '"0"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-2.")', '"-1"');
+
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, ".1")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, ".2")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "1.")', '"0"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "2.")', '"1"');
+
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-.1")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-.2")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-1.")', '"-2"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-2.")', '"-3"');
+
+// Same as above, but stepping by .1 rather than 1.
+debug('');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "0.1")', '"0.2"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "0.2")', '"0.3"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "1.0")', '"1.1"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "1.1")', '"1.2"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "1.2")', '"1.3"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "2.0")', '"2.1"');
+
+debug('');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-0.1")', '"0"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-0.2")', '"-0.1"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-1.0")', '"-0.9"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-1.1")', '"-1"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-1.2")', '"-1.1"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-2.0")', '"-1.9"');
+
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "0.1")', '"0"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "0.2")', '"0.1"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "1.0")', '"0.9"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "1.1")', '"1"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "1.2")', '"1.1"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "2.0")', '"1.9"');
+
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-0.1")', '"-0.2"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-0.2")', '"-0.3"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-1.0")', '"-1.1"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-1.1")', '"-1.2"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-1.2")', '"-1.3"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-2.0")', '"-2.1"');
+
+debug('');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, ".1")', '"0.2"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, ".2")', '"0.3"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "1.")', '"1.1"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "2.")', '"2.1"');
+
+debug('');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-.1")', '"0"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-.2")', '"-0.1"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-1.")', '"-0.9"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-2.")', '"-1.9"');
+
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, ".1")', '"0"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, ".2")', '"0.1"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "1.")', '"0.9"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "2.")', '"1.9"');
+
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-.1")', '"-0.2"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-.2")', '"-0.3"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-1.")', '"-1.1"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-2.")', '"-2.1"');
+
+debug('');
 debug('Extra arguments');
 shouldBe('setInputAttributes(null, null, null, "0"); input.stepUp(1,2); input.value', '"1"');
 shouldBe('setInputAttributes(null, null, null, "1"); input.stepDown(1,3); input.value', '"0"');
+
+debug('');
 debug('Invalid step value');
 shouldBe('stepUpExplicitBounds(null, null, "foo", "0")', '"1"');
 shouldBe('stepUpExplicitBounds(null, null, "0", "1")', '"2"');
@@ -87,9 +221,13 @@ shouldBe('stepUpExplicitBounds(null, null, "-1", "2")', '"3"');
 shouldBe('stepDownExplicitBounds(null, null, "foo", "1")', '"0"');
 shouldBe('stepDownExplicitBounds(null, null, "0", "2")', '"1"');
 shouldBe('stepDownExplicitBounds(null, null, "-1", "3")', '"2"');
+
+debug('');
 debug('Step=any');
 shouldThrow('stepUpExplicitBounds(null, null, "any", "1")', invalidStateErr);
 shouldThrow('stepDownExplicitBounds(null, null, "any", "1")', invalidStateErr);
+
+debug('');
 debug('Overflow/underflow');
 shouldBe('stepUpExplicitBounds(null, "100", "1", "99")', '"100"');
 shouldThrow('stepUpExplicitBounds(null, "100", "1", "100")', invalidStateErr);
@@ -107,16 +245,24 @@ shouldThrow('stepUpExplicitBounds(null, 0, 1, 0)', invalidStateErr);
 shouldThrow('stepUpExplicitBounds(-100, 0, 1, -1, 2)', invalidStateErr);
 shouldBe('input.value', '"-1"');
 shouldThrow('stepUpExplicitBounds(null, null, "3.40282346e+38", "1", "2")', invalidStateErr);
+
+debug('');
 debug('stepDown()/stepUp() for stepMismatch values');
 shouldBe('stepUpExplicitBounds(null, null, 2, 1)', '"4"');
 shouldBe('input.stepDown(); input.value', '"2"');
 shouldBe('stepUpExplicitBounds(0, null, 10, 9, 9)', '"100"');
 shouldBe('stepDownExplicitBounds(0, null, 10, 19)', '"10"');
+
+debug('');
 debug('value + step is <= max, but rounded result would be > max.');
 shouldThrow('stepUpExplicitBounds(null, 99, 10, 89)', invalidStateErr);
+
+debug('');
 debug('Huge value and small step');
 shouldBe('stepUpExplicitBounds(0, 1e38, 1, 1e38, 999999)', '"1e+38"');
 shouldBe('stepDownExplicitBounds(0, 1e38, 1, 1e38, 999999)', '"1e+38"');
+
+debug('');
 debug('Fractional numbers');
 shouldBe('stepUpExplicitBounds(null, null, 0.33333333333333333, 0, 3)', '"1"');
 shouldBe('stepUpExplicitBounds(null, null, 0.1, 1)', '"1.1"');
@@ -127,6 +273,8 @@ shouldBe('stepUpExplicitBounds(0, 1, 0.003921568627450980, 0, 255)', '"1"');
 shouldBe('for (var i = 0; i < 255; i++) { input.stepDown(); }; input.value', '"0"');
 shouldBe('stepDownExplicitBounds(null, null, 0.1, 1, 8)', '"0.2"');
 shouldBe('stepDownExplicitBounds(null, null, 0.1, 1)', '"0.9"');
+
+debug('');
 </script>
 <script src="../../../resources/js-test-post.js"></script>
 </body>
index 175f3f4..f3c2a45 100644 (file)
@@ -1,3 +1,32 @@
+2015-11-02  Keith Rollin  <krollin@apple.com>
+
+        input[type=number] does not increment/decrement integers with trailing decimal characters
+        https://bugs.webkit.org/show_bug.cgi?id=148867
+        rdar://problem/22589693
+
+        Reviewed by Chris Dumez.
+
+        Support input[type=number].value attributes of the form "###." (that
+        is, leading digits with a decimal but no trailing digits). This form
+        was supported in the setting of the attribute, but not when changing
+        it through stepUp/Down.
+
+        Testing turned up similarly incorrect processing of -.###, so
+        addressed that, too.
+
+        Test: fast/forms/range/input-appearance-range-decimals.html
+
+        Updated the following tests:
+        - fast/forms/number/number-stepup-stepdown-from-renderer.html
+        - fast/forms/number/number-stepup-stepdown.html
+        - fast/forms/range/range-stepup-stepdown-from-renderer.html
+        - fast/forms/range/range-stepup-stepdown.html
+
+        * html/InputType.cpp:
+        (WebCore::InputType::stepUpFromRenderer):
+        * platform/Decimal.cpp:
+        (WebCore::Decimal::fromString):
+
 2015-11-02  Jiewen Tan  <jiewen_tan@apple.com>
 
         Null dereference loading Blink layout test fast/css/background-repeat-null-y-crash.html
index a9922c1..dc4512c 100644 (file)
@@ -1062,7 +1062,7 @@ void InputType::stepUpFromRenderer(int n)
     //   * If 0 is in-range, but not matched to step value
     //     - The value should be the larger matched value nearest to 0 if n > 0
     //       e.g. <input type=number min=-100 step=3> -> 2
-    //     - The value should be the smaler matched value nearest to 0 if n < 0
+    //     - The value should be the smaller matched value nearest to 0 if n < 0
     //       e.g. <input type=number min=-100 step=3> -> -1
     //   As for date/datetime-local/month/time/week types, the current value is assumed as "the current local date/time".
     //   As for datetime type, the current value is assumed as "the current date/time in UTC".
@@ -1077,7 +1077,7 @@ void InputType::stepUpFromRenderer(int n)
     // If the current value is not matched to step value:
     // - The value should be the larger matched value nearest to 0 if n > 0
     //   e.g. <input type=number value=3 min=-100 step=3> -> 5
-    // - The value should be the smaler matched value nearest to 0 if n < 0
+    // - The value should be the smaller matched value nearest to 0 if n < 0
     //   e.g. <input type=number value=3 min=-100 step=3> -> 2
     //
     // n is assumed as -n if step < 0.
index ee20db5..66bd224 100644 (file)
@@ -824,6 +824,7 @@ Decimal Decimal::fromString(const String& str)
             }
 
             HandleCharAndBreak('0', StateZero);
+            HandleCharAndBreak('.', StateDot);
             return nan();
 
         case StateStart:
@@ -874,7 +875,7 @@ Decimal Decimal::fromString(const String& str)
     if (state == StateZero)
         return zero(sign);
 
-    if (state == StateDigit || state == StateEDigit || state == StateDotDigit) {
+    if (state == StateDigit || state == StateDot || state == StateDotDigit || state == StateEDigit) {
         int resultExponent = exponent * (exponentSign == Negative ? -1 : 1) - numberOfDigitsAfterDot + numberOfExtraDigits;
         if (resultExponent < ExponentMin)
             return zero(Positive);