Caret/js/ui/contextMenus.js

72 lines
1.9 KiB
JavaScript
Raw Normal View History

define(function() {
//track all assigned context menus in order to respond
var registry = {};
//all context menus created here are handled via onClick
var onClick = function(info) {
var handler = registry[info.menuItemId];
if (handler) {
var params = handler.parse(info.linkUrl);
handler.callback(params);
}
};
//provides a chrome-extension:// URL for menus based on a filter string
var makeURL = function(filter, id) {
var url = "chrome-extension://" + chrome.runtime.id + "/" + filter;
if (typeof id != "undefined") {
url += "/" + id;
}
return url;
};
var createRoute = function(route, handler) {
var parts = route.split("/");
var positionMap = {};
var position = 1;
parts = parts.map(function(s) {
if (s[0] == ":") {
//set the key to be used on parsing
positionMap[position++] = s.replace(/^:/, "");
return "*";
}
return s.replace(/[\^()\[\]]/, function(match) { return "\\" + match });
});
var re = new RegExp(parts.map(function(s) { return s == "*" ? "([^\/]+)" : s }).join("\\/"));
var parser = function(url) {
var result = re.exec(url);
if (!result) return result;
var params = {};
for (var place in positionMap) {
var key = positionMap[place];
params[key] = result[place];
}
params.url = url;
return params;
}
return {
parse: parser,
regex: re,
url: makeURL(parts.join("/")),
callback: handler
};
}
chrome.contextMenus.onClicked.addListener(onClick);
return {
register: function(label, id, route, handler) {
var compiled = createRoute(route, handler);
registry[id] = compiled;
chrome.contextMenus.create({
title: label,
targetUrlPatterns: [ compiled.url ],
contexts: ["link"],
id: id
});
},
makeURL: makeURL
};
});