fix(browser): platform code cleanup

This commit is contained in:
Victor Berchet
2016-05-20 16:11:49 -07:00
parent 9634e8d14a
commit 75e6dfb9ab
39 changed files with 626 additions and 821 deletions

View File

@ -0,0 +1,200 @@
import {
PLATFORM_INITIALIZER,
PLATFORM_DIRECTIVES,
PLATFORM_PIPES,
ExceptionHandler,
RootRenderer,
APPLICATION_COMMON_PROVIDERS,
PLATFORM_COMMON_PROVIDERS,
OpaqueToken,
Testability,
PlatformRef,
getPlatform,
createPlatform,
assertPlatform,
ReflectiveInjector,
reflector,
coreLoadAndBootstrap,
Type,
ComponentRef
} from "@angular/core";
import {isBlank, isPresent} from "./facade/lang";
import {wtfInit, SanitizationService, ReflectionCapabilities} from "../core_private";
import {COMMON_DIRECTIVES, COMMON_PIPES, FORM_PROVIDERS, PlatformLocation} from "@angular/common";
import {DomSanitizationService, DomSanitizationServiceImpl} from "./security/dom_sanitization_service";
import {BrowserDomAdapter} from "./browser/browser_adapter";
import {BrowserGetTestability} from "./browser/testability";
import {getDOM} from "./dom/dom_adapter";
import {DOCUMENT} from "./dom/dom_tokens";
import {EVENT_MANAGER_PLUGINS, EventManager} from "./dom/events/event_manager";
import {DomRootRenderer, DomRootRenderer_} from "./dom/dom_renderer";
import {SharedStylesHost, DomSharedStylesHost} from "./dom/shared_styles_host";
import {KeyEventsPlugin} from "./dom/events/key_events";
import {ELEMENT_PROBE_PROVIDERS} from "./dom/debug/ng_probe";
import {DomEventsPlugin} from "./dom/events/dom_events";
import {HAMMER_GESTURE_CONFIG, HammerGestureConfig, HammerGesturesPlugin} from "./dom/events/hammer_gestures";
import {AnimationBuilder} from "./animate/animation_builder";
import {BrowserDetails} from "./animate/browser_details";
import {BrowserPlatformLocation} from "./browser/location/browser_platform_location";
import {COMPILER_PROVIDERS, XHR} from "@angular/compiler";
import {CachedXHR} from "./xhr/xhr_cache";
import {XHRImpl} from "./xhr/xhr_impl";
export const CACHED_TEMPLATE_PROVIDER: Array<any /*Type | Provider | any[]*/> =
[{provide: XHR, useClass: CachedXHR}];
const BROWSER_PLATFORM_MARKER = 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_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
{provide: BROWSER_PLATFORM_MARKER, useValue: true},
PLATFORM_COMMON_PROVIDERS,
{provide: PLATFORM_INITIALIZER, useValue: initDomAdapter, multi: true},
{provide: PlatformLocation, useClass: BrowserPlatformLocation}
];
export const BROWSER_SANITIZATION_PROVIDERS: Array<any> = [
{provide: SanitizationService, useExisting: DomSanitizationService},
{provide: DomSanitizationService, useClass: DomSanitizationServiceImpl},
];
/**
* A set of providers to initialize an Angular application in a web browser.
*
* Used automatically by `bootstrap`, or can be passed to {@link PlatformRef.application}.
*/
export const BROWSER_APP_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
[
APPLICATION_COMMON_PROVIDERS,
FORM_PROVIDERS,
BROWSER_SANITIZATION_PROVIDERS,
{provide: PLATFORM_PIPES, useValue: COMMON_PIPES, multi: true},
{provide: PLATFORM_DIRECTIVES, useValue: COMMON_DIRECTIVES, multi: true},
{provide: ExceptionHandler, useFactory: _exceptionHandler, deps: []},
{provide: DOCUMENT, useFactory: _document, deps: []},
{provide: EVENT_MANAGER_PLUGINS, useClass: DomEventsPlugin, multi: true},
{provide: EVENT_MANAGER_PLUGINS, useClass: KeyEventsPlugin, multi: true},
{provide: EVENT_MANAGER_PLUGINS, useClass: HammerGesturesPlugin, multi: true},
{provide: HAMMER_GESTURE_CONFIG, useClass: HammerGestureConfig},
{provide: DomRootRenderer, useClass: DomRootRenderer_},
{provide: RootRenderer, useExisting: DomRootRenderer},
{provide: SharedStylesHost, useExisting: DomSharedStylesHost},
DomSharedStylesHost,
Testability,
BrowserDetails,
AnimationBuilder,
EventManager,
ELEMENT_PROBE_PROVIDERS
];
export const BROWSER_APP_COMPILER_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
[
COMPILER_PROVIDERS,
{provide: XHR, useClass: XHRImpl},
];
export function browserPlatform(): PlatformRef {
if (isBlank(getPlatform())) {
createPlatform(ReflectiveInjector.resolveAndCreate(BROWSER_PLATFORM_PROVIDERS));
}
return assertPlatform(BROWSER_PLATFORM_MARKER);
}
/**
* Bootstrapping for Angular applications.
*
* You instantiate an Angular application by explicitly specifying a component to use
* as the root component for your application via the `bootstrap()` method.
*
* ## Simple Example
*
* Assuming this `index.html`:
*
* ```html
* <html>
* <!-- load Angular script tags here. -->
* <body>
* <my-app>loading...</my-app>
* </body>
* </html>
* ```
*
* An application is bootstrapped inside an existing browser DOM, typically `index.html`.
* Unlike Angular 1, Angular 2 does not compile/process providers in `index.html`. This is
* mainly for security reasons, as well as architectural changes in Angular 2. This means
* that `index.html` can safely be processed using server-side technologies such as
* providers. Bindings can thus use double-curly `{{ syntax }}` without collision from
* Angular 2 component double-curly `{{ syntax }}`.
*
* We can use this script code:
*
* {@example core/ts/bootstrap/bootstrap.ts region='bootstrap'}
*
* When the app developer invokes `bootstrap()` with the root component `MyApp` as its
* argument, Angular performs the following tasks:
*
* 1. It uses the component's `selector` property to locate the DOM element which needs
* to be upgraded into the angular component.
* 2. It creates a new child injector (from the platform injector). Optionally, you can
* also override the injector configuration for an app by invoking `bootstrap` with the
* `componentInjectableBindings` argument.
* 3. It creates a new `Zone` and connects it to the angular application's change detection
* domain instance.
* 4. It creates an emulated or shadow DOM on the selected component's host element and loads the
* template into it.
* 5. It instantiates the specified component.
* 6. Finally, Angular performs change detection to apply the initial data providers for the
* application.
*
*
* ## Bootstrapping Multiple Applications
*
* When working within a browser window, there are many singleton resources: cookies, title,
* location, and others. Angular services that represent these resources must likewise be
* shared across all Angular applications that occupy the same browser window. For this
* reason, Angular creates exactly one global platform object which stores all shared
* services, and each angular application injector has the platform injector as its parent.
*
* Each application has its own private injector as well. When there are multiple
* applications on a page, Angular treats each application injector's services as private
* to that application.
*
* ## API
*
* - `appComponentType`: The root component which should act as the application. This is
* a reference to a `Type` which is annotated with `@Component(...)`.
* - `customProviders`: An additional set of providers that can be added to the
* app injector to override default injection behavior.
*
* Returns a `Promise` of {@link ComponentRef}.
*/
export function bootstrap(
appComponentType: Type,
customProviders?: Array<any /*Type | Provider | any[]*/>): Promise<ComponentRef<any>> {
reflector.reflectionCapabilities = new ReflectionCapabilities();
let providers = [
BROWSER_APP_PROVIDERS,
BROWSER_APP_COMPILER_PROVIDERS,
isPresent(customProviders) ? customProviders : []
];
var appInjector = ReflectiveInjector.resolveAndCreate(providers, browserPlatform().injector);
return coreLoadAndBootstrap(appComponentType, appInjector);
}
function initDomAdapter() {
BrowserDomAdapter.makeCurrent();
wtfInit();
BrowserGetTestability.init();
}
function _exceptionHandler(): ExceptionHandler {
return new ExceptionHandler(getDOM());
}
function _document(): any {
return getDOM().defaultDoc();
}

