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
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.
33 WebInspector
.KeyboardShortcut = function()
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.
46 Meta
: 8, // Command key on Mac, Win key on other platforms.
49 // "default" command/ctrl key for platform, Command on Mac, Ctrl on other platforms
50 return WebInspector
.isMac() ? this.Meta
: this.Ctrl
;
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
: "\'" },
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
= {};
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
;
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.
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
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
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
181 WebInspector
.KeyboardShortcut
.eventHasCtrlOrMeta = function(event
)
183 return WebInspector
.isMac() ? event
.metaKey
&& !event
.ctrlKey
: event
.ctrlKey
&& !event
.metaKey
;
187 * @param {!Event} event
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
)
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(/\+(?!$)/);
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
]];
225 console
.assert(i
=== parts
.length
- 1, "Only one key other than modifier is allowed in shortcut <" + shortcut
+ ">");
226 keyString
= parts
[i
];
229 console
.assert(keyString
, "Modifiers-only shortcuts are not allowed (encountered <" + shortcut
+ ">)");
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
244 WebInspector
.KeyboardShortcut
.shortcutToString = function(key
, modifiers
)
246 return WebInspector
.KeyboardShortcut
._modifiersToString(modifiers
) + WebInspector
.KeyboardShortcut
._keyName(key
);
250 * @param {string|!WebInspector.KeyboardShortcut.Key} key
253 WebInspector
.KeyboardShortcut
._keyName = function(key
)
255 if (typeof key
=== "string")
256 return key
.toUpperCase();
257 if (typeof key
.name
=== "string")
259 return key
.name
[WebInspector
.platform()] || key
.name
.other
|| '';
263 * @param {number} keyCode
264 * @param {?number} modifiers
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
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("");
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
);