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
|
||||
*/
|
||||
|
||||
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/directives';
|
||||
export * from './src/forms-deprecated';
|
||||
export * from './src/common_directives';
|
||||
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
|
||||
* explicitly.
|
||||
*/
|
||||
import {AppModule, Type} from '@angular/core';
|
||||
import {NgModule, Type} from '@angular/core';
|
||||
|
||||
import {FORM_DIRECTIVES} from './forms-deprecated/directives';
|
||||
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
|
||||
*/
|
||||
@AppModule({
|
||||
@NgModule({
|
||||
providers: [
|
||||
FORM_PROVIDERS,
|
||||
],
|
||||
directives: FORM_DIRECTIVES,
|
||||
pipes: []
|
||||
declarations: FORM_DIRECTIVES,
|
||||
exports: FORM_DIRECTIVES
|
||||
})
|
||||
export class DeprecatedFormsModule {
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ import {PromiseWrapper} from '../../src/facade/promise';
|
|||
export function main() {
|
||||
describe('integration tests', () => {
|
||||
|
||||
beforeEach(() => { configureModule({modules: [DeprecatedFormsModule]}); });
|
||||
beforeEach(() => configureModule({imports: [DeprecatedFormsModule]}));
|
||||
|
||||
it('should initialize DOM elements with the given form object',
|
||||
inject(
|
||||
|
|
|
@ -30,13 +30,14 @@ generated code:
|
|||
main_module.ts
|
||||
-------------
|
||||
import {BrowserModule} from '@angular/platform-browser';
|
||||
import {Component, AppModule, ApplicationRef} from '@angular/core';
|
||||
import {Component, NgModule, ApplicationRef} from '@angular/core';
|
||||
|
||||
@Component(...)
|
||||
export class MyComponent {}
|
||||
|
||||
@AppModule({
|
||||
modules: [BrowserModule],
|
||||
@NgModule({
|
||||
imports: [BrowserModule],
|
||||
declarations: [MyComponent],
|
||||
precompile: [MyComponent]
|
||||
})
|
||||
export class MainModule {
|
||||
|
|
|
@ -8,10 +8,7 @@
|
|||
|
||||
import {Component} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'my-comp',
|
||||
template: '<div></div>',
|
||||
})
|
||||
@Component({selector: 'my-comp', template: '<div></div>', directives: [NextComp]})
|
||||
export class MultipleComponentsMyComp {
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<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>
|
||||
<div *ngFor="let x of ctxArr" [attr.value]="x"></div>
|
||||
|
|
|
@ -6,8 +6,9 @@
|
|||
* 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 {FORM_DIRECTIVES} from '@angular/forms';
|
||||
|
||||
import {MultipleComponentsMyComp} from './a/multiple_components';
|
||||
|
||||
|
|
|
@ -10,4 +10,4 @@ import {browserPlatform} from '@angular/platform-browser';
|
|||
import {BasicComp} from './basic';
|
||||
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
|
||||
*/
|
||||
|
||||
import {AppModule, ApplicationRef} from '@angular/core';
|
||||
import {ApplicationRef, NgModule} from '@angular/core';
|
||||
import {FormsModule} from '@angular/forms';
|
||||
import {BrowserModule} from '@angular/platform-browser';
|
||||
|
||||
import {AnimateCmp} from './animate';
|
||||
import {BasicComp} from './basic';
|
||||
import {CompWithProviders, CompWithReferences} from './features';
|
||||
import {CompUsingRootModuleDirectiveAndPipe, SomeDirectiveInRootModule, SomeLibModule, SomePipeInRootModule, SomeService} from './module_fixtures';
|
||||
import {CompWithAnalyzePrecompileProvider, CompWithPrecompile} from './precompile';
|
||||
import {ProjectingComp} from './projection';
|
||||
import {CompWithChildQuery} from './queries';
|
||||
import {CompWithChildQuery, CompWithDirectiveChild} from './queries';
|
||||
|
||||
@AppModule({
|
||||
modules: [BrowserModule],
|
||||
@NgModule({
|
||||
declarations: [
|
||||
SomeDirectiveInRootModule, SomePipeInRootModule, AnimateCmp, BasicComp, CompWithPrecompile,
|
||||
CompWithAnalyzePrecompileProvider, ProjectingComp, CompWithChildQuery, CompWithDirectiveChild,
|
||||
CompUsingRootModuleDirectiveAndPipe, CompWithProviders, CompWithReferences
|
||||
],
|
||||
imports: [BrowserModule, FormsModule, SomeLibModule],
|
||||
providers: [SomeService],
|
||||
precompile: [
|
||||
AnimateCmp, BasicComp, CompWithPrecompile, CompWithAnalyzePrecompileProvider, ProjectingComp,
|
||||
CompWithChildQuery
|
||||
CompWithChildQuery, CompUsingRootModuleDirectiveAndPipe
|
||||
]
|
||||
})
|
||||
export class MainModule {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
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';
|
||||
|
||||
@Injectable()
|
||||
|
@ -16,50 +16,37 @@ export class SomeService {
|
|||
}
|
||||
|
||||
@Injectable()
|
||||
export class NestedService {
|
||||
export class ServiceUsingLibModule {
|
||||
}
|
||||
|
||||
@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()
|
||||
someDir: string;
|
||||
}
|
||||
|
||||
@Pipe({name: 'somePipe'})
|
||||
export class SomePipe {
|
||||
export class SomePipeInRootModule {
|
||||
transform(value: string): any { return `transformed ${value}`; }
|
||||
}
|
||||
|
||||
@Component({selector: 'cmp', template: `<div [someDir]="'someValue' | somePipe"></div>`})
|
||||
export class SomeComp {
|
||||
constructor() {}
|
||||
@Pipe({name: 'somePipe'})
|
||||
export class SomePipeInLibModule {
|
||||
transform(value: string): any { return `transformed ${value}`; }
|
||||
}
|
||||
|
||||
@Component({selector: 'parent', template: `<cmp></cmp>`, directives: [SomeComp]})
|
||||
export class ParentComp {
|
||||
@Component({selector: 'comp', template: `<div [someDir]="'someValue' | somePipe"></div>`})
|
||||
export class CompUsingRootModuleDirectiveAndPipe {
|
||||
}
|
||||
|
||||
@AppModule({providers: [NestedService]})
|
||||
export class NestedModule {
|
||||
}
|
||||
|
||||
@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 {
|
||||
@Component({selector: 'comp', template: `<div [someDir]="'someValue' | somePipe"></div>`})
|
||||
export class CompUsingLibModuleDirectiveAndPipe {
|
||||
}
|
||||
|
||||
export const SOME_TOKEN = new OpaqueToken('someToken');
|
||||
|
@ -71,7 +58,13 @@ export function provideValueWithPrecompile(value: any) {
|
|||
];
|
||||
}
|
||||
|
||||
@AppModule({providers: [provideValueWithPrecompile([{a: 'b', component: SomeComp}])]})
|
||||
export class SomeModuleWithAnalyzePrecompileProvider {
|
||||
constructor(@Inject(SOME_TOKEN) public providedValue: any) {}
|
||||
@NgModule({
|
||||
declarations: [SomeDirectiveInLibModule, SomePipeInLibModule, CompUsingLibModuleDirectiveAndPipe],
|
||||
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
|
||||
*/
|
||||
|
||||
import {AppModuleFactory, AppModuleRef, bootstrapModuleFactory} from '@angular/core';
|
||||
import {NgModuleFactory, NgModuleRef, bootstrapModuleFactory} from '@angular/core';
|
||||
import {ComponentFixture} from '@angular/core/testing';
|
||||
import {serverPlatform} from '@angular/platform-server';
|
||||
|
||||
import {MainModule} from '../src/module';
|
||||
import {MainModuleNgFactory} from '../src/module.ngfactory';
|
||||
|
||||
export function createModule<M>(factory: AppModuleFactory<M>): AppModuleRef<M> {
|
||||
return bootstrapModuleFactory(factory, serverPlatform());
|
||||
export function createModule(): NgModuleRef<MainModule> {
|
||||
return bootstrapModuleFactory(MainModuleNgFactory, serverPlatform());
|
||||
}
|
||||
|
||||
export function createComponent<C>(
|
||||
comp: {new (...args: any[]): C},
|
||||
moduleFactory: AppModuleFactory<any> = null): ComponentFixture<C> {
|
||||
if (!moduleFactory) {
|
||||
moduleFactory = MainModuleNgFactory;
|
||||
}
|
||||
const moduleRef = createModule(moduleFactory);
|
||||
export function createComponent<C>(comp: {new (...args: any[]): C}): ComponentFixture<C> {
|
||||
const moduleRef = createModule();
|
||||
const compRef =
|
||||
moduleRef.componentFactoryResolver.resolveComponentFactory(comp).create(moduleRef.injector);
|
||||
return new ComponentFixture(compRef, null, null);
|
||||
|
|
|
@ -11,12 +11,12 @@
|
|||
* Intended to be used in a build step.
|
||||
*/
|
||||
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 * as path from 'path';
|
||||
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 {StaticAndDynamicReflectionCapabilities} from './static_reflection_capabilities';
|
||||
import {StaticReflector, StaticSymbol} from './static_reflector';
|
||||
|
@ -39,7 +39,7 @@ export class CodeGenerator {
|
|||
|
||||
private readFileMetadata(absSourcePath: string): FileMetadata {
|
||||
const moduleMetadata = this.staticReflector.getModuleMetadata(absSourcePath);
|
||||
const result: FileMetadata = {components: [], appModules: [], fileUrl: absSourcePath};
|
||||
const result: FileMetadata = {components: [], ngModules: [], fileUrl: absSourcePath};
|
||||
if (!moduleMetadata) {
|
||||
console.log(`WARNING: no metadata found for ${absSourcePath}`);
|
||||
return result;
|
||||
|
@ -57,8 +57,8 @@ export class CodeGenerator {
|
|||
const staticType = this.reflectorHost.findDeclaration(absSourcePath, symbol, absSourcePath);
|
||||
const annotations = this.staticReflector.annotations(staticType);
|
||||
annotations.forEach((annotation) => {
|
||||
if (annotation instanceof AppModuleMetadata) {
|
||||
result.appModules.push(staticType);
|
||||
if (annotation instanceof NgModuleMetadata) {
|
||||
result.ngModules.push(staticType);
|
||||
} else if (annotation instanceof ComponentMetadata) {
|
||||
result.components.push(staticType);
|
||||
}
|
||||
|
@ -86,17 +86,17 @@ export class CodeGenerator {
|
|||
let filePaths =
|
||||
this.program.getSourceFiles().map(sf => sf.fileName).filter(f => !GENERATED_FILES.test(f));
|
||||
let fileMetas = filePaths.map((filePath) => this.readFileMetadata(filePath));
|
||||
let appModules = fileMetas.reduce((appModules, fileMeta) => {
|
||||
appModules.push(...fileMeta.appModules);
|
||||
return appModules;
|
||||
let ngModules = fileMetas.reduce((ngModules, fileMeta) => {
|
||||
ngModules.push(...fileMeta.ngModules);
|
||||
return ngModules;
|
||||
}, <StaticSymbol[]>[]);
|
||||
let analyzedAppModules = this.compiler.analyzeModules(appModules);
|
||||
let analyzedNgModules = this.compiler.analyzeModules(ngModules);
|
||||
return Promise
|
||||
.all(fileMetas.map(
|
||||
(fileMeta) => this.compiler
|
||||
.compile(
|
||||
fileMeta.fileUrl, analyzedAppModules, fileMeta.components,
|
||||
fileMeta.appModules)
|
||||
fileMeta.fileUrl, analyzedNgModules, fileMeta.components,
|
||||
fileMeta.ngModules)
|
||||
.then((generatedModules) => {
|
||||
generatedModules.forEach((generatedModule) => {
|
||||
const sourceFile = this.program.getSourceFile(fileMeta.fileUrl);
|
||||
|
@ -139,11 +139,12 @@ export class CodeGenerator {
|
|||
expressionParser, new DomElementSchemaRegistry(), htmlParser,
|
||||
/*console*/ null, []);
|
||||
const resolver = new CompileMetadataResolver(
|
||||
new compiler.NgModuleResolver(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(
|
||||
resolver, normalizer, tmplParser, new StyleCompiler(urlResolver), new ViewCompiler(config),
|
||||
new AppModuleCompiler(), new TypeScriptEmitter(reflectorHost));
|
||||
new NgModuleCompiler(), new TypeScriptEmitter(reflectorHost));
|
||||
|
||||
return new CodeGenerator(
|
||||
options, program, compilerHost, staticReflector, offlineCompiler, reflectorHost);
|
||||
|
@ -153,5 +154,5 @@ export class CodeGenerator {
|
|||
interface FileMetadata {
|
||||
fileUrl: string;
|
||||
components: StaticSymbol[];
|
||||
appModules: StaticSymbol[];
|
||||
}
|
||||
ngModules: StaticSymbol[];
|
||||
}
|
||||
|
|
|
@ -61,8 +61,8 @@ export var StyleCompiler: typeof _c.StyleCompiler = _c.StyleCompiler;
|
|||
export type ViewCompiler = _c.ViewCompiler;
|
||||
export var ViewCompiler: typeof _c.ViewCompiler = _c.ViewCompiler;
|
||||
|
||||
export type AppModuleCompiler = _c.AppModuleCompiler;
|
||||
export var AppModuleCompiler: typeof _c.AppModuleCompiler = _c.AppModuleCompiler;
|
||||
export type NgModuleCompiler = _c.NgModuleCompiler;
|
||||
export var NgModuleCompiler: typeof _c.NgModuleCompiler = _c.NgModuleCompiler;
|
||||
|
||||
export type TypeScriptEmitter = _c.TypeScriptEmitter;
|
||||
export var TypeScriptEmitter: typeof _c.TypeScriptEmitter = _c.TypeScriptEmitter;
|
||||
|
|
|
@ -76,7 +76,7 @@ class Extractor {
|
|||
for (const symbol of symbols) {
|
||||
const staticType = this._reflectorHost.findDeclaration(absSourcePath, symbol, absSourcePath);
|
||||
let directive: compiler.CompileDirectiveMetadata;
|
||||
directive = this._resolver.maybeGetDirectiveMetadata(<any>staticType);
|
||||
directive = this._resolver.getDirectiveMetadata(<any>staticType, false);
|
||||
|
||||
if (directive && directive.isComponent) {
|
||||
let promise = this._normalizer.normalizeDirective(directive).asyncResult;
|
||||
|
@ -147,8 +147,9 @@ class Extractor {
|
|||
const normalizer = new DirectiveNormalizer(xhr, urlResolver, htmlParser, config);
|
||||
const expressionParser = new Parser(new Lexer());
|
||||
const resolver = new CompileMetadataResolver(
|
||||
new compiler.NgModuleResolver(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
|
||||
const extractor = new MessageExtractor(htmlParser, expressionParser, [], {});
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* 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';
|
||||
|
||||
|
@ -217,7 +217,7 @@ export class StaticReflector implements ReflectorReader {
|
|||
this.registerDecoratorOrConstructor(
|
||||
this.host.findDeclaration(coreDecorators, 'Component'), ComponentMetadata);
|
||||
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.
|
||||
this.registerDecoratorOrConstructor(
|
||||
|
@ -619,4 +619,4 @@ function sameSymbol(a: StaticSymbol, b: StaticSymbol): boolean {
|
|||
|
||||
function shouldIgnore(value: any): boolean {
|
||||
return value && value.__symbolic == 'ignore';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
* @description
|
||||
* 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 * 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 type ReflectorReader = t.ReflectorReader;
|
||||
export var ReflectorReader: typeof t.ReflectorReader = r.ReflectorReader;
|
||||
export var ReflectorComponentResolver: typeof t.ReflectorComponentResolver =
|
||||
r.ReflectorComponentResolver;
|
||||
export type AppElement = t.AppElement;
|
||||
export var AppElement: typeof t.AppElement = r.AppElement;
|
||||
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 type DebugAppView<T> = t.DebugAppView<T>;
|
||||
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 var ViewType: typeof t.ViewType = r.ViewType;
|
||||
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: typeof t.Reflector = r.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 var NoOpAnimationPlayer: typeof t.NoOpAnimationPlayer = r.NoOpAnimationPlayer;
|
||||
export type AnimationPlayer = t.AnimationPlayer;
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
* 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 lexer from './src/expression_parser/lexer';
|
||||
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 xmb_serializer from './src/i18n/xmb_serializer';
|
||||
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 ts_emitter from './src/output/ts_emitter';
|
||||
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 var ViewCompiler = view_compiler.ViewCompiler;
|
||||
|
||||
export type AppModuleCompiler = app_module_compiler.AppModuleCompiler;
|
||||
export var AppModuleCompiler = app_module_compiler.AppModuleCompiler;
|
||||
export type NgModuleCompiler = ng_module_compiler.NgModuleCompiler;
|
||||
export var NgModuleCompiler = ng_module_compiler.NgModuleCompiler;
|
||||
|
||||
export type 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 2: "event" from "(event)"
|
||||
// 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 {
|
||||
abstract toJson(): {[key: string]: any};
|
||||
|
||||
get identifier(): CompileIdentifierMetadata { return <CompileIdentifierMetadata>unimplemented(); }
|
||||
}
|
||||
|
||||
export abstract class CompileMetadataWithType extends CompileMetadataWithIdentifier {
|
||||
abstract toJson(): {[key: string]: any};
|
||||
get runtimeCacheKey(): any { return unimplemented(); }
|
||||
|
||||
get type(): CompileTypeMetadata { return <CompileTypeMetadata>unimplemented(); }
|
||||
get assetCacheKey(): any { return unimplemented(); }
|
||||
|
||||
get identifier(): CompileIdentifierMetadata { return <CompileIdentifierMetadata>unimplemented(); }
|
||||
}
|
||||
|
||||
export function metadataFromJson(data: {[key: string]: any}): any {
|
||||
return (_COMPILE_METADATA_FROM_JSON as any)[data['class']](data);
|
||||
equalsTo(id2: CompileMetadataWithIdentifier): boolean { return unimplemented(); }
|
||||
}
|
||||
|
||||
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(
|
||||
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 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) {
|
||||
super();
|
||||
}
|
||||
|
||||
toJson(): {[key: string]: any} {
|
||||
return {
|
||||
'class': 'AnimationStateDeclarationMetadata',
|
||||
'value': {'stateNameExpr': this.stateNameExpr, 'styles': this.styles.toJson()}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
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(); }
|
||||
|
||||
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 {
|
||||
static fromJson(data: {[key: string]: any}): CompileAnimationKeyframesSequenceMetadata {
|
||||
var steps = _arrayFromJson(data['value'], metadataFromJson);
|
||||
return new CompileAnimationKeyframesSequenceMetadata(<CompileAnimationStyleMetadata[]>steps);
|
||||
}
|
||||
|
||||
constructor(public steps: CompileAnimationStyleMetadata[] = []) { super(); }
|
||||
|
||||
toJson(): {[key: string]: any} {
|
||||
return {'class': 'AnimationKeyframesSequenceMetadata', 'value': _arrayToJson(this.steps)};
|
||||
}
|
||||
}
|
||||
|
||||
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(
|
||||
public offset: number, public styles: Array<string|{[key: string]: string | number}> = null) {
|
||||
super();
|
||||
}
|
||||
|
||||
toJson(): {[key: string]: any} {
|
||||
return {
|
||||
'class': 'AnimationStyleMetadata',
|
||||
'value': {'offset': this.offset, 'styles': this.styles}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
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(
|
||||
public timings: string|number = 0, public styles: CompileAnimationStyleMetadata|
|
||||
CompileAnimationKeyframesSequenceMetadata = null) {
|
||||
super();
|
||||
}
|
||||
|
||||
toJson(): {[key: string]: any} {
|
||||
return {
|
||||
'class': 'AnimationAnimateMetadata',
|
||||
'value': {'timings': this.timings, 'styles': _objToJson(this.styles)}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class CompileAnimationWithStepsMetadata extends CompileAnimationMetadata {
|
||||
|
@ -162,29 +78,11 @@ export abstract class CompileAnimationWithStepsMetadata extends CompileAnimation
|
|||
}
|
||||
|
||||
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); }
|
||||
|
||||
toJson(): {[key: string]: any} {
|
||||
return {'class': 'AnimationSequenceMetadata', 'value': _arrayToJson(this.steps)};
|
||||
}
|
||||
}
|
||||
|
||||
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); }
|
||||
|
||||
toJson(): {[key: string]: any} {
|
||||
return {'class': 'AnimationGroupMetadata', 'value': _arrayToJson(this.steps)};
|
||||
}
|
||||
}
|
||||
|
||||
export class CompileIdentifierMetadata implements CompileMetadataWithIdentifier {
|
||||
|
@ -193,6 +91,7 @@ export class CompileIdentifierMetadata implements CompileMetadataWithIdentifier
|
|||
prefix: string;
|
||||
moduleUrl: string;
|
||||
value: any;
|
||||
private _assetCacheKey: any = UNDEFINED;
|
||||
|
||||
constructor(
|
||||
{runtime, name, moduleUrl, prefix, value}:
|
||||
|
@ -204,26 +103,28 @@ export class CompileIdentifierMetadata implements CompileMetadataWithIdentifier
|
|||
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 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 {
|
||||
|
@ -263,36 +164,6 @@ export class CompileDiDependencyMetadata {
|
|||
this.token = token;
|
||||
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 {
|
||||
|
@ -321,41 +192,9 @@ export class CompileProviderMetadata {
|
|||
this.deps = normalizeBlank(deps);
|
||||
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,
|
||||
CompileMetadataWithIdentifier {
|
||||
runtime: Function;
|
||||
name: string;
|
||||
prefix: string;
|
||||
moduleUrl: string;
|
||||
value: any;
|
||||
export class CompileFactoryMetadata extends CompileIdentifierMetadata {
|
||||
diDeps: CompileDiDependencyMetadata[];
|
||||
|
||||
constructor({runtime, name, moduleUrl, prefix, diDeps, value}: {
|
||||
|
@ -366,45 +205,15 @@ export class CompileFactoryMetadata implements CompileIdentifierMetadata,
|
|||
value?: boolean,
|
||||
diDeps?: CompileDiDependencyMetadata[]
|
||||
}) {
|
||||
this.runtime = runtime;
|
||||
this.name = name;
|
||||
this.prefix = prefix;
|
||||
this.moduleUrl = moduleUrl;
|
||||
super({runtime: runtime, name: name, prefix: prefix, moduleUrl: moduleUrl, value: value});
|
||||
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 {
|
||||
value: any;
|
||||
identifier: CompileIdentifierMetadata;
|
||||
identifierIsInstance: boolean;
|
||||
private _assetCacheKey = UNDEFINED;
|
||||
|
||||
constructor(
|
||||
{value, identifier, identifierIsInstance}:
|
||||
|
@ -414,46 +223,20 @@ export class CompileTokenMetadata implements CompileMetadataWithIdentifier {
|
|||
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 {
|
||||
if (isPresent(this.identifier)) {
|
||||
return this.identifier.runtime;
|
||||
return this.identifier.runtimeCacheKey;
|
||||
} else {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
get assetCacheKey(): any {
|
||||
if (this._assetCacheKey === UNDEFINED) {
|
||||
if (isPresent(this.identifier)) {
|
||||
if (isPresent(this.identifier.moduleUrl) &&
|
||||
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 {
|
||||
this._assetCacheKey = null;
|
||||
}
|
||||
} else {
|
||||
this._assetCacheKey = this.value;
|
||||
}
|
||||
if (isPresent(this.identifier)) {
|
||||
return this.identifier.assetCacheKey;
|
||||
} else {
|
||||
return this.value;
|
||||
}
|
||||
return this._assetCacheKey;
|
||||
}
|
||||
|
||||
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 _values: VALUE[] = [];
|
||||
private _tokens: CompileTokenMetadata[] = [];
|
||||
private _tokens: KEY[] = [];
|
||||
|
||||
add(token: CompileTokenMetadata, value: VALUE) {
|
||||
add(token: KEY, value: VALUE) {
|
||||
var existing = this.get(token);
|
||||
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._values.push(value);
|
||||
|
@ -489,7 +281,7 @@ export class CompileTokenMap<VALUE> {
|
|||
this._valueMap.set(ak, value);
|
||||
}
|
||||
}
|
||||
get(token: CompileTokenMetadata): VALUE {
|
||||
get(token: KEY): VALUE {
|
||||
var rk = token.runtimeCacheKey;
|
||||
var ak = token.assetCacheKey;
|
||||
var result: VALUE;
|
||||
|
@ -501,7 +293,7 @@ export class CompileTokenMap<VALUE> {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
keys(): CompileTokenMetadata[] { return this._tokens; }
|
||||
keys(): KEY[] { return this._tokens; }
|
||||
values(): VALUE[] { return this._values; }
|
||||
get size(): number { return this._values.length; }
|
||||
}
|
||||
|
@ -509,13 +301,8 @@ export class CompileTokenMap<VALUE> {
|
|||
/**
|
||||
* Metadata regarding compilation of a type.
|
||||
*/
|
||||
export class CompileTypeMetadata implements CompileIdentifierMetadata, CompileMetadataWithType {
|
||||
runtime: Type;
|
||||
name: string;
|
||||
prefix: string;
|
||||
moduleUrl: string;
|
||||
export class CompileTypeMetadata extends CompileIdentifierMetadata {
|
||||
isHost: boolean;
|
||||
value: any;
|
||||
diDeps: CompileDiDependencyMetadata[];
|
||||
|
||||
constructor({runtime, name, moduleUrl, prefix, isHost, value, diDeps}: {
|
||||
|
@ -527,41 +314,10 @@ export class CompileTypeMetadata implements CompileIdentifierMetadata, CompileMe
|
|||
value?: any,
|
||||
diDeps?: CompileDiDependencyMetadata[]
|
||||
} = {}) {
|
||||
this.runtime = runtime;
|
||||
this.name = name;
|
||||
this.moduleUrl = moduleUrl;
|
||||
this.prefix = prefix;
|
||||
super({runtime: runtime, name: name, moduleUrl: moduleUrl, prefix: prefix, value: value});
|
||||
this.isHost = normalizeBool(isHost);
|
||||
this.value = value;
|
||||
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 {
|
||||
|
@ -584,26 +340,6 @@ export class CompileQueryMetadata {
|
|||
this.propertyName = propertyName;
|
||||
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.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;
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
export class CompileDirectiveMetadata implements CompileMetadataWithType {
|
||||
export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
|
||||
static create(
|
||||
{type, isComponent, selector, exportAs, changeDetection, inputs, outputs, host,
|
||||
lifecycleHooks, providers, viewProviders, queries, viewQueries, precompile, template}: {
|
||||
|
@ -796,6 +489,7 @@ export class CompileDirectiveMetadata implements CompileMetadataWithType {
|
|||
viewProviders: CompileProviderMetadata[];
|
||||
queries: CompileQueryMetadata[];
|
||||
viewQueries: CompileQueryMetadata[];
|
||||
// Note: Need to keep types here to prevent cycles!
|
||||
precompile: CompileTypeMetadata[];
|
||||
template: CompileTemplateMetadata;
|
||||
|
||||
|
@ -844,68 +538,26 @@ export class CompileDirectiveMetadata implements CompileMetadataWithType {
|
|||
|
||||
get identifier(): CompileIdentifierMetadata { return this.type; }
|
||||
|
||||
static fromJson(data: {[key: string]: any}): CompileDirectiveMetadata {
|
||||
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)
|
||||
});
|
||||
}
|
||||
get runtimeCacheKey(): any { return this.type.runtimeCacheKey; }
|
||||
|
||||
toJson(): {[key: string]: any} {
|
||||
return {
|
||||
'class': 'Directive',
|
||||
'isComponent': this.isComponent,
|
||||
'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)
|
||||
};
|
||||
get assetCacheKey(): any { return this.type.assetCacheKey; }
|
||||
|
||||
equalsTo(other: CompileMetadataWithIdentifier): boolean {
|
||||
return this.type.equalsTo(other.identifier);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct {@link CompileDirectiveMetadata} from {@link ComponentTypeMetadata} and a selector.
|
||||
*/
|
||||
export function createHostComponentMeta(
|
||||
componentType: CompileTypeMetadata, componentSelector: string): CompileDirectiveMetadata {
|
||||
var template = CssSelector.parse(componentSelector)[0].getMatchingElementTemplate();
|
||||
export function createHostComponentMeta(compMeta: CompileDirectiveMetadata):
|
||||
CompileDirectiveMetadata {
|
||||
var template = CssSelector.parse(compMeta.selector)[0].getMatchingElementTemplate();
|
||||
return CompileDirectiveMetadata.create({
|
||||
type: new CompileTypeMetadata({
|
||||
runtime: Object,
|
||||
name: `${componentType.name}_Host`,
|
||||
moduleUrl: componentType.moduleUrl,
|
||||
name: `${compMeta.type.name}_Host`,
|
||||
moduleUrl: compMeta.type.moduleUrl,
|
||||
isHost: true
|
||||
}),
|
||||
template: new CompileTemplateMetadata({
|
||||
|
@ -931,7 +583,7 @@ export function createHostComponentMeta(
|
|||
}
|
||||
|
||||
|
||||
export class CompilePipeMetadata implements CompileMetadataWithType {
|
||||
export class CompilePipeMetadata implements CompileMetadataWithIdentifier {
|
||||
type: CompileTypeMetadata;
|
||||
name: string;
|
||||
pure: boolean;
|
||||
|
@ -949,114 +601,91 @@ export class CompilePipeMetadata implements CompileMetadataWithType {
|
|||
this.lifecycleHooks = _normalizeArray(lifecycleHooks);
|
||||
}
|
||||
get identifier(): CompileIdentifierMetadata { return this.type; }
|
||||
get runtimeCacheKey(): any { return this.type.runtimeCacheKey; }
|
||||
|
||||
static fromJson(data: {[key: string]: any}): CompilePipeMetadata {
|
||||
return new CompilePipeMetadata({
|
||||
type: isPresent(data['type']) ? CompileTypeMetadata.fromJson(data['type']) : data['type'],
|
||||
name: data['name'],
|
||||
pure: data['pure']
|
||||
});
|
||||
}
|
||||
get assetCacheKey(): any { return this.type.assetCacheKey; }
|
||||
|
||||
toJson(): {[key: string]: any} {
|
||||
return {
|
||||
'class': 'Pipe',
|
||||
'type': isPresent(this.type) ? this.type.toJson() : null,
|
||||
'name': this.name,
|
||||
'pure': this.pure
|
||||
};
|
||||
equalsTo(other: CompileMetadataWithIdentifier): boolean {
|
||||
return this.type.equalsTo(other.identifier);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Metadata regarding compilation of a directive.
|
||||
*/
|
||||
export class CompileAppModuleMetadata implements CompileMetadataWithType {
|
||||
export class CompileNgModuleMetadata implements CompileMetadataWithIdentifier {
|
||||
type: CompileTypeMetadata;
|
||||
providers: CompileProviderMetadata[];
|
||||
directives: CompileTypeMetadata[];
|
||||
pipes: CompileTypeMetadata[];
|
||||
declaredDirectives: CompileDirectiveMetadata[];
|
||||
exportedDirectives: CompileDirectiveMetadata[];
|
||||
declaredPipes: CompilePipeMetadata[];
|
||||
exportedPipes: CompilePipeMetadata[];
|
||||
// Note: See CompileDirectiveMetadata.precompile why this has to be a type.
|
||||
precompile: CompileTypeMetadata[];
|
||||
modules: CompileTypeMetadata[];
|
||||
providers: CompileProviderMetadata[];
|
||||
|
||||
constructor({type, providers, directives, pipes, precompile, modules}: {
|
||||
type?: CompileTypeMetadata,
|
||||
providers?: Array<CompileProviderMetadata|CompileTypeMetadata|CompileIdentifierMetadata|any[]>,
|
||||
directives?: CompileTypeMetadata[],
|
||||
pipes?: CompileTypeMetadata[],
|
||||
precompile?: CompileTypeMetadata[],
|
||||
modules?: CompileTypeMetadata[]
|
||||
} = {}) {
|
||||
importedModules: CompileNgModuleMetadata[];
|
||||
exportedModules: CompileNgModuleMetadata[];
|
||||
|
||||
transitiveModule: TransitiveCompileNgModuleMetadata;
|
||||
|
||||
constructor(
|
||||
{type, providers, declaredDirectives, exportedDirectives, declaredPipes, exportedPipes,
|
||||
precompile, importedModules, exportedModules, transitiveModule}: {
|
||||
type?: CompileTypeMetadata,
|
||||
providers?:
|
||||
Array<CompileProviderMetadata|CompileTypeMetadata|CompileIdentifierMetadata|any[]>,
|
||||
declaredDirectives?: CompileDirectiveMetadata[],
|
||||
exportedDirectives?: CompileDirectiveMetadata[],
|
||||
declaredPipes?: CompilePipeMetadata[],
|
||||
exportedPipes?: CompilePipeMetadata[],
|
||||
precompile?: CompileTypeMetadata[],
|
||||
importedModules?: CompileNgModuleMetadata[],
|
||||
exportedModules?: CompileNgModuleMetadata[],
|
||||
transitiveModule?: TransitiveCompileNgModuleMetadata
|
||||
} = {}) {
|
||||
this.type = type;
|
||||
this.directives = _normalizeArray(directives);
|
||||
this.pipes = _normalizeArray(pipes);
|
||||
this.declaredDirectives = _normalizeArray(declaredDirectives);
|
||||
this.exportedDirectives = _normalizeArray(exportedDirectives);
|
||||
this.declaredPipes = _normalizeArray(declaredPipes);
|
||||
this.exportedPipes = _normalizeArray(exportedPipes);
|
||||
this.providers = _normalizeArray(providers);
|
||||
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 runtimeCacheKey(): any { return this.type.runtimeCacheKey; }
|
||||
|
||||
static fromJson(data: {[key: string]: any}): CompileAppModuleMetadata {
|
||||
return new CompileAppModuleMetadata({
|
||||
type: isPresent(data['type']) ? CompileTypeMetadata.fromJson(data['type']) : data['type'],
|
||||
providers: _arrayFromJson(data['providers'], metadataFromJson),
|
||||
directives: _arrayFromJson(data['directives'], metadataFromJson),
|
||||
pipes: _arrayFromJson(data['pipes'], metadataFromJson),
|
||||
precompile: _arrayFromJson(data['precompile'], CompileTypeMetadata.fromJson),
|
||||
modules: _arrayFromJson(data['modules'], CompileTypeMetadata.fromJson)
|
||||
});
|
||||
}
|
||||
get assetCacheKey(): any { return this.type.assetCacheKey; }
|
||||
|
||||
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)
|
||||
};
|
||||
equalsTo(other: CompileMetadataWithIdentifier): boolean {
|
||||
return this.type.equalsTo(other.identifier);
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
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();
|
||||
}
|
||||
|
||||
function _normalizeArray(obj: any[]): any[] {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* 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 {TEMPLATE_TRANSFORMS} from './template_parser';
|
||||
|
@ -20,14 +20,17 @@ export * from './xhr';
|
|||
export {ViewResolver} from './view_resolver';
|
||||
export {DirectiveResolver} from './directive_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 {HtmlParser} from './html_parser';
|
||||
import {DirectiveNormalizer} from './directive_normalizer';
|
||||
import {CompileMetadataResolver} from './metadata_resolver';
|
||||
import {StyleCompiler} from './style_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 {RuntimeCompiler} from './runtime_compiler';
|
||||
import {ElementSchemaRegistry} from './schema/element_schema_registry';
|
||||
|
@ -38,19 +41,24 @@ import {Lexer} from './expression_parser/lexer';
|
|||
import {ViewResolver} from './view_resolver';
|
||||
import {DirectiveResolver} from './directive_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';
|
||||
|
||||
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
|
||||
* template compilation.
|
||||
*/
|
||||
export const COMPILER_PROVIDERS: Array<any|Type|{[k: string]: any}|any[]> =
|
||||
/*@ts2dart_const*/[
|
||||
{provide: PLATFORM_DIRECTIVES, useValue: [], multi: true},
|
||||
{provide: PLATFORM_PIPES, useValue: [], multi: true},
|
||||
{provide: Reflector, useValue: reflector},
|
||||
{provide: ReflectorReader, useExisting: Reflector},
|
||||
{provide: XHR, useValue: _NO_XHR},
|
||||
Console,
|
||||
Lexer,
|
||||
Parser,
|
||||
|
@ -61,112 +69,153 @@ export const COMPILER_PROVIDERS: Array<any|Type|{[k: string]: any}|any[]> =
|
|||
DEFAULT_PACKAGE_URL_PROVIDER,
|
||||
StyleCompiler,
|
||||
ViewCompiler,
|
||||
AppModuleCompiler,
|
||||
NgModuleCompiler,
|
||||
/*@ts2dart_Provider*/ {provide: CompilerConfig, useValue: new CompilerConfig()},
|
||||
RuntimeCompiler,
|
||||
/*@ts2dart_Provider*/ {provide: ComponentResolver, useExisting: RuntimeCompiler},
|
||||
/*@ts2dart_Provider*/ {provide: Compiler, useExisting: RuntimeCompiler},
|
||||
DomElementSchemaRegistry,
|
||||
/*@ts2dart_Provider*/ {provide: ElementSchemaRegistry, useExisting: DomElementSchemaRegistry},
|
||||
UrlResolver,
|
||||
ViewResolver,
|
||||
DirectiveResolver,
|
||||
PipeResolver
|
||||
PipeResolver,
|
||||
NgModuleResolver
|
||||
];
|
||||
|
||||
|
||||
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
|
||||
// of configuring platform directives / pipes and the compiler xhr.
|
||||
// This will soon be deprecated!
|
||||
const tempInj = ReflectiveInjector.resolveAndCreate(appProviders);
|
||||
const compilerConfig: CompilerConfig = tempInj.get(CompilerConfig, null);
|
||||
if (compilerConfig) {
|
||||
platformDirectives = compilerConfig.platformDirectives;
|
||||
platformPipes = compilerConfig.platformPipes;
|
||||
useJit = compilerConfig.useJit;
|
||||
useDebug = compilerConfig.genDebugInfo;
|
||||
defaultEncapsulation = compilerConfig.defaultEncapsulation;
|
||||
deprecationMessages.push(
|
||||
`Passing CompilerConfig as a regular provider is deprecated. Use the "compilerOptions" parameter of "bootstrap()" or use a custom "CompilerFactory" platform provider instead.`);
|
||||
} else {
|
||||
// If nobody provided a CompilerConfig, use the
|
||||
// PLATFORM_DIRECTIVES / PLATFORM_PIPES values directly if existing
|
||||
platformDirectives = tempInj.get(PLATFORM_DIRECTIVES, []);
|
||||
platformPipes = tempInj.get(PLATFORM_PIPES, []);
|
||||
}
|
||||
platformDirectives = ListWrapper.flatten(platformDirectives);
|
||||
platformPipes = ListWrapper.flatten(platformPipes);
|
||||
const xhr = tempInj.get(XHR, null);
|
||||
if (xhr) {
|
||||
compilerProviders.push([{provide: XHR, useValue: xhr}]);
|
||||
deprecationMessages.push(
|
||||
`Passing XHR as regular provider is deprecated. Pass the provider via "compilerOptions" instead.`);
|
||||
}
|
||||
|
||||
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 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) {
|
||||
// Note: This is a hack to still support the old way
|
||||
// of configuring platform directives / pipes and the compiler xhr.
|
||||
// This will soon be deprecated!
|
||||
const inj = ReflectiveInjector.resolveAndCreate(options.deprecatedAppProviders);
|
||||
const compilerConfig: CompilerConfig = inj.get(CompilerConfig, null);
|
||||
if (compilerConfig) {
|
||||
platformDirectivesFromAppProviders = compilerConfig.deprecatedPlatformDirectives;
|
||||
platformPipesFromAppProviders = compilerConfig.deprecatedPlatformPipes;
|
||||
useJitFromAppProviders = compilerConfig.useJit;
|
||||
useDebugFromAppProviders = compilerConfig.genDebugInfo;
|
||||
defaultEncapsulationFromAppProviders = compilerConfig.defaultEncapsulation;
|
||||
deprecationMessages.push(
|
||||
`Passing a CompilerConfig to "bootstrap()" as provider is deprecated. Pass the provider via the new parameter "compilerOptions" of "bootstrap()" instead.`);
|
||||
} else {
|
||||
// If nobody provided a CompilerConfig, use the
|
||||
// PLATFORM_DIRECTIVES / PLATFORM_PIPES values directly if existing
|
||||
platformDirectivesFromAppProviders = inj.get(PLATFORM_DIRECTIVES, []);
|
||||
if (platformDirectivesFromAppProviders.length > 0) {
|
||||
deprecationMessages.push(
|
||||
`Passing PLATFORM_DIRECTIVES to "bootstrap()" as provider is deprecated. Use the new parameter "directives" of "bootstrap()" instead.`);
|
||||
}
|
||||
platformPipesFromAppProviders = inj.get(PLATFORM_PIPES, []);
|
||||
if (platformPipesFromAppProviders.length > 0) {
|
||||
deprecationMessages.push(
|
||||
`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) {
|
||||
compilerProvidersFromAppProviders.push([{provide: XHR, useValue: xhr}]);
|
||||
deprecationMessages.push(
|
||||
`Passing an instance of XHR to "bootstrap()" as provider is deprecated. Pass the provider via the new parameter "compilerOptions" of "bootstrap()" 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}]);
|
||||
}
|
||||
}
|
||||
|
||||
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([
|
||||
COMPILER_PROVIDERS, {
|
||||
provide: CompilerConfig,
|
||||
useFactory: (platformDirectives: any[], platformPipes: any[]) => {
|
||||
useFactory: () => {
|
||||
return new CompilerConfig({
|
||||
deprecatedPlatformDirectives:
|
||||
_mergeArrays(platformDirectivesFromAppProviders, platformDirectives),
|
||||
deprecatedPlatformPipes: _mergeArrays(platformPipesFromAppProviders, platformPipes),
|
||||
// let explicit values from the compiler options overwrite options
|
||||
// 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
|
||||
// from the app providers
|
||||
useJit: _firstDefined(options.useJit, useJitFromAppProviders, true),
|
||||
useJit: mergedOptions.useJit,
|
||||
// let explicit values from the compiler options overwrite options
|
||||
// from the app providers
|
||||
defaultEncapsulation: _firstDefined(
|
||||
options.defaultEncapsulation, defaultEncapsulationFromAppProviders,
|
||||
ViewEncapsulation.Emulated)
|
||||
defaultEncapsulation: mergedOptions.defaultEncapsulation,
|
||||
logBindingUpdate: mergedOptions.useDebug
|
||||
});
|
||||
},
|
||||
deps: [PLATFORM_DIRECTIVES, PLATFORM_PIPES]
|
||||
deps: []
|
||||
},
|
||||
// options.providers will always contain a provider for XHR as well
|
||||
// (added by platforms). So allow compilerProvidersFromAppProviders to overwrite this
|
||||
_mergeArrays(options.providers, compilerProvidersFromAppProviders)
|
||||
mergedOptions.providers
|
||||
]);
|
||||
const console: Console = injector.get(Console);
|
||||
deprecationMessages.forEach((msg) => { console.warn(msg); });
|
||||
|
||||
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 {
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
function _mergeOptions(optionsArr: CompilerOptions[]): CompilerOptions {
|
||||
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) {
|
||||
return args[i];
|
||||
}
|
||||
|
@ -174,7 +223,7 @@ function _firstDefined<T>(...args: T[]): T {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
function _mergeArrays(...parts: any[][]): any[] {
|
||||
function _mergeArrays(parts: any[][]): any[] {
|
||||
let result: any[] = [];
|
||||
parts.forEach((part) => result.push(...part));
|
||||
return result;
|
||||
|
|
|
@ -20,17 +20,15 @@ export class CompilerConfig {
|
|||
private _logBindingUpdate: boolean;
|
||||
public useJit: boolean;
|
||||
/**
|
||||
* @deprecated Providing platform directives via the {@link CompilerConfig} deprecated. Provide
|
||||
* platform
|
||||
* directives via an {@link AppModule} instead.
|
||||
* @deprecated Providing platform directives via the {@link CompilerConfig} is deprecated. Provide
|
||||
* platform directives via an {@link NgModule} instead.
|
||||
*/
|
||||
public deprecatedPlatformDirectives: any[];
|
||||
public platformDirectives: any[];
|
||||
/**
|
||||
* @deprecated Providing platform pipes via the {@link CompilerConfig} deprecated. Provide
|
||||
* platform pipes
|
||||
* via an {@link AppModule} instead.
|
||||
* @deprecated Providing platform pipes via the {@link CompilerConfig} is deprecated. Provide
|
||||
* platform pipes via an {@link NgModule} instead.
|
||||
*/
|
||||
public deprecatedPlatformPipes: any[];
|
||||
public platformPipes: any[];
|
||||
|
||||
constructor(
|
||||
{renderTypes = new DefaultRenderTypes(), defaultEncapsulation = ViewEncapsulation.Emulated,
|
||||
|
@ -49,8 +47,8 @@ export class CompilerConfig {
|
|||
this._genDebugInfo = genDebugInfo;
|
||||
this._logBindingUpdate = logBindingUpdate;
|
||||
this.useJit = useJit;
|
||||
this.deprecatedPlatformDirectives = deprecatedPlatformDirectives;
|
||||
this.deprecatedPlatformPipes = deprecatedPlatformPipes;
|
||||
this.platformDirectives = deprecatedPlatformDirectives;
|
||||
this.platformPipes = deprecatedPlatformPipes;
|
||||
}
|
||||
|
||||
get genDebugInfo(): boolean {
|
||||
|
|
|
@ -33,7 +33,7 @@ export class DirectiveResolver {
|
|||
/**
|
||||
* Return {@link DirectiveMetadata} for a given `Type`.
|
||||
*/
|
||||
resolve(type: Type): DirectiveMetadata {
|
||||
resolve(type: Type, throwIfNotFound = true): DirectiveMetadata {
|
||||
var typeMetadata = this._reflector.annotations(resolveForwardRef(type));
|
||||
if (isPresent(typeMetadata)) {
|
||||
var metadata = typeMetadata.find(_isDirectiveMetadata);
|
||||
|
@ -42,8 +42,10 @@ export class DirectiveResolver {
|
|||
return this._mergeWithPropertyMetadata(metadata, propertyMetadata, type);
|
||||
}
|
||||
}
|
||||
|
||||
throw new BaseException(`No Directive annotation found on ${stringify(type)}`);
|
||||
if (throwIfNotFound) {
|
||||
throw new BaseException(`No Directive annotation found on ${stringify(type)}`);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private _mergeWithPropertyMetadata(
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
* 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 {assetUrl} from './util';
|
||||
|
@ -118,15 +118,15 @@ export class Identifiers {
|
|||
runtime: ComponentFactory,
|
||||
moduleUrl: assetUrl('core', 'linker/component_factory')
|
||||
});
|
||||
static AppModuleFactory = new CompileIdentifierMetadata({
|
||||
name: 'AppModuleFactory',
|
||||
runtime: AppModuleFactory,
|
||||
moduleUrl: assetUrl('core', 'linker/app_module_factory')
|
||||
static NgModuleFactory = new CompileIdentifierMetadata({
|
||||
name: 'NgModuleFactory',
|
||||
runtime: NgModuleFactory,
|
||||
moduleUrl: assetUrl('core', 'linker/ng_module_factory')
|
||||
});
|
||||
static AppModuleInjector = new CompileIdentifierMetadata({
|
||||
name: 'AppModuleInjector',
|
||||
runtime: AppModuleInjector,
|
||||
moduleUrl: assetUrl('core', 'linker/app_module_factory')
|
||||
static NgModuleInjector = new CompileIdentifierMetadata({
|
||||
name: 'NgModuleInjector',
|
||||
runtime: NgModuleInjector,
|
||||
moduleUrl: assetUrl('core', 'linker/ng_module_factory')
|
||||
});
|
||||
static ValueUnwrapper = new CompileIdentifierMetadata(
|
||||
{name: 'ValueUnwrapper', moduleUrl: CD_MODULE_URL, runtime: impValueUnwrapper});
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
* 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 {StringMapWrapper} from '../src/facade/collection';
|
||||
import {Console, LIFECYCLE_HOOKS_VALUES, ReflectorReader, createProvider, isProviderLiteral, reflector} from '../core_private';
|
||||
import {MapWrapper, StringMapWrapper} from '../src/facade/collection';
|
||||
import {BaseException} from '../src/facade/exceptions';
|
||||
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 {DirectiveResolver} from './directive_resolver';
|
||||
import {Identifiers, identifierToken} from './identifiers';
|
||||
import {NgModuleResolver} from './ng_module_resolver';
|
||||
import {PipeResolver} from './pipe_resolver';
|
||||
import {getUrlScheme} from './url_resolver';
|
||||
import {MODULE_SUFFIX, ValueTransformer, sanitizeIdentifier, visitValue} from './util';
|
||||
|
@ -28,13 +29,15 @@ import {ViewResolver} from './view_resolver';
|
|||
export class CompileMetadataResolver {
|
||||
private _directiveCache = new Map<Type, cpl.CompileDirectiveMetadata>();
|
||||
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 _anonymousTypeIndex = 0;
|
||||
|
||||
constructor(
|
||||
private _directiveResolver: DirectiveResolver, private _pipeResolver: PipeResolver,
|
||||
private _viewResolver: ViewResolver, private _config: CompilerConfig,
|
||||
private _ngModuleResolver: NgModuleResolver, private _directiveResolver: DirectiveResolver,
|
||||
private _pipeResolver: PipeResolver, private _viewResolver: ViewResolver,
|
||||
private _config: CompilerConfig, private _console: Console,
|
||||
private _reflector: ReflectorReader = reflector) {}
|
||||
|
||||
private sanitizeTokenName(token: any): string {
|
||||
|
@ -54,13 +57,16 @@ export class CompileMetadataResolver {
|
|||
clearCacheFor(type: Type) {
|
||||
this._directiveCache.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() {
|
||||
this._directiveCache.clear();
|
||||
this._pipeCache.clear();
|
||||
this._appModuleCache.clear();
|
||||
this._ngModuleCache.clear();
|
||||
this._ngModuleOfTypes.clear();
|
||||
}
|
||||
|
||||
getAnimationEntryMetadata(entry: AnimationEntryMetadata): cpl.CompileAnimationEntryMetadata {
|
||||
|
@ -105,11 +111,14 @@ export class CompileMetadataResolver {
|
|||
return null;
|
||||
}
|
||||
|
||||
getDirectiveMetadata(directiveType: Type): cpl.CompileDirectiveMetadata {
|
||||
getDirectiveMetadata(directiveType: Type, throwIfNotFound = true): cpl.CompileDirectiveMetadata {
|
||||
directiveType = resolveForwardRef(directiveType);
|
||||
var meta = this._directiveCache.get(directiveType);
|
||||
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 changeDetectionStrategy: ChangeDetectionStrategy = null;
|
||||
var viewProviders: Array<cpl.CompileProviderMetadata|cpl.CompileTypeMetadata|any[]> = [];
|
||||
|
@ -182,83 +191,254 @@ export class CompileMetadataResolver {
|
|||
return meta;
|
||||
}
|
||||
|
||||
getAppModuleMetadata(moduleType: any, meta: AppModuleMetadata = null):
|
||||
cpl.CompileAppModuleMetadata {
|
||||
// Only cache if we read the metadata via the reflector,
|
||||
// as we use the moduleType as cache key.
|
||||
let useCache = !meta;
|
||||
getNgModuleMetadata(moduleType: any, throwIfNotFound = true): cpl.CompileNgModuleMetadata {
|
||||
moduleType = resolveForwardRef(moduleType);
|
||||
var compileMeta = this._appModuleCache.get(moduleType);
|
||||
if (isBlank(compileMeta) || !useCache) {
|
||||
var compileMeta = this._ngModuleCache.get(moduleType);
|
||||
if (!compileMeta) {
|
||||
const meta = this._ngModuleResolver.resolve(moduleType, throwIfNotFound);
|
||||
if (!meta) {
|
||||
meta = this._reflector.annotations(moduleType)
|
||||
.find((meta) => meta instanceof AppModuleMetadata);
|
||||
return null;
|
||||
}
|
||||
if (!meta) {
|
||||
throw new BaseException(
|
||||
`Could not compile '${stringify(moduleType)}' because it is not an AppModule.`);
|
||||
}
|
||||
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);
|
||||
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(
|
||||
`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)}'`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
precompile.push(...flattenArray(meta.precompile)
|
||||
.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)),
|
||||
providers: providers,
|
||||
directives: directives,
|
||||
pipes: pipes,
|
||||
precompile: precompile,
|
||||
modules: modules
|
||||
declaredDirectives: declaredDirectives,
|
||||
exportedDirectives: exportedDirectives,
|
||||
declaredPipes: declaredPipes,
|
||||
exportedPipes: exportedPipes,
|
||||
importedModules: importedModules,
|
||||
exportedModules: exportedModules,
|
||||
transitiveModule: transitiveModule
|
||||
});
|
||||
if (useCache) {
|
||||
this._appModuleCache.set(moduleType, compileMeta);
|
||||
}
|
||||
transitiveModule.modules.push(compileMeta);
|
||||
this._verifyModule(compileMeta);
|
||||
this._ngModuleCache.set(moduleType, compileMeta);
|
||||
}
|
||||
return compileMeta;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param someType a symbol which may or may not be a directive type
|
||||
* @returns {cpl.CompileDirectiveMetadata} if possible, otherwise null.
|
||||
*/
|
||||
maybeGetDirectiveMetadata(someType: Type): cpl.CompileDirectiveMetadata {
|
||||
try {
|
||||
return this.getDirectiveMetadata(someType);
|
||||
} catch (e) {
|
||||
if (e.message.indexOf('No Directive annotation') !== -1) {
|
||||
return null;
|
||||
addComponentToModule(moduleType: Type, compType: Type) {
|
||||
const moduleMeta = this.getNgModuleMetadata(moduleType);
|
||||
// Collect @Component.directives/pipes/precompile into our declared directives/pipes.
|
||||
const compMeta = this.getDirectiveMetadata(compType, false);
|
||||
this._addDirectiveToModule(
|
||||
compMeta, moduleMeta.type.runtime, moduleMeta.transitiveModule,
|
||||
moduleMeta.declaredDirectives);
|
||||
this._getTransitiveViewDirectivesAndPipes(
|
||||
compMeta, moduleMeta.type.runtime, moduleMeta.transitiveModule,
|
||||
moduleMeta.declaredDirectives, moduleMeta.declaredPipes);
|
||||
|
||||
moduleMeta.transitiveModule.precompile.push(compMeta.type);
|
||||
moduleMeta.precompile.push(compMeta.type);
|
||||
|
||||
this._verifyModule(moduleMeta);
|
||||
}
|
||||
|
||||
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!`);
|
||||
}
|
||||
throw e;
|
||||
});
|
||||
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):
|
||||
|
@ -283,11 +463,14 @@ export class CompileMetadataResolver {
|
|||
});
|
||||
}
|
||||
|
||||
getPipeMetadata(pipeType: Type): cpl.CompilePipeMetadata {
|
||||
getPipeMetadata(pipeType: Type, throwIfNotFound = true): cpl.CompilePipeMetadata {
|
||||
pipeType = resolveForwardRef(pipeType);
|
||||
var meta = this._pipeCache.get(pipeType);
|
||||
if (isBlank(meta)) {
|
||||
var pipeMeta = this._pipeResolver.resolve(pipeType);
|
||||
var pipeMeta = this._pipeResolver.resolve(pipeType, throwIfNotFound);
|
||||
if (!pipeMeta) {
|
||||
return null;
|
||||
}
|
||||
meta = new cpl.CompilePipeMetadata({
|
||||
type: this.getTypeMetadata(pipeType, staticTypeModuleUrl(pipeType)),
|
||||
name: pipeMeta.name,
|
||||
|
@ -299,30 +482,6 @@ export class CompileMetadataResolver {
|
|||
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[]):
|
||||
cpl.CompileDiDependencyMetadata[] {
|
||||
let hasUnknownDeps = false;
|
||||
|
@ -454,7 +613,7 @@ export class CompileMetadataResolver {
|
|||
}
|
||||
convertToCompileValue(provider.useValue, collectedIdentifiers);
|
||||
collectedIdentifiers.forEach((identifier) => {
|
||||
let dirMeta = this.maybeGetDirectiveMetadata(identifier.runtime);
|
||||
let dirMeta = this.getDirectiveMetadata(identifier.runtime, false);
|
||||
if (dirMeta) {
|
||||
components.push(dirMeta.type);
|
||||
}
|
||||
|
@ -523,35 +682,35 @@ export class CompileMetadataResolver {
|
|||
}
|
||||
}
|
||||
|
||||
function flattenDirectives(view: ViewMetadata, platformDirectives: any[]): Type[] {
|
||||
let directives: Type[] = [];
|
||||
if (isPresent(platformDirectives)) {
|
||||
flattenArray(platformDirectives, directives);
|
||||
}
|
||||
if (isPresent(view.directives)) {
|
||||
flattenArray(view.directives, directives);
|
||||
}
|
||||
return directives;
|
||||
function getTransitiveModules(
|
||||
modules: cpl.CompileNgModuleMetadata[], includeImports: boolean,
|
||||
targetModules: cpl.CompileNgModuleMetadata[] = [],
|
||||
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);
|
||||
}
|
||||
});
|
||||
return targetModules;
|
||||
}
|
||||
|
||||
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> {
|
||||
for (var i = 0; i < tree.length; i++) {
|
||||
var item = resolveForwardRef(tree[i]);
|
||||
if (isArray(item)) {
|
||||
flattenArray(item, out);
|
||||
} else {
|
||||
out.push(item);
|
||||
function flattenArray(tree: any[], out: Array<any> = []): Array<any> {
|
||||
if (tree) {
|
||||
for (var i = 0; i < tree.length; i++) {
|
||||
var item = resolveForwardRef(tree[i]);
|
||||
if (isArray(item)) {
|
||||
flattenArray(item, out);
|
||||
} else {
|
||||
out.push(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
|
|
|
@ -8,13 +8,13 @@
|
|||
|
||||
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 {Identifiers, identifierToken} from './identifiers';
|
||||
import * as o from './output/output_ast';
|
||||
import {convertValueToOutputAst} from './output/value_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 {createDiTokenExpression} from './util';
|
||||
|
||||
|
@ -23,57 +23,58 @@ export class ComponentFactoryDependency {
|
|||
public comp: CompileIdentifierMetadata, public placeholder: CompileIdentifierMetadata) {}
|
||||
}
|
||||
|
||||
export class AppModuleCompileResult {
|
||||
export class NgModuleCompileResult {
|
||||
constructor(
|
||||
public statements: o.Statement[], public appModuleFactoryVar: string,
|
||||
public statements: o.Statement[], public ngModuleFactoryVar: string,
|
||||
public dependencies: ComponentFactoryDependency[]) {}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class AppModuleCompiler {
|
||||
compile(appModuleMeta: CompileAppModuleMetadata): AppModuleCompileResult {
|
||||
var sourceFileName = isPresent(appModuleMeta.type.moduleUrl) ?
|
||||
`in AppModule ${appModuleMeta.type.name} in ${appModuleMeta.type.moduleUrl}` :
|
||||
`in AppModule ${appModuleMeta.type.name}`;
|
||||
export class NgModuleCompiler {
|
||||
compile(ngModuleMeta: CompileNgModuleMetadata, extraProviders: CompileProviderMetadata[]):
|
||||
NgModuleCompileResult {
|
||||
var sourceFileName = isPresent(ngModuleMeta.type.moduleUrl) ?
|
||||
`in NgModule ${ngModuleMeta.type.name} in ${ngModuleMeta.type.moduleUrl}` :
|
||||
`in NgModule ${ngModuleMeta.type.name}`;
|
||||
var sourceFile = new ParseSourceFile('', sourceFileName);
|
||||
var sourceSpan = new ParseSourceSpan(
|
||||
new ParseLocation(sourceFile, null, null, null),
|
||||
new ParseLocation(sourceFile, null, null, null));
|
||||
var deps: ComponentFactoryDependency[] = [];
|
||||
var precompileComponents = appModuleMeta.precompile.map((precompileComp) => {
|
||||
var precompileComponents = ngModuleMeta.transitiveModule.precompile.map((precompileComp) => {
|
||||
var id = new CompileIdentifierMetadata({name: precompileComp.name});
|
||||
deps.push(new ComponentFactoryDependency(precompileComp, 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));
|
||||
var injectorClass = builder.build();
|
||||
var appModuleFactoryVar = `${appModuleMeta.type.name}NgFactory`;
|
||||
var appModuleFactoryStmt =
|
||||
o.variable(appModuleFactoryVar)
|
||||
.set(o.importExpr(Identifiers.AppModuleFactory)
|
||||
var ngModuleFactoryVar = `${ngModuleMeta.type.name}NgFactory`;
|
||||
var ngModuleFactoryStmt =
|
||||
o.variable(ngModuleFactoryVar)
|
||||
.set(o.importExpr(Identifiers.NgModuleFactory)
|
||||
.instantiate(
|
||||
[o.variable(injectorClass.name), o.importExpr(appModuleMeta.type)],
|
||||
[o.variable(injectorClass.name), o.importExpr(ngModuleMeta.type)],
|
||||
o.importType(
|
||||
Identifiers.AppModuleFactory, [o.importType(appModuleMeta.type)],
|
||||
Identifiers.NgModuleFactory, [o.importType(ngModuleMeta.type)],
|
||||
[o.TypeModifier.Const])))
|
||||
.toDeclStmt(null, [o.StmtModifier.Final]);
|
||||
|
||||
return new AppModuleCompileResult(
|
||||
[injectorClass, appModuleFactoryStmt], appModuleFactoryVar, deps);
|
||||
return new NgModuleCompileResult(
|
||||
[injectorClass, ngModuleFactoryStmt], ngModuleFactoryVar, deps);
|
||||
}
|
||||
}
|
||||
|
||||
class _InjectorBuilder {
|
||||
private _instances = new CompileTokenMap<o.Expression>();
|
||||
private _instances = new CompileIdentifierMap<CompileTokenMetadata, o.Expression>();
|
||||
private _fields: o.ClassField[] = [];
|
||||
private _createStmts: o.Statement[] = [];
|
||||
private _getters: o.ClassGetter[] = [];
|
||||
|
||||
constructor(
|
||||
private _appModuleMeta: CompileAppModuleMetadata,
|
||||
private _ngModuleMeta: CompileNgModuleMetadata,
|
||||
private _precompileComponents: CompileIdentifierMetadata[],
|
||||
private _sourceSpan: ParseSourceSpan) {}
|
||||
|
||||
|
@ -97,8 +98,8 @@ class _InjectorBuilder {
|
|||
var methods = [
|
||||
new o.ClassMethod(
|
||||
'createInternal', [], this._createStmts.concat(
|
||||
new o.ReturnStatement(this._instances.get(identifierToken(this._appModuleMeta.type)))
|
||||
), o.importType(this._appModuleMeta.type)
|
||||
new o.ReturnStatement(this._instances.get(identifierToken(this._ngModuleMeta.type)))
|
||||
), o.importType(this._ngModuleMeta.type)
|
||||
),
|
||||
new o.ClassMethod(
|
||||
'getInternal',
|
||||
|
@ -120,10 +121,10 @@ class _InjectorBuilder {
|
|||
])
|
||||
.toStmt()]);
|
||||
|
||||
var injClassName = `${this._appModuleMeta.type.name}Injector`;
|
||||
var injClassName = `${this._ngModuleMeta.type.name}Injector`;
|
||||
return new o.ClassStmt(
|
||||
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);
|
||||
}
|
||||
|
|
@ -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
|
||||
*/
|
||||
|
||||
import {AppModuleCompiler} from './app_module_compiler';
|
||||
import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompilePipeMetadata, StaticSymbol, createHostComponentMeta} from './compile_metadata';
|
||||
import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompileNgModuleMetadata, CompilePipeMetadata, StaticSymbol, createHostComponentMeta} from './compile_metadata';
|
||||
import {DirectiveNormalizer} from './directive_normalizer';
|
||||
import {ListWrapper} from './facade/collection';
|
||||
import {BaseException} from './facade/exceptions';
|
||||
import {Identifiers} from './identifiers';
|
||||
import {CompileMetadataResolver} from './metadata_resolver';
|
||||
import {NgModuleCompiler} from './ng_module_compiler';
|
||||
import {OutputEmitter} from './output/abstract_emitter';
|
||||
import * as o from './output/output_ast';
|
||||
import {CompiledStylesheet, StyleCompiler} from './style_compiler';
|
||||
|
@ -23,61 +23,29 @@ export class SourceModule {
|
|||
constructor(public moduleUrl: string, public source: string) {}
|
||||
}
|
||||
|
||||
export class AppModulesSummary {
|
||||
private _compAppModule = new Map<string, StaticSymbol>();
|
||||
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 NgModulesSummary {
|
||||
constructor(public ngModuleByComponent: Map<StaticSymbol, CompileNgModuleMetadata>) {}
|
||||
}
|
||||
|
||||
export class OfflineCompiler {
|
||||
constructor(
|
||||
private _metadataResolver: CompileMetadataResolver,
|
||||
private _directiveNormalizer: DirectiveNormalizer, private _templateParser: TemplateParser,
|
||||
private _styleCompiler: StyleCompiler, private _viewCompiler: ViewCompiler,
|
||||
private _appModuleCompiler: AppModuleCompiler, private _outputEmitter: OutputEmitter) {}
|
||||
private _ngModuleCompiler: NgModuleCompiler, private _outputEmitter: OutputEmitter) {}
|
||||
|
||||
analyzeModules(appModules: StaticSymbol[]): AppModulesSummary {
|
||||
let result = new AppModulesSummary();
|
||||
appModules.forEach((appModule) => {
|
||||
let appModuleMeta = this._metadataResolver.getAppModuleMetadata(appModule);
|
||||
appModuleMeta.precompile.forEach(
|
||||
(precompileComp) =>
|
||||
this._getTransitiveComponents(appModule, <any>precompileComp.runtime, result));
|
||||
});
|
||||
return result;
|
||||
}
|
||||
analyzeModules(ngModules: StaticSymbol[]): NgModulesSummary {
|
||||
const ngModuleByComponent = new Map<StaticSymbol, CompileNgModuleMetadata>();
|
||||
|
||||
private _getTransitiveComponents(
|
||||
appModule: StaticSymbol, component: StaticSymbol,
|
||||
target: AppModulesSummary = new AppModulesSummary()): AppModulesSummary {
|
||||
var compMeta = this._metadataResolver.getDirectiveMetadata(<any>component);
|
||||
// TODO(tbosch): preserve all modules per component, not just one.
|
||||
// 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);
|
||||
ngModules.forEach((ngModule) => {
|
||||
const ngModuleMeta = this._metadataResolver.getNgModuleMetadata(<any>ngModule);
|
||||
ngModuleMeta.declaredDirectives.forEach((dirMeta) => {
|
||||
if (dirMeta.isComponent) {
|
||||
ngModuleByComponent.set(dirMeta.type.runtime, ngModuleMeta);
|
||||
}
|
||||
});
|
||||
});
|
||||
compMeta.precompile.forEach((precompileComp) => {
|
||||
this._getTransitiveComponents(appModule, <any>precompileComp.type.runtime);
|
||||
});
|
||||
return target;
|
||||
return new NgModulesSummary(ngModuleByComponent);
|
||||
}
|
||||
|
||||
clearCache() {
|
||||
|
@ -86,55 +54,45 @@ export class OfflineCompiler {
|
|||
}
|
||||
|
||||
compile(
|
||||
moduleUrl: string, appModulesSummary: AppModulesSummary, components: StaticSymbol[],
|
||||
appModules: StaticSymbol[]): Promise<SourceModule[]> {
|
||||
moduleUrl: string, ngModulesSummary: NgModulesSummary, components: StaticSymbol[],
|
||||
ngModules: StaticSymbol[]): Promise<SourceModule[]> {
|
||||
let fileSuffix = _splitLastSuffix(moduleUrl)[1];
|
||||
let statements: o.Statement[] = [];
|
||||
let exportedVars: string[] = [];
|
||||
let outputSourceModules: SourceModule[] = [];
|
||||
|
||||
// compile app modules
|
||||
// compile all ng modules
|
||||
exportedVars.push(
|
||||
...appModules.map((appModule) => this._compileAppModule(appModule, statements)));
|
||||
...ngModules.map((ngModuleType) => this._compileModule(ngModuleType, statements)));
|
||||
|
||||
// compile components
|
||||
return Promise
|
||||
.all(components.map((compType) => {
|
||||
let appModule = appModulesSummary.getModule(compType);
|
||||
let appModuleDirectives: CompileDirectiveMetadata[] = [];
|
||||
let appModulePipes: CompilePipeMetadata[] = [];
|
||||
if (appModule) {
|
||||
let appModuleMeta = this._metadataResolver.getAppModuleMetadata(appModule);
|
||||
appModuleDirectives.push(...appModuleMeta.directives.map(
|
||||
type => this._metadataResolver.getDirectiveMetadata(type.runtime)));
|
||||
appModulePipes.push(...appModuleMeta.pipes.map(
|
||||
type => this._metadataResolver.getPipeMetadata(type.runtime)));
|
||||
const compMeta = this._metadataResolver.getDirectiveMetadata(<any>compType);
|
||||
let ngModule = ngModulesSummary.ngModuleByComponent.get(compType);
|
||||
if (!ngModule) {
|
||||
throw new BaseException(
|
||||
`Cannot determine the module for component ${compMeta.type.name}!`);
|
||||
}
|
||||
return Promise
|
||||
.all([
|
||||
this._metadataResolver.getDirectiveMetadata(<any>compType), ...appModuleDirectives,
|
||||
...this._metadataResolver.getViewDirectivesMetadata(<any>compType)
|
||||
].map(dirMeta => this._directiveNormalizer.normalizeDirective(dirMeta).asyncResult))
|
||||
.all([compMeta, ...ngModule.transitiveModule.directives].map(
|
||||
dirMeta => this._directiveNormalizer.normalizeDirective(dirMeta).asyncResult))
|
||||
.then((normalizedCompWithDirectives) => {
|
||||
let compMeta = normalizedCompWithDirectives[0];
|
||||
let dirMetas = normalizedCompWithDirectives.slice(1);
|
||||
const compMeta = normalizedCompWithDirectives[0];
|
||||
const dirMetas = normalizedCompWithDirectives.slice(1);
|
||||
_assertComponent(compMeta);
|
||||
|
||||
// compile styles
|
||||
let stylesCompileResults = this._styleCompiler.compileComponent(compMeta);
|
||||
const stylesCompileResults = this._styleCompiler.compileComponent(compMeta);
|
||||
stylesCompileResults.externalStylesheets.forEach((compiledStyleSheet) => {
|
||||
outputSourceModules.push(this._codgenStyles(compiledStyleSheet, fileSuffix));
|
||||
});
|
||||
|
||||
// compile components
|
||||
exportedVars.push(this._compileComponentFactory(compMeta, fileSuffix, statements));
|
||||
let pipeMetas = [
|
||||
...appModulePipes,
|
||||
...this._metadataResolver.getViewPipesMetadata(compMeta.type.runtime)
|
||||
];
|
||||
exportedVars.push(this._compileComponent(
|
||||
compMeta, dirMetas, pipeMetas, stylesCompileResults.componentStylesheet,
|
||||
fileSuffix, statements));
|
||||
compMeta, dirMetas, ngModule.transitiveModule.pipes,
|
||||
stylesCompileResults.componentStylesheet, fileSuffix, statements));
|
||||
});
|
||||
}))
|
||||
.then(() => {
|
||||
|
@ -146,21 +104,21 @@ export class OfflineCompiler {
|
|||
});
|
||||
}
|
||||
|
||||
private _compileAppModule(appModuleType: StaticSymbol, targetStatements: o.Statement[]): string {
|
||||
let appModuleMeta = this._metadataResolver.getAppModuleMetadata(appModuleType);
|
||||
let appCompileResult = this._appModuleCompiler.compile(appModuleMeta);
|
||||
private _compileModule(ngModuleType: StaticSymbol, targetStatements: o.Statement[]): string {
|
||||
const ngModule = this._metadataResolver.getNgModuleMetadata(<any>ngModuleType);
|
||||
let appCompileResult = this._ngModuleCompiler.compile(ngModule, []);
|
||||
appCompileResult.dependencies.forEach((dep) => {
|
||||
dep.placeholder.name = _componentFactoryName(dep.comp);
|
||||
dep.placeholder.moduleUrl = _ngfactoryModuleUrl(dep.comp.moduleUrl);
|
||||
});
|
||||
targetStatements.push(...appCompileResult.statements);
|
||||
return appCompileResult.appModuleFactoryVar;
|
||||
return appCompileResult.ngModuleFactoryVar;
|
||||
}
|
||||
|
||||
private _compileComponentFactory(
|
||||
compMeta: CompileDirectiveMetadata, fileSuffix: string,
|
||||
targetStatements: o.Statement[]): string {
|
||||
var hostMeta = createHostComponentMeta(compMeta.type, compMeta.selector);
|
||||
var hostMeta = createHostComponentMeta(compMeta);
|
||||
var hostViewFactoryVar =
|
||||
this._compileComponent(hostMeta, [compMeta], [], null, fileSuffix, targetStatements);
|
||||
var compFactoryVar = _componentFactoryName(compMeta.type);
|
||||
|
|
|
@ -30,7 +30,7 @@ export class PipeResolver {
|
|||
/**
|
||||
* Return {@link PipeMetadata} for a given `Type`.
|
||||
*/
|
||||
resolve(type: Type): PipeMetadata {
|
||||
resolve(type: Type, throwIfNotFound = true): PipeMetadata {
|
||||
var metas = this._reflector.annotations(resolveForwardRef(type));
|
||||
if (isPresent(metas)) {
|
||||
var annotation = metas.find(_isPipeMetadata);
|
||||
|
@ -38,6 +38,9 @@ export class PipeResolver {
|
|||
return annotation;
|
||||
}
|
||||
}
|
||||
throw new BaseException(`No Pipe decorator found on ${stringify(type)}`);
|
||||
if (throwIfNotFound) {
|
||||
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 {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 {ParseError, ParseSourceSpan} from './parse_util';
|
||||
import {AttrAst, DirectiveAst, ProviderAst, ProviderAstType, ReferenceAst, VariableAst} from './template_ast';
|
||||
|
@ -23,16 +23,16 @@ export class ProviderViewContext {
|
|||
/**
|
||||
* @internal
|
||||
*/
|
||||
viewQueries: CompileTokenMap<CompileQueryMetadata[]>;
|
||||
viewQueries: CompileIdentifierMap<CompileTokenMetadata, CompileQueryMetadata[]>;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
viewProviders: CompileTokenMap<boolean>;
|
||||
viewProviders: CompileIdentifierMap<CompileTokenMetadata, boolean>;
|
||||
errors: ProviderError[] = [];
|
||||
|
||||
constructor(public component: CompileDirectiveMetadata, public sourceSpan: ParseSourceSpan) {
|
||||
this.viewQueries = _getViewQueries(component);
|
||||
this.viewProviders = new CompileTokenMap<boolean>();
|
||||
this.viewProviders = new CompileIdentifierMap<CompileTokenMetadata, boolean>();
|
||||
_normalizeProviders(component.viewProviders, sourceSpan, this.errors).forEach((provider) => {
|
||||
if (isBlank(this.viewProviders.get(provider.token))) {
|
||||
this.viewProviders.add(provider.token, true);
|
||||
|
@ -42,11 +42,11 @@ export class ProviderViewContext {
|
|||
}
|
||||
|
||||
export class ProviderElementContext {
|
||||
private _contentQueries: CompileTokenMap<CompileQueryMetadata[]>;
|
||||
private _contentQueries: CompileIdentifierMap<CompileTokenMetadata, CompileQueryMetadata[]>;
|
||||
|
||||
private _transformedProviders = new CompileTokenMap<ProviderAst>();
|
||||
private _seenProviders = new CompileTokenMap<boolean>();
|
||||
private _allProviders: CompileTokenMap<ProviderAst>;
|
||||
private _transformedProviders = new CompileIdentifierMap<CompileTokenMetadata, ProviderAst>();
|
||||
private _seenProviders = new CompileIdentifierMap<CompileTokenMetadata, boolean>();
|
||||
private _allProviders: CompileIdentifierMap<CompileTokenMetadata, ProviderAst>;
|
||||
private _attrs: {[key: string]: string};
|
||||
private _hasViewContainer: boolean = false;
|
||||
|
||||
|
@ -60,7 +60,7 @@ export class ProviderElementContext {
|
|||
this._allProviders =
|
||||
_resolveProvidersFromDirectives(directivesMeta, _sourceSpan, _viewContext.errors);
|
||||
this._contentQueries = _getContentQueries(directivesMeta);
|
||||
var queriedTokens = new CompileTokenMap<boolean>();
|
||||
var queriedTokens = new CompileIdentifierMap<CompileTokenMetadata, boolean>();
|
||||
this._allProviders.values().forEach(
|
||||
(provider) => { this._addQueryReadsTo(provider.token, queriedTokens); });
|
||||
refs.forEach((refAst) => {
|
||||
|
@ -100,7 +100,9 @@ export class ProviderElementContext {
|
|||
|
||||
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) => {
|
||||
const queryReadToken = isPresent(query.read) ? query.read : token;
|
||||
if (isBlank(queryReadTokens.get(queryReadToken))) {
|
||||
|
@ -272,24 +274,28 @@ export class ProviderElementContext {
|
|||
}
|
||||
|
||||
|
||||
export class AppModuleProviderParser {
|
||||
private _transformedProviders = new CompileTokenMap<ProviderAst>();
|
||||
private _seenProviders = new CompileTokenMap<boolean>();
|
||||
export class NgModuleProviderAnalyzer {
|
||||
private _transformedProviders = new CompileIdentifierMap<CompileTokenMetadata, ProviderAst>();
|
||||
private _seenProviders = new CompileIdentifierMap<CompileTokenMetadata, boolean>();
|
||||
private _unparsedProviders: any[] = [];
|
||||
private _allProviders: CompileTokenMap<ProviderAst>;
|
||||
private _allProviders: CompileIdentifierMap<CompileTokenMetadata, ProviderAst>;
|
||||
private _errors: ProviderError[] = [];
|
||||
|
||||
constructor(appModule: CompileAppModuleMetadata, sourceSpan: ParseSourceSpan) {
|
||||
this._allProviders = new CompileTokenMap<ProviderAst>();
|
||||
[appModule.type].concat(appModule.modules).forEach((appModuleType: CompileTypeMetadata) => {
|
||||
const appModuleProvider = new CompileProviderMetadata(
|
||||
{token: new CompileTokenMetadata({identifier: appModuleType}), useClass: appModuleType});
|
||||
constructor(
|
||||
ngModule: CompileNgModuleMetadata, extraProviders: CompileProviderMetadata[],
|
||||
sourceSpan: ParseSourceSpan) {
|
||||
this._allProviders = new CompileIdentifierMap<CompileTokenMetadata, ProviderAst>();
|
||||
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(
|
||||
[appModuleProvider], ProviderAstType.PublicService, true, sourceSpan, this._errors,
|
||||
[ngModuleProvider], ProviderAstType.PublicService, true, sourceSpan, this._errors,
|
||||
this._allProviders);
|
||||
});
|
||||
_resolveProviders(
|
||||
_normalizeProviders(appModule.providers, sourceSpan, this._errors),
|
||||
_normalizeProviders(
|
||||
ngModule.transitiveModule.providers.concat(extraProviders), sourceSpan, this._errors),
|
||||
ProviderAstType.PublicService, false, sourceSpan, this._errors, this._allProviders);
|
||||
}
|
||||
|
||||
|
@ -436,8 +442,8 @@ function _normalizeProviders(
|
|||
|
||||
function _resolveProvidersFromDirectives(
|
||||
directives: CompileDirectiveMetadata[], sourceSpan: ParseSourceSpan,
|
||||
targetErrors: ParseError[]): CompileTokenMap<ProviderAst> {
|
||||
var providersByToken = new CompileTokenMap<ProviderAst>();
|
||||
targetErrors: ParseError[]): CompileIdentifierMap<CompileTokenMetadata, ProviderAst> {
|
||||
var providersByToken = new CompileIdentifierMap<CompileTokenMetadata, ProviderAst>();
|
||||
directives.forEach((directive) => {
|
||||
var dirProvider = new CompileProviderMetadata(
|
||||
{token: new CompileTokenMetadata({identifier: directive.type}), useClass: directive.type});
|
||||
|
@ -464,7 +470,7 @@ function _resolveProvidersFromDirectives(
|
|||
function _resolveProviders(
|
||||
providers: CompileProviderMetadata[], providerType: ProviderAstType, eager: boolean,
|
||||
sourceSpan: ParseSourceSpan, targetErrors: ParseError[],
|
||||
targetProvidersByToken: CompileTokenMap<ProviderAst>) {
|
||||
targetProvidersByToken: CompileIdentifierMap<CompileTokenMetadata, ProviderAst>) {
|
||||
providers.forEach((provider) => {
|
||||
var resolvedProvider = targetProvidersByToken.get(provider.token);
|
||||
if (isPresent(resolvedProvider) && resolvedProvider.multiProvider !== provider.multi) {
|
||||
|
@ -487,8 +493,8 @@ function _resolveProviders(
|
|||
|
||||
|
||||
function _getViewQueries(component: CompileDirectiveMetadata):
|
||||
CompileTokenMap<CompileQueryMetadata[]> {
|
||||
var viewQueries = new CompileTokenMap<CompileQueryMetadata[]>();
|
||||
CompileIdentifierMap<CompileTokenMetadata, CompileQueryMetadata[]> {
|
||||
var viewQueries = new CompileIdentifierMap<CompileTokenMetadata, CompileQueryMetadata[]>();
|
||||
if (isPresent(component.viewQueries)) {
|
||||
component.viewQueries.forEach((query) => _addQueryToTokenMap(viewQueries, query));
|
||||
}
|
||||
|
@ -501,8 +507,8 @@ function _getViewQueries(component: CompileDirectiveMetadata):
|
|||
}
|
||||
|
||||
function _getContentQueries(directives: CompileDirectiveMetadata[]):
|
||||
CompileTokenMap<CompileQueryMetadata[]> {
|
||||
var contentQueries = new CompileTokenMap<CompileQueryMetadata[]>();
|
||||
CompileIdentifierMap<CompileTokenMetadata, CompileQueryMetadata[]> {
|
||||
var contentQueries = new CompileIdentifierMap<CompileTokenMetadata, CompileQueryMetadata[]>();
|
||||
directives.forEach(directive => {
|
||||
if (isPresent(directive.queries)) {
|
||||
directive.queries.forEach((query) => _addQueryToTokenMap(contentQueries, query));
|
||||
|
@ -517,7 +523,8 @@ function _getContentQueries(directives: CompileDirectiveMetadata[]):
|
|||
}
|
||||
|
||||
function _addQueryToTokenMap(
|
||||
map: CompileTokenMap<CompileQueryMetadata[]>, query: CompileQueryMetadata) {
|
||||
map: CompileIdentifierMap<CompileTokenMetadata, CompileQueryMetadata[]>,
|
||||
query: CompileQueryMetadata) {
|
||||
query.selectors.forEach((token: CompileTokenMetadata) => {
|
||||
var entry = map.get(token);
|
||||
if (isBlank(entry)) {
|
|
@ -6,19 +6,19 @@
|
|||
* 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 {Console} from '../core_private';
|
||||
import {Compiler, ComponentFactory, ComponentResolver, ComponentStillLoadingError, Injectable, Injector, NgModule, NgModuleFactory, NgModuleMetadata, OptionalMetadata, Provider, SkipSelfMetadata} from '@angular/core';
|
||||
|
||||
import {Console} from '../core_private';
|
||||
import {BaseException} from '../src/facade/exceptions';
|
||||
import {ConcreteType, IS_DART, Type, isBlank, isString, stringify} from '../src/facade/lang';
|
||||
|
||||
import {ListWrapper,} from '../src/facade/collection';
|
||||
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 {StyleCompiler, StylesCompileDependency, CompiledStylesheet} from './style_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 {DirectiveNormalizer} from './directive_normalizer';
|
||||
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).
|
||||
*/
|
||||
@Injectable()
|
||||
export class RuntimeCompiler implements ComponentResolver, Compiler {
|
||||
export class RuntimeCompiler implements Compiler {
|
||||
private _compiledTemplateCache = new Map<Type, CompiledTemplate>();
|
||||
private _compiledHostTemplateCache = new Map<Type, CompiledTemplate>();
|
||||
private _compiledAppModuleCache = new Map<Type, AppModuleFactory<any>>();
|
||||
|
||||
private _warnOnComponentResolver = true;
|
||||
private _compiledNgModuleCache = new Map<Type, NgModuleFactory<any>>();
|
||||
|
||||
constructor(
|
||||
private _injector: Injector, private _metadataResolver: CompileMetadataResolver,
|
||||
private _templateNormalizer: DirectiveNormalizer, private _templateParser: TemplateParser,
|
||||
private _styleCompiler: StyleCompiler, private _viewCompiler: ViewCompiler,
|
||||
private _appModuleCompiler: AppModuleCompiler, private _genConfig: CompilerConfig,
|
||||
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));
|
||||
}
|
||||
}
|
||||
private _ngModuleCompiler: NgModuleCompiler, private _compilerConfig: CompilerConfig,
|
||||
private _console: Console) {}
|
||||
|
||||
get injector(): Injector { return this._injector; }
|
||||
|
||||
resolveComponent(component: Type|string): Promise<ComponentFactory<any>> {
|
||||
if (isString(component)) {
|
||||
return PromiseWrapper.reject(
|
||||
new BaseException(`Cannot resolve component using '${component}'.`), null);
|
||||
compileModuleSync<T>(moduleType: ConcreteType<T>): NgModuleFactory<T> {
|
||||
return this._compileModuleAndComponents(moduleType, true).syncResult;
|
||||
}
|
||||
|
||||
compileModuleAsync<T>(moduleType: ConcreteType<T>): Promise<NgModuleFactory<T>> {
|
||||
return this._compileModuleAndComponents(moduleType, false).asyncResult;
|
||||
}
|
||||
|
||||
compileComponentAsync<T>(compType: ConcreteType<T>, ngModule: ConcreteType<any> = null):
|
||||
Promise<ComponentFactory<T>> {
|
||||
if (!ngModule) {
|
||||
throw new BaseException(
|
||||
`Calling compileComponentAsync on the root compiler without a module is not allowed! (Compiling component ${stringify(compType)})`);
|
||||
}
|
||||
if (this._warnOnComponentResolver) {
|
||||
this._console.warn(ComponentResolver.DynamicCompilationDeprecationMsg);
|
||||
this._warnOnComponentResolver = false;
|
||||
return this._compileComponentInModule(compType, false, ngModule).asyncResult;
|
||||
}
|
||||
|
||||
compileComponentSync<T>(compType: ConcreteType<T>, ngModule: ConcreteType<any> = null):
|
||||
ComponentFactory<T> {
|
||||
if (!ngModule) {
|
||||
throw new BaseException(
|
||||
`Calling compileComponentSync on the root compiler without a module is not allowed! (Compiling component ${stringify(compType)})`);
|
||||
}
|
||||
return this.compileComponentAsync(<ConcreteType<any>>component);
|
||||
return this._compileComponentInModule(compType, true, ngModule).syncResult;
|
||||
}
|
||||
|
||||
compileAppModuleSync<T>(moduleType: ConcreteType<T>, metadata: AppModuleMetadata = null):
|
||||
AppModuleFactory<T> {
|
||||
return this._compileAppModule(moduleType, true, metadata).syncResult;
|
||||
private _compileModuleAndComponents<T>(moduleType: ConcreteType<T>, isSync: boolean):
|
||||
SyncAsyncResult<NgModuleFactory<T>> {
|
||||
const componentPromise = this._compileComponents(moduleType, isSync);
|
||||
const ngModuleFactory = this._compileModule(moduleType);
|
||||
return new SyncAsyncResult(ngModuleFactory, componentPromise.then(() => ngModuleFactory));
|
||||
}
|
||||
|
||||
compileAppModuleAsync<T>(moduleType: ConcreteType<T>, metadata: AppModuleMetadata = null):
|
||||
Promise<AppModuleFactory<T>> {
|
||||
return this._compileAppModule(moduleType, false, metadata).asyncResult;
|
||||
}
|
||||
|
||||
private _compileAppModule<T>(
|
||||
moduleType: ConcreteType<T>, isSync: boolean,
|
||||
metadata: AppModuleMetadata = null): SyncAsyncResult<AppModuleFactory<T>> {
|
||||
// Only cache if we read the metadata via the reflector,
|
||||
// as we use the moduleType as cache key.
|
||||
let useCache = !metadata;
|
||||
let appModuleFactory = this._compiledAppModuleCache.get(moduleType);
|
||||
let componentCompilePromises: Promise<any>[] = [];
|
||||
if (!appModuleFactory || !useCache) {
|
||||
var compileModuleMeta = this._metadataResolver.getAppModuleMetadata(moduleType, metadata);
|
||||
let boundCompilerFactory = (parentResolver: ComponentResolver) => new BoundCompiler(
|
||||
this, compileModuleMeta.directives.map(dir => dir.type.runtime),
|
||||
compileModuleMeta.pipes.map((pipe) => pipe.type.runtime), parentResolver);
|
||||
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
|
||||
compileModuleMeta.providers.push(
|
||||
this._metadataResolver.getProviderMetadata(new Provider(Compiler, {
|
||||
useFactory: boundCompilerFactory,
|
||||
deps: [[new OptionalMetadata(), new SkipSelfMetadata(), ComponentResolver]]
|
||||
})));
|
||||
compileModuleMeta.providers.push(this._metadataResolver.getProviderMetadata(
|
||||
new Provider(ComponentResolver, {useExisting: Compiler})));
|
||||
var compileResult = this._appModuleCompiler.compile(compileModuleMeta);
|
||||
const extraProviders = [
|
||||
this._metadataResolver.getProviderMetadata(new Provider(Compiler, {
|
||||
useFactory: boundCompilerFactory,
|
||||
deps: [[new OptionalMetadata(), new SkipSelfMetadata(), ComponentResolver]]
|
||||
})),
|
||||
this._metadataResolver.getProviderMetadata(
|
||||
new Provider(ComponentResolver, {useExisting: Compiler}))
|
||||
];
|
||||
var compileResult = this._ngModuleCompiler.compile(moduleMeta, extraProviders);
|
||||
compileResult.dependencies.forEach((dep) => {
|
||||
let compileResult = this._compileComponent(
|
||||
dep.comp.runtime, isSync,
|
||||
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.runtime =
|
||||
this._assertComponentKnown(dep.comp.runtime, true).proxyComponentFactory;
|
||||
dep.placeholder.name = `compFactory_${dep.comp.name}`;
|
||||
});
|
||||
if (IS_DART || !this._genConfig.useJit) {
|
||||
appModuleFactory =
|
||||
interpretStatements(compileResult.statements, compileResult.appModuleFactoryVar);
|
||||
if (IS_DART || !this._compilerConfig.useJit) {
|
||||
ngModuleFactory =
|
||||
interpretStatements(compileResult.statements, compileResult.ngModuleFactoryVar);
|
||||
} else {
|
||||
appModuleFactory = jitStatements(
|
||||
`${compileModuleMeta.type.name}.ngfactory.js`, compileResult.statements,
|
||||
compileResult.appModuleFactoryVar);
|
||||
}
|
||||
if (useCache) {
|
||||
this._compiledAppModuleCache.set(moduleType, appModuleFactory);
|
||||
ngModuleFactory = jitStatements(
|
||||
`${moduleMeta.type.name}.ngfactory.js`, compileResult.statements,
|
||||
compileResult.ngModuleFactoryVar);
|
||||
}
|
||||
this._compiledNgModuleCache.set(moduleMeta.type.runtime, ngModuleFactory);
|
||||
}
|
||||
return new SyncAsyncResult(
|
||||
appModuleFactory, Promise.all(componentCompilePromises).then(() => appModuleFactory));
|
||||
return ngModuleFactory;
|
||||
}
|
||||
|
||||
compileComponentAsync<T>(compType: ConcreteType<T>): Promise<ComponentFactory<T>> {
|
||||
return this._compileComponent(compType, false, [], []).asyncResult;
|
||||
}
|
||||
private _compileComponentInModule<T>(
|
||||
compType: ConcreteType<T>, isSync: boolean,
|
||||
moduleType: ConcreteType<any>): SyncAsyncResult<ComponentFactory<T>> {
|
||||
this._metadataResolver.addComponentToModule(moduleType, compType);
|
||||
|
||||
compileComponentSync<T>(compType: ConcreteType<T>): ComponentFactory<T> {
|
||||
return this._compileComponent(compType, true, [], []).syncResult;
|
||||
const componentPromise = this._compileComponents(moduleType, isSync);
|
||||
const componentFactory: ComponentFactory<T> =
|
||||
this._assertComponentKnown(compType, true).proxyComponentFactory;
|
||||
|
||||
return new SyncAsyncResult(componentFactory, componentPromise.then(() => componentFactory));
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_compileComponent<T>(
|
||||
compType: ConcreteType<T>, isSync: boolean, moduleDirectives: ConcreteType<any>[],
|
||||
modulePipes: ConcreteType<any>[]): SyncAsyncResult<ComponentFactory<T>> {
|
||||
var templates =
|
||||
this._getTransitiveCompiledTemplates(compType, true, moduleDirectives, modulePipes);
|
||||
_compileComponents(mainModule: Type, isSync: boolean): Promise<any> {
|
||||
const templates = new Set<CompiledTemplate>();
|
||||
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) => {
|
||||
if (template.loading) {
|
||||
if (isSync) {
|
||||
|
@ -167,16 +168,14 @@ export class RuntimeCompiler implements ComponentResolver, Compiler {
|
|||
() => { templates.forEach((template) => { this._compileTemplate(template); }); };
|
||||
if (isSync) {
|
||||
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) {
|
||||
this._compiledAppModuleCache.delete(type);
|
||||
this._compiledNgModuleCache.delete(type);
|
||||
this._metadataResolver.clearCacheFor(type);
|
||||
this._compiledHostTemplateCache.delete(type);
|
||||
var compiledTemplate = this._compiledTemplateCache.get(type);
|
||||
|
@ -191,71 +190,54 @@ export class RuntimeCompiler implements ComponentResolver, Compiler {
|
|||
this._compiledTemplateCache.clear();
|
||||
this._compiledHostTemplateCache.clear();
|
||||
this._templateNormalizer.clearCache();
|
||||
this._compiledAppModuleCache.clear();
|
||||
this._compiledNgModuleCache.clear();
|
||||
}
|
||||
|
||||
private _createCompiledHostTemplate(type: Type): CompiledTemplate {
|
||||
var compiledTemplate = this._compiledHostTemplateCache.get(type);
|
||||
private _createCompiledHostTemplate(compType: Type): CompiledTemplate {
|
||||
var compiledTemplate = this._compiledHostTemplateCache.get(compType);
|
||||
if (isBlank(compiledTemplate)) {
|
||||
var compMeta = this._metadataResolver.getDirectiveMetadata(type);
|
||||
var compMeta = this._metadataResolver.getDirectiveMetadata(compType);
|
||||
assertComponent(compMeta);
|
||||
var hostMeta = createHostComponentMeta(compMeta.type, compMeta.selector);
|
||||
var hostMeta = createHostComponentMeta(compMeta);
|
||||
compiledTemplate = new CompiledTemplate(
|
||||
true, compMeta.selector, compMeta.type, [], [type], [], [],
|
||||
true, compMeta.selector, compMeta.type, [compMeta], [],
|
||||
this._templateNormalizer.normalizeDirective(hostMeta));
|
||||
this._compiledHostTemplateCache.set(type, compiledTemplate);
|
||||
this._compiledHostTemplateCache.set(compType, compiledTemplate);
|
||||
}
|
||||
return compiledTemplate;
|
||||
}
|
||||
|
||||
private _createCompiledTemplate(
|
||||
type: Type, moduleDirectives: ConcreteType<any>[],
|
||||
modulePipes: ConcreteType<any>[]): CompiledTemplate {
|
||||
var compiledTemplate = this._compiledTemplateCache.get(type);
|
||||
compMeta: CompileDirectiveMetadata, directives: CompileDirectiveMetadata[],
|
||||
pipes: CompilePipeMetadata[]): CompiledTemplate {
|
||||
var compiledTemplate = this._compiledTemplateCache.get(compMeta.type.runtime);
|
||||
if (isBlank(compiledTemplate)) {
|
||||
const compMeta = this._metadataResolver.getDirectiveMetadata(type);
|
||||
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(
|
||||
false, compMeta.selector, compMeta.type, viewDirectives, viewComponentTypes,
|
||||
precompileComponentTypes, pipes, this._templateNormalizer.normalizeDirective(compMeta));
|
||||
this._compiledTemplateCache.set(type, compiledTemplate);
|
||||
false, compMeta.selector, compMeta.type, directives, pipes,
|
||||
this._templateNormalizer.normalizeDirective(compMeta));
|
||||
this._compiledTemplateCache.set(compMeta.type.runtime, compiledTemplate);
|
||||
}
|
||||
return compiledTemplate;
|
||||
}
|
||||
|
||||
private _getTransitiveCompiledTemplates(
|
||||
compType: Type, isHost: boolean, moduleDirectives: ConcreteType<any>[],
|
||||
modulePipes: ConcreteType<any>[],
|
||||
target: Set<CompiledTemplate> = new Set<CompiledTemplate>()): Set<CompiledTemplate> {
|
||||
const template = isHost ? this._createCompiledHostTemplate(compType) :
|
||||
this._createCompiledTemplate(compType, moduleDirectives, modulePipes);
|
||||
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);
|
||||
});
|
||||
private _assertComponentKnown(compType: any, isHost: boolean): CompiledTemplate {
|
||||
const compiledTemplate = isHost ? this._compiledHostTemplateCache.get(compType) :
|
||||
this._compiledTemplateCache.get(compType);
|
||||
if (!compiledTemplate) {
|
||||
throw new BaseException(
|
||||
`Illegal state: CompiledTemplate for ${stringify(compType)} (isHost: ${isHost}) does not exist!`);
|
||||
}
|
||||
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) {
|
||||
|
@ -270,7 +252,7 @@ export class RuntimeCompiler implements ComponentResolver, Compiler {
|
|||
this._resolveStylesCompileResult(
|
||||
stylesCompileResult.componentStylesheet, externalStylesheetsByModuleUrl);
|
||||
const viewCompMetas = template.viewComponentTypes.map(
|
||||
(compType) => this._compiledTemplateCache.get(compType).normalizedCompMeta);
|
||||
(compType) => this._assertComponentLoaded(compType, false).normalizedCompMeta);
|
||||
const parsedTemplate = this._templateParser.parse(
|
||||
compMeta, compMeta.template.template, template.viewDirectives.concat(viewCompMetas),
|
||||
template.viewPipes, compMeta.type.name);
|
||||
|
@ -281,12 +263,12 @@ export class RuntimeCompiler implements ComponentResolver, Compiler {
|
|||
let depTemplate: CompiledTemplate;
|
||||
if (dep instanceof ViewFactoryDependency) {
|
||||
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.name = `viewFactory_${vfd.comp.name}`;
|
||||
} else if (dep instanceof ComponentFactoryDependency) {
|
||||
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.name = `compFactory_${cfd.comp.name}`;
|
||||
}
|
||||
|
@ -294,7 +276,7 @@ export class RuntimeCompiler implements ComponentResolver, Compiler {
|
|||
const statements =
|
||||
stylesCompileResult.componentStylesheet.statements.concat(compileResult.statements);
|
||||
let factory: any;
|
||||
if (IS_DART || !this._genConfig.useJit) {
|
||||
if (IS_DART || !this._compilerConfig.useJit) {
|
||||
factory = interpretStatements(statements, compileResult.viewFactoryVar);
|
||||
} else {
|
||||
factory = jitStatements(
|
||||
|
@ -318,7 +300,7 @@ export class RuntimeCompiler implements ComponentResolver, Compiler {
|
|||
result: CompiledStylesheet,
|
||||
externalStylesheetsByModuleUrl: Map<string, CompiledStylesheet>): string[] {
|
||||
this._resolveStylesCompileResult(result, externalStylesheetsByModuleUrl);
|
||||
if (IS_DART || !this._genConfig.useJit) {
|
||||
if (IS_DART || !this._compilerConfig.useJit) {
|
||||
return interpretStatements(result.statements, result.stylesVar);
|
||||
} else {
|
||||
return jitStatements(`${result.meta.moduleUrl}.css.js`, result.statements, result.stylesVar);
|
||||
|
@ -334,13 +316,28 @@ class CompiledTemplate {
|
|||
private _normalizedCompMeta: CompileDirectiveMetadata = null;
|
||||
isCompiled = false;
|
||||
isCompiledWithDeps = false;
|
||||
viewComponentTypes: Type[] = [];
|
||||
viewDirectives: CompileDirectiveMetadata[] = [];
|
||||
|
||||
constructor(
|
||||
public isHost: boolean, selector: string, public compType: CompileIdentifierMetadata,
|
||||
public viewDirectives: CompileDirectiveMetadata[], public viewComponentTypes: Type[],
|
||||
public precompileHostComponentTypes: Type[], public viewPipes: CompilePipeMetadata[],
|
||||
viewDirectivesAndComponents: CompileDirectiveMetadata[],
|
||||
public viewPipes: CompilePipeMetadata[],
|
||||
_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 ?
|
||||
new ComponentFactory<any>(selector, this.proxyViewFactory, compType.runtime) :
|
||||
null;
|
||||
|
@ -376,13 +373,15 @@ function assertComponent(meta: CompileDirectiveMetadata) {
|
|||
}
|
||||
|
||||
/**
|
||||
* A wrapper around `Compiler` and `ComponentResolver` that
|
||||
* provides default patform directives / pipes.
|
||||
* Implements `Compiler` and `ComponentResolver` by delegating
|
||||
* to the RuntimeCompiler using a known module.
|
||||
*/
|
||||
class BoundCompiler implements Compiler, ComponentResolver {
|
||||
class ModuleBoundCompiler implements Compiler, ComponentResolver {
|
||||
private _warnOnComponentResolver = true;
|
||||
|
||||
constructor(
|
||||
private _delegate: RuntimeCompiler, private _directives: any[], private _pipes: any[],
|
||||
private _parentComponentResolver: ComponentResolver) {}
|
||||
private _delegate: RuntimeCompiler, private _ngModule: ConcreteType<any>,
|
||||
private _parentComponentResolver: ComponentResolver, private _console: Console) {}
|
||||
|
||||
get injector(): Injector { return this._delegate.injector; }
|
||||
|
||||
|
@ -395,27 +394,29 @@ class BoundCompiler implements Compiler, ComponentResolver {
|
|||
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);
|
||||
}
|
||||
|
||||
compileComponentAsync<T>(compType: ConcreteType<T>): Promise<ComponentFactory<T>> {
|
||||
return this._delegate._compileComponent(compType, false, this._directives, this._pipes)
|
||||
.asyncResult;
|
||||
compileComponentAsync<T>(compType: ConcreteType<T>, ngModule: ConcreteType<any> = null):
|
||||
Promise<ComponentFactory<T>> {
|
||||
return this._delegate.compileComponentAsync(compType, ngModule ? ngModule : this._ngModule);
|
||||
}
|
||||
|
||||
compileComponentSync<T>(compType: ConcreteType<T>): ComponentFactory<T> {
|
||||
return this._delegate._compileComponent(compType, true, this._directives, this._pipes)
|
||||
.syncResult;
|
||||
compileComponentSync<T>(compType: ConcreteType<T>, ngModule: ConcreteType<any> = null):
|
||||
ComponentFactory<T> {
|
||||
return this._delegate.compileComponentSync(compType, ngModule ? ngModule : this._ngModule);
|
||||
}
|
||||
|
||||
compileAppModuleSync<T>(moduleType: ConcreteType<T>, metadata: AppModuleMetadata = null):
|
||||
AppModuleFactory<T> {
|
||||
return this._delegate.compileAppModuleSync(moduleType, metadata);
|
||||
compileModuleSync<T>(moduleType: ConcreteType<T>): NgModuleFactory<T> {
|
||||
return this._delegate.compileModuleSync(moduleType);
|
||||
}
|
||||
|
||||
compileAppModuleAsync<T>(moduleType: ConcreteType<T>, metadata: AppModuleMetadata = null):
|
||||
Promise<AppModuleFactory<T>> {
|
||||
return this._delegate.compileAppModuleAsync(moduleType, metadata);
|
||||
compileModuleAsync<T>(moduleType: ConcreteType<T>): Promise<NgModuleFactory<T>> {
|
||||
return this._delegate.compileModuleAsync(moduleType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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); }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ import {RegExpWrapper, isPresent, StringWrapper, isBlank} from '../src/facade/la
|
|||
import {BaseException} from '../src/facade/exceptions';
|
||||
import {AST, Interpolation, ASTWithSource, TemplateBinding, RecursiveAstVisitor, BindingPipe, ParserError} from './expression_parser/ast';
|
||||
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 {splitNsName, mergeNsAndName} from './html_tags';
|
||||
import {ParseSourceSpan, ParseError, ParseErrorLevel} from './parse_util';
|
||||
|
@ -27,7 +27,7 @@ import {HtmlAstVisitor, HtmlElementAst, HtmlAttrAst, HtmlTextAst, HtmlCommentAst
|
|||
import {splitAtColon} from './util';
|
||||
import {identifierToken, Identifiers} from './identifiers';
|
||||
import {expandNodes} from './expander';
|
||||
import {ProviderElementContext, ProviderViewContext} from './provider_parser';
|
||||
import {ProviderElementContext, ProviderViewContext} from './provider_analyzer';
|
||||
|
||||
// Group 1 = "bind-"
|
||||
// Group 2 = "var-"
|
||||
|
@ -118,8 +118,8 @@ export class TemplateParser {
|
|||
}
|
||||
|
||||
if (htmlAstWithErrors.rootNodes.length > 0) {
|
||||
const uniqDirectives = <CompileDirectiveMetadata[]>removeDuplicates(directives);
|
||||
const uniqPipes = <CompilePipeMetadata[]>removeDuplicates(pipes);
|
||||
const uniqDirectives = removeIdentifierDuplicates(directives);
|
||||
const uniqPipes = removeIdentifierDuplicates(pipes);
|
||||
const providerViewContext =
|
||||
new ProviderViewContext(component, htmlAstWithErrors.rootNodes[0].sourceSpan);
|
||||
const parseVisitor = new TemplateParseVisitor(
|
||||
|
@ -181,7 +181,6 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
|||
|
||||
const tempMeta = providerViewContext.component.template;
|
||||
|
||||
// TODO
|
||||
if (isPresent(tempMeta) && isPresent(tempMeta.interpolation)) {
|
||||
this._interpolationConfig = {
|
||||
start: tempMeta.interpolation[0],
|
||||
|
@ -1015,18 +1014,3 @@ export class PipeCollector extends RecursiveAstVisitor {
|
|||
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 {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 {CompileQuery, createQueryList, addQueryToTokenMap} from './compile_query';
|
||||
import {CompileMethod} from './compile_method';
|
||||
|
@ -43,11 +43,11 @@ export class CompileElement extends CompileNode {
|
|||
public appElement: o.ReadPropExpr;
|
||||
public elementRef: o.Expression;
|
||||
public injector: o.Expression;
|
||||
private _instances = new CompileTokenMap<o.Expression>();
|
||||
private _resolvedProviders: CompileTokenMap<ProviderAst>;
|
||||
private _instances = new CompileIdentifierMap<CompileTokenMetadata, o.Expression>();
|
||||
private _resolvedProviders: CompileIdentifierMap<CompileTokenMetadata, ProviderAst>;
|
||||
|
||||
private _queryCount = 0;
|
||||
private _queries = new CompileTokenMap<CompileQuery[]>();
|
||||
private _queries = new CompileIdentifierMap<CompileTokenMetadata, CompileQuery[]>();
|
||||
private _componentConstructorViewQueryLists: o.Expression[] = [];
|
||||
|
||||
public contentNodesByNgContentIndex: Array<o.Expression>[] = null;
|
||||
|
@ -144,7 +144,7 @@ export class CompileElement extends CompileNode {
|
|||
identifierToken(Identifiers.ViewContainerRef), this.appElement.prop('vcRef'));
|
||||
}
|
||||
|
||||
this._resolvedProviders = new CompileTokenMap<ProviderAst>();
|
||||
this._resolvedProviders = new CompileIdentifierMap<CompileTokenMetadata, ProviderAst>();
|
||||
this._resolvedProvidersArray.forEach(
|
||||
provider => this._resolvedProviders.add(provider.token, provider));
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* 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 {isBlank, isPresent} from '../facade/lang';
|
||||
import {Identifiers} from '../identifiers';
|
||||
|
@ -125,7 +125,8 @@ export function createQueryList(
|
|||
return expr;
|
||||
}
|
||||
|
||||
export function addQueryToTokenMap(map: CompileTokenMap<CompileQuery[]>, query: CompileQuery) {
|
||||
export function addQueryToTokenMap(
|
||||
map: CompileIdentifierMap<CompileTokenMetadata, CompileQuery[]>, query: CompileQuery) {
|
||||
query.meta.selectors.forEach((selector) => {
|
||||
var entry = map.get(selector);
|
||||
if (isBlank(entry)) {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
import {ViewType} from '../../core_private';
|
||||
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 {ListWrapper} from '../facade/collection';
|
||||
import {isBlank, isPresent} from '../facade/lang';
|
||||
|
@ -27,7 +27,7 @@ import {createPureProxy, getPropertyInView, getViewFactoryName, injectFromViewPa
|
|||
|
||||
export class CompileView implements NameResolver {
|
||||
public viewType: ViewType;
|
||||
public viewQueries: CompileTokenMap<CompileQuery[]>;
|
||||
public viewQueries: CompileIdentifierMap<CompileTokenMetadata, CompileQuery[]>;
|
||||
|
||||
public nodes: CompileNode[] = [];
|
||||
// root nodes or AppElements for ViewContainers
|
||||
|
@ -98,7 +98,7 @@ export class CompileView implements NameResolver {
|
|||
this.componentContext =
|
||||
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) {
|
||||
var directiveInstance = o.THIS_EXPR.prop('context');
|
||||
ListWrapper.forEachWithIndex(this.component.viewQueries, (queryMeta, queryIndex) => {
|
||||
|
|
|
@ -22,7 +22,7 @@ function _isComponentMetadata(obj: any): obj is ComponentMetadata {
|
|||
export class ViewResolver {
|
||||
constructor(private _reflector: ReflectorReader = reflector) {}
|
||||
|
||||
resolve(component: Type): ViewMetadata {
|
||||
resolve(component: Type, throwIfNotFound = true): ViewMetadata {
|
||||
const compMeta: ComponentMetadata =
|
||||
this._reflector.annotations(component).find(_isComponentMetadata);
|
||||
|
||||
|
@ -45,8 +45,11 @@ export class ViewResolver {
|
|||
});
|
||||
}
|
||||
} else {
|
||||
throw new BaseException(
|
||||
`Could not compile '${stringify(component)}' because it is not a component.`);
|
||||
if (throwIfNotFound) {
|
||||
throw new BaseException(
|
||||
`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 {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 {CompileMetadataResolver} from '../src/metadata_resolver';
|
||||
|
||||
|
@ -22,7 +23,7 @@ export function main() {
|
|||
describe('CompileMetadataResolver', () => {
|
||||
beforeEach(() => { configureCompiler({providers: TEST_COMPILER_PROVIDERS}); });
|
||||
|
||||
describe('getMetadata', () => {
|
||||
describe('getDirectiveMetadata', () => {
|
||||
it('should read metadata',
|
||||
inject([CompileMetadataResolver], (resolver: CompileMetadataResolver) => {
|
||||
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 {
|
||||
}
|
|
@ -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 {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 {fakeAsync, tick, TestComponentBuilder, ComponentFixture, configureCompiler} from '@angular/core/testing';
|
||||
import {XHR, ViewResolver} from '@angular/compiler';
|
||||
|
@ -28,10 +28,6 @@ class SomeComp {
|
|||
class SomeCompWithUrlTemplate {
|
||||
}
|
||||
|
||||
@AppModule({})
|
||||
class SomeModule {
|
||||
}
|
||||
|
||||
export function main() {
|
||||
describe('RuntimeCompiler', () => {
|
||||
let compiler: Compiler;
|
||||
|
@ -118,49 +114,61 @@ export function main() {
|
|||
}));
|
||||
});
|
||||
|
||||
describe('compileAppModuleAsync', () => {
|
||||
describe('compileModuleAsync', () => {
|
||||
it('should allow to use templateUrl components', fakeAsync(() => {
|
||||
@NgModule(
|
||||
{declarations: [SomeCompWithUrlTemplate], precompile: [SomeCompWithUrlTemplate]})
|
||||
class SomeModule {
|
||||
}
|
||||
|
||||
xhr.spy('get').andCallFake(() => Promise.resolve('hello'));
|
||||
let appModuleFactory: AppModuleFactory<any>;
|
||||
compiler
|
||||
.compileAppModuleAsync(
|
||||
SomeModule, new AppModuleMetadata({precompile: [SomeCompWithUrlTemplate]}))
|
||||
.then((f) => appModuleFactory = f);
|
||||
let ngModuleFactory: NgModuleFactory<any>;
|
||||
compiler.compileModuleAsync(SomeModule).then((f) => ngModuleFactory = f);
|
||||
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', () => {
|
||||
@NgModule({declarations: [SomeCompWithUrlTemplate], precompile: [SomeCompWithUrlTemplate]})
|
||||
class SomeModule {
|
||||
}
|
||||
|
||||
xhr.spy('get').andCallFake(() => Promise.resolve(''));
|
||||
expect(
|
||||
() => compiler.compileAppModuleSync(
|
||||
SomeModule, new AppModuleMetadata({precompile: [SomeCompWithUrlTemplate]})))
|
||||
expect(() => compiler.compileModuleSync(SomeModule))
|
||||
.toThrowError(
|
||||
`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',
|
||||
() => {
|
||||
@NgModule({declarations: [SomeComp], precompile: [SomeComp]})
|
||||
class SomeModule {
|
||||
}
|
||||
|
||||
xhr.spy('get').andCallFake(() => Promise.resolve(''));
|
||||
viewResolver.setView(
|
||||
SomeComp, new ViewMetadata({template: '', directives: [ChildComp]}));
|
||||
viewResolver.setView(ChildComp, new ViewMetadata({templateUrl: '/someTpl.html'}));
|
||||
expect(
|
||||
() => compiler.compileAppModuleSync(
|
||||
SomeModule, new AppModuleMetadata({precompile: [SomeComp]})))
|
||||
expect(() => compiler.compileModuleSync(SomeModule))
|
||||
.toThrowError(
|
||||
`Can't compile synchronously as ${stringify(ChildComp)} is still being loaded!`);
|
||||
});
|
||||
|
||||
it('should allow to use templateUrl components that have been loaded before',
|
||||
fakeAsync(() => {
|
||||
@NgModule(
|
||||
{declarations: [SomeCompWithUrlTemplate], precompile: [SomeCompWithUrlTemplate]})
|
||||
class SomeModule {
|
||||
}
|
||||
|
||||
xhr.spy('get').andCallFake(() => Promise.resolve('hello'));
|
||||
tcb.createFakeAsync(SomeCompWithUrlTemplate);
|
||||
let appModuleFactory = compiler.compileAppModuleSync(
|
||||
SomeModule, new AppModuleMetadata({precompile: [SomeCompWithUrlTemplate]}));
|
||||
expect(appModuleFactory).toBeTruthy();
|
||||
compiler.compileModuleAsync(SomeModule);
|
||||
tick();
|
||||
|
||||
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 {expect} from '@angular/platform-browser/testing/matchers';
|
||||
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 {TimerWrapper} from '../src/facade/async';
|
||||
import {PromiseWrapper} from '../src/facade/promise';
|
||||
|
@ -327,6 +327,27 @@ export function main() {
|
|||
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', () => {
|
||||
it('should auto detect changes if autoDetectChanges is called',
|
||||
inject(
|
||||
|
|
|
@ -10,3 +10,29 @@ export * from './testing/schema_registry_mock';
|
|||
export * from './testing/view_resolver_mock';
|
||||
export * from './testing/test_component_builder';
|
||||
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); }
|
||||
|
||||
resolve(type: Type): DirectiveMetadata {
|
||||
var dm = super.resolve(type);
|
||||
resolve(type: Type, throwIfNotFound = true): DirectiveMetadata {
|
||||
var dm = super.resolve(type, throwIfNotFound);
|
||||
if (!dm) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var providerOverrides = this._providerOverrides.get(type);
|
||||
var viewProviderOverrides = this.viewProviderOverrides.get(type);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
createAsync<T>(rootComponentType: ConcreteType<T>): Promise<ComponentFixture<T>> {
|
||||
createAsync<T>(rootComponentType: ConcreteType<T>, ngModule: ConcreteType<any> = null):
|
||||
Promise<ComponentFixture<T>> {
|
||||
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();
|
||||
return super.createSync(rootComponentType);
|
||||
return super.createSync(rootComponentType, ngModule);
|
||||
}
|
||||
|
||||
private _applyMetadataOverrides() {
|
||||
|
|
|
@ -72,10 +72,13 @@ export class MockViewResolver extends ViewResolver {
|
|||
* - Override the directives, see `overrideViewDirective`.
|
||||
* - Override the @View definition, see `setInlineTemplate`.
|
||||
*/
|
||||
resolve(component: Type): ViewMetadata {
|
||||
resolve(component: Type, throwIfNotFound = true): ViewMetadata {
|
||||
var view = this._views.get(component);
|
||||
if (isBlank(view)) {
|
||||
view = super.resolve(component);
|
||||
view = super.resolve(component, throwIfNotFound);
|
||||
if (!view) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
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/change_detection';
|
||||
export * from './src/platform_directives_and_pipes';
|
||||
export * from './src/platform_common_providers';
|
||||
export {APPLICATION_COMMON_PROVIDERS} from './src/application_common_providers';
|
||||
export * from './src/platform_core_providers';
|
||||
export {APPLICATION_COMMON_PROVIDERS, ApplicationModule} from './src/application_module';
|
||||
export {wtfCreateScope, wtfLeave, wtfStartTimeRange, wtfEndTimeRange, WtfScopeFn} from './src/profile/profile';
|
||||
|
||||
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 provider_util from './src/di/provider_util';
|
||||
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_resolver from './src/linker/component_resolver';
|
||||
import * as debug_context from './src/linker/debug_context';
|
||||
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 view from './src/linker/view';
|
||||
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 type ReflectorReader = reflector_reader.ReflectorReader;
|
||||
export var ReflectorReader: typeof reflector_reader.ReflectorReader;
|
||||
export var ReflectorComponentResolver: typeof component_resolver.ReflectorComponentResolver;
|
||||
export var CodegenComponentFactoryResolver:
|
||||
typeof component_factory_resolver.CodegenComponentFactoryResolver;
|
||||
export type AppElement = element.AppElement;
|
||||
export var AppElement: typeof element.AppElement;
|
||||
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 var DebugAppView: typeof view.DebugAppView;
|
||||
export type ViewType = view_type.ViewType;
|
||||
|
@ -136,12 +135,11 @@ export var __core_private__ = {
|
|||
LifecycleHooks: lifecycle_hooks.LifecycleHooks,
|
||||
LIFECYCLE_HOOKS_VALUES: lifecycle_hooks.LIFECYCLE_HOOKS_VALUES,
|
||||
ReflectorReader: reflector_reader.ReflectorReader,
|
||||
ReflectorComponentResolver: component_resolver.ReflectorComponentResolver,
|
||||
CodegenComponentFactoryResolver: component_factory_resolver.CodegenComponentFactoryResolver,
|
||||
AppElement: element.AppElement,
|
||||
AppView: view.AppView,
|
||||
DebugAppView: view.DebugAppView,
|
||||
AppModuleInjector: app_module_factory.AppModuleInjector,
|
||||
NgModuleInjector: ng_module_factory.NgModuleInjector,
|
||||
ViewType: view_type.ViewType,
|
||||
MAX_INTERPOLATION_VALUES: view_utils.MAX_INTERPOLATION_VALUES,
|
||||
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_},
|
||||
];
|
|
@ -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 {ChangeDetectorRef} from './change_detection/change_detector_ref';
|
||||
import {Console} from './console';
|
||||
import {Inject, Injectable, Injector, OpaqueToken, Optional, OptionalMetadata, ReflectiveInjector, SkipSelf, SkipSelfMetadata, forwardRef} from './di';
|
||||
import {AppModuleFactory, AppModuleRef} from './linker/app_module_factory';
|
||||
import {Inject, Injectable, Injector, OpaqueToken, Optional, ReflectiveInjector, SkipSelf, forwardRef} from './di';
|
||||
import {Compiler, CompilerFactory, CompilerOptions} from './linker/compiler';
|
||||
import {ComponentFactory, ComponentRef} from './linker/component_factory';
|
||||
import {ComponentFactoryResolver} from './linker/component_factory_resolver';
|
||||
import {ComponentResolver} from './linker/component_resolver';
|
||||
import {NgModuleFactory, NgModuleRef} from './linker/ng_module_factory';
|
||||
import {WtfScopeFn, wtfCreateScope, wtfLeave} from './profile/profile';
|
||||
import {Testability, TestabilityRegistry} from './testability/testability';
|
||||
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 _runModeLocked: boolean = false;
|
||||
var _platform: PlatformRef;
|
||||
|
@ -113,17 +94,30 @@ export function createPlatform(injector: Injector): PlatformRef {
|
|||
return _platform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory for a platform.
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
export type PlatformFactory = (extraProviders?: any[]) => PlatformRef;
|
||||
|
||||
/**
|
||||
* Creates a fatory for a platform
|
||||
*
|
||||
* @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}`);
|
||||
return () => {
|
||||
return (extraProviders: any[] = []) => {
|
||||
if (!getPlatform()) {
|
||||
createPlatform(
|
||||
ReflectiveInjector.resolveAndCreate(providers.concat({provide: marker, useValue: true})));
|
||||
if (parentPlaformFactory) {
|
||||
parentPlaformFactory(
|
||||
providers.concat(extraProviders).concat({provide: marker, useValue: true}));
|
||||
} else {
|
||||
createPlatform(ReflectiveInjector.resolveAndCreate(
|
||||
providers.concat(extraProviders).concat({provide: marker, useValue: true})));
|
||||
}
|
||||
}
|
||||
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.
|
||||
*
|
||||
* ## Simple Example
|
||||
|
@ -176,8 +170,8 @@ export function getPlatform(): PlatformRef {
|
|||
* ```typescript
|
||||
* my_module.ts:
|
||||
*
|
||||
* @AppModule({
|
||||
* modules: [BrowserModule]
|
||||
* @NgModule({
|
||||
* imports: [BrowserModule]
|
||||
* })
|
||||
* class MyModule {}
|
||||
*
|
||||
|
@ -192,11 +186,11 @@ export function getPlatform(): PlatformRef {
|
|||
* @experimental APIs related to application bootstrap are currently under review.
|
||||
*/
|
||||
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,
|
||||
// as instantiating the module creates some providers eagerly.
|
||||
// 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 ngZoneInjector =
|
||||
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
|
||||
*
|
||||
* ```typescript
|
||||
* @AppModule({
|
||||
* modules: [BrowserModule]
|
||||
* @NgModule({
|
||||
* imports: [BrowserModule]
|
||||
* })
|
||||
* class MyModule {}
|
||||
*
|
||||
|
@ -220,10 +214,11 @@ export function bootstrapModuleFactory<M>(
|
|||
*/
|
||||
export function bootstrapModule<M>(
|
||||
moduleType: ConcreteType<M>, platform: PlatformRef,
|
||||
compilerOptions: CompilerOptions = {}): Promise<AppModuleRef<M>> {
|
||||
compilerOptions: CompilerOptions | CompilerOptions[] = []): Promise<NgModuleRef<M>> {
|
||||
const compilerFactory: CompilerFactory = platform.injector.get(CompilerFactory);
|
||||
const compiler = compilerFactory.createCompiler(compilerOptions);
|
||||
return compiler.compileAppModuleAsync(moduleType)
|
||||
const compiler = compilerFactory.createCompiler(
|
||||
compilerOptions instanceof Array ? compilerOptions : [compilerOptions]);
|
||||
return compiler.compileModuleAsync(moduleType)
|
||||
.then((moduleFactory) => bootstrapModuleFactory(moduleFactory, platform))
|
||||
.then((moduleRef) => {
|
||||
const appRef: ApplicationRef = moduleRef.injector.get(ApplicationRef);
|
||||
|
@ -239,10 +234,7 @@ export function bootstrapModule<M>(
|
|||
*/
|
||||
export function coreBootstrap<C>(
|
||||
componentFactory: ComponentFactory<C>, injector: Injector): ComponentRef<C> {
|
||||
let console = injector.get(Console);
|
||||
console.warn('coreBootstrap is deprecated. Use bootstrapModuleFactory instead.');
|
||||
var appRef: ApplicationRef = injector.get(ApplicationRef);
|
||||
return appRef.bootstrap(componentFactory);
|
||||
throw new BaseException('coreBootstrap is deprecated. Use bootstrapModuleFactory instead.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -254,15 +246,7 @@ export function coreBootstrap<C>(
|
|||
*/
|
||||
export function coreLoadAndBootstrap(
|
||||
componentType: Type, injector: Injector): Promise<ComponentRef<any>> {
|
||||
let console = injector.get(Console);
|
||||
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]));
|
||||
});
|
||||
throw new BaseException('coreLoadAndBootstrap is deprecated. Use bootstrapModule instead.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -592,20 +576,3 @@ export class ApplicationRef_ extends ApplicationRef {
|
|||
|
||||
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
|
||||
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 {ComponentFactory, ComponentRef} from './linker/component_factory';
|
||||
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 {ElementRef} from './linker/element_ref';
|
||||
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 {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 {TemplateRef} from './linker/template_ref';
|
||||
export {ViewContainerRef} from './linker/view_container_ref';
|
||||
|
|
|
@ -6,14 +6,15 @@
|
|||
* 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 {ConcreteType, Type, stringify} from '../facade/lang';
|
||||
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 {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
|
||||
* can later be used to create and render a Component instance.
|
||||
*
|
||||
* Each `@AppModule` provides an own `Compiler` to its injector,
|
||||
* that will use the directives/pipes of the app module for compilation
|
||||
* Each `@NgModule` provides an own `Compiler` to its injector,
|
||||
* that will use the directives/pipes of the ng module for compilation
|
||||
* of components.
|
||||
* @stable
|
||||
*/
|
||||
export class Compiler {
|
||||
/**
|
||||
* Returns the injector with which the compiler has been created.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
get injector(): 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`.
|
||||
*/
|
||||
compileComponentAsync<T>(component: ConcreteType<T>): Promise<ComponentFactory<T>> {
|
||||
compileComponentAsync<T>(component: ConcreteType<T>, ngModule: Type = null):
|
||||
Promise<ComponentFactory<T>> {
|
||||
throw new BaseException(
|
||||
`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
|
||||
* `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(
|
||||
`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` /
|
||||
* `compileAppModuleAsync`. Otherwise throws a {@link ComponentStillLoadingError}.
|
||||
* `compileModuleAsync`. Otherwise throws a {@link ComponentStillLoadingError}.
|
||||
*/
|
||||
compileAppModuleSync<T>(moduleType: ConcreteType<T>, metadata: AppModuleMetadata = null):
|
||||
AppModuleFactory<T> {
|
||||
compileModuleSync<T>(moduleType: ConcreteType<T>): NgModuleFactory<T> {
|
||||
throw new BaseException(
|
||||
`Runtime compiler is not loaded. Tried to compile ${stringify(moduleType)}`);
|
||||
}
|
||||
|
||||
compileAppModuleAsync<T>(moduleType: ConcreteType<T>, metadata: AppModuleMetadata = null):
|
||||
Promise<AppModuleFactory<T>> {
|
||||
compileModuleAsync<T>(moduleType: ConcreteType<T>): Promise<NgModuleFactory<T>> {
|
||||
throw new BaseException(
|
||||
`Runtime compiler is not loaded. Tried to compile ${stringify(moduleType)}`);
|
||||
}
|
||||
|
@ -83,7 +85,7 @@ export class Compiler {
|
|||
clearCache(): void {}
|
||||
|
||||
/**
|
||||
* Clears the cache for the given component/appModule.
|
||||
* Clears the cache for the given component/ngModule.
|
||||
*/
|
||||
clearCacheFor(type: Type) {}
|
||||
}
|
||||
|
@ -98,8 +100,14 @@ export type CompilerOptions = {
|
|||
useJit?: boolean,
|
||||
defaultEncapsulation?: ViewEncapsulation,
|
||||
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
|
||||
|
@ -107,44 +115,5 @@ export type CompilerOptions = {
|
|||
* @experimental
|
||||
*/
|
||||
export abstract class CompilerFactory {
|
||||
static mergeOptions(defaultOptions: CompilerOptions = {}, newOptions: CompilerOptions = {}):
|
||||
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;
|
||||
abstract createCompiler(options?: CompilerOptions[]): Compiler;
|
||||
}
|
||||
|
|
|
@ -6,12 +6,7 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Console} from '../console';
|
||||
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 {Type} from '../facade/lang';
|
||||
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.
|
||||
*
|
||||
* @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.
|
||||
* Use {@link AppModuleFactoryLoader} for lazy loading.
|
||||
* Use {@link NgModuleFactoryLoader} for lazy loading.
|
||||
*/
|
||||
export abstract class ComponentResolver {
|
||||
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 =
|
||||
'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 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 {Type, isPresent} from '../facade/lang';
|
||||
|
||||
import {Compiler} from './compiler';
|
||||
import {ComponentRef} from './component_factory';
|
||||
import {ComponentResolver} from './component_resolver';
|
||||
import {ViewContainerRef} from './view_container_ref';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Use ComponentResolver and ViewContainerRef directly.
|
||||
* Use ComponentFactoryResolver and ViewContainerRef directly.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
|
@ -119,12 +121,12 @@ export abstract class DynamicComponentLoader {
|
|||
|
||||
@Injectable()
|
||||
export class DynamicComponentLoader_ extends DynamicComponentLoader {
|
||||
constructor(private _compiler: ComponentResolver) { super(); }
|
||||
constructor(private _compiler: Compiler) { super(); }
|
||||
|
||||
loadAsRoot(
|
||||
type: Type, overrideSelectorOrNode: string|any, injector: Injector, onDispose?: () => void,
|
||||
projectableNodes?: any[][]): Promise<ComponentRef<any>> {
|
||||
return this._compiler.resolveComponent(type).then(componentFactory => {
|
||||
return this._compiler.compileComponentAsync(<any>type).then(componentFactory => {
|
||||
var componentRef = componentFactory.create(
|
||||
injector, projectableNodes,
|
||||
isPresent(overrideSelectorOrNode) ? overrideSelectorOrNode : componentFactory.selector);
|
||||
|
@ -138,7 +140,7 @@ export class DynamicComponentLoader_ extends DynamicComponentLoader {
|
|||
loadNextToLocation(
|
||||
type: Type, location: ViewContainerRef, providers: ResolvedReflectiveProvider[] = null,
|
||||
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 childInjector = isPresent(providers) && providers.length > 0 ?
|
||||
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
|
||||
* AppModule Instance.
|
||||
* @stable
|
||||
* `NgModuleRef` provides access to the NgModule Instance as well other objects related to this
|
||||
* NgModule Instance.
|
||||
*
|
||||
* @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(); }
|
||||
|
||||
|
@ -33,22 +34,22 @@ export abstract class AppModuleRef<T> {
|
|||
get componentFactoryResolver(): ComponentFactoryResolver { return unimplemented(); }
|
||||
|
||||
/**
|
||||
* The AppModule instance.
|
||||
* The NgModule instance.
|
||||
*/
|
||||
get instance(): T { return unimplemented(); }
|
||||
}
|
||||
|
||||
/**
|
||||
* @stable
|
||||
* @experimental
|
||||
*/
|
||||
export class AppModuleFactory<T> {
|
||||
export class NgModuleFactory<T> {
|
||||
constructor(
|
||||
private _injectorClass: {new (parentInjector: Injector): AppModuleInjector<T>},
|
||||
private _injectorClass: {new (parentInjector: Injector): NgModuleInjector<T>},
|
||||
private _moduleype: ConcreteType<T>) {}
|
||||
|
||||
get moduleType(): ConcreteType<T> { return this._moduleype; }
|
||||
|
||||
create(parentInjector: Injector = null): AppModuleRef<T> {
|
||||
create(parentInjector: Injector): NgModuleRef<T> {
|
||||
if (!parentInjector) {
|
||||
parentInjector = Injector.NULL;
|
||||
}
|
||||
|
@ -60,9 +61,9 @@ export class AppModuleFactory<T> {
|
|||
|
||||
const _UNDEFINED = new Object();
|
||||
|
||||
export abstract class AppModuleInjector<T> extends CodegenComponentFactoryResolver implements
|
||||
export abstract class NgModuleInjector<T> extends CodegenComponentFactoryResolver implements
|
||||
Injector,
|
||||
AppModuleRef<T> {
|
||||
NgModuleRef<T> {
|
||||
public instance: T;
|
||||
|
||||
constructor(public parent: Injector, factories: ComponentFactory<any>[]) {
|
|
@ -6,12 +6,12 @@
|
|||
* 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
|
||||
*/
|
||||
export abstract class AppModuleFactoryLoader {
|
||||
abstract load(path: string): Promise<AppModuleFactory<any>>;
|
||||
}
|
||||
export abstract class NgModuleFactoryLoader {
|
||||
abstract load(path: string): Promise<NgModuleFactory<any>>;
|
||||
}
|
|
@ -10,9 +10,9 @@
|
|||
import {Injectable, Optional} from '../di';
|
||||
import {global} from '../facade/lang';
|
||||
|
||||
import {AppModuleFactory} from './app_module_factory';
|
||||
import {AppModuleFactoryLoader} from './app_module_factory_loader';
|
||||
import {Compiler} from './compiler';
|
||||
import {NgModuleFactory} from './ng_module_factory';
|
||||
import {NgModuleFactoryLoader} from './ng_module_factory_loader';
|
||||
|
||||
const _SEPARATOR = '#';
|
||||
|
||||
|
@ -20,18 +20,18 @@ const FACTORY_MODULE_SUFFIX = '.ngfactory';
|
|||
const FACTORY_CLASS_SUFFIX = 'NgFactory';
|
||||
|
||||
/**
|
||||
* AppModuleFactoryLoader that uses SystemJS to load AppModuleFactory
|
||||
* NgModuleFactoryLoader that uses SystemJS to load NgModuleFactory
|
||||
* @experimental
|
||||
*/
|
||||
@Injectable()
|
||||
export class SystemJsAppModuleLoader implements AppModuleFactoryLoader {
|
||||
export class SystemJsNgModuleLoader implements NgModuleFactoryLoader {
|
||||
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);
|
||||
}
|
||||
|
||||
private loadAndCompile(path: string): Promise<AppModuleFactory<any>> {
|
||||
private loadAndCompile(path: string): Promise<NgModuleFactory<any>> {
|
||||
let [module, exportName] = path.split(_SEPARATOR);
|
||||
if (exportName === undefined) exportName = 'default';
|
||||
|
||||
|
@ -39,10 +39,10 @@ export class SystemJsAppModuleLoader implements AppModuleFactoryLoader {
|
|||
.System.import(module)
|
||||
.then((module: any) => 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);
|
||||
if (exportName === undefined) exportName = 'default';
|
||||
|
||||
|
@ -58,4 +58,4 @@ function checkNotEmpty(value: any, modulePath: string, exportName: string): any
|
|||
throw new Error(`Cannot find '${exportName}' in '${modulePath}'`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
|
@ -18,9 +18,9 @@ const _SEPARATOR = '#';
|
|||
/**
|
||||
* 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
|
||||
* {@link AppModuleFactory}s instead.
|
||||
* {@link NgModuleFactory}s instead.
|
||||
*/
|
||||
@Injectable()
|
||||
export class SystemJsComponentResolver implements ComponentResolver {
|
||||
|
@ -53,9 +53,9 @@ const FACTORY_CLASS_SUFFIX = 'NgFactory';
|
|||
/**
|
||||
* 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
|
||||
* load {@link AppModuleFactory}s instead.
|
||||
* load {@link NgModuleFactory}s instead.
|
||||
*/
|
||||
@Injectable()
|
||||
export class SystemJsCmpFactoryResolver implements ComponentResolver {
|
||||
|
|
|
@ -14,15 +14,15 @@
|
|||
import {ChangeDetectionStrategy} from '../src/change_detection/change_detection';
|
||||
|
||||
import {AnimationEntryMetadata} from './animation/metadata';
|
||||
import {AppModuleMetadata} from './metadata/app_module';
|
||||
import {AttributeMetadata, ContentChildMetadata, ContentChildrenMetadata, QueryMetadata, ViewChildMetadata, ViewChildrenMetadata, ViewQueryMetadata} from './metadata/di';
|
||||
import {ComponentMetadata, DirectiveMetadata, HostBindingMetadata, HostListenerMetadata, InputMetadata, OutputMetadata, PipeMetadata} from './metadata/directives';
|
||||
import {NgModuleMetadata} from './metadata/ng_module';
|
||||
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 {ComponentMetadata, DirectiveMetadata, HostBindingMetadata, HostListenerMetadata, InputMetadata, OutputMetadata, PipeMetadata} from './metadata/directives';
|
||||
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';
|
||||
|
||||
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
|
||||
*/
|
||||
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 {
|
||||
(obj: {
|
||||
export interface NgModuleMetadataFactory {
|
||||
(obj?: {
|
||||
providers?: any[],
|
||||
directives?: Array<Type|any[]>,
|
||||
pipes?: Array<Type|any[]>,
|
||||
precompile?: Array<Type|any[]>,
|
||||
modules?: Array<Type|any[]>,
|
||||
}): AppModuleDecorator;
|
||||
new (obj: {
|
||||
declarations?: Array<Type|any[]>,
|
||||
imports?: Array<Type|any[]>,
|
||||
exports?: Array<Type|any[]>,
|
||||
precompile?: Array<Type|any[]>
|
||||
}): NgModuleDecorator;
|
||||
new (obj?: {
|
||||
providers?: any[],
|
||||
directives?: Array<Type|any[]>,
|
||||
pipes?: Array<Type|any[]>,
|
||||
precompile?: Array<Type|any[]>,
|
||||
modules?: Array<Type|any[]>,
|
||||
}): AppModuleMetadata;
|
||||
declarations?: Array<Type|any[]>,
|
||||
imports?: Array<Type|any[]>,
|
||||
exports?: Array<Type|any[]>,
|
||||
precompile?: Array<Type|any[]>
|
||||
}): NgModuleMetadata;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
/**
|
||||
* Declares an app module.
|
||||
* @stable
|
||||
* Declares an ng module.
|
||||
* @experimental
|
||||
* @Annotation
|
||||
*/
|
||||
export var AppModule: AppModuleMetadataFactory =
|
||||
<AppModuleMetadataFactory>makeDecorator(AppModuleMetadata);
|
||||
export var NgModule: NgModuleMetadataFactory =
|
||||
<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
|
||||
* `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
|
||||
* or in a nested array or map) will be added to the `precompile` property.
|
||||
*
|
||||
* ### Example
|
||||
* 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.
|
||||
*
|
||||
* ```typescript
|
||||
|
@ -37,7 +37,7 @@ import {StringWrapper, Type, isString, stringify} from '../facade/lang';
|
|||
* {path: /teams', component: TeamsComp}
|
||||
* ];
|
||||
*
|
||||
* @AppModule({
|
||||
* @NgModule({
|
||||
* providers: [provideRoutes(routes)]
|
||||
* })
|
||||
* class ModuleWithRoutes {}
|
||||
|
|
|
@ -10,10 +10,10 @@ import {InjectableMetadata} from '../di/metadata';
|
|||
import {Type} from '../facade/lang';
|
||||
|
||||
/**
|
||||
* Declares an Application Module.
|
||||
* @stable
|
||||
* Declares an Angular Module.
|
||||
* @experimental
|
||||
*/
|
||||
export class AppModuleMetadata extends InjectableMetadata {
|
||||
export class NgModuleMetadata extends InjectableMetadata {
|
||||
/**
|
||||
* Defines the set of injectable objects that are available in the injector
|
||||
* of this module.
|
||||
|
@ -29,7 +29,7 @@ export class AppModuleMetadata extends InjectableMetadata {
|
|||
* }
|
||||
* }
|
||||
*
|
||||
* @AppModule({
|
||||
* @NgModule({
|
||||
* providers: [
|
||||
* Greeter
|
||||
* ]
|
||||
|
@ -48,36 +48,52 @@ export class AppModuleMetadata extends InjectableMetadata {
|
|||
|
||||
|
||||
/**
|
||||
* Specifies a list of directives that can be used within the template
|
||||
* of any component that is part of this application module.
|
||||
* Specifies a list of directives/pipes that belong to this module.
|
||||
*
|
||||
* ### Example
|
||||
*
|
||||
* ```javascript
|
||||
* @AppModule({
|
||||
* directives: [NgFor]
|
||||
* @NgModule({
|
||||
* 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
|
||||
* of any component that is part of this application module.
|
||||
* Specifies a list of modules whose exported directives/pipes
|
||||
* should be available to templates in this module.
|
||||
*
|
||||
* ### Example
|
||||
*
|
||||
* ```javascript
|
||||
* @AppModule({
|
||||
* pipes: [SomePipe]
|
||||
* @NgModule({
|
||||
* 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
|
||||
|
@ -87,27 +103,18 @@ export class AppModuleMetadata extends InjectableMetadata {
|
|||
*/
|
||||
precompile: Array<Type|any[]>;
|
||||
|
||||
/**
|
||||
* 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}: {
|
||||
constructor({providers, declarations, imports, exports, precompile}: {
|
||||
providers?: any[],
|
||||
directives?: Array<Type|any[]>,
|
||||
pipes?: Array<Type|any[]>,
|
||||
precompile?: Array<Type|any[]>,
|
||||
modules?: Array<Type|any[]>
|
||||
declarations?: Array<Type|any[]>,
|
||||
imports?: Array<Type|any[]>,
|
||||
exports?: Array<Type|any[]>,
|
||||
precompile?: Array<Type|any[]>
|
||||
} = {}) {
|
||||
super();
|
||||
this._providers = providers;
|
||||
this.directives = directives;
|
||||
this.pipes = pipes;
|
||||
this.declarations = declarations;
|
||||
this.imports = imports;
|
||||
this.exports = exports;
|
||||
this.precompile = precompile;
|
||||
this.modules = modules;
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
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 {Provider} from './di';
|
||||
import {Reflector, reflector} from './reflection/reflection';
|
||||
|
@ -21,13 +21,22 @@ function _reflector(): Reflector {
|
|||
|
||||
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
|
||||
*/
|
||||
export const PLATFORM_COMMON_PROVIDERS: Array<any|Type|Provider|any[]> = /*@ts2dart_const*/[
|
||||
PLATFORM_CORE_PROVIDERS,
|
||||
/*@ts2dart_Provider*/ {provide: Reflector, useFactory: _reflector, deps: []},
|
||||
/*@ts2dart_Provider*/ {provide: ReflectorReader, useExisting: Reflector}, TestabilityRegistry,
|
||||
Console
|
||||
];
|
||||
export const corePlatform = createPlatformFactory(null, 'core', _CORE_PLATFORM_PROVIDERS);
|
||||
|
||||
/**
|
||||
* A default set of providers which should be included in any Angular platform.
|
||||
*
|
||||
* @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
|
||||
* directives via an {@link AppModule} instead.
|
||||
* directives via an {@link NgModule} instead.
|
||||
*/
|
||||
export const PLATFORM_DIRECTIVES: OpaqueToken =
|
||||
/*@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
|
||||
* {@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 {SpyChangeDetectorRef} from './spies';
|
||||
import {ApplicationRef_, ApplicationRef, PLATFORM_CORE_PROVIDERS, APPLICATION_CORE_PROVIDERS} from '@angular/core/src/application_ref';
|
||||
import {Type, Injector, APP_INITIALIZER, Component, ReflectiveInjector, coreLoadAndBootstrap, PlatformRef, createPlatform, disposePlatform, ComponentResolver, ComponentFactoryResolver, ChangeDetectorRef} from '@angular/core';
|
||||
import {ConcreteType} from '../src/facade/lang';
|
||||
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 {BaseException} from '../src/facade/exceptions';
|
||||
import {PromiseWrapper, PromiseCompleter, TimerWrapper} from '../src/facade/async';
|
||||
|
@ -18,36 +20,48 @@ import {ExceptionHandler} from '../src/facade/exception_handler';
|
|||
|
||||
export function main() {
|
||||
describe('bootstrap', () => {
|
||||
var platform: PlatformRef;
|
||||
var defaultPlatform: PlatformRef;
|
||||
var errorLogger: _ArrayLogger;
|
||||
var someCompFactory: ComponentFactory<any>;
|
||||
var appProviders: any[];
|
||||
|
||||
beforeEach(() => {
|
||||
errorLogger = new _ArrayLogger();
|
||||
disposePlatform();
|
||||
platform = createPlatform(ReflectiveInjector.resolveAndCreate(PLATFORM_CORE_PROVIDERS));
|
||||
defaultPlatform = createPlatformFactory(coreDynamicPlatform, 'test')();
|
||||
someCompFactory =
|
||||
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(); });
|
||||
|
||||
function createApplication(providers: any[]): ApplicationRef_ {
|
||||
var appInjector = ReflectiveInjector.resolveAndCreate(
|
||||
[
|
||||
APPLICATION_CORE_PROVIDERS, {provide: Console, useValue: new _MockConsole()},
|
||||
{provide: ExceptionHandler, useValue: new ExceptionHandler(errorLogger, false)},
|
||||
{provide: ComponentResolver, useValue: new _MockComponentResolver(someCompFactory)},
|
||||
{provide: ComponentFactoryResolver, useValue: ComponentFactoryResolver.NULL}, providers
|
||||
],
|
||||
platform.injector);
|
||||
function createModule(providers: any[] = []): ConcreteType<any> {
|
||||
@NgModule({providers: [appProviders, providers], imports: [ApplicationModule]})
|
||||
class MyModule {
|
||||
}
|
||||
|
||||
return MyModule;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
describe('ApplicationRef', () => {
|
||||
it('should throw when reentering tick', () => {
|
||||
var cdRef = <any>new SpyChangeDetectorRef();
|
||||
var ref = createApplication([]);
|
||||
var ref = createApplication();
|
||||
try {
|
||||
ref.registerChangeDetector(cdRef);
|
||||
cdRef.spy('detectChanges').andCallFake(() => ref.tick());
|
||||
|
@ -59,14 +73,14 @@ export function main() {
|
|||
|
||||
describe('run', () => {
|
||||
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');
|
||||
});
|
||||
|
||||
it('should return a promise with rejected errors even if the exceptionHandler is not rethrowing',
|
||||
inject(
|
||||
[AsyncTestCompleter, Injector], (async: AsyncTestCompleter, injector: Injector) => {
|
||||
var ref = createApplication([]);
|
||||
var ref = createApplication();
|
||||
var promise = ref.run(() => PromiseWrapper.reject('Test', null));
|
||||
PromiseWrapper.catchError(promise, (e) => {
|
||||
expect(e).toEqual('Test');
|
||||
|
@ -76,7 +90,7 @@ export function main() {
|
|||
});
|
||||
});
|
||||
|
||||
describe('coreLoadAndBootstrap', () => {
|
||||
describe('bootstrapModule', () => {
|
||||
it('should wait for asynchronous app initializers',
|
||||
inject([AsyncTestCompleter, Injector], (async: AsyncTestCompleter, injector: Injector) => {
|
||||
let completer: PromiseCompleter<any> = PromiseWrapper.completer();
|
||||
|
@ -85,16 +99,19 @@ export function main() {
|
|||
completer.resolve(true);
|
||||
initializerDone = true;
|
||||
}, 1);
|
||||
var app = createApplication(
|
||||
[{provide: APP_INITIALIZER, useValue: () => completer.promise, multi: true}]);
|
||||
coreLoadAndBootstrap(MyComp6, app.injector).then(_ => {
|
||||
expect(initializerDone).toBe(true);
|
||||
async.done();
|
||||
});
|
||||
|
||||
bootstrapModule(
|
||||
createModule(
|
||||
[{provide: APP_INITIALIZER, useValue: () => completer.promise, multi: true}]),
|
||||
defaultPlatform)
|
||||
.then(_ => {
|
||||
expect(initializerDone).toBe(true);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
describe('coreBootstrap', () => {
|
||||
describe('ApplicationRef.bootstrap', () => {
|
||||
it('should throw if an APP_INITIIALIZER is not yet resolved',
|
||||
inject([Injector], (injector: Injector) => {
|
||||
var app = createApplication([{
|
||||
|
|
|
@ -87,14 +87,13 @@ export function main() {
|
|||
expect(log.result()).toEqual('1; 2');
|
||||
}));
|
||||
|
||||
// TODO(vicb): check why this doesn't work in JS - linked to open issues on GH ?
|
||||
xit('should complain if the test throws an exception during async calls', () => {
|
||||
it('should complain if the test throws an exception during async calls', () => {
|
||||
expect(() => {
|
||||
fakeAsync(() => {
|
||||
PromiseWrapper.resolve(null).then((_) => { throw new BaseException('async'); });
|
||||
flushMicrotasks();
|
||||
})();
|
||||
}).toThrowError('async');
|
||||
}).toThrowError('Uncaught (in promise): async');
|
||||
});
|
||||
|
||||
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', () => {
|
||||
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',
|
||||
inject(
|
||||
[TestComponentBuilder, AsyncTestCompleter],
|
||||
|
|
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 {TestComponentBuilder} from '@angular/core/testing';
|
||||
import {Component, ComponentFactoryResolver, NoComponentFactoryError, forwardRef, ANALYZE_FOR_PRECOMPILE} from '@angular/core';
|
||||
import {TestComponentBuilder, configureModule} from '@angular/core/testing';
|
||||
import {Component, ComponentFactoryResolver, NoComponentFactoryError, forwardRef, ANALYZE_FOR_PRECOMPILE, ViewMetadata} from '@angular/core';
|
||||
import {stringify} from '../../src/facade/lang';
|
||||
|
||||
export function main() {
|
||||
describe('jit', () => { declareTests({useJit: true}); });
|
||||
|
@ -17,19 +18,33 @@ export function main() {
|
|||
|
||||
function declareTests({useJit}: {useJit: boolean}) {
|
||||
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',
|
||||
inject(
|
||||
[TestComponentBuilder, AsyncTestCompleter],
|
||||
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||
tcb.createAsync(MainComp).then((compFixture) => {
|
||||
let mainComp: MainComp = compFixture.componentInstance;
|
||||
expect(compFixture.debugElement.injector.get(ComponentFactoryResolver))
|
||||
.toBe(mainComp.cfr);
|
||||
var cf = mainComp.cfr.resolveComponentFactory(ChildComp);
|
||||
expect(cf.componentType).toBe(ChildComp);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||
const compFixture = tcb.createSync(MainComp);
|
||||
let mainComp: MainComp = compFixture.componentInstance;
|
||||
expect(compFixture.componentRef.injector.get(ComponentFactoryResolver)).toBe(mainComp.cfr);
|
||||
var cf = mainComp.cfr.resolveComponentFactory(ChildComp);
|
||||
expect(cf.componentType).toBe(ChildComp);
|
||||
}));
|
||||
|
||||
|
||||
it('should resolve ComponentFactories via ANALYZE_FOR_PRECOMPILE',
|
||||
|
@ -37,63 +52,52 @@ function declareTests({useJit}: {useJit: boolean}) {
|
|||
let compFixture = tcb.createSync(CompWithAnalyzePrecompileProvider);
|
||||
let mainComp: CompWithAnalyzePrecompileProvider = compFixture.componentInstance;
|
||||
let cfr: ComponentFactoryResolver =
|
||||
compFixture.debugElement.injector.get(ComponentFactoryResolver);
|
||||
compFixture.componentRef.injector.get(ComponentFactoryResolver);
|
||||
expect(cfr.resolveComponentFactory(ChildComp).componentType).toBe(ChildComp);
|
||||
expect(cfr.resolveComponentFactory(NestedChildComp).componentType).toBe(NestedChildComp);
|
||||
}));
|
||||
|
||||
it('should be able to get a component form a parent component (view hiearchy)',
|
||||
inject(
|
||||
[TestComponentBuilder, AsyncTestCompleter],
|
||||
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||
tcb.overrideTemplate(MainComp, '<child></child>')
|
||||
.createAsync(MainComp)
|
||||
.then((compFixture) => {
|
||||
let childCompEl = compFixture.debugElement.children[0];
|
||||
let childComp: ChildComp = childCompEl.componentInstance;
|
||||
// declared on ChildComp directly
|
||||
expect(childComp.cfr.resolveComponentFactory(NestedChildComp).componentType)
|
||||
.toBe(NestedChildComp);
|
||||
// inherited from MainComp
|
||||
expect(childComp.cfr.resolveComponentFactory(ChildComp).componentType)
|
||||
.toBe(ChildComp);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||
const compFixture =
|
||||
tcb.overrideView(
|
||||
MainComp,
|
||||
new ViewMetadata({template: '<child></child>', directives: [ChildComp]}))
|
||||
.createSync(MainComp);
|
||||
let childCompEl = compFixture.debugElement.children[0];
|
||||
let childComp: ChildComp = childCompEl.componentInstance;
|
||||
// declared on ChildComp directly
|
||||
expect(childComp.cfr.resolveComponentFactory(NestedChildComp).componentType)
|
||||
.toBe(NestedChildComp);
|
||||
// inherited from MainComp
|
||||
expect(childComp.cfr.resolveComponentFactory(ChildComp).componentType).toBe(ChildComp);
|
||||
}));
|
||||
|
||||
it('should not be able to get components from a parent component (content hierarchy)',
|
||||
inject(
|
||||
[TestComponentBuilder, AsyncTestCompleter],
|
||||
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||
tcb.overrideTemplate(MainComp, '<child><nested></nested></child>')
|
||||
.overrideTemplate(ChildComp, '<ng-content></ng-content>')
|
||||
.createAsync(MainComp)
|
||||
.then((compFixture) => {
|
||||
let nestedChildCompEl = compFixture.debugElement.children[0].children[0];
|
||||
let nestedChildComp: NestedChildComp = nestedChildCompEl.componentInstance;
|
||||
expect(nestedChildComp.cfr.resolveComponentFactory(ChildComp).componentType)
|
||||
.toBe(ChildComp);
|
||||
expect(() => nestedChildComp.cfr.resolveComponentFactory(NestedChildComp))
|
||||
.toThrow(new NoComponentFactoryError(NestedChildComp));
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||
const compFixture = tcb.overrideView(MainComp, new ViewMetadata({
|
||||
template: '<child><nested></nested></child>',
|
||||
directives: [ChildComp, NestedChildComp]
|
||||
}))
|
||||
.overrideTemplate(ChildComp, '<ng-content></ng-content>')
|
||||
.createSync(MainComp);
|
||||
let nestedChildCompEl = compFixture.debugElement.children[0].children[0];
|
||||
let nestedChildComp: NestedChildComp = nestedChildCompEl.componentInstance;
|
||||
expect(nestedChildComp.cfr.resolveComponentFactory(ChildComp).componentType)
|
||||
.toBe(ChildComp);
|
||||
expect(() => nestedChildComp.cfr.resolveComponentFactory(NestedChildComp))
|
||||
.toThrow(new NoComponentFactoryError(NestedChildComp));
|
||||
}));
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
var DIRECTIVES: any[] = [
|
||||
forwardRef(() => NestedChildComp),
|
||||
forwardRef(() => ChildComp),
|
||||
forwardRef(() => MainComp),
|
||||
];
|
||||
|
||||
@Component({selector: 'nested', directives: DIRECTIVES, template: ''})
|
||||
@Component({selector: 'nested', template: ''})
|
||||
class NestedChildComp {
|
||||
constructor(public cfr: ComponentFactoryResolver) {}
|
||||
}
|
||||
|
||||
@Component({selector: 'child', precompile: [NestedChildComp], directives: DIRECTIVES, template: ''})
|
||||
@Component({selector: 'child', precompile: [NestedChildComp], template: ''})
|
||||
class ChildComp {
|
||||
constructor(public cfr: ComponentFactoryResolver) {}
|
||||
}
|
||||
|
@ -101,7 +105,6 @@ class ChildComp {
|
|||
@Component({
|
||||
selector: 'main',
|
||||
precompile: [ChildComp],
|
||||
directives: DIRECTIVES,
|
||||
template: '',
|
||||
})
|
||||
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', () => {
|
||||
beforeEach(() => {
|
||||
configureCompiler({useJit: useJit});
|
||||
configureModule({pipes: [PlatformPipe]});
|
||||
configureModule({declarations: [PlatformPipe]});
|
||||
});
|
||||
|
||||
it('should overwrite them by custom pipes',
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
* 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 {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';
|
||||
|
||||
|
@ -22,105 +22,87 @@ export class TestBed implements Injector {
|
|||
private _instantiated: boolean = false;
|
||||
|
||||
private _compiler: Compiler = null;
|
||||
private _moduleRef: AppModuleRef<any> = null;
|
||||
private _appModuleFactory: AppModuleFactory<any> = null;
|
||||
private _moduleRef: NgModuleRef<any> = null;
|
||||
private _ngModuleFactory: NgModuleFactory<any> = null;
|
||||
|
||||
private _compilerProviders: Array<Type|Provider|any[]|any> = [];
|
||||
private _compilerUseJit: boolean = true;
|
||||
private _compilerOptions: CompilerOptions[] = [];
|
||||
|
||||
private _providers: Array<Type|Provider|any[]|any> = [];
|
||||
private _directives: Array<Type|any[]|any> = [];
|
||||
private _pipes: Array<Type|any[]|any> = [];
|
||||
private _modules: Array<Type|any[]|any> = [];
|
||||
private _declarations: Array<Type|any[]|any> = [];
|
||||
private _imports: Array<Type|any[]|any> = [];
|
||||
private _precompile: Array<Type|any[]|any> = [];
|
||||
|
||||
reset() {
|
||||
this._compiler = null;
|
||||
this._moduleRef = null;
|
||||
this._appModuleFactory = null;
|
||||
this._compilerProviders = [];
|
||||
this._compilerUseJit = true;
|
||||
this._ngModuleFactory = null;
|
||||
this._compilerOptions = [];
|
||||
this._providers = [];
|
||||
this._directives = [];
|
||||
this._pipes = [];
|
||||
this._modules = [];
|
||||
this._declarations = [];
|
||||
this._imports = [];
|
||||
this._precompile = [];
|
||||
this._instantiated = false;
|
||||
}
|
||||
|
||||
platform: PlatformRef = null;
|
||||
|
||||
appModule: Type = null;
|
||||
ngModule: Type = null;
|
||||
|
||||
configureCompiler(config: {providers?: any[], useJit?: boolean}) {
|
||||
if (this._instantiated) {
|
||||
throw new BaseException('Cannot add configuration after test injector is instantiated');
|
||||
}
|
||||
if (config.providers) {
|
||||
this._compilerProviders = ListWrapper.concat(this._compilerProviders, config.providers);
|
||||
}
|
||||
if (config.useJit !== undefined) {
|
||||
this._compilerUseJit = config.useJit;
|
||||
}
|
||||
this._compilerOptions.push(config);
|
||||
}
|
||||
|
||||
configureModule(moduleDef: {
|
||||
providers?: any[],
|
||||
directives?: any[],
|
||||
pipes?: any[],
|
||||
precompile?: any[],
|
||||
modules?: any[]
|
||||
}) {
|
||||
configureModule(
|
||||
moduleDef: {providers?: any[], declarations?: any[], imports?: any[], precompile?: any[]}) {
|
||||
if (this._instantiated) {
|
||||
throw new BaseException('Cannot add configuration after test injector is instantiated');
|
||||
}
|
||||
if (moduleDef.providers) {
|
||||
this._providers = ListWrapper.concat(this._providers, moduleDef.providers);
|
||||
}
|
||||
if (moduleDef.directives) {
|
||||
this._directives = ListWrapper.concat(this._directives, moduleDef.directives);
|
||||
if (moduleDef.declarations) {
|
||||
this._declarations = ListWrapper.concat(this._declarations, moduleDef.declarations);
|
||||
}
|
||||
if (moduleDef.pipes) {
|
||||
this._pipes = ListWrapper.concat(this._pipes, moduleDef.pipes);
|
||||
if (moduleDef.imports) {
|
||||
this._imports = ListWrapper.concat(this._imports, moduleDef.imports);
|
||||
}
|
||||
if (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) {
|
||||
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`.');
|
||||
}
|
||||
|
||||
if (this._appModuleFactory) {
|
||||
return Promise.resolve(this._appModuleFactory);
|
||||
if (this._ngModuleFactory) {
|
||||
return Promise.resolve(this._ngModuleFactory);
|
||||
}
|
||||
|
||||
let moduleMeta = this._createCompilerAndModuleMeta();
|
||||
const moduleType = this._createCompilerAndModule();
|
||||
|
||||
return this._compiler.compileAppModuleAsync(_NoopModule, moduleMeta)
|
||||
.then((appModuleFactory) => {
|
||||
this._appModuleFactory = appModuleFactory;
|
||||
return appModuleFactory;
|
||||
});
|
||||
return this._compiler.compileModuleAsync(moduleType).then((ngModuleFactory) => {
|
||||
this._ngModuleFactory = ngModuleFactory;
|
||||
return ngModuleFactory;
|
||||
});
|
||||
}
|
||||
|
||||
initTestAppModule() {
|
||||
initTestModule() {
|
||||
if (this._instantiated) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._appModuleFactory) {
|
||||
this._createFromModuleFactory(this._appModuleFactory);
|
||||
if (this._ngModuleFactory) {
|
||||
this._createFromModuleFactory(this._ngModuleFactory);
|
||||
} else {
|
||||
let moduleMeta = this._createCompilerAndModuleMeta();
|
||||
this._createFromModuleFactory(this._compiler.compileAppModuleSync(_NoopModule, moduleMeta));
|
||||
let moduleType = this._createCompilerAndModule();
|
||||
this._createFromModuleFactory(this._compiler.compileModuleSync(moduleType));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,31 +113,34 @@ export class TestBed implements Injector {
|
|||
if (this._instantiated) {
|
||||
return Promise.resolve(this);
|
||||
}
|
||||
let moduleMeta = this._createCompilerAndModuleMeta();
|
||||
return this._compiler.compileAppModuleAsync(_NoopModule, moduleMeta)
|
||||
.then((appModuleFactory) => this._createFromModuleFactory(appModuleFactory));
|
||||
let ngModule = this._createCompilerAndModule();
|
||||
return this._compiler.compileModuleAsync(ngModule).then(
|
||||
(ngModuleFactory) => this._createFromModuleFactory(ngModuleFactory));
|
||||
}
|
||||
|
||||
private _createCompilerAndModuleMeta(): AppModuleMetadata {
|
||||
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 {
|
||||
}
|
||||
|
||||
const compilerFactory: CompilerFactory = this.platform.injector.get(CompilerFactory);
|
||||
this._compiler = compilerFactory.createCompiler({
|
||||
providers: this._compilerProviders,
|
||||
useJit: this._compilerUseJit,
|
||||
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;
|
||||
this._compiler =
|
||||
compilerFactory.createCompiler(this._compilerOptions.concat([{useDebug: true}]));
|
||||
return DynamicTestModule;
|
||||
}
|
||||
|
||||
private _createFromModuleFactory(appModuleFactory: AppModuleFactory<any>): Injector {
|
||||
this._moduleRef = appModuleFactory.create(this.platform.injector);
|
||||
private _createFromModuleFactory(ngModuleFactory: NgModuleFactory<any>): Injector {
|
||||
this._moduleRef = ngModuleFactory.create(this.platform.injector);
|
||||
this._instantiated = true;
|
||||
return this;
|
||||
}
|
||||
|
@ -163,13 +148,13 @@ export class TestBed implements Injector {
|
|||
get(token: any, notFoundValue: any = Injector.THROW_IF_NOT_FOUND) {
|
||||
if (!this._instantiated) {
|
||||
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) {
|
||||
return this;
|
||||
}
|
||||
// Tests can inject things from the app module and from the compiler,
|
||||
// but the app module can't inject things from the compiler and vice versa.
|
||||
// Tests can inject things from the ng module and from the compiler,
|
||||
// but the ng module can't inject things from the compiler and vice versa.
|
||||
let result = this._moduleRef.injector.get(token, UNDEFINED);
|
||||
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 {
|
||||
if (!this._instantiated) {
|
||||
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));
|
||||
return FunctionWrapper.apply(fn, params);
|
||||
|
@ -219,20 +204,17 @@ export function getTestInjector() {
|
|||
export function setBaseTestProviders(
|
||||
platformProviders: Array<Type|Provider|any[]>,
|
||||
applicationProviders: Array<Type|Provider|any[]>) {
|
||||
// Create a platform based on the Platform Providers.
|
||||
var platformRef = createPlatform(ReflectiveInjector.resolveAndCreate(platformProviders));
|
||||
|
||||
// Create an AppModule based on the application providers.
|
||||
@AppModule({providers: applicationProviders})
|
||||
class TestAppModule {
|
||||
if (platformProviders.length === 1 && typeof platformProviders[0] === 'function') {
|
||||
(<any>platformProviders[0])(applicationProviders);
|
||||
} else {
|
||||
throw new Error(
|
||||
`setBaseTestProviders is deprecated and only supports platformProviders that are predefined by Angular. Use 'initTestEnvironment' instead.`);
|
||||
}
|
||||
|
||||
initTestEnvironment(TestAppModule, platformRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* suite on the current platform. If you absolutely need to change the providers,
|
||||
|
@ -243,13 +225,15 @@ export function setBaseTestProviders(
|
|||
*
|
||||
* @experimental
|
||||
*/
|
||||
export function initTestEnvironment(appModule: Type, platform: PlatformRef) {
|
||||
export function initTestEnvironment(ngModule: Type, platform: PlatformRef): Injector {
|
||||
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');
|
||||
}
|
||||
testBed.platform = platform;
|
||||
testBed.appModule = appModule;
|
||||
testBed.ngModule = ngModule;
|
||||
|
||||
return testBed;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -269,20 +253,20 @@ export function resetBaseTestProviders() {
|
|||
export function resetTestEnvironment() {
|
||||
var testBed = getTestBed();
|
||||
testBed.platform = null;
|
||||
testBed.appModule = null;
|
||||
testBed.ngModule = null;
|
||||
testBed.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Run asynchronous precompilation for the test's AppModule. It is necessary to call this function
|
||||
* if your test is using an AppModule which has precompiled components that require an asynchronous
|
||||
* Run asynchronous precompilation for the test's NgModule. It is necessary to call this function
|
||||
* 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.
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
export function doAsyncPrecompilation(): Promise<any> {
|
||||
let testBed = getTestBed();
|
||||
return testBed.createAppModuleFactory();
|
||||
return testBed.createModuleFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -324,7 +308,7 @@ export function inject(tokens: any[], fn: Function): () => any {
|
|||
} else {
|
||||
return () => {
|
||||
try {
|
||||
testBed.initTestAppModule();
|
||||
testBed.initTestModule();
|
||||
} catch (e) {
|
||||
if (e instanceof ComponentStillLoadingError) {
|
||||
throw new Error(
|
||||
|
@ -343,13 +327,9 @@ export function inject(tokens: any[], fn: Function): () => any {
|
|||
* @experimental
|
||||
*/
|
||||
export class InjectSetupWrapper {
|
||||
constructor(private _moduleDef: () => {
|
||||
providers?: any[],
|
||||
directives?: any[],
|
||||
pipes?: any[],
|
||||
precompile?: any[],
|
||||
modules?: any[]
|
||||
}) {}
|
||||
constructor(
|
||||
private _moduleDef:
|
||||
() => {providers?: any[], declarations?: any[], imports?: any[], precompile?: any[]}) {}
|
||||
|
||||
private _addModule() {
|
||||
var moduleDef = this._moduleDef();
|
||||
|
@ -378,12 +358,9 @@ export function withProviders(providers: () => any) {
|
|||
*/
|
||||
export function withModule(moduleDef: () => {
|
||||
providers?: any[],
|
||||
directives?: any[],
|
||||
pipes?: any[],
|
||||
precompile?: any[],
|
||||
modules?: any[]
|
||||
declarations?: any[],
|
||||
imports?: any[],
|
||||
precompile?: any[]
|
||||
}) {
|
||||
return new InjectSetupWrapper(moduleDef);
|
||||
}
|
||||
|
||||
class _NoopModule {}
|
||||
|
|
|
@ -119,25 +119,27 @@ export class TestComponentBuilder {
|
|||
/**
|
||||
* 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 ngZone: NgZone = noNgZone ? null : this._injector.get(NgZone, null);
|
||||
let compiler: Compiler = this._injector.get(Compiler);
|
||||
|
||||
let initComponent = () => {
|
||||
let promise: Promise<ComponentFactory<any>> =
|
||||
compiler.compileComponentAsync(rootComponentType);
|
||||
compiler.compileComponentAsync(rootComponentType, ngModule);
|
||||
return promise.then(componentFactory => this.createFromFactory(ngZone, componentFactory));
|
||||
};
|
||||
|
||||
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 error: any /** TODO #9100 */;
|
||||
PromiseWrapper.then(
|
||||
this.createAsync(rootComponentType), (_result) => { result = _result; },
|
||||
this.createAsync(rootComponentType, ngModule), (_result) => { result = _result; },
|
||||
(_error) => { error = _error; });
|
||||
tick();
|
||||
if (isPresent(error)) {
|
||||
|
@ -146,14 +148,15 @@ export class TestComponentBuilder {
|
|||
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 ngZone: NgZone = noNgZone ? null : this._injector.get(NgZone, null);
|
||||
let compiler: Compiler = this._injector.get(Compiler);
|
||||
|
||||
let initComponent = () => {
|
||||
return this.createFromFactory(
|
||||
ngZone, this._injector.get(Compiler).compileComponentSync(rootComponentType));
|
||||
ngZone, compiler.compileComponentSync(rootComponentType, ngModule));
|
||||
};
|
||||
|
||||
return ngZone == null ? initComponent() : ngZone.run(initComponent);
|
||||
|
|
|
@ -49,13 +49,9 @@ export function addProviders(providers: Array<any>): void {
|
|||
*
|
||||
* @stable
|
||||
*/
|
||||
export function configureModule(moduleDef: {
|
||||
providers?: any[],
|
||||
directives?: any[],
|
||||
pipes?: any[],
|
||||
precompile?: any[],
|
||||
modules?: any[]
|
||||
}): void {
|
||||
export function configureModule(
|
||||
moduleDef: {providers?: any[], declarations?: any[], imports?: any[], precompile?: any[]}):
|
||||
void {
|
||||
if (!moduleDef) return;
|
||||
try {
|
||||
testBed.configureModule(moduleDef);
|
||||
|
|
|
@ -6,8 +6,9 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Component, ReflectiveInjector, coreLoadAndBootstrap, createPlatform} from '@angular/core';
|
||||
import {BROWSER_APP_PROVIDERS, BROWSER_PLATFORM_PROVIDERS} from '@angular/platform-browser';
|
||||
import {Component, ReflectiveInjector, bootstrapModule, createPlatformFactory} from '@angular/core';
|
||||
import {BrowserModule} from '@angular/platform-browser';
|
||||
import {browserDynamicPlatform} from '@angular/platform-browser-dynamic';
|
||||
|
||||
var appProviders: any[] = [];
|
||||
|
||||
|
@ -16,8 +17,6 @@ var appProviders: any[] = [];
|
|||
class MyApp {
|
||||
}
|
||||
|
||||
var platform = createPlatform(ReflectiveInjector.resolveAndCreate(BROWSER_PLATFORM_PROVIDERS));
|
||||
var appInjector =
|
||||
ReflectiveInjector.resolveAndCreate([BROWSER_APP_PROVIDERS, appProviders], platform.injector);
|
||||
coreLoadAndBootstrap(MyApp, appInjector);
|
||||
var myPlatformFactory = createPlatformFactory(browserDynamicPlatform, 'myPlatform');
|
||||
bootstrapModule(MyApp, myPlatformFactory());
|
||||
// #enddocregion
|
||||
|
|
|
@ -155,12 +155,12 @@ export function stringify(token: any): string {
|
|||
return '' + token;
|
||||
}
|
||||
|
||||
if (token.name) {
|
||||
return token.name;
|
||||
}
|
||||
if (token.overriddenName) {
|
||||
return token.overriddenName;
|
||||
}
|
||||
if (token.name) {
|
||||
return token.name;
|
||||
}
|
||||
|
||||
var res = token.toString();
|
||||
var newLineIndex = res.indexOf('\n');
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* 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 {DefaultValueAccessor} from './directives/default_value_accessor';
|
||||
|
@ -83,3 +83,10 @@ export const FORM_DIRECTIVES: Type[][] =
|
|||
|
||||
export const REACTIVE_FORM_DIRECTIVES: Type[][] =
|
||||
/*@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
|
||||
*/
|
||||
|
||||
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 {FormBuilder} from './form_builder';
|
||||
|
||||
|
@ -28,18 +28,26 @@ export const REACTIVE_FORM_PROVIDERS: Type[] =
|
|||
/*@ts2dart_const*/[FormBuilder, RadioControlRegistry];
|
||||
|
||||
/**
|
||||
* The app module for forms.
|
||||
* The ng module for forms.
|
||||
* @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 {
|
||||
}
|
||||
|
||||
/**
|
||||
* The app module for reactive forms.
|
||||
* The ng module for reactive forms.
|
||||
* @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 {
|
||||
}
|
||||
|
||||
|
@ -57,4 +65,4 @@ export function provideForms(): any[] {
|
|||
return [
|
||||
{provide: PLATFORM_DIRECTIVES, useValue: FORM_DIRECTIVES, multi: true}, REACTIVE_FORM_PROVIDERS
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ import {PromiseWrapper} from '../src/facade/promise';
|
|||
export function main() {
|
||||
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',
|
||||
inject(
|
||||
|
|
|
@ -20,7 +20,7 @@ import {ListWrapper} from '../src/facade/collection';
|
|||
export function main() {
|
||||
describe('template-driven forms integration tests', () => {
|
||||
|
||||
beforeEach(() => { configureModule({modules: [FormsModule]}); });
|
||||
beforeEach(() => { configureModule({imports: [FormsModule]}); });
|
||||
|
||||
it('should support ngModel for single fields',
|
||||
fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||
|
|
|
@ -6,37 +6,24 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {COMMON_DIRECTIVES, COMMON_PIPES} from '@angular/common';
|
||||
import {COMPILER_PROVIDERS, CompilerConfig, XHR, RUNTIME_COMPILER_FACTORY,} from '@angular/compiler';
|
||||
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_APP_PROVIDERS, BrowserModule, WORKER_APP_APPLICATION_PROVIDERS, WORKER_SCRIPT, WORKER_UI_APPLICATION_PROVIDERS, browserPlatform, workerAppPlatform, workerUiPlatform, BROWSER_PLATFORM_PROVIDERS} from '@angular/platform-browser';
|
||||
import {XHR, analyzeAppProvidersForDeprecatedConfiguration, coreDynamicPlatform} 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 {BROWSER_PLATFORM_PROVIDERS, BrowserModule, WORKER_APP_PLATFORM_PROVIDERS, WORKER_SCRIPT, WorkerAppModule, browserPlatform, workerAppPlatform, workerUiPlatform} from '@angular/platform-browser';
|
||||
|
||||
import {Console, ReflectionCapabilities, reflector} from './core_private';
|
||||
import {getDOM, initDomAdapter} from './platform_browser_private';
|
||||
import {Console} from './core_private';
|
||||
import {PromiseWrapper} from './src/facade/async';
|
||||
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 {XHRImpl} from './src/xhr/xhr_impl';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated The compiler providers are already included in the {@link CompilerFactory} that is
|
||||
* contained the {@link browserDynamicPlatform}()`.
|
||||
*/
|
||||
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}
|
||||
];
|
||||
export const BROWSER_APP_COMPILER_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [];
|
||||
|
||||
/**
|
||||
* @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[]*/> =
|
||||
[{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.
|
||||
*/
|
||||
export const browserDynamicPlatform =
|
||||
createPlatformFactory('browserDynamic', BROWSER_DYNAMIC_PLATFORM_PROVIDERS);
|
||||
export const browserDynamicPlatform = createPlatformFactory(
|
||||
coreDynamicPlatform, 'browserDynamic', INTERNAL_BROWSER_DYNAMIC_PLATFORM_PROVIDERS);
|
||||
|
||||
/**
|
||||
* Bootstrapping for Angular applications.
|
||||
|
@ -142,8 +106,9 @@ export const browserDynamicPlatform =
|
|||
* ## API (version 2)
|
||||
* - `appComponentType`: The root component which should act as the application. This is
|
||||
* 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.
|
||||
* - to configure the compiler, use the `compilerOptions` parameter.
|
||||
*
|
||||
* Returns a `Promise` of {@link ComponentRef}.
|
||||
*
|
||||
|
@ -156,11 +121,10 @@ export function bootstrap<C>(
|
|||
customProviders?: Array<any /*Type | Provider | any[]*/>): Promise<ComponentRef<C>>;
|
||||
export function bootstrap<C>(
|
||||
appComponentType: ConcreteType<C>,
|
||||
{providers, directives, pipes, modules, precompile, compilerOptions}?: {
|
||||
{providers, imports, declarations, precompile, compilerOptions}?: {
|
||||
providers?: Array<any /*Type | Provider | any[]*/>,
|
||||
directives?: any[],
|
||||
pipes?: any[],
|
||||
modules?: any[],
|
||||
declarations?: any[],
|
||||
imports?: any[],
|
||||
precompile?: any[],
|
||||
compilerOptions?: CompilerOptions
|
||||
}): Promise<ComponentRef<C>>;
|
||||
|
@ -168,112 +132,107 @@ export function bootstrap<C>(
|
|||
appComponentType: ConcreteType<C>,
|
||||
customProvidersOrDynamicModule?: Array<any /*Type | Provider | any[]*/>| {
|
||||
providers: Array<any /*Type | Provider | any[]*/>,
|
||||
directives: any[],
|
||||
pipes: any[],
|
||||
modules: any[],
|
||||
declarations?: any[],
|
||||
imports: any[],
|
||||
precompile: any[],
|
||||
compilerOptions: CompilerOptions
|
||||
}): Promise<ComponentRef<C>> {
|
||||
let compilerOptions: CompilerOptions;
|
||||
let compilerProviders: any = [];
|
||||
let providers: any[] = [];
|
||||
let directives: any[] = [];
|
||||
let pipes: any[] = [];
|
||||
let modules: any[] = [];
|
||||
let declarations: any[] = [];
|
||||
let imports: any[] = [];
|
||||
let precompile: any[] = [];
|
||||
let deprecationMessages: string[] = [];
|
||||
if (customProvidersOrDynamicModule instanceof Array) {
|
||||
providers = customProvidersOrDynamicModule;
|
||||
const deprecatedConfiguration = analyzeAppProvidersForDeprecatedConfiguration(providers);
|
||||
declarations = deprecatedConfiguration.moduleDeclarations.concat(declarations);
|
||||
compilerOptions = deprecatedConfiguration.compilerOptions;
|
||||
deprecationMessages = deprecatedConfiguration.deprecationMessages;
|
||||
} else if (customProvidersOrDynamicModule) {
|
||||
providers = normalizeArray(customProvidersOrDynamicModule.providers);
|
||||
directives = normalizeArray(customProvidersOrDynamicModule.directives);
|
||||
pipes = normalizeArray(customProvidersOrDynamicModule.pipes);
|
||||
modules = normalizeArray(customProvidersOrDynamicModule.modules);
|
||||
declarations = normalizeArray(customProvidersOrDynamicModule.declarations);
|
||||
imports = normalizeArray(customProvidersOrDynamicModule.imports);
|
||||
precompile = normalizeArray(customProvidersOrDynamicModule.precompile);
|
||||
compilerOptions = customProvidersOrDynamicModule.compilerOptions;
|
||||
}
|
||||
|
||||
@AppModule({
|
||||
@NgModule({
|
||||
providers: providers,
|
||||
modules: modules.concat([BrowserModule]),
|
||||
directives: directives,
|
||||
pipes: pipes,
|
||||
declarations: declarations.concat([appComponentType]),
|
||||
imports: [BrowserModule, imports],
|
||||
precompile: precompile.concat([appComponentType])
|
||||
})
|
||||
class DynamicModule {
|
||||
}
|
||||
|
||||
return bootstrapModule(
|
||||
DynamicModule, browserDynamicPlatform(),
|
||||
CompilerFactory.mergeOptions(compilerOptions, {deprecatedAppProviders: providers}))
|
||||
return bootstrapModule(DynamicModule, browserDynamicPlatform(), compilerOptions)
|
||||
.then((moduleRef) => {
|
||||
const console = moduleRef.injector.get(Console);
|
||||
deprecationMessages.forEach((msg) => console.warn(msg));
|
||||
const appRef: ApplicationRef = moduleRef.injector.get(ApplicationRef);
|
||||
return appRef.bootstrap(appComponentType);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Create an {@link AppModule} that includes the {@link WorkerUiModule} and use {@link
|
||||
* bootstrapModule}
|
||||
* with the {@link workerUiPlatform}() instead.
|
||||
* Bootstraps the worker ui.
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
export function bootstrapWorkerUi(
|
||||
workerScriptUri: string,
|
||||
customProviders?: Array<any /*Type | Provider | any[]*/>): Promise<ApplicationRef> {
|
||||
console.warn(
|
||||
'bootstrapWorkerUi is deprecated. Create an @AppModule that includes the `WorkerUiModule` and use `bootstrapModule` with the `workerUiPlatform()` instead.');
|
||||
var app = ReflectiveInjector.resolveAndCreate(
|
||||
[
|
||||
WORKER_UI_APPLICATION_PROVIDERS, BROWSER_APP_COMPILER_PROVIDERS,
|
||||
{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));
|
||||
customProviders: Array<any /*Type | Provider | any[]*/> = []): Promise<PlatformRef> {
|
||||
// For now, just creates the worker ui platform...
|
||||
return Promise.resolve(workerUiPlatform([{
|
||||
provide: WORKER_SCRIPT,
|
||||
useValue: workerScriptUri,
|
||||
}].concat(customProviders)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated The compiler providers are already included in the {@link CompilerFactory} that is
|
||||
* contained the {@link workerAppPlatform}().
|
||||
* @experimental API related to bootstrapping are still under review.
|
||||
*/
|
||||
const WORKER_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}
|
||||
];
|
||||
|
||||
export const workerAppDynamicPlatform =
|
||||
createPlatformFactory(coreDynamicPlatform, 'workerAppDynamic', [{
|
||||
provide: CompilerOptions,
|
||||
useValue: {providers: [{provide: XHR, useClass: XHRImpl}]},
|
||||
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}
|
||||
* with the {@link workerAppPlatform}() instead.
|
||||
* with the {@link workerAppDynamicPlatform}() instead.
|
||||
*/
|
||||
export function bootstrapWorkerApp(
|
||||
appComponentType: Type,
|
||||
customProviders?: Array<any /*Type | Provider | any[]*/>): Promise<ComponentRef<any>> {
|
||||
export function bootstrapWorkerApp<T>(
|
||||
appComponentType: ConcreteType<T>,
|
||||
customProviders?: Array<any /*Type | Provider | any[]*/>): Promise<ComponentRef<T>> {
|
||||
console.warn(
|
||||
'bootstrapWorkerApp is deprecated. Create an @AppModule that includes the `WorkerAppModule` and use `bootstrapModule` with the `workerAppPlatform()` instead.');
|
||||
var appInjector = ReflectiveInjector.resolveAndCreate(
|
||||
[
|
||||
WORKER_APP_APPLICATION_PROVIDERS, WORKER_APP_COMPILER_PROVIDERS,
|
||||
isPresent(customProviders) ? customProviders : []
|
||||
],
|
||||
workerAppPlatform().injector);
|
||||
return coreLoadAndBootstrap(appComponentType, appInjector);
|
||||
'bootstrapWorkerApp is deprecated. Create an @NgModule that includes the `WorkerAppModule` and use `bootstrapModule` with the `workerAppDynamicPlatform()` instead.');
|
||||
|
||||
const deprecatedConfiguration = analyzeAppProvidersForDeprecatedConfiguration(customProviders);
|
||||
const declarations = [deprecatedConfiguration.moduleDeclarations.concat([appComponentType])];
|
||||
|
||||
@NgModule({
|
||||
providers: customProviders,
|
||||
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[] {
|
||||
return arr ? arr : [];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,5 +8,6 @@
|
|||
|
||||
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 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
|
||||
*/
|
||||
|
||||
import {COMMON_DIRECTIVES, COMMON_PIPES} from '@angular/common';
|
||||
import {CompilerConfig, DirectiveResolver, ViewResolver} from '@angular/compiler';
|
||||
import {MockDirectiveResolver, MockViewResolver, OverridingTestComponentBuilder} from '@angular/compiler/testing';
|
||||
import {AppModule, Compiler, CompilerFactory, PLATFORM_DIRECTIVES, PLATFORM_PIPES, PlatformRef, Provider, ReflectiveInjector, Type, createPlatformFactory} from '@angular/core';
|
||||
import {TestComponentBuilder, TestComponentRenderer} from '@angular/core/testing';
|
||||
import {BrowserTestModule, TEST_BROWSER_APPLICATION_PROVIDERS, TEST_BROWSER_PLATFORM_PROVIDERS} from '@angular/platform-browser/testing';
|
||||
import {CompilerConfig, DirectiveResolver, NgModuleResolver, ViewResolver, analyzeAppProvidersForDeprecatedConfiguration} from '@angular/compiler';
|
||||
import {OverridingTestComponentBuilder, coreDynamicTestingPlatform} from '@angular/compiler/testing';
|
||||
import {Compiler, CompilerFactory, CompilerOptions, NgModule, PlatformRef, Provider, ReflectiveInjector, Type, createPlatform, createPlatformFactory} from '@angular/core';
|
||||
import {TestComponentBuilder, TestComponentRenderer, initTestEnvironment} from '@angular/core/testing';
|
||||
import {BrowserTestingModule, browserTestingPlatform} 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';
|
||||
|
||||
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.
|
||||
*/
|
||||
export const browserDynamicTestPlatform =
|
||||
createPlatformFactory('browserDynamicTest', BROWSER_DYNAMIC_TEST_PLATFORM_PROVIDERS);
|
||||
export const browserDynamicTestingPlatform = createPlatformFactory(
|
||||
coreDynamicTestingPlatform, 'browserDynamicTesting',
|
||||
INTERNAL_BROWSER_DYNAMIC_PLATFORM_PROVIDERS);
|
||||
|
||||
/**
|
||||
* AppModule for testing.
|
||||
* NgModule for testing.
|
||||
*
|
||||
* @stable
|
||||
*/
|
||||
@AppModule({
|
||||
modules: [BrowserTestModule],
|
||||
@NgModule({
|
||||
exports: [BrowserTestingModule],
|
||||
providers: [
|
||||
{provide: TestComponentBuilder, useClass: OverridingTestComponentBuilder},
|
||||
{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({
|
||||
providers: [
|
||||
{provide: DirectiveResolver, useClass: MockDirectiveResolver},
|
||||
{provide: ViewResolver, useClass: MockViewResolver}
|
||||
],
|
||||
deprecatedAppProviders: [
|
||||
{provide: PLATFORM_DIRECTIVES, useValue: COMMON_DIRECTIVES, multi: true},
|
||||
{provide: PLATFORM_PIPES, useValue: COMMON_PIPES, multi: true}
|
||||
]
|
||||
});
|
||||
/**
|
||||
* @deprecated Use initTestEnvironment with browserDynamicTestingPlatform instead.
|
||||
*/
|
||||
export const TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||
// 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(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[]*/> = [
|
||||
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},
|
||||
];
|
||||
export const TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||
[];
|
||||
|
|
|
@ -42,5 +42,6 @@ export var __platform_browser_private__ = {
|
|||
SharedStylesHost: shared_styles_host.SharedStylesHost,
|
||||
ELEMENT_PROBE_PROVIDERS: ng_proble.ELEMENT_PROBE_PROVIDERS,
|
||||
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
|
||||
*/
|
||||
|
||||
import {COMMON_DIRECTIVES, COMMON_PIPES, 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 {CommonModule, PlatformLocation} from '@angular/common';
|
||||
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 {AnimationDriver} from '../src/dom/animation_driver';
|
||||
|
@ -28,18 +28,21 @@ import {DomSharedStylesHost, SharedStylesHost} from './dom/shared_styles_host';
|
|||
import {isBlank} from './facade/lang';
|
||||
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.
|
||||
*
|
||||
* 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[]*/> = [
|
||||
PLATFORM_COMMON_PROVIDERS, {provide: PLATFORM_INITIALIZER, useValue: initDomAdapter, multi: true},
|
||||
{provide: PlatformLocation, useClass: BrowserPlatformLocation}
|
||||
];
|
||||
export const BROWSER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||
[PLATFORM_COMMON_PROVIDERS, INTERNAL_BROWSER_PLATFORM_PROVIDERS];
|
||||
|
||||
/**
|
||||
* @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
|
||||
* 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[]*/> = [
|
||||
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
|
||||
];
|
||||
export const BROWSER_APP_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [];
|
||||
|
||||
/**
|
||||
* @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() {
|
||||
BrowserDomAdapter.makeCurrent();
|
||||
|
@ -102,16 +96,26 @@ export function _resolveDefaultAnimationDriver(): AnimationDriver {
|
|||
}
|
||||
|
||||
/**
|
||||
* The app module for the browser.
|
||||
* The ng module for the browser.
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
@AppModule({
|
||||
@NgModule({
|
||||
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,
|
||||
pipes: COMMON_PIPES
|
||||
exports: [CommonModule, ApplicationModule]
|
||||
})
|
||||
export class BrowserModule {
|
||||
}
|
||||
|
|
|
@ -6,13 +6,14 @@
|
|||
* 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 {MessageBasedPlatformLocation} from './platform_location';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
@ -20,7 +21,7 @@ import {MessageBasedPlatformLocation} from './platform_location';
|
|||
*/
|
||||
export const WORKER_UI_LOCATION_PROVIDERS = [
|
||||
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 {
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {COMMON_DIRECTIVES, COMMON_PIPES, 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 {CommonModule, FORM_PROVIDERS} from '@angular/common';
|
||||
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 {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[]*/> =
|
||||
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[]*/> = [
|
||||
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}
|
||||
];
|
||||
export const WORKER_APP_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [];
|
||||
|
||||
/**
|
||||
* @experimental
|
||||
*/
|
||||
export const workerAppPlatform = createPlatformFactory('workerApp', WORKER_APP_PLATFORM_PROVIDERS);
|
||||
export const workerAppPlatform = createPlatformFactory(corePlatform, 'workerApp');
|
||||
|
||||
function _exceptionHandler(): ExceptionHandler {
|
||||
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
|
||||
*/
|
||||
@AppModule({
|
||||
providers: WORKER_APP_APPLICATION_PROVIDERS,
|
||||
directives: COMMON_DIRECTIVES,
|
||||
pipes: COMMON_PIPES
|
||||
@NgModule({
|
||||
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}
|
||||
],
|
||||
exports: [CommonModule, ApplicationModule]
|
||||
})
|
||||
export class WorkerAppModule {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* 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';
|
||||
|
||||
|
@ -34,6 +34,7 @@ import {ServiceMessageBrokerFactory, ServiceMessageBrokerFactory_} from './web_w
|
|||
import {MessageBasedRenderer} from './web_workers/ui/renderer';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper class that exposes the Worker
|
||||
* 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.
|
||||
*/
|
||||
export const WORKER_UI_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
|
||||
PLATFORM_COMMON_PROVIDERS,
|
||||
{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,
|
||||
export const _WORKER_UI_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
|
||||
{provide: NgZone, useFactory: createNgZone, deps: []},
|
||||
MessageBasedRenderer,
|
||||
{provide: WORKER_UI_STARTABLE_MESSAGING_SERVICE, useExisting: MessageBasedRenderer, multi: true},
|
||||
BROWSER_SANITIZATION_PROVIDERS,
|
||||
|
@ -104,10 +97,27 @@ export const WORKER_UI_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[
|
|||
Testability,
|
||||
EventManager,
|
||||
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]}
|
||||
];
|
||||
|
||||
/**
|
||||
* * @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) {
|
||||
var bus = injector.get(MessageBus);
|
||||
let zone = injector.get(NgZone);
|
||||
|
@ -122,27 +132,11 @@ function messageBusFactory(instance: WebWorkerInstance): MessageBus {
|
|||
return instance.bus;
|
||||
}
|
||||
|
||||
function initWebWorkerRenderPlatform(): void {
|
||||
BrowserDomAdapter.makeCurrent();
|
||||
wtfInit();
|
||||
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 {
|
||||
function initWebWorkerRenderPlatform(injector: Injector): () => void {
|
||||
return () => {
|
||||
BrowserDomAdapter.makeCurrent();
|
||||
wtfInit();
|
||||
BrowserGetTestability.init();
|
||||
var scriptUri: string;
|
||||
try {
|
||||
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
|
||||
*/
|
||||
|
@ -175,14 +187,3 @@ function _resolveDefaultAnimationDriver(): AnimationDriver {
|
|||
// work with animations just yet...
|
||||
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 {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 {Console} from '@angular/core/src/console';
|
||||
import {ComponentRef} from '@angular/core/src/linker/component_factory';
|
||||
import {Testability, TestabilityRegistry} from '@angular/core/src/testability/testability';
|
||||
import {ComponentFixture} from '@angular/core/testing';
|
||||
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 {BROWSER_APP_COMPILER_PROVIDERS, bootstrap} from '@angular/platform-browser-dynamic';
|
||||
import {BrowserModule} from '@angular/platform-browser';
|
||||
import {bootstrap, browserDynamicPlatform} from '@angular/platform-browser-dynamic';
|
||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||
import {DOCUMENT} from '@angular/platform-browser/src/dom/dom_tokens';
|
||||
import {expect} from '@angular/platform-browser/testing/matchers';
|
||||
|
@ -223,16 +223,10 @@ export function main() {
|
|||
|
||||
it('should unregister change detectors when components are disposed',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
var platform =
|
||||
createPlatform(ReflectiveInjector.resolveAndCreate(BROWSER_PLATFORM_PROVIDERS));
|
||||
var app = ReflectiveInjector
|
||||
.resolveAndCreate(
|
||||
[BROWSER_APP_PROVIDERS, BROWSER_APP_COMPILER_PROVIDERS, testProviders],
|
||||
platform.injector)
|
||||
.get(ApplicationRef);
|
||||
coreLoadAndBootstrap(HelloRootCmp, app.injector).then((ref) => {
|
||||
bootstrap(HelloRootCmp, testProviders).then((ref) => {
|
||||
const appRef = ref.injector.get(ApplicationRef);
|
||||
ref.destroy();
|
||||
expect(() => app.tick()).not.toThrow();
|
||||
expect(() => appRef.tick()).not.toThrow();
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
@ -258,24 +252,29 @@ export function main() {
|
|||
});
|
||||
}));
|
||||
|
||||
it('should run platform initializers', inject([Log], (log: Log) => {
|
||||
let p = createPlatform(ReflectiveInjector.resolveAndCreate([
|
||||
BROWSER_PLATFORM_PROVIDERS,
|
||||
it('should run platform initializers',
|
||||
inject([Log, AsyncTestCompleter], (log: Log, async: AsyncTestCompleter) => {
|
||||
let p = createPlatformFactory(browserDynamicPlatform, 'someName', [
|
||||
{provide: PLATFORM_INITIALIZER, useValue: log.fn('platform_init1'), multi: true},
|
||||
{provide: PLATFORM_INITIALIZER, useValue: log.fn('platform_init2'), multi: true}
|
||||
]));
|
||||
])();
|
||||
|
||||
@NgModule({
|
||||
imports: [BrowserModule],
|
||||
providers: [
|
||||
{provide: APP_INITIALIZER, useValue: log.fn('app_init1'), multi: true},
|
||||
{provide: APP_INITIALIZER, useValue: log.fn('app_init2'), multi: true}
|
||||
]
|
||||
})
|
||||
class SomeModule {
|
||||
}
|
||||
|
||||
expect(log.result()).toEqual('platform_init1; platform_init2');
|
||||
log.clear();
|
||||
var a = ReflectiveInjector.resolveAndCreate(
|
||||
[
|
||||
BROWSER_APP_PROVIDERS,
|
||||
{provide: APP_INITIALIZER, useValue: log.fn('app_init1'), multi: true},
|
||||
{provide: APP_INITIALIZER, useValue: log.fn('app_init2'), multi: true}
|
||||
],
|
||||
p.injector);
|
||||
a.get(ApplicationRef);
|
||||
|
||||
expect(log.result()).toEqual('app_init1; app_init2');
|
||||
bootstrapModule(SomeModule, p).then(() => {
|
||||
expect(log.result()).toEqual('app_init1; app_init2');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should register each application with the testability registry',
|
||||
|
@ -305,7 +304,7 @@ export function main() {
|
|||
])).then((compRef) => {
|
||||
expect(el).toHaveText('hello world!');
|
||||
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();
|
||||
});
|
||||
|
@ -325,10 +324,8 @@ export function main() {
|
|||
.toBe('transformed someValue');
|
||||
|
||||
expect(compilerConsole.warnings).toEqual([
|
||||
'Passing PLATFORM_DIRECTIVES to "bootstrap()" as provider is deprecated. Use the new parameter "directives" of "bootstrap()" instead.',
|
||||
'Passing PLATFORM_PIPES to "bootstrap()" as provider is deprecated. Use the new parameter "pipes" of "bootstrap()" instead.',
|
||||
`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)}`
|
||||
`The PLATFORM_DIRECTIVES provider and CompilerConfig.platformDirectives is deprecated. Add the directives to an NgModule instead! (Directives: ${stringify(SomeDirective)})`,
|
||||
`The PLATFORM_PIPES provider and CompilerConfig.platformPipes is deprecated. Add the pipes to an NgModule instead! (Pipes: ${stringify(SomePipe)})`
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
import {NgIf} from '@angular/common';
|
||||
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 {expect} from '@angular/platform-browser/testing/matchers';
|
||||
|
||||
|
@ -112,8 +112,8 @@ class SomePipe {
|
|||
class CompUsingModuleDirectiveAndPipe {
|
||||
}
|
||||
|
||||
@AppModule({})
|
||||
class SomeNestedModule {
|
||||
@NgModule()
|
||||
class SomeLibModule {
|
||||
}
|
||||
|
||||
@Component({
|
||||
|
@ -233,10 +233,9 @@ export function main() {
|
|||
beforeEach(() => {
|
||||
moduleConfig = {
|
||||
providers: [FancyService],
|
||||
directives: [SomeDirective],
|
||||
pipes: [SomePipe],
|
||||
precompile: [CompUsingModuleDirectiveAndPipe],
|
||||
modules: [SomeNestedModule]
|
||||
imports: [SomeLibModule],
|
||||
declarations: [SomeDirective, SomePipe, CompUsingModuleDirectiveAndPipe],
|
||||
precompile: [CompUsingModuleDirectiveAndPipe]
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -256,9 +255,9 @@ export function main() {
|
|||
expect(el.children[0].properties['title']).toBe('transformed someValue');
|
||||
}));
|
||||
|
||||
it('should use set up nested modules',
|
||||
inject([SomeNestedModule], (nestedModule: SomeNestedModule) => {
|
||||
expect(nestedModule).toBeAnInstanceOf(SomeNestedModule);
|
||||
it('should use set up library modules',
|
||||
inject([SomeLibModule], (libModule: SomeLibModule) => {
|
||||
expect(libModule).toBeAnInstanceOf(SomeLibModule);
|
||||
}));
|
||||
|
||||
it('should use set up precompile components',
|
||||
|
@ -284,11 +283,10 @@ export function main() {
|
|||
expect(el.children[0].properties['title']).toBe('transformed someValue');
|
||||
}));
|
||||
|
||||
it('should use set up nested modules',
|
||||
withModule(() => moduleConfig)
|
||||
.inject([SomeNestedModule], (nestedModule: SomeNestedModule) => {
|
||||
expect(nestedModule).toBeAnInstanceOf(SomeNestedModule);
|
||||
}));
|
||||
it('should use set up library modules',
|
||||
withModule(() => moduleConfig).inject([SomeLibModule], (libModule: SomeLibModule) => {
|
||||
expect(libModule).toBeAnInstanceOf(SomeLibModule);
|
||||
}));
|
||||
|
||||
it('should use set up precompile components',
|
||||
withModule(() => moduleConfig)
|
||||
|
@ -301,7 +299,7 @@ export function main() {
|
|||
|
||||
describe('precompile components with template url', () => {
|
||||
beforeEach(async(() => {
|
||||
configureModule({precompile: [CompWithUrlTemplate]});
|
||||
configureModule({declarations: [CompWithUrlTemplate], precompile: [CompWithUrlTemplate]});
|
||||
doAsyncPrecompilation();
|
||||
}));
|
||||
|
||||
|
@ -450,7 +448,12 @@ export function main() {
|
|||
expect(
|
||||
() =>
|
||||
it('should fail',
|
||||
withModule(() => { return {precompile: [CompWithUrlTemplate]}; })
|
||||
withModule(() => {
|
||||
return {
|
||||
declarations: [CompWithUrlTemplate],
|
||||
precompile: [CompWithUrlTemplate]
|
||||
};
|
||||
})
|
||||
.inject(
|
||||
[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 {ServiceMessageBrokerFactory_} from '@angular/platform-browser/src/web_workers/shared/service_message_broker';
|
||||
import {dispatchEvent} from '../../../../platform-browser/testing/browser_util';
|
||||
import {BrowserTestModule} from '@angular/platform-browser/testing';
|
||||
import {browserDynamicTestPlatform} from '@angular/platform-browser-dynamic/testing';
|
||||
import {BrowserTestingModule} from '@angular/platform-browser/testing';
|
||||
import {browserDynamicTestingPlatform} from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
export function main() {
|
||||
function createWebWorkerBrokerFactory(
|
||||
|
@ -65,8 +65,8 @@ export function main() {
|
|||
beforeEach(() => {
|
||||
uiRenderStore = new RenderStore();
|
||||
var testUiInjector = new TestBed();
|
||||
testUiInjector.platform = browserDynamicTestPlatform();
|
||||
testUiInjector.appModule = BrowserTestModule;
|
||||
testUiInjector.platform = browserDynamicTestingPlatform();
|
||||
testUiInjector.ngModule = BrowserTestingModule;
|
||||
testUiInjector.configureModule({
|
||||
providers: [
|
||||
Serializer, {provide: RenderStore, useValue: uiRenderStore},
|
||||
|
@ -74,7 +74,7 @@ export function main() {
|
|||
{provide: RootRenderer, useExisting: DomRootRenderer}
|
||||
]
|
||||
});
|
||||
testUiInjector.initTestAppModule();
|
||||
testUiInjector.initTestModule();
|
||||
var uiSerializer = testUiInjector.get(Serializer);
|
||||
var domRootRenderer = testUiInjector.get(DomRootRenderer);
|
||||
workerRenderStore = new RenderStore();
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
*/
|
||||
|
||||
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 {AnimationDriver} from '../src/dom/animation_driver';
|
||||
import {ELEMENT_PROBE_PROVIDERS} from '../src/dom/debug/ng_probe';
|
||||
|
@ -25,45 +25,46 @@ function createNgZone(): NgZone {
|
|||
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
|
||||
*
|
||||
* @experimental
|
||||
* @deprecated Use `browserTestingPlatform()` or create a custom platform factory via
|
||||
* `createPlatformFactory(browserTestingPlatform, ...)`
|
||||
*/
|
||||
export const TEST_BROWSER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
|
||||
PLATFORM_COMMON_PROVIDERS,
|
||||
{provide: PLATFORM_INITIALIZER, useValue: initBrowserTests, multi: true}
|
||||
];
|
||||
export const TEST_BROWSER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||
[PLATFORM_COMMON_PROVIDERS, _TEST_BROWSER_PLATFORM_PROVIDERS];
|
||||
|
||||
/**
|
||||
* @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[]*/> = [
|
||||
BROWSER_APP_PROVIDERS, {provide: APP_ID, useValue: 'a'}, ELEMENT_PROBE_PROVIDERS,
|
||||
{provide: NgZone, useFactory: createNgZone},
|
||||
{provide: AnimationDriver, useValue: AnimationDriver.NOOP}
|
||||
];
|
||||
export const TEST_BROWSER_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [];
|
||||
|
||||
/**
|
||||
* Platform for testing
|
||||
*
|
||||
* @experimental API related to bootstrapping are still under review.
|
||||
*/
|
||||
export const browserTestPlatform =
|
||||
createPlatformFactory('browserTest', TEST_BROWSER_PLATFORM_PROVIDERS);
|
||||
export const browserTestingPlatform =
|
||||
createPlatformFactory(corePlatform, 'browserTesting', _TEST_BROWSER_PLATFORM_PROVIDERS);
|
||||
|
||||
/**
|
||||
* AppModule for testing.
|
||||
* NgModule for testing.
|
||||
*
|
||||
* @stable
|
||||
* @experimental
|
||||
*/
|
||||
@AppModule({
|
||||
modules: [BrowserModule],
|
||||
@NgModule({
|
||||
exports: [BrowserModule],
|
||||
providers: [
|
||||
{provide: APP_ID, useValue: 'a'}, ELEMENT_PROBE_PROVIDERS,
|
||||
{provide: NgZone, useFactory: createNgZone},
|
||||
{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 ReflectionCapabilities: typeof t.ReflectionCapabilities = r.ReflectionCapabilities;
|
||||
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 {CompilerFactory, ComponentRef, OpaqueToken, PLATFORM_COMMON_PROVIDERS, PLATFORM_INITIALIZER, PlatformRef, ReflectiveInjector, Type, assertPlatform, coreLoadAndBootstrap, createPlatform, createPlatformFactory, getPlatform} from '@angular/core';
|
||||
import {BROWSER_DYNAMIC_TEST_COMPILER_FACTORY} from '@angular/platform-browser-dynamic/testing';
|
||||
import {analyzeAppProvidersForDeprecatedConfiguration, coreDynamicPlatform} from '@angular/compiler';
|
||||
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';
|
||||
|
||||
function notSupported(feature: string): Error {
|
||||
|
@ -31,23 +33,21 @@ class ServerPlatformLocation extends PlatformLocation {
|
|||
back(): void { notSupported('back'); };
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,
|
||||
export const INTERNAL_SERVER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
|
||||
{provide: PLATFORM_INITIALIZER, useValue: initParse5Adapter, multi: true},
|
||||
{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() {
|
||||
Parse5DomAdapter.makeCurrent();
|
||||
|
@ -57,7 +57,8 @@ function initParse5Adapter() {
|
|||
/**
|
||||
* @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.
|
||||
|
@ -65,7 +66,7 @@ export const serverPlatform = createPlatformFactory('server', SERVER_PLATFORM_PR
|
|||
* @experimental
|
||||
*/
|
||||
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).
|
||||
|
@ -81,16 +82,35 @@ export const serverDynamicPlatform =
|
|||
* 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}()
|
||||
* instead.
|
||||
*/
|
||||
export function serverBootstrap(
|
||||
appComponentType: Type,
|
||||
providers: Array<any /*Type | Provider | any[]*/>): Promise<ComponentRef<any>> {
|
||||
export function serverBootstrap<T>(
|
||||
appComponentType: ConcreteType<T>,
|
||||
customProviders: Array<any /*Type | Provider | any[]*/>): Promise<ComponentRef<T>> {
|
||||
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();
|
||||
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
|
||||
*/
|
||||
|
||||
import {AppModule, CompilerFactory, OpaqueToken, PLATFORM_COMMON_PROVIDERS, PLATFORM_INITIALIZER, PlatformRef, ReflectiveInjector, assertPlatform, createPlatform, createPlatformFactory, getPlatform} from '@angular/core';
|
||||
import {BROWSER_DYNAMIC_TEST_COMPILER_FACTORY, BrowserDynamicTestModule, TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS} from '@angular/platform-browser-dynamic/testing';
|
||||
import {analyzeAppProvidersForDeprecatedConfiguration} from '@angular/compiler';
|
||||
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';
|
||||
|
||||
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},
|
||||
];
|
||||
import {INTERNAL_SERVER_PLATFORM_PROVIDERS} from '../src/server';
|
||||
|
||||
/**
|
||||
* Platform for testing
|
||||
*
|
||||
* @experimental API related to bootstrapping are still under review.
|
||||
*/
|
||||
export const serverTestPlatform =
|
||||
createPlatformFactory('serverTest', TEST_SERVER_PLATFORM_PROVIDERS);
|
||||
export const serverTestingPlatform = createPlatformFactory(
|
||||
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]})
|
||||
export class ServerTestModule {
|
||||
@NgModule({exports: [BrowserDynamicTestingModule]})
|
||||
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[]*/> =
|
||||
TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS;
|
||||
export const TEST_SERVER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||
// 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[]*/> = [];
|
||||
|
|
|
@ -9,4 +9,17 @@ The Angular router is designed to solve these problems. Using the router, you ca
|
|||
Read the overview of the Router [here](http://victorsavkin.com/post/145672529346/angular-router).
|
||||
|
||||
## 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…
Reference in New Issue