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