From b86aa5d8583fe0d423bbc43b55c88e3807675a06 Mon Sep 17 00:00:00 2001 From: Egil Moeller Date: Sat, 11 Apr 2015 16:51:01 +0200 Subject: [PATCH] Hook modules can be in either CommonJS or AMD format, have to be AMD for client side --- src/ep.json | 4 +- .../hooks/{express.js => express/main.js} | 2 +- src/node/server.js | 2 +- src/static/js/pluginfw/client_plugins.js | 8 +- src/static/js/pluginfw/plugins.js | 32 ++++++- src/static/js/pluginfw/shared.js | 92 ++++++++++++------- 6 files changed, 94 insertions(+), 46 deletions(-) rename src/node/hooks/{express.js => express/main.js} (97%) diff --git a/src/ep.json b/src/ep.json index eeb5c6409..ae6d02892 100644 --- a/src/ep.json +++ b/src/ep.json @@ -1,8 +1,8 @@ { "parts": [ { "name": "express", "hooks": { - "createServer": "ep_etherpad-lite/node/hooks/express:createServer", - "restartServer": "ep_etherpad-lite/node/hooks/express:restartServer" + "createServer": "ep_etherpad-lite/node/hooks/express/main:createServer", + "restartServer": "ep_etherpad-lite/node/hooks/express/main:restartServer" } }, { "name": "static", "hooks": { "expressCreateServer": "ep_etherpad-lite/node/hooks/express/static:expressCreateServer" } }, { "name": "i18n", "hooks": { "expressCreateServer": "ep_etherpad-lite/node/hooks/i18n:expressCreateServer" } }, diff --git a/src/node/hooks/express.js b/src/node/hooks/express/main.js similarity index 97% rename from src/node/hooks/express.js rename to src/node/hooks/express/main.js index 3abe41f89..ee696b6a0 100644 --- a/src/node/hooks/express.js +++ b/src/node/hooks/express/main.js @@ -1,6 +1,6 @@ var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks"); var express = require('express'); -var settings = require('../utils/Settings'); +var settings = require('../../utils/Settings'); var fs = require('fs'); var path = require('path'); var npm = require("npm/lib/npm.js"); diff --git a/src/node/server.js b/src/node/server.js index 605ce8479..8b9967a59 100755 --- a/src/node/server.js +++ b/src/node/server.js @@ -63,7 +63,7 @@ async.waterfall([ }, function(callback) { - plugins.update(callback) + plugins.ensure(callback) }, function (callback) { diff --git a/src/static/js/pluginfw/client_plugins.js b/src/static/js/pluginfw/client_plugins.js index feb2a14f0..062a2d8a8 100644 --- a/src/static/js/pluginfw/client_plugins.js +++ b/src/static/js/pluginfw/client_plugins.js @@ -26,9 +26,11 @@ exports.update = function (cb) { jQuery.getJSON(exports.baseURL + 'pluginfw/plugin-definitions.json', function(data) { exports.plugins = data.plugins; exports.parts = data.parts; - exports.hooks = pluginUtils.extractHooks(exports.parts, "client_hooks"); - exports.loaded = true; - callback(); + pluginUtils.extractHooks(exports.parts, "client_hooks", undefined, function (err, hooks) { + exports.hooks = hooks; + exports.loaded = true; + callback(); + }); }).error(function(xhr, s, err){ console.error("Failed to load plugin-definitions: " + err); callback(); diff --git a/src/static/js/pluginfw/plugins.js b/src/static/js/pluginfw/plugins.js index e02c1331a..9b94b2783 100644 --- a/src/static/js/pluginfw/plugins.js +++ b/src/static/js/pluginfw/plugins.js @@ -6,6 +6,7 @@ var fs = require("fs"); var tsort = require("./tsort"); var util = require("util"); var _ = require("underscore"); +var requirejs = require('requirejs'); var pluginUtils = require('./shared'); @@ -17,7 +18,22 @@ exports.hooks = {}; exports.ensure = function (cb) { if (!exports.loaded) - exports.update(cb); + 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); + }); else cb(); }; @@ -32,7 +48,7 @@ exports.formatParts = function () { exports.formatHooks = function (hook_set_name) { 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) { _.forEach(hooks[hook_name], function (hook) { @@ -82,9 +98,15 @@ exports.update = function (cb) { if (err) cb(err); exports.plugins = plugins; exports.parts = sortParts(parts); - exports.hooks = pluginUtils.extractHooks(exports.parts, "hooks", exports.pathNormalization); - exports.loaded = true; - exports.callInit(cb); + 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.callInit(cb); + }); + }); } ); }); diff --git a/src/static/js/pluginfw/shared.js b/src/static/js/pluginfw/shared.js index 544bb580b..767487264 100644 --- a/src/static/js/pluginfw/shared.js +++ b/src/static/js/pluginfw/shared.js @@ -1,6 +1,14 @@ 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 , parts = path.split(":"); @@ -15,48 +23,64 @@ function loadFn(path, hookName) { functionName = parts[1]; } - console.log(["LOADING", path]); - var fn = require(path); - functionName = functionName ? functionName : hookName; + console.log(["loadName", path, functionName]); - _.each(functionName.split("."), function (name) { - fn = fn[name]; - }); - return fn; + var handleFunction = function (fn) { + functionName = functionName ? functionName : hookName; + + _.each(functionName.split("."), function (name) { + fn = fn[name]; + }); + cb(null, fn); + }; + + 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) { +function extractHooks(parts, hook_set_name, normalizer, cb) { var hooks = {}; - _.each(parts,function (part) { - _.chain(part[hook_set_name] || {}) - .keys() - .each(function (hook_name) { - if (hooks[hook_name] === undefined) hooks[hook_name] = []; - var hook_fn_name = part[hook_set_name][hook_name]; + async.each(parts, function (part, cb) { + if (part[hook_set_name] == undefined) { + cb(null); + } else { + async.each(Object.keys(part[hook_set_name]), function (hook_name, cb) { + if (hooks[hook_name] === undefined) hooks[hook_name] = []; - /* On the server side, you can't just - * require("pluginname/whatever") if the plugin is installed as - * a dependency of another plugin! Bah, pesky little details of - * npm... */ - if (normalizer) { - hook_fn_name = normalizer(part, hook_fn_name); - } + var hook_fn_name = part[hook_set_name][hook_name]; - try { - var hook_fn = loadFn(hook_fn_name, hook_name); - if (!hook_fn) { - throw "Not a function"; + /* On the server side, you can't just + * require("pluginname/whatever") if the plugin is installed as + * a dependency of another plugin! Bah, pesky little details of + * npm... */ +/* + if (normalizer) { + hook_fn_name = normalizer(part, hook_fn_name); } - } catch (exc) { - console.error("Failed to load '" + hook_fn_name + "' for '" + part.full_name + "/" + hook_set_name + "/" + hook_name + "': " + exc.toString()) - } - if (hook_fn) { - hooks[hook_name].push({"hook_name": hook_name, "hook_fn": hook_fn, "hook_fn_name": hook_fn_name, "part": part}); - } - }); +*/ + + loadFn(hook_fn_name, hook_name, function (err, 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}); + } 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;