Home | History | Annotate | Download | only in front_end
      1 /*
      2  * Copyright (C) 2009 Apple Inc. All rights reserved.
      3  * Copyright (C) 2009 Google Inc. All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *
      9  * 1.  Redistributions of source code must retain the above copyright
     10  *     notice, this list of conditions and the following disclaimer.
     11  * 2.  Redistributions in binary form must reproduce the above copyright
     12  *     notice, this list of conditions and the following disclaimer in the
     13  *     documentation and/or other materials provided with the distribution.
     14  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
     15  *     its contributors may be used to endorse or promote products derived
     16  *     from this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28  */
     29 
     30 /**
     31  * @constructor
     32  */
     33 WebInspector.KeyboardShortcut = function()
     34 {
     35 }
     36 
     37 /**
     38  * Constants for encoding modifier key set as a bit mask.
     39  * @see #_makeKeyFromCodeAndModifiers
     40  */
     41 WebInspector.KeyboardShortcut.Modifiers = {
     42     None: 0,   // Constant for empty modifiers set.
     43     Shift: 1,
     44     Ctrl: 2,
     45     Alt: 4,
     46     Meta: 8,   // Command key on Mac, Win key on other platforms.
     47     get CtrlOrMeta()
     48     {
     49         // "default" command/ctrl key for platform, Command on Mac, Ctrl on other platforms
     50         return WebInspector.isMac() ? this.Meta : this.Ctrl;
     51     }
     52 };
     53 
     54 /** @typedef {!{code: number, name: (string|!Object.<string, string>)}} */
     55 WebInspector.KeyboardShortcut.Key;
     56 
     57 /** @type {!Object.<string, !WebInspector.KeyboardShortcut.Key>} */
     58 WebInspector.KeyboardShortcut.Keys = {
     59     Backspace: { code: 8, name: "\u21a4" },
     60     Tab: { code: 9, name: { mac: "\u21e5", other: "Tab" } },
     61     Enter: { code: 13, name: { mac: "\u21a9", other: "Enter" } },
     62     Esc: { code: 27, name: { mac: "\u238b", other: "Esc" } },
     63     Space: { code: 32, name: "Space" },
     64     PageUp: { code: 33,  name: { mac: "\u21de", other: "PageUp" } },      // also NUM_NORTH_EAST
     65     PageDown: { code: 34, name: { mac: "\u21df", other: "PageDown" } },   // also NUM_SOUTH_EAST
     66     End: { code: 35, name: { mac: "\u2197", other: "End" } },             // also NUM_SOUTH_WEST
     67     Home: { code: 36, name: { mac: "\u2196", other: "Home" } },           // also NUM_NORTH_WEST
     68     Left: { code: 37, name: "\u2190" },           // also NUM_WEST
     69     Up: { code: 38, name: "\u2191" },             // also NUM_NORTH
     70     Right: { code: 39, name: "\u2192" },          // also NUM_EAST
     71     Down: { code: 40, name: "\u2193" },           // also NUM_SOUTH
     72     Delete: { code: 46, name: "Del" },
     73     Zero: { code: 48, name: "0" },
     74     F1: { code: 112, name: "F1" },
     75     F2: { code: 113, name: "F2" },
     76     F3: { code: 114, name: "F3" },
     77     F4: { code: 115, name: "F4" },
     78     F5: { code: 116, name: "F5" },
     79     F6: { code: 117, name: "F6" },
     80     F7: { code: 118, name: "F7" },
     81     F8: { code: 119, name: "F8" },
     82     F9: { code: 120, name: "F9" },
     83     F10: { code: 121, name: "F10" },
     84     F11: { code: 122, name: "F11" },
     85     F12: { code: 123, name: "F12" },
     86     Semicolon: { code: 186, name: ";" },
     87     Plus: { code: 187, name: "+" },
     88     Comma: { code: 188, name: "," },
     89     Minus: { code: 189, name: "-" },
     90     Period: { code: 190, name: "." },
     91     Slash: { code: 191, name: "/" },
     92     Apostrophe: { code: 192, name: "`" },
     93     Backslash: { code: 220, name: "\\" },
     94     SingleQuote: { code: 222, name: "\'" },
     95     H: { code: 72, name: "H" },
     96     Ctrl: { code: 17, name: "Ctrl" },
     97     Meta: { code: 91, name: "Meta" },
     98     Tilde: { code: 192, name: "Tilde" },
     99     get CtrlOrMeta()
    100     {
    101         // "default" command/ctrl key for platform, Command on Mac, Ctrl on other platforms
    102         return WebInspector.isMac() ? this.Meta : this.Ctrl;
    103     },
    104 };
    105 
    106 /**
    107  * Creates a number encoding keyCode in the lower 8 bits and modifiers mask in the higher 8 bits.
    108  * It is useful for matching pressed keys.
    109  *
    110  * @param {number|string} keyCode The code of the key, or a character "a-z" which is converted to a keyCode value.
    111  * @param {number=} modifiers Optional list of modifiers passed as additional paramerters.
    112  * @return {number}
    113  */
    114 WebInspector.KeyboardShortcut.makeKey = function(keyCode, modifiers)
    115 {
    116     if (typeof keyCode === "string")
    117         keyCode = keyCode.charCodeAt(0) - 32;
    118     modifiers = modifiers || WebInspector.KeyboardShortcut.Modifiers.None;
    119     return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyCode, modifiers);
    120 }
    121 
    122 /**
    123  * @param {?KeyboardEvent} keyboardEvent
    124  * @return {number}
    125  */
    126 WebInspector.KeyboardShortcut.makeKeyFromEvent = function(keyboardEvent)
    127 {
    128     var modifiers = WebInspector.KeyboardShortcut.Modifiers.None;
    129     if (keyboardEvent.shiftKey)
    130         modifiers |= WebInspector.KeyboardShortcut.Modifiers.Shift;
    131     if (keyboardEvent.ctrlKey)
    132         modifiers |= WebInspector.KeyboardShortcut.Modifiers.Ctrl;
    133     if (keyboardEvent.altKey)
    134         modifiers |= WebInspector.KeyboardShortcut.Modifiers.Alt;
    135     if (keyboardEvent.metaKey)
    136         modifiers |= WebInspector.KeyboardShortcut.Modifiers.Meta;
    137     return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyboardEvent.keyCode, modifiers);
    138 }
    139 
    140 /**
    141  * @param {?KeyboardEvent} event
    142  * @return {boolean}
    143  */
    144 WebInspector.KeyboardShortcut.eventHasCtrlOrMeta = function(event)
    145 {
    146     return WebInspector.isMac() ? event.metaKey && !event.ctrlKey : event.ctrlKey && !event.metaKey;
    147 }
    148 
    149 /**
    150  * @param {?Event} event
    151  * @return {boolean}
    152  */
    153 WebInspector.KeyboardShortcut.hasNoModifiers = function(event)
    154 {
    155     return !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey;
    156 }
    157 
    158 /** @typedef {!{key: number, name: string}} */
    159 WebInspector.KeyboardShortcut.Descriptor;
    160 
    161 /**
    162  * @param {string|!WebInspector.KeyboardShortcut.Key} key
    163  * @param {number=} modifiers
    164  * @return {!WebInspector.KeyboardShortcut.Descriptor}
    165  */
    166 WebInspector.KeyboardShortcut.makeDescriptor = function(key, modifiers)
    167 {
    168     return {
    169         key: WebInspector.KeyboardShortcut.makeKey(typeof key === "string" ? key : key.code, modifiers),
    170         name: WebInspector.KeyboardShortcut.shortcutToString(key, modifiers)
    171     };
    172 }
    173 
    174 /**
    175  * @param {string|!WebInspector.KeyboardShortcut.Key} key
    176  * @param {number=} modifiers
    177  * @return {string}
    178  */
    179 WebInspector.KeyboardShortcut.shortcutToString = function(key, modifiers)
    180 {
    181     return WebInspector.KeyboardShortcut._modifiersToString(modifiers) + WebInspector.KeyboardShortcut._keyName(key);
    182 }
    183 
    184 /**
    185  * @param {string|!WebInspector.KeyboardShortcut.Key} key
    186  * @return {string}
    187  */
    188 WebInspector.KeyboardShortcut._keyName = function(key)
    189 {
    190     if (typeof key === "string")
    191         return key.toUpperCase();
    192     if (typeof key.name === "string")
    193         return key.name;
    194     return key.name[WebInspector.platform()] || key.name.other || '';
    195 }
    196 
    197 /**
    198  * @param {number} keyCode
    199  * @param {?number} modifiers
    200  * @return {number}
    201  */
    202 WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers = function(keyCode, modifiers)
    203 {
    204     return (keyCode & 255) | (modifiers << 8);
    205 };
    206 
    207 /**
    208  * @param {number|undefined} modifiers
    209  * @return {string}
    210  */
    211 WebInspector.KeyboardShortcut._modifiersToString = function(modifiers)
    212 {
    213     const cmdKey = "\u2318";
    214     const optKey = "\u2325";
    215     const shiftKey = "\u21e7";
    216     const ctrlKey = "\u2303";
    217 
    218     var isMac = WebInspector.isMac();
    219     var res = "";
    220     if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Ctrl)
    221         res += isMac ? ctrlKey : "Ctrl + ";
    222     if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Alt)
    223         res += isMac ? optKey : "Alt + ";
    224     if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Shift)
    225         res += isMac ? shiftKey : "Shift + ";
    226     if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Meta)
    227         res += isMac ? cmdKey : "Win + ";
    228 
    229     return res;
    230 };
    231 
    232 WebInspector.KeyboardShortcut.SelectAll = WebInspector.KeyboardShortcut.makeKey("a", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta);
    233