Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / Source / devtools / front_end / ui / KeyboardShortcut.js
blobba9f9596ab776eb38ac5a4e4731809659450172f
1 /*
2 * Copyright (C) 2009 Apple Inc. All rights reserved.
3 * Copyright (C) 2009 Google Inc. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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.
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.
30 /**
31 * @constructor
33 WebInspector.KeyboardShortcut = function()
37 /**
38 * Constants for encoding modifier key set as a bit mask.
39 * @see #_makeKeyFromCodeAndModifiers
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()
49 // "default" command/ctrl key for platform, Command on Mac, Ctrl on other platforms
50 return WebInspector.isMac() ? this.Meta : this.Ctrl;
52 get ShiftOrOption()
54 // Option on Mac, Shift on other platforms
55 return WebInspector.isMac() ? this.Alt : this.Shift;
59 /** @typedef {!{code: number, name: (string|!Object.<string, string>)}} */
60 WebInspector.KeyboardShortcut.Key;
62 /** @type {!Object.<string, !WebInspector.KeyboardShortcut.Key>} */
63 WebInspector.KeyboardShortcut.Keys = {
64 Backspace: { code: 8, name: "\u21a4" },
65 Tab: { code: 9, name: { mac: "\u21e5", other: "Tab" } },
66 Enter: { code: 13, name: { mac: "\u21a9", other: "Enter" } },
67 Shift: { code: 16, name: { mac: "\u21e7", other: "Shift" } },
68 Ctrl: { code: 17, name: "Ctrl" },
69 Esc: { code: 27, name: "Esc" },
70 Space: { code: 32, name: "Space" },
71 PageUp: { code: 33, name: { mac: "\u21de", other: "PageUp" } }, // also NUM_NORTH_EAST
72 PageDown: { code: 34, name: { mac: "\u21df", other: "PageDown" } }, // also NUM_SOUTH_EAST
73 End: { code: 35, name: { mac: "\u2197", other: "End" } }, // also NUM_SOUTH_WEST
74 Home: { code: 36, name: { mac: "\u2196", other: "Home" } }, // also NUM_NORTH_WEST
75 Left: { code: 37, name: "\u2190" }, // also NUM_WEST
76 Up: { code: 38, name: "\u2191" }, // also NUM_NORTH
77 Right: { code: 39, name: "\u2192" }, // also NUM_EAST
78 Down: { code: 40, name: "\u2193" }, // also NUM_SOUTH
79 Delete: { code: 46, name: "Del" },
80 Zero: { code: 48, name: "0" },
81 H: { code: 72, name: "H" },
82 Meta: { code: 91, name: "Meta" },
83 F1: { code: 112, name: "F1" },
84 F2: { code: 113, name: "F2" },
85 F3: { code: 114, name: "F3" },
86 F4: { code: 115, name: "F4" },
87 F5: { code: 116, name: "F5" },
88 F6: { code: 117, name: "F6" },
89 F7: { code: 118, name: "F7" },
90 F8: { code: 119, name: "F8" },
91 F9: { code: 120, name: "F9" },
92 F10: { code: 121, name: "F10" },
93 F11: { code: 122, name: "F11" },
94 F12: { code: 123, name: "F12" },
95 Semicolon: { code: 186, name: ";" },
96 NumpadPlus: { code: 107, name: "Numpad +" },
97 NumpadMinus: { code: 109, name: "Numpad -" },
98 Numpad0: { code: 96, name: "Numpad 0" },
99 Plus: { code: 187, name: "+" },
100 Comma: { code: 188, name: "," },
101 Minus: { code: 189, name: "-" },
102 Period: { code: 190, name: "." },
103 Slash: { code: 191, name: "/" },
104 QuestionMark: { code: 191, name: "?" },
105 Apostrophe: { code: 192, name: "`" },
106 Tilde: { code: 192, name: "Tilde" },
107 LeftSquareBracket: { code: 219, name: "[" },
108 RightSquareBracket: { code: 221, name: "]" },
109 Backslash: { code: 220, name: "\\" },
110 SingleQuote: { code: 222, name: "\'" },
111 get CtrlOrMeta()
113 // "default" command/ctrl key for platform, Command on Mac, Ctrl on other platforms
114 return WebInspector.isMac() ? this.Meta : this.Ctrl;
118 WebInspector.KeyboardShortcut.KeyBindings = {};
120 (function() {
121 for (var key in WebInspector.KeyboardShortcut.Keys) {
122 var descriptor = WebInspector.KeyboardShortcut.Keys[key];
123 if (typeof descriptor === "object" && descriptor["code"]) {
124 var name = typeof descriptor["name"] === "string" ? descriptor["name"] : key;
125 WebInspector.KeyboardShortcut.KeyBindings[name] = descriptor;
128 })();
131 * Creates a number encoding keyCode in the lower 8 bits and modifiers mask in the higher 8 bits.
132 * It is useful for matching pressed keys.
134 * @param {number|string} keyCode The code of the key, or a character "a-z" which is converted to a keyCode value.
135 * @param {number=} modifiers Optional list of modifiers passed as additional parameters.
136 * @return {number}
138 WebInspector.KeyboardShortcut.makeKey = function(keyCode, modifiers)
140 if (typeof keyCode === "string")
141 keyCode = keyCode.charCodeAt(0) - (/^[a-z]/.test(keyCode) ? 32 : 0);
142 modifiers = modifiers || WebInspector.KeyboardShortcut.Modifiers.None;
143 return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyCode, modifiers);
147 * @param {?KeyboardEvent} keyboardEvent
148 * @return {number}
150 WebInspector.KeyboardShortcut.makeKeyFromEvent = function(keyboardEvent)
152 var modifiers = WebInspector.KeyboardShortcut.Modifiers.None;
153 if (keyboardEvent.shiftKey)
154 modifiers |= WebInspector.KeyboardShortcut.Modifiers.Shift;
155 if (keyboardEvent.ctrlKey)
156 modifiers |= WebInspector.KeyboardShortcut.Modifiers.Ctrl;
157 if (keyboardEvent.altKey)
158 modifiers |= WebInspector.KeyboardShortcut.Modifiers.Alt;
159 if (keyboardEvent.metaKey)
160 modifiers |= WebInspector.KeyboardShortcut.Modifiers.Meta;
162 // Use either a real or a synthetic keyCode (for events originating from extensions).
163 var keyCode = keyboardEvent.keyCode || keyboardEvent["__keyCode"];
164 return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyCode, modifiers);
168 * @param {?KeyboardEvent} keyboardEvent
169 * @return {number}
171 WebInspector.KeyboardShortcut.makeKeyFromEventIgnoringModifiers = function(keyboardEvent)
173 var keyCode = keyboardEvent.keyCode || keyboardEvent["__keyCode"];
174 return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyCode, WebInspector.KeyboardShortcut.Modifiers.None);
178 * @param {(?KeyboardEvent|?MouseEvent)} event
179 * @return {boolean}
181 WebInspector.KeyboardShortcut.eventHasCtrlOrMeta = function(event)
183 return WebInspector.isMac() ? event.metaKey && !event.ctrlKey : event.ctrlKey && !event.metaKey;
187 * @param {!Event} event
188 * @return {boolean}
190 WebInspector.KeyboardShortcut.hasNoModifiers = function(event)
192 return !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey;
195 /** @typedef {!{key: number, name: string}} */
196 WebInspector.KeyboardShortcut.Descriptor;
199 * @param {string|!WebInspector.KeyboardShortcut.Key} key
200 * @param {number=} modifiers
201 * @return {!WebInspector.KeyboardShortcut.Descriptor}
203 WebInspector.KeyboardShortcut.makeDescriptor = function(key, modifiers)
205 return {
206 key: WebInspector.KeyboardShortcut.makeKey(typeof key === "string" ? key : key.code, modifiers),
207 name: WebInspector.KeyboardShortcut.shortcutToString(key, modifiers)
212 * @param {string} shortcut
213 * @return {?WebInspector.KeyboardShortcut.Descriptor}
215 WebInspector.KeyboardShortcut.makeDescriptorFromBindingShortcut = function(shortcut)
217 var parts = shortcut.split(/\+(?!$)/);
218 var modifiers = 0;
219 var keyString;
220 for (var i = 0; i < parts.length; ++i) {
221 if (typeof WebInspector.KeyboardShortcut.Modifiers[parts[i]] !== "undefined") {
222 modifiers |= WebInspector.KeyboardShortcut.Modifiers[parts[i]];
223 continue;
225 console.assert(i === parts.length - 1, "Only one key other than modifier is allowed in shortcut <" + shortcut + ">");
226 keyString = parts[i];
227 break;
229 console.assert(keyString, "Modifiers-only shortcuts are not allowed (encountered <" + shortcut + ">)");
230 if (!keyString)
231 return null;
233 var key = WebInspector.KeyboardShortcut.Keys[keyString] || WebInspector.KeyboardShortcut.KeyBindings[keyString];
234 if (key && key.shiftKey)
235 modifiers |= WebInspector.KeyboardShortcut.Modifiers.Shift;
236 return WebInspector.KeyboardShortcut.makeDescriptor(key ? key : keyString, modifiers);
240 * @param {string|!WebInspector.KeyboardShortcut.Key} key
241 * @param {number=} modifiers
242 * @return {string}
244 WebInspector.KeyboardShortcut.shortcutToString = function(key, modifiers)
246 return WebInspector.KeyboardShortcut._modifiersToString(modifiers) + WebInspector.KeyboardShortcut._keyName(key);
250 * @param {string|!WebInspector.KeyboardShortcut.Key} key
251 * @return {string}
253 WebInspector.KeyboardShortcut._keyName = function(key)
255 if (typeof key === "string")
256 return key.toUpperCase();
257 if (typeof key.name === "string")
258 return key.name;
259 return key.name[WebInspector.platform()] || key.name.other || '';
263 * @param {number} keyCode
264 * @param {?number} modifiers
265 * @return {number}
267 WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers = function(keyCode, modifiers)
269 return (keyCode & 255) | (modifiers << 8);
273 * @param {number} key
274 * @return {!{keyCode: number, modifiers: number}}
276 WebInspector.KeyboardShortcut.keyCodeAndModifiersFromKey = function(key)
278 return { keyCode: key & 255, modifiers: key >> 8 };
282 * @param {number|undefined} modifiers
283 * @return {string}
285 WebInspector.KeyboardShortcut._modifiersToString = function(modifiers)
287 var isMac = WebInspector.isMac();
288 var m = WebInspector.KeyboardShortcut.Modifiers;
289 var modifierNames = new Map([
290 [m.Ctrl, isMac ? "Ctrl\u2004" : "Ctrl\u200A+\u200A"],
291 [m.Alt, isMac ? "opt\u2004" : "Alt\u200A+\u200A"],
292 [m.Shift, isMac ? "\u21e7\u2004" : "Shift\u200A+\u200A"],
293 [m.Meta, isMac ? "\u2318\u2004" : "Win\u200A+\u200A"]
295 return [m.Meta, m.Ctrl, m.Alt, m.Shift].map(mapModifiers).join("");
298 * @param {number} m
299 * @return {string}
301 function mapModifiers(m)
303 return modifiers & m ? /** @type {string} */ (modifierNames.get(m)) : "";
307 WebInspector.KeyboardShortcut.SelectAll = WebInspector.KeyboardShortcut.makeKey("a", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta);