Hook modules can be in either CommonJS or AMD format, have to be AMD for client side

This commit is contained in:
Egil Moeller 2015-04-11 16:51:01 +02:00
parent 0e5cd65d8d
commit b86aa5d858
6 changed files with 94 additions and 46 deletions

View file

@ -1,8 +1,8 @@
{ {
"parts": [ "parts": [
{ "name": "express", "hooks": { { "name": "express", "hooks": {
"createServer": "ep_etherpad-lite/node/hooks/express:createServer", "createServer": "ep_etherpad-lite/node/hooks/express/main:createServer",
"restartServer": "ep_etherpad-lite/node/hooks/express:restartServer" "restartServer": "ep_etherpad-lite/node/hooks/express/main:restartServer"
} }, } },
{ "name": "static", "hooks": { "expressCreateServer": "ep_etherpad-lite/node/hooks/express/static:expressCreateServer" } }, { "name": "static", "hooks": { "expressCreateServer": "ep_etherpad-lite/node/hooks/express/static:expressCreateServer" } },
{ "name": "i18n", "hooks": { "expressCreateServer": "ep_etherpad-lite/node/hooks/i18n:expressCreateServer" } }, { "name": "i18n", "hooks": { "expressCreateServer": "ep_etherpad-lite/node/hooks/i18n:expressCreateServer" } },

View file

@ -1,6 +1,6 @@
var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks"); var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks");
var express = require('express'); var express = require('express');
var settings = require('../utils/Settings'); var settings = require('../../utils/Settings');
var fs = require('fs'); var fs = require('fs');
var path = require('path'); var path = require('path');
var npm = require("npm/lib/npm.js"); var npm = require("npm/lib/npm.js");

View file

@ -63,7 +63,7 @@ async.waterfall([
}, },
function(callback) { function(callback) {
plugins.update(callback) plugins.ensure(callback)
}, },
function (callback) { function (callback) {

View file

@ -26,9 +26,11 @@ exports.update = function (cb) {
jQuery.getJSON(exports.baseURL + 'pluginfw/plugin-definitions.json', function(data) { jQuery.getJSON(exports.baseURL + 'pluginfw/plugin-definitions.json', function(data) {
exports.plugins = data.plugins; exports.plugins = data.plugins;
exports.parts = data.parts; exports.parts = data.parts;
exports.hooks = pluginUtils.extractHooks(exports.parts, "client_hooks"); pluginUtils.extractHooks(exports.parts, "client_hooks", undefined, function (err, hooks) {
exports.hooks = hooks;
exports.loaded = true; exports.loaded = true;
callback(); callback();
});
}).error(function(xhr, s, err){ }).error(function(xhr, s, err){
console.error("Failed to load plugin-definitions: " + err); console.error("Failed to load plugin-definitions: " + err);
callback(); callback();

View file

@ -6,6 +6,7 @@ var fs = require("fs");
var tsort = require("./tsort"); var tsort = require("./tsort");
var util = require("util"); var util = require("util");
var _ = require("underscore"); var _ = require("underscore");
var requirejs = require('requirejs');
var pluginUtils = require('./shared'); var pluginUtils = require('./shared');
@ -17,7 +18,22 @@ exports.hooks = {};
exports.ensure = function (cb) { exports.ensure = function (cb) {
if (!exports.loaded) if (!exports.loaded)
exports.getPackages(function (er, packages) {
pkg = Object.keys(packages).map(function (name) {
return {
name: name,
location: packages[name].realPath
}
})
;
console.log(["AAAAAAAAA", pkg]);
requirejs.config({
packages: pkg
});
exports.update(cb); exports.update(cb);
});
else else
cb(); cb();
}; };
@ -32,7 +48,7 @@ exports.formatParts = function () {
exports.formatHooks = function (hook_set_name) { exports.formatHooks = function (hook_set_name) {
var res = []; var res = [];
var hooks = pluginUtils.extractHooks(exports.parts, hook_set_name || "hooks"); var hooks = exports[hook_set_name || "hooks"];
_.chain(hooks).keys().forEach(function (hook_name) { _.chain(hooks).keys().forEach(function (hook_name) {
_.forEach(hooks[hook_name], function (hook) { _.forEach(hooks[hook_name], function (hook) {
@ -82,9 +98,15 @@ exports.update = function (cb) {
if (err) cb(err); if (err) cb(err);
exports.plugins = plugins; exports.plugins = plugins;
exports.parts = sortParts(parts); exports.parts = sortParts(parts);
exports.hooks = pluginUtils.extractHooks(exports.parts, "hooks", exports.pathNormalization); pluginUtils.extractHooks(exports.parts, "hooks", exports.pathNormalization, function (err, hooks) {
exports.hooks = hooks;
// Load client side hooks here too, so we don't have to call it from formatHooks (which is synchronous)
pluginUtils.extractHooks(exports.parts, "client_hooks", exports.pathNormalization, function (err, hooks) {
exports.client_hooks = hooks;
exports.loaded = true; exports.loaded = true;
exports.callInit(cb); exports.callInit(cb);
});
});
} }
); );
}); });

View file

@ -1,6 +1,14 @@
var _ = require("underscore"); var _ = require("underscore");
var async = require("async/lib/async");
if (typeof(requirejs) == "undefined") {
if (typeof(window) != "undefined") {
var requirejs = window.requirejs;
} else {
var requirejs = require('requirejs');
}
}
function loadFn(path, hookName) { function loadFn(path, hookName, cb) {
var functionName var functionName
, parts = path.split(":"); , parts = path.split(":");
@ -15,22 +23,37 @@ function loadFn(path, hookName) {
functionName = parts[1]; functionName = parts[1];
} }
console.log(["LOADING", path]); console.log(["loadName", path, functionName]);
var fn = require(path);
var handleFunction = function (fn) {
functionName = functionName ? functionName : hookName; functionName = functionName ? functionName : hookName;
_.each(functionName.split("."), function (name) { _.each(functionName.split("."), function (name) {
fn = fn[name]; fn = fn[name];
}); });
return fn; cb(null, fn);
}; };
function extractHooks(parts, hook_set_name, normalizer) { if (require.resolve != undefined) {
/* We're apparently in NodeJS, so try to load using the built-in require first */
try {
handleFunction(require(path));
} catch (e) {
requirejs([path], handleFunction);
}
} else {
requirejs([path], handleFunction);
}
};
function extractHooks(parts, hook_set_name, normalizer, cb) {
var hooks = {}; var hooks = {};
_.each(parts,function (part) {
_.chain(part[hook_set_name] || {}) async.each(parts, function (part, cb) {
.keys() if (part[hook_set_name] == undefined) {
.each(function (hook_name) { cb(null);
} else {
async.each(Object.keys(part[hook_set_name]), function (hook_name, cb) {
if (hooks[hook_name] === undefined) hooks[hook_name] = []; if (hooks[hook_name] === undefined) hooks[hook_name] = [];
var hook_fn_name = part[hook_set_name][hook_name]; var hook_fn_name = part[hook_set_name][hook_name];
@ -39,24 +62,25 @@ function extractHooks(parts, hook_set_name, normalizer) {
* require("pluginname/whatever") if the plugin is installed as * require("pluginname/whatever") if the plugin is installed as
* a dependency of another plugin! Bah, pesky little details of * a dependency of another plugin! Bah, pesky little details of
* npm... */ * npm... */
/*
if (normalizer) { if (normalizer) {
hook_fn_name = normalizer(part, hook_fn_name); hook_fn_name = normalizer(part, hook_fn_name);
} }
*/
try { loadFn(hook_fn_name, hook_name, function (err, hook_fn) {
var hook_fn = loadFn(hook_fn_name, hook_name);
if (!hook_fn) {
throw "Not a function";
}
} catch (exc) {
console.error("Failed to load '" + hook_fn_name + "' for '" + part.full_name + "/" + hook_set_name + "/" + hook_name + "': " + exc.toString())
}
if (hook_fn) { if (hook_fn) {
hooks[hook_name].push({"hook_name": hook_name, "hook_fn": hook_fn, "hook_fn_name": hook_fn_name, "part": part}); hooks[hook_name].push({"hook_name": hook_name, "hook_fn": hook_fn, "hook_fn_name": hook_fn_name, "part": part});
} else {
console.error("Failed to load '" + hook_fn_name + "' for '" + part.full_name + "/" + hook_set_name + "/" + hook_name + ":" + err.toString());
} }
cb(err);
}); });
}, cb);
}
}, function (err) {
cb(err, hooks);
}); });
return hooks;
}; };
exports.extractHooks = extractHooks; exports.extractHooks = extractHooks;