View File

@ -12,7 +12,7 @@ import {getDOM} from '../dom_adapter';
import {DomRootRenderer} from '../dom_renderer';
const CORE_TOKENS = /*@ts2dart_const*/ {'ApplicationRef': ApplicationRef, 'NgZone': NgZone};
const CORE_TOKENS = {'ApplicationRef': ApplicationRef, 'NgZone': NgZone};
const INSPECT_GLOBAL_NAME = 'ng.probe';
const CORE_TOKENS_GLOBAL_NAME = 'ng.coreTokens';
@ -42,16 +42,16 @@ function _createRootRenderer(rootRenderer) {
/**
* Providers which support debugging Angular applications (e.g. via `ng.probe`).
*/
export const ELEMENT_PROBE_PROVIDERS: any[] = /*@ts2dart_const*/[
/*@ts2dart_Provider*/ {
export const ELEMENT_PROBE_PROVIDERS: any[] = [
{
provide: RootRenderer,
useFactory: _createConditionalRootRenderer,
deps: [DomRootRenderer]
}
];
export const ELEMENT_PROBE_PROVIDERS_PROD_MODE: any[] = /*@ts2dart_const*/[
/*@ts2dart_Provider*/ {
export const ELEMENT_PROBE_PROVIDERS_PROD_MODE: any[] = [
{
provide: RootRenderer,
useFactory: _createRootRenderer,
deps: [DomRootRenderer]

View File

@ -28,7 +28,6 @@ import {getDOM} from './dom_adapter';
import {camelCaseToDashCase} from './util';
const NAMESPACE_URIS =
/*@ts2dart_const*/
{'xlink': 'http://www.w3.org/1999/xlink', 'svg': 'http://www.w3.org/2000/svg'};
const TEMPLATE_COMMENT_TEXT = 'template bindings={}';
var TEMPLATE_BINDINGS_EXP = /^template bindings=(.*)$/g;
@ -304,8 +303,8 @@ function decoratePreventDefault(eventHandler: Function): Function {
var COMPONENT_REGEX = /%COMP%/g;
export const COMPONENT_VARIABLE = '%COMP%';
export const HOST_ATTR = /*@ts2dart_const*/ `_nghost-${COMPONENT_VARIABLE}`;
export const CONTENT_ATTR = /*@ts2dart_const*/ `_ngcontent-${COMPONENT_VARIABLE}`;
export const HOST_ATTR = `_nghost-${COMPONENT_VARIABLE}`;
export const CONTENT_ATTR = `_ngcontent-${COMPONENT_VARIABLE}`;
function _shimContentAttribute(componentShortId: string): string {
return StringWrapper.replaceAll(CONTENT_ATTR, COMPONENT_REGEX, componentShortId);

View File

@ -6,4 +6,4 @@ import {OpaqueToken} from '@angular/core';
* Note: Document might not be available in the Application Context when Application and Rendering
* Contexts are not the same (e.g. when running the application into a Web Worker).
*/
export const DOCUMENT: OpaqueToken = /*@ts2dart_const*/ new OpaqueToken('DocumentToken');
export const DOCUMENT: OpaqueToken = new OpaqueToken('DocumentToken');

View File

@ -4,8 +4,7 @@ import {BaseException} from '../../../src/facade/exceptions';
import {ListWrapper} from '../../../src/facade/collection';
export const EVENT_MANAGER_PLUGINS: OpaqueToken =
/*@ts2dart_const*/ new OpaqueToken("EventManagerPlugins");
export const EVENT_MANAGER_PLUGINS: OpaqueToken = new OpaqueToken("EventManagerPlugins");
@Injectable()
export class EventManager {

View File

@ -3,8 +3,7 @@ import {isPresent} from '../../../src/facade/lang';
import {BaseException} from '../../../src/facade/exceptions';
import {HammerGesturesPluginCommon} from './hammer_common';
export const HAMMER_GESTURE_CONFIG: OpaqueToken =
/*@ts2dart_const*/ new OpaqueToken("HammerGestureConfig");
export const HAMMER_GESTURE_CONFIG: OpaqueToken = new OpaqueToken("HammerGestureConfig");
export interface HammerInstance {
on(eventName: string, callback: Function): void;

View File

@ -1,104 +0,0 @@
import {
PLATFORM_INITIALIZER,
PLATFORM_DIRECTIVES,
PLATFORM_PIPES,
ExceptionHandler,
RootRenderer,
APPLICATION_COMMON_PROVIDERS,
PLATFORM_COMMON_PROVIDERS,
OpaqueToken,
Testability,
PlatformRef,
getPlatform,
createPlatform,
assertPlatform,
ReflectiveInjector
} from "@angular/core";
import {isBlank} from "../../facade/lang";
import {wtfInit, SanitizationService} from "../../../core_private";
import {COMMON_DIRECTIVES, COMMON_PIPES, FORM_PROVIDERS, PlatformLocation} from "@angular/common";
import {DomSanitizationService, DomSanitizationServiceImpl} from "../../security/dom_sanitization_service";
import {BrowserDomAdapter} from "../../browser/browser_adapter";
import {BrowserGetTestability} from "../../browser/testability";
import {getDOM} from "../../dom/dom_adapter";
import {DOCUMENT} from "../../dom/dom_tokens";
import {EVENT_MANAGER_PLUGINS, EventManager} from "../../dom/events/event_manager";
import {DomRootRenderer, DomRootRenderer_} from "../../dom/dom_renderer";
import {SharedStylesHost, DomSharedStylesHost} from "../../dom/shared_styles_host";
import {KeyEventsPlugin} from "../../dom/events/key_events";
import {ELEMENT_PROBE_PROVIDERS} from "../../dom/debug/ng_probe";
import {DomEventsPlugin} from "../../dom/events/dom_events";
import {HAMMER_GESTURE_CONFIG, HammerGestureConfig, HammerGesturesPlugin} from "../../dom/events/hammer_gestures";
import {AnimationBuilder} from "../../animate/animation_builder";
import {BrowserDetails} from "../../animate/browser_details";
import {BrowserPlatformLocation} from "../../browser/location/browser_platform_location";
const BROWSER_PLATFORM_MARKER =
/*@ts2dart_const*/ 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_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> = /*@ts2dart_const*/[
/*@ts2dart_Provider*/ {provide: BROWSER_PLATFORM_MARKER, useValue: true},
PLATFORM_COMMON_PROVIDERS,
/*@ts2dart_Provider*/ {provide: PLATFORM_INITIALIZER, useValue: initDomAdapter, multi: true},
/*@ts2dart_Provider*/ {provide: PlatformLocation, useClass: BrowserPlatformLocation}
];
export const BROWSER_SANITIZATION_PROVIDERS: Array<any> = /*@ts2dart_const*/[
/* @ts2dart_Provider */ {provide: SanitizationService, useExisting: DomSanitizationService},
/* @ts2dart_Provider */ {provide: DomSanitizationService, useClass: DomSanitizationServiceImpl},
];
/**
* A set of providers to initialize an Angular application in a web browser.
*
* Used automatically by `bootstrap`, or can be passed to {@link PlatformRef.application}.
*/
export const BROWSER_APP_COMMON_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
/*@ts2dart_const*/[
APPLICATION_COMMON_PROVIDERS,
FORM_PROVIDERS,
BROWSER_SANITIZATION_PROVIDERS,
/* @ts2dart_Provider */ {provide: PLATFORM_PIPES, useValue: COMMON_PIPES, multi: true},
/* @ts2dart_Provider */ {provide: PLATFORM_DIRECTIVES, useValue: COMMON_DIRECTIVES, multi: true},
/* @ts2dart_Provider */ {provide: ExceptionHandler, useFactory: _exceptionHandler, deps: []},
/* @ts2dart_Provider */ {provide: DOCUMENT, useFactory: _document, deps: []},
/* @ts2dart_Provider */ {provide: EVENT_MANAGER_PLUGINS, useClass: DomEventsPlugin, multi: true},
/* @ts2dart_Provider */ {provide: EVENT_MANAGER_PLUGINS, useClass: KeyEventsPlugin, multi: true},
/* @ts2dart_Provider */ {provide: EVENT_MANAGER_PLUGINS, useClass: HammerGesturesPlugin, multi: true},
/* @ts2dart_Provider */ {provide: HAMMER_GESTURE_CONFIG, useClass: HammerGestureConfig},
/* @ts2dart_Provider */ {provide: DomRootRenderer, useClass: DomRootRenderer_},
/* @ts2dart_Provider */ {provide: RootRenderer, useExisting: DomRootRenderer},
/* @ts2dart_Provider */ {provide: SharedStylesHost, useExisting: DomSharedStylesHost},
DomSharedStylesHost,
Testability,
BrowserDetails,
AnimationBuilder,
EventManager,
ELEMENT_PROBE_PROVIDERS
];
export function browserPlatform(): PlatformRef {
if (isBlank(getPlatform())) {
createPlatform(ReflectiveInjector.resolveAndCreate(BROWSER_PLATFORM_PROVIDERS));
}
return assertPlatform(BROWSER_PLATFORM_MARKER);
}
function initDomAdapter() {
BrowserDomAdapter.makeCurrent();
wtfInit();
BrowserGetTestability.init();
}
function _exceptionHandler(): ExceptionHandler {
return new ExceptionHandler(getDOM());
}
function _document(): any {
return getDOM().defaultDoc();
}

View File

@ -1,74 +0,0 @@
import {WebWorkerRootRenderer} from '../../web_workers/worker/renderer';
import {print, isBlank} from '../../../src/facade/lang';
import {
PLATFORM_DIRECTIVES,
PLATFORM_PIPES,
ExceptionHandler,
APPLICATION_COMMON_PROVIDERS,
PLATFORM_COMMON_PROVIDERS,
OpaqueToken,
RootRenderer,
PlatformRef,
getPlatform,
createPlatform,
assertPlatform,
ReflectiveInjector
} from '@angular/core';
import {COMMON_DIRECTIVES, COMMON_PIPES, FORM_PROVIDERS} from '@angular/common';
import {
ClientMessageBrokerFactory,
ClientMessageBrokerFactory_
} from '../../web_workers/shared/client_message_broker';
import {
ServiceMessageBrokerFactory,
ServiceMessageBrokerFactory_
} from '../../web_workers/shared/service_message_broker';
import {Serializer} from '../../web_workers/shared/serializer';
import {ON_WEB_WORKER} from '../../web_workers/shared/api';
import {RenderStore} from '../../web_workers/shared/render_store';
import {BROWSER_SANITIZATION_PROVIDERS} from './browser';
class PrintLogger {
log = print;
logError = print;
logGroup = print;
logGroupEnd() {}
}
const WORKER_APP_PLATFORM_MARKER =
/*@ts2dart_const*/ new OpaqueToken('WorkerAppPlatformMarker');
export const WORKER_APP_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
/*@ts2dart_const*/[
PLATFORM_COMMON_PROVIDERS,
/*@ts2dart_const*/ (
/* @ts2dart_Provider */ {provide: WORKER_APP_PLATFORM_MARKER, useValue: true})
];
export const WORKER_APP_APPLICATION_COMMON_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
/*@ts2dart_const*/[
APPLICATION_COMMON_PROVIDERS,
FORM_PROVIDERS,
BROWSER_SANITIZATION_PROVIDERS,
Serializer,
/* @ts2dart_Provider */ {provide: PLATFORM_PIPES, useValue: COMMON_PIPES, multi: true},
/* @ts2dart_Provider */ {provide: PLATFORM_DIRECTIVES, useValue: COMMON_DIRECTIVES, multi: true},
/* @ts2dart_Provider */ {provide: ClientMessageBrokerFactory, useClass: ClientMessageBrokerFactory_},
/* @ts2dart_Provider */ {provide: ServiceMessageBrokerFactory, useClass: ServiceMessageBrokerFactory_},
WebWorkerRootRenderer,
/* @ts2dart_Provider */ {provide: RootRenderer, useExisting: WebWorkerRootRenderer},
/* @ts2dart_Provider */ {provide: ON_WEB_WORKER, useValue: true},
RenderStore,
/* @ts2dart_Provider */ {provide: ExceptionHandler, useFactory: _exceptionHandler, deps: []}
];
export function workerAppPlatform(): PlatformRef {
if (isBlank(getPlatform())) {
createPlatform(ReflectiveInjector.resolveAndCreate(WORKER_APP_PLATFORM_PROVIDERS));
}
return assertPlatform(WORKER_APP_PLATFORM_MARKER);
}
function _exceptionHandler(): ExceptionHandler {
return new ExceptionHandler(new PrintLogger());
}

View File

@ -1,121 +0,0 @@
import {isBlank} from "../../../src/facade/lang";
import {MessageBus} from "../../web_workers/shared/message_bus";
import {
NgZone,
Injector,
OpaqueToken,
Testability,
ExceptionHandler,
APPLICATION_COMMON_PROVIDERS,
PLATFORM_COMMON_PROVIDERS,
RootRenderer,
PLATFORM_INITIALIZER,
PlatformRef,
getPlatform,
createPlatform,
assertPlatform,
ReflectiveInjector
} from "@angular/core";
import {wtfInit} from "../../../core_private";
import {getDOM} from "../../dom/dom_adapter";
import {DomEventsPlugin} from "../../dom/events/dom_events";
import {KeyEventsPlugin} from "../../dom/events/key_events";
import {HammerGesturesPlugin, HAMMER_GESTURE_CONFIG, HammerGestureConfig} from "../../dom/events/hammer_gestures";
import {DOCUMENT} from "../../dom/dom_tokens";
import {DomRootRenderer, DomRootRenderer_} from "../../dom/dom_renderer";
import {DomSharedStylesHost, SharedStylesHost} from "../../dom/shared_styles_host";
import {BrowserDetails} from "../../animate/browser_details";
import {AnimationBuilder} from "../../animate/animation_builder";
import {BrowserGetTestability} from "../../browser/testability";
import {BrowserDomAdapter} from "../../browser/browser_adapter";
import {MessageBasedRenderer} from "../../web_workers/ui/renderer";
import {
ServiceMessageBrokerFactory,
ServiceMessageBrokerFactory_
} from "../../web_workers/shared/service_message_broker";
import {ClientMessageBrokerFactory, ClientMessageBrokerFactory_} from "../../web_workers/shared/client_message_broker";
import {Serializer} from "../../web_workers/shared/serializer";
import {ON_WEB_WORKER} from "../../web_workers/shared/api";
import {RenderStore} from "../../web_workers/shared/render_store";
import {EventManager, EVENT_MANAGER_PLUGINS} from "../../dom/events/event_manager";
import {BROWSER_SANITIZATION_PROVIDERS} from "../common/browser";
const WORKER_RENDER_PLATFORM_MARKER =
/*@ts2dart_const*/ new OpaqueToken('WorkerRenderPlatformMarker');
export const WORKER_SCRIPT: OpaqueToken = /*@ts2dart_const*/ new OpaqueToken("WebWorkerScript");
/**
* A multiple providers used to automatically call the `start()` method after the service is
* created.
*
* TODO(vicb): create an interface for startable services to implement
*/
export const WORKER_RENDER_STARTABLE_MESSAGING_SERVICE =
/*@ts2dart_const*/ new OpaqueToken('WorkerRenderStartableMsgService');
export const WORKER_RENDER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> = /*@ts2dart_const*/[
PLATFORM_COMMON_PROVIDERS,
/*@ts2dart_const*/ (/* @ts2dart_Provider */ {provide: WORKER_RENDER_PLATFORM_MARKER, useValue: true}),
/* @ts2dart_Provider */ {provide: PLATFORM_INITIALIZER, useValue: initWebWorkerRenderPlatform, multi: true}
];
export const WORKER_RENDER_APPLICATION_COMMON_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
/*@ts2dart_const*/[
APPLICATION_COMMON_PROVIDERS,
MessageBasedRenderer,
/* @ts2dart_Provider */ {provide: WORKER_RENDER_STARTABLE_MESSAGING_SERVICE, useExisting: MessageBasedRenderer, multi: true},
BROWSER_SANITIZATION_PROVIDERS,
/* @ts2dart_Provider */ {provide: ExceptionHandler, useFactory: _exceptionHandler, deps: []},
/* @ts2dart_Provider */ {provide: DOCUMENT, useFactory: _document, deps: []},
// TODO(jteplitz602): Investigate if we definitely need EVENT_MANAGER on the render thread
// #5298
/* @ts2dart_Provider */ {provide: EVENT_MANAGER_PLUGINS, useClass: DomEventsPlugin, multi: true},
/* @ts2dart_Provider */ {provide: EVENT_MANAGER_PLUGINS, useClass: KeyEventsPlugin, multi: true},
/* @ts2dart_Provider */ {provide: EVENT_MANAGER_PLUGINS, useClass: HammerGesturesPlugin, multi: true},
/* @ts2dart_Provider */ {provide: HAMMER_GESTURE_CONFIG, useClass: HammerGestureConfig},
/* @ts2dart_Provider */ {provide: DomRootRenderer, useClass: DomRootRenderer_},
/* @ts2dart_Provider */ {provide: RootRenderer, useExisting: DomRootRenderer},
/* @ts2dart_Provider */ {provide: SharedStylesHost, useExisting: DomSharedStylesHost},
/* @ts2dart_Provider */ {provide: ServiceMessageBrokerFactory, useClass: ServiceMessageBrokerFactory_},
/* @ts2dart_Provider */ {provide: ClientMessageBrokerFactory, useClass: ClientMessageBrokerFactory_},
Serializer,
/* @ts2dart_Provider */ {provide: ON_WEB_WORKER, useValue: false},
RenderStore,
DomSharedStylesHost,
Testability,
BrowserDetails,
AnimationBuilder,
EventManager
];
export function initializeGenericWorkerRenderer(injector: Injector) {
var bus = injector.get(MessageBus);
let zone = injector.get(NgZone);
bus.attachToZone(zone);
// initialize message services after the bus has been created
let services = injector.get(WORKER_RENDER_STARTABLE_MESSAGING_SERVICE);
zone.runGuarded(() => { services.forEach((svc) => { svc.start(); }); });
}
function initWebWorkerRenderPlatform(): void {
BrowserDomAdapter.makeCurrent();
wtfInit();
BrowserGetTestability.init();
}
export function workerRenderPlatform(): PlatformRef {
if (isBlank(getPlatform())) {
createPlatform(ReflectiveInjector.resolveAndCreate(WORKER_RENDER_PLATFORM_PROVIDERS));
}
return assertPlatform(WORKER_RENDER_PLATFORM_MARKER);
}
function _exceptionHandler(): ExceptionHandler {
return new ExceptionHandler(getDOM());
}
function _document(): any {
return getDOM().defaultDoc();
}

View File

@ -1,106 +0,0 @@
import {
reflector,
ReflectiveInjector,
coreLoadAndBootstrap,
Type,
ComponentRef
} from '@angular/core';
import {COMPILER_PROVIDERS, XHR} from '@angular/compiler';
import {CachedXHR} from '../../../src/xhr/xhr_cache';
import {isPresent} from '../../../src/facade/lang';
import {XHRImpl} from '../../../src/xhr/xhr_impl';
import {browserPlatform, BROWSER_APP_COMMON_PROVIDERS} from '../common/browser';
import {ReflectionCapabilities} from '../../../core_private';
export const CACHED_TEMPLATE_PROVIDER: Array<any /*Type | Provider | any[]*/> =
/*@ts2dart_const*/[{provide: XHR, useClass: CachedXHR}];
/**
* An array of providers that should be passed into `application()` when bootstrapping a component.
*/
export const BROWSER_APP_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
/*@ts2dart_const*/[
BROWSER_APP_COMMON_PROVIDERS,
COMPILER_PROVIDERS,
{provide: XHR, useClass: XHRImpl},
];
/**
* Bootstrapping for Angular applications.
*
* You instantiate an Angular application by explicitly specifying a component to use
* as the root component for your application via the `bootstrap()` method.
*
* ## Simple Example
*
* Assuming this `index.html`:
*
* ```html
* <html>
* <!-- load Angular script tags here. -->
* <body>
* <my-app>loading...</my-app>
* </body>
* </html>
* ```
*
* An application is bootstrapped inside an existing browser DOM, typically `index.html`.
* Unlike Angular 1, Angular 2 does not compile/process providers in `index.html`. This is
* mainly for security reasons, as well as architectural changes in Angular 2. This means
* that `index.html` can safely be processed using server-side technologies such as
* providers. Bindings can thus use double-curly `{{ syntax }}` without collision from
* Angular 2 component double-curly `{{ syntax }}`.
*
* We can use this script code:
*
* {@example core/ts/bootstrap/bootstrap.ts region='bootstrap'}
*
* When the app developer invokes `bootstrap()` with the root component `MyApp` as its
* argument, Angular performs the following tasks:
*
* 1. It uses the component's `selector` property to locate the DOM element which needs
* to be upgraded into the angular component.
* 2. It creates a new child injector (from the platform injector). Optionally, you can
* also override the injector configuration for an app by invoking `bootstrap` with the
* `customProviders` argument.
* 3. It creates a new `Zone` and connects it to the angular application's change detection
* domain instance.
* 4. It creates an emulated or shadow DOM on the selected component's host element and loads the
* template into it.
* 5. It instantiates the specified component.
* 6. Finally, Angular performs change detection to apply the initial data providers for the
* application.
*
*
* ## Bootstrapping Multiple Applications
*
* When working within a browser window, there are many singleton resources: cookies, title,
* location, and others. Angular services that represent these resources must likewise be
* shared across all Angular applications that occupy the same browser window. For this
* reason, Angular creates exactly one global platform object which stores all shared
* services, and each angular application injector has the platform injector as its parent.
*
* Each application has its own private injector as well. When there are multiple
* applications on a page, Angular treats each application injector's services as private
* to that application.
*
* ## API
*
* - `appComponentType`: The root component which should act as the application. This is
* a reference to a `Type` which is annotated with `@Component(...)`.
* - `customProviders`: An additional set of providers that can be added to the
* app injector to override default injection behavior.
*
* Returns a `Promise` of {@link ComponentRef}.
*/
export function bootstrap(
appComponentType: Type,
customProviders?: Array<any /*Type | Provider | any[]*/>): Promise<ComponentRef<any>> {
reflector.reflectionCapabilities = new ReflectionCapabilities();
var appInjector = ReflectiveInjector.resolveAndCreate(
[BROWSER_APP_PROVIDERS, isPresent(customProviders) ? customProviders : []],
browserPlatform().injector);
return coreLoadAndBootstrap(appComponentType, appInjector);
}

View File

@ -1,27 +0,0 @@
import {WORKER_APP_STATIC_APPLICATION_PROVIDERS} from '../static/worker_app';
import {workerAppPlatform} from '../common/worker_app';
import {COMPILER_PROVIDERS, XHR} from '@angular/compiler';
import {XHRImpl} from '../../xhr/xhr_impl';
import {isPresent} from '../../facade/lang';
import {
Type,
ComponentRef,
ReflectiveInjector,
coreLoadAndBootstrap,
} from '@angular/core';
export const WORKER_APP_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
WORKER_APP_STATIC_APPLICATION_PROVIDERS,
COMPILER_PROVIDERS,
/* @ts2dart_Provider */ {provide: XHR, useClass: XHRImpl},
];
export function bootstrapApp(
appComponentType: Type,
customProviders?: Array<any /*Type | Provider | any[]*/>): Promise<ComponentRef<any>> {
var appInjector = ReflectiveInjector.resolveAndCreate(
[WORKER_APP_APPLICATION_PROVIDERS, isPresent(customProviders) ? customProviders : []],
workerAppPlatform().injector);
return coreLoadAndBootstrap(appComponentType, appInjector);
}

View File

@ -1,25 +0,0 @@
import {WORKER_RENDER_STATIC_APPLICATION_PROVIDERS} from "../static/worker_render";
import {ApplicationRef, ReflectiveInjector} from "@angular/core";
import {workerRenderPlatform, WORKER_SCRIPT} from "../common/worker_render";
import {isPresent} from "../../facade/lang";
import {PromiseWrapper} from "../../facade/async";
export const WORKER_RENDER_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
WORKER_RENDER_STATIC_APPLICATION_PROVIDERS
];
export function bootstrapRender(
workerScriptUri: string,
customProviders?: Array<any /*Type | Provider | any[]*/>): Promise<ApplicationRef> {
var app = ReflectiveInjector.resolveAndCreate(
[
WORKER_RENDER_APPLICATION_PROVIDERS,
/* @ts2dart_Provider */ {provide: 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));
}

View File

@ -1,34 +0,0 @@
import {
ComponentRef,
coreLoadAndBootstrap,
ReflectiveInjector
} from '@angular/core';
import {Type, isPresent} from '../../facade/lang';
import {
BROWSER_APP_COMMON_PROVIDERS,
browserPlatform
} from '../common/browser';
/**
* An array of providers that should be passed into `application()` when bootstrapping a component
* when all templates have been pre-compiled.
*/
export const BROWSER_APP_STATIC_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
/*@ts2dart_const*/ BROWSER_APP_COMMON_PROVIDERS;
/**
* See {@link bootstrap} for more information.
*/
export function bootstrapStatic(appComponentType: Type,
customProviders?: Array<any /*Type | Provider | any[]*/>,
initReflector?: Function): Promise<ComponentRef<any>> {
if (isPresent(initReflector)) {
initReflector();
}
let appProviders = isPresent(customProviders) ? [BROWSER_APP_STATIC_PROVIDERS, customProviders] :
BROWSER_APP_STATIC_PROVIDERS;
var appInjector =
ReflectiveInjector.resolveAndCreate(appProviders, browserPlatform().injector);
return coreLoadAndBootstrap(appComponentType, appInjector);
}

View File

@ -1,45 +0,0 @@
import {APP_INITIALIZER, NgZone, ReflectiveInjector, ComponentRef, coreLoadAndBootstrap} from '@angular/core';
import {Type, isPresent} from '../../../src/facade/lang';
import {workerAppPlatform} from '../common/worker_app';
import {WorkerDomAdapter} from '../../web_workers/worker/worker_adapter';
import {
PostMessageBus,
PostMessageBusSink,
PostMessageBusSource
} from '../../web_workers/shared/post_message_bus';
import {WORKER_APP_APPLICATION_COMMON_PROVIDERS} from '../common/worker_app';
import {MessageBus} from '../../web_workers/shared/message_bus';
// TODO(jteplitz602) remove this and compile with lib.webworker.d.ts (#3492)
let _postMessage = {
postMessage: (message: any, transferrables?:[ArrayBuffer]) => {
(<any>postMessage)(message, transferrables);
}
};
export const WORKER_APP_STATIC_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
WORKER_APP_APPLICATION_COMMON_PROVIDERS,
/* @ts2dart_Provider */ {provide: MessageBus, useFactory: createMessageBus, deps: [NgZone]},
/* @ts2dart_Provider */ {provide: APP_INITIALIZER, useValue: setupWebWorker, multi: true}
];
export function bootstrapStaticApp(
appComponentType: Type,
customProviders?: Array<any /*Type | Provider | any[]*/>): Promise<ComponentRef<any>> {
var appInjector = ReflectiveInjector.resolveAndCreate(
[WORKER_APP_STATIC_APPLICATION_PROVIDERS, isPresent(customProviders) ? customProviders : []],
workerAppPlatform().injector);
return coreLoadAndBootstrap(appComponentType, appInjector);
}
function createMessageBus(zone: NgZone): MessageBus {
let sink = new PostMessageBusSink(_postMessage);
let source = new PostMessageBusSource();
let bus = new PostMessageBus(sink, source);
bus.attachToZone(zone);
return bus;
}
function setupWebWorker(): void {
WorkerDomAdapter.makeCurrent();
}

View File

@ -1,100 +0,0 @@
import {
PostMessageBus,
PostMessageBusSink,
PostMessageBusSource
} from '../../web_workers/shared/post_message_bus';
import {MessageBus} from '../../web_workers/shared/message_bus';
import {Injector, Injectable, APP_INITIALIZER} from '@angular/core';
import {
WORKER_RENDER_APPLICATION_COMMON_PROVIDERS,
WORKER_SCRIPT,
initializeGenericWorkerRenderer
} from '../common/worker_render';
import {BaseException} from '../../../src/facade/exceptions';
import {isPresent} from '../../facade/lang';
import {PromiseWrapper} from '../../facade/async';
import {
ApplicationRef,
ReflectiveInjector,
} from '@angular/core';
import {workerRenderPlatform} from '../common/worker_render';
/**
* Wrapper class that exposes the Worker
* and underlying {@link MessageBus} for lower level message passing.
*/
@Injectable()
export class WebWorkerInstance {
public worker: Worker;
public bus: MessageBus;
/** @internal */
public init(worker: Worker, bus: MessageBus) {
this.worker = worker;
this.bus = bus;
}
}
/**
* An array of providers that should be passed into `application()` when initializing a new Worker.
*/
export const WORKER_RENDER_STATIC_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> = /*@ts2dart_const*/[
WORKER_RENDER_APPLICATION_COMMON_PROVIDERS, WebWorkerInstance,
/*@ts2dart_Provider*/ {
provide: APP_INITIALIZER,
useFactory: (injector => () => initWebWorkerApplication(injector)),
multi: true,
deps: [Injector]
},
/*@ts2dart_Provider*/ {
provide: MessageBus,
useFactory: (instance) => instance.bus,
deps: [WebWorkerInstance]
}
];
export function bootstrapStaticRender(
workerScriptUri: string,
customProviders?: Array<any /*Type | Provider | any[]*/>): Promise<ApplicationRef> {
var app = ReflectiveInjector.resolveAndCreate(
[
WORKER_RENDER_STATIC_APPLICATION_PROVIDERS,
/* @ts2dart_Provider */ {provide: 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));
}
function initWebWorkerApplication(injector: Injector): void {
var scriptUri: string;
try {
scriptUri = injector.get(WORKER_SCRIPT);
} catch (e) {
throw new BaseException(
"You must provide your WebWorker's initialization script with the WORKER_SCRIPT token");
}
let instance = injector.get(WebWorkerInstance);
spawnWebWorker(scriptUri, instance);
initializeGenericWorkerRenderer(injector);
}
/**
* Spawns a new class and initializes the WebWorkerInstance
*/
function spawnWebWorker(uri: string, instance: WebWorkerInstance): void {
var webWorker: Worker = new Worker(uri);
var sink = new PostMessageBusSink(webWorker);
var source = new PostMessageBusSource(webWorker);
var bus = new PostMessageBus(sink, source);
instance.init(webWorker, bus);
}

View File

@ -1,3 +1,3 @@
import {OpaqueToken} from '@angular/core';
export const ON_WEB_WORKER = /*@ts2dart_const*/ new OpaqueToken('WebWorker.onWebWorker');
export const ON_WEB_WORKER = new OpaqueToken('WebWorker.onWebWorker');

View File

@ -8,7 +8,7 @@ import {LocationType} from './serialized_types';
// PRIMITIVE is any type that does not need to be serialized (string, number, boolean)
// We set it to String so that it is considered a Type.
export const PRIMITIVE: Type = /*@ts2dart_const*/ String;
export const PRIMITIVE: Type = String;
@Injectable()
export class Serializer {

View File

@ -6,10 +6,10 @@ import {APP_INITIALIZER, Injector, NgZone} from '@angular/core';
* A list of {@link Provider}s. To use the router in a Worker enabled application you must
* include these providers when setting up the render thread.
*/
export const WORKER_RENDER_LOCATION_PROVIDERS = /*@ts2dart_const*/[
export const WORKER_RENDER_LOCATION_PROVIDERS = [
MessageBasedPlatformLocation,
BrowserPlatformLocation,
/* @ts2dart_Provider */ {provide: APP_INITIALIZER, useFactory: initUiLocation, multi: true, deps: [Injector]}
{provide: APP_INITIALIZER, useFactory: initUiLocation, multi: true, deps: [Injector]}
];
function initUiLocation(injector: Injector): () => void {

View File

@ -6,8 +6,8 @@ import {WebWorkerPlatformLocation} from './platform_location';
* Those providers should be added when the router is used in a worker context in addition to the
* {@link ROUTER_PROVIDERS} and after them.
*/
export const WORKER_APP_LOCATION_PROVIDERS = /*@ts2dart_const*/[
/* @ts2dart_Provider */ {provide: PlatformLocation, useClass: WebWorkerPlatformLocation},
export const WORKER_APP_LOCATION_PROVIDERS = [
{provide: PlatformLocation, useClass: WebWorkerPlatformLocation},
{
provide: APP_INITIALIZER,
useFactory: (platformLocation: WebWorkerPlatformLocation, zone: NgZone) => () =>

View File

@ -0,0 +1,110 @@
import {WebWorkerRootRenderer} from "./web_workers/worker/renderer";
import {print, isBlank, isPresent} from "./facade/lang";
import {
PLATFORM_DIRECTIVES,
PLATFORM_PIPES,
ExceptionHandler,
APPLICATION_COMMON_PROVIDERS,
PLATFORM_COMMON_PROVIDERS,
OpaqueToken,
RootRenderer,
PlatformRef,
getPlatform,
createPlatform,
assertPlatform,
ReflectiveInjector,
APP_INITIALIZER,
NgZone,
Type,
ComponentRef,
coreLoadAndBootstrap
} from "@angular/core";
import {COMMON_DIRECTIVES, COMMON_PIPES, FORM_PROVIDERS} from "@angular/common";
import {ClientMessageBrokerFactory, ClientMessageBrokerFactory_} from "./web_workers/shared/client_message_broker";
import {ServiceMessageBrokerFactory, ServiceMessageBrokerFactory_} from "./web_workers/shared/service_message_broker";
import {Serializer} from "./web_workers/shared/serializer";
import {ON_WEB_WORKER} from "./web_workers/shared/api";
import {RenderStore} from "./web_workers/shared/render_store";
import {BROWSER_SANITIZATION_PROVIDERS} from "./browser";
import {WorkerDomAdapter} from "./web_workers/worker/worker_adapter";
import {PostMessageBus, PostMessageBusSink, PostMessageBusSource} from "./web_workers/shared/post_message_bus";
import {MessageBus} from "./web_workers/shared/message_bus";
import {COMPILER_PROVIDERS, XHR} from "@angular/compiler";
import {XHRImpl} from "./xhr/xhr_impl";
class PrintLogger {
log = print;
logError = print;
logGroup = print;
logGroupEnd() {}
}
const WORKER_APP_PLATFORM_MARKER = new OpaqueToken('WorkerAppPlatformMarker');
export const WORKER_APP_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
[
PLATFORM_COMMON_PROVIDERS,
{provide: WORKER_APP_PLATFORM_MARKER, useValue: true}
];
export const WORKER_APP_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
[
APPLICATION_COMMON_PROVIDERS,
FORM_PROVIDERS,
BROWSER_SANITIZATION_PROVIDERS,
Serializer,
{provide: PLATFORM_PIPES, useValue: COMMON_PIPES, multi: true},
{provide: PLATFORM_DIRECTIVES, useValue: COMMON_DIRECTIVES, multi: true},
{provide: ClientMessageBrokerFactory, useClass: ClientMessageBrokerFactory_},
{provide: ServiceMessageBrokerFactory, useClass: ServiceMessageBrokerFactory_},
WebWorkerRootRenderer,
{provide: RootRenderer, useExisting: WebWorkerRootRenderer},
{provide: ON_WEB_WORKER, useValue: true},
RenderStore,
{provide: ExceptionHandler, useFactory: _exceptionHandler, deps: []},
{provide: MessageBus, useFactory: createMessageBus, deps: [NgZone]},
{provide: APP_INITIALIZER, useValue: setupWebWorker, multi: true}
];
export function workerAppPlatform(): PlatformRef {
if (isBlank(getPlatform())) {
createPlatform(ReflectiveInjector.resolveAndCreate(WORKER_APP_PLATFORM_PROVIDERS));
}
return assertPlatform(WORKER_APP_PLATFORM_MARKER);
}
export function bootstrapApp(
appComponentType: Type,
customProviders?: Array<any /*Type | Provider | any[]*/>): Promise<ComponentRef<any>> {
var appInjector = ReflectiveInjector.resolveAndCreate([
WORKER_APP_APPLICATION_PROVIDERS,
COMPILER_PROVIDERS,
{provide: XHR, useClass: XHRImpl},
isPresent(customProviders) ? customProviders : []],
workerAppPlatform().injector);
return coreLoadAndBootstrap(appComponentType, appInjector);
}
function _exceptionHandler(): ExceptionHandler {
return new ExceptionHandler(new PrintLogger());
}
// TODO(jteplitz602) remove this and compile with lib.webworker.d.ts (#3492)
let _postMessage = {
postMessage: (message: any, transferrables?:[ArrayBuffer]) => {
(<any>postMessage)(message, transferrables);
}
};
function createMessageBus(zone: NgZone): MessageBus {
let sink = new PostMessageBusSink(_postMessage);
let source = new PostMessageBusSource();
let bus = new PostMessageBus(sink, source);
bus.attachToZone(zone);
return bus;
}
function setupWebWorker(): void {
WorkerDomAdapter.makeCurrent();
}

View File

@ -0,0 +1,194 @@
import {isBlank, isPresent} from "./facade/lang";
import {MessageBus} from "./web_workers/shared/message_bus";
import {
NgZone,
Injector,
OpaqueToken,
Testability,
ExceptionHandler,
APPLICATION_COMMON_PROVIDERS,
PLATFORM_COMMON_PROVIDERS,
RootRenderer,
PLATFORM_INITIALIZER,
PlatformRef,
getPlatform,
createPlatform,
assertPlatform,
ReflectiveInjector,
Injectable,
APP_INITIALIZER,
ApplicationRef
} from "@angular/core";
import {wtfInit} from "../core_private";
import {getDOM} from "./dom/dom_adapter";
import {DomEventsPlugin} from "./dom/events/dom_events";
import {KeyEventsPlugin} from "./dom/events/key_events";
import {HammerGesturesPlugin, HAMMER_GESTURE_CONFIG, HammerGestureConfig} from "./dom/events/hammer_gestures";
import {DOCUMENT} from "./dom/dom_tokens";
import {DomRootRenderer, DomRootRenderer_} from "./dom/dom_renderer";
import {DomSharedStylesHost, SharedStylesHost} from "./dom/shared_styles_host";
import {BrowserDetails} from "./animate/browser_details";
import {AnimationBuilder} from "./animate/animation_builder";
import {BrowserGetTestability} from "./browser/testability";
import {BrowserDomAdapter} from "./browser/browser_adapter";
import {MessageBasedRenderer} from "./web_workers/ui/renderer";
import {ServiceMessageBrokerFactory, ServiceMessageBrokerFactory_} from "./web_workers/shared/service_message_broker";
import {ClientMessageBrokerFactory, ClientMessageBrokerFactory_} from "./web_workers/shared/client_message_broker";
import {Serializer} from "./web_workers/shared/serializer";
import {ON_WEB_WORKER} from "./web_workers/shared/api";
import {RenderStore} from "./web_workers/shared/render_store";
import {EventManager, EVENT_MANAGER_PLUGINS} from "./dom/events/event_manager";
import {BROWSER_SANITIZATION_PROVIDERS, BROWSER_APP_COMPILER_PROVIDERS} from "./browser";
import {PostMessageBus, PostMessageBusSink, PostMessageBusSource} from "./web_workers/shared/post_message_bus";
import {BaseException} from "./facade/exceptions";
import {PromiseWrapper} from "./facade/async";
const WORKER_RENDER_PLATFORM_MARKER = new OpaqueToken('WorkerRenderPlatformMarker');
/**
* Wrapper class that exposes the Worker
* and underlying {@link MessageBus} for lower level message passing.
*/
@Injectable()
export class WebWorkerInstance {
public worker: Worker;
public bus: MessageBus;
/** @internal */
public init(worker: Worker, bus: MessageBus) {
this.worker = worker;
this.bus = bus;
}
}
export const WORKER_SCRIPT: OpaqueToken = new OpaqueToken("WebWorkerScript");
/**
* A multiple providers used to automatically call the `start()` method after the service is
* created.
*
* TODO(vicb): create an interface for startable services to implement
*/
export const WORKER_RENDER_STARTABLE_MESSAGING_SERVICE = new OpaqueToken('WorkerRenderStartableMsgService');
export const WORKER_RENDER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
PLATFORM_COMMON_PROVIDERS,
{provide: WORKER_RENDER_PLATFORM_MARKER, useValue: true},
{provide: PLATFORM_INITIALIZER, useValue: initWebWorkerRenderPlatform, multi: true}
];
export const WORKER_RENDER_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
[
APPLICATION_COMMON_PROVIDERS,
MessageBasedRenderer,
{provide: WORKER_RENDER_STARTABLE_MESSAGING_SERVICE, useExisting: MessageBasedRenderer, multi: true},
BROWSER_SANITIZATION_PROVIDERS,
{provide: ExceptionHandler, useFactory: _exceptionHandler, deps: []},
{provide: DOCUMENT, useFactory: _document, deps: []},
// TODO(jteplitz602): Investigate if we definitely need EVENT_MANAGER on the render thread
// #5298
{provide: EVENT_MANAGER_PLUGINS, useClass: DomEventsPlugin, multi: true},
{provide: EVENT_MANAGER_PLUGINS, useClass: KeyEventsPlugin, multi: true},
{provide: EVENT_MANAGER_PLUGINS, useClass: HammerGesturesPlugin, multi: true},
{provide: HAMMER_GESTURE_CONFIG, useClass: HammerGestureConfig},
{provide: DomRootRenderer, useClass: DomRootRenderer_},
{provide: RootRenderer, useExisting: DomRootRenderer},
{provide: SharedStylesHost, useExisting: DomSharedStylesHost},
{provide: ServiceMessageBrokerFactory, useClass: ServiceMessageBrokerFactory_},
{provide: ClientMessageBrokerFactory, useClass: ClientMessageBrokerFactory_},
Serializer,
{provide: ON_WEB_WORKER, useValue: false},
RenderStore,
DomSharedStylesHost,
Testability,
BrowserDetails,
AnimationBuilder,
EventManager,
WebWorkerInstance,
{
provide: APP_INITIALIZER,
useFactory: (injector => () => initWebWorkerApplication(injector)),
multi: true,
deps: [Injector]
},
{
provide: MessageBus,
useFactory: (instance) => instance.bus,
deps: [WebWorkerInstance]
}
];
export function initializeGenericWorkerRenderer(injector: Injector) {
var bus = injector.get(MessageBus);
let zone = injector.get(NgZone);
bus.attachToZone(zone);
// initialize message services after the bus has been created
let services = injector.get(WORKER_RENDER_STARTABLE_MESSAGING_SERVICE);
zone.runGuarded(() => { services.forEach((svc) => { svc.start(); }); });
}
export function bootstrapRender(
workerScriptUri: string,
customProviders?: Array<any /*Type | Provider | any[]*/>): Promise<ApplicationRef> {
var app = ReflectiveInjector.resolveAndCreate(
[
WORKER_RENDER_APPLICATION_PROVIDERS,
BROWSER_APP_COMPILER_PROVIDERS,
{provide: 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));
}
function initWebWorkerRenderPlatform(): void {
BrowserDomAdapter.makeCurrent();
wtfInit();
BrowserGetTestability.init();
}
export function workerRenderPlatform(): PlatformRef {
if (isBlank(getPlatform())) {
createPlatform(ReflectiveInjector.resolveAndCreate(WORKER_RENDER_PLATFORM_PROVIDERS));
}
return assertPlatform(WORKER_RENDER_PLATFORM_MARKER);
}
function _exceptionHandler(): ExceptionHandler {
return new ExceptionHandler(getDOM());
}
function _document(): any {
return getDOM().defaultDoc();
}
function initWebWorkerApplication(injector: Injector): void {
var scriptUri: string;
try {
scriptUri = injector.get(WORKER_SCRIPT);
} catch (e) {
throw new BaseException(
"You must provide your WebWorker's initialization script with the WORKER_SCRIPT token");
}
let instance = injector.get(WebWorkerInstance);
spawnWebWorker(scriptUri, instance);
initializeGenericWorkerRenderer(injector);
}
/**
* Spawns a new class and initializes the WebWorkerInstance
*/
function spawnWebWorker(uri: string, instance: WebWorkerInstance): void {
var webWorker: Worker = new Worker(uri);
var sink = new PostMessageBusSink(webWorker);
var source = new PostMessageBusSource(webWorker);
var bus = new PostMessageBus(sink, source);
instance.init(webWorker, bus);
}