├── .editorconfig ├── .gitignore ├── README.md ├── demo ├── README.md ├── app_ui.ts ├── component.ts ├── index.html ├── main.ts └── package.json ├── package.json ├── src ├── main.ts ├── platform │ ├── electron.ts │ ├── electron_app.ts │ ├── electron_app_common.ts │ ├── electron_message_bus.ts │ ├── electron_renderer.ts │ └── electron_renderer_common.ts └── renderer.ts ├── tsconfig.json └── typings.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 2 9 | end_of_line = lf 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | insert_final_newline = false 15 | trim_trailing_whitespace = false 16 | 17 | [*.json] 18 | insert_final_newline = false -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | typings/ 4 | npm-debug.log 5 | .DS_Store 6 | demo/*.js 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Angular Electron 2 | 3 | Electron Platform for Angular 2. Work in progress. 4 | 5 | ## Testing the demo 6 | 7 | Make sure to have NodeJS version 5.x.x installed. 8 | 9 | Start off by running `npm run setup`. That command will install the dependencies and the required TypeScript typings (using the [typings](https://www.npmjs.com/package/typings) package). 10 | 11 | Since the demo application is not apart of the plugin, angular2 and 12 | its peer dependencies also need to be installed manually via npm. Run 13 | the following command to install everything required for the demo: `npm run setup-demo`. 14 | 15 | That command will install the following: 16 | * angular2 17 | * es6-promise 18 | * es6-shim 19 | * reflect-metadata 20 | * rxjs 21 | * zone.js 22 | 23 | Then execute `npm start` to see the demo application in action! 24 | -------------------------------------------------------------------------------- /demo/README.md: -------------------------------------------------------------------------------- 1 | ### Angular Electron Sample App 2 | -------------------------------------------------------------------------------- /demo/app_ui.ts: -------------------------------------------------------------------------------- 1 | import 'reflect-metadata'; 2 | import {bootstrapElectronRenderer} from '../dist/renderer'; 3 | 4 | bootstrapElectronRenderer(); 5 | 6 | 7 | -------------------------------------------------------------------------------- /demo/component.ts: -------------------------------------------------------------------------------- 1 | import {Component} from 'angular2/core'; 2 | 3 | @Component({ 4 | selector: 'app', 5 | template: `
Hello from {{name}}
` 6 | }) 7 | export class App { 8 | name: string; 9 | constructor(){ 10 | this.name = 'Angular2 Electron!'; 11 | 12 | setTimeout(() => { 13 | this.name = 'Angular2 Electron!!!'; 14 | },1000); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Loading... 8 | 9 | 10 | -------------------------------------------------------------------------------- /demo/main.ts: -------------------------------------------------------------------------------- 1 | import 'reflect-metadata'; 2 | import 'zone.js/dist/zone'; 3 | import {bootstrap} from '../dist/main'; 4 | 5 | import {App} from './component'; 6 | 7 | bootstrap(App, []); 8 | -------------------------------------------------------------------------------- /demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "angular-electron-demo", 3 | "version" : "1.0.0", 4 | "main" : "main.js" 5 | } 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@angular2/electron", 3 | "version": "1.0.0", 4 | "description": "Electron Platform for Angular2", 5 | "main": "index.js", 6 | "scripts": { 7 | "clean": "rimraf dist", 8 | "typings-install": "typings install", 9 | "setup": "npm install --no-optional && npm run typings-install", 10 | "setup-demo": "npm install --no-optional angular2@2.0.0-beta.12 es6-promise@^3.1.2 es6-shim@0.35.0 reflect-metadata@0.1.2 rxjs@5.0.0-beta.2 zone.js@^0.6.6", 11 | "build": "npm run clean && tsc", 12 | "build_demo": "tsc typings/browser.d.ts demo/main.ts demo/app_ui.ts --module commonjs -t es5 --experimentalDecorators --emitDecoratorMetadata", 13 | "test": "echo Not supported yet", 14 | "demo": "npm run build && npm run build_demo && electron ./demo", 15 | "start": "npm run demo" 16 | }, 17 | "repository": { 18 | "type": "git", 19 | "url": "git+https://github.com/angular/angular-electron.git" 20 | }, 21 | "keywords": [ 22 | "Angular2", 23 | "Electron" 24 | ], 25 | "author": "Rob Wormald ", 26 | "license": "MIT", 27 | "bugs": { 28 | "url": "https://github.com/angular/angular-electron/issues" 29 | }, 30 | "homepage": "https://github.com/angular/angular-electron#readme", 31 | "devDependencies": { 32 | "electron-prebuilt": "^0.37.2", 33 | "typescript": "^1.8.9", 34 | "rimraf": "^2.5.2" 35 | }, 36 | "peerDependencies": { 37 | "angular2": "2.0.0-beta.12" 38 | }, 39 | "dependencies": { 40 | "parse5": "^1.5.1" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | //public angular electron API for main (node/background) 2 | export * from 'angular2/common'; 3 | export * from 'angular2/core'; 4 | export * from 'angular2/platform/worker_app'; 5 | export {UrlResolver} from 'angular2/compiler'; 6 | export * from 'angular2/instrumentation'; 7 | export * from './platform/electron_app'; 8 | export * from './platform/electron'; 9 | -------------------------------------------------------------------------------- /src/platform/electron.ts: -------------------------------------------------------------------------------- 1 | import {platform} from 'angular2/core'; 2 | import { ELECTRON_APP_APPLICATION, bootstrap } from './electron_app'; 3 | import { ELECTRON_APP_PLATFORM } from './electron_app_common'; 4 | export { bootstrap } 5 | -------------------------------------------------------------------------------- /src/platform/electron_app.ts: -------------------------------------------------------------------------------- 1 | import * as electron from 'electron'; 2 | import {ElectronMessageBus, ElectronMessageBusSink, ElectronMessageBusSource, ELECTRON_READY} from './electron_message_bus'; 3 | import {ELECTRON_APP_APPLICATION_COMMON, ELECTRON_APP_PLATFORM} from './electron_app_common'; 4 | import {Type, CONST_EXPR, isPresent} from 'angular2/src/facade/lang'; 5 | import {Parse5DomAdapter} from 'angular2/src/platform/server/parse5_adapter'; 6 | import {APP_INITIALIZER, platform, ComponentRef, NgZone, Provider} from 'angular2/core'; 7 | import {MessageBus} from 'angular2/src/web_workers/shared/message_bus'; 8 | import {COMPILER_PROVIDERS} from 'angular2/compiler'; 9 | 10 | export const ELECTRON_APP_APPLICATION: Array = [ 11 | ELECTRON_APP_APPLICATION_COMMON, 12 | COMPILER_PROVIDERS, 13 | new Provider(MessageBus, { useFactory: createMessageBus, deps: [NgZone] }), 14 | new Provider(APP_INITIALIZER, { useValue: () => {}, multi: true }) 15 | ]; 16 | 17 | let applicationRef:Electron.BrowserWindow; 18 | 19 | function createMessageBus(zone: NgZone): MessageBus { 20 | let sink = new ElectronMessageBusSink(applicationRef.webContents); 21 | let source = new ElectronMessageBusSource(electron.ipcMain); 22 | let bus = new ElectronMessageBus(sink, source); 23 | bus.attachToZone(zone); 24 | return bus; 25 | } 26 | 27 | function waitForAppReady(){ 28 | return new Promise((resolve, reject) => { 29 | electron.app.on('ready', resolve); 30 | }); 31 | } 32 | 33 | function waitForPingback(){ 34 | initializeMainWindow() 35 | return new Promise((resolve) => { 36 | electron.ipcMain.once(ELECTRON_READY, (ev) => { 37 | ev.returnValue = 'ok'; 38 | resolve(); 39 | }); 40 | }); 41 | } 42 | 43 | function initializeMainWindow(){ 44 | applicationRef = new electron.BrowserWindow(); 45 | applicationRef.loadURL(`file://${process.cwd()}/demo/index.html`); 46 | } 47 | 48 | export function bootstrap(appComp, providers?:any) { 49 | Parse5DomAdapter.makeCurrent(); 50 | 51 | return platform([ ELECTRON_APP_PLATFORM ]) 52 | .asyncApplication((z) => { 53 | return z.run(() => { 54 | return waitForAppReady() 55 | .then(waitForPingback) 56 | .then(() => { 57 | return ELECTRON_APP_APPLICATION; 58 | }) 59 | }) 60 | }) 61 | .then((appRef) => { 62 | return appRef.bootstrap(appComp); 63 | }) 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/platform/electron_app_common.ts: -------------------------------------------------------------------------------- 1 | import {XHR} from 'angular2/src/compiler/xhr'; 2 | import {WebWorkerXHRImpl} from 'angular2/src/web_workers/worker/xhr_impl'; 3 | import {WebWorkerRootRenderer} from 'angular2/src/web_workers/worker/renderer'; 4 | import {print, Type, CONST_EXPR, isPresent} from 'angular2/src/facade/lang'; 5 | import {RootRenderer} from 'angular2/src/core/render/api'; 6 | import { 7 | PLATFORM_DIRECTIVES, 8 | PLATFORM_PIPES, 9 | ExceptionHandler, 10 | APPLICATION_COMMON_PROVIDERS, 11 | PLATFORM_COMMON_PROVIDERS, 12 | } from 'angular2/core'; 13 | import {COMMON_DIRECTIVES, COMMON_PIPES, FORM_PROVIDERS} from "angular2/common"; 14 | import { 15 | ClientMessageBrokerFactory, 16 | ClientMessageBrokerFactory_ 17 | } from 'angular2/src/web_workers/shared/client_message_broker'; 18 | import { 19 | ServiceMessageBrokerFactory, 20 | ServiceMessageBrokerFactory_ 21 | } from 'angular2/src/web_workers/shared/service_message_broker'; 22 | import {Serializer} from "angular2/src/web_workers/shared/serializer"; 23 | import {ON_WEB_WORKER} from "angular2/src/web_workers/shared/api"; 24 | import {Provider} from 'angular2/src/core/di'; 25 | import {RenderStore} from 'angular2/src/web_workers/shared/render_store'; 26 | 27 | class PrintLogger { 28 | log = print; 29 | logError = print; 30 | logGroup = print; 31 | logGroupEnd() {} 32 | } 33 | 34 | export const ELECTRON_APP_PLATFORM: Array = 35 | CONST_EXPR([PLATFORM_COMMON_PROVIDERS]); 36 | 37 | export const ELECTRON_APP_APPLICATION_COMMON: Array = CONST_EXPR([ 38 | APPLICATION_COMMON_PROVIDERS, 39 | FORM_PROVIDERS, 40 | Serializer, 41 | new Provider(PLATFORM_PIPES, {useValue: COMMON_PIPES, multi: true}), 42 | new Provider(PLATFORM_DIRECTIVES, {useValue: COMMON_DIRECTIVES, multi: true}), 43 | new Provider(ClientMessageBrokerFactory, {useClass: ClientMessageBrokerFactory_}), 44 | new Provider(ServiceMessageBrokerFactory, {useClass: ServiceMessageBrokerFactory_}), 45 | WebWorkerRootRenderer, 46 | new Provider(RootRenderer, {useExisting: WebWorkerRootRenderer}), 47 | new Provider(ON_WEB_WORKER, {useValue: true}), 48 | RenderStore, 49 | new Provider(ExceptionHandler, {useFactory: _exceptionHandler, deps: []}), 50 | WebWorkerXHRImpl, 51 | new Provider(XHR, {useExisting: WebWorkerXHRImpl}) 52 | ]); 53 | 54 | function _exceptionHandler(): ExceptionHandler { 55 | return new ExceptionHandler(new PrintLogger()); 56 | } 57 | -------------------------------------------------------------------------------- /src/platform/electron_message_bus.ts: -------------------------------------------------------------------------------- 1 | import * as electron from 'electron'; 2 | import { 3 | MessageBus, 4 | MessageBusSource, 5 | MessageBusSink 6 | } from "angular2/src/web_workers/shared/message_bus"; 7 | import {NgZone, EventEmitter, Injectable} from 'angular2/core'; 8 | 9 | /** 10 | * Typescript Implementation of MessageBus for use in electron apps 11 | */ 12 | 13 | export const ELECTRON_WORKER = '__ELECTRON_WORKER'; 14 | export const ELECTRON_CLIENT = '__ELECTRON_CLIENT'; 15 | export const ELECTRON_READY = '__ELECTRON_READY' 16 | 17 | const ELECTRON_CHANNEL = '__ELECTRON_CHANNEL'; 18 | 19 | @Injectable() 20 | export class ElectronMessageBus implements MessageBus { 21 | constructor(public sink: ElectronMessageBusSink, 22 | public source: ElectronMessageBusSource, 23 | private env: string = ELECTRON_CLIENT) {} 24 | 25 | attachToZone(zone: NgZone): void { 26 | this.source.attachToZone(zone); 27 | this.sink.attachToZone(zone); 28 | } 29 | 30 | initChannel(channel: string, runInZone: boolean = false): void { 31 | this.source.initChannel(channel, runInZone); 32 | this.sink.initChannel(channel, runInZone); 33 | } 34 | 35 | from(channel: string): EventEmitter { return this.source.from(channel); } 36 | 37 | to(channel: string): EventEmitter { return this.sink.to(channel); } 38 | } 39 | 40 | export class ElectronMessageBusSink implements MessageBusSink { 41 | private _zone: NgZone; 42 | private _channels: Map = 43 | new Map(); 44 | private _messageBuffer: Array = []; 45 | 46 | constructor(private _ipc: any) {} 47 | 48 | attachToZone(zone: NgZone): void { 49 | this._zone = zone; 50 | this._zone.onMicrotaskEmpty.subscribe(() => {this._handleOnEventDone()}); 51 | } 52 | 53 | initChannel(channel: string, runInZone: boolean = true): void { 54 | if (this._channels.has(channel)) { 55 | throw new Error(`${channel} has already been initialized`); 56 | } 57 | let _channel = new _ElectronMessageChannel(new EventEmitter(), runInZone); 58 | this._channels.set(channel, _channel); 59 | _channel.emitter.subscribe((data: any) => { 60 | var message = {channel : channel, message : data}; 61 | 62 | if (runInZone) { 63 | this._messageBuffer.push(message); 64 | } else { 65 | this._sendMessages([ message ]); 66 | } 67 | }); 68 | } 69 | 70 | to(channel: string): EventEmitter { 71 | if (!this._channels.has(channel)) { 72 | throw new Error(`${channel} does not exist!`); 73 | } 74 | return this._channels.get(channel).emitter; 75 | } 76 | 77 | private _sendMessages(messages: any[]) { 78 | if (this._ipc.sendChannel) { 79 | this._ipc.sendChannel(ELECTRON_CHANNEL, messages); 80 | } else { 81 | this._ipc.send(ELECTRON_CHANNEL, messages); 82 | } 83 | } 84 | private _handleOnEventDone() { 85 | if (this._messageBuffer.length > 0) { 86 | this._sendMessages(this._messageBuffer); 87 | this._messageBuffer = []; 88 | } 89 | } 90 | } 91 | 92 | export class ElectronMessageBusSource implements MessageBusSource { 93 | private _zone: NgZone; 94 | private _channels: Map = 95 | new Map(); 96 | 97 | constructor(private _ipc?: any) { 98 | this._ipc.on(ELECTRON_CHANNEL, (ev, data) => this._handleMessages(data || ev)); 99 | } 100 | attachToZone(zone: NgZone) { this._zone = zone; } 101 | 102 | initChannel(channel: string, runInZone: boolean = true) { 103 | 104 | if (this._channels.has(channel)) { 105 | throw new Error(`${channel} has already been initialized`); 106 | } 107 | 108 | let emitter = new EventEmitter(); 109 | let channelInfo = new _ElectronMessageChannel(emitter, runInZone); 110 | this._channels.set(channel, channelInfo); 111 | } 112 | 113 | from(channel: string): EventEmitter { 114 | if (this._channels.has(channel)) { 115 | return this._channels.get(channel).emitter; 116 | } else { 117 | throw new Error( 118 | `${channel} is not set up. Did you forget to call initChannel?`); 119 | } 120 | } 121 | 122 | private _handleMessages(messages: any[]): void { 123 | for (var i = 0; i < messages.length; i++) { 124 | this._handleMessage(messages[i]); 125 | } 126 | } 127 | 128 | private _handleMessage(data: any): void { 129 | var channel = data.channel; 130 | if (this._channels.has(channel)) { 131 | var channelInfo = this._channels.get(channel); 132 | this._zone.run(() => { channelInfo.emitter.next(data.message); }); 133 | } else { 134 | throw new Error('unhandled message!'); 135 | } 136 | } 137 | } 138 | 139 | class _ElectronMessageChannel { 140 | constructor(public emitter: EventEmitter, public runInZone: boolean) {} 141 | } 142 | -------------------------------------------------------------------------------- /src/platform/electron_renderer.ts: -------------------------------------------------------------------------------- 1 | import * as electron from 'electron'; 2 | import {ElectronMessageBus, ElectronMessageBusSink, ElectronMessageBusSource, ELECTRON_READY} from './electron_message_bus'; 3 | import {MessageBus} from 'angular2/src/web_workers/shared/message_bus'; 4 | import {APP_INITIALIZER, provide, platform} from 'angular2/core'; 5 | import {Injector, Injectable, Provider} from 'angular2/src/core/di'; 6 | import {MessageBasedRenderer} from 'angular2/src/web_workers/ui/renderer'; 7 | import {MessageBasedXHRImpl} from 'angular2/src/web_workers/ui/xhr_impl'; 8 | import { 9 | WORKER_RENDER_APPLICATION_COMMON, 10 | WORKER_RENDER_MESSAGING_PROVIDERS, 11 | WORKER_SCRIPT, 12 | WORKER_RENDER_PLATFORM, 13 | initializeGenericWorkerRenderer 14 | } from './electron_renderer_common'; 15 | import {BaseException} from 'angular2/src/facade/exceptions'; 16 | import {CONST_EXPR} from 'angular2/src/facade/lang'; 17 | 18 | /** 19 | * Wrapper class that exposes the Worker 20 | * and underlying {@link MessageBus} for lower level message passing. 21 | */ 22 | @Injectable() 23 | export class WebWorkerInstance { 24 | public worker: Worker; 25 | public bus: MessageBus; 26 | 27 | /** @internal */ 28 | public init(worker: Worker, bus: MessageBus) { 29 | this.worker = worker; 30 | this.bus = bus; 31 | } 32 | } 33 | 34 | /** 35 | * An array of providers that should be passed into `application()` when initializing a new Worker. 36 | */ 37 | export const WORKER_RENDER_APPLICATION: Array = CONST_EXPR([ 38 | WORKER_RENDER_APPLICATION_COMMON, 39 | WebWorkerInstance, 40 | new Provider(APP_INITIALIZER, 41 | { 42 | useFactory: (injector) => () => initWebWorkerApplication(injector), 43 | multi: true, 44 | deps: [Injector] 45 | }), 46 | new Provider(MessageBus, {useFactory: initMessageBus}) 47 | ]); 48 | 49 | function initMessageBus(){ 50 | var sink = new ElectronMessageBusSink(electron.ipcRenderer); 51 | var source = new ElectronMessageBusSource(electron.ipcRenderer); 52 | var bus = new ElectronMessageBus(sink, source); 53 | return bus; 54 | } 55 | 56 | function initWebWorkerApplication(injector: Injector): void { 57 | initializeGenericWorkerRenderer(injector); 58 | 59 | } 60 | 61 | export const bootstrapElectronRenderer = () => { 62 | electron.ipcRenderer.sendSync(ELECTRON_READY); 63 | platform([WORKER_RENDER_PLATFORM]).application([WORKER_RENDER_APPLICATION]) 64 | } 65 | -------------------------------------------------------------------------------- /src/platform/electron_renderer_common.ts: -------------------------------------------------------------------------------- 1 | import {CONST_EXPR, IS_DART} from 'angular2/src/facade/lang'; 2 | import {MessageBus} from 'angular2/src/web_workers/shared/message_bus'; 3 | import { 4 | PLATFORM_DIRECTIVES, 5 | PLATFORM_PIPES, 6 | ComponentRef, 7 | platform, 8 | ExceptionHandler, 9 | Reflector, 10 | reflector, 11 | APPLICATION_COMMON_PROVIDERS, 12 | PLATFORM_COMMON_PROVIDERS, 13 | RootRenderer, 14 | PLATFORM_INITIALIZER, 15 | APP_INITIALIZER, 16 | NgZone 17 | } from 'angular2/core'; 18 | import {EVENT_MANAGER_PLUGINS, EventManager} from 'angular2/platform/common_dom'; 19 | import {provide, Provider, Injector, OpaqueToken} from 'angular2/src/core/di'; 20 | // TODO change these imports once dom_adapter is moved out of core 21 | import {DOM} from 'angular2/src/platform/dom/dom_adapter'; 22 | import {DomEventsPlugin} from 'angular2/src/platform/dom/events/dom_events'; 23 | import {KeyEventsPlugin} from 'angular2/src/platform/dom/events/key_events'; 24 | import {HammerGesturesPlugin} from 'angular2/src/platform/dom/events/hammer_gestures'; 25 | import {DOCUMENT} from 'angular2/src/platform/dom/dom_tokens'; 26 | import {DomRootRenderer, DomRootRenderer_} from 'angular2/src/platform/dom/dom_renderer'; 27 | import {DomSharedStylesHost} from 'angular2/src/platform/dom/shared_styles_host'; 28 | import {SharedStylesHost} from "angular2/src/platform/dom/shared_styles_host"; 29 | import {BrowserDetails} from 'angular2/src/animate/browser_details'; 30 | import {AnimationBuilder} from 'angular2/src/animate/animation_builder'; 31 | import {XHR} from 'angular2/compiler'; 32 | import {XHRImpl} from 'angular2/src/platform/browser/xhr_impl'; 33 | import {Testability} from 'angular2/src/core/testability/testability'; 34 | import {BrowserGetTestability} from 'angular2/src/platform/browser/testability'; 35 | import {BrowserDomAdapter} from 'angular2/src/platform/browser/browser_adapter'; 36 | import {wtfInit} from 'angular2/src/core/profile/wtf_init'; 37 | import {MessageBasedRenderer} from 'angular2/src/web_workers/ui/renderer'; 38 | import {MessageBasedXHRImpl} from 'angular2/src/web_workers/ui/xhr_impl'; 39 | import {BrowserPlatformLocation} from 'angular2/src/router/location/browser_platform_location'; 40 | import { 41 | ServiceMessageBrokerFactory, 42 | ServiceMessageBrokerFactory_ 43 | } from 'angular2/src/web_workers/shared/service_message_broker'; 44 | import { 45 | ClientMessageBrokerFactory, 46 | ClientMessageBrokerFactory_ 47 | } from 'angular2/src/web_workers/shared/client_message_broker'; 48 | import {Serializer} from 'angular2/src/web_workers/shared/serializer'; 49 | import {ON_WEB_WORKER} from 'angular2/src/web_workers/shared/api'; 50 | import {RenderStore} from 'angular2/src/web_workers/shared/render_store'; 51 | import {ElectronMessageBus, ElectronMessageBusSink, ElectronMessageBusSource} from './electron_message_bus'; 52 | import * as electron from 'electron'; 53 | 54 | export const WORKER_SCRIPT: OpaqueToken = CONST_EXPR(new OpaqueToken("WebWorkerScript")); 55 | 56 | // Message based Worker classes that listen on the MessageBus 57 | export const WORKER_RENDER_MESSAGING_PROVIDERS: Array = 58 | CONST_EXPR([MessageBasedRenderer, MessageBasedXHRImpl]); 59 | 60 | export const WORKER_RENDER_PLATFORM: Array = CONST_EXPR([ 61 | PLATFORM_COMMON_PROVIDERS, 62 | new Provider(PLATFORM_INITIALIZER, {useValue: initWebWorkerRenderPlatform, multi: true}) 63 | ]); 64 | 65 | /** 66 | * A list of {@link Provider}s. To use the router in a Worker enabled application you must 67 | * include these providers when setting up the render thread. 68 | */ 69 | export const WORKER_RENDER_ROUTER: Array = 70 | CONST_EXPR([BrowserPlatformLocation]); 71 | 72 | export const WORKER_RENDER_APPLICATION_COMMON: Array = CONST_EXPR([ 73 | APPLICATION_COMMON_PROVIDERS, 74 | WORKER_RENDER_MESSAGING_PROVIDERS, 75 | new Provider(ExceptionHandler, {useFactory: _exceptionHandler, deps: []}), 76 | new Provider(DOCUMENT, {useFactory: _document, deps: []}), 77 | // TODO(jteplitz602): Investigate if we definitely need EVENT_MANAGER on the render thread 78 | // #5298 79 | new Provider(EVENT_MANAGER_PLUGINS, {useClass: DomEventsPlugin, multi: true}), 80 | new Provider(EVENT_MANAGER_PLUGINS, {useClass: KeyEventsPlugin, multi: true}), 81 | new Provider(EVENT_MANAGER_PLUGINS, {useClass: HammerGesturesPlugin, multi: true}), 82 | new Provider(DomRootRenderer, {useClass: DomRootRenderer_}), 83 | new Provider(RootRenderer, {useExisting: DomRootRenderer}), 84 | new Provider(SharedStylesHost, {useExisting: DomSharedStylesHost}), 85 | new Provider(XHR, {useClass: XHRImpl}), 86 | new Provider(MessageBus, {useFactory:createMessageBus, deps: [NgZone]}), 87 | MessageBasedXHRImpl, 88 | new Provider(ServiceMessageBrokerFactory, {useClass: ServiceMessageBrokerFactory_}), 89 | new Provider(ClientMessageBrokerFactory, {useClass: ClientMessageBrokerFactory_}), 90 | Serializer, 91 | new Provider(ON_WEB_WORKER, {useValue: false}), 92 | RenderStore, 93 | DomSharedStylesHost, 94 | Testability, 95 | BrowserDetails, 96 | AnimationBuilder, 97 | EventManager 98 | ]); 99 | 100 | export function initializeGenericWorkerRenderer(injector: Injector) { 101 | var bus = injector.get(MessageBus); 102 | let zone = injector.get(NgZone); 103 | bus.attachToZone(zone); 104 | 105 | zone.run(() => { 106 | WORKER_RENDER_MESSAGING_PROVIDERS.forEach((token) => { injector.get(token).start(); }); 107 | }); 108 | } 109 | 110 | function createMessageBus(zone: NgZone): MessageBus { 111 | let sink = new ElectronMessageBusSink(electron['ipcMain']); 112 | let source = new ElectronMessageBusSource(electron['ipcMain']); 113 | let bus = new ElectronMessageBus(sink, source); 114 | bus.attachToZone(zone); 115 | return bus; 116 | } 117 | 118 | export function initWebWorkerRenderPlatform(): void { 119 | BrowserDomAdapter.makeCurrent(); 120 | wtfInit(); 121 | BrowserGetTestability.init(); 122 | } 123 | 124 | function _exceptionHandler(): ExceptionHandler { 125 | return new ExceptionHandler(DOM, !IS_DART); 126 | } 127 | 128 | function _document(): any { 129 | return DOM.defaultDoc(); 130 | } 131 | -------------------------------------------------------------------------------- /src/renderer.ts: -------------------------------------------------------------------------------- 1 | //public angular electron API for renderer (UI/browser) 2 | export * from 'angular2/core'; 3 | export * from './platform/electron_renderer' 4 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es5", 5 | "noImplicitAny": false, 6 | "sourceMap": false, 7 | "experimentalDecorators": true, 8 | "emitDecoratorMetadata": true, 9 | "outDir": "dist", 10 | "declaration": true, 11 | "moduleResolution": "node" 12 | }, 13 | "files": [ 14 | "typings/browser.d.ts", 15 | "./src/renderer.ts", 16 | "./src/main.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@angular2/electron", 3 | "devDependencies": {}, 4 | "ambientDependencies": { 5 | "es6-shim": "github:DefinitelyTyped/DefinitelyTyped/es6-shim/es6-shim.d.ts#6697d6f7dadbf5773cb40ecda35a76027e0783b2", 6 | "github-electron": "github:DefinitelyTyped/DefinitelyTyped/github-electron/github-electron.d.ts#f16c4922a7dd6d359a197e4cc5103463ba68cf9e", 7 | "node": "github:DefinitelyTyped/DefinitelyTyped/node/node.d.ts#138ad74b9e8e6c08af7633964962835add4c91e2" 8 | } 9 | } 10 | --------------------------------------------------------------------------------