UNPKG

strong-arc

Version:

A visual suite for the StrongLoop API Platform

224 lines (199 loc) 6.78 kB
// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. /** * @constructor * @param {!WebInspector.ActionRegistry} actionRegistry */ WebInspector.ShortcutRegistry = function(actionRegistry) { this._actionRegistry = actionRegistry; /** @type {!StringMultimap.<string>} */ this._defaultKeyToActions = new StringMultimap(); /** @type {!StringMultimap.<!WebInspector.KeyboardShortcut.Descriptor>} */ this._defaultActionToShortcut = new StringMultimap(); this._registerBindings(); } WebInspector.ShortcutRegistry.prototype = { /** * @param {number} key * @return {!Array.<string>} */ applicableActions: function(key) { return this._actionRegistry.applicableActions(this._actionIdsForKey(key), WebInspector.context); }, /** * @param {number} key * @return {!Array.<string>} */ _actionIdsForKey: function(key) { var result = new StringSet(); var defaults = this._defaultActionsForKey(key); defaults.values().forEach(function(actionId) { result.add(actionId); }, this); return result.values(); }, /** * @param {number} key * @return {!Set.<string>} */ _defaultActionsForKey: function(key) { return this._defaultKeyToActions.get(String(key)); }, /** * @param {string} actionId * @return {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} */ shortcutDescriptorsForAction: function(actionId) { return this._defaultActionToShortcut.get(actionId).values(); }, /** * @param {!Array.<string>} actionIds * @return {!Array.<number>} */ keysForActions: function(actionIds) { var result = []; for (var i = 0; i < actionIds.length; ++i) { var descriptors = this.shortcutDescriptorsForAction(actionIds[i]); for (var j = 0; j < descriptors.length; ++j) result.push(descriptors[j].key); } return result; }, /** * @param {!KeyboardEvent} event */ handleShortcut: function(event) { this.handleKey(WebInspector.KeyboardShortcut.makeKeyFromEvent(event), event.keyIdentifier, event); }, /** * @param {number} key * @param {string} keyIdentifier * @param {!KeyboardEvent=} event */ handleKey: function(key, keyIdentifier, event) { var keyModifiers = key >> 8; var actionIds = this.applicableActions(key); if (WebInspector.GlassPane.DefaultFocusedViewStack.length > 1) { if (actionIds.length && !isPossiblyInputKey()) event.consume(true); return; } for (var i = 0; i < actionIds.length; ++i) { if (!isPossiblyInputKey()) { if (handler.call(this, actionIds[i])) break; } else { this._pendingActionTimer = setTimeout(handler.bind(this, actionIds[i]), 0); break; } } /** * @return {boolean} */ function isPossiblyInputKey() { if (!event || !WebInspector.isBeingEdited(/** @type {!Node} */ (event.target)) || /^F\d+|Control|Shift|Alt|Meta|Win|U\+001B$/.test(keyIdentifier)) return false; if (!keyModifiers) return true; var modifiers = WebInspector.KeyboardShortcut.Modifiers; if ((keyModifiers & (modifiers.Ctrl | modifiers.Alt)) === (modifiers.Ctrl | modifiers.Alt)) return WebInspector.isWin(); return !hasModifier(modifiers.Ctrl) && !hasModifier(modifiers.Alt) && !hasModifier(modifiers.Meta); } /** * @param {number} mod * @return {boolean} */ function hasModifier(mod) { return !!(keyModifiers & mod); } /** * @param {string} actionId * @return {boolean} * @this {WebInspector.ShortcutRegistry} */ function handler(actionId) { var result = this._actionRegistry.execute(actionId); if (result && event) event.consume(true); delete this._pendingActionTimer; return result; } }, /** * @param {string} actionId * @param {string} shortcut */ registerShortcut: function(actionId, shortcut) { var descriptor = WebInspector.KeyboardShortcut.makeDescriptorFromBindingShortcut(shortcut); if (!descriptor) return; this._defaultActionToShortcut.set(actionId, descriptor); this._defaultKeyToActions.set(String(descriptor.key), actionId); }, dismissPendingShortcutAction: function() { if (this._pendingActionTimer) { clearTimeout(this._pendingActionTimer); delete this._pendingActionTimer; } }, _registerBindings: function() { document.addEventListener("input", this.dismissPendingShortcutAction.bind(this), true); var extensions = self.runtime.extensions(WebInspector.ActionDelegate); extensions.forEach(registerExtension, this); /** * @param {!Runtime.Extension} extension * @this {WebInspector.ShortcutRegistry} */ function registerExtension(extension) { var descriptor = extension.descriptor(); var bindings = descriptor["bindings"]; for (var i = 0; bindings && i < bindings.length; ++i) { if (!platformMatches(bindings[i].platform)) continue; var shortcuts = bindings[i]["shortcut"].split(/\s+/); shortcuts.forEach(this.registerShortcut.bind(this, descriptor["actionId"])); } } /** * @param {string=} platformsString * @return {boolean} */ function platformMatches(platformsString) { if (!platformsString) return true; var platforms = platformsString.split(","); var isMatch = false; var currentPlatform = WebInspector.platform(); for (var i = 0; !isMatch && i < platforms.length; ++i) isMatch = platforms[i] === currentPlatform; return isMatch; } } } /** * @constructor */ WebInspector.ShortcutRegistry.ForwardedShortcut = function() { } WebInspector.ShortcutRegistry.ForwardedShortcut.instance = new WebInspector.ShortcutRegistry.ForwardedShortcut(); /** @type {!WebInspector.ShortcutRegistry} */ WebInspector.shortcutRegistry;