Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: template_binding/lib/src/mustache_tokens.dart

Issue 1400473008: Roll Observatory packages and add a roll script (Closed) Base URL: git@github.com:dart-lang/observatory_pub_packages.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « template_binding/lib/src/instance_binding_map.dart ('k') | template_binding/lib/src/node.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 library template_binding.src.mustache_tokens;
6
7 import 'package:observe/observe.dart';
8
9 // Dart note: this was added to decouple the parse function below from the rest
10 // of template_binding. This allows using this code in command-line tools as
11 // well.
12 typedef Function DelegateFunctionFactory(String pathString);
13
14 /**
15 * Represents a set of parsed tokens from a {{ mustache binding expression }}.
16 * This can be created by calling [parse].
17 *
18 * For performance reasons the data is stored in one linear array in [_tokens].
19 * This class wraps that array and provides accessors in an attempt to make the
20 * pattern easier to understand. See [length] and [getText] for example.
21 */
22 class MustacheTokens {
23 // Constants for indexing into the exploded structs in [_tokens] .
24 static const _TOKEN_TEXT = 0;
25 static const _TOKEN_ONETIME = 1;
26 static const _TOKEN_PATH = 2;
27 static const _TOKEN_PREPAREFN = 3;
28 static const _TOKEN_SIZE = 4;
29
30 // There is 1 extra entry for the end text.
31 static const _TOKEN_ENDTEXT = 1;
32
33 bool get hasOnePath => _tokens.length == _TOKEN_SIZE + _TOKEN_ENDTEXT;
34 bool get isSimplePath => hasOnePath &&
35 _tokens[_TOKEN_TEXT] == '' && _tokens[_TOKEN_SIZE + _TOKEN_TEXT] == '';
36
37 /**
38 * [TEXT, (ONE_TIME?, PATH, DELEGATE_FN, TEXT)+] if there is at least one
39 * mustache.
40 */
41 final List _tokens;
42
43 final bool onlyOneTime;
44
45 // Dart note: I think this is cached in JavaScript to avoid an extra
46 // allocation per template instance. Seems reasonable, so we do the same.
47 Function _combinator;
48 Function get combinator => _combinator;
49
50 MustacheTokens._(this._tokens, this.onlyOneTime) {
51 // Should be: [TEXT, (ONE_TIME?, PATH, DELEGATE_FN, TEXT)+].
52 assert((_tokens.length - _TOKEN_ENDTEXT) % _TOKEN_SIZE == 0);
53
54 _combinator = hasOnePath ? _singleCombinator : _listCombinator;
55 }
56
57 int get length => _tokens.length ~/ _TOKEN_SIZE;
58
59 /**
60 * Gets the [i]th text entry. Note that [length] can be passed to get the
61 * final text entry.
62 */
63 String getText(int i) => _tokens[i * _TOKEN_SIZE + _TOKEN_TEXT];
64
65 /** Gets the oneTime flag for the [i]th token. */
66 bool getOneTime(int i) => _tokens[i * _TOKEN_SIZE + _TOKEN_ONETIME];
67
68 /** Gets the path for the [i]th token. */
69 PropertyPath getPath(int i) => _tokens[i * _TOKEN_SIZE + _TOKEN_PATH];
70
71 /** Gets the prepareBinding function for the [i]th token. */
72 Function getPrepareBinding(int i) =>
73 _tokens[i * _TOKEN_SIZE + _TOKEN_PREPAREFN];
74
75
76 /**
77 * Parses {{ mustache }} bindings.
78 *
79 * Returns null if there are no matches. Otherwise returns the parsed tokens.
80 */
81 static MustacheTokens parse(String s, [DelegateFunctionFactory fnFactory]) {
82 if (s == null || s.isEmpty) return null;
83
84 var tokens = null;
85 var length = s.length;
86 var lastIndex = 0;
87 var onlyOneTime = true;
88 while (lastIndex < length) {
89 var startIndex = s.indexOf('{{', lastIndex);
90 var oneTimeStart = s.indexOf('[[', lastIndex);
91 var oneTime = false;
92 var terminator = '}}';
93
94 if (oneTimeStart >= 0 &&
95 (startIndex < 0 || oneTimeStart < startIndex)) {
96 startIndex = oneTimeStart;
97 oneTime = true;
98 terminator = ']]';
99 }
100
101 var endIndex = -1;
102 if (startIndex >= 0) {
103 endIndex = s.indexOf(terminator, startIndex + 2);
104 }
105
106 if (endIndex < 0) {
107 if (tokens == null) return null;
108
109 tokens.add(s.substring(lastIndex)); // TEXT
110 break;
111 }
112
113 if (tokens == null) tokens = [];
114 tokens.add(s.substring(lastIndex, startIndex)); // TEXT
115 var pathString = s.substring(startIndex + 2, endIndex).trim();
116 tokens.add(oneTime); // ONETIME?
117 onlyOneTime = onlyOneTime && oneTime;
118 var delegateFn = fnFactory == null ? null : fnFactory(pathString);
119 // Don't try to parse the expression if there's a prepareBinding function
120 if (delegateFn == null) {
121 tokens.add(new PropertyPath(pathString)); // PATH
122 } else {
123 tokens.add(null);
124 }
125 tokens.add(delegateFn); // DELEGATE_FN
126
127 lastIndex = endIndex + 2;
128 }
129
130 if (lastIndex == length) tokens.add(''); // TEXT
131
132 return new MustacheTokens._(tokens, onlyOneTime);
133 }
134
135
136 // Dart note: split "combinator" into the single/list variants, so the
137 // argument can be typed.
138 String _singleCombinator(Object value) {
139 if (value == null) value = '';
140 return '${getText(0)}$value${getText(length)}';
141 }
142
143 String _listCombinator(List<Object> values) {
144 var newValue = new StringBuffer(getText(0));
145 int len = this.length;
146 for (var i = 0; i < len; i++) {
147 var value = values[i];
148 if (value != null) newValue.write(value);
149 newValue.write(getText(i + 1));
150 }
151 return newValue.toString();
152 }
153 }
OLDNEW
« no previous file with comments | « template_binding/lib/src/instance_binding_map.dart ('k') | template_binding/lib/src/node.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698