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

Side by Side Diff: third_party/pkg/angular/lib/directive/ng_class.dart

Issue 257423008: Update all Angular libs (run update_all.sh). (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 part of angular.directive; 1 part of angular.directive;
2 2
3 /** 3 /**
4 * The `ngClass` allows you to set CSS classes on HTML an element, dynamically, 4 * The `ngClass` allows you to set CSS classes on HTML an element, dynamically,
5 * by databinding an expression that represents all classes to be added. 5 * by databinding an expression that represents all classes to be added.
6 * 6 *
7 * The directive won't add duplicate classes if a particular class was 7 * The directive won't add duplicate classes if a particular class was
8 * already set. 8 * already set.
9 * 9 *
10 * When the expression changes, the previously added classes are removed and 10 * When the expression changes, the previously added classes are removed and
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 * text-decoration: line-through; 55 * text-decoration: line-through;
56 * } 56 * }
57 * .bold { 57 * .bold {
58 * font-weight: bold; 58 * font-weight: bold;
59 * } 59 * }
60 * .red { 60 * .red {
61 * color: red; 61 * color: red;
62 * } 62 * }
63 * 63 *
64 */ 64 */
65 @NgDirective( 65 @Decorator(
66 selector: '[ng-class]', 66 selector: '[ng-class]',
67 map: const {'ng-class': '@valueExpression'}, 67 map: const {'ng-class': '@valueExpression'},
68 exportExpressionAttrs: const ['ng-class']) 68 exportExpressionAttrs: const ['ng-class'])
69 class NgClassDirective extends _NgClassBase { 69 class NgClass extends _NgClassBase {
70 NgClassDirective(dom.Element element, Scope scope, NodeAttrs attrs, AstParser parser) 70 NgClass(NgElement ngElement, Scope scope, NodeAttrs nodeAttrs)
71 : super(element, scope, null, attrs, parser); 71 : super(ngElement, scope, nodeAttrs);
72 } 72 }
73 73
74 /** 74 /**
75 * The `ngClassOdd` and `ngClassEven` directives work exactly as 75 * The `ngClassOdd` and `ngClassEven` directives work exactly as
76 * {@link ng.directive:ngClass ngClass}, except it works in 76 * {@link ng.directive:ngClass ngClass}, except it works in
77 * conjunction with `ngRepeat` and takes affect only on odd (even) rows. 77 * conjunction with `ngRepeat` and takes affect only on odd (even) rows.
78 * 78 *
79 * This directive can be applied only within a scope of an `ngRepeat`. 79 * This directive can be applied only within a scope of an `ngRepeat`.
80 * 80 *
81 * ##Examples 81 * ##Examples
82 * 82 *
83 * index.html: 83 * index.html:
84 * 84 *
85 * <li ng-repeat="name in ['John', 'Mary', 'Cate', 'Suz']"> 85 * <li ng-repeat="name in ['John', 'Mary', 'Cate', 'Suz']">
86 * <span ng-class-odd="'odd'" ng-class-even="'even'"> 86 * <span ng-class-odd="'odd'" ng-class-even="'even'">
87 * {{name}} 87 * {{name}}
88 * </span> 88 * </span>
89 * </li> 89 * </li>
90 * 90 *
91 * style.css: 91 * style.css:
92 * 92 *
93 * .odd { 93 * .odd {
94 * color: red; 94 * color: red;
95 * } 95 * }
96 * .even { 96 * .even {
97 * color: blue; 97 * color: blue;
98 * } 98 * }
99 */ 99 */
100 @NgDirective( 100 @Decorator(
101 selector: '[ng-class-odd]', 101 selector: '[ng-class-odd]',
102 map: const {'ng-class-odd': '@valueExpression'}, 102 map: const {'ng-class-odd': '@valueExpression'},
103 exportExpressionAttrs: const ['ng-class-odd']) 103 exportExpressionAttrs: const ['ng-class-odd'])
104 class NgClassOddDirective extends _NgClassBase { 104 class NgClassOdd extends _NgClassBase {
105 NgClassOddDirective(dom.Element element, Scope scope, NodeAttrs attrs, AstPars er parser) 105 NgClassOdd(NgElement ngElement, Scope scope, NodeAttrs nodeAttrs)
106 : super(element, scope, 0, attrs, parser); 106 : super(ngElement, scope, nodeAttrs, 0);
107 } 107 }
108 108
109 /** 109 /**
110 * The `ngClassOdd` and `ngClassEven` directives work exactly as 110 * The `ngClassOdd` and `ngClassEven` directives work exactly as
111 * {@link ng.directive:ngClass ngClass}, except it works in 111 * {@link ng.directive:ngClass ngClass}, except it works in
112 * conjunction with `ngRepeat` and takes affect only on odd (even) rows. 112 * conjunction with `ngRepeat` and takes affect only on odd (even) rows.
113 * 113 *
114 * This directive can be applied only within a scope of an `ngRepeat`. 114 * This directive can be applied only within a scope of an `ngRepeat`.
115 * 115 *
116 * ##Examples 116 * ##Examples
117 * 117 *
118 * index.html: 118 * index.html:
119 * 119 *
120 * <li ng-repeat="name in ['John', 'Mary', 'Cate', 'Suz']"> 120 * <li ng-repeat="name in ['John', 'Mary', 'Cate', 'Suz']">
121 * <span ng-class-odd="'odd'" ng-class-even="'even'"> 121 * <span ng-class-odd="'odd'" ng-class-even="'even'">
122 * {{name}} 122 * {{name}}
123 * </span> 123 * </span>
124 * </li> 124 * </li>
125 * 125 *
126 * style.css: 126 * style.css:
127 * 127 *
128 * .odd { 128 * .odd {
129 * color: red; 129 * color: red;
130 * } 130 * }
131 * .even { 131 * .even {
132 * color: blue; 132 * color: blue;
133 * } 133 * }
134 */ 134 */
135 @NgDirective( 135 @Decorator(
136 selector: '[ng-class-even]', 136 selector: '[ng-class-even]',
137 map: const {'ng-class-even': '@valueExpression'}, 137 map: const {'ng-class-even': '@valueExpression'},
138 exportExpressionAttrs: const ['ng-class-even']) 138 exportExpressionAttrs: const ['ng-class-even'])
139 class NgClassEvenDirective extends _NgClassBase { 139 class NgClassEven extends _NgClassBase {
140 NgClassEvenDirective(dom.Element element, Scope scope, NodeAttrs attrs, AstPar ser parser) 140 NgClassEven(NgElement ngElement, Scope scope, NodeAttrs nodeAttrs)
141 : super(element, scope, 1, attrs, parser); 141 : super(ngElement, scope, nodeAttrs, 1);
142 } 142 }
143 143
144 abstract class _NgClassBase { 144 abstract class _NgClassBase {
145 final dom.Element element; 145 final NgElement _ngElement;
146 final Scope scope; 146 final Scope _scope;
147 final int mode; 147 final int _mode;
148 final NodeAttrs nodeAttrs; 148 Watch _watchExpression;
149 final AstParser _parser; 149 Watch _watchPosition;
150 var previousSet = []; 150 var _previousSet = new Set<String>();
151 var currentSet = []; 151 var _currentSet = new Set<String>();
152 bool _first = true;
152 153
153 _NgClassBase(this.element, this.scope, this.mode, this.nodeAttrs, this._parser ) { 154 _NgClassBase(this._ngElement, this._scope, NodeAttrs nodeAttrs,
154 var prevClass; 155 [this._mode = null])
156 {
157 var prevCls;
155 158
156 nodeAttrs.observe('class', (String newValue) { 159 nodeAttrs.observe('class', (String cls) {
157 if (prevClass != newValue) { 160 if (prevCls != cls) {
158 prevClass = newValue; 161 prevCls = cls;
159 _handleChange(scope.context[r'$index']); 162 _applyChanges(_scope.context[r'$index']);
160 } 163 }
161 }); 164 });
162 } 165 }
163 166
164 set valueExpression(currentExpression) { 167 set valueExpression(expression) {
165 // this should be called only once, so we don't worry about cleaning up 168 if (_watchExpression != null) _watchExpression.remove();
166 // watcher registrations. 169 _watchExpression = _scope.watch(expression, (v, _) {
167 scope.watch( 170 _computeChanges(v);
168 _parser(currentExpression, collection: true), 171 _applyChanges(_scope.context[r'$index']);
169 (current, _) { 172 },
170 currentSet = _flatten(current); 173 canChangeModel: false,
171 _handleChange(scope.context[r'$index']); 174 collection: true);
172 }, 175
173 readOnly: true 176 if (_mode != null) {
174 ); 177 if (_watchPosition != null) _watchPosition.remove();
175 if (mode != null) { 178 _watchPosition = _scope.watch(r'$index', (idx, previousIdx) {
176 scope.watch(_parser(r'$index'), (index, oldIndex) { 179 var mod = idx % 2;
177 var mod = index % 2; 180 if (previousIdx == null || mod != previousIdx % 2) {
178 if (oldIndex == null || mod != oldIndex % 2) { 181 if (mod == _mode) {
179 if (mod == mode) { 182 _currentSet.forEach((cls) => _ngElement.addClass(cls));
180 element.classes.addAll(currentSet);
181 } else { 183 } else {
182 element.classes.removeAll(previousSet); 184 _previousSet.forEach((cls) => _ngElement.removeClass(cls));
183 } 185 }
184 } 186 }
185 }, readOnly: true); 187 }, canChangeModel: false);
186 } 188 }
187 } 189 }
188 190
189 _handleChange(index) { 191 void _computeChanges(value) {
190 if (mode == null || (index != null && index % 2 == mode)) { 192 if (value is CollectionChangeRecord) {
191 element.classes..removeAll(previousSet)..addAll(currentSet); 193 _computeCollectionChanges(value, _first);
194 } else if (value is MapChangeRecord) {
195 _computeMapChanges(value, _first);
196 } else {
197 if (value is String) {
198 _currentSet..clear()..addAll(value.split(' '));
199 } else if (value == null) {
200 _currentSet.clear();
201 } else {
202 throw 'ng-class expects expression value to be List, Map or String, '
203 'got $value';
204 }
192 } 205 }
193 206
194 previousSet = currentSet; 207 _first = false;
195 } 208 }
196 209
197 static List<String> _flatten(classes) { 210 // todo(vicb) refactor once GH-774 gets fixed
198 if (classes == null) return []; 211 void _computeCollectionChanges(CollectionChangeRecord changes, bool first) {
199 if (classes is CollectionChangeRecord) { 212 if (first) {
200 classes = (classes as CollectionChangeRecord).iterable.toList(); 213 changes.iterable.forEach((cls) {
214 _currentSet.add(cls);
215 });
216 } else {
217 changes.forEachAddition((CollectionChangeItem a) {
218 _currentSet.add(a.item);
219 });
220 changes.forEachRemoval((CollectionChangeItem r) {
221 _currentSet.remove(r.item);
222 });
201 } 223 }
202 if (classes is List) { 224 }
203 return classes.where((String e) => e != null && e.isNotEmpty) 225
204 .toList(growable: false); 226 // todo(vicb) refactor once GH-774 gets fixed
227 _computeMapChanges(MapChangeRecord changes, first) {
228 if (first) {
229 changes.map.forEach((cls, active) {
230 if (toBool(active)) _currentSet.add(cls);
231 });
232 } else {
233 changes.forEachChange((MapKeyValue kv) {
234 var cls = kv.key;
235 var active = toBool(kv.currentValue);
236 var wasActive = toBool(kv.previousValue);
237 if (active != wasActive) {
238 if (active) {
239 _currentSet.add(cls);
240 } else {
241 _currentSet.remove(cls);
242 }
243 }
244 });
245 changes.forEachAddition((MapKeyValue kv) {
246 if (toBool(kv.currentValue)) _currentSet.add(kv.key);
247 });
248 changes.forEachRemoval((MapKeyValue kv) {
249 if (toBool(kv.previousValue)) _currentSet.remove(kv.key);
250 });
205 } 251 }
206 if (classes is MapChangeRecord) { 252 }
207 classes = (classes as MapChangeRecord).map; 253
254 _applyChanges(index) {
255 if (_mode == null || (index != null && index % 2 == _mode)) {
256 _previousSet
257 .where((cls) => cls != null)
258 .forEach((cls) => _ngElement.removeClass(cls));
259 _currentSet
260 .where((cls) => cls != null)
261 .forEach((cls) => _ngElement.addClass(cls));
208 } 262 }
209 if (classes is Map) { 263
210 return classes.keys.where((key) => toBool(classes[key])).toList(); 264 _previousSet = _currentSet.toSet();
211 }
212 if (classes is String) return classes.split(' ');
213 throw 'ng-class expects expression value to be List, Map or String, got $cla sses';
214 } 265 }
215 } 266 }
OLDNEW
« no previous file with comments | « third_party/pkg/angular/lib/directive/ng_bind_template.dart ('k') | third_party/pkg/angular/lib/directive/ng_cloak.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698