1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 * @param {!WebInspector.ActionRegistry} actionRegistry
8 * @param {!Document} document
10 WebInspector
.ShortcutRegistry = function(actionRegistry
, document
)
12 this._actionRegistry
= actionRegistry
;
13 /** @type {!Multimap.<string, string>} */
14 this._defaultKeyToActions
= new Multimap();
15 /** @type {!Multimap.<string, !WebInspector.KeyboardShortcut.Descriptor>} */
16 this._defaultActionToShortcut
= new Multimap();
17 this._registerBindings(document
);
20 WebInspector
.ShortcutRegistry
.prototype = {
23 * @return {!Array.<string>}
25 applicableActions: function(key
)
27 return this._actionRegistry
.applicableActions(this._defaultActionsForKey(key
).valuesArray(), WebInspector
.context
);
32 * @return {!Set.<string>}
34 _defaultActionsForKey: function(key
)
36 return this._defaultKeyToActions
.get(String(key
));
40 * @param {string} actionId
41 * @return {!Array.<!WebInspector.KeyboardShortcut.Descriptor>}
43 shortcutDescriptorsForAction: function(actionId
)
45 return this._defaultActionToShortcut
.get(actionId
).valuesArray();
49 * @param {!Array.<string>} actionIds
50 * @return {!Array.<number>}
52 keysForActions: function(actionIds
)
55 for (var i
= 0; i
< actionIds
.length
; ++i
) {
56 var descriptors
= this.shortcutDescriptorsForAction(actionIds
[i
]);
57 for (var j
= 0; j
< descriptors
.length
; ++j
)
58 result
.push(descriptors
[j
].key
);
64 * @param {string} actionId
65 * @return {string|undefined}
67 shortcutTitleForAction: function(actionId
)
69 var descriptors
= this.shortcutDescriptorsForAction(actionId
);
70 if (descriptors
.length
)
71 return descriptors
[0].name
;
75 * @param {!KeyboardEvent} event
77 handleShortcut: function(event
)
79 this.handleKey(WebInspector
.KeyboardShortcut
.makeKeyFromEvent(event
), event
.keyIdentifier
, event
);
84 * @param {string} keyIdentifier
85 * @param {!KeyboardEvent=} event
87 handleKey: function(key
, keyIdentifier
, event
)
89 var keyModifiers
= key
>> 8;
90 var actionIds
= this.applicableActions(key
);
91 if (!actionIds
.length
)
93 if (WebInspector
.GlassPane
.DefaultFocusedViewStack
.length
> 1) {
94 if (event
&& !isPossiblyInputKey())
99 if (!isPossiblyInputKey()) {
102 processNextAction
.call(this);
104 this._pendingActionTimer
= setTimeout(processNextAction
.bind(this), 0);
108 * @this {WebInspector.ShortcutRegistry}
110 function processNextAction()
112 delete this._pendingActionTimer
;
113 var actionId
= actionIds
.shift();
117 this._actionRegistry
.execute(actionId
).then(processNextAction
.bind(this));
123 function isPossiblyInputKey()
125 if (!event
|| !WebInspector
.isEditing() || /^F\d+|Control|Shift|Alt|Meta|Win|U\+001B$/.test(keyIdentifier
))
131 var modifiers
= WebInspector
.KeyboardShortcut
.Modifiers
;
132 if ((keyModifiers
& (modifiers
.Ctrl
| modifiers
.Alt
)) === (modifiers
.Ctrl
| modifiers
.Alt
))
133 return WebInspector
.isWin();
135 return !hasModifier(modifiers
.Ctrl
) && !hasModifier(modifiers
.Alt
) && !hasModifier(modifiers
.Meta
);
139 * @param {number} mod
142 function hasModifier(mod
)
144 return !!(keyModifiers
& mod
);
149 * @param {string} actionId
150 * @param {string} shortcut
152 registerShortcut: function(actionId
, shortcut
)
154 var descriptor
= WebInspector
.KeyboardShortcut
.makeDescriptorFromBindingShortcut(shortcut
);
157 this._defaultActionToShortcut
.set(actionId
, descriptor
);
158 this._defaultKeyToActions
.set(String(descriptor
.key
), actionId
);
161 dismissPendingShortcutAction: function()
163 if (this._pendingActionTimer
) {
164 clearTimeout(this._pendingActionTimer
);
165 delete this._pendingActionTimer
;
170 * @param {!Document} document
172 _registerBindings: function(document
)
174 document
.addEventListener("input", this.dismissPendingShortcutAction
.bind(this), true);
175 var extensions
= self
.runtime
.extensions(WebInspector
.ActionDelegate
);
176 extensions
.forEach(registerExtension
, this);
179 * @param {!Runtime.Extension} extension
180 * @this {WebInspector.ShortcutRegistry}
182 function registerExtension(extension
)
184 var descriptor
= extension
.descriptor();
185 var bindings
= descriptor
["bindings"];
186 for (var i
= 0; bindings
&& i
< bindings
.length
; ++i
) {
187 if (!platformMatches(bindings
[i
].platform
))
189 var shortcuts
= bindings
[i
]["shortcut"].split(/\s+/);
190 shortcuts
.forEach(this.registerShortcut
.bind(this, descriptor
["actionId"]));
195 * @param {string=} platformsString
198 function platformMatches(platformsString
)
200 if (!platformsString
)
202 var platforms
= platformsString
.split(",");
204 var currentPlatform
= WebInspector
.platform();
205 for (var i
= 0; !isMatch
&& i
< platforms
.length
; ++i
)
206 isMatch
= platforms
[i
] === currentPlatform
;
215 WebInspector
.ShortcutRegistry
.ForwardedShortcut = function()
219 WebInspector
.ShortcutRegistry
.ForwardedShortcut
.instance
= new WebInspector
.ShortcutRegistry
.ForwardedShortcut();
221 /** @type {!WebInspector.ShortcutRegistry} */
222 WebInspector
.shortcutRegistry
;