Added context menu module, wired up a 'remove directory' menu in projects.
This commit is contained in:
parent
631b02d724
commit
213346822b
3 changed files with 91 additions and 8 deletions
|
@ -7,6 +7,11 @@
|
|||
box-shadow: inset 4px 4px 16px rgba(0, 0, 0, .4);
|
||||
background: @background;
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
|
67
js/contextMenus.js
Normal file
67
js/contextMenus.js
Normal file
|
@ -0,0 +1,67 @@
|
|||
define(function() {
|
||||
|
||||
var registry = {};
|
||||
|
||||
var onClick = function(info) {
|
||||
var handler = registry[info.menuItemId];
|
||||
if (handler) {
|
||||
var params = handler.parse(info.linkUrl);
|
||||
handler.callback(params);
|
||||
}
|
||||
};
|
||||
|
||||
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 positions = {};
|
||||
parts = parts.map(function(s, i) {
|
||||
if (s[0] == ":") {
|
||||
//set the key to be used on parsing
|
||||
positions[i] = 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 positions) {
|
||||
var key = positions[place];
|
||||
params[key] = result[place];
|
||||
}
|
||||
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
|
||||
};
|
||||
|
||||
});
|
|
@ -5,18 +5,14 @@ define([
|
|||
"file",
|
||||
"manos",
|
||||
"dialog",
|
||||
"contextMenus",
|
||||
"dom2"
|
||||
], function(Settings, command, sessions, File, M, dialog) {
|
||||
], function(Settings, command, sessions, File, M, dialog, context) {
|
||||
|
||||
/*
|
||||
It's tempting to store projects in local storage, similar to the way that we retain files for tabs, but this would be a mistake. Reading from storage is a pain, because it wants to store a single level deep, and we'll want to alter parts of the setup individually.
|
||||
|
||||
Instead, we'll retain a single file handle to the project file, which (as JSON) will store the IDs of individual directories, the project-specific settings, and (hopefully, one day) build systems. This also gets us around the issues of restored directory order and constantly updating the retained file list--we'll just update it when the project file is saved.
|
||||
|
||||
TODO:
|
||||
1. Get open directories, navigation, etc working.
|
||||
2. Enable project file generation, loading, restoration
|
||||
3. Allow projects to create a settings layer
|
||||
*/
|
||||
|
||||
var guidCounter = 0;
|
||||
|
@ -55,6 +51,7 @@ define([
|
|||
reader.readEntries(collect);
|
||||
};
|
||||
var complete = function() {
|
||||
self.children = [];
|
||||
for (var i = 0; i < entries.length; i++) {
|
||||
var entry = entries[i];
|
||||
if (entry.name[0] == "." && entry.isDirectory) continue;
|
||||
|
@ -107,6 +104,12 @@ define([
|
|||
root.walk(self.render.bind(self));
|
||||
});
|
||||
},
|
||||
removeDirectory: function(args) {
|
||||
this.directories = this.directories.filter(function(node) {
|
||||
return node.id != args.id;
|
||||
});
|
||||
this.render();
|
||||
},
|
||||
removeAllDirectories: function() {
|
||||
this.directories = [];
|
||||
this.render();
|
||||
|
@ -134,7 +137,7 @@ define([
|
|||
var self = this;
|
||||
this.element.addClass("show");
|
||||
this.pathMap = {};
|
||||
var walker = function(node) {
|
||||
var walker = function(node, depth) {
|
||||
var li = document.createElement("li");
|
||||
var a = document.createElement("a");
|
||||
li.append(a);
|
||||
|
@ -142,6 +145,12 @@ define([
|
|||
a.innerHTML = node.label;
|
||||
a.setAttribute("data-full-path", node.entry.fullPath);
|
||||
a.addClass("directory");
|
||||
if (depth == 0) {
|
||||
a.href = context.makeURL("root", node.id);
|
||||
} else {
|
||||
a.href = context.makeURL("directory", node.id);
|
||||
}
|
||||
a.setAttribute("command", null);
|
||||
if (self.expanded[node.entry.fullPath]) {
|
||||
li.addClass("expanded");
|
||||
}
|
||||
|
@ -156,7 +165,7 @@ define([
|
|||
return 0;
|
||||
});
|
||||
for (var i = 0; i < node.children.length; i++) {
|
||||
ul.append(walker(node.children[i]));
|
||||
ul.append(walker(node.children[i], depth+1));
|
||||
}
|
||||
li.append(ul);
|
||||
} else {
|
||||
|
@ -330,5 +339,7 @@ define([
|
|||
command.on("project:open", pm.openProjectFile.bind(pm));
|
||||
command.on("project:edit", pm.editProjectFile.bind(pm));
|
||||
command.on("project:clear", pm.clearProject.bind(pm));
|
||||
|
||||
context.register("Remove from Project", "removeDirectory", "root/:id", pm.removeDirectory.bind(pm));
|
||||
|
||||
});
|
Loading…
Reference in a new issue