fix(compiler): allow identifiers with `-` in the template bindings as keys.

This commit is contained in:
Tobias Bosch 2014-12-01 16:05:44 -08:00
parent 63053438ea
commit 0758165fb5
4 changed files with 47 additions and 10 deletions

View File

@ -420,20 +420,39 @@ class _ParseAST {
return positionals; return positionals;
} }
/**
* An identifier, a keyword, a string with an optional `-` inbetween.
*/
expectTemplateBindingKey() {
var result = '';
var operatorFound = false;
do {
result += this.expectIdentifierOrKeywordOrString();
operatorFound = this.optionalOperator('-');
if (operatorFound) {
result += '-';
}
} while (operatorFound);
return result.toString();
}
parseTemplateBindings() { parseTemplateBindings() {
var bindings = []; var bindings = [];
while (this.index < this.tokens.length) { while (this.index < this.tokens.length) {
var key = this.expectIdentifierOrKeywordOrString(); var key = this.expectTemplateBindingKey();
this.optionalCharacter($COLON); this.optionalCharacter($COLON);
var name = null; var name = null;
var expression = null; var expression = null;
if (this.optionalOperator("#")) { if (this.next !== EOF) {
name = this.expectIdentifierOrKeyword(); if (this.optionalOperator("#")) {
} else { name = this.expectIdentifierOrKeyword();
var start = this.inputIndex; } else {
var ast = this.parseExpression(); var start = this.inputIndex;
var source = this.input.substring(start, this.inputIndex); var ast = this.parseExpression();
expression = new ASTWithSource(ast, source); var source = this.input.substring(start, this.inputIndex);
expression = new ASTWithSource(ast, source);
}
} }
ListWrapper.push(bindings, new TemplateBinding(key, name, expression)); ListWrapper.push(bindings, new TemplateBinding(key, name, expression));
if (!this.optionalCharacter($SEMICOLON)) { if (!this.optionalCharacter($SEMICOLON)) {

View File

@ -417,7 +417,12 @@ export function main() {
expect(bindings).toEqual([]); expect(bindings).toEqual([]);
}); });
it('should only allow identifier, string, or keyword as keys', () => { it('should parse a string without a value', () => {
var bindings = parseTemplateBindings('a');
expect(keys(bindings)).toEqual(['a']);
});
it('should only allow identifier, string, or keyword including dashes as keys', () => {
var bindings = parseTemplateBindings("a:'b'"); var bindings = parseTemplateBindings("a:'b'");
expect(keys(bindings)).toEqual(['a']); expect(keys(bindings)).toEqual(['a']);
@ -427,6 +432,9 @@ export function main() {
bindings = parseTemplateBindings("\"a\":'b'"); bindings = parseTemplateBindings("\"a\":'b'");
expect(keys(bindings)).toEqual(['a']); expect(keys(bindings)).toEqual(['a']);
bindings = parseTemplateBindings("a-b:'c'");
expect(keys(bindings)).toEqual(['a-b']);
expect( () => { expect( () => {
parseTemplateBindings('(:0'); parseTemplateBindings('(:0');
}).toThrowError(new RegExp('expected identifier, keyword, or string')); }).toThrowError(new RegExp('expected identifier, keyword, or string'));

View File

@ -79,8 +79,10 @@ export class ViewSplitter extends CompileStep {
var binding = bindings[i]; var binding = bindings[i];
if (isPresent(binding.name)) { if (isPresent(binding.name)) {
compileElement.addVariableBinding(binding.key, binding.name); compileElement.addVariableBinding(binding.key, binding.name);
} else { } else if (isPresent(binding.expression)) {
compileElement.addPropertyBinding(binding.key, binding.expression); compileElement.addPropertyBinding(binding.key, binding.expression);
} else {
compileElement.element.setAttribute(binding.key, '');
} }
} }
} }

View File

@ -72,6 +72,14 @@ export function main() {
expect(results[1].variableBindings).toEqual(MapWrapper.createFromStringMap({'varName': 'mapName'})); expect(results[1].variableBindings).toEqual(MapWrapper.createFromStringMap({'varName': 'mapName'}));
}); });
it('should add entries without value as attribute to the element', () => {
var rootElement = createElement('<div><div template="varname"></div></div>');
var results = createPipeline().process(rootElement);
expect(results[1].attrs()).toEqual(MapWrapper.createFromStringMap({'varname': ''}));
expect(results[1].propertyBindings).toBe(null);
expect(results[1].variableBindings).toBe(null);
});
}); });
}); });