Bug 949134 - Use the default step for <input type=number>'s spin buttons if step='any'. r=smaug

This commit is contained in:
Jonathan Watt 2014-01-15 17:22:16 +00:00
parent c948a96d59
commit 74a361b8b9
4 changed files with 42 additions and 6 deletions

View File

@ -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

View File

@ -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

View File

@ -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
}
}

View File

@ -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();