testing/marionette/marionette-sendkeys.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

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 };

mercurial