зеркало из https://github.com/mozilla/gecko-dev.git
Bug 769370 - Add valueAsDate attribute and implement valueAsNumber/valueAsDate for date. r=mounir
This commit is contained in:
Родитель
b1782095c1
Коммит
90a26c1967
|
@ -93,6 +93,9 @@
|
|||
|
||||
#include <limits>
|
||||
|
||||
// input type=date
|
||||
#include "jsapi.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
|
@ -1057,17 +1060,72 @@ nsHTMLInputElement::IsValueEmpty() const
|
|||
return value.IsEmpty();
|
||||
}
|
||||
|
||||
bool
|
||||
nsHTMLInputElement::ConvertStringToNumber(nsAString& aValue,
|
||||
double& aResultValue) const
|
||||
{
|
||||
switch (mType) {
|
||||
case NS_FORM_INPUT_NUMBER:
|
||||
{
|
||||
nsresult ec;
|
||||
aResultValue = PromiseFlatString(aValue).ToDouble(&ec);
|
||||
if (NS_FAILED(ec)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case NS_FORM_INPUT_DATE:
|
||||
{
|
||||
JSContext* ctx = nsContentUtils::GetContextFromDocument(OwnerDoc());
|
||||
if (!ctx) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t year, month, day;
|
||||
if (!GetValueAsDate(aValue, year, month, day)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JSObject* date = JS_NewDateObjectMsec(ctx, 0);
|
||||
jsval rval;
|
||||
jsval fullYear[3];
|
||||
fullYear[0].setInt32(year);
|
||||
fullYear[1].setInt32(month-1);
|
||||
fullYear[2].setInt32(day);
|
||||
if (!JS::Call(ctx, date, "setUTCFullYear", 3, fullYear, &rval)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
jsval timestamp;
|
||||
if (!JS::Call(ctx, date, "getTime", 0, nullptr, ×tamp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!timestamp.isNumber()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aResultValue = timestamp.toNumber();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
double
|
||||
nsHTMLInputElement::GetValueAsDouble() const
|
||||
{
|
||||
double doubleValue;
|
||||
nsAutoString stringValue;
|
||||
nsresult ec;
|
||||
|
||||
GetValueInternal(stringValue);
|
||||
doubleValue = stringValue.ToDouble(&ec);
|
||||
|
||||
return NS_SUCCEEDED(ec) ? doubleValue : MOZ_DOUBLE_NaN();
|
||||
return !ConvertStringToNumber(stringValue, doubleValue) ? MOZ_DOUBLE_NaN()
|
||||
: doubleValue;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -1143,10 +1201,100 @@ void
|
|||
nsHTMLInputElement::SetValue(double aValue)
|
||||
{
|
||||
nsAutoString value;
|
||||
value.AppendFloat(aValue);
|
||||
switch (mType) {
|
||||
case NS_FORM_INPUT_NUMBER:
|
||||
value.AppendFloat(aValue);
|
||||
break;
|
||||
case NS_FORM_INPUT_DATE:
|
||||
{
|
||||
value.Truncate();
|
||||
JSContext* ctx = nsContentUtils::GetContextFromDocument(OwnerDoc());
|
||||
if (!ctx) {
|
||||
break;
|
||||
}
|
||||
|
||||
JSObject* date = JS_NewDateObjectMsec(ctx, aValue);
|
||||
if (!date) {
|
||||
break;
|
||||
}
|
||||
|
||||
jsval year, month, day;
|
||||
if(!JS::Call(ctx, date, "getUTCFullYear", 0, nullptr, &year)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(!JS::Call(ctx, date, "getUTCMonth", 0, nullptr, &month)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(!JS::Call(ctx, date, "getUTCDate", 0, nullptr, &day)) {
|
||||
break;
|
||||
}
|
||||
|
||||
value.AppendPrintf("%04.0f-%02.0f-%02.0f", year.toNumber(),
|
||||
month.toNumber() + 1, day.toNumber());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
SetValue(value);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLInputElement::GetValueAsDate(JSContext* aCtx, jsval* aDate)
|
||||
{
|
||||
if (mType != NS_FORM_INPUT_DATE) {
|
||||
aDate->setNull();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
uint32_t year, month, day;
|
||||
nsAutoString value;
|
||||
GetValueInternal(value);
|
||||
if (!GetValueAsDate(value, year, month, day)) {
|
||||
aDate->setNull();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
JSObject* date = JS_NewDateObjectMsec(aCtx, 0);
|
||||
jsval rval;
|
||||
jsval fullYear[3];
|
||||
fullYear[0].setInt32(year);
|
||||
fullYear[1].setInt32(month-1);
|
||||
fullYear[2].setInt32(day);
|
||||
if(!JS::Call(aCtx, date, "setUTCFullYear", 3, fullYear, &rval)) {
|
||||
aDate->setNull();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
aDate->setObjectOrNull(date);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLInputElement::SetValueAsDate(JSContext* aCtx, const jsval& aDate)
|
||||
{
|
||||
if (mType != NS_FORM_INPUT_DATE) {
|
||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
}
|
||||
|
||||
if (!aDate.isObject() || !JS_ObjectIsDate(aCtx, &aDate.toObject())) {
|
||||
SetValue(EmptyString());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
JSObject& date = aDate.toObject();
|
||||
jsval timestamp;
|
||||
bool ret = JS::Call(aCtx, &date, "getTime", 0, nullptr, ×tamp);
|
||||
if (!ret || !timestamp.isNumber() || MOZ_DOUBLE_IS_NaN(timestamp.toNumber())) {
|
||||
SetValue(EmptyString());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
SetValue(timestamp.toNumber());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLInputElement::GetValueAsNumber(double* aValueAsNumber)
|
||||
{
|
||||
|
@ -2770,6 +2918,17 @@ nsHTMLInputElement::SanitizeValue(nsAString& aValue)
|
|||
bool
|
||||
nsHTMLInputElement::IsValidDate(nsAString& aValue) const
|
||||
{
|
||||
uint32_t year, month, day;
|
||||
return GetValueAsDate(aValue, year, month, day);
|
||||
}
|
||||
|
||||
bool
|
||||
nsHTMLInputElement::GetValueAsDate(nsAString& aValue,
|
||||
uint32_t& aYear,
|
||||
uint32_t& aMonth,
|
||||
uint32_t& aDay) const
|
||||
{
|
||||
|
||||
/*
|
||||
* Parse the year, month, day values out a date string formatted as 'yyy-mm-dd'.
|
||||
* -The year must be 4 or more digits long, and year > 0
|
||||
|
@ -2782,9 +2941,6 @@ nsHTMLInputElement::IsValidDate(nsAString& aValue) const
|
|||
return false;
|
||||
}
|
||||
|
||||
uint32_t year = 0;
|
||||
uint32_t month = 0;
|
||||
uint32_t day = 0;
|
||||
int32_t fieldMaxSize = 0;
|
||||
int32_t fieldMinSize = 4;
|
||||
enum {
|
||||
|
@ -2818,10 +2974,10 @@ nsHTMLInputElement::IsValidDate(nsAString& aValue) const
|
|||
|
||||
switch(field) {
|
||||
case YEAR:
|
||||
year = PromiseFlatString(StringHead(aValue, offset)).ToInteger(&ec);
|
||||
aYear = PromiseFlatString(StringHead(aValue, offset)).ToInteger(&ec);
|
||||
NS_ENSURE_SUCCESS(ec, false);
|
||||
|
||||
if (year <= 0) {
|
||||
if (aYear <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2831,12 +2987,12 @@ nsHTMLInputElement::IsValidDate(nsAString& aValue) const
|
|||
fieldMinSize = 2;
|
||||
break;
|
||||
case MONTH:
|
||||
month = PromiseFlatString(Substring(aValue,
|
||||
aMonth = PromiseFlatString(Substring(aValue,
|
||||
offset-fieldSize,
|
||||
offset)).ToInteger(&ec);
|
||||
NS_ENSURE_SUCCESS(ec, false);
|
||||
|
||||
if (month < 1 || month > 12) {
|
||||
if (aMonth < 1 || aMonth > 12) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2847,12 +3003,12 @@ nsHTMLInputElement::IsValidDate(nsAString& aValue) const
|
|||
fieldMaxSize = 1;
|
||||
break;
|
||||
case DAY:
|
||||
day = PromiseFlatString(Substring(aValue,
|
||||
aDay = PromiseFlatString(Substring(aValue,
|
||||
offset-fieldSize,
|
||||
offset + 1)).ToInteger(&ec);
|
||||
NS_ENSURE_SUCCESS(ec, false);
|
||||
|
||||
if (day < 1 || day > NumberOfDaysInMonth(month, year)) {
|
||||
if (aDay < 1 || aDay > NumberOfDaysInMonth(aMonth, aYear)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -560,6 +560,17 @@ protected:
|
|||
*/
|
||||
double GetValueAsDouble() const;
|
||||
|
||||
/**
|
||||
* Convert a string to a number in a type specific way,
|
||||
* http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#concept-input-value-string-number
|
||||
* ie parse a date string to a timestamp if type=date,
|
||||
* or parse a number string to its value if type=number.
|
||||
* @param aValue the string to be parsed.
|
||||
* @param aResultValue the timestamp as a double.
|
||||
* @result whether the parsing was successful.
|
||||
*/
|
||||
bool ConvertStringToNumber(nsAString& aValue, double& aResultValue) const;
|
||||
|
||||
/**
|
||||
* Parse a date string of the form yyyy-mm-dd
|
||||
* @param the string to be parsed.
|
||||
|
@ -568,6 +579,17 @@ protected:
|
|||
*/
|
||||
bool IsValidDate(nsAString& aValue) const;
|
||||
|
||||
/**
|
||||
* Parse a date string of the form yyyy-mm-dd
|
||||
* @param the string to be parsed.
|
||||
* @return the date in aYear, aMonth, aDay.
|
||||
* @return whether the parsing was successful.
|
||||
*/
|
||||
bool GetValueAsDate(nsAString& aValue,
|
||||
uint32_t& aYear,
|
||||
uint32_t& aMonth,
|
||||
uint32_t& aDay) const;
|
||||
|
||||
/**
|
||||
* This methods returns the number of days in a given month, for a given year.
|
||||
*/
|
||||
|
|
|
@ -50,6 +50,7 @@ MOCHITEST_FILES = \
|
|||
test_experimental_forms_pref.html \
|
||||
test_input_number_value.html \
|
||||
test_input_sanitization.html \
|
||||
test_valueasdate_attribute.html \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -218,8 +218,8 @@ reflectString({
|
|||
// .value doesn't reflect a content attribute.
|
||||
|
||||
// .valueAsDate
|
||||
todo("valueAsDate" in document.createElement("input"),
|
||||
"valueAsDate isn't implemented yet");
|
||||
is("valueAsDate" in document.createElement("input"), true,
|
||||
"valueAsDate should be available");
|
||||
|
||||
// Deeper check will be done with bug 763305.
|
||||
is('valueAsNumber' in document.createElement("input"), true,
|
||||
|
|
|
@ -0,0 +1,206 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=769370
|
||||
-->
|
||||
<head>
|
||||
<title>Test for input.valueAsDate</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=769370">Mozilla Bug 769370</a>
|
||||
<p id="display"></p>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 769370**/
|
||||
|
||||
/**
|
||||
* This test is checking .valueAsDate.
|
||||
*/
|
||||
|
||||
var element = document.createElement("input");
|
||||
|
||||
function checkAvailability()
|
||||
{
|
||||
var testData =
|
||||
[
|
||||
["text", false],
|
||||
["password", false],
|
||||
["search", false],
|
||||
["telephone", false],
|
||||
["email", false],
|
||||
["url", false],
|
||||
["hidden", false],
|
||||
["checkbox", false],
|
||||
["radio", false],
|
||||
["file", false],
|
||||
["submit", false],
|
||||
["image", false],
|
||||
["reset", false],
|
||||
["button", false],
|
||||
["number", false],
|
||||
["date", true],
|
||||
// The next types have not been implemented but will fallback to "text"
|
||||
// which has the same value.
|
||||
["range", false],
|
||||
["color", false],
|
||||
];
|
||||
|
||||
var todoList =
|
||||
[
|
||||
["datetime", true],
|
||||
["month", true],
|
||||
["week", true],
|
||||
["time", true],
|
||||
["datetime-local", true],
|
||||
];
|
||||
|
||||
for (data of testData) {
|
||||
var exceptionCatched = false;
|
||||
element.type = data[0];
|
||||
try {
|
||||
element.valueAsDate;
|
||||
} catch (e) {
|
||||
exceptionCatched = true;
|
||||
}
|
||||
is(exceptionCatched, false,
|
||||
"valueAsDate shouldn't throw exception on getting");
|
||||
|
||||
exceptionCatched = false;
|
||||
try {
|
||||
element.valueAsDate = new Date();
|
||||
} catch (e) {
|
||||
exceptionCatched = true;
|
||||
}
|
||||
is(exceptionCatched, !data[1], "valueAsDate for " + data[0] +
|
||||
" availability is not correct");
|
||||
}
|
||||
|
||||
for (data of todoList) {
|
||||
var exceptionCatched = false;
|
||||
element.type = data[0];
|
||||
try {
|
||||
element.valueAsDate;
|
||||
} catch (e) {
|
||||
exceptionCatched = true;
|
||||
}
|
||||
is(exceptionCatched, false,
|
||||
"valueAsDate shouldn't throw exception on getting");
|
||||
|
||||
exceptionCatched = false;
|
||||
try {
|
||||
element.valueAsDate= 42;
|
||||
} catch (e) {
|
||||
exceptionCatched = true;
|
||||
}
|
||||
todo_is(exceptionCatched, !data[1],
|
||||
"valueAsDate for " + data[0] + " availability is not correct");
|
||||
}
|
||||
}
|
||||
|
||||
function checkGet()
|
||||
{
|
||||
var validData =
|
||||
[
|
||||
[ "2012-07-12", 1342051200000 ],
|
||||
[ "1970-01-01", 0 ],
|
||||
[ "1970-01-02", 86400000 ],
|
||||
[ "1969-12-31", -86400000 ],
|
||||
[ "0311-01-31", -52350451200000 ],
|
||||
[ "275760-09-13", 8640000000000000 ],
|
||||
[ "0001-01-01", -62135596800000 ],
|
||||
[ "2012-02-29", 1330473600000 ],
|
||||
[ "2011-02-28", 1298851200000 ],
|
||||
];
|
||||
|
||||
var invalidData =
|
||||
[
|
||||
[ "invaliddate" ],
|
||||
[ "-001-12-31" ],
|
||||
[ "901-12-31" ],
|
||||
[ "1901-13-31" ],
|
||||
[ "1901-12-32" ],
|
||||
[ "1901-00-12" ],
|
||||
[ "1901-01-00" ],
|
||||
[ "1900-02-29" ],
|
||||
[ "0000-01-01" ],
|
||||
[ "" ],
|
||||
// This date is valid for the input element, but is out of
|
||||
// the date object range. In this case, on getting valueAsDate,
|
||||
// a Date object will be created, but it will have a NaN internal value,
|
||||
// and will return the string "Invalid Date".
|
||||
[ "275760-09-14", true ],
|
||||
];
|
||||
|
||||
element.type = "date";
|
||||
for (data of validData) {
|
||||
element.value = data[0];
|
||||
is(element.valueAsDate.valueOf(), data[1],
|
||||
"valueAsDate should return the " +
|
||||
"valid date object representing this date");
|
||||
}
|
||||
|
||||
for (data of invalidData) {
|
||||
element.value = data[0];
|
||||
is(element.valueAsDate, data[1] ? "Invalid Date" : null,
|
||||
"valueAsDate should return null " +
|
||||
"when the element value is not a valid date");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function checkSet()
|
||||
{
|
||||
var testData =
|
||||
[
|
||||
[ 1342051200000, "2012-07-12" ],
|
||||
[ 0, "1970-01-01" ],
|
||||
// Maximum valid date (limited by the ecma date object range).
|
||||
[ 8640000000000000, "275760-09-13" ],
|
||||
// Minimum valid date (limited by the input element minimum valid value).
|
||||
[ -62135596800000 , "0001-01-01" ],
|
||||
[ 1330473600000, "2012-02-29" ],
|
||||
[ 1298851200000, "2011-02-28" ],
|
||||
// "Values must be truncated to valid dates"
|
||||
[ 42.1234, "1970-01-01" ],
|
||||
[ 123.123456789123, "1970-01-01" ],
|
||||
[ 1e-1, "1970-01-01" ],
|
||||
[ 1298851200010, "2011-02-28" ],
|
||||
[ -1, "1969-12-31" ],
|
||||
[ -86400000, "1969-12-31" ],
|
||||
[ 86400000, "1970-01-02" ],
|
||||
// Negative years, this is out of range for the input element,
|
||||
// the corresponding date string is the empty string
|
||||
[ -62135596800001, "" ],
|
||||
// Invalid dates.
|
||||
[ NaN, "" ],
|
||||
];
|
||||
|
||||
element.type = "date";
|
||||
for (data of testData) {
|
||||
element.valueAsDate = new Date(data[0]);
|
||||
is(element.value, data[1], "valueAsDate should set the value to "
|
||||
+ data[1]);
|
||||
}
|
||||
|
||||
element.valueAsDate = null;
|
||||
is(element.value, "", "valueAsDate should set the value to the empty string");
|
||||
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({'set': [["dom.experimental_forms", true]]}, function() {
|
||||
checkAvailability();
|
||||
checkGet();
|
||||
checkSet();
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -4,7 +4,7 @@
|
|||
https://bugzilla.mozilla.org/show_bug.cgi?id=636737
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 636737</title>
|
||||
<title>Test for Bug input.valueAsNumber</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
|
@ -43,6 +43,7 @@ function checkAvailability()
|
|||
["reset", false],
|
||||
["button", false],
|
||||
["number", true],
|
||||
["date", true],
|
||||
// The next types have not been implemented but will fallback to "text"
|
||||
// which has the same value.
|
||||
["color", false],
|
||||
|
@ -51,7 +52,6 @@ function checkAvailability()
|
|||
var todoList =
|
||||
[
|
||||
["datetime", true],
|
||||
["date", true],
|
||||
["month", true],
|
||||
["week", true],
|
||||
["time", true],
|
||||
|
@ -103,7 +103,7 @@ function checkAvailability()
|
|||
}
|
||||
}
|
||||
|
||||
function checkGet()
|
||||
function checkNumberGet()
|
||||
{
|
||||
var testData =
|
||||
[
|
||||
|
@ -136,7 +136,7 @@ function checkGet()
|
|||
}
|
||||
}
|
||||
|
||||
function checkSet()
|
||||
function checkNumberSet()
|
||||
{
|
||||
var testData =
|
||||
[
|
||||
|
@ -166,11 +166,107 @@ function checkSet()
|
|||
}
|
||||
}
|
||||
|
||||
function checkDateGet()
|
||||
{
|
||||
var validData =
|
||||
[
|
||||
[ "2012-07-12", 1342051200000 ],
|
||||
[ "1970-01-01", 0 ],
|
||||
// We are supposed to support at least until this date.
|
||||
// (corresponding to the date object maximal value)
|
||||
[ "275760-09-13", 8640000000000000 ],
|
||||
// Minimum valid date (limited by the input element minimum valid value)
|
||||
[ "0001-01-01", -62135596800000 ],
|
||||
[ "2012-02-29", 1330473600000 ],
|
||||
[ "2011-02-28", 1298851200000 ],
|
||||
];
|
||||
|
||||
var invalidData =
|
||||
[
|
||||
"invaliddate",
|
||||
"",
|
||||
"275760-09-14",
|
||||
"999-12-31",
|
||||
"-001-12-31",
|
||||
"0000-01-01",
|
||||
"2011-02-29",
|
||||
"1901-13-31",
|
||||
"1901-12-32",
|
||||
"1901-00-12",
|
||||
"1901-01-00",
|
||||
"1900-02-29",
|
||||
];
|
||||
|
||||
element.type = "date";
|
||||
for (data of validData) {
|
||||
element.value = data[0];
|
||||
is(element.valueAsNumber, data[1], "valueAsNumber should return the " +
|
||||
"timestamp representing this date");
|
||||
}
|
||||
|
||||
for (data of invalidData) {
|
||||
element.value = data;
|
||||
ok(isNaN(element.valueAsNumber), "valueAsNumber should return NaN " +
|
||||
"when the element value is not a valid date");
|
||||
}
|
||||
}
|
||||
|
||||
function checkDateSet()
|
||||
{
|
||||
var testData =
|
||||
[
|
||||
[ 1342051200000, "2012-07-12" ],
|
||||
[ 0, "1970-01-01" ],
|
||||
// Maximum valid date (limited by the ecma date object range).
|
||||
[ 8640000000000000, "275760-09-13" ],
|
||||
// Minimum valid date (limited by the input element minimum valid value)
|
||||
[ -62135596800000, "0001-01-01" ],
|
||||
[ 1330473600000, "2012-02-29" ],
|
||||
[ 1298851200000, "2011-02-28" ],
|
||||
// "Values must be truncated to valid dates"
|
||||
[ 42.1234, "1970-01-01" ],
|
||||
[ 123.123456789123, "1970-01-01" ],
|
||||
[ 1e2, "1970-01-01" ],
|
||||
[ 1E9, "1970-01-12" ],
|
||||
[ 1e-1, "1970-01-01" ],
|
||||
[ 2e10, "1970-08-20" ],
|
||||
[ 1298851200010, "2011-02-28" ],
|
||||
[ -1, "1969-12-31" ],
|
||||
[ -86400000, "1969-12-31" ],
|
||||
[ 86400000, "1970-01-02" ],
|
||||
// Invalid numbers.
|
||||
// Those are implicitly converted to numbers
|
||||
[ "", "1970-01-01" ],
|
||||
[ true, "1970-01-01" ],
|
||||
[ false, "1970-01-01" ],
|
||||
[ null, "1970-01-01" ],
|
||||
// Those are converted to NaN, the corresponding date string is the empty string
|
||||
[ "invaliddatenumber", "" ],
|
||||
[ NaN, "" ],
|
||||
[ undefined, "" ],
|
||||
// Out of range, the corresponding date string is the empty string
|
||||
[ -62135596800001, "" ],
|
||||
];
|
||||
|
||||
element.type = "date";
|
||||
for (data of testData) {
|
||||
element.valueAsNumber = data[0];
|
||||
is(element.value, data[1], "valueAsNumber should set the value to " + data[1]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({'set': [["dom.experimental_forms", true]]}, function() {
|
||||
checkAvailability();
|
||||
checkGet();
|
||||
checkSet();
|
||||
|
||||
// <input type='number'> test
|
||||
checkNumberGet();
|
||||
checkNumberSet();
|
||||
|
||||
// <input type='date'> test
|
||||
checkDateGet();
|
||||
checkDateSet();
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
|
|
@ -69,6 +69,7 @@ interface nsIDOMHTMLInputElement : nsIDOMHTMLElement
|
|||
attribute DOMString defaultValue;
|
||||
attribute DOMString value;
|
||||
attribute double valueAsNumber;
|
||||
[implicit_jscontext] attribute jsval valueAsDate;
|
||||
|
||||
[optional_argc] void stepDown([optional] in long n);
|
||||
[optional_argc] void stepUp([optional] in long n);
|
||||
|
|
Загрузка…
Ссылка в новой задаче