зеркало из https://github.com/mozilla/gecko-dev.git
168 строки
4.5 KiB
JavaScript
168 строки
4.5 KiB
JavaScript
/*
|
|
* Copyright 2007-2009 WebDriver committers
|
|
* Copyright 2007-2009 Google Inc.
|
|
* Portions copyright 2012 Software Freedom Conservancy
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
|
|
|
Cu.import("chrome://marionette/content/error.js");
|
|
|
|
var loader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
|
|
.getService(Ci.mozIJSSubScriptLoader);
|
|
|
|
var utils = {};
|
|
loader.loadSubScript("chrome://marionette/content/EventUtils.js", utils);
|
|
loader.loadSubScript("chrome://marionette/content/ChromeUtils.js", utils);
|
|
|
|
var keyModifierNames = {
|
|
"VK_SHIFT": 'shiftKey',
|
|
"VK_CONTROL": 'ctrlKey',
|
|
"VK_ALT": 'altKey',
|
|
"VK_META": 'metaKey'
|
|
};
|
|
|
|
var keyCodes = {
|
|
'\uE001': "VK_CANCEL",
|
|
'\uE002': "VK_HELP",
|
|
'\uE003': "VK_BACK_SPACE",
|
|
'\uE004': "VK_TAB",
|
|
'\uE005': "VK_CLEAR",
|
|
'\uE006': "VK_RETURN",
|
|
'\uE007': "VK_RETURN",
|
|
'\uE008': "VK_SHIFT",
|
|
'\uE009': "VK_CONTROL",
|
|
'\uE00A': "VK_ALT",
|
|
'\uE03D': "VK_META",
|
|
'\uE00B': "VK_PAUSE",
|
|
'\uE00C': "VK_ESCAPE",
|
|
'\uE00D': "VK_SPACE", // printable
|
|
'\uE00E': "VK_PAGE_UP",
|
|
'\uE00F': "VK_PAGE_DOWN",
|
|
'\uE010': "VK_END",
|
|
'\uE011': "VK_HOME",
|
|
'\uE012': "VK_LEFT",
|
|
'\uE013': "VK_UP",
|
|
'\uE014': "VK_RIGHT",
|
|
'\uE015': "VK_DOWN",
|
|
'\uE016': "VK_INSERT",
|
|
'\uE017': "VK_DELETE",
|
|
'\uE018': "VK_SEMICOLON",
|
|
'\uE019': "VK_EQUALS",
|
|
'\uE01A': "VK_NUMPAD0",
|
|
'\uE01B': "VK_NUMPAD1",
|
|
'\uE01C': "VK_NUMPAD2",
|
|
'\uE01D': "VK_NUMPAD3",
|
|
'\uE01E': "VK_NUMPAD4",
|
|
'\uE01F': "VK_NUMPAD5",
|
|
'\uE020': "VK_NUMPAD6",
|
|
'\uE021': "VK_NUMPAD7",
|
|
'\uE022': "VK_NUMPAD8",
|
|
'\uE023': "VK_NUMPAD9",
|
|
'\uE024': "VK_MULTIPLY",
|
|
'\uE025': "VK_ADD",
|
|
'\uE026': "VK_SEPARATOR",
|
|
'\uE027': "VK_SUBTRACT",
|
|
'\uE028': "VK_DECIMAL",
|
|
'\uE029': "VK_DIVIDE",
|
|
'\uE031': "VK_F1",
|
|
'\uE032': "VK_F2",
|
|
'\uE033': "VK_F3",
|
|
'\uE034': "VK_F4",
|
|
'\uE035': "VK_F5",
|
|
'\uE036': "VK_F6",
|
|
'\uE037': "VK_F7",
|
|
'\uE038': "VK_F8",
|
|
'\uE039': "VK_F9",
|
|
'\uE03A': "VK_F10",
|
|
'\uE03B': "VK_F11",
|
|
'\uE03C': "VK_F12"
|
|
};
|
|
|
|
function getKeyCode (c) {
|
|
if (c in keyCodes) {
|
|
return keyCodes[c];
|
|
}
|
|
return c;
|
|
};
|
|
|
|
function sendKeyDown (keyToSend, modifiers, document) {
|
|
modifiers.type = "keydown";
|
|
sendSingleKey(keyToSend, modifiers, document);
|
|
if (["VK_SHIFT", "VK_CONTROL",
|
|
"VK_ALT", "VK_META"].indexOf(getKeyCode(keyToSend)) == -1) {
|
|
modifiers.type = "keypress";
|
|
sendSingleKey(keyToSend, modifiers, document);
|
|
}
|
|
delete modifiers.type;
|
|
}
|
|
|
|
function sendKeyUp (keyToSend, modifiers, document) {
|
|
modifiers.type = "keyup";
|
|
sendSingleKey(keyToSend, modifiers, document);
|
|
delete modifiers.type;
|
|
}
|
|
|
|
function sendSingleKey (keyToSend, modifiers, document) {
|
|
let keyCode = getKeyCode(keyToSend);
|
|
if (keyCode in keyModifierNames) {
|
|
let modName = keyModifierNames[keyCode];
|
|
modifiers[modName] = !modifiers[modName];
|
|
} else if (modifiers.shiftKey) {
|
|
keyCode = keyCode.toUpperCase();
|
|
}
|
|
utils.synthesizeKey(keyCode, modifiers, document);
|
|
}
|
|
|
|
/**
|
|
* 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} el
|
|
* Element to focus.
|
|
*/
|
|
function focusElement(el) {
|
|
let t = el.type;
|
|
if (t && (t == "text" || t == "textarea")) {
|
|
if (el.selectionEnd == 0) {
|
|
let len = el.value.length;
|
|
el.setSelectionRange(len, len);
|
|
}
|
|
}
|
|
el.focus();
|
|
}
|
|
|
|
function sendKeysToElement(document, element, keysToSend, successCallback, errorCallback, command_id, ignoreVisibility) {
|
|
if (ignoreVisibility || checkVisible(element)) {
|
|
focusElement(element);
|
|
|
|
let modifiers = {
|
|
shiftKey: false,
|
|
ctrlKey: false,
|
|
altKey: false,
|
|
metaKey: false
|
|
};
|
|
let value = keysToSend.join("");
|
|
for (var i = 0; i < value.length; i++) {
|
|
var c = value.charAt(i);
|
|
sendSingleKey(c, modifiers, document);
|
|
}
|
|
|
|
successCallback(command_id);
|
|
} else {
|
|
errorCallback(new ElementNotVisibleError("Element is not visible"), command_id);
|
|
}
|
|
};
|