Bläddra i källkod

Handle dynamic names in parsing, so that they don't get cached non-dynamically

pull/828/head
Luke Blaney 1 år sedan
förälder
incheckning
675ca3b1de
3 ändrade filer med 47 tillägg och 6 borttagningar
  1. +29
    -6
      mustache.js
  2. +4
    -0
      test/parse-test.js
  3. +14
    -0
      test/partial-test.js

+ 29
- 6
mustache.js Visa fil

@@ -79,6 +79,7 @@ var spaceRe = /\s+/;
var equalsRe = /\s*=/;
var curlyRe = /\s*\}/;
var tagRe = /#|\^|\/|>|\{|&|=|!/;
var dynamicRe = /\*/;

/**
* Breaks up the given `template` string into a tree of tokens. If the `tags`
@@ -202,6 +203,14 @@ function parseTemplate (template, tags) {
scanner.scan(curlyRe);
scanner.scanUntil(closingTagRe);
type = '&';
} else if (type === '>') {
if (scanner.scan(dynamicRe) === '') {
value = scanner.scanUntil(closingTagRe);
} else {
scanner.scan(whiteRe);
type = '>*';
value = scanner.scanUntil(closingTagRe);
}
} else {
value = scanner.scanUntil(closingTagRe);
}
@@ -210,7 +219,7 @@ function parseTemplate (template, tags) {
if (!scanner.scan(closingTagRe))
throw new Error('Unclosed tag at ' + scanner.pos);

if (type == '>') {
if (type == '>' || type == '>*') {
token = [ type, value, start, scanner.pos, indentation, tagIndex, lineHasNonSpace ];
} else {
token = [ type, value, start, scanner.pos ];
@@ -571,6 +580,7 @@ Writer.prototype.renderTokens = function renderTokens (tokens, context, partials
if (symbol === '#') value = this.renderSection(token, context, partials, originalTemplate, config);
else if (symbol === '^') value = this.renderInverted(token, context, partials, originalTemplate, config);
else if (symbol === '>') value = this.renderPartial(token, context, partials, config);
else if (symbol === '>*') value = this.renderDynamicPartial(token, context, partials, config);
else if (symbol === '&') value = this.unescapedValue(token, context);
else if (symbol === 'name') value = this.escapedValue(token, context, config);
else if (symbol === 'text') value = this.rawValue(token);
@@ -636,14 +646,27 @@ Writer.prototype.indentPartial = function indentPartial (partial, indentation, l
return partialByNl.join('\n');
};

Writer.prototype.renderPartial = function renderPartial (token, context, partials, config) {
Writer.prototype.renderDynamicPartial = function renderPartial (token, context, partials, config) {
if (!partials) return;
var tags = this.getConfigTags(config);

// Partial names beginning with an asterix are treated as a dynamic name
if (token[1].trim().substring(0, 1) === '*') {
token[1] = context.lookup(token[1].trim().substring(1).trim());
var name = context.lookup(token[1].trim());
var value = isFunction(partials) ? partials(name) : partials[name];
if (value != null) {
var lineHasNonSpace = token[6];
var tagIndex = token[5];
var indentation = token[4];
var indentedValue = value;
if (tagIndex == 0 && indentation) {
indentedValue = this.indentPartial(value, indentation, lineHasNonSpace);
}
var tokens = this.parse(indentedValue, tags);
return this.renderTokens(tokens, context, partials, indentedValue, config);
}
};

Writer.prototype.renderPartial = function renderPartial (token, context, partials, config) {
if (!partials) return;
var tags = this.getConfigTags(config);
var value = isFunction(partials) ? partials(token[1]) : partials[token[1]];
if (value != null) {
var lineHasNonSpace = token[6];


+ 4
- 0
test/parse-test.js Visa fil

@@ -46,6 +46,10 @@ var expectations = {
' {{> abc }}\n' : [ [ '>', 'abc', 2, 12, ' ', 0, false ] ],
' {{> abc }} {{> abc }}\n' : [ [ '>', 'abc', 2, 12, ' ', 0, false ], [ '>', 'abc', 13, 23, ' ', 1, false ] ],
'{{ > abc }}' : [ [ '>', 'abc', 0, 11, '', 0, false ] ],
'{{>*abc}}' : [ [ '>*', 'abc', 0, 9, '', 0, false ] ],
'{{> *abc}}' : [ [ '>*', 'abc', 0, 10, '', 0, false ] ],
'{{>* abc}}' : [ [ '>*', 'abc', 0, 10, '', 0, false ] ],
'{{ > * abc }}' : [ [ '>*', 'abc', 0, 13, '', 0, false ] ],
'{{=<% %>=}}' : [ [ '=', '<% %>', 0, 11 ] ],
'{{= <% %> =}}' : [ [ '=', '<% %>', 0, 13 ] ],
'{{=<% %>=}}<%={{ }}=%>' : [ [ '=', '<% %>', 0, 11 ], [ '=', '{{ }}', 11, 22 ] ],


+ 14
- 0
test/partial-test.js Visa fil

@@ -172,4 +172,18 @@ describe('Partials spec', function () {
var renderResult = Mustache.render(template, {}, partials, tags);
assert.equal(renderResult, expected);
});

describe('when rendering a dynamically named partial after already having rendered that partial with a different name value', function () {
it('returns different output for the latter render', function () {
var template = 'Place: {{>*place}}';
var partials = {
first: '1st',
second: '2nd',
};
var renderedFirst = Mustache.render(template, {place:'first'}, partials);
var renderedSecond = Mustache.render(template, {place:'second'}, partials);

assert.notEqual(renderedFirst, renderedSecond);
});
});
});

Laddar…
Avbryt
Spara