fix(compiler): use parentheses around expressions and escape quotes
This commit is contained in:
parent
03882dcccc
commit
b2ecdb5da7
@ -1,4 +1,4 @@
|
|||||||
import {RegExpWrapper, StringWrapper} from 'facade/lang';
|
import {RegExpWrapper, StringWrapper, isPresent} from 'facade/lang';
|
||||||
import {Node, DOM} from 'facade/dom';
|
import {Node, DOM} from 'facade/dom';
|
||||||
|
|
||||||
import {CompileStep} from './compile_step';
|
import {CompileStep} from './compile_step';
|
||||||
@ -7,6 +7,7 @@ import {CompileControl} from './compile_control';
|
|||||||
|
|
||||||
// TODO(tbosch): Cannot make this const/final right now because of the transpiler...
|
// TODO(tbosch): Cannot make this const/final right now because of the transpiler...
|
||||||
var INTERPOLATION_REGEXP = RegExpWrapper.create('\\{\\{(.*?)\\}\\}');
|
var INTERPOLATION_REGEXP = RegExpWrapper.create('\\{\\{(.*?)\\}\\}');
|
||||||
|
var QUOTE_REGEXP = RegExpWrapper.create("'");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses interpolations in direct text child nodes of the current element.
|
* Parses interpolations in direct text child nodes of the current element.
|
||||||
@ -27,23 +28,30 @@ export class TextInterpolationParser extends CompileStep {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_parseTextNode(pipelineElement, node, nodeIndex) {
|
_parseTextNode(pipelineElement, node, nodeIndex) {
|
||||||
// TODO: escape fixed string quotes
|
// TODO: add stringify formatter when we support formatters
|
||||||
// TODO: add braces around the expression
|
|
||||||
// TODO: suppress empty strings
|
|
||||||
// TODO: add stringify formatter
|
|
||||||
var parts = StringWrapper.split(node.nodeValue, INTERPOLATION_REGEXP);
|
var parts = StringWrapper.split(node.nodeValue, INTERPOLATION_REGEXP);
|
||||||
if (parts.length > 1) {
|
if (parts.length > 1) {
|
||||||
|
var expression = '';
|
||||||
for (var i=0; i<parts.length; i++) {
|
for (var i=0; i<parts.length; i++) {
|
||||||
|
var expressionPart = null;
|
||||||
if (i%2 === 0) {
|
if (i%2 === 0) {
|
||||||
// fixed string
|
// fixed string
|
||||||
parts[i] = "'" + parts[i] + "'";
|
if (parts[i].length > 0) {
|
||||||
|
expressionPart = "'" + StringWrapper.replaceAll(parts[i], QUOTE_REGEXP, "\\'") + "'";
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// expression
|
// expression
|
||||||
parts[i] = "" + parts[i] + "";
|
expressionPart = "(" + parts[i] + ")";
|
||||||
|
}
|
||||||
|
if (isPresent(expressionPart)) {
|
||||||
|
if (expression.length > 0) {
|
||||||
|
expression += '+';
|
||||||
|
}
|
||||||
|
expression += expressionPart;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DOM.setText(node, ' ');
|
DOM.setText(node, ' ');
|
||||||
pipelineElement.addTextNodeBinding(nodeIndex, parts.join('+'));
|
pipelineElement.addTextNodeBinding(nodeIndex, expression);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,15 +13,32 @@ export function main() {
|
|||||||
it('should find text interpolation in normal elements', () => {
|
it('should find text interpolation in normal elements', () => {
|
||||||
var results = createPipeline().process(createElement('<div>{{expr1}}<span></span>{{expr2}}</div>'));
|
var results = createPipeline().process(createElement('<div>{{expr1}}<span></span>{{expr2}}</div>'));
|
||||||
var bindings = results[0].textNodeBindings;
|
var bindings = results[0].textNodeBindings;
|
||||||
expect(MapWrapper.get(bindings, 0)).toEqual("''+expr1+''");
|
expect(MapWrapper.get(bindings, 0)).toEqual("(expr1)");
|
||||||
expect(MapWrapper.get(bindings, 2)).toEqual("''+expr2+''");
|
expect(MapWrapper.get(bindings, 2)).toEqual("(expr2)");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should find text interpolation in template elements', () => {
|
it('should find text interpolation in template elements', () => {
|
||||||
var results = createPipeline().process(createElement('<template>{{expr1}}<span></span>{{expr2}}</template>'));
|
var results = createPipeline().process(createElement('<template>{{expr1}}<span></span>{{expr2}}</template>'));
|
||||||
var bindings = results[0].textNodeBindings;
|
var bindings = results[0].textNodeBindings;
|
||||||
expect(MapWrapper.get(bindings, 0)).toEqual("''+expr1+''");
|
expect(MapWrapper.get(bindings, 0)).toEqual("(expr1)");
|
||||||
expect(MapWrapper.get(bindings, 2)).toEqual("''+expr2+''");
|
expect(MapWrapper.get(bindings, 2)).toEqual("(expr2)");
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow multiple expressions', () => {
|
||||||
|
var results = createPipeline().process(createElement('<div>{{expr1}}{{expr2}}</div>'));
|
||||||
|
var bindings = results[0].textNodeBindings;
|
||||||
|
expect(MapWrapper.get(bindings, 0)).toEqual("(expr1)+(expr2)");
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow fixed text before, in between and after expressions', () => {
|
||||||
|
var results = createPipeline().process(createElement('<div>a{{expr1}}b{{expr2}}c</div>'));
|
||||||
|
var bindings = results[0].textNodeBindings;
|
||||||
|
expect(MapWrapper.get(bindings, 0)).toEqual("'a'+(expr1)+'b'+(expr2)+'c'");
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should escape quotes in fixed parts', () => {
|
||||||
|
var results = createPipeline().process(createElement("<div>'\"a{{expr1}}</div>"));
|
||||||
|
expect(MapWrapper.get(results[0].textNodeBindings, 0)).toEqual("'\\'\"a'+(expr1)");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -76,6 +76,10 @@ class StringWrapper {
|
|||||||
static equals(String s, String s2) {
|
static equals(String s, String s2) {
|
||||||
return s == s2;
|
return s == s2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static String replaceAll(String s, RegExp from, String replace) {
|
||||||
|
return s.replaceAll(from, replace);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class StringJoiner {
|
class StringJoiner {
|
||||||
|
@ -66,6 +66,10 @@ export class StringWrapper {
|
|||||||
static equals(s:string, s2:string) {
|
static equals(s:string, s2:string) {
|
||||||
return s === s2;
|
return s === s2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static replaceAll(s:string, from:RegExp, replace:string) {
|
||||||
|
return s.replace(from.multiple, replace);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class StringJoiner {
|
export class StringJoiner {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user