summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/uievents/keyboard/key.js
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/uievents/keyboard/key.js')
-rw-r--r--testing/web-platform/tests/uievents/keyboard/key.js671
1 files changed, 671 insertions, 0 deletions
diff --git a/testing/web-platform/tests/uievents/keyboard/key.js b/testing/web-platform/tests/uievents/keyboard/key.js
new file mode 100644
index 0000000000..175258bd88
--- /dev/null
+++ b/testing/web-platform/tests/uievents/keyboard/key.js
@@ -0,0 +1,671 @@
+var _testing = false;
+
+// The index into _keyTable of the key currently being tested.
+var _currKey = 0;
+
+var _keysTotal = 0;
+var _keysGood = 0;
+var _keysBad = 0;
+var _keysSkipped = 0;
+
+var _modifierMode = "None";
+
+var _keydownCapture = [];
+var _keyupCapture = [];
+
+var CAPTURE_KEYCODE = 0;
+var CAPTURE_CODE = 1;
+var CAPTURE_KEY = 2;
+var CAPTURE_SHIFTKEY = 3;
+var CAPTURE_CONTROLKEY = 4;
+var CAPTURE_ALTKEY = 5;
+var CAPTURE_METAKEY = 6;
+
+// An array of KeyInfo for each key to be tested.
+var _keyTable = [];
+
+// KeyInfo fields.
+var KEYINFO_CODE = 0; // |code| for this key
+var KEYINFO_ROW = 1; // Keyboard row
+var KEYINFO_TYPE = 2; // Key type (see below)
+var KEYINFO_WIDTH = 3; // Width of key: 0=normal
+var KEYINFO_KEYCAP = 4; // Keycap string to display
+var KEYINFO_KEY = 5; // Unmodified key value
+var KEYINFO_KEY_SHIFT = 6; // Shifted key value
+
+var KEYTYPE_NORMAL = 0;
+var KEYTYPE_DISABLED = 1; // Key cannot be tested: e.g., CapsLock
+var KEYTYPE_END = 2; // Used to mark end of KeyTable
+var KEYTYPE_MODIFIER = 3; // Modifer key
+
+function clearChildren(e) {
+ while (e.firstChild !== null) {
+ e.removeChild(e.firstChild);
+ }
+}
+
+function setText(e, text) {
+ clearChildren(e);
+ e.appendChild(document.createTextNode(text));
+}
+
+function setUserAgent() {
+ var userAgent = navigator.userAgent;
+ uaDiv = document.getElementById("useragent");
+ setText(uaDiv, userAgent);
+}
+
+function addEventListener(obj, etype, handler) {
+ if (obj.addEventListener) {
+ obj.addEventListener(etype, handler, false);
+ } else if (obj.attachEvent) {
+ obj.attachEvent("on"+etype, handler);
+ } else {
+ obj["on"+etype] = handler;
+ }
+}
+
+function addClass(obj, className) {
+ obj.classList.add(className);
+}
+
+function removeClass(obj, className) {
+ obj.classList.remove(className);
+}
+
+function addInnerText(obj, text) {
+ obj.appendChild(document.createTextNode(text));
+}
+
+function calcLocation(loc) {
+ if (loc == 1) return "LEFT";
+ if (loc == 2) return "RIGHT";
+ if (loc == 3) return "NUMPAD";
+ return loc;
+}
+
+function isModifierKey(e) {
+ // Shift, Control, Alt
+ if (e.keyCode >= 16 && e.keyCode <= 18) {
+ return true;
+ }
+ // Windows, Command or Meta key.
+ if (e.keyCode == 224 // Right/Left: Gecko
+ || e.keyCode == 91 // Left: WebKit/Blink
+ || e.keyCode == 93 // Right: WebKit/Blink
+ ) {
+ return true;
+ }
+ return false;
+}
+
+function init(title, keytable) {
+ _keyTable = keytable;
+
+ createBody(title, keytable);
+
+ setUserAgent();
+
+ var input = document.getElementById("input");
+ input.disabled = true;
+ addEventListener(input, "keydown", onKeyDown);
+ addEventListener(input, "keyup", onKeyUp);
+ //addEventListener(input, "beforeInput", onBeforeInput);
+ //addEventListener(input, "input", onInput);
+}
+
+function onKeyDown(e) {
+ // Ignore modifier keys when checking modifier combinations.
+ if (_modifierMode != "None" && isModifierKey(e)) {
+ return;
+ }
+
+ _keydownInfo = [e.keyCode, e.code, e.key, e.shiftKey, e.ctrlKey, e.altKey, e.metaKey];
+ if (e.keyCode == 9 || e.code == "Tab") {
+ e.preventDefault();
+ }
+}
+
+function onKeyUp(e) {
+ // Ignore modifier keys when checking modifier combinations.
+ if (_modifierMode != "None" && isModifierKey(e)) {
+ return;
+ }
+
+ _keyupInfo = [e.keyCode, e.code, e.key, e.shiftKey, e.ctrlKey, e.altKey, e.metaKey];
+
+ if (_testing) {
+ verifyKey();
+ nextKey();
+ }
+}
+
+function onBeforeInput(e) {
+}
+
+function onInput(e) {
+}
+
+function addError(elem, str) {
+ var p = document.createElement('p');
+ p.classList.add("error2");
+ p.textContent = str;
+ elem.appendChild(p);
+}
+
+function addErrorIncorrect(elem, eventName, attrName, keyEventInfo, attr, expected) {
+ addError(elem, "Incorrect " + eventName
+ + " |" + attrName + "| = " + keyEventInfo[attr]
+ + " - Expected " + expected);
+}
+
+function verifyKeyEventFields(eventName, keyEventInfo, code, key, error) {
+ var verifyCode = document.getElementById("opt_attr_code").checked;
+ var verifyKey = document.getElementById("opt_attr_key").checked;
+ var verifyModifiers = document.getElementById("opt_attr_modifiers").checked;
+ var good = true;
+
+ if (!verifyCode && !verifyKey && !verifyModifiers) {
+ good = false;
+ addError(error, "Invalid test: At least one attribute must be selected for testing.");
+ }
+ if (verifyCode && keyEventInfo[CAPTURE_CODE] != code) {
+ good = false;
+ addErrorIncorrect(error, eventName, "code", keyEventInfo, CAPTURE_CODE, code);
+ }
+ if (verifyKey && keyEventInfo[CAPTURE_KEY] != key) {
+ good = false;
+ addErrorIncorrect(error, eventName, "key", keyEventInfo, CAPTURE_KEY, key);
+ }
+ if (verifyModifiers) {
+ if (keyEventInfo[CAPTURE_SHIFTKEY] != (_modifierMode == "Shift")) {
+ good = false;
+ addErrorIncorrect(error, eventName, "shiftKey", keyEventInfo, CAPTURE_SHIFTKEY, false);
+ }
+ if (keyEventInfo[CAPTURE_CONTROLKEY]) {
+ good = false;
+ addErrorIncorrect(error, eventName, "controlKey", keyEventInfo, CAPTURE_CONTROLKEY, false);
+ }
+ if (keyEventInfo[CAPTURE_ALTKEY]) {
+ good = false;
+ addErrorIncorrect(error, eventName, "altKey", keyEventInfo, CAPTURE_ALTKEY, false);
+ }
+ if (keyEventInfo[CAPTURE_METAKEY]) {
+ good = false;
+ addErrorIncorrect(error, eventName, "metaKey", keyEventInfo, CAPTURE_METAKEY, false);
+ }
+ }
+
+ return good;
+}
+
+function verifyKey() {
+ _keysTotal++;
+
+ var keyInfo = _keyTable[_currKey];
+ var code = keyInfo[KEYINFO_CODE];
+ var key = keyInfo[KEYINFO_KEY];
+ var keyShift = keyInfo[KEYINFO_KEY_SHIFT];
+
+ var keyCheck = key;
+ if (_modifierMode == "Shift") {
+ keyCheck = keyShift;
+ }
+
+ var verifyKeydown = document.getElementById("opt_event_keydown").checked;
+ var verifyKeyup = document.getElementById("opt_event_keyup").checked;
+
+ var error = document.createElement('div');
+ error.classList.add("error");
+ var good = true;
+
+ if (verifyKeydown) {
+ good = verifyKeyEventFields("keydown", _keydownInfo, code, keyCheck, error);
+ }
+ if (verifyKeyup) {
+ good = verifyKeyEventFields("keyup", _keyupInfo, code, keyCheck, error);
+ }
+
+ if (!verifyKeydown && !verifyKeyup) {
+ good = false;
+ addError(error, "Invalid test: At least one event must be selected for testing.");
+ }
+
+ // Allow Escape key to skip the current key.
+ var skipped = false;
+ if (_keydownInfo[CAPTURE_KEYCODE] == 27 || _keydownInfo[CAPTURE_CODE] == "Escape") {
+ good = true;
+ skipped = true;
+ }
+
+ if (!good) {
+ var p = document.createElement('p');
+ p.classList.add("error1");
+ p.textContent = "Error : " + code;
+ error.insertBefore(p, error.firstChild);
+ }
+
+ removeNextKeyHilight();
+ if (skipped) {
+ _keysSkipped++;
+ document.getElementById(code).classList.add("skippedKey")
+ } else if (good) {
+ _keysGood++;
+ document.getElementById(code).classList.add("goodKey")
+ } else {
+ _keysBad++;
+ document.getElementById(code).classList.add("badKey")
+ }
+ updateTestSummary(good ? null : error);
+}
+
+function updateTestSummary(error) {
+ document.getElementById("keys-total").textContent = _keysTotal;
+ document.getElementById("keys-good").textContent = _keysGood;
+ document.getElementById("keys-bad").textContent = _keysBad;
+ document.getElementById("keys-skipped").textContent = _keysSkipped;
+
+ if (error) {
+ var errors = document.getElementById("errors");
+ errors.insertBefore(error, errors.firstChild);
+ }
+}
+
+function resetTest() {
+ _keysTotal = 0;
+ _keysGood = 0;
+ _keysBad = 0;
+
+ _currKey = -1;
+ nextKey();
+
+ updateTestSummary();
+
+ // Remove previous test results.
+ clearChildren(document.getElementById("errors"));
+
+ // Remove highlighting from keys.
+ for (var i = 0; i < _keyTable.length; i++) {
+ var code = _keyTable[i][KEYINFO_CODE];
+ var type = _keyTable[i][KEYINFO_TYPE];
+ if (type != KEYTYPE_END) {
+ var key = document.getElementById(code);
+ key.classList.remove("goodKey");
+ key.classList.remove("badKey");
+ key.classList.remove("skippedKey");
+ }
+ }
+}
+
+function startTest() {
+ if (_testing) {
+ // Cancel the currently running test.
+ endTest();
+ return;
+ }
+
+ resetTest();
+ _testing = true;
+ document.getElementById("start").value = "Stop Test"
+
+ var input = document.getElementById("input");
+ input.value = "";
+ input.disabled = false;
+ input.focus();
+
+ // Show test instructions and info.
+ document.getElementById("test-info").style.display = 'block';
+ document.getElementById("instructions").style.display = 'block';
+ document.getElementById("test-done").style.display = 'none';
+}
+
+function endTest() {
+ _testing = false;
+ removeNextKeyHilight();
+ document.getElementById("start").value = "Restart Test"
+ document.getElementById("input").disabled = true;
+ document.getElementById("instructions").style.display = 'none';
+ document.getElementById("test-done").style.display = 'block';
+}
+
+function removeNextKeyHilight() {
+ var curr = document.getElementById(_keyTable[_currKey][KEYINFO_CODE]);
+ if (curr) {
+ removeClass(curr, "nextKey")
+ }
+}
+
+function addNextKeyHilight() {
+ var curr = document.getElementById(_keyTable[_currKey][KEYINFO_CODE]);
+ if (curr) {
+ addClass(curr, "nextKey")
+ }
+}
+
+function nextKey() {
+ var keyInfo;
+ var keepLooking = true;
+ do {
+ _currKey++;
+ keyInfo = _keyTable[_currKey];
+ var type = keyInfo[KEYINFO_TYPE];
+
+ // Skip over disabled keys.
+ keepLooking = (type == KEYTYPE_DISABLED);
+
+ // Skip over modifier keys if we're testing modifier combinations.
+ if (_modifierMode != "None" && type == KEYTYPE_MODIFIER) {
+ keepLooking = true;
+ }
+
+ // Skip over keys in disabled rows.
+ if (type != KEYTYPE_END) {
+ var row = keyInfo[KEYINFO_ROW];
+ var rowEnabled = document.getElementById("opt_row_" + row).checked;
+ keepLooking = keepLooking || !rowEnabled;
+ }
+ } while (keepLooking);
+
+ if (keyInfo[KEYINFO_TYPE] == KEYTYPE_END) {
+ endTest();
+ } else {
+ addNextKeyHilight();
+ }
+}
+
+function toggleOptions() {
+ var link = document.getElementById("optionstoggle");
+ var options = document.getElementById("options");
+ clearChildren(link);
+ if (options.style.display == "block") {
+ options.style.display = "none";
+ addInnerText(link, "Show Options");
+ }
+ else {
+ options.style.display = "block";
+ addInnerText(link, "Hide Options");
+ }
+}
+
+function toggleHelp() {
+ var link = document.getElementById("helptoggle");
+ var help = document.getElementById("help");
+ clearChildren(link);
+ if (help.style.display == "block") {
+ help.style.display = "none";
+ addInnerText(link, "Show Help");
+ }
+ else {
+ help.style.display = "block";
+ addInnerText(link, "Hide Help");
+ }
+}
+
+function createBody(title, keytable) {
+ var body = document.getElementsByTagName("body")[0];
+ var p;
+ var span;
+
+ var h1 = document.createElement('h1');
+ h1.textContent = "Keyboard Event Manual Test - " + title;
+ body.appendChild(h1);
+
+ // Display useragent.
+ p = document.createElement('p');
+ p.textContent = "UserAgent: ";
+ var useragent = document.createElement('span');
+ useragent.id = "useragent";
+ p.appendChild(useragent);
+ body.appendChild(p);
+
+ // Display input textedit.
+ p = document.createElement('p');
+ p.textContent = "Test Input: ";
+ var input1 = document.createElement('input');
+ input1.id = "input";
+ input1.type = "text";
+ input1.size = 80;
+ p.appendChild(input1);
+ p.appendChild(document.createTextNode(" "));
+ var input2 = document.createElement('input');
+ input2.id = "start";
+ input2.type = "button";
+ input2.onclick = function() { startTest(); return false; }
+ input2.value = "Start Test";
+ p.appendChild(input2);
+ p.appendChild(document.createTextNode(" "));
+ var optionsToggle = document.createElement('a');
+ optionsToggle.id = "optionstoggle";
+ optionsToggle.href = "javascript:toggleOptions()";
+ optionsToggle.textContent = "Show Options";
+ p.appendChild(optionsToggle);
+ p.appendChild(document.createTextNode(" "));
+ var helpToggle = document.createElement('a');
+ helpToggle.id = "helptoggle";
+ helpToggle.href = "javascript:toggleHelp()";
+ helpToggle.textContent = "Show Help";
+ p.appendChild(helpToggle);
+ body.appendChild(p);
+
+ createOptions(body);
+
+ createHelp(body);
+
+ createKeyboard(body, keytable);
+
+ // Test info and summary.
+ var test_info = document.createElement('div');
+ test_info.id = "test-info";
+ test_info.style.display = "none";
+
+ var instructions = document.createElement('div');
+ instructions.id = "instructions";
+ p = document.createElement('p');
+ p.textContent = "Press the highlighted key.";
+ instructions.appendChild(p);
+ test_info.appendChild(instructions);
+
+ var test_done = document.createElement('div');
+ test_done.id = "test-done";
+ p = document.createElement('p');
+ p.textContent = "Test complete!";
+ test_done.appendChild(p);
+ test_info.appendChild(test_done);
+
+ var summary = document.createElement('div');
+ summary.id = "summary";
+ p = document.createElement('p');
+ summary.appendChild(document.createTextNode("Keys Tested: "));
+ span = document.createElement('span');
+ span.id = "keys-total";
+ span.textContent = 0;
+ summary.appendChild(span);
+ summary.appendChild(document.createTextNode("; Passed "));
+ span = document.createElement('span');
+ span.id = "keys-good";
+ span.textContent = 0;
+ summary.appendChild(span);
+ summary.appendChild(document.createTextNode("; Failed "));
+ span = document.createElement('span');
+ span.id = "keys-bad";
+ span.textContent = 0;
+ summary.appendChild(span);
+ summary.appendChild(document.createTextNode("; Skipped "));
+ span = document.createElement('span');
+ span.id = "keys-skipped";
+ span.textContent = 0;
+ summary.appendChild(span);
+ test_info.appendChild(summary);
+
+ var errors = document.createElement('div');
+ errors.id = "errors";
+ test_info.appendChild(errors);
+
+ body.appendChild(test_info);
+}
+
+function addOptionTitle(cell, title) {
+ var span = document.createElement('span');
+ span.classList.add("opttitle");
+ span.textContent = title;
+ cell.appendChild(span);
+ cell.appendChild(document.createElement("br"));
+}
+
+function addOptionCheckbox(cell, id, text) {
+ var label = document.createElement("label");
+
+ var input = document.createElement("input");
+ input.type = "checkbox";
+ input.id = id;
+ input.checked = true;
+ label.appendChild(input);
+
+ label.appendChild(document.createTextNode(" " + text));
+ cell.appendChild(label);
+
+ cell.appendChild(document.createElement("br"));
+}
+
+function addOptionRadio(cell, group, text, handler, checked) {
+ var label = document.createElement("label");
+
+ var input = document.createElement("input");
+ input.type = "radio";
+ input.name = group;
+ input.value = text;
+ input.onclick = handler;
+ input.checked = checked;
+ label.appendChild(input);
+
+ label.appendChild(document.createTextNode(" " + text));
+ cell.appendChild(label);
+
+ cell.appendChild(document.createElement("br"));
+}
+
+function handleModifierGroup() {
+ var radio = document.querySelector("input[name=opt_modifier]:checked");
+ var oldMode = _modifierMode;
+ _modifierMode = radio.value;
+
+ if (oldMode == "Shift") {
+ document.getElementById("ShiftLeft").classList.remove("activeModifierKey");
+ document.getElementById("ShiftRight").classList.remove("activeModifierKey");
+ }
+
+ if (_modifierMode == "Shift") {
+ document.getElementById("ShiftLeft").classList.add("activeModifierKey");
+ document.getElementById("ShiftRight").classList.add("activeModifierKey");
+ }
+}
+
+function createOptions(body) {
+ var options = document.createElement('div');
+ options.id = "options";
+ options.style.display = "none";
+
+ var table = document.createElement('table');
+ table.classList.add("opttable");
+ var row = document.createElement('tr');
+ var cell;
+
+ cell = document.createElement('td');
+ cell.classList.add("optcell");
+ addOptionTitle(cell, "Keyboard Rows");
+ addOptionCheckbox(cell, "opt_row_0", "Row E (top)");
+ addOptionCheckbox(cell, "opt_row_1", "Row D");
+ addOptionCheckbox(cell, "opt_row_2", "Row C");
+ addOptionCheckbox(cell, "opt_row_3", "Row B");
+ addOptionCheckbox(cell, "opt_row_4", "Row A (bottom)");
+ row.appendChild(cell);
+
+ cell = document.createElement('td');
+ cell.classList.add("optcell");
+ addOptionTitle(cell, "Events");
+ addOptionCheckbox(cell, "opt_event_keydown", "keydown");
+ addOptionCheckbox(cell, "opt_event_keyup", "keyup");
+ row.appendChild(cell);
+
+ cell = document.createElement('td');
+ cell.classList.add("optcell");
+ addOptionTitle(cell, "Attributes");
+ addOptionCheckbox(cell, "opt_attr_code", "code");
+ addOptionCheckbox(cell, "opt_attr_key", "key");
+ addOptionCheckbox(cell, "opt_attr_modifiers", "modifiers");
+ row.appendChild(cell);
+
+ cell = document.createElement('td');
+ cell.classList.add("optcell");
+ addOptionTitle(cell, "Modifiers");
+ addOptionRadio(cell, "opt_modifier", "None", handleModifierGroup, true);
+ addOptionRadio(cell, "opt_modifier", "Shift", handleModifierGroup, false);
+ row.appendChild(cell);
+
+ table.appendChild(row);
+ options.appendChild(table);
+
+ body.appendChild(options);
+}
+
+function addHelpText(div, text) {
+ var p = document.createElement('p');
+ p.classList.add("help");
+ p.textContent = text;
+ div.appendChild(p);
+}
+
+function createHelp(body) {
+ var help = document.createElement('div');
+ help.id = "help";
+ help.style.display = "none";
+
+ addHelpText(help, "Click on the \"Start Test\" button to begin testing.");
+ addHelpText(help, "Press the hilighted key to test it.");
+ addHelpText(help, "Clicking anywhere outside the \"Test Input\" editbox will pause testing. To resume, click back inside the editbox.");
+ addHelpText(help, "To skip a key while testing, press Escape.");
+ addHelpText(help, "When testing with modifier keys, the modifier must be pressed before the keydown and released after the keyup of the key being tested.");
+
+ body.appendChild(help);
+}
+
+function createKeyboard(body, keytable) {
+ var keyboard = document.createElement('div');
+ keyboard.classList.add("keyboard");
+
+ var currRow = 0;
+ var row = document.createElement('div');
+ row.classList.add("key-row");
+
+ for (var i = 0; i < keytable.length; i++) {
+ var code = keytable[i][KEYINFO_CODE];
+ var rowId = keytable[i][KEYINFO_ROW];
+ var type = keytable[i][KEYINFO_TYPE];
+ var width = keytable[i][KEYINFO_WIDTH];
+ var keyCap = keytable[i][KEYINFO_KEYCAP];
+
+ if (type == KEYTYPE_END) {
+ continue;
+ }
+
+ if (rowId != currRow) {
+ keyboard.appendChild(row);
+ row = document.createElement('div');
+ row.classList.add("key-row");
+ currRow = rowId;
+ }
+
+ var key = document.createElement('div');
+ key.id = code;
+ key.classList.add("key");
+ if (width != 0) {
+ key.classList.add("wide" + width);
+ }
+ key.textContent = keyCap;
+
+ row.appendChild(key);
+ }
+
+ keyboard.appendChild(row);
+ body.appendChild(keyboard);
+}