• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
33WebInspector.KeyboardShortcut = function()
34{
35}
36
37/**
38 * Constants for encoding modifier key set as a bit mask.
39 * @see #_makeKeyFromCodeAndModifiers
40 */
41WebInspector.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>)}} */
55WebInspector.KeyboardShortcut.Key;
56
57/** @type {!Object.<string, !WebInspector.KeyboardShortcut.Key>} */
58WebInspector.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 */
114WebInspector.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 */
126WebInspector.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 */
144WebInspector.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 */
153WebInspector.KeyboardShortcut.hasNoModifiers = function(event)
154{
155    return !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey;
156}
157
158/** @typedef {!{key: number, name: string}} */
159WebInspector.KeyboardShortcut.Descriptor;
160
161/**
162 * @param {string|!WebInspector.KeyboardShortcut.Key} key
163 * @param {number=} modifiers
164 * @return {!WebInspector.KeyboardShortcut.Descriptor}
165 */
166WebInspector.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 */
179WebInspector.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 */
188WebInspector.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 */
202WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers = function(keyCode, modifiers)
203{
204    return (keyCode & 255) | (modifiers << 8);
205};
206
207/**
208 * @param {number|undefined} modifiers
209 * @return {string}
210 */
211WebInspector.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
232WebInspector.KeyboardShortcut.SelectAll = WebInspector.KeyboardShortcut.makeKey("a", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta);
233