| OLD | NEW |
| 1 part of angular.filter; | 1 part of angular.formatter_internal; |
| 2 | 2 |
| 3 typedef dynamic Mapper(dynamic e); | 3 typedef dynamic _Mapper(dynamic e); |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * Orders the provided [Iterable] by the `expression` predicate. | 6 * Orders the provided [Iterable] by the `expression` predicate. |
| 7 * | 7 * |
| 8 * Example 1: Simple array and single/empty expression. | 8 * Example 1: Simple array and single/empty expression. |
| 9 * | 9 * |
| 10 * Assume that you have an array on scope called `colors` and that it has a list | 10 * Assume that you have an array on scope called `colors` and that it has a list |
| 11 * of these strings – `['red', 'blue', 'green']`. You might sort these in | 11 * of these strings – `['red', 'blue', 'green']`. You might sort these in |
| 12 * ascending order this way: | 12 * ascending order this way: |
| 13 * | 13 * |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 * For example, one might want to sort the authors list, first by last name and | 97 * For example, one might want to sort the authors list, first by last name and |
| 98 * then by first name when the last names are equal. You would do that like | 98 * then by first name when the last names are equal. You would do that like |
| 99 * this: | 99 * this: |
| 100 * | 100 * |
| 101 * <li ng-repeat="author in authors | orderBy:['lastName', 'firstName']"> | 101 * <li ng-repeat="author in authors | orderBy:['lastName', 'firstName']"> |
| 102 * | 102 * |
| 103 * The items in such a list may either be string expressions or callables. The | 103 * The items in such a list may either be string expressions or callables. The |
| 104 * list itself might be provided as an expression that is looked up on the scope | 104 * list itself might be provided as an expression that is looked up on the scope |
| 105 * chain. | 105 * chain. |
| 106 */ | 106 */ |
| 107 @NgFilter(name: 'orderBy') | 107 @Formatter(name: 'orderBy') |
| 108 class OrderByFilter { | 108 class OrderBy implements Function { |
| 109 Parser _parser; | 109 Parser _parser; |
| 110 | 110 |
| 111 OrderByFilter(this._parser); | 111 OrderBy(this._parser); |
| 112 | 112 |
| 113 static _nop(e) => e; | 113 static _nop(e) => e; |
| 114 static bool _isNonZero(int n) => (n != 0); | 114 static bool _isNonZero(int n) => (n != 0); |
| 115 static int _returnZero() => 0; | 115 static int _returnZero() => 0; |
| 116 static int _defaultComparator(a, b) => Comparable.compare(a, b); | 116 static int _defaultComparator(a, b) => Comparable.compare(a, b); |
| 117 static int _reverseComparator(a, b) => _defaultComparator(b, a); | 117 static int _reverseComparator(a, b) => _defaultComparator(b, a); |
| 118 | 118 |
| 119 static int _compareLists(List a, List b, List<Comparator> comparators) { | 119 static int _compareLists(List a, List b, List<Comparator> comparators) { |
| 120 return new Iterable.generate(a.length, (i) => comparators[i](a[i], b[i])) | 120 return new Iterable.generate(a.length, (i) => comparators[i](a[i], b[i])) |
| 121 .firstWhere(_isNonZero, orElse: _returnZero); | 121 .firstWhere(_isNonZero, orElse: _returnZero); |
| 122 } | 122 } |
| 123 | 123 |
| 124 static List _sorted( | 124 static List _sorted( |
| 125 List items, List<Mapper> mappers, List<Comparator> comparators, bool desce
nding) { | 125 List items, List<_Mapper> mappers, List<Comparator> comparators, bool desc
ending) { |
| 126 // Do the standard decorate-sort-undecorate aka Schwartzian dance since Dart | 126 // Do the standard decorate-sort-undecorate aka Schwartzian dance since Dart |
| 127 // doesn't support a key/transform parameter to sort(). | 127 // doesn't support a key/transform parameter to sort(). |
| 128 // Ref: http://en.wikipedia.org/wiki/Schwartzian_transform | 128 // Ref: http://en.wikipedia.org/wiki/Schwartzian_transform |
| 129 mapper(e) => mappers.map((m) => m(e)).toList(growable: false); | 129 mapper(e) => mappers.map((m) => m(e)).toList(growable: false); |
| 130 List decorated = items.map(mapper).toList(growable: false); | 130 List decorated = items.map(mapper).toList(growable: false); |
| 131 List<int> indices = new Iterable.generate(decorated.length, _nop).toList(gro
wable: false); | 131 List<int> indices = new Iterable.generate(decorated.length, _nop).toList(gro
wable: false); |
| 132 comparator(i, j) => _compareLists(decorated[i], decorated[j], comparators); | 132 comparator(i, j) => _compareLists(decorated[i], decorated[j], comparators); |
| 133 indices.sort((descending) ? (i, j) => comparator(j, i) : comparator); | 133 indices.sort((descending) ? (i, j) => comparator(j, i) : comparator); |
| 134 return indices.map((i) => items[i]).toList(growable: false); | 134 return indices.map((i) => items[i]).toList(growable: false); |
| 135 } | 135 } |
| 136 | 136 |
| 137 /** | 137 /** |
| 138 * expression: String/Function or Array of String/Function. | 138 * expression: String/Function or Array of String/Function. |
| 139 */ | 139 */ |
| 140 List call(List items, var expression, [bool descending=false]) { | 140 List call(List items, var expression, [bool descending=false]) { |
| 141 if (items == null) { | 141 if (items == null) { |
| 142 return null; | 142 return null; |
| 143 } | 143 } |
| 144 List expressions = null; | 144 List expressions = null; |
| 145 if (expression is String || expression is Mapper) { | 145 if (expression is String || expression is _Mapper) { |
| 146 expressions = [expression]; | 146 expressions = [expression]; |
| 147 } else if (expression is List) { | 147 } else if (expression is List) { |
| 148 expressions = expression as List; | 148 expressions = expression as List; |
| 149 } | 149 } |
| 150 if (expressions == null || expressions.length == 0) { | 150 if (expressions == null || expressions.length == 0) { |
| 151 // AngularJS behavior. You must have an expression to get any work done. | 151 // AngularJS behavior. You must have an expression to get any work done. |
| 152 return items; | 152 return items; |
| 153 } | 153 } |
| 154 int numExpressions = expressions.length; | 154 int numExpressions = expressions.length; |
| 155 List<Mapper> mappers = new List(numExpressions); | 155 List<_Mapper> mappers = new List(numExpressions); |
| 156 List<Comparator> comparators = new List<Comparator>(numExpressions); | 156 List<Comparator> comparators = new List<Comparator>(numExpressions); |
| 157 for (int i = 0; i < numExpressions; i++) { | 157 for (int i = 0; i < numExpressions; i++) { |
| 158 expression = expressions[i]; | 158 expression = expressions[i]; |
| 159 if (expression is String) { | 159 if (expression is String) { |
| 160 var strExp = expression as String; | 160 var strExp = expression as String; |
| 161 var desc = false; | 161 var desc = false; |
| 162 if (strExp.startsWith('-') || strExp.startsWith('+')) { | 162 if (strExp.startsWith('-') || strExp.startsWith('+')) { |
| 163 desc = strExp.startsWith('-'); | 163 desc = strExp.startsWith('-'); |
| 164 strExp = strExp.substring(1); | 164 strExp = strExp.substring(1); |
| 165 } | 165 } |
| 166 comparators[i] = desc ? _reverseComparator : _defaultComparator; | 166 comparators[i] = desc ? _reverseComparator : _defaultComparator; |
| 167 if (strExp == '') { | 167 if (strExp == '') { |
| 168 mappers[i] = _nop; | 168 mappers[i] = _nop; |
| 169 } else { | 169 } else { |
| 170 Expression parsed = _parser(strExp); | 170 Expression parsed = _parser(strExp); |
| 171 mappers[i] = (e) => parsed.eval(e); | 171 mappers[i] = (e) => parsed.eval(e); |
| 172 } | 172 } |
| 173 } else if (expression is Mapper) { | 173 } else if (expression is _Mapper) { |
| 174 mappers[i] = (expression as Mapper); | 174 mappers[i] = (expression as _Mapper); |
| 175 comparators[i] = _defaultComparator; | 175 comparators[i] = _defaultComparator; |
| 176 } | 176 } |
| 177 } | 177 } |
| 178 return _sorted(items, mappers, comparators, descending); | 178 return _sorted(items, mappers, comparators, descending); |
| 179 } | 179 } |
| 180 } | 180 } |
| OLD | NEW |