mustache-js-rails 0.0.5 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of mustache-js-rails might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5016f09bb6a7d5d85e61bbed6a6ef13248db23fa
4
- data.tar.gz: 677f8b752d447377da5f320f463965e0fe168795
3
+ metadata.gz: cbee184c60860b031ded3ba62f65b612d032f1f5
4
+ data.tar.gz: 1bb01b3f79faa7312ad4f70146250329a66fb601
5
5
  SHA512:
6
- metadata.gz: 451118b3037b7ea473b6e00daa927f0eec1423d3d955b2529f45adab32732d7376542bbc66025a3061b3e0587f6d917b97621186002141ddc82456b933f6eca1
7
- data.tar.gz: e8e40d3914ca288375bb2566185ac0e87054f39bd230a780729e21e4690751d2fa36b56e9360921b2c6667e0a16a622e5975a0152da57838e484bd109fbb9d41
6
+ metadata.gz: 446d05a48e8ff7b4e22fc520ad6be4d854eb4434b7b2612643d5ddc445a00b235dc3d27270e087e18918132ec0fc0494cadf3102f0763eb11623d961cb29a0ef
7
+ data.tar.gz: 1f385e4b45c99e97465dedb73fa546757e91bd013663d00d132f0ba23cd2d23f8de7d91df945557e9c5f404b40b24c22701c8271c7b87ff2c4a97a1bd34f4fbb
data/README.md CHANGED
@@ -5,7 +5,7 @@ and [mustache jQuery integration](https://github.com/jonnyreeves/jquery-Mustache
5
5
 
6
6
  Integrated versions are:
7
7
 
8
- * mustache.js - <b id="mustache-js-version">0.7.3</b>
8
+ * mustache.js - <b id="mustache-js-version">0.8.1</b>
9
9
  * jQuery mustache - <b id="jQuery-mustache-version">0.2.7</b>
10
10
 
11
11
  ### Installation
@@ -1,3 +1,3 @@
1
1
  module MustacheJsRails
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
@@ -65,6 +65,220 @@
65
65
  });
66
66
  }
67
67
 
