2013-12-04 17:24:04 +00:00
|
|
|
define([
|
2013-12-16 19:29:41 +00:00
|
|
|
"util/text!config/commands.json",
|
2013-12-04 17:24:04 +00:00
|
|
|
"util/dom2"
|
2013-12-16 19:29:41 +00:00
|
|
|
], function(list) {
|
|
|
|
|
2013-12-16 19:53:26 +00:00
|
|
|
try {
|
|
|
|
list = JSON.parse(list);
|
|
|
|
} catch (e) {
|
2013-12-16 22:28:25 +00:00
|
|
|
console.error(e);
|
2013-12-16 19:53:26 +00:00
|
|
|
list = [];
|
|
|
|
}
|
2013-08-22 06:35:47 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
|
2013-12-16 19:53:26 +00:00
|
|
|
The command module is the heart of Caret's loosely-coupled modules. It
|
|
|
|
serves as an event bus for inter-module communication, but it also listens
|
|
|
|
to the DOM for click/change events and makes it easy to bind page interactions
|
|
|
|
to command callbacks.
|
|
|
|
|
|
|
|
Command is usually called as if synchronous, but it does support asynchronous
|
|
|
|
operation--it will pass a callback in to any subscribers, but will also
|
|
|
|
immediately pass back the return value (if any) from the those subscribers.
|
2013-08-22 06:35:47 +00:00
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
var commands = {};
|
|
|
|
|
2013-11-25 01:53:55 +00:00
|
|
|
//commands can pass a callback, although most don't respond that way
|
|
|
|
var fire = function(command, argument, callback) {
|
2013-08-22 06:35:47 +00:00
|
|
|
if (!commands[command]) return;
|
2013-12-16 19:53:26 +00:00
|
|
|
var args = [].slice.call(arguments, 1);
|
2013-12-17 01:35:02 +00:00
|
|
|
//technically, a function as `argument` is a callback...
|
2013-12-16 19:53:26 +00:00
|
|
|
if (typeof argument == "function") {
|
|
|
|
callback = argument;
|
|
|
|
}
|
2013-09-02 01:26:22 +00:00
|
|
|
var registry = commands[command].slice();
|
|
|
|
registry.forEach(function(entry) {
|
2013-12-16 19:53:26 +00:00
|
|
|
var result = entry.callback.apply(null, args);
|
|
|
|
//immediately call back if sync-style return value was provided
|
2013-12-17 01:40:42 +00:00
|
|
|
if (typeof result !== "undefined" || entry.sync) {
|
2013-12-17 01:35:02 +00:00
|
|
|
//console.info("Immediate return from " + name, result);
|
|
|
|
if (callback) callback.call(null, result);
|
2013-12-16 19:53:26 +00:00
|
|
|
}
|
2013-09-02 01:26:22 +00:00
|
|
|
});
|
2014-02-27 06:34:02 +00:00
|
|
|
};
|
2013-08-22 06:35:47 +00:00
|
|
|
|
2013-12-17 01:40:42 +00:00
|
|
|
var register = function(command, listener, sync) {
|
2013-08-22 06:35:47 +00:00
|
|
|
if (!commands[command]) {
|
|
|
|
commands[command] = [];
|
|
|
|
}
|
2013-12-17 01:40:42 +00:00
|
|
|
//we allow a sync flag to be set for operations that will definitely return
|
2013-08-22 06:35:47 +00:00
|
|
|
commands[command].push({
|
2013-12-17 01:40:42 +00:00
|
|
|
callback: listener,
|
|
|
|
sync: sync
|
2013-08-22 06:35:47 +00:00
|
|
|
});
|
2014-02-27 06:34:02 +00:00
|
|
|
};
|
2014-01-12 09:12:14 +00:00
|
|
|
|
2013-08-22 06:35:47 +00:00
|
|
|
//delegate for all elements that have a command attribute
|
|
|
|
document.body.on("click", function(e) {
|
2013-08-23 23:03:46 +00:00
|
|
|
//cancel on inputs, selectboxes
|
|
|
|
if (["input", "select"].indexOf(e.target.tagName.toLowerCase()) >= 0) return;
|
2013-12-21 06:02:54 +00:00
|
|
|
if (e.button != 0) return;
|
2013-08-22 06:35:47 +00:00
|
|
|
//delegate all items with a command attribute
|
|
|
|
if (e.target.hasAttribute("command")) {
|
|
|
|
var command = e.target.getAttribute("command");
|
|
|
|
var arg = e.target.getAttribute("argument");
|
|
|
|
fire(command, arg);
|
2013-11-06 17:55:11 +00:00
|
|
|
e.preventDefault();
|
2013-08-22 06:35:47 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2013-08-23 23:03:46 +00:00
|
|
|
document.body.on("change", function(e) {
|
|
|
|
if (e.target.hasAttribute("command")) {
|
|
|
|
var command = e.target.getAttribute("command");
|
|
|
|
var arg = e.target.value;
|
|
|
|
fire(command, arg);
|
|
|
|
}
|
|
|
|
});
|
2014-07-22 18:51:29 +00:00
|
|
|
|
|
|
|
//handle command events directly dispatched via DOM
|
|
|
|
document.body.on("caret-command", function(e) {
|
|
|
|
if (!e.detail || !e.detail.command) return;
|
|
|
|
fire(e.detail.command, e.detail.argument);
|
|
|
|
});
|
2014-01-12 09:12:14 +00:00
|
|
|
|
2014-01-12 23:35:30 +00:00
|
|
|
//register for post-startup and fire any commands that are pending
|
|
|
|
register("init:complete", function() {
|
|
|
|
if (window.launchCommands) {
|
|
|
|
window.launchCommands.forEach(function(bundle) {
|
|
|
|
fire(bundle.message.command, bundle.message.argument, bundle.sendResponse);
|
|
|
|
});
|
|
|
|
delete window.launchCommands;
|
|
|
|
}
|
2014-01-11 06:15:35 +00:00
|
|
|
});
|
|
|
|
|
2013-12-16 16:51:56 +00:00
|
|
|
var facade = {
|
2013-08-22 06:35:47 +00:00
|
|
|
fire: fire,
|
2013-12-16 16:51:56 +00:00
|
|
|
on: register,
|
2013-12-16 19:53:26 +00:00
|
|
|
list: list
|
2013-08-22 06:35:47 +00:00
|
|
|
};
|
2013-12-16 16:51:56 +00:00
|
|
|
|
|
|
|
return facade;
|
2013-08-22 06:35:47 +00:00
|
|
|
|
|
|
|
});
|