handlebars-layouts.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.handlebarsLayouts = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
  2. 'use strict';
  3. var hasOwn = Object.prototype.hasOwnProperty;
  4. function noop() {
  5. return '';
  6. }
  7. function getStack(context) {
  8. return context.$$layoutStack || (
  9. context.$$layoutStack = []
  10. );
  11. }
  12. function applyStack(context) {
  13. var stack = getStack(context);
  14. while (stack.length) {
  15. stack.shift()(context);
  16. }
  17. }
  18. function getActions(context) {
  19. return context.$$layoutActions || (
  20. context.$$layoutActions = {}
  21. );
  22. }
  23. function getActionsByName(context, name) {
  24. var actions = getActions(context);
  25. return actions[name] || (
  26. actions[name] = []
  27. );
  28. }
  29. function applyAction(val, action) {
  30. var context = this;
  31. function fn() {
  32. return action.fn(context, action.options);
  33. }
  34. switch (action.mode) {
  35. case 'append': {
  36. return val + fn();
  37. }
  38. case 'prepend': {
  39. return fn() + val;
  40. }
  41. case 'replace': {
  42. return fn();
  43. }
  44. default: {
  45. return val;
  46. }
  47. }
  48. }
  49. function mixin(target) {
  50. var arg, key,
  51. len = arguments.length,
  52. i = 1;
  53. for (; i < len; i++) {
  54. arg = arguments[i];
  55. if (!arg) {
  56. continue;
  57. }
  58. for (key in arg) {
  59. // istanbul ignore else
  60. if (hasOwn.call(arg, key)) {
  61. target[key] = arg[key];
  62. }
  63. }
  64. }
  65. return target;
  66. }
  67. /**
  68. * Generates an object of layout helpers.
  69. *
  70. * @type {Function}
  71. * @param {Object} handlebars Handlebars instance.
  72. * @return {Object} Object of helpers.
  73. */
  74. function layouts(handlebars) {
  75. var helpers = {
  76. /**
  77. * @method extend
  78. * @param {String} name
  79. * @param {?Object} customContext
  80. * @param {Object} options
  81. * @param {Function(Object)} options.fn
  82. * @param {Object} options.hash
  83. * @return {String} Rendered partial.
  84. */
  85. extend: function (name, customContext, options) {
  86. // Make `customContext` optional
  87. if (arguments.length < 3) {
  88. options = customContext;
  89. customContext = null;
  90. }
  91. options = options || {};
  92. var fn = options.fn || noop,
  93. context = mixin({}, this, customContext, options.hash),
  94. data = handlebars.createFrame(options.data),
  95. template = handlebars.partials[name];
  96. // Partial template required
  97. if (template == null) {
  98. throw new Error('Missing partial: \'' + name + '\'');
  99. }
  100. // Compile partial, if needed
  101. if (typeof template !== 'function') {
  102. template = handlebars.compile(template);
  103. }
  104. // Add overrides to stack
  105. getStack(context).push(fn);
  106. // Render partial
  107. return template(context, { data: data });
  108. },
  109. /**
  110. * @method embed
  111. * @param {String} name
  112. * @param {?Object} customContext
  113. * @param {Object} options
  114. * @param {Function(Object)} options.fn
  115. * @param {Object} options.hash
  116. * @return {String} Rendered partial.
  117. */
  118. embed: function () {
  119. var context = mixin({}, this || {});
  120. // Reset context
  121. context.$$layoutStack = null;
  122. context.$$layoutActions = null;
  123. // Extend
  124. return helpers.extend.apply(context, arguments);
  125. },
  126. /**
  127. * @method block
  128. * @param {String} name
  129. * @param {Object} options
  130. * @param {Function(Object)} options.fn
  131. * @return {String} Modified block content.
  132. */
  133. block: function (name, options) {
  134. options = options || {};
  135. var fn = options.fn || noop,
  136. data = handlebars.createFrame(options.data),
  137. context = this || {};
  138. applyStack(context);
  139. return getActionsByName(context, name).reduce(
  140. applyAction.bind(context),
  141. fn(context, { data: data })
  142. );
  143. },
  144. /**
  145. * @method content
  146. * @param {String} name
  147. * @param {Object} options
  148. * @param {Function(Object)} options.fn
  149. * @param {Object} options.hash
  150. * @param {String} options.hash.mode
  151. * @return {String} Always empty.
  152. */
  153. content: function (name, options) {
  154. options = options || {};
  155. var fn = options.fn,
  156. data = handlebars.createFrame(options.data),
  157. hash = options.hash || {},
  158. mode = hash.mode || 'replace',
  159. context = this || {};
  160. applyStack(context);
  161. // Getter
  162. if (!fn) {
  163. return name in getActions(context);
  164. }
  165. // Setter
  166. getActionsByName(context, name).push({
  167. options: { data: data },
  168. mode: mode.toLowerCase(),
  169. fn: fn
  170. });
  171. }
  172. };
  173. return helpers;
  174. }
  175. /**
  176. * Registers layout helpers on a Handlebars instance.
  177. *
  178. * @method register
  179. * @param {Object} handlebars Handlebars instance.
  180. * @return {Object} Object of helpers.
  181. * @static
  182. */
  183. layouts.register = function (handlebars) {
  184. var helpers = layouts(handlebars);
  185. handlebars.registerHelper(helpers);
  186. return helpers;
  187. };
  188. module.exports = layouts;
  189. },{}]},{},[1])(1)
  190. });