|
203 | 203 | return fn;
|
204 | 204 | };
|
205 | 205 |
|
| 206 | + Writer.prototype.getPartial = function (name) { |
| 207 | + if (!(name in this._partialCache) && this._loadPartial) { |
| 208 | + this.compilePartial(name, this._loadPartial(name)); |
| 209 | + } |
| 210 | + |
| 211 | + return this._partialCache[name]; |
| 212 | + }; |
| 213 | + |
206 | 214 | Writer.prototype.compileTokens = function (tokens, template) {
|
207 |
| - var fn = compileTokens(tokens); |
208 | 215 | var self = this;
|
209 |
| - |
210 | 216 | return function (view, partials) {
|
211 | 217 | if (partials) {
|
212 |
| - if (typeof partials === "function") { |
| 218 | + if (typeof partials === 'function') { |
213 | 219 | self._loadPartial = partials;
|
214 | 220 | } else {
|
215 | 221 | for (var name in partials) {
|
|
218 | 224 | }
|
219 | 225 | }
|
220 | 226 |
|
221 |
| - return fn(self, Context.make(view), template); |
| 227 | + return renderTokens(tokens, self, Context.make(view), template); |
222 | 228 | };
|
223 | 229 | };
|
224 | 230 |
|
225 | 231 | Writer.prototype.render = function (template, view, partials) {
|
226 | 232 | return this.compile(template)(view, partials);
|
227 | 233 | };
|
228 | 234 |
|
229 |
| - Writer.prototype._section = function (token, context, template, callback) { |
230 |
| - var name = token[1]; |
231 |
| - var value = context.lookup(name); |
232 |
| - |
233 |
| - switch (typeof value) { |
234 |
| - case "object": |
235 |
| - if (isArray(value)) { |
236 |
| - var buffer = ''; |
237 |
| - |
238 |
| - for (var i = 0, len = value.length; i < len; ++i) { |
239 |
| - buffer += callback(this, context.push(value[i])); |
240 |
| - } |
241 |
| - |
242 |
| - return buffer; |
243 |
| - } |
244 |
| - |
245 |
| - return value ? callback(this, context.push(value)) : ""; |
246 |
| - case "function": |
247 |
| - var text = template == null ? null : template.slice(token[3], token[5]); |
248 |
| - var self = this; |
249 |
| - var scopedRender = function (template) { |
250 |
| - return self.render(template, context); |
251 |
| - }; |
252 |
| - |
253 |
| - var result = value.call(context.view, text, scopedRender); |
254 |
| - return result == null ? '' : result; |
255 |
| - default: |
256 |
| - if (value) { |
257 |
| - return callback(this, context); |
258 |
| - } |
259 |
| - } |
260 |
| - |
261 |
| - return ''; |
262 |
| - }; |
263 |
| - |
264 |
| - Writer.prototype._inverted = function (token, context, callback) { |
265 |
| - var value = context.lookup(token[1]); |
266 |
| - |
267 |
| - // Use JavaScript's definition of falsy. Include empty arrays. |
268 |
| - // See https://github.com/janl/mustache.js/issues/186 |
269 |
| - if (!value || (isArray(value) && value.length === 0)) { |
270 |
| - return callback(this, context); |
271 |
| - } |
272 |
| - |
273 |
| - return ''; |
274 |
| - }; |
275 |
| - |
276 |
| - Writer.prototype._partial = function (token, context) { |
277 |
| - var name = token[1]; |
| 235 | + /** |
| 236 | + * Low-level function that renders the given `tokens` using the given `writer` |
| 237 | + * and `context`. The `template` string is only needed for templates that use |
| 238 | + * higher-order sections to extract the portion of the original template that |
| 239 | + * was contained in that section. |
| 240 | + */ |
| 241 | + function renderTokens(tokens, writer, context, template) { |
| 242 | + var buffer = ''; |
278 | 243 |
|
279 |
| - if (!(name in this._partialCache) && this._loadPartial) { |
280 |
| - this.compilePartial(name, this._loadPartial(name)); |
281 |
| - } |
| 244 | + var token, tokenValue, value; |
| 245 | + for (var i = 0, len = tokens.length; i < len; ++i) { |
| 246 | + token = tokens[i]; |
| 247 | + tokenValue = token[1]; |
282 | 248 |
|
283 |
| - var fn = this._partialCache[name]; |
| 249 | + switch (token[0]) { |
| 250 | + case '#': |
| 251 | + value = context.lookup(tokenValue); |
284 | 252 |
|
285 |
| - return fn ? fn(context) : ''; |
286 |
| - }; |
| 253 | + if (typeof value === 'object') { |
| 254 | + if (isArray(value)) { |
| 255 | + for (var j = 0, jlen = value.length; j < jlen; ++j) { |
| 256 | + buffer += renderTokens(token[4], writer, context.push(value[j]), template); |
| 257 | + } |
| 258 | + } else if (value) { |
| 259 | + buffer += renderTokens(token[4], writer, context.push(value), template); |
| 260 | + } |
| 261 | + } else if (typeof value === 'function') { |
| 262 | + var text = template == null ? null : template.slice(token[3], token[5]); |
| 263 | + var result = value.call(context.view, text, function (template) { |
| 264 | + return writer.render(template, context); |
| 265 | + }); |
| 266 | + if (result != null) buffer += result; |
| 267 | + } else if (value) { |
| 268 | + buffer += renderTokens(token[4], writer, context, template); |
| 269 | + } |
287 | 270 |
|
288 |
| - Writer.prototype._name = function (token, context) { |
289 |
| - var value = context.lookup(token[1]); |
290 |
| - return value == null ? '' : value; |
291 |
| - }; |
| 271 | + break; |
| 272 | + case '^': |
| 273 | + value = context.lookup(tokenValue); |
292 | 274 |
|
293 |
| - Writer.prototype._escaped = function (token, context) { |
294 |
| - return exports.escape(this._name(token, context)); |
295 |
| - }; |
| 275 | + // Use JavaScript's definition of falsy. Include empty arrays. |
| 276 | + // See https://github.com/janl/mustache.js/issues/186 |
| 277 | + if (!value || (isArray(value) && value.length === 0)) { |
| 278 | + buffer += renderTokens(token[4], writer, context, template); |
| 279 | + } |
296 | 280 |
|
297 |
| - /** |
298 |
| - * Low-level function that compiles the given `tokens` into a function |
299 |
| - * that accepts three arguments: a Writer, a Context, and the template. |
300 |
| - */ |
301 |
| - function compileTokens(tokens) { |
302 |
| - var subRenders = {}; |
303 |
| - |
304 |
| - function subRender(i, tokens, template) { |
305 |
| - if (!subRenders[i]) { |
306 |
| - var fn = compileTokens(tokens); |
307 |
| - subRenders[i] = function (writer, context) { |
308 |
| - return fn(writer, context, template); |
309 |
| - }; |
| 281 | + break; |
| 282 | + case '>': |
| 283 | + value = writer.getPartial(tokenValue); |
| 284 | + if (typeof value === 'function') buffer += value(context); |
| 285 | + break; |
| 286 | + case '&': |
| 287 | + value = context.lookup(tokenValue); |
| 288 | + if (value != null) buffer += value; |
| 289 | + break; |
| 290 | + case 'name': |
| 291 | + value = context.lookup(tokenValue); |
| 292 | + if (value != null) buffer += exports.escape(value); |
| 293 | + break; |
| 294 | + case 'text': |
| 295 | + buffer += tokenValue; |
| 296 | + break; |
310 | 297 | }
|
311 |
| - |
312 |
| - return subRenders[i]; |
313 | 298 | }
|
314 | 299 |
|
315 |
| - return function (writer, context, template) { |
316 |
| - var buffer = ''; |
317 |
| - |
318 |
| - var token; |
319 |
| - for (var i = 0, len = tokens.length; i < len; ++i) { |
320 |
| - token = tokens[i]; |
321 |
| - switch (token[0]) { |
322 |
| - case "#": |
323 |
| - buffer += writer._section(token, context, template, subRender(i, token[4], template)); |
324 |
| - break; |
325 |
| - case "^": |
326 |
| - buffer += writer._inverted(token, context, subRender(i, token[4], template)); |
327 |
| - break; |
328 |
| - case ">": |
329 |
| - buffer += writer._partial(token, context); |
330 |
| - break; |
331 |
| - case "&": |
332 |
| - buffer += writer._name(token, context); |
333 |
| - break; |
334 |
| - case "name": |
335 |
| - buffer += writer._escaped(token, context); |
336 |
| - break; |
337 |
| - case "text": |
338 |
| - buffer += token[1]; |
339 |
| - break; |
340 |
| - } |
341 |
| - } |
342 |
| - |
343 |
| - return buffer; |
344 |
| - }; |
| 300 | + return buffer; |
345 | 301 | }
|
346 | 302 |
|
347 | 303 | /**
|
|
544 | 500 | return nestTokens(squashTokens(tokens));
|
545 | 501 | };
|
546 | 502 |
|
547 |
| - // The high-level clearCache, compile, compilePartial, and render functions |
548 |
| - // use this default writer. |
| 503 | + // All Mustache.* functions use this writer. |
549 | 504 | var _writer = new Writer();
|
550 | 505 |
|
551 | 506 | /**
|
|
0 commit comments