68
+ function escapeTags(tags) {
69
+ if (!isArray(tags) || tags.length !== 2) {
70
+ throw new Error('Invalid tags: ' + tags);
71
+ }
72
+
73
+ return [
74
+ new RegExp(escapeRegExp(tags[0]) + "\\s*"),
75
+ new RegExp("\\s*" + escapeRegExp(tags[1]))
76
+ ];
77
+ }
78
+
79
+ /**
80
+ * Breaks up the given `template` string into a tree of tokens. If the `tags`
81
+ * argument is given here it must be an array with two string values: the
82
+ * opening and closing tags used in the template (e.g. [ "<%", "%>" ]). Of
83
+ * course, the default is to use mustaches (i.e. mustache.tags).
84
+ *
85
+ * A token is an array with at least 4 elements. The first element is the
86
+ * mustache symbol that was used inside the tag, e.g. "#" or "&". If the tag
87
+ * did not contain a symbol (i.e. {{myValue}}) this element is "name". For
88
+ * all template text that appears outside a symbol this element is "text".
89
+ *
90
+ * The second element of a token is its "value". For mustache tags this is
91
+ * whatever else was inside the tag besides the opening symbol. For text tokens
92
+ * this is the text itself.
93
+ *
94
+ * The third and fourth elements of the token are the start and end indices
95
+ * in the original template of the token, respectively.
96
+ *
97
+ * Tokens that are the root node of a subtree contain two more elements: an
98
+ * array of tokens in the subtree and the index in the original template at which
99
+ * the closing tag for that section begins.
100
+ */
101
+ function parseTemplate(template, tags) {
102
+ tags = tags || mustache.tags;
103
+ template = template || '';
104
+
105
+ if (typeof tags === 'string') {
106
+ tags = tags.split(spaceRe);
107
+ }
108
+
109
+ var tagRes = escapeTags(tags);
110
+ var scanner = new Scanner(template);
111
+
112
+ var sections = []; // Stack to hold section tokens
113
+ var tokens = []; // Buffer to hold the tokens
114
+ var spaces = []; // Indices of whitespace tokens on the current line
115
+ var hasTag = false; // Is there a {{tag}} on the current line?
116
+ var nonSpace = false; // Is there a non-space char on the current line?
117
+
118
+ // Strips all whitespace tokens array for the current line
119
+ // if there was a {{#tag}} on it and otherwise only space.
120
+ function stripSpace() {
121
+ if (hasTag && !nonSpace) {
122
+ while (spaces.length) {
123
+ delete tokens[spaces.pop()];
124
+ }
125
+ } else {
126
+ spaces = [];
127
+ }
128
+
129
+ hasTag = false;
130
+ nonSpace = false;
131
+ }
132
+
133
+ var start, type, value, chr, token, openSection;
134
+ while (!scanner.eos()) {
135
+ start = scanner.pos;
136
+
137
+ // Match any text between tags.
138
+ value = scanner.scanUntil(tagRes[0]);
139
+ if (value) {
140
+ for (var i = 0, len = value.length; i < len; ++i) {
141
+ chr = value.charAt(i);
142
+
143
+ if (isWhitespace(chr)) {
144
+ spaces.push(tokens.length);
145
+ } else {
146
+ nonSpace = true;
147
+ }
148
+
149
+ tokens.push(['text', chr, start, start + 1]);
150
+ start += 1;
151
+
152
+ // Check for whitespace on the current line.
153
+ if (chr === '\n') {
154
+ stripSpace();
155
+ }
156
+ }
157
+ }
158
+
159
+ // Match the opening tag.
160
+ if (!scanner.scan(tagRes[0])) break;
161
+ hasTag = true;
162
+
163
+ // Get the tag type.
164
+ type = scanner.scan(tagRe) || 'name';
165
+ scanner.scan(whiteRe);
166
+
167
+ // Get the tag value.
168
+ if (type === '=') {
169
+ value = scanner.scanUntil(eqRe);
170
+ scanner.scan(eqRe);
171
+ scanner.scanUntil(tagRes[1]);
172
+ } else if (type === '{') {
173
+ value = scanner.scanUntil(new RegExp('\\s*' + escapeRegExp('}' + tags[1])));
174
+ scanner.scan(curlyRe);
175
+ scanner.scanUntil(tagRes[1]);
176
+ type = '&';
177
+ } else {
178
+ value = scanner.scanUntil(tagRes[1]);
179
+ }
180
+
181
+ // Match the closing tag.
182
+ if (!scanner.scan(tagRes[1])) {
183
+ throw new Error('Unclosed tag at ' + scanner.pos);
184
+ }
185
+
186
+ token = [ type, value, start, scanner.pos ];
187
+ tokens.push(token);
188
+
189
+ if (type === '#' || type === '^') {
190
+ sections.push(token);
191
+ } else if (type === '/') {
192
+ // Check section nesting.
193
+ openSection = sections.pop();
194
+
195
+ if (!openSection) {
196
+ throw new Error('Unopened section "' + value + '" at ' + start);
197
+ }
198
+ if (openSection[1] !== value) {
199
+ throw new Error('Unclosed section "' + openSection[1] + '" at ' + start);
200
+ }
201
+ } else if (type === 'name' || type === '{' || type === '&') {
202
+ nonSpace = true;
203
+ } else if (type === '=') {
204
+ // Set the tags for the next time around.
205
+ tagRes = escapeTags(tags = value.split(spaceRe));
206
+ }
207
+ }
208
+
209
+ // Make sure there are no open sections when we're done.
210
+ openSection = sections.pop();
211
+ if (openSection) {
212
+ throw new Error('Unclosed section "' + openSection[1] + '" at ' + scanner.pos);
213
+ }
214
+
215
+ return nestTokens(squashTokens(tokens));
216
+ }
217
+
218
+ /**
219
+ * Combines the values of consecutive text tokens in the given `tokens` array
220
+ * to a single token.
221
+ */
222
+ function squashTokens(tokens) {
223
+ var squashedTokens = [];
224
+
225
+ var token, lastToken;
226
+ for (var i = 0, len = tokens.length; i < len; ++i) {
227
+ token = tokens[i];
228
+
229
+ if (token) {
230
+ if (token[0] === 'text' && lastToken && lastToken[0] === 'text') {
231
+ lastToken[1] += token[1];
232
+ lastToken[3] = token[3];
233
+ } else {
234
+ squashedTokens.push(token);
235
+ lastToken = token;
236
+ }
237
+ }
238
+ }
239
+
240
+ return squashedTokens;
241
+ }
242
+
243
+ /**
244
+ * Forms the given array of `tokens` into a nested tree structure where
245
+ * tokens that represent a section have two additional items: 1) an array of
246
+ * all tokens that appear in that section and 2) the index in the original
247
+ * template that represents the end of that section.
248
+ */
249
+ function nestTokens(tokens) {
250
+ var nestedTokens = [];
251
+ var collector = nestedTokens;
252
+ var sections = [];
253
+
254
+ var token, section;
255
+ for (var i = 0, len = tokens.length; i < len; ++i) {
256
+ token = tokens[i];
257
+
258
+ switch (token[0]) {
259
+ case '#':
260
+ case '^':
261
+ collector.push(token);
262
+ sections.push(token);
263
+ collector = token[4] = [];
264
+ break;
265
+ case '/':
266
+ section = sections.pop();
267
+ section[5] = token[2];
268
+ collector = sections.length > 0 ? sections[sections.length - 1][4] : nestedTokens;
269
+ break;
270
+ default:
271
+ collector.push(token);
272
+ }
273
+ }
274
+
275
+ return nestedTokens;
276
+ }
277
+
278
+ /**
279
+ * A simple string scanner that is used by the template parser to find
280
+ * tokens in template strings.
281
+ */
68
282
  function Scanner(string) {
69
283
  this.string = string;
70
284
  this.tail = string;
@@ -120,24 +334,32 @@
120
334
  return match;
121
335
  };
