Skip to content

Commit 7f921d3

Browse files
committed
feat(interpolate): the service now returns an expression only
1 parent 31aa004 commit 7f921d3

File tree

2 files changed

+43
-145
lines changed

2 files changed

+43
-145
lines changed

lib/core/interpolate.dart

Lines changed: 32 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,12 @@
11
part of angular.core;
22

3-
class Interpolation implements Function {
4-
final String template;
5-
final List<String> separators;
6-
final List<String> expressions;
7-
Function setter = (_) => _;
8-
9-
Interpolation(this.template, this.separators, this.expressions);
10-
11-
String call(List parts, [_]) {
12-
if (parts == null) return separators.join('');
13-
var sb = new StringBuffer();
14-
for (var i = 0; i < parts.length; i++) {
15-
sb.write(separators[i]);
16-
var value = parts[i];
17-
sb.write(value == null ? '' : '$value');
18-
}
19-
sb.write(separators.last);
20-
return setter(sb.toString());
21-
}
22-
}
23-
243
/**
25-
* Compiles a string with markup into an interpolation function. This service
26-
* is used by the HTML [Compiler] service for data binding.
27-
*
4+
* Compiles a string with markup into an expression. This service is used by the
5+
* HTML [Compiler] service for data binding.
286
*
297
* var $interpolate = ...; // injected
308
* var exp = $interpolate('Hello {{name}}!');
31-
* expect(exp({name:'Angular'}).toEqual('Hello Angular!');
9+
* expect(exp).toEqual('"Hello "+(name)+"!"');
3210
*/
3311
@NgInjectableService()
3412
class Interpolate implements Function {
@@ -37,49 +15,49 @@ class Interpolate implements Function {
3715
Interpolate(this._parse);
3816

3917
/**
40-
* Compiles markup text into interpolation function.
18+
* Compiles markup text into expression.
4119
*
42-
* - `text`: The markup text to interpolate in form `foo {{expr}} bar`.
20+
* - `template`: The markup text to interpolate in form `foo {{expr}} bar`.
4321
* - `mustHaveExpression`: if set to true then the interpolation string must
44-
* have embedded expression in order to return an interpolation function.
45-
* Strings with no embedded expression will return null for the
46-
* interpolation function.
22+
* have embedded expression in order to return an expression. Strings with
23+
* no embedded expression will return null.
4724
* - `startSymbol`: The symbol to start interpolation. '{{' by default.
4825
* - `endSymbol`: The symbol to end interpolation. '}}' by default.
4926
*/
50-
Interpolation call(String template, [bool mustHaveExpression = false,
27+
28+
String call(String template, [bool mustHaveExpression = false,
5129
String startSymbol = '{{', String endSymbol = '}}']) {
52-
int startSymbolLength = startSymbol.length;
53-
int endSymbolLength = endSymbol.length;
54-
int startIndex;
55-
int endIndex;
56-
int index = 0;
30+
31+
int startLen = startSymbol.length;
32+
int endLen = endSymbol.length;
5733
int length = template.length;
34+
35+
int startIdx;
36+
int endIdx;
37+
int index = 0;
38+
5839
bool hasInterpolation = false;
59-
bool shouldAddSeparator = true;
40+
6041
String exp;
61-
final separators = <String>[];
62-
final expressions = <String>[];
42+
final expParts = <String>[];
6343

6444
while (index < length) {
65-
if (((startIndex = template.indexOf(startSymbol, index)) != -1) &&
66-
((endIndex = template.indexOf(endSymbol, startIndex + startSymbolLength)) != -1) ) {
67-
separators.add(template.substring(index, startIndex));
68-
exp = template.substring(startIndex + startSymbolLength, endIndex);
69-
expressions.add(exp);
70-
index = endIndex + endSymbolLength;
45+
startIdx = template.indexOf(startSymbol, index);
46+
endIdx = template.indexOf(endSymbol, startIdx + startLen);
47+
if (startIdx != -1 && endIdx != -1) {
48+
if (index < startIdx) {
49+
expParts.add('"${template.substring(index, startIdx)}"');
50+
}
51+
expParts.add('(${template.substring(startIdx + startLen, endIdx)})');
52+
index = endIdx + endLen;
7153
hasInterpolation = true;
7254
} else {
73-
// we did not find anything, so we have to add the remainder to the
74-
// chunks array
75-
separators.add(template.substring(index));
76-
shouldAddSeparator = false;
55+
// we did not find any interpolation, so add the remainder
56+
expParts.add('"${template.substring(index)}"');
7757
break;
7858
}
7959
}
80-
if (shouldAddSeparator) separators.add('');
81-
return (!mustHaveExpression || hasInterpolation)
82-
? new Interpolation(template, separators, expressions)
83-
: null;
60+
61+
return !mustHaveExpression || hasInterpolation ? expParts.join('+') : null;
8462
}
85-
}
63+
}

test/core/interpolate_spec.dart

Lines changed: 11 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -14,100 +14,20 @@ main() {
1414
expect($interpolate('some text', true)).toBe(null);
1515
});
1616

17-
it('should suppress falsy objects', (Interpolate $interpolate) {
18-
expect($interpolate('{{undefined}}')([null])).toEqual('');
19-
expect($interpolate('{{undefined+undefined}}')([null])).toEqual('');
20-
expect($interpolate('{{null}}')([null])).toEqual('');
21-
expect($interpolate('{{a.b}}')([null])).toEqual('');
17+
it('should return an expression', (Interpolate $interpolate) {
18+
expect($interpolate('Hello {{name}}!')).toEqual('"Hello "+(name)+"!"');
19+
expect($interpolate('a{{b}}C')).toEqual('"a"+(b)+"C"');
20+
expect($interpolate('a{{b}}')).toEqual('"a"+(b)');
21+
expect($interpolate('{{a}}b')).toEqual('(a)+"b"');
22+
expect($interpolate('{{b}}')).toEqual('(b)');
23+
expect($interpolate('{{b}}+{{c}}')).toEqual('(b)+"+"+(c)');
24+
expect($interpolate('{{b}}x{{c}}')).toEqual('(b)+"x"+(c)');
2225
});
2326

24-
it('should jsonify objects', (Interpolate $interpolate) {
25-
expect($interpolate('{{ {} }}')([{}])).toEqual('{}');
26-
expect($interpolate('{{ true }}')([true])).toEqual('true');
27-
expect($interpolate('{{ false }}')([false])).toEqual('false');
27+
it('should Parse Multiline', (Interpolate $interpolate) {
28+
expect($interpolate("X\nY{{A\n+B}}C\nD"))
29+
.toEqual('"X\nY"+(A\n+B)+"C\nD"');
2830
});
2931

30-
31-
it('should return interpolation function', (Interpolate $interpolate, Scope rootScope) {
32-
rootScope.context['name'] = 'Misko';
33-
var fn = $interpolate('Hello {{name}}!');
34-
expect(fn(['Misko'])).toEqual('Hello Misko!');
35-
});
36-
37-
38-
it('should ignore undefined model', (Interpolate $interpolate) {
39-
expect($interpolate("Hello {{'World' + foo}}")(['World'])).toEqual('Hello World');
40-
});
41-
42-
43-
it('should use toString to conver objects to string', (Interpolate $interpolate, Scope rootScope) {
44-
expect($interpolate("Hello, {{obj}}!")([new ToStringableObject()])).toEqual('Hello, World!');
45-
});
46-
47-
48-
describe('parseBindings', () {
49-
it('should Parse Text With No Bindings', (Interpolate $interpolate) {
50-
var parts = $interpolate("a").separators;
51-
expect(parts.length).toEqual(1);
52-
expect(parts[0]).toEqual("a");
53-
});
54-
55-
it('should Parse Empty Text', (Interpolate $interpolate) {
56-
var parts = $interpolate("").separators;
57-
expect(parts.length).toEqual(1);
58-
expect(parts[0]).toEqual("");
59-
});
60-
61-
it('should Parse Inner Binding', (Interpolate $interpolate) {
62-
var parts = $interpolate("a{{b}}C").separators;
63-
expect(parts.length).toEqual(2);
64-
expect(parts[0]).toEqual("a");
65-
expect(parts[1]).toEqual("C");
66-
});
67-
68-
it('should Parse Ending Binding', (Interpolate $interpolate) {
69-
var parts = $interpolate("a{{b}}").separators;
70-
expect(parts.length).toEqual(2);
71-
expect(parts[0]).toEqual("a");
72-
expect(parts[1]).toEqual("");
73-
});
74-
75-
it('should Parse Begging Binding', (Interpolate $interpolate) {
76-
var parts = $interpolate("{{b}}c").separators;
77-
expect(parts.length).toEqual(2);
78-
expect(parts[0]).toEqual("");
79-
expect(parts[1]).toEqual("c");
80-
});
81-
82-
it('should Parse Loan Binding', (Interpolate $interpolate) {
83-
var parts = $interpolate("{{b}}").separators;
84-
expect(parts.length).toEqual(2);
85-
expect(parts[0]).toEqual("");
86-
expect(parts[1]).toEqual("");
87-
});
88-
89-
it('should Parse Two Bindings', (Interpolate $interpolate) {
90-
var parts = $interpolate("{{b}}{{c}}").separators;
91-
expect(parts.length).toEqual(3);
92-
expect(parts[0]).toEqual("");
93-
expect(parts[1]).toEqual("");
94-
expect(parts[2]).toEqual("");
95-
});
96-
97-
it('should Parse Two Bindings With Text In Middle', (Interpolate $interpolate) {
98-
var parts = $interpolate("{{b}}x{{c}}").separators;
99-
expect(parts.length).toEqual(3);
100-
expect(parts[0]).toEqual("");
101-
expect(parts[1]).toEqual("x");
102-
expect(parts[2]).toEqual("");
103-
});
104-
105-
it('should Parse Multiline', (Interpolate $interpolate) {
106-
var parts = $interpolate('"X\nY{{A\n+B}}C\nD"').separators;
107-
expect(parts.length).toEqual(2);
108-
expect(parts[0]).toEqual('"X\nY');
109-
expect(parts[1]).toEqual('C\nD"');
110-
});
111-
});
11232
});
11333
}

0 commit comments

Comments
 (0)