diff --git a/modules/angular2/angular2.dart b/modules/angular2/angular2.dart index f585b57f47..d3bb1ab16d 100644 --- a/modules/angular2/angular2.dart +++ b/modules/angular2/angular2.dart @@ -10,7 +10,7 @@ export 'package:angular2/common.dart'; export 'package:angular2/instrumentation.dart'; export 'package:angular2/src/core/angular_entrypoint.dart' show AngularEntrypoint; export 'package:angular2/src/core/application_tokens.dart' - hide APP_COMPONENT_REF_PROMISE, APP_ID_RANDOM_PROVIDER; + hide APP_ID_RANDOM_PROVIDER; export 'package:angular2/src/platform/dom/dom_tokens.dart'; export 'package:angular2/src/platform/dom/dom_adapter.dart'; export 'package:angular2/src/platform/dom/events/event_manager.dart'; diff --git a/modules/angular2/core.dart b/modules/angular2/core.dart index 6546bfafd9..fe0cc13dd1 100644 --- a/modules/angular2/core.dart +++ b/modules/angular2/core.dart @@ -6,9 +6,10 @@ export './src/core/util.dart'; export 'package:angular2/src/facade/lang.dart' show enableProdMode; export './src/core/di.dart' hide ForwardRefFn, resolveForwardRef, forwardRef; export './src/facade/facade.dart'; -export './src/core/application_ref.dart' show platform, createNgZone, PlatformRef, ApplicationRef; +export './src/core/application_ref.dart' show createPlatform, assertPlatform, + disposePlatform, getPlatform, + coreLoadAndBootstrap, coreBootstrap, createNgZone, PlatformRef, ApplicationRef; export './src/core/application_tokens.dart' show APP_ID, - APP_COMPONENT, APP_INITIALIZER, PACKAGE_ROOT_URL, PLATFORM_INITIALIZER; diff --git a/modules/angular2/core.ts b/modules/angular2/core.ts index f7d786ae62..943b6af301 100644 --- a/modules/angular2/core.ts +++ b/modules/angular2/core.ts @@ -9,10 +9,19 @@ export * from './src/core/prod_mode'; export * from './src/core/di'; export * from './src/facade/facade'; export {enableProdMode} from 'angular2/src/facade/lang'; -export {platform, createNgZone, PlatformRef, ApplicationRef} from './src/core/application_ref'; +export { + createPlatform, + assertPlatform, + disposePlatform, + getPlatform, + coreBootstrap, + coreLoadAndBootstrap, + createNgZone, + PlatformRef, + ApplicationRef +} from './src/core/application_ref'; export { APP_ID, - APP_COMPONENT, APP_INITIALIZER, PACKAGE_ROOT_URL, PLATFORM_INITIALIZER diff --git a/modules/angular2/examples/core/ts/platform/platform.ts b/modules/angular2/examples/core/ts/platform/platform.ts index 98a916c9d3..7ecbfd9a40 100644 --- a/modules/angular2/examples/core/ts/platform/platform.ts +++ b/modules/angular2/examples/core/ts/platform/platform.ts @@ -1,4 +1,4 @@ -import {Component, platform} from 'angular2/core'; +import {Component, createPlatform, coreLoadAndBootstrap, ReflectiveInjector} from 'angular2/core'; import {BROWSER_PROVIDERS, BROWSER_APP_PROVIDERS} from 'angular2/platform/browser'; var appProviders: any[] = []; @@ -8,6 +8,8 @@ var appProviders: any[] = []; class MyApp { } -var app = platform(BROWSER_PROVIDERS).application([BROWSER_APP_PROVIDERS, appProviders]); -app.bootstrap(MyApp); +var platform = createPlatform(ReflectiveInjector.resolveAndCreate(BROWSER_PROVIDERS)); +var appInjector = + ReflectiveInjector.resolveAndCreate([BROWSER_APP_PROVIDERS, appProviders], platform.injector); +coreLoadAndBootstrap(appInjector, MyApp); // #enddocregion diff --git a/modules/angular2/examples/platform/dom/debug/ts/debug_element_view_listener/providers.ts b/modules/angular2/examples/platform/dom/debug/ts/debug_element_view_listener/providers.ts index b9dec70aae..1d36b5ae7e 100644 --- a/modules/angular2/examples/platform/dom/debug/ts/debug_element_view_listener/providers.ts +++ b/modules/angular2/examples/platform/dom/debug/ts/debug_element_view_listener/providers.ts @@ -7,4 +7,4 @@ class MyAppComponent { // #docregion providers bootstrap(MyAppComponent, [ELEMENT_PROBE_PROVIDERS]); -// #enddocregion \ No newline at end of file +// #enddocregion diff --git a/modules/angular2/examples/router/ts/on_activate/on_activate_example.ts b/modules/angular2/examples/router/ts/on_activate/on_activate_example.ts index 155714dde4..9e6b9aa236 100644 --- a/modules/angular2/examples/router/ts/on_activate/on_activate_example.ts +++ b/modules/angular2/examples/router/ts/on_activate/on_activate_example.ts @@ -10,7 +10,7 @@ class ChildCmp { @Component({ template: ` -

Parent

() +

Parent

()

{{log}}

`, directives: [ROUTER_DIRECTIVES] }) @@ -34,7 +34,7 @@ class ParentCmp implements OnActivate { selector: 'example-app', template: `

My app

- + diff --git a/modules/angular2/platform/browser.ts b/modules/angular2/platform/browser.ts index ee4f4498fe..fd2f63d32f 100644 --- a/modules/angular2/platform/browser.ts +++ b/modules/angular2/platform/browser.ts @@ -13,13 +13,24 @@ export { disableDebugTools } from 'angular2/src/platform/browser_common'; -import {Type, isPresent, CONST_EXPR} from 'angular2/src/facade/lang'; +import {Type, isPresent, isBlank, CONST_EXPR} from 'angular2/src/facade/lang'; import { BROWSER_PROVIDERS, - BROWSER_APP_COMMON_PROVIDERS + BROWSER_APP_COMMON_PROVIDERS, + BROWSER_PLATFORM_MARKER } from 'angular2/src/platform/browser_common'; import {COMPILER_PROVIDERS} from 'angular2/compiler'; -import {ComponentRef, platform, reflector} from 'angular2/core'; +import { + ComponentRef, + coreLoadAndBootstrap, + reflector, + ReflectiveInjector, + PlatformRef, + OpaqueToken, + getPlatform, + createPlatform, + assertPlatform +} from 'angular2/core'; import {ReflectionCapabilities} from 'angular2/src/core/reflection/reflection_capabilities'; import {XHRImpl} from "angular2/src/platform/browser/xhr_impl"; import {XHR} from 'angular2/compiler'; @@ -34,6 +45,13 @@ export const BROWSER_APP_PROVIDERS: Array = CON new Provider(XHR, {useClass: XHRImpl}), ]); +export function browserPlatform(): PlatformRef { + if (isBlank(getPlatform())) { + createPlatform(ReflectiveInjector.resolveAndCreate(BROWSER_PROVIDERS)); + } + return assertPlatform(BROWSER_PLATFORM_MARKER); +} + /** * Bootstrapping for Angular applications. * @@ -106,7 +124,8 @@ export function bootstrap( appComponentType: Type, customProviders?: Array): Promise { reflector.reflectionCapabilities = new ReflectionCapabilities(); - let appProviders = - isPresent(customProviders) ? [BROWSER_APP_PROVIDERS, customProviders] : BROWSER_APP_PROVIDERS; - return platform(BROWSER_PROVIDERS).application(appProviders).bootstrap(appComponentType); + var appInjector = ReflectiveInjector.resolveAndCreate( + [BROWSER_APP_PROVIDERS, isPresent(customProviders) ? customProviders : []], + browserPlatform().injector); + return coreLoadAndBootstrap(appInjector, appComponentType); } diff --git a/modules/angular2/platform/browser_static.ts b/modules/angular2/platform/browser_static.ts index 928a31639d..de7604c62e 100644 --- a/modules/angular2/platform/browser_static.ts +++ b/modules/angular2/platform/browser_static.ts @@ -11,12 +11,21 @@ export { disableDebugTools } from 'angular2/src/platform/browser_common'; -import {Type, isPresent} from 'angular2/src/facade/lang'; +import {Type, isPresent, isBlank} from 'angular2/src/facade/lang'; import { BROWSER_PROVIDERS, - BROWSER_APP_COMMON_PROVIDERS + BROWSER_APP_COMMON_PROVIDERS, + BROWSER_PLATFORM_MARKER } from 'angular2/src/platform/browser_common'; -import {ComponentRef, platform} from 'angular2/core'; +import { + ComponentRef, + coreLoadAndBootstrap, + ReflectiveInjector, + PlatformRef, + getPlatform, + createPlatform, + assertPlatform +} from 'angular2/core'; /** * An array of providers that should be passed into `application()` when bootstrapping a component @@ -26,6 +35,13 @@ import {ComponentRef, platform} from 'angular2/core'; export const BROWSER_APP_PROVIDERS: Array = BROWSER_APP_COMMON_PROVIDERS; +export function browserStaticPlatform(): PlatformRef { + if (isBlank(getPlatform())) { + createPlatform(ReflectiveInjector.resolveAndCreate(BROWSER_PROVIDERS)); + } + return assertPlatform(BROWSER_PLATFORM_MARKER); +} + /** * See {@link bootstrap} for more information. */ @@ -38,5 +54,7 @@ export function bootstrapStatic(appComponentType: Type, let appProviders = isPresent(customProviders) ? [BROWSER_APP_PROVIDERS, customProviders] : BROWSER_APP_PROVIDERS; - return platform(BROWSER_PROVIDERS).application(appProviders).bootstrap(appComponentType); + var appInjector = + ReflectiveInjector.resolveAndCreate(appProviders, browserStaticPlatform().injector); + return coreLoadAndBootstrap(appInjector, appComponentType); } diff --git a/modules/angular2/platform/worker_app.dart b/modules/angular2/platform/worker_app.dart index 8a2bfee74f..244331440d 100644 --- a/modules/angular2/platform/worker_app.dart +++ b/modules/angular2/platform/worker_app.dart @@ -1,5 +1,12 @@ library angular2.platform.worker_app; +import "package:angular2/src/platform/worker_app_common.dart"; +import "package:angular2/src/platform/worker_app.dart"; +import 'package:angular2/core.dart'; +import 'package:angular2/src/facade/lang.dart'; +import 'dart:isolate'; +import 'dart:async'; + export "package:angular2/src/platform/worker_app_common.dart" show WORKER_APP_PLATFORM, WORKER_APP_APPLICATION_COMMON; export "package:angular2/src/core/angular_entrypoint.dart" @@ -14,3 +21,31 @@ export 'package:angular2/src/web_workers/shared/serializer.dart' show PRIMITIVE; export 'package:angular2/src/web_workers/shared/message_bus.dart'; export 'package:angular2/src/web_workers/worker/router_providers.dart' show WORKER_APP_ROUTER; + +PlatformRef _platform = null; +SendPort _renderSendPort = null; + +PlatformRef workerAppPlatform(SendPort renderSendPort) { + if (isBlank(getPlatform())) { + createPlatform(ReflectiveInjector.resolveAndCreate([ + WORKER_APP_PLATFORM, + new Provider(RENDER_SEND_PORT, useValue: renderSendPort) + ])); + } + var platform = assertPlatform(WORKER_APP_PLATFORM_MARKER); + if (platform.injector.get(RENDER_SEND_PORT, null) != renderSendPort) { + throw 'Platform has already been created with a different SendPort. Please distroy it first.'; + } + return platform; +} + +Future bootstrapApp( + SendPort renderSendPort, + Type appComponentType, + [List customProviders]) { + var appInjector = ReflectiveInjector.resolveAndCreate([ + WORKER_APP_APPLICATION, + isPresent(customProviders) ? customProviders : [] + ], workerAppPlatform(renderSendPort).injector); + return coreLoadAndBootstrap(appInjector, appComponentType); +} diff --git a/modules/angular2/platform/worker_app.ts b/modules/angular2/platform/worker_app.ts index d3b255c430..d168056d58 100644 --- a/modules/angular2/platform/worker_app.ts +++ b/modules/angular2/platform/worker_app.ts @@ -1,3 +1,20 @@ +import {isPresent, isBlank} from 'angular2/src/facade/lang'; +import { + WORKER_APP_PLATFORM, + WORKER_APP_PLATFORM_MARKER +} from 'angular2/src/platform/worker_app_common'; +import {WORKER_APP_APPLICATION} from 'angular2/src/platform/worker_app'; +import { + PlatformRef, + Type, + ComponentRef, + ReflectiveInjector, + coreLoadAndBootstrap, + getPlatform, + createPlatform, + assertPlatform +} from 'angular2/core'; + export { WORKER_APP_PLATFORM, WORKER_APP_APPLICATION_COMMON @@ -18,3 +35,19 @@ export {PRIMITIVE} from 'angular2/src/web_workers/shared/serializer'; export * from 'angular2/src/web_workers/shared/message_bus'; export {AngularEntrypoint} from 'angular2/src/core/angular_entrypoint'; export {WORKER_APP_ROUTER} from 'angular2/src/web_workers/worker/router_providers'; + +export function workerAppPlatform(): PlatformRef { + if (isBlank(getPlatform())) { + createPlatform(ReflectiveInjector.resolveAndCreate(WORKER_APP_PLATFORM)); + } + return assertPlatform(WORKER_APP_PLATFORM_MARKER); +} + +export function bootstrapApp( + appComponentType: Type, + customProviders?: Array): Promise { + var appInjector = ReflectiveInjector.resolveAndCreate( + [WORKER_APP_APPLICATION, isPresent(customProviders) ? customProviders : []], + workerAppPlatform().injector); + return coreLoadAndBootstrap(appInjector, appComponentType); +} diff --git a/modules/angular2/platform/worker_render.dart b/modules/angular2/platform/worker_render.dart index f19e8e0a94..3d41a6b4f2 100644 --- a/modules/angular2/platform/worker_render.dart +++ b/modules/angular2/platform/worker_render.dart @@ -1,5 +1,11 @@ library angular2.platform.worker_render; +import 'package:angular2/src/platform/worker_render.dart'; +import 'package:angular2/src/platform/worker_render_common.dart'; +import 'package:angular2/core.dart'; +import 'package:angular2/src/facade/lang.dart'; +import 'dart:async'; + export 'package:angular2/src/platform/worker_render_common.dart' show WORKER_SCRIPT, @@ -8,7 +14,7 @@ export 'package:angular2/src/platform/worker_render_common.dart' initializeGenericWorkerRenderer; export 'package:angular2/src/platform/worker_render.dart' - show WORKER_RENDER_APPLICATION, initIsolate, WebWorkerInstance; + show WORKER_RENDER_APPLICATION, WebWorkerInstance; export '../src/web_workers/shared/client_message_broker.dart' show ClientMessageBroker, ClientMessageBrokerFactory, FnArg, UiArguments; @@ -20,7 +26,24 @@ export '../src/web_workers/shared/serializer.dart' show PRIMITIVE; export '../src/web_workers/shared/message_bus.dart'; export '../src/web_workers/ui/router_providers.dart' show WORKER_RENDER_ROUTER; -import 'package:angular2/src/platform/worker_render_common.dart'; const WORKER_RENDER_APP = WORKER_RENDER_APPLICATION_COMMON; +PlatformRef workerRenderPlatform() { + if (isBlank(getPlatform())) { + createPlatform(ReflectiveInjector.resolveAndCreate(WORKER_RENDER_PLATFORM)); + } + return assertPlatform(WORKER_RENDER_PLATFORM_MARKER); +} + +Future bootstrapRender( + String workerScriptUri, + [List customProviders]) { + return initIsolate(workerScriptUri).then( (appProviders) { + var appInjector = ReflectiveInjector.resolveAndCreate([ + appProviders, + isPresent(customProviders) ? customProviders : [] + ], workerRenderPlatform().injector); + return appInjector.get(ApplicationRef); + }); +} diff --git a/modules/angular2/platform/worker_render.ts b/modules/angular2/platform/worker_render.ts index b6b7f3ffa5..fbd596d4fe 100644 --- a/modules/angular2/platform/worker_render.ts +++ b/modules/angular2/platform/worker_render.ts @@ -1,3 +1,21 @@ +import {isPresent, isBlank} from 'angular2/src/facade/lang'; +import {PromiseWrapper} from 'angular2/src/facade/async'; +import { + ApplicationRef, + PlatformRef, + ReflectiveInjector, + Provider, + getPlatform, + createPlatform, + assertPlatform +} from 'angular2/core'; +import {WORKER_RENDER_APPLICATION} from 'angular2/src/platform/worker_render'; +import { + WORKER_SCRIPT, + WORKER_RENDER_PLATFORM, + WORKER_RENDER_PLATFORM_MARKER +} from 'angular2/src/platform/worker_render_common'; + export { WORKER_SCRIPT, WORKER_RENDER_PLATFORM, @@ -18,10 +36,33 @@ export { } from '../src/web_workers/shared/service_message_broker'; export {PRIMITIVE} from '../src/web_workers/shared/serializer'; export * from '../src/web_workers/shared/message_bus'; -import {WORKER_RENDER_APPLICATION} from 'angular2/src/platform/worker_render'; /** * @deprecated Use WORKER_RENDER_APPLICATION */ export const WORKER_RENDER_APP = WORKER_RENDER_APPLICATION; export {WORKER_RENDER_ROUTER} from 'angular2/src/web_workers/ui/router_providers'; + +export function workerRenderPlatform(): PlatformRef { + if (isBlank(getPlatform())) { + createPlatform(ReflectiveInjector.resolveAndCreate(WORKER_RENDER_PLATFORM)); + } + return assertPlatform(WORKER_RENDER_PLATFORM_MARKER); +} + +export function bootstrapRender( + workerScriptUri: string, + customProviders?: Array): Promise { + var pf = ReflectiveInjector.resolveAndCreate(WORKER_RENDER_PLATFORM); + var app = ReflectiveInjector.resolveAndCreate( + [ + WORKER_RENDER_APPLICATION, + new Provider(WORKER_SCRIPT, {useValue: workerScriptUri}), + isPresent(customProviders) ? customProviders : [] + ], + workerRenderPlatform().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)); +} diff --git a/modules/angular2/src/core/application_common_providers.ts b/modules/angular2/src/core/application_common_providers.ts index df0f8b7711..35bbc6963c 100644 --- a/modules/angular2/src/core/application_common_providers.ts +++ b/modules/angular2/src/core/application_common_providers.ts @@ -1,10 +1,7 @@ import {Type, CONST_EXPR} from 'angular2/src/facade/lang'; import {provide, Provider, Injector, OpaqueToken} from 'angular2/src/core/di'; -import { - APP_COMPONENT_REF_PROMISE, - APP_COMPONENT, - APP_ID_RANDOM_PROVIDER -} from './application_tokens'; +import {APP_ID_RANDOM_PROVIDER} from './application_tokens'; +import {APPLICATION_CORE_PROVIDERS} from './application_ref'; import { IterableDiffers, defaultIterableDiffers, @@ -24,6 +21,7 @@ var __unused: Type; // avoid unused import when Type union types are erased * application, regardless of the platform it runs onto. */ export const APPLICATION_COMMON_PROVIDERS: Array = CONST_EXPR([ + APPLICATION_CORE_PROVIDERS, new Provider(ComponentResolver, {useClass: ReflectorComponentResolver}), APP_ID_RANDOM_PROVIDER, ViewUtils, diff --git a/modules/angular2/src/core/application_ref.ts b/modules/angular2/src/core/application_ref.ts index c6e68d3f0b..b2c04a5620 100644 --- a/modules/angular2/src/core/application_ref.ts +++ b/modules/angular2/src/core/application_ref.ts @@ -5,20 +5,17 @@ import { isPresent, assertionsEnabled, print, - IS_DART + IS_DART, + CONST_EXPR, + lockMode, + isPromise } from 'angular2/src/facade/lang'; -import {provide, Provider, Injector, ReflectiveInjector, OpaqueToken} from 'angular2/src/core/di'; -import { - APP_COMPONENT_REF_PROMISE, - APP_COMPONENT, - APP_ID_RANDOM_PROVIDER, - PLATFORM_INITIALIZER, - APP_INITIALIZER -} from './application_tokens'; +import {provide, Provider, Injector, Injectable} from 'angular2/src/core/di'; +import {APP_ID_RANDOM_PROVIDER, PLATFORM_INITIALIZER, APP_INITIALIZER} from './application_tokens'; import {PromiseWrapper, PromiseCompleter, ObservableWrapper} from 'angular2/src/facade/async'; import {ListWrapper} from 'angular2/src/facade/collection'; import {TestabilityRegistry, Testability} from 'angular2/src/core/testability/testability'; -import {DynamicComponentLoader} from 'angular2/src/core/linker/dynamic_component_loader'; +import {ComponentResolver} from 'angular2/src/core/linker/component_resolver'; import {ComponentRef} from 'angular2/src/core/linker/component_factory'; import { BaseException, @@ -29,42 +26,7 @@ import { import {Console} from 'angular2/src/core/console'; import {wtfLeave, wtfCreateScope, WtfScopeFn} from './profile/profile'; import {ChangeDetectorRef} from 'angular2/src/core/change_detection/change_detector_ref'; -import {lockMode} from 'angular2/src/facade/lang'; - -/** - * Construct providers specific to an individual root component. - */ -function _componentProviders(appComponentType: Type): Array { - return [ - provide(APP_COMPONENT, {useValue: appComponentType}), - provide(APP_COMPONENT_REF_PROMISE, - { - useFactory: (dynamicComponentLoader: DynamicComponentLoader, appRef: ApplicationRef_, - injector: Injector) => { - // Save the ComponentRef for disposal later. - var ref: ComponentRef; - // TODO(rado): investigate whether to support providers on root component. - return dynamicComponentLoader.loadAsRoot(appComponentType, null, injector, - () => { appRef._unloadComponent(ref); }) - .then((componentRef) => { - ref = componentRef; - var testability = injector.get(Testability, null); - if (isPresent(testability)) { - injector.get(TestabilityRegistry) - .registerApplication(componentRef.location.nativeElement, testability); - } - return componentRef; - }); - }, - deps: [DynamicComponentLoader, ApplicationRef, Injector] - }), - provide(appComponentType, - { - useFactory: (p: Promise) => p.then(ref => ref.instance), - deps: [APP_COMPONENT_REF_PROMISE] - }), - ]; -} +import {ComponentFactory} from 'angular2/src/core/linker/component_factory'; /** * Create an Angular zone. @@ -74,59 +36,86 @@ export function createNgZone(): NgZone { } var _platform: PlatformRef; -var _platformProviders: any[]; +var _inPlatformCreate: boolean = false; /** - * Initialize the Angular 'platform' on the page. - * - * See {@link PlatformRef} for details on the Angular platform. - * - * It is also possible to specify providers to be made in the new platform. These providers - * will be shared between all applications on the page. For example, an abstraction for - * the browser cookie jar should be bound at the platform level, because there is only one - * cookie jar regardless of how many applications on the page will be accessing it. - * - * The platform function can be called multiple times as long as the same list of providers - * is passed into each call. If the platform function is called with a different set of - * provides, Angular will throw an exception. + * Creates a platform. + * Platforms have to be eagerly created via this function. */ -export function platform(providers?: Array): PlatformRef { - lockMode(); - if (isPresent(_platform)) { - if (ListWrapper.equals(_platformProviders, providers)) { - return _platform; - } else { - throw new BaseException("platform cannot be initialized with different sets of providers."); - } - } else { - return _createPlatform(providers); +export function createPlatform(injector: Injector): PlatformRef { + if (_inPlatformCreate) { + throw new BaseException('Already creating a platform...'); } + if (isPresent(_platform) && !_platform.disposed) { + throw new BaseException( + "There can be only one platform. Destroy the previous one to create a new one."); + } + lockMode(); + _inPlatformCreate = true; + try { + _platform = injector.get(PlatformRef); + } finally { + _inPlatformCreate = false; + } + return _platform; +} + +/** + * Checks that there currently is a platform + * which contains the given token as a provider. + */ +export function assertPlatform(requiredToken: any): PlatformRef { + var platform = getPlatform(); + if (isBlank(platform)) { + throw new BaseException('Not platform exists!'); + } + 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; } /** * Dispose the existing platform. */ export function disposePlatform(): void { - if (isPresent(_platform)) { + if (isPresent(_platform) && !_platform.disposed) { _platform.dispose(); - _platform = null; } } -function _createPlatform(providers?: Array): PlatformRef { - _platformProviders = providers; - let injector = ReflectiveInjector.resolveAndCreate(providers); - _platform = new PlatformRef_(injector, () => { - _platform = null; - _platformProviders = null; - }); - _runPlatformInitializers(injector); - return _platform; +/** + * Returns the current platform. + */ +export function getPlatform(): PlatformRef { + return isPresent(_platform) && !_platform.disposed ? _platform : null; } -function _runPlatformInitializers(injector: Injector): void { - let inits: Function[] = injector.get(PLATFORM_INITIALIZER, null); - if (isPresent(inits)) inits.forEach(init => init()); +/** + * Shortcut for ApplicationRef.bootstrap. + * Requires a platform the be created first. + */ +export function coreBootstrap(injector: Injector, + componentFactory: ComponentFactory): ComponentRef { + var appRef: ApplicationRef = injector.get(ApplicationRef); + return appRef.bootstrap(componentFactory); +} + +/** + * Resolves the componentFactory for the given component, + * waits for asynchronous initializers and bootstraps the component. + * Requires a platform the be created first. + */ +export function coreLoadAndBootstrap(injector: Injector, + componentType: Type): Promise { + 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])); + }); } /** @@ -135,7 +124,7 @@ function _runPlatformInitializers(injector: Injector): void { * to every Angular application running on the page are bound in its scope. * * A page's platform is initialized implicitly when {@link bootstrap}() is called, or - * explicitly by calling {@link platform}(). + * explicitly by calling {@link createPlatform}(). */ export abstract class PlatformRef { /** @@ -149,157 +138,50 @@ export abstract class PlatformRef { */ get injector(): Injector { throw unimplemented(); }; - /** - * Instantiate a new Angular application on the page. - * - * ### What is an application? - * - * Each Angular application has its own zone, change detection, compiler, - * renderer, and other framework components. An application hosts one or more - * root components, which can be initialized via `ApplicationRef.bootstrap()`. - * - * ### Application Providers - * - * Angular applications require numerous providers to be properly instantiated. - * When using `application()` to create a new app on the page, these providers - * must be provided. Fortunately, there are helper functions to configure - * typical providers, as shown in the example below. - * - * ### Example - * - * {@example core/ts/platform/platform.ts region='longform'} - * ### See Also - * - * See the {@link bootstrap} documentation for more details. - */ - abstract application(providers: Array): ApplicationRef; - - /** - * Instantiate a new Angular application on the page, using providers which - * are only available asynchronously. One such use case is to initialize an - * application running in a web worker. - * - * ### Usage - * - * `bindingFn` is a function that will be called in the new application's zone. - * It should return a `Promise` to a list of providers to be used for the - * new application. Once this promise resolves, the application will be - * constructed in the same manner as a normal `application()`. - */ - abstract asyncApplication(bindingFn: (zone: NgZone) => Promise>, - providers?: Array): Promise; - /** * Destroy the Angular platform and all Angular applications on the page. */ abstract dispose(): void; + + get disposed(): boolean { throw unimplemented(); } } +@Injectable() export class PlatformRef_ extends PlatformRef { /** @internal */ _applications: ApplicationRef[] = []; /** @internal */ _disposeListeners: Function[] = []; - constructor(private _injector: ReflectiveInjector, private _dispose: () => void) { super(); } + private _disposed: boolean = false; + + constructor(private _injector: Injector) { + super(); + if (!_inPlatformCreate) { + throw new BaseException('Platforms have to be created via `createPlatform`!'); + } + let inits: Function[] = _injector.get(PLATFORM_INITIALIZER, null); + if (isPresent(inits)) inits.forEach(init => init()); + } registerDisposeListener(dispose: () => void): void { this._disposeListeners.push(dispose); } - get injector(): ReflectiveInjector { return this._injector; } + get injector(): Injector { return this._injector; } - application(providers: Array): ApplicationRef { - var app = this._initApp(createNgZone(), providers); - if (PromiseWrapper.isPromise(app)) { - throw new BaseException( - "Cannot use asyncronous app initializers with application. Use asyncApplication instead."); - } - return app; - } + get disposed() { return this._disposed; } - asyncApplication(bindingFn: (zone: NgZone) => Promise>, - additionalProviders?: Array): Promise { - var zone = createNgZone(); - var completer = PromiseWrapper.completer(); - if (bindingFn === null) { - completer.resolve(this._initApp(zone, additionalProviders)); - } else { - zone.run(() => { - PromiseWrapper.then(bindingFn(zone), (providers: Array) => { - if (isPresent(additionalProviders)) { - providers = ListWrapper.concat(providers, additionalProviders); - } - let promise = this._initApp(zone, providers); - completer.resolve(promise); - }); - }); - } - return completer.promise; - } - - private _initApp(zone: NgZone, - providers: Array): Promise| - ApplicationRef { - var injector: ReflectiveInjector; - var app: ApplicationRef; - zone.run(() => { - providers = ListWrapper.concat(providers, [ - provide(NgZone, {useValue: zone}), - provide(ApplicationRef, {useFactory: (): ApplicationRef => app, deps: []}) - ]); - - var exceptionHandler: ExceptionHandler; - try { - injector = this.injector.resolveAndCreateChild(providers); - exceptionHandler = injector.get(ExceptionHandler); - ObservableWrapper.subscribe(zone.onError, (error: NgZoneError) => { - exceptionHandler.call(error.error, error.stackTrace); - }); - } catch (e) { - if (isPresent(exceptionHandler)) { - exceptionHandler.call(e, e.stack); - } else { - print(e.toString()); - } - } - }); - app = new ApplicationRef_(this, zone, injector); - this._applications.push(app); - var promise = _runAppInitializers(injector); - if (promise !== null) { - return PromiseWrapper.then(promise, (_) => app); - } else { - return app; - } - } + addApplication(appRef: ApplicationRef) { this._applications.push(appRef); } dispose(): void { ListWrapper.clone(this._applications).forEach((app) => app.dispose()); this._disposeListeners.forEach((dispose) => dispose()); - this._dispose(); + this._disposed = true; } /** @internal */ _applicationDisposed(app: ApplicationRef): void { ListWrapper.remove(this._applications, app); } } -function _runAppInitializers(injector: Injector): Promise { - let inits: Function[] = injector.get(APP_INITIALIZER, null); - let promises: Promise[] = []; - if (isPresent(inits)) { - inits.forEach(init => { - var retVal = init(); - if (PromiseWrapper.isPromise(retVal)) { - promises.push(retVal); - } - }); - } - if (promises.length > 0) { - return PromiseWrapper.all(promises); - } else { - return null; - } -} - /** * A reference to an Angular application running on a page. * @@ -317,6 +199,18 @@ export abstract class ApplicationRef { */ abstract registerDisposeListener(dispose: () => void): void; + /** + * Returns a promise that resolves when all asynchronous application initializers + * are done. + */ + abstract waitForAsyncInitializers(): Promise; + + /** + * Runs the given callback in the zone and returns the result of the callback. + * Exceptions will be forwarded to the ExceptionHandler and rethrown. + */ + abstract run(callback: Function): any; + /** * Bootstrap a new component at the root level of the application. * @@ -326,17 +220,10 @@ export abstract class ApplicationRef { * specified application component onto DOM elements identified by the [componentType]'s * selector and kicks off automatic change detection to finish initializing the component. * - * ### Optional Providers - * - * Providers for the given component can optionally be overridden via the `providers` - * parameter. These providers will only apply for the root component being added and any - * child components under it. - * * ### Example * {@example core/ts/platform/platform.ts region='longform'} */ - abstract bootstrap(componentType: Type, - providers?: Array): Promise; + abstract bootstrap(componentFactory: ComponentFactory): ComponentRef; /** * Retrieve the application {@link Injector}. @@ -371,6 +258,7 @@ export abstract class ApplicationRef { get componentTypes(): Type[] { return unimplemented(); }; } +@Injectable() export class ApplicationRef_ extends ApplicationRef { /** @internal */ static _tickScope: WtfScopeFn = wtfCreateScope('ApplicationRef#tick()'); @@ -390,14 +278,43 @@ export class ApplicationRef_ extends ApplicationRef { /** @internal */ private _enforceNoNewChanges: boolean = false; - constructor(private _platform: PlatformRef_, private _zone: NgZone, - private _injector: ReflectiveInjector) { + private _exceptionHandler: ExceptionHandler; + + private _asyncInitDonePromise: Promise; + private _asyncInitDone: boolean; + + constructor(private _platform: PlatformRef_, private _zone: NgZone, private _injector: Injector) { super(); - if (isPresent(this._zone)) { - ObservableWrapper.subscribe(this._zone.onMicrotaskEmpty, - (_) => { this._zone.run(() => { this.tick(); }); }); - } + var zone: NgZone = _injector.get(NgZone); this._enforceNoNewChanges = assertionsEnabled(); + zone.run(() => { this._exceptionHandler = _injector.get(ExceptionHandler); }); + this._asyncInitDonePromise = this.run(() => { + let inits: Function[] = _injector.get(APP_INITIALIZER, null); + var asyncInitResults = []; + var asyncInitDonePromise; + if (isPresent(inits)) { + for (var i = 0; i < inits.length; i++) { + var initResult = inits[i](); + if (isPromise(initResult)) { + asyncInitResults.push(initResult); + } + } + } + if (asyncInitResults.length > 0) { + asyncInitDonePromise = + PromiseWrapper.all(asyncInitResults).then((_) => this._asyncInitDone = true); + this._asyncInitDone = false; + } else { + this._asyncInitDone = true; + asyncInitDonePromise = PromiseWrapper.resolve(true); + } + return asyncInitDonePromise; + }); + ObservableWrapper.subscribe(zone.onError, (error: NgZoneError) => { + this._exceptionHandler.call(error.error, error.stackTrace); + }); + ObservableWrapper.subscribe(this._zone.onMicrotaskEmpty, + (_) => { this._zone.run(() => { this.tick(); }); }); } registerBootstrapListener(listener: (ref: ComponentRef) => void): void { @@ -414,42 +331,56 @@ export class ApplicationRef_ extends ApplicationRef { ListWrapper.remove(this._changeDetectorRefs, changeDetector); } - bootstrap(componentType: Type, - providers?: Array): Promise { + waitForAsyncInitializers(): Promise { return this._asyncInitDonePromise; } + + run(callback: Function): any { + var zone = this.injector.get(NgZone); + var result; + // Note: Don't use zone.runGuarded as we want to know about + // the thrown exception! + // Note: the completer needs to be created outside + // of `zone.run` as Dart swallows rejected promises + // via the onError callback of the promise. var completer = PromiseWrapper.completer(); - this._zone.run(() => { - var componentProviders = _componentProviders(componentType); - if (isPresent(providers)) { - componentProviders.push(providers); - } - var exceptionHandler = this._injector.get(ExceptionHandler); - this._rootComponentTypes.push(componentType); + zone.run(() => { try { - var injector: Injector = this._injector.resolveAndCreateChild(componentProviders); - var compRefToken: Promise = injector.get(APP_COMPONENT_REF_PROMISE); - var tick = (componentRef: ComponentRef) => { - this._loadComponent(componentRef); - completer.resolve(componentRef); - }; - - var tickResult = PromiseWrapper.then(compRefToken, tick); - - PromiseWrapper.then(tickResult, null, (err, stackTrace) => { - completer.reject(err, stackTrace); - exceptionHandler.call(err, stackTrace); - }); + result = callback(); + if (isPromise(result)) { + PromiseWrapper.then(result, (ref) => { completer.resolve(ref); }, (err, stackTrace) => { + completer.reject(err, stackTrace); + this._exceptionHandler.call(err, stackTrace); + }); + } } catch (e) { - exceptionHandler.call(e, e.stack); - completer.reject(e, e.stack); + this._exceptionHandler.call(e, e.stack); + throw e; } }); - return completer.promise.then((ref: ComponentRef) => { + return isPromise(result) ? completer.promise : result; + } + + bootstrap(componentFactory: ComponentFactory): ComponentRef { + if (!this._asyncInitDone) { + throw new BaseException( + 'Cannot bootstrap as there are still asynchronous initializers running. Wait for them using waitForAsyncInitializers().'); + } + return this.run(() => { + 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); + } + + this._loadComponent(compRef); let c = this._injector.get(Console); if (assertionsEnabled()) { c.log( "Angular 2 is running in the development mode. Call enableProdMode() to enable the production mode."); } - return ref; + return compRef; }); } @@ -501,3 +432,18 @@ export class ApplicationRef_ extends ApplicationRef { get componentTypes(): Type[] { return this._rootComponentTypes; } } + +/** + * @internal + */ +export const PLATFORM_CORE_PROVIDERS = + CONST_EXPR([PlatformRef_, CONST_EXPR(new Provider(PlatformRef, {useExisting: PlatformRef_}))]); + +/** + * @internal + */ +export const APPLICATION_CORE_PROVIDERS = CONST_EXPR([ + CONST_EXPR(new Provider(NgZone, {useFactory: createNgZone, deps: CONST_EXPR([])})), + ApplicationRef_, + CONST_EXPR(new Provider(ApplicationRef, {useExisting: ApplicationRef_})) +]); diff --git a/modules/angular2/src/core/application_tokens.ts b/modules/angular2/src/core/application_tokens.ts index d6f4feb39f..d9deff8e0f 100644 --- a/modules/angular2/src/core/application_tokens.ts +++ b/modules/angular2/src/core/application_tokens.ts @@ -1,29 +1,6 @@ import {OpaqueToken, Provider} from 'angular2/src/core/di'; import {CONST_EXPR, Math, StringWrapper} from 'angular2/src/facade/lang'; -/** - * @internal - */ -export const APP_COMPONENT_REF_PROMISE = CONST_EXPR(new OpaqueToken('Promise')); - -/** - * An {@link OpaqueToken-class.html} representing the application root type in the {@link - * Injector}. - * - * ``` - * @Component(...) - * class MyApp { - * ... - * } - * - * bootstrap(MyApp).then((appRef:ApplicationRef) { - * expect(appRef.injector.get(appComponentTypeToken)).toEqual(MyApp); - * }); - * - * ``` - */ -export const APP_COMPONENT: OpaqueToken = CONST_EXPR(new OpaqueToken('AppComponent')); - /** * A DI Token representing a unique string id assigned to the application by Angular and used * primarily for prefixing application attributes and CSS styles when diff --git a/modules/angular2/src/core/linker/element_ref.ts b/modules/angular2/src/core/linker/element_ref.ts index 02e7421b5e..5202c4f9dc 100644 --- a/modules/angular2/src/core/linker/element_ref.ts +++ b/modules/angular2/src/core/linker/element_ref.ts @@ -1,6 +1,3 @@ -import {unimplemented} from 'angular2/src/facade/exceptions'; -import {AppElement} from './element'; - /** * A wrapper around a native element inside of a View. * diff --git a/modules/angular2/src/core/linker/view_container_ref.ts b/modules/angular2/src/core/linker/view_container_ref.ts index 52eb398040..369a758022 100644 --- a/modules/angular2/src/core/linker/view_container_ref.ts +++ b/modules/angular2/src/core/linker/view_container_ref.ts @@ -1,8 +1,6 @@ import {ListWrapper} from 'angular2/src/facade/collection'; import {unimplemented} from 'angular2/src/facade/exceptions'; import {Injector} from 'angular2/src/core/di/injector'; -import {ReflectiveInjector} from 'angular2/src/core/di/reflective_injector'; -import {ResolvedReflectiveProvider} from 'angular2/src/core/di/reflective_provider'; import {isPresent, isBlank} from 'angular2/src/facade/lang'; import {wtfCreateScope, wtfLeave, WtfScopeFn} from '../profile/profile'; @@ -75,8 +73,7 @@ export abstract class ViewContainerRef { * * If `index` is not specified, the new View will be inserted as the last View in the container. * - * You can optionally specify the {@link Injector} - * that will be used for the component. + * You can optionally specify the {@link Injector} that will be used as parent for the Component. * * Returns the {@link ComponentRef} of the Host View created for the newly instantiated Component. */ diff --git a/modules/angular2/src/core/platform_common_providers.ts b/modules/angular2/src/core/platform_common_providers.ts index 5010c11b6d..a694b14cd0 100644 --- a/modules/angular2/src/core/platform_common_providers.ts +++ b/modules/angular2/src/core/platform_common_providers.ts @@ -4,6 +4,7 @@ import {Console} from 'angular2/src/core/console'; import {Reflector, reflector} from './reflection/reflection'; import {ReflectorReader} from './reflection/reflector_reader'; import {TestabilityRegistry} from 'angular2/src/core/testability/testability'; +import {PLATFORM_CORE_PROVIDERS} from './application_ref'; function _reflector(): Reflector { return reflector; @@ -13,6 +14,7 @@ function _reflector(): Reflector { * A default set of providers which should be included in any Angular platform. */ export const PLATFORM_COMMON_PROVIDERS: Array = CONST_EXPR([ + PLATFORM_CORE_PROVIDERS, new Provider(Reflector, {useFactory: _reflector, deps: []}), new Provider(ReflectorReader, {useExisting: Reflector}), TestabilityRegistry, diff --git a/modules/angular2/src/core/zone/ng_zone.ts b/modules/angular2/src/core/zone/ng_zone.ts index c593fdf4ba..fb34d02b74 100644 --- a/modules/angular2/src/core/zone/ng_zone.ts +++ b/modules/angular2/src/core/zone/ng_zone.ts @@ -200,9 +200,17 @@ export class NgZone { * * Any future tasks or microtasks scheduled from within this function will continue executing from * within the Angular zone. + * + * If a synchronous error happens it will be rethrown and not reported via `onError`. */ run(fn: () => any): any { return this._zoneImpl.runInner(fn); } + /** + * Same as #run, except that synchronous errors are caught and forwarded + * via `onError` and not rethrown. + */ + runGuarded(fn: () => any): any { return this._zoneImpl.runInnerGuarded(fn); } + /** * Executes the `fn` function synchronously in Angular's parent zone and returns value returned by * the function. diff --git a/modules/angular2/src/core/zone/ng_zone_impl.dart b/modules/angular2/src/core/zone/ng_zone_impl.dart index 2ec1e31dfb..15aa36e29e 100644 --- a/modules/angular2/src/core/zone/ng_zone_impl.dart +++ b/modules/angular2/src/core/zone/ng_zone_impl.dart @@ -122,10 +122,14 @@ class NgZoneImpl { ); } - dynamic runInner(fn()) { + dynamic runInnerGuarded(fn()) { return _innerZone.runGuarded(fn); } + dynamic runInner(fn()) { + return _innerZone.run(fn); + } + /** * Runs `fn` in the mount zone and returns whatever it returns. * diff --git a/modules/angular2/src/core/zone/ng_zone_impl.ts b/modules/angular2/src/core/zone/ng_zone_impl.ts index e9d513202d..4d5a356631 100644 --- a/modules/angular2/src/core/zone/ng_zone_impl.ts +++ b/modules/angular2/src/core/zone/ng_zone_impl.ts @@ -94,6 +94,7 @@ export class NgZoneImpl { } } - runInner(fn: () => any): any { return this.inner.runGuarded(fn); }; + runInner(fn: () => any): any { return this.inner.run(fn); }; + runInnerGuarded(fn: () => any): any { return this.inner.runGuarded(fn); }; runOuter(fn: () => any): any { return this.outer.run(fn); }; } diff --git a/modules/angular2/src/mock/mock_application_ref.ts b/modules/angular2/src/mock/mock_application_ref.ts index 08e479d146..f75d21ecbf 100644 --- a/modules/angular2/src/mock/mock_application_ref.ts +++ b/modules/angular2/src/mock/mock_application_ref.ts @@ -1,8 +1,8 @@ import {ApplicationRef} from 'angular2/src/core/application_ref'; import {Injectable} from 'angular2/src/core/di'; import {Type} from 'angular2/src/facade/lang'; -import {ComponentRef} from 'angular2/src/core/linker/component_factory'; -import {Provider, Injector} from 'angular2/src/core/di'; +import {ComponentRef, ComponentFactory} from 'angular2/src/core/linker/component_factory'; +import {Injector} from 'angular2/src/core/di'; import {NgZone} from 'angular2/src/core/zone/ng_zone'; /** @@ -14,14 +14,16 @@ export class MockApplicationRef extends ApplicationRef { registerDisposeListener(dispose: () => void): void {} - bootstrap(componentType: Type, bindings?: Array): Promise { - return null; - } + bootstrap(componentFactory: ComponentFactory): ComponentRef { return null; } get injector(): Injector { return null; }; get zone(): NgZone { return null; }; + run(callback: Function): any { return null; } + + waitForAsyncInitializers(): Promise { return null; } + dispose(): void {} tick(): void {} diff --git a/modules/angular2/src/platform/browser_common.ts b/modules/angular2/src/platform/browser_common.ts index 2495693f85..77c92a31b3 100644 --- a/modules/angular2/src/platform/browser_common.ts +++ b/modules/angular2/src/platform/browser_common.ts @@ -6,7 +6,6 @@ import { PLATFORM_DIRECTIVES, PLATFORM_PIPES, ComponentRef, - platform, ExceptionHandler, Reflector, RootRenderer, @@ -48,12 +47,15 @@ export {BrowserDomAdapter} from './browser/browser_adapter'; export {enableDebugTools, disableDebugTools} from 'angular2/src/platform/browser/tools/tools'; export {HAMMER_GESTURE_CONFIG, HammerGestureConfig} from './dom/events/hammer_gestures'; +export const BROWSER_PLATFORM_MARKER = CONST_EXPR(new OpaqueToken('BrowserPlatformMarker')); + /** * A set of providers to initialize the Angular platform in a web browser. * * Used automatically by `bootstrap`, or can be passed to {@link platform}. */ export const BROWSER_PROVIDERS: Array = CONST_EXPR([ + new Provider(BROWSER_PLATFORM_MARKER, {useValue: true}), PLATFORM_COMMON_PROVIDERS, new Provider(PLATFORM_INITIALIZER, {useValue: initDomAdapter, multi: true}), ]); diff --git a/modules/angular2/src/platform/dom/events/dom_events.ts b/modules/angular2/src/platform/dom/events/dom_events.ts index a8a5b1f4ad..a1fe4266ea 100644 --- a/modules/angular2/src/platform/dom/events/dom_events.ts +++ b/modules/angular2/src/platform/dom/events/dom_events.ts @@ -10,7 +10,7 @@ export class DomEventsPlugin extends EventManagerPlugin { addEventListener(element: HTMLElement, eventName: string, handler: Function): Function { var zone = this.manager.getZone(); - var outsideHandler = (event) => zone.run(() => handler(event)); + var outsideHandler = (event) => zone.runGuarded(() => handler(event)); return this.manager.getZone().runOutsideAngular( () => DOM.onAndCancel(element, eventName, outsideHandler)); } @@ -18,7 +18,7 @@ export class DomEventsPlugin extends EventManagerPlugin { addGlobalEventListener(target: string, eventName: string, handler: Function): Function { var element = DOM.getGlobalEventTarget(target); var zone = this.manager.getZone(); - var outsideHandler = (event) => zone.run(() => handler(event)); + var outsideHandler = (event) => zone.runGuarded(() => handler(event)); return this.manager.getZone().runOutsideAngular( () => DOM.onAndCancel(element, eventName, outsideHandler)); } diff --git a/modules/angular2/src/platform/dom/events/hammer_gestures.dart b/modules/angular2/src/platform/dom/events/hammer_gestures.dart index 5d93b10a95..501f018624 100644 --- a/modules/angular2/src/platform/dom/events/hammer_gestures.dart +++ b/modules/angular2/src/platform/dom/events/hammer_gestures.dart @@ -59,7 +59,7 @@ class HammerGesturesPlugin extends HammerGesturesPluginCommon { mc.callMethod('on', [ eventName, (eventObj) { - zone.run(() { + zone.runGuarded(() { var dartEvent = new HammerEvent._fromJsEvent(eventObj); handler(dartEvent); }); diff --git a/modules/angular2/src/platform/dom/events/hammer_gestures.ts b/modules/angular2/src/platform/dom/events/hammer_gestures.ts index 5fcbb97b6b..a50c04d9a1 100644 --- a/modules/angular2/src/platform/dom/events/hammer_gestures.ts +++ b/modules/angular2/src/platform/dom/events/hammer_gestures.ts @@ -52,7 +52,7 @@ export class HammerGesturesPlugin extends HammerGesturesPluginCommon { return zone.runOutsideAngular(() => { // Creating the manager bind events, must be done outside of angular var mc = this._config.buildHammer(element); - var callback = function(eventObj) { zone.run(function() { handler(eventObj); }); }; + var callback = function(eventObj) { zone.runGuarded(function() { handler(eventObj); }); }; mc.on(eventName, callback); return () => { mc.off(eventName, callback); }; }); diff --git a/modules/angular2/src/platform/dom/events/key_events.ts b/modules/angular2/src/platform/dom/events/key_events.ts index 551c82f3ec..330d3f1d25 100644 --- a/modules/angular2/src/platform/dom/events/key_events.ts +++ b/modules/angular2/src/platform/dom/events/key_events.ts @@ -95,7 +95,7 @@ export class KeyEventsPlugin extends EventManagerPlugin { zone: NgZone): Function { return (event) => { if (StringWrapper.equals(KeyEventsPlugin.getEventFullKey(event), fullKey)) { - zone.run(() => handler(event)); + zone.runGuarded(() => handler(event)); } }; } diff --git a/modules/angular2/src/platform/worker_app_common.ts b/modules/angular2/src/platform/worker_app_common.ts index 7157dfee8b..fe66684c62 100644 --- a/modules/angular2/src/platform/worker_app_common.ts +++ b/modules/angular2/src/platform/worker_app_common.ts @@ -9,6 +9,7 @@ import { ExceptionHandler, APPLICATION_COMMON_PROVIDERS, PLATFORM_COMMON_PROVIDERS, + OpaqueToken } from 'angular2/core'; import {COMMON_DIRECTIVES, COMMON_PIPES, FORM_PROVIDERS} from "angular2/common"; import { @@ -31,8 +32,12 @@ class PrintLogger { logGroupEnd() {} } -export const WORKER_APP_PLATFORM: Array = - CONST_EXPR([PLATFORM_COMMON_PROVIDERS]); +export const WORKER_APP_PLATFORM_MARKER = CONST_EXPR(new OpaqueToken('WorkerAppPlatformMarker')); + +export const WORKER_APP_PLATFORM: Array = CONST_EXPR([ + PLATFORM_COMMON_PROVIDERS, + CONST_EXPR(new Provider(WORKER_APP_PLATFORM_MARKER, {useValue: true})) +]); export const WORKER_APP_APPLICATION_COMMON: Array = CONST_EXPR([ APPLICATION_COMMON_PROVIDERS, diff --git a/modules/angular2/src/platform/worker_render.dart b/modules/angular2/src/platform/worker_render.dart index ad461fb6f0..d315f73151 100644 --- a/modules/angular2/src/platform/worker_render.dart +++ b/modules/angular2/src/platform/worker_render.dart @@ -10,26 +10,23 @@ import 'package:angular2/src/web_workers/shared/isolate_message_bus.dart'; import 'package:angular2/src/web_workers/shared/message_bus.dart'; import 'package:angular2/core.dart'; import 'package:angular2/src/core/di.dart'; -import 'package:angular2/src/core/zone/ng_zone.dart'; import 'dart:isolate'; import 'dart:async'; const WORKER_RENDER_APP = WORKER_RENDER_APPLICATION_COMMON; -initIsolate(String scriptUri) { - return (NgZone zone) async { - var instance = await spawnIsolate(Uri.parse(scriptUri)); +Future initIsolate(String scriptUri) async { + var instance = await spawnIsolate(Uri.parse(scriptUri)); - return [ - WORKER_RENDER_APPLICATION_COMMON, - new Provider(WebWorkerInstance, useValue: instance), - new Provider(APP_INITIALIZER, - useFactory: (injector) => () => initializeGenericWorkerRenderer(injector), - multi: true, - deps: [Injector]), - new Provider(MessageBus, useValue: instance.bus) - ]; - }; + return [ + WORKER_RENDER_APPLICATION_COMMON, + new Provider(WebWorkerInstance, useValue: instance), + new Provider(APP_INITIALIZER, + useFactory: (injector) => () => initializeGenericWorkerRenderer(injector), + multi: true, + deps: [Injector]), + new Provider(MessageBus, useValue: instance.bus) + ]; } /** diff --git a/modules/angular2/src/platform/worker_render_common.ts b/modules/angular2/src/platform/worker_render_common.ts index 4bcf974b18..ef3603c7df 100644 --- a/modules/angular2/src/platform/worker_render_common.ts +++ b/modules/angular2/src/platform/worker_render_common.ts @@ -5,7 +5,6 @@ import { PLATFORM_DIRECTIVES, PLATFORM_PIPES, ComponentRef, - platform, ExceptionHandler, Reflector, reflector, @@ -58,8 +57,12 @@ export const WORKER_SCRIPT: OpaqueToken = CONST_EXPR(new OpaqueToken("WebWorkerS export const WORKER_RENDER_MESSAGING_PROVIDERS: Array = CONST_EXPR([MessageBasedRenderer, MessageBasedXHRImpl]); +export const WORKER_RENDER_PLATFORM_MARKER = + CONST_EXPR(new OpaqueToken('WorkerRenderPlatformMarker')); + export const WORKER_RENDER_PLATFORM: Array = CONST_EXPR([ PLATFORM_COMMON_PROVIDERS, + CONST_EXPR(new Provider(WORKER_RENDER_PLATFORM_MARKER, {useValue: true})), new Provider(PLATFORM_INITIALIZER, {useValue: initWebWorkerRenderPlatform, multi: true}) ]); @@ -103,7 +106,7 @@ export function initializeGenericWorkerRenderer(injector: Injector) { let zone = injector.get(NgZone); bus.attachToZone(zone); - zone.run(() => { + zone.runGuarded(() => { WORKER_RENDER_MESSAGING_PROVIDERS.forEach((token) => { injector.get(token).start(); }); }); } diff --git a/modules/angular2/src/upgrade/upgrade_adapter.ts b/modules/angular2/src/upgrade/upgrade_adapter.ts index ecefdea1c3..aba3ebdac7 100644 --- a/modules/angular2/src/upgrade/upgrade_adapter.ts +++ b/modules/angular2/src/upgrade/upgrade_adapter.ts @@ -1,11 +1,11 @@ import { provide, - platform, ApplicationRef, ComponentResolver, Injector, NgZone, PlatformRef, + ReflectiveInjector, ComponentFactory, Provider, Type, @@ -14,7 +14,7 @@ import { } from 'angular2/core'; import {global} from 'angular2/src/facade/lang'; import {ObservableWrapper} from 'angular2/src/facade/async'; -import {BROWSER_PROVIDERS, BROWSER_APP_PROVIDERS} from 'angular2/platform/browser'; +import {BROWSER_PROVIDERS, BROWSER_APP_PROVIDERS, browserPlatform} from 'angular2/platform/browser'; import {getComponentInfo, ComponentInfo} from './metadata'; import {onError, controllerKey} from './util'; @@ -294,13 +294,18 @@ export class UpgradeAdapter { config?: angular.IAngularBootstrapConfig): UpgradeAdapterRef { var upgrade = new UpgradeAdapterRef(); var ng1Injector: angular.IInjectorService = null; - var platformRef: PlatformRef = platform(BROWSER_PROVIDERS); - var applicationRef: ApplicationRef = platformRef.application([ - BROWSER_APP_PROVIDERS, - provide(NG1_INJECTOR, {useFactory: () => ng1Injector}), - provide(NG1_COMPILE, {useFactory: () => ng1Injector.get(NG1_COMPILE)}), - this.providers - ]); + var platformRef: PlatformRef = browserPlatform(); + var applicationRef: ApplicationRef = + ReflectiveInjector.resolveAndCreate( + [ + BROWSER_APP_PROVIDERS, + provide(NG1_INJECTOR, {useFactory: () => ng1Injector}), + provide(NG1_COMPILE, + {useFactory: () => ng1Injector.get(NG1_COMPILE)}), + this.providers + ], + platformRef.injector) + .get(ApplicationRef); var injector: Injector = applicationRef.injector; var ngZone: NgZone = injector.get(NgZone); var compiler: ComponentResolver = injector.get(ComponentResolver); diff --git a/modules/angular2/src/web_workers/ui/router_providers.ts b/modules/angular2/src/web_workers/ui/router_providers.ts index 4d1df791d8..fa349e96b7 100644 --- a/modules/angular2/src/web_workers/ui/router_providers.ts +++ b/modules/angular2/src/web_workers/ui/router_providers.ts @@ -17,6 +17,6 @@ function initRouterListeners(injector: Injector): () => void { return () => { let zone = injector.get(NgZone); - zone.run(() => injector.get(MessageBasedPlatformLocation).start()); + zone.runGuarded(() => injector.get(MessageBasedPlatformLocation).start()); }; } diff --git a/modules/angular2/src/web_workers/worker/router_providers.ts b/modules/angular2/src/web_workers/worker/router_providers.ts index c6742ea581..968072ee81 100644 --- a/modules/angular2/src/web_workers/worker/router_providers.ts +++ b/modules/angular2/src/web_workers/worker/router_providers.ts @@ -16,5 +16,5 @@ export var WORKER_APP_ROUTER = [ ]; function initRouter(platformLocation: WebWorkerPlatformLocation, zone: NgZone): Promise { - return zone.run(() => { return platformLocation.init(); }); + return zone.runGuarded(() => { return platformLocation.init(); }); } diff --git a/modules/angular2/test/core/application_ref_spec.ts b/modules/angular2/test/core/application_ref_spec.ts index b506756f99..aea94a9bd3 100644 --- a/modules/angular2/test/core/application_ref_spec.ts +++ b/modules/angular2/test/core/application_ref_spec.ts @@ -14,131 +14,169 @@ import { inject, SpyObject } from 'angular2/testing_internal'; +import {Type} from 'angular2/src/facade/lang'; import {SpyChangeDetectorRef} from './spies'; -import {ApplicationRef_, ApplicationRef, PlatformRef_} from "angular2/src/core/application_ref"; -import {Injector, Provider, APP_INITIALIZER} from "angular2/core"; +import { + ApplicationRef_, + ApplicationRef, + PLATFORM_CORE_PROVIDERS, + APPLICATION_CORE_PROVIDERS +} from "angular2/src/core/application_ref"; +import { + Injector, + Provider, + APP_INITIALIZER, + Component, + ReflectiveInjector, + coreLoadAndBootstrap, + coreBootstrap, + PlatformRef, + createPlatform, + disposePlatform, + ComponentResolver, + ChangeDetectorRef +} from "angular2/core"; +import {Console} from 'angular2/src/core/console'; +import {BaseException} from 'angular2/src/facade/exceptions'; import {PromiseWrapper, PromiseCompleter, TimerWrapper} from "angular2/src/facade/async"; -import {ListWrapper} from "angular2/src/facade/collection"; +import { + ComponentFactory, + ComponentRef_, + ComponentRef +} from 'angular2/src/core/linker/component_factory'; import {ExceptionHandler} from 'angular2/src/facade/exception_handler'; -import {DOM} from 'angular2/src/platform/dom/dom_adapter'; export function main() { - describe("ApplicationRef", () => { - it("should throw when reentering tick", () => { - var cdRef = new SpyChangeDetectorRef(); - var ref = new ApplicationRef_(null, null, null); - ref.registerChangeDetector(cdRef); - cdRef.spy("detectChanges").andCallFake(() => ref.tick()); - expect(() => ref.tick()).toThrowError("ApplicationRef.tick is called recursively"); - }); - }); + describe("bootstrap", () => { + var platform: PlatformRef; + var errorLogger: _ArrayLogger; + var someCompFactory: ComponentFactory; - describe("PlatformRef", () => { - var exceptionHandler = - new Provider(ExceptionHandler, {useValue: new ExceptionHandler(DOM, true)}); - describe("asyncApplication", () => { - function expectProviders(injector: Injector, providers: Array): void { - for (let i = 0; i < providers.length; i++) { - let provider = providers[i]; - expect(injector.get(provider.token)).toBe(provider.useValue); + beforeEach(() => { + errorLogger = new _ArrayLogger(); + disposePlatform(); + platform = createPlatform(ReflectiveInjector.resolveAndCreate(PLATFORM_CORE_PROVIDERS)); + someCompFactory = + new _MockComponentFactory(new _MockComponentRef(ReflectiveInjector.resolveAndCreate([]))); + }); + + afterEach(() => { disposePlatform(); }); + + function createApplication(providers: any[]): ApplicationRef_ { + var appInjector = ReflectiveInjector.resolveAndCreate( + [ + APPLICATION_CORE_PROVIDERS, + new Provider(Console, {useValue: new _MockConsole()}), + new Provider(ExceptionHandler, {useValue: new ExceptionHandler(errorLogger, false)}), + new Provider(ComponentResolver, + {useValue: new _MockComponentResolver(someCompFactory)}), + providers + ], + platform.injector); + return appInjector.get(ApplicationRef); + } + + describe("ApplicationRef", () => { + it("should throw when reentering tick", () => { + var cdRef = new SpyChangeDetectorRef(); + var ref = createApplication([]); + try { + ref.registerChangeDetector(cdRef); + cdRef.spy("detectChanges").andCallFake(() => ref.tick()); + expect(() => ref.tick()).toThrowError("ApplicationRef.tick is called recursively"); + } finally { + ref.unregisterChangeDetector(cdRef); } - } + }); - it("should merge syncronous and asyncronous providers", + describe('run', () => { + it('should rethrow errors even if the exceptionHandler is not rethrowing', () => { + 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, injector) => { + var ref = createApplication([]); + var promise = ref.run(() => PromiseWrapper.reject('Test', null)); + PromiseWrapper.catchError(promise, (e) => { + expect(e).toEqual('Test'); + async.done(); + }); + })); + }); + }); + + describe("coreLoadAndBootstrap", () => { + it("should wait for asynchronous app initializers", inject([AsyncTestCompleter, Injector], (async, injector) => { - let ref = new PlatformRef_(injector, null); - let ASYNC_PROVIDERS = [new Provider(Foo, {useValue: new Foo()}), exceptionHandler]; - let SYNC_PROVIDERS = [new Provider(Bar, {useValue: new Bar()})]; - ref.asyncApplication((zone) => PromiseWrapper.resolve(ASYNC_PROVIDERS), SYNC_PROVIDERS) - .then((appRef) => { - var providers = ListWrapper.concat(ASYNC_PROVIDERS, SYNC_PROVIDERS); - expectProviders(appRef.injector, providers); - async.done(); - }); - })); - - it("should allow function to be null", - inject([AsyncTestCompleter, Injector], (async, injector) => { - let ref = new PlatformRef_(injector, null); - let SYNC_PROVIDERS = [new Provider(Bar, {useValue: new Bar()}), exceptionHandler]; - ref.asyncApplication(null, SYNC_PROVIDERS) - .then((appRef) => { - expectProviders(appRef.injector, SYNC_PROVIDERS); - async.done(); - }); - })); - - function mockAsyncAppInitializer(completer: PromiseCompleter, - providers: Array = null, injector?: Injector) { - return () => { - if (providers != null) { - expectProviders(injector, providers); - } - TimerWrapper.setTimeout(() => completer.resolve(true), 1); - return completer.promise; - }; - } - - it("should wait for asyncronous app initializers", - inject([AsyncTestCompleter, Injector], (async, injector) => { - let ref = new PlatformRef_(injector, null); - let completer: PromiseCompleter = PromiseWrapper.completer(); - let SYNC_PROVIDERS = [ - new Provider(Bar, {useValue: new Bar()}), - new Provider(APP_INITIALIZER, - {useValue: mockAsyncAppInitializer(completer), multi: true}) - ]; - ref.asyncApplication(null, [SYNC_PROVIDERS, exceptionHandler]) - .then((appRef) => { - expectProviders(appRef.injector, - SYNC_PROVIDERS.slice(0, SYNC_PROVIDERS.length - 1)); - completer.promise.then((_) => async.done()); - }); - })); - - it("should wait for async providers and then async app initializers", - inject([AsyncTestCompleter, Injector], (async, injector) => { - let ref = new PlatformRef_(injector, null); - let ASYNC_PROVIDERS = [new Provider(Foo, {useValue: new Foo()})]; - let completer: PromiseCompleter = PromiseWrapper.completer(); - let SYNC_PROVIDERS = [ - new Provider(Bar, {useValue: new Bar()}), - new Provider(APP_INITIALIZER, - { - useFactory: (injector) => mockAsyncAppInitializer( - completer, ASYNC_PROVIDERS, injector), - multi: true, - deps: [Injector] - }) - ]; - ref.asyncApplication((zone) => PromiseWrapper.resolve(ASYNC_PROVIDERS), - [SYNC_PROVIDERS, exceptionHandler]) - .then((appRef) => { - expectProviders(appRef.injector, - SYNC_PROVIDERS.slice(0, SYNC_PROVIDERS.length - 1)); - completer.promise.then((_) => async.done()); + var initializerDone = false; + TimerWrapper.setTimeout(() => { + completer.resolve(true); + initializerDone = true; + }, 1); + var app = createApplication( + [new Provider(APP_INITIALIZER, {useValue: () => completer.promise, multi: true})]); + coreLoadAndBootstrap(app.injector, MyComp) + .then((compRef) => { + expect(initializerDone).toBe(true); + async.done(); }); })); }); - describe("application", () => { - it("should throw if an APP_INITIIALIZER returns a promise", inject([Injector], (injector) => { - let ref = new PlatformRef_(injector, null); - let appInitializer = new Provider( - APP_INITIALIZER, {useValue: () => PromiseWrapper.resolve([]), multi: true}); - expect(() => ref.application([appInitializer, exceptionHandler])) + describe("coreBootstrap", () => { + it("should throw if an APP_INITIIALIZER is not yet resolved", + inject([Injector], (injector) => { + var app = createApplication([ + new Provider(APP_INITIALIZER, + {useValue: () => PromiseWrapper.completer().promise, multi: true}) + ]); + expect(() => app.bootstrap(someCompFactory)) .toThrowError( - "Cannot use asyncronous app initializers with application. Use asyncApplication instead."); + "Cannot bootstrap as there are still asynchronous initializers running. Wait for them using waitForAsyncInitializers()."); })); }); }); } -class Foo { - constructor() {} +@Component({selector: 'my-comp', template: ''}) +class MyComp { } -class Bar { - constructor() {} +class _ArrayLogger { + res: any[] = []; + log(s: any): void { this.res.push(s); } + logError(s: any): void { this.res.push(s); } + logGroup(s: any): void { this.res.push(s); } + logGroupEnd(){}; +} + +class _MockComponentFactory extends ComponentFactory { + constructor(private _compRef: ComponentRef) { super(null, null, null); } + create(injector: Injector, projectableNodes: any[][] = null, + rootSelectorOrNode: string | any = null): ComponentRef { + return this._compRef; + } +} + +class _MockComponentResolver implements ComponentResolver { + constructor(private _compFactory: ComponentFactory) {} + + resolveComponent(type: Type): Promise { + return PromiseWrapper.resolve(this._compFactory); + } + clearCache() {} +} + +class _MockComponentRef extends ComponentRef_ { + constructor(private _injector: Injector) { super(null, null); } + get injector(): Injector { return this._injector; } + get changeDetectorRef(): ChangeDetectorRef { return new SpyChangeDetectorRef(); } + onDestroy(cb: Function) {} +} + +class _MockConsole implements Console { + log(message) {} } diff --git a/modules/angular2/test/core/linker/dynamic_component_loader_spec.ts b/modules/angular2/test/core/linker/dynamic_component_loader_spec.ts index 62ec28ce71..b37b97abcd 100644 --- a/modules/angular2/test/core/linker/dynamic_component_loader_spec.ts +++ b/modules/angular2/test/core/linker/dynamic_component_loader_spec.ts @@ -18,7 +18,6 @@ import { import {Predicate} from 'angular2/src/facade/collection'; import {Injector, OnDestroy, DebugElement, Type, ViewContainerRef, ViewChild} from 'angular2/core'; -import {NgIf} from 'angular2/common'; import {Component, ViewMetadata} from 'angular2/src/core/metadata'; import {DynamicComponentLoader} from 'angular2/src/core/linker/dynamic_component_loader'; import {ElementRef} from 'angular2/src/core/linker/element_ref'; diff --git a/modules/angular2/test/core/spies.ts b/modules/angular2/test/core/spies.ts index d52627cd93..938b7c2dd1 100644 --- a/modules/angular2/test/core/spies.ts +++ b/modules/angular2/test/core/spies.ts @@ -8,7 +8,11 @@ import {DomAdapter} from 'angular2/src/platform/dom/dom_adapter'; import {SpyObject, proxy} from 'angular2/testing_internal'; export class SpyChangeDetectorRef extends SpyObject { - constructor() { super(ChangeDetectorRef); } + constructor() { + super(ChangeDetectorRef); + this.spy('detectChanges'); + this.spy('checkNoChanges'); + } } export class SpyIterableDifferFactory extends SpyObject {} diff --git a/modules/angular2/test/core/zone/ng_zone_spec.ts b/modules/angular2/test/core/zone/ng_zone_spec.ts index 56829bdb02..dd9ddd3c49 100644 --- a/modules/angular2/test/core/zone/ng_zone_spec.ts +++ b/modules/angular2/test/core/zone/ng_zone_spec.ts @@ -685,12 +685,12 @@ function commonTests() { }); describe('exceptions', () => { - it('should call the on error callback when it is defined', + it('should call the on error callback when it is invoked via zone.runGuarded', inject([AsyncTestCompleter], (async) => { macroTask(() => { var exception = new BaseException('sync'); - _zone.run(() => { throw exception; }); + _zone.runGuarded(() => { throw exception; }); expect(_errors.length).toBe(1); expect(_errors[0]).toBe(exception); @@ -698,6 +698,17 @@ function commonTests() { }); }), testTimeout); + it('should not call the on error callback but rethrow when it is invoked via zone.run', + inject([AsyncTestCompleter], (async) => { + macroTask(() => { + var exception = new BaseException('sync'); + expect(() => _zone.run(() => { throw exception; })).toThrowError('sync'); + + expect(_errors.length).toBe(0); + async.done(); + }); + }), testTimeout); + it('should call onError for errors from microtasks', inject([AsyncTestCompleter], (async) => { var exception = new BaseException('async'); diff --git a/modules/angular2/test/platform/browser/bootstrap_spec.ts b/modules/angular2/test/platform/browser/bootstrap_spec.ts index 03b52daca8..923625a2a7 100644 --- a/modules/angular2/test/platform/browser/bootstrap_spec.ts +++ b/modules/angular2/test/platform/browser/bootstrap_spec.ts @@ -14,13 +14,22 @@ import { } from 'angular2/testing_internal'; import {IS_DART, isPresent, stringify} from 'angular2/src/facade/lang'; import {bootstrap, BROWSER_PROVIDERS, BROWSER_APP_PROVIDERS} from 'angular2/platform/browser'; -import {ApplicationRef} from 'angular2/src/core/application_ref'; +import {ApplicationRef, PlatformRef} from 'angular2/src/core/application_ref'; import {Console} from 'angular2/src/core/console'; -import {Component, Directive, OnDestroy, platform} from 'angular2/core'; +import {Component, Directive, OnDestroy} from 'angular2/core'; import {DOM} from 'angular2/src/platform/dom/dom_adapter'; import {DOCUMENT} from 'angular2/src/platform/dom/dom_tokens'; import {PromiseWrapper, TimerWrapper} from 'angular2/src/facade/async'; -import {provide, Inject, Injector, PLATFORM_INITIALIZER, APP_INITIALIZER} from 'angular2/core'; +import { + provide, + Inject, + Injector, + PLATFORM_INITIALIZER, + APP_INITIALIZER, + coreLoadAndBootstrap, + createPlatform, + ReflectiveInjector +} from 'angular2/core'; import {disposePlatform} from 'angular2/src/core/application_ref'; import {ExceptionHandler, BaseException} from 'angular2/src/facade/exceptions'; import {Testability, TestabilityRegistry} from 'angular2/src/core/testability/testability'; @@ -91,6 +100,8 @@ export function main() { describe('bootstrap factory method', () => { beforeEach(() => { + disposePlatform(); + fakeDoc = DOM.createHtmlDocument(); el = DOM.createElement('hello-app', fakeDoc); el2 = DOM.createElement('hello-app-2', fakeDoc); @@ -105,21 +116,16 @@ export function main() { afterEach(disposePlatform); - it('should throw if bootstrapped Directive is not a Component', - inject([AsyncTestCompleter], (async) => { - var logger = new _ArrayLogger(); - var exceptionHandler = new ExceptionHandler(logger, false); - var refPromise = - bootstrap(HelloRootDirectiveIsNotCmp, - [testProviders, provide(ExceptionHandler, {useValue: exceptionHandler})]); - - PromiseWrapper.then(refPromise, null, (exception) => { - expect(exception).toContainError( - `Could not compile '${stringify(HelloRootDirectiveIsNotCmp)}' because it is not a component.`); - expect(logger.res.join("")).toContain("Could not compile"); - async.done(); - }); - })); + it('should throw if bootstrapped Directive is not a Component', () => { + var logger = new _ArrayLogger(); + var exceptionHandler = new ExceptionHandler(logger, false); + expect( + () => bootstrap(HelloRootDirectiveIsNotCmp, + [testProviders, provide(ExceptionHandler, {useValue: exceptionHandler})])) + .toThrowError( + `Could not compile '${stringify(HelloRootDirectiveIsNotCmp)}' because it is not a component.`); + expect(logger.res.join("")).toContain("Could not compile"); + }); it('should throw if no element is found', inject([AsyncTestCompleter], (async) => { var logger = new _ArrayLogger(); @@ -201,8 +207,11 @@ export function main() { it('should unregister change detectors when components are disposed', inject([AsyncTestCompleter], (async) => { - var app = platform(BROWSER_PROVIDERS).application([BROWSER_APP_PROVIDERS, testProviders]); - app.bootstrap(HelloRootCmp) + var platform = createPlatform(ReflectiveInjector.resolveAndCreate(BROWSER_PROVIDERS)); + var app = ReflectiveInjector.resolveAndCreate([BROWSER_APP_PROVIDERS, testProviders], + platform.injector) + .get(ApplicationRef); + coreLoadAndBootstrap(app.injector, HelloRootCmp) .then((ref) => { ref.destroy(); expect(() => app.tick()).not.toThrow(); @@ -232,18 +241,21 @@ export function main() { })); it("should run platform initializers", inject([Log], (log: Log) => { - let p = platform([ + let p = createPlatform(ReflectiveInjector.resolveAndCreate([ BROWSER_PROVIDERS, provide(PLATFORM_INITIALIZER, {useValue: log.fn("platform_init1"), multi: true}), provide(PLATFORM_INITIALIZER, {useValue: log.fn("platform_init2"), multi: true}) - ]); + ])); expect(log.result()).toEqual("platform_init1; platform_init2"); log.clear(); - p.application([ - BROWSER_APP_PROVIDERS, - provide(APP_INITIALIZER, {useValue: log.fn("app_init1"), multi: true}), - provide(APP_INITIALIZER, {useValue: log.fn("app_init2"), multi: true}) - ]); + 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"); })); diff --git a/modules/angular2/test/public_api_spec.ts b/modules/angular2/test/public_api_spec.ts index 0865d0caf1..295e935d0b 100644 --- a/modules/angular2/test/public_api_spec.ts +++ b/modules/angular2/test/public_api_spec.ts @@ -140,7 +140,6 @@ var NG_COMPILER = [ ]; var NG_CORE = [ - 'APP_COMPONENT', 'APP_INITIALIZER', 'APP_ID', 'AngularEntrypoint:dart', @@ -261,7 +260,12 @@ var NG_CORE = [ 'provide', 'createNgZone', 'forwardRef:js', - 'platform', + 'coreBootstrap', + 'coreLoadAndBootstrap', + 'createPlatform', + 'disposePlatform', + 'getPlatform', + 'assertPlatform', 'resolveForwardRef:js', 'PLATFORM_COMMON_PROVIDERS', 'PLATFORM_INITIALIZER', @@ -306,6 +310,7 @@ var NG_PLATFORM_BROWSER = [ 'ELEMENT_PROBE_PROVIDERS_PROD_MODE', 'Title', 'bootstrap', + 'browserPlatform', 'disableDebugTools', 'enableDebugTools', 'inspectNativeElement' diff --git a/modules/angular2/test/router/integration/bootstrap_spec.ts b/modules/angular2/test/router/integration/bootstrap_spec.ts index bd908ed395..06bac9634d 100644 --- a/modules/angular2/test/router/integration/bootstrap_spec.ts +++ b/modules/angular2/test/router/integration/bootstrap_spec.ts @@ -54,7 +54,7 @@ export function main() { ]); // do not refactor out the `bootstrap` functionality. We still want to - // keep this test around so we can ensure that bootstrapping a router works + // keep this test around so we can ensure that bootstrap a router works it('should bootstrap a simple app', inject([AsyncTestCompleter], (async) => { var fakeDoc = DOM.createHtmlDocument(); var el = DOM.createElement('app-cmp', fakeDoc); diff --git a/modules/angular2/test/router/integration/impl/fixture_components.ts b/modules/angular2/test/router/integration/impl/fixture_components.ts index e7309523ee..a48a271e8d 100644 --- a/modules/angular2/test/router/integration/impl/fixture_components.ts +++ b/modules/angular2/test/router/integration/impl/fixture_components.ts @@ -153,7 +153,8 @@ export class DynamicLoaderCmp { this._componentRef.destroy(); this._componentRef = null; } - return this._dynamicComponentLoader.loadNextToLocation(DynamicallyLoadedComponent, viewport) + return this._dynamicComponentLoader.loadNextToLocation(DynamicallyLoadedComponent, + this.viewport) .then((cmp) => { this._componentRef = cmp; }); } } diff --git a/modules/angular2/test/web_workers/debug_tools/bootstrap.server.spec.dart b/modules/angular2/test/web_workers/debug_tools/bootstrap.server.spec.dart index faccfdaad7..a1e52159dd 100644 --- a/modules/angular2/test/web_workers/debug_tools/bootstrap.server.spec.dart +++ b/modules/angular2/test/web_workers/debug_tools/bootstrap.server.spec.dart @@ -19,8 +19,11 @@ main() { it("should be able to load in a Dart VM", () { reflector.reflectionCapabilities = new ReflectionCapabilities(); var buses = createPairedMessageBuses(); - platform([WORKER_APP_PLATFORM]) - .application([WORKER_APP_APPLICATION_COMMON]); + disposePlatform(); + var platform = createPlatform(ReflectiveInjector.resolveAndCreate(WORKER_APP_PLATFORM)); + var appInjector = ReflectiveInjector.resolveAndCreate(WORKER_APP_APPLICATION_COMMON, + platform.injector); + appInjector.get(ApplicationRef); }); }); } diff --git a/modules/angular2/web_worker/ui.ts b/modules/angular2/web_worker/ui.ts index 3b28fff8b8..da03fd637a 100644 --- a/modules/angular2/web_worker/ui.ts +++ b/modules/angular2/web_worker/ui.ts @@ -1,11 +1,6 @@ export * from 'angular2/src/facade/facade'; export * from '../src/core/di'; -export {platform, PlatformRef, ApplicationRef} from '../src/core/application_ref'; -export { - APP_ID, - APP_COMPONENT, - APP_INITIALIZER, - PLATFORM_INITIALIZER -} from '../src/core/application_tokens'; +export {PlatformRef, ApplicationRef} from '../src/core/application_ref'; +export {APP_ID, APP_INITIALIZER, PLATFORM_INITIALIZER} from '../src/core/application_tokens'; export * from '../src/core/zone'; export * from 'angular2/platform/worker_render'; diff --git a/modules/playground/src/animate/index.html b/modules/playground/src/animate/index.html index da2500d629..fc3f467a00 100644 --- a/modules/playground/src/animate/index.html +++ b/modules/playground/src/animate/index.html @@ -2,7 +2,6 @@ Animation Example - Loading... $SCRIPTS$ diff --git a/modules/playground/src/web_workers/images/background_index.dart b/modules/playground/src/web_workers/images/background_index.dart index a911d188ac..554e526d4c 100644 --- a/modules/playground/src/web_workers/images/background_index.dart +++ b/modules/playground/src/web_workers/images/background_index.dart @@ -9,8 +9,5 @@ import "package:angular2/src/core/reflection/reflection.dart"; main(List args, SendPort replyTo) { reflector.reflectionCapabilities = new ReflectionCapabilities(); - platform([ - WORKER_APP_PLATFORM, - new Provider(RENDER_SEND_PORT, useValue: replyTo) - ]).application([WORKER_APP_APPLICATION]).bootstrap(ImageDemo); + bootstrapApp(replyTo, ImageDemo); } diff --git a/modules/playground/src/web_workers/images/background_index.ts b/modules/playground/src/web_workers/images/background_index.ts index addba4ae4e..809362362f 100644 --- a/modules/playground/src/web_workers/images/background_index.ts +++ b/modules/playground/src/web_workers/images/background_index.ts @@ -1,7 +1,6 @@ import {ImageDemo} from "./index_common"; -import {platform} from "angular2/core"; -import {WORKER_APP_PLATFORM, WORKER_APP_APPLICATION} from "angular2/platform/worker_app"; +import {bootstrapApp} from "angular2/platform/worker_app"; export function main() { - platform([WORKER_APP_PLATFORM]).application([WORKER_APP_APPLICATION]).bootstrap(ImageDemo) -} \ No newline at end of file + bootstrapApp(ImageDemo); +} diff --git a/modules/playground/src/web_workers/images/index.dart b/modules/playground/src/web_workers/images/index.dart index f9073cabb8..fea8f54601 100644 --- a/modules/playground/src/web_workers/images/index.dart +++ b/modules/playground/src/web_workers/images/index.dart @@ -7,6 +7,5 @@ import "package:angular2/src/core/reflection/reflection.dart"; main() { reflector.reflectionCapabilities = new ReflectionCapabilities(); - platform([WORKER_RENDER_PLATFORM]) - .asyncApplication(initIsolate("background_index.dart")); + bootstrapRender("background_index.dart"); } diff --git a/modules/playground/src/web_workers/images/index.ts b/modules/playground/src/web_workers/images/index.ts index e158157e5f..8f860c46f2 100644 --- a/modules/playground/src/web_workers/images/index.ts +++ b/modules/playground/src/web_workers/images/index.ts @@ -1,9 +1,6 @@ -import {platform, Provider} from 'angular2/core'; +import {Provider} from 'angular2/core'; import { - WORKER_RENDER_APPLICATION, - WORKER_RENDER_PLATFORM, - WORKER_SCRIPT + bootstrapRender, } from 'angular2/platform/worker_render'; -platform([WORKER_RENDER_PLATFORM]) - .application([WORKER_RENDER_APPLICATION, new Provider(WORKER_SCRIPT, {useValue: "loader.js"})]); +bootstrapRender("loader.js"); diff --git a/modules/playground/src/web_workers/input/background_index.dart b/modules/playground/src/web_workers/input/background_index.dart index 58d7ecebb7..6a441e5b17 100644 --- a/modules/playground/src/web_workers/input/background_index.dart +++ b/modules/playground/src/web_workers/input/background_index.dart @@ -7,7 +7,5 @@ import "package:angular2/core.dart"; @AngularEntrypoint() main(List args, SendPort replyTo) { - platform([WORKER_APP_PLATFORM, new Provider(RENDER_SEND_PORT, useValue: replyTo)]) - .application([WORKER_APP_APPLICATION]) - .bootstrap(InputCmp); + bootstrapApp(replyTo, InputCmp); } diff --git a/modules/playground/src/web_workers/input/background_index.ts b/modules/playground/src/web_workers/input/background_index.ts index 84ec3dc468..d220fdf70c 100644 --- a/modules/playground/src/web_workers/input/background_index.ts +++ b/modules/playground/src/web_workers/input/background_index.ts @@ -1,7 +1,6 @@ import {InputCmp} from "./index_common"; -import {platform} from "angular2/core"; -import {WORKER_APP_PLATFORM, WORKER_APP_APPLICATION} from "angular2/platform/worker_app"; +import {bootstrapApp} from "angular2/platform/worker_app"; export function main() { - platform([WORKER_APP_PLATFORM]).application([WORKER_APP_APPLICATION]).bootstrap(InputCmp); + bootstrapApp(InputCmp); } diff --git a/modules/playground/src/web_workers/input/index.dart b/modules/playground/src/web_workers/input/index.dart index b6008efc27..9d4ff05446 100644 --- a/modules/playground/src/web_workers/input/index.dart +++ b/modules/playground/src/web_workers/input/index.dart @@ -5,6 +5,5 @@ import "package:angular2/core.dart"; @AngularEntrypoint() main() { - platform([WORKER_RENDER_PLATFORM]) - .asyncApplication(initIsolate("background_index.dart")); + bootstrapRender("background_index.dart"); } diff --git a/modules/playground/src/web_workers/input/index.ts b/modules/playground/src/web_workers/input/index.ts index e158157e5f..a3decb09c4 100644 --- a/modules/playground/src/web_workers/input/index.ts +++ b/modules/playground/src/web_workers/input/index.ts @@ -1,9 +1,4 @@ -import {platform, Provider} from 'angular2/core'; -import { - WORKER_RENDER_APPLICATION, - WORKER_RENDER_PLATFORM, - WORKER_SCRIPT -} from 'angular2/platform/worker_render'; +import {Provider} from 'angular2/core'; +import {bootstrapRender} from 'angular2/platform/worker_render'; -platform([WORKER_RENDER_PLATFORM]) - .application([WORKER_RENDER_APPLICATION, new Provider(WORKER_SCRIPT, {useValue: "loader.js"})]); +bootstrapRender("loader.js"); diff --git a/modules/playground/src/web_workers/kitchen_sink/background_index.dart b/modules/playground/src/web_workers/kitchen_sink/background_index.dart index 63098155c6..8ca65b5413 100644 --- a/modules/playground/src/web_workers/kitchen_sink/background_index.dart +++ b/modules/playground/src/web_workers/kitchen_sink/background_index.dart @@ -7,7 +7,5 @@ import "package:angular2/core.dart"; @AngularEntrypoint() main(List args, SendPort replyTo) { - platform([WORKER_APP_PLATFORM, new Provider(RENDER_SEND_PORT, useValue: replyTo)]) - .application([WORKER_APP_APPLICATION]) - .bootstrap(HelloCmp); + bootstrapApp(replyTo, HelloCmp); } diff --git a/modules/playground/src/web_workers/kitchen_sink/background_index.ts b/modules/playground/src/web_workers/kitchen_sink/background_index.ts index b59f76a443..fcfc99fb06 100644 --- a/modules/playground/src/web_workers/kitchen_sink/background_index.ts +++ b/modules/playground/src/web_workers/kitchen_sink/background_index.ts @@ -1,7 +1,6 @@ import {HelloCmp} from "./index_common"; -import {platform} from "angular2/core"; -import {WORKER_APP_PLATFORM, WORKER_APP_APPLICATION} from "angular2/platform/worker_app"; +import {bootstrapApp} from "angular2/platform/worker_app"; export function main() { - platform([WORKER_APP_PLATFORM]).application([WORKER_APP_APPLICATION]).bootstrap(HelloCmp); + bootstrapApp(HelloCmp); } \ No newline at end of file diff --git a/modules/playground/src/web_workers/kitchen_sink/index.dart b/modules/playground/src/web_workers/kitchen_sink/index.dart index 4d604cdcd6..7c7a4af15e 100644 --- a/modules/playground/src/web_workers/kitchen_sink/index.dart +++ b/modules/playground/src/web_workers/kitchen_sink/index.dart @@ -5,6 +5,5 @@ import "package:angular2/core.dart"; @AngularEntrypoint() main() { - platform([WORKER_RENDER_PLATFORM]) - .asyncApplication(initIsolate("background_index.dart")); + bootstrapRender("background_index.dart"); } diff --git a/modules/playground/src/web_workers/kitchen_sink/index.ts b/modules/playground/src/web_workers/kitchen_sink/index.ts index e158157e5f..a3decb09c4 100644 --- a/modules/playground/src/web_workers/kitchen_sink/index.ts +++ b/modules/playground/src/web_workers/kitchen_sink/index.ts @@ -1,9 +1,4 @@ -import {platform, Provider} from 'angular2/core'; -import { - WORKER_RENDER_APPLICATION, - WORKER_RENDER_PLATFORM, - WORKER_SCRIPT -} from 'angular2/platform/worker_render'; +import {Provider} from 'angular2/core'; +import {bootstrapRender} from 'angular2/platform/worker_render'; -platform([WORKER_RENDER_PLATFORM]) - .application([WORKER_RENDER_APPLICATION, new Provider(WORKER_SCRIPT, {useValue: "loader.js"})]); +bootstrapRender("loader.js"); diff --git a/modules/playground/src/web_workers/message_broker/background_index.dart b/modules/playground/src/web_workers/message_broker/background_index.dart index 7aba3b7066..aac1a08702 100644 --- a/modules/playground/src/web_workers/message_broker/background_index.dart +++ b/modules/playground/src/web_workers/message_broker/background_index.dart @@ -7,7 +7,5 @@ import "dart:isolate"; @AngularEntrypoint() main(List args, SendPort replyTo) { - platform([WORKER_APP_PLATFORM, new Provider(RENDER_SEND_PORT, useValue: replyTo)]) - .application([WORKER_APP_APPLICATION]) - .bootstrap(App); + bootstrapApp(replyTo, App); } diff --git a/modules/playground/src/web_workers/message_broker/background_index.ts b/modules/playground/src/web_workers/message_broker/background_index.ts index 4b12ba8cbb..becb9c7d64 100644 --- a/modules/playground/src/web_workers/message_broker/background_index.ts +++ b/modules/playground/src/web_workers/message_broker/background_index.ts @@ -1,7 +1,6 @@ -import {platform} from "angular2/core"; -import {WORKER_APP_PLATFORM, WORKER_APP_APPLICATION} from "angular2/platform/worker_app"; +import {bootstrapApp} from "angular2/platform/worker_app"; import {App} from "./index_common"; export function main() { - platform([WORKER_APP_PLATFORM]).application([WORKER_APP_APPLICATION]).bootstrap(App) + bootstrapApp(App); } diff --git a/modules/playground/src/web_workers/message_broker/index.dart b/modules/playground/src/web_workers/message_broker/index.dart index 4290811107..e3153aa3b9 100644 --- a/modules/playground/src/web_workers/message_broker/index.dart +++ b/modules/playground/src/web_workers/message_broker/index.dart @@ -7,8 +7,7 @@ import "dart:html"; @AngularEntrypoint() main() { const ECHO_CHANNEL = "ECHO"; - platform([WORKER_RENDER_PLATFORM]) - .asyncApplication(initIsolate("background_index.dart")) + bootstrapRender("background_index.dart") .then((ref) { var brokerFactory = ref.injector.get(ClientMessageBrokerFactory); var broker = brokerFactory.createMessageBroker(ECHO_CHANNEL, false); diff --git a/modules/playground/src/web_workers/message_broker/index.ts b/modules/playground/src/web_workers/message_broker/index.ts index 2d49b80d81..4127e536b2 100644 --- a/modules/playground/src/web_workers/message_broker/index.ts +++ b/modules/playground/src/web_workers/message_broker/index.ts @@ -1,8 +1,6 @@ -import {platform, Provider} from 'angular2/core'; +import {Provider, ApplicationRef} from 'angular2/core'; import { - WORKER_RENDER_APPLICATION, - WORKER_RENDER_PLATFORM, - WORKER_SCRIPT, + bootstrapRender, UiArguments, FnArg, PRIMITIVE, @@ -11,28 +9,28 @@ import { const ECHO_CHANNEL = "ECHO"; -let ref = - platform([WORKER_RENDER_PLATFORM]) - .application( - [WORKER_RENDER_APPLICATION, new Provider(WORKER_SCRIPT, {useValue: "loader.js"})]); -let brokerFactory: ClientMessageBrokerFactory = ref.injector.get(ClientMessageBrokerFactory); -var broker = brokerFactory.createMessageBroker(ECHO_CHANNEL, false); +bootstrapRender("loader.js").then((ref) => afterBootstrap(ref)); -document.getElementById("send_echo") - .addEventListener("click", (e) => { - var val = (document.getElementById("echo_input")).value; - // TODO(jteplitz602): Replace default constructors with real constructors - // once they're in the .d.ts file (#3926) - var args = new UiArguments("echo"); - args.method = "echo"; - var fnArg = new FnArg(val, PRIMITIVE); - fnArg.value = val; - fnArg.type = PRIMITIVE; - args.args = [fnArg]; +function afterBootstrap(ref: ApplicationRef) { + let brokerFactory: ClientMessageBrokerFactory = ref.injector.get(ClientMessageBrokerFactory); + var broker = brokerFactory.createMessageBroker(ECHO_CHANNEL, false); - broker.runOnService(args, PRIMITIVE) - .then((echo_result: string) => { - document.getElementById("echo_result").innerHTML = - `${echo_result}`; - }); - }); + document.getElementById("send_echo") + .addEventListener("click", (e) => { + var val = (document.getElementById("echo_input")).value; + // TODO(jteplitz602): Replace default constructors with real constructors + // once they're in the .d.ts file (#3926) + var args = new UiArguments("echo"); + args.method = "echo"; + var fnArg = new FnArg(val, PRIMITIVE); + fnArg.value = val; + fnArg.type = PRIMITIVE; + args.args = [fnArg]; + + broker.runOnService(args, PRIMITIVE) + .then((echo_result: string) => { + document.getElementById("echo_result").innerHTML = + `${echo_result}`; + }); + }); +} \ No newline at end of file diff --git a/modules/playground/src/web_workers/router/background_index.dart b/modules/playground/src/web_workers/router/background_index.dart index 8089e62558..d82470bbac 100644 --- a/modules/playground/src/web_workers/router/background_index.dart +++ b/modules/playground/src/web_workers/router/background_index.dart @@ -9,12 +9,5 @@ import "package:angular2/src/web_workers/worker/router_providers.dart"; @AngularEntrypoint() main(List args, SendPort replyTo) { - platform([ - WORKER_APP_PLATFORM, - new Provider(RENDER_SEND_PORT, useValue: replyTo) - ]).asyncApplication(null, [ - WORKER_APP_APPLICATION, - WORKER_APP_ROUTER, - new Provider(LocationStrategy, useClass: HashLocationStrategy) - ]).then((ref) => ref.bootstrap(App)); + bootstrapApp(replyTo, App, [WORKER_APP_ROUTER, new Provider(LocationStrategy, useClass: HashLocationStrategy)]); } diff --git a/modules/playground/src/web_workers/router/background_index.ts b/modules/playground/src/web_workers/router/background_index.ts index 5e67f44e32..19e2558e37 100644 --- a/modules/playground/src/web_workers/router/background_index.ts +++ b/modules/playground/src/web_workers/router/background_index.ts @@ -1,18 +1,9 @@ -import {platform, Provider, NgZone} from "angular2/core"; +import {Provider} from "angular2/core"; +import {bootstrapApp, WORKER_APP_ROUTER} from "angular2/platform/worker_app"; import {HashLocationStrategy, LocationStrategy} from 'angular2/platform/common'; -import { - WORKER_APP_PLATFORM, - WORKER_APP_APPLICATION, - WORKER_APP_ROUTER -} from "angular2/platform/worker_app"; import {App} from "./index_common"; export function main() { - let refPromise = platform([WORKER_APP_PLATFORM]) - .asyncApplication(null, [ - WORKER_APP_APPLICATION, - WORKER_APP_ROUTER, - new Provider(LocationStrategy, {useClass: HashLocationStrategy}) - ]); - refPromise.then((ref) => ref.bootstrap(App)); + bootstrapApp( + App, [WORKER_APP_ROUTER, new Provider(LocationStrategy, {useClass: HashLocationStrategy})]); } diff --git a/modules/playground/src/web_workers/router/index.dart b/modules/playground/src/web_workers/router/index.dart index 84b34c9819..0a8d66d5b7 100644 --- a/modules/playground/src/web_workers/router/index.dart +++ b/modules/playground/src/web_workers/router/index.dart @@ -8,6 +8,5 @@ import "package:angular2/src/core/reflection/reflection.dart"; @AngularEntrypoint() main() { reflector.reflectionCapabilities = new ReflectionCapabilities(); - platform([WORKER_RENDER_PLATFORM]).asyncApplication( - initIsolate("background_index.dart"), [WORKER_RENDER_ROUTER]); + bootstrapRender("background_index.dart", WORKER_RENDER_ROUTER); } diff --git a/modules/playground/src/web_workers/router/index.ts b/modules/playground/src/web_workers/router/index.ts index 35d5f75bcd..4a7fa3c2b4 100644 --- a/modules/playground/src/web_workers/router/index.ts +++ b/modules/playground/src/web_workers/router/index.ts @@ -1,15 +1,5 @@ -import {platform, Provider} from 'angular2/core'; -import { - WORKER_RENDER_APP, - WORKER_RENDER_PLATFORM, - WORKER_SCRIPT, - WORKER_RENDER_ROUTER -} from 'angular2/platform/worker_render'; +import {Provider} from 'angular2/core'; +import {bootstrapRender, WORKER_RENDER_ROUTER} from 'angular2/platform/worker_render'; import {MessageBasedPlatformLocation} from "angular2/src/web_workers/ui/platform_location"; -let ref = platform([WORKER_RENDER_PLATFORM]) - .application([ - WORKER_RENDER_APP, - new Provider(WORKER_SCRIPT, {useValue: "loader.js"}), - WORKER_RENDER_ROUTER - ]); +let ref = bootstrapRender("loader.js", WORKER_RENDER_ROUTER); diff --git a/modules/playground/src/web_workers/todo/background_index.dart b/modules/playground/src/web_workers/todo/background_index.dart index 6bcf955eed..c993676bf3 100644 --- a/modules/playground/src/web_workers/todo/background_index.dart +++ b/modules/playground/src/web_workers/todo/background_index.dart @@ -7,7 +7,5 @@ import "package:angular2/core.dart"; @AngularEntrypoint() main(List args, SendPort replyTo) { - platform([WORKER_APP_PLATFORM, new Provider(RENDER_SEND_PORT, useValue: replyTo)]) - .application([WORKER_APP_APPLICATION]) - .bootstrap(TodoApp); + bootstrapApp(replyTo, TodoApp); } diff --git a/modules/playground/src/web_workers/todo/background_index.ts b/modules/playground/src/web_workers/todo/background_index.ts index 5b4d630786..4f970529f8 100644 --- a/modules/playground/src/web_workers/todo/background_index.ts +++ b/modules/playground/src/web_workers/todo/background_index.ts @@ -1,7 +1,6 @@ import {TodoApp} from "./index_common"; -import {platform} from "angular2/core"; -import {WORKER_APP_PLATFORM, WORKER_APP_APPLICATION} from "angular2/platform/worker_app"; +import {bootstrapApp} from "angular2/platform/worker_app"; export function main() { - platform([WORKER_APP_PLATFORM]).application([WORKER_APP_APPLICATION]).bootstrap(TodoApp) + bootstrapApp(TodoApp); } diff --git a/modules/playground/src/web_workers/todo/index.dart b/modules/playground/src/web_workers/todo/index.dart index 601de4e4e4..cadcbd2706 100644 --- a/modules/playground/src/web_workers/todo/index.dart +++ b/modules/playground/src/web_workers/todo/index.dart @@ -5,6 +5,5 @@ import "package:angular2/core.dart"; @AngularEntrypoint() main() { - platform([WORKER_RENDER_PLATFORM]) - .asyncApplication(initIsolate("background_index.dart")); + bootstrapRender("background_index.dart"); } diff --git a/modules/playground/src/web_workers/todo/index.ts b/modules/playground/src/web_workers/todo/index.ts index f48911768f..d0e988ec80 100644 --- a/modules/playground/src/web_workers/todo/index.ts +++ b/modules/playground/src/web_workers/todo/index.ts @@ -1,9 +1,4 @@ -import {platform, Provider} from 'angular2/core'; -import { - WORKER_RENDER_APPLICATION, - WORKER_RENDER_PLATFORM, - WORKER_SCRIPT -} from 'angular2/platform/worker_render'; +import {Provider} from 'angular2/core'; +import {bootstrapRender} from 'angular2/platform/worker_render'; -platform([WORKER_RENDER_PLATFORM]) - .application([WORKER_RENDER_APPLICATION, new Provider(WORKER_SCRIPT, {useValue: "loader.js"})]); \ No newline at end of file +bootstrapRender("loader.js"); \ No newline at end of file diff --git a/modules/playground/src/web_workers/todo/index_web_socket.dart b/modules/playground/src/web_workers/todo/index_web_socket.dart index 882af0d3f0..694df99513 100644 --- a/modules/playground/src/web_workers/todo/index_web_socket.dart +++ b/modules/playground/src/web_workers/todo/index_web_socket.dart @@ -10,13 +10,15 @@ main() { var webSocket = new WebSocket("ws://127.0.0.1:1337/ws"); webSocket.onOpen.listen((e) { var bus = new WebSocketMessageBus.fromWebSocket(webSocket); - platform([WORKER_RENDER_PLATFORM]) - .application([WORKER_RENDER_APPLICATION_COMMON, new Provider(MessageBus, useValue: bus), - new Provider(APP_INITIALIZER, + var platform = createPlatform(ReflectiveInjector.resolveAndCreate(WORKER_RENDER_PLATFORM)); + var appInjector = ReflectiveInjector.resolveAndCreate([ + WORKER_RENDER_APPLICATION_COMMON, new Provider(MessageBus, useValue: bus), + new Provider(APP_INITIALIZER, useFactory: (injector) => () => initializeGenericWorkerRenderer(injector), deps: [Injector], multi: true ) - ]); + ], platform.injector); + appInjector.get(ApplicationRef); }); } diff --git a/modules/playground/src/web_workers/todo/server_index.dart b/modules/playground/src/web_workers/todo/server_index.dart index 5b3cd8be66..67d4c63287 100644 --- a/modules/playground/src/web_workers/todo/server_index.dart +++ b/modules/playground/src/web_workers/todo/server_index.dart @@ -15,12 +15,14 @@ void main() { print("Server Listening for requests on 127.0.0.1:1337"); var bus = new MultiClientServerMessageBus.fromHttpServer(server); - platform([WORKER_APP_PLATFORM]).application([ + var platform = createPlatform(ReflectiveInjector.resolveAndCreate(WORKER_APP_PLATFORM)); + var appInjector = ReflectiveInjector.resolveAndCreate([ WORKER_APP_APPLICATION_COMMON, new Provider(MessageBus, useValue: bus), new Provider(APP_INITIALIZER, useFactory: initAppThread, multi: true, deps: [NgZone, MessageBus]) - ]).bootstrap(TodoApp); + ], platform.injector); + coreLoadAndBootstrap(appInjector, TodoApp); }); } diff --git a/modules_dart/angular2_testing/lib/angular2_testing.dart b/modules_dart/angular2_testing/lib/angular2_testing.dart index 0e95d586d0..07fa13aee9 100644 --- a/modules_dart/angular2_testing/lib/angular2_testing.dart +++ b/modules_dart/angular2_testing/lib/angular2_testing.dart @@ -4,7 +4,7 @@ import 'package:test/test.dart'; import 'package:angular2/angular2.dart'; import 'package:angular2/src/core/di/metadata.dart' show InjectMetadata; -import 'package:angular2/src/core/di/exceptions.dart' show NoAnnotationError; +import 'package:angular2/src/core/di/reflective_exceptions.dart' show NoAnnotationError; import 'package:angular2/src/core/reflection/reflection.dart'; import 'package:angular2/src/core/reflection/reflection_capabilities.dart'; import 'package:angular2/src/testing/test_injector.dart'; diff --git a/modules_dart/transform/test/transform/integration/list_of_types_files/bar.dart b/modules_dart/transform/test/transform/integration/list_of_types_files/bar.dart index ab350b7641..5422f073a0 100644 --- a/modules_dart/transform/test/transform/integration/list_of_types_files/bar.dart +++ b/modules_dart/transform/test/transform/integration/list_of_types_files/bar.dart @@ -3,7 +3,7 @@ library bar; import 'package:angular2/src/core/metadata.dart'; import 'foo.dart'; -@Component(componentServices: const [MyContext]) +@Component(selector: 'my', providers: const [MyContext]) @View(template: '') class MyComponent { final MyContext c; diff --git a/tools/public_api_guard/public_api_spec.ts b/tools/public_api_guard/public_api_spec.ts index c9237137cf..c6284a7df9 100644 --- a/tools/public_api_guard/public_api_spec.ts +++ b/tools/public_api_guard/public_api_spec.ts @@ -29,13 +29,15 @@ const CORE = [ 'AfterViewInit', 'AfterViewInit.ngAfterViewInit():any', 'ApplicationRef', - 'ApplicationRef.bootstrap(componentType:Type, providers:Array):Promise', + 'ApplicationRef.bootstrap(componentFactory:ComponentFactory):ComponentRef', 'ApplicationRef.componentTypes:Type[]', 'ApplicationRef.dispose():void', 'ApplicationRef.injector:Injector', 'ApplicationRef.registerBootstrapListener(listener:(ref: ComponentRef) => void):void', 'ApplicationRef.registerDisposeListener(dispose:() => void):void', 'ApplicationRef.tick():void', + 'ApplicationRef.run(callback:Function):any', + 'ApplicationRef.waitForAsyncInitializers():Promise', 'ApplicationRef.zone:NgZone', 'AttributeMetadataFactory', 'AttributeMetadata', @@ -157,7 +159,7 @@ const CORE = [ 'DoCheck', 'DoCheck.ngDoCheck():any', 'DynamicComponentLoader', - 'DynamicComponentLoader.loadAsRoot(type:Type, overrideSelectorOrNode:string, injector:Injector, onDispose:() => void, projectableNodes:any[][]):Promise', + 'DynamicComponentLoader.loadAsRoot(type:Type, overrideSelectorOrNode:string|any, injector:Injector, onDispose:() => void, projectableNodes:any[][]):Promise', 'DynamicComponentLoader.loadNextToLocation(type:Type, location:ViewContainerRef, providers:ResolvedReflectiveProvider[], projectableNodes:any[][]):Promise', 'ElementRef', 'ElementRef.nativeElement:any', @@ -274,6 +276,7 @@ const CORE = [ 'NgZone.onMicrotaskEmpty:EventEmitter', 'NgZone.onUnstable:EventEmitter', 'NgZone.run(fn:() => any):any', + 'NgZone.runGuarded(fn:() => any):any', 'NgZone.runOutsideAngular(fn:() => any):any', 'NgZoneError', 'NgZoneError.constructor(error:any, stackTrace:any)', @@ -306,11 +309,10 @@ const CORE = [ 'PipeTransform', 'PipeTransform.transform(value:any, args:any[]):any', 'PlatformRef', - 'PlatformRef.application(providers:Array):ApplicationRef', - 'PlatformRef.asyncApplication(bindingFn:(zone: NgZone) => Promise>, providers:Array):Promise', 'PlatformRef.dispose():void', 'PlatformRef.injector:Injector', 'PlatformRef.registerDisposeListener(dispose:() => void):void', + 'PlatformRef.disposed:boolean', 'Provider', 'Provider.constructor(token:any, {useClass,useValue,useExisting,useFactory,deps,multi}:{useClass?:Type, useValue?:any, useExisting?:any, useFactory?:Function, deps?:Object[], multi?:boolean})', 'Provider.dependencies:Object[]', @@ -493,7 +495,6 @@ const CORE = [ 'WrappedValue.wrap(value:any):WrappedValue', 'bind(token:any):ProviderBuilder', 'const APPLICATION_COMMON_PROVIDERS:Array', - 'const APP_COMPONENT:OpaqueToken', 'const APP_ID:OpaqueToken', 'const APP_INITIALIZER:OpaqueToken', 'const PACKAGE_ROOT_URL:OpaqueToken', @@ -504,7 +505,12 @@ const CORE = [ 'createNgZone():NgZone', 'enableProdMode():any', 'forwardRef(forwardRefFn:ForwardRefFn):Type', - 'platform(providers:Array):PlatformRef', + 'coreBootstrap(injector:Injector, componentFactory:ComponentFactory):ComponentRef', + 'coreLoadAndBootstrap(injector:Injector, componentType:Type):Promise', + 'assertPlatform(requiredToken:any):PlatformRef', + 'createPlatform(injector:Injector):PlatformRef', + 'disposePlatform():void', + 'getPlatform():PlatformRef', 'provide(token:any, {useClass,useValue,useExisting,useFactory,deps,multi}:{useClass?:Type, useValue?:any, useExisting?:any, useFactory?:Function, deps?:Object[], multi?:boolean}):Provider', 'resolveForwardRef(type:any):any', 'setTestabilityGetter(getter:GetTestability):void', @@ -1210,7 +1216,8 @@ const BROWSER = [ 'const ELEMENT_PROBE_PROVIDERS_PROD_MODE:any[]', 'disableDebugTools():void', 'enableDebugTools(ref:ComponentRef):void', - 'inspectNativeElement(element:any):DebugNode' + 'inspectNativeElement(element:any):DebugNode', + 'browserStaticPlatform():PlatformRef' ]; describe('public API', () => {