122
336
 
123
- function Context(view, parent) {
337
+ /**
338
+ * Represents a rendering context by wrapping a view object and
339
+ * maintaining a reference to the parent context.
340
+ */
341
+ function Context(view, parentContext) {
124
342
  this.view = view == null ? {} : view;
125
- this.parent = parent;
126
- this._cache = { '.': this.view };
343
+ this.cache = { '.': this.view };
344
+ this.parent = parentContext;
127
345
  }
128
346
 
129
- Context.make = function (view) {
130
- return (view instanceof Context) ? view : new Context(view);
131
- };
132
-
347
+ /**
348
+ * Creates a new context using the given view with this context
349
+ * as the parent.
350
+ */
133
351
  Context.prototype.push = function (view) {
134
352
  return new Context(view, this);
135
353
  };
136
354
 
355
+ /**
356
+ * Returns the value of the given name in this context, traversing
357
+ * up the context hierarchy if the value is absent in this context's view.
358
+ */
137
359
  Context.prototype.lookup = function (name) {
138
360
  var value;
139
- if (name in this._cache) {
140
- value = this._cache[name];
361
+ if (name in this.cache) {
362
+ value = this.cache[name];
141
363
  } else {
142
364
  var context = this;
143
365
 
@@ -158,7 +380,7 @@
158
380
  context = context.parent;
159
381
  }
160
382
 
161
- this._cache[name] = value;
383
+ this.cache[name] = value;
162
384
  }
163
385
 
164
386
  if (isFunction(value)) {
@@ -168,365 +390,153 @@
168
390
  return value;
169
391
  };
170
392
 
393
+ /**
394
+ * A Writer knows how to take a stream of tokens and render them to a
395
+ * string, given a context. It also maintains a cache of templates to
396
+ * avoid the need to parse the same template twice.
397
+ */
171
398
  function Writer() {
172
- this.clearCache();
399
+ this.cache = {};
173
400
  }
174
401
 
402
+ /**
403
+ * Clears all cached templates in this writer.
404
+ */
175
405
  Writer.prototype.clearCache = function () {
176
- this._cache = {};
177
- this._partialCache = {};
406
+ this.cache = {};
178
407
  };
179
408
 
180
- Writer.prototype.compile = function (template, tags) {
181
- var fn = this._cache[template];
182
-
183
- if (!fn) {
184
- var tokens = mustache.parse(template, tags);
185
- fn = this._cache[template] = this.compileTokens(tokens, template);
186
- }
187
-
188
- return fn;
189
- };
190
-
191
- Writer.prototype.compilePartial = function (name, template, tags) {
192
- var fn = this.compile(template, tags);
193
- this._partialCache[name] = fn;
194
- return fn;
195
- };
409
+ /**
410
+ * Parses and caches the given `template` and returns the array of tokens
411
+ * that is generated from the parse.
412
+ */
413
+ Writer.prototype.parse = function (template, tags) {
414
+ var cache = this.cache;
415
+ var tokens = cache[template];
196
416
 
197
- Writer.prototype.getPartial = function (name) {
198
- if (!(name in this._partialCache) && this._loadPartial) {
199
- this.compilePartial(name, this._loadPartial(name));
417
+ if (tokens == null) {
418
+ tokens = cache[template] = parseTemplate(template, tags);
200
419
  }
201
420
 
202
- return this._partialCache[name];
203
- };
204
-
205
- Writer.prototype.compileTokens = function (tokens, template) {
206
- var self = this;
207
- return function (view, partials) {
208
- if (partials) {
209
- if (isFunction(partials)) {
210
- self._loadPartial = partials;
211
- } else {
212
- for (var name in partials) {
213
- self.compilePartial(name, partials[name]);
214
- }
215
- }
216
- }
217
-
218
- return renderTokens(tokens, self, Context.make(view), template);
219
- };
421
+ return tokens;
220
422
  };
221
423
 
424
+ /**
425
+ * High-level method that is used to render the given `template` with
426
+ * the given `view`.
427
+ *
428
+ * The optional `partials` argument may be an object that contains the
429
+ * names and templates of partials that are used in the template. It may
430
+ * also be a function that is used to load partial templates on the fly
431
+ * that takes a single argument: the name of the partial.
432
+ */
222
433
  Writer.prototype.render = function (template, view, partials) {
223
- return this.compile(template)(view, partials);
434
+ var tokens = this.parse(template);
435
+ var context = (view instanceof Context) ? view : new Context(view);
436
+ return this.renderTokens(tokens, context, partials, template);
224
437
  };
225
438
 
226
439
  /**
227
- * Low-level function that renders the given `tokens` using the given `writer`
228
- * and `context`. The `template` string is only needed for templates that use
229
- * higher-order sections to extract the portion of the original template that
230
- * was contained in that section.
440
+ * Low-level method that renders the given array of `tokens` using
441
+ * the given `context` and `partials`.
442
+ *
443
+ * Note: The `originalTemplate` is only ever used to extract the portion
444
+ * of the original template that was contained in a higher-order section.
445
+ * If the template doesn't use higher-order sections, this argument may
446
+ * be omitted.
231
447
  */
232
- function renderTokens(tokens, writer, context, template) {
448
+ Writer.prototype.renderTokens = function (tokens, context, partials, originalTemplate) {
233
449
  var buffer = '';
234
450
 
235
- // This function is used to render an artbitrary template
236
- // in the current context by higher-order functions.
451
+ // This function is used to render an arbitrary template
452
+ // in the current context by higher-order sections.
453
+ var self = this;
237
454
  function subRender(template) {
238
- return writer.render(template, context);
455
+ return self.render(template, context, partials);
239
456
  }
240
457
 
241
- var token, tokenValue, value;
458
+ var token, value;
242
459
  for (var i = 0, len = tokens.length; i < len; ++i) {
243
460
  token = tokens[i];
244
- tokenValue = token[1];
245
461
 
246
462
  switch (token[0]) {
247
463
  case '#':
248
- value = context.lookup(tokenValue);
249
-
250
- if (typeof value === 'object' || typeof value === 'string') {
251
- if (isArray(value)) {
252
- for (var j = 0, jlen = value.length; j < jlen; ++j) {
253
- buffer += renderTokens(token[4], writer, context.push(value[j]), template);
254
- }
255
- } else if (value) {
256
- buffer += renderTokens(token[4], writer, context.push(value), template);
464
+ value = context.lookup(token[1]);
465
+ if (!value) continue;
466
+
467
+ if (isArray(value)) {
468
+ for (var j = 0, jlen = value.length; j < jlen; ++j) {
469
+ buffer += this.renderTokens(token[4], context.push(value[j]), partials, originalTemplate);
257
470
  }
471
+ } else if (typeof value === 'object' || typeof value === 'string') {
472
+ buffer += this.renderTokens(token[4], context.push(value), partials, originalTemplate);
258
473
  } else if (isFunction(value)) {
259
- var text = template == null ? null : template.slice(token[3], token[5]);
260
- value = value.call(context.view, text, subRender);
474
+ if (typeof originalTemplate !== 'string') {
475
+ throw new Error('Cannot use higher-order sections without the original template');
476
+ }
477
+
478
+ // Extract the portion of the original template that the section contains.
479
+ value = value.call(context.view, originalTemplate.slice(token[3], token[5]), subRender);
480
+
261
481
  if (value != null) buffer += value;
262
- } else if (value) {
263
- buffer += renderTokens(token[4], writer, context, template);
482
+ } else {
483
+ buffer += this.renderTokens(token[4], context, partials, originalTemplate);
264
484
  }
265
485
 
266
486
  break;
267
487
  case '^':
268
- value = context.lookup(tokenValue);
488
+ value = context.lookup(token[1]);
269
489
 
270
490
  // Use JavaScript's definition of falsy. Include empty arrays.
271
491
  // See https://github.com/janl/mustache.js/issues/186
272
492
  if (!value || (isArray(value) && value.length === 0)) {
273
- buffer += renderTokens(token[4], writer, context, template);
493
+ buffer += this.renderTokens(token[4], context, partials, originalTemplate);
274
494
  }
275
495
 
276
496
  break;
277
497
  case '>':
278
- value = writer.getPartial(tokenValue);
279
- if (isFunction(value)) buffer += value(context);
498
+ if (!partials) continue;
499
+ value = isFunction(partials) ? partials(token[1]) : partials[token[1]];
500
+ if (value != null) buffer += this.renderTokens(this.parse(value), context, partials, value);
280
501
  break;
281
502
  case '&':
282
- value = context.lookup(tokenValue);
503
+ value = context.lookup(token[1]);
283
504
  if (value != null) buffer += value;
284
505
  break;
285
506
  case 'name':
286
- value = context.lookup(tokenValue);
507
+ value = context.lookup(token[1]);
287
508
  if (value != null) buffer += mustache.escape(value);
288
509
  break;
289
510
  case 'text':
290
- buffer += tokenValue;
511
+ buffer += token[1];
291
512
  break;
292
513
  }
293
514
  }
294
515
 
295
516
  return buffer;
296
- }
297
-
298
- /**
299
- * Forms the given array of `tokens` into a nested tree structure where
300
- * tokens that represent a section have two additional items: 1) an array of
301
- * all tokens that appear in that section and 2) the index in the original
302
- * template that represents the end of that section.
303
- */
304
- function nestTokens(tokens) {
305
- var tree = [];
306
- var collector = tree;
307
- var sections = [];
308
-
309
- var token;
310
- for (var i = 0, len = tokens.length; i < len; ++i) {
311
- token = tokens[i];
312
- switch (token[0]) {
313
- case '#':
314
- case '^':
315
- sections.push(token);
316
- collector.push(token);
317
- collector = token[4] = [];
318
- break;
319
- case '/':
320
- var section = sections.pop();
321
- section[5] = token[2];
322
- collector = sections.length > 0 ? sections[sections.length - 1][4] : tree;
323
- break;
324
- default:
325
- collector.push(token);
326
- }
327
- }
328
-
329
- return tree;
330
- }
331
-
332
- /**
333
- * Combines the values of consecutive text tokens in the given `tokens` array
334
- * to a single token.
335
- */
336
- function squashTokens(tokens) {
337
- var squashedTokens = [];
338
-
339
- var token, lastToken;
340
- for (var i = 0, len = tokens.length; i < len; ++i) {
341
- token = tokens[i];
342
- if (token) {
343
- if (token[0] === 'text' && lastToken && lastToken[0] === 'text') {
344
- lastToken[1] += token[1];
345
- lastToken[3] = token[3];
346
- } else {
347
- lastToken = token;
348
- squashedTokens.push(token);
349
- }
350
- }
351
- }
352
-
353
- return squashedTokens;
354
- }
355
-
356
- function escapeTags(tags) {
357
- return [
358
- new RegExp(escapeRegExp(tags[0]) + "\\s*"),
359
- new RegExp("\\s*" + escapeRegExp(tags[1]))
360
- ];
361
- }
362
-
363
- /**
364
- * Breaks up the given `template` string into a tree of token objects. If
365
- * `tags` is given here it must be an array with two string values: the
366
- * opening and closing tags used in the template (e.g. ["<%", "%>"]). Of
367
- * course, the default is to use mustaches (i.e. Mustache.tags).
368
- */
369
- function parseTemplate(template, tags) {
370
- template = template || '';
371
- tags = tags || mustache.tags;
372
-
373
- if (typeof tags === 'string') tags = tags.split(spaceRe);
374
- if (tags.length !== 2) throw new Error('Invalid tags: ' + tags.join(', '));
375
-
376
- var tagRes = escapeTags(tags);
377
- var scanner = new Scanner(template);
378
-
379
- var sections = []; // Stack to hold section tokens
380
- var tokens = []; // Buffer to hold the tokens
381
- var spaces = []; // Indices of whitespace tokens on the current line
382
- var hasTag = false; // Is there a {{tag}} on the current line?
383
- var nonSpace = false; // Is there a non-space char on the current line?
384
-
385
- // Strips all whitespace tokens array for the current line
386
- // if there was a {{#tag}} on it and otherwise only space.
387
- function stripSpace() {
388
- if (hasTag && !nonSpace) {
389
- while (spaces.length) {
390
- delete tokens[spaces.pop()];
391
- }
392
- } else {
393
- spaces = [];
394
- }
395
-
396
- hasTag = false;
397
- nonSpace = false;
398
- }
399
-
400
- var start, type, value, chr, token, openSection;
401
- while (!scanner.eos()) {
402
- start = scanner.pos;
403
-
404
- // Match any text between tags.
405
- value = scanner.scanUntil(tagRes[0]);
406
- if (value) {
407
- for (var i = 0, len = value.length; i < len; ++i) {
408
- chr = value.charAt(i);
409
-
410
- if (isWhitespace(chr)) {
411
- spaces.push(tokens.length);
412
- } else {
413
- nonSpace = true;
414
- }
415
-
416
- tokens.push(['text', chr, start, start + 1]);
417
- start += 1;
418
-
419
- // Check for whitespace on the current line.
420
- if (chr == '\n') stripSpace();
421
- }
422
- }
423
-
424
- // Match the opening tag.
425
- if (!scanner.scan(tagRes[0])) break;
426
- hasTag = true;
427
-
428
- // Get the tag type.
429
- type = scanner.scan(tagRe) || 'name';
430
- scanner.scan(whiteRe);
431
-
432
- // Get the tag value.
433
- if (type === '=') {
434
- value = scanner.scanUntil(eqRe);
435
- scanner.scan(eqRe);
436
- scanner.scanUntil(tagRes[1]);
437
- } else if (type === '{') {
438
- value = scanner.scanUntil(new RegExp('\\s*' + escapeRegExp('}' + tags[1])));
439
- scanner.scan(curlyRe);
440
- scanner.scanUntil(tagRes[1]);
441
- type = '&';
442
- } else {
443
- value = scanner.scanUntil(tagRes[1]);
444
- }
445
-
446
- // Match the closing tag.
447
- if (!scanner.scan(tagRes[1])) throw new Error('Unclosed tag at ' + scanner.pos);
448
-
449
- token = [type, value, start, scanner.pos];
450
- tokens.push(token);
451
-
452
- if (type === '#' || type === '^') {
453
- sections.push(token);
454
- } else if (type === '/') {
455
- // Check section nesting.
456
- openSection = sections.pop();
457
- if (!openSection) {
458
- throw new Error('Unopened section "' + value + '" at ' + start);
459
- }
460
- if (openSection[1] !== value) {
461
- throw new Error('Unclosed section "' + openSection[1] + '" at ' + start);
462
- }
463
- } else if (type === 'name' || type === '{' || type === '&') {
464
- nonSpace = true;
465
- } else if (type === '=') {
466
- // Set the tags for the next time around.
467
- tags = value.split(spaceRe);
468
- if (tags.length !== 2) {
469
- throw new Error('Invalid tags at ' + start + ': ' + tags.join(', '));
470
- }
471
- tagRes = escapeTags(tags);
472
- }
473
- }
474
-
475
- // Make sure there are no open sections when we're done.
476
- openSection = sections.pop();
477
- if (openSection) {
478
- throw new Error('Unclosed section "' + openSection[1] + '" at ' + scanner.pos);
479
- }
480
-
481
- return nestTokens(squashTokens(tokens));
482
- }
517
+ };
483
518
 
484
519
  mustache.name = "mustache.js";
485
- mustache.version = "0.7.3";
486
- mustache.tags = ["{{", "}}"];
520
+ mustache.version = "0.8.1";
521
+ mustache.tags = [ "{{", "}}" ];
487
522
 
488
- mustache.Scanner = Scanner;
489
- mustache.Context = Context;
490
- mustache.Writer = Writer;
491
-
492
- mustache.parse = parseTemplate;
493
-
494
- // Export the escaping function so that the user may override it.
495
- // See https://github.com/janl/mustache.js/issues/244
496
- mustache.escape = escapeHtml;
497
-
498
- // All Mustache.* functions use this writer.
523
+ // All high-level mustache.* functions use this writer.
499
524
  var defaultWriter = new Writer();
500
525
 
501
526
  /**
502
- * Clears all cached templates and partials in the default writer.
527
+ * Clears all cached templates in the default writer.
503
528
  */
504
529
  mustache.clearCache = function () {
505
530
  return defaultWriter.clearCache();
506
531
  };
507
532
 
508
533
  /**
509
- * Compiles the given `template` to a reusable function using the default
510
- * writer.
511
- */
512
- mustache.compile = function (template, tags) {
513
- return defaultWriter.compile(template, tags);
514
- };
515
-
516
- /**
517
- * Compiles the partial with the given `name` and `template` to a reusable
518
- * function using the default writer.
534
+ * Parses and caches the given template in the default writer and returns the
535
+ * array of tokens it contains. Doing this ahead of time avoids the need to
536
+ * parse templates on the fly as they are rendered.
519
537
  */
520
- mustache.compilePartial = function (name, template, tags) {
521
- return defaultWriter.compilePartial(name, template, tags);
522
- };
523
-
524
- /**
525
- * Compiles the given array of tokens (the output of a parse) to a reusable
526
- * function using the default writer.
527
- */
528
- mustache.compileTokens = function (tokens, template) {
529
- return defaultWriter.compileTokens(tokens, template);
538
+ mustache.parse = function (template, tags) {
539
+ return defaultWriter.parse(template, tags);
530
540
  };
531
541
 
532
542
  /**
@@ -548,4 +558,13 @@
548
558
  }
549
559
  };
550
560
 
561
+ // Export the escaping function so that the user may override it.
562
+ // See https://github.com/janl/mustache.js/issues/244
563
+ mustache.escape = escapeHtml;
564
+
565
+ // Export these mainly for testing, but also for advanced usage.
566
+ mustache.Scanner = Scanner;
567
+ mustache.Context = Context;
568
+ mustache.Writer = Writer;
569
+
551
570
  }));
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mustache-js-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Krzysztof Knapik
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-05 00:00:00.000000000 Z
11
+ date: 2014-01-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -61,7 +61,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
61
61
  version: '0'
62
62
  requirements: []
63
63
  rubyforge_project: mustache-js-rails
64
- rubygems_version: 2.0.3
64
+ rubygems_version: 2.1.11
65
65
  signing_key:
66
66
  specification_version: 4
67
67
  summary: mustache.js and jQuery.mustache.js for Rails 3.1+ asset pipeline