OLD | NEW |
1 part of angular.core; | 1 part of angular.core_internal; |
2 | 2 |
3 class Interpolation { | |
4 final String template; | |
5 final List<String> seperators; | |
6 final List<String> expressions; | |
7 Function setter = (_) => _; | |
8 | |
9 Interpolation(this.template, this.seperators, this.expressions); | |
10 | |
11 String call(List parts, [_]) { | |
12 if (parts == null) return seperators.join(''); | |
13 var str = []; | |
14 for (var i = 0; i < parts.length; i++) { | |
15 str.add(seperators[i]); | |
16 var value = parts[i]; | |
17 str.add(value == null ? '' : '$value'); | |
18 } | |
19 str.add(seperators.last); | |
20 return setter(str.join('')); | |
21 } | |
22 } | |
23 | |
24 /** | 3 /** |
25 * Compiles a string with markup into an interpolation function. This service | 4 * Compiles a string with markup into an expression. This service is used by the |
26 * is used by the HTML [Compiler] service for data binding. | 5 * HTML [Compiler] service for data binding. |
27 * | 6 * |
28 * | 7 * var interpolate = ...; // injected |
29 * var $interpolate = ...; // injected | 8 * var exp = interpolate('Hello {{name}}!'); |
30 * var exp = $interpolate('Hello {{name}}!'); | 9 * expect(exp).toEqual('"Hello "+(name|stringify)+"!"'); |
31 * expect(exp({name:'Angular'}).toEqual('Hello Angular!'); | |
32 */ | 10 */ |
33 @NgInjectableService() | 11 @Injectable() |
34 class Interpolate { | 12 class Interpolate implements Function { |
35 final Parser _parse; | 13 /** |
| 14 * Compiles markup text into expression. |
| 15 * |
| 16 * - [template]: The markup text to interpolate in form `foo {{expr}} bar`. |
| 17 * - [mustHaveExpression]: if set to true then the interpolation string must |
| 18 * have embedded expression in order to return an expression. Strings with |
| 19 * no embedded expression will return null. |
| 20 * - [startSymbol]: The symbol to start interpolation. '{{' by default. |
| 21 * - [endSymbol]: The symbol to end interpolation. '}}' by default. |
| 22 */ |
36 | 23 |
37 Interpolate(this._parse); | 24 String call(String template, [bool mustHaveExpression = false, |
| 25 String startSymbol = '{{', String endSymbol = '}}']) { |
| 26 if (template == null || template.isEmpty) return ""; |
38 | 27 |
39 /** | 28 final startLen = startSymbol.length; |
40 * Compiles markup text into interpolation function. | 29 final endLen = endSymbol.length; |
41 * | 30 final length = template.length; |
42 * - `text`: The markup text to interpolate in form `foo {{expr}} bar`. | 31 |
43 * - `mustHaveExpression`: if set to true then the interpolation string must | 32 int startIdx; |
44 * have embedded expression in order to return an interpolation function. | 33 int endIdx; |
45 * Strings with no embedded expression will return null for the | |
46 * interpolation function. | |
47 * - `startSymbol`: The symbol to start interpolation. '{{' by default. | |
48 * - `endSymbol`: The symbol to end interpolation. '}}' by default. | |
49 */ | |
50 Interpolation call(String template, [bool mustHaveExpression = false, | |
51 String startSymbol = '{{', String endSymbol = '}}']) { | |
52 int startSymbolLength = startSymbol.length; | |
53 int endSymbolLength = endSymbol.length; | |
54 int startIndex; | |
55 int endIndex; | |
56 int index = 0; | 34 int index = 0; |
57 int length = template.length; | 35 |
58 bool hasInterpolation = false; | 36 bool hasInterpolation = false; |
59 bool shouldAddSeparator = true; | 37 |
60 String exp; | 38 String exp; |
61 List<String> separators = []; | 39 final expParts = <String>[]; |
62 List<String> expressions = []; | |
63 | 40 |
64 while(index < length) { | 41 while (index < length) { |
65 if ( ((startIndex = template.indexOf(startSymbol, index)) != -1) && | 42 startIdx = template.indexOf(startSymbol, index); |
66 ((endIndex = template.indexOf(endSymbol, startIndex + startSymbolLeng
th)) != -1) ) { | 43 endIdx = template.indexOf(endSymbol, startIdx + startLen); |
67 separators.add(template.substring(index, startIndex)); | 44 if (startIdx != -1 && endIdx != -1) { |
68 exp = template.substring(startIndex + startSymbolLength, endIndex); | 45 if (index < startIdx) { |
69 expressions.add(exp); | 46 // Empty strings could be stripped thanks to the stringify |
70 index = endIndex + endSymbolLength; | 47 // formatter |
| 48 expParts.add(_wrapInQuotes(template.substring(index, startIdx))); |
| 49 } |
| 50 expParts.add('(' + template.substring(startIdx + startLen, endIdx) + |
| 51 '|stringify)'); |
| 52 |
| 53 index = endIdx + endLen; |
71 hasInterpolation = true; | 54 hasInterpolation = true; |
72 } else { | 55 } else { |
73 // we did not find anything, so we have to add the remainder to the chun
ks array | 56 // we did not find any interpolation, so add the remainder |
74 separators.add(template.substring(index)); | 57 expParts.add(_wrapInQuotes(template.substring(index))); |
75 shouldAddSeparator = false; | |
76 break; | 58 break; |
77 } | 59 } |
78 } | 60 } |
79 if (shouldAddSeparator) { | 61 |
80 separators.add(''); | 62 return !mustHaveExpression || hasInterpolation ? expParts.join('+') : null; |
81 } | 63 } |
82 return (!mustHaveExpression || hasInterpolation) | 64 |
83 ? new Interpolation(template, separators, expressions) | 65 String _wrapInQuotes(String s){ |
84 : null; | 66 final escaped = s.replaceAll(r'\', r'\\').replaceAll(r'"', r'\"'); |
| 67 return '"$escaped"'; |
85 } | 68 } |
86 } | 69 } |
OLD | NEW |