# lib/goog/events/keycodes.js

    1// Copyright 2006 The Closure Library Authors. All Rights Reserved.2//3// Licensed under the Apache License, Version 2.0 (the "License");4// you may not use this file except in compliance with the License.5// You may obtain a copy of the License at6//7//      http://www.apache.org/licenses/LICENSE-2.08//9// Unless required by applicable law or agreed to in writing, software10// distributed under the License is distributed on an "AS-IS" BASIS,11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12// See the License for the specific language governing permissions and13// limitations under the License.1415/**16 * @fileoverview Constant declarations for common key codes.17 *18 * @author eae@google.com (Emil A Eklund)19 * @see ../demos/keyhandler.html20 */2122goog.provide('goog.events.KeyCodes');2324goog.require('goog.userAgent');252627/**28 * Key codes for common characters.29 *30 * This list is not localized and therefore some of the key codes are not31 * correct for non US keyboard layouts. See comments below.32 *33 * @enum {number}34 */35goog.events.KeyCodes = {36  WIN_KEY_FF_LINUX: 0,37  MAC_ENTER: 3,38  BACKSPACE: 8,39  TAB: 9,40  NUM_CENTER: 12,  // NUMLOCK on FF/Safari Mac41  ENTER: 13,42  SHIFT: 16,43  CTRL: 17,44  ALT: 18,45  PAUSE: 19,46  CAPS_LOCK: 20,47  ESC: 27,48  SPACE: 32,49  PAGE_UP: 33,     // also NUM_NORTH_EAST50  PAGE_DOWN: 34,   // also NUM_SOUTH_EAST51  END: 35,         // also NUM_SOUTH_WEST52  HOME: 36,        // also NUM_NORTH_WEST53  LEFT: 37,        // also NUM_WEST54  UP: 38,          // also NUM_NORTH55  RIGHT: 39,       // also NUM_EAST56  DOWN: 40,        // also NUM_SOUTH57  PRINT_SCREEN: 44,58  INSERT: 45,      // also NUM_INSERT59  DELETE: 46,      // also NUM_DELETE60  ZERO: 48,61  ONE: 49,62  TWO: 50,63  THREE: 51,64  FOUR: 52,65  FIVE: 53,66  SIX: 54,67  SEVEN: 55,68  EIGHT: 56,69  NINE: 57,70  FF_SEMICOLON: 59, // Firefox (Gecko) fires this for semicolon instead of 18671  FF_EQUALS: 61, // Firefox (Gecko) fires this for equals instead of 18772  FF_DASH: 173, // Firefox (Gecko) fires this for dash instead of 18973  QUESTION_MARK: 63, // needs localization74  A: 65,75  B: 66,76  C: 67,77  D: 68,78  E: 69,79  F: 70,80  G: 71,81  H: 72,82  I: 73,83  J: 74,84  K: 75,85  L: 76,86  M: 77,87  N: 78,88  O: 79,89  P: 80,90  Q: 81,91  R: 82,92  S: 83,93  T: 84,94  U: 85,95  V: 86,96  W: 87,97  X: 88,98  Y: 89,99  Z: 90,100  META: 91, // WIN_KEY_LEFT101  WIN_KEY_RIGHT: 92,102  CONTEXT_MENU: 93,103  NUM_ZERO: 96,104  NUM_ONE: 97,105  NUM_TWO: 98,106  NUM_THREE: 99,107  NUM_FOUR: 100,108  NUM_FIVE: 101,109  NUM_SIX: 102,110  NUM_SEVEN: 103,111  NUM_EIGHT: 104,112  NUM_NINE: 105,113  NUM_MULTIPLY: 106,114  NUM_PLUS: 107,115  NUM_MINUS: 109,116  NUM_PERIOD: 110,117  NUM_DIVISION: 111,118  F1: 112,119  F2: 113,120  F3: 114,121  F4: 115,122  F5: 116,123  F6: 117,124  F7: 118,125  F8: 119,126  F9: 120,127  F10: 121,128  F11: 122,129  F12: 123,130  NUMLOCK: 144,131  SCROLL_LOCK: 145,132133  // OS-specific media keys like volume controls and browser controls.134  FIRST_MEDIA_KEY: 166,135  LAST_MEDIA_KEY: 183,136137  SEMICOLON: 186,            // needs localization138  DASH: 189,                 // needs localization139  EQUALS: 187,               // needs localization140  COMMA: 188,                // needs localization141  PERIOD: 190,               // needs localization142  SLASH: 191,                // needs localization143  APOSTROPHE: 192,           // needs localization144  TILDE: 192,                // needs localization145  SINGLE_QUOTE: 222,         // needs localization146  OPEN_SQUARE_BRACKET: 219,  // needs localization147  BACKSLASH: 220,            // needs localization148  CLOSE_SQUARE_BRACKET: 221, // needs localization149  WIN_KEY: 224,150  MAC_FF_META: 224, // Firefox (Gecko) fires this for the meta key instead of 91151  MAC_WK_CMD_LEFT: 91,  // WebKit Left Command key fired, same as META152  MAC_WK_CMD_RIGHT: 93, // WebKit Right Command key fired, different from META153  WIN_IME: 229,154155  // We've seen users whose machines fire this keycode at regular one156  // second intervals. The common thread among these users is that157  // they're all using Dell Inspiron laptops, so we suspect that this158  // indicates a hardware/bios problem.159  // http://en.community.dell.com/support-forums/laptop/f/3518/p/19285957/19523128.aspx160  PHANTOM: 255161};162163164/**165 * Returns true if the event contains a text modifying key.166 * @param {goog.events.BrowserEvent} e A key event.167 * @return {boolean} Whether it's a text modifying key.168 */169goog.events.KeyCodes.isTextModifyingKeyEvent = function(e) {170  if (e.altKey && !e.ctrlKey ||171      e.metaKey ||172      // Function keys don't generate text173      e.keyCode >= goog.events.KeyCodes.F1 &&174      e.keyCode <= goog.events.KeyCodes.F12) {175    return false;176  }177178  // The following keys are quite harmless, even in combination with179  // CTRL, ALT or SHIFT.180  switch (e.keyCode) {181    case goog.events.KeyCodes.ALT:182    case goog.events.KeyCodes.CAPS_LOCK:183    case goog.events.KeyCodes.CONTEXT_MENU:184    case goog.events.KeyCodes.CTRL:185    case goog.events.KeyCodes.DOWN:186    case goog.events.KeyCodes.END:187    case goog.events.KeyCodes.ESC:188    case goog.events.KeyCodes.HOME:189    case goog.events.KeyCodes.INSERT:190    case goog.events.KeyCodes.LEFT:191    case goog.events.KeyCodes.MAC_FF_META:192    case goog.events.KeyCodes.META:193    case goog.events.KeyCodes.NUMLOCK:194    case goog.events.KeyCodes.NUM_CENTER:195    case goog.events.KeyCodes.PAGE_DOWN:196    case goog.events.KeyCodes.PAGE_UP:197    case goog.events.KeyCodes.PAUSE:198    case goog.events.KeyCodes.PHANTOM:199    case goog.events.KeyCodes.PRINT_SCREEN:200    case goog.events.KeyCodes.RIGHT:201    case goog.events.KeyCodes.SCROLL_LOCK:202    case goog.events.KeyCodes.SHIFT:203    case goog.events.KeyCodes.UP:204    case goog.events.KeyCodes.WIN_KEY:205    case goog.events.KeyCodes.WIN_KEY_RIGHT:206      return false;207    case goog.events.KeyCodes.WIN_KEY_FF_LINUX:208      return !goog.userAgent.GECKO;209    default:210      return e.keyCode < goog.events.KeyCodes.FIRST_MEDIA_KEY ||211          e.keyCode > goog.events.KeyCodes.LAST_MEDIA_KEY;212  }213};214215216/**217 * Returns true if the key fires a keypress event in the current browser.218 *219 * Accoridng to MSDN [1] IE only fires keypress events for the following keys:220 * - Letters: A - Z (uppercase and lowercase)221 * - Numerals: 0 - 9222 * - Symbols: ! @ # $ % ^ & * ( ) _ - + = < [ ] { } , . / ? \ | ' ` " ~223 * - System: ESC, SPACEBAR, ENTER224 *225 * That's not entirely correct though, for instance there's no distinction226 * between upper and lower case letters.227 *228 * [1] http://msdn2.microsoft.com/en-us/library/ms536939(VS.85).aspx)229 *230 * Safari is similar to IE, but does not fire keypress for ESC.231 *232 * Additionally, IE6 does not fire keydown or keypress events for letters when233 * the control or alt keys are held down and the shift key is not. IE7 does234 * fire keydown in these cases, though, but not keypress.235 *236 * @param {number} keyCode A key code.237 * @param {number=} opt_heldKeyCode Key code of a currently-held key.238 * @param {boolean=} opt_shiftKey Whether the shift key is held down.239 * @param {boolean=} opt_ctrlKey Whether the control key is held down.240 * @param {boolean=} opt_altKey Whether the alt key is held down.241 * @return {boolean} Whether it's a key that fires a keypress event.242 */243goog.events.KeyCodes.firesKeyPressEvent = function(keyCode, opt_heldKeyCode,244    opt_shiftKey, opt_ctrlKey, opt_altKey) {245  if (!goog.userAgent.IE &&246      !(goog.userAgent.WEBKIT && goog.userAgent.isVersionOrHigher('525'))) {247    return true;248  }249250  if (goog.userAgent.MAC && opt_altKey) {251    return goog.events.KeyCodes.isCharacterKey(keyCode);252  }253254  // Alt but not AltGr which is represented as Alt+Ctrl.255  if (opt_altKey && !opt_ctrlKey) {256    return false;257  }258259  // Saves Ctrl or Alt + key for IE and WebKit 525+, which won't fire keypress.260  // Non-IE browsers and WebKit prior to 525 won't get this far so no need to261  // check the user agent.262  if (goog.isNumber(opt_heldKeyCode)) {263    opt_heldKeyCode = goog.events.KeyCodes.normalizeKeyCode(opt_heldKeyCode);264  }265  if (!opt_shiftKey &&266      (opt_heldKeyCode == goog.events.KeyCodes.CTRL ||267       opt_heldKeyCode == goog.events.KeyCodes.ALT ||268       goog.userAgent.MAC &&269       opt_heldKeyCode == goog.events.KeyCodes.META)) {270    return false;271  }272273  // Some keys with Ctrl/Shift do not issue keypress in WEBKIT.274  if (goog.userAgent.WEBKIT && opt_ctrlKey && opt_shiftKey) {275    switch (keyCode) {276      case goog.events.KeyCodes.BACKSLASH:277      case goog.events.KeyCodes.OPEN_SQUARE_BRACKET:278      case goog.events.KeyCodes.CLOSE_SQUARE_BRACKET:279      case goog.events.KeyCodes.TILDE:280      case goog.events.KeyCodes.SEMICOLON:281      case goog.events.KeyCodes.DASH:282      case goog.events.KeyCodes.EQUALS:283      case goog.events.KeyCodes.COMMA:284      case goog.events.KeyCodes.PERIOD:285      case goog.events.KeyCodes.SLASH:286      case goog.events.KeyCodes.APOSTROPHE:287      case goog.events.KeyCodes.SINGLE_QUOTE:288        return false;289    }290  }291292  // When Ctrl+<somekey> is held in IE, it only fires a keypress once, but it293  // continues to fire keydown events as the event repeats.294  if (goog.userAgent.IE && opt_ctrlKey && opt_heldKeyCode == keyCode) {295    return false;296  }297298  switch (keyCode) {299    case goog.events.KeyCodes.ENTER:300      return true;301    case goog.events.KeyCodes.ESC:302      return !goog.userAgent.WEBKIT;303  }304305  return goog.events.KeyCodes.isCharacterKey(keyCode);306};307308309/**310 * Returns true if the key produces a character.311 * This does not cover characters on non-US keyboards (Russian, Hebrew, etc.).312 *313 * @param {number} keyCode A key code.314 * @return {boolean} Whether it's a character key.315 */316goog.events.KeyCodes.isCharacterKey = function(keyCode) {317  if (keyCode >= goog.events.KeyCodes.ZERO &&318      keyCode <= goog.events.KeyCodes.NINE) {319    return true;320  }321322  if (keyCode >= goog.events.KeyCodes.NUM_ZERO &&323      keyCode <= goog.events.KeyCodes.NUM_MULTIPLY) {324    return true;325  }326327  if (keyCode >= goog.events.KeyCodes.A &&328      keyCode <= goog.events.KeyCodes.Z) {329    return true;330  }331332  // Safari sends zero key code for non-latin characters.333  if (goog.userAgent.WEBKIT && keyCode == 0) {334    return true;335  }336337  switch (keyCode) {338    case goog.events.KeyCodes.SPACE:339    case goog.events.KeyCodes.QUESTION_MARK:340    case goog.events.KeyCodes.NUM_PLUS:341    case goog.events.KeyCodes.NUM_MINUS:342    case goog.events.KeyCodes.NUM_PERIOD:343    case goog.events.KeyCodes.NUM_DIVISION:344    case goog.events.KeyCodes.SEMICOLON:345    case goog.events.KeyCodes.FF_SEMICOLON:346    case goog.events.KeyCodes.DASH:347    case goog.events.KeyCodes.EQUALS:348    case goog.events.KeyCodes.FF_EQUALS:349    case goog.events.KeyCodes.COMMA:350    case goog.events.KeyCodes.PERIOD:351    case goog.events.KeyCodes.SLASH:352    case goog.events.KeyCodes.APOSTROPHE:353    case goog.events.KeyCodes.SINGLE_QUOTE:354    case goog.events.KeyCodes.OPEN_SQUARE_BRACKET:355    case goog.events.KeyCodes.BACKSLASH:356    case goog.events.KeyCodes.CLOSE_SQUARE_BRACKET:357      return true;358    default:359      return false;360  }361};362363364/**365 * Normalizes key codes from OS/Browser-specific value to the general one.366 * @param {number} keyCode The native key code.367 * @return {number} The normalized key code.368 */369goog.events.KeyCodes.normalizeKeyCode = function(keyCode) {370  if (goog.userAgent.GECKO) {371    return goog.events.KeyCodes.normalizeGeckoKeyCode(keyCode);372  } else if (goog.userAgent.MAC && goog.userAgent.WEBKIT) {373    return goog.events.KeyCodes.normalizeMacWebKitKeyCode(keyCode);374  } else {375    return keyCode;376  }377};378379380/**381 * Normalizes key codes from their Gecko-specific value to the general one.382 * @param {number} keyCode The native key code.383 * @return {number} The normalized key code.384 */385goog.events.KeyCodes.normalizeGeckoKeyCode = function(keyCode) {386  switch (keyCode) {387    case goog.events.KeyCodes.FF_EQUALS:388      return goog.events.KeyCodes.EQUALS;389    case goog.events.KeyCodes.FF_SEMICOLON:390      return goog.events.KeyCodes.SEMICOLON;391    case goog.events.KeyCodes.FF_DASH:392      return goog.events.KeyCodes.DASH;393    case goog.events.KeyCodes.MAC_FF_META:394      return goog.events.KeyCodes.META;395    case goog.events.KeyCodes.WIN_KEY_FF_LINUX:396      return goog.events.KeyCodes.WIN_KEY;397    default:398      return keyCode;399  }400};401402403/**404 * Normalizes key codes from their Mac WebKit-specific value to the general one.405 * @param {number} keyCode The native key code.406 * @return {number} The normalized key code.407 */408goog.events.KeyCodes.normalizeMacWebKitKeyCode = function(keyCode) {409  switch (keyCode) {410    case goog.events.KeyCodes.MAC_WK_CMD_RIGHT:  // 93411      return goog.events.KeyCodes.META;          // 91412    default:413      return keyCode;414  }415};