Skip to content

Instantly share code, notes, and snippets.

@ggoodman
Created April 4, 2014 18:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ggoodman/9980121 to your computer and use it in GitHub Desktop.
Save ggoodman/9980121 to your computer and use it in GitHub Desktop.
Angular commander
var _ = require("lodash");
module.exports =
angular.module("plunker.service.commander", [])
.factory("commander", [ "$q", "$injector", function ($q, $injector) {
var commands = {};
var service = {
addCommand: addCommand,
addInterceptor: addInterceptor,
addHotkey: addHotkey,
execute: executeCommand,
removeInterceptor: removeInterceptor
};
return service;
function addCommand (commandDef) {
commands[commandDef.name] = {
handler: commandDef.handler,
defaults: commandDef.defaults || {},
hotkeys: [],
interceptors: []
};
if (commandDef.hotkeys) this.addHotkey(commandDef.name, commandDef.hotkeys);
if (commandDef.scope) {
commandDef.scope.$on("$destroy", function () {
delete commands[commandDef.name];
});
}
}
function addHotkey (commandId, hotkey, defaults) {
var command = commands[commandId];
if (!defaults) defaults = {};
if (!command) throw new Error("Unable to run non-existent command: " + commandId);
Mousetrap.bind(hotkey, function (event, hotkey) {
$q.when(angular.isObject(defaults) ? defaults : $injector.invoke(command)).then(function (defaults) {
executeCommand(commandId, _.defaults(defaults, {event: event, hotkey: hotkey}));
});
return false;
});
command.hotkeys.push(hotkey);
}
function addInterceptor (commandId, interceptor) {
if (!commands[commandId]) throw new Error("Unable to add interceptor to a non-existent command: " + commandId);
commands[commandId].interceptors.push(interceptor);
}
function executeCommand (commandId, locals) {
var commandDef = commands[commandId];
if (!commandDef) throw new Error("Unable to run non-existent command: " + commandId);
if (!locals) locals = {};
var defaultsPromise = angular.isObject(commandDef.defaults) ? commandDef.defaults : $injector.invoke(commandDef.defaults, commandDef);
return $q.when(defaultsPromise).then(function (defaults) {
var interceptors = angular.copy(commandDef.interceptors);
locals = _.defaults(locals, defaults);
return nextInterceptor();
function nextInterceptor () {
return interceptors.length
? $q.when($injector.invoke(interceptors.shift(), {}, {commandId: commandId, locals: locals})).then(nextInterceptor)
: $q.when($injector.invoke(commandDef.handler, {}, locals));
}
});
}
function removeInterceptor (commandId, interceptor) {
var command = commands[commandId];
if (!command) throw new Error("Unable to remove interceptor for non-existent command: " + commandId);
var idx = command.interceptors.indexOf(interceptor);
if (idx >= 0) command.interceptors.splice(idx, 1);
}
}]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment