diff --git a/plugins/c9.ide.plugins/manager.js b/plugins/c9.ide.plugins/manager.js
index 074fe4e5..39220834 100644
--- a/plugins/c9.ide.plugins/manager.js
+++ b/plugins/c9.ide.plugins/manager.js
@@ -79,7 +79,7 @@ define(function(require, exports, module) {
var emit = plugin.getEmitter();
var model, datagrid, filterbox;
- var btnUninstall, btnServices, btnReadme, btnReload;
+ var btnInstall, btnUninstall, btnServices, btnReadme, btnReload;
var btnReloadLast;
var localPlugins;
var disabledPlugins = Object.create(null);
@@ -115,13 +115,13 @@ define(function(require, exports, module) {
}
}, plugin);
- menus.addItemByPath("Tools/Developer/Open Plugin Manager", new ui.item({
+ menus.addItemByPath("Tools/Developer/Open Plugin Explorer", new ui.item({
command: "openPluginManager"
}), 1100, plugin);
if (DEBUG) {
notify("
You are in
Debug Mode. "
- + "
"
+ + "
"
+ "
",
false);
@@ -163,10 +163,20 @@ define(function(require, exports, module) {
setTimeout(reloadModel);
});
- if (DEBUG && sessionStorage.localPackages) {
- loadPackage(
- util.safeParseJson(sessionStorage.localPackages) || []
- );
+ if (DEBUG) {
+ if (sessionStorage.localPackages) {
+ loadPackage(
+ util.safeParseJson(sessionStorage.localPackages) || []
+ );
+ }
+ var updateSessionStorage = function() {
+ sessionStorage.localPackages = JSON.stringify(Object.keys(packages).map(function(x) {
+ if (packages[x] && packages[x].fromVfs && packages[x].enabled)
+ return packages[x].filePath;
+ }).filter(Boolean));
+ };
+ plugin.on("enablePackage", updateSessionStorage);
+ plugin.on("disablePackage", updateSessionStorage);
}
}
@@ -183,9 +193,6 @@ define(function(require, exports, module) {
model.columns = [{
caption: "Name",
value: "name",
- // getText: function(p) {
- // return p.name + " (" + p.items.length + ")";
- // },
width: "250",
type: "tree"
}, {
@@ -261,33 +268,27 @@ define(function(require, exports, module) {
}
}),
new ui.filler({}),
+ btnInstall = new ui.button({
+ skin: "c9-toolbarbutton-glossy",
+ caption: "Enable",
+ class: "btn-red",
+ onclick: function() {
+ reloadGridSelection(true);
+ }
+ }),
btnUninstall = new ui.button({
skin: "c9-toolbarbutton-glossy",
caption: "Disable",
class: "btn-red",
onclick: function() {
- var item = datagrid.selection.getCursor();
- if (item.packageConfig) {
- if (item.enabled)
- unloadPackage(item.packageConfig);
- else
- loadPackage(item.packageConfig);
- }
- else {
- if (item.enabled)
- unloadPlugins(item);
- else
- loadPlugins(item);
- }
+ reloadGridSelection(false);
}
}),
btnReload = new ui.button({
skin: "c9-toolbarbutton-glossy",
caption: "Reload",
onclick: function() {
- var item = datagrid.selection.getCursor();
- if (item.name)
- reload(item.name);
+ reloadGridSelection();
}
})
]
@@ -369,17 +370,18 @@ define(function(require, exports, module) {
var readmeCache = {};
function renderDetails() {
var items = datagrid.selection.getSelectedNodes();
- var enabled = items.every(function(x) {
- return x.enabled == 1;
+ var hasEnabled = 0;
+ var hasDisabled = 0;
+ items.forEach(function(x) {
+ if (x.enabled) {
+ hasEnabled = true;
+ } else {
+ hasDisabled = true;
+ }
});
- if (enabled) {
- btnReload.enable();
- btnUninstall.setCaption("Disable");
- }
- else {
- btnReload.disable();
- btnUninstall.setCaption("Enable");
- }
+ btnUninstall.setProperty("visible", hasEnabled);
+ btnInstall.setProperty("visible", hasDisabled);
+
if (mode == "services") {
renderServiceDetails(items);
btnServices.$ext.classList.add("serviceButtonActive");
@@ -395,6 +397,13 @@ define(function(require, exports, module) {
btnReadme.$ext.classList.remove("serviceButtonActive");
btnServices.$ext.classList.remove("serviceButtonActive");
}
+
+ if (items.length == 1 && items[0].__error) {
+ var errorContainer = document.createElement("div");
+ errorContainer.style.cssText = "padding: 5px; white-space: pre-wrap";
+ errorContainer.textContent = items[0].__error.message;
+ descriptionBar.$ext.insertBefore(errorContainer, descriptionBar.$ext.firstChild);
+ }
}
function renderReadmeDetails(items) {
@@ -403,7 +412,7 @@ define(function(require, exports, module) {
return;
}
var item = items[0];
- while (item && !item.packageOptions) {
+ while (item && !item.packageConfig) {
item = item.parent;
}
if (!item) {
@@ -411,24 +420,27 @@ define(function(require, exports, module) {
return;
}
- if (readmeCache[item.readmePath]) {
- descriptionBar.$ext.textContent = readmeCache[item.readmePath];
- return;
- }
- descriptionBar.$ext.textContent = "Loading...";
- var parts = item.filePath.split("/");
- parts.pop();
- parts.push("README.md");
- var path = parts.join("/");
- fs.readFile(path, function(e, v) {
- if (e)
- return descriptionBar.$ext.textContent = "Readme is not available.";
+ if (readmeCache[item.name]) {
var div = document.createElement("div");
- div.textContent = v;
+ div.textContent = readmeCache[item.name];
div.style.cssText = "padding: 5px; white-space: pre-wrap";
descriptionBar.$ext.textContent = "";
descriptionBar.$ext.appendChild(div);
- });
+ return;
+ }
+ descriptionBar.$ext.textContent = "Loading...";
+ if (item.packageConfig.filePath) {
+ var parts = item.packageConfig.filePath.split("/");
+ parts.pop();
+ parts.push("README.md");
+ var path = parts.join("/");
+ fs.readFile(path, function(e, v) {
+ if (e)
+ return readmeCache[item.name] = "Readme is not available.";
+ readmeCache[item.name] = v;
+ renderDetails();
+ });
+ }
}
function renderServiceDetails(items) {
@@ -486,20 +498,21 @@ define(function(require, exports, module) {
}
descriptionBar.$ext.style.overflow = "auto";
- descriptionBar.$ext.innerHTML = '
\
-
' + (items.length == 1
- ? '' + escapeHTML(items[0].path) + ''
- : (items.length || "no") + " plugins selected") + '
\
-
\
-
Provided services [' + provided.length + ']
\
+ var serviceDesc = '
Provided services [' + provided.length + ']
\
' + (provided.length ? formatServices(provided) : "") + '
\
Consumed services [' + (consumedList.length - provided.length) + ']
\
' + consumedGroups.map(formatServices).join("
") + '
\
Dependent services [' + (depList.length - provided.length) + ']
\
' + depGroups.map(formatServices).join("
") + '
\
-
\
-
';
+
';
+ descriptionBar.$ext.innerHTML = '
\
+
' + (items.length == 1
+ ? '' + escapeHTML(items[0].path) + ''
+ : (items.length || "no") + " plugins selected") + '
\
+
'
+ + (items.length ? serviceDesc : "")
+ + '
';
}
descriptionBar.$ext.addEventListener("click", function(e) {
@@ -588,14 +601,15 @@ define(function(require, exports, module) {
menus.addItemByPath("context/pluginManager/Reveal in File Tree", new ui.item({
isAvailable: function() {
var selected = datagrid.selection.getCursor();
- return selected && selected.filePath;
+ return selected && selected.packageConfig && selected.packageConfig.filePath;
},
onclick: function() {
var selected = datagrid.selection.getCursor();
var tabbehavior = architectApp.services.tabbehavior;
- if (selected.filePath) {
- tabbehavior.revealtab({ path: selected.filePath });
+ var filePath = selected.packageConfig && selected.packageConfig.filePath;
+ if (filePath) {
+ tabbehavior.revealtab({ path: filePath });
}
},
}), plugin);
@@ -634,7 +648,7 @@ define(function(require, exports, module) {
}
var GROUPS = {
- "changed": "Recently Changed",
+ // "changed": "Recently Changed",
"remote": "Remote Plugins",
"vfs": "Locally Installed Plugins",
"pre": "Pre-installed Plugins",
@@ -690,35 +704,51 @@ define(function(require, exports, module) {
}
node = node.map[p];
node.className = plugin.__error ? "load-error" : "";
+ node.__error = plugin.__error;
});
}
}
+ function addPackage(name) {
+ var pkg = packages[name];
+ var parent = pkg.filePath ? groups.vfs : groups.remote;
+
+ var node = parent.map[name] = parent.map[name] || {
+ path: "plugins/" + name,
+ name: name,
+ enabled: 0,
+ parent: parent,
+ };
+
+ node.packageConfig = pkg;
+ node.className = pkg.__error ? "load-error" : "";
+ node.__error = pkg.__error;
+ }
+
architectApp.config.forEach(function(plugin) {
var node = CORE[plugin.packagePath] ? groups.core : groups.pre;
addPlugin(plugin, node);
});
if (localPlugins) {
- localPlugins.forEach(function(x) {
- groups.vfs.map[x] = groups.vfs.map[x] || {
- filePath: "~/.c9/plugins/" + x + "/package.json",
- path: "plugins/" + x,
- name: x,
- enabled: 0,
- parent: groups.vfs,
- packageOptions: {
- name: x,
+ localPlugins.forEach(function(name) {
+ if (!packages[name]) {
+ packages[name] = {
+ name: name,
+ filePath: "~/.c9/plugins/" + name + "/package.json",
}
- };
+ }
+
});
}
Object.keys(packages).forEach(function(n) {
- var node = groups.vfs;
var pkg = packages[n];
+ var node = pkg.filePath ? groups.vfs : groups.remote;
- if (pkg.c9.plugins) {
+ addPackage(n);
+
+ if (pkg.c9 && pkg.c9.plugins) {
pkg.c9.plugins.forEach(function(plugin) {
addPlugin(plugin, node);
});
@@ -738,12 +768,13 @@ define(function(require, exports, module) {
if (node.parent && node.parent.items[index] == node) {
node.parent.items[index] = other;
other.name = node.name + "/" + other.name;
- other.packageOptions = node.packageOptions;
+ other.packageConfig = node.packageConfig;
other.filePath = node.filePath;
other.url = node.url;
}
}
if (!node.isGroup) {
+ node.enabled = null;
node.items.some(function(i) {
if (node.enabled == null) {
node.enabled = i.enabled;
@@ -877,6 +908,25 @@ define(function(require, exports, module) {
updateReloadLastButton();
}
+ function reloadGridSelection(mode) {
+ var nodes = datagrid.selection.getSelectedNodes();
+ console.log(nodes, mode);
+ nodes.forEach(function(node) {
+ if (node.packageConfig) {
+ if (!mode)
+ unloadPackage(node.packageConfig.name);
+ if (mode != false)
+ loadPackage(node.packageConfig.filePath);
+ }
+ else {
+ if (!mode)
+ unloadPlugins({ path: node.path });
+ if (mode != false)
+ loadPlugins({ path: node.path });
+ }
+ });
+ }
+
function updateReloadLastButton() {
var last = getLastReloaded();
if (last) {
@@ -961,6 +1011,142 @@ define(function(require, exports, module) {
}
function unloadPackage(options, callback) {
+ if (Array.isArray(options))
+ return async.map(options, unloadPackage, callback || function() {});
+ var name = typeof options == "object" ? options.name : options;
+ if (packages[name]) {
+ packages[name].enabled = false;
+ unloadPlugins(packages[name].path);
+ emit("disablePackage");
+ }
+ }
+
+ function loadPackage(options, callback) {
+ if (Array.isArray(options))
+ return async.map(options, loadPackage, callback || function() {});
+
+ if (typeof options == "string") {
+ options = /^https?:/.test(options)
+ ? { url: options }
+ : { path: options };
+ }
+
+ if (!options.url && options.path)
+ options.url = vfs.url(options.path);
+
+ var parts = options.url.split("/");
+ var root = parts.pop();
+ options.url = parts.join("/");
+
+ if (!options.name) {
+ options.name = parts[parts.length - 1];
+ if (options.name == "build")
+ options.name = parts[parts.length - 2];
+ options.name = options.name.replace(/@.*$/, "");
+ }
+ if (!options.packageName)
+ options.packageName = root;
+
+ if (!options.rootDir)
+ options.rootDir = "plugins";
+
+ var name = options.name;
+ var id = options.rootDir + "/" + name;
+ var pathMappings = {};
+
+ unloadPlugins("plugins/" + options.name);
+
+ pathMappings[id] = options.url;
+ requirejs.config({ paths: pathMappings });
+ requirejs.undef(id + "/", true);
+
+ if (/\.js$/.test(root)) {
+ require([options.url + "/" + root], function(json) {
+ json = json || require(options.id + "/" + options.packageName);
+ getPluginsFromPackage(json, callback);
+ }, function(err) {
+ addError("Error loading plugin", err);
+ });
+ }
+ else if (options.path && /\.json$/.test(root)) {
+ fs.readFile(options.path, function(err, value) {
+ if (err) return addError("Error reading " + options.path, err);
+ try {
+ var json = JSON.parse(value);
+ } catch (e) {
+ return addError("Error parsing package.json", e);
+ }
+ json.fromVfs = true;
+ getPluginsFromPackage(json, callback);
+ });
+ }
+ else if (options.url && /\.json$/.test(root)) {
+ require(["text!" + options.id + "/" + root], function(value) {
+ try {
+ var json = JSON.parse(value);
+ } catch (e) {
+ return addError("Error parsing package.json", e);
+ }
+ getPluginsFromPackage(json, callback);
+ }, function(err) {
+ addError("Error loading plugin", err);
+ });
+ }
+ else {
+ callback && callback(new Error("Missing path and url"));
+ }
+
+ function addError(message, err) {
+ if (!packages[name])
+ packages[name] = {};
+ packages[name].filePath = options.path;
+ packages[name].url = options.url;
+ packages[name].__error = new Error(message + "\n" + err.message);
+
+ reloadModel();
+
+ callback && callback(err);
+ }
+
+ function getPluginsFromPackage(json, callback) {
+ var plugins = [];
+ if (json.name != name)
+ json.name = name;
+
+ if (json.plugins) {
+ Object.keys(json.plugins).forEach(function(name) {
+ var plugin = json.plugins[name];
+ if (typeof plugin == "string")
+ plugin = { packagePath: plugin };
+ if (!plugin.packagePath)
+ plugin.packagePath = id + "/" + name;
+ plugin.staticPrefix = options.url;
+ plugins.push(plugin);
+ });
+ }
+
+ packages[json.name] = json;
+ json.filePath = options.path;
+ json.url = options.url;
+
+ if (!json.c9)
+ json.c9 = {};
+ json.c9.plugins = plugins;
+ json.enabled = true;
+ json.path = id;
+
+ emit("enablePackage", json);
+ loadPlugins(plugins, callback);
+ }
+ }
+
+ function loadPlugins(plugins, callback) {
+ architectApp.loadAdditionalPlugins(plugins, function(err) {
+ callback && callback && callback(err);
+ });
+ }
+
+ function unloadPlugins(options, callback) {
var toUnload = Object.create(null);
var config = getAllPlugins();
function addPath(path) {
@@ -973,6 +1159,9 @@ define(function(require, exports, module) {
}
});
}
+ if (typeof options == "string") {
+ addPath(options);
+ }
if (options.path) {
addPath(options.path);
}
@@ -1020,102 +1209,6 @@ define(function(require, exports, module) {
reloadModel();
}
- function loadPackage(options, callback) {
- // 1 {url, }
- // 2
- if (Array.isArray(options))
- return async.map(options, loadPackage, callback);
-
- if (typeof options == "string") {
- options = /^https?:/.test(options)
- ? { path: options }
- : { url: options };
- }
-
- if (!options.url && options.path)
- options.url = vfs.url(options.path);
-
- var parts = options.url.split("/");
- var root = parts.pop();
- options.url = parts.join("/");
-
- if (!options.name) {
- options.name = parts[parts.length - 1];
- if (options.name == "build")
- options.name = parts[parts.length - 2];
- options.name = options.name.replace(/@.*$/, "");
- }
- if (!options.packageName)
- options.packageName = root;
-
- if (!options.rootDir)
- options.rootDir = "plugins";
-
- var id = options.rootDir + "/" + options.name;
- var pathMappings = {};
-
- pathMappings[id] = options.url;
- requirejs.config({ paths: pathMappings });
- requirejs.undef(id + "/", true);
-
- if (/\.js$/.test(root)) {
- require([options.url + "/" + root], function(json) {
- json = json || require(options.id + "/" + options.packageName);
- getPluginsFromPackage(json, callback);
- }, function(err) {
- callback && callback(err);
- });
- }
- else if (options.path && /\.json$/.test(root)) {
- fs.readFile(options.path, function(e, value) {
- try {
- var json = JSON.parse(value);
- } catch (e) {
- return callback(e);
- }
- getPluginsFromPackage(json, callback);
- });
- }
- else {
- callback(new Error("Missing path and url"));
- }
-
- function getPluginsFromPackage(json, callback) {
- var plugins = [];
- if (json.name != options.name)
- json.name = options.name;
-
- if (json.plugins) {
- Object.keys(json.plugins).forEach(function(name) {
- var plugin = json.plugins[name];
- if (typeof plugin == "string")
- plugin = { packagePath: plugin };
- if (!plugin.packagePath)
- plugin.packagePath = id + "/" + name;
- plugin.staticPrefix = options.url;
- plugins.push(plugin);
- });
- }
-
- packages[json.name] = json;
- if (!json.c9)
- json.c9 = {};
- json.c9.plugins = plugins;
-
- loadPlugins(plugins, callback);
- }
- }
-
- function loadPlugins(plugins, callback) {
- architectApp.loadAdditionalPlugins(plugins, function(err) {
- callback && callback(err);
- });
- }
-
- function unloadPlugins() {
-
- }
-
function cleanupCache(packagePath) {
var options = architectApp.pathToPackage[packagePath];
var url = require.toUrl(options.packagePath, ".js");
@@ -1223,6 +1316,7 @@ define(function(require, exports, module) {
model = null;
datagrid = null;
filterbox = null;
+ btnInstall = null;
btnUninstall = null;
localPlugins = null;
disabledPlugins = null;
@@ -1258,6 +1352,12 @@ define(function(require, exports, module) {
*
*/
reload: reload,
+
+ /*
+ * @ignore
+ */
+ get datagrid() { return datagrid; },
+ get packages() { return packages; },
});
var shim = new Plugin();
diff --git a/plugins/c9.ide.plugins/style.css b/plugins/c9.ide.plugins/style.css
index aefe7261..764a247f 100644
--- a/plugins/c9.ide.plugins/style.css
+++ b/plugins/c9.ide.plugins/style.css
@@ -12,5 +12,5 @@
text-decoration : underline;
}
.tree-row.load-error {
- color: #e44;
+ color: #f99145;
}