hooks.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. var fs = require("fs");
  2. var path = require("path");
  3. var pluginTmpl = templateFile("/plugin.tmpl");
  4. var configTmpl = templateFile("/config.tmpl");
  5. var configItem = templateFile("/config.item.tmpl");
  6. var inlineTemp = templateFile("/inline.template.tmpl");
  7. var pluginItemTmpl = fs.readFileSync(path.resolve(__dirname, "../", "templates/plugin.item.tmpl"), "utf-8");
  8. function templateFile (filepath) {
  9. return fs.readFileSync(path.join(__dirname, "/../templates", filepath || ""), "utf-8");
  10. }
  11. /**
  12. * @type {{page: Function, markup: Function, client:js: Function, templates: Function}}
  13. */
  14. module.exports = {
  15. /**
  16. * Create the url config for each section of the ui
  17. * @param hooks
  18. * @param ui
  19. */
  20. "page": function (hooks, ui) {
  21. var config = hooks
  22. .map(transformConfig)
  23. .reduce(createConfigItem, {});
  24. return {
  25. /**
  26. * pagesConfig - This is the angular configuration such as routes
  27. */
  28. pagesConfig: configTmpl
  29. .replace("%when%", hooks.reduce(
  30. createAngularRoutes,
  31. ""
  32. ))
  33. .replace("%pages%", JSON.stringify(
  34. config,
  35. null,
  36. 4
  37. )),
  38. /**
  39. * pagesConfig in object form
  40. */
  41. pagesObj: config,
  42. pageMarkup: function () {
  43. return preAngular(ui.pluginManager.plugins, config, ui);
  44. }
  45. };
  46. },
  47. /**
  48. * Controller markup for each plugin
  49. * @param hooks
  50. * @returns {*}
  51. */
  52. "markup": function (hooks) {
  53. return hooks.reduce(pluginTemplate, "");
  54. },
  55. /**
  56. * @param hooks
  57. * @param {UI} ui
  58. * @returns {*|string}
  59. */
  60. "client:js": function (hooks, ui) {
  61. /**
  62. * Add client JS from Browsersync Plugins
  63. */
  64. ui.bsPlugins.forEach(function (plugin) {
  65. if (plugin.has("client:js")) {
  66. plugin.get("client:js").forEach(function (value) {
  67. hooks.push(value);
  68. });
  69. }
  70. });
  71. var out = hooks.reduce(function (all, item) {
  72. if (typeof item === "string") {
  73. all += ";" + item;
  74. } else if (Array.isArray(item)) {
  75. item.forEach(function (item) {
  76. all += ";" + item;
  77. });
  78. }
  79. return all;
  80. }, "");
  81. return out;
  82. },
  83. /**
  84. * @param hooks
  85. * @param initial
  86. * @param {UI} ui
  87. * @returns {String}
  88. */
  89. "templates": function (hooks, initial, ui) {
  90. /**
  91. * Add templates from each Browsersync registered plugin
  92. * @type {string}
  93. */
  94. var pluginDirectives = ui.bsPlugins.reduce(function (all, plugin) {
  95. if (!plugin.has("templates")) {
  96. return all;
  97. }
  98. /**
  99. * Slugify-ish the plugin name
  100. * eg: Test Browsersync Plugin
  101. * = test-browsersync-plugin
  102. * @type {string}
  103. */
  104. var slug = plugin.get("name")
  105. .trim()
  106. .split(" ")
  107. .map(function (word) {
  108. return word.trim().toLowerCase();
  109. })
  110. .join("-");
  111. /**
  112. * For every plugin that has templates, wrap
  113. * the markup in the <script type="text/ng-template" id="{{slug}}"></script>
  114. * markup to result in the single output string.
  115. */
  116. plugin.get("templates").forEach(function (value, key) {
  117. all += angularWrap([slug, path.basename(key)].join("/"), value);
  118. });
  119. return all;
  120. }, "");
  121. /**
  122. * Combine the markup from the plugins done above with any
  123. * others registered via hooks + initial
  124. * to create the final markup
  125. */
  126. return [pluginDirectives, createInlineTemplates(hooks.concat([initial]))].join("");
  127. },
  128. /**
  129. * Allow plugins to register toggle-able elements
  130. * @param hooks
  131. * @returns {{}}
  132. */
  133. "elements": function (hooks) {
  134. var obj = {};
  135. hooks.forEach(function (elements) {
  136. elements.forEach(function (item) {
  137. if (!obj[item.name]) {
  138. obj[item.name] = item;
  139. }
  140. });
  141. });
  142. return obj;
  143. }
  144. };
  145. /**
  146. * @param hooks
  147. * @returns {String}
  148. */
  149. function createInlineTemplates (hooks) {
  150. return hooks.reduce(function (combined, item) {
  151. return combined + item.reduce(function (all, filepath) {
  152. return all + angularWrap(
  153. path.basename(filepath),
  154. fs.readFileSync(filepath));
  155. }, "");
  156. }, "");
  157. }
  158. /**
  159. * @param item
  160. * @returns {*}
  161. */
  162. function transformConfig (item) {
  163. return item;
  164. }
  165. /**
  166. * @param {String} all
  167. * @param {Object} item
  168. * @returns {*}
  169. */
  170. function createAngularRoutes(all, item) {
  171. return all + configItem.replace(/%(.+)%/g, function () {
  172. var key = arguments[1];
  173. if (item[key]) {
  174. return item[key];
  175. }
  176. });
  177. }
  178. /**
  179. * @param joined
  180. * @param item
  181. * @returns {*}
  182. */
  183. function createConfigItem (joined, item) {
  184. if (item.path === "/") {
  185. joined["overview"] = item;
  186. } else {
  187. joined[item.path.slice(1)] = item;
  188. }
  189. return joined;
  190. }
  191. /**
  192. * @returns {*}
  193. */
  194. function pluginTemplate (combined, item) {
  195. return [combined, pluginTmpl.replace("%markup%", item)].join("\n");
  196. }
  197. /**
  198. * @param plugins
  199. * @param config
  200. * @returns {*}
  201. */
  202. function preAngular (plugins, config, ui) {
  203. return Object.keys(plugins)
  204. .filter(function (key) {
  205. return config[key]; // only work on plugins that have pages
  206. })
  207. .map(function (key) {
  208. if (key === "plugins") {
  209. var pluginMarkup = ui.bsPlugins.reduce(function (all, item, i) {
  210. all += pluginItemTmpl
  211. .replace("%content%", item.get("markup") || "")
  212. .replace(/%index%/g, i)
  213. .replace(/%name%/g, item.get("name"));
  214. return all;
  215. }, "");
  216. plugins[key].hooks.markup = plugins[key].hooks.markup.replace("%pluginlist%", pluginMarkup);
  217. }
  218. return angularWrap(config[key].template, bindOnce(plugins[key].hooks.markup, config[key]));
  219. })
  220. .reduce(function (combined, item) {
  221. return combined + item;
  222. }, "");
  223. }
  224. /**
  225. * @param templateName
  226. * @param markup
  227. * @returns {*}
  228. */
  229. function angularWrap (templateName, markup) {
  230. return inlineTemp
  231. .replace("%content%", markup)
  232. .replace("%id%", templateName);
  233. }
  234. /**
  235. * @param markup
  236. * @param config
  237. * @returns {*|string}
  238. */
  239. function bindOnce (markup, config) {
  240. return markup.toString().replace(/\{\{ctrl.section\.(.+?)\}\}/g, function ($1, $2) {
  241. return config[$2] || "";
  242. });
  243. }
  244. module.exports.bindOnce = bindOnce;