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     SingleQuote: { code: 222, name: "\'" },
     94     H: { code: 72, name: "H" },
     95     Ctrl: { code: 17, name: "Ctrl" },
     96     Meta: { code: 91, name: "Meta" },
     97 };
     98 
     99 /**
    100  * Creates a number encoding keyCode in the lower 8 bits and modifiers mask in the higher 8 bits.
    101  * It is useful for matching pressed keys.
    102  *
    103  * @param {number|string} keyCode The Code of the key, or a character "a-z" which is converted to a keyCode value.
    104  * @param {number=} modifiers Optional list of modifiers passed as additional paramerters.
    105  * @return {number}
    106  */
    107 WebInspector.KeyboardShortcut.makeKey = function(keyCode, modifiers)
    108 {
    109     if (typeof keyCode === "string")
    110         keyCode = keyCode.charCodeAt(0) - 32;
    111     modifiers = modifiers || WebInspector.KeyboardShortcut.Modifiers.None;
    112     return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyCode, modifiers);
    113 }
    114 
    115 /**
    116  * @param {KeyboardEvent} keyboardEvent
    117  * @return {number}
    118  */
    119 WebInspector.KeyboardShortcut.makeKeyFromEvent = function(keyboardEvent)
    120 {
    121     var modifiers = WebInspector.KeyboardShortcut.Modifiers.None;
    122     if (keyboardEvent.shiftKey)
    123         modifiers |= WebInspector.KeyboardShortcut.Modifiers.Shift;
    124     if (keyboardEvent.ctrlKey)
    125         modifiers |= WebInspector.KeyboardShortcut.Modifiers.Ctrl;
    126     if (keyboardEvent.altKey)
    127         modifiers |= WebInspector.KeyboardShortcut.Modifiers.Alt;
    128     if (keyboardEvent.metaKey)
    129         modifiers |= WebInspector.KeyboardShortcut.Modifiers.Meta;
    130     return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyboardEvent.keyCode, modifiers);
    131 }
    132 
    133 /**
    134  * @param {KeyboardEvent} event
    135  * @return {boolean}
    136  */
    137 WebInspector.KeyboardShortcut.eventHasCtrlOrMeta = function(event)
    138 {
    139     return WebInspector.isMac() ? event.metaKey && !event.ctrlKey : event.ctrlKey && !event.metaKey;
    140 }
    141 
    142 /**
    143  * @param {Event} event
    144  * @return {boolean}
    145  */
    146 WebInspector.KeyboardShortcut.hasNoModifiers = function(event)
    147 {
    148     return !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey;
    149 }
    150 
    151 /** @typedef {{key: number, name: string}} */
    152 WebInspector.KeyboardShortcut.Descriptor;
    153 
    154 /**
    155  * @param {string|WebInspector.KeyboardShortcut.Key} key
    156  * @param {number=} modifiers
    157  * @return {WebInspector.KeyboardShortcut.Descriptor}
    158  */
    159 WebInspector.KeyboardShortcut.makeDescriptor = function(key, modifiers)
    160 {
    161     return {
    162         key: WebInspector.KeyboardShortcut.makeKey(typeof key === "string" ? key : key.code, modifiers),
    163         name: WebInspector.KeyboardShortcut.shortcutToString(key, modifiers)
    164     };
    165 }
    166 
    167 /**
    168  * @param {string|WebInspector.KeyboardShortcut.Key} key
    169  * @param {number=} modifiers
    170  * @return {string}
    171  */
    172 WebInspector.KeyboardShortcut.shortcutToString = function(key, modifiers)
    173 {
    174     return WebInspector.KeyboardShortcut._modifiersToString(modifiers) + WebInspector.KeyboardShortcut._keyName(key);
    175 }
    176 
    177 /**
    178  * @param {string|WebInspector.KeyboardShortcut.Key} key
    179  * @return {string}
    180  */
    181 WebInspector.KeyboardShortcut._keyName = function(key)
    182 {
    183     if (typeof key === "string")
    184         return key.toUpperCase();
    185     if (typeof key.name === "string")
    186         return key.name;
    187     return key.name[WebInspector.platform()] || key.name.other || '';
    188 }
    189 
    190 /**
    191  * @param {number} keyCode
    192  * @param {?number} modifiers
    193  * @return {number}
    194  */
    195 WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers = function(keyCode, modifiers)
    196 {
    197     return (keyCode & 255) | (modifiers << 8);
    198 };
    199 
    200 /**
    201  * @param {number|undefined} modifiers
    202  * @return {string}
    203  */
    204 WebInspector.KeyboardShortcut._modifiersToString = function(modifiers)
    205 {
    206     const cmdKey = "\u2318";
    207     const optKey = "\u2325";
    208     const shiftKey = "\u21e7";
    209     const ctrlKey = "\u2303";
    210 
    211     var isMac = WebInspector.isMac();
    212     var res = "";
    213     if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Ctrl)
    214         res += isMac ? ctrlKey : "Ctrl + ";
    215     if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Alt)
    216         res += isMac ? optKey : "Alt + ";
    217     if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Shift)
    218         res += isMac ? shiftKey : "Shift + ";
    219     if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Meta)
    220         res += isMac ? cmdKey : "Win + ";
    221 
    222     return res;
    223 };
    224 
    225 WebInspector.KeyboardShortcut.SelectAll = WebInspector.KeyboardShortcut.makeKey("a", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta);
    226