| OLD | NEW |
| (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 part of mdv; |
| 6 |
| 7 /** Extensions to the [SelectElement] API. */ |
| 8 class _SelectElementExtension extends _ElementExtension { |
| 9 _SelectElementExtension(SelectElement node) : super(node); |
| 10 |
| 11 SelectElement get node => super.node; |
| 12 |
| 13 _SelectedIndexBinding _valueBinding; |
| 14 |
| 15 void bind(String name, model, String path) { |
| 16 if (name.toLowerCase() == 'selectedindex') { |
| 17 unbind('selectedindex'); |
| 18 node.attributes.remove('selectedindex'); |
| 19 _valueBinding = new _SelectedIndexBinding(node, model, path); |
| 20 return; |
| 21 } |
| 22 super.bind(name, model, path); |
| 23 } |
| 24 |
| 25 void unbind(String name) { |
| 26 if (name.toLowerCase() == 'selectedindex' && _valueBinding != null) { |
| 27 _valueBinding.unbind(); |
| 28 _valueBinding = null; |
| 29 return; |
| 30 } |
| 31 super.unbind(name); |
| 32 } |
| 33 |
| 34 void unbindAll() { |
| 35 unbind('selectedindex'); |
| 36 super.unbindAll(); |
| 37 } |
| 38 } |
| 39 |
| 40 |
| 41 class _SelectedIndexBinding extends _InputBinding { |
| 42 _SelectedIndexBinding(element, model, path) : super(element, model, path); |
| 43 |
| 44 SelectElement get element => super.element; |
| 45 |
| 46 void valueChanged(value) { |
| 47 var newValue = _toInt(value); |
| 48 if (newValue <= element.length) { |
| 49 element.selectedIndex = newValue; |
| 50 return; |
| 51 } |
| 52 |
| 53 // The binding may wish to bind to an <option> which has not yet been |
| 54 // produced by a child <template>. Delay a maximum of twice -- once for |
| 55 // iterating <optgroup> and once for <option>. |
| 56 var maxRetries = 2; |
| 57 delaySetSelectedIndex() { |
| 58 if (newValue > element.length && --maxRetries >= 0) { |
| 59 runAsync(delaySetSelectedIndex); |
| 60 } else { |
| 61 element.selectedIndex = newValue; |
| 62 } |
| 63 } |
| 64 |
| 65 // TODO(jmesserly): we aren't matching MDV here. They schedule "model=" to |
| 66 // happen async and then delay using the same scheduler. By using "runAsync" |
| 67 // we're going to happen quite a bit later. |
| 68 // We need to port the "ensureScheduled" function: |
| 69 // https://github.com/Polymer/mdv/commit/9a51ad7ed74a292bf71662cea28acbd151f
f65c8 |
| 70 runAsync(delaySetSelectedIndex); |
| 71 } |
| 72 |
| 73 void updateBinding(e) { |
| 74 binding.value = element.selectedIndex; |
| 75 } |
| 76 |
| 77 // TODO(jmesserly,sigmund): I wonder how many bindings typically convert from |
| 78 // one type to another (e.g. value-as-number) and whether it is useful to |
| 79 // have something like a int/num binding converter (either as a base class or |
| 80 // a wrapper). |
| 81 static int _toInt(value) { |
| 82 if (value is String) return int.parse(value, onError: (_) => null); |
| 83 return value is int ? value : null; |
| 84 } |
| 85 } |
| OLD | NEW |