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

Unified Diff: pkg/template_binding/lib/src/mustache_tokens.dart

Issue 132403010: big update to observe, template_binding, polymer (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/template_binding/lib/src/instance_binding_map.dart ('k') | pkg/template_binding/lib/src/node.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/template_binding/lib/src/mustache_tokens.dart
diff --git a/pkg/template_binding/lib/src/mustache_tokens.dart b/pkg/template_binding/lib/src/mustache_tokens.dart
new file mode 100644
index 0000000000000000000000000000000000000000..be84d26205cba07597410dc02446e1604e4f646d
--- /dev/null
+++ b/pkg/template_binding/lib/src/mustache_tokens.dart
@@ -0,0 +1,146 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library template_binding.src.mustache_tokens;
+
+import 'package:observe/observe.dart';
+import 'package:template_binding/template_binding.dart';
+
+/**
+ * Represents a set of parsed tokens from a {{ mustache binding expression }}.
+ * This can be created by calling [parse].
+ *
+ * For performance reasons the data is stored in one linear array in [_tokens].
+ * This class wraps that array and provides accessors in an attempt to make the
+ * pattern easier to understand. See [length] and [getText] for example.
+ */
+class MustacheTokens {
+ // Constants for indexing into the exploded structs in [_tokens] .
+ static const _TOKEN_TEXT = 0;
+ static const _TOKEN_ONETIME = 1;
+ static const _TOKEN_PATH = 2;
+ static const _TOKEN_PREPAREFN = 3;
+ static const _TOKEN_SIZE = 4;
+
+ // There is 1 extra entry for the end text.
+ static const _TOKEN_ENDTEXT = 1;
+
+ bool get hasOnePath => _tokens.length == _TOKEN_SIZE + _TOKEN_ENDTEXT;
+ bool get isSimplePath => hasOnePath &&
+ _tokens[_TOKEN_TEXT] == '' && _tokens[_TOKEN_SIZE + _TOKEN_TEXT] == '';
+
+ /**
+ * [TEXT, (ONE_TIME?, PATH, DELEGATE_FN, TEXT)+] if there is at least one
+ * mustache.
+ */
+ final List _tokens;
+
+ final bool onlyOneTime;
+
+ // Dart note: I think this is cached in JavaScript to avoid an extra
+ // allocation per template instance. Seems reasonable, so we do the same.
+ Function _combinator;
+ Function get combinator => _combinator;
+
+ MustacheTokens._(this._tokens, this.onlyOneTime) {
+ // Should be: [TEXT, (ONE_TIME?, PATH, DELEGATE_FN, TEXT)+].
+ assert((_tokens.length - _TOKEN_ENDTEXT) % _TOKEN_SIZE == 0);
+
+ _combinator = hasOnePath ? _singleCombinator : _listCombinator;
+ }
+
+ int get length => _tokens.length ~/ _TOKEN_SIZE;
+
+ /**
+ * Gets the [i]th text entry. Note that [length] can be passed to get the
+ * final text entry.
+ */
+ String getText(int i) => _tokens[i * _TOKEN_SIZE + _TOKEN_TEXT];
+
+ /** Gets the oneTime flag for the [i]th token. */
+ bool getOneTime(int i) => _tokens[i * _TOKEN_SIZE + _TOKEN_ONETIME];
+
+ /** Gets the path for the [i]th token. */
+ PropertyPath getPath(int i) => _tokens[i * _TOKEN_SIZE + _TOKEN_PATH];
+
+ /** Gets the prepareBinding function for the [i]th token. */
+ Function getPrepareBinding(int i) =>
+ _tokens[i * _TOKEN_SIZE + _TOKEN_PREPAREFN];
+
+
+ /**
+ * Parses {{ mustache }} bindings.
+ *
+ * Returns null if there are no matches. Otherwise returns the parsed tokens.
+ */
+ static MustacheTokens parse(String s, String name, node,
+ BindingDelegate delegate) {
+ if (s == null || s.isEmpty) return null;
+
+ var tokens = null;
+ var length = s.length;
+ var lastIndex = 0;
+ var onlyOneTime = true;
+ while (lastIndex < length) {
+ var startIndex = s.indexOf('{{', lastIndex);
+ var oneTimeStart = s.indexOf('[[', lastIndex);
+ var oneTime = false;
+ var terminator = '}}';
+
+ if (oneTimeStart >= 0 &&
+ (startIndex < 0 || oneTimeStart < startIndex)) {
+ startIndex = oneTimeStart;
+ oneTime = true;
+ terminator = ']]';
+ }
+
+ var endIndex = -1;
+ if (startIndex >= 0) {
+ endIndex = s.indexOf(terminator, startIndex + 2);
+ }
+
+ if (endIndex < 0) {
+ if (tokens == null) return null;
+
+ tokens.add(s.substring(lastIndex)); // TEXT
+ break;
+ }
+
+ if (tokens == null) tokens = [];
+ tokens.add(s.substring(lastIndex, startIndex)); // TEXT
+ var pathString = s.substring(startIndex + 2, endIndex).trim();
+ tokens.add(oneTime); // ONETIME?
+ onlyOneTime = onlyOneTime && oneTime;
+ tokens.add(new PropertyPath(pathString)); // PATH
+ var delegateFn = delegate == null ? null :
+ delegate.prepareBinding(pathString, name, node);
+ tokens.add(delegateFn);
+
+ lastIndex = endIndex + 2;
+ }
+
+ if (lastIndex == length) tokens.add('');
+
+ return new MustacheTokens._(tokens, onlyOneTime);
+ }
+
+
+ // Dart note: split "combinator" into the single/list variants, so the
+ // argument can be typed.
+ String _singleCombinator(Object value) {
+ if (value == null) value = '';
+ return '${getText(0)}$value${getText(length)}';
+ }
+
+ String _listCombinator(List<Object> values) {
+ var newValue = new StringBuffer(getText(0));
+ int len = this.length;
+ for (var i = 0; i < len; i++) {
+ var value = values[i];
+ if (value != null) newValue.write(value);
+ newValue.write(getText(i + 1));
+ }
+ return newValue.toString();
+ }
+}
« no previous file with comments | « pkg/template_binding/lib/src/instance_binding_map.dart ('k') | pkg/template_binding/lib/src/node.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698