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

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

Issue 34453003: Rename mdv -> template_binding, remove experiemntal apis from dart:html (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/template_binding/lib/src/text_area_element.dart ('k') | pkg/template_binding/pubspec.yaml » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/template_binding/lib/template_binding.dart
diff --git a/pkg/template_binding/lib/template_binding.dart b/pkg/template_binding/lib/template_binding.dart
new file mode 100644
index 0000000000000000000000000000000000000000..72976ac01e0122b7ff25da1e2f6bfb830008baa9
--- /dev/null
+++ b/pkg/template_binding/lib/template_binding.dart
@@ -0,0 +1,171 @@
+// 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.
+
+/**
+ * This library provides access to the Polymer project's
+ * [Data Binding](http://www.polymer-project.org/docs/polymer/databinding.html)
+ * Find more information at the
+ * [Polymer.dart homepage](https://www.dartlang.org/polymer-dart/).
+ *
+ * Extends the capabilities of the HTML Template Element by enabling it to
+ * create, manage, and remove instances of content bound to data defined in
+ * Dart.
+ *
+ * Node.bind() is a new method added to all DOM nodes which instructs them to
+ * bind the named property to the data provided. These allows applications to
+ * create a data model in Dart or JavaScript that DOM reacts to.
+ */
+library template_binding;
+
+import 'dart:async';
+import 'dart:collection';
+import 'dart:html';
+import 'dart:svg' show SvgSvgElement;
+import 'package:observe/observe.dart';
+
+import 'src/list_diff.dart' show calculateSplices, ListChangeDelta;
+
+part 'src/element.dart';
+part 'src/input_bindings.dart';
+part 'src/input_element.dart';
+part 'src/node.dart';
+part 'src/select_element.dart';
+part 'src/template.dart';
+part 'src/template_iterator.dart';
+part 'src/text.dart';
+part 'src/text_area_element.dart';
+
+// TODO(jmesserly): ideally we would split TemplateBinding and Node.bind into
+// two packages, but this is not easy when we are faking extension methods.
+// Since TemplateElement needs to override Node.bind, it seems like the
+// Node.bind layer must have some innate knowledge of TemplateBinding.
+
+/**
+ * Provides access to the data binding APIs for the [node]. For example:
+ *
+ * templateBind(node).model = new MyModel();
+ *
+ * This is equivalent to [nodeBind], but provides access to
+ * [TemplateBindExtension] APIs. [node] should be a [TemplateElement], or
+ * equivalent semantic template such as:
+ *
+ * <table template repeat="{{row in rows}}">
+ * <tr template repeat="{{item in row}}">
+ * <td>{{item}}</td>
+ * </tr>
+ * </table>
+ */
+TemplateBindExtension templateBind(Element node) => nodeBind(node);
+
+/**
+ * Like [templateBind], but intended to be used only within a custom element
+ * that implements [TemplateBindExtension]. This method can be used to simulate
+ * a super call. For example:
+ *
+ * class CoolTemplate extends TemplateElement
+ * implements TemplateBindExtension {
+ *
+ * createInstance(model, delegate) {
+ * // do something cool...
+ * // otherwise, fall back to superclass
+ * return templateBindFallback(this).createInstance(model, delegate);
+ * }
+ * ...
+ * }
+ */
+TemplateBindExtension templateBindFallback(Element node) =>
+ nodeBindFallback(node);
+
+/**
+ * Provides access to the data binding APIs for the [node]. For example:
+ *
+ * nodeBind(node).bind('checked', model, 'path.to.some.value');
+ */
+NodeBindExtension nodeBind(Node node) {
+ return node is NodeBindExtension ? node : nodeBindFallback(node);
+}
+
+/**
+ * Like [nodeBind], but intended to be used only within a custom element that
+ * implements [NodeBindExtension]. This method can be used to simulate a super
+ * call. For example:
+ *
+ * class FancyButton extends ButtonElement implements NodeBindExtension {
+ * bind(name, model, path) {
+ * if (name == 'fancy-prop') ... // do fancy binding
+ * // otherwise, fall back to superclass
+ * return nodeBindFallback(this).bind(name, model, path);
+ * }
+ * ...
+ * }
+ */
+NodeBindExtension nodeBindFallback(Node node) {
+ var extension = _expando[node];
+ if (extension != null) return extension;
+
+ if (node is InputElement) {
+ extension = new _InputElementExtension(node);
+ } else if (node is SelectElement) {
+ extension = new _SelectElementExtension(node);
+ } else if (node is TextAreaElement) {
+ extension = new _TextAreaElementExtension(node);
+ } else if (node is Element) {
+ if (isSemanticTemplate(node)) {
+ extension = new TemplateBindExtension._(node);
+ } else {
+ extension = new _ElementExtension(node);
+ }
+ } else if (node is Text) {
+ extension = new _TextExtension(node);
+ } else {
+ extension = new NodeBindExtension._(node);
+ }
+
+ _expando[node] = extension;
+ return extension;
+}
+
+
+bool _isAttributeTemplate(Element n) => n.attributes.containsKey('template') &&
+ _SEMANTIC_TEMPLATE_TAGS.containsKey(n.localName);
+
+/**
+ * Returns true if this node is semantically a template.
+ *
+ * A node is a template if [tagName] is TEMPLATE, or the node has the
+ * 'template' attribute and this tag supports attribute form for backwards
+ * compatibility with existing HTML parsers. The nodes that can use attribute
+ * form are table elments (THEAD, TBODY, TFOOT, TH, TR, TD, CAPTION, COLGROUP
+ * and COL), OPTION, and OPTGROUP.
+ */
+bool isSemanticTemplate(Node n) => n is Element &&
+ ((n as Element).localName == 'template' || _isAttributeTemplate(n));
+
+// TODO(jmesserly): const set would be better
+const _SEMANTIC_TEMPLATE_TAGS = const {
+ 'caption': null,
+ 'col': null,
+ 'colgroup': null,
+ 'option': null,
+ 'optgroup': null,
+ 'tbody': null,
+ 'td': null,
+ 'tfoot': null,
+ 'th': null,
+ 'thead': null,
+ 'tr': null,
+};
+
+
+// TODO(jmesserly): investigate if expandos give us enough performance.
+
+// The expando for storing our MDV extensions.
+//
+// In general, we need state associated with the nodes. Rather than having a
+// bunch of individual expandos, we keep one per node.
+//
+// Aside from the potentially helping performance, it also keeps things simpler
+// if we decide to integrate MDV into the DOM later, and means less code needs
+// to worry about expandos.
+final Expando _expando = new Expando('template_binding');
« no previous file with comments | « pkg/template_binding/lib/src/text_area_element.dart ('k') | pkg/template_binding/pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698