2015-07-23 18:01:34 -07:00
|
|
|
import {
|
|
|
|
ListWrapper,
|
|
|
|
MapWrapper,
|
|
|
|
Map,
|
|
|
|
StringMapWrapper,
|
|
|
|
StringMap
|
2015-08-20 14:28:25 -07:00
|
|
|
} from 'angular2/src/core/facade/collection';
|
2015-05-20 09:48:15 -07:00
|
|
|
import {
|
|
|
|
AST,
|
2015-07-28 12:43:41 -07:00
|
|
|
ChangeDetector,
|
|
|
|
ChangeDetectorRef,
|
|
|
|
ChangeDispatcher,
|
2015-05-20 09:48:15 -07:00
|
|
|
DirectiveIndex,
|
2015-07-28 12:43:41 -07:00
|
|
|
DirectiveRecord,
|
2015-08-19 11:26:45 -07:00
|
|
|
BindingTarget,
|
2015-07-28 12:43:41 -07:00
|
|
|
Locals,
|
|
|
|
ProtoChangeDetector
|
2015-08-20 14:28:25 -07:00
|
|
|
} from 'angular2/src/core/change_detection/change_detection';
|
|
|
|
import {DebugContext} from 'angular2/src/core/change_detection/interfaces';
|
2015-05-20 09:48:15 -07:00
|
|
|
|
|
|
|
import {
|
|
|
|
ProtoElementInjector,
|
|
|
|
ElementInjector,
|
|
|
|
PreBuiltObjects,
|
|
|
|
DirectiveBinding
|
|
|
|
} from './element_injector';
|
2014-11-11 17:33:47 -08:00
|
|
|
import {ElementBinder} from './element_binder';
|
2015-08-20 14:28:25 -07:00
|
|
|
import {isPresent, isBlank, BaseException} from 'angular2/src/core/facade/lang';
|
|
|
|
import * as renderApi from 'angular2/src/core/render/api';
|
|
|
|
import {RenderEventDispatcher} from 'angular2/src/core/render/api';
|
2015-07-17 08:03:40 -07:00
|
|
|
import {ViewRef, ProtoViewRef, internalView} from './view_ref';
|
2015-06-23 11:21:56 -07:00
|
|
|
import {ElementRef} from './element_ref';
|
2015-08-07 11:41:38 -07:00
|
|
|
import {ProtoPipes} from 'angular2/src/core/pipes/pipes';
|
2015-08-20 14:28:25 -07:00
|
|
|
import {camelCaseToDashCase} from 'angular2/src/core/render/dom/util';
|
2015-04-24 17:53:06 -07:00
|
|
|
|
2015-08-20 14:28:25 -07:00
|
|
|
export {DebugContext} from 'angular2/src/core/change_detection/interfaces';
|
2015-07-28 12:43:41 -07:00
|
|
|
|
2015-08-20 15:11:12 -07:00
|
|
|
const REFLECT_PREFIX: string = 'ng-reflect-';
|
|
|
|
|
2015-06-24 13:46:39 -07:00
|
|
|
export class AppProtoViewMergeMapping {
|
|
|
|
renderProtoViewRef: renderApi.RenderProtoViewRef;
|
|
|
|
renderFragmentCount: number;
|
|
|
|
renderElementIndices: number[];
|
|
|
|
renderInverseElementIndices: number[];
|
|
|
|
renderTextIndices: number[];
|
|
|
|
nestedViewIndicesByElementIndex: number[];
|
|
|
|
hostElementIndicesByViewIndex: number[];
|
2015-07-20 09:59:44 -07:00
|
|
|
nestedViewCountByViewIndex: number[];
|
2015-06-24 13:46:39 -07:00
|
|
|
constructor(renderProtoViewMergeMapping: renderApi.RenderProtoViewMergeMapping) {
|
|
|
|
this.renderProtoViewRef = renderProtoViewMergeMapping.mergedProtoViewRef;
|
|
|
|
this.renderFragmentCount = renderProtoViewMergeMapping.fragmentCount;
|
|
|
|
this.renderElementIndices = renderProtoViewMergeMapping.mappedElementIndices;
|
2015-07-23 14:27:49 -07:00
|
|
|
this.renderInverseElementIndices = inverseIndexMapping(
|
|
|
|
this.renderElementIndices, renderProtoViewMergeMapping.mappedElementCount);
|
2015-06-24 13:46:39 -07:00
|
|
|
this.renderTextIndices = renderProtoViewMergeMapping.mappedTextIndices;
|
|
|
|
this.hostElementIndicesByViewIndex = renderProtoViewMergeMapping.hostElementIndicesByViewIndex;
|
|
|
|
this.nestedViewIndicesByElementIndex =
|
|
|
|
inverseIndexMapping(this.hostElementIndicesByViewIndex, this.renderElementIndices.length);
|
2015-07-20 09:59:44 -07:00
|
|
|
this.nestedViewCountByViewIndex = renderProtoViewMergeMapping.nestedViewCountByViewIndex;
|
2015-06-24 13:46:39 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function inverseIndexMapping(input: number[], resultLength: number): number[] {
|
2015-07-23 14:27:49 -07:00
|
|
|
var result = ListWrapper.createGrowableSize(resultLength);
|
2015-06-24 13:46:39 -07:00
|
|
|
for (var i = 0; i < input.length; i++) {
|
|
|
|
var value = input[i];
|
|
|
|
if (isPresent(value)) {
|
|
|
|
result[input[i]] = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2015-04-27 09:26:55 -07:00
|
|
|
export class AppViewContainer {
|
2015-06-03 11:02:51 -07:00
|
|
|
// The order in this list matches the DOM order.
|
2015-08-28 11:29:19 -07:00
|
|
|
views: AppView[] = [];
|
2015-04-24 17:53:06 -07:00
|
|
|
}
|
2014-09-28 16:29:11 -07:00
|
|
|
|
2014-11-21 15:13:01 -08:00
|
|
|
/**
|
2015-07-07 08:15:58 +02:00
|
|
|
* Cost of making objects: http://jsperf.com/instantiate-size-of-object
|
2015-03-31 22:47:11 +00:00
|
|
|
*
|
2014-10-10 20:44:55 -07:00
|
|
|
*/
|
2015-06-24 13:46:39 -07:00
|
|
|
export class AppView implements ChangeDispatcher, RenderEventDispatcher {
|
|
|
|
// AppViews that have been merged in depth first order.
|
|
|
|
// This list is shared between all merged views. Use this.elementOffset to get the local
|
|
|
|
// entries.
|
2015-08-28 11:29:19 -07:00
|
|
|
views: AppView[] = null;
|
2015-06-24 13:46:39 -07:00
|
|
|
// root elementInjectors of this AppView
|
|
|
|
// This list is local to this AppView and not shared with other Views.
|
2015-08-28 11:29:19 -07:00
|
|
|
rootElementInjectors: ElementInjector[];
|
2015-06-24 13:46:39 -07:00
|
|
|
// ElementInjectors of all AppViews in views grouped by view.
|
|
|
|
// This list is shared between all merged views. Use this.elementOffset to get the local
|
|
|
|
// entries.
|
2015-08-28 11:29:19 -07:00
|
|
|
elementInjectors: ElementInjector[] = null;
|
2015-06-24 13:46:39 -07:00
|
|
|
// ViewContainers of all AppViews in views grouped by view.
|
|
|
|
// This list is shared between all merged views. Use this.elementOffset to get the local
|
|
|
|
// entries.
|
2015-08-28 11:29:19 -07:00
|
|
|
viewContainers: AppViewContainer[] = null;
|
2015-06-24 13:46:39 -07:00
|
|
|
// PreBuiltObjects of all AppViews in views grouped by view.
|
|
|
|
// This list is shared between all merged views. Use this.elementOffset to get the local
|
|
|
|
// entries.
|
2015-08-28 11:29:19 -07:00
|
|
|
preBuiltObjects: PreBuiltObjects[] = null;
|
2015-06-24 13:46:39 -07:00
|
|
|
// ElementRef of all AppViews in views grouped by view.
|
|
|
|
// This list is shared between all merged views. Use this.elementOffset to get the local
|
|
|
|
// entries.
|
2015-08-28 11:29:19 -07:00
|
|
|
elementRefs: ElementRef[];
|
2015-06-24 13:46:39 -07:00
|
|
|
|
2015-06-23 11:21:56 -07:00
|
|
|
ref: ViewRef;
|
2015-06-24 13:46:39 -07:00
|
|
|
changeDetector: ChangeDetector = null;
|
|
|
|
|
2015-04-06 13:19:30 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The context against which data-binding expressions in this view are evaluated against.
|
|
|
|
* This is always a component instance.
|
|
|
|
*/
|
2015-04-09 21:20:11 +02:00
|
|
|
|
2015-06-12 22:38:44 +02:00
|
|
|
context: any = null;
|
2015-04-06 13:19:30 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Variables, local to this view, that can be used in binding expressions (in addition to the
|
|
|
|
* context). This is used for thing like `<video #player>` or
|
|
|
|
* `<li template="for #item of items">`, where "player" and "item" are locals, respectively.
|
|
|
|
*/
|
2015-05-20 09:48:15 -07:00
|
|
|
locals: Locals;
|
2015-01-02 14:23:59 -08:00
|
|
|
|
2015-05-20 09:48:15 -07:00
|
|
|
constructor(public renderer: renderApi.Renderer, public proto: AppProtoView,
|
2015-06-24 13:46:39 -07:00
|
|
|
public mainMergeMapping: AppProtoViewMergeMapping, public viewOffset: number,
|
|
|
|
public elementOffset: number, public textOffset: number,
|
|
|
|
protoLocals: Map<string, any>, public render: renderApi.RenderViewRef,
|
|
|
|
public renderFragment: renderApi.RenderFragmentRef) {
|
2015-06-23 11:21:56 -07:00
|
|
|
this.ref = new ViewRef(this);
|
2015-06-24 13:46:39 -07:00
|
|
|
|
2015-05-20 09:48:15 -07:00
|
|
|
this.locals = new Locals(null, MapWrapper.clone(protoLocals)); // TODO optimize this
|
2014-12-01 18:41:55 -08:00
|
|
|
}
|
|
|
|
|
2015-08-28 11:29:19 -07:00
|
|
|
init(changeDetector: ChangeDetector, elementInjectors: ElementInjector[],
|
|
|
|
rootElementInjectors: ElementInjector[], preBuiltObjects: PreBuiltObjects[],
|
|
|
|
views: AppView[], elementRefs: ElementRef[], viewContainers: AppViewContainer[]) {
|
2015-03-11 21:43:22 -07:00
|
|
|
this.changeDetector = changeDetector;
|
2014-12-09 10:31:19 -08:00
|
|
|
this.elementInjectors = elementInjectors;
|
|
|
|
this.rootElementInjectors = rootElementInjectors;
|
|
|
|
this.preBuiltObjects = preBuiltObjects;
|
2015-06-24 13:46:39 -07:00
|
|
|
this.views = views;
|
|
|
|
this.elementRefs = elementRefs;
|
|
|
|
this.viewContainers = viewContainers;
|
2014-12-01 18:41:55 -08:00
|
|
|
}
|
|
|
|
|
2015-07-07 20:03:00 -07:00
|
|
|
setLocal(contextName: string, value: any): void {
|
2014-12-01 18:41:55 -08:00
|
|
|
if (!this.hydrated()) throw new BaseException('Cannot set locals on dehydrated view.');
|
2015-06-17 21:42:56 -07:00
|
|
|
if (!this.proto.variableBindings.has(contextName)) {
|
2015-01-28 00:42:08 +01:00
|
|
|
return;
|
2014-12-01 18:41:55 -08:00
|
|
|
}
|
2015-06-17 16:21:40 -07:00
|
|
|
var templateName = this.proto.variableBindings.get(contextName);
|
2015-03-11 21:11:39 -07:00
|
|
|
this.locals.set(templateName, value);
|
2014-12-01 18:41:55 -08:00
|
|
|
}
|
|
|
|
|
2015-05-20 09:48:15 -07:00
|
|
|
hydrated(): boolean { return isPresent(this.context); }
|
2014-12-01 18:41:55 -08:00
|
|
|
|
2015-03-10 10:03:26 +01:00
|
|
|
/**
|
|
|
|
* Triggers the event handlers for the element and the directives.
|
|
|
|
*
|
|
|
|
* This method is intended to be called from directive EventEmitters.
|
|
|
|
*
|
|
|
|
* @param {string} eventName
|
|
|
|
* @param {*} eventObj
|
2015-08-20 16:25:34 -07:00
|
|
|
* @param {number} boundElementIndex
|
2015-03-10 10:03:26 +01:00
|
|
|
*/
|
2015-08-20 16:25:34 -07:00
|
|
|
triggerEventHandlers(eventName: string, eventObj: Event, boundElementIndex: number): void {
|
2015-06-17 16:21:40 -07:00
|
|
|
var locals = new Map();
|
|
|
|
locals.set('$event', eventObj);
|
2015-06-24 13:46:39 -07:00
|
|
|
this.dispatchEvent(boundElementIndex, eventName, locals);
|
2015-03-10 10:03:26 +01:00
|
|
|
}
|
|
|
|
|
2015-03-31 09:07:01 -07:00
|
|
|
// dispatch to element injector or text nodes based on context
|
2015-08-19 11:26:45 -07:00
|
|
|
notifyOnBinding(b: BindingTarget, currentValue: any): void {
|
2015-06-24 13:46:39 -07:00
|
|
|
if (b.isTextNode()) {
|
|
|
|
this.renderer.setText(
|
|
|
|
this.render, this.mainMergeMapping.renderTextIndices[b.elementIndex + this.textOffset],
|
|
|
|
currentValue);
|
2015-06-18 15:44:44 -07:00
|
|
|
} else {
|
2015-06-24 13:46:39 -07:00
|
|
|
var elementRef = this.elementRefs[this.elementOffset + b.elementIndex];
|
|
|
|
if (b.isElementProperty()) {
|
2015-08-19 11:26:45 -07:00
|
|
|
this.renderer.setElementProperty(elementRef, b.name, currentValue);
|
2015-06-24 13:46:39 -07:00
|
|
|
} else if (b.isElementAttribute()) {
|
2015-08-28 14:55:12 -07:00
|
|
|
this.renderer.setElementAttribute(elementRef, b.name, `${currentValue}`);
|
2015-06-24 13:46:39 -07:00
|
|
|
} else if (b.isElementClass()) {
|
2015-08-19 11:26:45 -07:00
|
|
|
this.renderer.setElementClass(elementRef, b.name, currentValue);
|
2015-06-24 13:46:39 -07:00
|
|
|
} else if (b.isElementStyle()) {
|
2015-08-19 11:26:45 -07:00
|
|
|
var unit = isPresent(b.unit) ? b.unit : '';
|
|
|
|
this.renderer.setElementStyle(elementRef, b.name, `${currentValue}${unit}`);
|
2015-06-24 13:46:39 -07:00
|
|
|
} else {
|
|
|
|
throw new BaseException('Unsupported directive record');
|
|
|
|
}
|
2015-04-07 20:54:20 -07:00
|
|
|
}
|
|
|
|
}
|
2015-04-09 21:20:11 +02:00
|
|
|
|
2015-08-20 15:11:12 -07:00
|
|
|
logBindingUpdate(b: BindingTarget, value: any): void {
|
|
|
|
if (b.isDirective() || b.isElementProperty()) {
|
|
|
|
var elementRef = this.elementRefs[this.elementOffset + b.elementIndex];
|
|
|
|
this.renderer.setElementAttribute(
|
|
|
|
elementRef, `${REFLECT_PREFIX}${camelCaseToDashCase(b.name)}`, `${value}`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-27 21:19:56 -07:00
|
|
|
notifyAfterContentChecked(): void {
|
2015-06-24 13:46:39 -07:00
|
|
|
var eiCount = this.proto.elementBinders.length;
|
2015-06-12 09:45:31 -07:00
|
|
|
var ei = this.elementInjectors;
|
2015-06-24 13:46:39 -07:00
|
|
|
for (var i = eiCount - 1; i >= 0; i--) {
|
2015-08-27 21:19:56 -07:00
|
|
|
if (isPresent(ei[i + this.elementOffset])) ei[i + this.elementOffset].afterContentChecked();
|
2015-06-12 09:45:31 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-28 18:11:04 -07:00
|
|
|
notifyAfterViewChecked(): void {
|
|
|
|
// required for query
|
|
|
|
}
|
|
|
|
|
2015-06-26 11:10:52 -07:00
|
|
|
getDirectiveFor(directive: DirectiveIndex): any {
|
2015-06-24 13:46:39 -07:00
|
|
|
var elementInjector = this.elementInjectors[this.elementOffset + directive.elementIndex];
|
2015-04-09 07:57:33 -07:00
|
|
|
return elementInjector.getDirectiveAtIndex(directive.directiveIndex);
|
|
|
|
}
|
2015-04-07 20:54:20 -07:00
|
|
|
|
2015-06-24 13:46:39 -07:00
|
|
|
getNestedView(boundElementIndex: number): AppView {
|
|
|
|
var viewIndex = this.mainMergeMapping.nestedViewIndicesByElementIndex[boundElementIndex];
|
|
|
|
return isPresent(viewIndex) ? this.views[viewIndex] : null;
|
|
|
|
}
|
|
|
|
|
2015-07-22 12:00:35 -07:00
|
|
|
getHostElement(): ElementRef {
|
|
|
|
var boundElementIndex = this.mainMergeMapping.hostElementIndicesByViewIndex[this.viewOffset];
|
2015-07-23 18:01:34 -07:00
|
|
|
return isPresent(boundElementIndex) ? this.elementRefs[boundElementIndex] : null;
|
|
|
|
}
|
|
|
|
|
2015-07-27 15:47:42 -07:00
|
|
|
getDebugContext(elementIndex: number, directiveIndex: DirectiveIndex): DebugContext {
|
2015-07-23 18:01:34 -07:00
|
|
|
try {
|
|
|
|
var offsettedIndex = this.elementOffset + elementIndex;
|
|
|
|
var hasRefForIndex = offsettedIndex < this.elementRefs.length;
|
|
|
|
|
|
|
|
var elementRef = hasRefForIndex ? this.elementRefs[this.elementOffset + elementIndex] : null;
|
|
|
|
var host = this.getHostElement();
|
|
|
|
var ei = hasRefForIndex ? this.elementInjectors[this.elementOffset + elementIndex] : null;
|
|
|
|
|
|
|
|
var element = isPresent(elementRef) ? elementRef.nativeElement : null;
|
|
|
|
var componentElement = isPresent(host) ? host.nativeElement : null;
|
|
|
|
var directive = isPresent(directiveIndex) ? this.getDirectiveFor(directiveIndex) : null;
|
|
|
|
var injector = isPresent(ei) ? ei.getInjector() : null;
|
|
|
|
|
2015-07-27 15:47:42 -07:00
|
|
|
return new DebugContext(element, componentElement, directive, this.context,
|
|
|
|
_localsToStringMap(this.locals), injector);
|
|
|
|
|
2015-07-23 18:01:34 -07:00
|
|
|
} catch (e) {
|
|
|
|
// TODO: vsavkin log the exception once we have a good way to log errors and warnings
|
|
|
|
// if an error happens during getting the debug context, we return an empty map.
|
2015-07-27 15:47:42 -07:00
|
|
|
return null;
|
2015-07-23 18:01:34 -07:00
|
|
|
}
|
2015-07-22 12:00:35 -07:00
|
|
|
}
|
|
|
|
|
2015-06-26 11:10:52 -07:00
|
|
|
getDetectorFor(directive: DirectiveIndex): any {
|
2015-06-24 13:46:39 -07:00
|
|
|
var childView = this.getNestedView(this.elementOffset + directive.elementIndex);
|
2015-04-24 17:53:06 -07:00
|
|
|
return isPresent(childView) ? childView.changeDetector : null;
|
2015-04-14 08:54:09 -07:00
|
|
|
}
|
|
|
|
|
2015-08-28 11:29:19 -07:00
|
|
|
invokeElementMethod(elementIndex: number, methodName: string, args: any[]) {
|
2015-06-23 11:21:56 -07:00
|
|
|
this.renderer.invokeElementMethod(this.elementRefs[elementIndex], methodName, args);
|
2015-05-11 12:31:16 -07:00
|
|
|
}
|
|
|
|
|
2015-06-24 13:46:39 -07:00
|
|
|
// implementation of RenderEventDispatcher#dispatchRenderEvent
|
|
|
|
dispatchRenderEvent(renderElementIndex: number, eventName: string,
|
|
|
|
locals: Map<string, any>): boolean {
|
|
|
|
var elementRef =
|
2015-07-20 09:59:44 -07:00
|
|
|
this.elementRefs[this.mainMergeMapping.renderInverseElementIndices[renderElementIndex]];
|
2015-06-24 13:46:39 -07:00
|
|
|
var view = internalView(elementRef.parentView);
|
|
|
|
return view.dispatchEvent(elementRef.boundElementIndex, eventName, locals);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-04-16 18:03:15 +02:00
|
|
|
// returns false if preventDefault must be applied to the DOM event
|
2015-06-24 13:46:39 -07:00
|
|
|
dispatchEvent(boundElementIndex: number, eventName: string, locals: Map<string, any>): boolean {
|
2015-07-27 15:47:42 -07:00
|
|
|
try {
|
|
|
|
if (this.hydrated()) {
|
2015-08-12 16:26:21 -07:00
|
|
|
return !this.changeDetector.handleEvent(eventName, boundElementIndex - this.elementOffset,
|
|
|
|
new Locals(this.locals, locals));
|
|
|
|
} else {
|
|
|
|
return true;
|
2015-07-27 15:47:42 -07:00
|
|
|
}
|
|
|
|
} catch (e) {
|
|
|
|
var c = this.getDebugContext(boundElementIndex - this.elementOffset, null);
|
|
|
|
var context = isPresent(c) ? new _Context(c.element, c.componentElement, c.context, c.locals,
|
|
|
|
c.injector) :
|
|
|
|
null;
|
|
|
|
throw new EventEvaluationError(eventName, e, e.stack, context);
|
2014-12-02 17:09:46 -08:00
|
|
|
}
|
|
|
|
}
|
2014-09-28 16:29:11 -07:00
|
|
|
}
|
|
|
|
|
2015-07-23 18:01:34 -07:00
|
|
|
function _localsToStringMap(locals: Locals): StringMap<string, any> {
|
|
|
|
var res = {};
|
|
|
|
var c = locals;
|
|
|
|
while (isPresent(c)) {
|
|
|
|
res = StringMapWrapper.merge(res, MapWrapper.toStringMap(c.current));
|
|
|
|
c = c.parent;
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2015-07-27 15:47:42 -07:00
|
|
|
/**
|
|
|
|
* Error context included when an event handler throws an exception.
|
|
|
|
*/
|
|
|
|
class _Context {
|
|
|
|
constructor(public element: any, public componentElement: any, public context: any,
|
|
|
|
public locals: any, public injector: any) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Wraps an exception thrown by an event handler.
|
|
|
|
*/
|
|
|
|
class EventEvaluationError extends BaseException {
|
|
|
|
constructor(eventName: string, originalException: any, originalStack: any, context: any) {
|
|
|
|
super(`Error during evaluation of "${eventName}"`, originalException, originalStack, context);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-03-17 19:22:13 +00:00
|
|
|
/**
|
2015-03-31 22:47:11 +00:00
|
|
|
*
|
2015-03-17 19:22:13 +00:00
|
|
|
*/
|
2015-04-09 21:20:11 +02:00
|
|
|
export class AppProtoView {
|
2015-08-28 11:29:19 -07:00
|
|
|
elementBinders: ElementBinder[] = [];
|
2015-06-17 16:21:40 -07:00
|
|
|
protoLocals: Map<string, any> = new Map();
|
2015-06-24 13:46:39 -07:00
|
|
|
mergeMapping: AppProtoViewMergeMapping;
|
2015-07-17 08:03:40 -07:00
|
|
|
ref: ProtoViewRef;
|
2015-05-20 09:48:15 -07:00
|
|
|
|
2015-07-20 09:59:44 -07:00
|
|
|
constructor(public type: renderApi.ViewType, public isEmbeddedFragment: boolean,
|
|
|
|
public render: renderApi.RenderProtoViewRef,
|
|
|
|
public protoChangeDetector: ProtoChangeDetector,
|
2015-06-16 09:45:03 -07:00
|
|
|
public variableBindings: Map<string, string>,
|
2015-08-07 11:41:38 -07:00
|
|
|
public variableLocations: Map<string, number>, public textBindingCount: number,
|
|
|
|
public pipes: ProtoPipes) {
|
2015-07-17 08:03:40 -07:00
|
|
|
this.ref = new ProtoViewRef(this);
|
2015-05-11 17:59:39 -07:00
|
|
|
if (isPresent(variableBindings)) {
|
2015-06-17 16:21:40 -07:00
|
|
|
MapWrapper.forEach(variableBindings,
|
|
|
|
(templateName, _) => { this.protoLocals.set(templateName, null); });
|
2015-05-11 17:59:39 -07:00
|
|
|
}
|
2014-11-18 16:38:36 -08:00
|
|
|
}
|
|
|
|
|
2015-08-20 16:25:34 -07:00
|
|
|
bindElement(parent: ElementBinder, distanceToParent: number,
|
2015-05-20 09:48:15 -07:00
|
|
|
protoElementInjector: ProtoElementInjector,
|
|
|
|
componentDirective: DirectiveBinding = null): ElementBinder {
|
2015-06-15 15:18:11 -07:00
|
|
|
var elBinder = new ElementBinder(this.elementBinders.length, parent, distanceToParent,
|
|
|
|
protoElementInjector, componentDirective);
|
2015-06-04 13:45:08 -07:00
|
|
|
|
2015-06-17 11:17:21 -07:00
|
|
|
this.elementBinders.push(elBinder);
|
2014-11-11 17:33:47 -08:00
|
|
|
return elBinder;
|
|
|
|
}
|
2015-04-09 21:20:11 +02:00
|
|
|
}
|