зеркало из https://github.com/mozilla/gecko-dev.git
Bug 781573 - Implement the step attribute for <input type=time>. r=smaug
--HG-- extra : rebase_source : 802145c921a679d041f83212e872cc5583ed4cc9
This commit is contained in:
Родитель
4a0ad76a83
Коммит
1d5d1d991e
|
@ -180,7 +180,10 @@ static const nsAttrValue::EnumTable* kInputDefaultInputmode = &kInputInputmodeTa
|
|||
|
||||
const double nsHTMLInputElement::kStepScaleFactorDate = 86400000;
|
||||
const double nsHTMLInputElement::kStepScaleFactorNumber = 1;
|
||||
const double nsHTMLInputElement::kStepScaleFactorTime = 1000;
|
||||
const double nsHTMLInputElement::kDefaultStepBase = 0;
|
||||
const double nsHTMLInputElement::kDefaultStep = 1;
|
||||
const double nsHTMLInputElement::kDefaultStepTime = 60;
|
||||
const double nsHTMLInputElement::kStepAny = 0;
|
||||
|
||||
#define NS_INPUT_ELEMENT_STATE_IID \
|
||||
|
@ -1486,7 +1489,8 @@ double
|
|||
nsHTMLInputElement::GetStepBase() const
|
||||
{
|
||||
MOZ_ASSERT(mType == NS_FORM_INPUT_NUMBER ||
|
||||
mType == NS_FORM_INPUT_DATE,
|
||||
mType == NS_FORM_INPUT_DATE ||
|
||||
mType == NS_FORM_INPUT_TIME,
|
||||
"Check that kDefaultStepBase is correct for this new type");
|
||||
|
||||
double stepBase;
|
||||
|
@ -4489,24 +4493,22 @@ nsHTMLInputElement::GetStep() const
|
|||
{
|
||||
MOZ_ASSERT(DoesStepApply(), "GetStep() can only be called if @step applies");
|
||||
|
||||
// NOTE: should be defaultStep, which is 1 for type=number and date.
|
||||
double step = 1;
|
||||
if (!HasAttr(kNameSpaceID_None, nsGkAtoms::step)) {
|
||||
return GetDefaultStep() * GetStepScaleFactor();
|
||||
}
|
||||
|
||||
if (HasAttr(kNameSpaceID_None, nsGkAtoms::step)) {
|
||||
nsAutoString stepStr;
|
||||
GetAttr(kNameSpaceID_None, nsGkAtoms::step, stepStr);
|
||||
nsAutoString stepStr;
|
||||
GetAttr(kNameSpaceID_None, nsGkAtoms::step, stepStr);
|
||||
|
||||
if (stepStr.LowerCaseEqualsLiteral("any")) {
|
||||
// The element can't suffer from step mismatch if there is no step.
|
||||
return kStepAny;
|
||||
}
|
||||
if (stepStr.LowerCaseEqualsLiteral("any")) {
|
||||
// The element can't suffer from step mismatch if there is no step.
|
||||
return kStepAny;
|
||||
}
|
||||
|
||||
nsresult ec;
|
||||
step = stepStr.ToDouble(&ec);
|
||||
if (NS_FAILED(ec) || step <= 0) {
|
||||
// NOTE: we should use defaultStep, which is 1 for type=number and date.
|
||||
step = 1;
|
||||
}
|
||||
nsresult ec;
|
||||
double step = stepStr.ToDouble(&ec);
|
||||
if (NS_FAILED(ec) || step <= 0) {
|
||||
step = GetDefaultStep();
|
||||
}
|
||||
|
||||
// TODO: This multiplication can lead to inexact results, we should use a
|
||||
|
@ -5008,17 +5010,24 @@ nsHTMLInputElement::GetValidationMessage(nsAString& aValidationMessage,
|
|||
ConvertNumberToString(valueLow, valueLowStr);
|
||||
ConvertNumberToString(valueHigh, valueHighStr);
|
||||
|
||||
const PRUnichar* params[] = { valueLowStr.get(), valueHighStr.get() };
|
||||
rv = nsContentUtils::FormatLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
||||
"FormValidationStepMismatch",
|
||||
params, message);
|
||||
if (valueLowStr.Equals(valueHighStr)) {
|
||||
const PRUnichar* params[] = { valueLowStr.get() };
|
||||
rv = nsContentUtils::FormatLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
||||
"FormValidationStepMismatchOneValue",
|
||||
params, message);
|
||||
} else {
|
||||
const PRUnichar* params[] = { valueLowStr.get(), valueHighStr.get() };
|
||||
rv = nsContentUtils::FormatLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
||||
"FormValidationStepMismatch",
|
||||
params, message);
|
||||
}
|
||||
} else {
|
||||
nsAutoString valueLowStr;
|
||||
ConvertNumberToString(valueLow, valueLowStr);
|
||||
|
||||
const PRUnichar* params[] = { valueLowStr.get() };
|
||||
rv = nsContentUtils::FormatLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
||||
"FormValidationStepMismatchWithoutMax",
|
||||
"FormValidationStepMismatchOneValue",
|
||||
params, message);
|
||||
}
|
||||
|
||||
|
@ -5441,6 +5450,25 @@ nsHTMLInputElement::GetStepScaleFactor() const
|
|||
return kStepScaleFactorDate;
|
||||
case NS_FORM_INPUT_NUMBER:
|
||||
return kStepScaleFactorNumber;
|
||||
case NS_FORM_INPUT_TIME:
|
||||
return kStepScaleFactorTime;
|
||||
default:
|
||||
MOZ_NOT_REACHED();
|
||||
return MOZ_DOUBLE_NaN();
|
||||
}
|
||||
}
|
||||
|
||||
double
|
||||
nsHTMLInputElement::GetDefaultStep() const
|
||||
{
|
||||
MOZ_ASSERT(DoesStepApply());
|
||||
|
||||
switch (mType) {
|
||||
case NS_FORM_INPUT_DATE:
|
||||
case NS_FORM_INPUT_NUMBER:
|
||||
return kDefaultStep;
|
||||
case NS_FORM_INPUT_TIME:
|
||||
return kDefaultStepTime;
|
||||
default:
|
||||
MOZ_NOT_REACHED();
|
||||
return MOZ_DOUBLE_NaN();
|
||||
|
|
|
@ -486,7 +486,7 @@ protected:
|
|||
/**
|
||||
* Returns if the step attribute apply for the current type.
|
||||
*/
|
||||
bool DoesStepApply() const { return DoesMinMaxApply() && mType != NS_FORM_INPUT_TIME; }
|
||||
bool DoesStepApply() const { return DoesMinMaxApply(); }
|
||||
|
||||
/**
|
||||
* Returns if stepDown and stepUp methods apply for the current type.
|
||||
|
@ -703,6 +703,12 @@ protected:
|
|||
*/
|
||||
double GetStepBase() const;
|
||||
|
||||
/**
|
||||
* Returns the default step for the current type.
|
||||
* @return the default step for the current type.
|
||||
*/
|
||||
double GetDefaultStep() const;
|
||||
|
||||
/**
|
||||
* Apply a step change from stepUp or stepDown by multiplying aStep by the
|
||||
* current step value.
|
||||
|
@ -768,10 +774,16 @@ protected:
|
|||
// Step scale factor values, for input types that have one.
|
||||
static const double kStepScaleFactorDate;
|
||||
static const double kStepScaleFactorNumber;
|
||||
static const double kStepScaleFactorTime;
|
||||
|
||||
// Default step base value when a type do not have specific one.
|
||||
static const double kDefaultStepBase;
|
||||
// Float alue returned by GetStep() when the step attribute is set to 'any'.
|
||||
|
||||
// Default step used when there is no specified step.
|
||||
static const double kDefaultStep;
|
||||
static const double kDefaultStepTime;
|
||||
|
||||
// Float value returned by GetStep() when the step attribute is set to 'any'.
|
||||
static const double kStepAny;
|
||||
|
||||
/**
|
||||
|
|
|
@ -239,6 +239,9 @@ for (var test of data) {
|
|||
|
||||
break;
|
||||
case 'time':
|
||||
// Don't worry about that.
|
||||
input.step = 'any';
|
||||
|
||||
input.max = '10:10';
|
||||
input.value = '10:09';
|
||||
checkValidity(input, true, apply, apply);
|
||||
|
|
|
@ -237,6 +237,9 @@ for (var test of data) {
|
|||
"validation message");
|
||||
break;
|
||||
case 'time':
|
||||
// Don't worry about that.
|
||||
input.step = 'any';
|
||||
|
||||
input.min = '20:20';
|
||||
input.value = '20:20:01';
|
||||
checkValidity(input, true, apply, apply);
|
||||
|
|
|
@ -19,30 +19,30 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=635553
|
|||
|
||||
/** Test for Bug 635553 **/
|
||||
|
||||
var types = [
|
||||
[ 'hidden', false ],
|
||||
[ 'text', false ],
|
||||
[ 'search', false ],
|
||||
[ 'tel', false ],
|
||||
[ 'url', false ],
|
||||
[ 'email', false ],
|
||||
[ 'password', false ],
|
||||
[ 'datetime', true, true ],
|
||||
[ 'date', true ],
|
||||
[ 'month', true, true ],
|
||||
[ 'week', true, true ],
|
||||
[ 'time', true ],
|
||||
[ 'datetime-local', true, true ],
|
||||
[ 'number', true ],
|
||||
[ 'range', true, true ],
|
||||
[ 'color', false, true ],
|
||||
[ 'checkbox', false ],
|
||||
[ 'radio', false ],
|
||||
[ 'file', false ],
|
||||
[ 'submit', false ],
|
||||
[ 'image', false ],
|
||||
[ 'reset', false ],
|
||||
[ 'button', false ],
|
||||
var data = [
|
||||
{ type: 'hidden', apply: false },
|
||||
{ type: 'text', apply: false },
|
||||
{ type: 'search', apply: false },
|
||||
{ type: 'tel', apply: false },
|
||||
{ type: 'url', apply: false },
|
||||
{ type: 'email', apply: false },
|
||||
{ type: 'password', apply: false },
|
||||
{ type: 'datetime', apply: true, todo: true },
|
||||
{ type: 'date', apply: true },
|
||||
{ type: 'month', apply: true, todo: true },
|
||||
{ type: 'week', apply: true, todo: true },
|
||||
{ type: 'time', apply: true },
|
||||
{ type: 'datetime-local', apply: true, todo: true },
|
||||
{ type: 'number', apply: true },
|
||||
{ type: 'range', apply: true, todo: true },
|
||||
{ type: 'color', apply: false, todo: true },
|
||||
{ type: 'checkbox', apply: false },
|
||||
{ type: 'radio', apply: false },
|
||||
{ type: 'file', apply: false },
|
||||
{ type: 'submit', apply: false },
|
||||
{ type: 'image', apply: false },
|
||||
{ type: 'reset', apply: false },
|
||||
{ type: 'button', apply: false },
|
||||
];
|
||||
|
||||
function getFreshElement(type) {
|
||||
|
@ -63,9 +63,18 @@ function checkValidity(aElement, aValidity, aApply, aData)
|
|||
if (aValidity) {
|
||||
is(aElement.validationMessage, "", "There should be no validation message.");
|
||||
} else {
|
||||
is(aElement.validationMessage, "Please select a valid value. " +
|
||||
"The two nearest valid values are " + aData.low + " and " + aData.high + ".",
|
||||
"There should be a validation message.");
|
||||
if (aElement.validity.rangeUnderflow) {
|
||||
is(aElement.validationMessage, "Please select a value that is higher than " +
|
||||
aElement.min + ".", "There should be a validation message.");
|
||||
} else if (aData.low == aData.high) {
|
||||
is(aElement.validationMessage, "Please select a valid value. " +
|
||||
"The nearest valid value is " + aData.low + ".",
|
||||
"There should be a validation message.");
|
||||
} else {
|
||||
is(aElement.validationMessage, "Please select a valid value. " +
|
||||
"The two nearest valid values are " + aData.low + " and " + aData.high + ".",
|
||||
"There should be a validation message.");
|
||||
}
|
||||
}
|
||||
|
||||
is(aElement.mozMatchesSelector(":valid"), aElement.willValidate && aValidity,
|
||||
|
@ -76,327 +85,441 @@ function checkValidity(aElement, aValidity, aApply, aData)
|
|||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({'set': [["dom.experimental_forms", true]]}, function() {
|
||||
for (var data of types) {
|
||||
var input = getFreshElement(data[0]);
|
||||
var apply = data[1];
|
||||
for (var test of data) {
|
||||
var input = getFreshElement(test.type);
|
||||
var apply = test.apply;
|
||||
|
||||
if (data[2]) {
|
||||
todo_is(input.type, data[0], data[0] + " isn't implemented yet");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (input.type == 'time') {
|
||||
if (test.todo) {
|
||||
todo_is(input.type, test.type, test.type + " isn't implemented yet");
|
||||
continue;
|
||||
}
|
||||
|
||||
// The element should be valid, there should be no step mismatch.
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.step = '0';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
if (input.type == 'url') {
|
||||
input.value = 'http://mozilla.org';
|
||||
checkValidity(input, true, apply);
|
||||
} else if (input.type == 'email') {
|
||||
input.value = 'foo@bar.com';
|
||||
checkValidity(input, true, apply);
|
||||
} else if (input.type == 'file') {
|
||||
// Need privileges to set a filename with .value.
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Components.interfaces.nsIProperties);
|
||||
var file = dirSvc.get("ProfD", Components.interfaces.nsIFile);
|
||||
file.append('635499_file');
|
||||
var outStream = Components.classes["@mozilla.org/network/file-output-stream;1"].
|
||||
createInstance(Components.interfaces.nsIFileOutputStream);
|
||||
outStream.init(file, 0x02 | 0x08 | 0x20, // write, create, truncate
|
||||
0666, 0);
|
||||
outStream.write("foo", 3);
|
||||
outStream.close();
|
||||
|
||||
input.value = file.path;
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
file.remove(false);
|
||||
} else if (input.type == 'date') {
|
||||
// For date, the step is calulated on the timestamp since 1970-01-01
|
||||
// which mean that for all dates prior to the epoch, this timestamp is < 0
|
||||
// and the behavior might differ, therefore we have to test for these cases.
|
||||
|
||||
// When step is 1 every date is valid
|
||||
input.value = '2012-07-05';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.step = 'foo';
|
||||
input.value = '1970-01-01';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.step = '-1';
|
||||
input.value = '1969-12-12';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.removeAttribute('step');
|
||||
input.value = '1500-01-01';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.step = 'any';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.step = 'aNy';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.step = 'AnY';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.step = 'ANY';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
// When min is set to a valid date, there is a step base.
|
||||
input.min = '2008-02-28';
|
||||
input.step = '2';
|
||||
input.value = '2008-03-01';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.value = '2008-02-29';
|
||||
checkValidity(input, false, apply, { low: "2008-02-28", high: "2008-03-01" });
|
||||
|
||||
input.min = '2008-02-27';
|
||||
input.value = '2008-02-28';
|
||||
checkValidity(input, false, apply, { low: "2008-02-27", high: "2008-02-29" });
|
||||
|
||||
input.min = '2009-02-27';
|
||||
input.value = '2009-02-28';
|
||||
checkValidity(input, false, apply, { low: "2009-02-27", high: "2009-03-01" });
|
||||
|
||||
input.min = '2009-02-01';
|
||||
input.step = '1.1';
|
||||
input.value = '2009-02-02';
|
||||
checkValidity(input, false, apply, { low: "2009-02-01", high: "2009-02-12" });
|
||||
|
||||
// Without any step attribute the date is valid
|
||||
input.removeAttribute('step');
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.min = '1950-01-01';
|
||||
input.step = '366';
|
||||
input.value = '1951-01-01';
|
||||
checkValidity(input, false, apply, { low: "1950-01-01", high: "1951-01-02" });
|
||||
|
||||
input.min = '1951-01-01';
|
||||
input.step = '365';
|
||||
input.value = '1952-01-01';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.step = '0.9';
|
||||
input.value = '1951-01-02';
|
||||
checkValidity(input, false, apply, { low: "1951-01-01", high: "1951-01-10" });
|
||||
|
||||
input.value = '1951-01-10'
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.step = '0.5';
|
||||
input.value = '1951-01-02';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.step = '1.5';
|
||||
input.value = '1951-01-03';
|
||||
checkValidity(input, false, apply, { low: "1951-01-01", high: "1951-01-04" });
|
||||
// Checks to do for all types that support step:
|
||||
// - check for @step=0,
|
||||
// - check for @step behind removed,
|
||||
// - check for @step being 'any' with different case variations.
|
||||
switch (input.type) {
|
||||
case 'text':
|
||||
case 'hidden':
|
||||
case 'search':
|
||||
case 'password':
|
||||
case 'tel':
|
||||
case 'radio':
|
||||
case 'checkbox':
|
||||
case 'reset':
|
||||
case 'button':
|
||||
case 'submit':
|
||||
case 'image':
|
||||
input.value = '0';
|
||||
checkValidity(input, true, apply);
|
||||
break;
|
||||
case 'url':
|
||||
input.value = 'http://mozilla.org';
|
||||
checkValidity(input, true, apply);
|
||||
break;
|
||||
case 'email':
|
||||
input.value = 'foo@bar.com';
|
||||
checkValidity(input, true, apply);
|
||||
break;
|
||||
case 'file':
|
||||
// Need privileges to set a filename with .value.
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Components.interfaces.nsIProperties);
|
||||
var file = dirSvc.get("ProfD", Components.interfaces.nsIFile);
|
||||
file.append('635499_file');
|
||||
var outStream = Components.classes["@mozilla.org/network/file-output-stream;1"].
|
||||
createInstance(Components.interfaces.nsIFileOutputStream);
|
||||
outStream.init(file, 0x02 | 0x08 | 0x20, // write, create, truncate
|
||||
0666, 0);
|
||||
outStream.write("foo", 3);
|
||||
outStream.close();
|
||||
|
||||
input.value = file.path;
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
file.remove(false);
|
||||
break;
|
||||
case 'date':
|
||||
// For date, the step is calulated on the timestamp since 1970-01-01
|
||||
// which mean that for all dates prior to the epoch, this timestamp is < 0
|
||||
// and the behavior might differ, therefore we have to test for these cases.
|
||||
|
||||
// When step is invalid, every date is valid
|
||||
input.step = 0;
|
||||
input.value = '2012-07-05';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.step = 'foo';
|
||||
input.value = '1970-01-01';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.step = '-1';
|
||||
input.value = '1969-12-12';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.removeAttribute('step');
|
||||
input.value = '1500-01-01';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.step = 'any';
|
||||
input.value = '1966-12-12';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.step = 'ANY';
|
||||
input.value = '2013-02-03';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
// When min is set to a valid date, there is a step base.
|
||||
input.min = '2008-02-28';
|
||||
input.step = '2';
|
||||
input.value = '2008-03-01';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.value = '2008-02-29';
|
||||
checkValidity(input, false, apply, { low: "2008-02-28", high: "2008-03-01" });
|
||||
|
||||
input.min = '2008-02-27';
|
||||
input.value = '2008-02-28';
|
||||
checkValidity(input, false, apply, { low: "2008-02-27", high: "2008-02-29" });
|
||||
|
||||
input.min = '2009-02-27';
|
||||
input.value = '2009-02-28';
|
||||
checkValidity(input, false, apply, { low: "2009-02-27", high: "2009-03-01" });
|
||||
|
||||
input.min = '2009-02-01';
|
||||
input.step = '1.1';
|
||||
input.value = '2009-02-02';
|
||||
checkValidity(input, false, apply, { low: "2009-02-01", high: "2009-02-12" });
|
||||
|
||||
// Without any step attribute the date is valid
|
||||
input.removeAttribute('step');
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.min = '1950-01-01';
|
||||
input.step = '366';
|
||||
input.value = '1951-01-01';
|
||||
checkValidity(input, false, apply, { low: "1950-01-01", high: "1951-01-02" });
|
||||
|
||||
input.min = '1951-01-01';
|
||||
input.step = '365';
|
||||
input.value = '1952-01-01';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.step = '0.9';
|
||||
input.value = '1951-01-02';
|
||||
checkValidity(input, false, apply, { low: "1951-01-01", high: "1951-01-10" });
|
||||
|
||||
input.value = '1951-01-10'
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.step = '0.5';
|
||||
input.value = '1951-01-02';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.step = '1.5';
|
||||
input.value = '1951-01-03';
|
||||
checkValidity(input, false, apply, { low: "1951-01-01", high: "1951-01-04" });
|
||||
|
||||
input.value = '1951-01-08';
|
||||
checkValidity(input, false, apply, { low: "1951-01-07", high: "1951-01-10" });
|
||||
|
||||
input.step = '3000';
|
||||
input.min= '1968-01-01';
|
||||
input.value = '1968-05-12';
|
||||
checkValidity(input, false, apply, { low: "1968-01-01", high: "1976-03-19" });
|
||||
|
||||
input.value = '1971-01-01';
|
||||
checkValidity(input, false, apply, { low: "1968-01-01", high: "1976-03-19" });
|
||||
|
||||
input.value = '1951-01-08';
|
||||
checkValidity(input, false, apply, { low: "1951-01-07", high: "1951-01-10" });
|
||||
input.value = '1991-01-01';
|
||||
checkValidity(input, false, apply, { low: "1984-06-05", high: "1992-08-22" });
|
||||
|
||||
input.step = '3000';
|
||||
input.min= '1968-01-01';
|
||||
input.value = '1968-05-12';
|
||||
checkValidity(input, false, apply, { low: "1968-01-01", high: "1976-03-19" });
|
||||
input.value = '1984-06-05';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.value = '1971-01-01';
|
||||
checkValidity(input, false, apply, { low: "1968-01-01", high: "1976-03-19" });
|
||||
input.value = '1992-08-22';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.value = '1991-01-01';
|
||||
checkValidity(input, false, apply, { low: "1984-06-05", high: "1992-08-22" });
|
||||
input.step = '1.1';
|
||||
input.min = '1991-01-01';
|
||||
input.value = '1991-01-01';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.value = '1984-06-05';
|
||||
checkValidity(input, true, apply);
|
||||
input.value = '1991-01-02';
|
||||
checkValidity(input, false, apply, { low: "1991-01-01", high: "1991-01-12" });
|
||||
|
||||
input.value = '1992-08-22';
|
||||
checkValidity(input, true, apply);
|
||||
input.value = '1991-01-12';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.step = '1.1';
|
||||
input.min = '1991-01-01';
|
||||
input.value = '1991-01-01';
|
||||
checkValidity(input, true, apply);
|
||||
input.step = '1.1';
|
||||
input.min = '1969-12-20';
|
||||
input.value = '1969-12-20';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.value = '1991-01-02';
|
||||
checkValidity(input, false, apply, { low: "1991-01-01", high: "1991-01-12" });
|
||||
input.value = '1969-12-21';
|
||||
checkValidity(input, false, apply, { low: "1969-12-20", high: "1969-12-31" });
|
||||
|
||||
input.value = '1991-01-12';
|
||||
checkValidity(input, true, apply);
|
||||
input.value = '1969-12-31';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.step = '1.1';
|
||||
input.min = '1969-12-20';
|
||||
input.value = '1969-12-20';
|
||||
checkValidity(input, true, apply);
|
||||
break;
|
||||
case 'number':
|
||||
// When step=0, the allowed step is 1.
|
||||
input.step = '0';
|
||||
input.value = '1.2';
|
||||
checkValidity(input, false, apply, { low: 1, high: 2 });
|
||||
|
||||
input.value = '1969-12-21';
|
||||
checkValidity(input, false, apply, { low: "1969-12-20", high: "1969-12-31" });
|
||||
input.value = '1';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.value = '1969-12-31';
|
||||
checkValidity(input, true, apply);
|
||||
input.value = '0';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
} else {
|
||||
// When step=0, the allowed step is 1.
|
||||
input.value = '1.2';
|
||||
checkValidity(input, false, apply, { low: 1, high: 2 });
|
||||
// When step is NaN, the allowed step value is 1.
|
||||
input.step = 'foo';
|
||||
input.value = '1';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.value = '1';
|
||||
checkValidity(input, true, apply);
|
||||
input.value = '1.5';
|
||||
checkValidity(input, false, apply, { low: 1, high: 2 });
|
||||
|
||||
input.value = '0';
|
||||
checkValidity(input, true, apply);
|
||||
// When step is negative, the allowed step value is 1.
|
||||
input.step = '-0.1';
|
||||
checkValidity(input, false, apply, { low: 1, high: 2 });
|
||||
|
||||
// When step is NaN, the allowed step value is 1.
|
||||
input.step = 'foo';
|
||||
input.value = '1';
|
||||
checkValidity(input, true, apply);
|
||||
input.value = '1';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.value = '1.5';
|
||||
checkValidity(input, false, apply, { low: 1, high: 2 });
|
||||
// When step is missing, the allowed step value is 1.
|
||||
input.removeAttribute('step');
|
||||
input.value = '1.5';
|
||||
checkValidity(input, false, apply, { low: 1, high: 2 });
|
||||
|
||||
// When step is negative, the allowed step value is 1.
|
||||
input.step = '-0.1';
|
||||
checkValidity(input, false, apply, { low: 1, high: 2 });
|
||||
input.value = '1';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.value = '1';
|
||||
checkValidity(input, true, apply);
|
||||
// When step is 'any', all values are fine wrt to step.
|
||||
input.step = 'any';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
// When step is missing, the allowed step value is 1.
|
||||
input.removeAttribute('step');
|
||||
input.value = '1.5';
|
||||
checkValidity(input, false, apply, { low: 1, high: 2 });
|
||||
input.step = 'aNy';
|
||||
input.value = '1337';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.value = '1';
|
||||
checkValidity(input, true, apply);
|
||||
input.step = 'AnY';
|
||||
input.value = '0.1';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
// When step is 'any', all values are fine wrt to step.
|
||||
input.step = 'any';
|
||||
checkValidity(input, true, apply);
|
||||
input.step = 'ANY';
|
||||
input.value = '-13.37';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.step = 'aNy';
|
||||
input.value = '1337';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.step = 'AnY';
|
||||
input.value = '0.1';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.step = 'ANY';
|
||||
input.value = '-13.37';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
// When min is set to a valid float, there is a step base.
|
||||
input.min = '1';
|
||||
input.step = '2';
|
||||
input.value = '3';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.value = '2';
|
||||
checkValidity(input, false, apply, { low: 1, high: 3 });
|
||||
|
||||
input.removeAttribute('step'); // step = 1
|
||||
input.min = '0.5';
|
||||
input.value = '5.5';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.value = '1';
|
||||
checkValidity(input, false, apply, { low: 0.5, high: 1.5 });
|
||||
|
||||
input.min = '-0.1';
|
||||
input.step = '1';
|
||||
input.value = '0.9';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.value = '0.1';
|
||||
checkValidity(input, false, apply, { low: -0.1, high: 0.9 });
|
||||
|
||||
// When min is set to NaN, there is no step base (step base=0 actually).
|
||||
input.min = 'foo';
|
||||
input.step = '1';
|
||||
input.value = '1';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.value = '0.5';
|
||||
checkValidity(input, false, apply, { low: 0, high: 1 });
|
||||
|
||||
input.min = '';
|
||||
input.value = '1';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.value = '0.5';
|
||||
checkValidity(input, false, apply, { low: 0, high: 1 });
|
||||
|
||||
input.removeAttribute('min');
|
||||
|
||||
// If value isn't a number, the element isn't invalid.
|
||||
input.value = '';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
// Regular situations.
|
||||
input.step = '2';
|
||||
input.value = '1.5';
|
||||
checkValidity(input, false, apply, { low: 0, high: 2 });
|
||||
|
||||
input.value = '42.0';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
|
||||
input.step = '0.1';
|
||||
input.value = '-0.1';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.step = '2';
|
||||
input.removeAttribute('min');
|
||||
input.max = '10';
|
||||
input.value = '-9';
|
||||
checkValidity(input, false, apply, {low: -10, high: -8});
|
||||
|
||||
// If there is a value defined but no min, the step base is the value.
|
||||
input = getFreshElement(data[0]);
|
||||
input.setAttribute('value', '1');
|
||||
input.step = 2;
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.value = 3;
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.value = 2;
|
||||
checkValidity(input, false, apply, {low: 1, high: 3});
|
||||
|
||||
// Should also work with defaultValue.
|
||||
input = getFreshElement(data[0]);
|
||||
input.defaultValue = 1;
|
||||
input.step = 2;
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.value = 3;
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.value = 2;
|
||||
checkValidity(input, false, apply, {low: 1, high: 3});
|
||||
}
|
||||
|
||||
if (input.type == 'number') {
|
||||
// Check that when the higher value is higher than max, we don't show it.
|
||||
input = getFreshElement(data[0]);
|
||||
input.step = '2';
|
||||
input.min = '1';
|
||||
input.max = '10.9';
|
||||
input.value = '10';
|
||||
|
||||
is(input.validationMessage, "Please select a valid value. " +
|
||||
"The nearest valid value is 9.",
|
||||
"The validation message should not include the higher value.");
|
||||
// When min is set to a valid float, there is a step base.
|
||||
input.min = '1';
|
||||
input.step = '2';
|
||||
input.value = '3';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.value = '2';
|
||||
checkValidity(input, false, apply, { low: 1, high: 3 });
|
||||
|
||||
input.removeAttribute('step'); // step = 1
|
||||
input.min = '0.5';
|
||||
input.value = '5.5';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.value = '1';
|
||||
checkValidity(input, false, apply, { low: 0.5, high: 1.5 });
|
||||
|
||||
input.min = '-0.1';
|
||||
input.step = '1';
|
||||
input.value = '0.9';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.value = '0.1';
|
||||
checkValidity(input, false, apply, { low: -0.1, high: 0.9 });
|
||||
|
||||
// When min is set to NaN, there is no step base (step base=0 actually).
|
||||
input.min = 'foo';
|
||||
input.step = '1';
|
||||
input.value = '1';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.value = '0.5';
|
||||
checkValidity(input, false, apply, { low: 0, high: 1 });
|
||||
|
||||
input.min = '';
|
||||
input.value = '1';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.value = '0.5';
|
||||
checkValidity(input, false, apply, { low: 0, high: 1 });
|
||||
|
||||
input.removeAttribute('min');
|
||||
|
||||
// If value isn't a number, the element isn't invalid.
|
||||
input.value = '';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
// Regular situations.
|
||||
input.step = '2';
|
||||
input.value = '1.5';
|
||||
checkValidity(input, false, apply, { low: 0, high: 2 });
|
||||
|
||||
input.value = '42.0';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.step = '0.1';
|
||||
input.value = '-0.1';
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.step = '2';
|
||||
input.removeAttribute('min');
|
||||
input.max = '10';
|
||||
input.value = '-9';
|
||||
checkValidity(input, false, apply, {low: -10, high: -8});
|
||||
|
||||
// If there is a value defined but no min, the step base is the value.
|
||||
input = getFreshElement(test.type);
|
||||
input.setAttribute('value', '1');
|
||||
input.step = 2;
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.value = 3;
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.value = 2;
|
||||
checkValidity(input, false, apply, {low: 1, high: 3});
|
||||
|
||||
// Should also work with defaultValue.
|
||||
input = getFreshElement(test.type);
|
||||
input.defaultValue = 1;
|
||||
input.step = 2;
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.value = 3;
|
||||
checkValidity(input, true, apply);
|
||||
|
||||
input.value = 2;
|
||||
checkValidity(input, false, apply, {low: 1, high: 3});
|
||||
|
||||
// Check that when the higher value is higher than max, we don't show it.
|
||||
input = getFreshElement(test.type);
|
||||
input.step = '2';
|
||||
input.min = '1';
|
||||
input.max = '10.9';
|
||||
input.value = '10';
|
||||
|
||||
is(input.validationMessage, "Please select a valid value. " +
|
||||
"The nearest valid value is 9.",
|
||||
"The validation message should not include the higher value.");
|
||||
break;
|
||||
case 'time':
|
||||
// Tests invalid step values. That defaults to step = 1 minute (60).
|
||||
var values = [ '0', '-1', 'foo', 'any', 'ANY', 'aNy' ];
|
||||
for (var value of values) {
|
||||
input.step = value;
|
||||
input.value = '19:06:00';
|
||||
checkValidity(input, true, apply);
|
||||
input.value = '19:06:51';
|
||||
if (value.toLowerCase() != 'any') {
|
||||
checkValidity(input, false, apply, {low: '19:06', high: '19:07'});
|
||||
} else {
|
||||
checkValidity(input, true, apply);
|
||||
}
|
||||
}
|
||||
|
||||
// No step means that we use the default step value.
|
||||
input.removeAttribute('step');
|
||||
input.value = '19:06:00';
|
||||
checkValidity(input, true, apply);
|
||||
input.value = '19:06:51';
|
||||
checkValidity(input, false, apply, {low: '19:06', high: '19:07'});
|
||||
|
||||
var tests = [
|
||||
// With step=1, we allow values by the second.
|
||||
{ step: '1', value: '19:11:01', min: '00:00', result: true },
|
||||
{ step: '1', value: '19:11:01.001', min: '00:00', result: false,
|
||||
low: '19:11:01', high: '19:11:02' },
|
||||
{ step: '1', value: '19:11:01.1', min: '00:00', result: false,
|
||||
low: '19:11:01', high: '19:11:02' },
|
||||
// When step >= 86400000, only the minimum value is valid.
|
||||
// This is actually @value if there is no @min.
|
||||
{ step: '86400000', value: '00:00', result: true },
|
||||
{ step: '86400000', value: '00:01', result: true },
|
||||
{ step: '86400000', value: '00:00', min: '00:01', result: false },
|
||||
{ step: '86400000', value: '00:01', min: '00:00', result: false,
|
||||
low: '00:00', high: '00:00' },
|
||||
// When step < 1, it should just work.
|
||||
{ step: '0.1', value: '15:05:05.1', min: '00:00', result: true },
|
||||
{ step: '0.1', value: '15:05:05.101', min: '00:00', result: false,
|
||||
low: '15:05:05.100', high: '15:05:05.200' },
|
||||
{ step: '0.2', value: '15:05:05.2', min: '00:00', result: true },
|
||||
{ step: '0.2', value: '15:05:05.1', min: '00:00', result: false,
|
||||
low: '15:05:05', high: '15:05:05.200' },
|
||||
{ step: '0.01', value: '15:05:05.01', min: '00:00', result: true },
|
||||
{ step: '0.01', value: '15:05:05.011', min: '00:00', result: false,
|
||||
low: '15:05:05.010', high: '15:05:05.020' },
|
||||
{ step: '0.02', value: '15:05:05.02', min: '00:00', result: true },
|
||||
{ step: '0.02', value: '15:05:05.01', min: '00:00', result: false,
|
||||
low: '15:05:05', high: '15:05:05.020' },
|
||||
{ step: '0.002', value: '15:05:05.002', min: '00:00', result: true },
|
||||
{ step: '0.002', value: '15:05:05.001', min: '00:00', result: false,
|
||||
low: '15:05:05', high: '15:05:05.002' },
|
||||
// When step<=0.001, any value is allowed.
|
||||
{ step: '0.001', value: '15:05:05.001', min: '00:00', result: true },
|
||||
{ step: '0.001', value: '15:05:05', min: '00:00', result: true },
|
||||
{ step: '0.000001', value: '15:05:05', min: '00:00', result: true },
|
||||
// This value has conversion to double issues.
|
||||
{ step: '0.0000001', value: '15:05:05', min: '00:00', result: true,
|
||||
todo: true },
|
||||
// Some random values.
|
||||
{ step: '100', value: '15:06:40', min: '00:00', result: true },
|
||||
{ step: '100', value: '15:05:05.010', min: '00:00', result: false,
|
||||
low: '15:05', high: '15:06:40' },
|
||||
{ step: '3600', value: '15:00', min: '00:00', result: true },
|
||||
{ step: '3600', value: '15:14', min: '00:00', result: false,
|
||||
low: '15:00', high: '16:00' },
|
||||
{ step: '7200', value: '14:00', min: '00:00', result: true },
|
||||
{ step: '7200', value: '15:14', min: '00:00', result: false,
|
||||
low: '14:00', high: '16:00' },
|
||||
{ step: '7260', value: '14:07', min: '00:00', result: true },
|
||||
{ step: '7260', value: '15:14', min: '00:00', result: false,
|
||||
low: '14:07', high: '16:08' },
|
||||
];
|
||||
|
||||
var type = test.type;
|
||||
for (var test of tests) {
|
||||
var input = getFreshElement(type);
|
||||
input.step = test.step;
|
||||
input.setAttribute('value', test.value);
|
||||
if (test.min !== undefined) {
|
||||
input.min = test.min;
|
||||
}
|
||||
|
||||
if (test.todo) {
|
||||
todo(input.validity.valid, test.result,
|
||||
"This test should fail for the moment because of precission issues");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (test.result) {
|
||||
checkValidity(input, true, apply);
|
||||
} else {
|
||||
checkValidity(input, false, apply,
|
||||
{ low: test.low, high: test.high });
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
ok(false, "Implement the tests for <input type='" + test.type + " >");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ function checkAvailability()
|
|||
["button", false],
|
||||
["number", true],
|
||||
["date", true],
|
||||
["time", true],
|
||||
// The next types have not been implemented but will fallback to "text"
|
||||
// which has the same value.
|
||||
["color", false],
|
||||
|
@ -58,7 +59,6 @@ function checkAvailability()
|
|||
["datetime", true],
|
||||
["month", true],
|
||||
["week", true],
|
||||
["time", true],
|
||||
["datetime-local", true],
|
||||
["range", true],
|
||||
];
|
||||
|
@ -246,6 +246,70 @@ function checkStepDown()
|
|||
[ '2012-01-01', 'AnY', null, null, 1, null, true ],
|
||||
[ '2012-01-01', 'aNy', null, null, 1, null, true ],
|
||||
]},
|
||||
{ type: 'time', data: [
|
||||
// Regular case.
|
||||
[ '16:39', null, null, null, null, '16:38', false ],
|
||||
// Argument testing.
|
||||
[ '16:40', null, null, null, 1, '16:39', false ],
|
||||
[ '16:40', null, null, null, 5, '16:35', false ],
|
||||
[ '16:40', null, null, null, -1, '16:41', false ],
|
||||
[ '16:40', null, null, null, 0, '16:40', false ],
|
||||
// hour/minutes/seconds wrapping.
|
||||
[ '05:00', null, null, null, null, '04:59', false ],
|
||||
[ '05:00:00', 1, null, null, null, '04:59:59', false ],
|
||||
[ '05:00:00', 0.1, null, null, null, '04:59:59.900', false ],
|
||||
[ '05:00:00', 0.01, null, null, null, '04:59:59.990', false ],
|
||||
[ '05:00:00', 0.001, null, null, null, '04:59:59.999', false ],
|
||||
// stepDown() on '00:00' gives '23:59'.
|
||||
[ '00:00', null, null, null, 1, '23:59', false ],
|
||||
[ '00:00', null, null, null, 3, '23:57', false ],
|
||||
// Some random step values..
|
||||
[ '16:56', '0.5', null, null, null, '16:55:59.500', false ],
|
||||
[ '16:56', '2', null, null, null, '16:55:58', false ],
|
||||
[ '16:56', '0.25',null, null, 4, '16:55:59', false ],
|
||||
[ '16:57', '1.1', '16:00', null, 1, '16:56:59.900', false ],
|
||||
[ '16:57', '1.1', '16:00', null, 2, '16:56:58.800', false ],
|
||||
[ '16:57', '1.1', '16:00', null, 10, '16:56:50', false ],
|
||||
[ '16:57', '1.1', '16:00', null, 11, '16:56:48.900', false ],
|
||||
[ '16:57', '1.1', '16:00', null, 8, '16:56:52.200', false ],
|
||||
// Invalid @step, means that we use the default value.
|
||||
[ '17:01', '0', null, null, null, '17:00', false ],
|
||||
[ '17:01', '-1', null, null, null, '17:00', false ],
|
||||
[ '17:01', 'foo', null, null, null, '17:00', false ],
|
||||
// Min values testing.
|
||||
[ '17:02', '60', 'foo', null, 2, '17:00', false ],
|
||||
[ '17:10', '60', '17:09', null, null, '17:09', false ],
|
||||
[ '17:10', '60', '17:10', null, null, '17:10', false ],
|
||||
[ '17:10', '60', '17:30', null, 1, '17:10', false ],
|
||||
[ '17:10', '180', '17:05', null, null, '17:08', false ],
|
||||
[ '17:10', '300', '17:10', '17:11', null, '17:10', false ],
|
||||
// Max values testing.
|
||||
[ '17:15', '60', null, 'foo', null, '17:14', false ],
|
||||
[ '17:15', null, null, '17:20', null, '17:14', false ],
|
||||
[ '17:15', null, null, '17:15', null, '17:14', false ],
|
||||
[ '17:15', null, null, '17:13', 4, '17:11', false ],
|
||||
[ '17:15', '120', null, '17:13', 3, '17:09', false ],
|
||||
// Step mismatch.
|
||||
[ '17:19', '120', '17:10', null, null, '17:18', false ],
|
||||
[ '17:19', '120', '17:10', null, 2, '17:16', false ],
|
||||
[ '17:19', '120', '17:18', '17:25', null, '17:18', false ],
|
||||
[ '17:19', '120', null, null, null, '17:17', false ],
|
||||
[ '17:19', '180', null, null, null, '17:16', false ],
|
||||
// Clamping.
|
||||
[ '17:22', null, null, '17:11', null, '17:11', false ],
|
||||
[ '17:22', '120', '17:20', '17:22', null, '17:20', false ],
|
||||
[ '17:22', '300', '17:12', '17:20', 10, '17:12', false ],
|
||||
[ '17:22', '300', '17:18', '17:20', 2, '17:18', false ],
|
||||
[ '17:22', '180', '17:00', '17:20', 15, '17:00', false ],
|
||||
[ '17:22', '180', '17:10', '17:20', 2, '17:16', false ],
|
||||
// value = "" (NaN).
|
||||
[ '', null, null, null, null, '', false ],
|
||||
// With step = 'any'.
|
||||
[ '17:26', 'any', null, null, 1, null, true ],
|
||||
[ '17:26', 'ANY', null, null, 1, null, true ],
|
||||
[ '17:26', 'AnY', null, null, 1, null, true ],
|
||||
[ '17:26', 'aNy', null, null, 1, null, true ],
|
||||
]},
|
||||
];
|
||||
|
||||
for (var test of testData) {
|
||||
|
@ -429,6 +493,70 @@ function checkStepUp()
|
|||
[ '2012-01-01', 'AnY', null, null, 1, null, true ],
|
||||
[ '2012-01-01', 'aNy', null, null, 1, null, true ],
|
||||
]},
|
||||
{ type: 'time', data: [
|
||||
// Regular case.
|
||||
[ '16:39', null, null, null, null, '16:40', false ],
|
||||
// Argument testing.
|
||||
[ '16:40', null, null, null, 1, '16:41', false ],
|
||||
[ '16:40', null, null, null, 5, '16:45', false ],
|
||||
[ '16:40', null, null, null, -1, '16:39', false ],
|
||||
[ '16:40', null, null, null, 0, '16:40', false ],
|
||||
// hour/minutes/seconds wrapping.
|
||||
[ '04:59', null, null, null, null, '05:00', false ],
|
||||
[ '04:59:59', 1, null, null, null, '05:00', false ],
|
||||
[ '04:59:59.900', 0.1, null, null, null, '05:00', false ],
|
||||
[ '04:59:59.990', 0.01, null, null, null, '05:00', false ],
|
||||
[ '04:59:59.999', 0.001, null, null, null, '05:00', false ],
|
||||
// stepUp() on '23:59' gives '00:00'.
|
||||
[ '23:59', null, null, null, 1, '00:00', false ],
|
||||
[ '23:59', null, null, null, 3, '00:02', false ],
|
||||
// Some random step values..
|
||||
[ '16:56', '0.5', null, null, null, '16:56:00.500', false ],
|
||||
[ '16:56', '2', null, null, null, '16:56:02', false ],
|
||||
[ '16:56', '0.25',null, null, 4, '16:56:01', false ],
|
||||
[ '16:57', '1.1', '16:00', null, 1, '16:57:01', false ],
|
||||
[ '16:57', '1.1', '16:00', null, 2, '16:57:02.100', false ],
|
||||
[ '16:57', '1.1', '16:00', null, 10, '16:57:10.900', false ],
|
||||
[ '16:57', '1.1', '16:00', null, 11, '16:57:12', false ],
|
||||
[ '16:57', '1.1', '16:00', null, 8, '16:57:08.700', false ],
|
||||
// Invalid @step, means that we use the default value.
|
||||
[ '17:01', '0', null, null, null, '17:02', false ],
|
||||
[ '17:01', '-1', null, null, null, '17:02', false ],
|
||||
[ '17:01', 'foo', null, null, null, '17:02', false ],
|
||||
// Min values testing.
|
||||
[ '17:02', '60', 'foo', null, 2, '17:04', false ],
|
||||
[ '17:10', '60', '17:09', null, null, '17:11', false ],
|
||||
[ '17:10', '60', '17:10', null, null, '17:11', false ],
|
||||
[ '17:10', '60', '17:30', null, 1, '17:30', false ],
|
||||
[ '17:10', '180', '17:05', null, null, '17:11', false ],
|
||||
[ '17:10', '300', '17:10', '17:11', null,'17:10', false ],
|
||||
// Max values testing.
|
||||
[ '17:15', '60', null, 'foo', null, '17:16', false ],
|
||||
[ '17:15', null, null, '17:20', null, '17:16', false ],
|
||||
[ '17:15', null, null, '17:15', null, '17:15', false ],
|
||||
[ '17:15', null, null, '17:13', 4, '17:15', false ],
|
||||
[ '17:15', '120', null, '17:13', 3, '17:15', false ],
|
||||
// Step mismatch.
|
||||
[ '17:19', '120', '17:10', null, null, '17:20', false ],
|
||||
[ '17:19', '120', '17:10', null, 2, '17:22', false ],
|
||||
[ '17:19', '120', '17:18', '17:25', null, '17:20', false ],
|
||||
[ '17:19', '120', null, null, null, '17:21', false ],
|
||||
[ '17:19', '180', null, null, null, '17:22', false ],
|
||||
// Clamping.
|
||||
[ '17:22', null, null, '17:11', null, '17:22', false ],
|
||||
[ '17:22', '120', '17:20', '17:22', null, '17:22', false ],
|
||||
[ '17:22', '300', '17:12', '17:20', 10, '17:22', false ],
|
||||
[ '17:22', '300', '17:18', '17:20', 2, '17:22', false ],
|
||||
[ '17:22', '180', '17:00', '17:20', 15, '17:22', false ],
|
||||
[ '17:22', '180', '17:10', '17:20', 2, '17:22', false ],
|
||||
// value = "" (NaN).
|
||||
[ '', null, null, null, null, '', false ],
|
||||
// With step = 'any'.
|
||||
[ '17:26', 'any', null, null, 1, null, true ],
|
||||
[ '17:26', 'ANY', null, null, 1, null, true ],
|
||||
[ '17:26', 'AnY', null, null, 1, null, true ],
|
||||
[ '17:26', 'aNy', null, null, 1, null, true ],
|
||||
]},
|
||||
];
|
||||
|
||||
for (var test of testData) {
|
||||
|
|
|
@ -40,14 +40,14 @@ FormValidationInvalidURL=Please enter a URL.
|
|||
FormValidationPatternMismatch=Please match the requested format.
|
||||
# LOCALIZATION NOTE (FormValidationPatternMismatchWithTitle): %S is the (possibly truncated) title attribute value.
|
||||
FormValidationPatternMismatchWithTitle=Please match the requested format: %S.
|
||||
# LOCALIZATION NOTE (FormValidationRangeOverflow): %S can be a number or a date.
|
||||
# LOCALIZATION NOTE (FormValidationRangeOverflow): %S can be a number, a date or a time.
|
||||
FormValidationRangeOverflow=Please select a value that is lower than %S.
|
||||
# LOCALIZATION NOTE (FormValidationRangeUnderflow): %S can be a number or a date.
|
||||
# LOCALIZATION NOTE (FormValidationRangeUnderflow): %S can be a number, a date or a time.
|
||||
FormValidationRangeUnderflow=Please select a value that is higher than %S.
|
||||
# LOCALIZATION NOTE (FormValidationStepMismatch): both %S can be a number or a date.
|
||||
# LOCALIZATION NOTE (FormValidationStepMismatch): both %S can be a number, a date or a time.
|
||||
FormValidationStepMismatch=Please select a valid value. The two nearest valid values are %S and %S.
|
||||
# LOCALIZATION NOTE (FormValidationStepMismatchWitoutMax): %S can be a number or a date. This is called instead of FormValidationStepMismatch when the second value isn't valid because it's higher than the maximum allowed value.
|
||||
FormValidationStepMismatchWithoutMax=Please select a valid value. The nearest valid value is %S.
|
||||
# LOCALIZATION NOTE (FormValidationStepMismatchOneValue): %S can be a number, a date or a time. This is called instead of FormValidationStepMismatch when the second value is the same as the first.
|
||||
FormValidationStepMismatchOneValue=Please select a valid value. The nearest valid value is %S.
|
||||
GetAttributeNodeWarning=Use of getAttributeNode() is deprecated. Use getAttribute() instead.
|
||||
SetAttributeNodeWarning=Use of setAttributeNode() is deprecated. Use setAttribute() instead.
|
||||
GetAttributeNodeNSWarning=Use of getAttributeNodeNS() is deprecated. Use getAttributeNS() instead.
|
||||
|
|
Загрузка…
Ссылка в новой задаче