Manages global application commands that can be called from menu items, key bindings, or subparts of the application.
This module dispatches these event(s):
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 = {};
}
Looks up and runs a global command. Additional arguments are passed to the command.
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;
});
Retrieves a Command object by id
function get(id) {
return _commands[id];
}
Returns the ids of all registered commands
function getAll() {
return Object.keys(_commands);
}
Registers a global 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.
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;
}
Events:
function Command(name, id, commandFn) {
this._name = name;
this._id = id;
this._commandFn = commandFn;
this._checked = undefined;
this._enabled = true;
}
EventDispatcher.makeEventDispatcher(Command.prototype);
Executes the command. Additional arguments are passed to the executing function
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 checked?
Command.prototype.getChecked = function () {
return this._checked;
};
Is command enabled?
Command.prototype.getEnabled = function () {
return this._enabled;
};
Get command name
Command.prototype.getName = function () {
return this._name;
};
Sets enabled state of Command and dispatches "checkedStateChange" when the enabled state changes.
Command.prototype.setChecked = function (checked) {
var changed = this._checked !== checked;
this._checked = checked;
if (changed) {
this.trigger("checkedStateChange");
}
};
Sets enabled state of Command and dispatches "enabledStateChange" when the enabled state changes.
Command.prototype.setEnabled = function (enabled) {
var changed = this._enabled !== enabled;
this._enabled = enabled;
if (changed) {
this.trigger("enabledStateChange");
}
};
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.
Command.prototype.setName = function (name) {
var changed = this._name !== name;
this._name = name;
if (changed) {
this.trigger("nameChange");
}
};