diff --git a/packages/common/http/src/module.ts b/packages/common/http/src/module.ts index 83a9fbfc94..feceb505e0 100644 --- a/packages/common/http/src/module.ts +++ b/packages/common/http/src/module.ts @@ -19,12 +19,13 @@ import {BrowserXhr, HttpXhrBackend, XhrFactory} from './xhr'; import {HttpXsrfCookieExtractor, HttpXsrfInterceptor, HttpXsrfTokenExtractor, XSRF_COOKIE_NAME, XSRF_HEADER_NAME} from './xsrf'; /** - * An `HttpHandler` that applies a bunch of `HttpInterceptor`s + * An injectable `HttpHandler` that applies multiple interceptors * to a request before passing it to the given `HttpBackend`. * * The interceptors are loaded lazily from the injector, to allow * interceptors to themselves inject classes depending indirectly * on `HttpInterceptingHandler` itself. + * @see `HttpInterceptor` */ @Injectable() export class HttpInterceptingHandler implements HttpHandler { @@ -42,6 +43,23 @@ export class HttpInterceptingHandler implements HttpHandler { } } +/** + * Constructs an `HttpHandler` that applies interceptors + * to a request before passing it to the given `HttpBackend`. + * + * Use as a factory function within `HttpClientModule`. + * + * + */ +export function interceptingHandler( + backend: HttpBackend, interceptors: HttpInterceptor[] | null = []): HttpHandler { + if (!interceptors) { + return backend; + } + return interceptors.reduceRight( + (next, interceptor) => new HttpInterceptorHandler(next, interceptor), backend); +} + /** * Factory function that determines where to store JSONP callbacks. * @@ -58,14 +76,14 @@ export function jsonpCallbackContext(): Object { } /** - * `NgModule` which adds XSRF protection support to outgoing requests. + * An NgModule that adds XSRF protection support to outgoing requests. * - * Provided the server supports a cookie-based XSRF protection system, this - * module can be used directly to configure XSRF protection with the correct + * For a server that supports a cookie-based XSRF protection system, + * use directly to configure XSRF protection with the correct * cookie and header names. * - * If no such names are provided, the default is to use `X-XSRF-TOKEN` for - * the header name and `XSRF-TOKEN` for the cookie name. + * If no names are supplied, the default cookie name is `XSRF-TOKEN` + * and the default header name is `X-XSRF-TOKEN`. * * */ @@ -92,8 +110,12 @@ export class HttpClientXsrfModule { } /** - * Configure XSRF protection to use the given cookie name or header name, - * or the default names (as described above) if not provided. + * Configure XSRF protection. + * @param options An object that can specify either or both + * cookie name or header name. + * - Cookie name default is `XSRF-TOKEN`. + * - Header name default is `X-XSRF-TOKEN`. + * */ static withOptions(options: { cookieName?: string, @@ -110,7 +132,7 @@ export class HttpClientXsrfModule { } /** - * `NgModule` which provides the `HttpClient` and associated services. + * An NgModule that provides the `HttpClient` and associated services. * * Interceptors can be added to the chain behind `HttpClient` by binding them * to the multiprovider for `HTTP_INTERCEPTORS`. @@ -118,12 +140,18 @@ export class HttpClientXsrfModule { * */ @NgModule({ + /** + * Optional configuration for XSRF protection. + */ imports: [ HttpClientXsrfModule.withOptions({ cookieName: 'XSRF-TOKEN', headerName: 'X-XSRF-TOKEN', }), ], + /** + * The module provides `HttpClient` itself, and supporting services. + */ providers: [ HttpClient, {provide: HttpHandler, useClass: HttpInterceptingHandler}, @@ -137,7 +165,7 @@ export class HttpClientModule { } /** - * `NgModule` which enables JSONP support in `HttpClient`. + * An NgModule that enables JSONP support in `HttpClient`. * * Without this module, Jsonp requests will reach the backend * with method JSONP, where they'll be rejected. diff --git a/packages/core/src/metadata/directives.ts b/packages/core/src/metadata/directives.ts index 61e3ef7cfa..4a5692cbb4 100644 --- a/packages/core/src/metadata/directives.ts +++ b/packages/core/src/metadata/directives.ts @@ -137,17 +137,6 @@ export interface Directive { * bankName: string; * id: string; * - * // this property is not bound, and won't be automatically updated by Angular - * normalizedBankName: string; - * } - * - * @Component({ - * selector: 'app', - * template: ` - * - * ` - * }) - * class App {} * ``` */ inputs?: string[]; @@ -169,29 +158,17 @@ export interface Directive { * * ```typescript * @Directive({ - * selector: 'interval-dir', - * outputs: ['everySecond', 'five5Secs: everyFiveSeconds'] + * selector: 'child-dir', + * exportAs: 'child' * }) - * class IntervalDir { - * everySecond = new EventEmitter(); - * five5Secs = new EventEmitter(); - * - * constructor() { - * setInterval(() => this.everySecond.emit("event"), 1000); - * setInterval(() => this.five5Secs.emit("event"), 5000); - * } + * class ChildDir { * } * * @Component({ - * selector: 'app', - * template: ` - * - * - * ` + * selector: 'main', + * template: `` * }) - * class App { - * everySecond() { console.log('second'); } - * everyFiveSeconds() { console.log('five seconds'); } + * class MainComponent { * } * ``` */ @@ -243,6 +220,7 @@ export interface Directive { * }) * class App {} * ``` + * See [live demo](http://plnkr.co/edit/DlA5KU?p=preview) * * ### Host Property Bindings * @@ -276,6 +254,7 @@ export interface Directive { * prop; * } * ``` + * See [live demo](http://plnkr.co/edit/gNg0ED?p=preview). * * ### Attributes * @@ -294,17 +273,18 @@ export interface Directive { * class MyButton { * } * ``` - */ - host?: {[key: string]: string}; - - /** - * Defines the set of injectable objects that are visible to a Directive and its light DOM - * children. + * Attaching the `my-button` directive to the host `
` element + * ensures that this element gets the "button" role. + * + * ```html + *
+ * ``` * * @usageNotes * ### Simple Example * - * Here is an example of a class that can be injected: + * The following simple example shows how a class is injected, + * using a provider specified in the directive metadata: * * ``` * class Greeter { @@ -364,6 +344,7 @@ export interface Directive { * @usageNotes * ### Example * + * The followoing example (shows what??) * ``` * @Component({ * selector: 'someDir', @@ -386,6 +367,8 @@ export interface Directive { * } * } * ``` + * + * @Annotation */ queries?: {[key: string]: any}; @@ -403,94 +386,148 @@ export interface Directive { * * @Annotation */ -export const Directive: DirectiveDecorator = makeDecorator( - 'Directive', (dir: Directive = {}) => dir, undefined, undefined, - (type: Type, meta: Directive) => (R3_COMPILE_DIRECTIVE || (() => {}))(type, meta)); - -/** - * Type of the Component decorator / constructor function. - */ -export interface ComponentDecorator { +export interface Directive { /** - * Marks a class as an Angular component and collects component configuration - * metadata. + * The CSS selector that identifies this directive in a template + * and triggers instantiation of the directive. * - * Component decorator allows you to mark a class as an Angular component and provide additional - * metadata that determines how the component should be processed, instantiated and used at - * runtime. + * Declare as one of the following: * - * Components are the most basic building block of an UI in an Angular application. - * An Angular application is a tree of Angular components. - * Angular components are a subset of directives. Unlike directives, components always have - * a template and only one component can be instantiated per an element in a template. + * - `element-name`: Select by element name. + * - `.class`: Select by class name. + * - `[attribute]`: Select by attribute name. + * - `[attribute=value]`: Select by attribute name and value. + * - `:not(sub_selector)`: Select only if the element does not match the `sub_selector`. + * - `selector1, selector2`: Select if either `selector1` or `selector2` matches. * - * A component must belong to an NgModule in order for it to be usable - * by another component or application. To specify that a component is a member of an NgModule, - * you should list it in the `declarations` field of that NgModule. + * Angular only allows directives to apply on CSS selectors that do not cross + * element boundaries. * - * In addition to the metadata configuration specified via the Component decorator, - * components can control their runtime behavior by implementing various Life-Cycle hooks. + * For the following template HTML, a directive with an `input[type=text]` selector, + * would be instantiated only on the `` element. * - * **Metadata Properties:** + * ```html + *
+ * + * + * + * ``` * - * * **animations** - list of animations of this component - * * **changeDetection** - change detection strategy used by this component - * * **encapsulation** - style encapsulation strategy used by this component - * * **entryComponents** - list of components that are dynamically inserted into the view of this - * component - * * **exportAs** - name under which the component instance is exported in a template - * * **host** - map of class property to host element bindings for events, properties and - * attributes - * * **inputs** - list of class property names to data-bind as component inputs - * * **interpolation** - custom interpolation markers used in this component's template - * * **moduleId** - ES/CommonJS module id of the file in which this component is defined - * * **outputs** - list of class property names that expose output events that others can - * subscribe to - * * **providers** - list of providers available to this component and its children - * * **queries** - configure queries that can be injected into the component - * * **selector** - css selector that identifies this component in a template - * * **styleUrls** - list of urls to stylesheets to be applied to this component's view - * * **styles** - inline-defined styles to be applied to this component's view - * * **template** - inline-defined template for the view - * * **templateUrl** - url to an external file containing a template for the view - * * **viewProviders** - list of providers available to this component and its view children - * - * @usageNotes - * ### Example - * - * {@example core/ts/metadata/metadata.ts region='component'} - * - * @Annotation */ - (obj: Component): TypeDecorator; + selector?: string; + + /** + * The set of event-bound output properties. + * When an output property emits an event, an event handler attached + * to that event in the template is invoked. + * + * Each output property maps a `directiveProperty` to a `bindingProperty`: + * - `directiveProperty` specifies the component property that emits events. + * - `bindingProperty` specifies the HTML attribute the event handler is attached to. + * + */ + outputs?: string[]; + + /** + * Maps class properties to host element bindings for properties, + * attributes, and events, using a set of key-value pairs. + * + * Angular automatically checks host property bindings during change detection. + * If a binding changes, Angular updates the directive's host element. + * + * When the key is a property of the host element, the property value is + * the propagated to the specified DOM property. + * + * When the key is a static attribute in the DOM, the attribute value + * is propagated to the specified property in the host element. + * + * For event handling: + * - The key is the DOM event that the directive listens to. + * To listen to global events, add the target to the event name. + * The target can be `window`, `document` or `body`. + * - The value is the statement to execute when the event occurs. If the + * statement evalueates to `false`, then `preventDefault` is applied on the DOM + * event. A handler method can refer to the `$event` local variable. + * + */ + host?: {[key: string]: string}; + /** * See the `Component` decorator. */ - new (obj: Component): Component; + providers?: Provider[]; + + /** + * The name or names that can be used in the template to assign this directive to a variable. + * For multiple names, use a comma-separated string. + * + */ + exportAs?: string; + + /** + * Configures the queries that will be injected into the directive. + * + * Content queries are set before the `ngAfterContentInit` callback is called. + * View queries are set before the `ngAfterViewInit` callback is called. + * + */ + queries?: {[key: string]: any}; } /** * Type of the Component metadata. */ -export interface Component extends Directive { - /** - * Defines the used change detection strategy. - * - * When a component is instantiated, Angular creates a change detector, which is responsible for - * propagating the component's bindings. - * - * The `changeDetection` property defines, whether the change detection will be checked every time - * or only when the component tells it to do so. - */ - changeDetection?: ChangeDetectionStrategy; +export const Directive: DirectiveDecorator = makeDecorator( + 'Directive', (dir: Directive = {}) => dir, undefined, undefined, + (type: Type, meta: Directive) => (R3_COMPILE_DIRECTIVE || (() => {}))(type, meta)); +/** + * Component decorator interface + * + */ +export interface ComponentDecorator { /** - * Defines the set of injectable objects that are visible to its view DOM children. + * Decorator that marks a class as an Angular component and provides configuration + * metadata that determines how the component should be processed, + * instantiated, and used at runtime. + * + * Components are the most basic UI building block of an Angular app. + * An Angular app contains a tree of Angular components. + * + * Angular components are a subset of directives, always associated with a template. + * Unlike other directives, only one component can be instantiated per an element in a template. + * + * A component must belong to an NgModule in order for it to be available + * to another component or application. To make it a member of an NgModule, + * list it in the `declarations` field of the `@NgModule` metadata. + * + * Note that, in addition to these options for configuring a directive, + * you can control a component's runtime behavior by implementing + * life-cycle hooks. For more information, see the + * [Lifecycle Hooks](guide/lifecycle-hooks) guide. * * @usageNotes - * ### Simple Example * - * Here is an example of a class that can be injected: + * ### Setting component inputs + * + * The following example creates a component with two data-bound properties, + * specified by the `inputs` value. + * + * + * + * + * + * ### Setting component outputs + * + * The following example shows two event emitters that emit on an interval. One + * emits an output every second, while the other emits every five seconds. + * + * {@example core/ts/metadata/directives.ts region='component-output-interval'} + * + * ### Injecting a class with a view provider + * + * The following simple example injects a class into a component + * using the view provider specified in component metadata: * * ``` * class Greeter { @@ -521,224 +558,117 @@ export interface Component extends Directive { * } * * ``` + * + * + * @Annotation + */ + (obj: Component): TypeDecorator; + /** + * See the `@Component` decorator. + */ + new (obj: Component): Component; +} + +/** + * Supplies configuration metadata for an Angular component. + */ +export interface Component extends Directive { + /** + * The change-detection strategy to use for this component. + * + * When a component is instantiated, Angular creates a change detector, + * which is responsible for propagating the component's bindings. + * The strategy is one of: + * - `ChangeDetectionStrategy#OnPush` sets the strategy to `CheckOnce` (on demand). + * - `ChangeDetectionStrategy#Default` sets the strategy to `CheckAlways`. + */ + changeDetection?: ChangeDetectionStrategy; + + /** + * Defines the set of injectable objects that are visible to its view DOM children. + * See [example](#injecting-a-class-with-a-view-provider). + * */ viewProviders?: Provider[]; /** - * The module id of the module that contains the component. - * Needed to be able to resolve relative urls for templates and styles. - * In CommonJS, this can always be set to `module.id`, similarly SystemJS exposes `__moduleName` - * variable within each module. + * The module ID of the module that contains the component. + * The component must be able to resolve relative URLs for templates and styles. + * SystemJS exposes the `__moduleName` variable within each module. + * In CommonJS, this can be set to `module.id`. * - * @usageNotes - * ### Simple Example - * - * ``` - * @Directive({ - * selector: 'someDir', - * moduleId: module.id - * }) - * class SomeDir { - * } - * - * ``` */ moduleId?: string; /** - * Specifies a template URL for an Angular component. + * The URL of a template file for an Angular component. If provided, + * do not supply an inline template using `template`. * - * Only one of `templateUrl` or `template` can be defined per View. */ templateUrl?: string; /** - * Specifies an inline template for an Angular component. + * An inline template for an Angular component. If provided, + * do not supply a template file using `templateUrl`. * - * Only one of `templateUrl` or `template` can be defined per Component. */ template?: string; /** - * Specifies stylesheet URLs for an Angular component. + * One or more URLs for files containing CSS stylesheets to use + * in this component. */ styleUrls?: string[]; /** - * Specifies inline stylesheets for an Angular component. + * One or more inline CSS stylesheets to use + * in this component. */ styles?: string[]; /** - * Animations are defined on components via an animation-like DSL. This DSL approach to describing - * animations allows for a flexibility that both benefits developers and the framework. + * One or more animation `trigger()` calls, containing + * `state()` and `transition()` definitions. + * See the [Animations guide](/guide/animations) and animations API documentation. * - * Animations work by listening on state changes that occur on an element within - * the template. When a state change occurs, Angular can then take advantage and animate the - * arc in between. This works similar to how CSS transitions work, however, by having a - * programmatic DSL, animations are not limited to environments that are DOM-specific. - * (Angular can also perform optimizations behind the scenes to make animations more performant.) - * - * For animations to be available for use, animation state changes are placed within - * {@link trigger animation triggers} which are housed inside of the `animations` annotation - * metadata. Within a trigger both `state` and `transition` entries - * can be placed. - * - * @usageNotes - * ### Example - * - * ```typescript - * @Component({ - * selector: 'animation-cmp', - * templateUrl: 'animation-cmp.html', - * animations: [ - * // this here is our animation trigger that - * // will contain our state change animations. - * trigger('myTriggerName', [ - * // the styles defined for the `on` and `off` - * // states declared below are persisted on the - * // element once the animation completes. - * state('on', style({ opacity: 1 }), - * state('off', style({ opacity: 0 }), - * - * // this here is our animation that kicks off when - * // this state change jump is true - * transition('on => off', [ - * animate("1s") - * ]) - * ]) - * ] - * }) - * ``` - * - * As depicted in the code above, a group of related animation states are all contained within - * an animation `trigger` (the code example above called the trigger `myTriggerName`). - * When a trigger is created then it can be bound onto an element within the component's - * template via a property prefixed by an `@` symbol followed by trigger name and an expression - * that - * is used to determine the state value for that trigger. - * - * ```html - * - *
...
- * ``` - * - * For state changes to be executed, the `expression` value must change value from its existing - * value - * to something that we have set an animation to animate on (in the example above we are listening - * to a change of state between `on` and `off`). The `expression` value attached to the trigger - * must be something that can be evaluated with the template/component context. - * - * ### DSL Animation Functions - * - * Please visit each of the animation DSL functions listed below to gain a better understanding - * of how and why they are used for crafting animations in Angular: - * - * - `trigger()` - * - `state()` - * - `transition()` - * - `group()` - * - `sequence()` - * - `style()` - * - `animate()` - * - `keyframes()` */ animations?: any[]; /** - * Specifies how the template and the styles should be encapsulated: - * - `ViewEncapsulation.Native` to use shadow roots - only works if natively available on the - * platform, - * - `ViewEncapsulation.Emulated` to use shimmed CSS that emulates the native behavior, - * - `ViewEncapsulation.None` to use global CSS without any encapsulation. + * An encapsulation policy for the template and CSS styles. One of: + * - `ViewEncapsulation.Native`: Use shadow roots. This works + * only if natively available on the platform. + * - `ViewEncapsulation.Emulated`: Use shimmed CSS that + * emulates the native behavior. + * - `ViewEncapsulation.None`: Use global CSS without any + * encapsulation. * - * When no `encapsulation` is defined for the component, the default value from the - * `CompilerOptions` is used. The default is `ViewEncapsulation.Emulated`. Provide a new - * `CompilerOptions` to override this value. + * If not supplied, the value is taken from `CompilerOptions`. The default compiler option is + * `ViewEncapsulation.Emulated`. * - * If the encapsulation is set to `ViewEncapsulation.Emulated` and the component has no `styles` - * nor `styleUrls` the encapsulation will automatically be switched to `ViewEncapsulation.None`. + * If the policy is set to `ViewEncapsulation.Emulated` and the component has no `styles` + * or `styleUrls` specified, the policy is automatically switched to `ViewEncapsulation.None`. */ encapsulation?: ViewEncapsulation; /** - * Overrides the default encapsulation start and end delimiters (respectively `{{` and `}}`) + * Overrides the default encapsulation start and end delimiters (`{{` and `}}`) */ interpolation?: [string, string]; /** - * Defines the components that should be compiled as well when - * this component is defined. For each components listed here, - * Angular will create a `ComponentFactory` and store it in the - * `ComponentFactoryResolver`. + * A set of components that should be compiled along with + * this component. For each component listed here, + * Angular creates a {@link ComponentFactory} and stores it in the + * {@link ComponentFactoryResolver}. */ entryComponents?: Array|any[]>; /** - * If `Component.preserveWhitespaces` is set to `false` - * potentially superfluous whitespace characters (ones matching the `\s` character class in - * JavaScript regular expressions) will be removed from a compiled template. This can greatly - * reduce AOT-generated code size as well as speed up view creation. - * - * Current implementation works according to the following rules: - * - all whitespaces at the beginning and the end of a template are removed (trimmed); - * - text nodes consisting of whitespaces only are removed (ex.: - * ` ` will be converted to - * `` (no whitespaces between buttons); - * - series of whitespaces in text nodes are replaced with one space (ex.: - * `\n some text\n` will be converted to ` some text `); - * - text nodes are left as-is inside HTML tags where whitespaces are significant (ex. `
`,
-   *   `