Bug 1286182: Implement the layout for <input type=date>

This commit is contained in:
janekptacijarabaci 2018-02-14 14:41:19 +01:00 committed by Roy Tam
commit d8bcf2270a
15 changed files with 846 additions and 141 deletions

View file

@ -30,8 +30,12 @@ skip-if = os == "android" # up/down arrow keys not supported on android
skip-if = android_version == '18' # Android, bug 1147974
[test_input_color_picker_update.html]
skip-if = android_version == '18' # Android, bug 1147974
[test_input_date_key_events.html]
skip-if = os == "android"
[test_input_datetime_focus_blur.html]
skip-if = os == "android"
[test_input_datetime_focus_blur_events.html]
skip-if = os == "android"
[test_input_datetime_tabindex.html]
skip-if = os == "android"
[test_input_defaultValue.html]
@ -61,8 +65,6 @@ skip-if = os == "android"
[test_input_textarea_set_value_no_scroll.html]
[test_input_time_key_events.html]
skip-if = os == "android"
[test_input_time_focus_blur_events.html]
skip-if = os == "android"
[test_input_types_pref.html]
[test_input_typing_sanitization.html]
[test_input_untrusted_key_events.html]

View file

@ -0,0 +1,228 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1286182
-->
<head>
<title>Test key events for time control</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<meta charset="UTF-8">
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1286182">Mozilla Bug 1286182</a>
<p id="display"></p>
<div id="content">
<input id="input" type="date">
</div>
<pre id="test">
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
// Turn off Spatial Navigation because it hijacks arrow keydown events:
SimpleTest.waitForFocus(function() {
SpecialPowers.pushPrefEnv({"set":[["snav.enabled", false]]}, function() {
test();
SimpleTest.finish();
});
});
var testData = [
/**
* keys: keys to send to the input element.
* initialVal: initial value set to the input element.
* expectedVal: expected value of the input element after sending the keys.
*/
{
// Type 11222016, default order is month, day, year.
keys: ["11222016"],
initialVal: "",
expectedVal: "2016-11-22"
},
{
// Type 3 in the month field will automatically advance to the day field,
// then type 5 in the day field will automatically advance to the year
// field.
keys: ["352016"],
initialVal: "",
expectedVal: "2016-03-05"
},
{
// Type 13 in the month field will set it to the maximum month, which is
// 12.
keys: ["13012016"],
initialVal: "",
expectedVal: "2016-12-01"
},
{
// Type 00 in the month field will set it to the minimum month, which is 1.
keys: ["00012016"],
initialVal: "",
expectedVal: "2016-01-01"
},
{
// Type 33 in the day field will set it to the maximum day, which is 31.
keys: ["12332016"],
initialVal: "",
expectedVal: "2016-12-31"
},
{
// Type 00 in the day field will set it to the minimum day, which is 1.
keys: ["12002016"],
initialVal: "",
expectedVal: "2016-12-01"
},
{
// Type 275769 in the year field will set it to the maximum year, which is
// 275760.
keys: ["0101275769"],
initialVal: "",
expectedVal: "275760-01-01"
},
{
// Type 000000 in the year field will set it to the minimum year, which is
// 0001.
keys: ["0101000000"],
initialVal: "",
expectedVal: "0001-01-01"
},
{
// Advance to year field and decrement.
keys: ["VK_TAB", "VK_TAB", "VK_DOWN"],
initialVal: "2016-11-25",
expectedVal: "2015-11-25"
},
{
// Right key should do the same thing as TAB key.
keys: ["VK_RIGHT", "VK_RIGHT", "VK_DOWN"],
initialVal: "2016-11-25",
expectedVal: "2015-11-25"
},
{
// Advance to day field then back to month field and decrement.
keys: ["VK_RIGHT", "VK_LEFT", "VK_DOWN"],
initialVal: "2000-05-01",
expectedVal: "2000-04-01"
},
{
// Focus starts on the first field, month in this case, and increment.
keys: ["VK_UP"],
initialVal: "2000-03-01",
expectedVal: "2000-04-01"
},
{
// Advance to day field and decrement.
keys: ["VK_TAB", "VK_DOWN"],
initialVal: "1234-01-01",
expectedVal: "1234-01-31"
},
{
// Advance to day field and increment.
keys: ["VK_TAB", "VK_UP"],
initialVal: "1234-01-01",
expectedVal: "1234-01-02"
},
{
// PageUp on month field increments month by 3.
keys: ["VK_PAGE_UP"],
initialVal: "1999-01-01",
expectedVal: "1999-04-01"
},
{
// PageDown on month field decrements month by 3.
keys: ["VK_PAGE_DOWN"],
initialVal: "1999-01-01",
expectedVal: "1999-10-01"
},
{
// PageUp on day field increments day by 7.
keys: ["VK_TAB", "VK_PAGE_UP"],
initialVal: "1999-01-01",
expectedVal: "1999-01-08"
},
{
// PageDown on day field decrements day by 7.
keys: ["VK_TAB", "VK_PAGE_DOWN"],
initialVal: "1999-01-01",
expectedVal: "1999-01-25"
},
{
// PageUp on year field increments year by 10.
keys: ["VK_TAB", "VK_TAB", "VK_PAGE_UP"],
initialVal: "1999-01-01",
expectedVal: "2009-01-01"
},
{
// PageDown on year field decrements year by 10.
keys: ["VK_TAB", "VK_TAB", "VK_PAGE_DOWN"],
initialVal: "1999-01-01",
expectedVal: "1989-01-01"
},
{
// Home key on month field sets it to the minimum month, which is 01.
keys: ["VK_HOME"],
initialVal: "2016-06-01",
expectedVal: "2016-01-01"
},
{
// End key on month field sets it to the maximum month, which is 12.
keys: ["VK_END"],
initialVal: "2016-06-01",
expectedVal: "2016-12-01"
},
{
// Home key on day field sets it to the minimum day, which is 01.
keys: ["VK_TAB", "VK_HOME"],
initialVal: "2016-01-10",
expectedVal: "2016-01-01"
},
{
// End key on day field sets it to the maximum day, which is 31.
keys: ["VK_TAB", "VK_END"],
initialVal: "2016-01-10",
expectedVal: "2016-01-31"
},
{
// Home key on year field sets it to the minimum year, which is 0001.
keys: ["VK_TAB", "VK_TAB", "VK_HOME"],
initialVal: "2016-01-01",
expectedVal: "0001-01-01"
},
{
// End key on year field sets it to the maximum year, which is 275760.
keys: ["VK_TAB", "VK_TAB", "VK_END"],
initialVal: "2016-01-01",
expectedVal: "275760-01-01"
},
];
function sendKeys(aKeys) {
for (let i = 0; i < aKeys.length; i++) {
let key = aKeys[i];
if (key.startsWith("VK")) {
synthesizeKey(key, {});
} else {
sendString(key);
}
}
}
function test() {
var elem = document.getElementById("input");
for (let { keys, initialVal, expectedVal } of testData) {
elem.focus();
elem.value = initialVal;
sendKeys(keys);
elem.blur();
is(elem.value, expectedVal,
"Test with " + keys + ", result should be " + expectedVal);
elem.value = "";
}
}
</script>
</pre>
</body>
</html>

