--- a/testing/marionette/action.js
+++ b/testing/marionette/action.js
@@ -54,17 +54,17 @@ const MODIFIER_NAME_LOOKUP = {
/** Map from raw key (codepoint) to normalized key value */
const NORMALIZED_KEY_LOOKUP = {
"\uE000": "Unidentified",
"\uE001": "Cancel",
"\uE002": "Help",
"\uE003": "Backspace",
"\uE004": "Tab",
"\uE005": "Clear",
- "\uE006": "Return",
+ "\uE006": "Enter",
"\uE007": "Enter",
"\uE008": "Shift",
"\uE009": "Control",
"\uE00A": "Alt",
"\uE00B": "Pause",
"\uE00C": "Escape",
"\uE00D": " ",
"\uE00E": "PageUp",
@@ -874,18 +874,17 @@ action.Key = class {
this.code = KEY_CODE_LOOKUP[rawKey];
this.location = KEY_LOCATION_LOOKUP[rawKey] || 0;
this.altKey = false;
this.shiftKey = false;
this.ctrlKey = false;
this.metaKey = false;
this.repeat = false;
this.isComposing = false;
- // Prevent keyCode from being guessed in event.js; we don't want to use it anyway.
- this.keyCode = 0;
+ // keyCode will be computed by event.sendKeyDown
}
update(inputState) {
this.altKey = inputState.alt;
this.shiftKey = inputState.shift;
this.ctrlKey = inputState.ctrl;
this.metaKey = inputState.meta;
}
@@ -1077,17 +1076,17 @@ function dispatchKeyDown(a, inputState,
keyEvent.repeat = inputState.isPressed(keyEvent.key);
inputState.press(keyEvent.key);
if (keyEvent.key in MODIFIER_NAME_LOOKUP) {
inputState.setModState(keyEvent.key, true);
}
// Append a copy of |a| with keyUp subtype
action.inputsToCancel.push(Object.assign({}, a, {subtype: action.KeyUp}));
keyEvent.update(inputState);
- event.sendKeyDown(keyEvent.key, keyEvent, win);
+ event.sendKeyDown(a.value, keyEvent, win);
resolve();
});
}
/**
* Dispatch a keyUp action equivalent to releasing a key on a keyboard.
*
@@ -1108,17 +1107,17 @@ function dispatchKeyUp(a, inputState, wi
resolve();
return;
}
if (keyEvent.key in MODIFIER_NAME_LOOKUP) {
inputState.setModState(keyEvent.key, false);
}
inputState.release(keyEvent.key);
keyEvent.update(inputState);
- event.sendKeyUp(keyEvent.key, keyEvent, win);
+ event.sendKeyUp(a.value, keyEvent, win);
resolve();
});
}
/**
* Dispatch a pointerDown action equivalent to pressing a pointer-device
* button.
--- a/testing/marionette/event.js
+++ b/testing/marionette/event.js
@@ -352,16 +352,20 @@ event.synthesizeMouseScroll = function (
modifiers);
};
function computeKeyCodeFromChar_(char) {
if (char.length != 1) {
return 0;
}
+ if (char in VIRTUAL_KEYCODE_LOOKUP) {
+ return Ci.nsIDOMKeyEvent["DOM_" + VIRTUAL_KEYCODE_LOOKUP[char]];
+ }
+
if (char >= "a" && char <= "z") {
return Ci.nsIDOMKeyEvent.DOM_VK_A + char.charCodeAt(0) - "a".charCodeAt(0);
}
if (char >= "A" && char <= "Z") {
return Ci.nsIDOMKeyEvent.DOM_VK_A + char.charCodeAt(0) - "A".charCodeAt(0);
}
if (char >= "0" && char <= "9") {
return Ci.nsIDOMKeyEvent.DOM_VK_0 + char.charCodeAt(0) - "0".charCodeAt(0);
@@ -577,50 +581,52 @@ function getKeyboardEvent_(win = window)
if (typeof content != "undefined" && ("KeyboardEvent" in content)) {
return content.KeyboardEvent;
}
return win.KeyboardEvent;
}
function createKeyboardEventDictionary_(key, keyEvent, win = window) {
var result = { dictionary: null, flags: 0 };
- var keyCodeIsDefined = "keyCode" in keyEvent;
+ var keyCodeIsDefined = "keyCode" in keyEvent && keyEvent.keyCode != undefined;
var keyCode =
(keyCodeIsDefined && keyEvent.keyCode >= 0 && keyEvent.keyCode <= 255) ?
keyEvent.keyCode : 0;
var keyName = "Unidentified";
if (key.indexOf("KEY_") == 0) {
keyName = key.substr("KEY_".length);
result.flags |= Ci.nsITextInputProcessor.KEY_NON_PRINTABLE_KEY;
} else if (key.indexOf("VK_") == 0) {
keyCode = Ci.nsIDOMKeyEvent["DOM_" + key];
if (!keyCode) {
throw "Unknown key: " + key;
}
keyName = guessKeyNameFromKeyCode_(keyCode, win);
- result.flags |= Ci.nsITextInputProcessor.KEY_NON_PRINTABLE_KEY;
+ if (!isPrintable(keyCode, win)) {
+ result.flags |= Ci.nsITextInputProcessor.KEY_NON_PRINTABLE_KEY;
+ }
} else if (key != "") {
keyName = key;
if (!keyCodeIsDefined) {
keyCode = computeKeyCodeFromChar_(key.charAt(0));
}
if (!keyCode) {
result.flags |= Ci.nsITextInputProcessor.KEY_KEEP_KEYCODE_ZERO;
}
- // keyName was already determined in keyEvent so no fall-back needed
- if (!("key" in keyEvent && keyName == keyEvent.key)) {
+ // only force printable if "raw character" and event key match, like "a"
+ if (!("key" in keyEvent && key != keyEvent.key)) {
result.flags |= Ci.nsITextInputProcessor.KEY_FORCE_PRINTABLE_KEY;
}
}
var locationIsDefined = "location" in keyEvent;
if (locationIsDefined && keyEvent.location === 0) {
result.flags |= Ci.nsITextInputProcessor.KEY_KEEP_KEY_LOCATION_STANDARD;
}
result.dictionary = {
- key: keyName,
+ key: "key" in keyEvent ? keyEvent.key : keyName,
code: "code" in keyEvent ? keyEvent.code : "",
location: locationIsDefined ? keyEvent.location : 0,
repeat: "repeat" in keyEvent ? keyEvent.repeat === true : false,
keyCode: keyCode,
};
return result;
}
@@ -1215,16 +1221,92 @@ const VIRTUAL_KEYCODE_LOOKUP = {
function getKeyCode(c) {
if (c in VIRTUAL_KEYCODE_LOOKUP) {
return VIRTUAL_KEYCODE_LOOKUP[c];
}
return c;
}
+function isPrintable(c, win = window) {
+ let KeyboardEvent = getKeyboardEvent_(win);
+ let NON_PRINT_KEYS = [
+ KeyboardEvent.DOM_VK_CANCEL,
+ KeyboardEvent.DOM_VK_HELP,
+ KeyboardEvent.DOM_VK_BACK_SPACE,
+ KeyboardEvent.DOM_VK_TAB,
+ KeyboardEvent.DOM_VK_CLEAR,
+ KeyboardEvent.DOM_VK_SHIFT,
+ KeyboardEvent.DOM_VK_CONTROL,
+ KeyboardEvent.DOM_VK_ALT,
+ KeyboardEvent.DOM_VK_PAUSE,
+ KeyboardEvent.DOM_VK_EISU,
+ KeyboardEvent.DOM_VK_ESCAPE,
+ KeyboardEvent.DOM_VK_CONVERT,
+ KeyboardEvent.DOM_VK_NONCONVERT,
+ KeyboardEvent.DOM_VK_ACCEPT,
+ KeyboardEvent.DOM_VK_MODECHANGE,
+ KeyboardEvent.DOM_VK_PAGE_UP,
+ KeyboardEvent.DOM_VK_PAGE_DOWN,
+ KeyboardEvent.DOM_VK_END,
+ KeyboardEvent.DOM_VK_HOME,
+ KeyboardEvent.DOM_VK_LEFT,
+ KeyboardEvent.DOM_VK_UP,
+ KeyboardEvent.DOM_VK_RIGHT,
+ KeyboardEvent.DOM_VK_DOWN,
+ KeyboardEvent.DOM_VK_SELECT,
+ KeyboardEvent.DOM_VK_PRINT,
+ KeyboardEvent.DOM_VK_EXECUTE,
+ KeyboardEvent.DOM_VK_PRINTSCREEN,
+ KeyboardEvent.DOM_VK_INSERT,
+ KeyboardEvent.DOM_VK_DELETE,
+ KeyboardEvent.DOM_VK_WIN,
+ KeyboardEvent.DOM_VK_CONTEXT_MENU,
+ KeyboardEvent.DOM_VK_SLEEP,
+ KeyboardEvent.DOM_VK_F1,
+ KeyboardEvent.DOM_VK_F2,
+ KeyboardEvent.DOM_VK_F3,
+ KeyboardEvent.DOM_VK_F4,
+ KeyboardEvent.DOM_VK_F5,
+ KeyboardEvent.DOM_VK_F6,
+ KeyboardEvent.DOM_VK_F7,
+ KeyboardEvent.DOM_VK_F8,
+ KeyboardEvent.DOM_VK_F9,
+ KeyboardEvent.DOM_VK_F10,
+ KeyboardEvent.DOM_VK_F11,
+ KeyboardEvent.DOM_VK_F12,
+ KeyboardEvent.DOM_VK_F13,
+ KeyboardEvent.DOM_VK_F14,
+ KeyboardEvent.DOM_VK_F15,
+ KeyboardEvent.DOM_VK_F16,
+ KeyboardEvent.DOM_VK_F17,
+ KeyboardEvent.DOM_VK_F18,
+ KeyboardEvent.DOM_VK_F19,
+ KeyboardEvent.DOM_VK_F20,
+ KeyboardEvent.DOM_VK_F21,
+ KeyboardEvent.DOM_VK_F22,
+ KeyboardEvent.DOM_VK_F23,
+ KeyboardEvent.DOM_VK_F24,
+ KeyboardEvent.DOM_VK_NUM_LOCK,
+ KeyboardEvent.DOM_VK_SCROLL_LOCK,
+ KeyboardEvent.DOM_VK_VOLUME_MUTE,
+ KeyboardEvent.DOM_VK_VOLUME_DOWN,
+ KeyboardEvent.DOM_VK_VOLUME_UP,
+ KeyboardEvent.DOM_VK_META,
+ KeyboardEvent.DOM_VK_ALTGR,
+ KeyboardEvent.DOM_VK_ATTN,
+ KeyboardEvent.DOM_VK_CRSEL,
+ KeyboardEvent.DOM_VK_EXSEL,
+ KeyboardEvent.DOM_VK_EREOF,
+ KeyboardEvent.DOM_VK_PLAY,
+ KeyboardEvent.DOM_VK_RETURN,
+ ];
+ return !(NON_PRINT_KEYS.includes(c));
+}
+
event.sendKeyDown = function (keyToSend, modifiers, document) {
modifiers.type = "keydown";
event.sendSingleKey(keyToSend, modifiers, document);
// TODO This doesn't do anything since |synthesizeKeyEvent| ignores explicit
// keypress request, and instead figures out itself when to send keypress
if (["VK_SHIFT", "VK_CONTROL", "VK_ALT", "VK_META"].indexOf(getKeyCode(keyToSend)) < 0) {
modifiers.type = "keypress";
event.sendSingleKey(keyToSend, modifiers, document);
@@ -1246,27 +1328,27 @@ event.sendKeyUp = function (keyToSend, m
* @param {?} modifiers
* Object with properties used in KeyboardEvent (shiftkey, repeat, ...)
* as well as, the event |type| such as keydown. All properties are optional.
* @param {Window=} window
* Window object. If |window| is undefined, the event is synthesized in
* current window.
*/
event.sendSingleKey = function (keyToSend, modifiers, window = undefined) {
- let keyCode = getKeyCode(keyToSend);
- if (keyCode in KEYCODES_LOOKUP) {
+ let keyName = getKeyCode(keyToSend);
+ if (keyName in KEYCODES_LOOKUP) {
// We assume that if |keyToSend| is a raw code point (like "\uE009") then
// |modifiers| does not already have correct value for corresponding
// |modName| attribute (like ctrlKey), so that value needs to be flipped
- let modName = KEYCODES_LOOKUP[keyCode];
+ let modName = KEYCODES_LOOKUP[keyName];
modifiers[modName] = !modifiers[modName];
- } else if (modifiers.shiftKey && keyCode != "Shift") {
- keyCode = keyCode.toUpperCase();
+ } else if (modifiers.shiftKey && keyName != "Shift") {
+ keyName = keyName.toUpperCase();
}
- event.synthesizeKey(keyCode, modifiers, window);
+ event.synthesizeKey(keyName, modifiers, window);
};
/**
* Focus element and, if a textual input field and no previous selection
* state exists, move the caret to the end of the input field.
*
* @param {Element} element
* Element to focus.