From 74a361b8b987fac3e2b6189080f2c8b7075bcbcb Mon Sep 17 00:00:00 2001 From: Jonathan Watt Date: Wed, 15 Jan 2014 17:22:16 +0000 Subject: [PATCH] Bug 949134 - Use the default step for 's spin buttons if step='any'. r=smaug --- content/html/content/src/HTMLInputElement.cpp | 14 ++++++++++---- content/html/content/src/HTMLInputElement.h | 9 ++++++++- .../test/forms/test_input_number_key_events.html | 11 ++++++++++- .../test/forms/test_input_number_mouse_events.html | 14 ++++++++++++++ 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/content/html/content/src/HTMLInputElement.cpp b/content/html/content/src/HTMLInputElement.cpp index 0a027845a23..ea7ba39c3e8 100644 --- a/content/html/content/src/HTMLInputElement.cpp +++ b/content/html/content/src/HTMLInputElement.cpp @@ -2078,7 +2078,9 @@ HTMLInputElement::GetStepBase() const } nsresult -HTMLInputElement::GetValueIfStepped(int32_t aStep, Decimal* aNextStep) +HTMLInputElement::GetValueIfStepped(int32_t aStep, + StepCallerType aCallerType, + Decimal* aNextStep) { if (!DoStepDownStepUpApply()) { return NS_ERROR_DOM_INVALID_STATE_ERR; @@ -2086,7 +2088,11 @@ HTMLInputElement::GetValueIfStepped(int32_t aStep, Decimal* aNextStep) Decimal step = GetStep(); if (step == kStepAny) { - return NS_ERROR_DOM_INVALID_STATE_ERR; + if (aCallerType != CALLED_FOR_USER_EVENT) { + return NS_ERROR_DOM_INVALID_STATE_ERR; + } + // Allow the spin buttons and up/down arrow keys to do something sensible: + step = GetDefaultStep(); } Decimal value = GetValueAsDecimal(); @@ -2168,7 +2174,7 @@ HTMLInputElement::ApplyStep(int32_t aStep) { Decimal nextStep = Decimal::nan(); // unchanged if value will not change - nsresult rv = GetValueIfStepped(aStep, &nextStep); + nsresult rv = GetValueIfStepped(aStep, CALLED_FOR_SCRIPT, &nextStep); if (NS_SUCCEEDED(rv) && nextStep.isFinite()) { SetValue(nextStep); @@ -3603,7 +3609,7 @@ HTMLInputElement::StepNumberControlForUserEvent(int32_t aDirection) { Decimal newValue = Decimal::nan(); // unchanged if value will not change - nsresult rv = GetValueIfStepped(aDirection, &newValue); + nsresult rv = GetValueIfStepped(aDirection, CALLED_FOR_USER_EVENT, &newValue); if (NS_FAILED(rv) || !newValue.isFinite()) { return; // value should not or will not change diff --git a/content/html/content/src/HTMLInputElement.h b/content/html/content/src/HTMLInputElement.h index 2e4db8fa4d4..112c5efb5f2 100644 --- a/content/html/content/src/HTMLInputElement.h +++ b/content/html/content/src/HTMLInputElement.h @@ -1112,6 +1112,11 @@ protected: */ Decimal GetDefaultStep() const; + enum StepCallerType { + CALLED_FOR_USER_EVENT, + CALLED_FOR_SCRIPT + }; + /** * Sets the aValue outparam to the value that this input would take if * someone tries to step aStep steps and this input's value would change as @@ -1124,7 +1129,9 @@ protected: * was initiated by a stepUp()/stepDown() call from script under conditions * that such a call should throw. */ - nsresult GetValueIfStepped(int32_t aStep, Decimal* aNextStep); + nsresult GetValueIfStepped(int32_t aStepCount, + StepCallerType aCallerType, + Decimal* aNextStep); /** * Apply a step change from stepUp or stepDown by multiplying aStep by the diff --git a/content/html/content/test/forms/test_input_number_key_events.html b/content/html/content/test/forms/test_input_number_key_events.html index 8237cd0293d..e81596c45b6 100644 --- a/content/html/content/test/forms/test_input_number_key_events.html +++ b/content/html/content/test/forms/test_input_number_key_events.html @@ -82,7 +82,7 @@ function expectedValueAfterStepUpOrDown(stepFactor, element) { } var step = getStep(element); if (step == "any") { - return value; + step = 1; } var minimum = getMinimum(element); @@ -187,6 +187,15 @@ function test() { expectedVal = 0; synthesizeKey(key, {}); is(elem.value, expectedVal, "Test " + key + " for number control where scripted preventDefault() should prevent the value changing"); + + // Test step="any" behavior: + var oldStep = elem.step; + elem.step = "any"; + oldVal = elem.value = 0; + expectedVal = expectedValAfterKeyEvent(key, elem); + synthesizeKey(key, {}); + is(elem.value, expectedVal, "Test " + key + " for number control with value set to the midpoint and step='any' (" + oldVal + ")"); + elem.step = oldStep; // restore } } diff --git a/content/html/content/test/forms/test_input_number_mouse_events.html b/content/html/content/test/forms/test_input_number_mouse_events.html index b4c5a267061..388765e933b 100644 --- a/content/html/content/test/forms/test_input_number_mouse_events.html +++ b/content/html/content/test/forms/test_input_number_mouse_events.html @@ -62,6 +62,20 @@ function test() { synthesizeMouse(input, SPIN_DOWN_X, SPIN_DOWN_Y, { type: "mouseup" }); is(input.value, 0, "Test mouseup on spin-down button"); + // Test step="any" behavior: + input.value = 0; + var oldStep = input.step; + input.step = "any"; + synthesizeMouse(input, SPIN_UP_X, SPIN_UP_Y, { type: "mousedown" }); + is(input.value, 1, "Test step-up on mousedown on spin-up button with step='any'"); + synthesizeMouse(input, SPIN_UP_X, SPIN_UP_Y, { type: "mouseup" }); + is(input.value, 1, "Test mouseup on spin-up button with step='any'"); + synthesizeMouse(input, SPIN_DOWN_X, SPIN_DOWN_Y, { type: "mousedown" }); + is(input.value, 0, "Test step-down on mousedown on spin-down button with step='any'"); + synthesizeMouse(input, SPIN_DOWN_X, SPIN_DOWN_Y, { type: "mouseup" }); + is(input.value, 0, "Test mouseup on spin-down button with step='any'"); + input.step = oldStep; // restore + // Test that preventDefault() works: function preventDefault(e) { e.preventDefault();