Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / Source / devtools / front_end / ui / ShortcutRegistry.js
blob99e62d7de9fbb9e394e5df79c07d88b0b8288108
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.
5 /**
6 * @constructor
7 * @param {!WebInspector.ActionRegistry} actionRegistry
8 * @param {!Document} document
9 */
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 = {
21 /**
22 * @param {number} key
23 * @return {!Array.<string>}
25 applicableActions: function(key)
27 return this._actionRegistry.applicableActions(this._defaultActionsForKey(key).valuesArray(), WebInspector.context);
30 /**
31 * @param {number} key
32 * @return {!Set.<string>}
34 _defaultActionsForKey: function(key)
36 return this._defaultKeyToActions.get(String(key));
39 /**
40 * @param {string} actionId
41 * @return {!Array.<!WebInspector.KeyboardShortcut.Descriptor>}
43 shortcutDescriptorsForAction: function(actionId)
45 return this._defaultActionToShortcut.get(actionId).valuesArray();
48 /**
49 * @param {!Array.<string>} actionIds
50 * @return {!Array.<number>}
52 keysForActions: function(actionIds)
54 var result = [];
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);
60 return result;
63 /**
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;
74 /**
75 * @param {!KeyboardEvent} event
77 handleShortcut: function(event)
79 this.handleKey(WebInspector.KeyboardShortcut.makeKeyFromEvent(event), event.keyIdentifier, event);
82 /**
83 * @param {number} key
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)
92 return;
93 if (WebInspector.GlassPane.DefaultFocusedViewStack.length > 1) {
94 if (event && !isPossiblyInputKey())
95 event.consume(true);
96 return;
99 if (!isPossiblyInputKey()) {
100 if (event)
101 event.consume(true);
102 processNextAction.call(this);
103 } else {
104 this._pendingActionTimer = setTimeout(processNextAction.bind(this), 0);
108 * @this {WebInspector.ShortcutRegistry}
110 function processNextAction()
112 delete this._pendingActionTimer;
113 var actionId = actionIds.shift();
114 if (!actionId)
115 return;
117 this._actionRegistry.execute(actionId).then(processNextAction.bind(this));
121 * @return {boolean}
123 function isPossiblyInputKey()
125 if (!event || !WebInspector.isEditing() || /^F\d+|Control|Shift|Alt|Meta|Win|U\+001B$/.test(keyIdentifier))
126 return false;
128 if (!keyModifiers)
129 return true;
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
140 * @return {boolean}
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);
155 if (!descriptor)
156 return;
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))
188 continue;
189 var shortcuts = bindings[i]["shortcut"].split(/\s+/);
190 shortcuts.forEach(this.registerShortcut.bind(this, descriptor["actionId"]));
195 * @param {string=} platformsString
196 * @return {boolean}
198 function platformMatches(platformsString)
200 if (!platformsString)
201 return true;
202 var platforms = platformsString.split(",");
203 var isMatch = false;
204 var currentPlatform = WebInspector.platform();
205 for (var i = 0; !isMatch && i < platforms.length; ++i)
206 isMatch = platforms[i] === currentPlatform;
207 return isMatch;
213 * @constructor
215 WebInspector.ShortcutRegistry.ForwardedShortcut = function()
219 WebInspector.ShortcutRegistry.ForwardedShortcut.instance = new WebInspector.ShortcutRegistry.ForwardedShortcut();
221 /** @type {!WebInspector.ShortcutRegistry} */
222 WebInspector.shortcutRegistry;