OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2009 Apple Inc. All rights reserved. | 2 * Copyright (C) 2009 Apple Inc. All rights reserved. |
3 * Copyright (C) 2009 Google Inc. All rights reserved. | 3 * Copyright (C) 2009 Google Inc. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * | 8 * |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
11 * 2. Redistributions in binary form must reproduce the above copyright | 11 * 2. Redistributions in binary form must reproduce the above copyright |
12 * notice, this list of conditions and the following disclaimer in the | 12 * notice, this list of conditions and the following disclaimer in the |
13 * documentation and/or other materials provided with the distribution. | 13 * documentation and/or other materials provided with the distribution. |
14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of | 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 | 15 * its contributors may be used to endorse or promote products derived |
16 * from this software without specific prior written permission. | 16 * from this software without specific prior written permission. |
17 * | 17 * |
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY | 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 | 19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 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 | 21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY |
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 */ | 28 */ |
29 | |
30 /** | 29 /** |
31 * @constructor | 30 * @unrestricted |
32 */ | 31 */ |
33 WebInspector.KeyboardShortcut = function() | 32 WebInspector.KeyboardShortcut = class { |
34 { | 33 /** |
| 34 * Creates a number encoding keyCode in the lower 8 bits and modifiers mask in
the higher 8 bits. |
| 35 * It is useful for matching pressed keys. |
| 36 * |
| 37 * @param {number|string} keyCode The code of the key, or a character "a-z" wh
ich is converted to a keyCode value. |
| 38 * @param {number=} modifiers Optional list of modifiers passed as additional
parameters. |
| 39 * @return {number} |
| 40 */ |
| 41 static makeKey(keyCode, modifiers) { |
| 42 if (typeof keyCode === 'string') |
| 43 keyCode = keyCode.charCodeAt(0) - (/^[a-z]/.test(keyCode) ? 32 : 0); |
| 44 modifiers = modifiers || WebInspector.KeyboardShortcut.Modifiers.None; |
| 45 return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyCode, m
odifiers); |
| 46 } |
| 47 |
| 48 /** |
| 49 * @param {?KeyboardEvent} keyboardEvent |
| 50 * @return {number} |
| 51 */ |
| 52 static makeKeyFromEvent(keyboardEvent) { |
| 53 var modifiers = WebInspector.KeyboardShortcut.Modifiers.None; |
| 54 if (keyboardEvent.shiftKey) |
| 55 modifiers |= WebInspector.KeyboardShortcut.Modifiers.Shift; |
| 56 if (keyboardEvent.ctrlKey) |
| 57 modifiers |= WebInspector.KeyboardShortcut.Modifiers.Ctrl; |
| 58 if (keyboardEvent.altKey) |
| 59 modifiers |= WebInspector.KeyboardShortcut.Modifiers.Alt; |
| 60 if (keyboardEvent.metaKey) |
| 61 modifiers |= WebInspector.KeyboardShortcut.Modifiers.Meta; |
| 62 |
| 63 // Use either a real or a synthetic keyCode (for events originating from ext
ensions). |
| 64 var keyCode = keyboardEvent.keyCode || keyboardEvent['__keyCode']; |
| 65 return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyCode, m
odifiers); |
| 66 } |
| 67 |
| 68 /** |
| 69 * @param {?KeyboardEvent} keyboardEvent |
| 70 * @return {number} |
| 71 */ |
| 72 static makeKeyFromEventIgnoringModifiers(keyboardEvent) { |
| 73 var keyCode = keyboardEvent.keyCode || keyboardEvent['__keyCode']; |
| 74 return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers( |
| 75 keyCode, WebInspector.KeyboardShortcut.Modifiers.None); |
| 76 } |
| 77 |
| 78 /** |
| 79 * @param {(?KeyboardEvent|?MouseEvent)} event |
| 80 * @return {boolean} |
| 81 */ |
| 82 static eventHasCtrlOrMeta(event) { |
| 83 return WebInspector.isMac() ? event.metaKey && !event.ctrlKey : event.ctrlKe
y && !event.metaKey; |
| 84 } |
| 85 |
| 86 /** |
| 87 * @param {!Event} event |
| 88 * @return {boolean} |
| 89 */ |
| 90 static hasNoModifiers(event) { |
| 91 return !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey; |
| 92 } |
| 93 |
| 94 /** |
| 95 * @param {string|!WebInspector.KeyboardShortcut.Key} key |
| 96 * @param {number=} modifiers |
| 97 * @return {!WebInspector.KeyboardShortcut.Descriptor} |
| 98 */ |
| 99 static makeDescriptor(key, modifiers) { |
| 100 return { |
| 101 key: WebInspector.KeyboardShortcut.makeKey(typeof key === 'string' ? key :
key.code, modifiers), |
| 102 name: WebInspector.KeyboardShortcut.shortcutToString(key, modifiers) |
| 103 }; |
| 104 } |
| 105 |
| 106 /** |
| 107 * @param {string} shortcut |
| 108 * @return {?WebInspector.KeyboardShortcut.Descriptor} |
| 109 */ |
| 110 static makeDescriptorFromBindingShortcut(shortcut) { |
| 111 var parts = shortcut.split(/\+(?!$)/); |
| 112 var modifiers = 0; |
| 113 var keyString; |
| 114 for (var i = 0; i < parts.length; ++i) { |
| 115 if (typeof WebInspector.KeyboardShortcut.Modifiers[parts[i]] !== 'undefine
d') { |
| 116 modifiers |= WebInspector.KeyboardShortcut.Modifiers[parts[i]]; |
| 117 continue; |
| 118 } |
| 119 console.assert( |
| 120 i === parts.length - 1, 'Only one key other than modifier is allowed i
n shortcut <' + shortcut + '>'); |
| 121 keyString = parts[i]; |
| 122 break; |
| 123 } |
| 124 console.assert(keyString, 'Modifiers-only shortcuts are not allowed (encount
ered <' + shortcut + '>)'); |
| 125 if (!keyString) |
| 126 return null; |
| 127 |
| 128 var key = WebInspector.KeyboardShortcut.Keys[keyString] || WebInspector.Keyb
oardShortcut.KeyBindings[keyString]; |
| 129 if (key && key.shiftKey) |
| 130 modifiers |= WebInspector.KeyboardShortcut.Modifiers.Shift; |
| 131 return WebInspector.KeyboardShortcut.makeDescriptor(key ? key : keyString, m
odifiers); |
| 132 } |
| 133 |
| 134 /** |
| 135 * @param {string|!WebInspector.KeyboardShortcut.Key} key |
| 136 * @param {number=} modifiers |
| 137 * @return {string} |
| 138 */ |
| 139 static shortcutToString(key, modifiers) { |
| 140 return WebInspector.KeyboardShortcut._modifiersToString(modifiers) + WebInsp
ector.KeyboardShortcut._keyName(key); |
| 141 } |
| 142 |
| 143 /** |
| 144 * @param {string|!WebInspector.KeyboardShortcut.Key} key |
| 145 * @return {string} |
| 146 */ |
| 147 static _keyName(key) { |
| 148 if (typeof key === 'string') |
| 149 return key.toUpperCase(); |
| 150 if (typeof key.name === 'string') |
| 151 return key.name; |
| 152 return key.name[WebInspector.platform()] || key.name.other || ''; |
| 153 } |
| 154 |
| 155 /** |
| 156 * @param {number} keyCode |
| 157 * @param {?number} modifiers |
| 158 * @return {number} |
| 159 */ |
| 160 static _makeKeyFromCodeAndModifiers(keyCode, modifiers) { |
| 161 return (keyCode & 255) | (modifiers << 8); |
| 162 } |
| 163 |
| 164 /** |
| 165 * @param {number} key |
| 166 * @return {!{keyCode: number, modifiers: number}} |
| 167 */ |
| 168 static keyCodeAndModifiersFromKey(key) { |
| 169 return {keyCode: key & 255, modifiers: key >> 8}; |
| 170 } |
| 171 |
| 172 /** |
| 173 * @param {number|undefined} modifiers |
| 174 * @return {string} |
| 175 */ |
| 176 static _modifiersToString(modifiers) { |
| 177 var isMac = WebInspector.isMac(); |
| 178 var m = WebInspector.KeyboardShortcut.Modifiers; |
| 179 var modifierNames = new Map([ |
| 180 [m.Ctrl, isMac ? 'Ctrl\u2004' : 'Ctrl\u200A+\u200A'], [m.Alt, isMac ? 'opt
\u2004' : 'Alt\u200A+\u200A'], |
| 181 [m.Shift, isMac ? '\u21e7\u2004' : 'Shift\u200A+\u200A'], [m.Meta, isMac ?
'\u2318\u2004' : 'Win\u200A+\u200A'] |
| 182 ]); |
| 183 return [m.Meta, m.Ctrl, m.Alt, m.Shift].map(mapModifiers).join(''); |
| 184 |
| 185 /** |
| 186 * @param {number} m |
| 187 * @return {string} |
| 188 */ |
| 189 function mapModifiers(m) { |
| 190 return modifiers & m ? /** @type {string} */ (modifierNames.get(m)) : ''; |
| 191 } |
| 192 } |
35 }; | 193 }; |
36 | 194 |
37 /** | 195 /** |
38 * Constants for encoding modifier key set as a bit mask. | 196 * Constants for encoding modifier key set as a bit mask. |
39 * @see #_makeKeyFromCodeAndModifiers | 197 * @see #_makeKeyFromCodeAndModifiers |
40 */ | 198 */ |
41 WebInspector.KeyboardShortcut.Modifiers = { | 199 WebInspector.KeyboardShortcut.Modifiers = { |
42 None: 0, // Constant for empty modifiers set. | 200 None: 0, // Constant for empty modifiers set. |
43 Shift: 1, | 201 Shift: 1, |
44 Ctrl: 2, | 202 Ctrl: 2, |
45 Alt: 4, | 203 Alt: 4, |
46 Meta: 8, // Command key on Mac, Win key on other platforms. | 204 Meta: 8, // Command key on Mac, Win key on other platforms. |
47 get CtrlOrMeta() | 205 get CtrlOrMeta() { |
48 { | 206 // "default" command/ctrl key for platform, Command on Mac, Ctrl on other pl
atforms |
49 // "default" command/ctrl key for platform, Command on Mac, Ctrl on othe
r platforms | 207 return WebInspector.isMac() ? this.Meta : this.Ctrl; |
50 return WebInspector.isMac() ? this.Meta : this.Ctrl; | 208 }, |
51 }, | 209 get ShiftOrOption() { |
52 get ShiftOrOption() | 210 // Option on Mac, Shift on other platforms |
53 { | 211 return WebInspector.isMac() ? this.Alt : this.Shift; |
54 // Option on Mac, Shift on other platforms | 212 } |
55 return WebInspector.isMac() ? this.Alt : this.Shift; | |
56 } | |
57 }; | 213 }; |
58 | 214 |
59 /** @typedef {!{code: number, name: (string|!Object.<string, string>)}} */ | 215 /** @typedef {!{code: number, name: (string|!Object.<string, string>)}} */ |
60 WebInspector.KeyboardShortcut.Key; | 216 WebInspector.KeyboardShortcut.Key; |
61 | 217 |
62 /** @type {!Object.<string, !WebInspector.KeyboardShortcut.Key>} */ | 218 /** @type {!Object.<string, !WebInspector.KeyboardShortcut.Key>} */ |
63 WebInspector.KeyboardShortcut.Keys = { | 219 WebInspector.KeyboardShortcut.Keys = { |
64 Backspace: { code: 8, name: "\u21a4" }, | 220 Backspace: {code: 8, name: '\u21a4'}, |
65 Tab: { code: 9, name: { mac: "\u21e5", other: "Tab" } }, | 221 Tab: {code: 9, name: {mac: '\u21e5', other: 'Tab'}}, |
66 Enter: { code: 13, name: { mac: "\u21a9", other: "Enter" } }, | 222 Enter: {code: 13, name: {mac: '\u21a9', other: 'Enter'}}, |
67 Shift: { code: 16, name: { mac: "\u21e7", other: "Shift" } }, | 223 Shift: {code: 16, name: {mac: '\u21e7', other: 'Shift'}}, |
68 Ctrl: { code: 17, name: "Ctrl" }, | 224 Ctrl: {code: 17, name: 'Ctrl'}, |
69 Esc: { code: 27, name: "Esc" }, | 225 Esc: {code: 27, name: 'Esc'}, |
70 Space: { code: 32, name: "Space" }, | 226 Space: {code: 32, name: 'Space'}, |
71 PageUp: { code: 33, name: { mac: "\u21de", other: "PageUp" } }, // als
o NUM_NORTH_EAST | 227 PageUp: {code: 33, name: {mac: '\u21de', other: 'PageUp'}}, // also NUM_N
ORTH_EAST |
72 PageDown: { code: 34, name: { mac: "\u21df", other: "PageDown" } }, // als
o NUM_SOUTH_EAST | 228 PageDown: {code: 34, name: {mac: '\u21df', other: 'PageDown'}}, // also NUM_S
OUTH_EAST |
73 End: { code: 35, name: { mac: "\u2197", other: "End" } }, // als
o NUM_SOUTH_WEST | 229 End: {code: 35, name: {mac: '\u2197', other: 'End'}}, // also NUM_S
OUTH_WEST |
74 Home: { code: 36, name: { mac: "\u2196", other: "Home" } }, // als
o NUM_NORTH_WEST | 230 Home: {code: 36, name: {mac: '\u2196', other: 'Home'}}, // also NUM_N
ORTH_WEST |
75 Left: { code: 37, name: "\u2190" }, // also NUM_WEST | 231 Left: {code: 37, name: '\u2190'}, // also NUM_W
EST |
76 Up: { code: 38, name: "\u2191" }, // also NUM_NORTH | 232 Up: {code: 38, name: '\u2191'}, // also NUM_N
ORTH |
77 Right: { code: 39, name: "\u2192" }, // also NUM_EAST | 233 Right: {code: 39, name: '\u2192'}, // also NUM_E
AST |
78 Down: { code: 40, name: "\u2193" }, // also NUM_SOUTH | 234 Down: {code: 40, name: '\u2193'}, // also NUM_S
OUTH |
79 Delete: { code: 46, name: "Del" }, | 235 Delete: {code: 46, name: 'Del'}, |
80 Zero: { code: 48, name: "0" }, | 236 Zero: {code: 48, name: '0'}, |
81 H: { code: 72, name: "H" }, | 237 H: {code: 72, name: 'H'}, |
82 N: { code: 78, name: "N" }, | 238 N: {code: 78, name: 'N'}, |
83 P: { code: 80, name: "P" }, | 239 P: {code: 80, name: 'P'}, |
84 Meta: { code: 91, name: "Meta" }, | 240 Meta: {code: 91, name: 'Meta'}, |
85 F1: { code: 112, name: "F1" }, | 241 F1: {code: 112, name: 'F1'}, |
86 F2: { code: 113, name: "F2" }, | 242 F2: {code: 113, name: 'F2'}, |
87 F3: { code: 114, name: "F3" }, | 243 F3: {code: 114, name: 'F3'}, |
88 F4: { code: 115, name: "F4" }, | 244 F4: {code: 115, name: 'F4'}, |
89 F5: { code: 116, name: "F5" }, | 245 F5: {code: 116, name: 'F5'}, |
90 F6: { code: 117, name: "F6" }, | 246 F6: {code: 117, name: 'F6'}, |
91 F7: { code: 118, name: "F7" }, | 247 F7: {code: 118, name: 'F7'}, |
92 F8: { code: 119, name: "F8" }, | 248 F8: {code: 119, name: 'F8'}, |
93 F9: { code: 120, name: "F9" }, | 249 F9: {code: 120, name: 'F9'}, |
94 F10: { code: 121, name: "F10" }, | 250 F10: {code: 121, name: 'F10'}, |
95 F11: { code: 122, name: "F11" }, | 251 F11: {code: 122, name: 'F11'}, |
96 F12: { code: 123, name: "F12" }, | 252 F12: {code: 123, name: 'F12'}, |
97 Semicolon: { code: 186, name: ";" }, | 253 Semicolon: {code: 186, name: ';'}, |
98 NumpadPlus: { code: 107, name: "Numpad +" }, | 254 NumpadPlus: {code: 107, name: 'Numpad +'}, |
99 NumpadMinus: { code: 109, name: "Numpad -" }, | 255 NumpadMinus: {code: 109, name: 'Numpad -'}, |
100 Numpad0: { code: 96, name: "Numpad 0" }, | 256 Numpad0: {code: 96, name: 'Numpad 0'}, |
101 Plus: { code: 187, name: "+" }, | 257 Plus: {code: 187, name: '+'}, |
102 Comma: { code: 188, name: "," }, | 258 Comma: {code: 188, name: ','}, |
103 Minus: { code: 189, name: "-" }, | 259 Minus: {code: 189, name: '-'}, |
104 Period: { code: 190, name: "." }, | 260 Period: {code: 190, name: '.'}, |
105 Slash: { code: 191, name: "/" }, | 261 Slash: {code: 191, name: '/'}, |
106 QuestionMark: { code: 191, name: "?" }, | 262 QuestionMark: {code: 191, name: '?'}, |
107 Apostrophe: { code: 192, name: "`" }, | 263 Apostrophe: {code: 192, name: '`'}, |
108 Tilde: { code: 192, name: "Tilde" }, | 264 Tilde: {code: 192, name: 'Tilde'}, |
109 LeftSquareBracket: { code: 219, name: "[" }, | 265 LeftSquareBracket: {code: 219, name: '['}, |
110 RightSquareBracket: { code: 221, name: "]" }, | 266 RightSquareBracket: {code: 221, name: ']'}, |
111 Backslash: { code: 220, name: "\\" }, | 267 Backslash: {code: 220, name: '\\'}, |
112 SingleQuote: { code: 222, name: "\'" }, | 268 SingleQuote: {code: 222, name: '\''}, |
113 get CtrlOrMeta() | 269 get CtrlOrMeta() { |
114 { | 270 // "default" command/ctrl key for platform, Command on Mac, Ctrl on other pl
atforms |
115 // "default" command/ctrl key for platform, Command on Mac, Ctrl on othe
r platforms | 271 return WebInspector.isMac() ? this.Meta : this.Ctrl; |
116 return WebInspector.isMac() ? this.Meta : this.Ctrl; | 272 }, |
117 }, | |
118 }; | 273 }; |
119 | 274 |
120 WebInspector.KeyboardShortcut.KeyBindings = {}; | 275 WebInspector.KeyboardShortcut.KeyBindings = {}; |
121 | 276 |
122 (function() { | 277 (function() { |
123 for (var key in WebInspector.KeyboardShortcut.Keys) { | 278 for (var key in WebInspector.KeyboardShortcut.Keys) { |
124 var descriptor = WebInspector.KeyboardShortcut.Keys[key]; | 279 var descriptor = WebInspector.KeyboardShortcut.Keys[key]; |
125 if (typeof descriptor === "object" && descriptor["code"]) { | 280 if (typeof descriptor === 'object' && descriptor['code']) { |
126 var name = typeof descriptor["name"] === "string" ? descriptor["name
"] : key; | 281 var name = typeof descriptor['name'] === 'string' ? descriptor['name'] : k
ey; |
127 WebInspector.KeyboardShortcut.KeyBindings[name] = descriptor; | 282 WebInspector.KeyboardShortcut.KeyBindings[name] = descriptor; |
128 } | |
129 } | 283 } |
| 284 } |
130 })(); | 285 })(); |
131 | 286 |
132 /** | |
133 * Creates a number encoding keyCode in the lower 8 bits and modifiers mask in t
he higher 8 bits. | |
134 * It is useful for matching pressed keys. | |
135 * | |
136 * @param {number|string} keyCode The code of the key, or a character "a-z" whic
h is converted to a keyCode value. | |
137 * @param {number=} modifiers Optional list of modifiers passed as additional pa
rameters. | |
138 * @return {number} | |
139 */ | |
140 WebInspector.KeyboardShortcut.makeKey = function(keyCode, modifiers) | |
141 { | |
142 if (typeof keyCode === "string") | |
143 keyCode = keyCode.charCodeAt(0) - (/^[a-z]/.test(keyCode) ? 32 : 0); | |
144 modifiers = modifiers || WebInspector.KeyboardShortcut.Modifiers.None; | |
145 return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyCode, m
odifiers); | |
146 }; | |
147 | |
148 /** | |
149 * @param {?KeyboardEvent} keyboardEvent | |
150 * @return {number} | |
151 */ | |
152 WebInspector.KeyboardShortcut.makeKeyFromEvent = function(keyboardEvent) | |
153 { | |
154 var modifiers = WebInspector.KeyboardShortcut.Modifiers.None; | |
155 if (keyboardEvent.shiftKey) | |
156 modifiers |= WebInspector.KeyboardShortcut.Modifiers.Shift; | |
157 if (keyboardEvent.ctrlKey) | |
158 modifiers |= WebInspector.KeyboardShortcut.Modifiers.Ctrl; | |
159 if (keyboardEvent.altKey) | |
160 modifiers |= WebInspector.KeyboardShortcut.Modifiers.Alt; | |
161 if (keyboardEvent.metaKey) | |
162 modifiers |= WebInspector.KeyboardShortcut.Modifiers.Meta; | |
163 | |
164 // Use either a real or a synthetic keyCode (for events originating from ext
ensions). | |
165 var keyCode = keyboardEvent.keyCode || keyboardEvent["__keyCode"]; | |
166 return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyCode, m
odifiers); | |
167 }; | |
168 | |
169 /** | |
170 * @param {?KeyboardEvent} keyboardEvent | |
171 * @return {number} | |
172 */ | |
173 WebInspector.KeyboardShortcut.makeKeyFromEventIgnoringModifiers = function(keybo
ardEvent) | |
174 { | |
175 var keyCode = keyboardEvent.keyCode || keyboardEvent["__keyCode"]; | |
176 return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyCode, W
ebInspector.KeyboardShortcut.Modifiers.None); | |
177 }; | |
178 | |
179 /** | |
180 * @param {(?KeyboardEvent|?MouseEvent)} event | |
181 * @return {boolean} | |
182 */ | |
183 WebInspector.KeyboardShortcut.eventHasCtrlOrMeta = function(event) | |
184 { | |
185 return WebInspector.isMac() ? event.metaKey && !event.ctrlKey : event.ctrlKe
y && !event.metaKey; | |
186 }; | |
187 | |
188 /** | |
189 * @param {!Event} event | |
190 * @return {boolean} | |
191 */ | |
192 WebInspector.KeyboardShortcut.hasNoModifiers = function(event) | |
193 { | |
194 return !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey; | |
195 }; | |
196 | 287 |
197 /** @typedef {!{key: number, name: string}} */ | 288 /** @typedef {!{key: number, name: string}} */ |
198 WebInspector.KeyboardShortcut.Descriptor; | 289 WebInspector.KeyboardShortcut.Descriptor; |
199 | 290 |
200 /** | 291 |
201 * @param {string|!WebInspector.KeyboardShortcut.Key} key | 292 WebInspector.KeyboardShortcut.SelectAll = |
202 * @param {number=} modifiers | 293 WebInspector.KeyboardShortcut.makeKey('a', WebInspector.KeyboardShortcut.Mod
ifiers.CtrlOrMeta); |
203 * @return {!WebInspector.KeyboardShortcut.Descriptor} | |
204 */ | |
205 WebInspector.KeyboardShortcut.makeDescriptor = function(key, modifiers) | |
206 { | |
207 return { | |
208 key: WebInspector.KeyboardShortcut.makeKey(typeof key === "string" ? key
: key.code, modifiers), | |
209 name: WebInspector.KeyboardShortcut.shortcutToString(key, modifiers) | |
210 }; | |
211 }; | |
212 | |
213 /** | |
214 * @param {string} shortcut | |
215 * @return {?WebInspector.KeyboardShortcut.Descriptor} | |
216 */ | |
217 WebInspector.KeyboardShortcut.makeDescriptorFromBindingShortcut = function(short
cut) | |
218 { | |
219 var parts = shortcut.split(/\+(?!$)/); | |
220 var modifiers = 0; | |
221 var keyString; | |
222 for (var i = 0; i < parts.length; ++i) { | |
223 if (typeof WebInspector.KeyboardShortcut.Modifiers[parts[i]] !== "undefi
ned") { | |
224 modifiers |= WebInspector.KeyboardShortcut.Modifiers[parts[i]]; | |
225 continue; | |
226 } | |
227 console.assert(i === parts.length - 1, "Only one key other than modifier
is allowed in shortcut <" + shortcut + ">"); | |
228 keyString = parts[i]; | |
229 break; | |
230 } | |
231 console.assert(keyString, "Modifiers-only shortcuts are not allowed (encount
ered <" + shortcut + ">)"); | |
232 if (!keyString) | |
233 return null; | |
234 | |
235 var key = WebInspector.KeyboardShortcut.Keys[keyString] || WebInspector.Keyb
oardShortcut.KeyBindings[keyString]; | |
236 if (key && key.shiftKey) | |
237 modifiers |= WebInspector.KeyboardShortcut.Modifiers.Shift; | |
238 return WebInspector.KeyboardShortcut.makeDescriptor(key ? key : keyString, m
odifiers); | |
239 }; | |
240 | |
241 /** | |
242 * @param {string|!WebInspector.KeyboardShortcut.Key} key | |
243 * @param {number=} modifiers | |
244 * @return {string} | |
245 */ | |
246 WebInspector.KeyboardShortcut.shortcutToString = function(key, modifiers) | |
247 { | |
248 return WebInspector.KeyboardShortcut._modifiersToString(modifiers) + WebInsp
ector.KeyboardShortcut._keyName(key); | |
249 }; | |
250 | |
251 /** | |
252 * @param {string|!WebInspector.KeyboardShortcut.Key} key | |
253 * @return {string} | |
254 */ | |
255 WebInspector.KeyboardShortcut._keyName = function(key) | |
256 { | |
257 if (typeof key === "string") | |
258 return key.toUpperCase(); | |
259 if (typeof key.name === "string") | |
260 return key.name; | |
261 return key.name[WebInspector.platform()] || key.name.other || ""; | |
262 }; | |
263 | |
264 /** | |
265 * @param {number} keyCode | |
266 * @param {?number} modifiers | |
267 * @return {number} | |
268 */ | |
269 WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers = function(keyCode, m
odifiers) | |
270 { | |
271 return (keyCode & 255) | (modifiers << 8); | |
272 }; | |
273 | |
274 /** | |
275 * @param {number} key | |
276 * @return {!{keyCode: number, modifiers: number}} | |
277 */ | |
278 WebInspector.KeyboardShortcut.keyCodeAndModifiersFromKey = function(key) | |
279 { | |
280 return { keyCode: key & 255, modifiers: key >> 8 }; | |
281 }; | |
282 | |
283 /** | |
284 * @param {number|undefined} modifiers | |
285 * @return {string} | |
286 */ | |
287 WebInspector.KeyboardShortcut._modifiersToString = function(modifiers) | |
288 { | |
289 var isMac = WebInspector.isMac(); | |
290 var m = WebInspector.KeyboardShortcut.Modifiers; | |
291 var modifierNames = new Map([ | |
292 [m.Ctrl, isMac ? "Ctrl\u2004" : "Ctrl\u200A+\u200A"], | |
293 [m.Alt, isMac ? "opt\u2004" : "Alt\u200A+\u200A"], | |
294 [m.Shift, isMac ? "\u21e7\u2004" : "Shift\u200A+\u200A"], | |
295 [m.Meta, isMac ? "\u2318\u2004" : "Win\u200A+\u200A"] | |
296 ]); | |
297 return [m.Meta, m.Ctrl, m.Alt, m.Shift].map(mapModifiers).join(""); | |
298 | |
299 /** | |
300 * @param {number} m | |
301 * @return {string} | |
302 */ | |
303 function mapModifiers(m) | |
304 { | |
305 return modifiers & m ? /** @type {string} */ (modifierNames.get(m)) : ""
; | |
306 } | |
307 }; | |
308 | |
309 WebInspector.KeyboardShortcut.SelectAll = WebInspector.KeyboardShortcut.makeKey(
"a", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta); | |
OLD | NEW |