Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /*
2 * Copyright 2007-2009 WebDriver committers
3 * Copyright 2007-2009 Google Inc.
4 * Portions copyright 2012 Software Freedom Conservancy
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
20 var type = function(doc, element, text, releaseModifiers,
21 opt_keysState) {
23 var currentTextLength = element.value ? element.value.length : 0;
24 element.selectionStart = currentTextLength;
25 element.selectionEnd = currentTextLength;
27 // For consistency between native and synthesized events, convert common
28 // escape sequences to their Key enum aliases.
29 text = text.replace(new RegExp('\b', 'g'), '\uE003'). // DOM_VK_BACK_SPACE
30 replace(/\t/g, '\uE004'). // DOM_VK_TAB
31 replace(/(\r\n|\n|\r)/g, '\uE006'); // DOM_VK_RETURN
33 var controlKey = false;
34 var shiftKey = false;
35 var altKey = false;
36 var metaKey = false;
37 if (opt_keysState) {
38 controlKey = opt_keysState.control;
39 shiftKey = opt_keysState.shiftKey;
40 altKey = opt_keysState.alt;
41 metaKey = opt_keysState.meta;
42 }
44 shiftCount = 0;
46 var upper = text.toUpperCase();
48 for (var i = 0; i < text.length; i++) {
49 var c = text.charAt(i);
51 // NULL key: reset modifier key states, and continue
53 if (c == '\uE000') {
54 if (controlKey) {
55 var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_CONTROL;
56 keyEvent(doc, element, "keyup", kCode, 0,
57 controlKey = false, shiftKey, altKey, metaKey, false);
58 }
60 if (shiftKey) {
61 var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_SHIFT;
62 keyEvent(doc, element, "keyup", kCode, 0,
63 controlKey, shiftKey = false, altKey, metaKey, false);
64 }
66 if (altKey) {
67 var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_ALT;
68 keyEvent(doc, element, "keyup", kCode, 0,
69 controlKey, shiftKey, altKey = false, metaKey, false);
70 }
72 if (metaKey) {
73 var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_META;
74 keyEvent(doc, element, "keyup", kCode, 0,
75 controlKey, shiftKey, altKey, metaKey = false, false);
76 }
78 continue;
79 }
81 // otherwise decode keyCode, charCode, modifiers ...
83 var modifierEvent = "";
84 var charCode = 0;
85 var keyCode = 0;
87 if (c == '\uE001') {
88 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_CANCEL;
89 } else if (c == '\uE002') {
90 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_HELP;
91 } else if (c == '\uE003') {
92 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_BACK_SPACE;
93 } else if (c == '\uE004') {
94 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_TAB;
95 } else if (c == '\uE005') {
96 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_CLEAR;
97 } else if (c == '\uE006' || c == '\uE007') {
98 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_RETURN;
99 } else if (c == '\uE008') {
100 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_SHIFT;
101 shiftKey = !shiftKey;
102 modifierEvent = shiftKey ? "keydown" : "keyup";
103 } else if (c == '\uE009') {
104 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_CONTROL;
105 controlKey = !controlKey;
106 modifierEvent = controlKey ? "keydown" : "keyup";
107 } else if (c == '\uE00A') {
108 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_ALT;
109 altKey = !altKey;
110 modifierEvent = altKey ? "keydown" : "keyup";
111 } else if (c == '\uE03D') {
112 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_META;
113 metaKey = !metaKey;
114 modifierEvent = metaKey ? "keydown" : "keyup";
115 } else if (c == '\uE00B') {
116 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_PAUSE;
117 } else if (c == '\uE00C') {
118 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_ESCAPE;
119 } else if (c == '\uE00D') {
120 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_SPACE;
121 keyCode = charCode = ' '.charCodeAt(0); // printable
122 } else if (c == '\uE00E') {
123 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_PAGE_UP;
124 } else if (c == '\uE00F') {
125 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_PAGE_DOWN;
126 } else if (c == '\uE010') {
127 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_END;
128 } else if (c == '\uE011') {
129 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_HOME;
130 } else if (c == '\uE012') {
131 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_LEFT;
132 } else if (c == '\uE013') {
133 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_UP;
134 } else if (c == '\uE014') {
135 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_RIGHT;
136 } else if (c == '\uE015') {
137 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_DOWN;
138 } else if (c == '\uE016') {
139 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_INSERT;
140 } else if (c == '\uE017') {
141 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_DELETE;
142 } else if (c == '\uE018') {
143 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_SEMICOLON;
144 charCode = ';'.charCodeAt(0);
145 } else if (c == '\uE019') {
146 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_EQUALS;
147 charCode = '='.charCodeAt(0);
148 } else if (c == '\uE01A') {
149 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_NUMPAD0;
150 charCode = '0'.charCodeAt(0);
151 } else if (c == '\uE01B') {
152 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_NUMPAD1;
153 charCode = '1'.charCodeAt(0);
154 } else if (c == '\uE01C') {
155 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_NUMPAD2;
156 charCode = '2'.charCodeAt(0);
157 } else if (c == '\uE01D') {
158 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_NUMPAD3;
159 charCode = '3'.charCodeAt(0);
160 } else if (c == '\uE01E') {
161 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_NUMPAD4;
162 charCode = '4'.charCodeAt(0);
163 } else if (c == '\uE01F') {
164 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_NUMPAD5;
165 charCode = '5'.charCodeAt(0);
166 } else if (c == '\uE020') {
167 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_NUMPAD6;
168 charCode = '6'.charCodeAt(0);
169 } else if (c == '\uE021') {
170 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_NUMPAD7;
171 charCode = '7'.charCodeAt(0);
172 } else if (c == '\uE022') {
173 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_NUMPAD8;
174 charCode = '8'.charCodeAt(0);
175 } else if (c == '\uE023') {
176 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_NUMPAD9;
177 charCode = '9'.charCodeAt(0);
178 } else if (c == '\uE024') {
179 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_MULTIPLY;
180 charCode = '*'.charCodeAt(0);
181 } else if (c == '\uE025') {
182 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_ADD;
183 charCode = '+'.charCodeAt(0);
184 } else if (c == '\uE026') {
185 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_SEPARATOR;
186 charCode = ','.charCodeAt(0);
187 } else if (c == '\uE027') {
188 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_SUBTRACT;
189 charCode = '-'.charCodeAt(0);
190 } else if (c == '\uE028') {
191 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_DECIMAL;
192 charCode = '.'.charCodeAt(0);
193 } else if (c == '\uE029') {
194 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_DIVIDE;
195 charCode = '/'.charCodeAt(0);
196 } else if (c == '\uE031') {
197 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_F1;
198 } else if (c == '\uE032') {
199 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_F2;
200 } else if (c == '\uE033') {
201 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_F3;
202 } else if (c == '\uE034') {
203 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_F4;
204 } else if (c == '\uE035') {
205 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_F5;
206 } else if (c == '\uE036') {
207 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_F6;
208 } else if (c == '\uE037') {
209 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_F7;
210 } else if (c == '\uE038') {
211 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_F8;
212 } else if (c == '\uE039') {
213 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_F9;
214 } else if (c == '\uE03A') {
215 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_F10;
216 } else if (c == '\uE03B') {
217 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_F11;
218 } else if (c == '\uE03C') {
219 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_F12;
220 } else if (c == ',' || c == '<') {
221 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_COMMA;
222 charCode = c.charCodeAt(0);
223 } else if (c == '.' || c == '>') {
224 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_PERIOD;
225 charCode = c.charCodeAt(0);
226 } else if (c == '/' || c == '?') {
227 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_SLASH;
228 charCode = text.charCodeAt(i);
229 } else if (c == '`' || c == '~') {
230 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_BACK_QUOTE;
231 charCode = c.charCodeAt(0);
232 } else if (c == '{' || c == '[') {
233 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_OPEN_BRACKET;
234 charCode = c.charCodeAt(0);
235 } else if (c == '\\' || c == '|') {
236 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_BACK_SLASH;
237 charCode = c.charCodeAt(0);
238 } else if (c == '}' || c == ']') {
239 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET;
240 charCode = c.charCodeAt(0);
241 } else if (c == '\'' || c == '"') {
242 keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_QUOTE;
243 charCode = c.charCodeAt(0);
244 } else {
245 keyCode = upper.charCodeAt(i);
246 charCode = text.charCodeAt(i);
247 }
249 // generate modifier key event if needed, and continue
251 if (modifierEvent) {
252 keyEvent(doc, element, modifierEvent, keyCode, 0,
253 controlKey, shiftKey, altKey, metaKey, false);
254 continue;
255 }
257 // otherwise, shift down if needed
259 var needsShift = false;
260 if (charCode) {
261 needsShift = /[A-Z\!\$\^\*\(\)\+\{\}\:\?\|~@#%&_"<>]/.test(c);
262 }
264 if (needsShift && !shiftKey) {
265 var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_SHIFT;
266 keyEvent(doc, element, "keydown", kCode, 0,
267 controlKey, true, altKey, metaKey, false);
268 shiftCount += 1;
269 }
271 // generate key[down/press/up] for key
273 var pressCode = keyCode;
274 if (charCode >= 32 && charCode < 127) {
275 pressCode = 0;
276 if (!needsShift && shiftKey && charCode > 32) {
277 // If typing a lowercase character key and the shiftKey is down, the
278 // charCode should be mapped to the shifted key value. This assumes
279 // a default 104 international keyboard layout.
280 if (charCode >= 97 && charCode <= 122) {
281 charCode = charCode + 65 - 97; // [a-z] -> [A-Z]
282 } else {
283 var mapFrom = '`1234567890-=[]\\;\',./';
284 var mapTo = '~!@#$%^&*()_+{}|:"<>?';
286 var value = String.fromCharCode(charCode).
287 replace(/([\[\\\.])/g, '\\$1');
288 var index = mapFrom.search(value);
289 if (index >= 0) {
290 charCode = mapTo.charCodeAt(index);
291 }
292 }
293 }
294 }
296 var accepted =
297 keyEvent(doc, element, "keydown", keyCode, 0,
298 controlKey, needsShift || shiftKey, altKey, metaKey, false);
300 keyEvent(doc, element, "keypress", pressCode, charCode,
301 controlKey, needsShift || shiftKey, altKey, metaKey, !accepted);
303 keyEvent(doc, element, "keyup", keyCode, 0,
304 controlKey, needsShift || shiftKey, altKey, metaKey, false);
306 // shift up if needed
308 if (needsShift && !shiftKey) {
309 var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_SHIFT;
310 keyEvent(doc, element, "keyup", kCode, 0,
311 controlKey, false, altKey, metaKey, false);
312 }
313 }
315 // exit cleanup: keyup active modifier keys
317 if (controlKey && releaseModifiers) {
318 var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_CONTROL;
319 keyEvent(doc, element, "keyup", kCode, 0,
320 controlKey = false, shiftKey, altKey, metaKey, false);
321 }
323 if (shiftKey && releaseModifiers) {
324 var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_SHIFT;
325 keyEvent(doc, element, "keyup", kCode, 0,
326 controlKey, shiftKey = false, altKey, metaKey, false);
327 }
329 if (altKey && releaseModifiers) {
330 var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_ALT;
331 keyEvent(doc, element, "keyup", kCode, 0,
332 controlKey, shiftKey, altKey = false, metaKey, false);
333 }
335 if (metaKey && releaseModifiers) {
336 var kCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_META;
337 keyEvent(doc, element, "keyup", kCode, 0,
338 controlKey, shiftKey, altKey, metaKey = false, false);
339 }
341 return {
342 shiftKey: shiftKey,
343 alt: altKey,
344 meta: metaKey,
345 control: controlKey
346 };
347 };
350 var keyEvent = function(doc, element, type, keyCode, charCode,
351 controlState, shiftState, altState, metaState,
352 shouldPreventDefault) {
353 var preventDefault = shouldPreventDefault == undefined ? false
354 : shouldPreventDefault;
356 var keyboardEvent = doc.createEvent("KeyEvents");
357 var currentView = doc.defaultView;
359 keyboardEvent.initKeyEvent(
360 type, // in DOMString typeArg,
361 true, // in boolean canBubbleArg
362 true, // in boolean cancelableArg
363 currentView, // in nsIDOMAbstractView viewArg
364 controlState, // in boolean ctrlKeyArg
365 altState, // in boolean altKeyArg
366 shiftState, // in boolean shiftKeyArg
367 metaState, // in boolean metaKeyArg
368 keyCode, // in unsigned long keyCodeArg
369 charCode); // in unsigned long charCodeArg
371 if (preventDefault) {
372 keyboardEvent.preventDefault();
373 }
375 var win = doc.defaultView;
376 var domUtil = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
377 .getInterface(Components.interfaces.nsIDOMWindowUtils);
378 return domUtil.dispatchDOMEventViaPresShell(element, keyboardEvent, true);
379 };