From b4c92ecedf14a354fbfecc1a175e85618a5b7e44 Mon Sep 17 00:00:00 2001 From: Misko Hevery Date: Mon, 7 Apr 2014 22:43:04 -0700 Subject: [PATCH] doc(annotation): added documentation to annotations library. --- lib/core/annotation.dart | 549 +---------------- lib/core/annotation_src.dart | 567 ++++++++++++++++++ lib/core/registry_dynamic.dart | 22 +- lib/core_dom/common.dart | 2 +- lib/core_dom/directive_map.dart | 2 +- lib/core_dom/element_binder.dart | 4 +- lib/core_dom/element_binder_builder.dart | 8 +- lib/core_dom/module_internal.dart | 2 +- lib/core_dom/selector.dart | 6 +- lib/directive/ng_if.dart | 4 +- lib/directive/ng_non_bindable.dart | 2 +- lib/directive/ng_repeat.dart | 2 +- lib/directive/ng_switch.dart | 4 +- lib/directive/ng_template.dart | 2 +- lib/tools/transformer/metadata_extractor.dart | 8 +- test/angular_spec.dart | 12 +- test/core_dom/compiler_spec.dart | 4 +- .../core_dom/element_binder_builder_spec.dart | 10 +- test/core_dom/selector_spec.dart | 4 +- test/core_dom/view_spec.dart | 4 +- test/directive/ng_if_spec.dart | 2 +- test/directive/ng_include_spec.dart | 2 +- test/io/test_files/main.dart | 2 +- .../transformer/metadata_generator_spec.dart | 6 +- 24 files changed, 641 insertions(+), 589 deletions(-) create mode 100644 lib/core/annotation_src.dart diff --git a/lib/core/annotation.dart b/lib/core/annotation.dart index f3bc6b3b8..edd7fe4c9 100644 --- a/lib/core/annotation.dart +++ b/lib/core/annotation.dart @@ -1,539 +1,24 @@ -library angular.core.annotation; - -import "package:di/di.dart" show Visibility, Injector; - -/** - * An annotation when applied to a class indicates that the class (service) will - * be instantiated by di injector. - */ -class NgInjectableService { - const NgInjectableService(); -} - -abstract class NgAnnotation { - /** - * CSS selector which will trigger this component/directive. - * CSS Selectors are limited to a single element and can contain: - * - * * `element-name` limit to a given element name. - * * `.class` limit to an element with a given class. - * * `[attribute]` limit to an element with a given attribute name. - * * `[attribute=value]` limit to an element with a given attribute and value. - * * `:contains(/abc/)` limit to an element which contains the given text. - * - * - * Example: `input[type=checkbox][ng-model]` - */ - final String selector; - - /** - * Specifies the compiler action to be taken on the child nodes of the - * element which this currently being compiled. The values are: - * - * * [COMPILE_CHILDREN] (*default*) - * * [TRANSCLUDE_CHILDREN] - * * [IGNORE_CHILDREN] - */ - final String children; - - /** - * Compile the child nodes of the element. This is the default. - */ - static const String COMPILE_CHILDREN = 'compile'; - /** - * Compile the child nodes for transclusion and makes available - * [BoundViewFactory], [ViewFactory] and [ViewPort] for injection. - */ - static const String TRANSCLUDE_CHILDREN = 'transclude'; - /** - * Do not compile/visit the child nodes. Angular markup on descendant nodes - * will not be processed. - */ - static const String IGNORE_CHILDREN = 'ignore'; - - /** - * A directive/component controller class can be injected into other - * directives/components. This attribute controls whether the - * controller is available to others. - * - * * `local` [NgDirective.LOCAL_VISIBILITY] - the controller can be injected - * into other directives / components on the same DOM element. - * * `children` [NgDirective.CHILDREN_VISIBILITY] - the controller can be - * injected into other directives / components on the same or child DOM - * elements. - * * `direct_children` [NgDirective.DIRECT_CHILDREN_VISIBILITY] - the - * controller can be injected into other directives / components on the - * direct children of the current DOM element. - */ - final Visibility visibility; - - /** - * A directive/component class can publish types by using a factory - * function to generate a module. The module is then installed into - * the injector at that element. Any types declared in the module then - * become available for injection. - * - * Example: - * - * @NgDirective( - * selector: '[foo]', - * module: Foo.moduleFactory) - * class Foo { - * static moduleFactory() => new Module() - * ..type(SomeTypeA, visibility: NgDirective.LOCAL_VISIBILITY); - * } - * - * When specifying types, factories or values in the module, notice that - * `Visibility` maps to: - * * [NgDirective.LOCAL_VISIBILITY] - * * [NgDirective.CHILDREN_VISIBILITY] - * * [NgDirective.DIRECT_CHILDREN_VISIBILITY] - */ - final Function module; - - /** - * Use map to define the mapping of DOM attributes to fields. - * The map's key is the DOM attribute name (DOM attribute is in dash-case). - * The Map's value consists of a mode prefix followed by an expression. - * The destination expression will be evaluated against the instance of the - * directive / component class. - * - * * `@` - Map the DOM attribute string. The attribute string will be taken - * literally or interpolated if it contains binding {{}} systax and assigned - * to the expression. (cost: 0 watches) - * - * * `=>` - Treat the DOM attribute value as an expression. Set up a watch, - * which will read the expression in the attribute and assign the value - * to destination expression. (cost: 1 watch) - * - * * `<=>` - Treat the DOM attribute value as an expression. Set up a watch - * on both outside as well as component scope to keep the src and - * destination in sync. (cost: 2 watches) - * - * * `=>!` - Treat the DOM attribute value as an expression. Set up a one time - * watch on expression. Once the expression turns truthy it will no longer - * update. (cost: 1 watches until not null, then 0 watches) - * - * * `&` - Treat the DOM attribute value as an expression. Assign a closure - * function into the field. This allows the component to control - * the invocation of the closure. This is useful for passing - * expressions into controllers which act like callbacks. (cost: 0 watches) - * - * Example: - * - * - * - * @NgComponent( - * selector: 'my-component' - * map: const { - * 'title': '@title', - * 'selection': '<=>currentItem', - * 'on-selection-change': '&onChange'}) - * class MyComponent { - * String title; - * var currentItem; - * ParsedFn onChange; - * } - * - * The above example shows how all three mapping modes are used. - * - * * `@title` maps the title DOM attribute to the controller `title` - * field. Notice that this maps the content of the attribute, which - * means that it can be used with `{{}}` interpolation. - * - * * `<=>currentItem` maps the expression (in this case the `selectedItem` - * in the current scope into the `currentItem` in the controller. Notice - * that mapping is bi-directional. A change either in field or on - * parent scope will result in change to the other. - * - * * `&onChange` maps the expression into the controller `onChange` - * field. The result of mapping is a callable function which can be - * invoked at any time by the controller. The invocation of the - * callable function will result in the expression `doSomething()` to - * be executed in the parent context. - */ - final Map map; - - /** - * Use the list to specify expressions containing attributes which are not - * included under [map] with '=' or '@' specification. - */ - final List exportExpressionAttrs; - - /** - * Use the list to specify expressions which are evaluated dynamically - * (ex. via [Scope.eval]) and are otherwise not statically discoverable. - */ - final List exportExpressions; - - const NgAnnotation({ - this.selector, - this.children: NgAnnotation.COMPILE_CHILDREN, - this.visibility: NgDirective.LOCAL_VISIBILITY, - this.module, - this.map: const {}, - this.exportExpressions: const [], - this.exportExpressionAttrs: const [] - }); - - toString() => selector; - get hashCode => selector.hashCode; - operator==(other) => - other is NgAnnotation && selector == other.selector; - - NgAnnotation cloneWithNewMap(newMap); -} - - -bool _applyAuthorStylesDeprecationWarningPrinted = false; -bool _resetStyleInheritanceDeprecationWarningPrinted = false; - -/** - * Meta-data marker placed on a class which should act as a controller for the - * component. Angular components are a light-weight version of web-components. - * Angular components use shadow-DOM for rendering their templates. - * - * Angular components are instantiated using dependency injection, and can - * ask for any injectable object in their constructor. Components - * can also ask for other components or directives declared on the DOM element. - * - * Components can implement [NgAttachAware], [NgDetachAware], - * [NgShadowRootAware] and declare these optional methods: - * - * * `attach()` - Called on first [Scope.apply()]. - * * `detach()` - Called on when owning scope is destroyed. - * * `onShadowRoot(ShadowRoot shadowRoot)` - Called when [ShadowRoot] is loaded. - */ -class NgComponent extends NgAnnotation { - /** - * Inlined HTML template for the component. - */ - final String template; - - /** - * A URL to HTML template. This will be loaded asynchronously and - * cached for future component instances. - */ - final String templateUrl; - - /** - * A list of CSS URLs to load into the shadow DOM. - */ - final _cssUrls; - - /** - * Set the shadow root applyAuthorStyles property. See shadow-DOM - * documentation for further details. - * - * This feature will be removed in Chrome 35. - */ - @deprecated - bool get applyAuthorStyles { - if (!_applyAuthorStylesDeprecationWarningPrinted && _applyAuthorStyles == true) { - print("WARNING applyAuthorStyles is deprecated in component $selector"); - _applyAuthorStylesDeprecationWarningPrinted = true; - } - return _applyAuthorStyles; - } - final bool _applyAuthorStyles; - - /** - * Set the shadow root resetStyleInheritance property. See shadow-DOM - * documentation for further details. - * - * This feature will be removed in Chrome 35. - */ - @deprecated - bool get resetStyleInheritance { - if (!_resetStyleInheritanceDeprecationWarningPrinted && _resetStyleInheritance == true) { - print("WARNING resetStyleInheritance is deprecated in component $selector"); - _resetStyleInheritanceDeprecationWarningPrinted = true; - } - return _resetStyleInheritance; - } - final bool _resetStyleInheritance; - - /** - * An expression under which the component's controller instance will be - * published into. This allows the expressions in the template to be referring - * to controller instance and its properties. - */ - final String publishAs; - - const NgComponent({ - this.template, - this.templateUrl, - cssUrl, - applyAuthorStyles, - resetStyleInheritance, - this.publishAs, - module, - map, - selector, - visibility, - exportExpressions, - exportExpressionAttrs}) - : _cssUrls = cssUrl, - _applyAuthorStyles = applyAuthorStyles, - _resetStyleInheritance = resetStyleInheritance, - super(selector: selector, - children: NgAnnotation.COMPILE_CHILDREN, - visibility: visibility, - map: map, - module: module, - exportExpressions: exportExpressions, - exportExpressionAttrs: exportExpressionAttrs); - - List get cssUrls => _cssUrls == null ? - const [] : - _cssUrls is List ? _cssUrls : [_cssUrls]; - - NgAnnotation cloneWithNewMap(newMap) => - new NgComponent( - template: template, - templateUrl: templateUrl, - cssUrl: cssUrls, - applyAuthorStyles: applyAuthorStyles, - resetStyleInheritance: resetStyleInheritance, - publishAs: publishAs, - map: newMap, - module: module, - selector: selector, - visibility: visibility, - exportExpressions: exportExpressions, - exportExpressionAttrs: exportExpressionAttrs); -} - -RegExp _ATTR_NAME = new RegExp(r'\[([^\]]+)\]$'); - -const String SHADOW_DOM_INJECTOR_NAME = 'SHADOW_INJECTOR'; - -_skipShadow(Injector injector) - => injector.name == SHADOW_DOM_INJECTOR_NAME ? injector.parent : injector; - -_localVisibility (Injector requesting, Injector defining) - => identical(_skipShadow(requesting), defining); - -_directChildrenVisibility(Injector requesting, Injector defining) { - requesting = _skipShadow(requesting); - return identical(requesting.parent, defining) || _localVisibility(requesting, defining); -} - -/** - * Meta-data marker placed on a class which should act as a directive. - * - * Angular directives are instantiated using dependency injection, and can - * ask for any injectable object in their constructor. Directives - * can also ask for other components or directives declared on the DOM element. - * - * Directives can implement [NgAttachAware], [NgDetachAware] and - * declare these optional methods: - * - * * `attach()` - Called on first [Scope.apply()]. - * * `detach()` - Called on when owning scope is destroyed. - */ -class NgDirective extends NgAnnotation { - static const Visibility LOCAL_VISIBILITY = _localVisibility; - static const Visibility CHILDREN_VISIBILITY = null; - static const Visibility DIRECT_CHILDREN_VISIBILITY = _directChildrenVisibility; - - const NgDirective({children: NgAnnotation.COMPILE_CHILDREN, - map, - selector, - module, - visibility, - exportExpressions, - exportExpressionAttrs}) - : super(selector: selector, - children: children, - visibility: visibility, - map: map, - module: module, - exportExpressions: exportExpressions, - exportExpressionAttrs: exportExpressionAttrs); - - NgAnnotation cloneWithNewMap(newMap) => - new NgDirective( - children: children, - map: newMap, - module: module, - selector: selector, - visibility: visibility, - exportExpressions: exportExpressions, - exportExpressionAttrs: exportExpressionAttrs); -} - -/** - * Meta-data marker placed on a class which should act as a controller for your - * application. - * - * Controllers are essentially [NgDirective]s with few key differences: - * - * * Controllers create a new scope at the element. - * * Controllers should not do any DOM manipulation. - * * Controllers are meant for application-logic - * (rather then DOM monipulation logic which directives are meant for.) - * - * Controllers can implement [NgAttachAware], [NgDetachAware] and - * declare these optional methods: - * - * * `attach()` - Called on first [Scope.apply()]. - * * `detach()` - Called on when owning scope is destroyed. - */ -class NgController extends NgDirective { - static const String LOCAL_VISIBILITY = 'local'; - static const String CHILDREN_VISIBILITY = 'children'; - static const String DIRECT_CHILDREN_VISIBILITY = 'direct_children'; - - /** - * An expression under which the controller instance will be published into. - * This allows the expressions in the template to be referring to controller - * instance and its properties. - */ - final String publishAs; - - const NgController({ - children: NgAnnotation.COMPILE_CHILDREN, - this.publishAs, - map, - module, - selector, - visibility, - exportExpressions, - exportExpressionAttrs - }) - : super(selector: selector, - children: children, - visibility: visibility, - map: map, - module: module, - exportExpressions: exportExpressions, - exportExpressionAttrs: exportExpressionAttrs); - - NgAnnotation cloneWithNewMap(newMap) => - new NgController( - children: children, - publishAs: publishAs, - module: module, - map: newMap, - selector: selector, - visibility: visibility, - exportExpressions: exportExpressions, - exportExpressionAttrs: exportExpressionAttrs); -} - -abstract class AttrFieldAnnotation { - final String attrName; - const AttrFieldAnnotation(this.attrName); - String get mappingSpec; -} - -/** - * When applied as an annotation on a directive field specifies that - * the field is to be mapped to DOM attribute with the provided [attrName]. - * The value of the attribute to be treated as a string, equivalent - * to `@` specification. - */ -class NgAttr extends AttrFieldAnnotation { - final mappingSpec = '@'; - const NgAttr(String attrName) : super(attrName); -} - -/** - * When applied as an annotation on a directive field specifies that - * the field is to be mapped to DOM attribute with the provided [attrName]. - * The value of the attribute to be treated as a one-way expression, equivalent - * to `=>` specification. - */ -class NgOneWay extends AttrFieldAnnotation { - final mappingSpec = '=>'; - const NgOneWay(String attrName) : super(attrName); -} - -/** - * When applied as an annotation on a directive field specifies that - * the field is to be mapped to DOM attribute with the provided [attrName]. - * The value of the attribute to be treated as a one time one-way expression, - * equivalent to `=>!` specification. - */ -class NgOneWayOneTime extends AttrFieldAnnotation { - final mappingSpec = '=>!'; - const NgOneWayOneTime(String attrName) : super(attrName); -} - /** - * When applied as an annotation on a directive field specifies that - * the field is to be mapped to DOM attribute with the provided [attrName]. - * The value of the attribute to be treated as a two-way expression, - * equivalent to `<=>` specification. + * Angular class annotations for Directives, Filters, and Services. */ -class NgTwoWay extends AttrFieldAnnotation { - final mappingSpec = '<=>'; - const NgTwoWay(String attrName) : super(attrName); -} - -/** - * When applied as an annotation on a directive field specifies that - * the field is to be mapped to DOM attribute with the provided [attrName]. - * The value of the attribute to be treated as a callback expression, - * equivalent to `&` specification. - */ -class NgCallback extends AttrFieldAnnotation { - final mappingSpec = '&'; - const NgCallback(String attrName) : super(attrName); -} - -/** - * Implementing directives or components [attach] method will be called when - * the next scope digest occurs after component instantiation. It is guaranteed - * that when [attach] is invoked, that all attribute mappings have already - * been processed. - */ -abstract class NgAttachAware { - void attach(); -} - -/** - * Implementing directives or components [detach] method will be called when - * the associated scope is destroyed. - */ -abstract class NgDetachAware { - void detach(); -} +library angular.core.annotation; +export "package:angular/core/annotation_src.dart" show + NgAttachAware, + NgDetachAware, -/** - * Use @[NgFilter] annotation to register a new filter. A filter is a class - * with a [call] method (a callable function). - * - * Usage: - * - * // Declaration - * @NgFilter(name:'myFilter') - * class MyFilter { - * call(valueToFilter, optArg1, optArg2) { - * return ...; - * } - * } - * - * - * // Registration - * var module = ...; - * module.type(MyFilter); - * - * - * - * {{something | myFilter:arg1:arg2}} - */ -class NgFilter { - final String name; + NgFilter, + NgInjectableService, - const NgFilter({this.name}); + AbstractNgAnnotation, + NgComponent, + NgController, + NgDirective, - int get hashCode => name.hashCode; - bool operator==(other) => name == other.name; + AbstractNgFieldAnnotation, + NgAttr, + NgCallback, + NgOneWay, + NgOneWayOneTime, + NgTwoWay; - toString() => 'NgFilter: $name'; -} diff --git a/lib/core/annotation_src.dart b/lib/core/annotation_src.dart new file mode 100644 index 000000000..93974de73 --- /dev/null +++ b/lib/core/annotation_src.dart @@ -0,0 +1,567 @@ +library angular.core.annotation_src; + +import "package:di/di.dart" show Injector, Visibility; + +RegExp _ATTR_NAME = new RegExp(r'\[([^\]]+)\]$'); + +const String SHADOW_DOM_INJECTOR_NAME = 'SHADOW_INJECTOR'; + +skipShadow(Injector injector) + => injector.name == SHADOW_DOM_INJECTOR_NAME ? injector.parent : injector; + +localVisibility (Injector requesting, Injector defining) + => identical(skipShadow(requesting), defining); + +directChildrenVisibility(Injector requesting, Injector defining) { + requesting = skipShadow(requesting); + return identical(requesting.parent, defining) || localVisibility(requesting, defining); +} + +AbstractNgAnnotation cloneWithNewMap(AbstractNgAnnotation annotation, map) + => annotation._cloneWithNewMap(map); + +String mappingSpec(AbstractNgFieldAnnotation annotation) => annotation._mappingSpec; + + +/** + * An annotation when applied to a class indicates that the class (service) will + * be instantiated by di injector. This annotation is also used to designate which + * classes need to have a static factory generated when using static angular, and + * therefore is required on any injectable class. + */ +class NgInjectableService { + const NgInjectableService(); +} + +/** + * Abstract supper class of [NgController], [NgComponent], and [NgDirective]. + */ +abstract class AbstractNgAnnotation { + /** + * CSS selector which will trigger this component/directive. + * CSS Selectors are limited to a single element and can contain: + * + * * `element-name` limit to a given element name. + * * `.class` limit to an element with a given class. + * * `[attribute]` limit to an element with a given attribute name. + * * `[attribute=value]` limit to an element with a given attribute and value. + * * `:contains(/abc/)` limit to an element which contains the given text. + * + * + * Example: `input[type=checkbox][ng-model]` + */ + final String selector; + + /** + * Specifies the compiler action to be taken on the child nodes of the + * element which this currently being compiled. The values are: + * + * * [COMPILE_CHILDREN] (*default*) + * * [TRANSCLUDE_CHILDREN] + * * [IGNORE_CHILDREN] + */ + @deprecated + final String children; + + /** + * Compile the child nodes of the element. This is the default. + */ + @deprecated + static const String COMPILE_CHILDREN = 'compile'; + /** + * Compile the child nodes for transclusion and makes available + * [BoundViewFactory], [ViewFactory] and [ViewPort] for injection. + */ + @deprecated + static const String TRANSCLUDE_CHILDREN = 'transclude'; + /** + * Do not compile/visit the child nodes. Angular markup on descendant nodes + * will not be processed. + */ + @deprecated + static const String IGNORE_CHILDREN = 'ignore'; + + /** + * A directive/component controller class can be injected into other + * directives/components. This attribute controls whether the + * controller is available to others. + * + * * `local` [NgDirective.LOCAL_VISIBILITY] - the controller can be injected + * into other directives / components on the same DOM element. + * * `children` [NgDirective.CHILDREN_VISIBILITY] - the controller can be + * injected into other directives / components on the same or child DOM + * elements. + * * `direct_children` [NgDirective.DIRECT_CHILDREN_VISIBILITY] - the + * controller can be injected into other directives / components on the + * direct children of the current DOM element. + */ + final Visibility visibility; + + /** + * A directive/component class can publish types by using a factory + * function to generate a module. The module is then installed into + * the injector at that element. Any types declared in the module then + * become available for injection. + * + * Example: + * + * @NgDirective( + * selector: '[foo]', + * module: Foo.moduleFactory) + * class Foo { + * static moduleFactory() => new Module() + * ..type(SomeTypeA, visibility: NgDirective.LOCAL_VISIBILITY); + * } + * + * When specifying types, factories or values in the module, notice that + * `Visibility` maps to: + * * [NgDirective.LOCAL_VISIBILITY] + * * [NgDirective.CHILDREN_VISIBILITY] + * * [NgDirective.DIRECT_CHILDREN_VISIBILITY] + */ + final Function module; + + /** + * Use map to define the mapping of DOM attributes to fields. + * The map's key is the DOM attribute name (DOM attribute is in dash-case). + * The Map's value consists of a mode prefix followed by an expression. + * The destination expression will be evaluated against the instance of the + * directive / component class. + * + * * `@` - Map the DOM attribute string. The attribute string will be taken + * literally or interpolated if it contains binding {{}} systax and assigned + * to the expression. (cost: 0 watches) + * + * * `=>` - Treat the DOM attribute value as an expression. Set up a watch, + * which will read the expression in the attribute and assign the value + * to destination expression. (cost: 1 watch) + * + * * `<=>` - Treat the DOM attribute value as an expression. Set up a watch + * on both outside as well as component scope to keep the src and + * destination in sync. (cost: 2 watches) + * + * * `=>!` - Treat the DOM attribute value as an expression. Set up a one time + * watch on expression. Once the expression turns truthy it will no longer + * update. (cost: 1 watches until not null, then 0 watches) + * + * * `&` - Treat the DOM attribute value as an expression. Assign a closure + * function into the field. This allows the component to control + * the invocation of the closure. This is useful for passing + * expressions into controllers which act like callbacks. (cost: 0 watches) + * + * Example: + * + * + * + * @NgComponent( + * selector: 'my-component' + * map: const { + * 'title': '@title', + * 'selection': '<=>currentItem', + * 'on-selection-change': '&onChange'}) + * class MyComponent { + * String title; + * var currentItem; + * ParsedFn onChange; + * } + * + * The above example shows how all three mapping modes are used. + * + * * `@title` maps the title DOM attribute to the controller `title` + * field. Notice that this maps the content of the attribute, which + * means that it can be used with `{{}}` interpolation. + * + * * `<=>currentItem` maps the expression (in this case the `selectedItem` + * in the current scope into the `currentItem` in the controller. Notice + * that mapping is bi-directional. A change either in field or on + * parent scope will result in change to the other. + * + * * `&onChange` maps the expression into the controller `onChange` + * field. The result of mapping is a callable function which can be + * invoked at any time by the controller. The invocation of the + * callable function will result in the expression `doSomething()` to + * be executed in the parent context. + */ + final Map map; + + /** + * Use the list to specify expressions containing attributes which are not + * included under [map] with '=' or '@' specification. This is used by + * angular transformer during deployment. + */ + final List exportExpressionAttrs; + + /** + * Use the list to specify expressions which are evaluated dynamically + * (ex. via [Scope.eval]) and are otherwise not statically discoverable. + * This is used by angular transformer during deployment. + */ + final List exportExpressions; + + const AbstractNgAnnotation({ + this.selector, + this.children: AbstractNgAnnotation.COMPILE_CHILDREN, + this.visibility: NgDirective.LOCAL_VISIBILITY, + this.module, + this.map: const {}, + this.exportExpressions: const [], + this.exportExpressionAttrs: const [] + }); + + toString() => selector; + get hashCode => selector.hashCode; + operator==(other) => + other is AbstractNgAnnotation && selector == other.selector; + + AbstractNgAnnotation _cloneWithNewMap(newMap); +} + + +bool _applyAuthorStylesDeprecationWarningPrinted = false; +bool _resetStyleInheritanceDeprecationWarningPrinted = false; + +/** + * Meta-data marker placed on a class which should act as a controller for the + * component. Angular components are a light-weight version of web-components. + * Angular components use shadow-DOM for rendering their templates. + * + * Angular components are instantiated using dependency injection, and can + * ask for any injectable object in their constructor. Components + * can also ask for other components or directives declared on the DOM element. + * + * Components can implement [NgAttachAware], [NgDetachAware], + * [NgShadowRootAware] and declare these optional methods: + * + * * `attach()` - Called on first [Scope.apply()]. + * * `detach()` - Called on when owning scope is destroyed. + * * `onShadowRoot(ShadowRoot shadowRoot)` - Called when [ShadowRoot] is loaded. + */ +class NgComponent extends AbstractNgAnnotation { + /** + * Inlined HTML template for the component. + */ + final String template; + + /** + * A URL to HTML template. This will be loaded asynchronously and + * cached for future component instances. + */ + final String templateUrl; + + /** + * A list of CSS URLs to load into the shadow DOM. + */ + final _cssUrls; + + /** + * Set the shadow root applyAuthorStyles property. See shadow-DOM + * documentation for further details. + * + * This feature will be removed in Chrome 35. + */ + @deprecated + bool get applyAuthorStyles { + if (!_applyAuthorStylesDeprecationWarningPrinted && _applyAuthorStyles == true) { + print("WARNING applyAuthorStyles is deprecated in component $selector"); + _applyAuthorStylesDeprecationWarningPrinted = true; + } + return _applyAuthorStyles; + } + final bool _applyAuthorStyles; + + /** + * Set the shadow root resetStyleInheritance property. See shadow-DOM + * documentation for further details. + * + * This feature will be removed in Chrome 35. + */ + @deprecated + bool get resetStyleInheritance { + if (!_resetStyleInheritanceDeprecationWarningPrinted && _resetStyleInheritance == true) { + print("WARNING resetStyleInheritance is deprecated in component $selector"); + _resetStyleInheritanceDeprecationWarningPrinted = true; + } + return _resetStyleInheritance; + } + final bool _resetStyleInheritance; + + /** + * An expression under which the component's controller instance will be + * published into. This allows the expressions in the template to be referring + * to controller instance and its properties. + */ + @deprecated + final String publishAs; + + const NgComponent({ + this.template, + this.templateUrl, + cssUrl, + applyAuthorStyles, + resetStyleInheritance, + this.publishAs, + module, + map, + selector, + visibility, + exportExpressions, + exportExpressionAttrs}) + : _cssUrls = cssUrl, + _applyAuthorStyles = applyAuthorStyles, + _resetStyleInheritance = resetStyleInheritance, + super(selector: selector, + children: AbstractNgAnnotation.COMPILE_CHILDREN, + visibility: visibility, + map: map, + module: module, + exportExpressions: exportExpressions, + exportExpressionAttrs: exportExpressionAttrs); + + List get cssUrls => _cssUrls == null ? + const [] : + _cssUrls is List ? _cssUrls : [_cssUrls]; + + AbstractNgAnnotation _cloneWithNewMap(newMap) => + new NgComponent( + template: template, + templateUrl: templateUrl, + cssUrl: cssUrls, + applyAuthorStyles: applyAuthorStyles, + resetStyleInheritance: resetStyleInheritance, + publishAs: publishAs, + map: newMap, + module: module, + selector: selector, + visibility: visibility, + exportExpressions: exportExpressions, + exportExpressionAttrs: exportExpressionAttrs); +} + +/** + * Meta-data marker placed on a class which should act as a directive. + * + * Angular directives are instantiated using dependency injection, and can + * ask for any injectable object in their constructor. Directives + * can also ask for other components or directives declared on the DOM element. + * + * Directives can implement [NgAttachAware], [NgDetachAware] and + * declare these optional methods: + * + * * `attach()` - Called on first [Scope.apply()]. + * * `detach()` - Called on when owning scope is destroyed. + */ +class NgDirective extends AbstractNgAnnotation { + + /// The directive can only be injected to other directives on the same element. + static const Visibility LOCAL_VISIBILITY = localVisibility; + + /// The directive can be injected to other directives on the same or child elements. + static const Visibility CHILDREN_VISIBILITY = null; + + /** + * The directive on this element can only be injected to other directives + * declared on elements which are direct children of the current element. + */ + static const Visibility DIRECT_CHILDREN_VISIBILITY = directChildrenVisibility; + + const NgDirective({children: AbstractNgAnnotation.COMPILE_CHILDREN, + map, + selector, + module, + visibility, + exportExpressions, + exportExpressionAttrs}) + : super(selector: selector, + children: children, + visibility: visibility, + map: map, + module: module, + exportExpressions: exportExpressions, + exportExpressionAttrs: exportExpressionAttrs); + + AbstractNgAnnotation _cloneWithNewMap(newMap) => + new NgDirective( + children: children, + map: newMap, + module: module, + selector: selector, + visibility: visibility, + exportExpressions: exportExpressions, + exportExpressionAttrs: exportExpressionAttrs); +} + +/** + * Meta-data marker placed on a class which should act as a controller for your + * application. + * + * Controllers are essentially [NgDirective]s with few key differences: + * + * * Controllers create a new scope at the element. + * * Controllers should not do any DOM manipulation. + * * Controllers are meant for application-logic + * (rather then DOM manipulation logic which directives are meant for.) + * + * Controllers can implement [NgAttachAware], [NgDetachAware] and + * declare these optional methods: + * + * * `attach()` - Called on first [Scope.apply()]. + * * `detach()` - Called on when owning scope is destroyed. + */ +class NgController extends NgDirective { + /** + * An expression under which the controller instance will be published into. + * This allows the expressions in the template to be referring to controller + * instance and its properties. + */ + final String publishAs; + + const NgController({ + children: AbstractNgAnnotation.COMPILE_CHILDREN, + this.publishAs, + map, + module, + selector, + visibility, + exportExpressions, + exportExpressionAttrs + }) + : super(selector: selector, + children: children, + visibility: visibility, + map: map, + module: module, + exportExpressions: exportExpressions, + exportExpressionAttrs: exportExpressionAttrs); + + AbstractNgAnnotation _cloneWithNewMap(newMap) => + new NgController( + children: children, + publishAs: publishAs, + module: module, + map: newMap, + selector: selector, + visibility: visibility, + exportExpressions: exportExpressions, + exportExpressionAttrs: exportExpressionAttrs); +} + +/** + * Abstract supper class of [NgAttr], [NgCallback], [NgOneWay], [NgOneWayOneTime], and [NgTwoWay]. + */ +abstract class AbstractNgFieldAnnotation { + /// Element attribute name + final String attrName; + const AbstractNgFieldAnnotation(this.attrName); + /// Element attribute mapping mode: `@`, `=>`, `=>!`, `<=>`, and `&`. + String get _mappingSpec; +} + +/** + * When applied as an annotation on a directive field specifies that + * the field is to be mapped to DOM attribute with the provided [attrName]. + * The value of the attribute to be treated as a string, equivalent + * to `@` specification. + */ +class NgAttr extends AbstractNgFieldAnnotation { + final _mappingSpec = '@'; + const NgAttr(String attrName) : super(attrName); +} + +/** + * When applied as an annotation on a directive field specifies that + * the field is to be mapped to DOM attribute with the provided [attrName]. + * The value of the attribute to be treated as a one-way expression, equivalent + * to `=>` specification. + */ +class NgOneWay extends AbstractNgFieldAnnotation { + final _mappingSpec = '=>'; + const NgOneWay(String attrName) : super(attrName); +} + +/** + * When applied as an annotation on a directive field specifies that + * the field is to be mapped to DOM attribute with the provided [attrName]. + * The value of the attribute to be treated as a one time one-way expression, + * equivalent to `=>!` specification. + */ +class NgOneWayOneTime extends AbstractNgFieldAnnotation { + final _mappingSpec = '=>!'; + const NgOneWayOneTime(String attrName) : super(attrName); +} + +/** + * When applied as an annotation on a directive field specifies that + * the field is to be mapped to DOM attribute with the provided [attrName]. + * The value of the attribute to be treated as a two-way expression, + * equivalent to `<=>` specification. + */ +class NgTwoWay extends AbstractNgFieldAnnotation { + final _mappingSpec = '<=>'; + const NgTwoWay(String attrName) : super(attrName); +} + +/** + * When applied as an annotation on a directive field specifies that + * the field is to be mapped to DOM attribute with the provided [attrName]. + * The value of the attribute to be treated as a callback expression, + * equivalent to `&` specification. + */ +class NgCallback extends AbstractNgFieldAnnotation { + final _mappingSpec = '&'; + const NgCallback(String attrName) : super(attrName); +} + +/** + * A directives or components may chose to implements [NgAttachAware].[attach] method. + * If implemented the method will be called when the next scope digest occurs after + * component instantiation. It is guaranteed that when [attach] is invoked, that all + * attribute mappings have already been processed. + */ +abstract class NgAttachAware { + void attach(); +} + +/** + * A directives or components may chose to implements [NgDetachAware].[detach] method. + * If implemented the method will be called when the next associated scope is destroyed. + */ +abstract class NgDetachAware { + void detach(); +} + + +/** + * Use @[NgFilter] annotation to register a new filter. A filter is a class + * with a [call] method (a callable function). + * + * Usage: + * + * // Declaration + * @NgFilter(name:'myFilter') + * class MyFilter { + * call(valueToFilter, optArg1, optArg2) { + * return ...; + * } + * } + * + * + * // Registration + * var module = ...; + * module.type(MyFilter); + * + * + * + * {{something | myFilter:arg1:arg2}} + */ +class NgFilter { + final String name; + + const NgFilter({this.name}); + + int get hashCode => name.hashCode; + bool operator==(other) => name == other.name; + + toString() => 'NgFilter: $name'; +} diff --git a/lib/core/registry_dynamic.dart b/lib/core/registry_dynamic.dart index fe6929c73..4af594079 100644 --- a/lib/core/registry_dynamic.dart +++ b/lib/core/registry_dynamic.dart @@ -1,13 +1,13 @@ library angular.core_dynamic; import 'dart:mirrors'; -import 'package:angular/core/annotation.dart'; +import 'package:angular/core/annotation_src.dart'; import 'package:angular/core/registry.dart'; export 'package:angular/core/registry.dart' show MetadataExtractor; -var _fieldMetadataCache = new Map>(); +var _fieldMetadataCache = new Map>(); class DynamicMetadataExtractor implements MetadataExtractor { final _fieldAnnotations = [ @@ -30,38 +30,38 @@ class DynamicMetadataExtractor implements MetadataExtractor { } map(Type type, obj) { - if (obj is NgAnnotation) { + if (obj is AbstractNgAnnotation) { return mapDirectiveAnnotation(type, obj); } else { return obj; } } - NgAnnotation mapDirectiveAnnotation(Type type, NgAnnotation annotation) { + AbstractNgAnnotation mapDirectiveAnnotation(Type type, AbstractNgAnnotation annotation) { var match; var fieldMetadata = fieldMetadataExtractor(type); if (fieldMetadata.isNotEmpty) { var newMap = annotation.map == null ? {} : new Map.from(annotation.map); - fieldMetadata.forEach((String fieldName, AttrFieldAnnotation ann) { + fieldMetadata.forEach((String fieldName, AbstractNgFieldAnnotation ann) { var attrName = ann.attrName; if (newMap.containsKey(attrName)) { throw 'Mapping for attribute $attrName is already defined (while ' 'processing annottation for field $fieldName of $type)'; } - newMap[attrName] = '${ann.mappingSpec}$fieldName'; + newMap[attrName] = '${mappingSpec(ann)}$fieldName'; }); - annotation = annotation.cloneWithNewMap(newMap); + annotation = cloneWithNewMap(annotation, newMap); } return annotation; } - Map fieldMetadataExtractor(Type type) => + Map fieldMetadataExtractor(Type type) => _fieldMetadataCache.putIfAbsent(type, () => _fieldMetadataExtractor(type)); - Map _fieldMetadataExtractor(Type type) { + Map _fieldMetadataExtractor(Type type) { ClassMirror cm = reflectType(type); - final fields = {}; + final fields = {}; cm.declarations.forEach((Symbol name, DeclarationMirror decl) { if (decl is VariableMirror || decl is MethodMirror && (decl.isGetter || decl.isSetter)) { @@ -76,7 +76,7 @@ class DynamicMetadataExtractor implements MetadataExtractor { throw 'Attribute annotation for $fieldName is defined more ' 'than once in $type'; } - fields[fieldName] = meta.reflectee as AttrFieldAnnotation; + fields[fieldName] = meta.reflectee as AbstractNgFieldAnnotation; } }); } diff --git a/lib/core_dom/common.dart b/lib/core_dom/common.dart index 40329bbb2..43f1f782c 100644 --- a/lib/core_dom/common.dart +++ b/lib/core_dom/common.dart @@ -10,7 +10,7 @@ typedef ApplyMapping(NodeAttrs attrs, Scope scope, Object dst, class DirectiveRef { final dom.Node element; final Type type; - final NgAnnotation annotation; + final AbstractNgAnnotation annotation; final String value; final mappings = new List(); diff --git a/lib/core_dom/directive_map.dart b/lib/core_dom/directive_map.dart index b2c18cdb0..c093d9df9 100644 --- a/lib/core_dom/directive_map.dart +++ b/lib/core_dom/directive_map.dart @@ -1,7 +1,7 @@ part of angular.core.dom_internal; @NgInjectableService() -class DirectiveMap extends AnnotationsMap { +class DirectiveMap extends AnnotationsMap { DirectiveSelectorFactory _directiveSelectorFactory; DirectiveSelector _selector; DirectiveSelector get selector { diff --git a/lib/core_dom/element_binder.dart b/lib/core_dom/element_binder.dart index 843a7a153..eb91a675d 100644 --- a/lib/core_dom/element_binder.dart +++ b/lib/core_dom/element_binder.dart @@ -55,7 +55,7 @@ class ElementBinder { final bool hasTemplate = false; bool get shouldCompileChildren => - childMode == NgAnnotation.COMPILE_CHILDREN; + childMode == AbstractNgAnnotation.COMPILE_CHILDREN; var _directiveCache; List get _usableDirectiveRefs { @@ -199,7 +199,7 @@ class ElementBinder { ..factory(ElementProbe, (_) => probe); directiveRefs.forEach((DirectiveRef ref) { - NgAnnotation annotation = ref.annotation; + AbstractNgAnnotation annotation = ref.annotation; var visibility = ref.annotation.visibility; if (ref.annotation is NgController) { scope = scope.createChild(new PrototypeMap(scope.context)); diff --git a/lib/core_dom/element_binder_builder.dart b/lib/core_dom/element_binder_builder.dart index fb52b9161..de5bd3da0 100644 --- a/lib/core_dom/element_binder_builder.dart +++ b/lib/core_dom/element_binder_builder.dart @@ -34,7 +34,7 @@ class ElementBinderBuilder { DirectiveRef component; // Can be either COMPILE_CHILDREN or IGNORE_CHILDREN - String childMode = NgAnnotation.COMPILE_CHILDREN; + String childMode = AbstractNgAnnotation.COMPILE_CHILDREN; ElementBinderBuilder(this._factory, this._parser); @@ -43,7 +43,7 @@ class ElementBinderBuilder { var annotation = ref.annotation; var children = annotation.children; - if (annotation.children == NgAnnotation.TRANSCLUDE_CHILDREN) { + if (annotation.children == AbstractNgAnnotation.TRANSCLUDE_CHILDREN) { template = ref; } else if (annotation is NgComponent) { component = ref; @@ -51,7 +51,7 @@ class ElementBinderBuilder { decorators.add(ref); } - if (annotation.children == NgAnnotation.IGNORE_CHILDREN) { + if (annotation.children == AbstractNgAnnotation.IGNORE_CHILDREN) { childMode = annotation.children; } @@ -61,7 +61,7 @@ class ElementBinderBuilder { static RegExp _MAPPING = new RegExp(r'^(\@|=\>\!|\=\>|\<\=\>|\&)\s*(.*)$'); createMappings(DirectiveRef ref) { - NgAnnotation annotation = ref.annotation; + AbstractNgAnnotation annotation = ref.annotation; if (annotation.map != null) annotation.map.forEach((attrName, mapping) { Match match = _MAPPING.firstMatch(mapping); if (match == null) { diff --git a/lib/core_dom/module_internal.dart b/lib/core_dom/module_internal.dart index 6a1c8628a..4eda54165 100644 --- a/lib/core_dom/module_internal.dart +++ b/lib/core_dom/module_internal.dart @@ -7,7 +7,7 @@ import 'dart:html' as dom; import 'package:di/di.dart'; import 'package:perf_api/perf_api.dart'; -import 'package:angular/core/annotation.dart'; +import 'package:angular/core/annotation_src.dart'; import 'package:angular/core/module_internal.dart'; import 'package:angular/core/parser/parser.dart'; import 'package:angular/core_dom/dom_util.dart' as util; diff --git a/lib/core_dom/selector.dart b/lib/core_dom/selector.dart index 3dec8effa..24582b9c6 100644 --- a/lib/core_dom/selector.dart +++ b/lib/core_dom/selector.dart @@ -29,7 +29,7 @@ part of angular.core.dom_internal; */ class _Directive { final Type type; - final NgAnnotation annotation; + final AbstractNgAnnotation annotation; _Directive(this.type, this.annotation); @@ -38,7 +38,7 @@ class _Directive { class _ContainsSelector { - final NgAnnotation annotation; + final AbstractNgAnnotation annotation; final RegExp regexp; _ContainsSelector(this.annotation, String regexp) @@ -252,7 +252,7 @@ class DirectiveSelector { elementSelector = new _ElementSelector(''); attrSelector = <_ContainsSelector>[]; textSelector = <_ContainsSelector>[]; - _directives.forEach((NgAnnotation annotation, Type type) { + _directives.forEach((AbstractNgAnnotation annotation, Type type) { var match; var selector = annotation.selector; List<_SelectorPart> selectorParts; diff --git a/lib/directive/ng_if.dart b/lib/directive/ng_if.dart index 600db65f5..f0a0ce18e 100644 --- a/lib/directive/ng_if.dart +++ b/lib/directive/ng_if.dart @@ -90,7 +90,7 @@ abstract class _NgUnlessIfAttrDirectiveBase { * */ @NgDirective( - children: NgAnnotation.TRANSCLUDE_CHILDREN, + children: AbstractNgAnnotation.TRANSCLUDE_CHILDREN, selector:'[ng-if]', map: const {'.': '=>condition'}) class NgIf extends _NgUnlessIfAttrDirectiveBase { @@ -151,7 +151,7 @@ class NgIf extends _NgUnlessIfAttrDirectiveBase { * */ @NgDirective( - children: NgAnnotation.TRANSCLUDE_CHILDREN, + children: AbstractNgAnnotation.TRANSCLUDE_CHILDREN, selector:'[ng-unless]', map: const {'.': '=>condition'}) class NgUnless extends _NgUnlessIfAttrDirectiveBase { diff --git a/lib/directive/ng_non_bindable.dart b/lib/directive/ng_non_bindable.dart index fdacebc9e..975e154d8 100644 --- a/lib/directive/ng_non_bindable.dart +++ b/lib/directive/ng_non_bindable.dart @@ -20,5 +20,5 @@ part of angular.directive; */ @NgDirective( selector: '[ng-non-bindable]', - children: NgAnnotation.IGNORE_CHILDREN) + children: AbstractNgAnnotation.IGNORE_CHILDREN) class NgNonBindable {} diff --git a/lib/directive/ng_repeat.dart b/lib/directive/ng_repeat.dart index 777dfdf71..b29388a09 100644 --- a/lib/directive/ng_repeat.dart +++ b/lib/directive/ng_repeat.dart @@ -66,7 +66,7 @@ part of angular.directive; */ @NgDirective( - children: NgAnnotation.TRANSCLUDE_CHILDREN, + children: AbstractNgAnnotation.TRANSCLUDE_CHILDREN, selector: '[ng-repeat]', map: const {'.': '@expression'}) class NgRepeat { diff --git a/lib/directive/ng_switch.dart b/lib/directive/ng_switch.dart index fb97af97f..3a837fc23 100644 --- a/lib/directive/ng_switch.dart +++ b/lib/directive/ng_switch.dart @@ -111,7 +111,7 @@ class _Case { @NgDirective( selector: '[ng-switch-when]', - children: NgAnnotation.TRANSCLUDE_CHILDREN, + children: AbstractNgAnnotation.TRANSCLUDE_CHILDREN, map: const {'.': '@value'}) class NgSwitchWhen { final NgSwitch ngSwitch; @@ -125,7 +125,7 @@ class NgSwitchWhen { } @NgDirective( - children: NgAnnotation.TRANSCLUDE_CHILDREN, + children: AbstractNgAnnotation.TRANSCLUDE_CHILDREN, selector: '[ng-switch-default]') class NgSwitchDefault { diff --git a/lib/directive/ng_template.dart b/lib/directive/ng_template.dart index 36e4d1b47..4ea85ac63 100644 --- a/lib/directive/ng_template.dart +++ b/lib/directive/ng_template.dart @@ -23,7 +23,7 @@ part of angular.directive; map: const {'id': '@templateUrl'}) @NgDirective( selector: 'script[type=text/ng-template]', - children: NgAnnotation.IGNORE_CHILDREN, + children: AbstractNgAnnotation.IGNORE_CHILDREN, map: const {'id': '@templateUrl'}) class NgTemplate { final dom.Element element; diff --git a/lib/tools/transformer/metadata_extractor.dart b/lib/tools/transformer/metadata_extractor.dart index 7ffadf3de..cd424dd72 100644 --- a/lib/tools/transformer/metadata_extractor.dart +++ b/lib/tools/transformer/metadata_extractor.dart @@ -228,9 +228,9 @@ class AnnotationExtractor { } _annotationElements.add(type.unnamedConstructor); } - ngAnnotationType = resolver.getType('angular.core.annotation.NgAnnotation'); + ngAnnotationType = resolver.getType('angular.core.annotation.AbstractNgAnnotation'); if (ngAnnotationType == null) { - logger.warning('Unable to resolve NgAnnotation, ' + logger.warning('Unable to resolve AbstractNgAnnotation, ' 'skipping member annotations.'); } } @@ -296,11 +296,11 @@ class AnnotationExtractor { return type; } - /// Folds all AttrFieldAnnotations into the NgAnnotation annotation on the + /// Folds all AttrFieldAnnotations into the AbstractNgAnnotation annotation on the /// class. void _foldMemberAnnotations(Map memberAnnotations, AnnotatedType type) { - // Filter down to NgAnnotation constructors. + // Filter down to AbstractNgAnnotation constructors. var ngAnnotations = type.annotations.where((a) { var element = a.element; if (element is! ConstructorElement) return false; diff --git a/test/angular_spec.dart b/test/angular_spec.dart index 62f8b0a27..403ccd548 100644 --- a/test/angular_spec.dart +++ b/test/angular_spec.dart @@ -123,12 +123,12 @@ main() { var ALLOWED_NAMES = [ "angular.app.Application", "angular.app.AngularModule", - "angular.core.annotation.NgAttachAware", - "angular.core.annotation.NgComponent", - "angular.core.annotation.NgController", - "angular.core.annotation.NgDetachAware", - "angular.core.annotation.NgDirective", - "angular.core.annotation.NgInjectableService", + "angular.core.annotation_src.NgAttachAware", + "angular.core.annotation_src.NgComponent", + "angular.core.annotation_src.NgController", + "angular.core.annotation_src.NgDetachAware", + "angular.core.annotation_src.NgDirective", + "angular.core.annotation_src.NgInjectableService", "angular.core_internal.CacheStats", "angular.core_internal.ExceptionHandler", "angular.core_internal.Interpolate", diff --git a/test/core_dom/compiler_spec.dart b/test/core_dom/compiler_spec.dart index 383273001..7d02d694d 100644 --- a/test/core_dom/compiler_spec.dart +++ b/test/core_dom/compiler_spec.dart @@ -680,7 +680,7 @@ class LocalAttrDirective { @NgDirective( selector: '[simple-transclude-in-attach]', - visibility: NgDirective.CHILDREN_VISIBILITY, children: NgAnnotation.TRANSCLUDE_CHILDREN) + visibility: NgDirective.CHILDREN_VISIBILITY, children: AbstractNgAnnotation.TRANSCLUDE_CHILDREN) class SimpleTranscludeInAttachAttrDirective { SimpleTranscludeInAttachAttrDirective(ViewPort viewPort, BoundViewFactory boundViewFactory, Logger log, RootScope scope) { scope.runAsync(() { @@ -714,7 +714,7 @@ class TwoOfTwoDirectives { @NgDirective( selector: '[ignore-children]', - children: NgAnnotation.IGNORE_CHILDREN + children: AbstractNgAnnotation.IGNORE_CHILDREN ) class IgnoreChildrenDirective { IgnoreChildrenDirective(Logger log) { diff --git a/test/core_dom/element_binder_builder_spec.dart b/test/core_dom/element_binder_builder_spec.dart index dd81eb61e..990a3d309 100644 --- a/test/core_dom/element_binder_builder_spec.dart +++ b/test/core_dom/element_binder_builder_spec.dart @@ -5,10 +5,10 @@ import 'dart:mirrors'; @NgComponent(selector:'component') class _Component{} @NgDirective(selector:'[ignore-children]', - children: NgAnnotation.IGNORE_CHILDREN) + children: AbstractNgAnnotation.IGNORE_CHILDREN) class _IgnoreChildren{} @NgDirective(selector:'[structural]', - children: NgAnnotation.TRANSCLUDE_CHILDREN) + children: AbstractNgAnnotation.TRANSCLUDE_CHILDREN) class _Structural{} @NgDirective(selector:'[directive]') class _DirectiveAttr{} @@ -36,7 +36,7 @@ main() => describe('ElementBinderBuilder', () { }); addDirective(selector) { - directives.forEach((NgAnnotation annotation, Type type) { + directives.forEach((AbstractNgAnnotation annotation, Type type) { if (annotation.selector == selector) b.addDirective(new DirectiveRef(node, type, annotation, null)); }); @@ -50,7 +50,7 @@ main() => describe('ElementBinderBuilder', () { expect(b.decorators.length).toEqual(1); expect(b.component).toBeNull(); - expect(b.childMode).toEqual(NgAnnotation.COMPILE_CHILDREN); + expect(b.childMode).toEqual(AbstractNgAnnotation.COMPILE_CHILDREN); }); @@ -72,6 +72,6 @@ main() => describe('ElementBinderBuilder', () { expect(b.decorators.length).toEqual(1); expect(b.component).toBeNull(); - expect(b.childMode).toEqual(NgAnnotation.IGNORE_CHILDREN); + expect(b.childMode).toEqual(AbstractNgAnnotation.IGNORE_CHILDREN); }); }); diff --git a/test/core_dom/selector_spec.dart b/test/core_dom/selector_spec.dart index 6109c31af..550f51fa2 100644 --- a/test/core_dom/selector_spec.dart +++ b/test/core_dom/selector_spec.dart @@ -16,11 +16,11 @@ import '../_specs.dart'; @NgComponent(selector:'component') class _Component{} @NgDirective(selector:'[attribute]') class _Attribute{} @NgDirective(selector:'[structural]', - children: NgAnnotation.TRANSCLUDE_CHILDREN) + children: AbstractNgAnnotation.TRANSCLUDE_CHILDREN) class _Structural{} @NgDirective(selector:'[ignore-children]', - children: NgAnnotation.IGNORE_CHILDREN) + children: AbstractNgAnnotation.IGNORE_CHILDREN) class _IgnoreChildren{} @NgDirective(selector: '[my-model][required]') diff --git a/test/core_dom/view_spec.dart b/test/core_dom/view_spec.dart index 0c55ebcbc..7ed481ef4 100644 --- a/test/core_dom/view_spec.dart +++ b/test/core_dom/view_spec.dart @@ -9,7 +9,7 @@ class Log { add(String msg) => log.add(msg); } -@NgDirective(children: NgAnnotation.TRANSCLUDE_CHILDREN, selector: 'foo') +@NgDirective(children: AbstractNgAnnotation.TRANSCLUDE_CHILDREN, selector: 'foo') class LoggerViewDirective { LoggerViewDirective(ViewPort port, ViewFactory viewFactory, BoundViewFactory boundViewFactory, Logger logger) { @@ -142,7 +142,7 @@ main() { var directiveRef = new DirectiveRef(null, LoggerViewDirective, - new NgDirective(children: NgAnnotation.TRANSCLUDE_CHILDREN, selector: 'foo'), + new NgDirective(children: AbstractNgAnnotation.TRANSCLUDE_CHILDREN, selector: 'foo'), ''); directiveRef.viewFactory = viewFactoryFactory($('text'), [], perf, new Expando()); var binder = ebf.binder(); diff --git a/test/directive/ng_if_spec.dart b/test/directive/ng_if_spec.dart index c1228eaed..742cda8c3 100644 --- a/test/directive/ng_if_spec.dart +++ b/test/directive/ng_if_spec.dart @@ -4,7 +4,7 @@ import '../_specs.dart'; @NgDirective( selector: '[child-controller]', - children: NgAnnotation.TRANSCLUDE_CHILDREN) + children: AbstractNgAnnotation.TRANSCLUDE_CHILDREN) class ChildController { ChildController(BoundViewFactory boundViewFactory, ViewPort viewPort, diff --git a/test/directive/ng_include_spec.dart b/test/directive/ng_include_spec.dart index 1a7e91755..b1b793b70 100644 --- a/test/directive/ng_include_spec.dart +++ b/test/directive/ng_include_spec.dart @@ -21,7 +21,7 @@ main() { expect(element.text).toEqual('my name is Vojta'); })); - iit('should fetch template from url using interpolation', async((Scope scope, TemplateCache cache) { + it('should fetch template from url using interpolation', async((Scope scope, TemplateCache cache) { cache.put('tpl1.html', new HttpResponse(200, 'My name is {{name}}')); cache.put('tpl2.html', new HttpResponse(200, 'I am {{name}}')); diff --git a/test/io/test_files/main.dart b/test/io/test_files/main.dart index 508fb45a9..412630c03 100644 --- a/test/io/test_files/main.dart +++ b/test/io/test_files/main.dart @@ -3,7 +3,7 @@ library test_files.main; import 'package:angular/core/module.dart'; @NgDirective( - children: NgAnnotation.TRANSCLUDE_CHILDREN, + children: AbstractNgAnnotation.TRANSCLUDE_CHILDREN, selector:'[ng-if]', map: const {'.': '=>ngIfCondition'}) class NgIfDirective { diff --git a/test/tools/transformer/metadata_generator_spec.dart b/test/tools/transformer/metadata_generator_spec.dart index 3f1c71ef0..b470f1d9b 100644 --- a/test/tools/transformer/metadata_generator_spec.dart +++ b/test/tools/transformer/metadata_generator_spec.dart @@ -570,11 +570,11 @@ const String footer = ''' const String libAngular = ''' library angular.core.annotation; -class NgAnnotation { - NgAnnotation({map: const {}}); +class AbstractNgAnnotation { + AbstractNgAnnotation({map: const {}}); } -class NgDirective extends NgAnnotation { +class NgDirective extends AbstractNgAnnotation { const NgDirective({selector, module, map, visibility, exportExpressions}) : super(map: map);