OLD | NEW |
| (Empty) |
1 part of angular.core; | |
2 | |
3 abstract class NgAnnotation { | |
4 /** | |
5 * CSS selector which will trigger this component/directive. | |
6 * CSS Selectors are limited to a single element and can contain: | |
7 * | |
8 * * `element-name` limit to a given element name. | |
9 * * `.class` limit to an element with a given class. | |
10 * * `[attribute]` limit to an element with a given attribute name. | |
11 * * `[attribute=value]` limit to an element with a given attribute and value. | |
12 * | |
13 * | |
14 * Example: `input[type=checkbox][ng-model]` | |
15 */ | |
16 final String selector; | |
17 | |
18 /** | |
19 * Specifies the compiler action to be taken on the child nodes of the | |
20 * element which this currently being compiled. The values are: | |
21 * | |
22 * * [COMPILE_CHILDREN] (*default*) | |
23 * * [TRANSCLUDE_CHILDREN] | |
24 * * [IGNORE_CHILDREN] | |
25 */ | |
26 final String children; | |
27 | |
28 /** | |
29 * Compile the child nodes of the element. This is the default. | |
30 */ | |
31 static const String COMPILE_CHILDREN = 'compile'; | |
32 /** | |
33 * Compile the child nodes for transclusion and makes available | |
34 * [BoundBlockFactory], [BlockFactory] and [BlockHole] for injection. | |
35 */ | |
36 static const String TRANSCLUDE_CHILDREN = 'transclude'; | |
37 /** | |
38 * Do not compile/visit the child nodes. Angular markup on descendant nodes | |
39 * will not be processed. | |
40 */ | |
41 static const String IGNORE_CHILDREN = 'ignore'; | |
42 | |
43 /** | |
44 * A directive/component controller class can be injected into other | |
45 * directives/components. This attribute controls whether the | |
46 * controller is available to others. | |
47 * | |
48 * * `local` [NgDirective.LOCAL_VISIBILITY] - the controller can be injected | |
49 * into other directives / components on the same DOM element. | |
50 * * `children` [NgDirective.CHILDREN_VISIBILITY] - the controller can be | |
51 * injected into other directives / components on the same or child DOM | |
52 * elements. | |
53 * * `direct_children` [NgDirective.DIRECT_CHILDREN_VISIBILITY] - the | |
54 * controller can be injected into other directives / components on the | |
55 * direct children of the current DOM element. | |
56 */ | |
57 final String visibility; | |
58 final List<Type> publishTypes; | |
59 | |
60 /** | |
61 * Use map to define the mapping of DOM attributes to fields. | |
62 * The map's key is the DOM attribute name (DOM attribute is in dash-case). | |
63 * The Map's value consists of a mode prefix followed by an expression. | |
64 * The destination expression will be evaluated against the instance of the | |
65 * directive / component class. | |
66 * | |
67 * * `@` - Map the DOM attribute string. The attribute string will be taken | |
68 * literally or interpolated if it contains binding {{}} systax and assigned | |
69 * to the expression. (cost: 0 watches) | |
70 * | |
71 * * `=>` - Treat the DOM attribute value as an expression. Set up a watch, | |
72 * which will read the expression in the attribute and assign the value | |
73 * to destination expression. (cost: 1 watch) | |
74 * | |
75 * * `<=>` - Treat the DOM attribute value as an expression. Set up a watch | |
76 * on both outside as well as component scope to keep the src and | |
77 * destination in sync. (cost: 2 watches) | |
78 * | |
79 * * `=>!` - Treat the DOM attribute value as an expression. Set up a one time | |
80 * watch on expression. Once the expression turns truthy it will no longer | |
81 * update. (cost: 1 watches until not null, then 0 watches) | |
82 * | |
83 * * `&` - Treat the DOM attribute value as an expression. Assign a closure | |
84 * function into the field. This allows the component to control | |
85 * the invocation of the closure. This is useful for passing | |
86 * expressions into controllers which act like callbacks. (cost: 0 watches) | |
87 * | |
88 * Example: | |
89 * | |
90 * <my-component title="Hello {{username}}" | |
91 * selection="selectedItem" | |
92 * on-selection-change="doSomething()"> | |
93 * | |
94 * @NgComponent( | |
95 * selector: 'my-component' | |
96 * map: const { | |
97 * 'title': '@title', | |
98 * 'selection': '<=>currentItem', | |
99 * 'on-selection-change': '&onChange' | |
100 * } | |
101 * ) | |
102 * class MyComponent { | |
103 * String title; | |
104 * var currentItem; | |
105 * ParsedFn onChange; | |
106 * } | |
107 * | |
108 * The above example shows how all three mapping modes are used. | |
109 * | |
110 * * `@title` maps the title DOM attribute to the controller `title` | |
111 * field. Notice that this maps the content of the attribute, which | |
112 * means that it can be used with `{{}}` interpolation. | |
113 * | |
114 * * `<=>currentItem` maps the expression (in this case the `selectedItem` | |
115 * in the current scope into the `currentItem` in the controller. Notice | |
116 * that mapping is bi-directional. A change either in field or on | |
117 * parent scope will result in change to the other. | |
118 * | |
119 * * `&onChange` maps the expression into the controller `onChange` | |
120 * field. The result of mapping is a callable function which can be | |
121 * invoked at any time by the controller. The invocation of the | |
122 * callable function will result in the expression `doSomething()` to | |
123 * be executed in the parent context. | |
124 */ | |
125 final Map<String, String> map; | |
126 | |
127 /** | |
128 * Use the list to specify expression containing attributes which are not | |
129 * included under [map] with '=' or '@' specification. | |
130 */ | |
131 final List<String> exportExpressionAttrs; | |
132 | |
133 /** | |
134 * Use the list to specify a expressions which are evaluated dynamically | |
135 * (ex. via [Scope.eval]) and are otherwise not statically discoverable. | |
136 */ | |
137 final List<String> exportExpressions; | |
138 | |
139 const NgAnnotation({ | |
140 this.selector, | |
141 this.children: NgAnnotation.COMPILE_CHILDREN, | |
142 this.visibility: NgDirective.LOCAL_VISIBILITY, | |
143 this.publishTypes: const [], | |
144 this.map: const {}, | |
145 this.exportExpressions: const [], | |
146 this.exportExpressionAttrs: const [] | |
147 }); | |
148 | |
149 toString() => selector; | |
150 get hashCode => selector.hashCode; | |
151 operator==(other) => | |
152 other is NgAnnotation && this.selector == other.selector; | |
153 | |
154 NgAnnotation cloneWithNewMap(newMap); | |
155 } | |
156 | |
157 | |
158 /** | |
159 * Meta-data marker placed on a class which should act as a controller for the | |
160 * component. Angular components are a light-weight version of web-components. | |
161 * Angular components use shadow-DOM for rendering their templates. | |
162 * | |
163 * Angular components are instantiated using dependency injection, and can | |
164 * ask for any injectable object in their constructor. Components | |
165 * can also ask for other components or directives declared on the DOM element. | |
166 * | |
167 * Components can implement [NgAttachAware], [NgDetachAware], | |
168 * [NgShadowRootAware] and declare these optional methods: | |
169 * | |
170 * * `attach()` - Called on first [Scope.apply()]. | |
171 * * `detach()` - Called on when owning scope is destroyed. | |
172 * * `onShadowRoot(ShadowRoot shadowRoot)` - Called when [ShadowRoot] is loaded. | |
173 */ | |
174 class NgComponent extends NgAnnotation { | |
175 /** | |
176 * Inlined HTML template for the component. | |
177 */ | |
178 final String template; | |
179 | |
180 /** | |
181 * A URL to HTML template. This will be loaded asynchronously and | |
182 * cached for future component instances. | |
183 */ | |
184 final String templateUrl; | |
185 | |
186 /** | |
187 * A list of CSS URLs to load into the shadow DOM. | |
188 */ | |
189 final _cssUrls; | |
190 | |
191 /** | |
192 * Set the shadow root applyAuthorStyles property. See shadow-DOM | |
193 * documentation for further details. | |
194 */ | |
195 final bool applyAuthorStyles; | |
196 | |
197 /** | |
198 * Set the shadow root resetStyleInheritance property. See shadow-DOM | |
199 * documentation for further details. | |
200 */ | |
201 final bool resetStyleInheritance; | |
202 | |
203 /** | |
204 * An expression under which the component's controller instance will be | |
205 * published into. This allows the expressions in the template to be referring | |
206 * to controller instance and its properties. | |
207 */ | |
208 final String publishAs; | |
209 | |
210 const NgComponent({ | |
211 this.template, | |
212 this.templateUrl, | |
213 cssUrl, | |
214 this.applyAuthorStyles, | |
215 this.resetStyleInheritance, | |
216 this.publishAs, | |
217 map, | |
218 selector, | |
219 visibility, | |
220 publishTypes : const <Type>[], | |
221 exportExpressions, | |
222 exportExpressionAttrs}) | |
223 : _cssUrls = cssUrl, | |
224 super(selector: selector, | |
225 children: NgAnnotation.COMPILE_CHILDREN, | |
226 visibility: visibility, | |
227 publishTypes: publishTypes, | |
228 map: map, | |
229 exportExpressions: exportExpressions, | |
230 exportExpressionAttrs: exportExpressionAttrs); | |
231 | |
232 List<String> get cssUrls => _cssUrls == null ? | |
233 const [] : | |
234 _cssUrls is List ? _cssUrls : [_cssUrls]; | |
235 | |
236 NgAnnotation cloneWithNewMap(newMap) => | |
237 new NgComponent( | |
238 template: template, | |
239 templateUrl: templateUrl, | |
240 cssUrl: cssUrls, | |
241 applyAuthorStyles: applyAuthorStyles, | |
242 resetStyleInheritance: resetStyleInheritance, | |
243 publishAs: publishAs, | |
244 map: newMap, | |
245 selector: selector, | |
246 visibility: visibility, | |
247 publishTypes: publishTypes, | |
248 exportExpressions: exportExpressions, | |
249 exportExpressionAttrs: exportExpressionAttrs); | |
250 } | |
251 | |
252 RegExp _ATTR_NAME = new RegExp(r'\[([^\]]+)\]$'); | |
253 | |
254 /** | |
255 * Meta-data marker placed on a class which should act as a directive. | |
256 * | |
257 * Angular directives are instantiated using dependency injection, and can | |
258 * ask for any injectable object in their constructor. Directives | |
259 * can also ask for other components or directives declared on the DOM element. | |
260 * | |
261 * Directives can implement [NgAttachAware], [NgDetachAware] and | |
262 * declare these optional methods: | |
263 * | |
264 * * `attach()` - Called on first [Scope.apply()]. | |
265 * * `detach()` - Called on when owning scope is destroyed. | |
266 */ | |
267 class NgDirective extends NgAnnotation { | |
268 static const String LOCAL_VISIBILITY = 'local'; | |
269 static const String CHILDREN_VISIBILITY = 'children'; | |
270 static const String DIRECT_CHILDREN_VISIBILITY = 'direct_children'; | |
271 | |
272 const NgDirective({children: NgAnnotation.COMPILE_CHILDREN, | |
273 map, | |
274 selector, | |
275 visibility, | |
276 publishTypes : const <Type>[], | |
277 exportExpressions, | |
278 exportExpressionAttrs}) : super(selector: selector, children
: children, visibility: visibility, | |
279 publishTypes: publishTypes, map: map, | |
280 exportExpressions: exportExpressions, | |
281 exportExpressionAttrs: exportExpressionAttrs); | |
282 | |
283 NgAnnotation cloneWithNewMap(newMap) => | |
284 new NgDirective( | |
285 children: children, | |
286 map: newMap, | |
287 selector: selector, | |
288 visibility: visibility, | |
289 publishTypes: publishTypes, | |
290 exportExpressions: exportExpressions, | |
291 exportExpressionAttrs: exportExpressionAttrs); | |
292 } | |
293 | |
294 /** | |
295 * Meta-data marker placed on a class which should act as a controller for your
application. | |
296 * | |
297 * Controllers are essentially [NgDirective]s with few key differences: | |
298 * | |
299 * * Controllers create a new scope at the element. | |
300 * * Controllers should not do any DOM manipulation. | |
301 * * Controllers are meant for application-logic | |
302 * (rather then DOM monipulation logic which directives are meant for.) | |
303 * | |
304 * Controllers can implement [NgAttachAware], [NgDetachAware] and | |
305 * declare these optional methods: | |
306 * | |
307 * * `attach()` - Called on first [Scope.apply()]. | |
308 * * `detach()` - Called on when owning scope is destroyed. | |
309 */ | |
310 class NgController extends NgDirective { | |
311 static const String LOCAL_VISIBILITY = 'local'; | |
312 static const String CHILDREN_VISIBILITY = 'children'; | |
313 static const String DIRECT_CHILDREN_VISIBILITY = 'direct_children'; | |
314 | |
315 /** | |
316 * An expression under which the controller instance will be published into. | |
317 * This allows the expressions in the template to be referring to controller | |
318 * instance and its properties. | |
319 */ | |
320 final String publishAs; | |
321 | |
322 const NgController({ | |
323 children: NgAnnotation.COMPILE_CHILDREN, | |
324 this.publishAs, | |
325 map, | |
326 selector, | |
327 visibility, | |
328 publishTypes : const <Type>[], | |
329 exportExpressions, | |
330 exportExpressionAttrs | |
331 }) : super(selector: selector, children: children, visibilit
y: visibility, | |
332 publishTypes: publishTypes, map: map, | |
333 exportExpressions: exportExpressions, | |
334 exportExpressionAttrs: exportExpressionAttrs); | |
335 | |
336 NgAnnotation cloneWithNewMap(newMap) => | |
337 new NgController( | |
338 children: children, | |
339 publishAs: publishAs, | |
340 map: newMap, | |
341 selector: selector, | |
342 visibility: visibility, | |
343 publishTypes: publishTypes, | |
344 exportExpressions: exportExpressions, | |
345 exportExpressionAttrs: exportExpressionAttrs); | |
346 } | |
347 | |
348 abstract class AttrFieldAnnotation { | |
349 final String attrName; | |
350 const AttrFieldAnnotation(this.attrName); | |
351 String get mappingSpec; | |
352 } | |
353 | |
354 /** | |
355 * When applied as an annotation on a directive field specifies that | |
356 * the field is to be mapped to DOM attribute with the provided [attrName]. | |
357 * The value of the attribute to be treated as a string, equivalent | |
358 * to `@` specification. | |
359 */ | |
360 class NgAttr extends AttrFieldAnnotation { | |
361 final mappingSpec = '@'; | |
362 const NgAttr(String attrName) : super(attrName); | |
363 } | |
364 | |
365 /** | |
366 * When applied as an annotation on a directive field specifies that | |
367 * the field is to be mapped to DOM attribute with the provided [attrName]. | |
368 * The value of the attribute to be treated as a one-way expession, equivalent | |
369 * to `=>` specification. | |
370 */ | |
371 class NgOneWay extends AttrFieldAnnotation { | |
372 final mappingSpec = '=>'; | |
373 const NgOneWay(String attrName) : super(attrName); | |
374 } | |
375 | |
376 /** | |
377 * When applied as an annotation on a directive field specifies that | |
378 * the field is to be mapped to DOM attribute with the provided [attrName]. | |
379 * The value of the attribute to be treated as a one time one-way expession, | |
380 * equivalent to `=>!` specification. | |
381 */ | |
382 class NgOneWayOneTime extends AttrFieldAnnotation { | |
383 final mappingSpec = '=>!'; | |
384 const NgOneWayOneTime(String attrName) : super(attrName); | |
385 } | |
386 | |
387 /** | |
388 * When applied as an annotation on a directive field specifies that | |
389 * the field is to be mapped to DOM attribute with the provided [attrName]. | |
390 * The value of the attribute to be treated as a two-way expession, | |
391 * equivalent to `<=>` specification. | |
392 */ | |
393 class NgTwoWay extends AttrFieldAnnotation { | |
394 final mappingSpec = '<=>'; | |
395 const NgTwoWay(String attrName) : super(attrName); | |
396 } | |
397 | |
398 /** | |
399 * When applied as an annotation on a directive field specifies that | |
400 * the field is to be mapped to DOM attribute with the provided [attrName]. | |
401 * The value of the attribute to be treated as a callback expession, | |
402 * equivalent to `&` specification. | |
403 */ | |
404 class NgCallback extends AttrFieldAnnotation { | |
405 final mappingSpec = '&'; | |
406 const NgCallback(String attrName) : super(attrName); | |
407 } | |
408 | |
409 /** | |
410 * Implementing directives or components [attach] method will be called when | |
411 * the next scope digest occurs after component instantiation. It is guaranteed | |
412 * that when [attach] is invoked, that all attribute mappings have already | |
413 * been processed. | |
414 */ | |
415 abstract class NgAttachAware { | |
416 void attach(); | |
417 } | |
418 | |
419 /** | |
420 * Implementing directives or components [detach] method will be called when | |
421 * the associated scope is destroyed. | |
422 */ | |
423 abstract class NgDetachAware { | |
424 void detach(); | |
425 } | |
426 | |
OLD | NEW |