This repository has been archived by the owner on Feb 26, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 115
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature(electron): initial functionality working
- Loading branch information
1 parent
eff42f5
commit 6e0775e
Showing
21 changed files
with
563 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# http://editorconfig.org | ||
|
||
root = true | ||
|
||
[*] | ||
charset = utf-8 | ||
indent_style = space | ||
indent_size = 2 | ||
end_of_line = lf | ||
insert_final_newline = true | ||
trim_trailing_whitespace = true | ||
|
||
[*.md] | ||
insert_final_newline = false | ||
trim_trailing_whitespace = false | ||
|
||
[*.json] | ||
insert_final_newline = false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
### Angular Electron Sample App |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import 'reflect-metadata'; | ||
import {bootstrapElectronRenderer} from '../dist/renderer'; | ||
|
||
bootstrapElectronRenderer(); | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import {Component} from 'angular2/core'; | ||
|
||
@Component({ | ||
selector: 'app', | ||
template: `<div>Hello from {{name}}</div>` | ||
}) | ||
export class App { | ||
name: string; | ||
constructor(){ | ||
this.name = 'Angular2 Electron!'; | ||
|
||
setTimeout(() => { | ||
this.name = 'Angular2 Electron!!!'; | ||
},1000); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<html> | ||
<head> | ||
<script src="../node_modules/angular2/bundles/angular2-polyfills.js"></script> | ||
<script src="app_ui.js"></script> | ||
</head> | ||
<body> | ||
<app>Loading...</app> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import 'reflect-metadata'; | ||
import 'zone.js/dist/zone-microtask' | ||
import {bootstrap} from '../dist/main'; | ||
|
||
import {App} from './component'; | ||
|
||
bootstrap(App, []); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"name" : "angular-electron-demo", | ||
"version" : "1.0.0", | ||
"main" : "main.js" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
//public angular electron API for main (node/background) | ||
export * from 'angular2/common'; | ||
export * from 'angular2/core'; | ||
export * from 'angular2/platform/worker_app'; | ||
export {UrlResolver} from 'angular2/compiler'; | ||
export * from 'angular2/instrumentation'; | ||
export * from './platform/electron_app'; | ||
export * from './platform/electron'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import {platform} from 'angular2/core'; | ||
import { ELECTRON_APP_APPLICATION, bootstrap } from './electron_app'; | ||
import { ELECTRON_APP_PLATFORM } from './electron_app_common'; | ||
export { bootstrap } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import * as electron from 'electron'; | ||
import {ElectronMessageBus, ElectronMessageBusSink, ElectronMessageBusSource, ELECTRON_READY} from './electron_message_bus'; | ||
import {ELECTRON_APP_APPLICATION_COMMON, ELECTRON_APP_PLATFORM} from './electron_app_common'; | ||
import {NgZone} from 'angular2/src/core/zone/ng_zone'; | ||
import {Type, CONST_EXPR, isPresent} from 'angular2/src/facade/lang'; | ||
import {Provider} from 'angular2/src/core/di'; | ||
import {Parse5DomAdapter} from 'angular2/src/platform/server/parse5_adapter'; | ||
import {APP_INITIALIZER, platform, ComponentRef} from 'angular2/core'; | ||
import {MessageBus} from 'angular2/src/web_workers/shared/message_bus'; | ||
import {COMPILER_PROVIDERS} from 'angular2/src/compiler/compiler'; | ||
|
||
export const ELECTRON_APP_APPLICATION: Array<any /*Type | Provider | any[]*/> = [ | ||
ELECTRON_APP_APPLICATION_COMMON, | ||
COMPILER_PROVIDERS, | ||
new Provider(MessageBus, { useFactory: createMessageBus, deps: [NgZone] }), | ||
new Provider(APP_INITIALIZER, { useValue: () => {}, multi: true }) | ||
]; | ||
|
||
let applicationRef:Electron.BrowserWindow; | ||
|
||
function createMessageBus(zone: NgZone): MessageBus { | ||
let sink = new ElectronMessageBusSink(applicationRef.webContents); | ||
let source = new ElectronMessageBusSource(electron.ipcMain); | ||
let bus = new ElectronMessageBus(sink, source); | ||
bus.attachToZone(zone); | ||
return bus; | ||
} | ||
|
||
function waitForAppReady(){ | ||
return new Promise((resolve, reject) => { | ||
electron.app.on('ready', resolve); | ||
}); | ||
} | ||
|
||
function waitForPingback(){ | ||
initializeMainWindow() | ||
return new Promise((resolve) => { | ||
electron.ipcMain.once(ELECTRON_READY, (ev) => { | ||
ev.returnValue = 'ok'; | ||
resolve(); | ||
}); | ||
}); | ||
} | ||
|
||
function initializeMainWindow(){ | ||
applicationRef = new electron.BrowserWindow(); | ||
applicationRef.loadURL(`file://${process.cwd()}/demo/index.html`); | ||
} | ||
|
||
export function bootstrap(appComp, providers?:any) { | ||
Parse5DomAdapter.makeCurrent(); | ||
|
||
return platform([ ELECTRON_APP_PLATFORM ]) | ||
.asyncApplication((z) => { | ||
return z.run(() => { | ||
return waitForAppReady() | ||
.then(waitForPingback) | ||
.then(() => { | ||
return ELECTRON_APP_APPLICATION; | ||
}) | ||
}) | ||
}) | ||
.then((appRef) => { | ||
return appRef.bootstrap(appComp); | ||
}) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import {XHR} from 'angular2/src/compiler/xhr'; | ||
import {WebWorkerXHRImpl} from 'angular2/src/web_workers/worker/xhr_impl'; | ||
import {WebWorkerRootRenderer} from 'angular2/src/web_workers/worker/renderer'; | ||
import {print, Type, CONST_EXPR, isPresent} from 'angular2/src/facade/lang'; | ||
import {RootRenderer} from 'angular2/src/core/render/api'; | ||
import { | ||
PLATFORM_DIRECTIVES, | ||
PLATFORM_PIPES, | ||
ExceptionHandler, | ||
APPLICATION_COMMON_PROVIDERS, | ||
PLATFORM_COMMON_PROVIDERS, | ||
} from 'angular2/core'; | ||
import {COMMON_DIRECTIVES, COMMON_PIPES, FORM_PROVIDERS} from "angular2/common"; | ||
import { | ||
ClientMessageBrokerFactory, | ||
ClientMessageBrokerFactory_ | ||
} from 'angular2/src/web_workers/shared/client_message_broker'; | ||
import { | ||
ServiceMessageBrokerFactory, | ||
ServiceMessageBrokerFactory_ | ||
} from 'angular2/src/web_workers/shared/service_message_broker'; | ||
import {Serializer} from "angular2/src/web_workers/shared/serializer"; | ||
import {ON_WEB_WORKER} from "angular2/src/web_workers/shared/api"; | ||
import {Provider} from 'angular2/src/core/di'; | ||
import {RenderStore} from 'angular2/src/web_workers/shared/render_store'; | ||
|
||
class PrintLogger { | ||
log = print; | ||
logError = print; | ||
logGroup = print; | ||
logGroupEnd() {} | ||
} | ||
|
||
export const ELECTRON_APP_PLATFORM: Array<any /*Type | Provider | any[]*/> = | ||
CONST_EXPR([PLATFORM_COMMON_PROVIDERS]); | ||
|
||
export const ELECTRON_APP_APPLICATION_COMMON: Array<any /*Type | Provider | any[]*/> = CONST_EXPR([ | ||
APPLICATION_COMMON_PROVIDERS, | ||
FORM_PROVIDERS, | ||
Serializer, | ||
new Provider(PLATFORM_PIPES, {useValue: COMMON_PIPES, multi: true}), | ||
new Provider(PLATFORM_DIRECTIVES, {useValue: COMMON_DIRECTIVES, multi: true}), | ||
new Provider(ClientMessageBrokerFactory, {useClass: ClientMessageBrokerFactory_}), | ||
new Provider(ServiceMessageBrokerFactory, {useClass: ServiceMessageBrokerFactory_}), | ||
WebWorkerRootRenderer, | ||
new Provider(RootRenderer, {useExisting: WebWorkerRootRenderer}), | ||
new Provider(ON_WEB_WORKER, {useValue: true}), | ||
RenderStore, | ||
new Provider(ExceptionHandler, {useFactory: _exceptionHandler, deps: []}), | ||
WebWorkerXHRImpl, | ||
new Provider(XHR, {useExisting: WebWorkerXHRImpl}) | ||
]); | ||
|
||
function _exceptionHandler(): ExceptionHandler { | ||
return new ExceptionHandler(new PrintLogger()); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
import * as electron from 'electron'; | ||
import { | ||
MessageBus, | ||
MessageBusSource, | ||
MessageBusSink | ||
} from "angular2/src/web_workers/shared/message_bus"; | ||
import {NgZone, EventEmitter, Injectable} from 'angular2/core'; | ||
|
||
/** | ||
* Typescript Implementation of MessageBus for use in electron apps | ||
*/ | ||
|
||
export const ELECTRON_WORKER = '__ELECTRON_WORKER'; | ||
export const ELECTRON_CLIENT = '__ELECTRON_CLIENT'; | ||
export const ELECTRON_READY = '__ELECTRON_READY' | ||
|
||
const ELECTRON_CHANNEL = '__ELECTRON_CHANNEL'; | ||
|
||
@Injectable() | ||
export class ElectronMessageBus implements MessageBus { | ||
constructor(public sink: ElectronMessageBusSink, | ||
public source: ElectronMessageBusSource, | ||
private env: string = ELECTRON_CLIENT) {} | ||
|
||
attachToZone(zone: NgZone): void { | ||
this.source.attachToZone(zone); | ||
this.sink.attachToZone(zone); | ||
} | ||
|
||
initChannel(channel: string, runInZone: boolean = false): void { | ||
this.source.initChannel(channel, runInZone); | ||
this.sink.initChannel(channel, runInZone); | ||
} | ||
|
||
from(channel: string): EventEmitter<any> { return this.source.from(channel); } | ||
|
||
to(channel: string): EventEmitter<any> { return this.sink.to(channel); } | ||
} | ||
|
||
export class ElectronMessageBusSink implements MessageBusSink { | ||
private _zone: NgZone; | ||
private _channels: Map<string, _ElectronMessageChannel> = | ||
new Map<string, _ElectronMessageChannel>(); | ||
private _messageBuffer: Array<Object> = []; | ||
|
||
constructor(private _ipc: any) {} | ||
|
||
attachToZone(zone: NgZone): void { | ||
this._zone = zone; | ||
this._zone.onTurnDone.subscribe(() => {this._handleOnEventDone()}); | ||
} | ||
|
||
initChannel(channel: string, runInZone: boolean = true): void { | ||
if (this._channels.has(channel)) { | ||
throw new Error(`${channel} has already been initialized`); | ||
} | ||
let _channel = new _ElectronMessageChannel(new EventEmitter(), runInZone); | ||
this._channels.set(channel, _channel); | ||
_channel.emitter.subscribe((data: any) => { | ||
var message = {channel : channel, message : data}; | ||
|
||
if (runInZone) { | ||
this._messageBuffer.push(message); | ||
} else { | ||
this._sendMessages([ message ]); | ||
} | ||
}); | ||
} | ||
|
||
to(channel: string): EventEmitter<any> { | ||
if (!this._channels.has(channel)) { | ||
throw new Error(`${channel} does not exist!`); | ||
} | ||
return this._channels.get(channel).emitter; | ||
} | ||
|
||
private _sendMessages(messages: any[]) { | ||
if (this._ipc.sendChannel) { | ||
this._ipc.sendChannel(ELECTRON_CHANNEL, messages); | ||
} else { | ||
this._ipc.send(ELECTRON_CHANNEL, messages); | ||
} | ||
} | ||
private _handleOnEventDone() { | ||
if (this._messageBuffer.length > 0) { | ||
this._sendMessages(this._messageBuffer); | ||
this._messageBuffer = []; | ||
} | ||
} | ||
} | ||
|
||
export class ElectronMessageBusSource implements MessageBusSource { | ||
private _zone: NgZone; | ||
private _channels: Map<string, _ElectronMessageChannel> = | ||
new Map<string, _ElectronMessageChannel>(); | ||
|
||
constructor(private _ipc?: any) { | ||
this._ipc.on(ELECTRON_CHANNEL, (ev, data) => this._handleMessages(data || ev)); | ||
} | ||
attachToZone(zone: NgZone) { this._zone = zone; } | ||
|
||
initChannel(channel: string, runInZone: boolean = true) { | ||
|
||
if (this._channels.has(channel)) { | ||
throw new Error(`${channel} has already been initialized`); | ||
} | ||
|
||
let emitter = new EventEmitter(); | ||
let channelInfo = new _ElectronMessageChannel(emitter, runInZone); | ||
this._channels.set(channel, channelInfo); | ||
} | ||
|
||
from(channel: string): EventEmitter<any> { | ||
if (this._channels.has(channel)) { | ||
return this._channels.get(channel).emitter; | ||
} else { | ||
throw new Error( | ||
`${channel} is not set up. Did you forget to call initChannel?`); | ||
} | ||
} | ||
|
||
private _handleMessages(messages: any[]): void { | ||
for (var i = 0; i < messages.length; i++) { | ||
this._handleMessage(messages[i]); | ||
} | ||
} | ||
|
||
private _handleMessage(data: any): void { | ||
var channel = data.channel; | ||
if (this._channels.has(channel)) { | ||
var channelInfo = this._channels.get(channel); | ||
this._zone.run(() => { channelInfo.emitter.next(data.message); }); | ||
} else { | ||
throw new Error('unhandled message!'); | ||
} | ||
} | ||
} | ||
|
||
class _ElectronMessageChannel { | ||
constructor(public emitter: EventEmitter<any>, public runInZone: boolean) {} | ||
} |
Oops, something went wrong.