From e5a46f585018e5f49bd6bb1f8d9384584bfc14d3 Mon Sep 17 00:00:00 2001 From: Egil Moeller Date: Fri, 24 Feb 2012 17:37:40 +0100 Subject: [PATCH] Added hook.callAll and hook.aCallAll --- node/pluginfw/hooks.js | 46 ++++++++++++++++++++++++++++++++++++ node/pluginfw/plugins.js | 50 +++++++++++++++++++++++++++++++++++----- 2 files changed, 90 insertions(+), 6 deletions(-) create mode 100644 node/pluginfw/hooks.js diff --git a/node/pluginfw/hooks.js b/node/pluginfw/hooks.js new file mode 100644 index 00000000..d284b229 --- /dev/null +++ b/node/pluginfw/hooks.js @@ -0,0 +1,46 @@ +var plugins = require("./plugins"); +var async = require("async"); + + +/* Don't use Array.concat as it flatterns arrays within the array */ +exports.flatten = function (lst) { + var res = []; + if (lst != undefined && lst != null) { + for (var i = 0; i < lst.length; i++) { + if (lst[i] != undefined && lst[i] != null) { + for (var j = 0; j < lst[i].length; j++) { + res.push(lst[i][j]); + } + } + } + } + return res; +} + +exports.callAll = function (hook_name, args) { + return exports.flatten(plugins.hooks[hook_name].map(function (hook) { + return hook.hook(hook_name, args, function (x) { return x; }); + })); +} + +exports.aCallAll = function (hook_name, args, cb) { + async.map( + plugins.hooks[hook_name], + function (hook, cb) { + hook.hook(hook_name, args, function (res) { cb(null, res); }); + }, + function (err, res) { + cb(exports.flatten(res)); + } + ); +} + +exports.callFirst = function (hook_name, args) { + if (plugins.hooks[hook_name][0] === undefined) return []; + return exports.flatten(plugins.hooks[hook_name][0].hook(hook_name, args, function (x) { return x; })); +} + +exports.aCallFirst = function (hook_name, args, cb) { + if (plugins.hooks[hook_name][0] === undefined) cb([]); + plugins.hooks[hook_name][0].hook(hook_name, args, function (res) { cb(exports.flatten(res)); }); +} diff --git a/node/pluginfw/plugins.js b/node/pluginfw/plugins.js index 39cdffa6..910e0028 100644 --- a/node/pluginfw/plugins.js +++ b/node/pluginfw/plugins.js @@ -7,11 +7,39 @@ var async = require("async"); var fs = require("fs"); var tsort = require("./tsort"); -var PLUGIN_PREFIX = 'pluginomatic_'; +exports.prefix = 'pluginomatic_'; +exports.loaded = false; +exports.plugins = {}; +exports.parts = []; +exports.hooks = {}; -exports.getPlugins = function (cb, prefix) { - prefix = prefix || PLUGIN_PREFIX; +exports.ensure = function (cb) { + if (!exports.loaded) + exports.update(cb); + else + cb(); +} +exports.update = function (cb) { + exports.getPlugins(function (er, plugins, parts, hooks) { + exports.plugins = plugins; + exports.parts = parts; + exports.hooks = hooks; + exports.loaded = true; + cb(er); + }); +} + +exports.loadFn = function (path) { + var x = path.split(":"); + var fn = require(x[0]); + x[1].split(".").forEach(function (name) { + fn = fn[name]; + }); + return fn; +} + +exports.getPlugins = function (cb) { // Load list of installed NPM packages, flatten it to a list, and filter out only packages with names that // ../.. and not just .. because current dir is like ETHERPAD_ROOT/node/node_modules (!!!!) var dir = path.resolve(npm.dir, "../..") @@ -20,7 +48,7 @@ exports.getPlugins = function (cb, prefix) { var parts = {}; function flatten(deps) { Object.keys(deps).forEach(function (name) { - if (name.indexOf(prefix) == 0) { + if (name.indexOf(exports.prefix) == 0) { plugins[name] = deps[name]; } if (deps[name].dependencies !== undefined) @@ -41,7 +69,7 @@ exports.getPlugins = function (cb, prefix) { plugins[plugin_name] = plugin; plugin.parts.forEach(function (part) { part.plugin = plugin; - part.full_name = plugin_name + "." + part.name; + part.full_name = plugin_name + "/" + part.name; parts[part.full_name] = part; }); cb(); @@ -49,7 +77,17 @@ exports.getPlugins = function (cb, prefix) { ); }, function (err) { - cb(err, plugins, exports.sortParts(parts)); + parts = exports.sortParts(parts); + var hooks = {}; + parts.forEach(function (part) { + Object.keys(part.hooks || {}).forEach(function (hook_name) { + if (hooks[hook_name] === undefined) hooks[hook_name] = []; + var hook_fn_name = part.hooks[hook_name]; + + hooks[hook_name].push({"hook": exports.loadFn(part.hooks[hook_name]), "part": part}); + }); + }); + cb(err, plugins, parts, hooks); } ); });