forked from angular/angular
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrenderer.ts
More file actions
287 lines (263 loc) · 10.3 KB
/
renderer.ts
File metadata and controls
287 lines (263 loc) · 10.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
import {
Renderer,
RenderCompiler,
RenderDirectiveMetadata,
ProtoViewDto,
ViewDefinition,
RenderProtoViewRef,
RenderViewRef,
RenderElementRef,
RenderEventDispatcher,
RenderProtoViewMergeMapping,
RenderViewWithFragments,
RenderFragmentRef
} from 'angular2/src/core/render/api';
import {Promise, PromiseWrapper} from "angular2/src/core/facade/async";
import {
ClientMessageBroker,
ClientMessageBrokerFactory,
FnArg,
UiArguments
} from "angular2/src/web_workers/shared/client_message_broker";
import {isPresent, print, BaseException} from "angular2/src/core/facade/lang";
import {Injectable} from "angular2/src/core/di";
import {
RenderViewWithFragmentsStore,
WebWorkerRenderViewRef
} from 'angular2/src/web_workers/shared/render_view_with_fragments_store';
import {WebWorkerElementRef} from 'angular2/src/web_workers/shared/api';
import {
RENDER_COMPILER_CHANNEL,
RENDERER_CHANNEL
} from 'angular2/src/web_workers/shared/messaging_api';
import {WebWorkerEventDispatcher} from 'angular2/src/web_workers/worker/event_dispatcher';
@Injectable()
export class WebWorkerCompiler implements RenderCompiler {
private _messageBroker;
constructor(messageBrokerFactory: ClientMessageBrokerFactory) {
this._messageBroker = messageBrokerFactory.createMessageBroker(RENDER_COMPILER_CHANNEL);
}
/**
* Creats a ProtoViewDto that contains a single nested component with the given componentId.
*/
compileHost(directiveMetadata: RenderDirectiveMetadata): Promise<ProtoViewDto> {
var fnArgs: FnArg[] = [new FnArg(directiveMetadata, RenderDirectiveMetadata)];
var args: UiArguments = new UiArguments("compileHost", fnArgs);
return this._messageBroker.runOnService(args, ProtoViewDto);
}
/**
* Compiles a single DomProtoView. Non recursive so that
* we don't need to serialize all possible components over the wire,
* but only the needed ones based on previous calls.
*/
compile(view: ViewDefinition): Promise<ProtoViewDto> {
var fnArgs: FnArg[] = [new FnArg(view, ViewDefinition)];
var args: UiArguments = new UiArguments("compile", fnArgs);
return this._messageBroker.runOnService(args, ProtoViewDto);
}
/**
* Merges ProtoViews.
* The first entry of the array is the protoview into which all the other entries of the array
* should be merged.
* If the array contains other arrays, they will be merged before processing the parent array.
* The array must contain an entry for every component and embedded ProtoView of the first entry.
* @param protoViewRefs Array of ProtoViewRefs or nested
* @return the merge result for every input array in depth first order.
*/
mergeProtoViewsRecursively(
protoViewRefs: Array<RenderProtoViewRef | any[]>): Promise<RenderProtoViewMergeMapping> {
var fnArgs: FnArg[] = [new FnArg(protoViewRefs, RenderProtoViewRef)];
var args: UiArguments = new UiArguments("mergeProtoViewsRecursively", fnArgs);
return this._messageBroker.runOnService(args, RenderProtoViewMergeMapping);
}
}
@Injectable()
export class WebWorkerRenderer implements Renderer {
private _messageBroker;
constructor(messageBrokerFactory: ClientMessageBrokerFactory,
private _renderViewStore: RenderViewWithFragmentsStore,
private _eventDispatcher: WebWorkerEventDispatcher) {
this._messageBroker = messageBrokerFactory.createMessageBroker(RENDERER_CHANNEL);
}
/**
* Creates a root host view that includes the given element.
* Note that the fragmentCount needs to be passed in so that we can create a result
* synchronously even when dealing with webworkers!
*
* @param {RenderProtoViewRef} hostProtoViewRef a RenderProtoViewRef of type
* ProtoViewDto.HOST_VIEW_TYPE
* @param {any} hostElementSelector css selector for the host element (will be queried against the
* main document)
* @return {RenderViewRef} the created view
*/
createRootHostView(hostProtoViewRef: RenderProtoViewRef, fragmentCount: number,
hostElementSelector: string): RenderViewWithFragments {
return this._createViewHelper(hostProtoViewRef, fragmentCount, hostElementSelector);
}
/**
* Creates a regular view out of the given ProtoView
* Note that the fragmentCount needs to be passed in so that we can create a result
* synchronously even when dealing with webworkers!
*/
createView(protoViewRef: RenderProtoViewRef, fragmentCount: number): RenderViewWithFragments {
return this._createViewHelper(protoViewRef, fragmentCount);
}
private _createViewHelper(protoViewRef: RenderProtoViewRef, fragmentCount: number,
hostElementSelector?: string): RenderViewWithFragments {
var renderViewWithFragments = this._renderViewStore.allocate(fragmentCount);
var startIndex = (<WebWorkerRenderViewRef>(renderViewWithFragments.viewRef)).refNumber;
var fnArgs: FnArg[] = [
new FnArg(protoViewRef, RenderProtoViewRef),
new FnArg(fragmentCount, null),
];
var method = "createView";
if (isPresent(hostElementSelector) && hostElementSelector != null) {
fnArgs.push(new FnArg(hostElementSelector, null));
method = "createRootHostView";
}
fnArgs.push(new FnArg(startIndex, null));
var args = new UiArguments(method, fnArgs);
this._messageBroker.runOnService(args, null);
return renderViewWithFragments;
}
/**
* Destroys the given view after it has been dehydrated and detached
*/
destroyView(viewRef: RenderViewRef) {
var fnArgs = [new FnArg(viewRef, RenderViewRef)];
var args = new UiArguments("destroyView", fnArgs);
this._messageBroker.runOnService(args, null);
this._renderViewStore.remove(viewRef);
}
/**
* Attaches a fragment after another fragment.
*/
attachFragmentAfterFragment(previousFragmentRef: RenderFragmentRef,
fragmentRef: RenderFragmentRef) {
var fnArgs = [
new FnArg(previousFragmentRef, RenderFragmentRef),
new FnArg(fragmentRef, RenderFragmentRef)
];
var args = new UiArguments("attachFragmentAfterFragment", fnArgs);
this._messageBroker.runOnService(args, null);
}
/**
* Attaches a fragment after an element.
*/
attachFragmentAfterElement(elementRef: RenderElementRef, fragmentRef: RenderFragmentRef) {
var fnArgs =
[new FnArg(elementRef, WebWorkerElementRef), new FnArg(fragmentRef, RenderFragmentRef)];
var args = new UiArguments("attachFragmentAfterElement", fnArgs);
this._messageBroker.runOnService(args, null);
}
/**
* Detaches a fragment.
*/
detachFragment(fragmentRef: RenderFragmentRef) {
var fnArgs = [new FnArg(fragmentRef, RenderFragmentRef)];
var args = new UiArguments("detachFragment", fnArgs);
this._messageBroker.runOnService(args, null);
}
/**
* Hydrates a view after it has been attached. Hydration/dehydration is used for reusing views
* inside of the view pool.
*/
hydrateView(viewRef: RenderViewRef) {
var fnArgs = [new FnArg(viewRef, RenderViewRef)];
var args = new UiArguments("hydrateView", fnArgs);
this._messageBroker.runOnService(args, null);
}
/**
* Dehydrates a view after it has been attached. Hydration/dehydration is used for reusing views
* inside of the view pool.
*/
dehydrateView(viewRef: RenderViewRef) {
var fnArgs = [new FnArg(viewRef, RenderViewRef)];
var args = new UiArguments("dehydrateView", fnArgs);
this._messageBroker.runOnService(args, null);
}
/**
* Returns the native element at the given location.
* Attention: In a WebWorker scenario, this should always return null!
*/
getNativeElementSync(location: RenderElementRef): any { return null; }
/**
* Sets a property on an element.
*/
setElementProperty(location: RenderElementRef, propertyName: string, propertyValue: any) {
var fnArgs = [
new FnArg(location, WebWorkerElementRef),
new FnArg(propertyName, null),
new FnArg(propertyValue, null)
];
var args = new UiArguments("setElementProperty", fnArgs);
this._messageBroker.runOnService(args, null);
}
/**
* Sets an attribute on an element.
*/
setElementAttribute(location: RenderElementRef, attributeName: string, attributeValue: string) {
var fnArgs = [
new FnArg(location, WebWorkerElementRef),
new FnArg(attributeName, null),
new FnArg(attributeValue, null)
];
var args = new UiArguments("setElementAttribute", fnArgs);
this._messageBroker.runOnService(args, null);
}
/**
* Sets a class on an element.
*/
setElementClass(location: RenderElementRef, className: string, isAdd: boolean) {
var fnArgs = [
new FnArg(location, WebWorkerElementRef),
new FnArg(className, null),
new FnArg(isAdd, null)
];
var args = new UiArguments("setElementClass", fnArgs);
this._messageBroker.runOnService(args, null);
}
/**
* Sets a style on an element.
*/
setElementStyle(location: RenderElementRef, styleName: string, styleValue: string) {
var fnArgs = [
new FnArg(location, WebWorkerElementRef),
new FnArg(styleName, null),
new FnArg(styleValue, null)
];
var args = new UiArguments("setElementStyle", fnArgs);
this._messageBroker.runOnService(args, null);
}
/**
* Calls a method on an element.
* Note: For now we're assuming that everything in the args list are primitive
*/
invokeElementMethod(location: RenderElementRef, methodName: string, args: any[]) {
var fnArgs = [
new FnArg(location, WebWorkerElementRef),
new FnArg(methodName, null),
new FnArg(args, null)
];
var uiArgs = new UiArguments("invokeElementMethod", fnArgs);
this._messageBroker.runOnService(uiArgs, null);
}
/**
* Sets the value of a text node.
*/
setText(viewRef: RenderViewRef, textNodeIndex: number, text: string) {
var fnArgs =
[new FnArg(viewRef, RenderViewRef), new FnArg(textNodeIndex, null), new FnArg(text, null)];
var args = new UiArguments("setText", fnArgs);
this._messageBroker.runOnService(args, null);
}
/**
* Sets the dispatcher for all events of the given view
*/
setEventDispatcher(viewRef: RenderViewRef, dispatcher: RenderEventDispatcher) {
var fnArgs = [new FnArg(viewRef, RenderViewRef)];
var args = new UiArguments("setEventDispatcher", fnArgs);
this._eventDispatcher.registerEventDispatcher(viewRef, dispatcher);
this._messageBroker.runOnService(args, null);
}
}