refactor(core): change module semantics
This contains major changes to the compiler, bootstrap of the platforms and test environment initialization. Main part of #10043 Closes #10164 BREAKING CHANGE: - Semantics and name of `@AppModule` (now `@NgModule`) changed quite a bit. This is actually not breaking as `@AppModules` were not part of rc.4. We will have detailed docs on `@NgModule` separately. - `coreLoadAndBootstrap` and `coreBootstrap` can't be used any more (without migration support). Use `bootstrapModule` / `bootstrapModuleFactory` instead. - All Components listed in routes have to be part of the `declarations` of an NgModule. Either directly on the bootstrap module / lazy loaded module, or in an NgModule imported by them.
This commit is contained in:
parent
ca16fc29a6
commit
46b212706b
@ -6,9 +6,25 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {NgModule} from '@angular/core';
|
||||||
|
import {COMMON_DIRECTIVES} from './src/common_directives';
|
||||||
|
import {COMMON_PIPES} from './src/pipes';
|
||||||
|
|
||||||
export * from './src/pipes';
|
export * from './src/pipes';
|
||||||
export * from './src/directives';
|
export * from './src/directives';
|
||||||
export * from './src/forms-deprecated';
|
export * from './src/forms-deprecated';
|
||||||
export * from './src/common_directives';
|
export * from './src/common_directives';
|
||||||
export * from './src/location';
|
export * from './src/location';
|
||||||
export {NgLocalization} from './src/localization';
|
export {NgLocalization} from './src/localization';
|
||||||
|
|
||||||
|
// Note: This does not contain the location providers,
|
||||||
|
// as they need some platform specific implementations to work.
|
||||||
|
/**
|
||||||
|
* The module that includes all the basic Angular directives like {@link NgIf}, ${link NgFor}, ...
|
||||||
|
*
|
||||||
|
* @experimental
|
||||||
|
*/
|
||||||
|
@NgModule(
|
||||||
|
{declarations: [COMMON_DIRECTIVES, COMMON_PIPES], exports: [COMMON_DIRECTIVES, COMMON_PIPES]})
|
||||||
|
export class CommonModule {
|
||||||
|
}
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
* Forms providers are not included in default providers; you must import these providers
|
* Forms providers are not included in default providers; you must import these providers
|
||||||
* explicitly.
|
* explicitly.
|
||||||
*/
|
*/
|
||||||
import {AppModule, Type} from '@angular/core';
|
import {NgModule, Type} from '@angular/core';
|
||||||
|
|
||||||
import {FORM_DIRECTIVES} from './forms-deprecated/directives';
|
import {FORM_DIRECTIVES} from './forms-deprecated/directives';
|
||||||
import {RadioControlRegistry} from './forms-deprecated/directives/radio_control_value_accessor';
|
import {RadioControlRegistry} from './forms-deprecated/directives/radio_control_value_accessor';
|
||||||
@ -61,15 +61,15 @@ export const FORM_PROVIDERS: Type[] = /*@ts2dart_const*/[FormBuilder, RadioContr
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The app module for the deprecated forms API.
|
* The ng module for the deprecated forms API.
|
||||||
* @deprecated
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
@AppModule({
|
@NgModule({
|
||||||
providers: [
|
providers: [
|
||||||
FORM_PROVIDERS,
|
FORM_PROVIDERS,
|
||||||
],
|
],
|
||||||
directives: FORM_DIRECTIVES,
|
declarations: FORM_DIRECTIVES,
|
||||||
pipes: []
|
exports: FORM_DIRECTIVES
|
||||||
})
|
})
|
||||||
export class DeprecatedFormsModule {
|
export class DeprecatedFormsModule {
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ import {PromiseWrapper} from '../../src/facade/promise';
|
|||||||
export function main() {
|
export function main() {
|
||||||
describe('integration tests', () => {
|
describe('integration tests', () => {
|
||||||
|
|
||||||
beforeEach(() => { configureModule({modules: [DeprecatedFormsModule]}); });
|
beforeEach(() => configureModule({imports: [DeprecatedFormsModule]}));
|
||||||
|
|
||||||
it('should initialize DOM elements with the given form object',
|
it('should initialize DOM elements with the given form object',
|
||||||
inject(
|
inject(
|
||||||
|
@ -30,13 +30,14 @@ generated code:
|
|||||||
main_module.ts
|
main_module.ts
|
||||||
-------------
|
-------------
|
||||||
import {BrowserModule} from '@angular/platform-browser';
|
import {BrowserModule} from '@angular/platform-browser';
|
||||||
import {Component, AppModule, ApplicationRef} from '@angular/core';
|
import {Component, NgModule, ApplicationRef} from '@angular/core';
|
||||||
|
|
||||||
@Component(...)
|
@Component(...)
|
||||||
export class MyComponent {}
|
export class MyComponent {}
|
||||||
|
|
||||||
@AppModule({
|
@NgModule({
|
||||||
modules: [BrowserModule],
|
imports: [BrowserModule],
|
||||||
|
declarations: [MyComponent],
|
||||||
precompile: [MyComponent]
|
precompile: [MyComponent]
|
||||||
})
|
})
|
||||||
export class MainModule {
|
export class MainModule {
|
||||||
|
@ -8,10 +8,7 @@
|
|||||||
|
|
||||||
import {Component} from '@angular/core';
|
import {Component} from '@angular/core';
|
||||||
|
|
||||||
@Component({
|
@Component({selector: 'my-comp', template: '<div></div>', directives: [NextComp]})
|
||||||
selector: 'my-comp',
|
|
||||||
template: '<div></div>',
|
|
||||||
})
|
|
||||||
export class MultipleComponentsMyComp {
|
export class MultipleComponentsMyComp {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<div [attr.array]="[0]" [attr.map]="{a:1}" title="translate me" i18n-title="meaning|desc">{{ctxProp}}</div>
|
<div [attr.array]="[0]" [attr.map]="{a:1}" title="translate me" i18n-title="meaning|desc">{{ctxProp}}</div>
|
||||||
<form><input type="button" [(ngModel)]="ctxProp"/></form>
|
<form><input type="button" [(ngModel)]="ctxProp" name="first"/></form>
|
||||||
<my-comp *ngIf="ctxBool"></my-comp>
|
<my-comp *ngIf="ctxBool"></my-comp>
|
||||||
<div *ngFor="let x of ctxArr" [attr.value]="x"></div>
|
<div *ngFor="let x of ctxArr" [attr.value]="x"></div>
|
||||||
|
@ -6,8 +6,9 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {FORM_DIRECTIVES, NgFor, NgIf} from '@angular/common';
|
import {NgFor, NgIf} from '@angular/common';
|
||||||
import {Component, Inject} from '@angular/core';
|
import {Component, Inject} from '@angular/core';
|
||||||
|
import {FORM_DIRECTIVES} from '@angular/forms';
|
||||||
|
|
||||||
import {MultipleComponentsMyComp} from './a/multiple_components';
|
import {MultipleComponentsMyComp} from './a/multiple_components';
|
||||||
|
|
||||||
|
@ -10,4 +10,4 @@ import {browserPlatform} from '@angular/platform-browser';
|
|||||||
import {BasicComp} from './basic';
|
import {BasicComp} from './basic';
|
||||||
import {MainModuleNgFactory} from './module.ngfactory';
|
import {MainModuleNgFactory} from './module.ngfactory';
|
||||||
|
|
||||||
MainModuleNgFactory.create().instance.appRef.bootstrap(BasicComp);
|
MainModuleNgFactory.create(null).instance.appRef.bootstrap(BasicComp);
|
||||||
|
@ -6,20 +6,29 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {AppModule, ApplicationRef} from '@angular/core';
|
import {ApplicationRef, NgModule} from '@angular/core';
|
||||||
|
import {FormsModule} from '@angular/forms';
|
||||||
import {BrowserModule} from '@angular/platform-browser';
|
import {BrowserModule} from '@angular/platform-browser';
|
||||||
|
|
||||||
import {AnimateCmp} from './animate';
|
import {AnimateCmp} from './animate';
|
||||||
import {BasicComp} from './basic';
|
import {BasicComp} from './basic';
|
||||||
|
import {CompWithProviders, CompWithReferences} from './features';
|
||||||
|
import {CompUsingRootModuleDirectiveAndPipe, SomeDirectiveInRootModule, SomeLibModule, SomePipeInRootModule, SomeService} from './module_fixtures';
|
||||||
import {CompWithAnalyzePrecompileProvider, CompWithPrecompile} from './precompile';
|
import {CompWithAnalyzePrecompileProvider, CompWithPrecompile} from './precompile';
|
||||||
import {ProjectingComp} from './projection';
|
import {ProjectingComp} from './projection';
|
||||||
import {CompWithChildQuery} from './queries';
|
import {CompWithChildQuery, CompWithDirectiveChild} from './queries';
|
||||||
|
|
||||||
@AppModule({
|
@NgModule({
|
||||||
modules: [BrowserModule],
|
declarations: [
|
||||||
|
SomeDirectiveInRootModule, SomePipeInRootModule, AnimateCmp, BasicComp, CompWithPrecompile,
|
||||||
|
CompWithAnalyzePrecompileProvider, ProjectingComp, CompWithChildQuery, CompWithDirectiveChild,
|
||||||
|
CompUsingRootModuleDirectiveAndPipe, CompWithProviders, CompWithReferences
|
||||||
|
],
|
||||||
|
imports: [BrowserModule, FormsModule, SomeLibModule],
|
||||||
|
providers: [SomeService],
|
||||||
precompile: [
|
precompile: [
|
||||||
AnimateCmp, BasicComp, CompWithPrecompile, CompWithAnalyzePrecompileProvider, ProjectingComp,
|
AnimateCmp, BasicComp, CompWithPrecompile, CompWithAnalyzePrecompileProvider, ProjectingComp,
|
||||||
CompWithChildQuery
|
CompWithChildQuery, CompUsingRootModuleDirectiveAndPipe
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class MainModule {
|
export class MainModule {
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {LowerCasePipe, NgIf} from '@angular/common';
|
import {LowerCasePipe, NgIf} from '@angular/common';
|
||||||
import {ANALYZE_FOR_PRECOMPILE, AppModule, Component, ComponentFactoryResolver, Directive, Inject, Injectable, Input, OpaqueToken, Pipe} from '@angular/core';
|
import {ANALYZE_FOR_PRECOMPILE, Component, ComponentFactoryResolver, Directive, Inject, Injectable, Input, NgModule, OpaqueToken, Pipe} from '@angular/core';
|
||||||
import {BrowserModule} from '@angular/platform-browser';
|
import {BrowserModule} from '@angular/platform-browser';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -16,50 +16,37 @@ export class SomeService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class NestedService {
|
export class ServiceUsingLibModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Directive({selector: '[someDir]', host: {'[title]': 'someDir'}})
|
@Directive({selector: '[someDir]', host: {'[title]': 'someDir'}})
|
||||||
export class SomeDirective {
|
export class SomeDirectiveInRootModule {
|
||||||
|
@Input()
|
||||||
|
someDir: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Directive({selector: '[someDir]', host: {'[title]': 'someDir'}})
|
||||||
|
export class SomeDirectiveInLibModule {
|
||||||
@Input()
|
@Input()
|
||||||
someDir: string;
|
someDir: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Pipe({name: 'somePipe'})
|
@Pipe({name: 'somePipe'})
|
||||||
export class SomePipe {
|
export class SomePipeInRootModule {
|
||||||
transform(value: string): any { return `transformed ${value}`; }
|
transform(value: string): any { return `transformed ${value}`; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({selector: 'cmp', template: `<div [someDir]="'someValue' | somePipe"></div>`})
|
@Pipe({name: 'somePipe'})
|
||||||
export class SomeComp {
|
export class SomePipeInLibModule {
|
||||||
constructor() {}
|
transform(value: string): any { return `transformed ${value}`; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({selector: 'parent', template: `<cmp></cmp>`, directives: [SomeComp]})
|
@Component({selector: 'comp', template: `<div [someDir]="'someValue' | somePipe"></div>`})
|
||||||
export class ParentComp {
|
export class CompUsingRootModuleDirectiveAndPipe {
|
||||||
}
|
}
|
||||||
|
|
||||||
@AppModule({providers: [NestedService]})
|
@Component({selector: 'comp', template: `<div [someDir]="'someValue' | somePipe"></div>`})
|
||||||
export class NestedModule {
|
export class CompUsingLibModuleDirectiveAndPipe {
|
||||||
}
|
|
||||||
|
|
||||||
@AppModule({
|
|
||||||
directives: [SomeDirective],
|
|
||||||
pipes: [SomePipe],
|
|
||||||
providers: [SomeService],
|
|
||||||
precompile: [SomeComp],
|
|
||||||
modules: [NestedModule, BrowserModule]
|
|
||||||
})
|
|
||||||
export class SomeModule {
|
|
||||||
}
|
|
||||||
|
|
||||||
@AppModule({
|
|
||||||
directives: [SomeDirective],
|
|
||||||
pipes: [SomePipe],
|
|
||||||
precompile: [ParentComp],
|
|
||||||
modules: [BrowserModule]
|
|
||||||
})
|
|
||||||
export class SomeModuleUsingParentComp {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SOME_TOKEN = new OpaqueToken('someToken');
|
export const SOME_TOKEN = new OpaqueToken('someToken');
|
||||||
@ -71,7 +58,13 @@ export function provideValueWithPrecompile(value: any) {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@AppModule({providers: [provideValueWithPrecompile([{a: 'b', component: SomeComp}])]})
|
@NgModule({
|
||||||
export class SomeModuleWithAnalyzePrecompileProvider {
|
declarations: [SomeDirectiveInLibModule, SomePipeInLibModule, CompUsingLibModuleDirectiveAndPipe],
|
||||||
constructor(@Inject(SOME_TOKEN) public providedValue: any) {}
|
precompile: [CompUsingLibModuleDirectiveAndPipe],
|
||||||
|
providers: [
|
||||||
|
ServiceUsingLibModule,
|
||||||
|
provideValueWithPrecompile([{a: 'b', component: CompUsingLibModuleDirectiveAndPipe}])
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class SomeLibModule {
|
||||||
}
|
}
|
||||||
|
@ -1,62 +0,0 @@
|
|||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright Google Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by an MIT-style license that can be
|
|
||||||
* found in the LICENSE file at https://angular.io/license
|
|
||||||
*/
|
|
||||||
import './init';
|
|
||||||
import {NestedModule, NestedService, ParentComp, SomeComp, SomeModule, SomeService} from '../src/module_fixtures';
|
|
||||||
import {SomeModuleNgFactory, SomeModuleUsingParentCompNgFactory, SomeModuleWithAnalyzePrecompileProviderNgFactory} from '../src/module_fixtures.ngfactory';
|
|
||||||
import {createComponent, createModule} from './util';
|
|
||||||
|
|
||||||
describe('AppModule', () => {
|
|
||||||
it('should support providers', () => {
|
|
||||||
var moduleRef = createModule(SomeModuleNgFactory);
|
|
||||||
expect(moduleRef.instance instanceof SomeModule).toBe(true);
|
|
||||||
expect(moduleRef.injector.get(SomeModule) instanceof SomeModule).toBe(true);
|
|
||||||
expect(moduleRef.injector.get(SomeService) instanceof SomeService).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should support precompile components', () => {
|
|
||||||
var moduleRef = createModule(SomeModuleNgFactory);
|
|
||||||
var cf = moduleRef.componentFactoryResolver.resolveComponentFactory(SomeComp);
|
|
||||||
expect(cf.componentType).toBe(SomeComp);
|
|
||||||
var compRef = cf.create(moduleRef.injector);
|
|
||||||
expect(compRef.instance instanceof SomeComp).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should support precompile via the ANALYZE_FOR_PRECOMPILE provider and function providers in components',
|
|
||||||
() => {
|
|
||||||
const moduleRef = createModule(SomeModuleWithAnalyzePrecompileProviderNgFactory);
|
|
||||||
const cf = moduleRef.componentFactoryResolver.resolveComponentFactory(SomeComp);
|
|
||||||
expect(cf.componentType).toBe(SomeComp);
|
|
||||||
// check that the function call that created the provider for ANALYZE_FOR_PRECOMPILE worked.
|
|
||||||
expect(moduleRef.instance.providedValue).toEqual([{a: 'b', component: SomeComp}]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should support module directives and pipes', () => {
|
|
||||||
var compFixture = createComponent(SomeComp, SomeModuleNgFactory);
|
|
||||||
compFixture.detectChanges();
|
|
||||||
|
|
||||||
var debugElement = compFixture.debugElement;
|
|
||||||
expect(debugElement.children[0].properties['title']).toBe('transformed someValue');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should support module directives and pipes on nested components', () => {
|
|
||||||
var compFixture = createComponent(ParentComp, SomeModuleUsingParentCompNgFactory);
|
|
||||||
compFixture.detectChanges();
|
|
||||||
|
|
||||||
var debugElement = compFixture.debugElement;
|
|
||||||
debugElement = debugElement.children[0];
|
|
||||||
expect(debugElement.children[0].properties['title']).toBe('transformed someValue');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should support child moduless', () => {
|
|
||||||
var moduleRef = createModule(SomeModuleNgFactory);
|
|
||||||
expect(moduleRef.instance instanceof SomeModule).toBe(true);
|
|
||||||
expect(moduleRef.injector.get(NestedModule) instanceof NestedModule).toBe(true);
|
|
||||||
expect(moduleRef.injector.get(NestedService) instanceof NestedService).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
@ -0,0 +1,63 @@
|
|||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright Google Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by an MIT-style license that can be
|
||||||
|
* found in the LICENSE file at https://angular.io/license
|
||||||
|
*/
|
||||||
|
import './init';
|
||||||
|
|
||||||
|
import {MainModule} from '../src/module';
|
||||||
|
import {CompUsingLibModuleDirectiveAndPipe, CompUsingRootModuleDirectiveAndPipe, SOME_TOKEN, ServiceUsingLibModule, SomeLibModule, SomeService} from '../src/module_fixtures';
|
||||||
|
|
||||||
|
import {createComponent, createModule} from './util';
|
||||||
|
|
||||||
|
describe('NgModule', () => {
|
||||||
|
it('should support providers', () => {
|
||||||
|
const moduleRef = createModule();
|
||||||
|
expect(moduleRef.instance instanceof MainModule).toBe(true);
|
||||||
|
expect(moduleRef.injector.get(MainModule) instanceof MainModule).toBe(true);
|
||||||
|
expect(moduleRef.injector.get(SomeService) instanceof SomeService).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support precompile components', () => {
|
||||||
|
const moduleRef = createModule();
|
||||||
|
const cf = moduleRef.componentFactoryResolver.resolveComponentFactory(
|
||||||
|
CompUsingRootModuleDirectiveAndPipe);
|
||||||
|
expect(cf.componentType).toBe(CompUsingRootModuleDirectiveAndPipe);
|
||||||
|
const compRef = cf.create(moduleRef.injector);
|
||||||
|
expect(compRef.instance instanceof CompUsingRootModuleDirectiveAndPipe).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support precompile via the ANALYZE_FOR_PRECOMPILE provider and function providers in components',
|
||||||
|
() => {
|
||||||
|
const moduleRef = createModule();
|
||||||
|
const cf = moduleRef.componentFactoryResolver.resolveComponentFactory(
|
||||||
|
CompUsingRootModuleDirectiveAndPipe);
|
||||||
|
expect(cf.componentType).toBe(CompUsingRootModuleDirectiveAndPipe);
|
||||||
|
// check that the function call that created the provider for ANALYZE_FOR_PRECOMPILE worked.
|
||||||
|
expect(moduleRef.injector.get(SOME_TOKEN)).toEqual([
|
||||||
|
{a: 'b', component: CompUsingLibModuleDirectiveAndPipe}
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support module directives and pipes', () => {
|
||||||
|
const compFixture = createComponent(CompUsingRootModuleDirectiveAndPipe);
|
||||||
|
compFixture.detectChanges();
|
||||||
|
|
||||||
|
const debugElement = compFixture.debugElement;
|
||||||
|
expect(debugElement.children[0].properties['title']).toBe('transformed someValue');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support module directives and pipes on lib modules', () => {
|
||||||
|
const compFixture = createComponent(CompUsingLibModuleDirectiveAndPipe);
|
||||||
|
compFixture.detectChanges();
|
||||||
|
|
||||||
|
const debugElement = compFixture.debugElement;
|
||||||
|
expect(debugElement.children[0].properties['title']).toBe('transformed someValue');
|
||||||
|
|
||||||
|
expect(debugElement.injector.get(SomeLibModule) instanceof SomeLibModule).toBe(true);
|
||||||
|
expect(debugElement.injector.get(ServiceUsingLibModule) instanceof ServiceUsingLibModule)
|
||||||
|
.toBe(true);
|
||||||
|
});
|
||||||
|
});
|
@ -6,23 +6,19 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {AppModuleFactory, AppModuleRef, bootstrapModuleFactory} from '@angular/core';
|
import {NgModuleFactory, NgModuleRef, bootstrapModuleFactory} from '@angular/core';
|
||||||
import {ComponentFixture} from '@angular/core/testing';
|
import {ComponentFixture} from '@angular/core/testing';
|
||||||
import {serverPlatform} from '@angular/platform-server';
|
import {serverPlatform} from '@angular/platform-server';
|
||||||
|
|
||||||
|
import {MainModule} from '../src/module';
|
||||||
import {MainModuleNgFactory} from '../src/module.ngfactory';
|
import {MainModuleNgFactory} from '../src/module.ngfactory';
|
||||||
|
|
||||||
export function createModule<M>(factory: AppModuleFactory<M>): AppModuleRef<M> {
|
export function createModule(): NgModuleRef<MainModule> {
|
||||||
return bootstrapModuleFactory(factory, serverPlatform());
|
return bootstrapModuleFactory(MainModuleNgFactory, serverPlatform());
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createComponent<C>(
|
export function createComponent<C>(comp: {new (...args: any[]): C}): ComponentFixture<C> {
|
||||||
comp: {new (...args: any[]): C},
|
const moduleRef = createModule();
|
||||||
moduleFactory: AppModuleFactory<any> = null): ComponentFixture<C> {
|
|
||||||
if (!moduleFactory) {
|
|
||||||
moduleFactory = MainModuleNgFactory;
|
|
||||||
}
|
|
||||||
const moduleRef = createModule(moduleFactory);
|
|
||||||
const compRef =
|
const compRef =
|
||||||
moduleRef.componentFactoryResolver.resolveComponentFactory(comp).create(moduleRef.injector);
|
moduleRef.componentFactoryResolver.resolveComponentFactory(comp).create(moduleRef.injector);
|
||||||
return new ComponentFixture(compRef, null, null);
|
return new ComponentFixture(compRef, null, null);
|
||||||
|
@ -11,12 +11,12 @@
|
|||||||
* Intended to be used in a build step.
|
* Intended to be used in a build step.
|
||||||
*/
|
*/
|
||||||
import * as compiler from '@angular/compiler';
|
import * as compiler from '@angular/compiler';
|
||||||
import {AppModuleMetadata, ComponentMetadata, ViewEncapsulation} from '@angular/core';
|
import {ComponentMetadata, NgModuleMetadata, ViewEncapsulation} from '@angular/core';
|
||||||
import {AngularCompilerOptions} from '@angular/tsc-wrapped';
|
import {AngularCompilerOptions} from '@angular/tsc-wrapped';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
|
|
||||||
import {AppModuleCompiler, CompileMetadataResolver, DirectiveNormalizer, DomElementSchemaRegistry, HtmlParser, Lexer, Parser, StyleCompiler, TemplateParser, TypeScriptEmitter, ViewCompiler} from './compiler_private';
|
import {CompileMetadataResolver, DirectiveNormalizer, DomElementSchemaRegistry, HtmlParser, Lexer, NgModuleCompiler, Parser, StyleCompiler, TemplateParser, TypeScriptEmitter, ViewCompiler} from './compiler_private';
|
||||||
import {ReflectorHost, ReflectorHostContext} from './reflector_host';
|
import {ReflectorHost, ReflectorHostContext} from './reflector_host';
|
||||||
import {StaticAndDynamicReflectionCapabilities} from './static_reflection_capabilities';
|
import {StaticAndDynamicReflectionCapabilities} from './static_reflection_capabilities';
|
||||||
import {StaticReflector, StaticSymbol} from './static_reflector';
|
import {StaticReflector, StaticSymbol} from './static_reflector';
|
||||||
@ -39,7 +39,7 @@ export class CodeGenerator {
|
|||||||
|
|
||||||
private readFileMetadata(absSourcePath: string): FileMetadata {
|
private readFileMetadata(absSourcePath: string): FileMetadata {
|
||||||
const moduleMetadata = this.staticReflector.getModuleMetadata(absSourcePath);
|
const moduleMetadata = this.staticReflector.getModuleMetadata(absSourcePath);
|
||||||
const result: FileMetadata = {components: [], appModules: [], fileUrl: absSourcePath};
|
const result: FileMetadata = {components: [], ngModules: [], fileUrl: absSourcePath};
|
||||||
if (!moduleMetadata) {
|
if (!moduleMetadata) {
|
||||||
console.log(`WARNING: no metadata found for ${absSourcePath}`);
|
console.log(`WARNING: no metadata found for ${absSourcePath}`);
|
||||||
return result;
|
return result;
|
||||||
@ -57,8 +57,8 @@ export class CodeGenerator {
|
|||||||
const staticType = this.reflectorHost.findDeclaration(absSourcePath, symbol, absSourcePath);
|
const staticType = this.reflectorHost.findDeclaration(absSourcePath, symbol, absSourcePath);
|
||||||
const annotations = this.staticReflector.annotations(staticType);
|
const annotations = this.staticReflector.annotations(staticType);
|
||||||
annotations.forEach((annotation) => {
|
annotations.forEach((annotation) => {
|
||||||
if (annotation instanceof AppModuleMetadata) {
|
if (annotation instanceof NgModuleMetadata) {
|
||||||
result.appModules.push(staticType);
|
result.ngModules.push(staticType);
|
||||||
} else if (annotation instanceof ComponentMetadata) {
|
} else if (annotation instanceof ComponentMetadata) {
|
||||||
result.components.push(staticType);
|
result.components.push(staticType);
|
||||||
}
|
}
|
||||||
@ -86,17 +86,17 @@ export class CodeGenerator {
|
|||||||
let filePaths =
|
let filePaths =
|
||||||
this.program.getSourceFiles().map(sf => sf.fileName).filter(f => !GENERATED_FILES.test(f));
|
this.program.getSourceFiles().map(sf => sf.fileName).filter(f => !GENERATED_FILES.test(f));
|
||||||
let fileMetas = filePaths.map((filePath) => this.readFileMetadata(filePath));
|
let fileMetas = filePaths.map((filePath) => this.readFileMetadata(filePath));
|
||||||
let appModules = fileMetas.reduce((appModules, fileMeta) => {
|
let ngModules = fileMetas.reduce((ngModules, fileMeta) => {
|
||||||
appModules.push(...fileMeta.appModules);
|
ngModules.push(...fileMeta.ngModules);
|
||||||
return appModules;
|
return ngModules;
|
||||||
}, <StaticSymbol[]>[]);
|
}, <StaticSymbol[]>[]);
|
||||||
let analyzedAppModules = this.compiler.analyzeModules(appModules);
|
let analyzedNgModules = this.compiler.analyzeModules(ngModules);
|
||||||
return Promise
|
return Promise
|
||||||
.all(fileMetas.map(
|
.all(fileMetas.map(
|
||||||
(fileMeta) => this.compiler
|
(fileMeta) => this.compiler
|
||||||
.compile(
|
.compile(
|
||||||
fileMeta.fileUrl, analyzedAppModules, fileMeta.components,
|
fileMeta.fileUrl, analyzedNgModules, fileMeta.components,
|
||||||
fileMeta.appModules)
|
fileMeta.ngModules)
|
||||||
.then((generatedModules) => {
|
.then((generatedModules) => {
|
||||||
generatedModules.forEach((generatedModule) => {
|
generatedModules.forEach((generatedModule) => {
|
||||||
const sourceFile = this.program.getSourceFile(fileMeta.fileUrl);
|
const sourceFile = this.program.getSourceFile(fileMeta.fileUrl);
|
||||||
@ -139,11 +139,12 @@ export class CodeGenerator {
|
|||||||
expressionParser, new DomElementSchemaRegistry(), htmlParser,
|
expressionParser, new DomElementSchemaRegistry(), htmlParser,
|
||||||
/*console*/ null, []);
|
/*console*/ null, []);
|
||||||
const resolver = new CompileMetadataResolver(
|
const resolver = new CompileMetadataResolver(
|
||||||
|
new compiler.NgModuleResolver(staticReflector),
|
||||||
new compiler.DirectiveResolver(staticReflector), new compiler.PipeResolver(staticReflector),
|
new compiler.DirectiveResolver(staticReflector), new compiler.PipeResolver(staticReflector),
|
||||||
new compiler.ViewResolver(staticReflector), config, staticReflector);
|
new compiler.ViewResolver(staticReflector), config, /*console*/ null, staticReflector);
|
||||||
const offlineCompiler = new compiler.OfflineCompiler(
|
const offlineCompiler = new compiler.OfflineCompiler(
|
||||||
resolver, normalizer, tmplParser, new StyleCompiler(urlResolver), new ViewCompiler(config),
|
resolver, normalizer, tmplParser, new StyleCompiler(urlResolver), new ViewCompiler(config),
|
||||||
new AppModuleCompiler(), new TypeScriptEmitter(reflectorHost));
|
new NgModuleCompiler(), new TypeScriptEmitter(reflectorHost));
|
||||||
|
|
||||||
return new CodeGenerator(
|
return new CodeGenerator(
|
||||||
options, program, compilerHost, staticReflector, offlineCompiler, reflectorHost);
|
options, program, compilerHost, staticReflector, offlineCompiler, reflectorHost);
|
||||||
@ -153,5 +154,5 @@ export class CodeGenerator {
|
|||||||
interface FileMetadata {
|
interface FileMetadata {
|
||||||
fileUrl: string;
|
fileUrl: string;
|
||||||
components: StaticSymbol[];
|
components: StaticSymbol[];
|
||||||
appModules: StaticSymbol[];
|
ngModules: StaticSymbol[];
|
||||||
}
|
}
|
@ -61,8 +61,8 @@ export var StyleCompiler: typeof _c.StyleCompiler = _c.StyleCompiler;
|
|||||||
export type ViewCompiler = _c.ViewCompiler;
|
export type ViewCompiler = _c.ViewCompiler;
|
||||||
export var ViewCompiler: typeof _c.ViewCompiler = _c.ViewCompiler;
|
export var ViewCompiler: typeof _c.ViewCompiler = _c.ViewCompiler;
|
||||||
|
|
||||||
export type AppModuleCompiler = _c.AppModuleCompiler;
|
export type NgModuleCompiler = _c.NgModuleCompiler;
|
||||||
export var AppModuleCompiler: typeof _c.AppModuleCompiler = _c.AppModuleCompiler;
|
export var NgModuleCompiler: typeof _c.NgModuleCompiler = _c.NgModuleCompiler;
|
||||||
|
|
||||||
export type TypeScriptEmitter = _c.TypeScriptEmitter;
|
export type TypeScriptEmitter = _c.TypeScriptEmitter;
|
||||||
export var TypeScriptEmitter: typeof _c.TypeScriptEmitter = _c.TypeScriptEmitter;
|
export var TypeScriptEmitter: typeof _c.TypeScriptEmitter = _c.TypeScriptEmitter;
|
||||||
|
@ -76,7 +76,7 @@ class Extractor {
|
|||||||
for (const symbol of symbols) {
|
for (const symbol of symbols) {
|
||||||
const staticType = this._reflectorHost.findDeclaration(absSourcePath, symbol, absSourcePath);
|
const staticType = this._reflectorHost.findDeclaration(absSourcePath, symbol, absSourcePath);
|
||||||
let directive: compiler.CompileDirectiveMetadata;
|
let directive: compiler.CompileDirectiveMetadata;
|
||||||
directive = this._resolver.maybeGetDirectiveMetadata(<any>staticType);
|
directive = this._resolver.getDirectiveMetadata(<any>staticType, false);
|
||||||
|
|
||||||
if (directive && directive.isComponent) {
|
if (directive && directive.isComponent) {
|
||||||
let promise = this._normalizer.normalizeDirective(directive).asyncResult;
|
let promise = this._normalizer.normalizeDirective(directive).asyncResult;
|
||||||
@ -147,8 +147,9 @@ class Extractor {
|
|||||||
const normalizer = new DirectiveNormalizer(xhr, urlResolver, htmlParser, config);
|
const normalizer = new DirectiveNormalizer(xhr, urlResolver, htmlParser, config);
|
||||||
const expressionParser = new Parser(new Lexer());
|
const expressionParser = new Parser(new Lexer());
|
||||||
const resolver = new CompileMetadataResolver(
|
const resolver = new CompileMetadataResolver(
|
||||||
|
new compiler.NgModuleResolver(staticReflector),
|
||||||
new compiler.DirectiveResolver(staticReflector), new compiler.PipeResolver(staticReflector),
|
new compiler.DirectiveResolver(staticReflector), new compiler.PipeResolver(staticReflector),
|
||||||
new compiler.ViewResolver(staticReflector), config, staticReflector);
|
new compiler.ViewResolver(staticReflector), config, /*console*/ null, staticReflector);
|
||||||
|
|
||||||
// TODO(vicb): handle implicit
|
// TODO(vicb): handle implicit
|
||||||
const extractor = new MessageExtractor(htmlParser, expressionParser, [], {});
|
const extractor = new MessageExtractor(htmlParser, expressionParser, [], {});
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {AppModuleMetadata, AttributeMetadata, ComponentMetadata, ContentChildMetadata, ContentChildrenMetadata, DirectiveMetadata, HostBindingMetadata, HostListenerMetadata, HostMetadata, InjectMetadata, InjectableMetadata, InputMetadata, OptionalMetadata, OutputMetadata, PipeMetadata, Provider, QueryMetadata, SelfMetadata, SkipSelfMetadata, ViewChildMetadata, ViewChildrenMetadata, ViewQueryMetadata, animate, group, keyframes, sequence, state, style, transition, trigger} from '@angular/core';
|
import {AttributeMetadata, ComponentMetadata, ContentChildMetadata, ContentChildrenMetadata, DirectiveMetadata, HostBindingMetadata, HostListenerMetadata, HostMetadata, InjectMetadata, InjectableMetadata, InputMetadata, NgModuleMetadata, OptionalMetadata, OutputMetadata, PipeMetadata, Provider, QueryMetadata, SelfMetadata, SkipSelfMetadata, ViewChildMetadata, ViewChildrenMetadata, ViewQueryMetadata, animate, group, keyframes, sequence, state, style, transition, trigger} from '@angular/core';
|
||||||
|
|
||||||
import {ReflectorReader} from './core_private';
|
import {ReflectorReader} from './core_private';
|
||||||
|
|
||||||
@ -217,7 +217,7 @@ export class StaticReflector implements ReflectorReader {
|
|||||||
this.registerDecoratorOrConstructor(
|
this.registerDecoratorOrConstructor(
|
||||||
this.host.findDeclaration(coreDecorators, 'Component'), ComponentMetadata);
|
this.host.findDeclaration(coreDecorators, 'Component'), ComponentMetadata);
|
||||||
this.registerDecoratorOrConstructor(
|
this.registerDecoratorOrConstructor(
|
||||||
this.host.findDeclaration(coreDecorators, 'AppModule'), AppModuleMetadata);
|
this.host.findDeclaration(coreDecorators, 'NgModule'), NgModuleMetadata);
|
||||||
|
|
||||||
// Note: Some metadata classes can be used directly with Provider.deps.
|
// Note: Some metadata classes can be used directly with Provider.deps.
|
||||||
this.registerDecoratorOrConstructor(
|
this.registerDecoratorOrConstructor(
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
* @description
|
* @description
|
||||||
* Starting point to import all compiler APIs.
|
* Starting point to import all compiler APIs.
|
||||||
*/
|
*/
|
||||||
export {COMPILER_PROVIDERS, CompileDiDependencyMetadata, CompileDirectiveMetadata, CompileFactoryMetadata, CompileIdentifierMetadata, CompileMetadataWithIdentifier, CompileMetadataWithType, CompilePipeMetadata, CompileProviderMetadata, CompileQueryMetadata, CompileTemplateMetadata, CompileTokenMetadata, CompileTypeMetadata, CompilerConfig, DEFAULT_PACKAGE_URL_PROVIDER, DirectiveResolver, OfflineCompiler, PipeResolver, RUNTIME_COMPILER_FACTORY, RenderTypes, RuntimeCompiler, SourceModule, TEMPLATE_TRANSFORMS, UrlResolver, ViewResolver, XHR, createOfflineCompileUrlResolver} from './src/compiler';
|
export {COMPILER_PROVIDERS, CompileDiDependencyMetadata, CompileDirectiveMetadata, CompileFactoryMetadata, CompileIdentifierMetadata, CompileMetadataWithIdentifier, CompilePipeMetadata, CompileProviderMetadata, CompileQueryMetadata, CompileTemplateMetadata, CompileTokenMetadata, CompileTypeMetadata, CompilerConfig, DEFAULT_PACKAGE_URL_PROVIDER, DirectiveResolver, NgModuleResolver, OfflineCompiler, PipeResolver, RenderTypes, RuntimeCompiler, SourceModule, TEMPLATE_TRANSFORMS, UrlResolver, ViewResolver, XHR, analyzeAppProvidersForDeprecatedConfiguration, coreDynamicPlatform, createOfflineCompileUrlResolver} from './src/compiler';
|
||||||
export {ElementSchemaRegistry} from './src/schema/element_schema_registry';
|
export {ElementSchemaRegistry} from './src/schema/element_schema_registry';
|
||||||
|
|
||||||
export * from './src/template_ast';
|
export * from './src/template_ast';
|
||||||
|
@ -20,8 +20,6 @@ export var LifecycleHooks: typeof t.LifecycleHooks = r.LifecycleHooks;
|
|||||||
export var LIFECYCLE_HOOKS_VALUES: typeof t.LIFECYCLE_HOOKS_VALUES = r.LIFECYCLE_HOOKS_VALUES;
|
export var LIFECYCLE_HOOKS_VALUES: typeof t.LIFECYCLE_HOOKS_VALUES = r.LIFECYCLE_HOOKS_VALUES;
|
||||||
export type ReflectorReader = t.ReflectorReader;
|
export type ReflectorReader = t.ReflectorReader;
|
||||||
export var ReflectorReader: typeof t.ReflectorReader = r.ReflectorReader;
|
export var ReflectorReader: typeof t.ReflectorReader = r.ReflectorReader;
|
||||||
export var ReflectorComponentResolver: typeof t.ReflectorComponentResolver =
|
|
||||||
r.ReflectorComponentResolver;
|
|
||||||
export type AppElement = t.AppElement;
|
export type AppElement = t.AppElement;
|
||||||
export var AppElement: typeof t.AppElement = r.AppElement;
|
export var AppElement: typeof t.AppElement = r.AppElement;
|
||||||
export var CodegenComponentFactoryResolver: typeof t.CodegenComponentFactoryResolver =
|
export var CodegenComponentFactoryResolver: typeof t.CodegenComponentFactoryResolver =
|
||||||
@ -29,7 +27,7 @@ export var CodegenComponentFactoryResolver: typeof t.CodegenComponentFactoryReso
|
|||||||
export var AppView: typeof t.AppView = r.AppView;
|
export var AppView: typeof t.AppView = r.AppView;
|
||||||
export type DebugAppView<T> = t.DebugAppView<T>;
|
export type DebugAppView<T> = t.DebugAppView<T>;
|
||||||
export var DebugAppView: typeof t.DebugAppView = r.DebugAppView;
|
export var DebugAppView: typeof t.DebugAppView = r.DebugAppView;
|
||||||
export var AppModuleInjector: typeof t.AppModuleInjector = r.AppModuleInjector;
|
export var NgModuleInjector: typeof t.NgModuleInjector = r.NgModuleInjector;
|
||||||
export type ViewType = t.ViewType;
|
export type ViewType = t.ViewType;
|
||||||
export var ViewType: typeof t.ViewType = r.ViewType;
|
export var ViewType: typeof t.ViewType = r.ViewType;
|
||||||
export var MAX_INTERPOLATION_VALUES: typeof t.MAX_INTERPOLATION_VALUES = r.MAX_INTERPOLATION_VALUES;
|
export var MAX_INTERPOLATION_VALUES: typeof t.MAX_INTERPOLATION_VALUES = r.MAX_INTERPOLATION_VALUES;
|
||||||
@ -68,6 +66,8 @@ export var Console: typeof t.Console = r.Console;
|
|||||||
export var reflector: t.Reflector = r.reflector;
|
export var reflector: t.Reflector = r.reflector;
|
||||||
export var Reflector: typeof t.Reflector = r.Reflector;
|
export var Reflector: typeof t.Reflector = r.Reflector;
|
||||||
export type Reflector = t.Reflector;
|
export type Reflector = t.Reflector;
|
||||||
|
export var ReflectionCapabilities: typeof t.ReflectionCapabilities = r.ReflectionCapabilities;
|
||||||
|
export type ReflectionCapabilities = t.ReflectionCapabilities;
|
||||||
export type NoOpAnimationPlayer = t.NoOpAnimationPlayer;
|
export type NoOpAnimationPlayer = t.NoOpAnimationPlayer;
|
||||||
export var NoOpAnimationPlayer: typeof t.NoOpAnimationPlayer = r.NoOpAnimationPlayer;
|
export var NoOpAnimationPlayer: typeof t.NoOpAnimationPlayer = r.NoOpAnimationPlayer;
|
||||||
export type AnimationPlayer = t.AnimationPlayer;
|
export type AnimationPlayer = t.AnimationPlayer;
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as app_module_compiler from './src/app_module_compiler';
|
|
||||||
import * as directive_normalizer from './src/directive_normalizer';
|
import * as directive_normalizer from './src/directive_normalizer';
|
||||||
import * as lexer from './src/expression_parser/lexer';
|
import * as lexer from './src/expression_parser/lexer';
|
||||||
import * as parser from './src/expression_parser/parser';
|
import * as parser from './src/expression_parser/parser';
|
||||||
@ -16,6 +15,7 @@ import * as i18n_message from './src/i18n/message';
|
|||||||
import * as i18n_extractor from './src/i18n/message_extractor';
|
import * as i18n_extractor from './src/i18n/message_extractor';
|
||||||
import * as xmb_serializer from './src/i18n/xmb_serializer';
|
import * as xmb_serializer from './src/i18n/xmb_serializer';
|
||||||
import * as metadata_resolver from './src/metadata_resolver';
|
import * as metadata_resolver from './src/metadata_resolver';
|
||||||
|
import * as ng_module_compiler from './src/ng_module_compiler';
|
||||||
import * as path_util from './src/output/path_util';
|
import * as path_util from './src/output/path_util';
|
||||||
import * as ts_emitter from './src/output/ts_emitter';
|
import * as ts_emitter from './src/output/ts_emitter';
|
||||||
import * as parse_util from './src/parse_util';
|
import * as parse_util from './src/parse_util';
|
||||||
@ -99,8 +99,8 @@ export var StyleCompiler = style_compiler.StyleCompiler;
|
|||||||
export type ViewCompiler = view_compiler.ViewCompiler;
|
export type ViewCompiler = view_compiler.ViewCompiler;
|
||||||
export var ViewCompiler = view_compiler.ViewCompiler;
|
export var ViewCompiler = view_compiler.ViewCompiler;
|
||||||
|
|
||||||
export type AppModuleCompiler = app_module_compiler.AppModuleCompiler;
|
export type NgModuleCompiler = ng_module_compiler.NgModuleCompiler;
|
||||||
export var AppModuleCompiler = app_module_compiler.AppModuleCompiler;
|
export var NgModuleCompiler = ng_module_compiler.NgModuleCompiler;
|
||||||
|
|
||||||
export type TypeScriptEmitter = ts_emitter.TypeScriptEmitter;
|
export type TypeScriptEmitter = ts_emitter.TypeScriptEmitter;
|
||||||
export var TypeScriptEmitter = ts_emitter.TypeScriptEmitter;
|
export var TypeScriptEmitter = ts_emitter.TypeScriptEmitter;
|
||||||
|
@ -22,139 +22,55 @@ import {sanitizeIdentifier, splitAtColon} from './util';
|
|||||||
// group 1: "prop" from "[prop]"
|
// group 1: "prop" from "[prop]"
|
||||||
// group 2: "event" from "(event)"
|
// group 2: "event" from "(event)"
|
||||||
// group 3: "@trigger" from "@trigger"
|
// group 3: "@trigger" from "@trigger"
|
||||||
var HOST_REG_EXP = /^(?:(?:\[([^\]]+)\])|(?:\(([^\)]+)\)))|(\@[-\w]+)$/g;
|
const HOST_REG_EXP = /^(?:(?:\[([^\]]+)\])|(?:\(([^\)]+)\)))|(\@[-\w]+)$/g;
|
||||||
|
const UNDEFINED = new Object();
|
||||||
|
|
||||||
export abstract class CompileMetadataWithIdentifier {
|
export abstract class CompileMetadataWithIdentifier {
|
||||||
abstract toJson(): {[key: string]: any};
|
|
||||||
|
|
||||||
get identifier(): CompileIdentifierMetadata { return <CompileIdentifierMetadata>unimplemented(); }
|
get identifier(): CompileIdentifierMetadata { return <CompileIdentifierMetadata>unimplemented(); }
|
||||||
}
|
|
||||||
|
|
||||||
export abstract class CompileMetadataWithType extends CompileMetadataWithIdentifier {
|
get runtimeCacheKey(): any { return unimplemented(); }
|
||||||
abstract toJson(): {[key: string]: any};
|
|
||||||
|
|
||||||
get type(): CompileTypeMetadata { return <CompileTypeMetadata>unimplemented(); }
|
get assetCacheKey(): any { return unimplemented(); }
|
||||||
|
|
||||||
get identifier(): CompileIdentifierMetadata { return <CompileIdentifierMetadata>unimplemented(); }
|
equalsTo(id2: CompileMetadataWithIdentifier): boolean { return unimplemented(); }
|
||||||
}
|
|
||||||
|
|
||||||
export function metadataFromJson(data: {[key: string]: any}): any {
|
|
||||||
return (_COMPILE_METADATA_FROM_JSON as any)[data['class']](data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CompileAnimationEntryMetadata {
|
export class CompileAnimationEntryMetadata {
|
||||||
static fromJson(data: {[key: string]: any}): CompileAnimationEntryMetadata {
|
|
||||||
var value = data['value'];
|
|
||||||
var defs = _arrayFromJson(value['definitions'], metadataFromJson);
|
|
||||||
return new CompileAnimationEntryMetadata(value['name'], defs);
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public name: string = null, public definitions: CompileAnimationStateMetadata[] = null) {}
|
public name: string = null, public definitions: CompileAnimationStateMetadata[] = null) {}
|
||||||
|
|
||||||
toJson(): {[key: string]: any} {
|
|
||||||
return {
|
|
||||||
'class': 'AnimationEntryMetadata',
|
|
||||||
'value': {'name': this.name, 'definitions': _arrayToJson(this.definitions)}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export abstract class CompileAnimationStateMetadata {}
|
export abstract class CompileAnimationStateMetadata {}
|
||||||
|
|
||||||
export class CompileAnimationStateDeclarationMetadata extends CompileAnimationStateMetadata {
|
export class CompileAnimationStateDeclarationMetadata extends CompileAnimationStateMetadata {
|
||||||
static fromJson(data: {[key: string]: any}): CompileAnimationStateDeclarationMetadata {
|
|
||||||
var value = data['value'];
|
|
||||||
var styles = _objFromJson(value['styles'], metadataFromJson);
|
|
||||||
return new CompileAnimationStateDeclarationMetadata(value['stateNameExpr'], styles);
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(public stateNameExpr: string, public styles: CompileAnimationStyleMetadata) {
|
constructor(public stateNameExpr: string, public styles: CompileAnimationStyleMetadata) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
toJson(): {[key: string]: any} {
|
|
||||||
return {
|
|
||||||
'class': 'AnimationStateDeclarationMetadata',
|
|
||||||
'value': {'stateNameExpr': this.stateNameExpr, 'styles': this.styles.toJson()}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CompileAnimationStateTransitionMetadata extends CompileAnimationStateMetadata {
|
export class CompileAnimationStateTransitionMetadata extends CompileAnimationStateMetadata {
|
||||||
static fromJson(data: {[key: string]: any}): CompileAnimationStateTransitionMetadata {
|
|
||||||
var value = data['value'];
|
|
||||||
var steps = _objFromJson(value['steps'], metadataFromJson);
|
|
||||||
return new CompileAnimationStateTransitionMetadata(value['stateChangeExpr'], steps);
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(public stateChangeExpr: string, public steps: CompileAnimationMetadata) { super(); }
|
constructor(public stateChangeExpr: string, public steps: CompileAnimationMetadata) { super(); }
|
||||||
|
|
||||||
toJson(): {[key: string]: any} {
|
|
||||||
return {
|
|
||||||
'class': 'AnimationStateTransitionMetadata',
|
|
||||||
'value': {'stateChangeExpr': this.stateChangeExpr, 'steps': this.steps.toJson()}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export abstract class CompileAnimationMetadata { abstract toJson(): {[key: string]: any}; }
|
export abstract class CompileAnimationMetadata {}
|
||||||
|
|
||||||
export class CompileAnimationKeyframesSequenceMetadata extends CompileAnimationMetadata {
|
export class CompileAnimationKeyframesSequenceMetadata extends CompileAnimationMetadata {
|
||||||
static fromJson(data: {[key: string]: any}): CompileAnimationKeyframesSequenceMetadata {
|
|
||||||
var steps = _arrayFromJson(data['value'], metadataFromJson);
|
|
||||||
return new CompileAnimationKeyframesSequenceMetadata(<CompileAnimationStyleMetadata[]>steps);
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(public steps: CompileAnimationStyleMetadata[] = []) { super(); }
|
constructor(public steps: CompileAnimationStyleMetadata[] = []) { super(); }
|
||||||
|
|
||||||
toJson(): {[key: string]: any} {
|
|
||||||
return {'class': 'AnimationKeyframesSequenceMetadata', 'value': _arrayToJson(this.steps)};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CompileAnimationStyleMetadata extends CompileAnimationMetadata {
|
export class CompileAnimationStyleMetadata extends CompileAnimationMetadata {
|
||||||
static fromJson(data: {[key: string]: any}): CompileAnimationStyleMetadata {
|
|
||||||
var value = data['value'];
|
|
||||||
var offsetVal = value['offset'];
|
|
||||||
var offset = isPresent(offsetVal) ? NumberWrapper.parseFloat(offsetVal) : null;
|
|
||||||
var styles = <Array<string|{[key: string]: string | number}>>value['styles'];
|
|
||||||
return new CompileAnimationStyleMetadata(offset, styles);
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public offset: number, public styles: Array<string|{[key: string]: string | number}> = null) {
|
public offset: number, public styles: Array<string|{[key: string]: string | number}> = null) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
toJson(): {[key: string]: any} {
|
|
||||||
return {
|
|
||||||
'class': 'AnimationStyleMetadata',
|
|
||||||
'value': {'offset': this.offset, 'styles': this.styles}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CompileAnimationAnimateMetadata extends CompileAnimationMetadata {
|
export class CompileAnimationAnimateMetadata extends CompileAnimationMetadata {
|
||||||
static fromJson(data: {[key: string]: any}): CompileAnimationAnimateMetadata {
|
|
||||||
var value = data['value'];
|
|
||||||
var timings = <string|number>value['timings'];
|
|
||||||
var styles = _objFromJson(value['styles'], metadataFromJson);
|
|
||||||
return new CompileAnimationAnimateMetadata(timings, styles);
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public timings: string|number = 0, public styles: CompileAnimationStyleMetadata|
|
public timings: string|number = 0, public styles: CompileAnimationStyleMetadata|
|
||||||
CompileAnimationKeyframesSequenceMetadata = null) {
|
CompileAnimationKeyframesSequenceMetadata = null) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
toJson(): {[key: string]: any} {
|
|
||||||
return {
|
|
||||||
'class': 'AnimationAnimateMetadata',
|
|
||||||
'value': {'timings': this.timings, 'styles': _objToJson(this.styles)}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export abstract class CompileAnimationWithStepsMetadata extends CompileAnimationMetadata {
|
export abstract class CompileAnimationWithStepsMetadata extends CompileAnimationMetadata {
|
||||||
@ -162,29 +78,11 @@ export abstract class CompileAnimationWithStepsMetadata extends CompileAnimation
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class CompileAnimationSequenceMetadata extends CompileAnimationWithStepsMetadata {
|
export class CompileAnimationSequenceMetadata extends CompileAnimationWithStepsMetadata {
|
||||||
static fromJson(data: {[key: string]: any}): CompileAnimationSequenceMetadata {
|
|
||||||
var steps = _arrayFromJson(data['value'], metadataFromJson);
|
|
||||||
return new CompileAnimationSequenceMetadata(steps);
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(steps: CompileAnimationMetadata[] = null) { super(steps); }
|
constructor(steps: CompileAnimationMetadata[] = null) { super(steps); }
|
||||||
|
|
||||||
toJson(): {[key: string]: any} {
|
|
||||||
return {'class': 'AnimationSequenceMetadata', 'value': _arrayToJson(this.steps)};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CompileAnimationGroupMetadata extends CompileAnimationWithStepsMetadata {
|
export class CompileAnimationGroupMetadata extends CompileAnimationWithStepsMetadata {
|
||||||
static fromJson(data: {[key: string]: any}): CompileAnimationGroupMetadata {
|
|
||||||
var steps = _arrayFromJson(data['value'], metadataFromJson);
|
|
||||||
return new CompileAnimationGroupMetadata(steps);
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(steps: CompileAnimationMetadata[] = null) { super(steps); }
|
constructor(steps: CompileAnimationMetadata[] = null) { super(steps); }
|
||||||
|
|
||||||
toJson(): {[key: string]: any} {
|
|
||||||
return {'class': 'AnimationGroupMetadata', 'value': _arrayToJson(this.steps)};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CompileIdentifierMetadata implements CompileMetadataWithIdentifier {
|
export class CompileIdentifierMetadata implements CompileMetadataWithIdentifier {
|
||||||
@ -193,6 +91,7 @@ export class CompileIdentifierMetadata implements CompileMetadataWithIdentifier
|
|||||||
prefix: string;
|
prefix: string;
|
||||||
moduleUrl: string;
|
moduleUrl: string;
|
||||||
value: any;
|
value: any;
|
||||||
|
private _assetCacheKey: any = UNDEFINED;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
{runtime, name, moduleUrl, prefix, value}:
|
{runtime, name, moduleUrl, prefix, value}:
|
||||||
@ -204,26 +103,28 @@ export class CompileIdentifierMetadata implements CompileMetadataWithIdentifier
|
|||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromJson(data: {[key: string]: any}): CompileIdentifierMetadata {
|
|
||||||
let value = isArray(data['value']) ? _arrayFromJson(data['value'], metadataFromJson) :
|
|
||||||
_objFromJson(data['value'], metadataFromJson);
|
|
||||||
return new CompileIdentifierMetadata(
|
|
||||||
{name: data['name'], prefix: data['prefix'], moduleUrl: data['moduleUrl'], value: value});
|
|
||||||
}
|
|
||||||
|
|
||||||
toJson(): {[key: string]: any} {
|
|
||||||
let value = isArray(this.value) ? _arrayToJson(this.value) : _objToJson(this.value);
|
|
||||||
return {
|
|
||||||
// Note: Runtime type can't be serialized...
|
|
||||||
'class': 'Identifier',
|
|
||||||
'name': this.name,
|
|
||||||
'moduleUrl': this.moduleUrl,
|
|
||||||
'prefix': this.prefix,
|
|
||||||
'value': value
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
get identifier(): CompileIdentifierMetadata { return this; }
|
get identifier(): CompileIdentifierMetadata { return this; }
|
||||||
|
|
||||||
|
get runtimeCacheKey(): any { return this.identifier.runtime; }
|
||||||
|
|
||||||
|
get assetCacheKey(): any {
|
||||||
|
if (this._assetCacheKey === UNDEFINED) {
|
||||||
|
if (isPresent(this.moduleUrl) && isPresent(getUrlScheme(this.moduleUrl))) {
|
||||||
|
var uri = reflector.importUri({'filePath': this.moduleUrl, 'name': this.name});
|
||||||
|
this._assetCacheKey = `${this.name}|${uri}`;
|
||||||
|
} else {
|
||||||
|
this._assetCacheKey = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this._assetCacheKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
equalsTo(id2: CompileIdentifierMetadata): boolean {
|
||||||
|
var rk = this.runtimeCacheKey;
|
||||||
|
var ak = this.assetCacheKey;
|
||||||
|
return (isPresent(rk) && rk == id2.runtimeCacheKey) ||
|
||||||
|
(isPresent(ak) && ak == id2.assetCacheKey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CompileDiDependencyMetadata {
|
export class CompileDiDependencyMetadata {
|
||||||
@ -263,36 +164,6 @@ export class CompileDiDependencyMetadata {
|
|||||||
this.token = token;
|
this.token = token;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromJson(data: {[key: string]: any}): CompileDiDependencyMetadata {
|
|
||||||
return new CompileDiDependencyMetadata({
|
|
||||||
token: _objFromJson(data['token'], CompileTokenMetadata.fromJson),
|
|
||||||
query: _objFromJson(data['query'], CompileQueryMetadata.fromJson),
|
|
||||||
viewQuery: _objFromJson(data['viewQuery'], CompileQueryMetadata.fromJson),
|
|
||||||
value: data['value'],
|
|
||||||
isAttribute: data['isAttribute'],
|
|
||||||
isSelf: data['isSelf'],
|
|
||||||
isHost: data['isHost'],
|
|
||||||
isSkipSelf: data['isSkipSelf'],
|
|
||||||
isOptional: data['isOptional'],
|
|
||||||
isValue: data['isValue']
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
toJson(): {[key: string]: any} {
|
|
||||||
return {
|
|
||||||
'token': _objToJson(this.token),
|
|
||||||
'query': _objToJson(this.query),
|
|
||||||
'viewQuery': _objToJson(this.viewQuery),
|
|
||||||
'value': this.value,
|
|
||||||
'isAttribute': this.isAttribute,
|
|
||||||
'isSelf': this.isSelf,
|
|
||||||
'isHost': this.isHost,
|
|
||||||
'isSkipSelf': this.isSkipSelf,
|
|
||||||
'isOptional': this.isOptional,
|
|
||||||
'isValue': this.isValue
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CompileProviderMetadata {
|
export class CompileProviderMetadata {
|
||||||
@ -321,41 +192,9 @@ export class CompileProviderMetadata {
|
|||||||
this.deps = normalizeBlank(deps);
|
this.deps = normalizeBlank(deps);
|
||||||
this.multi = normalizeBool(multi);
|
this.multi = normalizeBool(multi);
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromJson(data: {[key: string]: any}): CompileProviderMetadata {
|
|
||||||
return new CompileProviderMetadata({
|
|
||||||
token: _objFromJson(data['token'], CompileTokenMetadata.fromJson),
|
|
||||||
useClass: _objFromJson(data['useClass'], CompileTypeMetadata.fromJson),
|
|
||||||
useExisting: _objFromJson(data['useExisting'], CompileTokenMetadata.fromJson),
|
|
||||||
useValue: _objFromJson(data['useValue'], CompileIdentifierMetadata.fromJson),
|
|
||||||
useFactory: _objFromJson(data['useFactory'], CompileFactoryMetadata.fromJson),
|
|
||||||
multi: data['multi'],
|
|
||||||
deps: _arrayFromJson(data['deps'], CompileDiDependencyMetadata.fromJson)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
toJson(): {[key: string]: any} {
|
|
||||||
return {
|
|
||||||
// Note: Runtime type can't be serialized...
|
|
||||||
'class': 'Provider',
|
|
||||||
'token': _objToJson(this.token),
|
|
||||||
'useClass': _objToJson(this.useClass),
|
|
||||||
'useExisting': _objToJson(this.useExisting),
|
|
||||||
'useValue': _objToJson(this.useValue),
|
|
||||||
'useFactory': _objToJson(this.useFactory),
|
|
||||||
'multi': this.multi,
|
|
||||||
'deps': _arrayToJson(this.deps)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CompileFactoryMetadata implements CompileIdentifierMetadata,
|
export class CompileFactoryMetadata extends CompileIdentifierMetadata {
|
||||||
CompileMetadataWithIdentifier {
|
|
||||||
runtime: Function;
|
|
||||||
name: string;
|
|
||||||
prefix: string;
|
|
||||||
moduleUrl: string;
|
|
||||||
value: any;
|
|
||||||
diDeps: CompileDiDependencyMetadata[];
|
diDeps: CompileDiDependencyMetadata[];
|
||||||
|
|
||||||
constructor({runtime, name, moduleUrl, prefix, diDeps, value}: {
|
constructor({runtime, name, moduleUrl, prefix, diDeps, value}: {
|
||||||
@ -366,45 +205,15 @@ export class CompileFactoryMetadata implements CompileIdentifierMetadata,
|
|||||||
value?: boolean,
|
value?: boolean,
|
||||||
diDeps?: CompileDiDependencyMetadata[]
|
diDeps?: CompileDiDependencyMetadata[]
|
||||||
}) {
|
}) {
|
||||||
this.runtime = runtime;
|
super({runtime: runtime, name: name, prefix: prefix, moduleUrl: moduleUrl, value: value});
|
||||||
this.name = name;
|
|
||||||
this.prefix = prefix;
|
|
||||||
this.moduleUrl = moduleUrl;
|
|
||||||
this.diDeps = _normalizeArray(diDeps);
|
this.diDeps = _normalizeArray(diDeps);
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
get identifier(): CompileIdentifierMetadata { return this; }
|
|
||||||
|
|
||||||
static fromJson(data: {[key: string]: any}): CompileFactoryMetadata {
|
|
||||||
return new CompileFactoryMetadata({
|
|
||||||
name: data['name'],
|
|
||||||
prefix: data['prefix'],
|
|
||||||
moduleUrl: data['moduleUrl'],
|
|
||||||
value: data['value'],
|
|
||||||
diDeps: _arrayFromJson(data['diDeps'], CompileDiDependencyMetadata.fromJson)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
toJson(): {[key: string]: any} {
|
|
||||||
return {
|
|
||||||
'class': 'Factory',
|
|
||||||
'name': this.name,
|
|
||||||
'prefix': this.prefix,
|
|
||||||
'moduleUrl': this.moduleUrl,
|
|
||||||
'value': this.value,
|
|
||||||
'diDeps': _arrayToJson(this.diDeps)
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var UNDEFINED = new Object();
|
|
||||||
|
|
||||||
export class CompileTokenMetadata implements CompileMetadataWithIdentifier {
|
export class CompileTokenMetadata implements CompileMetadataWithIdentifier {
|
||||||
value: any;
|
value: any;
|
||||||
identifier: CompileIdentifierMetadata;
|
identifier: CompileIdentifierMetadata;
|
||||||
identifierIsInstance: boolean;
|
identifierIsInstance: boolean;
|
||||||
private _assetCacheKey = UNDEFINED;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
{value, identifier, identifierIsInstance}:
|
{value, identifier, identifierIsInstance}:
|
||||||
@ -414,46 +223,20 @@ export class CompileTokenMetadata implements CompileMetadataWithIdentifier {
|
|||||||
this.identifierIsInstance = normalizeBool(identifierIsInstance);
|
this.identifierIsInstance = normalizeBool(identifierIsInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromJson(data: {[key: string]: any}): CompileTokenMetadata {
|
|
||||||
return new CompileTokenMetadata({
|
|
||||||
value: data['value'],
|
|
||||||
identifier: _objFromJson(data['identifier'], CompileIdentifierMetadata.fromJson),
|
|
||||||
identifierIsInstance: data['identifierIsInstance']
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
toJson(): {[key: string]: any} {
|
|
||||||
return {
|
|
||||||
'value': this.value,
|
|
||||||
'identifier': _objToJson(this.identifier),
|
|
||||||
'identifierIsInstance': this.identifierIsInstance
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
get runtimeCacheKey(): any {
|
get runtimeCacheKey(): any {
|
||||||
if (isPresent(this.identifier)) {
|
if (isPresent(this.identifier)) {
|
||||||
return this.identifier.runtime;
|
return this.identifier.runtimeCacheKey;
|
||||||
} else {
|
} else {
|
||||||
return this.value;
|
return this.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get assetCacheKey(): any {
|
get assetCacheKey(): any {
|
||||||
if (this._assetCacheKey === UNDEFINED) {
|
|
||||||
if (isPresent(this.identifier)) {
|
if (isPresent(this.identifier)) {
|
||||||
if (isPresent(this.identifier.moduleUrl) &&
|
return this.identifier.assetCacheKey;
|
||||||
isPresent(getUrlScheme(this.identifier.moduleUrl))) {
|
|
||||||
var uri = reflector.importUri(
|
|
||||||
{'filePath': this.identifier.moduleUrl, 'name': this.identifier.name});
|
|
||||||
this._assetCacheKey = `${this.identifier.name}|${uri}|${this.identifierIsInstance}`;
|
|
||||||
} else {
|
} else {
|
||||||
this._assetCacheKey = null;
|
return this.value;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
this._assetCacheKey = this.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this._assetCacheKey;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
equalsTo(token2: CompileTokenMetadata): boolean {
|
equalsTo(token2: CompileTokenMetadata): boolean {
|
||||||
@ -468,15 +251,24 @@ export class CompileTokenMetadata implements CompileMetadataWithIdentifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CompileTokenMap<VALUE> {
|
/**
|
||||||
|
* Note: We only need this in places where we need to support identifiers that
|
||||||
|
* don't have a `runtime` value given by the `StaticReflector`. E.g. see the `identifiers`
|
||||||
|
* file where we have some identifiers hard coded by name/module path.
|
||||||
|
*
|
||||||
|
* TODO(tbosch): Eventually, all of these places should go through the static reflector
|
||||||
|
* as well, providing them with a valid `StaticSymbol` that is again a singleton.
|
||||||
|
*/
|
||||||
|
export class CompileIdentifierMap<KEY extends CompileMetadataWithIdentifier, VALUE> {
|
||||||
private _valueMap = new Map<any, VALUE>();
|
private _valueMap = new Map<any, VALUE>();
|
||||||
private _values: VALUE[] = [];
|
private _values: VALUE[] = [];
|
||||||
private _tokens: CompileTokenMetadata[] = [];
|
private _tokens: KEY[] = [];
|
||||||
|
|
||||||
add(token: CompileTokenMetadata, value: VALUE) {
|
add(token: KEY, value: VALUE) {
|
||||||
var existing = this.get(token);
|
var existing = this.get(token);
|
||||||
if (isPresent(existing)) {
|
if (isPresent(existing)) {
|
||||||
throw new BaseException(`Can only add to a TokenMap! Token: ${token.name}`);
|
throw new BaseException(
|
||||||
|
`Cannot overwrite in a CompileIdentifierMap! Token: ${token.identifier.name}`);
|
||||||
}
|
}
|
||||||
this._tokens.push(token);
|
this._tokens.push(token);
|
||||||
this._values.push(value);
|
this._values.push(value);
|
||||||
@ -489,7 +281,7 @@ export class CompileTokenMap<VALUE> {
|
|||||||
this._valueMap.set(ak, value);
|
this._valueMap.set(ak, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
get(token: CompileTokenMetadata): VALUE {
|
get(token: KEY): VALUE {
|
||||||
var rk = token.runtimeCacheKey;
|
var rk = token.runtimeCacheKey;
|
||||||
var ak = token.assetCacheKey;
|
var ak = token.assetCacheKey;
|
||||||
var result: VALUE;
|
var result: VALUE;
|
||||||
@ -501,7 +293,7 @@ export class CompileTokenMap<VALUE> {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
keys(): CompileTokenMetadata[] { return this._tokens; }
|
keys(): KEY[] { return this._tokens; }
|
||||||
values(): VALUE[] { return this._values; }
|
values(): VALUE[] { return this._values; }
|
||||||
get size(): number { return this._values.length; }
|
get size(): number { return this._values.length; }
|
||||||
}
|
}
|
||||||
@ -509,13 +301,8 @@ export class CompileTokenMap<VALUE> {
|
|||||||
/**
|
/**
|
||||||
* Metadata regarding compilation of a type.
|
* Metadata regarding compilation of a type.
|
||||||
*/
|
*/
|
||||||
export class CompileTypeMetadata implements CompileIdentifierMetadata, CompileMetadataWithType {
|
export class CompileTypeMetadata extends CompileIdentifierMetadata {
|
||||||
runtime: Type;
|
|
||||||
name: string;
|
|
||||||
prefix: string;
|
|
||||||
moduleUrl: string;
|
|
||||||
isHost: boolean;
|
isHost: boolean;
|
||||||
value: any;
|
|
||||||
diDeps: CompileDiDependencyMetadata[];
|
diDeps: CompileDiDependencyMetadata[];
|
||||||
|
|
||||||
constructor({runtime, name, moduleUrl, prefix, isHost, value, diDeps}: {
|
constructor({runtime, name, moduleUrl, prefix, isHost, value, diDeps}: {
|
||||||
@ -527,41 +314,10 @@ export class CompileTypeMetadata implements CompileIdentifierMetadata, CompileMe
|
|||||||
value?: any,
|
value?: any,
|
||||||
diDeps?: CompileDiDependencyMetadata[]
|
diDeps?: CompileDiDependencyMetadata[]
|
||||||
} = {}) {
|
} = {}) {
|
||||||
this.runtime = runtime;
|
super({runtime: runtime, name: name, moduleUrl: moduleUrl, prefix: prefix, value: value});
|
||||||
this.name = name;
|
|
||||||
this.moduleUrl = moduleUrl;
|
|
||||||
this.prefix = prefix;
|
|
||||||
this.isHost = normalizeBool(isHost);
|
this.isHost = normalizeBool(isHost);
|
||||||
this.value = value;
|
|
||||||
this.diDeps = _normalizeArray(diDeps);
|
this.diDeps = _normalizeArray(diDeps);
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromJson(data: {[key: string]: any}): CompileTypeMetadata {
|
|
||||||
return new CompileTypeMetadata({
|
|
||||||
name: data['name'],
|
|
||||||
moduleUrl: data['moduleUrl'],
|
|
||||||
prefix: data['prefix'],
|
|
||||||
isHost: data['isHost'],
|
|
||||||
value: data['value'],
|
|
||||||
diDeps: _arrayFromJson(data['diDeps'], CompileDiDependencyMetadata.fromJson)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
get identifier(): CompileIdentifierMetadata { return this; }
|
|
||||||
get type(): CompileTypeMetadata { return this; }
|
|
||||||
|
|
||||||
toJson(): {[key: string]: any} {
|
|
||||||
return {
|
|
||||||
// Note: Runtime type can't be serialized...
|
|
||||||
'class': 'Type',
|
|
||||||
'name': this.name,
|
|
||||||
'moduleUrl': this.moduleUrl,
|
|
||||||
'prefix': this.prefix,
|
|
||||||
'isHost': this.isHost,
|
|
||||||
'value': this.value,
|
|
||||||
'diDeps': _arrayToJson(this.diDeps)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CompileQueryMetadata {
|
export class CompileQueryMetadata {
|
||||||
@ -584,26 +340,6 @@ export class CompileQueryMetadata {
|
|||||||
this.propertyName = propertyName;
|
this.propertyName = propertyName;
|
||||||
this.read = read;
|
this.read = read;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromJson(data: {[key: string]: any}): CompileQueryMetadata {
|
|
||||||
return new CompileQueryMetadata({
|
|
||||||
selectors: _arrayFromJson(data['selectors'], CompileTokenMetadata.fromJson),
|
|
||||||
descendants: data['descendants'],
|
|
||||||
first: data['first'],
|
|
||||||
propertyName: data['propertyName'],
|
|
||||||
read: _objFromJson(data['read'], CompileTokenMetadata.fromJson)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
toJson(): {[key: string]: any} {
|
|
||||||
return {
|
|
||||||
'selectors': _arrayToJson(this.selectors),
|
|
||||||
'descendants': this.descendants,
|
|
||||||
'first': this.first,
|
|
||||||
'propertyName': this.propertyName,
|
|
||||||
'read': _objToJson(this.read)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -620,15 +356,6 @@ export class CompileStylesheetMetadata {
|
|||||||
this.styles = _normalizeArray(styles);
|
this.styles = _normalizeArray(styles);
|
||||||
this.styleUrls = _normalizeArray(styleUrls);
|
this.styleUrls = _normalizeArray(styleUrls);
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromJson(data: {[key: string]: any}): CompileStylesheetMetadata {
|
|
||||||
return new CompileStylesheetMetadata(
|
|
||||||
{moduleUrl: data['moduleUrl'], styles: data['styles'], styleUrls: data['styleUrls']});
|
|
||||||
}
|
|
||||||
|
|
||||||
toJson(): {[key: string]: any} {
|
|
||||||
return {'moduleUrl': this.moduleUrl, 'styles': this.styles, 'styleUrls': this.styleUrls};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -670,46 +397,12 @@ export class CompileTemplateMetadata {
|
|||||||
}
|
}
|
||||||
this.interpolation = interpolation;
|
this.interpolation = interpolation;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromJson(data: {[key: string]: any}): CompileTemplateMetadata {
|
|
||||||
var animations =
|
|
||||||
<CompileAnimationEntryMetadata[]>_arrayFromJson(data['animations'], metadataFromJson);
|
|
||||||
return new CompileTemplateMetadata({
|
|
||||||
encapsulation: isPresent(data['encapsulation']) ?
|
|
||||||
VIEW_ENCAPSULATION_VALUES[data['encapsulation']] :
|
|
||||||
data['encapsulation'],
|
|
||||||
template: data['template'],
|
|
||||||
templateUrl: data['templateUrl'],
|
|
||||||
styles: data['styles'],
|
|
||||||
styleUrls: data['styleUrls'],
|
|
||||||
externalStylesheets:
|
|
||||||
_arrayFromJson(data['externalStylesheets'], CompileStylesheetMetadata.fromJson),
|
|
||||||
animations: animations,
|
|
||||||
ngContentSelectors: data['ngContentSelectors'],
|
|
||||||
interpolation: data['interpolation']
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
toJson(): {[key: string]: any} {
|
|
||||||
return {
|
|
||||||
'encapsulation': isPresent(this.encapsulation) ? serializeEnum(this.encapsulation) :
|
|
||||||
this.encapsulation,
|
|
||||||
'template': this.template,
|
|
||||||
'templateUrl': this.templateUrl,
|
|
||||||
'styles': this.styles,
|
|
||||||
'styleUrls': this.styleUrls,
|
|
||||||
'externalStylesheets': _objToJson(this.externalStylesheets),
|
|
||||||
'animations': _objToJson(this.animations),
|
|
||||||
'ngContentSelectors': this.ngContentSelectors,
|
|
||||||
'interpolation': this.interpolation
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Metadata regarding compilation of a directive.
|
* Metadata regarding compilation of a directive.
|
||||||
*/
|
*/
|
||||||
export class CompileDirectiveMetadata implements CompileMetadataWithType {
|
export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
|
||||||
static create(
|
static create(
|
||||||
{type, isComponent, selector, exportAs, changeDetection, inputs, outputs, host,
|
{type, isComponent, selector, exportAs, changeDetection, inputs, outputs, host,
|
||||||
lifecycleHooks, providers, viewProviders, queries, viewQueries, precompile, template}: {
|
lifecycleHooks, providers, viewProviders, queries, viewQueries, precompile, template}: {
|
||||||
@ -796,6 +489,7 @@ export class CompileDirectiveMetadata implements CompileMetadataWithType {
|
|||||||
viewProviders: CompileProviderMetadata[];
|
viewProviders: CompileProviderMetadata[];
|
||||||
queries: CompileQueryMetadata[];
|
queries: CompileQueryMetadata[];
|
||||||
viewQueries: CompileQueryMetadata[];
|
viewQueries: CompileQueryMetadata[];
|
||||||
|
// Note: Need to keep types here to prevent cycles!
|
||||||
precompile: CompileTypeMetadata[];
|
precompile: CompileTypeMetadata[];
|
||||||
template: CompileTemplateMetadata;
|
template: CompileTemplateMetadata;
|
||||||
|
|
||||||
@ -844,68 +538,26 @@ export class CompileDirectiveMetadata implements CompileMetadataWithType {
|
|||||||
|
|
||||||
get identifier(): CompileIdentifierMetadata { return this.type; }
|
get identifier(): CompileIdentifierMetadata { return this.type; }
|
||||||
|
|
||||||
static fromJson(data: {[key: string]: any}): CompileDirectiveMetadata {
|
get runtimeCacheKey(): any { return this.type.runtimeCacheKey; }
|
||||||
return new CompileDirectiveMetadata({
|
|
||||||
isComponent: data['isComponent'],
|
|
||||||
selector: data['selector'],
|
|
||||||
exportAs: data['exportAs'],
|
|
||||||
type: isPresent(data['type']) ? CompileTypeMetadata.fromJson(data['type']) : data['type'],
|
|
||||||
changeDetection: isPresent(data['changeDetection']) ?
|
|
||||||
CHANGE_DETECTION_STRATEGY_VALUES[data['changeDetection']] :
|
|
||||||
data['changeDetection'],
|
|
||||||
inputs: data['inputs'],
|
|
||||||
outputs: data['outputs'],
|
|
||||||
hostListeners: data['hostListeners'],
|
|
||||||
hostProperties: data['hostProperties'],
|
|
||||||
hostAttributes: data['hostAttributes'],
|
|
||||||
lifecycleHooks:
|
|
||||||
(<any[]>data['lifecycleHooks']).map(hookValue => LIFECYCLE_HOOKS_VALUES[hookValue]),
|
|
||||||
template: isPresent(data['template']) ? CompileTemplateMetadata.fromJson(data['template']) :
|
|
||||||
data['template'],
|
|
||||||
providers: _arrayFromJson(data['providers'], metadataFromJson),
|
|
||||||
viewProviders: _arrayFromJson(data['viewProviders'], metadataFromJson),
|
|
||||||
queries: _arrayFromJson(data['queries'], CompileQueryMetadata.fromJson),
|
|
||||||
viewQueries: _arrayFromJson(data['viewQueries'], CompileQueryMetadata.fromJson),
|
|
||||||
precompile: _arrayFromJson(data['precompile'], CompileTypeMetadata.fromJson)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
toJson(): {[key: string]: any} {
|
get assetCacheKey(): any { return this.type.assetCacheKey; }
|
||||||
return {
|
|
||||||
'class': 'Directive',
|
equalsTo(other: CompileMetadataWithIdentifier): boolean {
|
||||||
'isComponent': this.isComponent,
|
return this.type.equalsTo(other.identifier);
|
||||||
'selector': this.selector,
|
|
||||||
'exportAs': this.exportAs,
|
|
||||||
'type': isPresent(this.type) ? this.type.toJson() : this.type,
|
|
||||||
'changeDetection': isPresent(this.changeDetection) ? serializeEnum(this.changeDetection) :
|
|
||||||
this.changeDetection,
|
|
||||||
'inputs': this.inputs,
|
|
||||||
'outputs': this.outputs,
|
|
||||||
'hostListeners': this.hostListeners,
|
|
||||||
'hostProperties': this.hostProperties,
|
|
||||||
'hostAttributes': this.hostAttributes,
|
|
||||||
'lifecycleHooks': this.lifecycleHooks.map(hook => serializeEnum(hook)),
|
|
||||||
'template': isPresent(this.template) ? this.template.toJson() : this.template,
|
|
||||||
'providers': _arrayToJson(this.providers),
|
|
||||||
'viewProviders': _arrayToJson(this.viewProviders),
|
|
||||||
'queries': _arrayToJson(this.queries),
|
|
||||||
'viewQueries': _arrayToJson(this.viewQueries),
|
|
||||||
'precompile': _arrayToJson(this.precompile)
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct {@link CompileDirectiveMetadata} from {@link ComponentTypeMetadata} and a selector.
|
* Construct {@link CompileDirectiveMetadata} from {@link ComponentTypeMetadata} and a selector.
|
||||||
*/
|
*/
|
||||||
export function createHostComponentMeta(
|
export function createHostComponentMeta(compMeta: CompileDirectiveMetadata):
|
||||||
componentType: CompileTypeMetadata, componentSelector: string): CompileDirectiveMetadata {
|
CompileDirectiveMetadata {
|
||||||
var template = CssSelector.parse(componentSelector)[0].getMatchingElementTemplate();
|
var template = CssSelector.parse(compMeta.selector)[0].getMatchingElementTemplate();
|
||||||
return CompileDirectiveMetadata.create({
|
return CompileDirectiveMetadata.create({
|
||||||
type: new CompileTypeMetadata({
|
type: new CompileTypeMetadata({
|
||||||
runtime: Object,
|
runtime: Object,
|
||||||
name: `${componentType.name}_Host`,
|
name: `${compMeta.type.name}_Host`,
|
||||||
moduleUrl: componentType.moduleUrl,
|
moduleUrl: compMeta.type.moduleUrl,
|
||||||
isHost: true
|
isHost: true
|
||||||
}),
|
}),
|
||||||
template: new CompileTemplateMetadata({
|
template: new CompileTemplateMetadata({
|
||||||
@ -931,7 +583,7 @@ export function createHostComponentMeta(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export class CompilePipeMetadata implements CompileMetadataWithType {
|
export class CompilePipeMetadata implements CompileMetadataWithIdentifier {
|
||||||
type: CompileTypeMetadata;
|
type: CompileTypeMetadata;
|
||||||
name: string;
|
name: string;
|
||||||
pure: boolean;
|
pure: boolean;
|
||||||
@ -949,114 +601,91 @@ export class CompilePipeMetadata implements CompileMetadataWithType {
|
|||||||
this.lifecycleHooks = _normalizeArray(lifecycleHooks);
|
this.lifecycleHooks = _normalizeArray(lifecycleHooks);
|
||||||
}
|
}
|
||||||
get identifier(): CompileIdentifierMetadata { return this.type; }
|
get identifier(): CompileIdentifierMetadata { return this.type; }
|
||||||
|
get runtimeCacheKey(): any { return this.type.runtimeCacheKey; }
|
||||||
|
|
||||||
static fromJson(data: {[key: string]: any}): CompilePipeMetadata {
|
get assetCacheKey(): any { return this.type.assetCacheKey; }
|
||||||
return new CompilePipeMetadata({
|
|
||||||
type: isPresent(data['type']) ? CompileTypeMetadata.fromJson(data['type']) : data['type'],
|
|
||||||
name: data['name'],
|
|
||||||
pure: data['pure']
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
toJson(): {[key: string]: any} {
|
equalsTo(other: CompileMetadataWithIdentifier): boolean {
|
||||||
return {
|
return this.type.equalsTo(other.identifier);
|
||||||
'class': 'Pipe',
|
|
||||||
'type': isPresent(this.type) ? this.type.toJson() : null,
|
|
||||||
'name': this.name,
|
|
||||||
'pure': this.pure
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Metadata regarding compilation of a directive.
|
* Metadata regarding compilation of a directive.
|
||||||
*/
|
*/
|
||||||
export class CompileAppModuleMetadata implements CompileMetadataWithType {
|
export class CompileNgModuleMetadata implements CompileMetadataWithIdentifier {
|
||||||
type: CompileTypeMetadata;
|
type: CompileTypeMetadata;
|
||||||
providers: CompileProviderMetadata[];
|
declaredDirectives: CompileDirectiveMetadata[];
|
||||||
directives: CompileTypeMetadata[];
|
exportedDirectives: CompileDirectiveMetadata[];
|
||||||
pipes: CompileTypeMetadata[];
|
declaredPipes: CompilePipeMetadata[];
|
||||||
|
exportedPipes: CompilePipeMetadata[];
|
||||||
|
// Note: See CompileDirectiveMetadata.precompile why this has to be a type.
|
||||||
precompile: CompileTypeMetadata[];
|
precompile: CompileTypeMetadata[];
|
||||||
modules: CompileTypeMetadata[];
|
providers: CompileProviderMetadata[];
|
||||||
|
|
||||||
constructor({type, providers, directives, pipes, precompile, modules}: {
|
importedModules: CompileNgModuleMetadata[];
|
||||||
|
exportedModules: CompileNgModuleMetadata[];
|
||||||
|
|
||||||
|
transitiveModule: TransitiveCompileNgModuleMetadata;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
{type, providers, declaredDirectives, exportedDirectives, declaredPipes, exportedPipes,
|
||||||
|
precompile, importedModules, exportedModules, transitiveModule}: {
|
||||||
type?: CompileTypeMetadata,
|
type?: CompileTypeMetadata,
|
||||||
providers?: Array<CompileProviderMetadata|CompileTypeMetadata|CompileIdentifierMetadata|any[]>,
|
providers?:
|
||||||
directives?: CompileTypeMetadata[],
|
Array<CompileProviderMetadata|CompileTypeMetadata|CompileIdentifierMetadata|any[]>,
|
||||||
pipes?: CompileTypeMetadata[],
|
declaredDirectives?: CompileDirectiveMetadata[],
|
||||||
|
exportedDirectives?: CompileDirectiveMetadata[],
|
||||||
|
declaredPipes?: CompilePipeMetadata[],
|
||||||
|
exportedPipes?: CompilePipeMetadata[],
|
||||||
precompile?: CompileTypeMetadata[],
|
precompile?: CompileTypeMetadata[],
|
||||||
modules?: CompileTypeMetadata[]
|
importedModules?: CompileNgModuleMetadata[],
|
||||||
|
exportedModules?: CompileNgModuleMetadata[],
|
||||||
|
transitiveModule?: TransitiveCompileNgModuleMetadata
|
||||||
} = {}) {
|
} = {}) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.directives = _normalizeArray(directives);
|
this.declaredDirectives = _normalizeArray(declaredDirectives);
|
||||||
this.pipes = _normalizeArray(pipes);
|
this.exportedDirectives = _normalizeArray(exportedDirectives);
|
||||||
|
this.declaredPipes = _normalizeArray(declaredPipes);
|
||||||
|
this.exportedPipes = _normalizeArray(exportedPipes);
|
||||||
this.providers = _normalizeArray(providers);
|
this.providers = _normalizeArray(providers);
|
||||||
this.precompile = _normalizeArray(precompile);
|
this.precompile = _normalizeArray(precompile);
|
||||||
this.modules = _normalizeArray(modules);
|
this.importedModules = _normalizeArray(importedModules);
|
||||||
|
this.exportedModules = _normalizeArray(exportedModules);
|
||||||
|
this.transitiveModule = transitiveModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
get identifier(): CompileIdentifierMetadata { return this.type; }
|
get identifier(): CompileIdentifierMetadata { return this.type; }
|
||||||
|
get runtimeCacheKey(): any { return this.type.runtimeCacheKey; }
|
||||||
|
|
||||||
static fromJson(data: {[key: string]: any}): CompileAppModuleMetadata {
|
get assetCacheKey(): any { return this.type.assetCacheKey; }
|
||||||
return new CompileAppModuleMetadata({
|
|
||||||
type: isPresent(data['type']) ? CompileTypeMetadata.fromJson(data['type']) : data['type'],
|
equalsTo(other: CompileMetadataWithIdentifier): boolean {
|
||||||
providers: _arrayFromJson(data['providers'], metadataFromJson),
|
return this.type.equalsTo(other.identifier);
|
||||||
directives: _arrayFromJson(data['directives'], metadataFromJson),
|
}
|
||||||
pipes: _arrayFromJson(data['pipes'], metadataFromJson),
|
}
|
||||||
precompile: _arrayFromJson(data['precompile'], CompileTypeMetadata.fromJson),
|
|
||||||
modules: _arrayFromJson(data['modules'], CompileTypeMetadata.fromJson)
|
export class TransitiveCompileNgModuleMetadata {
|
||||||
|
directivesSet = new Set<Type>();
|
||||||
|
pipesSet = new Set<Type>();
|
||||||
|
constructor(
|
||||||
|
public modules: CompileNgModuleMetadata[], public providers: CompileProviderMetadata[],
|
||||||
|
public precompile: CompileTypeMetadata[], public directives: CompileDirectiveMetadata[],
|
||||||
|
public pipes: CompilePipeMetadata[]) {
|
||||||
|
directives.forEach(dir => this.directivesSet.add(dir.type.runtime));
|
||||||
|
pipes.forEach(pipe => this.pipesSet.add(pipe.type.runtime));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function removeIdentifierDuplicates<T extends CompileMetadataWithIdentifier>(items: T[]):
|
||||||
|
T[] {
|
||||||
|
const map = new CompileIdentifierMap<T, T>();
|
||||||
|
items.forEach((item) => {
|
||||||
|
if (!map.get(item)) {
|
||||||
|
map.add(item, item);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
return map.keys();
|
||||||
|
|
||||||
toJson(): {[key: string]: any} {
|
|
||||||
return {
|
|
||||||
'class': 'AppModule',
|
|
||||||
'type': isPresent(this.type) ? this.type.toJson() : this.type,
|
|
||||||
'providers': _arrayToJson(this.providers),
|
|
||||||
'directives': _arrayToJson(this.directives),
|
|
||||||
'pipes': _arrayToJson(this.pipes),
|
|
||||||
'precompile': _arrayToJson(this.precompile),
|
|
||||||
'modules': _arrayToJson(this.modules)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var _COMPILE_METADATA_FROM_JSON = {
|
|
||||||
'AppModule': CompileAppModuleMetadata.fromJson,
|
|
||||||
'Directive': CompileDirectiveMetadata.fromJson,
|
|
||||||
'Pipe': CompilePipeMetadata.fromJson,
|
|
||||||
'Type': CompileTypeMetadata.fromJson,
|
|
||||||
'Provider': CompileProviderMetadata.fromJson,
|
|
||||||
'Identifier': CompileIdentifierMetadata.fromJson,
|
|
||||||
'Factory': CompileFactoryMetadata.fromJson,
|
|
||||||
'AnimationEntryMetadata': CompileAnimationEntryMetadata.fromJson,
|
|
||||||
'AnimationStateDeclarationMetadata': CompileAnimationStateDeclarationMetadata.fromJson,
|
|
||||||
'AnimationStateTransitionMetadata': CompileAnimationStateTransitionMetadata.fromJson,
|
|
||||||
'AnimationSequenceMetadata': CompileAnimationSequenceMetadata.fromJson,
|
|
||||||
'AnimationGroupMetadata': CompileAnimationGroupMetadata.fromJson,
|
|
||||||
'AnimationAnimateMetadata': CompileAnimationAnimateMetadata.fromJson,
|
|
||||||
'AnimationStyleMetadata': CompileAnimationStyleMetadata.fromJson,
|
|
||||||
'AnimationKeyframesSequenceMetadata': CompileAnimationKeyframesSequenceMetadata.fromJson
|
|
||||||
};
|
|
||||||
|
|
||||||
function _arrayFromJson(obj: any[], fn: (a: {[key: string]: any}) => any): any {
|
|
||||||
return isBlank(obj) ? null : obj.map(o => _objFromJson(o, fn));
|
|
||||||
}
|
|
||||||
|
|
||||||
function _arrayToJson(obj: any[]): string|{[key: string]: any} {
|
|
||||||
return isBlank(obj) ? null : obj.map(_objToJson);
|
|
||||||
}
|
|
||||||
|
|
||||||
function _objFromJson(obj: any, fn: (a: {[key: string]: any}) => any): any {
|
|
||||||
if (isArray(obj)) return _arrayFromJson(obj, fn);
|
|
||||||
if (isString(obj) || isBlank(obj) || isBoolean(obj) || isNumber(obj)) return obj;
|
|
||||||
return fn(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
function _objToJson(obj: any): string|{[key: string]: any} {
|
|
||||||
if (isArray(obj)) return _arrayToJson(obj);
|
|
||||||
if (isString(obj) || isBlank(obj) || isBoolean(obj) || isNumber(obj)) return obj;
|
|
||||||
return obj.toJson();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function _normalizeArray(obj: any[]): any[] {
|
function _normalizeArray(obj: any[]): any[] {
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {Compiler, CompilerFactory, CompilerOptions, ComponentResolver, Injectable, PLATFORM_DIRECTIVES, PLATFORM_PIPES, ReflectiveInjector, Type, ViewEncapsulation, isDevMode} from '@angular/core';
|
import {Compiler, CompilerFactory, CompilerOptions, Component, ComponentResolver, Inject, Injectable, NgModule, PLATFORM_DIRECTIVES, PLATFORM_INITIALIZER, PLATFORM_PIPES, PlatformRef, ReflectiveInjector, Type, ViewEncapsulation, corePlatform, createPlatformFactory, disposePlatform, isDevMode} from '@angular/core';
|
||||||
|
|
||||||
export * from './template_ast';
|
export * from './template_ast';
|
||||||
export {TEMPLATE_TRANSFORMS} from './template_parser';
|
export {TEMPLATE_TRANSFORMS} from './template_parser';
|
||||||
@ -20,14 +20,17 @@ export * from './xhr';
|
|||||||
export {ViewResolver} from './view_resolver';
|
export {ViewResolver} from './view_resolver';
|
||||||
export {DirectiveResolver} from './directive_resolver';
|
export {DirectiveResolver} from './directive_resolver';
|
||||||
export {PipeResolver} from './pipe_resolver';
|
export {PipeResolver} from './pipe_resolver';
|
||||||
|
export {NgModuleResolver} from './ng_module_resolver';
|
||||||
|
|
||||||
|
import {stringify} from './facade/lang';
|
||||||
|
import {ListWrapper} from './facade/collection';
|
||||||
import {TemplateParser} from './template_parser';
|
import {TemplateParser} from './template_parser';
|
||||||
import {HtmlParser} from './html_parser';
|
import {HtmlParser} from './html_parser';
|
||||||
import {DirectiveNormalizer} from './directive_normalizer';
|
import {DirectiveNormalizer} from './directive_normalizer';
|
||||||
import {CompileMetadataResolver} from './metadata_resolver';
|
import {CompileMetadataResolver} from './metadata_resolver';
|
||||||
import {StyleCompiler} from './style_compiler';
|
import {StyleCompiler} from './style_compiler';
|
||||||
import {ViewCompiler} from './view_compiler/view_compiler';
|
import {ViewCompiler} from './view_compiler/view_compiler';
|
||||||
import {AppModuleCompiler} from './app_module_compiler';
|
import {NgModuleCompiler} from './ng_module_compiler';
|
||||||
import {CompilerConfig} from './config';
|
import {CompilerConfig} from './config';
|
||||||
import {RuntimeCompiler} from './runtime_compiler';
|
import {RuntimeCompiler} from './runtime_compiler';
|
||||||
import {ElementSchemaRegistry} from './schema/element_schema_registry';
|
import {ElementSchemaRegistry} from './schema/element_schema_registry';
|
||||||
@ -38,19 +41,24 @@ import {Lexer} from './expression_parser/lexer';
|
|||||||
import {ViewResolver} from './view_resolver';
|
import {ViewResolver} from './view_resolver';
|
||||||
import {DirectiveResolver} from './directive_resolver';
|
import {DirectiveResolver} from './directive_resolver';
|
||||||
import {PipeResolver} from './pipe_resolver';
|
import {PipeResolver} from './pipe_resolver';
|
||||||
import {Console, Reflector, reflector, ReflectorReader} from '../core_private';
|
import {NgModuleResolver} from './ng_module_resolver';
|
||||||
|
import {Console, Reflector, reflector, ReflectorReader, ReflectionCapabilities} from '../core_private';
|
||||||
import {XHR} from './xhr';
|
import {XHR} from './xhr';
|
||||||
|
|
||||||
|
const _NO_XHR: XHR = {
|
||||||
|
get(url: string): Promise<string>{
|
||||||
|
throw new Error(`No XHR implementation has been provided. Can't read the url "${url}"`);}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A set of providers that provide `RuntimeCompiler` and its dependencies to use for
|
* A set of providers that provide `RuntimeCompiler` and its dependencies to use for
|
||||||
* template compilation.
|
* template compilation.
|
||||||
*/
|
*/
|
||||||
export const COMPILER_PROVIDERS: Array<any|Type|{[k: string]: any}|any[]> =
|
export const COMPILER_PROVIDERS: Array<any|Type|{[k: string]: any}|any[]> =
|
||||||
/*@ts2dart_const*/[
|
/*@ts2dart_const*/[
|
||||||
{provide: PLATFORM_DIRECTIVES, useValue: [], multi: true},
|
|
||||||
{provide: PLATFORM_PIPES, useValue: [], multi: true},
|
|
||||||
{provide: Reflector, useValue: reflector},
|
{provide: Reflector, useValue: reflector},
|
||||||
{provide: ReflectorReader, useExisting: Reflector},
|
{provide: ReflectorReader, useExisting: Reflector},
|
||||||
|
{provide: XHR, useValue: _NO_XHR},
|
||||||
Console,
|
Console,
|
||||||
Lexer,
|
Lexer,
|
||||||
Parser,
|
Parser,
|
||||||
@ -61,112 +69,153 @@ export const COMPILER_PROVIDERS: Array<any|Type|{[k: string]: any}|any[]> =
|
|||||||
DEFAULT_PACKAGE_URL_PROVIDER,
|
DEFAULT_PACKAGE_URL_PROVIDER,
|
||||||
StyleCompiler,
|
StyleCompiler,
|
||||||
ViewCompiler,
|
ViewCompiler,
|
||||||
AppModuleCompiler,
|
NgModuleCompiler,
|
||||||
/*@ts2dart_Provider*/ {provide: CompilerConfig, useValue: new CompilerConfig()},
|
/*@ts2dart_Provider*/ {provide: CompilerConfig, useValue: new CompilerConfig()},
|
||||||
RuntimeCompiler,
|
RuntimeCompiler,
|
||||||
/*@ts2dart_Provider*/ {provide: ComponentResolver, useExisting: RuntimeCompiler},
|
|
||||||
/*@ts2dart_Provider*/ {provide: Compiler, useExisting: RuntimeCompiler},
|
/*@ts2dart_Provider*/ {provide: Compiler, useExisting: RuntimeCompiler},
|
||||||
DomElementSchemaRegistry,
|
DomElementSchemaRegistry,
|
||||||
/*@ts2dart_Provider*/ {provide: ElementSchemaRegistry, useExisting: DomElementSchemaRegistry},
|
/*@ts2dart_Provider*/ {provide: ElementSchemaRegistry, useExisting: DomElementSchemaRegistry},
|
||||||
UrlResolver,
|
UrlResolver,
|
||||||
ViewResolver,
|
ViewResolver,
|
||||||
DirectiveResolver,
|
DirectiveResolver,
|
||||||
PipeResolver
|
PipeResolver,
|
||||||
|
NgModuleResolver
|
||||||
];
|
];
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class _RuntimeCompilerFactory extends CompilerFactory {
|
|
||||||
createCompiler(options: CompilerOptions): Compiler {
|
|
||||||
const deprecationMessages: string[] = [];
|
|
||||||
let platformDirectivesFromAppProviders: any[] = [];
|
|
||||||
let platformPipesFromAppProviders: any[] = [];
|
|
||||||
let compilerProvidersFromAppProviders: any[] = [];
|
|
||||||
let useDebugFromAppProviders: boolean;
|
|
||||||
let useJitFromAppProviders: boolean;
|
|
||||||
let defaultEncapsulationFromAppProviders: ViewEncapsulation;
|
|
||||||
|
|
||||||
if (options.deprecatedAppProviders && options.deprecatedAppProviders.length > 0) {
|
export function analyzeAppProvidersForDeprecatedConfiguration(appProviders: any[] = []):
|
||||||
|
{compilerOptions: CompilerOptions, moduleDeclarations: Type[], deprecationMessages: string[]} {
|
||||||
|
let platformDirectives: any[] = [];
|
||||||
|
let platformPipes: any[] = [];
|
||||||
|
|
||||||
|
let compilerProviders: any[] = [];
|
||||||
|
let useDebug: boolean;
|
||||||
|
let useJit: boolean;
|
||||||
|
let defaultEncapsulation: ViewEncapsulation;
|
||||||
|
const deprecationMessages: string[] = [];
|
||||||
|
|
||||||
// Note: This is a hack to still support the old way
|
// Note: This is a hack to still support the old way
|
||||||
// of configuring platform directives / pipes and the compiler xhr.
|
// of configuring platform directives / pipes and the compiler xhr.
|
||||||
// This will soon be deprecated!
|
// This will soon be deprecated!
|
||||||
const inj = ReflectiveInjector.resolveAndCreate(options.deprecatedAppProviders);
|
const tempInj = ReflectiveInjector.resolveAndCreate(appProviders);
|
||||||
const compilerConfig: CompilerConfig = inj.get(CompilerConfig, null);
|
const compilerConfig: CompilerConfig = tempInj.get(CompilerConfig, null);
|
||||||
if (compilerConfig) {
|
if (compilerConfig) {
|
||||||
platformDirectivesFromAppProviders = compilerConfig.deprecatedPlatformDirectives;
|
platformDirectives = compilerConfig.platformDirectives;
|
||||||
platformPipesFromAppProviders = compilerConfig.deprecatedPlatformPipes;
|
platformPipes = compilerConfig.platformPipes;
|
||||||
useJitFromAppProviders = compilerConfig.useJit;
|
useJit = compilerConfig.useJit;
|
||||||
useDebugFromAppProviders = compilerConfig.genDebugInfo;
|
useDebug = compilerConfig.genDebugInfo;
|
||||||
defaultEncapsulationFromAppProviders = compilerConfig.defaultEncapsulation;
|
defaultEncapsulation = compilerConfig.defaultEncapsulation;
|
||||||
deprecationMessages.push(
|
deprecationMessages.push(
|
||||||
`Passing a CompilerConfig to "bootstrap()" as provider is deprecated. Pass the provider via the new parameter "compilerOptions" of "bootstrap()" instead.`);
|
`Passing CompilerConfig as a regular provider is deprecated. Use the "compilerOptions" parameter of "bootstrap()" or use a custom "CompilerFactory" platform provider instead.`);
|
||||||
} else {
|
} else {
|
||||||
// If nobody provided a CompilerConfig, use the
|
// If nobody provided a CompilerConfig, use the
|
||||||
// PLATFORM_DIRECTIVES / PLATFORM_PIPES values directly if existing
|
// PLATFORM_DIRECTIVES / PLATFORM_PIPES values directly if existing
|
||||||
platformDirectivesFromAppProviders = inj.get(PLATFORM_DIRECTIVES, []);
|
platformDirectives = tempInj.get(PLATFORM_DIRECTIVES, []);
|
||||||
if (platformDirectivesFromAppProviders.length > 0) {
|
platformPipes = tempInj.get(PLATFORM_PIPES, []);
|
||||||
deprecationMessages.push(
|
|
||||||
`Passing PLATFORM_DIRECTIVES to "bootstrap()" as provider is deprecated. Use the new parameter "directives" of "bootstrap()" instead.`);
|
|
||||||
}
|
}
|
||||||
platformPipesFromAppProviders = inj.get(PLATFORM_PIPES, []);
|
platformDirectives = ListWrapper.flatten(platformDirectives);
|
||||||
if (platformPipesFromAppProviders.length > 0) {
|
platformPipes = ListWrapper.flatten(platformPipes);
|
||||||
deprecationMessages.push(
|
const xhr = tempInj.get(XHR, null);
|
||||||
`Passing PLATFORM_PIPES to "bootstrap()" as provider is deprecated. Use the new parameter "pipes" of "bootstrap()" instead.`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const xhr = inj.get(XHR, null);
|
|
||||||
if (xhr) {
|
if (xhr) {
|
||||||
compilerProvidersFromAppProviders.push([{provide: XHR, useValue: xhr}]);
|
compilerProviders.push([{provide: XHR, useValue: xhr}]);
|
||||||
deprecationMessages.push(
|
deprecationMessages.push(
|
||||||
`Passing an instance of XHR to "bootstrap()" as provider is deprecated. Pass the provider via the new parameter "compilerOptions" of "bootstrap()" instead.`);
|
`Passing XHR as regular provider is deprecated. Pass the provider via "compilerOptions" instead.`);
|
||||||
}
|
|
||||||
// Need to copy console from deprecatedAppProviders to compiler providers
|
|
||||||
// as well so that we can test the above deprecation messages in old style bootstrap
|
|
||||||
// where we only have app providers!
|
|
||||||
const console = inj.get(Console, null);
|
|
||||||
if (console) {
|
|
||||||
compilerProvidersFromAppProviders.push([{provide: Console, useValue: console}]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (platformDirectives.length > 0) {
|
||||||
|
deprecationMessages.push(
|
||||||
|
`The PLATFORM_DIRECTIVES provider and CompilerConfig.platformDirectives is deprecated. Add the directives to an NgModule instead! ` +
|
||||||
|
`(Directives: ${platformDirectives.map(type => stringify(type))})`);
|
||||||
|
}
|
||||||
|
if (platformPipes.length > 0) {
|
||||||
|
deprecationMessages.push(
|
||||||
|
`The PLATFORM_PIPES provider and CompilerConfig.platformPipes is deprecated. Add the pipes to an NgModule instead! ` +
|
||||||
|
`(Pipes: ${platformPipes.map(type => stringify(type))})`);
|
||||||
|
}
|
||||||
|
const compilerOptions: CompilerOptions = {
|
||||||
|
useJit: useJit,
|
||||||
|
useDebug: useDebug,
|
||||||
|
defaultEncapsulation: defaultEncapsulation,
|
||||||
|
providers: compilerProviders
|
||||||
|
};
|
||||||
|
|
||||||
|
// Declare a component that uses @Component.directives / pipes as these
|
||||||
|
// will be added to the module declarations only if they are not already
|
||||||
|
// imported by other modules.
|
||||||
|
@Component({directives: platformDirectives, pipes: platformPipes, template: ''})
|
||||||
|
class DynamicComponent {
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
compilerOptions,
|
||||||
|
moduleDeclarations: [DynamicComponent],
|
||||||
|
deprecationMessages: deprecationMessages
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class RuntimeCompilerFactory implements CompilerFactory {
|
||||||
|
private _defaultOptions: CompilerOptions[];
|
||||||
|
constructor(@Inject(CompilerOptions) defaultOptions: CompilerOptions[]) {
|
||||||
|
this._defaultOptions = [<CompilerOptions>{
|
||||||
|
useDebug: isDevMode(),
|
||||||
|
useJit: true,
|
||||||
|
defaultEncapsulation: ViewEncapsulation.Emulated
|
||||||
|
}].concat(defaultOptions);
|
||||||
|
}
|
||||||
|
createCompiler(options: CompilerOptions[] = []): Compiler {
|
||||||
|
const mergedOptions = _mergeOptions(this._defaultOptions.concat(options));
|
||||||
const injector = ReflectiveInjector.resolveAndCreate([
|
const injector = ReflectiveInjector.resolveAndCreate([
|
||||||
COMPILER_PROVIDERS, {
|
COMPILER_PROVIDERS, {
|
||||||
provide: CompilerConfig,
|
provide: CompilerConfig,
|
||||||
useFactory: (platformDirectives: any[], platformPipes: any[]) => {
|
useFactory: () => {
|
||||||
return new CompilerConfig({
|
return new CompilerConfig({
|
||||||
deprecatedPlatformDirectives:
|
|
||||||
_mergeArrays(platformDirectivesFromAppProviders, platformDirectives),
|
|
||||||
deprecatedPlatformPipes: _mergeArrays(platformPipesFromAppProviders, platformPipes),
|
|
||||||
// let explicit values from the compiler options overwrite options
|
// let explicit values from the compiler options overwrite options
|
||||||
// from the app providers. E.g. important for the testing platform.
|
// from the app providers. E.g. important for the testing platform.
|
||||||
genDebugInfo: _firstDefined(options.useDebug, useDebugFromAppProviders, isDevMode()),
|
genDebugInfo: mergedOptions.useDebug,
|
||||||
// let explicit values from the compiler options overwrite options
|
// let explicit values from the compiler options overwrite options
|
||||||
// from the app providers
|
// from the app providers
|
||||||
useJit: _firstDefined(options.useJit, useJitFromAppProviders, true),
|
useJit: mergedOptions.useJit,
|
||||||
// let explicit values from the compiler options overwrite options
|
// let explicit values from the compiler options overwrite options
|
||||||
// from the app providers
|
// from the app providers
|
||||||
defaultEncapsulation: _firstDefined(
|
defaultEncapsulation: mergedOptions.defaultEncapsulation,
|
||||||
options.defaultEncapsulation, defaultEncapsulationFromAppProviders,
|
logBindingUpdate: mergedOptions.useDebug
|
||||||
ViewEncapsulation.Emulated)
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
deps: [PLATFORM_DIRECTIVES, PLATFORM_PIPES]
|
deps: []
|
||||||
},
|
},
|
||||||
// options.providers will always contain a provider for XHR as well
|
mergedOptions.providers
|
||||||
// (added by platforms). So allow compilerProvidersFromAppProviders to overwrite this
|
|
||||||
_mergeArrays(options.providers, compilerProvidersFromAppProviders)
|
|
||||||
]);
|
]);
|
||||||
const console: Console = injector.get(Console);
|
|
||||||
deprecationMessages.forEach((msg) => { console.warn(msg); });
|
|
||||||
|
|
||||||
return injector.get(Compiler);
|
return injector.get(Compiler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _initReflector() {
|
||||||
|
reflector.reflectionCapabilities = new ReflectionCapabilities();
|
||||||
|
}
|
||||||
|
|
||||||
export const RUNTIME_COMPILER_FACTORY = new _RuntimeCompilerFactory();
|
/**
|
||||||
|
* A platform that included corePlatform and the compiler.
|
||||||
|
*
|
||||||
|
* @experimental
|
||||||
|
*/
|
||||||
|
export const coreDynamicPlatform = createPlatformFactory(corePlatform, 'coreDynamic', [
|
||||||
|
{provide: CompilerOptions, useValue: {}, multi: true},
|
||||||
|
{provide: CompilerFactory, useClass: RuntimeCompilerFactory},
|
||||||
|
{provide: PLATFORM_INITIALIZER, useValue: _initReflector, multi: true},
|
||||||
|
]);
|
||||||
|
|
||||||
function _firstDefined<T>(...args: T[]): T {
|
function _mergeOptions(optionsArr: CompilerOptions[]): CompilerOptions {
|
||||||
for (var i = 0; i < args.length; i++) {
|
return {
|
||||||
|
useDebug: _lastDefined(optionsArr.map(options => options.useDebug)),
|
||||||
|
useJit: _lastDefined(optionsArr.map(options => options.useJit)),
|
||||||
|
defaultEncapsulation: _lastDefined(optionsArr.map(options => options.defaultEncapsulation)),
|
||||||
|
providers: _mergeArrays(optionsArr.map(options => options.providers))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function _lastDefined<T>(args: T[]): T {
|
||||||
|
for (var i = args.length - 1; i >= 0; i--) {
|
||||||
if (args[i] !== undefined) {
|
if (args[i] !== undefined) {
|
||||||
return args[i];
|
return args[i];
|
||||||
}
|
}
|
||||||
@ -174,7 +223,7 @@ function _firstDefined<T>(...args: T[]): T {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _mergeArrays(...parts: any[][]): any[] {
|
function _mergeArrays(parts: any[][]): any[] {
|
||||||
let result: any[] = [];
|
let result: any[] = [];
|
||||||
parts.forEach((part) => result.push(...part));
|
parts.forEach((part) => result.push(...part));
|
||||||
return result;
|
return result;
|
||||||
|
@ -20,17 +20,15 @@ export class CompilerConfig {
|
|||||||
private _logBindingUpdate: boolean;
|
private _logBindingUpdate: boolean;
|
||||||
public useJit: boolean;
|
public useJit: boolean;
|
||||||
/**
|
/**
|
||||||
* @deprecated Providing platform directives via the {@link CompilerConfig} deprecated. Provide
|
* @deprecated Providing platform directives via the {@link CompilerConfig} is deprecated. Provide
|
||||||
* platform
|
* platform directives via an {@link NgModule} instead.
|
||||||
* directives via an {@link AppModule} instead.
|
|
||||||
*/
|
*/
|
||||||
public deprecatedPlatformDirectives: any[];
|
public platformDirectives: any[];
|
||||||
/**
|
/**
|
||||||
* @deprecated Providing platform pipes via the {@link CompilerConfig} deprecated. Provide
|
* @deprecated Providing platform pipes via the {@link CompilerConfig} is deprecated. Provide
|
||||||
* platform pipes
|
* platform pipes via an {@link NgModule} instead.
|
||||||
* via an {@link AppModule} instead.
|
|
||||||
*/
|
*/
|
||||||
public deprecatedPlatformPipes: any[];
|
public platformPipes: any[];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
{renderTypes = new DefaultRenderTypes(), defaultEncapsulation = ViewEncapsulation.Emulated,
|
{renderTypes = new DefaultRenderTypes(), defaultEncapsulation = ViewEncapsulation.Emulated,
|
||||||
@ -49,8 +47,8 @@ export class CompilerConfig {
|
|||||||
this._genDebugInfo = genDebugInfo;
|
this._genDebugInfo = genDebugInfo;
|
||||||
this._logBindingUpdate = logBindingUpdate;
|
this._logBindingUpdate = logBindingUpdate;
|
||||||
this.useJit = useJit;
|
this.useJit = useJit;
|
||||||
this.deprecatedPlatformDirectives = deprecatedPlatformDirectives;
|
this.platformDirectives = deprecatedPlatformDirectives;
|
||||||
this.deprecatedPlatformPipes = deprecatedPlatformPipes;
|
this.platformPipes = deprecatedPlatformPipes;
|
||||||
}
|
}
|
||||||
|
|
||||||
get genDebugInfo(): boolean {
|
get genDebugInfo(): boolean {
|
||||||
|
@ -33,7 +33,7 @@ export class DirectiveResolver {
|
|||||||
/**
|
/**
|
||||||
* Return {@link DirectiveMetadata} for a given `Type`.
|
* Return {@link DirectiveMetadata} for a given `Type`.
|
||||||
*/
|
*/
|
||||||
resolve(type: Type): DirectiveMetadata {
|
resolve(type: Type, throwIfNotFound = true): DirectiveMetadata {
|
||||||
var typeMetadata = this._reflector.annotations(resolveForwardRef(type));
|
var typeMetadata = this._reflector.annotations(resolveForwardRef(type));
|
||||||
if (isPresent(typeMetadata)) {
|
if (isPresent(typeMetadata)) {
|
||||||
var metadata = typeMetadata.find(_isDirectiveMetadata);
|
var metadata = typeMetadata.find(_isDirectiveMetadata);
|
||||||
@ -42,9 +42,11 @@ export class DirectiveResolver {
|
|||||||
return this._mergeWithPropertyMetadata(metadata, propertyMetadata, type);
|
return this._mergeWithPropertyMetadata(metadata, propertyMetadata, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (throwIfNotFound) {
|
||||||
throw new BaseException(`No Directive annotation found on ${stringify(type)}`);
|
throw new BaseException(`No Directive annotation found on ${stringify(type)}`);
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private _mergeWithPropertyMetadata(
|
private _mergeWithPropertyMetadata(
|
||||||
dm: DirectiveMetadata, propertyMetadata: {[key: string]: any[]},
|
dm: DirectiveMetadata, propertyMetadata: {[key: string]: any[]},
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {ANALYZE_FOR_PRECOMPILE, AppModuleFactory, ChangeDetectionStrategy, ChangeDetectorRef, ComponentFactory, ComponentFactoryResolver, ElementRef, Injector, QueryList, RenderComponentType, Renderer, SecurityContext, SimpleChange, TemplateRef, ViewContainerRef, ViewEncapsulation} from '@angular/core';
|
import {ANALYZE_FOR_PRECOMPILE, ChangeDetectionStrategy, ChangeDetectorRef, ComponentFactory, ComponentFactoryResolver, ElementRef, Injector, NgModuleFactory, QueryList, RenderComponentType, Renderer, SecurityContext, SimpleChange, TemplateRef, ViewContainerRef, ViewEncapsulation} from '@angular/core';
|
||||||
|
|
||||||
import {AnimationGroupPlayer as AnimationGroupPlayer_, AnimationKeyframe as AnimationKeyframe_, AnimationSequencePlayer as AnimationSequencePlayer_, AnimationStyles as AnimationStyles_, AppElement, AppModuleInjector, AppView, ChangeDetectorStatus, CodegenComponentFactoryResolver, DebugAppView, DebugContext, EMPTY_ARRAY, EMPTY_MAP, NoOpAnimationPlayer as NoOpAnimationPlayer_, StaticNodeDebugInfo, TemplateRef_, UNINITIALIZED, ValueUnwrapper, ViewType, ViewUtils, balanceAnimationKeyframes as impBalanceAnimationKeyframes, castByValue, checkBinding, clearStyles as impClearStyles, collectAndResolveStyles as impCollectAndResolveStyles, devModeEqual, flattenNestedViewRenderNodes, interpolate, prepareFinalAnimationStyles as impBalanceAnimationStyles, pureProxy1, pureProxy10, pureProxy2, pureProxy3, pureProxy4, pureProxy5, pureProxy6, pureProxy7, pureProxy8, pureProxy9, renderStyles as impRenderStyles} from '../core_private';
|
import {AnimationGroupPlayer as AnimationGroupPlayer_, AnimationKeyframe as AnimationKeyframe_, AnimationSequencePlayer as AnimationSequencePlayer_, AnimationStyles as AnimationStyles_, AppElement, AppView, ChangeDetectorStatus, CodegenComponentFactoryResolver, DebugAppView, DebugContext, EMPTY_ARRAY, EMPTY_MAP, NgModuleInjector, NoOpAnimationPlayer as NoOpAnimationPlayer_, StaticNodeDebugInfo, TemplateRef_, UNINITIALIZED, ValueUnwrapper, ViewType, ViewUtils, balanceAnimationKeyframes as impBalanceAnimationKeyframes, castByValue, checkBinding, clearStyles as impClearStyles, collectAndResolveStyles as impCollectAndResolveStyles, devModeEqual, flattenNestedViewRenderNodes, interpolate, prepareFinalAnimationStyles as impBalanceAnimationStyles, pureProxy1, pureProxy10, pureProxy2, pureProxy3, pureProxy4, pureProxy5, pureProxy6, pureProxy7, pureProxy8, pureProxy9, renderStyles as impRenderStyles} from '../core_private';
|
||||||
|
|
||||||
import {CompileIdentifierMetadata, CompileTokenMetadata} from './compile_metadata';
|
import {CompileIdentifierMetadata, CompileTokenMetadata} from './compile_metadata';
|
||||||
import {assetUrl} from './util';
|
import {assetUrl} from './util';
|
||||||
@ -118,15 +118,15 @@ export class Identifiers {
|
|||||||
runtime: ComponentFactory,
|
runtime: ComponentFactory,
|
||||||
moduleUrl: assetUrl('core', 'linker/component_factory')
|
moduleUrl: assetUrl('core', 'linker/component_factory')
|
||||||
});
|
});
|
||||||
static AppModuleFactory = new CompileIdentifierMetadata({
|
static NgModuleFactory = new CompileIdentifierMetadata({
|
||||||
name: 'AppModuleFactory',
|
name: 'NgModuleFactory',
|
||||||
runtime: AppModuleFactory,
|
runtime: NgModuleFactory,
|
||||||
moduleUrl: assetUrl('core', 'linker/app_module_factory')
|
moduleUrl: assetUrl('core', 'linker/ng_module_factory')
|
||||||
});
|
});
|
||||||
static AppModuleInjector = new CompileIdentifierMetadata({
|
static NgModuleInjector = new CompileIdentifierMetadata({
|
||||||
name: 'AppModuleInjector',
|
name: 'NgModuleInjector',
|
||||||
runtime: AppModuleInjector,
|
runtime: NgModuleInjector,
|
||||||
moduleUrl: assetUrl('core', 'linker/app_module_factory')
|
moduleUrl: assetUrl('core', 'linker/ng_module_factory')
|
||||||
});
|
});
|
||||||
static ValueUnwrapper = new CompileIdentifierMetadata(
|
static ValueUnwrapper = new CompileIdentifierMetadata(
|
||||||
{name: 'ValueUnwrapper', moduleUrl: CD_MODULE_URL, runtime: impValueUnwrapper});
|
{name: 'ValueUnwrapper', moduleUrl: CD_MODULE_URL, runtime: impValueUnwrapper});
|
||||||
|
@ -6,10 +6,10 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {AnimationAnimateMetadata, AnimationEntryMetadata, AnimationGroupMetadata, AnimationKeyframesSequenceMetadata, AnimationMetadata, AnimationStateDeclarationMetadata, AnimationStateMetadata, AnimationStateTransitionMetadata, AnimationStyleMetadata, AnimationWithStepsMetadata, AppModuleMetadata, AttributeMetadata, ChangeDetectionStrategy, ComponentMetadata, HostMetadata, Inject, InjectMetadata, Injectable, Optional, OptionalMetadata, Provider, QueryMetadata, SelfMetadata, SkipSelfMetadata, ViewMetadata, ViewQueryMetadata, resolveForwardRef} from '@angular/core';
|
import {AnimationAnimateMetadata, AnimationEntryMetadata, AnimationGroupMetadata, AnimationKeyframesSequenceMetadata, AnimationMetadata, AnimationStateDeclarationMetadata, AnimationStateMetadata, AnimationStateTransitionMetadata, AnimationStyleMetadata, AnimationWithStepsMetadata, AttributeMetadata, ChangeDetectionStrategy, ComponentMetadata, HostMetadata, Inject, InjectMetadata, Injectable, NgModule, NgModuleMetadata, Optional, OptionalMetadata, Provider, QueryMetadata, SelfMetadata, SkipSelfMetadata, ViewMetadata, ViewQueryMetadata, resolveForwardRef} from '@angular/core';
|
||||||
|
|
||||||
import {LIFECYCLE_HOOKS_VALUES, ReflectorReader, createProvider, isProviderLiteral, reflector} from '../core_private';
|
import {Console, LIFECYCLE_HOOKS_VALUES, ReflectorReader, createProvider, isProviderLiteral, reflector} from '../core_private';
|
||||||
import {StringMapWrapper} from '../src/facade/collection';
|
import {MapWrapper, StringMapWrapper} from '../src/facade/collection';
|
||||||
import {BaseException} from '../src/facade/exceptions';
|
import {BaseException} from '../src/facade/exceptions';
|
||||||
import {Type, isArray, isBlank, isPresent, isString, isStringMap, stringify} from '../src/facade/lang';
|
import {Type, isArray, isBlank, isPresent, isString, isStringMap, stringify} from '../src/facade/lang';
|
||||||
|
|
||||||
@ -19,6 +19,7 @@ import {CompilerConfig} from './config';
|
|||||||
import {hasLifecycleHook} from './directive_lifecycle_reflector';
|
import {hasLifecycleHook} from './directive_lifecycle_reflector';
|
||||||
import {DirectiveResolver} from './directive_resolver';
|
import {DirectiveResolver} from './directive_resolver';
|
||||||
import {Identifiers, identifierToken} from './identifiers';
|
import {Identifiers, identifierToken} from './identifiers';
|
||||||
|
import {NgModuleResolver} from './ng_module_resolver';
|
||||||
import {PipeResolver} from './pipe_resolver';
|
import {PipeResolver} from './pipe_resolver';
|
||||||
import {getUrlScheme} from './url_resolver';
|
import {getUrlScheme} from './url_resolver';
|
||||||
import {MODULE_SUFFIX, ValueTransformer, sanitizeIdentifier, visitValue} from './util';
|
import {MODULE_SUFFIX, ValueTransformer, sanitizeIdentifier, visitValue} from './util';
|
||||||
@ -28,13 +29,15 @@ import {ViewResolver} from './view_resolver';
|
|||||||
export class CompileMetadataResolver {
|
export class CompileMetadataResolver {
|
||||||
private _directiveCache = new Map<Type, cpl.CompileDirectiveMetadata>();
|
private _directiveCache = new Map<Type, cpl.CompileDirectiveMetadata>();
|
||||||
private _pipeCache = new Map<Type, cpl.CompilePipeMetadata>();
|
private _pipeCache = new Map<Type, cpl.CompilePipeMetadata>();
|
||||||
private _appModuleCache = new Map<Type, cpl.CompileAppModuleMetadata>();
|
private _ngModuleCache = new Map<Type, cpl.CompileNgModuleMetadata>();
|
||||||
|
private _ngModuleOfTypes = new Map<Type, Type>();
|
||||||
private _anonymousTypes = new Map<Object, number>();
|
private _anonymousTypes = new Map<Object, number>();
|
||||||
private _anonymousTypeIndex = 0;
|
private _anonymousTypeIndex = 0;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private _directiveResolver: DirectiveResolver, private _pipeResolver: PipeResolver,
|
private _ngModuleResolver: NgModuleResolver, private _directiveResolver: DirectiveResolver,
|
||||||
private _viewResolver: ViewResolver, private _config: CompilerConfig,
|
private _pipeResolver: PipeResolver, private _viewResolver: ViewResolver,
|
||||||
|
private _config: CompilerConfig, private _console: Console,
|
||||||
private _reflector: ReflectorReader = reflector) {}
|
private _reflector: ReflectorReader = reflector) {}
|
||||||
|
|
||||||
private sanitizeTokenName(token: any): string {
|
private sanitizeTokenName(token: any): string {
|
||||||
@ -54,13 +57,16 @@ export class CompileMetadataResolver {
|
|||||||
clearCacheFor(type: Type) {
|
clearCacheFor(type: Type) {
|
||||||
this._directiveCache.delete(type);
|
this._directiveCache.delete(type);
|
||||||
this._pipeCache.delete(type);
|
this._pipeCache.delete(type);
|
||||||
this._appModuleCache.delete(type);
|
this._ngModuleOfTypes.delete(type);
|
||||||
|
// Clear all of the NgModuleMetadata as they contain transitive information!
|
||||||
|
this._ngModuleCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
clearCache() {
|
clearCache() {
|
||||||
this._directiveCache.clear();
|
this._directiveCache.clear();
|
||||||
this._pipeCache.clear();
|
this._pipeCache.clear();
|
||||||
this._appModuleCache.clear();
|
this._ngModuleCache.clear();
|
||||||
|
this._ngModuleOfTypes.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
getAnimationEntryMetadata(entry: AnimationEntryMetadata): cpl.CompileAnimationEntryMetadata {
|
getAnimationEntryMetadata(entry: AnimationEntryMetadata): cpl.CompileAnimationEntryMetadata {
|
||||||
@ -105,11 +111,14 @@ export class CompileMetadataResolver {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
getDirectiveMetadata(directiveType: Type): cpl.CompileDirectiveMetadata {
|
getDirectiveMetadata(directiveType: Type, throwIfNotFound = true): cpl.CompileDirectiveMetadata {
|
||||||
directiveType = resolveForwardRef(directiveType);
|
directiveType = resolveForwardRef(directiveType);
|
||||||
var meta = this._directiveCache.get(directiveType);
|
var meta = this._directiveCache.get(directiveType);
|
||||||
if (isBlank(meta)) {
|
if (isBlank(meta)) {
|
||||||
var dirMeta = this._directiveResolver.resolve(directiveType);
|
var dirMeta = this._directiveResolver.resolve(directiveType, throwIfNotFound);
|
||||||
|
if (!dirMeta) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
var templateMeta: cpl.CompileTemplateMetadata = null;
|
var templateMeta: cpl.CompileTemplateMetadata = null;
|
||||||
var changeDetectionStrategy: ChangeDetectionStrategy = null;
|
var changeDetectionStrategy: ChangeDetectionStrategy = null;
|
||||||
var viewProviders: Array<cpl.CompileProviderMetadata|cpl.CompileTypeMetadata|any[]> = [];
|
var viewProviders: Array<cpl.CompileProviderMetadata|cpl.CompileTypeMetadata|any[]> = [];
|
||||||
@ -182,83 +191,254 @@ export class CompileMetadataResolver {
|
|||||||
return meta;
|
return meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
getAppModuleMetadata(moduleType: any, meta: AppModuleMetadata = null):
|
getNgModuleMetadata(moduleType: any, throwIfNotFound = true): cpl.CompileNgModuleMetadata {
|
||||||
cpl.CompileAppModuleMetadata {
|
|
||||||
// Only cache if we read the metadata via the reflector,
|
|
||||||
// as we use the moduleType as cache key.
|
|
||||||
let useCache = !meta;
|
|
||||||
moduleType = resolveForwardRef(moduleType);
|
moduleType = resolveForwardRef(moduleType);
|
||||||
var compileMeta = this._appModuleCache.get(moduleType);
|
var compileMeta = this._ngModuleCache.get(moduleType);
|
||||||
if (isBlank(compileMeta) || !useCache) {
|
if (!compileMeta) {
|
||||||
|
const meta = this._ngModuleResolver.resolve(moduleType, throwIfNotFound);
|
||||||
if (!meta) {
|
if (!meta) {
|
||||||
meta = this._reflector.annotations(moduleType)
|
return null;
|
||||||
.find((meta) => meta instanceof AppModuleMetadata);
|
|
||||||
}
|
}
|
||||||
if (!meta) {
|
const declaredDirectives: cpl.CompileDirectiveMetadata[] = [];
|
||||||
|
const exportedDirectives: cpl.CompileDirectiveMetadata[] = [];
|
||||||
|
const declaredPipes: cpl.CompilePipeMetadata[] = [];
|
||||||
|
const exportedPipes: cpl.CompilePipeMetadata[] = [];
|
||||||
|
const importedModules: cpl.CompileNgModuleMetadata[] = [];
|
||||||
|
const exportedModules: cpl.CompileNgModuleMetadata[] = [];
|
||||||
|
|
||||||
|
if (meta.imports) {
|
||||||
|
flattenArray(meta.imports).forEach((importedType) => {
|
||||||
|
if (!isValidType(importedType)) {
|
||||||
throw new BaseException(
|
throw new BaseException(
|
||||||
`Could not compile '${stringify(moduleType)}' because it is not an AppModule.`);
|
`Unexpected value '${stringify(importedType)}' imported by the module '${stringify(moduleType)}'`);
|
||||||
|
}
|
||||||
|
let importedModuleMeta: cpl.CompileNgModuleMetadata;
|
||||||
|
if (importedModuleMeta = this.getNgModuleMetadata(importedType, false)) {
|
||||||
|
importedModules.push(importedModuleMeta);
|
||||||
|
} else {
|
||||||
|
throw new BaseException(
|
||||||
|
`Unexpected value '${stringify(importedType)}' imported by the module '${stringify(moduleType)}'`);
|
||||||
}
|
}
|
||||||
let modules: cpl.CompileTypeMetadata[] = [];
|
|
||||||
let providers: any[] = [];
|
|
||||||
let directives: cpl.CompileTypeMetadata[] = [];
|
|
||||||
let pipes: cpl.CompileTypeMetadata[] = [];
|
|
||||||
let precompile: cpl.CompileTypeMetadata[] = [];
|
|
||||||
if (meta.modules) {
|
|
||||||
flattenArray(meta.modules).forEach((moduleType) => {
|
|
||||||
var meta = this.getAppModuleMetadata(moduleType);
|
|
||||||
providers.push(...meta.providers);
|
|
||||||
directives.push(...meta.directives);
|
|
||||||
pipes.push(...meta.pipes);
|
|
||||||
precompile.push(...meta.precompile);
|
|
||||||
modules.push(meta.type);
|
|
||||||
modules.push(...meta.modules);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (meta.exports) {
|
||||||
|
flattenArray(meta.exports).forEach((exportedType) => {
|
||||||
|
if (!isValidType(exportedType)) {
|
||||||
|
throw new BaseException(
|
||||||
|
`Unexpected value '${stringify(exportedType)}' exported by the module '${stringify(moduleType)}'`);
|
||||||
|
}
|
||||||
|
let exportedDirMeta: cpl.CompileDirectiveMetadata;
|
||||||
|
let exportedPipeMeta: cpl.CompilePipeMetadata;
|
||||||
|
let exportedModuleMeta: cpl.CompileNgModuleMetadata;
|
||||||
|
if (exportedDirMeta = this.getDirectiveMetadata(exportedType, false)) {
|
||||||
|
exportedDirectives.push(exportedDirMeta);
|
||||||
|
} else if (exportedPipeMeta = this.getPipeMetadata(exportedType, false)) {
|
||||||
|
exportedPipes.push(exportedPipeMeta);
|
||||||
|
} else if (exportedModuleMeta = this.getNgModuleMetadata(exportedType, false)) {
|
||||||
|
exportedModules.push(exportedModuleMeta);
|
||||||
|
} else {
|
||||||
|
throw new BaseException(
|
||||||
|
`Unexpected value '${stringify(exportedType)}' exported by the module '${stringify(moduleType)}'`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: This will be modified later, so we rely on
|
||||||
|
// getting a new instance every time!
|
||||||
|
const transitiveModule =
|
||||||
|
this._getTransitiveNgModuleMetadata(importedModules, exportedModules);
|
||||||
|
if (meta.declarations) {
|
||||||
|
flattenArray(meta.declarations).forEach((declaredType) => {
|
||||||
|
if (!isValidType(declaredType)) {
|
||||||
|
throw new BaseException(
|
||||||
|
`Unexpected value '${stringify(declaredType)}' declared by the module '${stringify(moduleType)}'`);
|
||||||
|
}
|
||||||
|
let declaredDirMeta: cpl.CompileDirectiveMetadata;
|
||||||
|
let declaredPipeMeta: cpl.CompilePipeMetadata;
|
||||||
|
if (declaredDirMeta = this.getDirectiveMetadata(declaredType, false)) {
|
||||||
|
this._addDirectiveToModule(
|
||||||
|
declaredDirMeta, moduleType, transitiveModule, declaredDirectives, true);
|
||||||
|
// Collect @Component.directives/pipes/precompile into our declared directives/pipes.
|
||||||
|
this._getTransitiveViewDirectivesAndPipes(
|
||||||
|
declaredDirMeta, moduleType, transitiveModule, declaredDirectives, declaredPipes);
|
||||||
|
} else if (declaredPipeMeta = this.getPipeMetadata(declaredType, false)) {
|
||||||
|
this._addPipeToModule(
|
||||||
|
declaredPipeMeta, moduleType, transitiveModule, declaredPipes, true);
|
||||||
|
} else {
|
||||||
|
throw new BaseException(
|
||||||
|
`Unexpected value '${stringify(declaredType)}' declared by the module '${stringify(moduleType)}'`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const providers: any[] = [];
|
||||||
|
const precompile: cpl.CompileTypeMetadata[] = [];
|
||||||
if (meta.providers) {
|
if (meta.providers) {
|
||||||
providers.push(...this.getProvidersMetadata(meta.providers, precompile));
|
providers.push(...this.getProvidersMetadata(meta.providers, precompile));
|
||||||
}
|
}
|
||||||
if (meta.directives) {
|
|
||||||
directives.push(...flattenArray(meta.directives)
|
|
||||||
.map(type => this.getTypeMetadata(type, staticTypeModuleUrl(type))));
|
|
||||||
}
|
|
||||||
if (meta.pipes) {
|
|
||||||
pipes.push(...flattenArray(meta.pipes)
|
|
||||||
.map(type => this.getTypeMetadata(type, staticTypeModuleUrl(type))));
|
|
||||||
}
|
|
||||||
if (meta.precompile) {
|
if (meta.precompile) {
|
||||||
precompile.push(...flattenArray(meta.precompile)
|
precompile.push(...flattenArray(meta.precompile)
|
||||||
.map(type => this.getTypeMetadata(type, staticTypeModuleUrl(type))));
|
.map(type => this.getTypeMetadata(type, staticTypeModuleUrl(type))));
|
||||||
}
|
}
|
||||||
|
|
||||||
compileMeta = new cpl.CompileAppModuleMetadata({
|
transitiveModule.precompile.push(...precompile);
|
||||||
|
transitiveModule.providers.push(...providers);
|
||||||
|
|
||||||
|
compileMeta = new cpl.CompileNgModuleMetadata({
|
||||||
type: this.getTypeMetadata(moduleType, staticTypeModuleUrl(moduleType)),
|
type: this.getTypeMetadata(moduleType, staticTypeModuleUrl(moduleType)),
|
||||||
providers: providers,
|
providers: providers,
|
||||||
directives: directives,
|
|
||||||
pipes: pipes,
|
|
||||||
precompile: precompile,
|
precompile: precompile,
|
||||||
modules: modules
|
declaredDirectives: declaredDirectives,
|
||||||
|
exportedDirectives: exportedDirectives,
|
||||||
|
declaredPipes: declaredPipes,
|
||||||
|
exportedPipes: exportedPipes,
|
||||||
|
importedModules: importedModules,
|
||||||
|
exportedModules: exportedModules,
|
||||||
|
transitiveModule: transitiveModule
|
||||||
});
|
});
|
||||||
if (useCache) {
|
transitiveModule.modules.push(compileMeta);
|
||||||
this._appModuleCache.set(moduleType, compileMeta);
|
this._verifyModule(compileMeta);
|
||||||
}
|
this._ngModuleCache.set(moduleType, compileMeta);
|
||||||
}
|
}
|
||||||
return compileMeta;
|
return compileMeta;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
addComponentToModule(moduleType: Type, compType: Type) {
|
||||||
* @param someType a symbol which may or may not be a directive type
|
const moduleMeta = this.getNgModuleMetadata(moduleType);
|
||||||
* @returns {cpl.CompileDirectiveMetadata} if possible, otherwise null.
|
// Collect @Component.directives/pipes/precompile into our declared directives/pipes.
|
||||||
*/
|
const compMeta = this.getDirectiveMetadata(compType, false);
|
||||||
maybeGetDirectiveMetadata(someType: Type): cpl.CompileDirectiveMetadata {
|
this._addDirectiveToModule(
|
||||||
try {
|
compMeta, moduleMeta.type.runtime, moduleMeta.transitiveModule,
|
||||||
return this.getDirectiveMetadata(someType);
|
moduleMeta.declaredDirectives);
|
||||||
} catch (e) {
|
this._getTransitiveViewDirectivesAndPipes(
|
||||||
if (e.message.indexOf('No Directive annotation') !== -1) {
|
compMeta, moduleMeta.type.runtime, moduleMeta.transitiveModule,
|
||||||
return null;
|
moduleMeta.declaredDirectives, moduleMeta.declaredPipes);
|
||||||
|
|
||||||
|
moduleMeta.transitiveModule.precompile.push(compMeta.type);
|
||||||
|
moduleMeta.precompile.push(compMeta.type);
|
||||||
|
|
||||||
|
this._verifyModule(moduleMeta);
|
||||||
}
|
}
|
||||||
throw e;
|
|
||||||
|
private _verifyModule(moduleMeta: cpl.CompileNgModuleMetadata) {
|
||||||
|
moduleMeta.exportedDirectives.forEach((dirMeta) => {
|
||||||
|
if (!moduleMeta.transitiveModule.directivesSet.has(dirMeta.type.runtime)) {
|
||||||
|
throw new BaseException(
|
||||||
|
`Can't export directive ${stringify(dirMeta.type.runtime)} from ${stringify(moduleMeta.type.runtime)} as it was neither declared nor imported!`);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
moduleMeta.exportedPipes.forEach((pipeMeta) => {
|
||||||
|
if (!moduleMeta.transitiveModule.pipesSet.has(pipeMeta.type.runtime)) {
|
||||||
|
throw new BaseException(
|
||||||
|
`Can't export pipe ${stringify(pipeMeta.type.runtime)} from ${stringify(moduleMeta.type.runtime)} as it was neither declared nor imported!`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
moduleMeta.declaredDirectives.forEach((dirMeta) => {
|
||||||
|
dirMeta.precompile.forEach((precompileComp) => {
|
||||||
|
if (!moduleMeta.transitiveModule.directivesSet.has(precompileComp.runtime)) {
|
||||||
|
throw new BaseException(
|
||||||
|
`Component ${stringify(dirMeta.type.runtime)} in NgModule ${stringify(moduleMeta.type.runtime)} uses ${stringify(precompileComp.runtime)} via "precompile" but it was neither declared nor imported into the module!`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
moduleMeta.precompile.forEach((precompileType) => {
|
||||||
|
if (!moduleMeta.transitiveModule.directivesSet.has(precompileType.runtime)) {
|
||||||
|
throw new BaseException(
|
||||||
|
`NgModule ${stringify(moduleMeta.type.runtime)} uses ${stringify(precompileType.runtime)} via "precompile" but it was neither declared nor imported!`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private _addTypeToModule(type: Type, moduleType: Type) {
|
||||||
|
const oldModule = this._ngModuleOfTypes.get(type);
|
||||||
|
if (oldModule && oldModule !== moduleType) {
|
||||||
|
throw new BaseException(
|
||||||
|
`Type ${stringify(type)} is part of the declarations of 2 modules: ${stringify(oldModule)} and ${stringify(moduleType)}!`);
|
||||||
|
}
|
||||||
|
this._ngModuleOfTypes.set(type, moduleType);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private _getTransitiveViewDirectivesAndPipes(
|
||||||
|
compMeta: cpl.CompileDirectiveMetadata, moduleType: any,
|
||||||
|
transitiveModule: cpl.TransitiveCompileNgModuleMetadata,
|
||||||
|
declaredDirectives: cpl.CompileDirectiveMetadata[],
|
||||||
|
declaredPipes: cpl.CompilePipeMetadata[]) {
|
||||||
|
if (!compMeta.isComponent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const addPipe = (pipeType: Type) => {
|
||||||
|
if (!pipeType) {
|
||||||
|
throw new BaseException(
|
||||||
|
`Unexpected pipe value '${pipeType}' on the View of component '${stringify(compMeta.type.runtime)}'`);
|
||||||
|
}
|
||||||
|
const pipeMeta = this.getPipeMetadata(pipeType);
|
||||||
|
this._addPipeToModule(pipeMeta, moduleType, transitiveModule, declaredPipes);
|
||||||
|
};
|
||||||
|
|
||||||
|
const addDirective = (dirType: Type) => {
|
||||||
|
if (!dirType) {
|
||||||
|
throw new BaseException(
|
||||||
|
`Unexpected directive value '${dirType}' on the View of component '${stringify(compMeta.type.runtime)}'`);
|
||||||
|
}
|
||||||
|
const dirMeta = this.getDirectiveMetadata(dirType);
|
||||||
|
if (this._addDirectiveToModule(dirMeta, moduleType, transitiveModule, declaredDirectives)) {
|
||||||
|
this._getTransitiveViewDirectivesAndPipes(
|
||||||
|
dirMeta, moduleType, transitiveModule, declaredDirectives, declaredPipes);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const view = this._viewResolver.resolve(compMeta.type.runtime);
|
||||||
|
if (view.pipes) {
|
||||||
|
flattenArray(view.pipes).forEach(addPipe);
|
||||||
|
}
|
||||||
|
if (view.directives) {
|
||||||
|
flattenArray(view.directives).forEach(addDirective);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _getTransitiveNgModuleMetadata(
|
||||||
|
importedModules: cpl.CompileNgModuleMetadata[],
|
||||||
|
exportedModules: cpl.CompileNgModuleMetadata[]): cpl.TransitiveCompileNgModuleMetadata {
|
||||||
|
// collect `providers` / `precompile` from all imported and all exported modules
|
||||||
|
const transitiveModules = getTransitiveModules(importedModules.concat(exportedModules), true);
|
||||||
|
const providers = flattenArray(transitiveModules.map((ngModule) => ngModule.providers));
|
||||||
|
const precompile = flattenArray(transitiveModules.map((ngModule) => ngModule.precompile));
|
||||||
|
|
||||||
|
const transitiveExportedModules = getTransitiveModules(importedModules, false);
|
||||||
|
const directives =
|
||||||
|
flattenArray(transitiveExportedModules.map((ngModule) => ngModule.exportedDirectives));
|
||||||
|
const pipes = flattenArray(transitiveExportedModules.map((ngModule) => ngModule.exportedPipes));
|
||||||
|
return new cpl.TransitiveCompileNgModuleMetadata(
|
||||||
|
transitiveModules, providers, precompile, directives, pipes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _addDirectiveToModule(
|
||||||
|
dirMeta: cpl.CompileDirectiveMetadata, moduleType: any,
|
||||||
|
transitiveModule: cpl.TransitiveCompileNgModuleMetadata,
|
||||||
|
declaredDirectives: cpl.CompileDirectiveMetadata[], force: boolean = false): boolean {
|
||||||
|
if (force || !transitiveModule.directivesSet.has(dirMeta.type.runtime)) {
|
||||||
|
transitiveModule.directivesSet.add(dirMeta.type.runtime);
|
||||||
|
transitiveModule.directives.push(dirMeta);
|
||||||
|
declaredDirectives.push(dirMeta);
|
||||||
|
this._addTypeToModule(dirMeta.type.runtime, moduleType);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _addPipeToModule(
|
||||||
|
pipeMeta: cpl.CompilePipeMetadata, moduleType: any,
|
||||||
|
transitiveModule: cpl.TransitiveCompileNgModuleMetadata,
|
||||||
|
declaredPipes: cpl.CompilePipeMetadata[], force: boolean = false): boolean {
|
||||||
|
if (force || !transitiveModule.pipesSet.has(pipeMeta.type.runtime)) {
|
||||||
|
transitiveModule.pipesSet.add(pipeMeta.type.runtime);
|
||||||
|
transitiveModule.pipes.push(pipeMeta);
|
||||||
|
declaredPipes.push(pipeMeta);
|
||||||
|
this._addTypeToModule(pipeMeta.type.runtime, moduleType);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
getTypeMetadata(type: Type, moduleUrl: string, dependencies: any[] = null):
|
getTypeMetadata(type: Type, moduleUrl: string, dependencies: any[] = null):
|
||||||
@ -283,11 +463,14 @@ export class CompileMetadataResolver {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getPipeMetadata(pipeType: Type): cpl.CompilePipeMetadata {
|
getPipeMetadata(pipeType: Type, throwIfNotFound = true): cpl.CompilePipeMetadata {
|
||||||
pipeType = resolveForwardRef(pipeType);
|
pipeType = resolveForwardRef(pipeType);
|
||||||
var meta = this._pipeCache.get(pipeType);
|
var meta = this._pipeCache.get(pipeType);
|
||||||
if (isBlank(meta)) {
|
if (isBlank(meta)) {
|
||||||
var pipeMeta = this._pipeResolver.resolve(pipeType);
|
var pipeMeta = this._pipeResolver.resolve(pipeType, throwIfNotFound);
|
||||||
|
if (!pipeMeta) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
meta = new cpl.CompilePipeMetadata({
|
meta = new cpl.CompilePipeMetadata({
|
||||||
type: this.getTypeMetadata(pipeType, staticTypeModuleUrl(pipeType)),
|
type: this.getTypeMetadata(pipeType, staticTypeModuleUrl(pipeType)),
|
||||||
name: pipeMeta.name,
|
name: pipeMeta.name,
|
||||||
@ -299,30 +482,6 @@ export class CompileMetadataResolver {
|
|||||||
return meta;
|
return meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
getViewDirectivesMetadata(component: Type): cpl.CompileDirectiveMetadata[] {
|
|
||||||
var view = this._viewResolver.resolve(component);
|
|
||||||
var directives = flattenDirectives(view, this._config.deprecatedPlatformDirectives);
|
|
||||||
for (var i = 0; i < directives.length; i++) {
|
|
||||||
if (!isValidType(directives[i])) {
|
|
||||||
throw new BaseException(
|
|
||||||
`Unexpected directive value '${stringify(directives[i])}' on the View of component '${stringify(component)}'`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return directives.map(type => this.getDirectiveMetadata(type));
|
|
||||||
}
|
|
||||||
|
|
||||||
getViewPipesMetadata(component: Type): cpl.CompilePipeMetadata[] {
|
|
||||||
var view = this._viewResolver.resolve(component);
|
|
||||||
var pipes = flattenPipes(view, this._config.deprecatedPlatformPipes);
|
|
||||||
for (var i = 0; i < pipes.length; i++) {
|
|
||||||
if (!isValidType(pipes[i])) {
|
|
||||||
throw new BaseException(
|
|
||||||
`Unexpected piped value '${stringify(pipes[i])}' on the View of component '${stringify(component)}'`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return pipes.map(type => this.getPipeMetadata(type));
|
|
||||||
}
|
|
||||||
|
|
||||||
getDependenciesMetadata(typeOrFunc: Type|Function, dependencies: any[]):
|
getDependenciesMetadata(typeOrFunc: Type|Function, dependencies: any[]):
|
||||||
cpl.CompileDiDependencyMetadata[] {
|
cpl.CompileDiDependencyMetadata[] {
|
||||||
let hasUnknownDeps = false;
|
let hasUnknownDeps = false;
|
||||||
@ -454,7 +613,7 @@ export class CompileMetadataResolver {
|
|||||||
}
|
}
|
||||||
convertToCompileValue(provider.useValue, collectedIdentifiers);
|
convertToCompileValue(provider.useValue, collectedIdentifiers);
|
||||||
collectedIdentifiers.forEach((identifier) => {
|
collectedIdentifiers.forEach((identifier) => {
|
||||||
let dirMeta = this.maybeGetDirectiveMetadata(identifier.runtime);
|
let dirMeta = this.getDirectiveMetadata(identifier.runtime, false);
|
||||||
if (dirMeta) {
|
if (dirMeta) {
|
||||||
components.push(dirMeta.type);
|
components.push(dirMeta.type);
|
||||||
}
|
}
|
||||||
@ -523,29 +682,28 @@ export class CompileMetadataResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function flattenDirectives(view: ViewMetadata, platformDirectives: any[]): Type[] {
|
function getTransitiveModules(
|
||||||
let directives: Type[] = [];
|
modules: cpl.CompileNgModuleMetadata[], includeImports: boolean,
|
||||||
if (isPresent(platformDirectives)) {
|
targetModules: cpl.CompileNgModuleMetadata[] = [],
|
||||||
flattenArray(platformDirectives, directives);
|
visitedModules = new Set<Type>()): cpl.CompileNgModuleMetadata[] {
|
||||||
|
modules.forEach((ngModule) => {
|
||||||
|
if (!visitedModules.has(ngModule.type.runtime)) {
|
||||||
|
visitedModules.add(ngModule.type.runtime);
|
||||||
|
const nestedModules = includeImports ?
|
||||||
|
ngModule.importedModules.concat(ngModule.exportedModules) :
|
||||||
|
ngModule.exportedModules;
|
||||||
|
getTransitiveModules(nestedModules, includeImports, targetModules, visitedModules);
|
||||||
|
// Add after recursing so imported/exported modules are before the module itself.
|
||||||
|
// This is important for overwriting providers of imported modules!
|
||||||
|
targetModules.push(ngModule);
|
||||||
}
|
}
|
||||||
if (isPresent(view.directives)) {
|
});
|
||||||
flattenArray(view.directives, directives);
|
return targetModules;
|
||||||
}
|
|
||||||
return directives;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function flattenPipes(view: ViewMetadata, platformPipes: any[]): Type[] {
|
|
||||||
let pipes: Type[] = [];
|
|
||||||
if (isPresent(platformPipes)) {
|
|
||||||
flattenArray(platformPipes, pipes);
|
|
||||||
}
|
|
||||||
if (isPresent(view.pipes)) {
|
|
||||||
flattenArray(view.pipes, pipes);
|
|
||||||
}
|
|
||||||
return pipes;
|
|
||||||
}
|
|
||||||
|
|
||||||
function flattenArray(tree: any[], out: Array<Type> = []): Array<Type> {
|
function flattenArray(tree: any[], out: Array<any> = []): Array<any> {
|
||||||
|
if (tree) {
|
||||||
for (var i = 0; i < tree.length; i++) {
|
for (var i = 0; i < tree.length; i++) {
|
||||||
var item = resolveForwardRef(tree[i]);
|
var item = resolveForwardRef(tree[i]);
|
||||||
if (isArray(item)) {
|
if (isArray(item)) {
|
||||||
@ -554,6 +712,7 @@ function flattenArray(tree: any[], out: Array<Type> = []): Array<Type> {
|
|||||||
out.push(item);
|
out.push(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,13 +8,13 @@
|
|||||||
|
|
||||||
import {Injectable} from '@angular/core';
|
import {Injectable} from '@angular/core';
|
||||||
|
|
||||||
import {CompileAppModuleMetadata, CompileDiDependencyMetadata, CompileIdentifierMetadata, CompileProviderMetadata, CompileTokenMap, CompileTokenMetadata, CompileTypeMetadata} from './compile_metadata';
|
import {CompileDiDependencyMetadata, CompileIdentifierMap, CompileIdentifierMetadata, CompileNgModuleMetadata, CompileProviderMetadata, CompileTokenMetadata} from './compile_metadata';
|
||||||
import {isBlank, isPresent} from './facade/lang';
|
import {isBlank, isPresent} from './facade/lang';
|
||||||
import {Identifiers, identifierToken} from './identifiers';
|
import {Identifiers, identifierToken} from './identifiers';
|
||||||
import * as o from './output/output_ast';
|
import * as o from './output/output_ast';
|
||||||
import {convertValueToOutputAst} from './output/value_util';
|
import {convertValueToOutputAst} from './output/value_util';
|
||||||
import {ParseLocation, ParseSourceFile, ParseSourceSpan} from './parse_util';
|
import {ParseLocation, ParseSourceFile, ParseSourceSpan} from './parse_util';
|
||||||
import {AppModuleProviderParser} from './provider_parser';
|
import {NgModuleProviderAnalyzer} from './provider_analyzer';
|
||||||
import {ProviderAst, ProviderAstType} from './template_ast';
|
import {ProviderAst, ProviderAstType} from './template_ast';
|
||||||
import {createDiTokenExpression} from './util';
|
import {createDiTokenExpression} from './util';
|
||||||
|
|
||||||
@ -23,57 +23,58 @@ export class ComponentFactoryDependency {
|
|||||||
public comp: CompileIdentifierMetadata, public placeholder: CompileIdentifierMetadata) {}
|
public comp: CompileIdentifierMetadata, public placeholder: CompileIdentifierMetadata) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AppModuleCompileResult {
|
export class NgModuleCompileResult {
|
||||||
constructor(
|
constructor(
|
||||||
public statements: o.Statement[], public appModuleFactoryVar: string,
|
public statements: o.Statement[], public ngModuleFactoryVar: string,
|
||||||
public dependencies: ComponentFactoryDependency[]) {}
|
public dependencies: ComponentFactoryDependency[]) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AppModuleCompiler {
|
export class NgModuleCompiler {
|
||||||
compile(appModuleMeta: CompileAppModuleMetadata): AppModuleCompileResult {
|
compile(ngModuleMeta: CompileNgModuleMetadata, extraProviders: CompileProviderMetadata[]):
|
||||||
var sourceFileName = isPresent(appModuleMeta.type.moduleUrl) ?
|
NgModuleCompileResult {
|
||||||
`in AppModule ${appModuleMeta.type.name} in ${appModuleMeta.type.moduleUrl}` :
|
var sourceFileName = isPresent(ngModuleMeta.type.moduleUrl) ?
|
||||||
`in AppModule ${appModuleMeta.type.name}`;
|
`in NgModule ${ngModuleMeta.type.name} in ${ngModuleMeta.type.moduleUrl}` :
|
||||||
|
`in NgModule ${ngModuleMeta.type.name}`;
|
||||||
var sourceFile = new ParseSourceFile('', sourceFileName);
|
var sourceFile = new ParseSourceFile('', sourceFileName);
|
||||||
var sourceSpan = new ParseSourceSpan(
|
var sourceSpan = new ParseSourceSpan(
|
||||||
new ParseLocation(sourceFile, null, null, null),
|
new ParseLocation(sourceFile, null, null, null),
|
||||||
new ParseLocation(sourceFile, null, null, null));
|
new ParseLocation(sourceFile, null, null, null));
|
||||||
var deps: ComponentFactoryDependency[] = [];
|
var deps: ComponentFactoryDependency[] = [];
|
||||||
var precompileComponents = appModuleMeta.precompile.map((precompileComp) => {
|
var precompileComponents = ngModuleMeta.transitiveModule.precompile.map((precompileComp) => {
|
||||||
var id = new CompileIdentifierMetadata({name: precompileComp.name});
|
var id = new CompileIdentifierMetadata({name: precompileComp.name});
|
||||||
deps.push(new ComponentFactoryDependency(precompileComp, id));
|
deps.push(new ComponentFactoryDependency(precompileComp, id));
|
||||||
return id;
|
return id;
|
||||||
});
|
});
|
||||||
var builder = new _InjectorBuilder(appModuleMeta, precompileComponents, sourceSpan);
|
var builder = new _InjectorBuilder(ngModuleMeta, precompileComponents, sourceSpan);
|
||||||
|
|
||||||
var providerParser = new AppModuleProviderParser(appModuleMeta, sourceSpan);
|
var providerParser = new NgModuleProviderAnalyzer(ngModuleMeta, extraProviders, sourceSpan);
|
||||||
providerParser.parse().forEach((provider) => builder.addProvider(provider));
|
providerParser.parse().forEach((provider) => builder.addProvider(provider));
|
||||||
var injectorClass = builder.build();
|
var injectorClass = builder.build();
|
||||||
var appModuleFactoryVar = `${appModuleMeta.type.name}NgFactory`;
|
var ngModuleFactoryVar = `${ngModuleMeta.type.name}NgFactory`;
|
||||||
var appModuleFactoryStmt =
|
var ngModuleFactoryStmt =
|
||||||
o.variable(appModuleFactoryVar)
|
o.variable(ngModuleFactoryVar)
|
||||||
.set(o.importExpr(Identifiers.AppModuleFactory)
|
.set(o.importExpr(Identifiers.NgModuleFactory)
|
||||||
.instantiate(
|
.instantiate(
|
||||||
[o.variable(injectorClass.name), o.importExpr(appModuleMeta.type)],
|
[o.variable(injectorClass.name), o.importExpr(ngModuleMeta.type)],
|
||||||
o.importType(
|
o.importType(
|
||||||
Identifiers.AppModuleFactory, [o.importType(appModuleMeta.type)],
|
Identifiers.NgModuleFactory, [o.importType(ngModuleMeta.type)],
|
||||||
[o.TypeModifier.Const])))
|
[o.TypeModifier.Const])))
|
||||||
.toDeclStmt(null, [o.StmtModifier.Final]);
|
.toDeclStmt(null, [o.StmtModifier.Final]);
|
||||||
|
|
||||||
return new AppModuleCompileResult(
|
return new NgModuleCompileResult(
|
||||||
[injectorClass, appModuleFactoryStmt], appModuleFactoryVar, deps);
|
[injectorClass, ngModuleFactoryStmt], ngModuleFactoryVar, deps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _InjectorBuilder {
|
class _InjectorBuilder {
|
||||||
private _instances = new CompileTokenMap<o.Expression>();
|
private _instances = new CompileIdentifierMap<CompileTokenMetadata, o.Expression>();
|
||||||
private _fields: o.ClassField[] = [];
|
private _fields: o.ClassField[] = [];
|
||||||
private _createStmts: o.Statement[] = [];
|
private _createStmts: o.Statement[] = [];
|
||||||
private _getters: o.ClassGetter[] = [];
|
private _getters: o.ClassGetter[] = [];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private _appModuleMeta: CompileAppModuleMetadata,
|
private _ngModuleMeta: CompileNgModuleMetadata,
|
||||||
private _precompileComponents: CompileIdentifierMetadata[],
|
private _precompileComponents: CompileIdentifierMetadata[],
|
||||||
private _sourceSpan: ParseSourceSpan) {}
|
private _sourceSpan: ParseSourceSpan) {}
|
||||||
|
|
||||||
@ -97,8 +98,8 @@ class _InjectorBuilder {
|
|||||||
var methods = [
|
var methods = [
|
||||||
new o.ClassMethod(
|
new o.ClassMethod(
|
||||||
'createInternal', [], this._createStmts.concat(
|
'createInternal', [], this._createStmts.concat(
|
||||||
new o.ReturnStatement(this._instances.get(identifierToken(this._appModuleMeta.type)))
|
new o.ReturnStatement(this._instances.get(identifierToken(this._ngModuleMeta.type)))
|
||||||
), o.importType(this._appModuleMeta.type)
|
), o.importType(this._ngModuleMeta.type)
|
||||||
),
|
),
|
||||||
new o.ClassMethod(
|
new o.ClassMethod(
|
||||||
'getInternal',
|
'getInternal',
|
||||||
@ -120,10 +121,10 @@ class _InjectorBuilder {
|
|||||||
])
|
])
|
||||||
.toStmt()]);
|
.toStmt()]);
|
||||||
|
|
||||||
var injClassName = `${this._appModuleMeta.type.name}Injector`;
|
var injClassName = `${this._ngModuleMeta.type.name}Injector`;
|
||||||
return new o.ClassStmt(
|
return new o.ClassStmt(
|
||||||
injClassName,
|
injClassName,
|
||||||
o.importExpr(Identifiers.AppModuleInjector, [o.importType(this._appModuleMeta.type)]),
|
o.importExpr(Identifiers.NgModuleInjector, [o.importType(this._ngModuleMeta.type)]),
|
||||||
this._fields, this._getters, ctor, methods);
|
this._fields, this._getters, ctor, methods);
|
||||||
}
|
}
|
||||||
|
|
39
modules/@angular/compiler/src/ng_module_resolver.ts
Normal file
39
modules/@angular/compiler/src/ng_module_resolver.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright Google Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by an MIT-style license that can be
|
||||||
|
* found in the LICENSE file at https://angular.io/license
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {Injectable, NgModuleMetadata} from '@angular/core';
|
||||||
|
|
||||||
|
import {ReflectorReader, reflector} from '../core_private';
|
||||||
|
import {BaseException} from '../src/facade/exceptions';
|
||||||
|
import {Type, isBlank, isPresent, stringify} from '../src/facade/lang';
|
||||||
|
|
||||||
|
function _isNgModuleMetadata(obj: any): obj is NgModuleMetadata {
|
||||||
|
return obj instanceof NgModuleMetadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves types to {@link NgModuleMetadata}.
|
||||||
|
*/
|
||||||
|
@Injectable()
|
||||||
|
export class NgModuleResolver {
|
||||||
|
constructor(private _reflector: ReflectorReader = reflector) {}
|
||||||
|
|
||||||
|
resolve(type: Type, throwIfNotFound = true): NgModuleMetadata {
|
||||||
|
const ngModuleMeta: NgModuleMetadata =
|
||||||
|
this._reflector.annotations(type).find(_isNgModuleMetadata);
|
||||||
|
|
||||||
|
if (isPresent(ngModuleMeta)) {
|
||||||
|
return ngModuleMeta;
|
||||||
|
} else {
|
||||||
|
if (throwIfNotFound) {
|
||||||
|
throw new BaseException(`No NgModule metadata found for '${stringify(type)}'.`);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6,13 +6,13 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {AppModuleCompiler} from './app_module_compiler';
|
import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompileNgModuleMetadata, CompilePipeMetadata, StaticSymbol, createHostComponentMeta} from './compile_metadata';
|
||||||
import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompilePipeMetadata, StaticSymbol, createHostComponentMeta} from './compile_metadata';
|
|
||||||
import {DirectiveNormalizer} from './directive_normalizer';
|
import {DirectiveNormalizer} from './directive_normalizer';
|
||||||
import {ListWrapper} from './facade/collection';
|
import {ListWrapper} from './facade/collection';
|
||||||
import {BaseException} from './facade/exceptions';
|
import {BaseException} from './facade/exceptions';
|
||||||
import {Identifiers} from './identifiers';
|
import {Identifiers} from './identifiers';
|
||||||
import {CompileMetadataResolver} from './metadata_resolver';
|
import {CompileMetadataResolver} from './metadata_resolver';
|
||||||
|
import {NgModuleCompiler} from './ng_module_compiler';
|
||||||
import {OutputEmitter} from './output/abstract_emitter';
|
import {OutputEmitter} from './output/abstract_emitter';
|
||||||
import * as o from './output/output_ast';
|
import * as o from './output/output_ast';
|
||||||
import {CompiledStylesheet, StyleCompiler} from './style_compiler';
|
import {CompiledStylesheet, StyleCompiler} from './style_compiler';
|
||||||
@ -23,61 +23,29 @@ export class SourceModule {
|
|||||||
constructor(public moduleUrl: string, public source: string) {}
|
constructor(public moduleUrl: string, public source: string) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AppModulesSummary {
|
export class NgModulesSummary {
|
||||||
private _compAppModule = new Map<string, StaticSymbol>();
|
constructor(public ngModuleByComponent: Map<StaticSymbol, CompileNgModuleMetadata>) {}
|
||||||
private _hashKey(type: StaticSymbol) { return `${type.filePath}#${type.name}`; }
|
|
||||||
|
|
||||||
hasComponent(component: StaticSymbol): boolean {
|
|
||||||
return this._compAppModule.has(this._hashKey(component));
|
|
||||||
}
|
|
||||||
|
|
||||||
addComponent(module: StaticSymbol, component: StaticSymbol) {
|
|
||||||
this._compAppModule.set(this._hashKey(component), module);
|
|
||||||
}
|
|
||||||
|
|
||||||
getModule(comp: StaticSymbol): StaticSymbol {
|
|
||||||
return this._compAppModule.get(this._hashKey(comp));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class OfflineCompiler {
|
export class OfflineCompiler {
|
||||||
constructor(
|
constructor(
|
||||||
private _metadataResolver: CompileMetadataResolver,
|
private _metadataResolver: CompileMetadataResolver,
|
||||||
private _directiveNormalizer: DirectiveNormalizer, private _templateParser: TemplateParser,
|
private _directiveNormalizer: DirectiveNormalizer, private _templateParser: TemplateParser,
|
||||||
private _styleCompiler: StyleCompiler, private _viewCompiler: ViewCompiler,
|
private _styleCompiler: StyleCompiler, private _viewCompiler: ViewCompiler,
|
||||||
private _appModuleCompiler: AppModuleCompiler, private _outputEmitter: OutputEmitter) {}
|
private _ngModuleCompiler: NgModuleCompiler, private _outputEmitter: OutputEmitter) {}
|
||||||
|
|
||||||
analyzeModules(appModules: StaticSymbol[]): AppModulesSummary {
|
analyzeModules(ngModules: StaticSymbol[]): NgModulesSummary {
|
||||||
let result = new AppModulesSummary();
|
const ngModuleByComponent = new Map<StaticSymbol, CompileNgModuleMetadata>();
|
||||||
appModules.forEach((appModule) => {
|
|
||||||
let appModuleMeta = this._metadataResolver.getAppModuleMetadata(appModule);
|
|
||||||
appModuleMeta.precompile.forEach(
|
|
||||||
(precompileComp) =>
|
|
||||||
this._getTransitiveComponents(appModule, <any>precompileComp.runtime, result));
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _getTransitiveComponents(
|
ngModules.forEach((ngModule) => {
|
||||||
appModule: StaticSymbol, component: StaticSymbol,
|
const ngModuleMeta = this._metadataResolver.getNgModuleMetadata(<any>ngModule);
|
||||||
target: AppModulesSummary = new AppModulesSummary()): AppModulesSummary {
|
ngModuleMeta.declaredDirectives.forEach((dirMeta) => {
|
||||||
var compMeta = this._metadataResolver.getDirectiveMetadata(<any>component);
|
if (dirMeta.isComponent) {
|
||||||
// TODO(tbosch): preserve all modules per component, not just one.
|
ngModuleByComponent.set(dirMeta.type.runtime, ngModuleMeta);
|
||||||
// Then run the template parser with the union and the intersection of the modules (regarding
|
|
||||||
// directives/pipes)
|
|
||||||
// and report an error if some directives/pipes are only matched with the union but not with the
|
|
||||||
// intersection!
|
|
||||||
// -> this means that a component is used in the wrong way!
|
|
||||||
if (!compMeta.isComponent || target.hasComponent(component)) {
|
|
||||||
return target;
|
|
||||||
}
|
}
|
||||||
target.addComponent(appModule, component);
|
|
||||||
this._metadataResolver.getViewDirectivesMetadata(<any>component).forEach((dirMeta) => {
|
|
||||||
this._getTransitiveComponents(appModule, <any>dirMeta.type.runtime);
|
|
||||||
});
|
});
|
||||||
compMeta.precompile.forEach((precompileComp) => {
|
|
||||||
this._getTransitiveComponents(appModule, <any>precompileComp.type.runtime);
|
|
||||||
});
|
});
|
||||||
return target;
|
return new NgModulesSummary(ngModuleByComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
clearCache() {
|
clearCache() {
|
||||||
@ -86,55 +54,45 @@ export class OfflineCompiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
compile(
|
compile(
|
||||||
moduleUrl: string, appModulesSummary: AppModulesSummary, components: StaticSymbol[],
|
moduleUrl: string, ngModulesSummary: NgModulesSummary, components: StaticSymbol[],
|
||||||
appModules: StaticSymbol[]): Promise<SourceModule[]> {
|
ngModules: StaticSymbol[]): Promise<SourceModule[]> {
|
||||||
let fileSuffix = _splitLastSuffix(moduleUrl)[1];
|
let fileSuffix = _splitLastSuffix(moduleUrl)[1];
|
||||||
let statements: o.Statement[] = [];
|
let statements: o.Statement[] = [];
|
||||||
let exportedVars: string[] = [];
|
let exportedVars: string[] = [];
|
||||||
let outputSourceModules: SourceModule[] = [];
|
let outputSourceModules: SourceModule[] = [];
|
||||||
|
|
||||||
// compile app modules
|
// compile all ng modules
|
||||||
exportedVars.push(
|
exportedVars.push(
|
||||||
...appModules.map((appModule) => this._compileAppModule(appModule, statements)));
|
...ngModules.map((ngModuleType) => this._compileModule(ngModuleType, statements)));
|
||||||
|
|
||||||
// compile components
|
// compile components
|
||||||
return Promise
|
return Promise
|
||||||
.all(components.map((compType) => {
|
.all(components.map((compType) => {
|
||||||
let appModule = appModulesSummary.getModule(compType);
|
const compMeta = this._metadataResolver.getDirectiveMetadata(<any>compType);
|
||||||
let appModuleDirectives: CompileDirectiveMetadata[] = [];
|
let ngModule = ngModulesSummary.ngModuleByComponent.get(compType);
|
||||||
let appModulePipes: CompilePipeMetadata[] = [];
|
if (!ngModule) {
|
||||||
if (appModule) {
|
throw new BaseException(
|
||||||
let appModuleMeta = this._metadataResolver.getAppModuleMetadata(appModule);
|
`Cannot determine the module for component ${compMeta.type.name}!`);
|
||||||
appModuleDirectives.push(...appModuleMeta.directives.map(
|
|
||||||
type => this._metadataResolver.getDirectiveMetadata(type.runtime)));
|
|
||||||
appModulePipes.push(...appModuleMeta.pipes.map(
|
|
||||||
type => this._metadataResolver.getPipeMetadata(type.runtime)));
|
|
||||||
}
|
}
|
||||||
return Promise
|
return Promise
|
||||||
.all([
|
.all([compMeta, ...ngModule.transitiveModule.directives].map(
|
||||||
this._metadataResolver.getDirectiveMetadata(<any>compType), ...appModuleDirectives,
|
dirMeta => this._directiveNormalizer.normalizeDirective(dirMeta).asyncResult))
|
||||||
...this._metadataResolver.getViewDirectivesMetadata(<any>compType)
|
|
||||||
].map(dirMeta => this._directiveNormalizer.normalizeDirective(dirMeta).asyncResult))
|
|
||||||
.then((normalizedCompWithDirectives) => {
|
.then((normalizedCompWithDirectives) => {
|
||||||
let compMeta = normalizedCompWithDirectives[0];
|
const compMeta = normalizedCompWithDirectives[0];
|
||||||
let dirMetas = normalizedCompWithDirectives.slice(1);
|
const dirMetas = normalizedCompWithDirectives.slice(1);
|
||||||
_assertComponent(compMeta);
|
_assertComponent(compMeta);
|
||||||
|
|
||||||
// compile styles
|
// compile styles
|
||||||
let stylesCompileResults = this._styleCompiler.compileComponent(compMeta);
|
const stylesCompileResults = this._styleCompiler.compileComponent(compMeta);
|
||||||
stylesCompileResults.externalStylesheets.forEach((compiledStyleSheet) => {
|
stylesCompileResults.externalStylesheets.forEach((compiledStyleSheet) => {
|
||||||
outputSourceModules.push(this._codgenStyles(compiledStyleSheet, fileSuffix));
|
outputSourceModules.push(this._codgenStyles(compiledStyleSheet, fileSuffix));
|
||||||
});
|
});
|
||||||
|
|
||||||
// compile components
|
// compile components
|
||||||
exportedVars.push(this._compileComponentFactory(compMeta, fileSuffix, statements));
|
exportedVars.push(this._compileComponentFactory(compMeta, fileSuffix, statements));
|
||||||
let pipeMetas = [
|
|
||||||
...appModulePipes,
|
|
||||||
...this._metadataResolver.getViewPipesMetadata(compMeta.type.runtime)
|
|
||||||
];
|
|
||||||
exportedVars.push(this._compileComponent(
|
exportedVars.push(this._compileComponent(
|
||||||
compMeta, dirMetas, pipeMetas, stylesCompileResults.componentStylesheet,
|
compMeta, dirMetas, ngModule.transitiveModule.pipes,
|
||||||
fileSuffix, statements));
|
stylesCompileResults.componentStylesheet, fileSuffix, statements));
|
||||||
});
|
});
|
||||||
}))
|
}))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@ -146,21 +104,21 @@ export class OfflineCompiler {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private _compileAppModule(appModuleType: StaticSymbol, targetStatements: o.Statement[]): string {
|
private _compileModule(ngModuleType: StaticSymbol, targetStatements: o.Statement[]): string {
|
||||||
let appModuleMeta = this._metadataResolver.getAppModuleMetadata(appModuleType);
|
const ngModule = this._metadataResolver.getNgModuleMetadata(<any>ngModuleType);
|
||||||
let appCompileResult = this._appModuleCompiler.compile(appModuleMeta);
|
let appCompileResult = this._ngModuleCompiler.compile(ngModule, []);
|
||||||
appCompileResult.dependencies.forEach((dep) => {
|
appCompileResult.dependencies.forEach((dep) => {
|
||||||
dep.placeholder.name = _componentFactoryName(dep.comp);
|
dep.placeholder.name = _componentFactoryName(dep.comp);
|
||||||
dep.placeholder.moduleUrl = _ngfactoryModuleUrl(dep.comp.moduleUrl);
|
dep.placeholder.moduleUrl = _ngfactoryModuleUrl(dep.comp.moduleUrl);
|
||||||
});
|
});
|
||||||
targetStatements.push(...appCompileResult.statements);
|
targetStatements.push(...appCompileResult.statements);
|
||||||
return appCompileResult.appModuleFactoryVar;
|
return appCompileResult.ngModuleFactoryVar;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _compileComponentFactory(
|
private _compileComponentFactory(
|
||||||
compMeta: CompileDirectiveMetadata, fileSuffix: string,
|
compMeta: CompileDirectiveMetadata, fileSuffix: string,
|
||||||
targetStatements: o.Statement[]): string {
|
targetStatements: o.Statement[]): string {
|
||||||
var hostMeta = createHostComponentMeta(compMeta.type, compMeta.selector);
|
var hostMeta = createHostComponentMeta(compMeta);
|
||||||
var hostViewFactoryVar =
|
var hostViewFactoryVar =
|
||||||
this._compileComponent(hostMeta, [compMeta], [], null, fileSuffix, targetStatements);
|
this._compileComponent(hostMeta, [compMeta], [], null, fileSuffix, targetStatements);
|
||||||
var compFactoryVar = _componentFactoryName(compMeta.type);
|
var compFactoryVar = _componentFactoryName(compMeta.type);
|
||||||
|
@ -30,7 +30,7 @@ export class PipeResolver {
|
|||||||
/**
|
/**
|
||||||
* Return {@link PipeMetadata} for a given `Type`.
|
* Return {@link PipeMetadata} for a given `Type`.
|
||||||
*/
|
*/
|
||||||
resolve(type: Type): PipeMetadata {
|
resolve(type: Type, throwIfNotFound = true): PipeMetadata {
|
||||||
var metas = this._reflector.annotations(resolveForwardRef(type));
|
var metas = this._reflector.annotations(resolveForwardRef(type));
|
||||||
if (isPresent(metas)) {
|
if (isPresent(metas)) {
|
||||||
var annotation = metas.find(_isPipeMetadata);
|
var annotation = metas.find(_isPipeMetadata);
|
||||||
@ -38,6 +38,9 @@ export class PipeResolver {
|
|||||||
return annotation;
|
return annotation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (throwIfNotFound) {
|
||||||
throw new BaseException(`No Pipe decorator found on ${stringify(type)}`);
|
throw new BaseException(`No Pipe decorator found on ${stringify(type)}`);
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
@ -10,7 +10,7 @@ import {ListWrapper} from '../src/facade/collection';
|
|||||||
import {BaseException} from '../src/facade/exceptions';
|
import {BaseException} from '../src/facade/exceptions';
|
||||||
import {isArray, isBlank, isPresent, normalizeBlank} from '../src/facade/lang';
|
import {isArray, isBlank, isPresent, normalizeBlank} from '../src/facade/lang';
|
||||||
|
|
||||||
import {CompileAppModuleMetadata, CompileDiDependencyMetadata, CompileDirectiveMetadata, CompileProviderMetadata, CompileQueryMetadata, CompileTokenMap, CompileTokenMetadata, CompileTypeMetadata} from './compile_metadata';
|
import {CompileDiDependencyMetadata, CompileDirectiveMetadata, CompileIdentifierMap, CompileNgModuleMetadata, CompileProviderMetadata, CompileQueryMetadata, CompileTokenMetadata, CompileTypeMetadata} from './compile_metadata';
|
||||||
import {Identifiers, identifierToken} from './identifiers';
|
import {Identifiers, identifierToken} from './identifiers';
|
||||||
import {ParseError, ParseSourceSpan} from './parse_util';
|
import {ParseError, ParseSourceSpan} from './parse_util';
|
||||||
import {AttrAst, DirectiveAst, ProviderAst, ProviderAstType, ReferenceAst, VariableAst} from './template_ast';
|
import {AttrAst, DirectiveAst, ProviderAst, ProviderAstType, ReferenceAst, VariableAst} from './template_ast';
|
||||||
@ -23,16 +23,16 @@ export class ProviderViewContext {
|
|||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
viewQueries: CompileTokenMap<CompileQueryMetadata[]>;
|
viewQueries: CompileIdentifierMap<CompileTokenMetadata, CompileQueryMetadata[]>;
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
viewProviders: CompileTokenMap<boolean>;
|
viewProviders: CompileIdentifierMap<CompileTokenMetadata, boolean>;
|
||||||
errors: ProviderError[] = [];
|
errors: ProviderError[] = [];
|
||||||
|
|
||||||
constructor(public component: CompileDirectiveMetadata, public sourceSpan: ParseSourceSpan) {
|
constructor(public component: CompileDirectiveMetadata, public sourceSpan: ParseSourceSpan) {
|
||||||
this.viewQueries = _getViewQueries(component);
|
this.viewQueries = _getViewQueries(component);
|
||||||
this.viewProviders = new CompileTokenMap<boolean>();
|
this.viewProviders = new CompileIdentifierMap<CompileTokenMetadata, boolean>();
|
||||||
_normalizeProviders(component.viewProviders, sourceSpan, this.errors).forEach((provider) => {
|
_normalizeProviders(component.viewProviders, sourceSpan, this.errors).forEach((provider) => {
|
||||||
if (isBlank(this.viewProviders.get(provider.token))) {
|
if (isBlank(this.viewProviders.get(provider.token))) {
|
||||||
this.viewProviders.add(provider.token, true);
|
this.viewProviders.add(provider.token, true);
|
||||||
@ -42,11 +42,11 @@ export class ProviderViewContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class ProviderElementContext {
|
export class ProviderElementContext {
|
||||||
private _contentQueries: CompileTokenMap<CompileQueryMetadata[]>;
|
private _contentQueries: CompileIdentifierMap<CompileTokenMetadata, CompileQueryMetadata[]>;
|
||||||
|
|
||||||
private _transformedProviders = new CompileTokenMap<ProviderAst>();
|
private _transformedProviders = new CompileIdentifierMap<CompileTokenMetadata, ProviderAst>();
|
||||||
private _seenProviders = new CompileTokenMap<boolean>();
|
private _seenProviders = new CompileIdentifierMap<CompileTokenMetadata, boolean>();
|
||||||
private _allProviders: CompileTokenMap<ProviderAst>;
|
private _allProviders: CompileIdentifierMap<CompileTokenMetadata, ProviderAst>;
|
||||||
private _attrs: {[key: string]: string};
|
private _attrs: {[key: string]: string};
|
||||||
private _hasViewContainer: boolean = false;
|
private _hasViewContainer: boolean = false;
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ export class ProviderElementContext {
|
|||||||
this._allProviders =
|
this._allProviders =
|
||||||
_resolveProvidersFromDirectives(directivesMeta, _sourceSpan, _viewContext.errors);
|
_resolveProvidersFromDirectives(directivesMeta, _sourceSpan, _viewContext.errors);
|
||||||
this._contentQueries = _getContentQueries(directivesMeta);
|
this._contentQueries = _getContentQueries(directivesMeta);
|
||||||
var queriedTokens = new CompileTokenMap<boolean>();
|
var queriedTokens = new CompileIdentifierMap<CompileTokenMetadata, boolean>();
|
||||||
this._allProviders.values().forEach(
|
this._allProviders.values().forEach(
|
||||||
(provider) => { this._addQueryReadsTo(provider.token, queriedTokens); });
|
(provider) => { this._addQueryReadsTo(provider.token, queriedTokens); });
|
||||||
refs.forEach((refAst) => {
|
refs.forEach((refAst) => {
|
||||||
@ -100,7 +100,9 @@ export class ProviderElementContext {
|
|||||||
|
|
||||||
get transformedHasViewContainer(): boolean { return this._hasViewContainer; }
|
get transformedHasViewContainer(): boolean { return this._hasViewContainer; }
|
||||||
|
|
||||||
private _addQueryReadsTo(token: CompileTokenMetadata, queryReadTokens: CompileTokenMap<boolean>) {
|
private _addQueryReadsTo(
|
||||||
|
token: CompileTokenMetadata,
|
||||||
|
queryReadTokens: CompileIdentifierMap<CompileTokenMetadata, boolean>) {
|
||||||
this._getQueriesFor(token).forEach((query) => {
|
this._getQueriesFor(token).forEach((query) => {
|
||||||
const queryReadToken = isPresent(query.read) ? query.read : token;
|
const queryReadToken = isPresent(query.read) ? query.read : token;
|
||||||
if (isBlank(queryReadTokens.get(queryReadToken))) {
|
if (isBlank(queryReadTokens.get(queryReadToken))) {
|
||||||
@ -272,24 +274,28 @@ export class ProviderElementContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export class AppModuleProviderParser {
|
export class NgModuleProviderAnalyzer {
|
||||||
private _transformedProviders = new CompileTokenMap<ProviderAst>();
|
private _transformedProviders = new CompileIdentifierMap<CompileTokenMetadata, ProviderAst>();
|
||||||
private _seenProviders = new CompileTokenMap<boolean>();
|
private _seenProviders = new CompileIdentifierMap<CompileTokenMetadata, boolean>();
|
||||||
private _unparsedProviders: any[] = [];
|
private _unparsedProviders: any[] = [];
|
||||||
private _allProviders: CompileTokenMap<ProviderAst>;
|
private _allProviders: CompileIdentifierMap<CompileTokenMetadata, ProviderAst>;
|
||||||
private _errors: ProviderError[] = [];
|
private _errors: ProviderError[] = [];
|
||||||
|
|
||||||
constructor(appModule: CompileAppModuleMetadata, sourceSpan: ParseSourceSpan) {
|
constructor(
|
||||||
this._allProviders = new CompileTokenMap<ProviderAst>();
|
ngModule: CompileNgModuleMetadata, extraProviders: CompileProviderMetadata[],
|
||||||
[appModule.type].concat(appModule.modules).forEach((appModuleType: CompileTypeMetadata) => {
|
sourceSpan: ParseSourceSpan) {
|
||||||
const appModuleProvider = new CompileProviderMetadata(
|
this._allProviders = new CompileIdentifierMap<CompileTokenMetadata, ProviderAst>();
|
||||||
{token: new CompileTokenMetadata({identifier: appModuleType}), useClass: appModuleType});
|
const ngModuleTypes = ngModule.transitiveModule.modules.map((moduleMeta) => moduleMeta.type);
|
||||||
|
ngModuleTypes.forEach((ngModuleType: CompileTypeMetadata) => {
|
||||||
|
const ngModuleProvider = new CompileProviderMetadata(
|
||||||
|
{token: new CompileTokenMetadata({identifier: ngModuleType}), useClass: ngModuleType});
|
||||||
_resolveProviders(
|
_resolveProviders(
|
||||||
[appModuleProvider], ProviderAstType.PublicService, true, sourceSpan, this._errors,
|
[ngModuleProvider], ProviderAstType.PublicService, true, sourceSpan, this._errors,
|
||||||
this._allProviders);
|
this._allProviders);
|
||||||
});
|
});
|
||||||
_resolveProviders(
|
_resolveProviders(
|
||||||
_normalizeProviders(appModule.providers, sourceSpan, this._errors),
|
_normalizeProviders(
|
||||||
|
ngModule.transitiveModule.providers.concat(extraProviders), sourceSpan, this._errors),
|
||||||
ProviderAstType.PublicService, false, sourceSpan, this._errors, this._allProviders);
|
ProviderAstType.PublicService, false, sourceSpan, this._errors, this._allProviders);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,8 +442,8 @@ function _normalizeProviders(
|
|||||||
|
|
||||||
function _resolveProvidersFromDirectives(
|
function _resolveProvidersFromDirectives(
|
||||||
directives: CompileDirectiveMetadata[], sourceSpan: ParseSourceSpan,
|
directives: CompileDirectiveMetadata[], sourceSpan: ParseSourceSpan,
|
||||||
targetErrors: ParseError[]): CompileTokenMap<ProviderAst> {
|
targetErrors: ParseError[]): CompileIdentifierMap<CompileTokenMetadata, ProviderAst> {
|
||||||
var providersByToken = new CompileTokenMap<ProviderAst>();
|
var providersByToken = new CompileIdentifierMap<CompileTokenMetadata, ProviderAst>();
|
||||||
directives.forEach((directive) => {
|
directives.forEach((directive) => {
|
||||||
var dirProvider = new CompileProviderMetadata(
|
var dirProvider = new CompileProviderMetadata(
|
||||||
{token: new CompileTokenMetadata({identifier: directive.type}), useClass: directive.type});
|
{token: new CompileTokenMetadata({identifier: directive.type}), useClass: directive.type});
|
||||||
@ -464,7 +470,7 @@ function _resolveProvidersFromDirectives(
|
|||||||
function _resolveProviders(
|
function _resolveProviders(
|
||||||
providers: CompileProviderMetadata[], providerType: ProviderAstType, eager: boolean,
|
providers: CompileProviderMetadata[], providerType: ProviderAstType, eager: boolean,
|
||||||
sourceSpan: ParseSourceSpan, targetErrors: ParseError[],
|
sourceSpan: ParseSourceSpan, targetErrors: ParseError[],
|
||||||
targetProvidersByToken: CompileTokenMap<ProviderAst>) {
|
targetProvidersByToken: CompileIdentifierMap<CompileTokenMetadata, ProviderAst>) {
|
||||||
providers.forEach((provider) => {
|
providers.forEach((provider) => {
|
||||||
var resolvedProvider = targetProvidersByToken.get(provider.token);
|
var resolvedProvider = targetProvidersByToken.get(provider.token);
|
||||||
if (isPresent(resolvedProvider) && resolvedProvider.multiProvider !== provider.multi) {
|
if (isPresent(resolvedProvider) && resolvedProvider.multiProvider !== provider.multi) {
|
||||||
@ -487,8 +493,8 @@ function _resolveProviders(
|
|||||||
|
|
||||||
|
|
||||||
function _getViewQueries(component: CompileDirectiveMetadata):
|
function _getViewQueries(component: CompileDirectiveMetadata):
|
||||||
CompileTokenMap<CompileQueryMetadata[]> {
|
CompileIdentifierMap<CompileTokenMetadata, CompileQueryMetadata[]> {
|
||||||
var viewQueries = new CompileTokenMap<CompileQueryMetadata[]>();
|
var viewQueries = new CompileIdentifierMap<CompileTokenMetadata, CompileQueryMetadata[]>();
|
||||||
if (isPresent(component.viewQueries)) {
|
if (isPresent(component.viewQueries)) {
|
||||||
component.viewQueries.forEach((query) => _addQueryToTokenMap(viewQueries, query));
|
component.viewQueries.forEach((query) => _addQueryToTokenMap(viewQueries, query));
|
||||||
}
|
}
|
||||||
@ -501,8 +507,8 @@ function _getViewQueries(component: CompileDirectiveMetadata):
|
|||||||
}
|
}
|
||||||
|
|
||||||
function _getContentQueries(directives: CompileDirectiveMetadata[]):
|
function _getContentQueries(directives: CompileDirectiveMetadata[]):
|
||||||
CompileTokenMap<CompileQueryMetadata[]> {
|
CompileIdentifierMap<CompileTokenMetadata, CompileQueryMetadata[]> {
|
||||||
var contentQueries = new CompileTokenMap<CompileQueryMetadata[]>();
|
var contentQueries = new CompileIdentifierMap<CompileTokenMetadata, CompileQueryMetadata[]>();
|
||||||
directives.forEach(directive => {
|
directives.forEach(directive => {
|
||||||
if (isPresent(directive.queries)) {
|
if (isPresent(directive.queries)) {
|
||||||
directive.queries.forEach((query) => _addQueryToTokenMap(contentQueries, query));
|
directive.queries.forEach((query) => _addQueryToTokenMap(contentQueries, query));
|
||||||
@ -517,7 +523,8 @@ function _getContentQueries(directives: CompileDirectiveMetadata[]):
|
|||||||
}
|
}
|
||||||
|
|
||||||
function _addQueryToTokenMap(
|
function _addQueryToTokenMap(
|
||||||
map: CompileTokenMap<CompileQueryMetadata[]>, query: CompileQueryMetadata) {
|
map: CompileIdentifierMap<CompileTokenMetadata, CompileQueryMetadata[]>,
|
||||||
|
query: CompileQueryMetadata) {
|
||||||
query.selectors.forEach((token: CompileTokenMetadata) => {
|
query.selectors.forEach((token: CompileTokenMetadata) => {
|
||||||
var entry = map.get(token);
|
var entry = map.get(token);
|
||||||
if (isBlank(entry)) {
|
if (isBlank(entry)) {
|
@ -6,19 +6,19 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {AppModuleFactory, AppModuleMetadata, Compiler, ComponentFactory, ComponentResolver, ComponentStillLoadingError, Injectable, Injector, OptionalMetadata, Provider, SkipSelfMetadata} from '@angular/core';
|
import {Compiler, ComponentFactory, ComponentResolver, ComponentStillLoadingError, Injectable, Injector, NgModule, NgModuleFactory, NgModuleMetadata, OptionalMetadata, Provider, SkipSelfMetadata} from '@angular/core';
|
||||||
import {Console} from '../core_private';
|
|
||||||
|
|
||||||
|
import {Console} from '../core_private';
|
||||||
import {BaseException} from '../src/facade/exceptions';
|
import {BaseException} from '../src/facade/exceptions';
|
||||||
import {ConcreteType, IS_DART, Type, isBlank, isString, stringify} from '../src/facade/lang';
|
import {ConcreteType, IS_DART, Type, isBlank, isString, stringify} from '../src/facade/lang';
|
||||||
|
|
||||||
import {ListWrapper,} from '../src/facade/collection';
|
import {ListWrapper,} from '../src/facade/collection';
|
||||||
import {PromiseWrapper} from '../src/facade/async';
|
import {PromiseWrapper} from '../src/facade/async';
|
||||||
import {createHostComponentMeta, CompileDirectiveMetadata, CompilePipeMetadata, CompileIdentifierMetadata} from './compile_metadata';
|
import {createHostComponentMeta, CompileDirectiveMetadata, CompilePipeMetadata, CompileIdentifierMetadata, CompileNgModuleMetadata} from './compile_metadata';
|
||||||
import {TemplateAst,} from './template_ast';
|
import {TemplateAst,} from './template_ast';
|
||||||
import {StyleCompiler, StylesCompileDependency, CompiledStylesheet} from './style_compiler';
|
import {StyleCompiler, StylesCompileDependency, CompiledStylesheet} from './style_compiler';
|
||||||
import {ViewCompiler, ViewCompileResult, ViewFactoryDependency, ComponentFactoryDependency} from './view_compiler/view_compiler';
|
import {ViewCompiler, ViewCompileResult, ViewFactoryDependency, ComponentFactoryDependency} from './view_compiler/view_compiler';
|
||||||
import {AppModuleCompiler} from './app_module_compiler';
|
import {NgModuleCompiler} from './ng_module_compiler';
|
||||||
import {TemplateParser} from './template_parser';
|
import {TemplateParser} from './template_parser';
|
||||||
import {DirectiveNormalizer} from './directive_normalizer';
|
import {DirectiveNormalizer} from './directive_normalizer';
|
||||||
import {CompileMetadataResolver} from './metadata_resolver';
|
import {CompileMetadataResolver} from './metadata_resolver';
|
||||||
@ -38,122 +38,123 @@ import {SyncAsyncResult} from './util';
|
|||||||
* application to XSS risks. For more detail, see the [Security Guide](http://g.co/ng/security).
|
* application to XSS risks. For more detail, see the [Security Guide](http://g.co/ng/security).
|
||||||
*/
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class RuntimeCompiler implements ComponentResolver, Compiler {
|
export class RuntimeCompiler implements Compiler {
|
||||||
private _compiledTemplateCache = new Map<Type, CompiledTemplate>();
|
private _compiledTemplateCache = new Map<Type, CompiledTemplate>();
|
||||||
private _compiledHostTemplateCache = new Map<Type, CompiledTemplate>();
|
private _compiledHostTemplateCache = new Map<Type, CompiledTemplate>();
|
||||||
private _compiledAppModuleCache = new Map<Type, AppModuleFactory<any>>();
|
private _compiledNgModuleCache = new Map<Type, NgModuleFactory<any>>();
|
||||||
|
|
||||||
private _warnOnComponentResolver = true;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private _injector: Injector, private _metadataResolver: CompileMetadataResolver,
|
private _injector: Injector, private _metadataResolver: CompileMetadataResolver,
|
||||||
private _templateNormalizer: DirectiveNormalizer, private _templateParser: TemplateParser,
|
private _templateNormalizer: DirectiveNormalizer, private _templateParser: TemplateParser,
|
||||||
private _styleCompiler: StyleCompiler, private _viewCompiler: ViewCompiler,
|
private _styleCompiler: StyleCompiler, private _viewCompiler: ViewCompiler,
|
||||||
private _appModuleCompiler: AppModuleCompiler, private _genConfig: CompilerConfig,
|
private _ngModuleCompiler: NgModuleCompiler, private _compilerConfig: CompilerConfig,
|
||||||
private _console: Console) {
|
private _console: Console) {}
|
||||||
const flatDeprecatedPlatformDirectives =
|
|
||||||
ListWrapper.flatten(_genConfig.deprecatedPlatformDirectives);
|
|
||||||
if (flatDeprecatedPlatformDirectives.length > 0) {
|
|
||||||
this._console.warn(
|
|
||||||
`Providing platform directives via the PLATFORM_DIRECTIVES provider or the "CompilerConfig" is deprecated. Provide platform directives via an @AppModule instead. Directives: ` +
|
|
||||||
flatDeprecatedPlatformDirectives.map(stringify));
|
|
||||||
}
|
|
||||||
const flatDeprecatedPlatformPipes = ListWrapper.flatten(_genConfig.deprecatedPlatformPipes);
|
|
||||||
if (flatDeprecatedPlatformPipes.length > 0) {
|
|
||||||
this._console.warn(
|
|
||||||
`Providing platform pipes via the PLATFORM_PIPES provider or the "CompilerConfig" is deprecated. Provide platform pipes via an @AppModule instead. Pipes: ` +
|
|
||||||
flatDeprecatedPlatformPipes.map(stringify));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get injector(): Injector { return this._injector; }
|
get injector(): Injector { return this._injector; }
|
||||||
|
|
||||||
resolveComponent(component: Type|string): Promise<ComponentFactory<any>> {
|
compileModuleSync<T>(moduleType: ConcreteType<T>): NgModuleFactory<T> {
|
||||||
if (isString(component)) {
|
return this._compileModuleAndComponents(moduleType, true).syncResult;
|
||||||
return PromiseWrapper.reject(
|
|
||||||
new BaseException(`Cannot resolve component using '${component}'.`), null);
|
|
||||||
}
|
|
||||||
if (this._warnOnComponentResolver) {
|
|
||||||
this._console.warn(ComponentResolver.DynamicCompilationDeprecationMsg);
|
|
||||||
this._warnOnComponentResolver = false;
|
|
||||||
}
|
|
||||||
return this.compileComponentAsync(<ConcreteType<any>>component);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
compileAppModuleSync<T>(moduleType: ConcreteType<T>, metadata: AppModuleMetadata = null):
|
compileModuleAsync<T>(moduleType: ConcreteType<T>): Promise<NgModuleFactory<T>> {
|
||||||
AppModuleFactory<T> {
|
return this._compileModuleAndComponents(moduleType, false).asyncResult;
|
||||||
return this._compileAppModule(moduleType, true, metadata).syncResult;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
compileAppModuleAsync<T>(moduleType: ConcreteType<T>, metadata: AppModuleMetadata = null):
|
compileComponentAsync<T>(compType: ConcreteType<T>, ngModule: ConcreteType<any> = null):
|
||||||
Promise<AppModuleFactory<T>> {
|
Promise<ComponentFactory<T>> {
|
||||||
return this._compileAppModule(moduleType, false, metadata).asyncResult;
|
if (!ngModule) {
|
||||||
|
throw new BaseException(
|
||||||
|
`Calling compileComponentAsync on the root compiler without a module is not allowed! (Compiling component ${stringify(compType)})`);
|
||||||
|
}
|
||||||
|
return this._compileComponentInModule(compType, false, ngModule).asyncResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _compileAppModule<T>(
|
compileComponentSync<T>(compType: ConcreteType<T>, ngModule: ConcreteType<any> = null):
|
||||||
moduleType: ConcreteType<T>, isSync: boolean,
|
ComponentFactory<T> {
|
||||||
metadata: AppModuleMetadata = null): SyncAsyncResult<AppModuleFactory<T>> {
|
if (!ngModule) {
|
||||||
// Only cache if we read the metadata via the reflector,
|
throw new BaseException(
|
||||||
// as we use the moduleType as cache key.
|
`Calling compileComponentSync on the root compiler without a module is not allowed! (Compiling component ${stringify(compType)})`);
|
||||||
let useCache = !metadata;
|
}
|
||||||
let appModuleFactory = this._compiledAppModuleCache.get(moduleType);
|
return this._compileComponentInModule(compType, true, ngModule).syncResult;
|
||||||
let componentCompilePromises: Promise<any>[] = [];
|
}
|
||||||
if (!appModuleFactory || !useCache) {
|
|
||||||
var compileModuleMeta = this._metadataResolver.getAppModuleMetadata(moduleType, metadata);
|
private _compileModuleAndComponents<T>(moduleType: ConcreteType<T>, isSync: boolean):
|
||||||
let boundCompilerFactory = (parentResolver: ComponentResolver) => new BoundCompiler(
|
SyncAsyncResult<NgModuleFactory<T>> {
|
||||||
this, compileModuleMeta.directives.map(dir => dir.type.runtime),
|
const componentPromise = this._compileComponents(moduleType, isSync);
|
||||||
compileModuleMeta.pipes.map((pipe) => pipe.type.runtime), parentResolver);
|
const ngModuleFactory = this._compileModule(moduleType);
|
||||||
|
return new SyncAsyncResult(ngModuleFactory, componentPromise.then(() => ngModuleFactory));
|
||||||
|
}
|
||||||
|
|
||||||
|
private _compileModule<T>(moduleType: ConcreteType<T>): NgModuleFactory<T> {
|
||||||
|
let ngModuleFactory = this._compiledNgModuleCache.get(moduleType);
|
||||||
|
if (!ngModuleFactory) {
|
||||||
|
const moduleMeta = this._metadataResolver.getNgModuleMetadata(moduleType);
|
||||||
|
const transitiveModuleMeta = moduleMeta.transitiveModule;
|
||||||
|
let boundCompilerFactory = (parentResolver: ComponentResolver) =>
|
||||||
|
new ModuleBoundCompiler(this, moduleMeta.type.runtime, parentResolver, this._console);
|
||||||
// Always provide a bound Compiler and ComponentResolver
|
// Always provide a bound Compiler and ComponentResolver
|
||||||
compileModuleMeta.providers.push(
|
const extraProviders = [
|
||||||
this._metadataResolver.getProviderMetadata(new Provider(Compiler, {
|
this._metadataResolver.getProviderMetadata(new Provider(Compiler, {
|
||||||
useFactory: boundCompilerFactory,
|
useFactory: boundCompilerFactory,
|
||||||
deps: [[new OptionalMetadata(), new SkipSelfMetadata(), ComponentResolver]]
|
deps: [[new OptionalMetadata(), new SkipSelfMetadata(), ComponentResolver]]
|
||||||
})));
|
})),
|
||||||
compileModuleMeta.providers.push(this._metadataResolver.getProviderMetadata(
|
this._metadataResolver.getProviderMetadata(
|
||||||
new Provider(ComponentResolver, {useExisting: Compiler})));
|
new Provider(ComponentResolver, {useExisting: Compiler}))
|
||||||
var compileResult = this._appModuleCompiler.compile(compileModuleMeta);
|
];
|
||||||
|
var compileResult = this._ngModuleCompiler.compile(moduleMeta, extraProviders);
|
||||||
compileResult.dependencies.forEach((dep) => {
|
compileResult.dependencies.forEach((dep) => {
|
||||||
let compileResult = this._compileComponent(
|
dep.placeholder.runtime =
|
||||||
dep.comp.runtime, isSync,
|
this._assertComponentKnown(dep.comp.runtime, true).proxyComponentFactory;
|
||||||
compileModuleMeta.directives.map(compileType => <any>compileType.runtime),
|
|
||||||
compileModuleMeta.pipes.map(compileType => <any>compileType.runtime));
|
|
||||||
dep.placeholder.runtime = compileResult.syncResult;
|
|
||||||
componentCompilePromises.push(compileResult.asyncResult);
|
|
||||||
dep.placeholder.name = `compFactory_${dep.comp.name}`;
|
dep.placeholder.name = `compFactory_${dep.comp.name}`;
|
||||||
});
|
});
|
||||||
if (IS_DART || !this._genConfig.useJit) {
|
if (IS_DART || !this._compilerConfig.useJit) {
|
||||||
appModuleFactory =
|
ngModuleFactory =
|
||||||
interpretStatements(compileResult.statements, compileResult.appModuleFactoryVar);
|
interpretStatements(compileResult.statements, compileResult.ngModuleFactoryVar);
|
||||||
} else {
|
} else {
|
||||||
appModuleFactory = jitStatements(
|
ngModuleFactory = jitStatements(
|
||||||
`${compileModuleMeta.type.name}.ngfactory.js`, compileResult.statements,
|
`${moduleMeta.type.name}.ngfactory.js`, compileResult.statements,
|
||||||
compileResult.appModuleFactoryVar);
|
compileResult.ngModuleFactoryVar);
|
||||||
}
|
}
|
||||||
if (useCache) {
|
this._compiledNgModuleCache.set(moduleMeta.type.runtime, ngModuleFactory);
|
||||||
this._compiledAppModuleCache.set(moduleType, appModuleFactory);
|
|
||||||
}
|
}
|
||||||
}
|
return ngModuleFactory;
|
||||||
return new SyncAsyncResult(
|
|
||||||
appModuleFactory, Promise.all(componentCompilePromises).then(() => appModuleFactory));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
compileComponentAsync<T>(compType: ConcreteType<T>): Promise<ComponentFactory<T>> {
|
private _compileComponentInModule<T>(
|
||||||
return this._compileComponent(compType, false, [], []).asyncResult;
|
compType: ConcreteType<T>, isSync: boolean,
|
||||||
}
|
moduleType: ConcreteType<any>): SyncAsyncResult<ComponentFactory<T>> {
|
||||||
|
this._metadataResolver.addComponentToModule(moduleType, compType);
|
||||||
|
|
||||||
compileComponentSync<T>(compType: ConcreteType<T>): ComponentFactory<T> {
|
const componentPromise = this._compileComponents(moduleType, isSync);
|
||||||
return this._compileComponent(compType, true, [], []).syncResult;
|
const componentFactory: ComponentFactory<T> =
|
||||||
|
this._assertComponentKnown(compType, true).proxyComponentFactory;
|
||||||
|
|
||||||
|
return new SyncAsyncResult(componentFactory, componentPromise.then(() => componentFactory));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
_compileComponent<T>(
|
_compileComponents(mainModule: Type, isSync: boolean): Promise<any> {
|
||||||
compType: ConcreteType<T>, isSync: boolean, moduleDirectives: ConcreteType<any>[],
|
const templates = new Set<CompiledTemplate>();
|
||||||
modulePipes: ConcreteType<any>[]): SyncAsyncResult<ComponentFactory<T>> {
|
|
||||||
var templates =
|
|
||||||
this._getTransitiveCompiledTemplates(compType, true, moduleDirectives, modulePipes);
|
|
||||||
var loadingPromises: Promise<any>[] = [];
|
var loadingPromises: Promise<any>[] = [];
|
||||||
|
|
||||||
|
const ngModule = this._metadataResolver.getNgModuleMetadata(mainModule);
|
||||||
|
ngModule.transitiveModule.modules.forEach((localModuleMeta) => {
|
||||||
|
localModuleMeta.declaredDirectives.forEach((dirMeta) => {
|
||||||
|
if (dirMeta.isComponent) {
|
||||||
|
templates.add(this._createCompiledTemplate(
|
||||||
|
dirMeta, localModuleMeta.transitiveModule.directives,
|
||||||
|
localModuleMeta.transitiveModule.pipes));
|
||||||
|
dirMeta.precompile.forEach((precompileType) => {
|
||||||
|
templates.add(this._createCompiledHostTemplate(precompileType.runtime));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
localModuleMeta.precompile.forEach((precompileType) => {
|
||||||
|
templates.add(this._createCompiledHostTemplate(precompileType.runtime));
|
||||||
|
});
|
||||||
|
});
|
||||||
templates.forEach((template) => {
|
templates.forEach((template) => {
|
||||||
if (template.loading) {
|
if (template.loading) {
|
||||||
if (isSync) {
|
if (isSync) {
|
||||||
@ -167,16 +168,14 @@ export class RuntimeCompiler implements ComponentResolver, Compiler {
|
|||||||
() => { templates.forEach((template) => { this._compileTemplate(template); }); };
|
() => { templates.forEach((template) => { this._compileTemplate(template); }); };
|
||||||
if (isSync) {
|
if (isSync) {
|
||||||
compile();
|
compile();
|
||||||
|
return Promise.resolve(null);
|
||||||
|
} else {
|
||||||
|
return Promise.all(loadingPromises).then(compile);
|
||||||
}
|
}
|
||||||
let result = this._compiledHostTemplateCache.get(compType).proxyComponentFactory;
|
|
||||||
return new SyncAsyncResult(result, Promise.all(loadingPromises).then(() => {
|
|
||||||
compile();
|
|
||||||
return result;
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clearCacheFor(type: Type) {
|
clearCacheFor(type: Type) {
|
||||||
this._compiledAppModuleCache.delete(type);
|
this._compiledNgModuleCache.delete(type);
|
||||||
this._metadataResolver.clearCacheFor(type);
|
this._metadataResolver.clearCacheFor(type);
|
||||||
this._compiledHostTemplateCache.delete(type);
|
this._compiledHostTemplateCache.delete(type);
|
||||||
var compiledTemplate = this._compiledTemplateCache.get(type);
|
var compiledTemplate = this._compiledTemplateCache.get(type);
|
||||||
@ -191,71 +190,54 @@ export class RuntimeCompiler implements ComponentResolver, Compiler {
|
|||||||
this._compiledTemplateCache.clear();
|
this._compiledTemplateCache.clear();
|
||||||
this._compiledHostTemplateCache.clear();
|
this._compiledHostTemplateCache.clear();
|
||||||
this._templateNormalizer.clearCache();
|
this._templateNormalizer.clearCache();
|
||||||
this._compiledAppModuleCache.clear();
|
this._compiledNgModuleCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _createCompiledHostTemplate(type: Type): CompiledTemplate {
|
private _createCompiledHostTemplate(compType: Type): CompiledTemplate {
|
||||||
var compiledTemplate = this._compiledHostTemplateCache.get(type);
|
var compiledTemplate = this._compiledHostTemplateCache.get(compType);
|
||||||
if (isBlank(compiledTemplate)) {
|
if (isBlank(compiledTemplate)) {
|
||||||
var compMeta = this._metadataResolver.getDirectiveMetadata(type);
|
var compMeta = this._metadataResolver.getDirectiveMetadata(compType);
|
||||||
assertComponent(compMeta);
|
assertComponent(compMeta);
|
||||||
var hostMeta = createHostComponentMeta(compMeta.type, compMeta.selector);
|
var hostMeta = createHostComponentMeta(compMeta);
|
||||||
compiledTemplate = new CompiledTemplate(
|
compiledTemplate = new CompiledTemplate(
|
||||||
true, compMeta.selector, compMeta.type, [], [type], [], [],
|
true, compMeta.selector, compMeta.type, [compMeta], [],
|
||||||
this._templateNormalizer.normalizeDirective(hostMeta));
|
this._templateNormalizer.normalizeDirective(hostMeta));
|
||||||
this._compiledHostTemplateCache.set(type, compiledTemplate);
|
this._compiledHostTemplateCache.set(compType, compiledTemplate);
|
||||||
}
|
}
|
||||||
return compiledTemplate;
|
return compiledTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _createCompiledTemplate(
|
private _createCompiledTemplate(
|
||||||
type: Type, moduleDirectives: ConcreteType<any>[],
|
compMeta: CompileDirectiveMetadata, directives: CompileDirectiveMetadata[],
|
||||||
modulePipes: ConcreteType<any>[]): CompiledTemplate {
|
pipes: CompilePipeMetadata[]): CompiledTemplate {
|
||||||
var compiledTemplate = this._compiledTemplateCache.get(type);
|
var compiledTemplate = this._compiledTemplateCache.get(compMeta.type.runtime);
|
||||||
if (isBlank(compiledTemplate)) {
|
if (isBlank(compiledTemplate)) {
|
||||||
const compMeta = this._metadataResolver.getDirectiveMetadata(type);
|
|
||||||
assertComponent(compMeta);
|
assertComponent(compMeta);
|
||||||
const viewDirectives: CompileDirectiveMetadata[] = [];
|
|
||||||
moduleDirectives.forEach(
|
|
||||||
(type) => viewDirectives.push(this._metadataResolver.getDirectiveMetadata(type)));
|
|
||||||
const viewComponentTypes: Type[] = [];
|
|
||||||
this._metadataResolver.getViewDirectivesMetadata(type).forEach(dirOrComp => {
|
|
||||||
if (dirOrComp.isComponent) {
|
|
||||||
viewComponentTypes.push(dirOrComp.type.runtime);
|
|
||||||
} else {
|
|
||||||
viewDirectives.push(dirOrComp);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const precompileComponentTypes = compMeta.precompile.map((typeMeta) => typeMeta.runtime);
|
|
||||||
const pipes = [
|
|
||||||
...modulePipes.map((type) => this._metadataResolver.getPipeMetadata(type)),
|
|
||||||
...this._metadataResolver.getViewPipesMetadata(type)
|
|
||||||
];
|
|
||||||
compiledTemplate = new CompiledTemplate(
|
compiledTemplate = new CompiledTemplate(
|
||||||
false, compMeta.selector, compMeta.type, viewDirectives, viewComponentTypes,
|
false, compMeta.selector, compMeta.type, directives, pipes,
|
||||||
precompileComponentTypes, pipes, this._templateNormalizer.normalizeDirective(compMeta));
|
this._templateNormalizer.normalizeDirective(compMeta));
|
||||||
this._compiledTemplateCache.set(type, compiledTemplate);
|
this._compiledTemplateCache.set(compMeta.type.runtime, compiledTemplate);
|
||||||
}
|
}
|
||||||
return compiledTemplate;
|
return compiledTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _getTransitiveCompiledTemplates(
|
private _assertComponentKnown(compType: any, isHost: boolean): CompiledTemplate {
|
||||||
compType: Type, isHost: boolean, moduleDirectives: ConcreteType<any>[],
|
const compiledTemplate = isHost ? this._compiledHostTemplateCache.get(compType) :
|
||||||
modulePipes: ConcreteType<any>[],
|
this._compiledTemplateCache.get(compType);
|
||||||
target: Set<CompiledTemplate> = new Set<CompiledTemplate>()): Set<CompiledTemplate> {
|
if (!compiledTemplate) {
|
||||||
const template = isHost ? this._createCompiledHostTemplate(compType) :
|
throw new BaseException(
|
||||||
this._createCompiledTemplate(compType, moduleDirectives, modulePipes);
|
`Illegal state: CompiledTemplate for ${stringify(compType)} (isHost: ${isHost}) does not exist!`);
|
||||||
if (!target.has(template)) {
|
|
||||||
target.add(template);
|
|
||||||
template.viewComponentTypes.forEach((compType) => {
|
|
||||||
this._getTransitiveCompiledTemplates(
|
|
||||||
compType, false, moduleDirectives, modulePipes, target);
|
|
||||||
});
|
|
||||||
template.precompileHostComponentTypes.forEach((compType) => {
|
|
||||||
this._getTransitiveCompiledTemplates(compType, true, moduleDirectives, modulePipes, target);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return target;
|
return compiledTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _assertComponentLoaded(compType: any, isHost: boolean): CompiledTemplate {
|
||||||
|
const compiledTemplate = this._assertComponentKnown(compType, isHost);
|
||||||
|
if (compiledTemplate.loading) {
|
||||||
|
throw new BaseException(
|
||||||
|
`Illegal state: CompiledTemplate for ${stringify(compType)} (isHost: ${isHost}) is still loading!`);
|
||||||
|
}
|
||||||
|
return compiledTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _compileTemplate(template: CompiledTemplate) {
|
private _compileTemplate(template: CompiledTemplate) {
|
||||||
@ -270,7 +252,7 @@ export class RuntimeCompiler implements ComponentResolver, Compiler {
|
|||||||
this._resolveStylesCompileResult(
|
this._resolveStylesCompileResult(
|
||||||
stylesCompileResult.componentStylesheet, externalStylesheetsByModuleUrl);
|
stylesCompileResult.componentStylesheet, externalStylesheetsByModuleUrl);
|
||||||
const viewCompMetas = template.viewComponentTypes.map(
|
const viewCompMetas = template.viewComponentTypes.map(
|
||||||
(compType) => this._compiledTemplateCache.get(compType).normalizedCompMeta);
|
(compType) => this._assertComponentLoaded(compType, false).normalizedCompMeta);
|
||||||
const parsedTemplate = this._templateParser.parse(
|
const parsedTemplate = this._templateParser.parse(
|
||||||
compMeta, compMeta.template.template, template.viewDirectives.concat(viewCompMetas),
|
compMeta, compMeta.template.template, template.viewDirectives.concat(viewCompMetas),
|
||||||
template.viewPipes, compMeta.type.name);
|
template.viewPipes, compMeta.type.name);
|
||||||
@ -281,12 +263,12 @@ export class RuntimeCompiler implements ComponentResolver, Compiler {
|
|||||||
let depTemplate: CompiledTemplate;
|
let depTemplate: CompiledTemplate;
|
||||||
if (dep instanceof ViewFactoryDependency) {
|
if (dep instanceof ViewFactoryDependency) {
|
||||||
let vfd = <ViewFactoryDependency>dep;
|
let vfd = <ViewFactoryDependency>dep;
|
||||||
depTemplate = this._compiledTemplateCache.get(vfd.comp.runtime);
|
depTemplate = this._assertComponentLoaded(vfd.comp.runtime, false);
|
||||||
vfd.placeholder.runtime = depTemplate.proxyViewFactory;
|
vfd.placeholder.runtime = depTemplate.proxyViewFactory;
|
||||||
vfd.placeholder.name = `viewFactory_${vfd.comp.name}`;
|
vfd.placeholder.name = `viewFactory_${vfd.comp.name}`;
|
||||||
} else if (dep instanceof ComponentFactoryDependency) {
|
} else if (dep instanceof ComponentFactoryDependency) {
|
||||||
let cfd = <ComponentFactoryDependency>dep;
|
let cfd = <ComponentFactoryDependency>dep;
|
||||||
depTemplate = this._compiledHostTemplateCache.get(cfd.comp.runtime);
|
depTemplate = this._assertComponentLoaded(cfd.comp.runtime, true);
|
||||||
cfd.placeholder.runtime = depTemplate.proxyComponentFactory;
|
cfd.placeholder.runtime = depTemplate.proxyComponentFactory;
|
||||||
cfd.placeholder.name = `compFactory_${cfd.comp.name}`;
|
cfd.placeholder.name = `compFactory_${cfd.comp.name}`;
|
||||||
}
|
}
|
||||||
@ -294,7 +276,7 @@ export class RuntimeCompiler implements ComponentResolver, Compiler {
|
|||||||
const statements =
|
const statements =
|
||||||
stylesCompileResult.componentStylesheet.statements.concat(compileResult.statements);
|
stylesCompileResult.componentStylesheet.statements.concat(compileResult.statements);
|
||||||
let factory: any;
|
let factory: any;
|
||||||
if (IS_DART || !this._genConfig.useJit) {
|
if (IS_DART || !this._compilerConfig.useJit) {
|
||||||
factory = interpretStatements(statements, compileResult.viewFactoryVar);
|
factory = interpretStatements(statements, compileResult.viewFactoryVar);
|
||||||
} else {
|
} else {
|
||||||
factory = jitStatements(
|
factory = jitStatements(
|
||||||
@ -318,7 +300,7 @@ export class RuntimeCompiler implements ComponentResolver, Compiler {
|
|||||||
result: CompiledStylesheet,
|
result: CompiledStylesheet,
|
||||||
externalStylesheetsByModuleUrl: Map<string, CompiledStylesheet>): string[] {
|
externalStylesheetsByModuleUrl: Map<string, CompiledStylesheet>): string[] {
|
||||||
this._resolveStylesCompileResult(result, externalStylesheetsByModuleUrl);
|
this._resolveStylesCompileResult(result, externalStylesheetsByModuleUrl);
|
||||||
if (IS_DART || !this._genConfig.useJit) {
|
if (IS_DART || !this._compilerConfig.useJit) {
|
||||||
return interpretStatements(result.statements, result.stylesVar);
|
return interpretStatements(result.statements, result.stylesVar);
|
||||||
} else {
|
} else {
|
||||||
return jitStatements(`${result.meta.moduleUrl}.css.js`, result.statements, result.stylesVar);
|
return jitStatements(`${result.meta.moduleUrl}.css.js`, result.statements, result.stylesVar);
|
||||||
@ -334,13 +316,28 @@ class CompiledTemplate {
|
|||||||
private _normalizedCompMeta: CompileDirectiveMetadata = null;
|
private _normalizedCompMeta: CompileDirectiveMetadata = null;
|
||||||
isCompiled = false;
|
isCompiled = false;
|
||||||
isCompiledWithDeps = false;
|
isCompiledWithDeps = false;
|
||||||
|
viewComponentTypes: Type[] = [];
|
||||||
|
viewDirectives: CompileDirectiveMetadata[] = [];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public isHost: boolean, selector: string, public compType: CompileIdentifierMetadata,
|
public isHost: boolean, selector: string, public compType: CompileIdentifierMetadata,
|
||||||
public viewDirectives: CompileDirectiveMetadata[], public viewComponentTypes: Type[],
|
viewDirectivesAndComponents: CompileDirectiveMetadata[],
|
||||||
public precompileHostComponentTypes: Type[], public viewPipes: CompilePipeMetadata[],
|
public viewPipes: CompilePipeMetadata[],
|
||||||
_normalizeResult: SyncAsyncResult<CompileDirectiveMetadata>) {
|
_normalizeResult: SyncAsyncResult<CompileDirectiveMetadata>) {
|
||||||
this.proxyViewFactory = (...args: any[]) => this._viewFactory.apply(null, args);
|
viewDirectivesAndComponents.forEach((dirMeta) => {
|
||||||
|
if (dirMeta.isComponent) {
|
||||||
|
this.viewComponentTypes.push(dirMeta.type.runtime);
|
||||||
|
} else {
|
||||||
|
this.viewDirectives.push(dirMeta);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.proxyViewFactory = (...args: any[]) => {
|
||||||
|
if (!this._viewFactory) {
|
||||||
|
throw new BaseException(
|
||||||
|
`Illegal state: CompiledTemplate for ${stringify(this.compType)} is not compiled yet!`);
|
||||||
|
}
|
||||||
|
return this._viewFactory.apply(null, args);
|
||||||
|
};
|
||||||
this.proxyComponentFactory = isHost ?
|
this.proxyComponentFactory = isHost ?
|
||||||
new ComponentFactory<any>(selector, this.proxyViewFactory, compType.runtime) :
|
new ComponentFactory<any>(selector, this.proxyViewFactory, compType.runtime) :
|
||||||
null;
|
null;
|
||||||
@ -376,13 +373,15 @@ function assertComponent(meta: CompileDirectiveMetadata) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A wrapper around `Compiler` and `ComponentResolver` that
|
* Implements `Compiler` and `ComponentResolver` by delegating
|
||||||
* provides default patform directives / pipes.
|
* to the RuntimeCompiler using a known module.
|
||||||
*/
|
*/
|
||||||
class BoundCompiler implements Compiler, ComponentResolver {
|
class ModuleBoundCompiler implements Compiler, ComponentResolver {
|
||||||
|
private _warnOnComponentResolver = true;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private _delegate: RuntimeCompiler, private _directives: any[], private _pipes: any[],
|
private _delegate: RuntimeCompiler, private _ngModule: ConcreteType<any>,
|
||||||
private _parentComponentResolver: ComponentResolver) {}
|
private _parentComponentResolver: ComponentResolver, private _console: Console) {}
|
||||||
|
|
||||||
get injector(): Injector { return this._delegate.injector; }
|
get injector(): Injector { return this._delegate.injector; }
|
||||||
|
|
||||||
@ -395,27 +394,29 @@ class BoundCompiler implements Compiler, ComponentResolver {
|
|||||||
new BaseException(`Cannot resolve component using '${component}'.`), null);
|
new BaseException(`Cannot resolve component using '${component}'.`), null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (this._warnOnComponentResolver) {
|
||||||
|
this._console.warn(ComponentResolver.DynamicCompilationDeprecationMsg);
|
||||||
|
this._warnOnComponentResolver = false;
|
||||||
|
}
|
||||||
return this.compileComponentAsync(<ConcreteType<any>>component);
|
return this.compileComponentAsync(<ConcreteType<any>>component);
|
||||||
}
|
}
|
||||||
|
|
||||||
compileComponentAsync<T>(compType: ConcreteType<T>): Promise<ComponentFactory<T>> {
|
compileComponentAsync<T>(compType: ConcreteType<T>, ngModule: ConcreteType<any> = null):
|
||||||
return this._delegate._compileComponent(compType, false, this._directives, this._pipes)
|
Promise<ComponentFactory<T>> {
|
||||||
.asyncResult;
|
return this._delegate.compileComponentAsync(compType, ngModule ? ngModule : this._ngModule);
|
||||||
}
|
}
|
||||||
|
|
||||||
compileComponentSync<T>(compType: ConcreteType<T>): ComponentFactory<T> {
|
compileComponentSync<T>(compType: ConcreteType<T>, ngModule: ConcreteType<any> = null):
|
||||||
return this._delegate._compileComponent(compType, true, this._directives, this._pipes)
|
ComponentFactory<T> {
|
||||||
.syncResult;
|
return this._delegate.compileComponentSync(compType, ngModule ? ngModule : this._ngModule);
|
||||||
}
|
}
|
||||||
|
|
||||||
compileAppModuleSync<T>(moduleType: ConcreteType<T>, metadata: AppModuleMetadata = null):
|
compileModuleSync<T>(moduleType: ConcreteType<T>): NgModuleFactory<T> {
|
||||||
AppModuleFactory<T> {
|
return this._delegate.compileModuleSync(moduleType);
|
||||||
return this._delegate.compileAppModuleSync(moduleType, metadata);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
compileAppModuleAsync<T>(moduleType: ConcreteType<T>, metadata: AppModuleMetadata = null):
|
compileModuleAsync<T>(moduleType: ConcreteType<T>): Promise<NgModuleFactory<T>> {
|
||||||
Promise<AppModuleFactory<T>> {
|
return this._delegate.compileModuleAsync(moduleType);
|
||||||
return this._delegate.compileAppModuleAsync(moduleType, metadata);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -429,7 +430,7 @@ class BoundCompiler implements Compiler, ComponentResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the cache for the given component/appModule.
|
* Clears the cache for the given component/ngModule.
|
||||||
*/
|
*/
|
||||||
clearCacheFor(type: Type) { this._delegate.clearCacheFor(type); }
|
clearCacheFor(type: Type) { this._delegate.clearCacheFor(type); }
|
||||||
}
|
}
|
@ -13,7 +13,7 @@ import {RegExpWrapper, isPresent, StringWrapper, isBlank} from '../src/facade/la
|
|||||||
import {BaseException} from '../src/facade/exceptions';
|
import {BaseException} from '../src/facade/exceptions';
|
||||||
import {AST, Interpolation, ASTWithSource, TemplateBinding, RecursiveAstVisitor, BindingPipe, ParserError} from './expression_parser/ast';
|
import {AST, Interpolation, ASTWithSource, TemplateBinding, RecursiveAstVisitor, BindingPipe, ParserError} from './expression_parser/ast';
|
||||||
import {Parser} from './expression_parser/parser';
|
import {Parser} from './expression_parser/parser';
|
||||||
import {CompileDirectiveMetadata, CompilePipeMetadata, CompileMetadataWithType, CompileTokenMetadata,} from './compile_metadata';
|
import {CompileDirectiveMetadata, CompilePipeMetadata, CompileMetadataWithIdentifier, CompileTokenMetadata, CompileIdentifierMap, removeIdentifierDuplicates} from './compile_metadata';
|
||||||
import {HtmlParser, HtmlParseTreeResult} from './html_parser';
|
import {HtmlParser, HtmlParseTreeResult} from './html_parser';
|
||||||
import {splitNsName, mergeNsAndName} from './html_tags';
|
import {splitNsName, mergeNsAndName} from './html_tags';
|
||||||
import {ParseSourceSpan, ParseError, ParseErrorLevel} from './parse_util';
|
import {ParseSourceSpan, ParseError, ParseErrorLevel} from './parse_util';
|
||||||
@ -27,7 +27,7 @@ import {HtmlAstVisitor, HtmlElementAst, HtmlAttrAst, HtmlTextAst, HtmlCommentAst
|
|||||||
import {splitAtColon} from './util';
|
import {splitAtColon} from './util';
|
||||||
import {identifierToken, Identifiers} from './identifiers';
|
import {identifierToken, Identifiers} from './identifiers';
|
||||||
import {expandNodes} from './expander';
|
import {expandNodes} from './expander';
|
||||||
import {ProviderElementContext, ProviderViewContext} from './provider_parser';
|
import {ProviderElementContext, ProviderViewContext} from './provider_analyzer';
|
||||||
|
|
||||||
// Group 1 = "bind-"
|
// Group 1 = "bind-"
|
||||||
// Group 2 = "var-"
|
// Group 2 = "var-"
|
||||||
@ -118,8 +118,8 @@ export class TemplateParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (htmlAstWithErrors.rootNodes.length > 0) {
|
if (htmlAstWithErrors.rootNodes.length > 0) {
|
||||||
const uniqDirectives = <CompileDirectiveMetadata[]>removeDuplicates(directives);
|
const uniqDirectives = removeIdentifierDuplicates(directives);
|
||||||
const uniqPipes = <CompilePipeMetadata[]>removeDuplicates(pipes);
|
const uniqPipes = removeIdentifierDuplicates(pipes);
|
||||||
const providerViewContext =
|
const providerViewContext =
|
||||||
new ProviderViewContext(component, htmlAstWithErrors.rootNodes[0].sourceSpan);
|
new ProviderViewContext(component, htmlAstWithErrors.rootNodes[0].sourceSpan);
|
||||||
const parseVisitor = new TemplateParseVisitor(
|
const parseVisitor = new TemplateParseVisitor(
|
||||||
@ -181,7 +181,6 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
|||||||
|
|
||||||
const tempMeta = providerViewContext.component.template;
|
const tempMeta = providerViewContext.component.template;
|
||||||
|
|
||||||
// TODO
|
|
||||||
if (isPresent(tempMeta) && isPresent(tempMeta.interpolation)) {
|
if (isPresent(tempMeta) && isPresent(tempMeta.interpolation)) {
|
||||||
this._interpolationConfig = {
|
this._interpolationConfig = {
|
||||||
start: tempMeta.interpolation[0],
|
start: tempMeta.interpolation[0],
|
||||||
@ -1015,18 +1014,3 @@ export class PipeCollector extends RecursiveAstVisitor {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeDuplicates(items: CompileMetadataWithType[]): CompileMetadataWithType[] {
|
|
||||||
let res: CompileMetadataWithType[] = [];
|
|
||||||
items.forEach(item => {
|
|
||||||
let hasMatch =
|
|
||||||
res.filter(
|
|
||||||
r => r.type.name == item.type.name && r.type.moduleUrl == item.type.moduleUrl &&
|
|
||||||
r.type.runtime == item.type.runtime)
|
|
||||||
.length > 0;
|
|
||||||
if (!hasMatch) {
|
|
||||||
res.push(item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
@ -18,7 +18,7 @@ import {ProviderAst, ProviderAstType, ReferenceAst, TemplateAst} from '../templa
|
|||||||
import {CompileView} from './compile_view';
|
import {CompileView} from './compile_view';
|
||||||
import {InjectMethodVars} from './constants';
|
import {InjectMethodVars} from './constants';
|
||||||
|
|
||||||
import {CompileTokenMap, CompileDirectiveMetadata, CompileTokenMetadata, CompileQueryMetadata, CompileProviderMetadata, CompileDiDependencyMetadata, CompileIdentifierMetadata,} from '../compile_metadata';
|
import {CompileIdentifierMap, CompileDirectiveMetadata, CompileTokenMetadata, CompileQueryMetadata, CompileProviderMetadata, CompileDiDependencyMetadata, CompileIdentifierMetadata,} from '../compile_metadata';
|
||||||
import {getPropertyInView, injectFromViewParentInjector} from './util';
|
import {getPropertyInView, injectFromViewParentInjector} from './util';
|
||||||
import {CompileQuery, createQueryList, addQueryToTokenMap} from './compile_query';
|
import {CompileQuery, createQueryList, addQueryToTokenMap} from './compile_query';
|
||||||
import {CompileMethod} from './compile_method';
|
import {CompileMethod} from './compile_method';
|
||||||
@ -43,11 +43,11 @@ export class CompileElement extends CompileNode {
|
|||||||
public appElement: o.ReadPropExpr;
|
public appElement: o.ReadPropExpr;
|
||||||
public elementRef: o.Expression;
|
public elementRef: o.Expression;
|
||||||
public injector: o.Expression;
|
public injector: o.Expression;
|
||||||
private _instances = new CompileTokenMap<o.Expression>();
|
private _instances = new CompileIdentifierMap<CompileTokenMetadata, o.Expression>();
|
||||||
private _resolvedProviders: CompileTokenMap<ProviderAst>;
|
private _resolvedProviders: CompileIdentifierMap<CompileTokenMetadata, ProviderAst>;
|
||||||
|
|
||||||
private _queryCount = 0;
|
private _queryCount = 0;
|
||||||
private _queries = new CompileTokenMap<CompileQuery[]>();
|
private _queries = new CompileIdentifierMap<CompileTokenMetadata, CompileQuery[]>();
|
||||||
private _componentConstructorViewQueryLists: o.Expression[] = [];
|
private _componentConstructorViewQueryLists: o.Expression[] = [];
|
||||||
|
|
||||||
public contentNodesByNgContentIndex: Array<o.Expression>[] = null;
|
public contentNodesByNgContentIndex: Array<o.Expression>[] = null;
|
||||||
@ -144,7 +144,7 @@ export class CompileElement extends CompileNode {
|
|||||||
identifierToken(Identifiers.ViewContainerRef), this.appElement.prop('vcRef'));
|
identifierToken(Identifiers.ViewContainerRef), this.appElement.prop('vcRef'));
|
||||||
}
|
}
|
||||||
|
|
||||||
this._resolvedProviders = new CompileTokenMap<ProviderAst>();
|
this._resolvedProviders = new CompileIdentifierMap<CompileTokenMetadata, ProviderAst>();
|
||||||
this._resolvedProvidersArray.forEach(
|
this._resolvedProvidersArray.forEach(
|
||||||
provider => this._resolvedProviders.add(provider.token, provider));
|
provider => this._resolvedProviders.add(provider.token, provider));
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {CompileQueryMetadata, CompileTokenMap} from '../compile_metadata';
|
import {CompileIdentifierMap, CompileQueryMetadata, CompileTokenMetadata} from '../compile_metadata';
|
||||||
import {ListWrapper} from '../facade/collection';
|
import {ListWrapper} from '../facade/collection';
|
||||||
import {isBlank, isPresent} from '../facade/lang';
|
import {isBlank, isPresent} from '../facade/lang';
|
||||||
import {Identifiers} from '../identifiers';
|
import {Identifiers} from '../identifiers';
|
||||||
@ -125,7 +125,8 @@ export function createQueryList(
|
|||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function addQueryToTokenMap(map: CompileTokenMap<CompileQuery[]>, query: CompileQuery) {
|
export function addQueryToTokenMap(
|
||||||
|
map: CompileIdentifierMap<CompileTokenMetadata, CompileQuery[]>, query: CompileQuery) {
|
||||||
query.meta.selectors.forEach((selector) => {
|
query.meta.selectors.forEach((selector) => {
|
||||||
var entry = map.get(selector);
|
var entry = map.get(selector);
|
||||||
if (isBlank(entry)) {
|
if (isBlank(entry)) {
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
import {ViewType} from '../../core_private';
|
import {ViewType} from '../../core_private';
|
||||||
import {CompiledAnimation} from '../animation/animation_compiler';
|
import {CompiledAnimation} from '../animation/animation_compiler';
|
||||||
import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompilePipeMetadata, CompileTokenMap} from '../compile_metadata';
|
import {CompileDirectiveMetadata, CompileIdentifierMap, CompileIdentifierMetadata, CompilePipeMetadata, CompileTokenMetadata} from '../compile_metadata';
|
||||||
import {CompilerConfig} from '../config';
|
import {CompilerConfig} from '../config';
|
||||||
import {ListWrapper} from '../facade/collection';
|
import {ListWrapper} from '../facade/collection';
|
||||||
import {isBlank, isPresent} from '../facade/lang';
|
import {isBlank, isPresent} from '../facade/lang';
|
||||||
@ -27,7 +27,7 @@ import {createPureProxy, getPropertyInView, getViewFactoryName, injectFromViewPa
|
|||||||
|
|
||||||
export class CompileView implements NameResolver {
|
export class CompileView implements NameResolver {
|
||||||
public viewType: ViewType;
|
public viewType: ViewType;
|
||||||
public viewQueries: CompileTokenMap<CompileQuery[]>;
|
public viewQueries: CompileIdentifierMap<CompileTokenMetadata, CompileQuery[]>;
|
||||||
|
|
||||||
public nodes: CompileNode[] = [];
|
public nodes: CompileNode[] = [];
|
||||||
// root nodes or AppElements for ViewContainers
|
// root nodes or AppElements for ViewContainers
|
||||||
@ -98,7 +98,7 @@ export class CompileView implements NameResolver {
|
|||||||
this.componentContext =
|
this.componentContext =
|
||||||
getPropertyInView(o.THIS_EXPR.prop('context'), this, this.componentView);
|
getPropertyInView(o.THIS_EXPR.prop('context'), this, this.componentView);
|
||||||
|
|
||||||
var viewQueries = new CompileTokenMap<CompileQuery[]>();
|
var viewQueries = new CompileIdentifierMap<CompileTokenMetadata, CompileQuery[]>();
|
||||||
if (this.viewType === ViewType.COMPONENT) {
|
if (this.viewType === ViewType.COMPONENT) {
|
||||||
var directiveInstance = o.THIS_EXPR.prop('context');
|
var directiveInstance = o.THIS_EXPR.prop('context');
|
||||||
ListWrapper.forEachWithIndex(this.component.viewQueries, (queryMeta, queryIndex) => {
|
ListWrapper.forEachWithIndex(this.component.viewQueries, (queryMeta, queryIndex) => {
|
||||||
|
@ -22,7 +22,7 @@ function _isComponentMetadata(obj: any): obj is ComponentMetadata {
|
|||||||
export class ViewResolver {
|
export class ViewResolver {
|
||||||
constructor(private _reflector: ReflectorReader = reflector) {}
|
constructor(private _reflector: ReflectorReader = reflector) {}
|
||||||
|
|
||||||
resolve(component: Type): ViewMetadata {
|
resolve(component: Type, throwIfNotFound = true): ViewMetadata {
|
||||||
const compMeta: ComponentMetadata =
|
const compMeta: ComponentMetadata =
|
||||||
this._reflector.annotations(component).find(_isComponentMetadata);
|
this._reflector.annotations(component).find(_isComponentMetadata);
|
||||||
|
|
||||||
@ -45,8 +45,11 @@ export class ViewResolver {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (throwIfNotFound) {
|
||||||
throw new BaseException(
|
throw new BaseException(
|
||||||
`Could not compile '${stringify(component)}' because it is not a component.`);
|
`Could not compile '${stringify(component)}' because it is not a component.`);
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,256 +0,0 @@
|
|||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright Google Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by an MIT-style license that can be
|
|
||||||
* found in the LICENSE file at https://angular.io/license
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {beforeEach, ddescribe, describe, expect, iit, inject, it, xit,} from '@angular/core/testing/testing_internal';
|
|
||||||
|
|
||||||
import {CompileDirectiveMetadata, CompileTypeMetadata, CompileTemplateMetadata, CompileProviderMetadata, CompileDiDependencyMetadata, CompileQueryMetadata, CompileIdentifierMetadata, CompileFactoryMetadata, CompileTokenMetadata, CompileAnimationEntryMetadata, CompileAnimationStyleMetadata, CompileAnimationAnimateMetadata, CompileAnimationSequenceMetadata, CompileAnimationStateTransitionMetadata, CompileAnimationKeyframesSequenceMetadata, CompileAnimationGroupMetadata} from '@angular/compiler/src/compile_metadata';
|
|
||||||
import {ViewEncapsulation} from '@angular/core/src/metadata/view';
|
|
||||||
import {ChangeDetectionStrategy} from '@angular/core/src/change_detection';
|
|
||||||
import {LifecycleHooks} from '@angular/core/src/metadata/lifecycle_hooks';
|
|
||||||
|
|
||||||
export function main() {
|
|
||||||
describe('CompileMetadata', () => {
|
|
||||||
var fullTypeMeta: CompileTypeMetadata;
|
|
||||||
var fullTemplateMeta: CompileTemplateMetadata;
|
|
||||||
var fullDirectiveMeta: CompileDirectiveMetadata;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
var diDep = new CompileDiDependencyMetadata({
|
|
||||||
isAttribute: true,
|
|
||||||
isSelf: true,
|
|
||||||
isHost: true,
|
|
||||||
isSkipSelf: true,
|
|
||||||
isOptional: true,
|
|
||||||
token: new CompileTokenMetadata({value: 'someToken'}),
|
|
||||||
query: new CompileQueryMetadata({
|
|
||||||
selectors: [new CompileTokenMetadata({value: 'one'})],
|
|
||||||
descendants: true,
|
|
||||||
first: true,
|
|
||||||
propertyName: 'one'
|
|
||||||
}),
|
|
||||||
viewQuery: new CompileQueryMetadata({
|
|
||||||
selectors: [new CompileTokenMetadata({value: 'one'})],
|
|
||||||
descendants: true,
|
|
||||||
first: true,
|
|
||||||
propertyName: 'one'
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
fullTypeMeta = new CompileTypeMetadata(
|
|
||||||
{name: 'SomeType', moduleUrl: 'someUrl', isHost: true, diDeps: [diDep]});
|
|
||||||
fullTemplateMeta = new CompileTemplateMetadata({
|
|
||||||
encapsulation: ViewEncapsulation.Emulated,
|
|
||||||
template: '<a></a>',
|
|
||||||
templateUrl: 'someTemplateUrl',
|
|
||||||
styles: ['someStyle'],
|
|
||||||
styleUrls: ['someStyleUrl'],
|
|
||||||
animations: [new CompileAnimationEntryMetadata(
|
|
||||||
'animation',
|
|
||||||
[new CompileAnimationStateTransitionMetadata(
|
|
||||||
'* => *', new CompileAnimationSequenceMetadata([
|
|
||||||
new CompileAnimationStyleMetadata(0, [{'opacity': 0}]),
|
|
||||||
new CompileAnimationAnimateMetadata(
|
|
||||||
1000, new CompileAnimationStyleMetadata(0, [{'opacity': 1}]))
|
|
||||||
]))])],
|
|
||||||
ngContentSelectors: ['*'],
|
|
||||||
interpolation: ['{{', '}}']
|
|
||||||
});
|
|
||||||
fullDirectiveMeta = CompileDirectiveMetadata.create({
|
|
||||||
selector: 'someSelector',
|
|
||||||
isComponent: true,
|
|
||||||
type: fullTypeMeta,
|
|
||||||
template: fullTemplateMeta,
|
|
||||||
changeDetection: ChangeDetectionStrategy.Default,
|
|
||||||
inputs: ['someProp'],
|
|
||||||
outputs: ['someEvent'],
|
|
||||||
host: {'(event1)': 'handler1', '[prop1]': 'expr1', 'attr1': 'attrValue2'},
|
|
||||||
lifecycleHooks: [LifecycleHooks.OnChanges],
|
|
||||||
providers: [new CompileProviderMetadata({
|
|
||||||
token: new CompileTokenMetadata({value: 'token'}),
|
|
||||||
multi: true,
|
|
||||||
useClass: fullTypeMeta,
|
|
||||||
useExisting: new CompileTokenMetadata({
|
|
||||||
identifier: new CompileIdentifierMetadata({name: 'someName'}),
|
|
||||||
identifierIsInstance: true
|
|
||||||
}),
|
|
||||||
useFactory: new CompileFactoryMetadata({name: 'someName', diDeps: [diDep]}),
|
|
||||||
useValue: 'someValue',
|
|
||||||
})],
|
|
||||||
viewProviders: [new CompileProviderMetadata({
|
|
||||||
token: new CompileTokenMetadata({value: 'token'}),
|
|
||||||
useClass: fullTypeMeta,
|
|
||||||
useExisting: new CompileTokenMetadata(
|
|
||||||
{identifier: new CompileIdentifierMetadata({name: 'someName'})}),
|
|
||||||
useFactory: new CompileFactoryMetadata({name: 'someName', diDeps: [diDep]}),
|
|
||||||
useValue: 'someValue'
|
|
||||||
})],
|
|
||||||
queries: [new CompileQueryMetadata({
|
|
||||||
selectors: [new CompileTokenMetadata({value: 'selector'})],
|
|
||||||
descendants: true,
|
|
||||||
first: false,
|
|
||||||
propertyName: 'prop',
|
|
||||||
read: new CompileTokenMetadata({value: 'readToken'})
|
|
||||||
})],
|
|
||||||
viewQueries: [new CompileQueryMetadata({
|
|
||||||
selectors: [new CompileTokenMetadata({value: 'selector'})],
|
|
||||||
descendants: true,
|
|
||||||
first: false,
|
|
||||||
propertyName: 'prop',
|
|
||||||
read: new CompileTokenMetadata({value: 'readToken'})
|
|
||||||
})]
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('CompileIdentifierMetadata', () => {
|
|
||||||
it('should serialize with full data', () => {
|
|
||||||
let full = new CompileIdentifierMetadata(
|
|
||||||
{name: 'name', moduleUrl: 'module', value: ['one', ['two']]});
|
|
||||||
expect(CompileIdentifierMetadata.fromJson(full.toJson())).toEqual(full);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should serialize with no data', () => {
|
|
||||||
let empty = new CompileIdentifierMetadata();
|
|
||||||
expect(CompileIdentifierMetadata.fromJson(empty.toJson())).toEqual(empty);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('DirectiveMetadata', () => {
|
|
||||||
it('should serialize with full data', () => {
|
|
||||||
expect(CompileDirectiveMetadata.fromJson(fullDirectiveMeta.toJson()))
|
|
||||||
.toEqual(fullDirectiveMeta);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should serialize with no data', () => {
|
|
||||||
var empty = CompileDirectiveMetadata.create();
|
|
||||||
expect(CompileDirectiveMetadata.fromJson(empty.toJson())).toEqual(empty);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('TypeMetadata', () => {
|
|
||||||
it('should serialize with full data', () => {
|
|
||||||
expect(CompileTypeMetadata.fromJson(fullTypeMeta.toJson())).toEqual(fullTypeMeta);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should serialize with no data', () => {
|
|
||||||
var empty = new CompileTypeMetadata();
|
|
||||||
expect(CompileTypeMetadata.fromJson(empty.toJson())).toEqual(empty);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('TemplateMetadata', () => {
|
|
||||||
|
|
||||||
it('should serialize with full data', () => {
|
|
||||||
expect(CompileTemplateMetadata.fromJson(fullTemplateMeta.toJson()))
|
|
||||||
.toEqual(fullTemplateMeta);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should serialize with no data', () => {
|
|
||||||
var empty = new CompileTemplateMetadata();
|
|
||||||
expect(CompileTemplateMetadata.fromJson(empty.toJson())).toEqual(empty);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw an error with invalid interpolation symbols', () => {
|
|
||||||
expect(() => new CompileTemplateMetadata(<any>{interpolation: ['{{']}))
|
|
||||||
.toThrowError(`'interpolation' should have a start and an end symbol.`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('CompileAnimationStyleMetadata', () => {
|
|
||||||
it('should serialize with full data', () => {
|
|
||||||
let full = new CompileAnimationStyleMetadata(0, [{'opacity': 0, 'color': 'red'}]);
|
|
||||||
expect(CompileAnimationStyleMetadata.fromJson(full.toJson())).toEqual(full);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should serialize with no data', () => {
|
|
||||||
let empty = new CompileAnimationStyleMetadata(0, []);
|
|
||||||
expect(CompileAnimationStyleMetadata.fromJson(empty.toJson())).toEqual(empty);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('CompileAnimationAnimateMetadata', () => {
|
|
||||||
it('should serialize with full data', () => {
|
|
||||||
let full = new CompileAnimationAnimateMetadata(
|
|
||||||
'1s linear', new CompileAnimationStyleMetadata(0, [{'opacity': 0.5, 'color': 'blue'}]));
|
|
||||||
expect(CompileAnimationAnimateMetadata.fromJson(full.toJson())).toEqual(full);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should serialize with no data', () => {
|
|
||||||
let empty = new CompileAnimationAnimateMetadata();
|
|
||||||
expect(CompileAnimationAnimateMetadata.fromJson(empty.toJson())).toEqual(empty);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('CompileAnimationSequenceMetadata', () => {
|
|
||||||
it('should serialize with full data', () => {
|
|
||||||
let full = new CompileAnimationSequenceMetadata([
|
|
||||||
new CompileAnimationStyleMetadata(0, [{'opacity': 0.5, 'width': 100}]),
|
|
||||||
new CompileAnimationAnimateMetadata(
|
|
||||||
1000, new CompileAnimationStyleMetadata(0, [{'opacity': 1, 'width': 0}]))
|
|
||||||
]);
|
|
||||||
expect(CompileAnimationSequenceMetadata.fromJson(full.toJson())).toEqual(full);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should serialize with no data', () => {
|
|
||||||
let empty = new CompileAnimationSequenceMetadata();
|
|
||||||
expect(CompileAnimationSequenceMetadata.fromJson(empty.toJson())).toEqual(empty);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('CompileAnimationGroupMetadata', () => {
|
|
||||||
it('should serialize with full data', () => {
|
|
||||||
let full = new CompileAnimationGroupMetadata([
|
|
||||||
new CompileAnimationStyleMetadata(0, [{'width': 100, 'border': '1px solid red'}]),
|
|
||||||
new CompileAnimationAnimateMetadata(
|
|
||||||
1000, new CompileAnimationStyleMetadata(
|
|
||||||
0, [{'width': 900, 'border': '10px solid blue'}]))
|
|
||||||
]);
|
|
||||||
expect(CompileAnimationGroupMetadata.fromJson(full.toJson())).toEqual(full);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should serialize with no data', () => {
|
|
||||||
let empty = new CompileAnimationGroupMetadata();
|
|
||||||
expect(CompileAnimationGroupMetadata.fromJson(empty.toJson())).toEqual(empty);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('CompileAnimationKeyframesSequenceMetadata', () => {
|
|
||||||
it('should serialize with full data', () => {
|
|
||||||
let full = new CompileAnimationKeyframesSequenceMetadata([
|
|
||||||
new CompileAnimationStyleMetadata(0, [{'width': 0}]),
|
|
||||||
new CompileAnimationStyleMetadata(0.5, [{'width': 100}]),
|
|
||||||
new CompileAnimationStyleMetadata(1, [{'width': 200}]),
|
|
||||||
]);
|
|
||||||
expect(CompileAnimationKeyframesSequenceMetadata.fromJson(full.toJson())).toEqual(full);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should serialize with no data', () => {
|
|
||||||
let empty = new CompileAnimationKeyframesSequenceMetadata();
|
|
||||||
expect(CompileAnimationKeyframesSequenceMetadata.fromJson(empty.toJson())).toEqual(empty);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('CompileAnimationEntryMetadata', () => {
|
|
||||||
it('should serialize with full data', () => {
|
|
||||||
let full = new CompileAnimationEntryMetadata(
|
|
||||||
'name', [new CompileAnimationStateTransitionMetadata(
|
|
||||||
'key => value', new CompileAnimationSequenceMetadata([
|
|
||||||
new CompileAnimationStyleMetadata(0, [{'color': 'red'}]),
|
|
||||||
new CompileAnimationAnimateMetadata(
|
|
||||||
1000, new CompileAnimationStyleMetadata(0, [{'color': 'blue'}]))
|
|
||||||
]))]);
|
|
||||||
expect(CompileAnimationEntryMetadata.fromJson(full.toJson())).toEqual(full);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should serialize with no data', () => {
|
|
||||||
let empty = new CompileAnimationEntryMetadata();
|
|
||||||
expect(CompileAnimationEntryMetadata.fromJson(empty.toJson())).toEqual(empty);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
@ -12,6 +12,7 @@ import {LIFECYCLE_HOOKS_VALUES} from '@angular/core/src/metadata/lifecycle_hooks
|
|||||||
import {configureCompiler} from '@angular/core/testing';
|
import {configureCompiler} from '@angular/core/testing';
|
||||||
import {afterEach, beforeEach, beforeEachProviders, ddescribe, describe, expect, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal';
|
import {afterEach, beforeEach, beforeEachProviders, ddescribe, describe, expect, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal';
|
||||||
|
|
||||||
|
import {CompileNgModuleMetadata} from '../src/compile_metadata';
|
||||||
import {IS_DART, stringify} from '../src/facade/lang';
|
import {IS_DART, stringify} from '../src/facade/lang';
|
||||||
import {CompileMetadataResolver} from '../src/metadata_resolver';
|
import {CompileMetadataResolver} from '../src/metadata_resolver';
|
||||||
|
|
||||||
@ -22,7 +23,7 @@ export function main() {
|
|||||||
describe('CompileMetadataResolver', () => {
|
describe('CompileMetadataResolver', () => {
|
||||||
beforeEach(() => { configureCompiler({providers: TEST_COMPILER_PROVIDERS}); });
|
beforeEach(() => { configureCompiler({providers: TEST_COMPILER_PROVIDERS}); });
|
||||||
|
|
||||||
describe('getMetadata', () => {
|
describe('getDirectiveMetadata', () => {
|
||||||
it('should read metadata',
|
it('should read metadata',
|
||||||
inject([CompileMetadataResolver], (resolver: CompileMetadataResolver) => {
|
inject([CompileMetadataResolver], (resolver: CompileMetadataResolver) => {
|
||||||
var meta = resolver.getDirectiveMetadata(ComponentWithEverything);
|
var meta = resolver.getDirectiveMetadata(ComponentWithEverything);
|
||||||
@ -102,35 +103,6 @@ export function main() {
|
|||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getViewDirectivesMetadata', () => {
|
|
||||||
|
|
||||||
it('should return the directive metadatas',
|
|
||||||
inject([CompileMetadataResolver], (resolver: CompileMetadataResolver) => {
|
|
||||||
expect(resolver.getViewDirectivesMetadata(ComponentWithEverything))
|
|
||||||
.toContain(resolver.getDirectiveMetadata(SomeDirective));
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('platform directives', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
configureCompiler({
|
|
||||||
providers: [{
|
|
||||||
provide: CompilerConfig,
|
|
||||||
useValue: new CompilerConfig(
|
|
||||||
{genDebugInfo: true, deprecatedPlatformDirectives: [ADirective]})
|
|
||||||
}]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should include platform directives when available',
|
|
||||||
inject([CompileMetadataResolver], (resolver: CompileMetadataResolver) => {
|
|
||||||
expect(resolver.getViewDirectivesMetadata(ComponentWithEverything))
|
|
||||||
.toContain(resolver.getDirectiveMetadata(ADirective));
|
|
||||||
expect(resolver.getViewDirectivesMetadata(ComponentWithEverything))
|
|
||||||
.toContain(resolver.getDirectiveMetadata(SomeDirective));
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright Google Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by an MIT-style license that can be
|
||||||
|
* found in the LICENSE file at https://angular.io/license
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {beforeEach, ddescribe, describe, expect, iit, it, inject,} from '@angular/core/testing/testing_internal';
|
||||||
|
|
||||||
|
import {stringify, isBlank} from '../src/facade/lang';
|
||||||
|
import {MockNgModuleResolver} from '../testing';
|
||||||
|
import {NgModule, NgModuleMetadata, Injector} from '@angular/core';
|
||||||
|
|
||||||
|
export function main() {
|
||||||
|
describe('MockNgModuleResolver', () => {
|
||||||
|
var ngModuleResolver: MockNgModuleResolver;
|
||||||
|
|
||||||
|
beforeEach(inject([Injector], (injector: Injector) => {
|
||||||
|
ngModuleResolver = new MockNgModuleResolver(injector);
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('NgModule overriding', () => {
|
||||||
|
it('should fallback to the default NgModuleResolver when templates are not overridden',
|
||||||
|
() => {
|
||||||
|
var ngModule = ngModuleResolver.resolve(SomeNgModule);
|
||||||
|
expect(ngModule.declarations).toEqual([SomeDirective]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow overriding the @NgModule', () => {
|
||||||
|
ngModuleResolver.setNgModule(
|
||||||
|
SomeNgModule, new NgModuleMetadata({declarations: [SomeOtherDirective]}));
|
||||||
|
var ngModule = ngModuleResolver.resolve(SomeNgModule);
|
||||||
|
expect(ngModule.declarations).toEqual([SomeOtherDirective]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class SomeDirective {}
|
||||||
|
|
||||||
|
class SomeOtherDirective {}
|
||||||
|
|
||||||
|
@NgModule({declarations: [SomeDirective]})
|
||||||
|
class SomeNgModule {
|
||||||
|
}
|
53
modules/@angular/compiler/test/ng_module_resolver_spec.ts
Normal file
53
modules/@angular/compiler/test/ng_module_resolver_spec.ts
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright Google Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by an MIT-style license that can be
|
||||||
|
* found in the LICENSE file at https://angular.io/license
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {NgModuleResolver} from '@angular/compiler/src/ng_module_resolver';
|
||||||
|
import {NgModule, NgModuleMetadata} from '@angular/core/src/metadata';
|
||||||
|
import {stringify} from '../src/facade/lang';
|
||||||
|
|
||||||
|
class SomeClass1 {}
|
||||||
|
class SomeClass2 {}
|
||||||
|
class SomeClass3 {}
|
||||||
|
class SomeClass4 {}
|
||||||
|
class SomeClass5 {}
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [SomeClass1],
|
||||||
|
imports: [SomeClass2],
|
||||||
|
exports: [SomeClass3],
|
||||||
|
providers: [SomeClass4],
|
||||||
|
precompile: [SomeClass5]
|
||||||
|
})
|
||||||
|
class SomeModule {
|
||||||
|
}
|
||||||
|
|
||||||
|
class SimpleClass {}
|
||||||
|
|
||||||
|
export function main() {
|
||||||
|
describe('NgModuleResolver', () => {
|
||||||
|
var resolver: NgModuleResolver;
|
||||||
|
|
||||||
|
beforeEach(() => { resolver = new NgModuleResolver(); });
|
||||||
|
|
||||||
|
it('should read out the metadata from the class', () => {
|
||||||
|
var viewMetadata = resolver.resolve(SomeModule);
|
||||||
|
expect(viewMetadata).toEqual(new NgModuleMetadata({
|
||||||
|
declarations: [SomeClass1],
|
||||||
|
imports: [SomeClass2],
|
||||||
|
exports: [SomeClass3],
|
||||||
|
providers: [SomeClass4],
|
||||||
|
precompile: [SomeClass5]
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw when simple class has no component decorator', () => {
|
||||||
|
expect(() => resolver.resolve(SimpleClass))
|
||||||
|
.toThrowError(`No NgModule metadata found for '${stringify(SimpleClass)}'.`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
import {beforeEach, ddescribe, xdescribe, describe, iit, inject, beforeEachProviders, it, xit,} from '@angular/core/testing/testing_internal';
|
import {beforeEach, ddescribe, xdescribe, describe, iit, inject, beforeEachProviders, it, xit,} from '@angular/core/testing/testing_internal';
|
||||||
import {expect} from '@angular/platform-browser/testing/matchers';
|
import {expect} from '@angular/platform-browser/testing/matchers';
|
||||||
import {Injectable, Component, Input, ViewMetadata, Compiler, ComponentFactory, Injector, AppModule, AppModuleMetadata, AppModuleFactory} from '@angular/core';
|
import {Injectable, Component, Input, ViewMetadata, Compiler, ComponentFactory, Injector, NgModule, NgModuleFactory} from '@angular/core';
|
||||||
import {ConcreteType, stringify} from '../src/facade/lang';
|
import {ConcreteType, stringify} from '../src/facade/lang';
|
||||||
import {fakeAsync, tick, TestComponentBuilder, ComponentFixture, configureCompiler} from '@angular/core/testing';
|
import {fakeAsync, tick, TestComponentBuilder, ComponentFixture, configureCompiler} from '@angular/core/testing';
|
||||||
import {XHR, ViewResolver} from '@angular/compiler';
|
import {XHR, ViewResolver} from '@angular/compiler';
|
||||||
@ -28,10 +28,6 @@ class SomeComp {
|
|||||||
class SomeCompWithUrlTemplate {
|
class SomeCompWithUrlTemplate {
|
||||||
}
|
}
|
||||||
|
|
||||||
@AppModule({})
|
|
||||||
class SomeModule {
|
|
||||||
}
|
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe('RuntimeCompiler', () => {
|
describe('RuntimeCompiler', () => {
|
||||||
let compiler: Compiler;
|
let compiler: Compiler;
|
||||||
@ -118,49 +114,61 @@ export function main() {
|
|||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('compileAppModuleAsync', () => {
|
describe('compileModuleAsync', () => {
|
||||||
it('should allow to use templateUrl components', fakeAsync(() => {
|
it('should allow to use templateUrl components', fakeAsync(() => {
|
||||||
|
@NgModule(
|
||||||
|
{declarations: [SomeCompWithUrlTemplate], precompile: [SomeCompWithUrlTemplate]})
|
||||||
|
class SomeModule {
|
||||||
|
}
|
||||||
|
|
||||||
xhr.spy('get').andCallFake(() => Promise.resolve('hello'));
|
xhr.spy('get').andCallFake(() => Promise.resolve('hello'));
|
||||||
let appModuleFactory: AppModuleFactory<any>;
|
let ngModuleFactory: NgModuleFactory<any>;
|
||||||
compiler
|
compiler.compileModuleAsync(SomeModule).then((f) => ngModuleFactory = f);
|
||||||
.compileAppModuleAsync(
|
|
||||||
SomeModule, new AppModuleMetadata({precompile: [SomeCompWithUrlTemplate]}))
|
|
||||||
.then((f) => appModuleFactory = f);
|
|
||||||
tick();
|
tick();
|
||||||
expect(appModuleFactory.moduleType).toBe(SomeModule);
|
expect(ngModuleFactory.moduleType).toBe(SomeModule);
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('compileAppModuleSync', () => {
|
describe('compileModuleSync', () => {
|
||||||
it('should throw when using a templateUrl that has not been compiled before', () => {
|
it('should throw when using a templateUrl that has not been compiled before', () => {
|
||||||
|
@NgModule({declarations: [SomeCompWithUrlTemplate], precompile: [SomeCompWithUrlTemplate]})
|
||||||
|
class SomeModule {
|
||||||
|
}
|
||||||
|
|
||||||
xhr.spy('get').andCallFake(() => Promise.resolve(''));
|
xhr.spy('get').andCallFake(() => Promise.resolve(''));
|
||||||
expect(
|
expect(() => compiler.compileModuleSync(SomeModule))
|
||||||
() => compiler.compileAppModuleSync(
|
|
||||||
SomeModule, new AppModuleMetadata({precompile: [SomeCompWithUrlTemplate]})))
|
|
||||||
.toThrowError(
|
.toThrowError(
|
||||||
`Can't compile synchronously as ${stringify(SomeCompWithUrlTemplate)} is still being loaded!`);
|
`Can't compile synchronously as ${stringify(SomeCompWithUrlTemplate)} is still being loaded!`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw when using a templateUrl in a nested component that has not been compiled before',
|
it('should throw when using a templateUrl in a nested component that has not been compiled before',
|
||||||
() => {
|
() => {
|
||||||
|
@NgModule({declarations: [SomeComp], precompile: [SomeComp]})
|
||||||
|
class SomeModule {
|
||||||
|
}
|
||||||
|
|
||||||
xhr.spy('get').andCallFake(() => Promise.resolve(''));
|
xhr.spy('get').andCallFake(() => Promise.resolve(''));
|
||||||
viewResolver.setView(
|
viewResolver.setView(
|
||||||
SomeComp, new ViewMetadata({template: '', directives: [ChildComp]}));
|
SomeComp, new ViewMetadata({template: '', directives: [ChildComp]}));
|
||||||
viewResolver.setView(ChildComp, new ViewMetadata({templateUrl: '/someTpl.html'}));
|
viewResolver.setView(ChildComp, new ViewMetadata({templateUrl: '/someTpl.html'}));
|
||||||
expect(
|
expect(() => compiler.compileModuleSync(SomeModule))
|
||||||
() => compiler.compileAppModuleSync(
|
|
||||||
SomeModule, new AppModuleMetadata({precompile: [SomeComp]})))
|
|
||||||
.toThrowError(
|
.toThrowError(
|
||||||
`Can't compile synchronously as ${stringify(ChildComp)} is still being loaded!`);
|
`Can't compile synchronously as ${stringify(ChildComp)} is still being loaded!`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow to use templateUrl components that have been loaded before',
|
it('should allow to use templateUrl components that have been loaded before',
|
||||||
fakeAsync(() => {
|
fakeAsync(() => {
|
||||||
|
@NgModule(
|
||||||
|
{declarations: [SomeCompWithUrlTemplate], precompile: [SomeCompWithUrlTemplate]})
|
||||||
|
class SomeModule {
|
||||||
|
}
|
||||||
|
|
||||||
xhr.spy('get').andCallFake(() => Promise.resolve('hello'));
|
xhr.spy('get').andCallFake(() => Promise.resolve('hello'));
|
||||||
tcb.createFakeAsync(SomeCompWithUrlTemplate);
|
compiler.compileModuleAsync(SomeModule);
|
||||||
let appModuleFactory = compiler.compileAppModuleSync(
|
tick();
|
||||||
SomeModule, new AppModuleMetadata({precompile: [SomeCompWithUrlTemplate]}));
|
|
||||||
expect(appModuleFactory).toBeTruthy();
|
let ngModuleFactory = compiler.compileModuleSync(SomeModule);
|
||||||
|
expect(ngModuleFactory).toBeTruthy();
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
import {AsyncTestCompleter, beforeEach, ddescribe, xdescribe, describe, iit, inject, beforeEachProviders, it, xit,} from '@angular/core/testing/testing_internal';
|
import {AsyncTestCompleter, beforeEach, ddescribe, xdescribe, describe, iit, inject, beforeEachProviders, it, xit,} from '@angular/core/testing/testing_internal';
|
||||||
import {expect} from '@angular/platform-browser/testing/matchers';
|
import {expect} from '@angular/platform-browser/testing/matchers';
|
||||||
import {TestComponentBuilder, ComponentFixtureAutoDetect, ComponentFixtureNoNgZone, withProviders} from '@angular/core/testing';
|
import {TestComponentBuilder, ComponentFixtureAutoDetect, ComponentFixtureNoNgZone, withProviders} from '@angular/core/testing';
|
||||||
import {Injectable, Component, Input, ViewMetadata} from '@angular/core';
|
import {Injectable, Component, Input, ViewMetadata, Pipe, NgModule} from '@angular/core';
|
||||||
import {NgIf} from '@angular/common';
|
import {NgIf} from '@angular/common';
|
||||||
import {TimerWrapper} from '../src/facade/async';
|
import {TimerWrapper} from '../src/facade/async';
|
||||||
import {PromiseWrapper} from '../src/facade/promise';
|
import {PromiseWrapper} from '../src/facade/promise';
|
||||||
@ -327,6 +327,27 @@ export function main() {
|
|||||||
expect(componentFixture.nativeElement).toHaveText('Mock');
|
expect(componentFixture.nativeElement).toHaveText('Mock');
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
it('should create components synchronously with a custom module',
|
||||||
|
inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||||
|
@Pipe({name: 'somePipe'})
|
||||||
|
class SomePipe {
|
||||||
|
transform(value: any) { return `transformed ${value}`; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@NgModule({declarations: [SomePipe]})
|
||||||
|
class SomeModule {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({selector: 'comp', template: `{{'hello' | somePipe}}`})
|
||||||
|
class SomeComponent {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let componentFixture = tcb.createSync(SomeComponent, SomeModule);
|
||||||
|
componentFixture.detectChanges();
|
||||||
|
expect(componentFixture.nativeElement).toHaveText('transformed hello');
|
||||||
|
}));
|
||||||
|
|
||||||
describe('ComponentFixture', () => {
|
describe('ComponentFixture', () => {
|
||||||
it('should auto detect changes if autoDetectChanges is called',
|
it('should auto detect changes if autoDetectChanges is called',
|
||||||
inject(
|
inject(
|
||||||
|
@ -10,3 +10,29 @@ export * from './testing/schema_registry_mock';
|
|||||||
export * from './testing/view_resolver_mock';
|
export * from './testing/view_resolver_mock';
|
||||||
export * from './testing/test_component_builder';
|
export * from './testing/test_component_builder';
|
||||||
export * from './testing/directive_resolver_mock';
|
export * from './testing/directive_resolver_mock';
|
||||||
|
export * from './testing/ng_module_resolver_mock';
|
||||||
|
|
||||||
|
import {createPlatformFactory, CompilerOptions, PlatformRef} from '@angular/core';
|
||||||
|
import {coreDynamicPlatform, DirectiveResolver, ViewResolver, NgModuleResolver} from './index';
|
||||||
|
import {MockViewResolver} from './testing/view_resolver_mock';
|
||||||
|
import {MockDirectiveResolver} from './testing/directive_resolver_mock';
|
||||||
|
import {MockNgModuleResolver} from './testing/ng_module_resolver_mock';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Platform for dynamic tests
|
||||||
|
*
|
||||||
|
* @experimental
|
||||||
|
*/
|
||||||
|
export const coreDynamicTestingPlatform =
|
||||||
|
createPlatformFactory(coreDynamicPlatform, 'coreDynamicTesting', [{
|
||||||
|
provide: CompilerOptions,
|
||||||
|
useValue: {
|
||||||
|
providers: [
|
||||||
|
{provide: DirectiveResolver, useClass: MockDirectiveResolver},
|
||||||
|
{provide: ViewResolver, useClass: MockViewResolver},
|
||||||
|
{provide: NgModuleResolver, useClass: MockNgModuleResolver}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
multi: true
|
||||||
|
}]);
|
||||||
|
@ -27,8 +27,11 @@ export class MockDirectiveResolver extends DirectiveResolver {
|
|||||||
|
|
||||||
private get _compiler(): Compiler { return this._injector.get(Compiler); }
|
private get _compiler(): Compiler { return this._injector.get(Compiler); }
|
||||||
|
|
||||||
resolve(type: Type): DirectiveMetadata {
|
resolve(type: Type, throwIfNotFound = true): DirectiveMetadata {
|
||||||
var dm = super.resolve(type);
|
var dm = super.resolve(type, throwIfNotFound);
|
||||||
|
if (!dm) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
var providerOverrides = this._providerOverrides.get(type);
|
var providerOverrides = this._providerOverrides.get(type);
|
||||||
var viewProviderOverrides = this.viewProviderOverrides.get(type);
|
var viewProviderOverrides = this.viewProviderOverrides.get(type);
|
||||||
|
46
modules/@angular/compiler/testing/ng_module_resolver_mock.ts
Normal file
46
modules/@angular/compiler/testing/ng_module_resolver_mock.ts
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright Google Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by an MIT-style license that can be
|
||||||
|
* found in the LICENSE file at https://angular.io/license
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {Compiler, Injectable, Injector, NgModuleMetadata, Type} from '@angular/core';
|
||||||
|
|
||||||
|
import {NgModuleResolver} from '../index';
|
||||||
|
import {Map} from '../src/facade/collection';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class MockNgModuleResolver extends NgModuleResolver {
|
||||||
|
/** @internal */
|
||||||
|
_ngModules = new Map<Type, NgModuleMetadata>();
|
||||||
|
|
||||||
|
constructor(private _injector: Injector) { super(); }
|
||||||
|
|
||||||
|
private get _compiler(): Compiler { return this._injector.get(Compiler); }
|
||||||
|
|
||||||
|
private _clearCacheFor(component: Type) { this._compiler.clearCacheFor(component); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the {@link NgModuleMetadata} for a module.
|
||||||
|
*/
|
||||||
|
setNgModule(type: Type, metadata: NgModuleMetadata): void {
|
||||||
|
this._ngModules.set(type, metadata);
|
||||||
|
this._clearCacheFor(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link NgModuleMetadata} for a module:
|
||||||
|
* - Set the {@link NgModuleMetadata} to the overridden view when it exists or fallback to the
|
||||||
|
* default
|
||||||
|
* `NgModuleResolver`, see `setNgModule`.
|
||||||
|
*/
|
||||||
|
resolve(type: Type, throwIfNotFound = true): NgModuleMetadata {
|
||||||
|
var metadata = this._ngModules.get(type);
|
||||||
|
if (!metadata) {
|
||||||
|
metadata = super.resolve(type, throwIfNotFound);
|
||||||
|
}
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
}
|
@ -87,14 +87,16 @@ export class OverridingTestComponentBuilder extends TestComponentBuilder {
|
|||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
createAsync<T>(rootComponentType: ConcreteType<T>): Promise<ComponentFixture<T>> {
|
createAsync<T>(rootComponentType: ConcreteType<T>, ngModule: ConcreteType<any> = null):
|
||||||
|
Promise<ComponentFixture<T>> {
|
||||||
this._applyMetadataOverrides();
|
this._applyMetadataOverrides();
|
||||||
return super.createAsync(rootComponentType);
|
return super.createAsync(rootComponentType, ngModule);
|
||||||
}
|
}
|
||||||
|
|
||||||
createSync<T>(rootComponentType: ConcreteType<T>): ComponentFixture<T> {
|
createSync<T>(rootComponentType: ConcreteType<T>, ngModule: ConcreteType<any> = null):
|
||||||
|
ComponentFixture<T> {
|
||||||
this._applyMetadataOverrides();
|
this._applyMetadataOverrides();
|
||||||
return super.createSync(rootComponentType);
|
return super.createSync(rootComponentType, ngModule);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _applyMetadataOverrides() {
|
private _applyMetadataOverrides() {
|
||||||
|
@ -72,10 +72,13 @@ export class MockViewResolver extends ViewResolver {
|
|||||||
* - Override the directives, see `overrideViewDirective`.
|
* - Override the directives, see `overrideViewDirective`.
|
||||||
* - Override the @View definition, see `setInlineTemplate`.
|
* - Override the @View definition, see `setInlineTemplate`.
|
||||||
*/
|
*/
|
||||||
resolve(component: Type): ViewMetadata {
|
resolve(component: Type, throwIfNotFound = true): ViewMetadata {
|
||||||
var view = this._views.get(component);
|
var view = this._views.get(component);
|
||||||
if (isBlank(view)) {
|
if (isBlank(view)) {
|
||||||
view = super.resolve(component);
|
view = super.resolve(component, throwIfNotFound);
|
||||||
|
if (!view) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var directives: any[] /** TODO #9100 */ = [];
|
var directives: any[] /** TODO #9100 */ = [];
|
||||||
|
@ -23,8 +23,8 @@ export {DebugElement, DebugNode, asNativeElements, getDebugNode} from './src/deb
|
|||||||
export * from './src/testability/testability';
|
export * from './src/testability/testability';
|
||||||
export * from './src/change_detection';
|
export * from './src/change_detection';
|
||||||
export * from './src/platform_directives_and_pipes';
|
export * from './src/platform_directives_and_pipes';
|
||||||
export * from './src/platform_common_providers';
|
export * from './src/platform_core_providers';
|
||||||
export {APPLICATION_COMMON_PROVIDERS} from './src/application_common_providers';
|
export {APPLICATION_COMMON_PROVIDERS, ApplicationModule} from './src/application_module';
|
||||||
export {wtfCreateScope, wtfLeave, wtfStartTimeRange, wtfEndTimeRange, WtfScopeFn} from './src/profile/profile';
|
export {wtfCreateScope, wtfLeave, wtfStartTimeRange, wtfEndTimeRange, WtfScopeFn} from './src/profile/profile';
|
||||||
|
|
||||||
export {Type} from './src/facade/lang';
|
export {Type} from './src/facade/lang';
|
||||||
|
@ -20,11 +20,11 @@ import * as console from './src/console';
|
|||||||
import * as debug from './src/debug/debug_renderer';
|
import * as debug from './src/debug/debug_renderer';
|
||||||
import * as provider_util from './src/di/provider_util';
|
import * as provider_util from './src/di/provider_util';
|
||||||
import * as reflective_provider from './src/di/reflective_provider';
|
import * as reflective_provider from './src/di/reflective_provider';
|
||||||
import * as app_module_factory from './src/linker/app_module_factory';
|
|
||||||
import * as component_factory_resolver from './src/linker/component_factory_resolver';
|
import * as component_factory_resolver from './src/linker/component_factory_resolver';
|
||||||
import * as component_resolver from './src/linker/component_resolver';
|
import * as component_resolver from './src/linker/component_resolver';
|
||||||
import * as debug_context from './src/linker/debug_context';
|
import * as debug_context from './src/linker/debug_context';
|
||||||
import * as element from './src/linker/element';
|
import * as element from './src/linker/element';
|
||||||
|
import * as ng_module_factory from './src/linker/ng_module_factory';
|
||||||
import * as template_ref from './src/linker/template_ref';
|
import * as template_ref from './src/linker/template_ref';
|
||||||
import * as view from './src/linker/view';
|
import * as view from './src/linker/view';
|
||||||
import * as view_type from './src/linker/view_type';
|
import * as view_type from './src/linker/view_type';
|
||||||
@ -52,13 +52,12 @@ export declare namespace __core_private_types__ {
|
|||||||
export var LIFECYCLE_HOOKS_VALUES: typeof lifecycle_hooks.LIFECYCLE_HOOKS_VALUES;
|
export var LIFECYCLE_HOOKS_VALUES: typeof lifecycle_hooks.LIFECYCLE_HOOKS_VALUES;
|
||||||
export type ReflectorReader = reflector_reader.ReflectorReader;
|
export type ReflectorReader = reflector_reader.ReflectorReader;
|
||||||
export var ReflectorReader: typeof reflector_reader.ReflectorReader;
|
export var ReflectorReader: typeof reflector_reader.ReflectorReader;
|
||||||
export var ReflectorComponentResolver: typeof component_resolver.ReflectorComponentResolver;
|
|
||||||
export var CodegenComponentFactoryResolver:
|
export var CodegenComponentFactoryResolver:
|
||||||
typeof component_factory_resolver.CodegenComponentFactoryResolver;
|
typeof component_factory_resolver.CodegenComponentFactoryResolver;
|
||||||
export type AppElement = element.AppElement;
|
export type AppElement = element.AppElement;
|
||||||
export var AppElement: typeof element.AppElement;
|
export var AppElement: typeof element.AppElement;
|
||||||
export var AppView: typeof view.AppView;
|
export var AppView: typeof view.AppView;
|
||||||
export var AppModuleInjector: typeof app_module_factory.AppModuleInjector;
|
export var NgModuleInjector: typeof ng_module_factory.NgModuleInjector;
|
||||||
export type DebugAppView<T> = view.DebugAppView<T>;
|
export type DebugAppView<T> = view.DebugAppView<T>;
|
||||||
export var DebugAppView: typeof view.DebugAppView;
|
export var DebugAppView: typeof view.DebugAppView;
|
||||||
export type ViewType = view_type.ViewType;
|
export type ViewType = view_type.ViewType;
|
||||||
@ -136,12 +135,11 @@ export var __core_private__ = {
|
|||||||
LifecycleHooks: lifecycle_hooks.LifecycleHooks,
|
LifecycleHooks: lifecycle_hooks.LifecycleHooks,
|
||||||
LIFECYCLE_HOOKS_VALUES: lifecycle_hooks.LIFECYCLE_HOOKS_VALUES,
|
LIFECYCLE_HOOKS_VALUES: lifecycle_hooks.LIFECYCLE_HOOKS_VALUES,
|
||||||
ReflectorReader: reflector_reader.ReflectorReader,
|
ReflectorReader: reflector_reader.ReflectorReader,
|
||||||
ReflectorComponentResolver: component_resolver.ReflectorComponentResolver,
|
|
||||||
CodegenComponentFactoryResolver: component_factory_resolver.CodegenComponentFactoryResolver,
|
CodegenComponentFactoryResolver: component_factory_resolver.CodegenComponentFactoryResolver,
|
||||||
AppElement: element.AppElement,
|
AppElement: element.AppElement,
|
||||||
AppView: view.AppView,
|
AppView: view.AppView,
|
||||||
DebugAppView: view.DebugAppView,
|
DebugAppView: view.DebugAppView,
|
||||||
AppModuleInjector: app_module_factory.AppModuleInjector,
|
NgModuleInjector: ng_module_factory.NgModuleInjector,
|
||||||
ViewType: view_type.ViewType,
|
ViewType: view_type.ViewType,
|
||||||
MAX_INTERPOLATION_VALUES: view_utils.MAX_INTERPOLATION_VALUES,
|
MAX_INTERPOLATION_VALUES: view_utils.MAX_INTERPOLATION_VALUES,
|
||||||
checkBinding: view_utils.checkBinding,
|
checkBinding: view_utils.checkBinding,
|
||||||
|
@ -1,56 +0,0 @@
|
|||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright Google Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by an MIT-style license that can be
|
|
||||||
* found in the LICENSE file at https://angular.io/license
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {Type} from '../src/facade/lang';
|
|
||||||
|
|
||||||
import {APPLICATION_CORE_PROVIDERS} from './application_ref';
|
|
||||||
import {APP_ID_RANDOM_PROVIDER} from './application_tokens';
|
|
||||||
import {IterableDiffers, KeyValueDiffers, defaultIterableDiffers, defaultKeyValueDiffers} from './change_detection/change_detection';
|
|
||||||
import {ComponentFactoryResolver} from './linker/component_factory_resolver';
|
|
||||||
import {ComponentResolver, ReflectorComponentResolver} from './linker/component_resolver';
|
|
||||||
import {DynamicComponentLoader, DynamicComponentLoader_} from './linker/dynamic_component_loader';
|
|
||||||
import {ViewUtils} from './linker/view_utils';
|
|
||||||
|
|
||||||
let __unused: Type; // avoid unused import when Type union types are erased
|
|
||||||
|
|
||||||
export function _componentFactoryResolverFactory() {
|
|
||||||
return ComponentFactoryResolver.NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function _iterableDiffersFactory() {
|
|
||||||
return defaultIterableDiffers;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function _keyValueDiffersFactory() {
|
|
||||||
return defaultKeyValueDiffers;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A default set of providers which should be included in any Angular
|
|
||||||
* application, regardless of the platform it runs onto.
|
|
||||||
* @stable
|
|
||||||
*/
|
|
||||||
export const APPLICATION_COMMON_PROVIDERS: Array<Type|{[k: string]: any}|any[]> =
|
|
||||||
/*@ts2dart_const*/[
|
|
||||||
APPLICATION_CORE_PROVIDERS,
|
|
||||||
/* @ts2dart_Provider */ {provide: ComponentResolver, useClass: ReflectorComponentResolver},
|
|
||||||
{provide: ComponentFactoryResolver, useFactory: _componentFactoryResolverFactory, deps: []},
|
|
||||||
APP_ID_RANDOM_PROVIDER,
|
|
||||||
ViewUtils,
|
|
||||||
/* @ts2dart_Provider */ {
|
|
||||||
provide: IterableDiffers,
|
|
||||||
useFactory: _iterableDiffersFactory,
|
|
||||||
deps: []
|
|
||||||
},
|
|
||||||
/* @ts2dart_Provider */ {
|
|
||||||
provide: KeyValueDiffers,
|
|
||||||
useFactory: _keyValueDiffersFactory,
|
|
||||||
deps: []
|
|
||||||
},
|
|
||||||
/* @ts2dart_Provider */ {provide: DynamicComponentLoader, useClass: DynamicComponentLoader_},
|
|
||||||
];
|
|
84
modules/@angular/core/src/application_module.ts
Normal file
84
modules/@angular/core/src/application_module.ts
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright Google Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by an MIT-style license that can be
|
||||||
|
* found in the LICENSE file at https://angular.io/license
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {Type} from '../src/facade/lang';
|
||||||
|
|
||||||
|
import {ApplicationRef, ApplicationRef_, isDevMode} from './application_ref';
|
||||||
|
import {APP_ID_RANDOM_PROVIDER} from './application_tokens';
|
||||||
|
import {IterableDiffers, KeyValueDiffers, defaultIterableDiffers, defaultKeyValueDiffers} from './change_detection/change_detection';
|
||||||
|
import {OptionalMetadata, SkipSelfMetadata} from './di';
|
||||||
|
import {Compiler} from './linker/compiler';
|
||||||
|
import {ComponentFactoryResolver} from './linker/component_factory_resolver';
|
||||||
|
import {ComponentResolver} from './linker/component_resolver';
|
||||||
|
import {DynamicComponentLoader, DynamicComponentLoader_} from './linker/dynamic_component_loader';
|
||||||
|
import {ViewUtils} from './linker/view_utils';
|
||||||
|
import {NgModule} from './metadata';
|
||||||
|
import {NgZone} from './zone/ng_zone';
|
||||||
|
|
||||||
|
let __unused: Type; // avoid unused import when Type union types are erased
|
||||||
|
|
||||||
|
export function _componentFactoryResolverFactory() {
|
||||||
|
return ComponentFactoryResolver.NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function _iterableDiffersFactory() {
|
||||||
|
return defaultIterableDiffers;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function _keyValueDiffersFactory() {
|
||||||
|
return defaultKeyValueDiffers;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createNgZone(parent: NgZone): NgZone {
|
||||||
|
// If an NgZone is already present in the parent injector,
|
||||||
|
// use that one. Creating the NgZone in the same injector as the
|
||||||
|
// application is dangerous as some services might get created before
|
||||||
|
// the NgZone has been created.
|
||||||
|
// We keep the NgZone factory in the application providers for
|
||||||
|
// backwards compatibility for now though.
|
||||||
|
if (parent) {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
return new NgZone({enableLongStackTrace: isDevMode()});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A default set of providers which should be included in any Angular
|
||||||
|
* application, regardless of the platform it runs onto.
|
||||||
|
*
|
||||||
|
* @deprecated Include `ApplicationModule` instead.
|
||||||
|
*/
|
||||||
|
export const APPLICATION_COMMON_PROVIDERS: Array<Type|{[k: string]: any}|any[]> = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This module includes the providers of @angular/core that are needed
|
||||||
|
* to bootstrap components via `ApplicationRef`.
|
||||||
|
*
|
||||||
|
* @experimental
|
||||||
|
*/
|
||||||
|
@NgModule({
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: NgZone,
|
||||||
|
useFactory: createNgZone,
|
||||||
|
deps: <any>[[new SkipSelfMetadata(), new OptionalMetadata(), NgZone]]
|
||||||
|
},
|
||||||
|
ApplicationRef_,
|
||||||
|
{provide: ApplicationRef, useExisting: ApplicationRef_},
|
||||||
|
Compiler,
|
||||||
|
{provide: ComponentResolver, useExisting: Compiler},
|
||||||
|
{provide: ComponentFactoryResolver, useFactory: _componentFactoryResolverFactory},
|
||||||
|
APP_ID_RANDOM_PROVIDER,
|
||||||
|
ViewUtils,
|
||||||
|
{provide: IterableDiffers, useFactory: _iterableDiffersFactory},
|
||||||
|
{provide: KeyValueDiffers, useFactory: _keyValueDiffersFactory},
|
||||||
|
{provide: DynamicComponentLoader, useClass: DynamicComponentLoader_},
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class ApplicationModule {
|
||||||
|
}
|
@ -14,35 +14,16 @@ import {ConcreteType, IS_DART, Type, isBlank, isPresent, isPromise} from '../src
|
|||||||
import {APP_INITIALIZER, PLATFORM_INITIALIZER} from './application_tokens';
|
import {APP_INITIALIZER, PLATFORM_INITIALIZER} from './application_tokens';
|
||||||
import {ChangeDetectorRef} from './change_detection/change_detector_ref';
|
import {ChangeDetectorRef} from './change_detection/change_detector_ref';
|
||||||
import {Console} from './console';
|
import {Console} from './console';
|
||||||
import {Inject, Injectable, Injector, OpaqueToken, Optional, OptionalMetadata, ReflectiveInjector, SkipSelf, SkipSelfMetadata, forwardRef} from './di';
|
import {Inject, Injectable, Injector, OpaqueToken, Optional, ReflectiveInjector, SkipSelf, forwardRef} from './di';
|
||||||
import {AppModuleFactory, AppModuleRef} from './linker/app_module_factory';
|
|
||||||
import {Compiler, CompilerFactory, CompilerOptions} from './linker/compiler';
|
import {Compiler, CompilerFactory, CompilerOptions} from './linker/compiler';
|
||||||
import {ComponentFactory, ComponentRef} from './linker/component_factory';
|
import {ComponentFactory, ComponentRef} from './linker/component_factory';
|
||||||
import {ComponentFactoryResolver} from './linker/component_factory_resolver';
|
import {ComponentFactoryResolver} from './linker/component_factory_resolver';
|
||||||
import {ComponentResolver} from './linker/component_resolver';
|
import {ComponentResolver} from './linker/component_resolver';
|
||||||
|
import {NgModuleFactory, NgModuleRef} from './linker/ng_module_factory';
|
||||||
import {WtfScopeFn, wtfCreateScope, wtfLeave} from './profile/profile';
|
import {WtfScopeFn, wtfCreateScope, wtfLeave} from './profile/profile';
|
||||||
import {Testability, TestabilityRegistry} from './testability/testability';
|
import {Testability, TestabilityRegistry} from './testability/testability';
|
||||||
import {NgZone, NgZoneError} from './zone/ng_zone';
|
import {NgZone, NgZoneError} from './zone/ng_zone';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an Angular zone.
|
|
||||||
* @experimental
|
|
||||||
*/
|
|
||||||
export function createNgZone(parent: NgZone): NgZone {
|
|
||||||
// If an NgZone is already present in the parent injector,
|
|
||||||
// use that one. Creating the NgZone in the same injector as the
|
|
||||||
// application is dangerous as some services might get created before
|
|
||||||
// the NgZone has been created.
|
|
||||||
// We keep the NgZone factory in the application providers for
|
|
||||||
// backwards compatibility for now though.
|
|
||||||
if (parent) {
|
|
||||||
return parent;
|
|
||||||
}
|
|
||||||
return new NgZone({enableLongStackTrace: isDevMode()});
|
|
||||||
}
|
|
||||||
|
|
||||||
var _devMode: boolean = true;
|
var _devMode: boolean = true;
|
||||||
var _runModeLocked: boolean = false;
|
var _runModeLocked: boolean = false;
|
||||||
var _platform: PlatformRef;
|
var _platform: PlatformRef;
|
||||||
@ -113,17 +94,30 @@ export function createPlatform(injector: Injector): PlatformRef {
|
|||||||
return _platform;
|
return _platform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory for a platform.
|
||||||
|
*
|
||||||
|
* @experimental
|
||||||
|
*/
|
||||||
|
export type PlatformFactory = (extraProviders?: any[]) => PlatformRef;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a fatory for a platform
|
* Creates a fatory for a platform
|
||||||
*
|
*
|
||||||
* @experimental APIs related to application bootstrap are currently under review.
|
* @experimental APIs related to application bootstrap are currently under review.
|
||||||
*/
|
*/
|
||||||
export function createPlatformFactory(name: string, providers: any[]): () => PlatformRef {
|
export function createPlatformFactory(
|
||||||
|
parentPlaformFactory: PlatformFactory, name: string, providers: any[] = []): PlatformFactory {
|
||||||
const marker = new OpaqueToken(`Platform: ${name}`);
|
const marker = new OpaqueToken(`Platform: ${name}`);
|
||||||
return () => {
|
return (extraProviders: any[] = []) => {
|
||||||
if (!getPlatform()) {
|
if (!getPlatform()) {
|
||||||
createPlatform(
|
if (parentPlaformFactory) {
|
||||||
ReflectiveInjector.resolveAndCreate(providers.concat({provide: marker, useValue: true})));
|
parentPlaformFactory(
|
||||||
|
providers.concat(extraProviders).concat({provide: marker, useValue: true}));
|
||||||
|
} else {
|
||||||
|
createPlatform(ReflectiveInjector.resolveAndCreate(
|
||||||
|
providers.concat(extraProviders).concat({provide: marker, useValue: true})));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return assertPlatform(marker);
|
return assertPlatform(marker);
|
||||||
};
|
};
|
||||||
@ -168,7 +162,7 @@ export function getPlatform(): PlatformRef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance of an `@AppModule` for the given platform
|
* Creates an instance of an `@NgModule` for the given platform
|
||||||
* for offline compilation.
|
* for offline compilation.
|
||||||
*
|
*
|
||||||
* ## Simple Example
|
* ## Simple Example
|
||||||
@ -176,8 +170,8 @@ export function getPlatform(): PlatformRef {
|
|||||||
* ```typescript
|
* ```typescript
|
||||||
* my_module.ts:
|
* my_module.ts:
|
||||||
*
|
*
|
||||||
* @AppModule({
|
* @NgModule({
|
||||||
* modules: [BrowserModule]
|
* imports: [BrowserModule]
|
||||||
* })
|
* })
|
||||||
* class MyModule {}
|
* class MyModule {}
|
||||||
*
|
*
|
||||||
@ -192,11 +186,11 @@ export function getPlatform(): PlatformRef {
|
|||||||
* @experimental APIs related to application bootstrap are currently under review.
|
* @experimental APIs related to application bootstrap are currently under review.
|
||||||
*/
|
*/
|
||||||
export function bootstrapModuleFactory<M>(
|
export function bootstrapModuleFactory<M>(
|
||||||
moduleFactory: AppModuleFactory<M>, platform: PlatformRef): AppModuleRef<M> {
|
moduleFactory: NgModuleFactory<M>, platform: PlatformRef): NgModuleRef<M> {
|
||||||
// Note: We need to create the NgZone _before_ we instantiate the module,
|
// Note: We need to create the NgZone _before_ we instantiate the module,
|
||||||
// as instantiating the module creates some providers eagerly.
|
// as instantiating the module creates some providers eagerly.
|
||||||
// So we create a mini parent injector that just contains the new NgZone and
|
// So we create a mini parent injector that just contains the new NgZone and
|
||||||
// pass that as parent to the AppModuleFactory.
|
// pass that as parent to the NgModuleFactory.
|
||||||
const ngZone = new NgZone({enableLongStackTrace: isDevMode()});
|
const ngZone = new NgZone({enableLongStackTrace: isDevMode()});
|
||||||
const ngZoneInjector =
|
const ngZoneInjector =
|
||||||
ReflectiveInjector.resolveAndCreate([{provide: NgZone, useValue: ngZone}], platform.injector);
|
ReflectiveInjector.resolveAndCreate([{provide: NgZone, useValue: ngZone}], platform.injector);
|
||||||
@ -204,13 +198,13 @@ export function bootstrapModuleFactory<M>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance of an `@AppModule` for a given platform using the given runtime compiler.
|
* Creates an instance of an `@NgModule` for a given platform using the given runtime compiler.
|
||||||
*
|
*
|
||||||
* ## Simple Example
|
* ## Simple Example
|
||||||
*
|
*
|
||||||
* ```typescript
|
* ```typescript
|
||||||
* @AppModule({
|
* @NgModule({
|
||||||
* modules: [BrowserModule]
|
* imports: [BrowserModule]
|
||||||
* })
|
* })
|
||||||
* class MyModule {}
|
* class MyModule {}
|
||||||
*
|
*
|
||||||
@ -220,10 +214,11 @@ export function bootstrapModuleFactory<M>(
|
|||||||
*/
|
*/
|
||||||
export function bootstrapModule<M>(
|
export function bootstrapModule<M>(
|
||||||
moduleType: ConcreteType<M>, platform: PlatformRef,
|
moduleType: ConcreteType<M>, platform: PlatformRef,
|
||||||
compilerOptions: CompilerOptions = {}): Promise<AppModuleRef<M>> {
|
compilerOptions: CompilerOptions | CompilerOptions[] = []): Promise<NgModuleRef<M>> {
|
||||||
const compilerFactory: CompilerFactory = platform.injector.get(CompilerFactory);
|
const compilerFactory: CompilerFactory = platform.injector.get(CompilerFactory);
|
||||||
const compiler = compilerFactory.createCompiler(compilerOptions);
|
const compiler = compilerFactory.createCompiler(
|
||||||
return compiler.compileAppModuleAsync(moduleType)
|
compilerOptions instanceof Array ? compilerOptions : [compilerOptions]);
|
||||||
|
return compiler.compileModuleAsync(moduleType)
|
||||||
.then((moduleFactory) => bootstrapModuleFactory(moduleFactory, platform))
|
.then((moduleFactory) => bootstrapModuleFactory(moduleFactory, platform))
|
||||||
.then((moduleRef) => {
|
.then((moduleRef) => {
|
||||||
const appRef: ApplicationRef = moduleRef.injector.get(ApplicationRef);
|
const appRef: ApplicationRef = moduleRef.injector.get(ApplicationRef);
|
||||||
@ -239,10 +234,7 @@ export function bootstrapModule<M>(
|
|||||||
*/
|
*/
|
||||||
export function coreBootstrap<C>(
|
export function coreBootstrap<C>(
|
||||||
componentFactory: ComponentFactory<C>, injector: Injector): ComponentRef<C> {
|
componentFactory: ComponentFactory<C>, injector: Injector): ComponentRef<C> {
|
||||||
let console = injector.get(Console);
|
throw new BaseException('coreBootstrap is deprecated. Use bootstrapModuleFactory instead.');
|
||||||
console.warn('coreBootstrap is deprecated. Use bootstrapModuleFactory instead.');
|
|
||||||
var appRef: ApplicationRef = injector.get(ApplicationRef);
|
|
||||||
return appRef.bootstrap(componentFactory);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -254,15 +246,7 @@ export function coreBootstrap<C>(
|
|||||||
*/
|
*/
|
||||||
export function coreLoadAndBootstrap(
|
export function coreLoadAndBootstrap(
|
||||||
componentType: Type, injector: Injector): Promise<ComponentRef<any>> {
|
componentType: Type, injector: Injector): Promise<ComponentRef<any>> {
|
||||||
let console = injector.get(Console);
|
throw new BaseException('coreLoadAndBootstrap is deprecated. Use bootstrapModule instead.');
|
||||||
console.warn('coreLoadAndBootstrap is deprecated. Use bootstrapModule instead.');
|
|
||||||
var appRef: ApplicationRef = injector.get(ApplicationRef);
|
|
||||||
return appRef.run(() => {
|
|
||||||
var componentResolver: ComponentResolver = injector.get(ComponentResolver);
|
|
||||||
return PromiseWrapper
|
|
||||||
.all([componentResolver.resolveComponent(componentType), appRef.waitForAsyncInitializers()])
|
|
||||||
.then((arr) => appRef.bootstrap(arr[0]));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -592,20 +576,3 @@ export class ApplicationRef_ extends ApplicationRef {
|
|||||||
|
|
||||||
get componentTypes(): Type[] { return this._rootComponentTypes; }
|
get componentTypes(): Type[] { return this._rootComponentTypes; }
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PLATFORM_CORE_PROVIDERS =
|
|
||||||
/*@ts2dart_const*/[
|
|
||||||
PlatformRef_,
|
|
||||||
/*@ts2dart_const*/ (
|
|
||||||
/* @ts2dart_Provider */ {provide: PlatformRef, useExisting: PlatformRef_})
|
|
||||||
];
|
|
||||||
|
|
||||||
export const APPLICATION_CORE_PROVIDERS = /*@ts2dart_const*/[
|
|
||||||
/* @ts2dart_Provider */ {
|
|
||||||
provide: NgZone,
|
|
||||||
useFactory: createNgZone,
|
|
||||||
deps: <any>[[new SkipSelfMetadata(), new OptionalMetadata(), NgZone]]
|
|
||||||
},
|
|
||||||
ApplicationRef_,
|
|
||||||
/* @ts2dart_Provider */ {provide: ApplicationRef, useExisting: ApplicationRef_},
|
|
||||||
];
|
|
||||||
|
@ -7,8 +7,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Public API for compiler
|
// Public API for compiler
|
||||||
export {AppModuleFactory, AppModuleRef} from './linker/app_module_factory';
|
|
||||||
export {AppModuleFactoryLoader} from './linker/app_module_factory_loader';
|
|
||||||
export {Compiler, CompilerFactory, CompilerOptions, ComponentStillLoadingError} from './linker/compiler';
|
export {Compiler, CompilerFactory, CompilerOptions, ComponentStillLoadingError} from './linker/compiler';
|
||||||
export {ComponentFactory, ComponentRef} from './linker/component_factory';
|
export {ComponentFactory, ComponentRef} from './linker/component_factory';
|
||||||
export {ComponentFactoryResolver, NoComponentFactoryError} from './linker/component_factory_resolver';
|
export {ComponentFactoryResolver, NoComponentFactoryError} from './linker/component_factory_resolver';
|
||||||
@ -16,8 +14,10 @@ export {ComponentResolver} from './linker/component_resolver';
|
|||||||
export {DynamicComponentLoader} from './linker/dynamic_component_loader';
|
export {DynamicComponentLoader} from './linker/dynamic_component_loader';
|
||||||
export {ElementRef} from './linker/element_ref';
|
export {ElementRef} from './linker/element_ref';
|
||||||
export {ExpressionChangedAfterItHasBeenCheckedException} from './linker/exceptions';
|
export {ExpressionChangedAfterItHasBeenCheckedException} from './linker/exceptions';
|
||||||
|
export {NgModuleFactory, NgModuleRef} from './linker/ng_module_factory';
|
||||||
|
export {NgModuleFactoryLoader} from './linker/ng_module_factory_loader';
|
||||||
export {QueryList} from './linker/query_list';
|
export {QueryList} from './linker/query_list';
|
||||||
export {SystemJsAppModuleLoader} from './linker/system_js_app_module_factory_loader';
|
export {SystemJsNgModuleLoader} from './linker/system_js_ng_module_factory_loader';
|
||||||
export {SystemJsCmpFactoryResolver, SystemJsComponentResolver} from './linker/systemjs_component_resolver';
|
export {SystemJsCmpFactoryResolver, SystemJsComponentResolver} from './linker/systemjs_component_resolver';
|
||||||
export {TemplateRef} from './linker/template_ref';
|
export {TemplateRef} from './linker/template_ref';
|
||||||
export {ViewContainerRef} from './linker/view_container_ref';
|
export {ViewContainerRef} from './linker/view_container_ref';
|
||||||
|
@ -6,14 +6,15 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {Injector} from '../di';
|
import {Injector, OpaqueToken} from '../di';
|
||||||
import {BaseException} from '../facade/exceptions';
|
import {BaseException} from '../facade/exceptions';
|
||||||
import {ConcreteType, Type, stringify} from '../facade/lang';
|
import {ConcreteType, Type, stringify} from '../facade/lang';
|
||||||
import {ViewEncapsulation} from '../metadata';
|
import {ViewEncapsulation} from '../metadata';
|
||||||
import {AppModuleMetadata} from '../metadata/app_module';
|
import {NgModuleMetadata} from '../metadata/ng_module';
|
||||||
|
|
||||||
import {AppModuleFactory} from './app_module_factory';
|
|
||||||
import {ComponentFactory} from './component_factory';
|
import {ComponentFactory} from './component_factory';
|
||||||
|
import {ComponentResolver} from './component_resolver';
|
||||||
|
import {NgModuleFactory} from './ng_module_factory';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -32,14 +33,16 @@ export class ComponentStillLoadingError extends BaseException {
|
|||||||
* to create {@link ComponentFactory}s, which
|
* to create {@link ComponentFactory}s, which
|
||||||
* can later be used to create and render a Component instance.
|
* can later be used to create and render a Component instance.
|
||||||
*
|
*
|
||||||
* Each `@AppModule` provides an own `Compiler` to its injector,
|
* Each `@NgModule` provides an own `Compiler` to its injector,
|
||||||
* that will use the directives/pipes of the app module for compilation
|
* that will use the directives/pipes of the ng module for compilation
|
||||||
* of components.
|
* of components.
|
||||||
* @stable
|
* @stable
|
||||||
*/
|
*/
|
||||||
export class Compiler {
|
export class Compiler {
|
||||||
/**
|
/**
|
||||||
* Returns the injector with which the compiler has been created.
|
* Returns the injector with which the compiler has been created.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
*/
|
*/
|
||||||
get injector(): Injector {
|
get injector(): Injector {
|
||||||
throw new BaseException(`Runtime compiler is not loaded. Tried to read the injector.`);
|
throw new BaseException(`Runtime compiler is not loaded. Tried to read the injector.`);
|
||||||
@ -48,7 +51,8 @@ export class Compiler {
|
|||||||
/**
|
/**
|
||||||
* Loads the template and styles of a component and returns the associated `ComponentFactory`.
|
* Loads the template and styles of a component and returns the associated `ComponentFactory`.
|
||||||
*/
|
*/
|
||||||
compileComponentAsync<T>(component: ConcreteType<T>): Promise<ComponentFactory<T>> {
|
compileComponentAsync<T>(component: ConcreteType<T>, ngModule: Type = null):
|
||||||
|
Promise<ComponentFactory<T>> {
|
||||||
throw new BaseException(
|
throw new BaseException(
|
||||||
`Runtime compiler is not loaded. Tried to compile ${stringify(component)}`);
|
`Runtime compiler is not loaded. Tried to compile ${stringify(component)}`);
|
||||||
}
|
}
|
||||||
@ -56,23 +60,21 @@ export class Compiler {
|
|||||||
* Compiles the given component. All templates have to be either inline or compiled via
|
* Compiles the given component. All templates have to be either inline or compiled via
|
||||||
* `compileComponentAsync` before. Otherwise throws a {@link ComponentStillLoadingError}.
|
* `compileComponentAsync` before. Otherwise throws a {@link ComponentStillLoadingError}.
|
||||||
*/
|
*/
|
||||||
compileComponentSync<T>(component: ConcreteType<T>): ComponentFactory<T> {
|
compileComponentSync<T>(component: ConcreteType<T>, ngModule: Type = null): ComponentFactory<T> {
|
||||||
throw new BaseException(
|
throw new BaseException(
|
||||||
`Runtime compiler is not loaded. Tried to compile ${stringify(component)}`);
|
`Runtime compiler is not loaded. Tried to compile ${stringify(component)}`);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Compiles the given App Module. All templates of the components listed in `precompile`
|
* Compiles the given NgModule. All templates of the components listed in `precompile`
|
||||||
* have to be either inline or compiled before via `compileComponentAsync` /
|
* have to be either inline or compiled before via `compileComponentAsync` /
|
||||||
* `compileAppModuleAsync`. Otherwise throws a {@link ComponentStillLoadingError}.
|
* `compileModuleAsync`. Otherwise throws a {@link ComponentStillLoadingError}.
|
||||||
*/
|
*/
|
||||||
compileAppModuleSync<T>(moduleType: ConcreteType<T>, metadata: AppModuleMetadata = null):
|
compileModuleSync<T>(moduleType: ConcreteType<T>): NgModuleFactory<T> {
|
||||||
AppModuleFactory<T> {
|
|
||||||
throw new BaseException(
|
throw new BaseException(
|
||||||
`Runtime compiler is not loaded. Tried to compile ${stringify(moduleType)}`);
|
`Runtime compiler is not loaded. Tried to compile ${stringify(moduleType)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
compileAppModuleAsync<T>(moduleType: ConcreteType<T>, metadata: AppModuleMetadata = null):
|
compileModuleAsync<T>(moduleType: ConcreteType<T>): Promise<NgModuleFactory<T>> {
|
||||||
Promise<AppModuleFactory<T>> {
|
|
||||||
throw new BaseException(
|
throw new BaseException(
|
||||||
`Runtime compiler is not loaded. Tried to compile ${stringify(moduleType)}`);
|
`Runtime compiler is not loaded. Tried to compile ${stringify(moduleType)}`);
|
||||||
}
|
}
|
||||||
@ -83,7 +85,7 @@ export class Compiler {
|
|||||||
clearCache(): void {}
|
clearCache(): void {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the cache for the given component/appModule.
|
* Clears the cache for the given component/ngModule.
|
||||||
*/
|
*/
|
||||||
clearCacheFor(type: Type) {}
|
clearCacheFor(type: Type) {}
|
||||||
}
|
}
|
||||||
@ -98,8 +100,14 @@ export type CompilerOptions = {
|
|||||||
useJit?: boolean,
|
useJit?: boolean,
|
||||||
defaultEncapsulation?: ViewEncapsulation,
|
defaultEncapsulation?: ViewEncapsulation,
|
||||||
providers?: any[],
|
providers?: any[],
|
||||||
deprecatedAppProviders?: any[]
|
};
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* Token to provide CompilerOptions in the platform injector.
|
||||||
|
*
|
||||||
|
* @experimental
|
||||||
|
*/
|
||||||
|
export const CompilerOptions = new OpaqueToken('compilerOptions');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A factory for creating a Compiler
|
* A factory for creating a Compiler
|
||||||
@ -107,44 +115,5 @@ export type CompilerOptions = {
|
|||||||
* @experimental
|
* @experimental
|
||||||
*/
|
*/
|
||||||
export abstract class CompilerFactory {
|
export abstract class CompilerFactory {
|
||||||
static mergeOptions(defaultOptions: CompilerOptions = {}, newOptions: CompilerOptions = {}):
|
abstract createCompiler(options?: CompilerOptions[]): Compiler;
|
||||||
CompilerOptions {
|
|
||||||
return {
|
|
||||||
useDebug: _firstDefined(newOptions.useDebug, defaultOptions.useDebug),
|
|
||||||
useJit: _firstDefined(newOptions.useJit, defaultOptions.useJit),
|
|
||||||
defaultEncapsulation:
|
|
||||||
_firstDefined(newOptions.defaultEncapsulation, defaultOptions.defaultEncapsulation),
|
|
||||||
providers: _mergeArrays(defaultOptions.providers, newOptions.providers),
|
|
||||||
deprecatedAppProviders:
|
|
||||||
_mergeArrays(defaultOptions.deprecatedAppProviders, newOptions.deprecatedAppProviders)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
withDefaults(options: CompilerOptions = {}): CompilerFactory {
|
|
||||||
return new _DefaultApplyingCompilerFactory(this, options);
|
|
||||||
}
|
|
||||||
abstract createCompiler(options?: CompilerOptions): Compiler;
|
|
||||||
}
|
|
||||||
|
|
||||||
class _DefaultApplyingCompilerFactory extends CompilerFactory {
|
|
||||||
constructor(private _delegate: CompilerFactory, private _options: CompilerOptions) { super(); }
|
|
||||||
|
|
||||||
createCompiler(options: CompilerOptions = {}): Compiler {
|
|
||||||
return this._delegate.createCompiler(CompilerFactory.mergeOptions(this._options, options));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function _firstDefined<T>(...args: T[]): T {
|
|
||||||
for (var i = 0; i < args.length; i++) {
|
|
||||||
if (args[i] !== undefined) {
|
|
||||||
return args[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
function _mergeArrays(...parts: any[][]): any[] {
|
|
||||||
let result: any[] = [];
|
|
||||||
parts.forEach((part) => result.push.apply(result, part));
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
@ -6,12 +6,7 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {Console} from '../console';
|
import {Type} from '../facade/lang';
|
||||||
import {Injectable} from '../di/decorators';
|
|
||||||
import {PromiseWrapper} from '../facade/async';
|
|
||||||
import {BaseException} from '../facade/exceptions';
|
|
||||||
import {Type, isBlank, isString, stringify} from '../facade/lang';
|
|
||||||
import {reflector} from '../reflection/reflection';
|
|
||||||
import {ComponentFactory} from './component_factory';
|
import {ComponentFactory} from './component_factory';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -19,43 +14,17 @@ import {ComponentFactory} from './component_factory';
|
|||||||
* can later be used to create and render a Component instance.
|
* can later be used to create and render a Component instance.
|
||||||
*
|
*
|
||||||
* @deprecated Use {@link ComponentFactoryResolver} together with {@link
|
* @deprecated Use {@link ComponentFactoryResolver} together with {@link
|
||||||
* AppModule}.precompile}/{@link Component}.precompile or
|
* NgModule}.precompile}/{@link Component}.precompile or
|
||||||
* {@link ANALYZE_FOR_PRECOMPILE} provider for dynamic component creation.
|
* {@link ANALYZE_FOR_PRECOMPILE} provider for dynamic component creation.
|
||||||
* Use {@link AppModuleFactoryLoader} for lazy loading.
|
* Use {@link NgModuleFactoryLoader} for lazy loading.
|
||||||
*/
|
*/
|
||||||
export abstract class ComponentResolver {
|
export abstract class ComponentResolver {
|
||||||
static DynamicCompilationDeprecationMsg =
|
static DynamicCompilationDeprecationMsg =
|
||||||
'ComponentResolver is deprecated for dynamic compilation. Use ComponentFactoryResolver together with @AppModule/@Component.precompile or ANALYZE_FOR_PRECOMPILE provider instead.';
|
'ComponentResolver is deprecated for dynamic compilation. Use ComponentFactoryResolver together with @NgModule/@Component.precompile or ANALYZE_FOR_PRECOMPILE provider instead. For runtime compile only, you can also use Compiler.compileComponentSync/Async.';
|
||||||
static LazyLoadingDeprecationMsg =
|
static LazyLoadingDeprecationMsg =
|
||||||
'ComponentResolver is deprecated for lazy loading. Use AppModuleFactoryLoader instead.';
|
'ComponentResolver is deprecated for lazy loading. Use NgModuleFactoryLoader instead.';
|
||||||
|
|
||||||
|
|
||||||
abstract resolveComponent(component: Type|string): Promise<ComponentFactory<any>>;
|
abstract resolveComponent(component: Type|string): Promise<ComponentFactory<any>>;
|
||||||
abstract clearCache(): void;
|
abstract clearCache(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _isComponentFactory(type: any): boolean {
|
|
||||||
return type instanceof ComponentFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class ReflectorComponentResolver extends ComponentResolver {
|
|
||||||
constructor(private _console: Console) { super(); }
|
|
||||||
resolveComponent(component: Type|string): Promise<ComponentFactory<any>> {
|
|
||||||
if (isString(component)) {
|
|
||||||
return PromiseWrapper.reject(
|
|
||||||
new BaseException(`Cannot resolve component using '${component}'.`), null);
|
|
||||||
}
|
|
||||||
this._console.warn(ComponentResolver.DynamicCompilationDeprecationMsg);
|
|
||||||
|
|
||||||
var metadatas = reflector.annotations(<Type>component);
|
|
||||||
var componentFactory = metadatas.find(_isComponentFactory);
|
|
||||||
|
|
||||||
if (isBlank(componentFactory)) {
|
|
||||||
throw new BaseException(`No precompiled component ${stringify(component)} found`);
|
|
||||||
}
|
|
||||||
return PromiseWrapper.resolve(componentFactory);
|
|
||||||
}
|
|
||||||
|
|
||||||
clearCache() {}
|
|
||||||
}
|
|
||||||
|
@ -8,13 +8,15 @@
|
|||||||
|
|
||||||
import {Injectable, Injector, ReflectiveInjector, ResolvedReflectiveProvider} from '../di';
|
import {Injectable, Injector, ReflectiveInjector, ResolvedReflectiveProvider} from '../di';
|
||||||
import {Type, isPresent} from '../facade/lang';
|
import {Type, isPresent} from '../facade/lang';
|
||||||
|
|
||||||
|
import {Compiler} from './compiler';
|
||||||
import {ComponentRef} from './component_factory';
|
import {ComponentRef} from './component_factory';
|
||||||
import {ComponentResolver} from './component_resolver';
|
|
||||||
import {ViewContainerRef} from './view_container_ref';
|
import {ViewContainerRef} from './view_container_ref';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use ComponentResolver and ViewContainerRef directly.
|
* Use ComponentFactoryResolver and ViewContainerRef directly.
|
||||||
*
|
*
|
||||||
* @deprecated
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
@ -119,12 +121,12 @@ export abstract class DynamicComponentLoader {
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DynamicComponentLoader_ extends DynamicComponentLoader {
|
export class DynamicComponentLoader_ extends DynamicComponentLoader {
|
||||||
constructor(private _compiler: ComponentResolver) { super(); }
|
constructor(private _compiler: Compiler) { super(); }
|
||||||
|
|
||||||
loadAsRoot(
|
loadAsRoot(
|
||||||
type: Type, overrideSelectorOrNode: string|any, injector: Injector, onDispose?: () => void,
|
type: Type, overrideSelectorOrNode: string|any, injector: Injector, onDispose?: () => void,
|
||||||
projectableNodes?: any[][]): Promise<ComponentRef<any>> {
|
projectableNodes?: any[][]): Promise<ComponentRef<any>> {
|
||||||
return this._compiler.resolveComponent(type).then(componentFactory => {
|
return this._compiler.compileComponentAsync(<any>type).then(componentFactory => {
|
||||||
var componentRef = componentFactory.create(
|
var componentRef = componentFactory.create(
|
||||||
injector, projectableNodes,
|
injector, projectableNodes,
|
||||||
isPresent(overrideSelectorOrNode) ? overrideSelectorOrNode : componentFactory.selector);
|
isPresent(overrideSelectorOrNode) ? overrideSelectorOrNode : componentFactory.selector);
|
||||||
@ -138,7 +140,7 @@ export class DynamicComponentLoader_ extends DynamicComponentLoader {
|
|||||||
loadNextToLocation(
|
loadNextToLocation(
|
||||||
type: Type, location: ViewContainerRef, providers: ResolvedReflectiveProvider[] = null,
|
type: Type, location: ViewContainerRef, providers: ResolvedReflectiveProvider[] = null,
|
||||||
projectableNodes: any[][] = null): Promise<ComponentRef<any>> {
|
projectableNodes: any[][] = null): Promise<ComponentRef<any>> {
|
||||||
return this._compiler.resolveComponent(type).then(componentFactory => {
|
return this._compiler.compileComponentAsync(<any>type).then(componentFactory => {
|
||||||
var contextInjector = location.parentInjector;
|
var contextInjector = location.parentInjector;
|
||||||
var childInjector = isPresent(providers) && providers.length > 0 ?
|
var childInjector = isPresent(providers) && providers.length > 0 ?
|
||||||
ReflectiveInjector.fromResolvedProviders(providers, contextInjector) :
|
ReflectiveInjector.fromResolvedProviders(providers, contextInjector) :
|
||||||
|
@ -14,15 +14,16 @@ import {CodegenComponentFactoryResolver, ComponentFactoryResolver} from './compo
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an instance of an AppModule created via a {@link AppModuleFactory}.
|
* Represents an instance of an NgModule created via a {@link NgModuleFactory}.
|
||||||
*
|
*
|
||||||
* `AppModuleRef` provides access to the AppModule Instance as well other objects related to this
|
* `NgModuleRef` provides access to the NgModule Instance as well other objects related to this
|
||||||
* AppModule Instance.
|
* NgModule Instance.
|
||||||
* @stable
|
*
|
||||||
|
* @experimental
|
||||||
*/
|
*/
|
||||||
export abstract class AppModuleRef<T> {
|
export abstract class NgModuleRef<T> {
|
||||||
/**
|
/**
|
||||||
* The injector that contains all of the providers of the AppModule.
|
* The injector that contains all of the providers of the NgModule.
|
||||||
*/
|
*/
|
||||||
get injector(): Injector { return unimplemented(); }
|
get injector(): Injector { return unimplemented(); }
|
||||||
|
|
||||||
@ -33,22 +34,22 @@ export abstract class AppModuleRef<T> {
|
|||||||
get componentFactoryResolver(): ComponentFactoryResolver { return unimplemented(); }
|
get componentFactoryResolver(): ComponentFactoryResolver { return unimplemented(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The AppModule instance.
|
* The NgModule instance.
|
||||||
*/
|
*/
|
||||||
get instance(): T { return unimplemented(); }
|
get instance(): T { return unimplemented(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @stable
|
* @experimental
|
||||||
*/
|
*/
|
||||||
export class AppModuleFactory<T> {
|
export class NgModuleFactory<T> {
|
||||||
constructor(
|
constructor(
|
||||||
private _injectorClass: {new (parentInjector: Injector): AppModuleInjector<T>},
|
private _injectorClass: {new (parentInjector: Injector): NgModuleInjector<T>},
|
||||||
private _moduleype: ConcreteType<T>) {}
|
private _moduleype: ConcreteType<T>) {}
|
||||||
|
|
||||||
get moduleType(): ConcreteType<T> { return this._moduleype; }
|
get moduleType(): ConcreteType<T> { return this._moduleype; }
|
||||||
|
|
||||||
create(parentInjector: Injector = null): AppModuleRef<T> {
|
create(parentInjector: Injector): NgModuleRef<T> {
|
||||||
if (!parentInjector) {
|
if (!parentInjector) {
|
||||||
parentInjector = Injector.NULL;
|
parentInjector = Injector.NULL;
|
||||||
}
|
}
|
||||||
@ -60,9 +61,9 @@ export class AppModuleFactory<T> {
|
|||||||
|
|
||||||
const _UNDEFINED = new Object();
|
const _UNDEFINED = new Object();
|
||||||
|
|
||||||
export abstract class AppModuleInjector<T> extends CodegenComponentFactoryResolver implements
|
export abstract class NgModuleInjector<T> extends CodegenComponentFactoryResolver implements
|
||||||
Injector,
|
Injector,
|
||||||
AppModuleRef<T> {
|
NgModuleRef<T> {
|
||||||
public instance: T;
|
public instance: T;
|
||||||
|
|
||||||
constructor(public parent: Injector, factories: ComponentFactory<any>[]) {
|
constructor(public parent: Injector, factories: ComponentFactory<any>[]) {
|
@ -6,12 +6,12 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {AppModuleFactory} from './app_module_factory';
|
import {NgModuleFactory} from './ng_module_factory';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to load app moduled factories.
|
* Used to load ng moduled factories.
|
||||||
* @experimental
|
* @experimental
|
||||||
*/
|
*/
|
||||||
export abstract class AppModuleFactoryLoader {
|
export abstract class NgModuleFactoryLoader {
|
||||||
abstract load(path: string): Promise<AppModuleFactory<any>>;
|
abstract load(path: string): Promise<NgModuleFactory<any>>;
|
||||||
}
|
}
|
@ -10,9 +10,9 @@
|
|||||||
import {Injectable, Optional} from '../di';
|
import {Injectable, Optional} from '../di';
|
||||||
import {global} from '../facade/lang';
|
import {global} from '../facade/lang';
|
||||||
|
|
||||||
import {AppModuleFactory} from './app_module_factory';
|
|
||||||
import {AppModuleFactoryLoader} from './app_module_factory_loader';
|
|
||||||
import {Compiler} from './compiler';
|
import {Compiler} from './compiler';
|
||||||
|
import {NgModuleFactory} from './ng_module_factory';
|
||||||
|
import {NgModuleFactoryLoader} from './ng_module_factory_loader';
|
||||||
|
|
||||||
const _SEPARATOR = '#';
|
const _SEPARATOR = '#';
|
||||||
|
|
||||||
@ -20,18 +20,18 @@ const FACTORY_MODULE_SUFFIX = '.ngfactory';
|
|||||||
const FACTORY_CLASS_SUFFIX = 'NgFactory';
|
const FACTORY_CLASS_SUFFIX = 'NgFactory';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AppModuleFactoryLoader that uses SystemJS to load AppModuleFactory
|
* NgModuleFactoryLoader that uses SystemJS to load NgModuleFactory
|
||||||
* @experimental
|
* @experimental
|
||||||
*/
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SystemJsAppModuleLoader implements AppModuleFactoryLoader {
|
export class SystemJsNgModuleLoader implements NgModuleFactoryLoader {
|
||||||
constructor(@Optional() private _compiler: Compiler) {}
|
constructor(@Optional() private _compiler: Compiler) {}
|
||||||
|
|
||||||
load(path: string): Promise<AppModuleFactory<any>> {
|
load(path: string): Promise<NgModuleFactory<any>> {
|
||||||
return this._compiler ? this.loadAndCompile(path) : this.loadFactory(path);
|
return this._compiler ? this.loadAndCompile(path) : this.loadFactory(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
private loadAndCompile(path: string): Promise<AppModuleFactory<any>> {
|
private loadAndCompile(path: string): Promise<NgModuleFactory<any>> {
|
||||||
let [module, exportName] = path.split(_SEPARATOR);
|
let [module, exportName] = path.split(_SEPARATOR);
|
||||||
if (exportName === undefined) exportName = 'default';
|
if (exportName === undefined) exportName = 'default';
|
||||||
|
|
||||||
@ -39,10 +39,10 @@ export class SystemJsAppModuleLoader implements AppModuleFactoryLoader {
|
|||||||
.System.import(module)
|
.System.import(module)
|
||||||
.then((module: any) => module[exportName])
|
.then((module: any) => module[exportName])
|
||||||
.then((type: any) => checkNotEmpty(type, module, exportName))
|
.then((type: any) => checkNotEmpty(type, module, exportName))
|
||||||
.then((type: any) => this._compiler.compileAppModuleAsync(type));
|
.then((type: any) => this._compiler.compileModuleAsync(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
private loadFactory(path: string): Promise<AppModuleFactory<any>> {
|
private loadFactory(path: string): Promise<NgModuleFactory<any>> {
|
||||||
let [module, exportName] = path.split(_SEPARATOR);
|
let [module, exportName] = path.split(_SEPARATOR);
|
||||||
if (exportName === undefined) exportName = 'default';
|
if (exportName === undefined) exportName = 'default';
|
||||||
|
|
@ -18,9 +18,9 @@ const _SEPARATOR = '#';
|
|||||||
/**
|
/**
|
||||||
* Component resolver that can load components lazily
|
* Component resolver that can load components lazily
|
||||||
*
|
*
|
||||||
* @deprecated Lazy loading of components is deprecated. Use {@link SystemJsAppModuleLoader} to lazy
|
* @deprecated Lazy loading of components is deprecated. Use {@link SystemJsNgModuleLoader} to lazy
|
||||||
* load
|
* load
|
||||||
* {@link AppModuleFactory}s instead.
|
* {@link NgModuleFactory}s instead.
|
||||||
*/
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SystemJsComponentResolver implements ComponentResolver {
|
export class SystemJsComponentResolver implements ComponentResolver {
|
||||||
@ -53,9 +53,9 @@ const FACTORY_CLASS_SUFFIX = 'NgFactory';
|
|||||||
/**
|
/**
|
||||||
* Component resolver that can load component factories lazily
|
* Component resolver that can load component factories lazily
|
||||||
*
|
*
|
||||||
* @deprecated Lazy loading of components is deprecated. Use {@link SystemJsAppModuleLoader}
|
* @deprecated Lazy loading of components is deprecated. Use {@link SystemJsNgModuleLoader}
|
||||||
* to lazy
|
* to lazy
|
||||||
* load {@link AppModuleFactory}s instead.
|
* load {@link NgModuleFactory}s instead.
|
||||||
*/
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SystemJsCmpFactoryResolver implements ComponentResolver {
|
export class SystemJsCmpFactoryResolver implements ComponentResolver {
|
||||||
|
@ -14,15 +14,15 @@
|
|||||||
import {ChangeDetectionStrategy} from '../src/change_detection/change_detection';
|
import {ChangeDetectionStrategy} from '../src/change_detection/change_detection';
|
||||||
|
|
||||||
import {AnimationEntryMetadata} from './animation/metadata';
|
import {AnimationEntryMetadata} from './animation/metadata';
|
||||||
import {AppModuleMetadata} from './metadata/app_module';
|
|
||||||
import {AttributeMetadata, ContentChildMetadata, ContentChildrenMetadata, QueryMetadata, ViewChildMetadata, ViewChildrenMetadata, ViewQueryMetadata} from './metadata/di';
|
import {AttributeMetadata, ContentChildMetadata, ContentChildrenMetadata, QueryMetadata, ViewChildMetadata, ViewChildrenMetadata, ViewQueryMetadata} from './metadata/di';
|
||||||
import {ComponentMetadata, DirectiveMetadata, HostBindingMetadata, HostListenerMetadata, InputMetadata, OutputMetadata, PipeMetadata} from './metadata/directives';
|
import {ComponentMetadata, DirectiveMetadata, HostBindingMetadata, HostListenerMetadata, InputMetadata, OutputMetadata, PipeMetadata} from './metadata/directives';
|
||||||
|
import {NgModuleMetadata} from './metadata/ng_module';
|
||||||
import {ViewEncapsulation, ViewMetadata} from './metadata/view';
|
import {ViewEncapsulation, ViewMetadata} from './metadata/view';
|
||||||
|
|
||||||
export {AppModuleMetadata} from './metadata/app_module';
|
|
||||||
export {ANALYZE_FOR_PRECOMPILE, AttributeMetadata, ContentChildMetadata, ContentChildrenMetadata, QueryMetadata, ViewChildMetadata, ViewChildrenMetadata, ViewQueryMetadata} from './metadata/di';
|
export {ANALYZE_FOR_PRECOMPILE, AttributeMetadata, ContentChildMetadata, ContentChildrenMetadata, QueryMetadata, ViewChildMetadata, ViewChildrenMetadata, ViewQueryMetadata} from './metadata/di';
|
||||||
export {ComponentMetadata, DirectiveMetadata, HostBindingMetadata, HostListenerMetadata, InputMetadata, OutputMetadata, PipeMetadata} from './metadata/directives';
|
export {ComponentMetadata, DirectiveMetadata, HostBindingMetadata, HostListenerMetadata, InputMetadata, OutputMetadata, PipeMetadata} from './metadata/directives';
|
||||||
export {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, DoCheck, OnChanges, OnDestroy, OnInit} from './metadata/lifecycle_hooks';
|
export {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, DoCheck, OnChanges, OnDestroy, OnInit} from './metadata/lifecycle_hooks';
|
||||||
|
export {NgModuleMetadata} from './metadata/ng_module';
|
||||||
export {ViewEncapsulation, ViewMetadata} from './metadata/view';
|
export {ViewEncapsulation, ViewMetadata} from './metadata/view';
|
||||||
|
|
||||||
import {makeDecorator, makeParamDecorator, makePropDecorator, TypeDecorator,} from './util/decorators';
|
import {makeDecorator, makeParamDecorator, makePropDecorator, TypeDecorator,} from './util/decorators';
|
||||||
@ -86,13 +86,13 @@ export interface ViewDecorator extends TypeDecorator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for the {@link AppModuleMetadata} decorator function.
|
* Interface for the {@link NgModuleMetadata} decorator function.
|
||||||
*
|
*
|
||||||
* See {@link AppModuleMetadataFactory}.
|
* See {@link NgModuleMetadataFactory}.
|
||||||
*
|
*
|
||||||
* @stable
|
* @stable
|
||||||
*/
|
*/
|
||||||
export interface AppModuleDecorator extends TypeDecorator {}
|
export interface NgModuleDecorator extends TypeDecorator {}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -490,25 +490,25 @@ export interface HostListenerMetadataFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link AppModuleMetadata} factory for creating annotations, decorators or DSL.
|
* {@link NgModuleMetadata} factory for creating annotations, decorators or DSL.
|
||||||
*
|
*
|
||||||
* @stable
|
* @experimental
|
||||||
*/
|
*/
|
||||||
export interface AppModuleMetadataFactory {
|
export interface NgModuleMetadataFactory {
|
||||||
(obj: {
|
(obj?: {
|
||||||
providers?: any[],
|
providers?: any[],
|
||||||
directives?: Array<Type|any[]>,
|
declarations?: Array<Type|any[]>,
|
||||||
pipes?: Array<Type|any[]>,
|
imports?: Array<Type|any[]>,
|
||||||
precompile?: Array<Type|any[]>,
|
exports?: Array<Type|any[]>,
|
||||||
modules?: Array<Type|any[]>,
|
precompile?: Array<Type|any[]>
|
||||||
}): AppModuleDecorator;
|
}): NgModuleDecorator;
|
||||||
new (obj: {
|
new (obj?: {
|
||||||
providers?: any[],
|
providers?: any[],
|
||||||
directives?: Array<Type|any[]>,
|
declarations?: Array<Type|any[]>,
|
||||||
pipes?: Array<Type|any[]>,
|
imports?: Array<Type|any[]>,
|
||||||
precompile?: Array<Type|any[]>,
|
exports?: Array<Type|any[]>,
|
||||||
modules?: Array<Type|any[]>,
|
precompile?: Array<Type|any[]>
|
||||||
}): AppModuleMetadata;
|
}): NgModuleMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(alexeagle): remove the duplication of this doc. It is copied from ComponentMetadata.
|
// TODO(alexeagle): remove the duplication of this doc. It is copied from ComponentMetadata.
|
||||||
@ -1537,9 +1537,9 @@ export var HostBinding: HostBindingMetadataFactory = makePropDecorator(HostBindi
|
|||||||
export var HostListener: HostListenerMetadataFactory = makePropDecorator(HostListenerMetadata);
|
export var HostListener: HostListenerMetadataFactory = makePropDecorator(HostListenerMetadata);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Declares an app module.
|
* Declares an ng module.
|
||||||
* @stable
|
* @experimental
|
||||||
* @Annotation
|
* @Annotation
|
||||||
*/
|
*/
|
||||||
export var AppModule: AppModuleMetadataFactory =
|
export var NgModule: NgModuleMetadataFactory =
|
||||||
<AppModuleMetadataFactory>makeDecorator(AppModuleMetadata);
|
<NgModuleMetadataFactory>makeDecorator(NgModuleMetadata);
|
||||||
|
@ -13,13 +13,13 @@ import {StringWrapper, Type, isString, stringify} from '../facade/lang';
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This token can be used to create a virtual provider that will populate the
|
* This token can be used to create a virtual provider that will populate the
|
||||||
* `precompile` fields of components and app modules based on its `useValue`.
|
* `precompile` fields of components and ng modules based on its `useValue`.
|
||||||
* All components that are referenced in the `useValue` value (either directly
|
* All components that are referenced in the `useValue` value (either directly
|
||||||
* or in a nested array or map) will be added to the `precompile` property.
|
* or in a nested array or map) will be added to the `precompile` property.
|
||||||
*
|
*
|
||||||
* ### Example
|
* ### Example
|
||||||
* The following example shows how the router can populate the `precompile`
|
* The following example shows how the router can populate the `precompile`
|
||||||
* field of an AppModule based on the router configuration which refers
|
* field of an NgModule based on the router configuration which refers
|
||||||
* to components.
|
* to components.
|
||||||
*
|
*
|
||||||
* ```typescript
|
* ```typescript
|
||||||
@ -37,7 +37,7 @@ import {StringWrapper, Type, isString, stringify} from '../facade/lang';
|
|||||||
* {path: /teams', component: TeamsComp}
|
* {path: /teams', component: TeamsComp}
|
||||||
* ];
|
* ];
|
||||||
*
|
*
|
||||||
* @AppModule({
|
* @NgModule({
|
||||||
* providers: [provideRoutes(routes)]
|
* providers: [provideRoutes(routes)]
|
||||||
* })
|
* })
|
||||||
* class ModuleWithRoutes {}
|
* class ModuleWithRoutes {}
|
||||||
|
@ -10,10 +10,10 @@ import {InjectableMetadata} from '../di/metadata';
|
|||||||
import {Type} from '../facade/lang';
|
import {Type} from '../facade/lang';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Declares an Application Module.
|
* Declares an Angular Module.
|
||||||
* @stable
|
* @experimental
|
||||||
*/
|
*/
|
||||||
export class AppModuleMetadata extends InjectableMetadata {
|
export class NgModuleMetadata extends InjectableMetadata {
|
||||||
/**
|
/**
|
||||||
* Defines the set of injectable objects that are available in the injector
|
* Defines the set of injectable objects that are available in the injector
|
||||||
* of this module.
|
* of this module.
|
||||||
@ -29,7 +29,7 @@ export class AppModuleMetadata extends InjectableMetadata {
|
|||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* @AppModule({
|
* @NgModule({
|
||||||
* providers: [
|
* providers: [
|
||||||
* Greeter
|
* Greeter
|
||||||
* ]
|
* ]
|
||||||
@ -48,36 +48,52 @@ export class AppModuleMetadata extends InjectableMetadata {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies a list of directives that can be used within the template
|
* Specifies a list of directives/pipes that belong to this module.
|
||||||
* of any component that is part of this application module.
|
|
||||||
*
|
*
|
||||||
* ### Example
|
* ### Example
|
||||||
*
|
*
|
||||||
* ```javascript
|
* ```javascript
|
||||||
* @AppModule({
|
* @NgModule({
|
||||||
* directives: [NgFor]
|
* declarations: [NgFor]
|
||||||
* })
|
* })
|
||||||
* class MyAppModule {
|
* class CommonModule {
|
||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
directives: Array<Type|any[]>;
|
declarations: Array<Type|any[]>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies a list of pipes that can be used within the template
|
* Specifies a list of modules whose exported directives/pipes
|
||||||
* of any component that is part of this application module.
|
* should be available to templates in this module.
|
||||||
*
|
*
|
||||||
* ### Example
|
* ### Example
|
||||||
*
|
*
|
||||||
* ```javascript
|
* ```javascript
|
||||||
* @AppModule({
|
* @NgModule({
|
||||||
* pipes: [SomePipe]
|
* imports: [CommonModule]
|
||||||
* })
|
* })
|
||||||
* class MyAppModule {
|
* class MainModule {
|
||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
pipes: Array<Type|any[]>;
|
imports: Array<Type|any[]>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies a list of directives/pipes/module that can be used within the template
|
||||||
|
* of any component that is part of an angular module
|
||||||
|
* that imports this angular module.
|
||||||
|
*
|
||||||
|
* ### Example
|
||||||
|
*
|
||||||
|
* ```javascript
|
||||||
|
* @NgModule({
|
||||||
|
* exports: [NgFor]
|
||||||
|
* })
|
||||||
|
* class CommonModule {
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
exports: Array<Type|any[]>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the components that should be precompiled as well when
|
* Defines the components that should be precompiled as well when
|
||||||
@ -87,27 +103,18 @@ export class AppModuleMetadata extends InjectableMetadata {
|
|||||||
*/
|
*/
|
||||||
precompile: Array<Type|any[]>;
|
precompile: Array<Type|any[]>;
|
||||||
|
|
||||||
/**
|
constructor({providers, declarations, imports, exports, precompile}: {
|
||||||
* Defines modules that should be included into this module.
|
|
||||||
* The providers / directives / pipes / precompile entries will be added
|
|
||||||
* to this module.
|
|
||||||
* Just like the main module, the modules listed here are also eagerly
|
|
||||||
* created and accessible via DI.
|
|
||||||
*/
|
|
||||||
modules: Array<Type|any[]>;
|
|
||||||
|
|
||||||
constructor({providers, directives, pipes, precompile, modules}: {
|
|
||||||
providers?: any[],
|
providers?: any[],
|
||||||
directives?: Array<Type|any[]>,
|
declarations?: Array<Type|any[]>,
|
||||||
pipes?: Array<Type|any[]>,
|
imports?: Array<Type|any[]>,
|
||||||
precompile?: Array<Type|any[]>,
|
exports?: Array<Type|any[]>,
|
||||||
modules?: Array<Type|any[]>
|
precompile?: Array<Type|any[]>
|
||||||
} = {}) {
|
} = {}) {
|
||||||
super();
|
super();
|
||||||
this._providers = providers;
|
this._providers = providers;
|
||||||
this.directives = directives;
|
this.declarations = declarations;
|
||||||
this.pipes = pipes;
|
this.imports = imports;
|
||||||
|
this.exports = exports;
|
||||||
this.precompile = precompile;
|
this.precompile = precompile;
|
||||||
this.modules = modules;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
import {Type} from '../src/facade/lang';
|
import {Type} from '../src/facade/lang';
|
||||||
|
|
||||||
import {PLATFORM_CORE_PROVIDERS} from './application_ref';
|
import {PlatformRef, PlatformRef_, createPlatformFactory} from './application_ref';
|
||||||
import {Console} from './console';
|
import {Console} from './console';
|
||||||
import {Provider} from './di';
|
import {Provider} from './di';
|
||||||
import {Reflector, reflector} from './reflection/reflection';
|
import {Reflector, reflector} from './reflection/reflection';
|
||||||
@ -21,13 +21,22 @@ function _reflector(): Reflector {
|
|||||||
|
|
||||||
var __unused: Type; // prevent missing use Dart warning.
|
var __unused: Type; // prevent missing use Dart warning.
|
||||||
|
|
||||||
|
const _CORE_PLATFORM_PROVIDERS: Array<any|Type|Provider|any[]> = [
|
||||||
|
PlatformRef_, {provide: PlatformRef, useExisting: PlatformRef_},
|
||||||
|
{provide: Reflector, useFactory: _reflector, deps: []},
|
||||||
|
{provide: ReflectorReader, useExisting: Reflector}, TestabilityRegistry, Console
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A default set of providers which should be included in any Angular platform.
|
* This platform has to be included in any other platform
|
||||||
|
*
|
||||||
* @experimental
|
* @experimental
|
||||||
*/
|
*/
|
||||||
export const PLATFORM_COMMON_PROVIDERS: Array<any|Type|Provider|any[]> = /*@ts2dart_const*/[
|
export const corePlatform = createPlatformFactory(null, 'core', _CORE_PLATFORM_PROVIDERS);
|
||||||
PLATFORM_CORE_PROVIDERS,
|
|
||||||
/*@ts2dart_Provider*/ {provide: Reflector, useFactory: _reflector, deps: []},
|
/**
|
||||||
/*@ts2dart_Provider*/ {provide: ReflectorReader, useExisting: Reflector}, TestabilityRegistry,
|
* A default set of providers which should be included in any Angular platform.
|
||||||
Console
|
*
|
||||||
];
|
* @deprecated Create platforms via `createPlatformFactory(corePlatform, ...) instead!
|
||||||
|
*/
|
||||||
|
export const PLATFORM_COMMON_PROVIDERS = _CORE_PLATFORM_PROVIDERS;
|
@ -34,7 +34,7 @@ import {OpaqueToken} from './di';
|
|||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* @deprecated Providing platform directives via a provider is deprecated. Provide platform
|
* @deprecated Providing platform directives via a provider is deprecated. Provide platform
|
||||||
* directives via an {@link AppModule} instead.
|
* directives via an {@link NgModule} instead.
|
||||||
*/
|
*/
|
||||||
export const PLATFORM_DIRECTIVES: OpaqueToken =
|
export const PLATFORM_DIRECTIVES: OpaqueToken =
|
||||||
/*@ts2dart_const*/ new OpaqueToken('Platform Directives');
|
/*@ts2dart_const*/ new OpaqueToken('Platform Directives');
|
||||||
@ -63,6 +63,6 @@ export const PLATFORM_DIRECTIVES: OpaqueToken =
|
|||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* @deprecated Providing platform pipes via a provider is deprecated. Provide platform pipes via an
|
* @deprecated Providing platform pipes via a provider is deprecated. Provide platform pipes via an
|
||||||
* {@link AppModule} instead.
|
* {@link NgModule} instead.
|
||||||
*/
|
*/
|
||||||
export const PLATFORM_PIPES: OpaqueToken = /*@ts2dart_const*/ new OpaqueToken('Platform Pipes');
|
export const PLATFORM_PIPES: OpaqueToken = /*@ts2dart_const*/ new OpaqueToken('Platform Pipes');
|
@ -8,8 +8,10 @@
|
|||||||
|
|
||||||
import {AsyncTestCompleter, ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach, inject,} from '@angular/core/testing/testing_internal';
|
import {AsyncTestCompleter, ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach, inject,} from '@angular/core/testing/testing_internal';
|
||||||
import {SpyChangeDetectorRef} from './spies';
|
import {SpyChangeDetectorRef} from './spies';
|
||||||
import {ApplicationRef_, ApplicationRef, PLATFORM_CORE_PROVIDERS, APPLICATION_CORE_PROVIDERS} from '@angular/core/src/application_ref';
|
import {ConcreteType} from '../src/facade/lang';
|
||||||
import {Type, Injector, APP_INITIALIZER, Component, ReflectiveInjector, coreLoadAndBootstrap, PlatformRef, createPlatform, disposePlatform, ComponentResolver, ComponentFactoryResolver, ChangeDetectorRef} from '@angular/core';
|
import {ApplicationRef_, ApplicationRef} from '@angular/core/src/application_ref';
|
||||||
|
import {Type, NgModule, CompilerFactory, Injector, APP_INITIALIZER, Component, ReflectiveInjector, bootstrapModule, bootstrapModuleFactory, PlatformRef, disposePlatform, createPlatformFactory, ComponentResolver, ComponentFactoryResolver, ChangeDetectorRef, ApplicationModule} from '@angular/core';
|
||||||
|
import {coreDynamicPlatform} from '@angular/compiler';
|
||||||
import {Console} from '@angular/core/src/console';
|
import {Console} from '@angular/core/src/console';
|
||||||
import {BaseException} from '../src/facade/exceptions';
|
import {BaseException} from '../src/facade/exceptions';
|
||||||
import {PromiseWrapper, PromiseCompleter, TimerWrapper} from '../src/facade/async';
|
import {PromiseWrapper, PromiseCompleter, TimerWrapper} from '../src/facade/async';
|
||||||
@ -18,36 +20,48 @@ import {ExceptionHandler} from '../src/facade/exception_handler';
|
|||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe('bootstrap', () => {
|
describe('bootstrap', () => {
|
||||||
var platform: PlatformRef;
|
var defaultPlatform: PlatformRef;
|
||||||
var errorLogger: _ArrayLogger;
|
var errorLogger: _ArrayLogger;
|
||||||
var someCompFactory: ComponentFactory<any>;
|
var someCompFactory: ComponentFactory<any>;
|
||||||
|
var appProviders: any[];
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
errorLogger = new _ArrayLogger();
|
errorLogger = new _ArrayLogger();
|
||||||
disposePlatform();
|
disposePlatform();
|
||||||
platform = createPlatform(ReflectiveInjector.resolveAndCreate(PLATFORM_CORE_PROVIDERS));
|
defaultPlatform = createPlatformFactory(coreDynamicPlatform, 'test')();
|
||||||
someCompFactory =
|
someCompFactory =
|
||||||
new _MockComponentFactory(new _MockComponentRef(ReflectiveInjector.resolveAndCreate([])));
|
new _MockComponentFactory(new _MockComponentRef(ReflectiveInjector.resolveAndCreate([])));
|
||||||
|
appProviders = [
|
||||||
|
{provide: Console, useValue: new _MockConsole()},
|
||||||
|
{provide: ExceptionHandler, useValue: new ExceptionHandler(errorLogger, false)},
|
||||||
|
{provide: ComponentResolver, useValue: new _MockComponentResolver(someCompFactory)}
|
||||||
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => { disposePlatform(); });
|
afterEach(() => { disposePlatform(); });
|
||||||
|
|
||||||
function createApplication(providers: any[]): ApplicationRef_ {
|
function createModule(providers: any[] = []): ConcreteType<any> {
|
||||||
var appInjector = ReflectiveInjector.resolveAndCreate(
|
@NgModule({providers: [appProviders, providers], imports: [ApplicationModule]})
|
||||||
[
|
class MyModule {
|
||||||
APPLICATION_CORE_PROVIDERS, {provide: Console, useValue: new _MockConsole()},
|
}
|
||||||
{provide: ExceptionHandler, useValue: new ExceptionHandler(errorLogger, false)},
|
|
||||||
{provide: ComponentResolver, useValue: new _MockComponentResolver(someCompFactory)},
|
return MyModule;
|
||||||
{provide: ComponentFactoryResolver, useValue: ComponentFactoryResolver.NULL}, providers
|
}
|
||||||
],
|
|
||||||
platform.injector);
|
function createApplication(
|
||||||
|
providers: any[] = [], platform: PlatformRef = defaultPlatform): ApplicationRef_ {
|
||||||
|
const compilerFactory: CompilerFactory = platform.injector.get(CompilerFactory);
|
||||||
|
const compiler = compilerFactory.createCompiler();
|
||||||
|
const appInjector =
|
||||||
|
bootstrapModuleFactory(compiler.compileModuleSync(createModule(providers)), platform)
|
||||||
|
.injector;
|
||||||
return appInjector.get(ApplicationRef);
|
return appInjector.get(ApplicationRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('ApplicationRef', () => {
|
describe('ApplicationRef', () => {
|
||||||
it('should throw when reentering tick', () => {
|
it('should throw when reentering tick', () => {
|
||||||
var cdRef = <any>new SpyChangeDetectorRef();
|
var cdRef = <any>new SpyChangeDetectorRef();
|
||||||
var ref = createApplication([]);
|
var ref = createApplication();
|
||||||
try {
|
try {
|
||||||
ref.registerChangeDetector(cdRef);
|
ref.registerChangeDetector(cdRef);
|
||||||
cdRef.spy('detectChanges').andCallFake(() => ref.tick());
|
cdRef.spy('detectChanges').andCallFake(() => ref.tick());
|
||||||
@ -59,14 +73,14 @@ export function main() {
|
|||||||
|
|
||||||
describe('run', () => {
|
describe('run', () => {
|
||||||
it('should rethrow errors even if the exceptionHandler is not rethrowing', () => {
|
it('should rethrow errors even if the exceptionHandler is not rethrowing', () => {
|
||||||
var ref = createApplication([]);
|
var ref = createApplication();
|
||||||
expect(() => ref.run(() => { throw new BaseException('Test'); })).toThrowError('Test');
|
expect(() => ref.run(() => { throw new BaseException('Test'); })).toThrowError('Test');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return a promise with rejected errors even if the exceptionHandler is not rethrowing',
|
it('should return a promise with rejected errors even if the exceptionHandler is not rethrowing',
|
||||||
inject(
|
inject(
|
||||||
[AsyncTestCompleter, Injector], (async: AsyncTestCompleter, injector: Injector) => {
|
[AsyncTestCompleter, Injector], (async: AsyncTestCompleter, injector: Injector) => {
|
||||||
var ref = createApplication([]);
|
var ref = createApplication();
|
||||||
var promise = ref.run(() => PromiseWrapper.reject('Test', null));
|
var promise = ref.run(() => PromiseWrapper.reject('Test', null));
|
||||||
PromiseWrapper.catchError(promise, (e) => {
|
PromiseWrapper.catchError(promise, (e) => {
|
||||||
expect(e).toEqual('Test');
|
expect(e).toEqual('Test');
|
||||||
@ -76,7 +90,7 @@ export function main() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('coreLoadAndBootstrap', () => {
|
describe('bootstrapModule', () => {
|
||||||
it('should wait for asynchronous app initializers',
|
it('should wait for asynchronous app initializers',
|
||||||
inject([AsyncTestCompleter, Injector], (async: AsyncTestCompleter, injector: Injector) => {
|
inject([AsyncTestCompleter, Injector], (async: AsyncTestCompleter, injector: Injector) => {
|
||||||
let completer: PromiseCompleter<any> = PromiseWrapper.completer();
|
let completer: PromiseCompleter<any> = PromiseWrapper.completer();
|
||||||
@ -85,16 +99,19 @@ export function main() {
|
|||||||
completer.resolve(true);
|
completer.resolve(true);
|
||||||
initializerDone = true;
|
initializerDone = true;
|
||||||
}, 1);
|
}, 1);
|
||||||
var app = createApplication(
|
|
||||||
[{provide: APP_INITIALIZER, useValue: () => completer.promise, multi: true}]);
|
bootstrapModule(
|
||||||
coreLoadAndBootstrap(MyComp6, app.injector).then(_ => {
|
createModule(
|
||||||
|
[{provide: APP_INITIALIZER, useValue: () => completer.promise, multi: true}]),
|
||||||
|
defaultPlatform)
|
||||||
|
.then(_ => {
|
||||||
expect(initializerDone).toBe(true);
|
expect(initializerDone).toBe(true);
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('coreBootstrap', () => {
|
describe('ApplicationRef.bootstrap', () => {
|
||||||
it('should throw if an APP_INITIIALIZER is not yet resolved',
|
it('should throw if an APP_INITIIALIZER is not yet resolved',
|
||||||
inject([Injector], (injector: Injector) => {
|
inject([Injector], (injector: Injector) => {
|
||||||
var app = createApplication([{
|
var app = createApplication([{
|
||||||
|
@ -87,14 +87,13 @@ export function main() {
|
|||||||
expect(log.result()).toEqual('1; 2');
|
expect(log.result()).toEqual('1; 2');
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// TODO(vicb): check why this doesn't work in JS - linked to open issues on GH ?
|
it('should complain if the test throws an exception during async calls', () => {
|
||||||
xit('should complain if the test throws an exception during async calls', () => {
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
fakeAsync(() => {
|
fakeAsync(() => {
|
||||||
PromiseWrapper.resolve(null).then((_) => { throw new BaseException('async'); });
|
PromiseWrapper.resolve(null).then((_) => { throw new BaseException('async'); });
|
||||||
flushMicrotasks();
|
flushMicrotasks();
|
||||||
})();
|
})();
|
||||||
}).toThrowError('async');
|
}).toThrowError('Uncaught (in promise): async');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should complain if a test throws an exception', () => {
|
it('should complain if a test throws an exception', () => {
|
||||||
|
@ -1,557 +0,0 @@
|
|||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright Google Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by an MIT-style license that can be
|
|
||||||
* found in the LICENSE file at https://angular.io/license
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {ANALYZE_FOR_PRECOMPILE, AppModule, AppModuleMetadata, Compiler, Component, ComponentFactoryResolver, ComponentRef, ComponentResolver, DebugElement, Directive, Host, Inject, Injectable, Injector, Input, OpaqueToken, Optional, Pipe, Provider, ReflectiveInjector, SelfMetadata, SkipSelf, SkipSelfMetadata, forwardRef, getDebugNode, provide} from '@angular/core';
|
|
||||||
import {ComponentFixture, configureCompiler} from '@angular/core/testing';
|
|
||||||
import {AsyncTestCompleter, beforeEach, beforeEachProviders, ddescribe, describe, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal';
|
|
||||||
import {expect} from '@angular/platform-browser/testing/matchers';
|
|
||||||
|
|
||||||
import {BaseException} from '../../src/facade/exceptions';
|
|
||||||
import {ConcreteType, IS_DART, Type, stringify} from '../../src/facade/lang';
|
|
||||||
|
|
||||||
class Engine {}
|
|
||||||
|
|
||||||
class BrokenEngine {
|
|
||||||
constructor() { throw new BaseException('Broken Engine'); }
|
|
||||||
}
|
|
||||||
|
|
||||||
class DashboardSoftware {}
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
class Dashboard {
|
|
||||||
constructor(software: DashboardSoftware) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TurboEngine extends Engine {}
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
class Car {
|
|
||||||
engine: Engine;
|
|
||||||
constructor(engine: Engine) { this.engine = engine; }
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
class CarWithOptionalEngine {
|
|
||||||
engine: Engine;
|
|
||||||
constructor(@Optional() engine: Engine) { this.engine = engine; }
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
class CarWithDashboard {
|
|
||||||
engine: Engine;
|
|
||||||
dashboard: Dashboard;
|
|
||||||
constructor(engine: Engine, dashboard: Dashboard) {
|
|
||||||
this.engine = engine;
|
|
||||||
this.dashboard = dashboard;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
class SportsCar extends Car {
|
|
||||||
engine: Engine;
|
|
||||||
constructor(engine: Engine) { super(engine); }
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
class CarWithInject {
|
|
||||||
engine: Engine;
|
|
||||||
constructor(@Inject(TurboEngine) engine: Engine) { this.engine = engine; }
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
class CyclicEngine {
|
|
||||||
constructor(car: Car) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
class NoAnnotations {
|
|
||||||
constructor(secretDependency: any) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
function factoryFn(a: any) {}
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
class SomeService {
|
|
||||||
}
|
|
||||||
|
|
||||||
@AppModule({})
|
|
||||||
class SomeModule {
|
|
||||||
}
|
|
||||||
|
|
||||||
@AppModule({providers: [{provide: 'someToken', useValue: 'someValue'}]})
|
|
||||||
class ModuleWithProvider {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({selector: 'comp', template: ''})
|
|
||||||
class SomeComp {
|
|
||||||
}
|
|
||||||
|
|
||||||
@AppModule({precompile: [SomeComp]})
|
|
||||||
class ModuleWithPrecompile {
|
|
||||||
}
|
|
||||||
|
|
||||||
@AppModule({
|
|
||||||
providers:
|
|
||||||
[{provide: ANALYZE_FOR_PRECOMPILE, multi: true, useValue: [{a: 'b', component: SomeComp}]}]
|
|
||||||
})
|
|
||||||
class ModuleWithAnalyzePrecompileProvider {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Directive({selector: '[someDir]', host: {'[title]': 'someDir'}})
|
|
||||||
class SomeDirective {
|
|
||||||
@Input()
|
|
||||||
someDir: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Pipe({name: 'somePipe'})
|
|
||||||
class SomePipe {
|
|
||||||
transform(value: string): any { return `transformed ${value}`; }
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({selector: 'comp', template: `<div [someDir]="'someValue' | somePipe"></div>`})
|
|
||||||
class CompUsingModuleDirectiveAndPipe {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component(
|
|
||||||
{selector: 'parent', template: `<comp></comp>`, directives: [CompUsingModuleDirectiveAndPipe]})
|
|
||||||
class ParentCompUsingModuleDirectiveAndPipe {
|
|
||||||
}
|
|
||||||
|
|
||||||
@AppModule(
|
|
||||||
{directives: [SomeDirective], pipes: [SomePipe], precompile: [CompUsingModuleDirectiveAndPipe]})
|
|
||||||
class ModuleWithDirectivesAndPipes {
|
|
||||||
}
|
|
||||||
|
|
||||||
export function main() {
|
|
||||||
if (IS_DART) {
|
|
||||||
declareTests({useJit: false});
|
|
||||||
} else {
|
|
||||||
describe('jit', () => { declareTests({useJit: true}); });
|
|
||||||
|
|
||||||
describe('no jit', () => { declareTests({useJit: false}); });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function declareTests({useJit}: {useJit: boolean}) {
|
|
||||||
describe('AppModule', () => {
|
|
||||||
var compiler: Compiler;
|
|
||||||
var injector: Injector;
|
|
||||||
|
|
||||||
beforeEach(() => { configureCompiler({useJit: useJit}); });
|
|
||||||
|
|
||||||
beforeEach(inject([Compiler, Injector], (_compiler: Compiler, _injector: Injector) => {
|
|
||||||
compiler = _compiler;
|
|
||||||
injector = _injector;
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('precompile', function() {
|
|
||||||
it('should resolve ComponentFactories', () => {
|
|
||||||
let appModule = compiler.compileAppModuleSync(ModuleWithPrecompile).create();
|
|
||||||
expect(appModule.componentFactoryResolver.resolveComponentFactory(SomeComp).componentType)
|
|
||||||
.toBe(SomeComp);
|
|
||||||
expect(appModule.injector.get(ComponentFactoryResolver)
|
|
||||||
.resolveComponentFactory(SomeComp)
|
|
||||||
.componentType)
|
|
||||||
.toBe(SomeComp);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should resolve ComponentFactories via ANALYZE_FOR_PRECOMPILE', () => {
|
|
||||||
let appModule = compiler.compileAppModuleSync(ModuleWithAnalyzePrecompileProvider).create();
|
|
||||||
expect(appModule.componentFactoryResolver.resolveComponentFactory(SomeComp).componentType)
|
|
||||||
.toBe(SomeComp);
|
|
||||||
expect(appModule.injector.get(ComponentFactoryResolver)
|
|
||||||
.resolveComponentFactory(SomeComp)
|
|
||||||
.componentType)
|
|
||||||
.toBe(SomeComp);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should resolve ComponentFactories for nested modules', () => {
|
|
||||||
let appModule =
|
|
||||||
compiler
|
|
||||||
.compileAppModuleSync(
|
|
||||||
SomeModule, new AppModuleMetadata({modules: [ModuleWithPrecompile]}))
|
|
||||||
.create();
|
|
||||||
expect(appModule.componentFactoryResolver.resolveComponentFactory(SomeComp).componentType)
|
|
||||||
.toBe(SomeComp);
|
|
||||||
expect(appModule.injector.get(ComponentFactoryResolver)
|
|
||||||
.resolveComponentFactory(SomeComp)
|
|
||||||
.componentType)
|
|
||||||
.toBe(SomeComp);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('directives and pipes', () => {
|
|
||||||
function createComp<T>(
|
|
||||||
compType: ConcreteType<T>, moduleType: ConcreteType<any>,
|
|
||||||
moduleMeta: AppModuleMetadata = null): ComponentFixture<T> {
|
|
||||||
let appModule = compiler.compileAppModuleSync(moduleType, moduleMeta).create();
|
|
||||||
var cf = appModule.componentFactoryResolver.resolveComponentFactory(compType);
|
|
||||||
return new ComponentFixture(cf.create(injector), null, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
it('should support module directives and pipes', () => {
|
|
||||||
let compFixture = createComp(CompUsingModuleDirectiveAndPipe, ModuleWithDirectivesAndPipes);
|
|
||||||
compFixture.detectChanges();
|
|
||||||
expect(compFixture.debugElement.children[0].properties['title'])
|
|
||||||
.toBe('transformed someValue');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should support module directives and pipes for nested modules', () => {
|
|
||||||
let compFixture = createComp(
|
|
||||||
CompUsingModuleDirectiveAndPipe, SomeModule,
|
|
||||||
new AppModuleMetadata({modules: [ModuleWithDirectivesAndPipes]}));
|
|
||||||
compFixture.detectChanges();
|
|
||||||
expect(compFixture.debugElement.children[0].properties['title'])
|
|
||||||
.toBe('transformed someValue');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should support module directives and pipes in nested components', () => {
|
|
||||||
let compFixture =
|
|
||||||
createComp(ParentCompUsingModuleDirectiveAndPipe, SomeModule, new AppModuleMetadata({
|
|
||||||
directives: [SomeDirective],
|
|
||||||
pipes: [SomePipe],
|
|
||||||
precompile: [ParentCompUsingModuleDirectiveAndPipe]
|
|
||||||
}));
|
|
||||||
compFixture.detectChanges();
|
|
||||||
expect(compFixture.debugElement.children[0].children[0].properties['title'])
|
|
||||||
.toBe('transformed someValue');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should provide a Compiler instance that uses the directives/pipes of the module', () => {
|
|
||||||
let appModule = compiler.compileAppModuleSync(ModuleWithDirectivesAndPipes).create();
|
|
||||||
let boundCompiler: Compiler = appModule.injector.get(Compiler);
|
|
||||||
var cf = boundCompiler.compileComponentSync(CompUsingModuleDirectiveAndPipe);
|
|
||||||
let compFixture = new ComponentFixture(cf.create(injector), null, false);
|
|
||||||
compFixture.detectChanges();
|
|
||||||
expect(compFixture.debugElement.children[0].properties['title'])
|
|
||||||
.toBe('transformed someValue');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should provide a ComponentResolver instance that uses the directives/pipes of the module',
|
|
||||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
|
||||||
|
|
||||||
let appModule = compiler.compileAppModuleSync(ModuleWithDirectivesAndPipes).create();
|
|
||||||
let boundCompiler: ComponentResolver = appModule.injector.get(ComponentResolver);
|
|
||||||
boundCompiler.resolveComponent(CompUsingModuleDirectiveAndPipe).then((cf) => {
|
|
||||||
let compFixture = new ComponentFixture(cf.create(injector), null, false);
|
|
||||||
compFixture.detectChanges();
|
|
||||||
expect(compFixture.debugElement.children[0].properties['title'])
|
|
||||||
.toBe('transformed someValue');
|
|
||||||
async.done();
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should provide a ComponentResolver instance that delegates to the parent ComponentResolver for strings',
|
|
||||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
|
||||||
let parentResolver: any =
|
|
||||||
jasmine.createSpyObj('resolver', ['resolveComponent', 'clearCache']);
|
|
||||||
let appModule = compiler.compileAppModuleSync(ModuleWithDirectivesAndPipes)
|
|
||||||
.create(ReflectiveInjector.resolveAndCreate(
|
|
||||||
[{provide: ComponentResolver, useValue: parentResolver}]));
|
|
||||||
parentResolver.resolveComponent.and.returnValue(
|
|
||||||
Promise.resolve('someFactoryFromParent'));
|
|
||||||
let boundCompiler: ComponentResolver = appModule.injector.get(ComponentResolver);
|
|
||||||
boundCompiler.resolveComponent('someString').then((result) => {
|
|
||||||
expect(parentResolver.resolveComponent).toHaveBeenCalledWith('someString');
|
|
||||||
expect(result).toBe('someFactoryFromParent');
|
|
||||||
async.done();
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('providers', function() {
|
|
||||||
function createInjector(providers: any[], parent: Injector = null): Injector {
|
|
||||||
return compiler
|
|
||||||
.compileAppModuleSync(SomeModule, new AppModuleMetadata({providers: providers}))
|
|
||||||
.create(parent)
|
|
||||||
.injector;
|
|
||||||
}
|
|
||||||
|
|
||||||
it('should provide the module',
|
|
||||||
() => { expect(createInjector([]).get(SomeModule)).toBeAnInstanceOf(SomeModule); });
|
|
||||||
|
|
||||||
it('should instantiate a class without dependencies', () => {
|
|
||||||
var injector = createInjector([Engine]);
|
|
||||||
var engine = injector.get(Engine);
|
|
||||||
|
|
||||||
expect(engine).toBeAnInstanceOf(Engine);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should resolve dependencies based on type information', () => {
|
|
||||||
var injector = createInjector([Engine, Car]);
|
|
||||||
var car = injector.get(Car);
|
|
||||||
|
|
||||||
expect(car).toBeAnInstanceOf(Car);
|
|
||||||
expect(car.engine).toBeAnInstanceOf(Engine);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should resolve dependencies based on @Inject annotation', () => {
|
|
||||||
var injector = createInjector([TurboEngine, Engine, CarWithInject]);
|
|
||||||
var car = injector.get(CarWithInject);
|
|
||||||
|
|
||||||
expect(car).toBeAnInstanceOf(CarWithInject);
|
|
||||||
expect(car.engine).toBeAnInstanceOf(TurboEngine);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw when no type and not @Inject (class case)', () => {
|
|
||||||
expect(() => createInjector([NoAnnotations]))
|
|
||||||
.toThrowError('Can\'t resolve all parameters for NoAnnotations: (?).');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw when no type and not @Inject (factory case)', () => {
|
|
||||||
expect(() => createInjector([provide('someToken', {useFactory: factoryFn})]))
|
|
||||||
.toThrowError('Can\'t resolve all parameters for factoryFn: (?).');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should cache instances', () => {
|
|
||||||
var injector = createInjector([Engine]);
|
|
||||||
|
|
||||||
var e1 = injector.get(Engine);
|
|
||||||
var e2 = injector.get(Engine);
|
|
||||||
|
|
||||||
expect(e1).toBe(e2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should provide to a value', () => {
|
|
||||||
var injector = createInjector([provide(Engine, {useValue: 'fake engine'})]);
|
|
||||||
|
|
||||||
var engine = injector.get(Engine);
|
|
||||||
expect(engine).toEqual('fake engine');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should provide to a factory', () => {
|
|
||||||
function sportsCarFactory(e: Engine) { return new SportsCar(e); }
|
|
||||||
|
|
||||||
var injector =
|
|
||||||
createInjector([Engine, provide(Car, {useFactory: sportsCarFactory, deps: [Engine]})]);
|
|
||||||
|
|
||||||
var car = injector.get(Car);
|
|
||||||
expect(car).toBeAnInstanceOf(SportsCar);
|
|
||||||
expect(car.engine).toBeAnInstanceOf(Engine);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should supporting provider to null', () => {
|
|
||||||
var injector = createInjector([provide(Engine, {useValue: null})]);
|
|
||||||
var engine = injector.get(Engine);
|
|
||||||
expect(engine).toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should provide to an alias', () => {
|
|
||||||
var injector = createInjector([
|
|
||||||
Engine, provide(SportsCar, {useClass: SportsCar}),
|
|
||||||
provide(Car, {useExisting: SportsCar})
|
|
||||||
]);
|
|
||||||
|
|
||||||
var car = injector.get(Car);
|
|
||||||
var sportsCar = injector.get(SportsCar);
|
|
||||||
expect(car).toBeAnInstanceOf(SportsCar);
|
|
||||||
expect(car).toBe(sportsCar);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should support multiProviders', () => {
|
|
||||||
var injector = createInjector([
|
|
||||||
Engine, provide(Car, {useClass: SportsCar, multi: true}),
|
|
||||||
provide(Car, {useClass: CarWithOptionalEngine, multi: true})
|
|
||||||
]);
|
|
||||||
|
|
||||||
var cars = injector.get(Car);
|
|
||||||
expect(cars.length).toEqual(2);
|
|
||||||
expect(cars[0]).toBeAnInstanceOf(SportsCar);
|
|
||||||
expect(cars[1]).toBeAnInstanceOf(CarWithOptionalEngine);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should support multiProviders that are created using useExisting', () => {
|
|
||||||
var injector = createInjector(
|
|
||||||
[Engine, SportsCar, provide(Car, {useExisting: SportsCar, multi: true})]);
|
|
||||||
|
|
||||||
var cars = injector.get(Car);
|
|
||||||
expect(cars.length).toEqual(1);
|
|
||||||
expect(cars[0]).toBe(injector.get(SportsCar));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw when the aliased provider does not exist', () => {
|
|
||||||
var injector = createInjector([provide('car', {useExisting: SportsCar})]);
|
|
||||||
var e = `No provider for ${stringify(SportsCar)}!`;
|
|
||||||
expect(() => injector.get('car')).toThrowError(e);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle forwardRef in useExisting', () => {
|
|
||||||
var injector = createInjector([
|
|
||||||
provide('originalEngine', {useClass: forwardRef(() => Engine)}),
|
|
||||||
provide('aliasedEngine', {useExisting: <any>forwardRef(() => 'originalEngine')})
|
|
||||||
]);
|
|
||||||
expect(injector.get('aliasedEngine')).toBeAnInstanceOf(Engine);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should support overriding factory dependencies', () => {
|
|
||||||
var injector = createInjector(
|
|
||||||
[Engine, provide(Car, {useFactory: (e: Engine) => new SportsCar(e), deps: [Engine]})]);
|
|
||||||
|
|
||||||
var car = injector.get(Car);
|
|
||||||
expect(car).toBeAnInstanceOf(SportsCar);
|
|
||||||
expect(car.engine).toBeAnInstanceOf(Engine);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should support optional dependencies', () => {
|
|
||||||
var injector = createInjector([CarWithOptionalEngine]);
|
|
||||||
|
|
||||||
var car = injector.get(CarWithOptionalEngine);
|
|
||||||
expect(car.engine).toEqual(null);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should flatten passed-in providers', () => {
|
|
||||||
var injector = createInjector([[[Engine, Car]]]);
|
|
||||||
|
|
||||||
var car = injector.get(Car);
|
|
||||||
expect(car).toBeAnInstanceOf(Car);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should use the last provider when there are multiple providers for same token', () => {
|
|
||||||
var injector = createInjector(
|
|
||||||
[provide(Engine, {useClass: Engine}), provide(Engine, {useClass: TurboEngine})]);
|
|
||||||
|
|
||||||
expect(injector.get(Engine)).toBeAnInstanceOf(TurboEngine);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should use non-type tokens', () => {
|
|
||||||
var injector = createInjector([provide('token', {useValue: 'value'})]);
|
|
||||||
|
|
||||||
expect(injector.get('token')).toEqual('value');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw when given invalid providers', () => {
|
|
||||||
expect(() => createInjector(<any>['blah']))
|
|
||||||
.toThrowError(
|
|
||||||
'Invalid provider - only instances of Provider and Type are allowed, got: blah');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should provide itself', () => {
|
|
||||||
var parent = createInjector([]);
|
|
||||||
var child = createInjector([], parent);
|
|
||||||
|
|
||||||
expect(child.get(Injector)).toBe(child);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw when no provider defined', () => {
|
|
||||||
var injector = createInjector([]);
|
|
||||||
expect(() => injector.get('NonExisting')).toThrowError('No provider for NonExisting!');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw when trying to instantiate a cyclic dependency', () => {
|
|
||||||
expect(() => createInjector([Car, provide(Engine, {useClass: CyclicEngine})]))
|
|
||||||
.toThrowError(/Cannot instantiate cyclic dependency! Car/g);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should support null values', () => {
|
|
||||||
var injector = createInjector([provide('null', {useValue: null})]);
|
|
||||||
expect(injector.get('null')).toBe(null);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
describe('child', () => {
|
|
||||||
it('should load instances from parent injector', () => {
|
|
||||||
var parent = createInjector([Engine]);
|
|
||||||
var child = createInjector([], parent);
|
|
||||||
|
|
||||||
var engineFromParent = parent.get(Engine);
|
|
||||||
var engineFromChild = child.get(Engine);
|
|
||||||
|
|
||||||
expect(engineFromChild).toBe(engineFromParent);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not use the child providers when resolving the dependencies of a parent provider',
|
|
||||||
() => {
|
|
||||||
var parent = createInjector([Car, Engine]);
|
|
||||||
var child = createInjector([provide(Engine, {useClass: TurboEngine})], parent);
|
|
||||||
|
|
||||||
var carFromChild = child.get(Car);
|
|
||||||
expect(carFromChild.engine).toBeAnInstanceOf(Engine);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create new instance in a child injector', () => {
|
|
||||||
var parent = createInjector([Engine]);
|
|
||||||
var child = createInjector([provide(Engine, {useClass: TurboEngine})], parent);
|
|
||||||
|
|
||||||
var engineFromParent = parent.get(Engine);
|
|
||||||
var engineFromChild = child.get(Engine);
|
|
||||||
|
|
||||||
expect(engineFromParent).not.toBe(engineFromChild);
|
|
||||||
expect(engineFromChild).toBeAnInstanceOf(TurboEngine);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('depedency resolution', () => {
|
|
||||||
describe('@Self()', () => {
|
|
||||||
it('should return a dependency from self', () => {
|
|
||||||
var inj = createInjector([
|
|
||||||
Engine,
|
|
||||||
provide(
|
|
||||||
Car,
|
|
||||||
{useFactory: (e: Engine) => new Car(e), deps: [[Engine, new SelfMetadata()]]})
|
|
||||||
]);
|
|
||||||
|
|
||||||
expect(inj.get(Car)).toBeAnInstanceOf(Car);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw when not requested provider on self', () => {
|
|
||||||
expect(() => createInjector([provide(Car, {
|
|
||||||
useFactory: (e: Engine) => new Car(e),
|
|
||||||
deps: [[Engine, new SelfMetadata()]]
|
|
||||||
})]))
|
|
||||||
.toThrowError(/No provider for Engine/g);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('default', () => {
|
|
||||||
it('should not skip self', () => {
|
|
||||||
var parent = createInjector([Engine]);
|
|
||||||
var child = createInjector(
|
|
||||||
[
|
|
||||||
provide(Engine, {useClass: TurboEngine}),
|
|
||||||
provide(Car, {useFactory: (e: Engine) => new Car(e), deps: [Engine]})
|
|
||||||
],
|
|
||||||
parent);
|
|
||||||
|
|
||||||
expect(child.get(Car).engine).toBeAnInstanceOf(TurboEngine);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('nested modules', () => {
|
|
||||||
it('should merge the providers of nested modules', () => {
|
|
||||||
var injector =
|
|
||||||
compiler
|
|
||||||
.compileAppModuleSync(SomeModule, new AppModuleMetadata({
|
|
||||||
providers: [{provide: 'a', useValue: 'aValue'}],
|
|
||||||
modules: [ModuleWithProvider]
|
|
||||||
}))
|
|
||||||
.create()
|
|
||||||
.injector;
|
|
||||||
expect(injector.get(SomeModule)).toBeAnInstanceOf(SomeModule);
|
|
||||||
expect(injector.get(ModuleWithProvider)).toBeAnInstanceOf(ModuleWithProvider);
|
|
||||||
expect(injector.get('a')).toBe('aValue');
|
|
||||||
expect(injector.get('someToken')).toBe('someValue');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should override the providers of nested modules', () => {
|
|
||||||
var injector = compiler
|
|
||||||
.compileAppModuleSync(
|
|
||||||
SomeModule, new AppModuleMetadata({
|
|
||||||
providers: [{provide: 'someToken', useValue: 'someNewValue'}],
|
|
||||||
modules: [ModuleWithProvider]
|
|
||||||
}))
|
|
||||||
.create()
|
|
||||||
.injector;
|
|
||||||
expect(injector.get('someToken')).toBe('someNewValue');
|
|
||||||
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
@ -1775,17 +1775,6 @@ function declareTests({useJit}: {useJit: boolean}) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('logging property updates', () => {
|
describe('logging property updates', () => {
|
||||||
beforeEach(() => {
|
|
||||||
configureCompiler({
|
|
||||||
providers: [{
|
|
||||||
provide: CompilerConfig,
|
|
||||||
// Note: we are testing the `genDebugInfo` flag here, so we
|
|
||||||
// need to set it explicitely!
|
|
||||||
useValue: new CompilerConfig({genDebugInfo: true, useJit: useJit})
|
|
||||||
}]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should reflect property values as attributes',
|
it('should reflect property values as attributes',
|
||||||
inject(
|
inject(
|
||||||
[TestComponentBuilder, AsyncTestCompleter],
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
1038
modules/@angular/core/test/linker/ng_module_integration_spec.ts
Normal file
1038
modules/@angular/core/test/linker/ng_module_integration_spec.ts
Normal file
File diff suppressed because it is too large
Load Diff
@ -7,8 +7,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {AsyncTestCompleter, beforeEach, ddescribe, xdescribe, describe, expect, iit, inject, beforeEachProviders, it, xit,} from '@angular/core/testing/testing_internal';
|
import {AsyncTestCompleter, beforeEach, ddescribe, xdescribe, describe, expect, iit, inject, beforeEachProviders, it, xit,} from '@angular/core/testing/testing_internal';
|
||||||
import {TestComponentBuilder} from '@angular/core/testing';
|
import {TestComponentBuilder, configureModule} from '@angular/core/testing';
|
||||||
import {Component, ComponentFactoryResolver, NoComponentFactoryError, forwardRef, ANALYZE_FOR_PRECOMPILE} from '@angular/core';
|
import {Component, ComponentFactoryResolver, NoComponentFactoryError, forwardRef, ANALYZE_FOR_PRECOMPILE, ViewMetadata} from '@angular/core';
|
||||||
|
import {stringify} from '../../src/facade/lang';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe('jit', () => { declareTests({useJit: true}); });
|
describe('jit', () => { declareTests({useJit: true}); });
|
||||||
@ -17,18 +18,32 @@ export function main() {
|
|||||||
|
|
||||||
function declareTests({useJit}: {useJit: boolean}) {
|
function declareTests({useJit}: {useJit: boolean}) {
|
||||||
describe('@Component.precompile', function() {
|
describe('@Component.precompile', function() {
|
||||||
|
beforeEach(() => { configureModule({declarations: [MainComp, ChildComp, NestedChildComp]}); });
|
||||||
|
|
||||||
|
it('should error if the component was not declared nor imported by the module',
|
||||||
|
inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||||
|
|
||||||
|
@Component({selector: 'child', template: ''})
|
||||||
|
class ChildComp {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({template: 'comp', precompile: [ChildComp]})
|
||||||
|
class SomeComp {
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(() => tcb.createSync(SomeComp))
|
||||||
|
.toThrowError(
|
||||||
|
`Component ${stringify(SomeComp)} in NgModule DynamicTestModule uses ${stringify(ChildComp)} via "precompile" but it was neither declared nor imported into the module!`);
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
it('should resolve ComponentFactories from the same component',
|
it('should resolve ComponentFactories from the same component',
|
||||||
inject(
|
inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||||
[TestComponentBuilder, AsyncTestCompleter],
|
const compFixture = tcb.createSync(MainComp);
|
||||||
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
|
||||||
tcb.createAsync(MainComp).then((compFixture) => {
|
|
||||||
let mainComp: MainComp = compFixture.componentInstance;
|
let mainComp: MainComp = compFixture.componentInstance;
|
||||||
expect(compFixture.debugElement.injector.get(ComponentFactoryResolver))
|
expect(compFixture.componentRef.injector.get(ComponentFactoryResolver)).toBe(mainComp.cfr);
|
||||||
.toBe(mainComp.cfr);
|
|
||||||
var cf = mainComp.cfr.resolveComponentFactory(ChildComp);
|
var cf = mainComp.cfr.resolveComponentFactory(ChildComp);
|
||||||
expect(cf.componentType).toBe(ChildComp);
|
expect(cf.componentType).toBe(ChildComp);
|
||||||
async.done();
|
|
||||||
});
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
@ -37,63 +52,52 @@ function declareTests({useJit}: {useJit: boolean}) {
|
|||||||
let compFixture = tcb.createSync(CompWithAnalyzePrecompileProvider);
|
let compFixture = tcb.createSync(CompWithAnalyzePrecompileProvider);
|
||||||
let mainComp: CompWithAnalyzePrecompileProvider = compFixture.componentInstance;
|
let mainComp: CompWithAnalyzePrecompileProvider = compFixture.componentInstance;
|
||||||
let cfr: ComponentFactoryResolver =
|
let cfr: ComponentFactoryResolver =
|
||||||
compFixture.debugElement.injector.get(ComponentFactoryResolver);
|
compFixture.componentRef.injector.get(ComponentFactoryResolver);
|
||||||
expect(cfr.resolveComponentFactory(ChildComp).componentType).toBe(ChildComp);
|
expect(cfr.resolveComponentFactory(ChildComp).componentType).toBe(ChildComp);
|
||||||
expect(cfr.resolveComponentFactory(NestedChildComp).componentType).toBe(NestedChildComp);
|
expect(cfr.resolveComponentFactory(NestedChildComp).componentType).toBe(NestedChildComp);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should be able to get a component form a parent component (view hiearchy)',
|
it('should be able to get a component form a parent component (view hiearchy)',
|
||||||
inject(
|
inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||||
[TestComponentBuilder, AsyncTestCompleter],
|
const compFixture =
|
||||||
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
tcb.overrideView(
|
||||||
tcb.overrideTemplate(MainComp, '<child></child>')
|
MainComp,
|
||||||
.createAsync(MainComp)
|
new ViewMetadata({template: '<child></child>', directives: [ChildComp]}))
|
||||||
.then((compFixture) => {
|
.createSync(MainComp);
|
||||||
let childCompEl = compFixture.debugElement.children[0];
|
let childCompEl = compFixture.debugElement.children[0];
|
||||||
let childComp: ChildComp = childCompEl.componentInstance;
|
let childComp: ChildComp = childCompEl.componentInstance;
|
||||||
// declared on ChildComp directly
|
// declared on ChildComp directly
|
||||||
expect(childComp.cfr.resolveComponentFactory(NestedChildComp).componentType)
|
expect(childComp.cfr.resolveComponentFactory(NestedChildComp).componentType)
|
||||||
.toBe(NestedChildComp);
|
.toBe(NestedChildComp);
|
||||||
// inherited from MainComp
|
// inherited from MainComp
|
||||||
expect(childComp.cfr.resolveComponentFactory(ChildComp).componentType)
|
expect(childComp.cfr.resolveComponentFactory(ChildComp).componentType).toBe(ChildComp);
|
||||||
.toBe(ChildComp);
|
|
||||||
async.done();
|
|
||||||
});
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should not be able to get components from a parent component (content hierarchy)',
|
it('should not be able to get components from a parent component (content hierarchy)',
|
||||||
inject(
|
inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||||
[TestComponentBuilder, AsyncTestCompleter],
|
const compFixture = tcb.overrideView(MainComp, new ViewMetadata({
|
||||||
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
template: '<child><nested></nested></child>',
|
||||||
tcb.overrideTemplate(MainComp, '<child><nested></nested></child>')
|
directives: [ChildComp, NestedChildComp]
|
||||||
|
}))
|
||||||
.overrideTemplate(ChildComp, '<ng-content></ng-content>')
|
.overrideTemplate(ChildComp, '<ng-content></ng-content>')
|
||||||
.createAsync(MainComp)
|
.createSync(MainComp);
|
||||||
.then((compFixture) => {
|
|
||||||
let nestedChildCompEl = compFixture.debugElement.children[0].children[0];
|
let nestedChildCompEl = compFixture.debugElement.children[0].children[0];
|
||||||
let nestedChildComp: NestedChildComp = nestedChildCompEl.componentInstance;
|
let nestedChildComp: NestedChildComp = nestedChildCompEl.componentInstance;
|
||||||
expect(nestedChildComp.cfr.resolveComponentFactory(ChildComp).componentType)
|
expect(nestedChildComp.cfr.resolveComponentFactory(ChildComp).componentType)
|
||||||
.toBe(ChildComp);
|
.toBe(ChildComp);
|
||||||
expect(() => nestedChildComp.cfr.resolveComponentFactory(NestedChildComp))
|
expect(() => nestedChildComp.cfr.resolveComponentFactory(NestedChildComp))
|
||||||
.toThrow(new NoComponentFactoryError(NestedChildComp));
|
.toThrow(new NoComponentFactoryError(NestedChildComp));
|
||||||
async.done();
|
|
||||||
});
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var DIRECTIVES: any[] = [
|
@Component({selector: 'nested', template: ''})
|
||||||
forwardRef(() => NestedChildComp),
|
|
||||||
forwardRef(() => ChildComp),
|
|
||||||
forwardRef(() => MainComp),
|
|
||||||
];
|
|
||||||
|
|
||||||
@Component({selector: 'nested', directives: DIRECTIVES, template: ''})
|
|
||||||
class NestedChildComp {
|
class NestedChildComp {
|
||||||
constructor(public cfr: ComponentFactoryResolver) {}
|
constructor(public cfr: ComponentFactoryResolver) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({selector: 'child', precompile: [NestedChildComp], directives: DIRECTIVES, template: ''})
|
@Component({selector: 'child', precompile: [NestedChildComp], template: ''})
|
||||||
class ChildComp {
|
class ChildComp {
|
||||||
constructor(public cfr: ComponentFactoryResolver) {}
|
constructor(public cfr: ComponentFactoryResolver) {}
|
||||||
}
|
}
|
||||||
@ -101,7 +105,6 @@ class ChildComp {
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'main',
|
selector: 'main',
|
||||||
precompile: [ChildComp],
|
precompile: [ChildComp],
|
||||||
directives: DIRECTIVES,
|
|
||||||
template: '',
|
template: '',
|
||||||
})
|
})
|
||||||
class MainComp {
|
class MainComp {
|
||||||
|
@ -1,50 +0,0 @@
|
|||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright Google Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by an MIT-style license that can be
|
|
||||||
* found in the LICENSE file at https://angular.io/license
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {ComponentFactory} from '@angular/core/src/linker/component_factory';
|
|
||||||
import {ComponentResolver, ReflectorComponentResolver} from '@angular/core/src/linker/component_resolver';
|
|
||||||
import {ReflectionInfo, reflector} from '@angular/core/src/reflection/reflection';
|
|
||||||
import {AsyncTestCompleter, afterEach, beforeEach, beforeEachProviders, ddescribe, describe, expect, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal';
|
|
||||||
import {Console} from '../../src/console';
|
|
||||||
|
|
||||||
class DummyConsole implements Console {
|
|
||||||
log(message: string) {}
|
|
||||||
warn(message: string) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function main() {
|
|
||||||
describe('Compiler', () => {
|
|
||||||
var someCompFactory: any /** TODO #9100 */;
|
|
||||||
var compiler: ComponentResolver;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
someCompFactory = new ComponentFactory(null, null, null);
|
|
||||||
reflector.registerType(SomeComponent, new ReflectionInfo([someCompFactory]));
|
|
||||||
compiler = new ReflectorComponentResolver(new DummyConsole());
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should read the template from an annotation',
|
|
||||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
|
||||||
compiler.resolveComponent(SomeComponent).then((compFactory: ComponentFactory<any>) => {
|
|
||||||
expect(compFactory).toBe(someCompFactory);
|
|
||||||
async.done();
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should throw when given a string',
|
|
||||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
|
||||||
compiler.resolveComponent('someString').catch((e) => {
|
|
||||||
expect(e.message).toContain('Cannot resolve component using \'someString\'.');
|
|
||||||
async.done();
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
class SomeComponent {}
|
|
@ -26,7 +26,7 @@ function declareTests({useJit}: {useJit: boolean}) {
|
|||||||
describe('platform pipes', () => {
|
describe('platform pipes', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
configureCompiler({useJit: useJit});
|
configureCompiler({useJit: useJit});
|
||||||
configureModule({pipes: [PlatformPipe]});
|
configureModule({declarations: [PlatformPipe]});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should overwrite them by custom pipes',
|
it('should overwrite them by custom pipes',
|
||||||
|
@ -6,10 +6,10 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {AppModule, AppModuleFactory, AppModuleMetadata, AppModuleRef, Compiler, CompilerFactory, ComponentStillLoadingError, Injector, PlatformRef, Provider, ReflectiveInjector, Type, assertPlatform, createPlatform, getPlatform} from '../index';
|
import {Compiler, CompilerFactory, CompilerOptions, ComponentStillLoadingError, Injector, NgModule, NgModuleFactory, NgModuleMetadata, NgModuleRef, PlatformRef, Provider, ReflectiveInjector, Type, assertPlatform, createPlatform, getPlatform} from '../index';
|
||||||
import {ListWrapper} from '../src/facade/collection';
|
import {ListWrapper} from '../src/facade/collection';
|
||||||
import {BaseException} from '../src/facade/exceptions';
|
import {BaseException} from '../src/facade/exceptions';
|
||||||
import {FunctionWrapper, isPresent, stringify} from '../src/facade/lang';
|
import {ConcreteType, FunctionWrapper, isPresent, stringify} from '../src/facade/lang';
|
||||||
|
|
||||||
import {AsyncTestCompleter} from './async_test_completer';
|
import {AsyncTestCompleter} from './async_test_completer';
|
||||||
|
|
||||||
@ -22,105 +22,87 @@ export class TestBed implements Injector {
|
|||||||
private _instantiated: boolean = false;
|
private _instantiated: boolean = false;
|
||||||
|
|
||||||
private _compiler: Compiler = null;
|
private _compiler: Compiler = null;
|
||||||
private _moduleRef: AppModuleRef<any> = null;
|
private _moduleRef: NgModuleRef<any> = null;
|
||||||
private _appModuleFactory: AppModuleFactory<any> = null;
|
private _ngModuleFactory: NgModuleFactory<any> = null;
|
||||||
|
|
||||||
private _compilerProviders: Array<Type|Provider|any[]|any> = [];
|
private _compilerOptions: CompilerOptions[] = [];
|
||||||
private _compilerUseJit: boolean = true;
|
|
||||||
|
|
||||||
private _providers: Array<Type|Provider|any[]|any> = [];
|
private _providers: Array<Type|Provider|any[]|any> = [];
|
||||||
private _directives: Array<Type|any[]|any> = [];
|
private _declarations: Array<Type|any[]|any> = [];
|
||||||
private _pipes: Array<Type|any[]|any> = [];
|
private _imports: Array<Type|any[]|any> = [];
|
||||||
private _modules: Array<Type|any[]|any> = [];
|
|
||||||
private _precompile: Array<Type|any[]|any> = [];
|
private _precompile: Array<Type|any[]|any> = [];
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
this._compiler = null;
|
this._compiler = null;
|
||||||
this._moduleRef = null;
|
this._moduleRef = null;
|
||||||
this._appModuleFactory = null;
|
this._ngModuleFactory = null;
|
||||||
this._compilerProviders = [];
|
this._compilerOptions = [];
|
||||||
this._compilerUseJit = true;
|
|
||||||
this._providers = [];
|
this._providers = [];
|
||||||
this._directives = [];
|
this._declarations = [];
|
||||||
this._pipes = [];
|
this._imports = [];
|
||||||
this._modules = [];
|
|
||||||
this._precompile = [];
|
this._precompile = [];
|
||||||
this._instantiated = false;
|
this._instantiated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
platform: PlatformRef = null;
|
platform: PlatformRef = null;
|
||||||
|
|
||||||
appModule: Type = null;
|
ngModule: Type = null;
|
||||||
|
|
||||||
configureCompiler(config: {providers?: any[], useJit?: boolean}) {
|
configureCompiler(config: {providers?: any[], useJit?: boolean}) {
|
||||||
if (this._instantiated) {
|
if (this._instantiated) {
|
||||||
throw new BaseException('Cannot add configuration after test injector is instantiated');
|
throw new BaseException('Cannot add configuration after test injector is instantiated');
|
||||||
}
|
}
|
||||||
if (config.providers) {
|
this._compilerOptions.push(config);
|
||||||
this._compilerProviders = ListWrapper.concat(this._compilerProviders, config.providers);
|
|
||||||
}
|
|
||||||
if (config.useJit !== undefined) {
|
|
||||||
this._compilerUseJit = config.useJit;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
configureModule(moduleDef: {
|
configureModule(
|
||||||
providers?: any[],
|
moduleDef: {providers?: any[], declarations?: any[], imports?: any[], precompile?: any[]}) {
|
||||||
directives?: any[],
|
|
||||||
pipes?: any[],
|
|
||||||
precompile?: any[],
|
|
||||||
modules?: any[]
|
|
||||||
}) {
|
|
||||||
if (this._instantiated) {
|
if (this._instantiated) {
|
||||||
throw new BaseException('Cannot add configuration after test injector is instantiated');
|
throw new BaseException('Cannot add configuration after test injector is instantiated');
|
||||||
}
|
}
|
||||||
if (moduleDef.providers) {
|
if (moduleDef.providers) {
|
||||||
this._providers = ListWrapper.concat(this._providers, moduleDef.providers);
|
this._providers = ListWrapper.concat(this._providers, moduleDef.providers);
|
||||||
}
|
}
|
||||||
if (moduleDef.directives) {
|
if (moduleDef.declarations) {
|
||||||
this._directives = ListWrapper.concat(this._directives, moduleDef.directives);
|
this._declarations = ListWrapper.concat(this._declarations, moduleDef.declarations);
|
||||||
}
|
}
|
||||||
if (moduleDef.pipes) {
|
if (moduleDef.imports) {
|
||||||
this._pipes = ListWrapper.concat(this._pipes, moduleDef.pipes);
|
this._imports = ListWrapper.concat(this._imports, moduleDef.imports);
|
||||||
}
|
}
|
||||||
if (moduleDef.precompile) {
|
if (moduleDef.precompile) {
|
||||||
this._precompile = ListWrapper.concat(this._precompile, moduleDef.precompile);
|
this._precompile = ListWrapper.concat(this._precompile, moduleDef.precompile);
|
||||||
}
|
}
|
||||||
if (moduleDef.modules) {
|
|
||||||
this._modules = ListWrapper.concat(this._modules, moduleDef.modules);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
createAppModuleFactory(): Promise<AppModuleFactory<any>> {
|
createModuleFactory(): Promise<NgModuleFactory<any>> {
|
||||||
if (this._instantiated) {
|
if (this._instantiated) {
|
||||||
throw new BaseException(
|
throw new BaseException(
|
||||||
'Cannot run precompilation when the test AppModule has already been instantiated. ' +
|
'Cannot run precompilation when the test NgModule has already been instantiated. ' +
|
||||||
'Make sure you are not using `inject` before `doAsyncPrecompilation`.');
|
'Make sure you are not using `inject` before `doAsyncPrecompilation`.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._appModuleFactory) {
|
if (this._ngModuleFactory) {
|
||||||
return Promise.resolve(this._appModuleFactory);
|
return Promise.resolve(this._ngModuleFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
let moduleMeta = this._createCompilerAndModuleMeta();
|
const moduleType = this._createCompilerAndModule();
|
||||||
|
|
||||||
return this._compiler.compileAppModuleAsync(_NoopModule, moduleMeta)
|
return this._compiler.compileModuleAsync(moduleType).then((ngModuleFactory) => {
|
||||||
.then((appModuleFactory) => {
|
this._ngModuleFactory = ngModuleFactory;
|
||||||
this._appModuleFactory = appModuleFactory;
|
return ngModuleFactory;
|
||||||
return appModuleFactory;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
initTestAppModule() {
|
initTestModule() {
|
||||||
if (this._instantiated) {
|
if (this._instantiated) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._appModuleFactory) {
|
if (this._ngModuleFactory) {
|
||||||
this._createFromModuleFactory(this._appModuleFactory);
|
this._createFromModuleFactory(this._ngModuleFactory);
|
||||||
} else {
|
} else {
|
||||||
let moduleMeta = this._createCompilerAndModuleMeta();
|
let moduleType = this._createCompilerAndModule();
|
||||||
this._createFromModuleFactory(this._compiler.compileAppModuleSync(_NoopModule, moduleMeta));
|
this._createFromModuleFactory(this._compiler.compileModuleSync(moduleType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,31 +113,34 @@ export class TestBed implements Injector {
|
|||||||
if (this._instantiated) {
|
if (this._instantiated) {
|
||||||
return Promise.resolve(this);
|
return Promise.resolve(this);
|
||||||
}
|
}
|
||||||
let moduleMeta = this._createCompilerAndModuleMeta();
|
let ngModule = this._createCompilerAndModule();
|
||||||
return this._compiler.compileAppModuleAsync(_NoopModule, moduleMeta)
|
return this._compiler.compileModuleAsync(ngModule).then(
|
||||||
.then((appModuleFactory) => this._createFromModuleFactory(appModuleFactory));
|
(ngModuleFactory) => this._createFromModuleFactory(ngModuleFactory));
|
||||||
|
}
|
||||||
|
|
||||||
|
private _createCompilerAndModule(): ConcreteType<any> {
|
||||||
|
const providers = this._providers.concat([{provide: TestBed, useValue: this}]);
|
||||||
|
const declarations = this._declarations;
|
||||||
|
const imports = [this.ngModule, this._imports];
|
||||||
|
const precompile = this._precompile;
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
providers: providers,
|
||||||
|
declarations: declarations,
|
||||||
|
imports: imports,
|
||||||
|
precompile: precompile
|
||||||
|
})
|
||||||
|
class DynamicTestModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
private _createCompilerAndModuleMeta(): AppModuleMetadata {
|
|
||||||
const compilerFactory: CompilerFactory = this.platform.injector.get(CompilerFactory);
|
const compilerFactory: CompilerFactory = this.platform.injector.get(CompilerFactory);
|
||||||
this._compiler = compilerFactory.createCompiler({
|
this._compiler =
|
||||||
providers: this._compilerProviders,
|
compilerFactory.createCompiler(this._compilerOptions.concat([{useDebug: true}]));
|
||||||
useJit: this._compilerUseJit,
|
return DynamicTestModule;
|
||||||
deprecatedAppProviders: this._providers
|
|
||||||
});
|
|
||||||
const moduleMeta = new AppModuleMetadata({
|
|
||||||
providers: this._providers.concat([{provide: TestBed, useValue: this}]),
|
|
||||||
modules: this._modules.concat([this.appModule]),
|
|
||||||
directives: this._directives,
|
|
||||||
pipes: this._pipes,
|
|
||||||
precompile: this._precompile
|
|
||||||
});
|
|
||||||
|
|
||||||
return moduleMeta;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private _createFromModuleFactory(appModuleFactory: AppModuleFactory<any>): Injector {
|
private _createFromModuleFactory(ngModuleFactory: NgModuleFactory<any>): Injector {
|
||||||
this._moduleRef = appModuleFactory.create(this.platform.injector);
|
this._moduleRef = ngModuleFactory.create(this.platform.injector);
|
||||||
this._instantiated = true;
|
this._instantiated = true;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -163,13 +148,13 @@ export class TestBed implements Injector {
|
|||||||
get(token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND) {
|
get(token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND) {
|
||||||
if (!this._instantiated) {
|
if (!this._instantiated) {
|
||||||
throw new BaseException(
|
throw new BaseException(
|
||||||
'Illegal state: The test bed\'s injector has not yet been created. Call initTestAppModule first!');
|
'Illegal state: The test bed\'s injector has not yet been created. Call initTestNgModule first!');
|
||||||
}
|
}
|
||||||
if (token === TestBed) {
|
if (token === TestBed) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
// Tests can inject things from the app module and from the compiler,
|
// Tests can inject things from the ng module and from the compiler,
|
||||||
// but the app module can't inject things from the compiler and vice versa.
|
// but the ng module can't inject things from the compiler and vice versa.
|
||||||
let result = this._moduleRef.injector.get(token, UNDEFINED);
|
let result = this._moduleRef.injector.get(token, UNDEFINED);
|
||||||
return result === UNDEFINED ? this._compiler.injector.get(token, notFoundValue) : result;
|
return result === UNDEFINED ? this._compiler.injector.get(token, notFoundValue) : result;
|
||||||
}
|
}
|
||||||
@ -177,7 +162,7 @@ export class TestBed implements Injector {
|
|||||||
execute(tokens: any[], fn: Function): any {
|
execute(tokens: any[], fn: Function): any {
|
||||||
if (!this._instantiated) {
|
if (!this._instantiated) {
|
||||||
throw new BaseException(
|
throw new BaseException(
|
||||||
'Illegal state: The test bed\'s injector has not yet been created. Call initTestAppModule first!');
|
'Illegal state: The test bed\'s injector has not yet been created. Call initTestNgModule first!');
|
||||||
}
|
}
|
||||||
var params = tokens.map(t => this.get(t));
|
var params = tokens.map(t => this.get(t));
|
||||||
return FunctionWrapper.apply(fn, params);
|
return FunctionWrapper.apply(fn, params);
|
||||||
@ -219,20 +204,17 @@ export function getTestInjector() {
|
|||||||
export function setBaseTestProviders(
|
export function setBaseTestProviders(
|
||||||
platformProviders: Array<Type|Provider|any[]>,
|
platformProviders: Array<Type|Provider|any[]>,
|
||||||
applicationProviders: Array<Type|Provider|any[]>) {
|
applicationProviders: Array<Type|Provider|any[]>) {
|
||||||
// Create a platform based on the Platform Providers.
|
if (platformProviders.length === 1 && typeof platformProviders[0] === 'function') {
|
||||||
var platformRef = createPlatform(ReflectiveInjector.resolveAndCreate(platformProviders));
|
(<any>platformProviders[0])(applicationProviders);
|
||||||
|
} else {
|
||||||
// Create an AppModule based on the application providers.
|
throw new Error(
|
||||||
@AppModule({providers: applicationProviders})
|
`setBaseTestProviders is deprecated and only supports platformProviders that are predefined by Angular. Use 'initTestEnvironment' instead.`);
|
||||||
class TestAppModule {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
initTestEnvironment(TestAppModule, platformRef);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the environment for testing with a compiler factory, a PlatformRef, and an
|
* Initialize the environment for testing with a compiler factory, a PlatformRef, and an
|
||||||
* application module. These are common to every test in the suite.
|
* angular module. These are common to every test in the suite.
|
||||||
*
|
*
|
||||||
* This may only be called once, to set up the common providers for the current test
|
* This may only be called once, to set up the common providers for the current test
|
||||||
* suite on the current platform. If you absolutely need to change the providers,
|
* suite on the current platform. If you absolutely need to change the providers,
|
||||||
@ -243,13 +225,15 @@ export function setBaseTestProviders(
|
|||||||
*
|
*
|
||||||
* @experimental
|
* @experimental
|
||||||
*/
|
*/
|
||||||
export function initTestEnvironment(appModule: Type, platform: PlatformRef) {
|
export function initTestEnvironment(ngModule: Type, platform: PlatformRef): Injector {
|
||||||
var testBed = getTestBed();
|
var testBed = getTestBed();
|
||||||
if (testBed.platform || testBed.appModule) {
|
if (testBed.platform || testBed.ngModule) {
|
||||||
throw new BaseException('Cannot set base providers because it has already been called');
|
throw new BaseException('Cannot set base providers because it has already been called');
|
||||||
}
|
}
|
||||||
testBed.platform = platform;
|
testBed.platform = platform;
|
||||||
testBed.appModule = appModule;
|
testBed.ngModule = ngModule;
|
||||||
|
|
||||||
|
return testBed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -269,20 +253,20 @@ export function resetBaseTestProviders() {
|
|||||||
export function resetTestEnvironment() {
|
export function resetTestEnvironment() {
|
||||||
var testBed = getTestBed();
|
var testBed = getTestBed();
|
||||||
testBed.platform = null;
|
testBed.platform = null;
|
||||||
testBed.appModule = null;
|
testBed.ngModule = null;
|
||||||
testBed.reset();
|
testBed.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run asynchronous precompilation for the test's AppModule. It is necessary to call this function
|
* Run asynchronous precompilation for the test's NgModule. It is necessary to call this function
|
||||||
* if your test is using an AppModule which has precompiled components that require an asynchronous
|
* if your test is using an NgModule which has precompiled components that require an asynchronous
|
||||||
* call, such as an XHR. Should be called once before the test case.
|
* call, such as an XHR. Should be called once before the test case.
|
||||||
*
|
*
|
||||||
* @experimental
|
* @experimental
|
||||||
*/
|
*/
|
||||||
export function doAsyncPrecompilation(): Promise<any> {
|
export function doAsyncPrecompilation(): Promise<any> {
|
||||||
let testBed = getTestBed();
|
let testBed = getTestBed();
|
||||||
return testBed.createAppModuleFactory();
|
return testBed.createModuleFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -324,7 +308,7 @@ export function inject(tokens: any[], fn: Function): () => any {
|
|||||||
} else {
|
} else {
|
||||||
return () => {
|
return () => {
|
||||||
try {
|
try {
|
||||||
testBed.initTestAppModule();
|
testBed.initTestModule();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof ComponentStillLoadingError) {
|
if (e instanceof ComponentStillLoadingError) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@ -343,13 +327,9 @@ export function inject(tokens: any[], fn: Function): () => any {
|
|||||||
* @experimental
|
* @experimental
|
||||||
*/
|
*/
|
||||||
export class InjectSetupWrapper {
|
export class InjectSetupWrapper {
|
||||||
constructor(private _moduleDef: () => {
|
constructor(
|
||||||
providers?: any[],
|
private _moduleDef:
|
||||||
directives?: any[],
|
() => {providers?: any[], declarations?: any[], imports?: any[], precompile?: any[]}) {}
|
||||||
pipes?: any[],
|
|
||||||
precompile?: any[],
|
|
||||||
modules?: any[]
|
|
||||||
}) {}
|
|
||||||
|
|
||||||
private _addModule() {
|
private _addModule() {
|
||||||
var moduleDef = this._moduleDef();
|
var moduleDef = this._moduleDef();
|
||||||
@ -378,12 +358,9 @@ export function withProviders(providers: () => any) {
|
|||||||
*/
|
*/
|
||||||
export function withModule(moduleDef: () => {
|
export function withModule(moduleDef: () => {
|
||||||
providers?: any[],
|
providers?: any[],
|
||||||
directives?: any[],
|
declarations?: any[],
|
||||||
pipes?: any[],
|
imports?: any[],
|
||||||
precompile?: any[],
|
precompile?: any[]
|
||||||
modules?: any[]
|
|
||||||
}) {
|
}) {
|
||||||
return new InjectSetupWrapper(moduleDef);
|
return new InjectSetupWrapper(moduleDef);
|
||||||
}
|
}
|
||||||
|
|
||||||
class _NoopModule {}
|
|
||||||
|
@ -119,25 +119,27 @@ export class TestComponentBuilder {
|
|||||||
/**
|
/**
|
||||||
* Builds and returns a ComponentFixture.
|
* Builds and returns a ComponentFixture.
|
||||||
*/
|
*/
|
||||||
createAsync<T>(rootComponentType: ConcreteType<T>): Promise<ComponentFixture<T>> {
|
createAsync<T>(rootComponentType: ConcreteType<T>, ngModule: ConcreteType<any> = null):
|
||||||
|
Promise<ComponentFixture<T>> {
|
||||||
let noNgZone = IS_DART || this._injector.get(ComponentFixtureNoNgZone, false);
|
let noNgZone = IS_DART || this._injector.get(ComponentFixtureNoNgZone, false);
|
||||||
let ngZone: NgZone = noNgZone ? null : this._injector.get(NgZone, null);
|
let ngZone: NgZone = noNgZone ? null : this._injector.get(NgZone, null);
|
||||||
let compiler: Compiler = this._injector.get(Compiler);
|
let compiler: Compiler = this._injector.get(Compiler);
|
||||||
|
|
||||||
let initComponent = () => {
|
let initComponent = () => {
|
||||||
let promise: Promise<ComponentFactory<any>> =
|
let promise: Promise<ComponentFactory<any>> =
|
||||||
compiler.compileComponentAsync(rootComponentType);
|
compiler.compileComponentAsync(rootComponentType, ngModule);
|
||||||
return promise.then(componentFactory => this.createFromFactory(ngZone, componentFactory));
|
return promise.then(componentFactory => this.createFromFactory(ngZone, componentFactory));
|
||||||
};
|
};
|
||||||
|
|
||||||
return ngZone == null ? initComponent() : ngZone.run(initComponent);
|
return ngZone == null ? initComponent() : ngZone.run(initComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
createFakeAsync<T>(rootComponentType: ConcreteType<T>): ComponentFixture<T> {
|
createFakeAsync<T>(rootComponentType: ConcreteType<T>, ngModule: ConcreteType<any> = null):
|
||||||
|
ComponentFixture<T> {
|
||||||
let result: any /** TODO #9100 */;
|
let result: any /** TODO #9100 */;
|
||||||
let error: any /** TODO #9100 */;
|
let error: any /** TODO #9100 */;
|
||||||
PromiseWrapper.then(
|
PromiseWrapper.then(
|
||||||
this.createAsync(rootComponentType), (_result) => { result = _result; },
|
this.createAsync(rootComponentType, ngModule), (_result) => { result = _result; },
|
||||||
(_error) => { error = _error; });
|
(_error) => { error = _error; });
|
||||||
tick();
|
tick();
|
||||||
if (isPresent(error)) {
|
if (isPresent(error)) {
|
||||||
@ -146,14 +148,15 @@ export class TestComponentBuilder {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
createSync<T>(rootComponentType: ConcreteType<T>): ComponentFixture<T> {
|
createSync<T>(rootComponentType: ConcreteType<T>, ngModule: ConcreteType<any> = null):
|
||||||
|
ComponentFixture<T> {
|
||||||
let noNgZone = IS_DART || this._injector.get(ComponentFixtureNoNgZone, false);
|
let noNgZone = IS_DART || this._injector.get(ComponentFixtureNoNgZone, false);
|
||||||
let ngZone: NgZone = noNgZone ? null : this._injector.get(NgZone, null);
|
let ngZone: NgZone = noNgZone ? null : this._injector.get(NgZone, null);
|
||||||
let compiler: Compiler = this._injector.get(Compiler);
|
let compiler: Compiler = this._injector.get(Compiler);
|
||||||
|
|
||||||
let initComponent = () => {
|
let initComponent = () => {
|
||||||
return this.createFromFactory(
|
return this.createFromFactory(
|
||||||
ngZone, this._injector.get(Compiler).compileComponentSync(rootComponentType));
|
ngZone, compiler.compileComponentSync(rootComponentType, ngModule));
|
||||||
};
|
};
|
||||||
|
|
||||||
return ngZone == null ? initComponent() : ngZone.run(initComponent);
|
return ngZone == null ? initComponent() : ngZone.run(initComponent);
|
||||||
|
@ -49,13 +49,9 @@ export function addProviders(providers: Array<any>): void {
|
|||||||
*
|
*
|
||||||
* @stable
|
* @stable
|
||||||
*/
|
*/
|
||||||
export function configureModule(moduleDef: {
|
export function configureModule(
|
||||||
providers?: any[],
|
moduleDef: {providers?: any[], declarations?: any[], imports?: any[], precompile?: any[]}):
|
||||||
directives?: any[],
|
void {
|
||||||
pipes?: any[],
|
|
||||||
precompile?: any[],
|
|
||||||
modules?: any[]
|
|
||||||
}): void {
|
|
||||||
if (!moduleDef) return;
|
if (!moduleDef) return;
|
||||||
try {
|
try {
|
||||||
testBed.configureModule(moduleDef);
|
testBed.configureModule(moduleDef);
|
||||||
|
@ -6,8 +6,9 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {Component, ReflectiveInjector, coreLoadAndBootstrap, createPlatform} from '@angular/core';
|
import {Component, ReflectiveInjector, bootstrapModule, createPlatformFactory} from '@angular/core';
|
||||||
import {BROWSER_APP_PROVIDERS, BROWSER_PLATFORM_PROVIDERS} from '@angular/platform-browser';
|
import {BrowserModule} from '@angular/platform-browser';
|
||||||
|
import {browserDynamicPlatform} from '@angular/platform-browser-dynamic';
|
||||||
|
|
||||||
var appProviders: any[] = [];
|
var appProviders: any[] = [];
|
||||||
|
|
||||||
@ -16,8 +17,6 @@ var appProviders: any[] = [];
|
|||||||
class MyApp {
|
class MyApp {
|
||||||
}
|
}
|
||||||
|
|
||||||
var platform = createPlatform(ReflectiveInjector.resolveAndCreate(BROWSER_PLATFORM_PROVIDERS));
|
var myPlatformFactory = createPlatformFactory(browserDynamicPlatform, 'myPlatform');
|
||||||
var appInjector =
|
bootstrapModule(MyApp, myPlatformFactory());
|
||||||
ReflectiveInjector.resolveAndCreate([BROWSER_APP_PROVIDERS, appProviders], platform.injector);
|
|
||||||
coreLoadAndBootstrap(MyApp, appInjector);
|
|
||||||
// #enddocregion
|
// #enddocregion
|
||||||
|
@ -155,12 +155,12 @@ export function stringify(token: any): string {
|
|||||||
return '' + token;
|
return '' + token;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token.name) {
|
|
||||||
return token.name;
|
|
||||||
}
|
|
||||||
if (token.overriddenName) {
|
if (token.overriddenName) {
|
||||||
return token.overriddenName;
|
return token.overriddenName;
|
||||||
}
|
}
|
||||||
|
if (token.name) {
|
||||||
|
return token.name;
|
||||||
|
}
|
||||||
|
|
||||||
var res = token.toString();
|
var res = token.toString();
|
||||||
var newLineIndex = res.indexOf('\n');
|
var newLineIndex = res.indexOf('\n');
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {Type} from '@angular/core';
|
import {NgModule, Type} from '@angular/core';
|
||||||
|
|
||||||
import {CheckboxControlValueAccessor} from './directives/checkbox_value_accessor';
|
import {CheckboxControlValueAccessor} from './directives/checkbox_value_accessor';
|
||||||
import {DefaultValueAccessor} from './directives/default_value_accessor';
|
import {DefaultValueAccessor} from './directives/default_value_accessor';
|
||||||
@ -83,3 +83,10 @@ export const FORM_DIRECTIVES: Type[][] =
|
|||||||
|
|
||||||
export const REACTIVE_FORM_DIRECTIVES: Type[][] =
|
export const REACTIVE_FORM_DIRECTIVES: Type[][] =
|
||||||
/*@ts2dart_const*/[REACTIVE_DRIVEN_DIRECTIVES, SHARED_FORM_DIRECTIVES];
|
/*@ts2dart_const*/[REACTIVE_DRIVEN_DIRECTIVES, SHARED_FORM_DIRECTIVES];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal module used for sharing directives between FormsModule and ReactiveFormsModule
|
||||||
|
*/
|
||||||
|
@NgModule({declarations: SHARED_FORM_DIRECTIVES, exports: SHARED_FORM_DIRECTIVES})
|
||||||
|
export class InternalFormsSharedModule {
|
||||||
|
}
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {AppModule, PLATFORM_DIRECTIVES, Type} from '@angular/core';
|
import {NgModule, PLATFORM_DIRECTIVES, Type} from '@angular/core';
|
||||||
|
|
||||||
import {FORM_DIRECTIVES, REACTIVE_FORM_DIRECTIVES} from './directives';
|
import {FORM_DIRECTIVES, InternalFormsSharedModule, REACTIVE_DRIVEN_DIRECTIVES, REACTIVE_FORM_DIRECTIVES, SHARED_FORM_DIRECTIVES, TEMPLATE_DRIVEN_DIRECTIVES} from './directives';
|
||||||
import {RadioControlRegistry} from './directives/radio_control_value_accessor';
|
import {RadioControlRegistry} from './directives/radio_control_value_accessor';
|
||||||
import {FormBuilder} from './form_builder';
|
import {FormBuilder} from './form_builder';
|
||||||
|
|
||||||
@ -28,18 +28,26 @@ export const REACTIVE_FORM_PROVIDERS: Type[] =
|
|||||||
/*@ts2dart_const*/[FormBuilder, RadioControlRegistry];
|
/*@ts2dart_const*/[FormBuilder, RadioControlRegistry];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The app module for forms.
|
* The ng module for forms.
|
||||||
* @experimental
|
* @experimental
|
||||||
*/
|
*/
|
||||||
@AppModule({providers: [FORM_PROVIDERS], directives: FORM_DIRECTIVES, pipes: []})
|
@NgModule({
|
||||||
|
declarations: TEMPLATE_DRIVEN_DIRECTIVES,
|
||||||
|
providers: [FORM_PROVIDERS],
|
||||||
|
exports: [InternalFormsSharedModule, TEMPLATE_DRIVEN_DIRECTIVES]
|
||||||
|
})
|
||||||
export class FormsModule {
|
export class FormsModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The app module for reactive forms.
|
* The ng module for reactive forms.
|
||||||
* @experimental
|
* @experimental
|
||||||
*/
|
*/
|
||||||
@AppModule({providers: [REACTIVE_FORM_PROVIDERS], directives: REACTIVE_FORM_DIRECTIVES, pipes: []})
|
@NgModule({
|
||||||
|
declarations: [REACTIVE_DRIVEN_DIRECTIVES],
|
||||||
|
providers: [REACTIVE_FORM_PROVIDERS],
|
||||||
|
exports: [InternalFormsSharedModule, REACTIVE_DRIVEN_DIRECTIVES]
|
||||||
|
})
|
||||||
export class ReactiveFormsModule {
|
export class ReactiveFormsModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ import {PromiseWrapper} from '../src/facade/promise';
|
|||||||
export function main() {
|
export function main() {
|
||||||
describe('reactive forms integration tests', () => {
|
describe('reactive forms integration tests', () => {
|
||||||
|
|
||||||
beforeEach(() => { configureModule({modules: [FormsModule, ReactiveFormsModule]}); });
|
beforeEach(() => { configureModule({imports: [FormsModule, ReactiveFormsModule]}); });
|
||||||
|
|
||||||
it('should initialize DOM elements with the given form object',
|
it('should initialize DOM elements with the given form object',
|
||||||
inject(
|
inject(
|
||||||
|
@ -20,7 +20,7 @@ import {ListWrapper} from '../src/facade/collection';
|
|||||||
export function main() {
|
export function main() {
|
||||||
describe('template-driven forms integration tests', () => {
|
describe('template-driven forms integration tests', () => {
|
||||||
|
|
||||||
beforeEach(() => { configureModule({modules: [FormsModule]}); });
|
beforeEach(() => { configureModule({imports: [FormsModule]}); });
|
||||||
|
|
||||||
it('should support ngModel for single fields',
|
it('should support ngModel for single fields',
|
||||||
fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||||
|
@ -6,37 +6,24 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {COMMON_DIRECTIVES, COMMON_PIPES} from '@angular/common';
|
import {XHR, analyzeAppProvidersForDeprecatedConfiguration, coreDynamicPlatform} from '@angular/compiler';
|
||||||
import {COMPILER_PROVIDERS, CompilerConfig, XHR, RUNTIME_COMPILER_FACTORY,} from '@angular/compiler';
|
import {ApplicationRef, Compiler, CompilerFactory, CompilerOptions, ComponentRef, ComponentResolver, ExceptionHandler, NgModule, NgModuleRef, OpaqueToken, PLATFORM_DIRECTIVES, PLATFORM_INITIALIZER, PLATFORM_PIPES, PlatformRef, ReflectiveInjector, Type, assertPlatform, bootstrapModule, bootstrapModuleFactory, createPlatform, createPlatformFactory, getPlatform, isDevMode} from '@angular/core';
|
||||||
import {AppModule, AppModuleRef, ApplicationRef, Compiler, ComponentRef, ComponentResolver, ExceptionHandler, PLATFORM_DIRECTIVES, PLATFORM_PIPES, ReflectiveInjector, Type, coreLoadAndBootstrap, bootstrapModule, bootstrapModuleFactory, isDevMode, OpaqueToken, PlatformRef, getPlatform, assertPlatform, createPlatform, PLATFORM_INITIALIZER, CompilerOptions, CompilerFactory, createPlatformFactory} from '@angular/core';
|
import {BROWSER_PLATFORM_PROVIDERS, BrowserModule, WORKER_APP_PLATFORM_PROVIDERS, WORKER_SCRIPT, WorkerAppModule, browserPlatform, workerAppPlatform, workerUiPlatform} from '@angular/platform-browser';
|
||||||
import {BROWSER_APP_PROVIDERS, BrowserModule, WORKER_APP_APPLICATION_PROVIDERS, WORKER_SCRIPT, WORKER_UI_APPLICATION_PROVIDERS, browserPlatform, workerAppPlatform, workerUiPlatform, BROWSER_PLATFORM_PROVIDERS} from '@angular/platform-browser';
|
|
||||||
|
|
||||||
import {Console, ReflectionCapabilities, reflector} from './core_private';
|
import {Console} from './core_private';
|
||||||
import {getDOM, initDomAdapter} from './platform_browser_private';
|
|
||||||
import {PromiseWrapper} from './src/facade/async';
|
import {PromiseWrapper} from './src/facade/async';
|
||||||
import {ConcreteType, isPresent, stringify} from './src/facade/lang';
|
import {ConcreteType, isPresent, stringify} from './src/facade/lang';
|
||||||
|
import {INTERNAL_BROWSER_DYNAMIC_PLATFORM_PROVIDERS} from './src/platform_providers';
|
||||||
import {CachedXHR} from './src/xhr/xhr_cache';
|
import {CachedXHR} from './src/xhr/xhr_cache';
|
||||||
import {XHRImpl} from './src/xhr/xhr_impl';
|
import {XHRImpl} from './src/xhr/xhr_impl';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated The compiler providers are already included in the {@link CompilerFactory} that is
|
* @deprecated The compiler providers are already included in the {@link CompilerFactory} that is
|
||||||
* contained the {@link browserDynamicPlatform}()`.
|
* contained the {@link browserDynamicPlatform}()`.
|
||||||
*/
|
*/
|
||||||
export const BROWSER_APP_COMPILER_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
|
export const BROWSER_APP_COMPILER_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [];
|
||||||
COMPILER_PROVIDERS, {
|
|
||||||
provide: CompilerConfig,
|
|
||||||
useFactory: (platformDirectives: any[], platformPipes: any[]) => {
|
|
||||||
return new CompilerConfig({
|
|
||||||
deprecatedPlatformDirectives: platformDirectives,
|
|
||||||
deprecatedPlatformPipes: platformPipes
|
|
||||||
});
|
|
||||||
},
|
|
||||||
deps: [PLATFORM_DIRECTIVES, PLATFORM_PIPES]
|
|
||||||
},
|
|
||||||
{provide: XHR, useClass: XHRImpl},
|
|
||||||
{provide: PLATFORM_DIRECTIVES, useValue: COMMON_DIRECTIVES, multi: true},
|
|
||||||
{provide: PLATFORM_PIPES, useValue: COMMON_PIPES, multi: true}
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @experimental
|
* @experimental
|
||||||
@ -44,34 +31,11 @@ export const BROWSER_APP_COMPILER_PROVIDERS: Array<any /*Type | Provider | any[]
|
|||||||
export const CACHED_TEMPLATE_PROVIDER: Array<any /*Type | Provider | any[]*/> =
|
export const CACHED_TEMPLATE_PROVIDER: Array<any /*Type | Provider | any[]*/> =
|
||||||
[{provide: XHR, useClass: CachedXHR}];
|
[{provide: XHR, useClass: CachedXHR}];
|
||||||
|
|
||||||
function initReflector() {
|
|
||||||
reflector.reflectionCapabilities = new ReflectionCapabilities();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CompilerFactory for the browser dynamic platform
|
|
||||||
*
|
|
||||||
* @experimental
|
|
||||||
*/
|
|
||||||
export const BROWSER_DYNAMIC_COMPILER_FACTORY =
|
|
||||||
RUNTIME_COMPILER_FACTORY.withDefaults({providers: [{provide: XHR, useClass: XHRImpl}]});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Providers for the browser dynamic platform
|
|
||||||
*
|
|
||||||
* @experimental
|
|
||||||
*/
|
|
||||||
export const BROWSER_DYNAMIC_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
|
|
||||||
BROWSER_PLATFORM_PROVIDERS,
|
|
||||||
{provide: CompilerFactory, useValue: BROWSER_DYNAMIC_COMPILER_FACTORY},
|
|
||||||
{provide: PLATFORM_INITIALIZER, useValue: initReflector, multi: true},
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @experimental API related to bootstrapping are still under review.
|
* @experimental API related to bootstrapping are still under review.
|
||||||
*/
|
*/
|
||||||
export const browserDynamicPlatform =
|
export const browserDynamicPlatform = createPlatformFactory(
|
||||||
createPlatformFactory('browserDynamic', BROWSER_DYNAMIC_PLATFORM_PROVIDERS);
|
coreDynamicPlatform, 'browserDynamic', INTERNAL_BROWSER_DYNAMIC_PLATFORM_PROVIDERS);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bootstrapping for Angular applications.
|
* Bootstrapping for Angular applications.
|
||||||
@ -142,8 +106,9 @@ export const browserDynamicPlatform =
|
|||||||
* ## API (version 2)
|
* ## API (version 2)
|
||||||
* - `appComponentType`: The root component which should act as the application. This is
|
* - `appComponentType`: The root component which should act as the application. This is
|
||||||
* a reference to a `Type` which is annotated with `@Component(...)`.
|
* a reference to a `Type` which is annotated with `@Component(...)`.
|
||||||
* - `providers`, `directives`, `pipes`, `modules`, `precompile`: Defines the properties
|
* - `providers`, `declarations`, `imports`, `precompile`: Defines the properties
|
||||||
* of the dynamically created module that is used to bootstrap the module.
|
* of the dynamically created module that is used to bootstrap the module.
|
||||||
|
* - to configure the compiler, use the `compilerOptions` parameter.
|
||||||
*
|
*
|
||||||
* Returns a `Promise` of {@link ComponentRef}.
|
* Returns a `Promise` of {@link ComponentRef}.
|
||||||
*
|
*
|
||||||
@ -156,11 +121,10 @@ export function bootstrap<C>(
|
|||||||
customProviders?: Array<any /*Type | Provider | any[]*/>): Promise<ComponentRef<C>>;
|
customProviders?: Array<any /*Type | Provider | any[]*/>): Promise<ComponentRef<C>>;
|
||||||
export function bootstrap<C>(
|
export function bootstrap<C>(
|
||||||
appComponentType: ConcreteType<C>,
|
appComponentType: ConcreteType<C>,
|
||||||
{providers, directives, pipes, modules, precompile, compilerOptions}?: {
|
{providers, imports, declarations, precompile, compilerOptions}?: {
|
||||||
providers?: Array<any /*Type | Provider | any[]*/>,
|
providers?: Array<any /*Type | Provider | any[]*/>,
|
||||||
directives?: any[],
|
declarations?: any[],
|
||||||
pipes?: any[],
|
imports?: any[],
|
||||||
modules?: any[],
|
|
||||||
precompile?: any[],
|
precompile?: any[],
|
||||||
compilerOptions?: CompilerOptions
|
compilerOptions?: CompilerOptions
|
||||||
}): Promise<ComponentRef<C>>;
|
}): Promise<ComponentRef<C>>;
|
||||||
@ -168,110 +132,105 @@ export function bootstrap<C>(
|
|||||||
appComponentType: ConcreteType<C>,
|
appComponentType: ConcreteType<C>,
|
||||||
customProvidersOrDynamicModule?: Array<any /*Type | Provider | any[]*/>| {
|
customProvidersOrDynamicModule?: Array<any /*Type | Provider | any[]*/>| {
|
||||||
providers: Array<any /*Type | Provider | any[]*/>,
|
providers: Array<any /*Type | Provider | any[]*/>,
|
||||||
directives: any[],
|
declarations?: any[],
|
||||||
pipes: any[],
|
imports: any[],
|
||||||
modules: any[],
|
|
||||||
precompile: any[],
|
precompile: any[],
|
||||||
compilerOptions: CompilerOptions
|
compilerOptions: CompilerOptions
|
||||||
}): Promise<ComponentRef<C>> {
|
}): Promise<ComponentRef<C>> {
|
||||||
let compilerOptions: CompilerOptions;
|
let compilerOptions: CompilerOptions;
|
||||||
let compilerProviders: any = [];
|
|
||||||
let providers: any[] = [];
|
let providers: any[] = [];
|
||||||
let directives: any[] = [];
|
let declarations: any[] = [];
|
||||||
let pipes: any[] = [];
|
let imports: any[] = [];
|
||||||
let modules: any[] = [];
|
|
||||||
let precompile: any[] = [];
|
let precompile: any[] = [];
|
||||||
|
let deprecationMessages: string[] = [];
|
||||||
if (customProvidersOrDynamicModule instanceof Array) {
|
if (customProvidersOrDynamicModule instanceof Array) {
|
||||||
providers = customProvidersOrDynamicModule;
|
providers = customProvidersOrDynamicModule;
|
||||||
|
const deprecatedConfiguration = analyzeAppProvidersForDeprecatedConfiguration(providers);
|
||||||
|
declarations = deprecatedConfiguration.moduleDeclarations.concat(declarations);
|
||||||
|
compilerOptions = deprecatedConfiguration.compilerOptions;
|
||||||
|
deprecationMessages = deprecatedConfiguration.deprecationMessages;
|
||||||
} else if (customProvidersOrDynamicModule) {
|
} else if (customProvidersOrDynamicModule) {
|
||||||
providers = normalizeArray(customProvidersOrDynamicModule.providers);
|
providers = normalizeArray(customProvidersOrDynamicModule.providers);
|
||||||
directives = normalizeArray(customProvidersOrDynamicModule.directives);
|
declarations = normalizeArray(customProvidersOrDynamicModule.declarations);
|
||||||
pipes = normalizeArray(customProvidersOrDynamicModule.pipes);
|
imports = normalizeArray(customProvidersOrDynamicModule.imports);
|
||||||
modules = normalizeArray(customProvidersOrDynamicModule.modules);
|
|
||||||
precompile = normalizeArray(customProvidersOrDynamicModule.precompile);
|
precompile = normalizeArray(customProvidersOrDynamicModule.precompile);
|
||||||
compilerOptions = customProvidersOrDynamicModule.compilerOptions;
|
compilerOptions = customProvidersOrDynamicModule.compilerOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@AppModule({
|
@NgModule({
|
||||||
providers: providers,
|
providers: providers,
|
||||||
modules: modules.concat([BrowserModule]),
|
declarations: declarations.concat([appComponentType]),
|
||||||
directives: directives,
|
imports: [BrowserModule, imports],
|
||||||
pipes: pipes,
|
|
||||||
precompile: precompile.concat([appComponentType])
|
precompile: precompile.concat([appComponentType])
|
||||||
})
|
})
|
||||||
class DynamicModule {
|
class DynamicModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
return bootstrapModule(
|
return bootstrapModule(DynamicModule, browserDynamicPlatform(), compilerOptions)
|
||||||
DynamicModule, browserDynamicPlatform(),
|
|
||||||
CompilerFactory.mergeOptions(compilerOptions, {deprecatedAppProviders: providers}))
|
|
||||||
.then((moduleRef) => {
|
.then((moduleRef) => {
|
||||||
|
const console = moduleRef.injector.get(Console);
|
||||||
|
deprecationMessages.forEach((msg) => console.warn(msg));
|
||||||
const appRef: ApplicationRef = moduleRef.injector.get(ApplicationRef);
|
const appRef: ApplicationRef = moduleRef.injector.get(ApplicationRef);
|
||||||
return appRef.bootstrap(appComponentType);
|
return appRef.bootstrap(appComponentType);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Create an {@link AppModule} that includes the {@link WorkerUiModule} and use {@link
|
* Bootstraps the worker ui.
|
||||||
* bootstrapModule}
|
*
|
||||||
* with the {@link workerUiPlatform}() instead.
|
* @experimental
|
||||||
*/
|
*/
|
||||||
export function bootstrapWorkerUi(
|
export function bootstrapWorkerUi(
|
||||||
workerScriptUri: string,
|
workerScriptUri: string,
|
||||||
customProviders?: Array<any /*Type | Provider | any[]*/>): Promise<ApplicationRef> {
|
customProviders: Array<any /*Type | Provider | any[]*/> = []): Promise<PlatformRef> {
|
||||||
console.warn(
|
// For now, just creates the worker ui platform...
|
||||||
'bootstrapWorkerUi is deprecated. Create an @AppModule that includes the `WorkerUiModule` and use `bootstrapModule` with the `workerUiPlatform()` instead.');
|
return Promise.resolve(workerUiPlatform([{
|
||||||
var app = ReflectiveInjector.resolveAndCreate(
|
provide: WORKER_SCRIPT,
|
||||||
[
|
useValue: workerScriptUri,
|
||||||
WORKER_UI_APPLICATION_PROVIDERS, BROWSER_APP_COMPILER_PROVIDERS,
|
}].concat(customProviders)));
|
||||||
{provide: WORKER_SCRIPT, useValue: workerScriptUri},
|
|
||||||
isPresent(customProviders) ? customProviders : []
|
|
||||||
],
|
|
||||||
workerUiPlatform().injector);
|
|
||||||
// Return a promise so that we keep the same semantics as Dart,
|
|
||||||
// and we might want to wait for the app side to come up
|
|
||||||
// in the future...
|
|
||||||
return PromiseWrapper.resolve(app.get(ApplicationRef));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated The compiler providers are already included in the {@link CompilerFactory} that is
|
* @experimental API related to bootstrapping are still under review.
|
||||||
* contained the {@link workerAppPlatform}().
|
|
||||||
*/
|
*/
|
||||||
const WORKER_APP_COMPILER_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
|
export const workerAppDynamicPlatform =
|
||||||
COMPILER_PROVIDERS, {
|
createPlatformFactory(coreDynamicPlatform, 'workerAppDynamic', [{
|
||||||
provide: CompilerConfig,
|
provide: CompilerOptions,
|
||||||
useFactory: (platformDirectives: any[], platformPipes: any[]) => {
|
useValue: {providers: [{provide: XHR, useClass: XHRImpl}]},
|
||||||
return new CompilerConfig({
|
multi: true
|
||||||
deprecatedPlatformDirectives: platformDirectives,
|
}]);
|
||||||
deprecatedPlatformPipes: platformPipes
|
|
||||||
});
|
|
||||||
},
|
|
||||||
deps: [PLATFORM_DIRECTIVES, PLATFORM_PIPES]
|
|
||||||
},
|
|
||||||
{provide: XHR, useClass: XHRImpl},
|
|
||||||
{provide: PLATFORM_DIRECTIVES, useValue: COMMON_DIRECTIVES, multi: true},
|
|
||||||
{provide: PLATFORM_PIPES, useValue: COMMON_PIPES, multi: true}
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Create an {@link AppModule} that includes the {@link WorkerAppModule} and use {@link
|
* @deprecated Create an {@link NgModule} that includes the {@link WorkerAppModule} and use {@link
|
||||||
* bootstrapModule}
|
* bootstrapModule}
|
||||||
* with the {@link workerAppPlatform}() instead.
|
* with the {@link workerAppDynamicPlatform}() instead.
|
||||||
*/
|
*/
|
||||||
export function bootstrapWorkerApp(
|
export function bootstrapWorkerApp<T>(
|
||||||
appComponentType: Type,
|
appComponentType: ConcreteType<T>,
|
||||||
customProviders?: Array<any /*Type | Provider | any[]*/>): Promise<ComponentRef<any>> {
|
customProviders?: Array<any /*Type | Provider | any[]*/>): Promise<ComponentRef<T>> {
|
||||||
console.warn(
|
console.warn(
|
||||||
'bootstrapWorkerApp is deprecated. Create an @AppModule that includes the `WorkerAppModule` and use `bootstrapModule` with the `workerAppPlatform()` instead.');
|
'bootstrapWorkerApp is deprecated. Create an @NgModule that includes the `WorkerAppModule` and use `bootstrapModule` with the `workerAppDynamicPlatform()` instead.');
|
||||||
var appInjector = ReflectiveInjector.resolveAndCreate(
|
|
||||||
[
|
const deprecatedConfiguration = analyzeAppProvidersForDeprecatedConfiguration(customProviders);
|
||||||
WORKER_APP_APPLICATION_PROVIDERS, WORKER_APP_COMPILER_PROVIDERS,
|
const declarations = [deprecatedConfiguration.moduleDeclarations.concat([appComponentType])];
|
||||||
isPresent(customProviders) ? customProviders : []
|
|
||||||
],
|
@NgModule({
|
||||||
workerAppPlatform().injector);
|
providers: customProviders,
|
||||||
return coreLoadAndBootstrap(appComponentType, appInjector);
|
declarations: declarations,
|
||||||
|
imports: [WorkerAppModule],
|
||||||
|
precompile: [appComponentType]
|
||||||
|
})
|
||||||
|
class DynamicModule {
|
||||||
|
}
|
||||||
|
|
||||||
|
return bootstrapModule(
|
||||||
|
DynamicModule, workerAppDynamicPlatform(), deprecatedConfiguration.compilerOptions)
|
||||||
|
.then((moduleRef) => {
|
||||||
|
const console = moduleRef.injector.get(Console);
|
||||||
|
deprecatedConfiguration.deprecationMessages.forEach((msg) => console.warn(msg));
|
||||||
|
const appRef: ApplicationRef = moduleRef.injector.get(ApplicationRef);
|
||||||
|
return appRef.bootstrap(appComponentType);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizeArray(arr: any[]): any[] {
|
function normalizeArray(arr: any[]): any[] {
|
||||||
|
@ -8,5 +8,6 @@
|
|||||||
|
|
||||||
import {__platform_browser_private__ as r, __platform_browser_private__ as t} from '@angular/platform-browser';
|
import {__platform_browser_private__ as r, __platform_browser_private__ as t} from '@angular/platform-browser';
|
||||||
|
|
||||||
|
export var INTERNAL_BROWSER_PLATFORM_PROVIDERS: typeof t.INTERNAL_BROWSER_PLATFORM_PROVIDERS =
|
||||||
|
r.INTERNAL_BROWSER_PLATFORM_PROVIDERS;
|
||||||
export var getDOM: typeof t.getDOM = r.getDOM;
|
export var getDOM: typeof t.getDOM = r.getDOM;
|
||||||
export var initDomAdapter: typeof t.initDomAdapter = r.initDomAdapter;
|
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright Google Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by an MIT-style license that can be
|
||||||
|
* found in the LICENSE file at https://angular.io/license
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {XHR} from '@angular/compiler';
|
||||||
|
import {CompilerOptions} from '@angular/core';
|
||||||
|
|
||||||
|
import {INTERNAL_BROWSER_PLATFORM_PROVIDERS} from '../platform_browser_private';
|
||||||
|
|
||||||
|
import {XHRImpl} from './xhr/xhr_impl';
|
||||||
|
|
||||||
|
export const INTERNAL_BROWSER_DYNAMIC_PLATFORM_PROVIDERS: any[] = [
|
||||||
|
INTERNAL_BROWSER_PLATFORM_PROVIDERS,
|
||||||
|
{
|
||||||
|
provide: CompilerOptions,
|
||||||
|
useValue: {providers: [{provide: XHR, useClass: XHRImpl}]},
|
||||||
|
multi: true
|
||||||
|
},
|
||||||
|
];
|
@ -6,90 +6,70 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {COMMON_DIRECTIVES, COMMON_PIPES} from '@angular/common';
|
import {CompilerConfig, DirectiveResolver, NgModuleResolver, ViewResolver, analyzeAppProvidersForDeprecatedConfiguration} from '@angular/compiler';
|
||||||
import {CompilerConfig, DirectiveResolver, ViewResolver} from '@angular/compiler';
|
import {OverridingTestComponentBuilder, coreDynamicTestingPlatform} from '@angular/compiler/testing';
|
||||||
import {MockDirectiveResolver, MockViewResolver, OverridingTestComponentBuilder} from '@angular/compiler/testing';
|
import {Compiler, CompilerFactory, CompilerOptions, NgModule, PlatformRef, Provider, ReflectiveInjector, Type, createPlatform, createPlatformFactory} from '@angular/core';
|
||||||
import {AppModule, Compiler, CompilerFactory, PLATFORM_DIRECTIVES, PLATFORM_PIPES, PlatformRef, Provider, ReflectiveInjector, Type, createPlatformFactory} from '@angular/core';
|
import {TestComponentBuilder, TestComponentRenderer, initTestEnvironment} from '@angular/core/testing';
|
||||||
import {TestComponentBuilder, TestComponentRenderer} from '@angular/core/testing';
|
import {BrowserTestingModule, browserTestingPlatform} from '@angular/platform-browser/testing';
|
||||||
import {BrowserTestModule, TEST_BROWSER_APPLICATION_PROVIDERS, TEST_BROWSER_PLATFORM_PROVIDERS} from '@angular/platform-browser/testing';
|
|
||||||
|
|
||||||
import {BROWSER_APP_COMPILER_PROVIDERS, BROWSER_DYNAMIC_COMPILER_FACTORY, BROWSER_DYNAMIC_PLATFORM_PROVIDERS} from './index';
|
import {Console} from './core_private';
|
||||||
|
import {browserDynamicPlatform} from './index';
|
||||||
|
import {INTERNAL_BROWSER_DYNAMIC_PLATFORM_PROVIDERS} from './src/platform_providers';
|
||||||
import {DOMTestComponentRenderer} from './testing/dom_test_component_renderer';
|
import {DOMTestComponentRenderer} from './testing/dom_test_component_renderer';
|
||||||
|
|
||||||
export * from './private_export_testing'
|
export * from './private_export_testing'
|
||||||
|
|
||||||
/**
|
|
||||||
* CompilerFactory for browser dynamic test platform
|
|
||||||
*
|
|
||||||
* @experimental
|
|
||||||
*/
|
|
||||||
export const BROWSER_DYNAMIC_TEST_COMPILER_FACTORY = BROWSER_DYNAMIC_COMPILER_FACTORY.withDefaults({
|
|
||||||
providers: [
|
|
||||||
{provide: DirectiveResolver, useClass: MockDirectiveResolver},
|
|
||||||
{provide: ViewResolver, useClass: MockViewResolver}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Providers for the browser dynamic platform
|
|
||||||
*
|
|
||||||
* @experimental
|
|
||||||
*/
|
|
||||||
const BROWSER_DYNAMIC_TEST_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
|
|
||||||
TEST_BROWSER_PLATFORM_PROVIDERS,
|
|
||||||
BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
|
|
||||||
{provide: CompilerFactory, useValue: BROWSER_DYNAMIC_TEST_COMPILER_FACTORY},
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @experimental API related to bootstrapping are still under review.
|
* @experimental API related to bootstrapping are still under review.
|
||||||
*/
|
*/
|
||||||
export const browserDynamicTestPlatform =
|
export const browserDynamicTestingPlatform = createPlatformFactory(
|
||||||
createPlatformFactory('browserDynamicTest', BROWSER_DYNAMIC_TEST_PLATFORM_PROVIDERS);
|
coreDynamicTestingPlatform, 'browserDynamicTesting',
|
||||||
|
INTERNAL_BROWSER_DYNAMIC_PLATFORM_PROVIDERS);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AppModule for testing.
|
* NgModule for testing.
|
||||||
*
|
*
|
||||||
* @stable
|
* @stable
|
||||||
*/
|
*/
|
||||||
@AppModule({
|
@NgModule({
|
||||||
modules: [BrowserTestModule],
|
exports: [BrowserTestingModule],
|
||||||
providers: [
|
providers: [
|
||||||
{provide: TestComponentBuilder, useClass: OverridingTestComponentBuilder},
|
{provide: TestComponentBuilder, useClass: OverridingTestComponentBuilder},
|
||||||
{provide: TestComponentRenderer, useClass: DOMTestComponentRenderer},
|
{provide: TestComponentRenderer, useClass: DOMTestComponentRenderer},
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class BrowserDynamicTestModule {
|
export class BrowserDynamicTestingModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used only as a shim until TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS is deprecated.
|
/**
|
||||||
const BROWSER_DYNAMIC_TEST_COMPILER_FACTORY_OLD = BROWSER_DYNAMIC_COMPILER_FACTORY.withDefaults({
|
* @deprecated Use initTestEnvironment with browserDynamicTestingPlatform instead.
|
||||||
providers: [
|
*/
|
||||||
{provide: DirectiveResolver, useClass: MockDirectiveResolver},
|
export const TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||||
{provide: ViewResolver, useClass: MockViewResolver}
|
// Note: This is not a real provider but a hack to still support the deprecated
|
||||||
],
|
// `setBaseTestProviders` method!
|
||||||
deprecatedAppProviders: [
|
[(appProviders: any[]) => {
|
||||||
{provide: PLATFORM_DIRECTIVES, useValue: COMMON_DIRECTIVES, multi: true},
|
const deprecatedConfiguration = analyzeAppProvidersForDeprecatedConfiguration(appProviders);
|
||||||
{provide: PLATFORM_PIPES, useValue: COMMON_PIPES, multi: true}
|
const platformRef =
|
||||||
]
|
createPlatformFactory(browserDynamicTestingPlatform, 'browserDynamicTestingDeprecated', [{
|
||||||
});
|
provide: CompilerOptions,
|
||||||
|
useValue: deprecatedConfiguration.compilerOptions,
|
||||||
|
multi: true
|
||||||
|
}])();
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
exports: [BrowserDynamicTestingModule],
|
||||||
|
declarations: [deprecatedConfiguration.moduleDeclarations]
|
||||||
|
})
|
||||||
|
class DynamicTestModule {
|
||||||
|
}
|
||||||
|
|
||||||
|
const testInjector = initTestEnvironment(DynamicTestModule, platformRef);
|
||||||
|
const console: Console = testInjector.get(Console);
|
||||||
|
deprecatedConfiguration.deprecationMessages.forEach((msg) => console.warn(msg));
|
||||||
|
}];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use initTestEnvironment with browserDynamicTestPlatform instead.
|
* @deprecated Use initTestEnvironment with BrowserDynamicTestingModule instead.
|
||||||
*/
|
*/
|
||||||
export const TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
|
export const TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||||
TEST_BROWSER_PLATFORM_PROVIDERS,
|
[];
|
||||||
BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
|
|
||||||
{provide: CompilerFactory, useValue: BROWSER_DYNAMIC_TEST_COMPILER_FACTORY_OLD},
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Use initTestEnvironment with BrowserDynamicTestModule instead.
|
|
||||||
*/
|
|
||||||
export const TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
|
|
||||||
TEST_BROWSER_APPLICATION_PROVIDERS,
|
|
||||||
{provide: TestComponentBuilder, useClass: OverridingTestComponentBuilder},
|
|
||||||
{provide: TestComponentRenderer, useClass: DOMTestComponentRenderer},
|
|
||||||
];
|
|
||||||
|
@ -42,5 +42,6 @@ export var __platform_browser_private__ = {
|
|||||||
SharedStylesHost: shared_styles_host.SharedStylesHost,
|
SharedStylesHost: shared_styles_host.SharedStylesHost,
|
||||||
ELEMENT_PROBE_PROVIDERS: ng_proble.ELEMENT_PROBE_PROVIDERS,
|
ELEMENT_PROBE_PROVIDERS: ng_proble.ELEMENT_PROBE_PROVIDERS,
|
||||||
DomEventsPlugin: dom_events.DomEventsPlugin,
|
DomEventsPlugin: dom_events.DomEventsPlugin,
|
||||||
initDomAdapter: browser.initDomAdapter
|
initDomAdapter: browser.initDomAdapter,
|
||||||
|
INTERNAL_BROWSER_PLATFORM_PROVIDERS: browser.INTERNAL_BROWSER_PLATFORM_PROVIDERS
|
||||||
};
|
};
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {COMMON_DIRECTIVES, COMMON_PIPES, PlatformLocation} from '@angular/common';
|
import {CommonModule, PlatformLocation} from '@angular/common';
|
||||||
import {APPLICATION_COMMON_PROVIDERS, AppModule, AppModuleFactory, AppModuleRef, ExceptionHandler, NgZone, OpaqueToken, PLATFORM_COMMON_PROVIDERS, PLATFORM_INITIALIZER, PlatformRef, ReflectiveInjector, RootRenderer, SanitizationService, Testability, assertPlatform, createPlatform, createPlatformFactory, getPlatform, isDevMode} from '@angular/core';
|
import {ApplicationModule, ExceptionHandler, NgModule, NgModuleFactory, NgModuleRef, NgZone, OpaqueToken, PLATFORM_COMMON_PROVIDERS, PLATFORM_INITIALIZER, PlatformRef, ReflectiveInjector, RootRenderer, SanitizationService, Testability, assertPlatform, corePlatform, createPlatform, createPlatformFactory, getPlatform, isDevMode} from '@angular/core';
|
||||||
|
|
||||||
import {wtfInit} from '../core_private';
|
import {wtfInit} from '../core_private';
|
||||||
import {AnimationDriver} from '../src/dom/animation_driver';
|
import {AnimationDriver} from '../src/dom/animation_driver';
|
||||||
@ -28,18 +28,21 @@ import {DomSharedStylesHost, SharedStylesHost} from './dom/shared_styles_host';
|
|||||||
import {isBlank} from './facade/lang';
|
import {isBlank} from './facade/lang';
|
||||||
import {DomSanitizationService, DomSanitizationServiceImpl} from './security/dom_sanitization_service';
|
import {DomSanitizationService, DomSanitizationServiceImpl} from './security/dom_sanitization_service';
|
||||||
|
|
||||||
|
export const INTERNAL_BROWSER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
|
||||||
|
{provide: PLATFORM_INITIALIZER, useValue: initDomAdapter, multi: true},
|
||||||
|
{provide: PlatformLocation, useClass: BrowserPlatformLocation}
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A set of providers to initialize the Angular platform in a web browser.
|
* A set of providers to initialize the Angular platform in a web browser.
|
||||||
*
|
*
|
||||||
* Used automatically by `bootstrap`, or can be passed to `platform`.
|
* Used automatically by `bootstrap`, or can be passed to `platform`.
|
||||||
*
|
*
|
||||||
* @experimental API related to bootstrapping are still under review.
|
* @deprecated Use `browserPlatform()` or create a custom platform factory via
|
||||||
|
* `createPlatformFactory(browserPlatform, ...)`
|
||||||
*/
|
*/
|
||||||
export const BROWSER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
|
export const BROWSER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||||
PLATFORM_COMMON_PROVIDERS, {provide: PLATFORM_INITIALIZER, useValue: initDomAdapter, multi: true},
|
[PLATFORM_COMMON_PROVIDERS, INTERNAL_BROWSER_PLATFORM_PROVIDERS];
|
||||||
{provide: PlatformLocation, useClass: BrowserPlatformLocation}
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @security Replacing built-in sanitization providers exposes the application to XSS risks.
|
* @security Replacing built-in sanitization providers exposes the application to XSS risks.
|
||||||
@ -58,27 +61,18 @@ export const BROWSER_SANITIZATION_PROVIDERS: Array<any> = [
|
|||||||
* Used automatically by `bootstrap`, or can be passed to {@link PlatformRef
|
* Used automatically by `bootstrap`, or can be passed to {@link PlatformRef
|
||||||
* PlatformRef.application}.
|
* PlatformRef.application}.
|
||||||
*
|
*
|
||||||
* @experimental API related to bootstrapping are still under review.
|
* @deprecated Create a module that includes `BrowserModule` instead. This is empty for backwards
|
||||||
|
* compatibility,
|
||||||
|
* as all of our bootstrap methods add a module implicitly, i.e. keeping this filled would add the
|
||||||
|
* providers 2x.
|
||||||
*/
|
*/
|
||||||
export const BROWSER_APP_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
|
export const BROWSER_APP_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [];
|
||||||
APPLICATION_COMMON_PROVIDERS, BROWSER_SANITIZATION_PROVIDERS,
|
|
||||||
{provide: ExceptionHandler, useFactory: _exceptionHandler, deps: []},
|
|
||||||
{provide: DOCUMENT, useFactory: _document, deps: []},
|
|
||||||
{provide: EVENT_MANAGER_PLUGINS, useClass: DomEventsPlugin, multi: true},
|
|
||||||
{provide: EVENT_MANAGER_PLUGINS, useClass: KeyEventsPlugin, multi: true},
|
|
||||||
{provide: EVENT_MANAGER_PLUGINS, useClass: HammerGesturesPlugin, multi: true},
|
|
||||||
{provide: HAMMER_GESTURE_CONFIG, useClass: HammerGestureConfig},
|
|
||||||
{provide: DomRootRenderer, useClass: DomRootRenderer_},
|
|
||||||
{provide: RootRenderer, useExisting: DomRootRenderer},
|
|
||||||
{provide: SharedStylesHost, useExisting: DomSharedStylesHost},
|
|
||||||
{provide: AnimationDriver, useFactory: _resolveDefaultAnimationDriver}, DomSharedStylesHost,
|
|
||||||
Testability, EventManager, ELEMENT_PROBE_PROVIDERS
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @experimental API related to bootstrapping are still under review.
|
* @experimental API related to bootstrapping are still under review.
|
||||||
*/
|
*/
|
||||||
export const browserPlatform = createPlatformFactory('browser', BROWSER_PLATFORM_PROVIDERS);
|
export const browserPlatform =
|
||||||
|
createPlatformFactory(corePlatform, 'browser', INTERNAL_BROWSER_PLATFORM_PROVIDERS);
|
||||||
|
|
||||||
export function initDomAdapter() {
|
export function initDomAdapter() {
|
||||||
BrowserDomAdapter.makeCurrent();
|
BrowserDomAdapter.makeCurrent();
|
||||||
@ -102,16 +96,26 @@ export function _resolveDefaultAnimationDriver(): AnimationDriver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The app module for the browser.
|
* The ng module for the browser.
|
||||||
*
|
*
|
||||||
* @experimental
|
* @experimental
|
||||||
*/
|
*/
|
||||||
@AppModule({
|
@NgModule({
|
||||||
providers: [
|
providers: [
|
||||||
BROWSER_APP_PROVIDERS,
|
BROWSER_SANITIZATION_PROVIDERS,
|
||||||
|
{provide: ExceptionHandler, useFactory: _exceptionHandler, deps: []},
|
||||||
|
{provide: DOCUMENT, useFactory: _document, deps: []},
|
||||||
|
{provide: EVENT_MANAGER_PLUGINS, useClass: DomEventsPlugin, multi: true},
|
||||||
|
{provide: EVENT_MANAGER_PLUGINS, useClass: KeyEventsPlugin, multi: true},
|
||||||
|
{provide: EVENT_MANAGER_PLUGINS, useClass: HammerGesturesPlugin, multi: true},
|
||||||
|
{provide: HAMMER_GESTURE_CONFIG, useClass: HammerGestureConfig},
|
||||||
|
{provide: DomRootRenderer, useClass: DomRootRenderer_},
|
||||||
|
{provide: RootRenderer, useExisting: DomRootRenderer},
|
||||||
|
{provide: SharedStylesHost, useExisting: DomSharedStylesHost},
|
||||||
|
{provide: AnimationDriver, useFactory: _resolveDefaultAnimationDriver}, DomSharedStylesHost,
|
||||||
|
Testability, EventManager, ELEMENT_PROBE_PROVIDERS
|
||||||
],
|
],
|
||||||
directives: COMMON_DIRECTIVES,
|
exports: [CommonModule, ApplicationModule]
|
||||||
pipes: COMMON_PIPES
|
|
||||||
})
|
})
|
||||||
export class BrowserModule {
|
export class BrowserModule {
|
||||||
}
|
}
|
||||||
|
@ -6,13 +6,14 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {APP_INITIALIZER, Injector, NgZone} from '@angular/core';
|
import {Injector, NgZone, PLATFORM_INITIALIZER} from '@angular/core';
|
||||||
|
|
||||||
import {BrowserPlatformLocation} from '../../browser/location/browser_platform_location';
|
import {BrowserPlatformLocation} from '../../browser/location/browser_platform_location';
|
||||||
|
|
||||||
import {MessageBasedPlatformLocation} from './platform_location';
|
import {MessageBasedPlatformLocation} from './platform_location';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A list of {@link Provider}s. To use the router in a Worker enabled application you must
|
* A list of {@link Provider}s. To use the router in a Worker enabled application you must
|
||||||
* include these providers when setting up the render thread.
|
* include these providers when setting up the render thread.
|
||||||
@ -20,7 +21,7 @@ import {MessageBasedPlatformLocation} from './platform_location';
|
|||||||
*/
|
*/
|
||||||
export const WORKER_UI_LOCATION_PROVIDERS = [
|
export const WORKER_UI_LOCATION_PROVIDERS = [
|
||||||
MessageBasedPlatformLocation, BrowserPlatformLocation,
|
MessageBasedPlatformLocation, BrowserPlatformLocation,
|
||||||
{provide: APP_INITIALIZER, useFactory: initUiLocation, multi: true, deps: [Injector]}
|
{provide: PLATFORM_INITIALIZER, useFactory: initUiLocation, multi: true, deps: [Injector]}
|
||||||
];
|
];
|
||||||
|
|
||||||
function initUiLocation(injector: Injector): () => void {
|
function initUiLocation(injector: Injector): () => void {
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {COMMON_DIRECTIVES, COMMON_PIPES, FORM_PROVIDERS} from '@angular/common';
|
import {CommonModule, FORM_PROVIDERS} from '@angular/common';
|
||||||
import {APPLICATION_COMMON_PROVIDERS, APP_INITIALIZER, AppModule, ExceptionHandler, NgZone, OpaqueToken, PLATFORM_COMMON_PROVIDERS, PlatformRef, ReflectiveInjector, RootRenderer, assertPlatform, createPlatform, createPlatformFactory, getPlatform} from '@angular/core';
|
import {APP_INITIALIZER, ApplicationModule, ExceptionHandler, NgModule, NgZone, OpaqueToken, PLATFORM_COMMON_PROVIDERS, PlatformRef, ReflectiveInjector, RootRenderer, assertPlatform, corePlatform, createPlatform, createPlatformFactory, getPlatform} from '@angular/core';
|
||||||
|
|
||||||
import {BROWSER_SANITIZATION_PROVIDERS} from './browser';
|
import {BROWSER_SANITIZATION_PROVIDERS} from './browser';
|
||||||
import {isBlank, print} from './facade/lang';
|
import {isBlank, print} from './facade/lang';
|
||||||
@ -29,29 +29,24 @@ class PrintLogger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @experimental
|
* @deprecated Use `workerAppPlatform()` or create a custom platform factory via
|
||||||
|
* `createPlatformFactory(workerAppPlatform, ...)`
|
||||||
*/
|
*/
|
||||||
export const WORKER_APP_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
export const WORKER_APP_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||||
PLATFORM_COMMON_PROVIDERS;
|
PLATFORM_COMMON_PROVIDERS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @experimental
|
* @deprecated Create a module that includes `WorkerAppModule` instead. This is empty for backwards
|
||||||
|
* compatibility,
|
||||||
|
* as all of our bootstrap methods add a module implicitly, i.e. keeping this filled would add the
|
||||||
|
* providers 2x.
|
||||||
*/
|
*/
|
||||||
export const WORKER_APP_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
|
export const WORKER_APP_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [];
|
||||||
APPLICATION_COMMON_PROVIDERS, FORM_PROVIDERS, BROWSER_SANITIZATION_PROVIDERS, Serializer,
|
|
||||||
{provide: ClientMessageBrokerFactory, useClass: ClientMessageBrokerFactory_},
|
|
||||||
{provide: ServiceMessageBrokerFactory, useClass: ServiceMessageBrokerFactory_},
|
|
||||||
WebWorkerRootRenderer, {provide: RootRenderer, useExisting: WebWorkerRootRenderer},
|
|
||||||
{provide: ON_WEB_WORKER, useValue: true}, RenderStore,
|
|
||||||
{provide: ExceptionHandler, useFactory: _exceptionHandler, deps: []},
|
|
||||||
{provide: MessageBus, useFactory: createMessageBus, deps: [NgZone]},
|
|
||||||
{provide: APP_INITIALIZER, useValue: setupWebWorker, multi: true}
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @experimental
|
* @experimental
|
||||||
*/
|
*/
|
||||||
export const workerAppPlatform = createPlatformFactory('workerApp', WORKER_APP_PLATFORM_PROVIDERS);
|
export const workerAppPlatform = createPlatformFactory(corePlatform, 'workerApp');
|
||||||
|
|
||||||
function _exceptionHandler(): ExceptionHandler {
|
function _exceptionHandler(): ExceptionHandler {
|
||||||
return new ExceptionHandler(new PrintLogger());
|
return new ExceptionHandler(new PrintLogger());
|
||||||
@ -77,14 +72,22 @@ function setupWebWorker(): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The app module for the worker app side.
|
* The ng module for the worker app side.
|
||||||
*
|
*
|
||||||
* @experimental
|
* @experimental
|
||||||
*/
|
*/
|
||||||
@AppModule({
|
@NgModule({
|
||||||
providers: WORKER_APP_APPLICATION_PROVIDERS,
|
providers: [
|
||||||
directives: COMMON_DIRECTIVES,
|
FORM_PROVIDERS, BROWSER_SANITIZATION_PROVIDERS, Serializer,
|
||||||
pipes: COMMON_PIPES
|
{provide: ClientMessageBrokerFactory, useClass: ClientMessageBrokerFactory_},
|
||||||
|
{provide: ServiceMessageBrokerFactory, useClass: ServiceMessageBrokerFactory_},
|
||||||
|
WebWorkerRootRenderer, {provide: RootRenderer, useExisting: WebWorkerRootRenderer},
|
||||||
|
{provide: ON_WEB_WORKER, useValue: true}, RenderStore,
|
||||||
|
{provide: ExceptionHandler, useFactory: _exceptionHandler, deps: []},
|
||||||
|
{provide: MessageBus, useFactory: createMessageBus, deps: [NgZone]},
|
||||||
|
{provide: APP_INITIALIZER, useValue: setupWebWorker, multi: true}
|
||||||
|
],
|
||||||
|
exports: [CommonModule, ApplicationModule]
|
||||||
})
|
})
|
||||||
export class WorkerAppModule {
|
export class WorkerAppModule {
|
||||||
}
|
}
|
@ -6,7 +6,7 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {APPLICATION_COMMON_PROVIDERS, APP_INITIALIZER, AppModule, ExceptionHandler, Injectable, Injector, NgZone, OpaqueToken, PLATFORM_COMMON_PROVIDERS, PLATFORM_INITIALIZER, PlatformRef, ReflectiveInjector, RootRenderer, Testability, assertPlatform, createPlatform, createPlatformFactory, getPlatform} from '@angular/core';
|
import {ExceptionHandler, Injectable, Injector, NgZone, OpaqueToken, PLATFORM_COMMON_PROVIDERS, PLATFORM_INITIALIZER, PlatformRef, ReflectiveInjector, RootRenderer, Testability, assertPlatform, corePlatform, createPlatform, createPlatformFactory, getPlatform, isDevMode} from '@angular/core';
|
||||||
|
|
||||||
import {wtfInit} from '../core_private';
|
import {wtfInit} from '../core_private';
|
||||||
|
|
||||||
@ -34,6 +34,7 @@ import {ServiceMessageBrokerFactory, ServiceMessageBrokerFactory_} from './web_w
|
|||||||
import {MessageBasedRenderer} from './web_workers/ui/renderer';
|
import {MessageBasedRenderer} from './web_workers/ui/renderer';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper class that exposes the Worker
|
* Wrapper class that exposes the Worker
|
||||||
* and underlying {@link MessageBus} for lower level message passing.
|
* and underlying {@link MessageBus} for lower level message passing.
|
||||||
@ -70,16 +71,8 @@ export const WORKER_UI_STARTABLE_MESSAGING_SERVICE =
|
|||||||
/**
|
/**
|
||||||
* @experimental WebWorker support is currently experimental.
|
* @experimental WebWorker support is currently experimental.
|
||||||
*/
|
*/
|
||||||
export const WORKER_UI_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
|
export const _WORKER_UI_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
|
||||||
PLATFORM_COMMON_PROVIDERS,
|
{provide: NgZone, useFactory: createNgZone, deps: []},
|
||||||
{provide: PLATFORM_INITIALIZER, useValue: initWebWorkerRenderPlatform, multi: true}
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @experimental WebWorker support is currently experimental.
|
|
||||||
*/
|
|
||||||
export const WORKER_UI_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
|
|
||||||
APPLICATION_COMMON_PROVIDERS,
|
|
||||||
MessageBasedRenderer,
|
MessageBasedRenderer,
|
||||||
{provide: WORKER_UI_STARTABLE_MESSAGING_SERVICE, useExisting: MessageBasedRenderer, multi: true},
|
{provide: WORKER_UI_STARTABLE_MESSAGING_SERVICE, useExisting: MessageBasedRenderer, multi: true},
|
||||||
BROWSER_SANITIZATION_PROVIDERS,
|
BROWSER_SANITIZATION_PROVIDERS,
|
||||||
@ -104,10 +97,27 @@ export const WORKER_UI_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[
|
|||||||
Testability,
|
Testability,
|
||||||
EventManager,
|
EventManager,
|
||||||
WebWorkerInstance,
|
WebWorkerInstance,
|
||||||
{provide: APP_INITIALIZER, useFactory: initWebWorkerAppFn, multi: true, deps: [Injector]},
|
{
|
||||||
|
provide: PLATFORM_INITIALIZER,
|
||||||
|
useFactory: initWebWorkerRenderPlatform,
|
||||||
|
multi: true,
|
||||||
|
deps: [Injector]
|
||||||
|
},
|
||||||
{provide: MessageBus, useFactory: messageBusFactory, deps: [WebWorkerInstance]}
|
{provide: MessageBus, useFactory: messageBusFactory, deps: [WebWorkerInstance]}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * @deprecated Use `workerUiPlatform()` or create a custom platform factory via
|
||||||
|
* `createPlatformFactory(workerUiPlatform, ...)`
|
||||||
|
*/
|
||||||
|
export const WORKER_UI_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||||
|
[PLATFORM_COMMON_PROVIDERS, _WORKER_UI_PLATFORM_PROVIDERS];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Worker UI only has a platform but no application
|
||||||
|
*/
|
||||||
|
export const WORKER_UI_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [];
|
||||||
|
|
||||||
function initializeGenericWorkerRenderer(injector: Injector) {
|
function initializeGenericWorkerRenderer(injector: Injector) {
|
||||||
var bus = injector.get(MessageBus);
|
var bus = injector.get(MessageBus);
|
||||||
let zone = injector.get(NgZone);
|
let zone = injector.get(NgZone);
|
||||||
@ -122,27 +132,11 @@ function messageBusFactory(instance: WebWorkerInstance): MessageBus {
|
|||||||
return instance.bus;
|
return instance.bus;
|
||||||
}
|
}
|
||||||
|
|
||||||
function initWebWorkerRenderPlatform(): void {
|
function initWebWorkerRenderPlatform(injector: Injector): () => void {
|
||||||
|
return () => {
|
||||||
BrowserDomAdapter.makeCurrent();
|
BrowserDomAdapter.makeCurrent();
|
||||||
wtfInit();
|
wtfInit();
|
||||||
BrowserGetTestability.init();
|
BrowserGetTestability.init();
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @experimental WebWorker support is currently experimental.
|
|
||||||
*/
|
|
||||||
export const workerUiPlatform = createPlatformFactory('workerUi', WORKER_UI_PLATFORM_PROVIDERS);
|
|
||||||
|
|
||||||
function _exceptionHandler(): ExceptionHandler {
|
|
||||||
return new ExceptionHandler(getDOM());
|
|
||||||
}
|
|
||||||
|
|
||||||
function _document(): any {
|
|
||||||
return getDOM().defaultDoc();
|
|
||||||
}
|
|
||||||
|
|
||||||
function initWebWorkerAppFn(injector: Injector): () => void {
|
|
||||||
return () => {
|
|
||||||
var scriptUri: string;
|
var scriptUri: string;
|
||||||
try {
|
try {
|
||||||
scriptUri = injector.get(WORKER_SCRIPT);
|
scriptUri = injector.get(WORKER_SCRIPT);
|
||||||
@ -158,6 +152,24 @@ function initWebWorkerAppFn(injector: Injector): () => void {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @experimental WebWorker support is currently experimental.
|
||||||
|
*/
|
||||||
|
export const workerUiPlatform =
|
||||||
|
createPlatformFactory(corePlatform, 'workerUi', _WORKER_UI_PLATFORM_PROVIDERS);
|
||||||
|
|
||||||
|
function _exceptionHandler(): ExceptionHandler {
|
||||||
|
return new ExceptionHandler(getDOM());
|
||||||
|
}
|
||||||
|
|
||||||
|
function _document(): any {
|
||||||
|
return getDOM().defaultDoc();
|
||||||
|
}
|
||||||
|
|
||||||
|
function createNgZone(): NgZone {
|
||||||
|
return new NgZone({enableLongStackTrace: isDevMode()});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Spawns a new class and initializes the WebWorkerInstance
|
* Spawns a new class and initializes the WebWorkerInstance
|
||||||
*/
|
*/
|
||||||
@ -175,14 +187,3 @@ function _resolveDefaultAnimationDriver(): AnimationDriver {
|
|||||||
// work with animations just yet...
|
// work with animations just yet...
|
||||||
return AnimationDriver.NOOP;
|
return AnimationDriver.NOOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The app module for the worker ui side.
|
|
||||||
* To use this, you need to create an own module that includes this module
|
|
||||||
* and provides the `WORKER_SCRIPT` token.
|
|
||||||
*
|
|
||||||
* @experimental
|
|
||||||
*/
|
|
||||||
@AppModule({providers: WORKER_UI_APPLICATION_PROVIDERS})
|
|
||||||
export class WorkerUiModule {
|
|
||||||
}
|
|
||||||
|
@ -8,15 +8,15 @@
|
|||||||
|
|
||||||
import {LowerCasePipe, NgIf} from '@angular/common';
|
import {LowerCasePipe, NgIf} from '@angular/common';
|
||||||
import {XHR} from '@angular/compiler';
|
import {XHR} from '@angular/compiler';
|
||||||
import {APP_INITIALIZER, Component, Directive, ExceptionHandler, Inject, Input, OnDestroy, PLATFORM_DIRECTIVES, PLATFORM_INITIALIZER, PLATFORM_PIPES, Pipe, ReflectiveInjector, coreLoadAndBootstrap, createPlatform, provide} from '@angular/core';
|
import {APP_INITIALIZER, Component, Directive, ExceptionHandler, Inject, Input, NgModule, OnDestroy, PLATFORM_DIRECTIVES, PLATFORM_INITIALIZER, PLATFORM_PIPES, Pipe, ReflectiveInjector, bootstrapModule, createPlatformFactory, provide} from '@angular/core';
|
||||||
import {ApplicationRef, disposePlatform} from '@angular/core/src/application_ref';
|
import {ApplicationRef, disposePlatform} from '@angular/core/src/application_ref';
|
||||||
import {Console} from '@angular/core/src/console';
|
import {Console} from '@angular/core/src/console';
|
||||||
import {ComponentRef} from '@angular/core/src/linker/component_factory';
|
import {ComponentRef} from '@angular/core/src/linker/component_factory';
|
||||||
import {Testability, TestabilityRegistry} from '@angular/core/src/testability/testability';
|
import {Testability, TestabilityRegistry} from '@angular/core/src/testability/testability';
|
||||||
import {ComponentFixture} from '@angular/core/testing';
|
import {ComponentFixture} from '@angular/core/testing';
|
||||||
import {AsyncTestCompleter, Log, afterEach, beforeEach, beforeEachProviders, ddescribe, describe, iit, inject, it} from '@angular/core/testing/testing_internal';
|
import {AsyncTestCompleter, Log, afterEach, beforeEach, beforeEachProviders, ddescribe, describe, iit, inject, it} from '@angular/core/testing/testing_internal';
|
||||||
import {BROWSER_APP_PROVIDERS, BROWSER_PLATFORM_PROVIDERS} from '@angular/platform-browser';
|
import {BrowserModule} from '@angular/platform-browser';
|
||||||
import {BROWSER_APP_COMPILER_PROVIDERS, bootstrap} from '@angular/platform-browser-dynamic';
|
import {bootstrap, browserDynamicPlatform} from '@angular/platform-browser-dynamic';
|
||||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||||
import {DOCUMENT} from '@angular/platform-browser/src/dom/dom_tokens';
|
import {DOCUMENT} from '@angular/platform-browser/src/dom/dom_tokens';
|
||||||
import {expect} from '@angular/platform-browser/testing/matchers';
|
import {expect} from '@angular/platform-browser/testing/matchers';
|
||||||
@ -223,16 +223,10 @@ export function main() {
|
|||||||
|
|
||||||
it('should unregister change detectors when components are disposed',
|
it('should unregister change detectors when components are disposed',
|
||||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||||
var platform =
|
bootstrap(HelloRootCmp, testProviders).then((ref) => {
|
||||||
createPlatform(ReflectiveInjector.resolveAndCreate(BROWSER_PLATFORM_PROVIDERS));
|
const appRef = ref.injector.get(ApplicationRef);
|
||||||
var app = ReflectiveInjector
|
|
||||||
.resolveAndCreate(
|
|
||||||
[BROWSER_APP_PROVIDERS, BROWSER_APP_COMPILER_PROVIDERS, testProviders],
|
|
||||||
platform.injector)
|
|
||||||
.get(ApplicationRef);
|
|
||||||
coreLoadAndBootstrap(HelloRootCmp, app.injector).then((ref) => {
|
|
||||||
ref.destroy();
|
ref.destroy();
|
||||||
expect(() => app.tick()).not.toThrow();
|
expect(() => appRef.tick()).not.toThrow();
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
@ -258,24 +252,29 @@ export function main() {
|
|||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should run platform initializers', inject([Log], (log: Log) => {
|
it('should run platform initializers',
|
||||||
let p = createPlatform(ReflectiveInjector.resolveAndCreate([
|
inject([Log, AsyncTestCompleter], (log: Log, async: AsyncTestCompleter) => {
|
||||||
BROWSER_PLATFORM_PROVIDERS,
|
let p = createPlatformFactory(browserDynamicPlatform, 'someName', [
|
||||||
{provide: PLATFORM_INITIALIZER, useValue: log.fn('platform_init1'), multi: true},
|
{provide: PLATFORM_INITIALIZER, useValue: log.fn('platform_init1'), multi: true},
|
||||||
{provide: PLATFORM_INITIALIZER, useValue: log.fn('platform_init2'), multi: true}
|
{provide: PLATFORM_INITIALIZER, useValue: log.fn('platform_init2'), multi: true}
|
||||||
]));
|
])();
|
||||||
expect(log.result()).toEqual('platform_init1; platform_init2');
|
|
||||||
log.clear();
|
@NgModule({
|
||||||
var a = ReflectiveInjector.resolveAndCreate(
|
imports: [BrowserModule],
|
||||||
[
|
providers: [
|
||||||
BROWSER_APP_PROVIDERS,
|
|
||||||
{provide: APP_INITIALIZER, useValue: log.fn('app_init1'), multi: true},
|
{provide: APP_INITIALIZER, useValue: log.fn('app_init1'), multi: true},
|
||||||
{provide: APP_INITIALIZER, useValue: log.fn('app_init2'), multi: true}
|
{provide: APP_INITIALIZER, useValue: log.fn('app_init2'), multi: true}
|
||||||
],
|
]
|
||||||
p.injector);
|
})
|
||||||
a.get(ApplicationRef);
|
class SomeModule {
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(log.result()).toEqual('platform_init1; platform_init2');
|
||||||
|
log.clear();
|
||||||
|
bootstrapModule(SomeModule, p).then(() => {
|
||||||
expect(log.result()).toEqual('app_init1; app_init2');
|
expect(log.result()).toEqual('app_init1; app_init2');
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should register each application with the testability registry',
|
it('should register each application with the testability registry',
|
||||||
@ -305,7 +304,7 @@ export function main() {
|
|||||||
])).then((compRef) => {
|
])).then((compRef) => {
|
||||||
expect(el).toHaveText('hello world!');
|
expect(el).toHaveText('hello world!');
|
||||||
expect(compilerConsole.warnings).toEqual([
|
expect(compilerConsole.warnings).toEqual([
|
||||||
'Passing an instance of XHR to "bootstrap()" as provider is deprecated. Pass the provider via the new parameter "compilerOptions" of "bootstrap()" instead.'
|
'Passing XHR as regular provider is deprecated. Pass the provider via "compilerOptions" instead.'
|
||||||
]);
|
]);
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
@ -325,10 +324,8 @@ export function main() {
|
|||||||
.toBe('transformed someValue');
|
.toBe('transformed someValue');
|
||||||
|
|
||||||
expect(compilerConsole.warnings).toEqual([
|
expect(compilerConsole.warnings).toEqual([
|
||||||
'Passing PLATFORM_DIRECTIVES to "bootstrap()" as provider is deprecated. Use the new parameter "directives" of "bootstrap()" instead.',
|
`The PLATFORM_DIRECTIVES provider and CompilerConfig.platformDirectives is deprecated. Add the directives to an NgModule instead! (Directives: ${stringify(SomeDirective)})`,
|
||||||
'Passing PLATFORM_PIPES to "bootstrap()" as provider is deprecated. Use the new parameter "pipes" of "bootstrap()" instead.',
|
`The PLATFORM_PIPES provider and CompilerConfig.platformPipes is deprecated. Add the pipes to an NgModule instead! (Pipes: ${stringify(SomePipe)})`
|
||||||
`Providing platform directives via the PLATFORM_DIRECTIVES provider or the "CompilerConfig" is deprecated. Provide platform directives via an @AppModule instead. Directives: ${stringify(SomeDirective)}`,
|
|
||||||
`Providing platform pipes via the PLATFORM_PIPES provider or the "CompilerConfig" is deprecated. Provide platform pipes via an @AppModule instead. Pipes: ${stringify(SomePipe)}`
|
|
||||||
]);
|
]);
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
import {NgIf} from '@angular/common';
|
import {NgIf} from '@angular/common';
|
||||||
import {CompilerConfig, XHR} from '@angular/compiler';
|
import {CompilerConfig, XHR} from '@angular/compiler';
|
||||||
import {AppModule, Component, ComponentFactoryResolver, Directive, Injectable, Input, Pipe, ViewMetadata, provide} from '@angular/core';
|
import {Component, ComponentFactoryResolver, Directive, Injectable, Input, NgModule, Pipe, ViewMetadata, provide} from '@angular/core';
|
||||||
import {TestComponentBuilder, addProviders, async, configureCompiler, configureModule, doAsyncPrecompilation, fakeAsync, inject, tick, withModule, withProviders} from '@angular/core/testing';
|
import {TestComponentBuilder, addProviders, async, configureCompiler, configureModule, doAsyncPrecompilation, fakeAsync, inject, tick, withModule, withProviders} from '@angular/core/testing';
|
||||||
import {expect} from '@angular/platform-browser/testing/matchers';
|
import {expect} from '@angular/platform-browser/testing/matchers';
|
||||||
|
|
||||||
@ -112,8 +112,8 @@ class SomePipe {
|
|||||||
class CompUsingModuleDirectiveAndPipe {
|
class CompUsingModuleDirectiveAndPipe {
|
||||||
}
|
}
|
||||||
|
|
||||||
@AppModule({})
|
@NgModule()
|
||||||
class SomeNestedModule {
|
class SomeLibModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -233,10 +233,9 @@ export function main() {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
moduleConfig = {
|
moduleConfig = {
|
||||||
providers: [FancyService],
|
providers: [FancyService],
|
||||||
directives: [SomeDirective],
|
imports: [SomeLibModule],
|
||||||
pipes: [SomePipe],
|
declarations: [SomeDirective, SomePipe, CompUsingModuleDirectiveAndPipe],
|
||||||
precompile: [CompUsingModuleDirectiveAndPipe],
|
precompile: [CompUsingModuleDirectiveAndPipe]
|
||||||
modules: [SomeNestedModule]
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -256,9 +255,9 @@ export function main() {
|
|||||||
expect(el.children[0].properties['title']).toBe('transformed someValue');
|
expect(el.children[0].properties['title']).toBe('transformed someValue');
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should use set up nested modules',
|
it('should use set up library modules',
|
||||||
inject([SomeNestedModule], (nestedModule: SomeNestedModule) => {
|
inject([SomeLibModule], (libModule: SomeLibModule) => {
|
||||||
expect(nestedModule).toBeAnInstanceOf(SomeNestedModule);
|
expect(libModule).toBeAnInstanceOf(SomeLibModule);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should use set up precompile components',
|
it('should use set up precompile components',
|
||||||
@ -284,10 +283,9 @@ export function main() {
|
|||||||
expect(el.children[0].properties['title']).toBe('transformed someValue');
|
expect(el.children[0].properties['title']).toBe('transformed someValue');
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should use set up nested modules',
|
it('should use set up library modules',
|
||||||
withModule(() => moduleConfig)
|
withModule(() => moduleConfig).inject([SomeLibModule], (libModule: SomeLibModule) => {
|
||||||
.inject([SomeNestedModule], (nestedModule: SomeNestedModule) => {
|
expect(libModule).toBeAnInstanceOf(SomeLibModule);
|
||||||
expect(nestedModule).toBeAnInstanceOf(SomeNestedModule);
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should use set up precompile components',
|
it('should use set up precompile components',
|
||||||
@ -301,7 +299,7 @@ export function main() {
|
|||||||
|
|
||||||
describe('precompile components with template url', () => {
|
describe('precompile components with template url', () => {
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
configureModule({precompile: [CompWithUrlTemplate]});
|
configureModule({declarations: [CompWithUrlTemplate], precompile: [CompWithUrlTemplate]});
|
||||||
doAsyncPrecompilation();
|
doAsyncPrecompilation();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -450,7 +448,12 @@ export function main() {
|
|||||||
expect(
|
expect(
|
||||||
() =>
|
() =>
|
||||||
it('should fail',
|
it('should fail',
|
||||||
withModule(() => { return {precompile: [CompWithUrlTemplate]}; })
|
withModule(() => {
|
||||||
|
return {
|
||||||
|
declarations: [CompWithUrlTemplate],
|
||||||
|
precompile: [CompWithUrlTemplate]
|
||||||
|
};
|
||||||
|
})
|
||||||
.inject(
|
.inject(
|
||||||
[ComponentFactoryResolver],
|
[ComponentFactoryResolver],
|
||||||
(resolver: ComponentFactoryResolver) => {
|
(resolver: ComponentFactoryResolver) => {
|
||||||
|
@ -23,8 +23,8 @@ import {MessageBasedRenderer} from '@angular/platform-browser/src/web_workers/ui
|
|||||||
import {createPairedMessageBuses, PairedMessageBuses} from '../shared/web_worker_test_util';
|
import {createPairedMessageBuses, PairedMessageBuses} from '../shared/web_worker_test_util';
|
||||||
import {ServiceMessageBrokerFactory_} from '@angular/platform-browser/src/web_workers/shared/service_message_broker';
|
import {ServiceMessageBrokerFactory_} from '@angular/platform-browser/src/web_workers/shared/service_message_broker';
|
||||||
import {dispatchEvent} from '../../../../platform-browser/testing/browser_util';
|
import {dispatchEvent} from '../../../../platform-browser/testing/browser_util';
|
||||||
import {BrowserTestModule} from '@angular/platform-browser/testing';
|
import {BrowserTestingModule} from '@angular/platform-browser/testing';
|
||||||
import {browserDynamicTestPlatform} from '@angular/platform-browser-dynamic/testing';
|
import {browserDynamicTestingPlatform} from '@angular/platform-browser-dynamic/testing';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
function createWebWorkerBrokerFactory(
|
function createWebWorkerBrokerFactory(
|
||||||
@ -65,8 +65,8 @@ export function main() {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
uiRenderStore = new RenderStore();
|
uiRenderStore = new RenderStore();
|
||||||
var testUiInjector = new TestBed();
|
var testUiInjector = new TestBed();
|
||||||
testUiInjector.platform = browserDynamicTestPlatform();
|
testUiInjector.platform = browserDynamicTestingPlatform();
|
||||||
testUiInjector.appModule = BrowserTestModule;
|
testUiInjector.ngModule = BrowserTestingModule;
|
||||||
testUiInjector.configureModule({
|
testUiInjector.configureModule({
|
||||||
providers: [
|
providers: [
|
||||||
Serializer, {provide: RenderStore, useValue: uiRenderStore},
|
Serializer, {provide: RenderStore, useValue: uiRenderStore},
|
||||||
@ -74,7 +74,7 @@ export function main() {
|
|||||||
{provide: RootRenderer, useExisting: DomRootRenderer}
|
{provide: RootRenderer, useExisting: DomRootRenderer}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
testUiInjector.initTestAppModule();
|
testUiInjector.initTestModule();
|
||||||
var uiSerializer = testUiInjector.get(Serializer);
|
var uiSerializer = testUiInjector.get(Serializer);
|
||||||
var domRootRenderer = testUiInjector.get(DomRootRenderer);
|
var domRootRenderer = testUiInjector.get(DomRootRenderer);
|
||||||
workerRenderStore = new RenderStore();
|
workerRenderStore = new RenderStore();
|
||||||
|
@ -7,9 +7,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {LocationStrategy} from '@angular/common';
|
import {LocationStrategy} from '@angular/common';
|
||||||
import {APP_ID, AppModule, NgZone, OpaqueToken, PLATFORM_COMMON_PROVIDERS, PLATFORM_INITIALIZER, PlatformRef, ReflectiveInjector, assertPlatform, createPlatform, createPlatformFactory, getPlatform} from '@angular/core';
|
import {APP_ID, NgModule, NgZone, OpaqueToken, PLATFORM_COMMON_PROVIDERS, PLATFORM_INITIALIZER, PlatformRef, ReflectiveInjector, assertPlatform, corePlatform, createPlatform, createPlatformFactory, getPlatform} from '@angular/core';
|
||||||
|
|
||||||
import {BROWSER_APP_PROVIDERS, BrowserModule} from '../src/browser';
|
import {BrowserModule} from '../src/browser';
|
||||||
import {BrowserDomAdapter} from '../src/browser/browser_adapter';
|
import {BrowserDomAdapter} from '../src/browser/browser_adapter';
|
||||||
import {AnimationDriver} from '../src/dom/animation_driver';
|
import {AnimationDriver} from '../src/dom/animation_driver';
|
||||||
import {ELEMENT_PROBE_PROVIDERS} from '../src/dom/debug/ng_probe';
|
import {ELEMENT_PROBE_PROVIDERS} from '../src/dom/debug/ng_probe';
|
||||||
@ -25,45 +25,46 @@ function createNgZone(): NgZone {
|
|||||||
return new NgZone({enableLongStackTrace: true});
|
return new NgZone({enableLongStackTrace: true});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const _TEST_BROWSER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||||
|
[{provide: PLATFORM_INITIALIZER, useValue: initBrowserTests, multi: true}];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Providers for the browser test platform
|
* Providers for the browser test platform
|
||||||
*
|
*
|
||||||
* @experimental
|
* @deprecated Use `browserTestingPlatform()` or create a custom platform factory via
|
||||||
|
* `createPlatformFactory(browserTestingPlatform, ...)`
|
||||||
*/
|
*/
|
||||||
export const TEST_BROWSER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
|
export const TEST_BROWSER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||||
PLATFORM_COMMON_PROVIDERS,
|
[PLATFORM_COMMON_PROVIDERS, _TEST_BROWSER_PLATFORM_PROVIDERS];
|
||||||
{provide: PLATFORM_INITIALIZER, useValue: initBrowserTests, multi: true}
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use initTestEnvironment with BrowserTestModule instead.
|
* @deprecated Use initTestEnvironment with BrowserTestModule instead. This is empty for backwards
|
||||||
|
* compatibility,
|
||||||
|
* as all of our bootstrap methods add a module implicitly, i.e. keeping this filled would add the
|
||||||
|
* providers 2x.
|
||||||
*/
|
*/
|
||||||
export const TEST_BROWSER_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
|
export const TEST_BROWSER_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [];
|
||||||
BROWSER_APP_PROVIDERS, {provide: APP_ID, useValue: 'a'}, ELEMENT_PROBE_PROVIDERS,
|
|
||||||
{provide: NgZone, useFactory: createNgZone},
|
|
||||||
{provide: AnimationDriver, useValue: AnimationDriver.NOOP}
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Platform for testing
|
* Platform for testing
|
||||||
*
|
*
|
||||||
* @experimental API related to bootstrapping are still under review.
|
* @experimental API related to bootstrapping are still under review.
|
||||||
*/
|
*/
|
||||||
export const browserTestPlatform =
|
export const browserTestingPlatform =
|
||||||
createPlatformFactory('browserTest', TEST_BROWSER_PLATFORM_PROVIDERS);
|
createPlatformFactory(corePlatform, 'browserTesting', _TEST_BROWSER_PLATFORM_PROVIDERS);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AppModule for testing.
|
* NgModule for testing.
|
||||||
*
|
*
|
||||||
* @stable
|
* @experimental
|
||||||
*/
|
*/
|
||||||
@AppModule({
|
@NgModule({
|
||||||
modules: [BrowserModule],
|
exports: [BrowserModule],
|
||||||
providers: [
|
providers: [
|
||||||
{provide: APP_ID, useValue: 'a'}, ELEMENT_PROBE_PROVIDERS,
|
{provide: APP_ID, useValue: 'a'}, ELEMENT_PROBE_PROVIDERS,
|
||||||
{provide: NgZone, useFactory: createNgZone},
|
{provide: NgZone, useFactory: createNgZone},
|
||||||
{provide: AnimationDriver, useValue: AnimationDriver.NOOP}
|
{provide: AnimationDriver, useValue: AnimationDriver.NOOP}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class BrowserTestModule {
|
export class BrowserTestingModule {
|
||||||
}
|
}
|
||||||
|
@ -11,3 +11,4 @@ import {__core_private__ as r, __core_private_types__ as t} from '@angular/core'
|
|||||||
export var reflector: typeof t.reflector = r.reflector;
|
export var reflector: typeof t.reflector = r.reflector;
|
||||||
export var ReflectionCapabilities: typeof t.ReflectionCapabilities = r.ReflectionCapabilities;
|
export var ReflectionCapabilities: typeof t.ReflectionCapabilities = r.ReflectionCapabilities;
|
||||||
export var wtfInit: typeof t.wtfInit = r.wtfInit;
|
export var wtfInit: typeof t.wtfInit = r.wtfInit;
|
||||||
|
export var Console: typeof t.Console = r.Console;
|
@ -7,11 +7,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {PlatformLocation} from '@angular/common';
|
import {PlatformLocation} from '@angular/common';
|
||||||
import {CompilerFactory, ComponentRef, OpaqueToken, PLATFORM_COMMON_PROVIDERS, PLATFORM_INITIALIZER, PlatformRef, ReflectiveInjector, Type, assertPlatform, coreLoadAndBootstrap, createPlatform, createPlatformFactory, getPlatform} from '@angular/core';
|
import {analyzeAppProvidersForDeprecatedConfiguration, coreDynamicPlatform} from '@angular/compiler';
|
||||||
import {BROWSER_DYNAMIC_TEST_COMPILER_FACTORY} from '@angular/platform-browser-dynamic/testing';
|
import {ApplicationRef, CompilerFactory, ComponentRef, NgModule, OpaqueToken, PLATFORM_COMMON_PROVIDERS, PLATFORM_INITIALIZER, PlatformRef, ReflectiveInjector, Type, assertPlatform, bootstrapModule, corePlatform, createPlatform, createPlatformFactory, getPlatform} from '@angular/core';
|
||||||
|
import {BrowserModule} from '@angular/platform-browser';
|
||||||
|
|
||||||
import {ReflectionCapabilities, reflector, wtfInit} from '../core_private';
|
import {Console, ReflectionCapabilities, reflector, wtfInit} from '../core_private';
|
||||||
|
|
||||||
|
import {ConcreteType} from './facade/lang';
|
||||||
import {Parse5DomAdapter} from './parse5_adapter';
|
import {Parse5DomAdapter} from './parse5_adapter';
|
||||||
|
|
||||||
function notSupported(feature: string): Error {
|
function notSupported(feature: string): Error {
|
||||||
@ -31,23 +33,21 @@ class ServerPlatformLocation extends PlatformLocation {
|
|||||||
back(): void { notSupported('back'); };
|
back(): void { notSupported('back'); };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
export const INTERNAL_SERVER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
|
||||||
* A set of providers to initialize the Angular platform in a server.
|
|
||||||
*
|
|
||||||
* Used automatically by `serverBootstrap`, or can be passed to `platform`.
|
|
||||||
* @experimental
|
|
||||||
*/
|
|
||||||
export const SERVER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
|
|
||||||
PLATFORM_COMMON_PROVIDERS,
|
|
||||||
{provide: PLATFORM_INITIALIZER, useValue: initParse5Adapter, multi: true},
|
{provide: PLATFORM_INITIALIZER, useValue: initParse5Adapter, multi: true},
|
||||||
{provide: PlatformLocation, useClass: ServerPlatformLocation},
|
{provide: PlatformLocation, useClass: ServerPlatformLocation},
|
||||||
];
|
];
|
||||||
|
|
||||||
const SERVER_DYNAMIC_PROVIDERS: any[] = [
|
|
||||||
SERVER_PLATFORM_PROVIDERS,
|
|
||||||
{provide: CompilerFactory, useValue: BROWSER_DYNAMIC_TEST_COMPILER_FACTORY},
|
|
||||||
];
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A set of providers to initialize the Angular platform in a server.
|
||||||
|
*
|
||||||
|
* Used automatically by `serverBootstrap`, or can be passed to `platform`.
|
||||||
|
* @deprecated Use `serverPlatform()` or create a custom platform factory via
|
||||||
|
* `createPlatformFactory(serverPlatform, ...)`
|
||||||
|
*/
|
||||||
|
export const SERVER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||||
|
[PLATFORM_COMMON_PROVIDERS, INTERNAL_SERVER_PLATFORM_PROVIDERS];
|
||||||
|
|
||||||
function initParse5Adapter() {
|
function initParse5Adapter() {
|
||||||
Parse5DomAdapter.makeCurrent();
|
Parse5DomAdapter.makeCurrent();
|
||||||
@ -57,7 +57,8 @@ function initParse5Adapter() {
|
|||||||
/**
|
/**
|
||||||
* @experimental
|
* @experimental
|
||||||
*/
|
*/
|
||||||
export const serverPlatform = createPlatformFactory('server', SERVER_PLATFORM_PROVIDERS);
|
export const serverPlatform =
|
||||||
|
createPlatformFactory(corePlatform, 'server', INTERNAL_SERVER_PLATFORM_PROVIDERS);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The server platform that supports the runtime compiler.
|
* The server platform that supports the runtime compiler.
|
||||||
@ -65,7 +66,7 @@ export const serverPlatform = createPlatformFactory('server', SERVER_PLATFORM_PR
|
|||||||
* @experimental
|
* @experimental
|
||||||
*/
|
*/
|
||||||
export const serverDynamicPlatform =
|
export const serverDynamicPlatform =
|
||||||
createPlatformFactory('serverDynamic', SERVER_DYNAMIC_PROVIDERS);
|
createPlatformFactory(coreDynamicPlatform, 'serverDynamic', INTERNAL_SERVER_PLATFORM_PROVIDERS);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to bootstrap Angular in server environment (such as node).
|
* Used to bootstrap Angular in server environment (such as node).
|
||||||
@ -81,16 +82,35 @@ export const serverDynamicPlatform =
|
|||||||
* serverBootstrap(..., [BROWSER_APP_PROVIDERS, BROWSER_APP_COMPILER_PROVIDERS])
|
* serverBootstrap(..., [BROWSER_APP_PROVIDERS, BROWSER_APP_COMPILER_PROVIDERS])
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* @deprecated create an {@link AppModule} and use {@link bootstrapModule} with the {@link
|
* @deprecated create an {@link NgModule} and use {@link bootstrapModule} with the {@link
|
||||||
* serverDynamicPlatform}()
|
* serverDynamicPlatform}()
|
||||||
* instead.
|
* instead.
|
||||||
*/
|
*/
|
||||||
export function serverBootstrap(
|
export function serverBootstrap<T>(
|
||||||
appComponentType: Type,
|
appComponentType: ConcreteType<T>,
|
||||||
providers: Array<any /*Type | Provider | any[]*/>): Promise<ComponentRef<any>> {
|
customProviders: Array<any /*Type | Provider | any[]*/>): Promise<ComponentRef<T>> {
|
||||||
console.warn(
|
console.warn(
|
||||||
'serverBootstrap is deprecated. Create an @AppModule and use `bootstrapModule` with the `serverDynamicPlatform()` instead.');
|
'serverBootstrap is deprecated. Create an @NgModule and use `bootstrapModule` with the `serverDynamicPlatform()` instead.');
|
||||||
reflector.reflectionCapabilities = new ReflectionCapabilities();
|
reflector.reflectionCapabilities = new ReflectionCapabilities();
|
||||||
var appInjector = ReflectiveInjector.resolveAndCreate(providers, serverPlatform().injector);
|
|
||||||
return coreLoadAndBootstrap(appComponentType, appInjector);
|
const deprecatedConfiguration = analyzeAppProvidersForDeprecatedConfiguration(customProviders);
|
||||||
|
const declarations = [deprecatedConfiguration.moduleDeclarations.concat([appComponentType])];
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
providers: customProviders,
|
||||||
|
declarations: declarations,
|
||||||
|
imports: [BrowserModule],
|
||||||
|
precompile: [appComponentType]
|
||||||
|
})
|
||||||
|
class DynamicModule {
|
||||||
|
}
|
||||||
|
|
||||||
|
return bootstrapModule(
|
||||||
|
DynamicModule, serverDynamicPlatform(), deprecatedConfiguration.compilerOptions)
|
||||||
|
.then((moduleRef) => {
|
||||||
|
const console = moduleRef.injector.get(Console);
|
||||||
|
deprecatedConfiguration.deprecationMessages.forEach((msg) => console.warn(msg));
|
||||||
|
const appRef: ApplicationRef = moduleRef.injector.get(ApplicationRef);
|
||||||
|
return appRef.bootstrap(appComponentType);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@ -6,44 +6,67 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {AppModule, CompilerFactory, OpaqueToken, PLATFORM_COMMON_PROVIDERS, PLATFORM_INITIALIZER, PlatformRef, ReflectiveInjector, assertPlatform, createPlatform, createPlatformFactory, getPlatform} from '@angular/core';
|
import {analyzeAppProvidersForDeprecatedConfiguration} from '@angular/compiler';
|
||||||
import {BROWSER_DYNAMIC_TEST_COMPILER_FACTORY, BrowserDynamicTestModule, TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS} from '@angular/platform-browser-dynamic/testing';
|
import {coreDynamicTestingPlatform} from '@angular/compiler/testing';
|
||||||
|
import {CompilerFactory, CompilerOptions, NgModule, OpaqueToken, PLATFORM_COMMON_PROVIDERS, PLATFORM_INITIALIZER, PlatformRef, ReflectiveInjector, assertPlatform, createPlatform, createPlatformFactory, getPlatform} from '@angular/core';
|
||||||
|
import {initTestEnvironment} from '@angular/core/testing';
|
||||||
|
import {BrowserDynamicTestingModule, TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS, browserDynamicTestingPlatform} from '@angular/platform-browser-dynamic/testing';
|
||||||
|
|
||||||
|
import {Console} from '../core_private';
|
||||||
|
import {serverPlatform} from '../index';
|
||||||
import {Parse5DomAdapter} from '../src/parse5_adapter';
|
import {Parse5DomAdapter} from '../src/parse5_adapter';
|
||||||
|
import {INTERNAL_SERVER_PLATFORM_PROVIDERS} from '../src/server';
|
||||||
function initServerTests() {
|
|
||||||
Parse5DomAdapter.makeCurrent();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Use initTestEnvironment with serverTestPlatform instead.
|
|
||||||
*/
|
|
||||||
export const TEST_SERVER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
|
||||||
/*@ts2dart_const*/[
|
|
||||||
PLATFORM_COMMON_PROVIDERS,
|
|
||||||
/*@ts2dart_Provider*/ {provide: PLATFORM_INITIALIZER, useValue: initServerTests, multi: true},
|
|
||||||
{provide: CompilerFactory, useValue: BROWSER_DYNAMIC_TEST_COMPILER_FACTORY},
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Platform for testing
|
* Platform for testing
|
||||||
*
|
*
|
||||||
* @experimental API related to bootstrapping are still under review.
|
* @experimental API related to bootstrapping are still under review.
|
||||||
*/
|
*/
|
||||||
export const serverTestPlatform =
|
export const serverTestingPlatform = createPlatformFactory(
|
||||||
createPlatformFactory('serverTest', TEST_SERVER_PLATFORM_PROVIDERS);
|
coreDynamicTestingPlatform, 'serverTesting', INTERNAL_SERVER_PLATFORM_PROVIDERS);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AppModule for testing.
|
* NgModule for testing.
|
||||||
*
|
*
|
||||||
* @stable
|
* @experimental API related to bootstrapping are still under review.
|
||||||
*/
|
*/
|
||||||
@AppModule({modules: [BrowserDynamicTestModule]})
|
@NgModule({exports: [BrowserDynamicTestingModule]})
|
||||||
export class ServerTestModule {
|
export class ServerTestingModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use initTestEnvironment with ServerTestModule instead.
|
* Providers of the `serverTestingPlatform` to be used for creating own platform based on this.
|
||||||
|
*
|
||||||
|
* @deprecated Use `serverTestingPlatform()` or create a custom platform factory via
|
||||||
|
* `createPlatformFactory(serverTestingPlatform, ...)`
|
||||||
*/
|
*/
|
||||||
export const TEST_SERVER_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
export const TEST_SERVER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||||
TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS;
|
// Note: This is not a real provider but a hack to still support the deprecated
|
||||||
|
// `setBaseTestProviders` method!
|
||||||
|
[(appProviders: any[]) => {
|
||||||
|
const deprecatedConfiguration = analyzeAppProvidersForDeprecatedConfiguration(appProviders);
|
||||||
|
const platformRef = createPlatformFactory(serverTestingPlatform, 'serverTestingDeprecated', [{
|
||||||
|
provide: CompilerOptions,
|
||||||
|
useValue: deprecatedConfiguration.compilerOptions,
|
||||||
|
multi: true
|
||||||
|
}])();
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
exports: [ServerTestingModule],
|
||||||
|
declarations: [deprecatedConfiguration.moduleDeclarations]
|
||||||
|
})
|
||||||
|
class DynamicTestModule {
|
||||||
|
}
|
||||||
|
|
||||||
|
const testInjector = initTestEnvironment(DynamicTestModule, platformRef);
|
||||||
|
const console: Console = testInjector.get(Console);
|
||||||
|
deprecatedConfiguration.deprecationMessages.forEach((msg) => console.warn(msg));
|
||||||
|
}];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use initTestEnvironment with ServerTestModule instead. This is empty for backwards
|
||||||
|
* compatibility,
|
||||||
|
* as all of our bootstrap methods add a module implicitly, i.e. keeping this filled would add the
|
||||||
|
* providers 2x.
|
||||||
|
*/
|
||||||
|
export const TEST_SERVER_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [];
|
||||||
|
@ -10,3 +10,16 @@ Read the overview of the Router [here](http://victorsavkin.com/post/145672529346
|
|||||||
|
|
||||||
## Guide
|
## Guide
|
||||||
Read the dev guide [here](https://angular.io/docs/ts/latest/guide/router.html).
|
Read the dev guide [here](https://angular.io/docs/ts/latest/guide/router.html).
|
||||||
|
|
||||||
|
## Local development
|
||||||
|
|
||||||
|
```
|
||||||
|
# keep @angular/router fresh
|
||||||
|
$ ./scripts/karma.sh
|
||||||
|
|
||||||
|
# keep @angular/core fresh
|
||||||
|
$ ../../../node_modules/.bin/tsc -p modules --emitDecoratorMetadata -w
|
||||||
|
|
||||||
|
# start karma
|
||||||
|
$ ./scripts/karma.sh
|
||||||
|
```
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user