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

Side by Side Diff: packages/template_binding/lib/template_binding.dart

Issue 2989763002: Update charted to 0.4.8 and roll (Closed)
Patch Set: Removed Cutch from list of reviewers Created 3 years, 4 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
OLDNEW
(Empty)
1 // Copyright (c) 2014, 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 /**
6 * This library provides access to the Polymer project's
7 * [Data Binding](http://www.polymer-project.org/docs/polymer/databinding.html)
8 * Find more information at the
9 * [Polymer.dart homepage](https://www.dartlang.org/polymer-dart/).
10 *
11 * Extends the capabilities of the HTML Template Element by enabling it to
12 * create, manage, and remove instances of content bound to data defined in
13 * Dart.
14 *
15 * Node.bind() is a new method added to all DOM nodes which instructs them to
16 * bind the named property to the data provided. These allows applications to
17 * create a data model in Dart or JavaScript that DOM reacts to.
18 */
19 library template_binding;
20
21 import 'dart:async';
22 import 'dart:collection';
23 import 'dart:html';
24 import 'dart:js' as js show context;
25 import 'dart:js' show JsObject;
26 import 'dart:svg' show SvgSvgElement;
27 import 'package:observe/observe.dart';
28
29 import 'src/mustache_tokens.dart';
30
31 part 'src/binding_delegate.dart';
32 part 'src/instance_binding_map.dart';
33 part 'src/node.dart';
34 part 'src/template.dart';
35 part 'src/template_iterator.dart';
36
37 // TODO(jmesserly): ideally we would split TemplateBinding and Node.bind into
38 // two packages, but this is not easy when we are faking extension methods.
39 // Since TemplateElement needs to override Node.bind, it seems like the
40 // Node.bind layer must have some innate knowledge of TemplateBinding.
41 // NOTE: I've heard NodeBind might become an internal API, which is all the more
42 // reason to have it in this package.
43
44 /**
45 * Provides access to the data binding APIs for the [node]. For example:
46 *
47 * templateBind(node).model = new MyModel();
48 *
49 * This is equivalent to [nodeBind], but provides access to
50 * [TemplateBindExtension] APIs. [node] should be a [TemplateElement], or
51 * equivalent semantic template such as:
52 *
53 * <table template repeat="{{row in rows}}">
54 * <tr template repeat="{{item in row}}">
55 * <td>{{item}}</td>
56 * </tr>
57 * </table>
58 */
59 TemplateBindExtension templateBind(Element node) => nodeBind(node);
60
61 /**
62 * Like [templateBind], but intended to be used only within a custom element
63 * that implements [TemplateBindExtension]. This method can be used to simulate
64 * a super call. For example:
65 *
66 * class CoolTemplate extends TemplateElement
67 * implements TemplateBindExtension {
68 *
69 * createInstance(model, delegate) {
70 * // do something cool...
71 * // otherwise, fall back to superclass
72 * return templateBindFallback(this).createInstance(model, delegate);
73 * }
74 * ...
75 * }
76 */
77 TemplateBindExtension templateBindFallback(Element node) =>
78 nodeBindFallback(node);
79
80 /**
81 * Provides access to the data binding APIs for the [node]. For example:
82 *
83 * nodeBind(node).bind('checked', model, 'path.to.some.value');
84 */
85 NodeBindExtension nodeBind(Node node) {
86 return node is NodeBindExtension ? node : nodeBindFallback(node);
87 }
88
89 /**
90 * Like [nodeBind], but intended to be used only within a custom element that
91 * implements [NodeBindExtension]. This method can be used to simulate a super
92 * call. For example:
93 *
94 * class FancyButton extends ButtonElement implements NodeBindExtension {
95 * bind(name, model, path) {
96 * if (name == 'fancy-prop') ... // do fancy binding
97 * // otherwise, fall back to superclass
98 * return nodeBindFallback(this).bind(name, model, path);
99 * }
100 * ...
101 * }
102 */
103 NodeBindExtension nodeBindFallback(Node node) {
104 var extension = _expando[node];
105 if (extension != null) return extension;
106
107 if (isSemanticTemplate(node)) {
108 extension = new TemplateBindExtension._(node);
109 } else {
110 extension = new NodeBindExtension._(node);
111 }
112 _expando[node] = extension;
113 return extension;
114 }
115
116
117 bool _isAttributeTemplate(Element n) => n.attributes.containsKey('template') &&
118 _SEMANTIC_TEMPLATE_TAGS.containsKey(n.localName);
119
120 bool _isSvgTemplate(Element el) => el.tagName == 'template' &&
121 el.namespaceUri == 'http://www.w3.org/2000/svg';
122
123 bool _isHtmlTemplate(Element el) => el.tagName == 'TEMPLATE' &&
124 el.namespaceUri == 'http://www.w3.org/1999/xhtml';
125
126 /**
127 * Returns true if this node is semantically a template.
128 *
129 * A node is a template if [tagName] is TEMPLATE, or the node has the
130 * 'template' attribute and this tag supports attribute form for backwards
131 * compatibility with existing HTML parsers. The nodes that can use attribute
132 * form are table elements (THEAD, TBODY, TFOOT, TH, TR, TD, CAPTION, COLGROUP
133 * and COL), OPTION, and OPTGROUP.
134 */
135 bool isSemanticTemplate(Node n) => n is Element &&
136 (_isHtmlTemplate(n) || _isAttributeTemplate(n) || _isSvgTemplate(n));
137
138 /** Returns true if this is the staging document for a template. */
139 bool isTemplateStagingDocument(Document d) => _isStagingDocument[d] == true;
140
141
142 /**
143 * True to enable [NodeBindingExtension.bindings]. This can be used by tools
144 * such as UI builders to easily inspect live bindings. Defaults to false for
145 * performance reasons.
146 */
147 bool get enableBindingsReflection =>
148 js.context['Platform']['enableBindingsReflection'] == true;
149
150 set enableBindingsReflection(bool value) {
151 js.context['Platform']['enableBindingsReflection'] = value;
152 }
153
154 // TODO(jmesserly): const set would be better
155 const _SEMANTIC_TEMPLATE_TAGS = const {
156 'caption': null,
157 'col': null,
158 'colgroup': null,
159 'option': null,
160 'optgroup': null,
161 'tbody': null,
162 'td': null,
163 'tfoot': null,
164 'th': null,
165 'thead': null,
166 'tr': null,
167 };
168
169
170 // TODO(jmesserly): investigate if expandos give us enough performance.
171
172 // The expando for storing our MDV extensions.
173 //
174 // In general, we need state associated with the nodes. Rather than having a
175 // bunch of individual expandos, we keep one per node.
176 //
177 // Aside from the potentially helping performance, it also keeps things simpler
178 // if we decide to integrate MDV into the DOM later, and means less code needs
179 // to worry about expandos.
180 final Expando _expando = new Expando('template_binding');
OLDNEW
« no previous file with comments | « packages/template_binding/lib/src/template_iterator.dart ('k') | packages/template_binding/pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698