/
githubmirror
/
brackets
Обзор
Документация
Войти
/
githubmirror
/
brackets
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
release-1.8
src/command/CommandManager.js
303 строки
10 KB
ficristo
Move most inline jslint directives to config files
12 авг 2016, 10:22
12 авг 2016, 10:22
074382a
Код
Авторство
О чём код?
/* * Copyright (c) 2012 - present Adobe Systems Incorporated. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * */ /** * Manages global application commands that can be called from menu items, key bindings, or subparts * of the application. * * This module dispatches these event(s): * - commandRegistered -- when a new command is registered * - beforeExecuteCommand -- before dispatching a command */ define(function (require, exports, module) { "use strict"; var EventDispatcher = require("utils/EventDispatcher"); /** * Map of all registered global commands * @type {Object.<commandID: string, Command>} */ var _commands = {}; /** * Temporary copy of commands map for restoring after testing * TODO (issue #1039): implement separate require contexts for unit tests * @type {Object.<commandID: string, Command>} */ var _commandsOriginal = {}; /** * Events: * - enabledStateChange * - checkedStateChange * - keyBindingAdded * - keyBindingRemoved * * @constructor * @private * @param {string} name - text that will be displayed in the UI to represent command * @param {string} id * @param {function} commandFn - the function that is called when the command is executed. * * TODO: where should this be triggered, The Command or Exports? */ function Command(name, id, commandFn) { this._name = name; this._id = id; this._commandFn = commandFn; this._checked = undefined; this._enabled = true; } EventDispatcher.makeEventDispatcher(Command.prototype); /** * Get command id * @return {string} */ Command.prototype.getID = function () { return this._id; }; /** * Executes the command. Additional arguments are passed to the executing function * * @return {$.Promise} a jQuery promise that will be resolved when the command completes. */ Command.prototype.execute = function () { if (!this._enabled) { return (new $.Deferred()).reject().promise(); } var result = this._commandFn.apply(this, arguments); if (!result) { // If command does not return a promise, assume that it handled the // command and return a resolved promise return (new $.Deferred()).resolve().promise(); } else { return result; } }; /** * Is command enabled? * @return {boolean} */ Command.prototype.getEnabled = function () { return this._enabled; }; /** * Sets enabled state of Command and dispatches "enabledStateChange" * when the enabled state changes. * @param {boolean} enabled */ Command.prototype.setEnabled = function (enabled) { var changed = this._enabled !== enabled; this._enabled = enabled; if (changed) { this.trigger("enabledStateChange"); } }; /** * Sets enabled state of Command and dispatches "checkedStateChange" * when the enabled state changes. * @param {boolean} checked */ Command.prototype.setChecked = function (checked) { var changed = this._checked !== checked; this._checked = checked; if (changed) { this.trigger("checkedStateChange"); } }; /** * Is command checked? * @return {boolean} */ Command.prototype.getChecked = function () { return this._checked; }; /** * Sets the name of the Command and dispatches "nameChange" so that * UI that reflects the command name can update. * * Note, a Command name can appear in either HTML or native UI * so HTML tags should not be used. To add a Unicode character, * use \uXXXX instead of an HTML entity. * * @param {string} name */ Command.prototype.setName = function (name) { var changed = this._name !== name; this._name = name; if (changed) { this.trigger("nameChange"); } }; /** * Get command name * @return {string} */ Command.prototype.getName = function () { return this._name; }; /** * Registers a global command. * @param {string} name - text that will be displayed in the UI to represent command * @param {string} id - unique identifier for command. * Core commands in Brackets use a simple command title as an id, for example "open.file". * Extensions should use the following format: "author.myextension.mycommandname". * For example, "lschmitt.csswizard.format.css". * @param {function(...)} commandFn - the function to call when the command is executed. Any arguments passed to * execute() (after the id) are passed as arguments to the function. If the function is asynchronous, * it must return a jQuery promise that is resolved when the command completes. Otherwise, the * CommandManager will assume it is synchronous, and return a promise that is already resolved. * @return {?Command} */ function register(name, id, commandFn) { if (_commands[id]) { console.log("Attempting to register an already-registered command: " + id); return null; } if (!name || !id || !commandFn) { console.error("Attempting to register a command with a missing name, id, or command function:" + name + " " + id); return null; } var command = new Command(name, id, commandFn); _commands[id] = command; exports.trigger("commandRegistered", command); return command; } /** * Registers a global internal only command. * @param {string} id - unique identifier for command. * Core commands in Brackets use a simple command title as an id, for example "app.abort_quit". * Extensions should use the following format: "author.myextension.mycommandname". * For example, "lschmitt.csswizard.format.css". * @param {function(...)} commandFn - the function to call when the command is executed. Any arguments passed to * execute() (after the id) are passed as arguments to the function. If the function is asynchronous, * it must return a jQuery promise that is resolved when the command completes. Otherwise, the * CommandManager will assume it is synchronous, and return a promise that is already resolved. * @return {?Command} */ function registerInternal(id, commandFn) { if (_commands[id]) { console.log("Attempting to register an already-registered command: " + id); return null; } if (!id || !commandFn) { console.error("Attempting to register an internal command with a missing id, or command function: " + id); return null; } var command = new Command(null, id, commandFn); _commands[id] = command; exports.trigger("commandRegistered", command); return command; } /** * Clear all commands for unit testing, but first make copy of commands so that * they can be restored afterward */ function _testReset() { _commandsOriginal = _commands; _commands = {}; } /** * Restore original commands after test and release copy */ function _testRestore() { _commands = _commandsOriginal; _commandsOriginal = {}; } /** * Retrieves a Command object by id * @param {string} id * @return {Command} */ function get(id) { return _commands[id]; } /** * Returns the ids of all registered commands * @return {Array.<string>} */ function getAll() { return Object.keys(_commands); } /** * Looks up and runs a global command. Additional arguments are passed to the command. * * @param {string} id The ID of the command to run. * @return {$.Promise} a jQuery promise that will be resolved when the command completes. */ function execute(id) { var command = _commands[id]; if (command) { try { exports.trigger("beforeExecuteCommand", id); } catch (err) { console.error(err); } return command.execute.apply(command, Array.prototype.slice.call(arguments, 1)); } else { return (new $.Deferred()).reject().promise(); } } EventDispatcher.makeEventDispatcher(exports); // Define public API exports.register = register; exports.registerInternal = registerInternal; exports.execute = execute; exports.get = get; exports.getAll = getAll; exports._testReset = _testReset; exports._testRestore = _testRestore; });