| Index: third_party/pkg/angular/lib/directive/input_select.dart
|
| diff --git a/third_party/pkg/angular/lib/directive/input_select.dart b/third_party/pkg/angular/lib/directive/input_select.dart
|
| index 3c5aaf3e32ac016e6360889c0be77e5fd1ede90c..af568b30aaac49e0f0a293782c74ca4ac4c8c0f1 100644
|
| --- a/third_party/pkg/angular/lib/directive/input_select.dart
|
| +++ b/third_party/pkg/angular/lib/directive/input_select.dart
|
| @@ -3,26 +3,28 @@ part of angular.directive;
|
| typedef dynamic ItemEval(dynamic item, num index);
|
|
|
| /**
|
| - * HTML [SELECT] element with angular data-binding if used with [NgModelDirective].
|
| + * HTML [SELECT] element with angular data-binding if used with
|
| + * [NgModelDirective].
|
| *
|
| - * The [NgModelDirective] will receive the currently selected item. The binding is
|
| - * performed on the [OPTION].[value] property.
|
| - * An empty [OPTION].[value] is treated as null.
|
| + * The [NgModelDirective] will receive the currently selected item. The binding
|
| + * is performed on the [OPTION].[value] property. An empty [OPTION].[value] is
|
| + * treated as null.
|
| *
|
| * If you the model contains value which does not map to any [OPTION] then a new
|
| - * unknown [OPTION] is inserted into the list. Once the model points to an existing
|
| - * [OPTION] the unknown [OPTION] is removed.
|
| + * unknown [OPTION] is inserted into the list. Once the model points to an
|
| + * existing [OPTION] the unknown [OPTION] is removed.
|
| *
|
| - * Becouse [OPTION].[value] attribute is a string, the model is bound to a string.
|
| - * If there is need to bind to an object then [OptionValueDirective] should be used.
|
| + * Becouse [OPTION].[value] attribute is a string, the model is bound to a
|
| + * string. If there is need to bind to an object then [OptionValueDirective]
|
| + * should be used.
|
| *
|
| */
|
| @NgDirective(
|
| selector: 'select[ng-model]',
|
| - visibility: NgDirective.CHILDREN_VISIBILITY
|
| -)
|
| + visibility: NgDirective.CHILDREN_VISIBILITY)
|
| class InputSelectDirective implements NgAttachAware {
|
| - final Expando<OptionValueDirective> expando = new Expando<OptionValueDirective>();
|
| + final Expando<OptionValueDirective> expando =
|
| + new Expando<OptionValueDirective>();
|
| final dom.SelectElement _selectElement;
|
| final NodeAttrs _attrs;
|
| final NgModel _model;
|
| @@ -34,7 +36,8 @@ class InputSelectDirective implements NgAttachAware {
|
| _SelectMode _mode = new _SelectMode(null, null, null);
|
| bool _dirty = false;
|
|
|
| - InputSelectDirective(dom.Element this._selectElement, this._attrs, this._model, this._scope) {
|
| + InputSelectDirective(dom.Element this._selectElement, this._attrs, this._model,
|
| + this._scope) {
|
| _unknownOption.value = '?';
|
| _unknownOption.text = ''; // Explicit due to dartbug.com/14407
|
| _selectElement.querySelectorAll('option').forEach((o) {
|
| @@ -58,54 +61,58 @@ class InputSelectDirective implements NgAttachAware {
|
| });
|
|
|
| _selectElement.onChange.listen((event) => _mode.onViewChange(event));
|
| - _model.render = (value) => _mode.onModelChange(value);
|
| + _model.render = (value) {
|
| + // TODO(misko): this hack need to delay the rendering until after domRead
|
| + // because the modelChange reads from the DOM. We should be able to render
|
| + // without DOM changes.
|
| + _scope.rootScope.domRead(() {
|
| + _scope.rootScope.domWrite(() => _mode.onModelChange(value));
|
| + });
|
| + };
|
| }
|
|
|
| /**
|
| - * This method invalidates the current state of the selector and forces a re-rendering of the
|
| - * options using the [Scope.$evalAsync].
|
| + * This method invalidates the current state of the selector and forces a
|
| + * re-rendering of the options using the [Scope.evalAsync].
|
| */
|
| dirty() {
|
| if (!_dirty) {
|
| _dirty = true;
|
| - _scope.$evalAsync(() {
|
| - _dirty = false;
|
| - _mode.onModelChange(_model.viewValue);
|
| + // TODO(misko): this hack need to delay the rendering until after domRead
|
| + // becouse the modelChange reads from the DOM. We should be able to render
|
| + // without DOM changes.
|
| + _scope.rootScope.domRead(() {
|
| + _scope.rootScope.domWrite(() {
|
| + _dirty = false;
|
| + _mode.onModelChange(_model.viewValue);
|
| + });
|
| });
|
| }
|
| }
|
| }
|
|
|
| /**
|
| - * Since the [value] attirbute of the [OPTION] can only be a string, Angular provides
|
| - * [ng-value] which allows binding to any expression.
|
| + * Since the [value] attribute of the [OPTION] can only be a string, Angular
|
| + * provides [ng-value] which allows binding to any expression.
|
| *
|
| */
|
| @NgDirective(
|
| - selector: 'option',
|
| - publishTypes: const [TextChangeListener],
|
| - map: const {'ng-value': '&ngValue'}
|
| -)
|
| -class OptionValueDirective implements TextChangeListener, NgAttachAware, NgDetachAware {
|
| + selector: 'option')
|
| +class OptionValueDirective implements NgAttachAware,
|
| + NgDetachAware {
|
| final InputSelectDirective _inputSelectDirective;
|
| - final NodeAttrs _attrs;
|
| + final dom.Element _element;
|
|
|
| - Getter _ngValue;
|
| + NgValue _ngValue;
|
|
|
| - OptionValueDirective(this._attrs, this._inputSelectDirective) {
|
| + OptionValueDirective(this._element, this._inputSelectDirective, this._ngValue) {
|
| if (_inputSelectDirective != null) {
|
| - _inputSelectDirective.expando[_attrs.element] = this;
|
| + _inputSelectDirective.expando[_element] = this;
|
| }
|
| }
|
|
|
| attach() {
|
| if (_inputSelectDirective != null) {
|
| - this._attrs.observe('value', (_) => _inputSelectDirective.dirty());
|
| - }
|
| - }
|
| -
|
| - call(String text) {
|
| - if (_inputSelectDirective != null) {
|
| _inputSelectDirective.dirty();
|
| }
|
| }
|
| @@ -113,13 +120,11 @@ class OptionValueDirective implements TextChangeListener, NgAttachAware, NgDetac
|
| detach() {
|
| if (_inputSelectDirective != null) {
|
| _inputSelectDirective.dirty();
|
| - _inputSelectDirective.expando[_attrs.element] = null;
|
| + _inputSelectDirective.expando[_element] = null;
|
| }
|
| }
|
|
|
| - set ngValue(Getter value) => _ngValue = value;
|
| - get ngValue =>
|
| - _attrs['ng-value'] is String ? _ngValue() : (_attrs.element as dom.OptionElement).value;
|
| + get ngValue => _ngValue.readValue(_element);
|
| }
|
|
|
| class _SelectMode {
|
| @@ -135,11 +140,9 @@ class _SelectMode {
|
|
|
| get _options => select.querySelectorAll('option');
|
| _forEachOption(fn, [quiteOnReturn = false]) {
|
| - for(var os = _options, i = 0, ii = os.length; i < ii; i++) {
|
| - var retValue = fn(os[i], i);
|
| - if (quiteOnReturn && retValue != null) {
|
| - return retValue;
|
| - }
|
| + for (var i = 0; i < _options.length; i++) {
|
| + var retValue = fn(_options[i], i);
|
| + if (quiteOnReturn && retValue != null) return retValue;
|
| }
|
| return null;
|
| }
|
| @@ -165,9 +168,7 @@ class _SingleSelectMode extends _SelectMode {
|
| if (option.selected) {
|
| return option == _nullOption ? null : expando[option].ngValue;
|
| }
|
| - if (option != _unknownOption && option != _nullOption) {
|
| - i++;
|
| - }
|
| + if (option != _unknownOption && option != _nullOption) i++;
|
| }, true);
|
| }
|
|
|
| @@ -204,16 +205,14 @@ class _SingleSelectMode extends _SelectMode {
|
| class _MultipleSelectionMode extends _SelectMode {
|
| _MultipleSelectionMode(Expando<OptionValueDirective> expando,
|
| dom.SelectElement select,
|
| - NgModel model
|
| - ): super(expando, select, model);
|
| + NgModel model)
|
| + : super(expando, select, model);
|
|
|
| onViewChange(event) {
|
| var selected = [];
|
|
|
| _forEachOption((o, i) {
|
| - if (o.selected) {
|
| - selected.add(expando[o].ngValue);
|
| - }
|
| + if (o.selected) selected.add(expando[o].ngValue);
|
| });
|
| model.viewValue = selected;
|
| }
|
| @@ -222,7 +221,14 @@ class _MultipleSelectionMode extends _SelectMode {
|
| Function fn = (o, i) => o.selected = null;
|
|
|
| if (selectedValues is List) {
|
| - fn = (o, i) => o.selected = selectedValues.contains(expando[o].ngValue);
|
| + fn = (o, i) {
|
| + var selected = expando[o];
|
| + if (selected == null) {
|
| + return false;
|
| + } else {
|
| + return o.selected = selectedValues.contains(selected.ngValue);
|
| + }
|
| + };
|
| }
|
|
|
| _forEachOption(fn);
|
|
|