2015-07-10 16:09:18 -07:00
|
|
|
import {
|
|
|
|
|
Renderer,
|
|
|
|
|
RenderCompiler,
|
2015-08-14 10:03:45 -07:00
|
|
|
RenderDirectiveMetadata,
|
2015-07-10 16:09:18 -07:00
|
|
|
ProtoViewDto,
|
|
|
|
|
ViewDefinition,
|
|
|
|
|
RenderProtoViewRef,
|
|
|
|
|
RenderViewRef,
|
|
|
|
|
RenderElementRef,
|
|
|
|
|
RenderEventDispatcher,
|
|
|
|
|
RenderProtoViewMergeMapping,
|
|
|
|
|
RenderViewWithFragments,
|
|
|
|
|
RenderFragmentRef
|
|
|
|
|
} from 'angular2/src/render/api';
|
|
|
|
|
import {Promise, PromiseWrapper} from "angular2/src/facade/async";
|
2015-08-17 10:28:47 -07:00
|
|
|
import {
|
|
|
|
|
MessageBroker,
|
|
|
|
|
MessageBrokerFactory,
|
|
|
|
|
FnArg,
|
|
|
|
|
UiArguments
|
|
|
|
|
} from "angular2/src/web-workers/worker/broker";
|
2015-07-10 16:09:18 -07:00
|
|
|
import {isPresent, print, BaseException} from "angular2/src/facade/lang";
|
|
|
|
|
import {Injectable} from "angular2/di";
|
|
|
|
|
import {
|
|
|
|
|
RenderViewWithFragmentsStore,
|
2015-08-07 13:17:54 -07:00
|
|
|
WebWorkerRenderViewRef
|
2015-07-10 16:09:18 -07:00
|
|
|
} from 'angular2/src/web-workers/shared/render_view_with_fragments_store';
|
2015-08-07 13:17:54 -07:00
|
|
|
import {WebWorkerElementRef} from 'angular2/src/web-workers/shared/api';
|
2015-08-17 10:28:47 -07:00
|
|
|
import {
|
|
|
|
|
RENDER_COMPILER_CHANNEL,
|
|
|
|
|
RENDERER_CHANNEL
|
|
|
|
|
} from 'angular2/src/web-workers/shared/messaging_api';
|
|
|
|
|
import {WebWorkerEventDispatcher} from 'angular2/src/web-workers/worker/event_dispatcher';
|
2015-07-10 16:09:18 -07:00
|
|
|
|
|
|
|
|
@Injectable()
|
2015-08-07 13:17:54 -07:00
|
|
|
export class WebWorkerCompiler implements RenderCompiler {
|
2015-08-17 10:28:47 -07:00
|
|
|
private _messageBroker;
|
|
|
|
|
constructor(messageBrokerFactory: MessageBrokerFactory) {
|
|
|
|
|
this._messageBroker = messageBrokerFactory.createMessageBroker(RENDER_COMPILER_CHANNEL);
|
|
|
|
|
}
|
2015-07-10 16:09:18 -07:00
|
|
|
/**
|
|
|
|
|
* Creats a ProtoViewDto that contains a single nested component with the given componentId.
|
|
|
|
|
*/
|
2015-08-14 10:03:45 -07:00
|
|
|
compileHost(directiveMetadata: RenderDirectiveMetadata): Promise<ProtoViewDto> {
|
|
|
|
|
var fnArgs: List<FnArg> = [new FnArg(directiveMetadata, RenderDirectiveMetadata)];
|
2015-08-17 10:28:47 -07:00
|
|
|
var args: UiArguments = new UiArguments("compileHost", fnArgs);
|
2015-07-10 16:09:18 -07:00
|
|
|
return this._messageBroker.runOnUiThread(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: List<FnArg> = [new FnArg(view, ViewDefinition)];
|
2015-08-17 10:28:47 -07:00
|
|
|
var args: UiArguments = new UiArguments("compile", fnArgs);
|
2015-07-10 16:09:18 -07:00
|
|
|
return this._messageBroker.runOnUiThread(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 List of ProtoViewRefs or nested
|
|
|
|
|
* @return the merge result for every input array in depth first order.
|
|
|
|
|
*/
|
|
|
|
|
mergeProtoViewsRecursively(
|
|
|
|
|
protoViewRefs: List<RenderProtoViewRef | List<any>>): Promise<RenderProtoViewMergeMapping> {
|
|
|
|
|
var fnArgs: List<FnArg> = [new FnArg(protoViewRefs, RenderProtoViewRef)];
|
2015-08-17 10:28:47 -07:00
|
|
|
var args: UiArguments = new UiArguments("mergeProtoViewsRecursively", fnArgs);
|
2015-07-10 16:09:18 -07:00
|
|
|
return this._messageBroker.runOnUiThread(args, RenderProtoViewMergeMapping);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Injectable()
|
2015-08-07 13:17:54 -07:00
|
|
|
export class WebWorkerRenderer implements Renderer {
|
2015-08-17 10:28:47 -07:00
|
|
|
private _messageBroker;
|
|
|
|
|
constructor(messageBrokerFactory: MessageBrokerFactory,
|
|
|
|
|
private _renderViewStore: RenderViewWithFragmentsStore,
|
|
|
|
|
private _eventDispatcher: WebWorkerEventDispatcher) {
|
|
|
|
|
this._messageBroker = messageBrokerFactory.createMessageBroker(RENDERER_CHANNEL);
|
|
|
|
|
}
|
2015-07-10 16:09:18 -07:00
|
|
|
/**
|
|
|
|
|
* 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);
|
|
|
|
|
|
2015-08-07 13:17:54 -07:00
|
|
|
var startIndex = (<WebWorkerRenderViewRef>(renderViewWithFragments.viewRef)).refNumber;
|
2015-07-10 16:09:18 -07:00
|
|
|
var fnArgs: List<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));
|
|
|
|
|
|
2015-08-17 10:28:47 -07:00
|
|
|
var args = new UiArguments(method, fnArgs);
|
2015-07-10 16:09:18 -07:00
|
|
|
this._messageBroker.runOnUiThread(args, null);
|
|
|
|
|
|
|
|
|
|
return renderViewWithFragments;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Destroys the given view after it has been dehydrated and detached
|
|
|
|
|
*/
|
|
|
|
|
destroyView(viewRef: RenderViewRef) {
|
|
|
|
|
var fnArgs = [new FnArg(viewRef, RenderViewRef)];
|
2015-08-17 10:28:47 -07:00
|
|
|
var args = new UiArguments("destroyView", fnArgs);
|
2015-07-10 16:09:18 -07:00
|
|
|
this._messageBroker.runOnUiThread(args, null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Attaches a fragment after another fragment.
|
|
|
|
|
*/
|
|
|
|
|
attachFragmentAfterFragment(previousFragmentRef: RenderFragmentRef,
|
|
|
|
|
fragmentRef: RenderFragmentRef) {
|
|
|
|
|
var fnArgs = [
|
|
|
|
|
new FnArg(previousFragmentRef, RenderFragmentRef),
|
|
|
|
|
new FnArg(fragmentRef, RenderFragmentRef)
|
|
|
|
|
];
|
2015-08-17 10:28:47 -07:00
|
|
|
var args = new UiArguments("attachFragmentAfterFragment", fnArgs);
|
2015-07-10 16:09:18 -07:00
|
|
|
this._messageBroker.runOnUiThread(args, null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Attaches a fragment after an element.
|
|
|
|
|
*/
|
|
|
|
|
attachFragmentAfterElement(elementRef: RenderElementRef, fragmentRef: RenderFragmentRef) {
|
|
|
|
|
var fnArgs =
|
2015-08-07 13:17:54 -07:00
|
|
|
[new FnArg(elementRef, WebWorkerElementRef), new FnArg(fragmentRef, RenderFragmentRef)];
|
2015-08-17 10:28:47 -07:00
|
|
|
var args = new UiArguments("attachFragmentAfterElement", fnArgs);
|
2015-07-10 16:09:18 -07:00
|
|
|
this._messageBroker.runOnUiThread(args, null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Detaches a fragment.
|
|
|
|
|
*/
|
|
|
|
|
detachFragment(fragmentRef: RenderFragmentRef) {
|
|
|
|
|
var fnArgs = [new FnArg(fragmentRef, RenderFragmentRef)];
|
2015-08-17 10:28:47 -07:00
|
|
|
var args = new UiArguments("detachFragment", fnArgs);
|
2015-07-10 16:09:18 -07:00
|
|
|
this._messageBroker.runOnUiThread(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)];
|
2015-08-17 10:28:47 -07:00
|
|
|
var args = new UiArguments("hydrateView", fnArgs);
|
2015-07-10 16:09:18 -07:00
|
|
|
this._messageBroker.runOnUiThread(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)];
|
2015-08-17 10:28:47 -07:00
|
|
|
var args = new UiArguments("dehydrateView", fnArgs);
|
2015-07-10 16:09:18 -07:00
|
|
|
this._messageBroker.runOnUiThread(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 = [
|
2015-08-07 13:17:54 -07:00
|
|
|
new FnArg(location, WebWorkerElementRef),
|
2015-07-10 16:09:18 -07:00
|
|
|
new FnArg(propertyName, null),
|
|
|
|
|
new FnArg(propertyValue, null)
|
|
|
|
|
];
|
2015-08-17 10:28:47 -07:00
|
|
|
var args = new UiArguments("setElementProperty", fnArgs);
|
2015-07-10 16:09:18 -07:00
|
|
|
this._messageBroker.runOnUiThread(args, null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Sets an attribute on an element.
|
|
|
|
|
*/
|
|
|
|
|
setElementAttribute(location: RenderElementRef, attributeName: string, attributeValue: string) {
|
|
|
|
|
var fnArgs = [
|
2015-08-07 13:17:54 -07:00
|
|
|
new FnArg(location, WebWorkerElementRef),
|
2015-07-10 16:09:18 -07:00
|
|
|
new FnArg(attributeName, null),
|
|
|
|
|
new FnArg(attributeValue, null)
|
|
|
|
|
];
|
2015-08-17 10:28:47 -07:00
|
|
|
var args = new UiArguments("setElementAttribute", fnArgs);
|
2015-07-10 16:09:18 -07:00
|
|
|
this._messageBroker.runOnUiThread(args, null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Sets a class on an element.
|
|
|
|
|
*/
|
|
|
|
|
setElementClass(location: RenderElementRef, className: string, isAdd: boolean) {
|
2015-08-07 13:17:54 -07:00
|
|
|
var fnArgs = [
|
|
|
|
|
new FnArg(location, WebWorkerElementRef),
|
|
|
|
|
new FnArg(className, null),
|
|
|
|
|
new FnArg(isAdd, null)
|
|
|
|
|
];
|
2015-08-17 10:28:47 -07:00
|
|
|
var args = new UiArguments("setElementClass", fnArgs);
|
2015-07-10 16:09:18 -07:00
|
|
|
this._messageBroker.runOnUiThread(args, null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Sets a style on an element.
|
|
|
|
|
*/
|
|
|
|
|
setElementStyle(location: RenderElementRef, styleName: string, styleValue: string) {
|
|
|
|
|
var fnArgs = [
|
2015-08-07 13:17:54 -07:00
|
|
|
new FnArg(location, WebWorkerElementRef),
|
2015-07-10 16:09:18 -07:00
|
|
|
new FnArg(styleName, null),
|
|
|
|
|
new FnArg(styleValue, null)
|
|
|
|
|
];
|
2015-08-17 10:28:47 -07:00
|
|
|
var args = new UiArguments("setElementStyle", fnArgs);
|
2015-07-10 16:09:18 -07:00
|
|
|
this._messageBroker.runOnUiThread(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: List<any>) {
|
2015-08-07 13:17:54 -07:00
|
|
|
var fnArgs = [
|
|
|
|
|
new FnArg(location, WebWorkerElementRef),
|
|
|
|
|
new FnArg(methodName, null),
|
|
|
|
|
new FnArg(args, null)
|
|
|
|
|
];
|
2015-08-17 10:28:47 -07:00
|
|
|
var uiArgs = new UiArguments("invokeElementMethod", fnArgs);
|
2015-07-10 16:09:18 -07:00
|
|
|
this._messageBroker.runOnUiThread(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)];
|
2015-08-17 10:28:47 -07:00
|
|
|
var args = new UiArguments("setText", fnArgs);
|
2015-07-10 16:09:18 -07:00
|
|
|
this._messageBroker.runOnUiThread(args, null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Sets the dispatcher for all events of the given view
|
|
|
|
|
*/
|
|
|
|
|
setEventDispatcher(viewRef: RenderViewRef, dispatcher: RenderEventDispatcher) {
|
2015-07-10 16:09:18 -07:00
|
|
|
var fnArgs = [new FnArg(viewRef, RenderViewRef)];
|
2015-08-17 10:28:47 -07:00
|
|
|
var args = new UiArguments("setEventDispatcher", fnArgs);
|
|
|
|
|
this._eventDispatcher.registerEventDispatcher(viewRef, dispatcher);
|
2015-07-10 16:09:18 -07:00
|
|
|
this._messageBroker.runOnUiThread(args, null);
|
2015-07-10 16:09:18 -07:00
|
|
|
}
|
|
|
|
|
}
|