Bones/node_modules/browser-sync-ui/lib/hooks.js

272 lines
7.0 KiB
JavaScript
Raw Normal View History

2017-05-17 13:45:25 -04:00
var fs = require("fs");
var path = require("path");
var pluginTmpl = templateFile("/plugin.tmpl");
var configTmpl = templateFile("/config.tmpl");
var configItem = templateFile("/config.item.tmpl");
var inlineTemp = templateFile("/inline.template.tmpl");
var pluginItemTmpl = fs.readFileSync(path.resolve(__dirname, "../", "templates/plugin.item.tmpl"), "utf-8");
function templateFile (filepath) {
return fs.readFileSync(path.join(__dirname, "/../templates", filepath || ""), "utf-8");
}
/**
* @type {{page: Function, markup: Function, client:js: Function, templates: Function}}
*/
module.exports = {
/**
* Create the url config for each section of the ui
* @param hooks
* @param ui
*/
"page": function (hooks, ui) {
var config = hooks
.map(transformConfig)
.reduce(createConfigItem, {});
return {
/**
* pagesConfig - This is the angular configuration such as routes
*/
pagesConfig: configTmpl
.replace("%when%", hooks.reduce(
createAngularRoutes,
""
))
.replace("%pages%", JSON.stringify(
config,
null,
4
)),
/**
* pagesConfig in object form
*/
pagesObj: config,
pageMarkup: function () {
return preAngular(ui.pluginManager.plugins, config, ui);
}
};
},
/**
* Controller markup for each plugin
* @param hooks
* @returns {*}
*/
"markup": function (hooks) {
return hooks.reduce(pluginTemplate, "");
},
/**
* @param hooks
* @param {UI} ui
* @returns {*|string}
*/
"client:js": function (hooks, ui) {
/**
* Add client JS from Browsersync Plugins
*/
ui.bsPlugins.forEach(function (plugin) {
if (plugin.has("client:js")) {
plugin.get("client:js").forEach(function (value) {
hooks.push(value);
});
}
});
var out = hooks.reduce(function (all, item) {
if (typeof item === "string") {
all += ";" + item;
} else if (Array.isArray(item)) {
item.forEach(function (item) {
all += ";" + item;
});
}
return all;
}, "");
return out;
},
/**
* @param hooks
* @param initial
* @param {UI} ui
* @returns {String}
*/
"templates": function (hooks, initial, ui) {
/**
* Add templates from each Browsersync registered plugin
* @type {string}
*/
var pluginDirectives = ui.bsPlugins.reduce(function (all, plugin) {
if (!plugin.has("templates")) {
return all;
}
/**
* Slugify-ish the plugin name
* eg: Test Browsersync Plugin
* = test-browsersync-plugin
* @type {string}
*/
var slug = plugin.get("name")
.trim()
.split(" ")
.map(function (word) {
return word.trim().toLowerCase();
})
.join("-");
/**
* For every plugin that has templates, wrap
* the markup in the <script type="text/ng-template" id="{{slug}}"></script>
* markup to result in the single output string.
*/
plugin.get("templates").forEach(function (value, key) {
all += angularWrap([slug, path.basename(key)].join("/"), value);
});
return all;
}, "");
/**
* Combine the markup from the plugins done above with any
* others registered via hooks + initial
* to create the final markup
*/
return [pluginDirectives, createInlineTemplates(hooks.concat([initial]))].join("");
},
/**
* Allow plugins to register toggle-able elements
* @param hooks
* @returns {{}}
*/
"elements": function (hooks) {
var obj = {};
hooks.forEach(function (elements) {
elements.forEach(function (item) {
if (!obj[item.name]) {
obj[item.name] = item;
}
});
});
return obj;
}
};
/**
* @param hooks
* @returns {String}
*/
function createInlineTemplates (hooks) {
return hooks.reduce(function (combined, item) {
return combined + item.reduce(function (all, filepath) {
return all + angularWrap(
path.basename(filepath),
fs.readFileSync(filepath));
}, "");
}, "");
}
/**
* @param item
* @returns {*}
*/
function transformConfig (item) {
return item;
}
/**
* @param {String} all
* @param {Object} item
* @returns {*}
*/
function createAngularRoutes(all, item) {
return all + configItem.replace(/%(.+)%/g, function () {
var key = arguments[1];
if (item[key]) {
return item[key];
}
});
}
/**
* @param joined
* @param item
* @returns {*}
*/
function createConfigItem (joined, item) {
if (item.path === "/") {
joined["overview"] = item;
} else {
joined[item.path.slice(1)] = item;
}
return joined;
}
/**
* @returns {*}
*/
function pluginTemplate (combined, item) {
return [combined, pluginTmpl.replace("%markup%", item)].join("\n");
}
/**
* @param plugins
* @param config
* @returns {*}
*/
function preAngular (plugins, config, ui) {
return Object.keys(plugins)
.filter(function (key) {
return config[key]; // only work on plugins that have pages
})
.map(function (key) {
if (key === "plugins") {
var pluginMarkup = ui.bsPlugins.reduce(function (all, item, i) {
all += pluginItemTmpl
.replace("%content%", item.get("markup") || "")
.replace(/%index%/g, i)
.replace(/%name%/g, item.get("name"));
return all;
}, "");
plugins[key].hooks.markup = plugins[key].hooks.markup.replace("%pluginlist%", pluginMarkup);
}
return angularWrap(config[key].template, bindOnce(plugins[key].hooks.markup, config[key]));
})
.reduce(function (combined, item) {
return combined + item;
}, "");
}
/**
* @param templateName
* @param markup
* @returns {*}
*/
function angularWrap (templateName, markup) {
return inlineTemp
.replace("%content%", markup)
.replace("%id%", templateName);
}
/**
* @param markup
* @param config
* @returns {*|string}
*/
function bindOnce (markup, config) {
return markup.toString().replace(/\{\{ctrl.section\.(.+?)\}\}/g, function ($1, $2) {
return config[$2] || "";
});
}
module.exports.bindOnce = bindOnce;