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

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

Issue 42433002: port Node.bind to bd0a0591920da9091b326627a46a104a92c7efe7 (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
Index: pkg/template_binding/lib/src/input_bindings.dart
diff --git a/pkg/template_binding/lib/src/input_bindings.dart b/pkg/template_binding/lib/src/input_bindings.dart
index e00b3a9e6b24714c7c539d7670ccd613c99d0882..fc89dc5d1ae1d32e6e188afd6128a4fbd2e9505d 100644
--- a/pkg/template_binding/lib/src/input_bindings.dart
+++ b/pkg/template_binding/lib/src/input_bindings.dart
@@ -11,7 +11,7 @@ abstract class _InputBinding extends NodeBinding {
_eventSub = _getStreamForInputType(node).listen(nodeValueChanged);
}
- void boundValueChanged(newValue);
+ void valueChanged(newValue);
void nodeValueChanged(e);
@@ -41,6 +41,7 @@ abstract class _InputBinding extends NodeBinding {
}();
static Stream<Event> _getStreamForInputType(element) {
+ if (element is OptionElement) return element.onInput;
switch (element.type) {
case 'checkbox':
return _checkboxEventType.forTarget(element);
@@ -59,13 +60,14 @@ class _ValueBinding extends _InputBinding {
get node => super.node;
- void boundValueChanged(newValue) {
+ void valueChanged(newValue) {
// Note: node can be an InputElement or TextAreaElement. Both have "value".
- (node as dynamic).value = sanitizeBoundValue(newValue);
+ node.value = sanitizeBoundValue(newValue);
}
void nodeValueChanged(e) {
- value = (node as dynamic).value;
+ value = node.value;
+ Observable.dirtyCheck();
}
}
@@ -74,7 +76,7 @@ class _CheckedBinding extends _InputBinding {
InputElement get node => super.node;
- void boundValueChanged(newValue) {
+ void valueChanged(newValue) {
node.checked = _toBoolean(newValue);
}
@@ -93,6 +95,8 @@ class _CheckedBinding extends _InputBinding {
}
}
}
+
+ Observable.dirtyCheck();
}
// |element| is assumed to be an HTMLInputElement with |type| == 'radio'.
@@ -105,7 +109,6 @@ class _CheckedBinding extends _InputBinding {
// http://www.whatwg.org/specs/web-apps/current-work/multipage/number-state.html#radio-button-group
//
static Iterable _getAssociatedRadioButtons(element) {
- if (!_isNodeInDocument(element)) return [];
if (element.form != null) {
return element.form.nodes.where((el) {
return el != element &&
@@ -114,41 +117,32 @@ class _CheckedBinding extends _InputBinding {
el.name == element.name;
});
} else {
- var radios = element.ownerDocument.queryAll(
+ var treeScope = _getTreeScope(element);
+ if (treeScope == null) return const [];
+
+ var radios = treeScope.querySelectorAll(
'input[type="radio"][name="${element.name}"]');
return radios.where((el) => el != element && el.form == null);
}
}
-
- // TODO(jmesserly): polyfill document.contains API instead of doing it here
- static bool _isNodeInDocument(Node node) {
- // On non-IE this works:
- // return node.ownerDocument.contains(node);
- var document = node.ownerDocument;
- if (node == document || node.parentNode == document) return true;
- return document.documentElement.contains(node);
- }
}
-class _SelectedIndexBinding extends _InputBinding {
- _SelectedIndexBinding(node, model, path)
- : super(node, 'selectedIndex', model, path);
+class _SelectBinding extends _InputBinding {
+ _SelectBinding(node, property, model, path)
+ : super(node, property, model, path);
SelectElement get node => super.node;
- void boundValueChanged(value) {
- var newValue = _toInt(value);
- if (newValue <= node.length) {
- node.selectedIndex = newValue;
- return;
- }
+ void valueChanged(newValue) {
+ if (_tryUpdateValue(newValue)) return;
// The binding may wish to bind to an <option> which has not yet been
// produced by a child <template>. Furthermore, we may need to wait for
// <optgroup> iterating and then for <option>.
//
- // Unlike the JavaScript MDV, we don't have a special "Object.observe" event
- // loop to schedule on. (See the the "ensureScheduled" function:
+ // Unlike the JavaScript implemenation, we don't have a special
+ // "Object.observe" event loop to schedule on.
+ // (See the the "ensureScheduled" function:
// https://github.com/Polymer/mdv/commit/9a51ad7ed74a292bf71662cea28acbd151ff65c8)
//
// Instead we use scheduleMicrotask. Each <template repeat> needs a delay of
@@ -159,20 +153,35 @@ class _SelectedIndexBinding extends _InputBinding {
// * once for OPTGROUP
// * once for OPTION.
// The resulting 2 * 2 is our maxRetries.
+ // TODO(jmesserly): a much better approach would be to find the nested
+ // <template> and wait on some future that completes when it has expanded.
var maxRetries = 4;
delaySetSelectedIndex() {
- if (newValue > node.length && --maxRetries >= 0) {
+ if (!_tryUpdateValue(newValue) && maxRetries-- > 0) {
scheduleMicrotask(delaySetSelectedIndex);
- } else {
- node.selectedIndex = newValue;
}
}
scheduleMicrotask(delaySetSelectedIndex);
}
+ bool _tryUpdateValue(newValue) {
+ if (property == 'selectedIndex') {
+ var intValue = _toInt(newValue);
+ node.selectedIndex = intValue;
+ return node.selectedIndex == intValue;
+ } else if (property == 'value') {
+ node.value = sanitizeBoundValue(newValue);
+ return node.value == newValue;
+ }
+ }
+
void nodeValueChanged(e) {
- value = node.selectedIndex;
+ if (property == 'selectedIndex') {
+ value = node.selectedIndex;
+ } else if (property == 'value') {
+ value = node.value;
+ }
}
// TODO(jmesserly,sigmund): I wonder how many bindings typically convert from
@@ -180,7 +189,7 @@ class _SelectedIndexBinding extends _InputBinding {
// have something like a int/num binding converter (either as a base class or
// a wrapper).
static int _toInt(value) {
- if (value is String) return int.parse(value, onError: (_) => null);
- return value is int ? value : null;
+ if (value is String) return int.parse(value, onError: (_) => 0);
+ return value is int ? value : 0;
}
}

Powered by Google App Engine
This is Rietveld 408576698