2016-06-23 12:47:54 -04:00
/ * *
* @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
* /
2016-04-28 20:50:03 -04:00
import { ListWrapper } from '../src/facade/collection' ;
2016-05-02 01:50:37 -04:00
import { BaseException , ExceptionHandler , unimplemented } from '../src/facade/exceptions' ;
2016-08-10 21:21:28 -04:00
import { isBlank , isPresent , isPromise , stringify } from '../src/facade/lang' ;
2016-06-08 19:38:52 -04:00
2016-08-02 10:54:14 -04:00
import { ApplicationInitStatus } from './application_init' ;
2016-08-02 10:38:14 -04:00
import { APP_BOOTSTRAP_LISTENER , PLATFORM_INITIALIZER } from './application_tokens' ;
2016-04-28 20:50:03 -04:00
import { ChangeDetectorRef } from './change_detection/change_detector_ref' ;
2016-06-08 19:38:52 -04:00
import { Console } from './console' ;
2016-08-11 18:24:35 -04:00
import { Injectable , Injector , OpaqueToken , Optional , ReflectiveInjector } from './di' ;
import { CompilerFactory , CompilerOptions } from './linker/compiler' ;
2016-06-08 19:38:52 -04:00
import { ComponentFactory , ComponentRef } from './linker/component_factory' ;
feat(browser): use AppModules for bootstrap in the browser
This introduces the `BrowserModule` to be used for long form
bootstrap and offline compile bootstrap:
```
@AppModule({
modules: [BrowserModule],
precompile: [MainComponent],
providers: […], // additional providers
directives: […], // additional platform directives
pipes: […] // additional platform pipes
})
class MyModule {
constructor(appRef: ApplicationRef) {
appRef.bootstrap(MainComponent);
}
}
// offline compile
import {bootstrapModuleFactory} from ‘@angular/platform-browser’;
bootstrapModuleFactory(MyModuleNgFactory);
// runtime compile long form
import {bootstrapModule} from ‘@angular/platform-browser-dynamic’;
bootstrapModule(MyModule);
```
The short form, `bootstrap(...)`, can now creates a module on the fly,
given `directives`, `pipes, `providers`, `precompile` and `modules`
properties.
Related changes:
- make `SanitizationService`, `SecurityContext` public in `@angular/core` so that the offline compiler can resolve the token
- move `AnimationDriver` to `platform-browser` and make it
public so that the offline compiler can resolve the token
BREAKING CHANGES:
- short form bootstrap does no longer allow
to inject compiler internals (i.e. everything
from `@angular/compiler). Inject `Compiler` instead.
To provide custom providers for the compiler,
create a custom compiler via `browserCompiler({providers: [...]})`
and pass that into the `bootstrap` method.
2016-06-30 16:07:17 -04:00
import { ComponentFactoryResolver } from './linker/component_factory_resolver' ;
2016-08-02 09:54:08 -04:00
import { NgModuleFactory , NgModuleInjector , NgModuleRef } from './linker/ng_module_factory' ;
2016-06-08 19:38:52 -04:00
import { WtfScopeFn , wtfCreateScope , wtfLeave } from './profile/profile' ;
import { Testability , TestabilityRegistry } from './testability/testability' ;
2016-08-10 21:21:28 -04:00
import { Type } from './type' ;
2016-06-08 19:38:52 -04:00
import { NgZone , NgZoneError } from './zone/ng_zone' ;
2016-06-17 17:09:19 -04:00
var _devMode : boolean = true ;
var _runModeLocked : boolean = false ;
2015-09-02 18:19:26 -04:00
var _platform : PlatformRef ;
2016-06-17 17:09:19 -04:00
/ * *
* Disable Angular ' s development mode , which turns off assertions and other
* checks within the framework .
*
* One important assertion this disables verifies that a change detection pass
* does not result in additional changes to any bindings ( also known as
* unidirectional data flow ) .
2016-06-27 15:27:23 -04:00
*
* @experimental APIs related to application bootstrap are currently under review .
2016-06-17 17:09:19 -04:00
* /
export function enableProdMode ( ) : void {
if ( _runModeLocked ) {
// Cannot use BaseException as that ends up importing from facade/lang.
throw new BaseException ( 'Cannot enable prod mode after platform setup.' ) ;
}
_devMode = false ;
}
/ * *
2016-07-07 17:42:46 -04:00
* Returns whether Angular is in development mode . After called once ,
* the value is locked and won ' t change any more .
*
* By default , this is true , unless a user calls ` enableProdMode ` before calling this .
2016-06-27 15:27:23 -04:00
*
* @experimental APIs related to application bootstrap are currently under review .
2016-06-17 17:09:19 -04:00
* /
2016-07-07 17:42:46 -04:00
export function isDevMode ( ) : boolean {
2016-06-17 17:09:19 -04:00
_runModeLocked = true ;
2016-07-07 17:42:46 -04:00
return _devMode ;
2016-06-17 17:09:19 -04:00
}
2015-11-13 14:21:16 -05:00
/ * *
2016-04-14 17:52:35 -04:00
* Creates a platform .
* Platforms have to be eagerly created via this function .
2016-06-27 15:27:23 -04:00
*
* @experimental APIs related to application bootstrap are currently under review .
2015-11-13 14:21:16 -05:00
* /
2016-04-14 17:52:35 -04:00
export function createPlatform ( injector : Injector ) : PlatformRef {
2016-08-12 17:46:45 -04:00
if ( isPresent ( _platform ) && ! _platform . destroyed ) {
2016-04-14 17:52:35 -04:00
throw new BaseException (
2016-06-08 19:38:52 -04:00
'There can be only one platform. Destroy the previous one to create a new one.' ) ;
2016-04-14 17:52:35 -04:00
}
2016-07-29 09:47:40 -04:00
_platform = injector . get ( PlatformRef ) ;
const inits : Function [ ] = < Function [ ] > injector . get ( PLATFORM_INITIALIZER , null ) ;
if ( isPresent ( inits ) ) inits . forEach ( init = > init ( ) ) ;
2016-04-14 17:52:35 -04:00
return _platform ;
}
2016-07-18 06:50:31 -04:00
/ * *
* Factory for a platform .
*
* @experimental
* /
export type PlatformFactory = ( extraProviders? : any [ ] ) = > PlatformRef ;
refactor(core): clean up platform bootstrap and initTestEnvironment
- Introduces `CompilerFactory` which can be part of a `PlatformRef`.
- Introduces `WorkerAppModule`, `WorkerUiModule`, `ServerModule`
- Introduces `serverDynamicPlatform` for applications using runtime compilation
on the server.
- Changes browser bootstrap for runtime and offline compilation (see below for an example).
* introduces `bootstrapModule` and `bootstrapModuleFactory` in `@angular/core`
* introduces new `browserDynamicPlatform` in `@angular/platform-browser-dynamic
- Changes `initTestEnvironment` (which used to be `setBaseTestProviders`) to not take a compiler factory any more (see below for an example).
BREAKING CHANGE:
## Migration from `setBaseTestProviders` to `initTestEnvironment`:
- For the browser platform:
BEFORE:
```
import {setBaseTestProviders} from ‘@angular/core/testing’;
import {TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS} from ‘@angular/platform-browser-dynamic/testing’;
setBaseTestProviders(TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS);
```
AFTER:
```
import {initTestEnvironment} from ‘@angular/core/testing’;
import {browserDynamicTestPlatform,
BrowserDynamicTestModule} from ‘@angular/platform-browser-dynamic/testing’;
initTestEnvironment(
BrowserDynamicTestModule,
browserDynamicTestPlatform());
```
- For the server platform:
BEFORE:
```
import {setBaseTestProviders} from ‘@angular/core/testing’;
import {TEST_SERVER_PLATFORM_PROVIDERS,
TEST_SERVER_APPLICATION_PROVIDERS} from ‘@angular/platform-server/testing/server’;
setBaseTestProviders(TEST_SERVER_PLATFORM_PROVIDERS,
TEST_SERVER_APPLICATION_PROVIDERS);
```
AFTER:
```
import {initTestEnvironment} from ‘@angular/core/testing’;
import {serverTestPlatform,
ServerTestModule} from ‘@angular/platform-browser-dynamic/testing’;
initTestEnvironment(
ServerTestModule,
serverTestPlatform());
```
## Bootstrap changes
```
@AppModule({
modules: [BrowserModule],
precompile: [MainComponent],
providers: […], // additional providers
directives: […], // additional platform directives
pipes: […] // additional platform pipes
})
class MyModule {
constructor(appRef: ApplicationRef) {
appRef.bootstrap(MainComponent);
}
}
// offline compile
import {browserPlatform} from ‘@angular/platform-browser’;
import {bootstrapModuleFactory} from ‘@angular/core’;
bootstrapModuleFactory(MyModuleNgFactory, browserPlatform());
// runtime compile long form
import {browserDynamicPlatform} from ‘@angular/platform-browser-dynamic’;
import {bootstrapModule} from ‘@angular/core’;
bootstrapModule(MyModule, browserDynamicPlatform());
```
Closes #9922
Part of #9726
2016-07-08 13:47:17 -04:00
/ * *
2016-08-08 20:18:50 -04:00
* Creates a factory for a platform
refactor(core): clean up platform bootstrap and initTestEnvironment
- Introduces `CompilerFactory` which can be part of a `PlatformRef`.
- Introduces `WorkerAppModule`, `WorkerUiModule`, `ServerModule`
- Introduces `serverDynamicPlatform` for applications using runtime compilation
on the server.
- Changes browser bootstrap for runtime and offline compilation (see below for an example).
* introduces `bootstrapModule` and `bootstrapModuleFactory` in `@angular/core`
* introduces new `browserDynamicPlatform` in `@angular/platform-browser-dynamic
- Changes `initTestEnvironment` (which used to be `setBaseTestProviders`) to not take a compiler factory any more (see below for an example).
BREAKING CHANGE:
## Migration from `setBaseTestProviders` to `initTestEnvironment`:
- For the browser platform:
BEFORE:
```
import {setBaseTestProviders} from ‘@angular/core/testing’;
import {TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS} from ‘@angular/platform-browser-dynamic/testing’;
setBaseTestProviders(TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS);
```
AFTER:
```
import {initTestEnvironment} from ‘@angular/core/testing’;
import {browserDynamicTestPlatform,
BrowserDynamicTestModule} from ‘@angular/platform-browser-dynamic/testing’;
initTestEnvironment(
BrowserDynamicTestModule,
browserDynamicTestPlatform());
```
- For the server platform:
BEFORE:
```
import {setBaseTestProviders} from ‘@angular/core/testing’;
import {TEST_SERVER_PLATFORM_PROVIDERS,
TEST_SERVER_APPLICATION_PROVIDERS} from ‘@angular/platform-server/testing/server’;
setBaseTestProviders(TEST_SERVER_PLATFORM_PROVIDERS,
TEST_SERVER_APPLICATION_PROVIDERS);
```
AFTER:
```
import {initTestEnvironment} from ‘@angular/core/testing’;
import {serverTestPlatform,
ServerTestModule} from ‘@angular/platform-browser-dynamic/testing’;
initTestEnvironment(
ServerTestModule,
serverTestPlatform());
```
## Bootstrap changes
```
@AppModule({
modules: [BrowserModule],
precompile: [MainComponent],
providers: […], // additional providers
directives: […], // additional platform directives
pipes: […] // additional platform pipes
})
class MyModule {
constructor(appRef: ApplicationRef) {
appRef.bootstrap(MainComponent);
}
}
// offline compile
import {browserPlatform} from ‘@angular/platform-browser’;
import {bootstrapModuleFactory} from ‘@angular/core’;
bootstrapModuleFactory(MyModuleNgFactory, browserPlatform());
// runtime compile long form
import {browserDynamicPlatform} from ‘@angular/platform-browser-dynamic’;
import {bootstrapModule} from ‘@angular/core’;
bootstrapModule(MyModule, browserDynamicPlatform());
```
Closes #9922
Part of #9726
2016-07-08 13:47:17 -04:00
*
* @experimental APIs related to application bootstrap are currently under review .
* /
2016-07-18 06:50:31 -04:00
export function createPlatformFactory (
parentPlaformFactory : PlatformFactory , name : string , providers : any [ ] = [ ] ) : PlatformFactory {
refactor(core): clean up platform bootstrap and initTestEnvironment
- Introduces `CompilerFactory` which can be part of a `PlatformRef`.
- Introduces `WorkerAppModule`, `WorkerUiModule`, `ServerModule`
- Introduces `serverDynamicPlatform` for applications using runtime compilation
on the server.
- Changes browser bootstrap for runtime and offline compilation (see below for an example).
* introduces `bootstrapModule` and `bootstrapModuleFactory` in `@angular/core`
* introduces new `browserDynamicPlatform` in `@angular/platform-browser-dynamic
- Changes `initTestEnvironment` (which used to be `setBaseTestProviders`) to not take a compiler factory any more (see below for an example).
BREAKING CHANGE:
## Migration from `setBaseTestProviders` to `initTestEnvironment`:
- For the browser platform:
BEFORE:
```
import {setBaseTestProviders} from ‘@angular/core/testing’;
import {TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS} from ‘@angular/platform-browser-dynamic/testing’;
setBaseTestProviders(TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS);
```
AFTER:
```
import {initTestEnvironment} from ‘@angular/core/testing’;
import {browserDynamicTestPlatform,
BrowserDynamicTestModule} from ‘@angular/platform-browser-dynamic/testing’;
initTestEnvironment(
BrowserDynamicTestModule,
browserDynamicTestPlatform());
```
- For the server platform:
BEFORE:
```
import {setBaseTestProviders} from ‘@angular/core/testing’;
import {TEST_SERVER_PLATFORM_PROVIDERS,
TEST_SERVER_APPLICATION_PROVIDERS} from ‘@angular/platform-server/testing/server’;
setBaseTestProviders(TEST_SERVER_PLATFORM_PROVIDERS,
TEST_SERVER_APPLICATION_PROVIDERS);
```
AFTER:
```
import {initTestEnvironment} from ‘@angular/core/testing’;
import {serverTestPlatform,
ServerTestModule} from ‘@angular/platform-browser-dynamic/testing’;
initTestEnvironment(
ServerTestModule,
serverTestPlatform());
```
## Bootstrap changes
```
@AppModule({
modules: [BrowserModule],
precompile: [MainComponent],
providers: […], // additional providers
directives: […], // additional platform directives
pipes: […] // additional platform pipes
})
class MyModule {
constructor(appRef: ApplicationRef) {
appRef.bootstrap(MainComponent);
}
}
// offline compile
import {browserPlatform} from ‘@angular/platform-browser’;
import {bootstrapModuleFactory} from ‘@angular/core’;
bootstrapModuleFactory(MyModuleNgFactory, browserPlatform());
// runtime compile long form
import {browserDynamicPlatform} from ‘@angular/platform-browser-dynamic’;
import {bootstrapModule} from ‘@angular/core’;
bootstrapModule(MyModule, browserDynamicPlatform());
```
Closes #9922
Part of #9726
2016-07-08 13:47:17 -04:00
const marker = new OpaqueToken ( ` Platform: ${ name } ` ) ;
2016-07-18 06:50:31 -04:00
return ( extraProviders : any [ ] = [ ] ) = > {
refactor(core): clean up platform bootstrap and initTestEnvironment
- Introduces `CompilerFactory` which can be part of a `PlatformRef`.
- Introduces `WorkerAppModule`, `WorkerUiModule`, `ServerModule`
- Introduces `serverDynamicPlatform` for applications using runtime compilation
on the server.
- Changes browser bootstrap for runtime and offline compilation (see below for an example).
* introduces `bootstrapModule` and `bootstrapModuleFactory` in `@angular/core`
* introduces new `browserDynamicPlatform` in `@angular/platform-browser-dynamic
- Changes `initTestEnvironment` (which used to be `setBaseTestProviders`) to not take a compiler factory any more (see below for an example).
BREAKING CHANGE:
## Migration from `setBaseTestProviders` to `initTestEnvironment`:
- For the browser platform:
BEFORE:
```
import {setBaseTestProviders} from ‘@angular/core/testing’;
import {TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS} from ‘@angular/platform-browser-dynamic/testing’;
setBaseTestProviders(TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS);
```
AFTER:
```
import {initTestEnvironment} from ‘@angular/core/testing’;
import {browserDynamicTestPlatform,
BrowserDynamicTestModule} from ‘@angular/platform-browser-dynamic/testing’;
initTestEnvironment(
BrowserDynamicTestModule,
browserDynamicTestPlatform());
```
- For the server platform:
BEFORE:
```
import {setBaseTestProviders} from ‘@angular/core/testing’;
import {TEST_SERVER_PLATFORM_PROVIDERS,
TEST_SERVER_APPLICATION_PROVIDERS} from ‘@angular/platform-server/testing/server’;
setBaseTestProviders(TEST_SERVER_PLATFORM_PROVIDERS,
TEST_SERVER_APPLICATION_PROVIDERS);
```
AFTER:
```
import {initTestEnvironment} from ‘@angular/core/testing’;
import {serverTestPlatform,
ServerTestModule} from ‘@angular/platform-browser-dynamic/testing’;
initTestEnvironment(
ServerTestModule,
serverTestPlatform());
```
## Bootstrap changes
```
@AppModule({
modules: [BrowserModule],
precompile: [MainComponent],
providers: […], // additional providers
directives: […], // additional platform directives
pipes: […] // additional platform pipes
})
class MyModule {
constructor(appRef: ApplicationRef) {
appRef.bootstrap(MainComponent);
}
}
// offline compile
import {browserPlatform} from ‘@angular/platform-browser’;
import {bootstrapModuleFactory} from ‘@angular/core’;
bootstrapModuleFactory(MyModuleNgFactory, browserPlatform());
// runtime compile long form
import {browserDynamicPlatform} from ‘@angular/platform-browser-dynamic’;
import {bootstrapModule} from ‘@angular/core’;
bootstrapModule(MyModule, browserDynamicPlatform());
```
Closes #9922
Part of #9726
2016-07-08 13:47:17 -04:00
if ( ! getPlatform ( ) ) {
2016-07-18 06:50:31 -04:00
if ( parentPlaformFactory ) {
parentPlaformFactory (
providers . concat ( extraProviders ) . concat ( { provide : marker , useValue : true } ) ) ;
} else {
createPlatform ( ReflectiveInjector . resolveAndCreate (
providers . concat ( extraProviders ) . concat ( { provide : marker , useValue : true } ) ) ) ;
}
refactor(core): clean up platform bootstrap and initTestEnvironment
- Introduces `CompilerFactory` which can be part of a `PlatformRef`.
- Introduces `WorkerAppModule`, `WorkerUiModule`, `ServerModule`
- Introduces `serverDynamicPlatform` for applications using runtime compilation
on the server.
- Changes browser bootstrap for runtime and offline compilation (see below for an example).
* introduces `bootstrapModule` and `bootstrapModuleFactory` in `@angular/core`
* introduces new `browserDynamicPlatform` in `@angular/platform-browser-dynamic
- Changes `initTestEnvironment` (which used to be `setBaseTestProviders`) to not take a compiler factory any more (see below for an example).
BREAKING CHANGE:
## Migration from `setBaseTestProviders` to `initTestEnvironment`:
- For the browser platform:
BEFORE:
```
import {setBaseTestProviders} from ‘@angular/core/testing’;
import {TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS} from ‘@angular/platform-browser-dynamic/testing’;
setBaseTestProviders(TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS);
```
AFTER:
```
import {initTestEnvironment} from ‘@angular/core/testing’;
import {browserDynamicTestPlatform,
BrowserDynamicTestModule} from ‘@angular/platform-browser-dynamic/testing’;
initTestEnvironment(
BrowserDynamicTestModule,
browserDynamicTestPlatform());
```
- For the server platform:
BEFORE:
```
import {setBaseTestProviders} from ‘@angular/core/testing’;
import {TEST_SERVER_PLATFORM_PROVIDERS,
TEST_SERVER_APPLICATION_PROVIDERS} from ‘@angular/platform-server/testing/server’;
setBaseTestProviders(TEST_SERVER_PLATFORM_PROVIDERS,
TEST_SERVER_APPLICATION_PROVIDERS);
```
AFTER:
```
import {initTestEnvironment} from ‘@angular/core/testing’;
import {serverTestPlatform,
ServerTestModule} from ‘@angular/platform-browser-dynamic/testing’;
initTestEnvironment(
ServerTestModule,
serverTestPlatform());
```
## Bootstrap changes
```
@AppModule({
modules: [BrowserModule],
precompile: [MainComponent],
providers: […], // additional providers
directives: […], // additional platform directives
pipes: […] // additional platform pipes
})
class MyModule {
constructor(appRef: ApplicationRef) {
appRef.bootstrap(MainComponent);
}
}
// offline compile
import {browserPlatform} from ‘@angular/platform-browser’;
import {bootstrapModuleFactory} from ‘@angular/core’;
bootstrapModuleFactory(MyModuleNgFactory, browserPlatform());
// runtime compile long form
import {browserDynamicPlatform} from ‘@angular/platform-browser-dynamic’;
import {bootstrapModule} from ‘@angular/core’;
bootstrapModule(MyModule, browserDynamicPlatform());
```
Closes #9922
Part of #9726
2016-07-08 13:47:17 -04:00
}
return assertPlatform ( marker ) ;
} ;
}
2016-04-14 17:52:35 -04:00
/ * *
* Checks that there currently is a platform
* which contains the given token as a provider .
2016-06-27 15:27:23 -04:00
*
* @experimental APIs related to application bootstrap are currently under review .
2016-04-14 17:52:35 -04:00
* /
export function assertPlatform ( requiredToken : any ) : PlatformRef {
var platform = getPlatform ( ) ;
if ( isBlank ( platform ) ) {
2016-05-20 14:18:08 -04:00
throw new BaseException ( 'No platform exists!' ) ;
2016-04-14 17:52:35 -04:00
}
if ( isPresent ( platform ) && isBlank ( platform . injector . get ( requiredToken , null ) ) ) {
throw new BaseException (
'A platform with a different configuration has been created. Please destroy it first.' ) ;
}
return platform ;
2015-11-13 14:21:16 -05:00
}
2015-11-12 16:40:29 -05:00
2016-08-02 05:32:27 -04:00
/ * *
* Destroy the existing platform .
*
* @experimental APIs related to application bootstrap are currently under review .
* /
export function destroyPlatform ( ) : void {
if ( isPresent ( _platform ) && ! _platform . destroyed ) {
_platform . destroy ( ) ;
2015-11-18 12:18:37 -05:00
}
}
2016-04-14 17:52:35 -04:00
/ * *
* Returns the current platform .
2016-06-27 15:27:23 -04:00
*
* @experimental APIs related to application bootstrap are currently under review .
2016-04-14 17:52:35 -04:00
* /
export function getPlatform ( ) : PlatformRef {
2016-08-12 17:46:45 -04:00
return isPresent ( _platform ) && ! _platform . destroyed ? _platform : null ;
2015-09-02 18:19:26 -04:00
}
/ * *
2015-09-15 18:51:15 -04:00
* The Angular platform is the entry point for Angular on a web page . Each page
* has exactly one platform , and services ( such as reflection ) which are common
* to every Angular application running on the page are bound in its scope .
2015-08-20 20:18:27 -04:00
*
2015-09-15 18:51:15 -04:00
* A page ' s platform is initialized implicitly when { @link bootstrap } ( ) is called , or
2016-04-14 17:52:35 -04:00
* explicitly by calling { @link createPlatform } ( ) .
2016-06-27 15:27:23 -04:00
*
* @experimental APIs related to application bootstrap are currently under review .
2015-08-20 20:18:27 -04:00
* /
2015-10-06 09:53:39 -04:00
export abstract class PlatformRef {
2015-10-26 13:50:25 -04:00
/ * *
2016-07-26 08:21:19 -04:00
* Creates an instance of an ` @NgModule ` for the given platform
* for offline compilation .
*
* # # Simple Example
*
* ` ` ` typescript
* my_module . ts :
*
* @NgModule ( {
* imports : [ BrowserModule ]
* } )
* class MyModule { }
*
* main . ts :
* import { MyModuleNgFactory } from './my_module.ngfactory' ;
2016-08-15 16:44:01 -04:00
* import { platformBrowser } from '@angular/platform-browser' ;
2016-07-26 08:21:19 -04:00
*
2016-08-15 16:44:01 -04:00
* let module Ref = platformBrowser ( ) . bootstrapModuleFactory ( MyModuleNgFactory ) ;
2016-07-26 08:21:19 -04:00
* ` ` `
*
* @experimental APIs related to application bootstrap are currently under review .
* /
2016-07-29 09:47:40 -04:00
bootstrapModuleFactory < M > ( module Factory : NgModuleFactory < M > ) : Promise < NgModuleRef < M > > {
2016-07-26 08:21:19 -04:00
throw unimplemented ( ) ;
}
/ * *
* Creates an instance of an ` @NgModule ` for a given platform using the given runtime compiler .
*
* # # Simple Example
*
* ` ` ` typescript
* @NgModule ( {
* imports : [ BrowserModule ]
* } )
* class MyModule { }
*
2016-08-15 16:44:01 -04:00
* let module Ref = platformBrowser ( ) . bootstrapModule ( MyModule ) ;
2016-07-26 08:21:19 -04:00
* ` ` `
* @stable
2015-10-26 13:50:25 -04:00
* /
2016-08-10 21:21:28 -04:00
bootstrapModule < M > ( module Type : Type < M > , compilerOptions : CompilerOptions | CompilerOptions [ ] = [ ] ) :
Promise < NgModuleRef < M > > {
2016-07-26 08:21:19 -04:00
throw unimplemented ( ) ;
}
2016-08-02 05:32:27 -04:00
/ * *
* Register a listener to be called when the platform is disposed .
* /
abstract onDestroy ( callback : ( ) = > void ) : void ;
2015-09-02 18:19:26 -04:00
/ * *
2015-09-15 18:51:15 -04:00
* Retrieve the platform { @link Injector } , which is the parent injector for
2015-10-11 01:11:13 -04:00
* every Angular application on the page and provides singleton providers .
2015-09-02 18:19:26 -04:00
* /
2016-02-19 14:49:31 -05:00
get injector ( ) : Injector { throw unimplemented ( ) ; } ;
2015-08-20 20:18:27 -04:00
2016-08-02 05:32:27 -04:00
/ * *
* Destroy the Angular platform and all Angular applications on the page .
* /
abstract destroy ( ) : void ;
get destroyed ( ) : boolean { throw unimplemented ( ) ; }
2015-10-06 09:53:39 -04:00
}
2016-07-29 09:47:40 -04:00
function _callAndReportToExceptionHandler (
exceptionHandler : ExceptionHandler , callback : ( ) = > any ) : any {
try {
const result = callback ( ) ;
if ( isPromise ( result ) ) {
return result . catch ( ( e : any ) = > {
exceptionHandler . call ( e ) ;
// rethrow as the exception handler might not do it
throw e ;
} ) ;
} else {
return result ;
}
} catch ( e ) {
exceptionHandler . call ( e ) ;
// rethrow as the exception handler might not do it
throw e ;
}
}
2016-04-14 17:52:35 -04:00
@Injectable ( )
2015-10-06 09:53:39 -04:00
export class PlatformRef_ extends PlatformRef {
2016-08-02 05:32:27 -04:00
private _modules : NgModuleRef < any > [ ] = [ ] ;
private _destroyListeners : Function [ ] = [ ] ;
2015-10-06 09:53:39 -04:00
2016-08-02 05:32:27 -04:00
private _destroyed : boolean = false ;
2015-10-06 09:53:39 -04:00
2016-07-29 09:47:40 -04:00
constructor ( private _injector : Injector ) { super ( ) ; }
2015-10-06 09:53:39 -04:00
2016-08-02 05:32:27 -04:00
/ * *
* @deprecated
* /
registerDisposeListener ( dispose : ( ) = > void ) : void { this . onDestroy ( dispose ) ; }
onDestroy ( callback : ( ) = > void ) : void { this . _destroyListeners . push ( callback ) ; }
2015-09-02 18:19:26 -04:00
2016-04-14 17:52:35 -04:00
get injector ( ) : Injector { return this . _injector ; }
2015-09-02 18:19:26 -04:00
2016-08-02 05:32:27 -04:00
/ * *
* @deprecated
* /
get disposed() { return this . destroyed ; }
get destroyed() { return this . _destroyed ; }
2016-04-14 17:52:35 -04:00
2016-08-02 05:32:27 -04:00
destroy() {
if ( this . _destroyed ) {
2016-08-02 10:54:14 -04:00
throw new BaseException ( 'The platform has already been destroyed!' ) ;
2016-08-02 05:32:27 -04:00
}
ListWrapper . clone ( this . _modules ) . forEach ( ( app ) = > app . destroy ( ) ) ;
this . _destroyListeners . forEach ( ( dispose ) = > dispose ( ) ) ;
this . _destroyed = true ;
2015-09-02 18:19:26 -04:00
}
2016-08-02 05:32:27 -04:00
/ * *
* @deprecated
* /
dispose ( ) : void { this . destroy ( ) ; }
2016-07-26 08:21:19 -04:00
2016-07-29 09:47:40 -04:00
bootstrapModuleFactory < M > ( module Factory : NgModuleFactory < M > ) : Promise < NgModuleRef < M > > {
2016-08-05 16:32:04 -04:00
return this . _bootstrapModuleFactoryWithZone ( module Factory , null ) ;
}
private _bootstrapModuleFactoryWithZone < M > ( module Factory : NgModuleFactory < M > , ngZone : NgZone ) :
Promise < NgModuleRef < M > > {
2016-07-26 08:21:19 -04:00
// 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 NgModuleFactory.
2016-08-05 16:32:04 -04:00
if ( ! ngZone ) ngZone = new NgZone ( { enableLongStackTrace : isDevMode ( ) } ) ;
2016-07-29 09:47:40 -04:00
// Attention: Don't use ApplicationRef.run here,
// as we want to be sure that all possible constructor calls are inside `ngZone.run`!
return ngZone . run ( ( ) = > {
const ngZoneInjector =
ReflectiveInjector . resolveAndCreate ( [ { provide : NgZone , useValue : ngZone } ] , this . injector ) ;
2016-08-02 09:54:08 -04:00
const module Ref = < NgModuleInjector < M > > module Factory.create ( ngZoneInjector ) ;
2016-07-29 17:45:05 -04:00
const exceptionHandler : ExceptionHandler = module Ref.injector.get ( ExceptionHandler , null ) ;
if ( ! exceptionHandler ) {
throw new Error ( 'No ExceptionHandler. Is platform module (BrowserModule) included?' ) ;
}
2016-08-02 05:32:27 -04:00
module Ref.onDestroy ( ( ) = > ListWrapper . remove ( this . _modules , module Ref ) ) ;
2016-08-02 18:53:34 -04:00
ngZone . onError . subscribe ( {
next : ( error : NgZoneError ) = > { exceptionHandler . call ( error . error , error . stackTrace ) ; }
2016-07-29 09:47:40 -04:00
} ) ;
return _callAndReportToExceptionHandler ( exceptionHandler , ( ) = > {
2016-08-02 10:54:14 -04:00
const initStatus : ApplicationInitStatus = module Ref.injector.get ( ApplicationInitStatus ) ;
2016-08-02 10:38:14 -04:00
return initStatus . donePromise . then ( ( ) = > {
2016-08-02 09:54:08 -04:00
this . _moduleDoBootstrap ( module Ref ) ;
2016-07-29 09:47:40 -04:00
return module Ref ;
} ) ;
} ) ;
} ) ;
2016-07-26 08:21:19 -04:00
}
2016-08-10 21:21:28 -04:00
bootstrapModule < M > ( module Type : Type < M > , compilerOptions : CompilerOptions | CompilerOptions [ ] = [ ] ) :
Promise < NgModuleRef < M > > {
2016-08-05 16:32:04 -04:00
return this . _bootstrapModuleWithZone ( module Type , compilerOptions , null ) ;
}
private _bootstrapModuleWithZone < M > (
2016-08-10 21:21:28 -04:00
module Type : Type < M > , compilerOptions : CompilerOptions | CompilerOptions [ ] = [ ] ,
2016-08-05 16:32:04 -04:00
ngZone : NgZone ) : Promise < NgModuleRef < M > > {
2016-07-26 08:21:19 -04:00
const compilerFactory : CompilerFactory = this . injector . get ( CompilerFactory ) ;
const compiler = compilerFactory . createCompiler (
compilerOptions instanceof Array ? compilerOptions : [ compilerOptions ] ) ;
return compiler . compileModuleAsync ( module Type )
2016-08-05 16:32:04 -04:00
. then ( ( module Factory ) = > this . _bootstrapModuleFactoryWithZone ( module Factory , ngZone ) ) ;
2016-07-26 08:21:19 -04:00
}
2016-08-02 09:54:08 -04:00
private _moduleDoBootstrap ( module Ref : NgModuleInjector < any > ) {
const appRef = module Ref.injector.get ( ApplicationRef ) ;
if ( module Ref.bootstrapFactories.length > 0 ) {
module Ref.bootstrapFactories.forEach ( ( compFactory ) = > appRef . bootstrap ( compFactory ) ) ;
} else if ( module Ref.instance.ngDoBootstrap ) {
module Ref.instance.ngDoBootstrap ( appRef ) ;
} else {
throw new BaseException (
` The module ${ stringify ( module Ref.instance.constructor ) } was bootstrapped, but it does not declare "@NgModule.bootstrap" components nor a "ngDoBootstrap" method. ` +
` Please define one of these. ` ) ;
}
}
2015-09-02 18:19:26 -04:00
}
/ * *
2015-09-15 18:51:15 -04:00
* A reference to an Angular application running on a page .
2015-09-02 18:19:26 -04:00
*
2015-09-15 18:51:15 -04:00
* For more about Angular applications , see the documentation for { @link bootstrap } .
2016-06-27 15:27:23 -04:00
*
* @experimental APIs related to application bootstrap are currently under review .
2015-09-02 18:19:26 -04:00
* /
2015-10-06 09:53:39 -04:00
export abstract class ApplicationRef {
2015-08-20 20:18:27 -04:00
/ * *
2015-09-15 18:51:15 -04:00
* Bootstrap a new component at the root level of the application .
*
2015-11-17 12:41:31 -05:00
* # # # Bootstrap process
2015-09-15 18:51:15 -04:00
*
* When bootstrapping a new root component into an application , Angular mounts the
* specified application component onto DOM elements identified by the [ componentType ] ' s
* selector and kicks off automatic change detection to finish initializing the component .
*
2015-10-19 10:37:32 -04:00
* # # # Example
2015-11-30 11:28:54 -05:00
* { @example core / ts / platform / platform . ts region = 'longform' }
2015-09-02 18:19:26 -04:00
* /
2016-08-10 21:21:28 -04:00
abstract bootstrap < C > ( componentFactory : ComponentFactory < C > | Type < C > ) : ComponentRef < C > ;
2015-10-06 09:53:39 -04:00
2015-10-28 13:34:13 -04:00
/ * *
* Invoke this method to explicitly process change detection and its side - effects .
*
* In development mode , ` tick() ` also performs a second change detection cycle to ensure that no
* further changes are detected . If additional changes are picked up during this second cycle ,
* bindings in the app have side - effects that cannot be resolved in a single change detection
* pass .
* In this case , Angular throws an error , since an Angular application can only have one change
* detection pass during which all change detection must complete .
* /
abstract tick ( ) : void ;
2015-10-09 19:22:07 -04:00
/ * *
* Get a list of component types registered to this application .
2016-08-02 10:49:33 -04:00
* This list is populated even before the component is created .
2015-10-09 19:22:07 -04:00
* /
2016-08-10 21:21:28 -04:00
get componentTypes ( ) : Type < any > [ ] { return < Type < any > [ ] > unimplemented ( ) ; } ;
2016-08-02 10:49:33 -04:00
2016-08-02 09:54:08 -04:00
/ * *
* Get a list of components registered to this application .
* /
get components ( ) : ComponentRef < any > [ ] { return < ComponentRef < any > [ ] > unimplemented ( ) ; } ;
2015-10-06 09:53:39 -04:00
}
2016-04-14 17:52:35 -04:00
@Injectable ( )
2015-10-06 09:53:39 -04:00
export class ApplicationRef_ extends ApplicationRef {
2015-10-28 13:34:13 -04:00
/** @internal */
static _tickScope : WtfScopeFn = wtfCreateScope ( 'ApplicationRef#tick()' ) ;
2015-10-06 09:53:39 -04:00
private _bootstrapListeners : Function [ ] = [ ] ;
2016-04-30 13:52:04 -04:00
private _rootComponents : ComponentRef < any > [ ] = [ ] ;
2016-08-10 21:21:28 -04:00
private _rootComponentTypes : Type < any > [ ] = [ ] ;
2015-10-28 13:34:13 -04:00
private _changeDetectorRefs : ChangeDetectorRef [ ] = [ ] ;
private _runningTick : boolean = false ;
private _enforceNoNewChanges : boolean = false ;
2015-10-06 09:53:39 -04:00
feat(browser): use AppModules for bootstrap in the browser
This introduces the `BrowserModule` to be used for long form
bootstrap and offline compile bootstrap:
```
@AppModule({
modules: [BrowserModule],
precompile: [MainComponent],
providers: […], // additional providers
directives: […], // additional platform directives
pipes: […] // additional platform pipes
})
class MyModule {
constructor(appRef: ApplicationRef) {
appRef.bootstrap(MainComponent);
}
}
// offline compile
import {bootstrapModuleFactory} from ‘@angular/platform-browser’;
bootstrapModuleFactory(MyModuleNgFactory);
// runtime compile long form
import {bootstrapModule} from ‘@angular/platform-browser-dynamic’;
bootstrapModule(MyModule);
```
The short form, `bootstrap(...)`, can now creates a module on the fly,
given `directives`, `pipes, `providers`, `precompile` and `modules`
properties.
Related changes:
- make `SanitizationService`, `SecurityContext` public in `@angular/core` so that the offline compiler can resolve the token
- move `AnimationDriver` to `platform-browser` and make it
public so that the offline compiler can resolve the token
BREAKING CHANGES:
- short form bootstrap does no longer allow
to inject compiler internals (i.e. everything
from `@angular/compiler). Inject `Compiler` instead.
To provide custom providers for the compiler,
create a custom compiler via `browserCompiler({providers: [...]})`
and pass that into the `bootstrap` method.
2016-06-30 16:07:17 -04:00
constructor (
2016-08-02 05:32:27 -04:00
private _zone : NgZone , private _console : Console , private _injector : Injector ,
private _exceptionHandler : ExceptionHandler ,
feat(browser): use AppModules for bootstrap in the browser
This introduces the `BrowserModule` to be used for long form
bootstrap and offline compile bootstrap:
```
@AppModule({
modules: [BrowserModule],
precompile: [MainComponent],
providers: […], // additional providers
directives: […], // additional platform directives
pipes: […] // additional platform pipes
})
class MyModule {
constructor(appRef: ApplicationRef) {
appRef.bootstrap(MainComponent);
}
}
// offline compile
import {bootstrapModuleFactory} from ‘@angular/platform-browser’;
bootstrapModuleFactory(MyModuleNgFactory);
// runtime compile long form
import {bootstrapModule} from ‘@angular/platform-browser-dynamic’;
bootstrapModule(MyModule);
```
The short form, `bootstrap(...)`, can now creates a module on the fly,
given `directives`, `pipes, `providers`, `precompile` and `modules`
properties.
Related changes:
- make `SanitizationService`, `SecurityContext` public in `@angular/core` so that the offline compiler can resolve the token
- move `AnimationDriver` to `platform-browser` and make it
public so that the offline compiler can resolve the token
BREAKING CHANGES:
- short form bootstrap does no longer allow
to inject compiler internals (i.e. everything
from `@angular/compiler). Inject `Compiler` instead.
To provide custom providers for the compiler,
create a custom compiler via `browserCompiler({providers: [...]})`
and pass that into the `bootstrap` method.
2016-06-30 16:07:17 -04:00
private _componentFactoryResolver : ComponentFactoryResolver ,
2016-08-02 10:54:14 -04:00
private _initStatus : ApplicationInitStatus ,
feat(browser): use AppModules for bootstrap in the browser
This introduces the `BrowserModule` to be used for long form
bootstrap and offline compile bootstrap:
```
@AppModule({
modules: [BrowserModule],
precompile: [MainComponent],
providers: […], // additional providers
directives: […], // additional platform directives
pipes: […] // additional platform pipes
})
class MyModule {
constructor(appRef: ApplicationRef) {
appRef.bootstrap(MainComponent);
}
}
// offline compile
import {bootstrapModuleFactory} from ‘@angular/platform-browser’;
bootstrapModuleFactory(MyModuleNgFactory);
// runtime compile long form
import {bootstrapModule} from ‘@angular/platform-browser-dynamic’;
bootstrapModule(MyModule);
```
The short form, `bootstrap(...)`, can now creates a module on the fly,
given `directives`, `pipes, `providers`, `precompile` and `modules`
properties.
Related changes:
- make `SanitizationService`, `SecurityContext` public in `@angular/core` so that the offline compiler can resolve the token
- move `AnimationDriver` to `platform-browser` and make it
public so that the offline compiler can resolve the token
BREAKING CHANGES:
- short form bootstrap does no longer allow
to inject compiler internals (i.e. everything
from `@angular/compiler). Inject `Compiler` instead.
To provide custom providers for the compiler,
create a custom compiler via `browserCompiler({providers: [...]})`
and pass that into the `bootstrap` method.
2016-06-30 16:07:17 -04:00
@Optional ( ) private _testabilityRegistry : TestabilityRegistry ,
2016-07-29 09:47:40 -04:00
@Optional ( ) private _testability : Testability ) {
2015-10-06 09:53:39 -04:00
super ( ) ;
2016-06-17 17:09:19 -04:00
this . _enforceNoNewChanges = isDevMode ( ) ;
2016-08-02 18:53:34 -04:00
this . _zone . onMicrotaskEmpty . subscribe (
{ next : ( ) = > { this . _zone . run ( ( ) = > { this . tick ( ) ; } ) ; } } ) ;
2015-10-06 09:53:39 -04:00
}
2015-10-28 13:34:13 -04:00
registerChangeDetector ( changeDetector : ChangeDetectorRef ) : void {
this . _changeDetectorRefs . push ( changeDetector ) ;
}
2015-11-10 13:40:33 -05:00
unregisterChangeDetector ( changeDetector : ChangeDetectorRef ) : void {
ListWrapper . remove ( this . _changeDetectorRefs , changeDetector ) ;
}
2016-08-10 21:21:28 -04:00
bootstrap < C > ( componentOrFactory : ComponentFactory < C > | Type < C > ) : ComponentRef < C > {
2016-08-02 10:38:14 -04:00
if ( ! this . _initStatus . done ) {
throw new BaseException (
'Cannot bootstrap as there are still asynchronous initializers running. Bootstrap components in the `ngDoBootstrap` method of the root module.' ) ;
}
2016-08-02 10:48:15 -04:00
let componentFactory : ComponentFactory < C > ;
if ( componentOrFactory instanceof ComponentFactory ) {
componentFactory = componentOrFactory ;
} else {
componentFactory = this . _componentFactoryResolver . resolveComponentFactory ( componentOrFactory ) ;
}
this . _rootComponentTypes . push ( componentFactory . componentType ) ;
var compRef = componentFactory . create ( this . _injector , [ ] , componentFactory . selector ) ;
compRef . onDestroy ( ( ) = > { this . _unloadComponent ( compRef ) ; } ) ;
var testability = compRef . injector . get ( Testability , null ) ;
if ( isPresent ( testability ) ) {
compRef . injector . get ( TestabilityRegistry )
. registerApplication ( compRef . location . nativeElement , testability ) ;
}
2016-04-14 17:52:35 -04:00
2016-08-02 10:48:15 -04:00
this . _loadComponent ( compRef ) ;
if ( isDevMode ( ) ) {
this . _console . log (
` Angular 2 is running in the development mode. Call enableProdMode() to enable the production mode. ` ) ;
}
return compRef ;
2015-09-02 18:19:26 -04:00
}
2015-11-10 13:40:33 -05:00
/** @internal */
2016-04-30 13:52:04 -04:00
_loadComponent ( componentRef : ComponentRef < any > ) : void {
2016-04-13 20:05:17 -04:00
this . _changeDetectorRefs . push ( componentRef . changeDetectorRef ) ;
2015-11-10 13:40:33 -05:00
this . tick ( ) ;
2016-02-11 20:01:17 -05:00
this . _rootComponents . push ( componentRef ) ;
2016-08-02 08:22:44 -04:00
// Get the listeners lazily to prevent DI cycles.
const listeners =
< ( ( compRef : ComponentRef < any > ) = > void ) [ ] > this . _injector . get ( APP_BOOTSTRAP_LISTENER , [ ] )
. concat ( this . _bootstrapListeners ) ;
listeners . forEach ( ( listener ) = > listener ( componentRef ) ) ;
2015-11-10 13:40:33 -05:00
}
/** @internal */
2016-04-30 13:52:04 -04:00
_unloadComponent ( componentRef : ComponentRef < any > ) : void {
2016-02-11 20:01:17 -05:00
if ( ! ListWrapper . contains ( this . _rootComponents , componentRef ) ) {
2015-11-10 13:40:33 -05:00
return ;
}
2016-04-13 20:05:17 -04:00
this . unregisterChangeDetector ( componentRef . changeDetectorRef ) ;
2016-02-11 20:01:17 -05:00
ListWrapper . remove ( this . _rootComponents , componentRef ) ;
2015-11-10 13:40:33 -05:00
}
2015-10-28 13:34:13 -04:00
tick ( ) : void {
if ( this . _runningTick ) {
2016-06-08 19:38:52 -04:00
throw new BaseException ( 'ApplicationRef.tick is called recursively' ) ;
2015-10-28 13:34:13 -04:00
}
var s = ApplicationRef_ . _tickScope ( ) ;
try {
this . _runningTick = true ;
this . _changeDetectorRefs . forEach ( ( detector ) = > detector . detectChanges ( ) ) ;
if ( this . _enforceNoNewChanges ) {
this . _changeDetectorRefs . forEach ( ( detector ) = > detector . checkNoChanges ( ) ) ;
}
} finally {
this . _runningTick = false ;
wtfLeave ( s ) ;
}
}
2016-08-02 05:32:27 -04:00
ngOnDestroy() {
2015-09-02 18:19:26 -04:00
// TODO(alxhub): Dispose of the NgZone.
2016-04-13 20:05:17 -04:00
ListWrapper . clone ( this . _rootComponents ) . forEach ( ( ref ) = > ref . destroy ( ) ) ;
2015-09-02 18:19:26 -04:00
}
2015-10-09 19:22:07 -04:00
2016-08-10 21:21:28 -04:00
get componentTypes ( ) : Type < any > [ ] { return this . _rootComponentTypes ; }
2016-08-02 09:54:08 -04:00
get components ( ) : ComponentRef < any > [ ] { return this . _rootComponents ; }
2015-08-20 20:18:27 -04:00
}