View file

@ -4,7 +4,7 @@
https://bugzilla.mozilla.org/show_bug.cgi?id=1288591
-->
<head>
<title>Test focus/blur behaviour for &lt;input type='time'&gt;</title>
<title>Test focus/blur behaviour for date/time input types</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
@ -12,7 +12,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1288591
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1288591">Mozilla Bug 1288591</a>
<p id="display"></p>
<div id="content">
<input id="input" type="time">
<input id="input_time" type="time">
<input id="input_date" type="date">
</div>
<pre id="test">
<script type="application/javascript">
@ -30,15 +31,15 @@ SimpleTest.waitForFocus(function() {
SimpleTest.finish();
});
function test() {
let time = document.getElementById("input");
time.focus();
function testFocusBlur(type) {
let input = document.getElementById("input_" + type);
input.focus();
// The active element returns the input type=time.
// The active element returns the date/time input element.
let activeElement = document.activeElement;
is(activeElement, time, "activeElement should be the time element");
is(activeElement, input, "activeElement should be the date/time input element");
is(activeElement.localName, "input", "activeElement should be an input element");
is(activeElement.type, "time", "activeElement should be of type time");
is(activeElement.type, type, "activeElement should be of type " + type);
// Use FocusManager to check that the actual focus is on the anonymous
// text control.
@ -48,10 +49,17 @@ function test() {
is(focusedElement.localName, "input", "focusedElement should be an input element");
is(focusedElement.type, "text", "focusedElement should be of type text");
time.blur();
isnot(document.activeElement, time, "activeElement should no longer be the time element");
input.blur();
isnot(document.activeElement, input, "activeElement should no longer be the datetime input element");
}
function test() {
let inputTypes = ["time", "date"];
for (let i = 0; i < inputTypes.length; i++) {
testFocusBlur(inputTypes[i]);
}
}
</script>
</pre>
</body>

View file

@ -0,0 +1,90 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1301306
-->
<head>
<title>Test for Bug 1301306</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.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=1301306">Mozilla Bug 722599</a>
<p id="display"></p>
<div id="content">
<input type="time" id="input_time" onfocus="++focusEvents[0]"
onblur="++blurEvents[0]" onfocusin="++focusInEvents[0]"
onfocusout="++focusOutEvents[0]">
<input type="date" id="input_date" onfocus="++focusEvents[1]"
onblur="++blurEvents[1]" onfocusin="++focusInEvents[1]"
onfocusout="++focusOutEvents[1]">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/**
* Test for Bug 1301306.
* This test checks that when moving inside the time input element, e.g. jumping
* through the inner text boxes, does not fire extra focus/blur events.
**/
var inputTypes = ["time", "date"];
var focusEvents = [0, 0];
var focusInEvents = [0, 0];
var focusOutEvents = [0, 0];
var blurEvents = [0, 0];
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(function() {
test();
SimpleTest.finish();
});
function test() {
for (var i = 0; i < inputTypes.length; i++) {
var input = document.getElementById("input_" + inputTypes[i]);
input.focus();
is(focusEvents[i], 1, inputTypes[i] + " input element should have dispatched focus event.");
is(focusInEvents[i], 1, inputTypes[i] + " input element should have dispatched focusin event.");
is(focusOutEvents[i], 0, inputTypes[i] + " input element should not have dispatched focusout event.");
is(blurEvents[i], 0, inputTypes[i] + " input element should not have dispatched blur event.");
// Move around inside the input element's input box.
synthesizeKey("VK_TAB", {});
is(focusEvents[i], 1, inputTypes[i] + " input element should not have dispatched focus event.");
is(focusInEvents[i], 1, inputTypes[i] + " input element should not have dispatched focusin event.");
is(focusOutEvents[i], 0, inputTypes[i] + " input element should not have dispatched focusout event.");
is(blurEvents[i], 0, inputTypes[i] + " time input element should not have dispatched blur event.");
synthesizeKey("VK_RIGHT", {});
is(focusEvents[i], 1, inputTypes[i] + " input element should not have dispatched focus event.");
is(focusInEvents[i], 1, inputTypes[i] + " input element should not have dispatched focusin event.");
is(focusOutEvents[i], 0, inputTypes[i] + " input element should not have dispatched focusout event.");
is(blurEvents[i], 0, inputTypes[i] + " input element should not have dispatched blur event.");
synthesizeKey("VK_LEFT", {});
is(focusEvents[i], 1,inputTypes[i] + " input element should not have dispatched focus event.");
is(focusInEvents[i], 1, inputTypes[i] + " input element should not have dispatched focusin event.");
is(focusOutEvents[i], 0, inputTypes[i] + " input element should not have dispatched focusout event.");
is(blurEvents[i], 0, inputTypes[i] + " input element should not have dispatched blur event.");
synthesizeKey("VK_RIGHT", {});
is(focusEvents[i], 1, inputTypes[i] + " input element should not have dispatched focus event.");
is(focusInEvents[i], 1, inputTypes[i] + " input element should not have dispatched focusin event.");
is(focusOutEvents[i], 0, inputTypes[i] + " input element should not have dispatched focusout event.");
is(blurEvents[i], 0, inputTypes[i] + " input element should not have dispatched blur event.");
input.blur();
is(focusEvents[i], 1, inputTypes[i] + " input element should not have dispatched focus event.");
is(focusInEvents[i], 1, inputTypes[i] + " input element should not have dispatched focusin event.");
is(focusOutEvents[i], 1, inputTypes[i] + " input element should have dispatched focusout event.");
is(blurEvents[i], 1, inputTypes[i] + " input element should have dispatched blur event.");
}
}
</script>
</pre>
</body>
</html>

View file

@ -4,7 +4,7 @@
https://bugzilla.mozilla.org/show_bug.cgi?id=1288591
-->
<head>
<title>Test tabindex attribute for &lt;input type='time'&gt;</title>
<title>Test tabindex attribute for date/time input types</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
@ -16,13 +16,16 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1288591
<input id="time1" type="time" tabindex="0">
<input id="time2" type="time" tabindex="-1">
<input id="time3" type="time" tabindex="0">
<input id="date1" type="date" tabindex="0">
<input id="date2" type="date" tabindex="-1">
<input id="date3" type="date" tabindex="0">
</div>
<pre id="test">
<script type="application/javascript">
/**
* Test for Bug 1288591.
* This test checks whether date/time input types' tabindex attribute works
* This test checks whether date/time input types tabindex attribute works
* correctly.
**/
SimpleTest.waitForExplicitFinish();
@ -31,41 +34,49 @@ SimpleTest.waitForFocus(function() {
SimpleTest.finish();
});
function test() {
let time1 = document.getElementById("time1");
let time2 = document.getElementById("time2");
let time3 = document.getElementById("time3");
function testTabindex(type) {
let input1 = document.getElementById(type + "1");
let input2 = document.getElementById(type + "2");
let input3 = document.getElementById(type + "3");
time1.focus();
is(document.activeElement, time1,
input1.focus();
is(document.activeElement, input1,
"input element with tabindex=0 is focusable");
// Advance to time1 minute field
// Advance to next inner field
synthesizeKey("VK_TAB", {});
is(document.activeElement, time1,
is(document.activeElement, input1,
"input element with tabindex=0 is tabbable");
// Advance to time1 AM/PM field
// Advance to next inner field
synthesizeKey("VK_TAB", {});
is(document.activeElement, time1,
is(document.activeElement, input1,
"input element with tabindex=0 is tabbable");
// Advance to next element
synthesizeKey("VK_TAB", {});
is(document.activeElement, time3,
is(document.activeElement, input3,
"input element with tabindex=-1 is not tabbable");
time2.focus();
is(document.activeElement, time2,
input2.focus();
is(document.activeElement, input2,
"input element with tabindex=-1 is still focusable");
// Changing the tabindex attribute dynamically.
time3.setAttribute("tabindex", "-1");
synthesizeKey("VK_TAB", {}); // need only one TAB since time2 is not tabbable
isnot(document.activeElement, time3,
input3.setAttribute("tabindex", "-1");
synthesizeKey("VK_TAB", {}); // need only one TAB since input2 is not tabbable
isnot(document.activeElement, input3,
"element with tabindex changed to -1 should not be tabbable");
}
function test() {
let inputTypes = ["time", "date"];
for (let i = 0; i < inputTypes.length; i++) {
testTabindex(inputTypes[i]);
}
}
</script>
</pre>
</body>

View file

@ -1,82 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1301306
-->
<head>
<title>Test for Bug 1301306</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.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=1301306">Mozilla Bug 722599</a>
<p id="display"></p>
<div id="content">
<input type="time" id="input_time" onfocus="++focusEvent" onblur="++blurEvent"
onfocusin="++focusInEvent" onfocusout="++focusOutEvent">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/**
* Test for Bug 1301306.
* This test checks that when moving inside the time input element, e.g. jumping
* through the inner text boxes, does not fire extra focus/blur events.
**/
var focusEvent = 0;
var focusInEvent = 0;
var focusOutEvent = 0;
var blurEvent = 0;
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(function() {
test();
SimpleTest.finish();
});
function test() {
var time = document.getElementById("input_time");
time.focus();
is(focusEvent, 1, "time input element should have dispatched focus event.");
is(focusInEvent, 1, "time input element should have dispatched focusin event.");
is(focusOutEvent, 0, "time input element should not have dispatched focusout event.");
is(blurEvent, 0, "time input element should not have dispatched blur event.");
// Move around inside the input element's input box.
synthesizeKey("VK_TAB", {});
is(focusEvent, 1, "time input element should not have dispatched focus event.");
is(focusInEvent, 1, "time input element should have dispatched focusin event.");
is(focusOutEvent, 0, "time input element should not have dispatched focusout event.");
is(blurEvent, 0, "time input element should not have dispatched blur event.");
synthesizeKey("VK_RIGHT", {});
is(focusEvent, 1, "time input element should not have dispatched focus event.");
is(focusInEvent, 1, "time input element should have dispatched focusin event.");
is(focusOutEvent, 0, "time input element should not have dispatched focusout event.");
is(blurEvent, 0, "time input element should not have dispatched blur event.");
synthesizeKey("VK_LEFT", {});
is(focusEvent, 1, "time input element should not have dispatched focus event.");
is(focusInEvent, 1, "time input element should have dispatched focusin event.");
is(focusOutEvent, 0, "time input element should not have dispatched focusout event.");
is(blurEvent, 0, "time input element should not have dispatched blur event.");
synthesizeKey("VK_RIGHT", {});
is(focusEvent, 1, "time input element should not have dispatched focus event.");
is(focusInEvent, 1, "time input element should have dispatched focusin event.");
is(focusOutEvent, 0, "time input element should not have dispatched focusout event.");
is(blurEvent, 0, "time input element should not have dispatched blur event.");
time.blur();
is(focusEvent, 1, "time input element should not have dispatched focus event.");
is(focusInEvent, 1, "time input element should have dispatched focusin event.");
is(focusOutEvent, 1, "time input element should not have dispatched focusout event.");
is(blurEvent, 1, "time input element should have dispatched blur event.");
}
</script>
</pre>
</body>
</html>

View file

@ -26,6 +26,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=765772
* This test checks that when a user types in some input types, it will not be
* in a state where the value will be un-sanitized and usable (by a script).
*/
const isDesktop = !/Mobile|Tablet/.test(navigator.userAgent);
var input = document.getElementById('i');
var form = document.getElementById('f');
@ -143,6 +144,7 @@ function runTest()
]
},
{
mobileOnly: true,
type: 'date',
validData: [
'0001-01-01',
@ -160,6 +162,28 @@ function runTest()
'1000-12-99',
]
},
{
mobileOnly: true,
type: 'time',
validData: [
'00:00',
'09:09:00',
'08:23:23.1',
'21:43:56.12',
'23:12:45.100',
],
invalidData: [
'00:',
'00:00:',
'25:00',
'-00:00',
'00:00:00.',
'00:60',
'10:58:99',
':19:10',
'23:08:09.1012',
]
},
{
type: 'month',
validData: [
@ -218,6 +242,10 @@ function runTest()
for (test of data) {
gCurrentTest = test;
if (gCurrentTest.mobileOnly && isDesktop) {
continue;
}
input.type = test.type;
gValidData = test.validData;
gInvalidData = test.invalidData;