refactor(render): add DomElement
Replaces the multiple arrays of `DomView` by a single array with `DomElement`s. Note: this commit does not show a performance regression (tested against the tree benchmark locally).
This commit is contained in:
parent
0a50a3f564
commit
827841ec5b
@ -80,7 +80,7 @@ function _injectorBindings(appComponentType): List<Type | Binding | List<any>> {
|
|||||||
var domView = resolveInternalDomView(componentRef.hostView.render);
|
var domView = resolveInternalDomView(componentRef.hostView.render);
|
||||||
// We need to do this here to ensure that we create Testability and
|
// We need to do this here to ensure that we create Testability and
|
||||||
// it's ready on the window for users.
|
// it's ready on the window for users.
|
||||||
registry.registerApplication(domView.boundElements[0], testability);
|
registry.registerApplication(domView.boundElements[0].element, testability);
|
||||||
|
|
||||||
return componentRef;
|
return componentRef;
|
||||||
});
|
});
|
||||||
|
@ -23,7 +23,9 @@ export class ElementRef {
|
|||||||
// We need a more general way to read/write to the DOM element
|
// We need a more general way to read/write to the DOM element
|
||||||
// via a proper abstraction in the render layer
|
// via a proper abstraction in the render layer
|
||||||
get domElement() {
|
get domElement() {
|
||||||
return resolveInternalDomView(this.parentView.render).boundElements[this.boundElementIndex];
|
return resolveInternalDomView(this.parentView.render)
|
||||||
|
.boundElements[this.boundElementIndex]
|
||||||
|
.element;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,7 +43,9 @@ export class DebugElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get domElement(): any {
|
get domElement(): any {
|
||||||
return resolveInternalDomView(this._parentView.render).boundElements[this._boundElementIndex];
|
return resolveInternalDomView(this._parentView.render)
|
||||||
|
.boundElements[this._boundElementIndex]
|
||||||
|
.element;
|
||||||
}
|
}
|
||||||
|
|
||||||
getDirectiveInstance(directiveIndex: number): any {
|
getDirectiveInstance(directiveIndex: number): any {
|
||||||
|
@ -61,7 +61,7 @@ export class DebugElementViewListener implements AppViewListener {
|
|||||||
MapWrapper.set(_allIdsByView, view, viewId);
|
MapWrapper.set(_allIdsByView, view, viewId);
|
||||||
var renderView = resolveInternalDomView(view.render);
|
var renderView = resolveInternalDomView(view.render);
|
||||||
for (var i = 0; i < renderView.boundElements.length; i++) {
|
for (var i = 0; i < renderView.boundElements.length; i++) {
|
||||||
_setElementId(renderView.boundElements[i], [viewId, i]);
|
_setElementId(renderView.boundElements[i].element, [viewId, i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ import {EventManager} from './events/event_manager';
|
|||||||
|
|
||||||
import {DomProtoView, DomProtoViewRef, resolveInternalDomProtoView} from './view/proto_view';
|
import {DomProtoView, DomProtoViewRef, resolveInternalDomProtoView} from './view/proto_view';
|
||||||
import {DomView, DomViewRef, resolveInternalDomView} from './view/view';
|
import {DomView, DomViewRef, resolveInternalDomView} from './view/view';
|
||||||
|
import {DomElement} from './view/element';
|
||||||
import {DomViewContainer} from './view/view_container';
|
import {DomViewContainer} from './view/view_container';
|
||||||
import {NG_BINDING_CLASS_SELECTOR, NG_BINDING_CLASS} from './util';
|
import {NG_BINDING_CLASS_SELECTOR, NG_BINDING_CLASS} from './util';
|
||||||
|
|
||||||
@ -65,8 +66,8 @@ export class DomRenderer extends Renderer {
|
|||||||
componentViewRef: RenderViewRef) {
|
componentViewRef: RenderViewRef) {
|
||||||
var hostView = resolveInternalDomView(hostViewRef);
|
var hostView = resolveInternalDomView(hostViewRef);
|
||||||
var componentView = resolveInternalDomView(componentViewRef);
|
var componentView = resolveInternalDomView(componentViewRef);
|
||||||
var element = hostView.boundElements[elementIndex];
|
var element = hostView.boundElements[elementIndex].element;
|
||||||
var lightDom = hostView.lightDoms[elementIndex];
|
var lightDom = hostView.boundElements[elementIndex].lightDom;
|
||||||
if (isPresent(lightDom)) {
|
if (isPresent(lightDom)) {
|
||||||
lightDom.attachShadowDomView(componentView);
|
lightDom.attachShadowDomView(componentView);
|
||||||
}
|
}
|
||||||
@ -92,7 +93,7 @@ export class DomRenderer extends Renderer {
|
|||||||
var hostView = resolveInternalDomView(hostViewRef);
|
var hostView = resolveInternalDomView(hostViewRef);
|
||||||
var componentView = resolveInternalDomView(componentViewRef);
|
var componentView = resolveInternalDomView(componentViewRef);
|
||||||
this._removeViewNodes(componentView);
|
this._removeViewNodes(componentView);
|
||||||
var lightDom = hostView.lightDoms[boundElementIndex];
|
var lightDom = hostView.boundElements[boundElementIndex].lightDom;
|
||||||
if (isPresent(lightDom)) {
|
if (isPresent(lightDom)) {
|
||||||
lightDom.detachShadowDomView();
|
lightDom.detachShadowDomView();
|
||||||
}
|
}
|
||||||
@ -108,11 +109,11 @@ export class DomRenderer extends Renderer {
|
|||||||
ListWrapper.insert(viewContainer.views, atIndex, view);
|
ListWrapper.insert(viewContainer.views, atIndex, view);
|
||||||
view.hostLightDom = parentView.hostLightDom;
|
view.hostLightDom = parentView.hostLightDom;
|
||||||
|
|
||||||
var directParentLightDom = parentView.getDirectParentLightDom(boundElementIndex);
|
var directParentLightDom = this._directParentLightDom(parentView, boundElementIndex);
|
||||||
if (isBlank(directParentLightDom)) {
|
if (isBlank(directParentLightDom)) {
|
||||||
var siblingToInsertAfter;
|
var siblingToInsertAfter;
|
||||||
if (atIndex == 0) {
|
if (atIndex == 0) {
|
||||||
siblingToInsertAfter = parentView.boundElements[boundElementIndex];
|
siblingToInsertAfter = parentView.boundElements[boundElementIndex].element;
|
||||||
} else {
|
} else {
|
||||||
siblingToInsertAfter = ListWrapper.last(viewContainer.views[atIndex - 1].rootNodes);
|
siblingToInsertAfter = ListWrapper.last(viewContainer.views[atIndex - 1].rootNodes);
|
||||||
}
|
}
|
||||||
@ -130,10 +131,10 @@ export class DomRenderer extends Renderer {
|
|||||||
viewRef: RenderViewRef) {
|
viewRef: RenderViewRef) {
|
||||||
var parentView = resolveInternalDomView(parentViewRef);
|
var parentView = resolveInternalDomView(parentViewRef);
|
||||||
var view = resolveInternalDomView(viewRef);
|
var view = resolveInternalDomView(viewRef);
|
||||||
var viewContainer = parentView.viewContainers[boundElementIndex];
|
var viewContainer = parentView.boundElements[boundElementIndex].viewContainer;
|
||||||
var detachedView = viewContainer.views[atIndex];
|
var detachedView = viewContainer.views[atIndex];
|
||||||
ListWrapper.removeAt(viewContainer.views, atIndex);
|
ListWrapper.removeAt(viewContainer.views, atIndex);
|
||||||
var directParentLightDom = parentView.getDirectParentLightDom(boundElementIndex);
|
var directParentLightDom = this._directParentLightDom(parentView, boundElementIndex);
|
||||||
if (isBlank(directParentLightDom)) {
|
if (isBlank(directParentLightDom)) {
|
||||||
this._removeViewNodes(detachedView);
|
this._removeViewNodes(detachedView);
|
||||||
} else {
|
} else {
|
||||||
@ -151,8 +152,8 @@ export class DomRenderer extends Renderer {
|
|||||||
if (view.hydrated) throw new BaseException('The view is already hydrated.');
|
if (view.hydrated) throw new BaseException('The view is already hydrated.');
|
||||||
view.hydrated = true;
|
view.hydrated = true;
|
||||||
|
|
||||||
for (var i = 0; i < view.lightDoms.length; ++i) {
|
for (var i = 0; i < view.boundElements.length; ++i) {
|
||||||
var lightDom = view.lightDoms[i];
|
var lightDom = view.boundElements[i].lightDom;
|
||||||
if (isPresent(lightDom)) {
|
if (isPresent(lightDom)) {
|
||||||
lightDom.redistribute();
|
lightDom.redistribute();
|
||||||
}
|
}
|
||||||
@ -244,7 +245,6 @@ export class DomRenderer extends Renderer {
|
|||||||
var binders = protoView.elementBinders;
|
var binders = protoView.elementBinders;
|
||||||
var boundTextNodes = [];
|
var boundTextNodes = [];
|
||||||
var boundElements = ListWrapper.createFixedSize(binders.length);
|
var boundElements = ListWrapper.createFixedSize(binders.length);
|
||||||
var contentTags = ListWrapper.createFixedSize(binders.length);
|
|
||||||
|
|
||||||
for (var binderIdx = 0; binderIdx < binders.length; binderIdx++) {
|
for (var binderIdx = 0; binderIdx < binders.length; binderIdx++) {
|
||||||
var binder = binders[binderIdx];
|
var binder = binders[binderIdx];
|
||||||
@ -261,7 +261,6 @@ export class DomRenderer extends Renderer {
|
|||||||
element = elementsWithBindings[binderIdx - protoView.rootBindingOffset];
|
element = elementsWithBindings[binderIdx - protoView.rootBindingOffset];
|
||||||
childNodes = DOM.childNodes(element);
|
childNodes = DOM.childNodes(element);
|
||||||
}
|
}
|
||||||
boundElements[binderIdx] = element;
|
|
||||||
|
|
||||||
// boundTextNodes
|
// boundTextNodes
|
||||||
var textNodeIndices = binder.textNodeIndices;
|
var textNodeIndices = binder.textNodeIndices;
|
||||||
@ -274,10 +273,10 @@ export class DomRenderer extends Renderer {
|
|||||||
if (isPresent(binder.contentTagSelector)) {
|
if (isPresent(binder.contentTagSelector)) {
|
||||||
contentTag = new Content(element, binder.contentTagSelector);
|
contentTag = new Content(element, binder.contentTagSelector);
|
||||||
}
|
}
|
||||||
contentTags[binderIdx] = contentTag;
|
boundElements[binderIdx] = new DomElement(binder, element, contentTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
var view = new DomView(protoView, viewRootNodes, boundTextNodes, boundElements, contentTags);
|
var view = new DomView(protoView, viewRootNodes, boundTextNodes, boundElements);
|
||||||
|
|
||||||
for (var binderIdx = 0; binderIdx < binders.length; binderIdx++) {
|
for (var binderIdx = 0; binderIdx < binders.length; binderIdx++) {
|
||||||
var binder = binders[binderIdx];
|
var binder = binders[binderIdx];
|
||||||
@ -286,21 +285,21 @@ export class DomRenderer extends Renderer {
|
|||||||
// lightDoms
|
// lightDoms
|
||||||
var lightDom = null;
|
var lightDom = null;
|
||||||
if (isPresent(binder.componentId)) {
|
if (isPresent(binder.componentId)) {
|
||||||
lightDom = this._shadowDomStrategy.constructLightDom(view, boundElements[binderIdx]);
|
lightDom = this._shadowDomStrategy.constructLightDom(view, element.element);
|
||||||
}
|
}
|
||||||
view.lightDoms[binderIdx] = lightDom;
|
element.lightDom = lightDom;
|
||||||
|
|
||||||
// init contentTags
|
// init contentTags
|
||||||
var contentTag = contentTags[binderIdx];
|
var contentTag = element.contentTag;
|
||||||
if (isPresent(contentTag)) {
|
if (isPresent(contentTag)) {
|
||||||
var destLightDom = view.getDirectParentLightDom(binderIdx);
|
var directParentLightDom = this._directParentLightDom(view, binderIdx);
|
||||||
contentTag.init(destLightDom);
|
contentTag.init(directParentLightDom);
|
||||||
}
|
}
|
||||||
|
|
||||||
// events
|
// events
|
||||||
if (isPresent(binder.eventLocals) && isPresent(binder.localEvents)) {
|
if (isPresent(binder.eventLocals) && isPresent(binder.localEvents)) {
|
||||||
for (var i = 0; i < binder.localEvents.length; i++) {
|
for (var i = 0; i < binder.localEvents.length; i++) {
|
||||||
this._createEventListener(view, element, binderIdx, binder.localEvents[i].name,
|
this._createEventListener(view, element.element, binderIdx, binder.localEvents[i].name,
|
||||||
binder.eventLocals);
|
binder.eventLocals);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -337,14 +336,20 @@ export class DomRenderer extends Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_getOrCreateViewContainer(parentView: DomView, boundElementIndex) {
|
_getOrCreateViewContainer(parentView: DomView, boundElementIndex) {
|
||||||
var vc = parentView.viewContainers[boundElementIndex];
|
var el = parentView.boundElements[boundElementIndex];
|
||||||
|
var vc = el.viewContainer;
|
||||||
if (isBlank(vc)) {
|
if (isBlank(vc)) {
|
||||||
vc = new DomViewContainer();
|
vc = new DomViewContainer();
|
||||||
parentView.viewContainers[boundElementIndex] = vc;
|
el.viewContainer = vc;
|
||||||
}
|
}
|
||||||
return vc;
|
return vc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_directParentLightDom(view: DomView, boundElementIndex: number) {
|
||||||
|
var directParentEl = view.getDirectParentElement(boundElementIndex);
|
||||||
|
return isPresent(directParentEl) ? directParentEl.lightDom : null;
|
||||||
|
}
|
||||||
|
|
||||||
_createGlobalEventListener(view, elementIndex, eventName, eventTarget, fullName): Function {
|
_createGlobalEventListener(view, elementIndex, eventName, eventTarget, fullName): Function {
|
||||||
return this._eventManager.addGlobalEventListener(
|
return this._eventManager.addGlobalEventListener(
|
||||||
eventTarget, eventName, (event) => { view.dispatchEvent(elementIndex, fullName, event); });
|
eventTarget, eventName, (event) => { view.dispatchEvent(elementIndex, fullName, event); });
|
||||||
|
@ -3,18 +3,13 @@ import {List, ListWrapper} from 'angular2/src/facade/collection';
|
|||||||
import {isBlank, isPresent} from 'angular2/src/facade/lang';
|
import {isBlank, isPresent} from 'angular2/src/facade/lang';
|
||||||
|
|
||||||
import * as viewModule from '../view/view';
|
import * as viewModule from '../view/view';
|
||||||
|
import * as elModule from '../view/element';
|
||||||
import {Content} from './content_tag';
|
import {Content} from './content_tag';
|
||||||
|
|
||||||
export class DestinationLightDom {}
|
export class DestinationLightDom {}
|
||||||
|
|
||||||
class _Root {
|
class _Root {
|
||||||
node;
|
constructor(public node, public boundElement: elModule.DomElement) {}
|
||||||
boundElementIndex: number;
|
|
||||||
|
|
||||||
constructor(node, boundElementIndex) {
|
|
||||||
this.node = node;
|
|
||||||
this.boundElementIndex = boundElementIndex;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: LightDom should implement DestinationLightDom
|
// TODO: LightDom should implement DestinationLightDom
|
||||||
@ -59,16 +54,14 @@ export class LightDom {
|
|||||||
if (view.proto.transitiveContentTagCount === 0) {
|
if (view.proto.transitiveContentTagCount === 0) {
|
||||||
return acc;
|
return acc;
|
||||||
}
|
}
|
||||||
var contentTags = view.contentTags;
|
var els = view.boundElements;
|
||||||
var vcs = view.viewContainers;
|
for (var i = 0; i < els.length; i++) {
|
||||||
for (var i = 0; i < vcs.length; i++) {
|
var el = els[i];
|
||||||
var vc = vcs[i];
|
if (isPresent(el.contentTag)) {
|
||||||
var contentTag = contentTags[i];
|
ListWrapper.push(acc, el.contentTag);
|
||||||
if (isPresent(contentTag)) {
|
|
||||||
ListWrapper.push(acc, contentTag);
|
|
||||||
}
|
}
|
||||||
if (isPresent(vc)) {
|
if (isPresent(el.viewContainer)) {
|
||||||
ListWrapper.forEach(vc.contentTagContainers(),
|
ListWrapper.forEach(el.viewContainer.contentTagContainers(),
|
||||||
(view) => { this._collectAllContentTags(view, acc); });
|
(view) => { this._collectAllContentTags(view, acc); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,9 +78,9 @@ export class LightDom {
|
|||||||
var roots = this._findRoots();
|
var roots = this._findRoots();
|
||||||
for (var i = 0; i < roots.length; ++i) {
|
for (var i = 0; i < roots.length; ++i) {
|
||||||
var root = roots[i];
|
var root = roots[i];
|
||||||
if (isPresent(root.boundElementIndex)) {
|
if (isPresent(root.boundElement)) {
|
||||||
var vc = this.lightDomView.viewContainers[root.boundElementIndex];
|
var vc = root.boundElement.viewContainer;
|
||||||
var content = this.lightDomView.contentTags[root.boundElementIndex];
|
var content = root.boundElement.contentTag;
|
||||||
if (isPresent(vc)) {
|
if (isPresent(vc)) {
|
||||||
res = ListWrapper.concat(res, vc.nodes());
|
res = ListWrapper.concat(res, vc.nodes());
|
||||||
} else if (isPresent(content)) {
|
} else if (isPresent(content)) {
|
||||||
@ -103,22 +96,22 @@ export class LightDom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns a list of Roots for all the nodes of the light DOM.
|
// Returns a list of Roots for all the nodes of the light DOM.
|
||||||
// The Root object contains the DOM node and its corresponding boundElementIndex
|
// The Root object contains the DOM node and its corresponding boundElement
|
||||||
private _findRoots() {
|
private _findRoots() {
|
||||||
if (isPresent(this._roots)) return this._roots;
|
if (isPresent(this._roots)) return this._roots;
|
||||||
|
|
||||||
var boundElements = this.lightDomView.boundElements;
|
var boundElements = this.lightDomView.boundElements;
|
||||||
|
|
||||||
this._roots = ListWrapper.map(this.nodes, (n) => {
|
this._roots = ListWrapper.map(this.nodes, (n) => {
|
||||||
var boundElementIndex = null;
|
var boundElement = null;
|
||||||
for (var i = 0; i < boundElements.length; i++) {
|
for (var i = 0; i < boundElements.length; i++) {
|
||||||
var boundEl = boundElements[i];
|
var boundEl = boundElements[i];
|
||||||
if (isPresent(boundEl) && boundEl === n) {
|
if (isPresent(boundEl) && boundEl.element === n) {
|
||||||
boundElementIndex = i;
|
boundElement = boundEl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new _Root(n, boundElementIndex);
|
return new _Root(n, boundElement);
|
||||||
});
|
});
|
||||||
|
|
||||||
return this._roots;
|
return this._roots;
|
||||||
|
11
modules/angular2/src/render/dom/view/element.ts
Normal file
11
modules/angular2/src/render/dom/view/element.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import {ElementBinder} from './element_binder';
|
||||||
|
import {DomViewContainer} from './view_container';
|
||||||
|
import {LightDom} from '../shadow_dom/light_dom';
|
||||||
|
import {Content} from '../shadow_dom/content_tag';
|
||||||
|
|
||||||
|
export class DomElement {
|
||||||
|
viewContainer: DomViewContainer;
|
||||||
|
lightDom: LightDom;
|
||||||
|
constructor(public proto: ElementBinder, public element: any /* element */,
|
||||||
|
public contentTag: Content) {}
|
||||||
|
}
|
@ -3,10 +3,9 @@ import {ListWrapper, MapWrapper, Map, StringMapWrapper, List} from 'angular2/src
|
|||||||
import {Locals} from 'angular2/change_detection';
|
import {Locals} from 'angular2/change_detection';
|
||||||
import {isPresent, isBlank, BaseException} from 'angular2/src/facade/lang';
|
import {isPresent, isBlank, BaseException} from 'angular2/src/facade/lang';
|
||||||
|
|
||||||
import {DomViewContainer} from './view_container';
|
|
||||||
import {DomProtoView} from './proto_view';
|
import {DomProtoView} from './proto_view';
|
||||||
import {LightDom} from '../shadow_dom/light_dom';
|
import {LightDom} from '../shadow_dom/light_dom';
|
||||||
import {Content} from '../shadow_dom/content_tag';
|
import {DomElement} from './element';
|
||||||
|
|
||||||
import {RenderViewRef, EventDispatcher} from '../../api';
|
import {RenderViewRef, EventDispatcher} from '../../api';
|
||||||
|
|
||||||
@ -29,10 +28,6 @@ const NG_BINDING_CLASS = 'ng-binding';
|
|||||||
* Const of making objects: http://jsperf.com/instantiate-size-of-object
|
* Const of making objects: http://jsperf.com/instantiate-size-of-object
|
||||||
*/
|
*/
|
||||||
export class DomView {
|
export class DomView {
|
||||||
// TODO(tbosch): move componentChildViews, viewContainers, contentTags, lightDoms into
|
|
||||||
// a single array with records inside
|
|
||||||
viewContainers: List<DomViewContainer>;
|
|
||||||
lightDoms: List<LightDom>;
|
|
||||||
hostLightDom: LightDom;
|
hostLightDom: LightDom;
|
||||||
shadowRoot;
|
shadowRoot;
|
||||||
hydrated: boolean;
|
hydrated: boolean;
|
||||||
@ -40,10 +35,7 @@ export class DomView {
|
|||||||
eventHandlerRemovers: List<Function>;
|
eventHandlerRemovers: List<Function>;
|
||||||
|
|
||||||
constructor(public proto: DomProtoView, public rootNodes: List</*node*/ any>,
|
constructor(public proto: DomProtoView, public rootNodes: List</*node*/ any>,
|
||||||
public boundTextNodes: List</*node*/ any>,
|
public boundTextNodes: List</*node*/ any>, public boundElements: List<DomElement>) {
|
||||||
public boundElements: List</*element*/ any>, public contentTags: List<Content>) {
|
|
||||||
this.viewContainers = ListWrapper.createFixedSize(boundElements.length);
|
|
||||||
this.lightDoms = ListWrapper.createFixedSize(boundElements.length);
|
|
||||||
this.hostLightDom = null;
|
this.hostLightDom = null;
|
||||||
this.hydrated = false;
|
this.hydrated = false;
|
||||||
this.eventHandlerRemovers = [];
|
this.eventHandlerRemovers = [];
|
||||||
@ -51,25 +43,25 @@ export class DomView {
|
|||||||
this.shadowRoot = null;
|
this.shadowRoot = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
getDirectParentLightDom(boundElementIndex: number) {
|
getDirectParentElement(boundElementIndex: number): DomElement {
|
||||||
var binder = this.proto.elementBinders[boundElementIndex];
|
var binder = this.proto.elementBinders[boundElementIndex];
|
||||||
var destLightDom = null;
|
var parent = null;
|
||||||
if (binder.parentIndex !== -1 && binder.distanceToParent === 1) {
|
if (binder.parentIndex !== -1 && binder.distanceToParent === 1) {
|
||||||
destLightDom = this.lightDoms[binder.parentIndex];
|
parent = this.boundElements[binder.parentIndex];
|
||||||
}
|
}
|
||||||
return destLightDom;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
setElementProperty(elementIndex: number, propertyName: string, value: any) {
|
setElementProperty(elementIndex: number, propertyName: string, value: any) {
|
||||||
var setter =
|
var setter =
|
||||||
MapWrapper.get(this.proto.elementBinders[elementIndex].propertySetters, propertyName);
|
MapWrapper.get(this.proto.elementBinders[elementIndex].propertySetters, propertyName);
|
||||||
setter(this.boundElements[elementIndex], value);
|
setter(this.boundElements[elementIndex].element, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
callAction(elementIndex: number, actionExpression: string, actionArgs: any) {
|
callAction(elementIndex: number, actionExpression: string, actionArgs: any) {
|
||||||
var binder = this.proto.elementBinders[elementIndex];
|
var binder = this.proto.elementBinders[elementIndex];
|
||||||
var hostAction = MapWrapper.get(binder.hostActions, actionExpression);
|
var hostAction = MapWrapper.get(binder.hostActions, actionExpression);
|
||||||
hostAction.eval(this.boundElements[elementIndex], this._localsWithAction(actionArgs));
|
hostAction.eval(this.boundElements[elementIndex].element, this._localsWithAction(actionArgs));
|
||||||
}
|
}
|
||||||
|
|
||||||
_localsWithAction(action: Object): Locals {
|
_localsWithAction(action: Object): Locals {
|
||||||
|
@ -123,7 +123,7 @@ export class DomTestbed {
|
|||||||
}
|
}
|
||||||
|
|
||||||
triggerEvent(viewRef: RenderViewRef, boundElementIndex: number, eventName: string) {
|
triggerEvent(viewRef: RenderViewRef, boundElementIndex: number, eventName: string) {
|
||||||
var element = resolveInternalDomView(viewRef).boundElements[boundElementIndex];
|
var element = resolveInternalDomView(viewRef).boundElements[boundElementIndex].element;
|
||||||
dispatchEvent(element, eventName);
|
dispatchEvent(element, eventName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import {LightDom} from 'angular2/src/render/dom/shadow_dom/light_dom';
|
|||||||
import {DomView} from 'angular2/src/render/dom/view/view';
|
import {DomView} from 'angular2/src/render/dom/view/view';
|
||||||
import {DomProtoView} from 'angular2/src/render/dom/view/proto_view';
|
import {DomProtoView} from 'angular2/src/render/dom/view/proto_view';
|
||||||
import {DomViewContainer} from 'angular2/src/render/dom/view/view_container';
|
import {DomViewContainer} from 'angular2/src/render/dom/view/view_container';
|
||||||
|
import {DomElement} from 'angular2/src/render/dom/view/element';
|
||||||
|
|
||||||
@proxy
|
@proxy
|
||||||
@IMPLEMENTS(DomProtoView)
|
@IMPLEMENTS(DomProtoView)
|
||||||
@ -31,31 +32,27 @@ class FakeProtoView extends SpyObject {
|
|||||||
@IMPLEMENTS(DomView)
|
@IMPLEMENTS(DomView)
|
||||||
class FakeView extends SpyObject {
|
class FakeView extends SpyObject {
|
||||||
boundElements;
|
boundElements;
|
||||||
contentTags;
|
|
||||||
viewContainers;
|
|
||||||
proto;
|
proto;
|
||||||
|
|
||||||
constructor(containers = null, transitiveContentTagCount: number = 1) {
|
constructor(containers = null, transitiveContentTagCount: number = 1) {
|
||||||
super(DomView);
|
super(DomView);
|
||||||
this.proto = new FakeProtoView(transitiveContentTagCount);
|
this.proto = new FakeProtoView(transitiveContentTagCount);
|
||||||
this.boundElements = [];
|
this.boundElements = [];
|
||||||
this.contentTags = [];
|
|
||||||
this.viewContainers = [];
|
|
||||||
if (isPresent(containers)) {
|
if (isPresent(containers)) {
|
||||||
ListWrapper.forEach(containers, (c) => {
|
ListWrapper.forEach(containers, (c) => {
|
||||||
var boundElement = null;
|
var element = null;
|
||||||
var contentTag = null;
|
var contentTag = null;
|
||||||
var vc = null;
|
var vc = null;
|
||||||
if (c instanceof FakeContentTag) {
|
if (c instanceof FakeContentTag) {
|
||||||
contentTag = c;
|
contentTag = c;
|
||||||
boundElement = c.contentStartElement;
|
element = c.contentStartElement;
|
||||||
}
|
}
|
||||||
if (c instanceof FakeViewContainer) {
|
if (c instanceof FakeViewContainer) {
|
||||||
vc = c;
|
vc = c;
|
||||||
boundElement = c.templateElement;
|
element = c.templateElement;
|
||||||
}
|
}
|
||||||
ListWrapper.push(this.contentTags, contentTag);
|
var boundElement = new DomElement(null, element, contentTag);
|
||||||
ListWrapper.push(this.viewContainers, vc);
|
boundElement.viewContainer = vc;
|
||||||
ListWrapper.push(this.boundElements, boundElement);
|
ListWrapper.push(this.boundElements, boundElement);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -15,13 +15,13 @@ import {
|
|||||||
SpyObject,
|
SpyObject,
|
||||||
proxy
|
proxy
|
||||||
} from 'angular2/test_lib';
|
} from 'angular2/test_lib';
|
||||||
import {IMPLEMENTS, isBlank} from 'angular2/src/facade/lang';
|
import {isBlank} from 'angular2/src/facade/lang';
|
||||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||||
|
|
||||||
import {DomProtoView} from 'angular2/src/render/dom/view/proto_view';
|
import {DomProtoView} from 'angular2/src/render/dom/view/proto_view';
|
||||||
import {ElementBinder} from 'angular2/src/render/dom/view/element_binder';
|
import {ElementBinder} from 'angular2/src/render/dom/view/element_binder';
|
||||||
import {DomView} from 'angular2/src/render/dom/view/view';
|
import {DomView} from 'angular2/src/render/dom/view/view';
|
||||||
import {LightDom} from 'angular2/src/render/dom/shadow_dom/light_dom';
|
import {DomElement} from 'angular2/src/render/dom/view/element';
|
||||||
import {DOM} from 'angular2/src/dom/dom_adapter';
|
import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
@ -42,20 +42,19 @@ export function main() {
|
|||||||
var root = el('<div><div></div></div>');
|
var root = el('<div><div></div></div>');
|
||||||
var boundElements = [];
|
var boundElements = [];
|
||||||
for (var i = 0; i < boundElementCount; i++) {
|
for (var i = 0; i < boundElementCount; i++) {
|
||||||
ListWrapper.push(boundElements, el('<span></span'));
|
ListWrapper.push(boundElements,
|
||||||
|
new DomElement(pv.elementBinders[i], el('<span></span'), null));
|
||||||
}
|
}
|
||||||
return new DomView(pv, [DOM.childNodes(root)[0]], [], boundElements, []);
|
return new DomView(pv, [DOM.childNodes(root)[0]], [], boundElements);
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('getDirectParentLightDom', () => {
|
describe('getDirectParentElement', () => {
|
||||||
|
|
||||||
it('should return the LightDom of the direct parent', () => {
|
it('should return the DomElement of the direct parent', () => {
|
||||||
var pv = createProtoView(
|
var pv = createProtoView(
|
||||||
[new ElementBinder(), new ElementBinder({parentIndex: 0, distanceToParent: 1})]);
|
[new ElementBinder(), new ElementBinder({parentIndex: 0, distanceToParent: 1})]);
|
||||||
var view = createView(pv, 2);
|
var view = createView(pv, 2);
|
||||||
view.lightDoms[0] = <any>new SpyLightDom();
|
expect(view.getDirectParentElement(1)).toBe(view.boundElements[0]);
|
||||||
view.lightDoms[1] = <any>new SpyLightDom();
|
|
||||||
expect(view.getDirectParentLightDom(1)).toBe(view.lightDoms[0]);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return null if the direct parent is not bound', () => {
|
it('should return null if the direct parent is not bound', () => {
|
||||||
@ -65,20 +64,10 @@ export function main() {
|
|||||||
new ElementBinder({parentIndex: 0, distanceToParent: 2})
|
new ElementBinder({parentIndex: 0, distanceToParent: 2})
|
||||||
]);
|
]);
|
||||||
var view = createView(pv, 3);
|
var view = createView(pv, 3);
|
||||||
view.lightDoms[0] = <any>new SpyLightDom();
|
expect(view.getDirectParentElement(2)).toBe(null);
|
||||||
view.lightDoms[1] = <any>new SpyLightDom();
|
|
||||||
view.lightDoms[2] = <any>new SpyLightDom();
|
|
||||||
expect(view.getDirectParentLightDom(2)).toBe(null);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@proxy
|
|
||||||
@IMPLEMENTS(LightDom)
|
|
||||||
class SpyLightDom extends SpyObject {
|
|
||||||
constructor() { super(LightDom); }
|
|
||||||
noSuchMethod(m) { return super.noSuchMethod(m) }
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user