Skip to content

Commit 771c017

Browse files
committed
feat(web-workers) Add WebWorker Renderer
Allows angular apps to be rendered from the webworker! Closes angular#3052, angular#3053, and angular#3097
1 parent 21b988f commit 771c017

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+3864
-476
lines changed

modules/angular2/src/change_detection/parser/parser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ export class Parser {
106106
}
107107
}
108108

109-
class _ParseAST {
109+
export class _ParseAST {
110110
index: int = 0;
111111
constructor(public input: string, public location: any, public tokens: List<any>,
112112
public reflector: Reflector, public parseAction: boolean) {}

modules/angular2/src/core/application_common.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import {HammerGesturesPlugin} from 'angular2/src/render/dom/events/hammer_gestur
4545
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
4646
import {UrlResolver} from 'angular2/src/services/url_resolver';
4747
import {AppRootUrl} from 'angular2/src/services/app_root_url';
48+
import {AnchorBasedAppRootUrl} from 'angular2/src/services/anchor_based_app_root_url';
4849
import {
4950
ComponentRef,
5051
DynamicComponentLoader
@@ -136,14 +137,14 @@ function _injectorBindings(appComponentType): List<Type | Binding | List<any>> {
136137
StyleInliner,
137138
DynamicComponentLoader,
138139
Testability,
139-
AppRootUrl
140+
AnchorBasedAppRootUrl,
141+
bind(AppRootUrl).toAlias(AnchorBasedAppRootUrl)
140142
];
141143
}
142144

143-
function _createNgZone(): NgZone {
145+
export function createNgZone(handler: ExceptionHandler): NgZone {
144146
// bootstrapErrorReporter is needed because we cannot use custom exception handler
145147
// configured via DI until the root Injector has been created.
146-
var handler = new ExceptionHandler();
147148
var bootstrapErrorReporter = (exception, stackTrace) => handler.call(exception, stackTrace);
148149
var zone = new NgZone({enableLongStackTrace: assertionsEnabled()});
149150
zone.overrideOnErrorHandler(bootstrapErrorReporter);
@@ -282,7 +283,7 @@ export function commonBootstrap(
282283
BrowserDomAdapter.makeCurrent();
283284
var bootstrapProcess = PromiseWrapper.completer();
284285

285-
var zone = _createNgZone();
286+
var zone = createNgZone(new ExceptionHandler());
286287
zone.run(() => {
287288
// TODO(rado): prepopulate template cache, so applications with only
288289
// index.html and main.js are possible.

modules/angular2/src/facade/lang.dart

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,19 @@ bool isDate(obj) => obj is DateTime;
3939

4040
String stringify(obj) => obj.toString();
4141

42+
int serializeEnum(val) {
43+
return val.index;
44+
}
45+
46+
/**
47+
* Deserializes an enum
48+
* val should be the indexed value of the enum (sa returned from @Link{serializeEnum})
49+
* values should be a map from indexes to values for the enum that you want to deserialize.
50+
*/
51+
dynamic deserializeEnum(int val, Map<int, dynamic> values) {
52+
return values[val];
53+
}
54+
4255
class StringWrapper {
4356
static String fromCharCode(int code) {
4457
return new String.fromCharCode(code);

modules/angular2/src/facade/lang.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,17 @@ export function stringify(token): string {
130130
return (newLineIndex === -1) ? res : res.substring(0, newLineIndex);
131131
}
132132

133+
// serialize / deserialize enum exist only for consistency with dart API
134+
// enums in typescript don't need to be serialized
135+
136+
export function serializeEnum(val): int {
137+
return val;
138+
}
139+
140+
export function deserializeEnum(val, values: Map<int, any>): any {
141+
return val;
142+
}
143+
133144
export class StringWrapper {
134145
static fromCharCode(code: int): string { return String.fromCharCode(code); }
135146

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import {AppRootUrl} from "angular2/src/services/app_root_url";
2+
import {DOM} from "angular2/src/dom/dom_adapter";
3+
import {Injectable} from "angular2/di";
4+
5+
/**
6+
* Extension of {@link AppRootUrl} that uses a DOM anchor tag to set the root url to
7+
* the current page's url.
8+
*/
9+
@Injectable()
10+
export class AnchorBasedAppRootUrl extends AppRootUrl {
11+
constructor() {
12+
super("");
13+
// compute the root url to pass to AppRootUrl
14+
var rootUrl: string;
15+
var a = DOM.createElement('a');
16+
DOM.resolveAndSetHref(a, './', null);
17+
rootUrl = DOM.getHref(a);
18+
19+
this.value = rootUrl;
20+
}
21+
}
Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import {Injectable} from 'angular2/di';
22
import {isBlank} from 'angular2/src/facade/lang';
3-
import {DOM} from 'angular2/src/dom/dom_adapter';
43

54
/**
65
* Specifies app root url for the application.
@@ -15,16 +14,12 @@ import {DOM} from 'angular2/src/dom/dom_adapter';
1514
export class AppRootUrl {
1615
private _value: string;
1716

17+
constructor(value: string) { this._value = value; }
18+
1819
/**
1920
* Returns the base URL of the currently running application.
2021
*/
21-
get value() {
22-
if (isBlank(this._value)) {
23-
var a = DOM.createElement('a');
24-
DOM.resolveAndSetHref(a, './', null);
25-
this._value = DOM.getHref(a);
26-
}
22+
get value() { return this._value; }
2723

28-
return this._value;
29-
}
24+
set value(value: string) { this._value = value; }
3025
}

modules/angular2/src/test_lib/test_injector.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {XHR} from 'angular2/src/render/xhr';
2323
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
2424
import {UrlResolver} from 'angular2/src/services/url_resolver';
2525
import {AppRootUrl} from 'angular2/src/services/app_root_url';
26+
import {AnchorBasedAppRootUrl} from 'angular2/src/services/anchor_based_app_root_url';
2627
import {StyleUrlResolver} from 'angular2/src/render/dom/compiler/style_url_resolver';
2728
import {StyleInliner} from 'angular2/src/render/dom/compiler/style_inliner';
2829
import {NgZone} from 'angular2/src/core/zone/ng_zone';
@@ -56,6 +57,7 @@ import {
5657
DOM_REFLECT_PROPERTIES_AS_ATTRIBUTES
5758
} from 'angular2/src/render/dom/dom_renderer';
5859
import {DefaultDomCompiler} from 'angular2/src/render/dom/compiler/compiler';
60+
import {Serializer} from "angular2/src/web-workers/shared/serializer";
5961
import {Log} from './utils';
6062

6163
/**
@@ -88,6 +90,7 @@ function _getAppBindings() {
8890
} catch (e) {
8991
appDoc = null;
9092
}
93+
9194
return [
9295
bind(DOCUMENT_TOKEN)
9396
.toValue(appDoc),
@@ -102,6 +105,7 @@ function _getAppBindings() {
102105
AppViewPool,
103106
AppViewManager,
104107
AppViewManagerUtils,
108+
Serializer,
105109
ELEMENT_PROBE_CONFIG,
106110
bind(APP_VIEW_POOL_CAPACITY).toValue(500),
107111
Compiler,
@@ -120,7 +124,8 @@ function _getAppBindings() {
120124
bind(XHR).toClass(MockXHR),
121125
ComponentUrlMapper,
122126
UrlResolver,
123-
AppRootUrl,
127+
AnchorBasedAppRootUrl,
128+
bind(AppRootUrl).toAlias(AnchorBasedAppRootUrl),
124129
StyleUrlResolver,
125130
StyleInliner,
126131
TestComponentBuilder,
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import {CONST_EXPR} from "angular2/src/facade/lang";
2+
import {OpaqueToken} from "angular2/di";
3+
import {RenderElementRef, RenderViewRef} from "angular2/src/render/api";
4+
5+
export const ON_WEBWORKER = CONST_EXPR(new OpaqueToken('WebWorker.onWebWorker'));
6+
7+
export class WorkerElementRef implements RenderElementRef {
8+
constructor(public renderView: RenderViewRef, public renderBoundElementIndex: number) {}
9+
}

modules/angular2/src/web-workers/shared/message_bus.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ export interface SourceListener {
1313
(data: any): void; // TODO: Replace this any type with the type of a real messaging protocol
1414
}
1515

16-
export interface MessageBusSource { listen(fn: SourceListener): void; }
16+
export interface MessageBusSource {
17+
/**
18+
* Attaches the SourceListener to this source.
19+
* The SourceListener will get called whenever the bus receives a message
20+
* Returns a listener id that can be passed to {@link removeListener}
21+
*/
22+
addListener(fn: SourceListener): number;
23+
removeListener(index: number);
24+
}
1725

1826
export interface MessageBusSink { send(message: Object): void; }
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import {Injectable, Inject} from "angular2/di";
2+
import {RenderProtoViewRef} from "angular2/src/render/api";
3+
import {ON_WEBWORKER} from "angular2/src/web-workers/shared/api";
4+
5+
@Injectable()
6+
export class RenderProtoViewRefStore {
7+
private _lookupByIndex: Map<number, RenderProtoViewRef> = new Map<number, RenderProtoViewRef>();
8+
private _lookupByProtoView: Map<RenderProtoViewRef, number> =
9+
new Map<RenderProtoViewRef, number>();
10+
private _nextIndex: number = 0;
11+
private _onWebworker: boolean;
12+
13+
constructor(@Inject(ON_WEBWORKER) onWebworker) { this._onWebworker = onWebworker; }
14+
15+
storeRenderProtoViewRef(ref: RenderProtoViewRef): number {
16+
if (this._lookupByProtoView.has(ref)) {
17+
return this._lookupByProtoView.get(ref);
18+
} else {
19+
this._lookupByIndex.set(this._nextIndex, ref);
20+
this._lookupByProtoView.set(ref, this._nextIndex);
21+
return this._nextIndex++;
22+
}
23+
}
24+
25+
retreiveRenderProtoViewRef(index: number): RenderProtoViewRef {
26+
return this._lookupByIndex.get(index);
27+
}
28+
29+
deserialize(index: number): RenderProtoViewRef {
30+
if (index == null) {
31+
return null;
32+
}
33+
34+
if (this._onWebworker) {
35+
return new WebworkerRenderProtoViewRef(index);
36+
} else {
37+
return this.retreiveRenderProtoViewRef(index);
38+
}
39+
}
40+
41+
serialize(ref: RenderProtoViewRef): number {
42+
if (ref == null) {
43+
return null;
44+
}
45+
46+
if (this._onWebworker) {
47+
return (<WebworkerRenderProtoViewRef>ref).refNumber;
48+
} else {
49+
return this.storeRenderProtoViewRef(ref);
50+
}
51+
}
52+
}
53+
54+
export class WebworkerRenderProtoViewRef extends RenderProtoViewRef {
55+
constructor(public refNumber: number) { super(); }
56+
}

0 commit comments

Comments
 (0)