From 5948abab7ae39f558758c52508c66a52bafa9ad8 Mon Sep 17 00:00:00 2001 From: vsavkin Date: Mon, 2 Nov 2015 16:03:42 -0800 Subject: [PATCH] feat(core): add support for ambient directives Ambient directives can be configured when bootstraping an application. Ambient directives can be used in every component of the application without needing to explicitly list them. --- modules/angular2/angular2.dart | 1 + modules/angular2/angular2.ts | 1 + modules/angular2/common.ts | 51 ++++++++++++++++++ modules/angular2/core.ts | 1 + modules/angular2/src/core/application_ref.ts | 6 ++- modules/angular2/src/core/compiler/ambient.ts | 53 +++++++++++++++++++ .../angular2/src/core/compiler/compiler.ts | 1 + .../src/core/compiler/runtime_metadata.ts | 24 +++++---- .../src/core/linker/proto_view_factory.ts | 30 +++++------ modules/angular2/src/core/pipes.ts | 21 +++++++- .../angular2/src/core/pipes/default_pipes.ts | 27 ---------- modules/angular2/src/testing/test_injector.ts | 2 - .../src/web_workers/ui/di_bindings.ts | 6 ++- .../core/compiler/runtime_metadata_spec.ts | 25 +++++++-- .../test/core/linker/integration_spec.ts | 10 +++- modules/angular2/test/public_api_spec.ts | 6 ++- 16 files changed, 199 insertions(+), 66 deletions(-) create mode 100644 modules/angular2/common.ts create mode 100644 modules/angular2/src/core/compiler/ambient.ts delete mode 100644 modules/angular2/src/core/pipes/default_pipes.ts diff --git a/modules/angular2/angular2.dart b/modules/angular2/angular2.dart index 697c5230b8..d0c2e10178 100644 --- a/modules/angular2/angular2.dart +++ b/modules/angular2/angular2.dart @@ -7,6 +7,7 @@ library angular2; */ export 'package:angular2/core.dart' hide forwardRef, resolveForwardRef, ForwardRefFn; +export 'package:angular2/common.dart'; export 'package:angular2/profile.dart'; export 'package:angular2/lifecycle_hooks.dart'; export 'package:angular2/src/core/application_tokens.dart' diff --git a/modules/angular2/angular2.ts b/modules/angular2/angular2.ts index fb3ffaab93..c4358d1b21 100644 --- a/modules/angular2/angular2.ts +++ b/modules/angular2/angular2.ts @@ -1,3 +1,4 @@ +export * from './common'; export * from './core'; export * from './profile'; export * from './lifecycle_hooks'; diff --git a/modules/angular2/common.ts b/modules/angular2/common.ts new file mode 100644 index 0000000000..f23536805b --- /dev/null +++ b/modules/angular2/common.ts @@ -0,0 +1,51 @@ +import {CONST_EXPR, Type} from './src/core/facade/lang'; + +import {FORM_DIRECTIVES} from './src/core/forms'; +import {CORE_DIRECTIVES} from './src/core/directives'; +export * from './src/core/pipes'; +export * from './src/core/directives'; + +/** + * A collection of Angular core directives that are likely to be used in each and every Angular + * application. This includes core directives (e.g., NgIf and NgFor), and forms directives (e.g., + * NgModel). + * + * This collection can be used to quickly enumerate all the built-in directives in the `directives` + * property of the `@Component` or `@View` decorators. + * + * ### Example + * + * Instead of writing: + * + * ```typescript + * import {NgClass, NgIf, NgFor, NgSwitch, NgSwitchWhen, NgSwitchDefault, NgModel, NgForm} from + * 'angular2/angular2'; + * import {OtherDirective} from './myDirectives'; + * + * @Component({ + * selector: 'my-component', + * templateUrl: 'myComponent.html', + * directives: [NgClass, NgIf, NgFor, NgSwitch, NgSwitchWhen, NgSwitchDefault, NgModel, NgForm, + * OtherDirective] + * }) + * export class MyComponent { + * ... + * } + * ``` + * one could import all the common directives at once: + * + * ```typescript + * import {COMMON_DIRECTIVES} from 'angular2/angular2'; + * import {OtherDirective} from './myDirectives'; + * + * @Component({ + * selector: 'my-component', + * templateUrl: 'myComponent.html', + * directives: [COMMON_DIRECTIVES, OtherDirective] + * }) + * export class MyComponent { + * ... + * } + * ``` + */ +export const COMMON_DIRECTIVES: Type[][] = CONST_EXPR([CORE_DIRECTIVES, FORM_DIRECTIVES]); \ No newline at end of file diff --git a/modules/angular2/core.ts b/modules/angular2/core.ts index 10a89e462d..7a8efa80e3 100644 --- a/modules/angular2/core.ts +++ b/modules/angular2/core.ts @@ -19,3 +19,4 @@ export * from './src/core/directives'; export * from './src/core/forms'; export * from './src/core/debug'; export * from './src/core/change_detection'; +export * from './src/core/compiler/ambient'; diff --git a/modules/angular2/src/core/application_ref.ts b/modules/angular2/src/core/application_ref.ts index cdf5e3f84e..b74f089982 100644 --- a/modules/angular2/src/core/application_ref.ts +++ b/modules/angular2/src/core/application_ref.ts @@ -38,7 +38,6 @@ import {AppViewManager} from 'angular2/src/core/linker/view_manager'; import {AppViewManagerUtils} from 'angular2/src/core/linker/view_manager_utils'; import {AppViewListener} from 'angular2/src/core/linker/view_listener'; import {ProtoViewFactory} from './linker/proto_view_factory'; -import {DEFAULT_PIPES} from 'angular2/src/core/pipes'; import {ViewResolver} from './linker/view_resolver'; import {DirectiveResolver} from './linker/directive_resolver'; import {PipeResolver} from './linker/pipe_resolver'; @@ -48,6 +47,8 @@ import {AppViewManager_} from "./linker/view_manager"; import {Compiler_} from "./linker/compiler"; import {wtfLeave, wtfCreateScope, WtfScopeFn} from './profile/profile'; import {ChangeDetectorRef} from 'angular2/src/core/change_detection/change_detector_ref'; +import {AMBIENT_DIRECTIVES, AMBIENT_PIPES} from "angular2/src/core/compiler/ambient"; +import {COMMON_DIRECTIVES, COMMON_PIPES} from "angular2/common"; /** * Constructs the set of providers meant for use at the platform level. @@ -104,11 +105,12 @@ export function applicationCommonProviders(): Array { AppViewListener, ProtoViewFactory, ViewResolver, - DEFAULT_PIPES, provide(IterableDiffers, {useValue: defaultIterableDiffers}), provide(KeyValueDiffers, {useValue: defaultKeyValueDiffers}), DirectiveResolver, PipeResolver, + provide(AMBIENT_PIPES, {useValue: COMMON_PIPES, multi: true}), + provide(AMBIENT_DIRECTIVES, {useValue: COMMON_DIRECTIVES, multi: true}), provide(DynamicComponentLoader, {useClass: DynamicComponentLoader_}) ]; } diff --git a/modules/angular2/src/core/compiler/ambient.ts b/modules/angular2/src/core/compiler/ambient.ts new file mode 100644 index 0000000000..d0a1de4ebf --- /dev/null +++ b/modules/angular2/src/core/compiler/ambient.ts @@ -0,0 +1,53 @@ +import {OpaqueToken} from "angular2/src/core/di"; +import {CONST_EXPR} from "angular2/src/core/facade/lang"; + +/** + * A token that can be provided when bootstraping an application to make an array of directives + * available in every component of the application. + * + * ### Example + * + * ```typescript + * import {AMBIENT_DIRECTIVES} from 'angular2/angular2'; + * import {OtherDirective} from './myDirectives'; + * + * @Component({ + * selector: 'my-component', + * template: ` + * + * + * ` + * }) + * export class MyComponent { + * ... + * } + * + * bootstrap(MyComponent, [provide(AMBIENT_DIRECTIVES, {useValue: [OtherDirective], multi:true})]); + * ``` + */ +export const AMBIENT_DIRECTIVES: OpaqueToken = CONST_EXPR(new OpaqueToken("Ambient Directives")); + +/** + * A token that can be provided when bootstraping an application to make an array of pipes + * available in every component of the application. + * + * ### Example + * + * ```typescript + * import {AMBIENT_PIPES} from 'angular2/angular2'; + * import {OtherPipe} from './myPipe'; + * + * @Component({ + * selector: 'my-component', + * template: ` + * {{123 | other-pipe}} + * ` + * }) + * export class MyComponent { + * ... + * } + * + * bootstrap(MyComponent, [provide(AMBIENT_PIPES, {useValue: [OtherPipe], multi:true})]); + * ``` + */ +export const AMBIENT_PIPES: OpaqueToken = CONST_EXPR(new OpaqueToken("Ambient Pipes")); diff --git a/modules/angular2/src/core/compiler/compiler.ts b/modules/angular2/src/core/compiler/compiler.ts index 09ac936f90..a87cfec5f5 100644 --- a/modules/angular2/src/core/compiler/compiler.ts +++ b/modules/angular2/src/core/compiler/compiler.ts @@ -6,6 +6,7 @@ export { CompileTemplateMetadata } from './directive_metadata'; export {SourceModule, SourceWithImports} from './source_module'; +export {AMBIENT_DIRECTIVES, AMBIENT_PIPES} from './ambient'; import {assertionsEnabled, Type} from 'angular2/src/core/facade/lang'; import {provide, Provider} from 'angular2/src/core/di'; diff --git a/modules/angular2/src/core/compiler/runtime_metadata.ts b/modules/angular2/src/core/compiler/runtime_metadata.ts index 2dfbf27484..9baa736be9 100644 --- a/modules/angular2/src/core/compiler/runtime_metadata.ts +++ b/modules/angular2/src/core/compiler/runtime_metadata.ts @@ -17,14 +17,16 @@ import {ViewMetadata} from 'angular2/src/core/metadata/view'; import {hasLifecycleHook} from 'angular2/src/core/linker/directive_lifecycle_reflector'; import {LifecycleHooks, LIFECYCLE_HOOKS_VALUES} from 'angular2/src/core/linker/interfaces'; import {reflector} from 'angular2/src/core/reflection/reflection'; -import {Injectable} from 'angular2/src/core/di'; +import {Injectable, Inject, Optional} from 'angular2/src/core/di'; +import {AMBIENT_DIRECTIVES} from 'angular2/src/core/compiler/ambient'; import {MODULE_SUFFIX} from './util'; @Injectable() export class RuntimeMetadataResolver { private _cache = new Map(); - constructor(private _directiveResolver: DirectiveResolver, private _viewResolver: ViewResolver) {} + constructor(private _directiveResolver: DirectiveResolver, private _viewResolver: ViewResolver, + @Optional() @Inject(AMBIENT_DIRECTIVES) private _ambientDirectives: Type[]) {} getMetadata(directiveType: Type): cpl.CompileDirectiveMetadata { var meta = this._cache.get(directiveType); @@ -68,7 +70,7 @@ export class RuntimeMetadataResolver { getViewDirectivesMetadata(component: Type): cpl.CompileDirectiveMetadata[] { var view = this._viewResolver.resolve(component); - var directives = flattenDirectives(view); + var directives = flattenDirectives(view, this._ambientDirectives); for (var i = 0; i < directives.length; i++) { if (!isValidDirective(directives[i])) { throw new BaseException( @@ -86,18 +88,22 @@ function removeDuplicates(items: any[]): any[] { return MapWrapper.keys(m); } -function flattenDirectives(view: ViewMetadata): Type[] { - if (isBlank(view.directives)) return []; - var directives = []; - flattenList(view.directives, directives); +function flattenDirectives(view: ViewMetadata, ambientDirectives: any[]): Type[] { + let directives = []; + if (isPresent(ambientDirectives)) { + flattenArray(ambientDirectives, directives); + } + if (isPresent(view.directives)) { + flattenArray(view.directives, directives); + } return directives; } -function flattenList(tree: any[], out: Array): void { +function flattenArray(tree: any[], out: Array): void { for (var i = 0; i < tree.length; i++) { var item = resolveForwardRef(tree[i]); if (isArray(item)) { - flattenList(item, out); + flattenArray(item, out); } else { out.push(item); } diff --git a/modules/angular2/src/core/linker/proto_view_factory.ts b/modules/angular2/src/core/linker/proto_view_factory.ts index 8e7bd33471..c6ab82fe81 100644 --- a/modules/angular2/src/core/linker/proto_view_factory.ts +++ b/modules/angular2/src/core/linker/proto_view_factory.ts @@ -1,9 +1,8 @@ -import {ListWrapper} from 'angular2/src/core/facade/collection'; import {isPresent, isBlank, Type, isArray, isNumber} from 'angular2/src/core/facade/lang'; import {RenderProtoViewRef} from 'angular2/src/core/render/api'; -import {Injectable, Provider, resolveForwardRef, Inject} from 'angular2/src/core/di'; +import {Optional, Injectable, Provider, resolveForwardRef, Inject} from 'angular2/src/core/di'; import {PipeProvider} from '../pipes/pipe_provider'; import {ProtoPipes} from '../pipes/pipes'; @@ -15,7 +14,7 @@ import {DirectiveResolver} from './directive_resolver'; import {ViewResolver} from './view_resolver'; import {PipeResolver} from './pipe_resolver'; import {ViewMetadata} from '../metadata/view'; -import {DEFAULT_PIPES_TOKEN} from 'angular2/src/core/pipes'; +import {AMBIENT_PIPES} from 'angular2/src/core/compiler/ambient'; import { visitAllCommands, @@ -38,15 +37,10 @@ import {APP_ID} from 'angular2/src/core/application_tokens'; @Injectable() export class ProtoViewFactory { private _cache: Map = new Map(); - private _defaultPipes: Type[]; - private _appId: string; - - constructor(private _renderer: Renderer, @Inject(DEFAULT_PIPES_TOKEN) defaultPipes: Type[], + constructor(private _renderer: Renderer, + @Optional() @Inject(AMBIENT_PIPES) private _ambientPipes: Array, private _directiveResolver: DirectiveResolver, private _viewResolver: ViewResolver, - private _pipeResolver: PipeResolver, @Inject(APP_ID) appId: string) { - this._defaultPipes = defaultPipes; - this._appId = appId; - } + private _pipeResolver: PipeResolver, @Inject(APP_ID) private _appId: string) {} clearCache() { this._cache.clear(); } @@ -118,9 +112,13 @@ export class ProtoViewFactory { } private _flattenPipes(view: ViewMetadata): any[] { - if (isBlank(view.pipes)) return this._defaultPipes; - var pipes = ListWrapper.clone(this._defaultPipes); - _flattenList(view.pipes, pipes); + let pipes = []; + if (isPresent(this._ambientPipes)) { + _flattenArray(this._ambientPipes, pipes); + } + if (isPresent(view.pipes)) { + _flattenArray(view.pipes, pipes); + } return pipes; } } @@ -313,11 +311,11 @@ function arrayToMap(arr: string[], inverse: boolean): Map { return result; } -function _flattenList(tree: any[], out: Array): void { +function _flattenArray(tree: any[], out: Array): void { for (var i = 0; i < tree.length; i++) { var item = resolveForwardRef(tree[i]); if (isArray(item)) { - _flattenList(item, out); + _flattenArray(item, out); } else { out.push(item); } diff --git a/modules/angular2/src/core/pipes.ts b/modules/angular2/src/core/pipes.ts index 8487d3ef89..a1dea1f563 100644 --- a/modules/angular2/src/core/pipes.ts +++ b/modules/angular2/src/core/pipes.ts @@ -3,12 +3,31 @@ * @description * This module provides a set of common Pipes. */ +import {AsyncPipe} from './pipes/async_pipe'; +import {UpperCasePipe} from './pipes/uppercase_pipe'; +import {LowerCasePipe} from './pipes/lowercase_pipe'; +import {JsonPipe} from './pipes/json_pipe'; +import {SlicePipe} from './pipes/slice_pipe'; +import {DatePipe} from './pipes/date_pipe'; +import {DecimalPipe, PercentPipe, CurrencyPipe} from './pipes/number_pipe'; +import {CONST_EXPR} from 'angular2/src/core/facade/lang'; export {AsyncPipe} from './pipes/async_pipe'; export {DatePipe} from './pipes/date_pipe'; -export {DEFAULT_PIPES, DEFAULT_PIPES_TOKEN} from './pipes/default_pipes'; export {JsonPipe} from './pipes/json_pipe'; export {SlicePipe} from './pipes/slice_pipe'; export {LowerCasePipe} from './pipes/lowercase_pipe'; export {NumberPipe, DecimalPipe, PercentPipe, CurrencyPipe} from './pipes/number_pipe'; export {UpperCasePipe} from './pipes/uppercase_pipe'; + +export const COMMON_PIPES = CONST_EXPR([ + AsyncPipe, + UpperCasePipe, + LowerCasePipe, + JsonPipe, + SlicePipe, + DecimalPipe, + PercentPipe, + CurrencyPipe, + DatePipe +]); diff --git a/modules/angular2/src/core/pipes/default_pipes.ts b/modules/angular2/src/core/pipes/default_pipes.ts deleted file mode 100644 index 0c9179490c..0000000000 --- a/modules/angular2/src/core/pipes/default_pipes.ts +++ /dev/null @@ -1,27 +0,0 @@ -import {AsyncPipe} from './async_pipe'; -import {UpperCasePipe} from './uppercase_pipe'; -import {LowerCasePipe} from './lowercase_pipe'; -import {JsonPipe} from './json_pipe'; -import {SlicePipe} from './slice_pipe'; -import {DatePipe} from './date_pipe'; -import {DecimalPipe, PercentPipe, CurrencyPipe} from './number_pipe'; - -import {CONST_EXPR} from 'angular2/src/core/facade/lang'; -import {Provider, OpaqueToken} from 'angular2/src/core/di'; - -const DEFAULT_PIPES_LIST = CONST_EXPR([ - AsyncPipe, - UpperCasePipe, - LowerCasePipe, - JsonPipe, - SlicePipe, - DecimalPipe, - PercentPipe, - CurrencyPipe, - DatePipe -]); - -export const DEFAULT_PIPES_TOKEN: OpaqueToken = CONST_EXPR(new OpaqueToken("Default Pipes")); - -export const DEFAULT_PIPES: Provider = - CONST_EXPR(new Provider(DEFAULT_PIPES_TOKEN, {useValue: DEFAULT_PIPES_LIST})); diff --git a/modules/angular2/src/testing/test_injector.ts b/modules/angular2/src/testing/test_injector.ts index ce7494634a..eb3554b524 100644 --- a/modules/angular2/src/testing/test_injector.ts +++ b/modules/angular2/src/testing/test_injector.ts @@ -1,5 +1,4 @@ import {provide, Provider} from 'angular2/src/core/di'; -import {DEFAULT_PIPES} from 'angular2/src/core/pipes'; import {AnimationBuilder} from 'angular2/src/animate/animation_builder'; import {MockAnimationBuilder} from 'angular2/src/mock/animation_builder_mock'; @@ -107,7 +106,6 @@ function _getAppBindings() { ProtoViewFactory, provide(DirectiveResolver, {useClass: MockDirectiveResolver}), provide(ViewResolver, {useClass: MockViewResolver}), - DEFAULT_PIPES, provide(IterableDiffers, {useValue: defaultIterableDiffers}), provide(KeyValueDiffers, {useValue: defaultKeyValueDiffers}), Log, diff --git a/modules/angular2/src/web_workers/ui/di_bindings.ts b/modules/angular2/src/web_workers/ui/di_bindings.ts index 24351a3203..9ce2bf54d1 100644 --- a/modules/angular2/src/web_workers/ui/di_bindings.ts +++ b/modules/angular2/src/web_workers/ui/di_bindings.ts @@ -1,7 +1,6 @@ // TODO (jteplitz602): This whole file is nearly identical to core/application.ts. // There should be a way to refactor application so that this file is unnecessary. See #3277 import {Injector, provide, Provider} from "angular2/src/core/di"; -import {DEFAULT_PIPES} from 'angular2/src/core/pipes'; import {AnimationBuilder} from 'angular2/src/animate/animation_builder'; import {BrowserDetails} from 'angular2/src/animate/browser_details'; import {Reflector, reflector} from 'angular2/src/core/reflection/reflection'; @@ -64,6 +63,8 @@ import { ClientMessageBrokerFactory, ClientMessageBrokerFactory_ } from 'angular2/src/web_workers/shared/client_message_broker'; +import {AMBIENT_DIRECTIVES, AMBIENT_PIPES} from "angular2/src/core/compiler/ambient"; +import {COMMON_DIRECTIVES, COMMON_PIPES} from "angular2/common"; var _rootInjector: Injector; @@ -96,7 +97,8 @@ function _injectorProviders(): any[] { AppViewListener, ProtoViewFactory, ViewResolver, - DEFAULT_PIPES, + provide(AMBIENT_PIPES, {useValue: COMMON_PIPES, multi: true}), + provide(AMBIENT_DIRECTIVES, {useValue: COMMON_DIRECTIVES, multi: true}), DirectiveResolver, Parser, Lexer, diff --git a/modules/angular2/test/core/compiler/runtime_metadata_spec.ts b/modules/angular2/test/core/compiler/runtime_metadata_spec.ts index a767b8474d..17965066c8 100644 --- a/modules/angular2/test/core/compiler/runtime_metadata_spec.ts +++ b/modules/angular2/test/core/compiler/runtime_metadata_spec.ts @@ -10,7 +10,7 @@ import { afterEach, AsyncTestCompleter, inject, - beforeEachBindings + beforeEachProviders } from 'angular2/testing_internal'; import {stringify} from 'angular2/src/core/facade/lang'; @@ -30,15 +30,17 @@ import { AfterContentChecked, AfterViewInit, AfterViewChecked, - SimpleChange + SimpleChange, + provide } from 'angular2/core'; import {TEST_PROVIDERS} from './test_bindings'; import {MODULE_SUFFIX, IS_DART} from 'angular2/src/core/compiler/util'; +import {AMBIENT_DIRECTIVES} from 'angular2/src/core/compiler/ambient'; export function main() { describe('RuntimeMetadataResolver', () => { - beforeEachBindings(() => TEST_PROVIDERS); + beforeEachProviders(() => TEST_PROVIDERS); describe('getMetadata', () => { it('should read metadata', @@ -82,6 +84,19 @@ export function main() { expect(resolver.getViewDirectivesMetadata(ComponentWithEverything)) .toEqual([resolver.getMetadata(DirectiveWithoutModuleId)]); })); + + describe("ambient directives", () => { + beforeEachProviders(() => [provide(AMBIENT_DIRECTIVES, {useValue: [ADirective]})]); + + it('should include ambient directives when available', + inject([RuntimeMetadataResolver], (resolver: RuntimeMetadataResolver) => { + expect(resolver.getViewDirectivesMetadata(ComponentWithEverything)) + .toEqual([ + resolver.getMetadata(ADirective), + resolver.getMetadata(DirectiveWithoutModuleId) + ]); + })); + }); }); }); @@ -89,6 +104,10 @@ export function main() { +@Directive({selector: 'a-directive'}) +class ADirective { +} + @Directive({selector: 'someSelector'}) class DirectiveWithoutModuleId { } diff --git a/modules/angular2/test/core/linker/integration_spec.ts b/modules/angular2/test/core/linker/integration_spec.ts index e26331f51b..e2bc3ca673 100644 --- a/modules/angular2/test/core/linker/integration_spec.ts +++ b/modules/angular2/test/core/linker/integration_spec.ts @@ -59,6 +59,8 @@ import { NgFor } from 'angular2/core'; +import {AsyncPipe} from 'angular2/common'; + import { PipeTransform, ChangeDetectorRef, @@ -1867,8 +1869,12 @@ class PushCmpWithRef { propagate() { this.ref.markForCheck(); } } -@Component({selector: 'push-cmp-with-async', changeDetection: ChangeDetectionStrategy.OnPush}) -@View({template: '{{field | async}}'}) +@Component({ + selector: 'push-cmp-with-async', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '{{field | async}}', + pipes: [AsyncPipe] +}) @Injectable() class PushCmpWithAsyncPipe { numberOfChecks: number = 0; diff --git a/modules/angular2/test/public_api_spec.ts b/modules/angular2/test/public_api_spec.ts index 3594e58494..9d13af6e09 100644 --- a/modules/angular2/test/public_api_spec.ts +++ b/modules/angular2/test/public_api_spec.ts @@ -147,6 +147,8 @@ var NG_ALL = [ 'By#directive()', 'By', 'CORE_DIRECTIVES', + 'COMMON_DIRECTIVES', + 'AMBIENT_DIRECTIVES:js', 'ChangeDetectionError', 'ChangeDetectionError.context', 'ChangeDetectionError.location', @@ -398,8 +400,8 @@ var NG_ALL = [ 'CyclicDependencyError.message', 'CyclicDependencyError.message=', 'CyclicDependencyError.stackTrace', - 'DEFAULT_PIPES', - 'DEFAULT_PIPES_TOKEN', + 'COMMON_PIPES', + 'AMBIENT_PIPES:js', 'DOCUMENT', 'DatePipe', 'DatePipe.supports()',