From f75a50c1ddb542d3898def5464629c1f13540ee2 Mon Sep 17 00:00:00 2001 From: Tobias Bosch Date: Thu, 30 Apr 2015 13:38:40 -0700 Subject: [PATCH] refactor(compiler): rename decorator directives into directive BREAKING CHANGE: Previously, `Directive` was the abstract base class of several directives. Now, `Directive` is the former `Decorator`, and `Component` inherits from it. --- modules/angular2/annotations.js | 2 +- modules/angular2/docs/core/02_directives.md | 26 +- .../src/core/annotations/annotations.es6 | 1 - .../src/core/annotations_impl/annotations.js | 396 ++++++++---------- .../angular2/src/core/annotations_impl/di.js | 4 +- .../src/core/annotations_impl/visibility.js | 8 +- .../angular2/src/core/compiler/compiler.js | 9 +- .../src/core/decorators/decorators.es6 | 4 +- modules/angular2/src/directives/class.js | 4 +- modules/angular2/src/directives/for.js | 4 +- modules/angular2/src/directives/if.js | 4 +- .../angular2/src/directives/non_bindable.js | 4 +- modules/angular2/src/directives/switch.js | 8 +- modules/angular2/src/forms/directives.js | 10 +- .../src/forms/validator_directives.js | 4 +- modules/angular2/src/render/api.js | 2 +- modules/angular2/src/router/router_link.js | 4 +- modules/angular2/src/router/router_outlet.js | 4 +- .../directive_processor/transformer.dart | 2 +- .../directive_metadata_reader.dart | 6 +- .../angular2/test/core/application_spec.js | 4 +- .../test/core/compiler/compiler_spec.js | 34 +- .../directive_metadata_reader_spec.js | 12 +- .../compiler/dynamic_component_loader_spec.js | 2 +- .../test/core/compiler/integration_spec.js | 78 ++-- .../core/compiler/query_integration_spec.js | 4 +- .../test/directives/non_bindable_spec.js | 8 +- .../angular2/test/forms/integration_spec.js | 4 +- .../dom/compiler/directive_parser_spec.js | 32 +- .../angular2/test/render/dom/convert_spec.js | 4 +- .../shadow_dom_emulation_integration_spec.js | 4 +- .../basic_bind_files/bar.ng_deps.dart | 2 +- .../expected/bar.ng_deps.dart | 2 +- .../compile_children.ng_deps.dart | 2 +- .../host_listeners.ng_deps.dart | 2 +- .../properties.ng_deps.dart | 2 +- .../selector.ng_deps.dart | 2 +- .../too_many_directives.ng_deps.dart | 2 +- .../expected/hello.ng_deps.dart | 2 +- .../duplicate_files/hello.ng_deps.dart | 2 +- .../expected/hello.ng_deps.dart | 2 +- .../hello.ng_deps.dart | 2 +- .../expected/hello.ng_deps.dart | 2 +- .../inline_method_files/hello.ng_deps.dart | 2 +- .../expected/hello.ng_deps.dart | 2 +- .../url_expression_files/hello.ng_deps.dart | 2 +- .../expected/hello.ng_deps.dart | 2 +- .../url_method_files/hello.ng_deps.dart | 2 +- .../src/components/input/input.js | 6 +- modules/angular2_material/src/core/theme.js | 4 +- modules/benchmarks/e2e_test/costs_perf.es6 | 2 +- .../src/compiler/compiler_benchmark.js | 12 +- modules/benchmarks/src/costs/index.html | 2 +- modules/benchmarks/src/costs/index.js | 22 +- .../src/largetable/largetable_benchmark.js | 2 +- .../src/naive_infinite_scroll/app.js | 2 +- .../src/naive_infinite_scroll/cells.js | 2 +- .../src/naive_infinite_scroll/scroll_area.js | 2 +- .../src/naive_infinite_scroll/scroll_item.js | 2 +- modules/benchmarks/src/tree/tree_benchmark.js | 2 +- .../src/compiler/compiler_benchmark.dart | 10 +- modules/examples/src/forms/index.es6 | 2 +- .../examples/src/hello_world/index_common.js | 8 +- modules/examples/src/material/button/index.js | 2 +- .../examples/src/material/checkbox/index.js | 2 +- .../examples/src/material/grid_list/index.js | 2 +- modules/examples/src/material/input/index.js | 2 +- .../src/material/progress-linear/index.js | 2 +- modules/examples/src/material/radio/index.js | 2 +- .../examples/src/material/switcher/index.js | 2 +- modules/examples/src/todo/index.js | 2 +- 71 files changed, 384 insertions(+), 438 deletions(-) diff --git a/modules/angular2/annotations.js b/modules/angular2/annotations.js index 196ee45fa5..5ac5df5b82 100644 --- a/modules/angular2/annotations.js +++ b/modules/angular2/annotations.js @@ -4,7 +4,7 @@ * @description * * Annotations provide the additional information that Angular requires in order to run your application. This module - * contains {@link Component}, {@link Decorator}, and {@link View} annotations, as well as {@link Parent} and {@link Ancestor} annotations that are + * contains {@link Component}, {@link Directive}, and {@link View} annotations, as well as {@link Parent} and {@link Ancestor} annotations that are * used by Angular to resolve dependencies. * */ diff --git a/modules/angular2/docs/core/02_directives.md b/modules/angular2/docs/core/02_directives.md index 6a5da8afe3..69af3c7de8 100644 --- a/modules/angular2/docs/core/02_directives.md +++ b/modules/angular2/docs/core/02_directives.md @@ -6,11 +6,7 @@ Directives are the cornerstone of an Angular application. We use Directives to b Angular applications do not have a main method. Instead they have a root Component. Dependency Injection then assembles the directives into a working Angular application. -There are three different kinds of directives (described in more detail in later sections). - -1. *Decorators*: can be placed on any DOM element and can be combined with other directives. -2. *Components*: Components have an encapsulated view and can configure injectors. - +Directives with an encapsulated view and an optional injector are called *Components*. ## CSS Selectors @@ -53,18 +49,18 @@ CSS Selectors can be combined: -## Decorators +## Directives The simplest kind of directive is a decorator. Directives are usefull for encapsulating behavior. * Multiple decorators can be placed on a single element. -* Decorators do not introduce new evaluation context. -* Decorators are registered through the `@Decorator` meta-data annotation. +* Directives do not introduce new evaluation context. +* Directives are registered through the `@Directive` meta-data annotation. Here is a trivial example of a tooltip decorator. The directive will log a tooltip into the console on every time mouse enters a region: ``` -@Decorator({ +@Directive({ selector: '[tooltip]', // CSS Selector which triggers the decorator properties: { // List which properties need to be bound text: 'tooltip' // - DOM element tooltip property should be @@ -75,7 +71,7 @@ Here is a trivial example of a tooltip decorator. The directive will log a toolt }) class Form { // Directive controller class, instantiated // when CSS matches. - text:string; // text property on the Decorator Controller. + text:string; // text property on the Directive Controller. show(event) { // Show method which implements the show action. console.log(this.text); @@ -238,7 +234,7 @@ class MyService {} | Assume a service which needs to be inject }) | class MyApp {} | | -@Decorator({ | This is the directive into which we would like +@Directive({ | This is the directive into which we would like selector: '[house]' | to inject the MyService. }) | class House { | @@ -285,7 +281,7 @@ Here is an example of the kinds of injections which can be achieved: }) | class MyApp {} | | -@Decorator({ selector: 'form' }) | +@Directive({ selector: 'form' }) | class Form { | constructor( | @descendant sets:Query
| @@ -293,14 +289,14 @@ class Form { | } | } | | -@Decorator({ selector: 'fieldset' }) | +@Directive({ selector: 'fieldset' }) | class FieldSet { | constructor( | @child sets:Query | ) { ... } | } | | -@Decorator({ selector: 'field' }) | +@Directive({ selector: 'field' }) | class Field { | constructor( | @ancestor field:Form, | @@ -308,7 +304,7 @@ class Field { | ) { ... } | } | | -@Decorator({ selector: '[primary]'}) | +@Directive({ selector: '[primary]'}) | class Primary { | constructor(field:Field ) { ... } | } | diff --git a/modules/angular2/src/core/annotations/annotations.es6 b/modules/angular2/src/core/annotations/annotations.es6 index 256276c3b1..1cef71cfb3 100644 --- a/modules/angular2/src/core/annotations/annotations.es6 +++ b/modules/angular2/src/core/annotations/annotations.es6 @@ -5,7 +5,6 @@ export { Component as ComponentAnnotation, - Decorator as DecoratorAnnotation, Directive as DirectiveAnnotation, onDestroy, onChange, onAllChangesDone } from '../annotations_impl/annotations'; diff --git a/modules/angular2/src/core/annotations_impl/annotations.js b/modules/angular2/src/core/annotations_impl/annotations.js index 80400469f4..8f9423b968 100644 --- a/modules/angular2/src/core/annotations_impl/annotations.js +++ b/modules/angular2/src/core/annotations_impl/annotations.js @@ -1,4 +1,4 @@ -import {ABSTRACT, CONST, normalizeBlank, isPresent} from 'angular2/src/facade/lang'; +import {CONST, normalizeBlank, isPresent} from 'angular2/src/facade/lang'; import {ListWrapper, List} from 'angular2/src/facade/collection'; import {Injectable} from 'angular2/di'; import {DEFAULT} from 'angular2/change_detection'; @@ -8,7 +8,7 @@ import {DEFAULT} from 'angular2/change_detection'; /** * Directives allow you to attach behavior to elements in the DOM. * - * Directive is an abstract concept, instead use concrete directives: {@link Component}, or {@link Decorator}. + * {@link Directive}s with an embedded view are called {@link Component}s. * * A directive consists of a single directive annotation and a controller class. When the directive's `selector` matches * elements in the DOM, the following steps occur: @@ -54,7 +54,7 @@ import {DEFAULT} from 'angular2/change_detection'; * * To inject element-specific special objects, declare the constructor parameter as: * - `element: ElementRef` to obtain a reference to logical element in the view. - * - `viewContainer: ViewContainerRef` to control child template instantiation, for {@link Decorator} directives only + * - `viewContainer: ViewContainerRef` to control child template instantiation, for {@link Directive} directives only * - `bindingPropagation: BindingPropagation` to control change detection in a more granular way. * * ## Example @@ -84,7 +84,7 @@ import {DEFAULT} from 'angular2/change_detection'; * class SomeService { * } * - * @Decorator({ + * @Directive({ * selector: '[dependency]', * properties: { * 'id':'dependency' @@ -103,7 +103,7 @@ import {DEFAULT} from 'angular2/change_detection'; * Here the constructor is declared with no arguments, therefore nothing is injected into `MyDirective`. * * ``` - * @Decorator({ selector: '[my-directive]' }) + * @Directive({ selector: '[my-directive]' }) * class MyDirective { * constructor() { * } @@ -120,7 +120,7 @@ import {DEFAULT} from 'angular2/change_detection'; * Here, the constructor declares a parameter, `someService`, and injects the `SomeService` type from the parent * component's injector. * ``` - * @Decorator({ selector: '[my-directive]' }) + * @Directive({ selector: '[my-directive]' }) * class MyDirective { * constructor(someService: SomeService) { * } @@ -135,7 +135,7 @@ import {DEFAULT} from 'angular2/change_detection'; * Directives can inject other directives declared on the current element. * * ``` - * @Decorator({ selector: '[my-directive]' }) + * @Directive({ selector: '[my-directive]' }) * class MyDirective { * constructor(dependency: Dependency) { * expect(dependency.id).toEqual(3); @@ -152,7 +152,7 @@ import {DEFAULT} from 'angular2/change_detection'; * the dependency. * * ``` - * @Decorator({ selector: '[my-directive]' }) + * @Directive({ selector: '[my-directive]' }) * class MyDirective { * constructor(@Parent() dependency: Dependency) { * expect(dependency.id).toEqual(2); @@ -169,7 +169,7 @@ import {DEFAULT} from 'angular2/change_detection'; * resolve dependencies for the current element, even if this would satisfy the dependency. * * ``` - * @Decorator({ selector: '[my-directive]' }) + * @Directive({ selector: '[my-directive]' }) * class MyDirective { * constructor(@Ancestor() dependency: Dependency) { * expect(dependency.id).toEqual(2); @@ -191,7 +191,7 @@ import {DEFAULT} from 'angular2/change_detection'; * that uses a {@link ViewContainerRef} such as a `for`, an `if`, or a `switch`. * * ``` - * @Decorator({ selector: '[my-directive]' }) + * @Directive({ selector: '[my-directive]' }) * class MyDirective { * constructor(@Query(Marker) dependencies:QueryList) { * } @@ -208,7 +208,7 @@ import {DEFAULT} from 'angular2/change_detection'; * Similar to `@Children` above, but also includes the children of the child elements. * * ``` - * @Decorator({ selector: '[my-directive]' }) + * @Directive({ selector: '[my-directive]' }) * class MyDirective { * constructor(@QueryDescendents(Marker) dependencies:QueryList) { * } @@ -224,7 +224,7 @@ import {DEFAULT} from 'angular2/change_detection'; * This explicitly permits the author of a template to treat some of the surrounding directives as optional. * * ``` - * @Decorator({ selector: '[my-directive]' }) + * @Directive({ selector: '[my-directive]' }) * class MyDirective { * constructor(@Optional() dependency:Dependency) { * } @@ -234,9 +234,141 @@ import {DEFAULT} from 'angular2/change_detection'; * This directive would be instantiated with a `Dependency` directive found on the current element. If none can be * found, the injector supplies `null` instead of throwing an error. * + * ## Example + * + * Here we use a decorator directive to simply define basic tool-tip behavior. + * + * ``` + * @Directive({ + * selector: '[tooltip]', + * properties: { + * 'text': 'tooltip' + * }, + * hostListeners: { + * 'onmouseenter': 'onMouseEnter()', + * 'onmouseleave': 'onMouseLeave()' + * } + * }) + * class Tooltip{ + * text:string; + * overlay:Overlay; // NOT YET IMPLEMENTED + * overlayManager:OverlayManager; // NOT YET IMPLEMENTED + * + * constructor(overlayManager:OverlayManager) { + * this.overlay = overlay; + * } + * + * onMouseEnter() { + * // exact signature to be determined + * this.overlay = this.overlayManager.open(text, ...); + * } + * + * onMouseLeave() { + * this.overlay.close(); + * this.overlay = null; + * } + * } + * ``` + * In our HTML template, we can then add this behavior to a `
` or any other element with the `tooltip` selector, + * like so: + * + * ``` + *
+ * ``` + * + * Directives can also control the instantiation, destruction, and positioning of inline template elements: + * + * A directive uses a {@link ViewContainerRef} to instantiate, insert, move, and destroy views at runtime. + * The {@link ViewContainerRef} is created as a result of `