2015-02-10 19:41:24 +00:00
|
|
|
/*global requirejs*/
|
|
|
|
define(function(require, exports, module) {
|
|
|
|
main.consumes = [
|
|
|
|
"Plugin", "vfs", "fs", "plugin.loader", "c9", "ext", "watcher",
|
2015-11-29 14:50:48 +00:00
|
|
|
"dialog.notification", "dialog.info", "ui", "menus", "commands", "settings", "auth",
|
2015-09-15 05:22:43 +00:00
|
|
|
"installer", "find", "util", "preferences.experimental"
|
2015-02-10 19:41:24 +00:00
|
|
|
];
|
|
|
|
main.provides = ["plugin.debug"];
|
|
|
|
return main;
|
|
|
|
|
|
|
|
function main(options, imports, register) {
|
|
|
|
var Plugin = imports.Plugin;
|
|
|
|
var vfs = imports.vfs;
|
|
|
|
var watcher = imports.watcher;
|
|
|
|
var ext = imports.ext;
|
2015-04-03 00:38:55 +00:00
|
|
|
var util = imports.util;
|
|
|
|
var find = imports.find;
|
2015-02-10 19:41:24 +00:00
|
|
|
var ui = imports.ui;
|
|
|
|
var menus = imports.menus;
|
2015-04-02 17:35:43 +00:00
|
|
|
var installer = imports.installer;
|
2015-02-10 19:41:24 +00:00
|
|
|
var settings = imports.settings;
|
|
|
|
var commands = imports.commands;
|
|
|
|
var fs = imports.fs;
|
|
|
|
var c9 = imports.c9;
|
|
|
|
var auth = imports.auth;
|
|
|
|
var loader = imports["plugin.loader"];
|
|
|
|
var notify = imports["dialog.notification"].show;
|
2015-09-15 05:22:43 +00:00
|
|
|
var experimental = imports["preferences.experimental"];
|
2015-11-29 14:50:48 +00:00
|
|
|
var showInfo = imports["dialog.info"].show;
|
2015-02-10 19:41:24 +00:00
|
|
|
|
|
|
|
var dirname = require("path").dirname;
|
2015-04-16 23:53:16 +00:00
|
|
|
var basename = require("path").basename;
|
2015-02-10 19:41:24 +00:00
|
|
|
var join = require("path").join;
|
2015-04-03 00:38:55 +00:00
|
|
|
var async = require("async");
|
2015-02-10 19:41:24 +00:00
|
|
|
|
|
|
|
var architect;
|
|
|
|
|
|
|
|
/***** Initialization *****/
|
|
|
|
|
|
|
|
var plugin = new Plugin("Ajax.org", main.consumes);
|
2015-04-20 23:51:50 +00:00
|
|
|
var emit = plugin.getEmitter();
|
|
|
|
|
|
|
|
var plugins = [];
|
2015-02-10 19:41:24 +00:00
|
|
|
|
|
|
|
var ENABLED = c9.location.indexOf("debug=2") > -1;
|
2015-11-11 11:59:56 +00:00
|
|
|
var HASSDK = experimental.addExperiment("sdk", false, "SDK/Load Custom Plugins");;
|
2015-02-10 19:41:24 +00:00
|
|
|
|
2015-05-06 15:14:31 +00:00
|
|
|
var reParts = /^(builders|keymaps|modes|outline|runners|snippets|themes)\/(.*)/;
|
2015-06-28 13:06:07 +00:00
|
|
|
var reModule = /(?:_highlight_rules|_test|_worker|_fold|_behaviou?r)\.js$/;
|
|
|
|
var jsExtRe = /\.js$/;
|
2015-04-03 00:38:55 +00:00
|
|
|
|
2015-02-10 19:41:24 +00:00
|
|
|
var loaded = false;
|
|
|
|
function load() {
|
|
|
|
if (loaded) return false;
|
|
|
|
loaded = true;
|
|
|
|
|
|
|
|
if (!HASSDK) return;
|
|
|
|
|
|
|
|
menus.addItemByPath("Tools/~", new ui.divider(), 100000, plugin);
|
|
|
|
menus.addItemByPath("Tools/Developer", null, 100100, plugin);
|
2015-04-21 02:01:11 +00:00
|
|
|
|
|
|
|
if (!ENABLED) {
|
|
|
|
menus.addItemByPath("Tools/Developer/Start in Debug Mode", new ui.item({
|
|
|
|
onclick: function(){
|
|
|
|
var url = location.href + (location.href.indexOf("?") > -1
|
|
|
|
? "&debug=2"
|
|
|
|
: "?debug=2");
|
|
|
|
window.open(url);
|
|
|
|
}
|
|
|
|
}), 900, plugin);
|
|
|
|
}
|
2015-02-10 19:41:24 +00:00
|
|
|
|
|
|
|
if (!ENABLED) return;
|
|
|
|
|
|
|
|
notify("<div class='c9-readonly'>You are in <span style='color:rgb(245, 234, 15)'>Debug</span> Mode. "
|
|
|
|
+ "Don't forget to open the browser's dev tools to see any errors.",
|
|
|
|
false);
|
|
|
|
|
|
|
|
// Insert relevant LESS libraries
|
|
|
|
var theme = settings.get("user/general/@skin");
|
|
|
|
|
|
|
|
ui.defineLessLibrary(require("text!../c9.ide.layout.classic/themes/default-" + theme + ".less"), plugin);
|
|
|
|
ui.defineLessLibrary(require("text!../c9.ide.layout.classic/less/lesshat.less"), plugin);
|
|
|
|
|
|
|
|
fs.readdir("~/.c9/plugins", function(err, list){
|
|
|
|
if (err) return console.error(err);
|
|
|
|
|
|
|
|
var names = loader.plugins;
|
|
|
|
var toLoad = [];
|
|
|
|
|
|
|
|
list.forEach(function(stat){
|
|
|
|
var name = stat.name;
|
|
|
|
// If the plugin doesn't exist
|
2015-02-11 23:23:40 +00:00
|
|
|
if (names.indexOf(name) == -1 && name.charAt(0) != "." && name.charAt(0) != "_")
|
2015-02-10 19:41:24 +00:00
|
|
|
toLoad.push(name);
|
|
|
|
});
|
|
|
|
|
|
|
|
loadPlugins(toLoad);
|
|
|
|
});
|
|
|
|
|
|
|
|
commands.addCommand({
|
2015-11-29 14:50:48 +00:00
|
|
|
name: "reloadCustomPlugin",
|
2015-02-10 19:41:24 +00:00
|
|
|
group: "Plugins",
|
|
|
|
bindKey: {
|
|
|
|
mac: "Command-Enter",
|
|
|
|
win: "Ctrl-Enter"
|
|
|
|
},
|
|
|
|
exec: function(){
|
|
|
|
reloadPluginUI();
|
|
|
|
}
|
|
|
|
}, plugin);
|
|
|
|
|
2015-11-29 14:50:48 +00:00
|
|
|
menus.addItemByPath("Tools/Developer/Reload Custom Plugin", new ui.item({
|
|
|
|
command: "reloadCustomPlugin"
|
2015-04-20 23:51:50 +00:00
|
|
|
}), 1000, plugin);
|
2015-02-10 19:41:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***** Methods *****/
|
|
|
|
|
|
|
|
function loadPlugins(list){
|
|
|
|
if (!vfs.connected) {
|
|
|
|
vfs.once("connect", loadPlugins.bind(this, config));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-04-21 14:50:58 +00:00
|
|
|
if (typeof list == "string")
|
|
|
|
list = [list];
|
|
|
|
|
2015-02-10 19:41:24 +00:00
|
|
|
var config = [];
|
2015-04-17 17:26:43 +00:00
|
|
|
var loadConfig = function(){
|
|
|
|
architect.loadAdditionalPlugins(config, function(err){
|
|
|
|
if (err) console.error(err);
|
|
|
|
});
|
|
|
|
};
|
2015-02-10 19:41:24 +00:00
|
|
|
|
2015-04-17 17:26:43 +00:00
|
|
|
async.each(list, function(name, next){
|
2015-04-15 22:18:02 +00:00
|
|
|
var resourceHolder = new Plugin();
|
2015-04-16 22:28:31 +00:00
|
|
|
var resourceVersion = "";
|
|
|
|
|
2015-04-17 17:26:43 +00:00
|
|
|
resourceHolder.on("load", function(){
|
|
|
|
if (inited) load();
|
|
|
|
});
|
2015-04-16 23:53:16 +00:00
|
|
|
|
2015-04-16 22:28:31 +00:00
|
|
|
resourceHolder.freezePublicAPI({
|
|
|
|
get version(){ return resourceVersion },
|
|
|
|
set version(v){ resourceVersion = v; }
|
|
|
|
});
|
|
|
|
|
|
|
|
var inited = false;
|
2015-04-16 23:53:16 +00:00
|
|
|
function load(){
|
2015-04-16 22:28:31 +00:00
|
|
|
async.parallel([
|
|
|
|
function(next){
|
|
|
|
// Fetch package.json
|
|
|
|
fs.readFile("~/.c9/plugins/" + name + "/package.json", function(err, data){
|
|
|
|
if (err)
|
|
|
|
return next(err);
|
|
|
|
|
|
|
|
try {
|
|
|
|
var options = JSON.parse(data);
|
|
|
|
if (!options.plugins)
|
|
|
|
throw new Error("Missing plugins property in package.json of " + name);
|
|
|
|
}
|
|
|
|
catch(e){
|
|
|
|
return next(err);
|
|
|
|
}
|
2015-04-03 00:38:55 +00:00
|
|
|
|
2015-04-16 22:28:31 +00:00
|
|
|
var host = vfs.baseUrl + "/";
|
|
|
|
var base = join(String(c9.projectId),
|
|
|
|
"plugins", auth.accessToken);
|
2015-04-03 00:38:55 +00:00
|
|
|
|
2015-04-17 17:26:43 +00:00
|
|
|
// Configure Require.js
|
2015-04-16 22:28:31 +00:00
|
|
|
var pathConfig = {};
|
|
|
|
pathConfig["plugins/" + name] = host + join(base, name);
|
2015-04-17 17:26:43 +00:00
|
|
|
requirejs.config({ paths: pathConfig });
|
|
|
|
|
2015-04-16 22:28:31 +00:00
|
|
|
// Add the plugin to the config
|
|
|
|
Object.keys(options.plugins).forEach(function(path){
|
|
|
|
var pluginPath = name + "/" + path;
|
|
|
|
|
|
|
|
// Watch project path
|
|
|
|
watch("~/.c9/plugins/" + pluginPath);
|
|
|
|
var cfg = options.plugins[path];
|
|
|
|
cfg.packagePath = "plugins/" + name + "/" + path;
|
|
|
|
cfg.staticPrefix = host + join(base, name);
|
|
|
|
cfg.apikey = "0000000000000000000000000000=";
|
|
|
|
|
2015-10-28 22:46:10 +00:00
|
|
|
// Set version for package manager
|
|
|
|
cfg.version = options.version;
|
|
|
|
|
2015-04-16 22:28:31 +00:00
|
|
|
config.push(cfg);
|
2015-04-20 23:51:50 +00:00
|
|
|
plugins.push(name + "/" + path);
|
2015-04-16 22:28:31 +00:00
|
|
|
});
|
|
|
|
|
2015-04-17 17:26:43 +00:00
|
|
|
// Set version for package manager
|
2015-04-16 22:28:31 +00:00
|
|
|
resourceHolder.version = options.version;
|
|
|
|
|
|
|
|
// Start the installer if one is included
|
|
|
|
if (options.installer) {
|
|
|
|
addStaticPlugin("installer", name, options.installer,
|
|
|
|
null, resourceHolder);
|
|
|
|
}
|
|
|
|
|
|
|
|
next();
|
2015-04-03 00:38:55 +00:00
|
|
|
});
|
2015-04-16 22:28:31 +00:00
|
|
|
},
|
|
|
|
function(next){
|
2015-04-16 23:53:16 +00:00
|
|
|
var path = join("~/.c9/plugins", name);
|
|
|
|
var rePath = new RegExp("^" + util.escapeRegExp(path.replace(/^~/, c9.home) + "/"), "gm");
|
2015-04-16 22:28:31 +00:00
|
|
|
find.getFileList({
|
|
|
|
path: path,
|
|
|
|
nocache: true,
|
|
|
|
buffer: true
|
|
|
|
}, function(err, data){
|
2015-04-03 00:38:55 +00:00
|
|
|
if (err)
|
|
|
|
return next(err);
|
|
|
|
|
2015-04-16 22:28:31 +00:00
|
|
|
// Remove the base path
|
|
|
|
data = data.replace(rePath, "");
|
|
|
|
|
2015-04-16 23:53:16 +00:00
|
|
|
if (data.match(/^__installed__.js/))
|
2015-04-16 22:28:31 +00:00
|
|
|
return next("installed");
|
|
|
|
|
|
|
|
// Process all the submodules
|
|
|
|
var parallel = processModules(path, data, resourceHolder);
|
|
|
|
async.parallel(parallel, function(err, data){
|
|
|
|
if (err)
|
|
|
|
return next(err);
|
|
|
|
|
2015-04-16 23:53:16 +00:00
|
|
|
if (!inited)
|
|
|
|
resourceHolder.load(name + ".bundle");
|
|
|
|
|
2015-04-16 22:28:31 +00:00
|
|
|
// Done
|
|
|
|
next();
|
|
|
|
});
|
2015-04-02 17:35:43 +00:00
|
|
|
});
|
2015-04-16 22:28:31 +00:00
|
|
|
}
|
|
|
|
], function(err, results){
|
|
|
|
if (err) console.error(err);
|
|
|
|
|
|
|
|
if (!inited) {
|
|
|
|
next();
|
|
|
|
inited = true;
|
|
|
|
}
|
|
|
|
});
|
2015-04-16 23:53:16 +00:00
|
|
|
}
|
2015-04-17 17:26:43 +00:00
|
|
|
|
2015-04-16 23:53:16 +00:00
|
|
|
load();
|
2015-04-17 17:26:43 +00:00
|
|
|
}, function(){
|
2015-04-20 23:51:50 +00:00
|
|
|
emit.sticky("ready");
|
|
|
|
|
2015-02-10 19:41:24 +00:00
|
|
|
if (!config.length) return;
|
|
|
|
|
|
|
|
// Load config
|
2015-04-02 17:35:43 +00:00
|
|
|
if (installer.sessions.length) {
|
2015-04-17 17:26:43 +00:00
|
|
|
installer.on("stop", function listen(err){
|
2015-04-02 17:35:43 +00:00
|
|
|
if (err)
|
|
|
|
return console.error(err);
|
2015-04-17 17:26:43 +00:00
|
|
|
|
|
|
|
if (!installer.sessions.length) {
|
|
|
|
loadConfig();
|
|
|
|
installer.off("stop", listen);
|
|
|
|
}
|
2015-04-02 17:35:43 +00:00
|
|
|
});
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-04-17 17:26:43 +00:00
|
|
|
loadConfig();
|
|
|
|
});
|
2015-02-10 19:41:24 +00:00
|
|
|
}
|
|
|
|
|
2015-04-15 22:18:02 +00:00
|
|
|
function processModules(path, data, plugin){
|
2015-04-03 00:38:55 +00:00
|
|
|
var parallel = [];
|
|
|
|
|
|
|
|
data.split("\n").forEach(function(line){
|
|
|
|
if (!line.match(reParts)) return;
|
|
|
|
|
|
|
|
var type = RegExp.$1;
|
|
|
|
var filename = RegExp.$2;
|
|
|
|
if (filename.indexOf("/") > -1) return;
|
|
|
|
|
2015-06-28 13:06:07 +00:00
|
|
|
if (type == "modes" && (reModule.test(filename) || !jsExtRe.test(filename)))
|
2015-04-03 19:25:27 +00:00
|
|
|
return;
|
|
|
|
|
2015-06-28 13:06:07 +00:00
|
|
|
if (type == "snippets") {
|
|
|
|
if (jsExtRe.test(filename)) {
|
|
|
|
var snippetPath = join("plugins", basename(path), type, filename).replace(jsExtRe, "");
|
|
|
|
require([snippetPath], function(m) {
|
|
|
|
architect.services["language.complete"].addSnippet(m, plugin);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
if (!/\.snippets$/.test(filename))
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-04-03 18:35:05 +00:00
|
|
|
parallel.push(function(next){
|
2015-04-16 23:53:16 +00:00
|
|
|
fs.readFile(join(path, type, filename), function(err, data){
|
2015-04-03 18:35:05 +00:00
|
|
|
if (err) {
|
|
|
|
console.error(err);
|
|
|
|
return next(err);
|
|
|
|
}
|
|
|
|
|
2015-04-16 23:53:16 +00:00
|
|
|
addStaticPlugin(type, basename(path), filename, data, plugin);
|
2015-04-03 18:35:05 +00:00
|
|
|
|
|
|
|
next();
|
|
|
|
});
|
|
|
|
});
|
2015-04-03 00:38:55 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
return parallel;
|
|
|
|
}
|
|
|
|
|
2015-04-13 19:44:42 +00:00
|
|
|
function addStaticPlugin(type, pluginName, filename, data, plugin) {
|
|
|
|
var services = architect.services;
|
2015-04-16 22:28:31 +00:00
|
|
|
var path = "plugins/" + pluginName + "/"
|
|
|
|
+ (type == "installer" ? "" : type + "/")
|
|
|
|
+ filename.replace(/\.js$/, "");
|
|
|
|
|
2015-04-16 23:53:16 +00:00
|
|
|
var bundleName = pluginName + ".bundle";
|
|
|
|
if (!services[bundleName] && type !== "installer") {
|
|
|
|
services[bundleName] = plugin;
|
2015-04-16 22:28:31 +00:00
|
|
|
architect.lut["~/.c9/plugins/" + pluginName] = {
|
|
|
|
provides: []
|
|
|
|
};
|
2015-04-16 23:53:16 +00:00
|
|
|
architect.pluginToPackage[bundleName] = {
|
|
|
|
path: "~/.c9/plugins/" + pluginName,
|
2015-04-16 22:28:31 +00:00
|
|
|
package: pluginName,
|
|
|
|
version: plugin.version,
|
|
|
|
isAdditionalMode: true
|
|
|
|
};
|
|
|
|
if (!architect.packages[pluginName])
|
|
|
|
architect.packages[pluginName] = [];
|
|
|
|
architect.packages[pluginName].push(name);
|
|
|
|
}
|
|
|
|
|
2015-04-13 19:44:42 +00:00
|
|
|
switch (type) {
|
|
|
|
case "builders":
|
|
|
|
data = util.safeParseJson(data, function() {});
|
|
|
|
if (!data) return;
|
|
|
|
|
|
|
|
services.build.addBuilder(filename, data, plugin);
|
|
|
|
break;
|
|
|
|
case "keymaps":
|
|
|
|
data = util.safeParseJson(data, function() {});
|
|
|
|
if (!data) return;
|
|
|
|
|
|
|
|
services["preferences.keybindings"].addCustomKeymap(filename, data, plugin);
|
|
|
|
break;
|
|
|
|
case "modes":
|
|
|
|
var mode = {};
|
|
|
|
var firstLine = data.split("\n", 1)[0].replace(/\/\*|\*\//g, "").trim();
|
|
|
|
firstLine.split(";").forEach(function(n){
|
|
|
|
if (!n) return;
|
|
|
|
var info = n.split(":");
|
|
|
|
mode[info[0].trim()] = info[1].trim();
|
|
|
|
});
|
|
|
|
|
|
|
|
services.ace.defineSyntax({
|
2015-04-17 21:12:13 +00:00
|
|
|
name: path,
|
2015-04-13 19:44:42 +00:00
|
|
|
caption: mode.caption,
|
|
|
|
extensions: (mode.extensions || "").trim()
|
2015-04-17 21:12:13 +00:00
|
|
|
.replace(/\s*,\s*/g, "|").replace(/(^|\|)\./g, "$1")
|
2015-04-13 19:44:42 +00:00
|
|
|
});
|
|
|
|
break;
|
|
|
|
case "outline":
|
|
|
|
if (!data) return;
|
|
|
|
|
2015-04-14 21:46:06 +00:00
|
|
|
services.outline.addOutlinePlugin(path, data, plugin);
|
2015-04-13 19:44:42 +00:00
|
|
|
break;
|
|
|
|
case "runners":
|
|
|
|
data = util.safeParseJson(data, function() {});
|
|
|
|
if (!data) return;
|
|
|
|
|
2015-09-01 14:46:01 +00:00
|
|
|
services.run.addRunner(data.caption || filename, data, plugin);
|
2015-04-13 19:44:42 +00:00
|
|
|
break;
|
|
|
|
case "snippets":
|
2015-04-14 20:02:27 +00:00
|
|
|
services["language.complete"].addSnippet(data, plugin);
|
2015-04-13 19:44:42 +00:00
|
|
|
break;
|
|
|
|
case "themes":
|
|
|
|
services.ace.addTheme(data, plugin);
|
|
|
|
break;
|
2015-04-14 00:44:47 +00:00
|
|
|
case "templates":
|
2015-04-13 19:44:42 +00:00
|
|
|
services.newresource.addFileTemplate(data, plugin);
|
|
|
|
break;
|
2015-04-15 22:18:02 +00:00
|
|
|
case "installer":
|
2015-04-16 21:31:19 +00:00
|
|
|
if (data) {
|
|
|
|
installer.createSession(pluginName, data, function(v, o){
|
|
|
|
require([path], function(fn){
|
|
|
|
fn(v, o);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
else {
|
2015-04-15 22:18:02 +00:00
|
|
|
require([path], function(fn){
|
2015-04-16 21:31:19 +00:00
|
|
|
installer.createSession(pluginName, fn.version, function(v, o){
|
|
|
|
fn(v, o);
|
|
|
|
});
|
2015-04-15 22:18:02 +00:00
|
|
|
});
|
2015-04-16 21:31:19 +00:00
|
|
|
}
|
2015-04-13 19:44:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-10 19:41:24 +00:00
|
|
|
// Check if require.s.contexts._ can help watching all dependencies
|
|
|
|
function watch(path){
|
|
|
|
watcher.watch(path);
|
|
|
|
|
|
|
|
watcher.on("change", function(e){
|
|
|
|
if (e.path == path)
|
|
|
|
reloadPackage(path.replace(/^~\/\.c9\//, ""));
|
|
|
|
});
|
|
|
|
watcher.on("delete", function(e){
|
|
|
|
if (e.path == path)
|
|
|
|
reloadPackage(path.replace(/^~\/\.c9\//, ""));
|
|
|
|
});
|
|
|
|
watcher.on("failed", function(e){
|
|
|
|
if (e.path == path) {
|
|
|
|
setTimeout(function(){
|
|
|
|
watcher.watch(path); // Retries once after 1s
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function reloadPackage(path){
|
|
|
|
var unloaded = [];
|
|
|
|
|
|
|
|
function recurUnload(name){
|
|
|
|
var plugin = architect.services[name];
|
|
|
|
unloaded.push(name);
|
|
|
|
|
|
|
|
// Find all the dependencies
|
|
|
|
var deps = ext.getDependencies(plugin.name);
|
|
|
|
|
|
|
|
// Unload all the dependencies (and their deps)
|
|
|
|
deps.forEach(function(name){
|
|
|
|
recurUnload(name);
|
|
|
|
});
|
|
|
|
|
|
|
|
// Unload plugin
|
|
|
|
plugin.unload();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Recursively unload plugin
|
|
|
|
var p = architect.lut[path];
|
|
|
|
if (p.provides) { // Plugin might not been initialized all the way
|
|
|
|
p.provides.forEach(function(name){
|
|
|
|
recurUnload(name);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// create reverse lookup table
|
|
|
|
var rlut = {};
|
|
|
|
for (var packagePath in architect.lut) {
|
|
|
|
var provides = architect.lut[packagePath].provides;
|
|
|
|
if (provides) { // Plugin might not been initialized all the way
|
|
|
|
provides.forEach(function(name){
|
|
|
|
rlut[name] = packagePath;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Build config of unloaded plugins
|
|
|
|
var config = [], done = {};
|
|
|
|
unloaded.forEach(function(name){
|
|
|
|
var packagePath = rlut[name];
|
|
|
|
|
|
|
|
// Make sure we include each plugin only once
|
|
|
|
if (done[packagePath]) return;
|
|
|
|
done[packagePath] = true;
|
|
|
|
|
|
|
|
var options = architect.lut[packagePath];
|
|
|
|
delete options.provides;
|
|
|
|
delete options.consumes;
|
|
|
|
delete options.setup;
|
|
|
|
|
|
|
|
config.push(options);
|
|
|
|
|
|
|
|
// Clear require cache
|
|
|
|
requirejs.undef(options.packagePath); // global
|
|
|
|
});
|
|
|
|
|
|
|
|
// Load all plugins again
|
|
|
|
architect.loadAdditionalPlugins(config, function(err){
|
|
|
|
if (err) console.error(err);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function reloadPluginUI(){
|
|
|
|
var list = [];
|
|
|
|
Object.keys(architect.pluginToPackage).forEach(function(name){
|
|
|
|
if (architect.pluginToPackage[name].isAdditionalMode)
|
|
|
|
list.push(architect.pluginToPackage[name].path);
|
|
|
|
});
|
|
|
|
|
|
|
|
var path = list[list.length - 1];
|
|
|
|
reloadPackage(path.replace(/^~\/\.c9\//, ""));
|
2015-11-29 14:50:48 +00:00
|
|
|
|
|
|
|
// Avoid confusion with "Reload Last Plugin"
|
|
|
|
var href = document.location.href.replace(/[?&]reload=[^&]+/, "");
|
|
|
|
window.history.replaceState(window.history.state, null, href);
|
|
|
|
showInfo("Reloaded " + path + ".", 1000);
|
2015-02-10 19:41:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***** Lifecycle *****/
|
|
|
|
|
|
|
|
plugin.on("load", function() {
|
|
|
|
load();
|
|
|
|
});
|
|
|
|
plugin.on("unload", function() {
|
|
|
|
loaded = false;
|
|
|
|
});
|
|
|
|
|
|
|
|
/***** Register and define API *****/
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
**/
|
|
|
|
plugin.freezePublicAPI({
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
get architect(){ throw new Error(); },
|
|
|
|
set architect(v){ architect = v; },
|
2015-04-20 23:51:50 +00:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
get plugins(){ return plugins; },
|
|
|
|
|
|
|
|
_events: [
|
|
|
|
/**
|
|
|
|
* @event ready
|
|
|
|
*/
|
|
|
|
"ready"
|
|
|
|
],
|
2015-02-10 19:41:24 +00:00
|
|
|
|
2015-04-13 21:08:51 +00:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
addStaticPlugin: addStaticPlugin,
|
2015-04-20 23:51:50 +00:00
|
|
|
|
2015-02-10 19:41:24 +00:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
2015-04-21 14:50:58 +00:00
|
|
|
reloadPackage: reloadPackage,
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
loadPackage: loadPlugins
|
2015-02-10 19:41:24 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
register(null, {
|
|
|
|
"plugin.debug": plugin
|
|
|
|
});
|
|
|
|
}
|
2015-09-01 14:46:01 +00:00
|
|
|
});
|