refactor(core): introduce `ViewRef` and `ProtoViewRef`

BREAKING CHANGES:
- `NgElement` merged into `ElementRef`
- `Compiler.compile…` returns `ProtoViewRef`
- `ViewContainer` uses `ProtoViewRef`s and `ViewRef`s.
- `ViewRef`/`ProtoViewRef` in renderer were renamed to
  `RenderViewRef`/`RenderProtoViewRef`.

Related to #1477
Closes #1592
This commit is contained in:
Tobias Bosch 2015-04-28 11:20:01 -07:00
parent 1205f54d01
commit 09f8d8f7ba
35 changed files with 473 additions and 404 deletions

View File

@ -21,9 +21,7 @@ export * from './src/render/dom/shadow_dom/native_shadow_dom_strategy';
export * from './src/render/dom/shadow_dom/emulated_scoped_shadow_dom_strategy'; export * from './src/render/dom/shadow_dom/emulated_scoped_shadow_dom_strategy';
export * from './src/render/dom/shadow_dom/emulated_unscoped_shadow_dom_strategy'; export * from './src/render/dom/shadow_dom/emulated_unscoped_shadow_dom_strategy';
export * from './src/core/compiler/dynamic_component_loader'; export * from './src/core/compiler/dynamic_component_loader';
export {ElementRef, ComponentRef} from './src/core/compiler/element_injector'; export {ViewRef, ProtoViewRef} from './src/core/compiler/view_ref';
export * from './src/core/compiler/view'; export {ViewContainerRef} from './src/core/compiler/view_container_ref';
export * from './src/core/compiler/view_container_ref'; export {ElementRef} from './src/core/compiler/element_ref';
export * from './src/core/compiler/ng_element';

View File

@ -54,7 +54,7 @@ import {DEFAULT} from 'angular2/change_detection';
* - `@Descendants query:Query<DirectiveType>`: A live collection of any child directives (will be implemented in later relaese). * - `@Descendants query:Query<DirectiveType>`: A live collection of any child directives (will be implemented in later relaese).
* *
* To inject element-specific special objects, declare the constructor parameter as: * To inject element-specific special objects, declare the constructor parameter as:
* - `element: NgElement` to obtain a DOM element (DEPRECATED: replacement coming) * - `element: ElementRef` to obtain a reference to logical element in the view.
* - `viewContainer: ViewContainerRef` to control child template instantiation, for {@link Viewport} directives only * - `viewContainer: ViewContainerRef` to control child template instantiation, for {@link Viewport} directives only
* - `bindingPropagation: BindingPropagation` to control change detection in a more granular way. * - `bindingPropagation: BindingPropagation` to control change detection in a more granular way.
* *

View File

@ -37,10 +37,10 @@ import {DirectDomRenderer} from 'angular2/src/render/dom/direct_dom_renderer';
import * as rc from 'angular2/src/render/dom/compiler/compiler'; import * as rc from 'angular2/src/render/dom/compiler/compiler';
import * as rvf from 'angular2/src/render/dom/view/view_factory'; import * as rvf from 'angular2/src/render/dom/view/view_factory';
import * as rvh from 'angular2/src/render/dom/view/view_hydrator'; import * as rvh from 'angular2/src/render/dom/view/view_hydrator';
import {internalView} from 'angular2/src/core/compiler/view_ref';
import { import {
appComponentRefToken, appComponentRefToken,
appChangeDetectorToken,
appElementToken, appElementToken,
appComponentAnnotatedTypeToken, appComponentAnnotatedTypeToken,
appDocumentToken, appDocumentToken,
@ -80,8 +80,6 @@ function _injectorBindings(appComponentType): List<Binding> {
}, [DynamicComponentLoader, Injector, appElementToken, appComponentAnnotatedTypeToken, }, [DynamicComponentLoader, Injector, appElementToken, appComponentAnnotatedTypeToken,
Testability, TestabilityRegistry]), Testability, TestabilityRegistry]),
bind(appChangeDetectorToken).toFactory((ref) => ref.hostView.changeDetector,
[appComponentRefToken]),
bind(appComponentType).toFactory((ref) => ref.instance, bind(appComponentType).toFactory((ref) => ref.instance,
[appComponentRefToken]), [appComponentRefToken]),
bind(LifeCycle).toFactory((exceptionHandler) => new LifeCycle(exceptionHandler, null, assertionsEnabled()),[ExceptionHandler]), bind(LifeCycle).toFactory((exceptionHandler) => new LifeCycle(exceptionHandler, null, assertionsEnabled()),[ExceptionHandler]),
@ -253,7 +251,7 @@ function _createVmZone(givenReporter:Function): VmTurnZone {
*/ */
export function bootstrap(appComponentType: Type, export function bootstrap(appComponentType: Type,
componentInjectableBindings: List<Binding> = null, componentInjectableBindings: List<Binding> = null,
errorReporter: Function = null): Promise<ComponentRef> { errorReporter: Function = null): Promise<ApplicationRef> {
BrowserDomAdapter.makeCurrent(); BrowserDomAdapter.makeCurrent();
var bootstrapProcess = PromiseWrapper.completer(); var bootstrapProcess = PromiseWrapper.completer();
@ -266,13 +264,13 @@ export function bootstrap(appComponentType: Type,
PromiseWrapper.then(appInjector.asyncGet(appComponentRefToken), PromiseWrapper.then(appInjector.asyncGet(appComponentRefToken),
(componentRef) => { (componentRef) => {
var appChangeDetector = componentRef.hostView.changeDetector; var appChangeDetector = internalView(componentRef.hostView).changeDetector;
// retrieve life cycle: may have already been created if injected in root component // retrieve life cycle: may have already been created if injected in root component
var lc = appInjector.get(LifeCycle); var lc = appInjector.get(LifeCycle);
lc.registerWith(zone, appChangeDetector); lc.registerWith(zone, appChangeDetector);
lc.tick(); //the first tick that will bootstrap the app lc.tick(); //the first tick that will bootstrap the app
bootstrapProcess.resolve(componentRef); bootstrapProcess.resolve(new ApplicationRef(componentRef, appInjector));
}, },
(err) => { (err) => {
@ -283,6 +281,28 @@ export function bootstrap(appComponentType: Type,
return bootstrapProcess.promise; return bootstrapProcess.promise;
} }
export class ApplicationRef {
_hostComponent:ComponentRef;
_injector:Injector;
constructor(hostComponent:ComponentRef, injector:Injector) {
this._hostComponent = hostComponent;
this._injector = injector;
}
get hostComponent() {
return this._hostComponent.instance;
}
dispose() {
// TODO: We also need to clean up the Zone, ... here!
return this._hostComponent.dispose();
}
get injector() {
return this._injector;
}
}
function _createAppInjector(appComponentType: Type, bindings: List<Binding>, zone: VmTurnZone): Injector { function _createAppInjector(appComponentType: Type, bindings: List<Binding>, zone: VmTurnZone): Injector {
if (isBlank(_rootInjector)) _rootInjector = Injector.resolveAndCreate(_rootBindings); if (isBlank(_rootInjector)) _rootInjector = Injector.resolveAndCreate(_rootBindings);
var mergedBindings = isPresent(bindings) ? var mergedBindings = isPresent(bindings) ?

View File

@ -1,7 +1,6 @@
import {OpaqueToken} from 'angular2/di'; import {OpaqueToken} from 'angular2/di';
export var appComponentRefToken:OpaqueToken = new OpaqueToken('ComponentRef'); export var appComponentRefToken:OpaqueToken = new OpaqueToken('ComponentRef');
export var appChangeDetectorToken:OpaqueToken = new OpaqueToken('AppChangeDetector');
export var appElementToken:OpaqueToken = new OpaqueToken('AppElement'); export var appElementToken:OpaqueToken = new OpaqueToken('AppElement');
export var appComponentAnnotatedTypeToken:OpaqueToken = new OpaqueToken('AppComponentAnnotatedType'); export var appComponentAnnotatedTypeToken:OpaqueToken = new OpaqueToken('AppComponentAnnotatedType');
export var appDocumentToken:OpaqueToken = new OpaqueToken('AppDocument'); export var appDocumentToken:OpaqueToken = new OpaqueToken('AppDocument');

View File

@ -6,6 +6,7 @@ import {List, ListWrapper, Map, MapWrapper} from 'angular2/src/facade/collection
import {DirectiveMetadataReader} from './directive_metadata_reader'; import {DirectiveMetadataReader} from './directive_metadata_reader';
import {Component, Viewport, DynamicComponent, Decorator} from '../annotations/annotations'; import {Component, Viewport, DynamicComponent, Decorator} from '../annotations/annotations';
import {AppProtoView} from './view'; import {AppProtoView} from './view';
import {ProtoViewRef} from './view_ref';
import {DirectiveBinding} from './element_injector'; import {DirectiveBinding} from './element_injector';
import {TemplateResolver} from './template_resolver'; import {TemplateResolver} from './template_resolver';
import {View} from '../annotations/view'; import {View} from '../annotations/view';
@ -87,21 +88,26 @@ export class Compiler {
// Create a hostView as if the compiler encountered <hostcmp></hostcmp>. // Create a hostView as if the compiler encountered <hostcmp></hostcmp>.
// Used for bootstrapping. // Used for bootstrapping.
compileInHost(componentTypeOrBinding:any):Promise<AppProtoView> { compileInHost(componentTypeOrBinding:any):Promise<ProtoViewRef> {
var componentBinding = this._bindDirective(componentTypeOrBinding); var componentBinding = this._bindDirective(componentTypeOrBinding);
this._assertTypeIsComponent(componentBinding); this._assertTypeIsComponent(componentBinding);
var directiveMetadata = Compiler.buildRenderDirective(componentBinding); var directiveMetadata = Compiler.buildRenderDirective(componentBinding);
return this._renderer.createHostProtoView(directiveMetadata).then( (hostRenderPv) => { return this._renderer.createHostProtoView(directiveMetadata).then( (hostRenderPv) => {
return this._compileNestedProtoViews(null, hostRenderPv, [componentBinding], true); return this._compileNestedProtoViews(null, hostRenderPv, [componentBinding], true);
}).then( (appProtoView) => {
return new ProtoViewRef(appProtoView);
}); });
} }
compile(component: Type):Promise<AppProtoView> { compile(component: Type):Promise<ProtoViewRef> {
var componentBinding = this._bindDirective(component); var componentBinding = this._bindDirective(component);
this._assertTypeIsComponent(componentBinding); this._assertTypeIsComponent(componentBinding);
var protoView = this._compile(componentBinding); var protoView = this._compile(componentBinding);
return PromiseWrapper.isPromise(protoView) ? protoView : PromiseWrapper.resolve(protoView); var pvPromise = PromiseWrapper.isPromise(protoView) ? protoView : PromiseWrapper.resolve(protoView);
return pvPromise.then( (appProtoView) => {
return new ProtoViewRef(appProtoView);
});
} }
// TODO(vicb): union type return AppProtoView or Promise<AppProtoView> // TODO(vicb): union type return AppProtoView or Promise<AppProtoView>

View File

@ -2,9 +2,8 @@ import {Key, Injector, Injectable, ResolvedBinding, Binding, bind} from 'angular
import {Compiler} from './compiler'; import {Compiler} from './compiler';
import {Type, BaseException, stringify, isPresent} from 'angular2/src/facade/lang'; import {Type, BaseException, stringify, isPresent} from 'angular2/src/facade/lang';
import {Promise} from 'angular2/src/facade/async'; import {Promise} from 'angular2/src/facade/async';
import {AppViewManager} from 'angular2/src/core/compiler/view_manager'; import {AppViewManager, ComponentCreateResult} from 'angular2/src/core/compiler/view_manager';
import {ElementRef} from './element_injector'; import {ElementRef} from './element_ref';
import {AppView} from './view';
/** /**
* @exportedAs angular2/view * @exportedAs angular2/view
@ -12,22 +11,16 @@ import {AppView} from './view';
export class ComponentRef { export class ComponentRef {
location:ElementRef; location:ElementRef;
instance:any; instance:any;
componentView:AppView;
_dispose:Function; _dispose:Function;
constructor(location:ElementRef, instance:any, componentView:AppView, dispose:Function){ constructor(location:ElementRef, instance:any, dispose:Function) {
this.location = location; this.location = location;
this.instance = instance; this.instance = instance;
this.componentView = componentView;
this._dispose = dispose; this._dispose = dispose;
} }
get injector() {
return this.location.injector;
}
get hostView() { get hostView() {
return this.location.hostView; return this.location.parentView;
} }
dispose() { dispose() {
@ -58,12 +51,12 @@ export class DynamicComponentLoader {
*/ */
loadIntoExistingLocation(typeOrBinding, location:ElementRef, injector:Injector = null):Promise<ComponentRef> { loadIntoExistingLocation(typeOrBinding, location:ElementRef, injector:Injector = null):Promise<ComponentRef> {
var binding = this._getBinding(typeOrBinding); var binding = this._getBinding(typeOrBinding);
return this._compiler.compile(binding.token).then(componentProtoView => { return this._compiler.compile(binding.token).then(componentProtoViewRef => {
var componentView = this._viewManager.createDynamicComponentView( this._viewManager.createDynamicComponentView(
location, componentProtoView, binding, injector); location, componentProtoViewRef, binding, injector);
var component = this._viewManager.getComponent(location);
var dispose = () => {throw new BaseException("Not implemented");}; var dispose = () => {throw new BaseException("Not implemented");};
return new ComponentRef(location, location.elementInjector.getDynamicallyLoadedComponent(), componentView, dispose); return new ComponentRef(location, component, dispose);
}); });
} }
@ -73,16 +66,16 @@ export class DynamicComponentLoader {
*/ */
loadIntoNewLocation(typeOrBinding, parentComponentLocation:ElementRef, elementOrSelector:any, loadIntoNewLocation(typeOrBinding, parentComponentLocation:ElementRef, elementOrSelector:any,
injector:Injector = null):Promise<ComponentRef> { injector:Injector = null):Promise<ComponentRef> {
return this._compiler.compileInHost(this._getBinding(typeOrBinding)).then(hostProtoView => { return this._compiler.compileInHost(this._getBinding(typeOrBinding)).then(hostProtoViewRef => {
var hostView = this._viewManager.createInPlaceHostView( var hostViewRef = this._viewManager.createInPlaceHostView(
parentComponentLocation, elementOrSelector, hostProtoView, injector); parentComponentLocation, elementOrSelector, hostProtoViewRef, injector);
var newLocation = new ElementRef(hostViewRef, 0);
var component = this._viewManager.getComponent(newLocation);
var newLocation = hostView.elementInjectors[0].getElementRef();
var component = hostView.elementInjectors[0].getComponent();
var dispose = () => { var dispose = () => {
this._viewManager.destroyInPlaceHostView(parentComponentLocation, hostView); this._viewManager.destroyInPlaceHostView(parentComponentLocation, hostViewRef);
}; };
return new ComponentRef(newLocation, component, hostView.componentChildViews[0], dispose); return new ComponentRef(newLocation, component, dispose);
}); });
} }
@ -92,16 +85,17 @@ export class DynamicComponentLoader {
*/ */
loadNextToExistingLocation(typeOrBinding, location:ElementRef, injector:Injector = null):Promise<ComponentRef> { loadNextToExistingLocation(typeOrBinding, location:ElementRef, injector:Injector = null):Promise<ComponentRef> {
var binding = this._getBinding(typeOrBinding); var binding = this._getBinding(typeOrBinding);
return this._compiler.compileInHost(binding).then(hostProtoView => { return this._compiler.compileInHost(binding).then(hostProtoViewRef => {
var hostView = location.viewContainer.create(-1, hostProtoView, injector); var viewContainer = this._viewManager.getViewContainer(location);
var hostViewRef = viewContainer.create(-1, hostProtoViewRef, injector);
var newLocation = new ElementRef(hostViewRef, 0);
var component = this._viewManager.getComponent(newLocation);
var newLocation = hostView.elementInjectors[0].getElementRef();
var component = hostView.elementInjectors[0].getComponent();
var dispose = () => { var dispose = () => {
var index = location.viewContainer.indexOf(hostView); var index = viewContainer.indexOf(hostViewRef);
location.viewContainer.remove(index); viewContainer.remove(index);
}; };
return new ComponentRef(newLocation, component, hostView.componentChildViews[0], dispose); return new ComponentRef(newLocation, component, dispose);
}); });
} }

View File

@ -6,10 +6,11 @@ import {Injector, Key, Dependency, bind, Binding, ResolvedBinding, NoBindingErro
AbstractBindingError, CyclicDependencyError} from 'angular2/di'; AbstractBindingError, CyclicDependencyError} from 'angular2/di';
import {Parent, Ancestor} from 'angular2/src/core/annotations/visibility'; import {Parent, Ancestor} from 'angular2/src/core/annotations/visibility';
import {Attribute, Query} from 'angular2/src/core/annotations/di'; import {Attribute, Query} from 'angular2/src/core/annotations/di';
import * as viewModule from 'angular2/src/core/compiler/view'; import * as viewModule from './view';
import * as avmModule from './view_manager'; import * as avmModule from './view_manager';
import {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref'; import {ViewContainerRef} from './view_container_ref';
import {NgElement} from 'angular2/src/core/compiler/ng_element'; import {ElementRef} from './element_ref';
import {ProtoViewRef, ViewRef} from './view_ref';
import {Directive, Component, onChange, onDestroy, onAllChangesDone} from 'angular2/src/core/annotations/annotations'; import {Directive, Component, onChange, onDestroy, onAllChangesDone} from 'angular2/src/core/annotations/annotations';
import {ChangeDetector, ChangeDetectorRef} from 'angular2/change_detection'; import {ChangeDetector, ChangeDetectorRef} from 'angular2/change_detection';
import {QueryList} from './query_list'; import {QueryList} from './query_list';
@ -23,30 +24,9 @@ var _undefined = new Object();
var _staticKeys; var _staticKeys;
/**
* @exportedAs angular2/view
*/
export class ElementRef {
hostView:viewModule.AppView;
boundElementIndex:number;
injector:Injector;
elementInjector:ElementInjector;
viewContainer:ViewContainerRef;
constructor(elementInjector, hostView, boundElementIndex, injector, viewManager, defaultProtoView){
this.elementInjector = elementInjector;
this.hostView = hostView;
this.boundElementIndex = boundElementIndex;
this.injector = injector;
this.viewContainer = new ViewContainerRef(viewManager, this, defaultProtoView);
}
}
class StaticKeys { class StaticKeys {
viewManagerId:number; viewManagerId:number;
viewId:number; protoViewId:number;
ngElementId:number;
defaultProtoViewId:number;
viewContainerId:number; viewContainerId:number;
changeDetectorRefId:number; changeDetectorRefId:number;
elementRefId:number; elementRefId:number;
@ -54,9 +34,7 @@ class StaticKeys {
constructor() { constructor() {
//TODO: vsavkin Key.annotate(Key.get(AppView), 'static') //TODO: vsavkin Key.annotate(Key.get(AppView), 'static')
this.viewManagerId = Key.get(avmModule.AppViewManager).id; this.viewManagerId = Key.get(avmModule.AppViewManager).id;
this.defaultProtoViewId = Key.get(viewModule.AppProtoView).id; this.protoViewId = Key.get(ProtoViewRef).id;
this.viewId = Key.get(viewModule.AppView).id;
this.ngElementId = Key.get(NgElement).id;
this.viewContainerId = Key.get(ViewContainerRef).id; this.viewContainerId = Key.get(ViewContainerRef).id;
this.changeDetectorRefId = Key.get(ChangeDetectorRef).id; this.changeDetectorRefId = Key.get(ChangeDetectorRef).id;
this.elementRefId = Key.get(ElementRef).id; this.elementRefId = Key.get(ElementRef).id;
@ -294,14 +272,12 @@ export class DirectiveBinding extends ResolvedBinding {
// TODO(rado): benchmark and consider rolling in as ElementInjector fields. // TODO(rado): benchmark and consider rolling in as ElementInjector fields.
export class PreBuiltObjects { export class PreBuiltObjects {
viewManager:avmModule.AppViewManager; viewManager:avmModule.AppViewManager;
defaultProtoView:viewModule.AppProtoView; protoView:viewModule.AppProtoView;
view:viewModule.AppView; view:viewModule.AppView;
element:NgElement; constructor(viewManager:avmModule.AppViewManager, view:viewModule.AppView, protoView:viewModule.AppProtoView) {
constructor(viewManager:avmModule.AppViewManager, view:viewModule.AppView, element:NgElement, defaultProtoView:viewModule.AppProtoView) {
this.viewManager = viewManager; this.viewManager = viewManager;
this.view = view; this.view = view;
this.defaultProtoView = defaultProtoView; this.protoView = protoView;
this.element = element;
} }
} }
@ -649,11 +625,6 @@ export class ElementInjector extends TreeNode {
return this._proto.eventEmitterAccessors; return this._proto.eventEmitterAccessors;
} }
/** Gets the NgElement associated with this ElementInjector */
getNgElement() {
return this._preBuiltObjects.element;
}
getComponent() { getComponent() {
if (this._proto._binding0IsComponent) { if (this._proto._binding0IsComponent) {
return this._obj0; return this._obj0;
@ -663,8 +634,11 @@ export class ElementInjector extends TreeNode {
} }
getElementRef() { getElementRef() {
return new ElementRef(this, this._preBuiltObjects.view, this._proto.index, this._lightDomAppInjector, return new ElementRef(new ViewRef(this._preBuiltObjects.view), this._proto.index);
this._preBuiltObjects.viewManager, this._preBuiltObjects.defaultProtoView); }
getViewContainerRef() {
return new ViewContainerRef(this._preBuiltObjects.viewManager, this.getElementRef(), new ProtoViewRef(this._preBuiltObjects.protoView));
} }
getDynamicallyLoadedComponent() { getDynamicallyLoadedComponent() {
@ -742,7 +716,10 @@ export class ElementInjector extends TreeNode {
return this.getElementRef(); return this.getElementRef();
} }
if (dep.key.id === StaticKeys.instance().viewContainerId) { if (dep.key.id === StaticKeys.instance().viewContainerId) {
return this.getElementRef().viewContainer; return this.getViewContainerRef();
}
if (dep.key.id === StaticKeys.instance().protoViewId) {
return new ProtoViewRef(this._preBuiltObjects.protoView);
} }
return this._getByKey(dep.key, dep.depth, dep.optional, requestor); return this._getByKey(dep.key, dep.depth, dep.optional, requestor);
} }
@ -914,11 +891,7 @@ export class ElementInjector extends TreeNode {
_getPreBuiltObjectByKeyId(keyId:int) { _getPreBuiltObjectByKeyId(keyId:int) {
var staticKeys = StaticKeys.instance(); var staticKeys = StaticKeys.instance();
// TODO: AppView should not be injectable. Remove it.
if (keyId === staticKeys.viewManagerId) return this._preBuiltObjects.viewManagerId; if (keyId === staticKeys.viewManagerId) return this._preBuiltObjects.viewManagerId;
if (keyId === staticKeys.viewId) return this._preBuiltObjects.view;
if (keyId === staticKeys.ngElementId) return this._preBuiltObjects.element;
if (keyId === staticKeys.defaultProtoViewId) return this._preBuiltObjects.defaultProtoView;
//TODO add other objects as needed //TODO add other objects as needed
return _undefined; return _undefined;

View File

@ -0,0 +1,40 @@
import {DOM} from 'angular2/src/dom/dom_adapter';
import {normalizeBlank} from 'angular2/src/facade/lang';
import {ViewRef} from './view_ref';
import {DirectDomViewRef} from 'angular2/src/render/dom/direct_dom_renderer';
/**
* @exportedAs angular2/view
*/
export class ElementRef {
parentView:ViewRef;
boundElementIndex:number;
constructor(parentView:ViewRef, boundElementIndex:number) {
this.parentView = parentView;
this.boundElementIndex = boundElementIndex;
}
/**
* Exposes the underlying DOM element.
* (DEPRECATED way of accessing the DOM, replacement coming)
*/
// TODO(tbosch): Here we expose the real DOM element.
// We need a more general way to read/write to the DOM element
// via a proper abstraction in the render layer
get domElement() {
var renderViewRef:DirectDomViewRef = this.parentView.render;
return renderViewRef.delegate.boundElements[this.boundElementIndex];
}
/**
* Gets an attribute from the underlying DOM element.
* (DEPRECATED way of accessing the DOM, replacement coming)
*/
// TODO(tbosch): Here we expose the real DOM element.
// We need a more general way to read/write to the DOM element
// via a proper abstraction in the render layer
getAttribute(name:string):string {
return normalizeBlank(DOM.getAttribute(this.domElement, name));
}
}

View File

@ -1,34 +0,0 @@
import {DOM} from 'angular2/src/dom/dom_adapter';
import {normalizeBlank} from 'angular2/src/facade/lang';
import * as viewModule from '../compiler/view';
import {DirectDomViewRef} from 'angular2/src/render/dom/direct_dom_renderer';
/**
* Allows direct access to the underlying DOM element.
*
* Attention: NgElement will be replaced by a different concept
* for accessing an element in a way that is compatible with the render layer.
*
* @exportedAs angular2/core
*/
export class NgElement {
_view:viewModule.AppView;
_boundElementIndex:number;
constructor(view, boundElementIndex) {
this._view = view;
this._boundElementIndex = boundElementIndex;
}
// TODO(tbosch): Here we expose the real DOM element.
// We need a more general way to read/write to the DOM element
// via a proper abstraction in the render layer
get domElement() {
var domViewRef:DirectDomViewRef = this._view.render;
return domViewRef.delegate.boundElements[this._boundElementIndex];
}
getAttribute(name:string):string {
return normalizeBlank(DOM.getAttribute(this.domElement, name));
}
}

View File

@ -25,7 +25,7 @@ export class AppViewContainer {
// TODO(tbosch): this is not supported in dart2js (no '.' is allowed) // TODO(tbosch): this is not supported in dart2js (no '.' is allowed)
// @IMPLEMENTS(renderApi.EventDispatcher) // @IMPLEMENTS(renderApi.EventDispatcher)
export class AppView { export class AppView {
render:renderApi.ViewRef; render:renderApi.RenderViewRef;
/// This list matches the _nodes list. It is sparse, since only Elements have ElementInjector /// This list matches the _nodes list. It is sparse, since only Elements have ElementInjector
rootElementInjectors:List<ElementInjector>; rootElementInjectors:List<ElementInjector>;
elementInjectors:List<ElementInjector>; elementInjectors:List<ElementInjector>;
@ -171,10 +171,10 @@ export class AppProtoView {
_directiveRecordsMap:Map; _directiveRecordsMap:Map;
_directiveRecords:List; _directiveRecords:List;
render:renderApi.ProtoViewRef; render:renderApi.RenderProtoViewRef;
constructor( constructor(
render:renderApi.ProtoViewRef, render:renderApi.RenderProtoViewRef,
protoChangeDetector:ProtoChangeDetector) { protoChangeDetector:ProtoChangeDetector) {
this.render = render; this.render = render;
this.elementBinders = []; this.elementBinders = [];

View File

@ -1,29 +1,27 @@
import {ListWrapper, MapWrapper, List} from 'angular2/src/facade/collection'; import {ListWrapper, List} from 'angular2/src/facade/collection';
import {Injector} from 'angular2/di'; import {Injector} from 'angular2/di';
import * as eiModule from 'angular2/src/core/compiler/element_injector';
import {isPresent, isBlank} from 'angular2/src/facade/lang'; import {isPresent, isBlank} from 'angular2/src/facade/lang';
import * as viewModule from './view';
import * as avmModule from './view_manager'; import * as avmModule from './view_manager';
/** import {ElementRef} from './element_ref';
* @exportedAs angular2/view import {ViewRef, ProtoViewRef, internalView} from './view_ref';
*/
export class ViewContainerRef { export class ViewContainerRef {
_viewManager: avmModule.AppViewManager; _viewManager: avmModule.AppViewManager;
_location: eiModule.ElementRef; _element: ElementRef;
_defaultProtoView: viewModule.AppProtoView; _defaultProtoViewRef: ProtoViewRef;
constructor(viewManager: avmModule.AppViewManager, constructor(viewManager: avmModule.AppViewManager,
location: eiModule.ElementRef, element: ElementRef,
defaultProtoView: viewModule.AppProtoView) { defaultProtoViewRef: ProtoViewRef) {
this._viewManager = viewManager; this._viewManager = viewManager;
this._location = location; this._element = element;
this._defaultProtoView = defaultProtoView; this._defaultProtoViewRef = defaultProtoViewRef;
} }
_getViews() { _getViews() {
var vc = this._location.hostView.viewContainers[this._location.boundElementIndex]; var vc = internalView(this._element.parentView).viewContainers[this._element.boundElementIndex];
return isPresent(vc) ? vc.views : []; return isPresent(vc) ? vc.views : [];
} }
@ -33,8 +31,8 @@ export class ViewContainerRef {
} }
} }
get(index: number): viewModule.AppView { get(index: number): ViewRef {
return this._getViews()[index]; return new ViewRef(this._getViews()[index]);
} }
get length() /* :int */ { get length() /* :int */ {
@ -43,26 +41,26 @@ export class ViewContainerRef {
// TODO(rado): profile and decide whether bounds checks should be added // TODO(rado): profile and decide whether bounds checks should be added
// to the methods below. // to the methods below.
create(atIndex:number=-1, protoView:viewModule.AppProtoView = null, injector:Injector = null): viewModule.AppView { create(atIndex:number=-1, protoViewRef:ProtoViewRef = null, injector:Injector = null): ViewRef {
if (atIndex == -1) atIndex = this.length; if (atIndex == -1) atIndex = this.length;
if (isBlank(protoView)) { if (isBlank(protoViewRef)) {
protoView = this._defaultProtoView; protoViewRef = this._defaultProtoViewRef;
} }
return this._viewManager.createViewInContainer(this._location, atIndex, protoView, injector); return this._viewManager.createViewInContainer(this._element, atIndex, protoViewRef, injector);
} }
insert(view:viewModule.AppView, atIndex:number=-1): viewModule.AppView { insert(viewRef:ViewRef, atIndex:number=-1): ViewRef {
if (atIndex == -1) atIndex = this.length; if (atIndex == -1) atIndex = this.length;
return this._viewManager.attachViewInContainer(this._location, atIndex, view); return this._viewManager.attachViewInContainer(this._element, atIndex, viewRef);
} }
indexOf(view:viewModule.AppView) { indexOf(viewRef:ViewRef) {
return ListWrapper.indexOf(this._getViews(), view); return ListWrapper.indexOf(this._getViews(), internalView(viewRef));
} }
remove(atIndex:number=-1):void { remove(atIndex:number=-1):void {
if (atIndex == -1) atIndex = this.length - 1; if (atIndex == -1) atIndex = this.length - 1;
this._viewManager.destroyViewInContainer(this._location, atIndex); this._viewManager.destroyViewInContainer(this._element, atIndex);
// view is intentionally not returned to the client. // view is intentionally not returned to the client.
} }
@ -70,8 +68,8 @@ export class ViewContainerRef {
* The method can be used together with insert to implement a view move, i.e. * The method can be used together with insert to implement a view move, i.e.
* moving the dom nodes while the directives in the view stay intact. * moving the dom nodes while the directives in the view stay intact.
*/ */
detach(atIndex:number=-1): viewModule.AppView { detach(atIndex:number=-1): ViewRef {
if (atIndex == -1) atIndex = this.length - 1; if (atIndex == -1) atIndex = this.length - 1;
return this._viewManager.detachViewInContainer(this._location, atIndex); return this._viewManager.detachViewInContainer(this._element, atIndex);
} }
} }

View File

@ -1,9 +1,11 @@
import {Injector, Injectable, Binding} from 'angular2/di'; import {Injector, Injectable, Binding} from 'angular2/di';
import {ListWrapper, MapWrapper, Map, StringMapWrapper, List} from 'angular2/src/facade/collection'; import {ListWrapper, MapWrapper, Map, StringMapWrapper, List} from 'angular2/src/facade/collection';
import {isPresent, isBlank, BaseException} from 'angular2/src/facade/lang'; import {isPresent, isBlank, BaseException} from 'angular2/src/facade/lang';
import * as eli from './element_injector';
import * as viewModule from './view'; import * as viewModule from './view';
import {Renderer, ViewRef, RenderViewContainerRef} from 'angular2/src/render/api'; import {ElementRef} from './element_ref';
import {ProtoViewRef, ViewRef, internalView, internalProtoView} from './view_ref';
import {ViewContainerRef} from './view_container_ref';
import {Renderer, RenderViewRef, RenderViewContainerRef} from 'angular2/src/render/api';
import {AppViewManagerUtils} from './view_manager_utils'; import {AppViewManagerUtils} from './view_manager_utils';
import {AppViewPool} from './view_pool'; import {AppViewPool} from './view_pool';
@ -24,9 +26,21 @@ export class AppViewManager {
this._utils = utils; this._utils = utils;
} }
createDynamicComponentView(hostLocation:eli.ElementRef, getViewContainer(location:ElementRef):ViewContainerRef {
componentProtoView:viewModule.AppProtoView, componentBinding:Binding, injector:Injector):viewModule.AppView { var hostView = internalView(location.parentView);
var hostView = hostLocation.hostView; return hostView.elementInjectors[location.boundElementIndex].getViewContainerRef();
}
getComponent(hostLocation:ElementRef):any {
var hostView = internalView(hostLocation.parentView);
var boundElementIndex = hostLocation.boundElementIndex;
return this._utils.getComponentInstance(hostView, boundElementIndex);
}
createDynamicComponentView(hostLocation:ElementRef,
componentProtoViewRef:ProtoViewRef, componentBinding:Binding, injector:Injector):ViewRef {
var componentProtoView = internalProtoView(componentProtoViewRef);
var hostView = internalView(hostLocation.parentView);
var boundElementIndex = hostLocation.boundElementIndex; var boundElementIndex = hostLocation.boundElementIndex;
var binder = hostView.proto.elementBinders[boundElementIndex]; var binder = hostView.proto.elementBinders[boundElementIndex];
if (!binder.hasDynamicComponent()) { if (!binder.hasDynamicComponent()) {
@ -39,34 +53,36 @@ export class AppViewManager {
this._utils.attachComponentView(hostView, boundElementIndex, componentView); this._utils.attachComponentView(hostView, boundElementIndex, componentView);
this._utils.hydrateDynamicComponentInElementInjector(hostView, boundElementIndex, componentBinding, injector); this._utils.hydrateDynamicComponentInElementInjector(hostView, boundElementIndex, componentBinding, injector);
this._utils.hydrateComponentView(hostView, boundElementIndex); this._utils.hydrateComponentView(hostView, boundElementIndex);
this._viewHydrateRecurse(componentView, renderViewRefs, 1); this._viewHydrateRecurse(componentView, renderViewRefs, 1);
return componentView;
return new ViewRef(componentView);
} }
createInPlaceHostView(parentComponentLocation:eli.ElementRef, createInPlaceHostView(parentComponentLocation:ElementRef,
hostElementSelector, hostProtoView:viewModule.AppProtoView, injector:Injector):viewModule.AppView { hostElementSelector, hostProtoViewRef:ProtoViewRef, injector:Injector):ViewRef {
var hostProtoView = internalProtoView(hostProtoViewRef);
var parentComponentHostView = null; var parentComponentHostView = null;
var parentComponentBoundElementIndex = null; var parentComponentBoundElementIndex = null;
var parentRenderViewRef = null; var parentRenderViewRef = null;
if (isPresent(parentComponentLocation)) { if (isPresent(parentComponentLocation)) {
parentComponentHostView = parentComponentLocation.hostView; parentComponentHostView = internalView(parentComponentLocation.parentView);
parentComponentBoundElementIndex = parentComponentLocation.boundElementIndex; parentComponentBoundElementIndex = parentComponentLocation.boundElementIndex;
parentRenderViewRef = parentComponentHostView.componentChildViews[parentComponentBoundElementIndex].render; parentRenderViewRef = parentComponentHostView.componentChildViews[parentComponentBoundElementIndex].render;
} }
var hostView = this._createViewRecurse(hostProtoView); var hostView = this._createViewRecurse(hostProtoView);
var renderViewRefs = this._renderer.createInPlaceHostView(parentRenderViewRef, hostElementSelector, hostView.proto.render); var renderViewRefs = this._renderer.createInPlaceHostView(parentRenderViewRef, hostElementSelector, hostProtoView.render);
hostView.render = renderViewRefs[0]; hostView.render = renderViewRefs[0];
this._utils.attachAndHydrateInPlaceHostView(parentComponentHostView, parentComponentBoundElementIndex, hostView, injector); this._utils.attachAndHydrateInPlaceHostView(parentComponentHostView, parentComponentBoundElementIndex, hostView, injector);
this._viewHydrateRecurse(hostView, renderViewRefs, 1); this._viewHydrateRecurse(hostView, renderViewRefs, 1);
return hostView; return new ViewRef(hostView);
} }
destroyInPlaceHostView(parentComponentLocation:eli.ElementRef, hostView:viewModule.AppView) { destroyInPlaceHostView(parentComponentLocation:ElementRef, hostViewRef:ViewRef) {
var hostView = internalView(hostViewRef);
var parentView = null; var parentView = null;
var parentRenderViewRef = null; var parentRenderViewRef = null;
if (isPresent(parentComponentLocation)) { if (isPresent(parentComponentLocation)) {
parentView = parentComponentLocation.hostView.componentChildViews[parentComponentLocation.boundElementIndex]; parentView = internalView(parentComponentLocation.parentView).componentChildViews[parentComponentLocation.boundElementIndex];
parentRenderViewRef = parentView.render; parentRenderViewRef = parentView.render;
} }
var hostViewRenderRef = hostView.render; var hostViewRenderRef = hostView.render;
@ -76,10 +92,12 @@ export class AppViewManager {
this._destroyView(hostView); this._destroyView(hostView);
} }
createViewInContainer(viewContainerLocation:eli.ElementRef, createViewInContainer(viewContainerLocation:ElementRef,
atIndex:number, protoView:viewModule.AppProtoView, injector:Injector = null):viewModule.AppView { atIndex:number, protoViewRef:ProtoViewRef, injector:Injector = null):ViewRef {
var parentView = viewContainerLocation.hostView; var protoView = internalProtoView(protoViewRef);
var boundElementIndex:number = viewContainerLocation.boundElementIndex; var parentView = internalView(viewContainerLocation.parentView);
var boundElementIndex = viewContainerLocation.boundElementIndex;
var view = this._createViewRecurse(protoView); var view = this._createViewRecurse(protoView);
var renderViewRefs = this._renderer.createViewInContainer(this._getRenderViewContainerRef(parentView, boundElementIndex), atIndex, view.proto.render); var renderViewRefs = this._renderer.createViewInContainer(this._getRenderViewContainerRef(parentView, boundElementIndex), atIndex, view.proto.render);
view.render = renderViewRefs[0]; view.render = renderViewRefs[0];
@ -87,12 +105,12 @@ export class AppViewManager {
this._utils.attachViewInContainer(parentView, boundElementIndex, atIndex, view); this._utils.attachViewInContainer(parentView, boundElementIndex, atIndex, view);
this._utils.hydrateViewInContainer(parentView, boundElementIndex, atIndex, injector); this._utils.hydrateViewInContainer(parentView, boundElementIndex, atIndex, injector);
this._viewHydrateRecurse(view, renderViewRefs, 1); this._viewHydrateRecurse(view, renderViewRefs, 1);
return view; return new ViewRef(view);
} }
destroyViewInContainer(viewContainerLocation:eli.ElementRef, atIndex:number) { destroyViewInContainer(viewContainerLocation:ElementRef, atIndex:number) {
var parentView = viewContainerLocation.hostView; var parentView = internalView(viewContainerLocation.parentView);
var boundElementIndex:number = viewContainerLocation.boundElementIndex; var boundElementIndex = viewContainerLocation.boundElementIndex;
var viewContainer = parentView.viewContainers[boundElementIndex]; var viewContainer = parentView.viewContainers[boundElementIndex];
var view = viewContainer.views[atIndex]; var view = viewContainer.views[atIndex];
this._viewDehydrateRecurse(view); this._viewDehydrateRecurse(view);
@ -101,22 +119,23 @@ export class AppViewManager {
this._destroyView(view); this._destroyView(view);
} }
attachViewInContainer(viewContainerLocation:eli.ElementRef, atIndex:number, view:viewModule.AppView):viewModule.AppView { attachViewInContainer(viewContainerLocation:ElementRef, atIndex:number, viewRef:ViewRef):ViewRef {
var parentView = viewContainerLocation.hostView; var view = internalView(viewRef);
var boundElementIndex:number = viewContainerLocation.boundElementIndex; var parentView = internalView(viewContainerLocation.parentView);
var boundElementIndex = viewContainerLocation.boundElementIndex;
this._utils.attachViewInContainer(parentView, boundElementIndex, atIndex, view); this._utils.attachViewInContainer(parentView, boundElementIndex, atIndex, view);
this._renderer.insertViewIntoContainer(this._getRenderViewContainerRef(parentView, boundElementIndex), atIndex, view.render); this._renderer.insertViewIntoContainer(this._getRenderViewContainerRef(parentView, boundElementIndex), atIndex, view.render);
return view; return viewRef;
} }
detachViewInContainer(viewContainerLocation:eli.ElementRef, atIndex:number):viewModule.AppView { detachViewInContainer(viewContainerLocation:ElementRef, atIndex:number):ViewRef {
var parentView = viewContainerLocation.hostView; var parentView = internalView(viewContainerLocation.parentView);
var boundElementIndex:number = viewContainerLocation.boundElementIndex; var boundElementIndex = viewContainerLocation.boundElementIndex;
var viewContainer = parentView.viewContainers[boundElementIndex]; var viewContainer = parentView.viewContainers[boundElementIndex];
var view = viewContainer.views[atIndex]; var view = viewContainer.views[atIndex];
this._utils.detachViewInContainer(parentView, boundElementIndex, atIndex); this._utils.detachViewInContainer(parentView, boundElementIndex, atIndex);
this._renderer.detachViewFromContainer(this._getRenderViewContainerRef(parentView, boundElementIndex), atIndex); this._renderer.detachViewFromContainer(this._getRenderViewContainerRef(parentView, boundElementIndex), atIndex);
return view; return new ViewRef(view);
} }
_getRenderViewContainerRef(parentView:viewModule.AppView, boundElementIndex:number) { _getRenderViewContainerRef(parentView:viewModule.AppView, boundElementIndex:number) {
@ -145,7 +164,7 @@ export class AppViewManager {
_viewHydrateRecurse( _viewHydrateRecurse(
view:viewModule.AppView, view:viewModule.AppView,
renderComponentViewRefs:List<ViewRef>, renderComponentViewRefs:List<RenderViewRef>,
renderComponentIndex:number):number { renderComponentIndex:number):number {
this._renderer.setEventDispatcher(view.render, view); this._renderer.setEventDispatcher(view.render, view);

View File

@ -2,7 +2,6 @@ import {Injectable, Injector, Binding} from 'angular2/di';
import {ListWrapper, MapWrapper, Map, StringMapWrapper, List} from 'angular2/src/facade/collection'; import {ListWrapper, MapWrapper, Map, StringMapWrapper, List} from 'angular2/src/facade/collection';
import * as eli from './element_injector'; import * as eli from './element_injector';
import {isPresent, isBlank, BaseException} from 'angular2/src/facade/lang'; import {isPresent, isBlank, BaseException} from 'angular2/src/facade/lang';
import {NgElement} from 'angular2/src/core/compiler/ng_element';
import * as viewModule from './view'; import * as viewModule from './view';
import * as avmModule from './view_manager'; import * as avmModule from './view_manager';
import {Renderer} from 'angular2/src/render/api'; import {Renderer} from 'angular2/src/render/api';
@ -17,6 +16,16 @@ export class AppViewManagerUtils {
this._metadataReader = metadataReader; this._metadataReader = metadataReader;
} }
getComponentInstance(parentView:viewModule.AppView, boundElementIndex:number):any {
var binder = parentView.proto.elementBinders[boundElementIndex];
var eli = parentView.elementInjectors[boundElementIndex];
if (binder.hasDynamicComponent()) {
return eli.getDynamicallyLoadedComponent();
} else {
return eli.getComponent();
}
}
createView(protoView:viewModule.AppProtoView, viewManager:avmModule.AppViewManager, renderer:Renderer): viewModule.AppView { createView(protoView:viewModule.AppProtoView, viewManager:avmModule.AppViewManager, renderer:Renderer): viewModule.AppView {
var view = new viewModule.AppView(renderer, protoView, protoView.protoLocals); var view = new viewModule.AppView(renderer, protoView, protoView.protoLocals);
var changeDetector = protoView.protoChangeDetector.instantiate(view, protoView.bindings, var changeDetector = protoView.protoChangeDetector.instantiate(view, protoView.bindings,
@ -48,7 +57,7 @@ export class AppViewManagerUtils {
// preBuiltObjects // preBuiltObjects
if (isPresent(elementInjector)) { if (isPresent(elementInjector)) {
var defaultProtoView = isPresent(binder.viewportDirective) ? binder.nestedProtoView : null; var defaultProtoView = isPresent(binder.viewportDirective) ? binder.nestedProtoView : null;
preBuiltObjects[binderIdx] = new eli.PreBuiltObjects(viewManager, view, new NgElement(view, binderIdx), defaultProtoView); preBuiltObjects[binderIdx] = new eli.PreBuiltObjects(viewManager, view, defaultProtoView);
} }
} }
@ -74,13 +83,7 @@ export class AppViewManagerUtils {
hydrateComponentView(hostView:viewModule.AppView, boundElementIndex:number, injector:Injector = null) { hydrateComponentView(hostView:viewModule.AppView, boundElementIndex:number, injector:Injector = null) {
var elementInjector = hostView.elementInjectors[boundElementIndex]; var elementInjector = hostView.elementInjectors[boundElementIndex];
var componentView = hostView.componentChildViews[boundElementIndex]; var componentView = hostView.componentChildViews[boundElementIndex];
var binder = hostView.proto.elementBinders[boundElementIndex]; var component = this.getComponentInstance(hostView, boundElementIndex);
var component;
if (binder.hasDynamicComponent()) {
component = elementInjector.getDynamicallyLoadedComponent();
} else {
component = elementInjector.getComponent();
}
this._hydrateView( this._hydrateView(
componentView, injector, elementInjector, component, null componentView, injector, elementInjector, component, null
); );
@ -106,7 +109,8 @@ export class AppViewManagerUtils {
} }
} }
attachViewInContainer(parentView:viewModule.AppView, boundElementIndex:number, atIndex:number, view:viewModule.AppView) { attachViewInContainer(parentView:viewModule.AppView, boundElementIndex:number,
atIndex:number, view:viewModule.AppView) {
parentView.changeDetector.addChild(view.changeDetector); parentView.changeDetector.addChild(view.changeDetector);
var viewContainer = parentView.viewContainers[boundElementIndex]; var viewContainer = parentView.viewContainers[boundElementIndex];
if (isBlank(viewContainer)) { if (isBlank(viewContainer)) {
@ -136,7 +140,8 @@ export class AppViewManagerUtils {
} }
} }
hydrateViewInContainer(parentView:viewModule.AppView, boundElementIndex:number, atIndex:number, injector:Injector) { hydrateViewInContainer(parentView:viewModule.AppView, boundElementIndex:number,
atIndex:number, injector:Injector) {
var viewContainer = parentView.viewContainers[boundElementIndex]; var viewContainer = parentView.viewContainers[boundElementIndex];
var view = viewContainer.views[atIndex]; var view = viewContainer.views[atIndex];
var elementInjector = parentView.elementInjectors[boundElementIndex]; var elementInjector = parentView.elementInjectors[boundElementIndex];
@ -203,7 +208,7 @@ export class AppViewManagerUtils {
if (elementInjector.isExportingComponent()) { if (elementInjector.isExportingComponent()) {
view.locals.set(exportImplicitName, elementInjector.getComponent()); view.locals.set(exportImplicitName, elementInjector.getComponent());
} else if (elementInjector.isExportingElement()) { } else if (elementInjector.isExportingElement()) {
view.locals.set(exportImplicitName, elementInjector.getNgElement().domElement); view.locals.set(exportImplicitName, elementInjector.getElementRef().domElement);
} }
} }
} }

View File

@ -0,0 +1,43 @@
import {isPresent} from 'angular2/src/facade/lang';
import * as viewModule from './view';
import {RenderViewRef} from 'angular2/src/render/api';
// This is a workaround for privacy in Dart as we don't have library parts
export function internalView(viewRef:ViewRef) {
return viewRef._view;
}
// This is a workaround for privacy in Dart as we don't have library parts
export function internalProtoView(protoViewRef:ProtoViewRef) {
return isPresent(protoViewRef) ? protoViewRef._protoView : null;
}
/**
* @exportedAs angular2/view
*/
export class ViewRef {
_view:viewModule.AppView;
constructor(view:viewModule.AppView) {
this._view = view;
}
get render():RenderViewRef {
return this._view.render;
}
setLocal(contextName: string, value:any) {
this._view.setLocal(contextName, value);
}
}
/**
* @exportedAs angular2/view
*/
export class ProtoViewRef {
_protoView:viewModule.AppProtoView;
constructor(protoView) {
this._protoView = protoView;
}
}

View File

@ -1,7 +1,7 @@
import {Decorator} from 'angular2/src/core/annotations/annotations'; import {Decorator} from 'angular2/src/core/annotations/annotations';
import {isPresent} from 'angular2/src/facade/lang'; import {isPresent} from 'angular2/src/facade/lang';
import {DOM} from 'angular2/src/dom/dom_adapter'; import {DOM} from 'angular2/src/dom/dom_adapter';
import {NgElement} from 'angular2/src/core/compiler/ng_element'; import {ElementRef} from 'angular2/src/core/compiler/element_ref';
@Decorator({ @Decorator({
selector: '[class]', selector: '[class]',
@ -11,7 +11,7 @@ import {NgElement} from 'angular2/src/core/compiler/ng_element';
}) })
export class CSSClass { export class CSSClass {
_domEl; _domEl;
constructor(ngEl: NgElement) { constructor(ngEl: ElementRef) {
this._domEl = ngEl.domElement; this._domEl = ngEl.domElement;
} }

View File

@ -1,6 +1,6 @@
import {Viewport} from 'angular2/src/core/annotations/annotations'; import {Viewport} from 'angular2/src/core/annotations/annotations';
import {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref'; import {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref';
import {AppView} from 'angular2/src/core/compiler/view'; import {ViewRef} from 'angular2/src/core/compiler/view_ref';
import {isPresent, isBlank} from 'angular2/src/facade/lang'; import {isPresent, isBlank} from 'angular2/src/facade/lang';
import {ListWrapper} from 'angular2/src/facade/collection'; import {ListWrapper} from 'angular2/src/facade/collection';
@ -114,7 +114,7 @@ export class For {
} }
class RecordViewTuple { class RecordViewTuple {
view: AppView; view: ViewRef;
record: any; record: any;
constructor(record, view) { constructor(record, view) {
this.record = record; this.record = record;

View File

@ -1,6 +1,6 @@
import {Decorator, onChange} from 'angular2/src/core/annotations/annotations'; import {Decorator, onChange} from 'angular2/src/core/annotations/annotations';
import {Ancestor} from 'angular2/src/core/annotations/visibility'; import {Ancestor} from 'angular2/src/core/annotations/visibility';
import {ElementRef} from 'angular2/src/core/compiler/element_injector'; import {ElementRef} from 'angular2/src/core/compiler/element_ref';
import {Optional} from 'angular2/di'; import {Optional} from 'angular2/di';
import {Renderer} from 'angular2/src/render/api'; import {Renderer} from 'angular2/src/render/api';
import {isPresent, isString} from 'angular2/src/facade/lang'; import {isPresent, isString} from 'angular2/src/facade/lang';
@ -83,7 +83,7 @@ export class CheckboxControlValueAccessor {
} }
writeValue(value) { writeValue(value) {
this._renderer.setElementProperty(this._elementRef.hostView.render, this._elementRef.boundElementIndex, this._renderer.setElementProperty(this._elementRef.parentView.render, this._elementRef.boundElementIndex,
'checked', value) 'checked', value)
} }
} }

View File

@ -95,7 +95,7 @@ export class ProtoViewDto {
// inside of a component view // inside of a component view
static get EMBEDDED_VIEW_TYPE() { return 1; } static get EMBEDDED_VIEW_TYPE() { return 1; }
render: ProtoViewRef; render: RenderProtoViewRef;
elementBinders:List<ElementBinder>; elementBinders:List<ElementBinder>;
variableBindings: Map<string, string>; variableBindings: Map<string, string>;
type: number; type: number;
@ -133,15 +133,15 @@ export class DirectiveMetadata {
} }
// An opaque reference to a RenderProtoView // An opaque reference to a RenderProtoView
export class ProtoViewRef {} export class RenderProtoViewRef {}
// An opaque reference to a RenderView // An opaque reference to a RenderView
export class ViewRef {} export class RenderViewRef {}
export class RenderViewContainerRef { export class RenderViewContainerRef {
view:ViewRef; view:RenderViewRef;
elementIndex:number; elementIndex:number;
constructor(view:ViewRef, elementIndex: number) { constructor(view:RenderViewRef, elementIndex: number) {
this.view = view; this.view = view;
this.elementIndex = elementIndex; this.elementIndex = elementIndex;
} }
@ -186,19 +186,19 @@ export class Renderer {
* Sets the preset nested components, * Sets the preset nested components,
* which will be instantiated when this protoView is instantiated. * which will be instantiated when this protoView is instantiated.
* Note: We can't create new ProtoViewRefs here as we need to support cycles / recursive components. * Note: We can't create new ProtoViewRefs here as we need to support cycles / recursive components.
* @param {List<ProtoViewRef>} protoViewRefs * @param {List<RenderProtoViewRef>} protoViewRefs
* RenderProtoView for every element with a component in this protoView or in a view container's protoView * RenderProtoView for every element with a component in this protoView or in a view container's protoView
*/ */
mergeChildComponentProtoViews(protoViewRef:ProtoViewRef, componentProtoViewRefs:List<ProtoViewRef>) { return null; } mergeChildComponentProtoViews(protoViewRef:RenderProtoViewRef, componentProtoViewRefs:List<RenderProtoViewRef>) { return null; }
/** /**
* Creates a view and inserts it into a ViewContainer. * Creates a view and inserts it into a ViewContainer.
* @param {RenderViewContainerRef} viewContainerRef * @param {RenderViewContainerRef} viewContainerRef
* @param {ProtoViewRef} protoViewRef A ProtoViewRef of type ProtoViewDto.HOST_VIEW_TYPE or ProtoViewDto.EMBEDDED_VIEW_TYPE * @param {RenderProtoViewRef} protoViewRef A RenderProtoViewRef of type ProtoViewDto.HOST_VIEW_TYPE or ProtoViewDto.EMBEDDED_VIEW_TYPE
* @param {number} atIndex * @param {number} atIndex
* @return {List<ViewRef>} the view and all of its nested child component views * @return {List<RenderViewRef>} the view and all of its nested child component views
*/ */
createViewInContainer(vcRef:RenderViewContainerRef, atIndex:number, protoViewRef:ProtoViewRef):List<ViewRef> { return null; } createViewInContainer(vcRef:RenderViewContainerRef, atIndex:number, protoViewRef:RenderProtoViewRef):List<RenderViewRef> { return null; }
/** /**
* Destroys the view in the given ViewContainer * Destroys the view in the given ViewContainer
@ -208,7 +208,7 @@ export class Renderer {
/** /**
* Inserts a detached view into a viewContainer. * Inserts a detached view into a viewContainer.
*/ */
insertViewIntoContainer(vcRef:RenderViewContainerRef, atIndex:number, view:ViewRef):void {} insertViewIntoContainer(vcRef:RenderViewContainerRef, atIndex:number, view:RenderViewRef):void {}
/** /**
* Detaches a view from a container so that it can be inserted later on * Detaches a view from a container so that it can be inserted later on
@ -220,53 +220,53 @@ export class Renderer {
* installs it as a shadow view for an element. * installs it as a shadow view for an element.
* *
* Note: only allowed if there is a dynamic component directive at this place. * Note: only allowed if there is a dynamic component directive at this place.
* @param {ViewRef} hostView * @param {RenderViewRef} hostView
* @param {number} elementIndex * @param {number} elementIndex
* @param {ProtoViewRef} componentProtoViewRef A ProtoViewRef of type ProtoViewDto.COMPONENT_VIEW_TYPE * @param {RenderProtoViewRef} componentProtoViewRef A RenderProtoViewRef of type ProtoViewDto.COMPONENT_VIEW_TYPE
* @return {List<ViewRef>} the view and all of its nested child component views * @return {List<RenderViewRef>} the view and all of its nested child component views
*/ */
createDynamicComponentView(hostViewRef:ViewRef, elementIndex:number, componentProtoViewRef:ProtoViewRef):List<ViewRef> { return null; } createDynamicComponentView(hostViewRef:RenderViewRef, elementIndex:number, componentProtoViewRef:RenderProtoViewRef):List<RenderViewRef> { return null; }
/** /**
* Destroys the component view at the given index * Destroys the component view at the given index
* *
* Note: only allowed if there is a dynamic component directive at this place. * Note: only allowed if there is a dynamic component directive at this place.
*/ */
destroyDynamicComponentView(hostViewRef:ViewRef, elementIndex:number):void {} destroyDynamicComponentView(hostViewRef:RenderViewRef, elementIndex:number):void {}
/** /**
* Creates a host view that includes the given element. * Creates a host view that includes the given element.
* @param {ViewRef} parentViewRef (might be null) * @param {RenderViewRef} parentViewRef (might be null)
* @param {any} hostElementSelector element or css selector for the host element * @param {any} hostElementSelector element or css selector for the host element
* @param {ProtoViewRef} hostProtoView a ProtoViewRef of type ProtoViewDto.HOST_VIEW_TYPE * @param {RenderProtoViewRef} hostProtoView a RenderProtoViewRef of type ProtoViewDto.HOST_VIEW_TYPE
* @return {List<ViewRef>} the view and all of its nested child component views * @return {List<RenderViewRef>} the view and all of its nested child component views
*/ */
createInPlaceHostView(parentViewRef:ViewRef, hostElementSelector, hostProtoViewRef:ProtoViewRef):List<ViewRef> { return null; } createInPlaceHostView(parentViewRef:RenderViewRef, hostElementSelector, hostProtoViewRef:RenderProtoViewRef):List<RenderViewRef> { return null; }
/** /**
* Destroys the given host view in the given parent view. * Destroys the given host view in the given parent view.
*/ */
destroyInPlaceHostView(parentViewRef:ViewRef, hostViewRef:ViewRef):void {} destroyInPlaceHostView(parentViewRef:RenderViewRef, hostViewRef:RenderViewRef):void {}
/** /**
* Sets a property on an element. * Sets a property on an element.
* Note: This will fail if the property was not mentioned previously as a host property * Note: This will fail if the property was not mentioned previously as a host property
* in the View. * in the View.
*/ */
setElementProperty(view:ViewRef, elementIndex:number, propertyName:string, propertyValue:any):void {} setElementProperty(view:RenderViewRef, elementIndex:number, propertyName:string, propertyValue:any):void {}
/** /**
* This will set the value for a text node. * This will set the value for a text node.
* Note: This needs to be separate from setElementProperty as we don't have ElementBinders * Note: This needs to be separate from setElementProperty as we don't have ElementBinders
* for text nodes in the RenderProtoView either. * for text nodes in the RenderProtoView either.
*/ */
setText(view:ViewRef, textNodeIndex:number, text:string):void {} setText(view:RenderViewRef, textNodeIndex:number, text:string):void {}
/** /**
* Sets the dispatcher for all events that have been defined in the template or in directives * Sets the dispatcher for all events that have been defined in the template or in directives
* in the given view. * in the given view.
*/ */
setEventDispatcher(viewRef:ViewRef, dispatcher:any/*EventDispatcher*/):void {} setEventDispatcher(viewRef:RenderViewRef, dispatcher:any/*EventDispatcher*/):void {}
/** /**
* To be called at the end of the VmTurn so the API can buffer calls * To be called at the end of the VmTurn so the API can buffer calls

View File

@ -45,7 +45,7 @@ function _collectComponentChildViewRefs(view, target = null) {
// public so that the compiler can use it. // public so that the compiler can use it.
export class DirectDomProtoViewRef extends api.ProtoViewRef { export class DirectDomProtoViewRef extends api.RenderProtoViewRef {
delegate:RenderProtoView; delegate:RenderProtoView;
constructor(delegate:RenderProtoView) { constructor(delegate:RenderProtoView) {
@ -54,7 +54,7 @@ export class DirectDomProtoViewRef extends api.ProtoViewRef {
} }
} }
export class DirectDomViewRef extends api.ViewRef { export class DirectDomViewRef extends api.RenderViewRef {
delegate:RenderView; delegate:RenderView;
constructor(delegate:RenderView) { constructor(delegate:RenderView) {
@ -95,13 +95,13 @@ export class DirectDomRenderer extends api.Renderer {
return this._compiler.compile(view); return this._compiler.compile(view);
} }
mergeChildComponentProtoViews(protoViewRef:api.ProtoViewRef, protoViewRefs:List<api.ProtoViewRef>) { mergeChildComponentProtoViews(protoViewRef:api.RenderProtoViewRef, protoViewRefs:List<api.RenderProtoViewRef>) {
_resolveProtoView(protoViewRef).mergeChildComponentProtoViews( _resolveProtoView(protoViewRef).mergeChildComponentProtoViews(
ListWrapper.map(protoViewRefs, _resolveProtoView) ListWrapper.map(protoViewRefs, _resolveProtoView)
); );
} }
createViewInContainer(vcRef:api.RenderViewContainerRef, atIndex:number, protoViewRef:api.ProtoViewRef):List<api.ViewRef> { createViewInContainer(vcRef:api.RenderViewContainerRef, atIndex:number, protoViewRef:api.RenderProtoViewRef):List<api.RenderViewRef> {
var view = this._viewFactory.getView(_resolveProtoView(protoViewRef)); var view = this._viewFactory.getView(_resolveProtoView(protoViewRef));
var vc = _resolveViewContainer(vcRef); var vc = _resolveViewContainer(vcRef);
this._viewHydrator.hydrateViewInViewContainer(vc, view); this._viewHydrator.hydrateViewInViewContainer(vc, view);
@ -116,7 +116,7 @@ export class DirectDomRenderer extends api.Renderer {
this._viewFactory.returnView(view); this._viewFactory.returnView(view);
} }
insertViewIntoContainer(vcRef:api.RenderViewContainerRef, atIndex=-1, viewRef:api.ViewRef):void { insertViewIntoContainer(vcRef:api.RenderViewContainerRef, atIndex=-1, viewRef:api.RenderViewRef):void {
_resolveViewContainer(vcRef).insert(_resolveView(viewRef), atIndex); _resolveViewContainer(vcRef).insert(_resolveView(viewRef), atIndex);
} }
@ -124,14 +124,14 @@ export class DirectDomRenderer extends api.Renderer {
_resolveViewContainer(vcRef).detach(atIndex); _resolveViewContainer(vcRef).detach(atIndex);
} }
createDynamicComponentView(hostViewRef:api.ViewRef, elementIndex:number, componentViewRef:api.ProtoViewRef):List<api.ViewRef> { createDynamicComponentView(hostViewRef:api.RenderViewRef, elementIndex:number, componentViewRef:api.RenderProtoViewRef):List<api.RenderViewRef> {
var hostView = _resolveView(hostViewRef); var hostView = _resolveView(hostViewRef);
var componentView = this._viewFactory.getView(_resolveProtoView(componentViewRef)); var componentView = this._viewFactory.getView(_resolveProtoView(componentViewRef));
this._viewHydrator.hydrateDynamicComponentView(hostView, elementIndex, componentView); this._viewHydrator.hydrateDynamicComponentView(hostView, elementIndex, componentView);
return _collectComponentChildViewRefs(componentView); return _collectComponentChildViewRefs(componentView);
} }
destroyDynamicComponentView(hostViewRef:api.ViewRef, elementIndex:number):void { destroyDynamicComponentView(hostViewRef:api.RenderViewRef, elementIndex:number):void {
throw new BaseException('Not supported yet'); throw new BaseException('Not supported yet');
// Something along these lines: // Something along these lines:
// var hostView = _resolveView(hostViewRef); // var hostView = _resolveView(hostViewRef);
@ -139,7 +139,7 @@ export class DirectDomRenderer extends api.Renderer {
// this._viewHydrator.dehydrateDynamicComponentView(hostView, componentView); // this._viewHydrator.dehydrateDynamicComponentView(hostView, componentView);
} }
createInPlaceHostView(parentViewRef:api.ViewRef, hostElementSelector, hostProtoViewRef:api.ProtoViewRef):List<api.ViewRef> { createInPlaceHostView(parentViewRef:api.RenderViewRef, hostElementSelector, hostProtoViewRef:api.RenderProtoViewRef):List<api.RenderViewRef> {
var parentView = _resolveView(parentViewRef); var parentView = _resolveView(parentViewRef);
var hostView = this._viewFactory.createInPlaceHostView(hostElementSelector, _resolveProtoView(hostProtoViewRef)); var hostView = this._viewFactory.createInPlaceHostView(hostElementSelector, _resolveProtoView(hostProtoViewRef));
this._viewHydrator.hydrateInPlaceHostView(parentView, hostView); this._viewHydrator.hydrateInPlaceHostView(parentView, hostView);
@ -149,13 +149,13 @@ export class DirectDomRenderer extends api.Renderer {
/** /**
* Destroys the given host view in the given parent view. * Destroys the given host view in the given parent view.
*/ */
destroyInPlaceHostView(parentViewRef:api.ViewRef, hostViewRef:api.ViewRef):void { destroyInPlaceHostView(parentViewRef:api.RenderViewRef, hostViewRef:api.RenderViewRef):void {
var parentView = _resolveView(parentViewRef); var parentView = _resolveView(parentViewRef);
var hostView = _resolveView(hostViewRef); var hostView = _resolveView(hostViewRef);
this._viewHydrator.dehydrateInPlaceHostView(parentView, hostView); this._viewHydrator.dehydrateInPlaceHostView(parentView, hostView);
} }
setImperativeComponentRootNodes(parentViewRef:api.ViewRef, elementIndex:number, nodes:List):void { setImperativeComponentRootNodes(parentViewRef:api.RenderViewRef, elementIndex:number, nodes:List):void {
var parentView = _resolveView(parentViewRef); var parentView = _resolveView(parentViewRef);
var hostElement = parentView.boundElements[elementIndex]; var hostElement = parentView.boundElements[elementIndex];
var componentView = parentView.componentChildViews[elementIndex]; var componentView = parentView.componentChildViews[elementIndex];
@ -170,15 +170,15 @@ export class DirectDomRenderer extends api.Renderer {
this._shadowDomStrategy.attachTemplate(hostElement, componentView); this._shadowDomStrategy.attachTemplate(hostElement, componentView);
} }
setElementProperty(viewRef:api.ViewRef, elementIndex:number, propertyName:string, propertyValue:any):void { setElementProperty(viewRef:api.RenderViewRef, elementIndex:number, propertyName:string, propertyValue:any):void {
_resolveView(viewRef).setElementProperty(elementIndex, propertyName, propertyValue); _resolveView(viewRef).setElementProperty(elementIndex, propertyName, propertyValue);
} }
setText(viewRef:api.ViewRef, textNodeIndex:number, text:string):void { setText(viewRef:api.RenderViewRef, textNodeIndex:number, text:string):void {
_resolveView(viewRef).setText(textNodeIndex, text); _resolveView(viewRef).setText(textNodeIndex, text);
} }
setEventDispatcher(viewRef:api.ViewRef, dispatcher:any/*api.EventDispatcher*/):void { setEventDispatcher(viewRef:api.RenderViewRef, dispatcher:any/*api.EventDispatcher*/):void {
_resolveView(viewRef).setEventDispatcher(dispatcher); _resolveView(viewRef).setEventDispatcher(dispatcher);
} }
} }

View File

@ -1,5 +1,5 @@
import {Decorator} from 'angular2/annotations'; import {Decorator} from 'angular2/annotations';
import {NgElement} from 'angular2/core'; import {ElementRef} from 'angular2/core';
import {isPresent} from 'angular2/src/facade/lang'; import {isPresent} from 'angular2/src/facade/lang';
import {DOM} from 'angular2/src/dom/dom_adapter'; import {DOM} from 'angular2/src/dom/dom_adapter';
@ -41,8 +41,8 @@ export class RouterLink {
_router:Router; _router:Router;
//TODO: handle click events //TODO: handle click events
constructor(ngEl:NgElement, router:Router) { constructor(elementRef:ElementRef, router:Router) {
this._domEl = ngEl.domElement; this._domEl = elementRef.domElement;
this._router = router; this._router = router;
} }

View File

@ -1,6 +1,6 @@
import {Promise, PromiseWrapper} from 'angular2/src/facade/async'; import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
import {DomAdapter} from 'angular2/src/dom/dom_adapter'; import {DomAdapter} from 'angular2/src/dom/dom_adapter';
import {NgElement} from 'angular2/src/core/compiler/ng_element'; import {ElementRef} from 'angular2/src/core/compiler/element_ref';
export class Rectangle { export class Rectangle {
left; left;
@ -25,7 +25,7 @@ export class Ruler {
this.domAdapter = domAdapter; this.domAdapter = domAdapter;
} }
measure(el:NgElement): Promise<Rectangle> { measure(el:ElementRef): Promise<Rectangle> {
var clntRect = this.domAdapter.getBoundingClientRect(el.domElement); var clntRect = this.domAdapter.getBoundingClientRect(el.domElement);
//even if getBoundingClientRect is synchronous we use async API in preparation for further changes //even if getBoundingClientRect is synchronous we use async API in preparation for further changes

View File

@ -9,6 +9,7 @@ import {View} from 'angular2/src/core/annotations/view';
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver'; import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
import {AppView} from 'angular2/src/core/compiler/view'; import {AppView} from 'angular2/src/core/compiler/view';
import {internalView} from 'angular2/src/core/compiler/view_ref';
import {DynamicComponentLoader, ComponentRef} from 'angular2/src/core/compiler/dynamic_component_loader'; import {DynamicComponentLoader, ComponentRef} from 'angular2/src/core/compiler/dynamic_component_loader';
import {queryView, viewRootNodes, el} from './utils'; import {queryView, viewRootNodes, el} from './utils';
@ -103,7 +104,7 @@ export class ViewProxy {
constructor(componentRef: ComponentRef) { constructor(componentRef: ComponentRef) {
this._componentRef = componentRef; this._componentRef = componentRef;
this._view = componentRef.hostView.componentChildViews[0]; this._view = internalView(componentRef.hostView).componentChildViews[0];
} }
get context(): any { get context(): any {

View File

@ -276,7 +276,15 @@ export class SpyObject {
constructor(type = null) { constructor(type = null) {
if (type) { if (type) {
for (var prop in type.prototype) { for (var prop in type.prototype) {
var m = type.prototype[prop]; var m = null;
try {
m = type.prototype[prop];
} catch (e) {
// As we are creating spys for abstract classes,
// these classes might have getters that throw when they are accessed.
// As we are only auto creating spys for methods, this
// should not matter.
}
if (typeof m === 'function') { if (typeof m === 'function') {
this.spy(prop); this.spy(prop);
} }

View File

@ -24,6 +24,7 @@ import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_meta
import {Component, DynamicComponent, Viewport, Decorator} from 'angular2/src/core/annotations/annotations'; import {Component, DynamicComponent, Viewport, Decorator} from 'angular2/src/core/annotations/annotations';
import {Attribute} from 'angular2/src/core/annotations/di'; import {Attribute} from 'angular2/src/core/annotations/di';
import {View} from 'angular2/src/core/annotations/view'; import {View} from 'angular2/src/core/annotations/view';
import {internalProtoView} from 'angular2/src/core/compiler/view_ref';
import {DirectiveBinding} from 'angular2/src/core/compiler/element_injector'; import {DirectiveBinding} from 'angular2/src/core/compiler/element_injector';
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver'; import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
import {ComponentUrlMapper, RuntimeComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper'; import {ComponentUrlMapper, RuntimeComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
@ -70,7 +71,7 @@ export function main() {
function captureTemplate(template:View):Promise<renderApi.ViewDefinition> { function captureTemplate(template:View):Promise<renderApi.ViewDefinition> {
tplResolver.setView(MainComponent, template); tplResolver.setView(MainComponent, template);
var compiler = createCompiler([createRenderProtoView()], [createProtoView()]); var compiler = createCompiler([createRenderProtoView()], [createProtoView()]);
return compiler.compile(MainComponent).then( (protoView) => { return compiler.compile(MainComponent).then( (_) => {
expect(renderCompileRequests.length).toBe(1); expect(renderCompileRequests.length).toBe(1);
return renderCompileRequests[0]; return renderCompileRequests[0];
}); });
@ -226,7 +227,7 @@ export function main() {
var renderProtoView = createRenderProtoView(); var renderProtoView = createRenderProtoView();
var expectedProtoView = createProtoView(); var expectedProtoView = createProtoView();
var compiler = createCompiler([renderProtoView], [expectedProtoView]); var compiler = createCompiler([renderProtoView], [expectedProtoView]);
compiler.compile(MainComponent).then( (protoView) => { compiler.compile(MainComponent).then( (_) => {
var request = protoViewFactory.requests[0]; var request = protoViewFactory.requests[0];
expect(request[1]).toBe(renderProtoView); expect(request[1]).toBe(renderProtoView);
async.done(); async.done();
@ -236,7 +237,7 @@ export function main() {
it('should pass the component binding', inject([AsyncTestCompleter], (async) => { it('should pass the component binding', inject([AsyncTestCompleter], (async) => {
tplResolver.setView(MainComponent, new View({template: '<div></div>'})); tplResolver.setView(MainComponent, new View({template: '<div></div>'}));
var compiler = createCompiler([createRenderProtoView()], [createProtoView()]); var compiler = createCompiler([createRenderProtoView()], [createProtoView()]);
compiler.compile(MainComponent).then( (protoView) => { compiler.compile(MainComponent).then( (_) => {
var request = protoViewFactory.requests[0]; var request = protoViewFactory.requests[0];
expect(request[0].key.token).toBe(MainComponent); expect(request[0].key.token).toBe(MainComponent);
async.done(); async.done();
@ -251,7 +252,7 @@ export function main() {
}) })
); );
var compiler = createCompiler([createRenderProtoView()], [createProtoView()]); var compiler = createCompiler([createRenderProtoView()], [createProtoView()]);
compiler.compile(MainComponent).then( (protoView) => { compiler.compile(MainComponent).then( (_) => {
var request = protoViewFactory.requests[0]; var request = protoViewFactory.requests[0];
var binding = request[2][0]; var binding = request[2][0];
expect(binding.key.token).toBe(SomeDecoratorDirective); expect(binding.key.token).toBe(SomeDecoratorDirective);
@ -264,8 +265,8 @@ export function main() {
var renderProtoView = createRenderProtoView(); var renderProtoView = createRenderProtoView();
var expectedProtoView = createProtoView(); var expectedProtoView = createProtoView();
var compiler = createCompiler([renderProtoView], [expectedProtoView]); var compiler = createCompiler([renderProtoView], [expectedProtoView]);
compiler.compile(MainComponent).then( (protoView) => { compiler.compile(MainComponent).then( (protoViewRef) => {
expect(protoView).toBe(expectedProtoView); expect(internalProtoView(protoViewRef)).toBe(expectedProtoView);
async.done(); async.done();
}); });
})); }));
@ -286,8 +287,8 @@ export function main() {
], ],
[mainProtoView, nestedProtoView] [mainProtoView, nestedProtoView]
); );
compiler.compile(MainComponent).then( (protoView) => { compiler.compile(MainComponent).then( (protoViewRef) => {
expect(protoView).toBe(mainProtoView); expect(internalProtoView(protoViewRef)).toBe(mainProtoView);
expect(mainProtoView.elementBinders[0].nestedProtoView).toBe(nestedProtoView); expect(mainProtoView.elementBinders[0].nestedProtoView).toBe(nestedProtoView);
// parentProtoView of nested components has to be null as components can // parentProtoView of nested components has to be null as components can
// be used by multiple other components. // be used by multiple other components.
@ -319,8 +320,8 @@ export function main() {
], ],
[mainProtoView, viewportProtoView, nestedProtoView] [mainProtoView, viewportProtoView, nestedProtoView]
); );
compiler.compile(MainComponent).then( (protoView) => { compiler.compile(MainComponent).then( (protoViewRef) => {
expect(protoView).toBe(mainProtoView); expect(internalProtoView(protoViewRef)).toBe(mainProtoView);
expect(mainProtoView.elementBinders[0].nestedProtoView).toBe(viewportProtoView); expect(mainProtoView.elementBinders[0].nestedProtoView).toBe(viewportProtoView);
expect(viewportProtoView.parentProtoView).toBe(mainProtoView); expect(viewportProtoView.parentProtoView).toBe(mainProtoView);
expect(viewportProtoView.elementBinders[0].nestedProtoView).toBe(nestedProtoView); expect(viewportProtoView.elementBinders[0].nestedProtoView).toBe(nestedProtoView);
@ -337,11 +338,11 @@ export function main() {
var renderProtoView = createRenderProtoView(); var renderProtoView = createRenderProtoView();
var expectedProtoView = createProtoView(); var expectedProtoView = createProtoView();
var compiler = createCompiler([renderProtoView], [expectedProtoView]); var compiler = createCompiler([renderProtoView], [expectedProtoView]);
compiler.compile(MainComponent).then( (protoView) => { compiler.compile(MainComponent).then( (protoViewRef) => {
expect(protoView).toBe(expectedProtoView); expect(internalProtoView(protoViewRef)).toBe(expectedProtoView);
return compiler.compile(MainComponent); return compiler.compile(MainComponent);
}).then( (protoView) => { }).then( (protoViewRef) => {
expect(protoView).toBe(expectedProtoView); expect(internalProtoView(protoViewRef)).toBe(expectedProtoView);
async.done(); async.done();
}); });
})); }));
@ -355,9 +356,9 @@ export function main() {
PromiseWrapper.all([ PromiseWrapper.all([
compiler.compile(MainComponent), compiler.compile(MainComponent),
compiler.compile(MainComponent) compiler.compile(MainComponent)
]).then( (protoViews) => { ]).then( (protoViewRefs) => {
expect(protoViews[0]).toBe(expectedProtoView); expect(internalProtoView(protoViewRefs[0])).toBe(expectedProtoView);
expect(protoViews[1]).toBe(expectedProtoView); expect(internalProtoView(protoViewRefs[1])).toBe(expectedProtoView);
async.done(); async.done();
}); });
})); }));
@ -373,8 +374,8 @@ export function main() {
])], ])],
[mainProtoView] [mainProtoView]
); );
compiler.compile(MainComponent).then( (protoView) => { compiler.compile(MainComponent).then( (protoViewRef) => {
expect(protoView).toBe(mainProtoView); expect(internalProtoView(protoViewRef)).toBe(mainProtoView);
expect(mainProtoView.elementBinders[0].nestedProtoView).toBe(mainProtoView); expect(mainProtoView.elementBinders[0].nestedProtoView).toBe(mainProtoView);
async.done(); async.done();
}); });
@ -397,8 +398,8 @@ export function main() {
], ],
[rootProtoView, mainProtoView] [rootProtoView, mainProtoView]
); );
compiler.compileInHost(MainComponent).then( (protoView) => { compiler.compileInHost(MainComponent).then( (protoViewRef) => {
expect(protoView).toBe(rootProtoView); expect(internalProtoView(protoViewRef)).toBe(rootProtoView);
expect(rootProtoView.elementBinders[0].nestedProtoView).toBe(mainProtoView); expect(rootProtoView.elementBinders[0].nestedProtoView).toBe(mainProtoView);
async.done(); async.done();
}); });
@ -416,8 +417,8 @@ export function main() {
[], [],
[mainProtoView] [mainProtoView]
); );
compiler.compile(MainComponent).then( (protoView) => { compiler.compile(MainComponent).then( (protoViewRef) => {
expect(protoView).toBe(mainProtoView); expect(internalProtoView(protoViewRef)).toBe(mainProtoView);
expect(renderer.spy('createImperativeComponentProtoView')).toHaveBeenCalledWith('some-renderer'); expect(renderer.spy('createImperativeComponentProtoView')).toHaveBeenCalledWith('some-renderer');
async.done(); async.done();
}); });

View File

@ -19,7 +19,7 @@ import {TestBed} from 'angular2/src/test_lib/test_bed';
import {Decorator, Component, Viewport, DynamicComponent} from 'angular2/src/core/annotations/annotations'; import {Decorator, Component, Viewport, DynamicComponent} from 'angular2/src/core/annotations/annotations';
import {View} from 'angular2/src/core/annotations/view'; import {View} from 'angular2/src/core/annotations/view';
import {DynamicComponentLoader} from 'angular2/src/core/compiler/dynamic_component_loader'; import {DynamicComponentLoader} from 'angular2/src/core/compiler/dynamic_component_loader';
import {ElementRef} from 'angular2/src/core/compiler/element_injector'; import {ElementRef} from 'angular2/src/core/compiler/element_ref';
import {If} from 'angular2/src/directives/if'; import {If} from 'angular2/src/directives/if';
import {DirectDomRenderer} from 'angular2/src/render/dom/direct_dom_renderer'; import {DirectDomRenderer} from 'angular2/src/render/dom/direct_dom_renderer';
import {DOM} from 'angular2/src/dom/dom_adapter'; import {DOM} from 'angular2/src/dom/dom_adapter';
@ -207,7 +207,7 @@ class ImperativeViewComponentUsingNgComponent {
constructor(self:ElementRef, dynamicComponentLoader:DynamicComponentLoader, renderer:DirectDomRenderer) { constructor(self:ElementRef, dynamicComponentLoader:DynamicComponentLoader, renderer:DirectDomRenderer) {
var div = el('<div></div>'); var div = el('<div></div>');
renderer.setImperativeComponentRootNodes(self.hostView.render, self.boundElementIndex, [div]); renderer.setImperativeComponentRootNodes(self.parentView.render, self.boundElementIndex, [div]);
this.done = dynamicComponentLoader.loadIntoNewLocation(ChildComp, self, div, null); this.done = dynamicComponentLoader.loadIntoNewLocation(ChildComp, self, div, null);
} }
} }

View File

@ -1,7 +1,7 @@
import {describe, ddescribe, it, iit, xit, xdescribe, expect, beforeEach, SpyObject, proxy, el} from 'angular2/test_lib'; import {describe, ddescribe, it, iit, xit, xdescribe, expect, beforeEach, SpyObject, proxy, el} from 'angular2/test_lib';
import {isBlank, isPresent, IMPLEMENTS} from 'angular2/src/facade/lang'; import {isBlank, isPresent, IMPLEMENTS} from 'angular2/src/facade/lang';
import {ListWrapper, MapWrapper, List, StringMapWrapper, iterateListLike} from 'angular2/src/facade/collection'; import {ListWrapper, MapWrapper, List, StringMapWrapper, iterateListLike} from 'angular2/src/facade/collection';
import {ProtoElementInjector, PreBuiltObjects, DirectiveBinding, TreeNode, ElementRef} import {ProtoElementInjector, PreBuiltObjects, DirectiveBinding, TreeNode}
from 'angular2/src/core/compiler/element_injector'; from 'angular2/src/core/compiler/element_injector';
import {Parent, Ancestor} from 'angular2/src/core/annotations/visibility'; import {Parent, Ancestor} from 'angular2/src/core/annotations/visibility';
import {Attribute, Query} from 'angular2/src/core/annotations/di'; import {Attribute, Query} from 'angular2/src/core/annotations/di';
@ -9,7 +9,8 @@ import {onDestroy} from 'angular2/src/core/annotations/annotations';
import {Optional, Injector, Inject, bind} from 'angular2/di'; import {Optional, Injector, Inject, bind} from 'angular2/di';
import {AppProtoView, AppView} from 'angular2/src/core/compiler/view'; import {AppProtoView, AppView} from 'angular2/src/core/compiler/view';
import {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref'; import {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref';
import {NgElement} from 'angular2/src/core/compiler/ng_element'; import {ProtoViewRef} from 'angular2/src/core/compiler/view_ref';
import {ElementRef} from 'angular2/src/core/compiler/element_ref';
import {Directive} from 'angular2/src/core/annotations/annotations'; import {Directive} from 'angular2/src/core/annotations/annotations';
import {DynamicChangeDetector, ChangeDetectorRef, Parser, Lexer} from 'angular2/change_detection'; import {DynamicChangeDetector, ChangeDetectorRef, Parser, Lexer} from 'angular2/change_detection';
import {ViewRef, Renderer} from 'angular2/src/render/api'; import {ViewRef, Renderer} from 'angular2/src/render/api';
@ -135,6 +136,13 @@ class NeedsViewContainer {
} }
} }
class NeedsProtoViewRef {
protoViewRef;
constructor(ref:ProtoViewRef) {
this.protoViewRef = ref;
}
}
class NeedsChangeDetectorRef { class NeedsChangeDetectorRef {
changeDetectorRef; changeDetectorRef;
constructor(cdr:ChangeDetectorRef) { constructor(cdr:ChangeDetectorRef) {
@ -150,13 +158,6 @@ class B_Needs_A {
constructor(dep){} constructor(dep){}
} }
class NeedsView {
view:any;
constructor(@Inject(AppView) view) {
this.view = view;
}
}
class DirectiveWithDestroy { class DirectiveWithDestroy {
onDestroyCounter:number; onDestroyCounter:number;
@ -181,7 +182,7 @@ class TestNode extends TreeNode {
} }
export function main() { export function main() {
var defaultPreBuiltObjects = new PreBuiltObjects(null, null, null, null); var defaultPreBuiltObjects = new PreBuiltObjects(null, null, null);
var appInjector = Injector.resolveAndCreate([]); var appInjector = Injector.resolveAndCreate([]);
function humanize(tree, names:List) { function humanize(tree, names:List) {
@ -453,10 +454,10 @@ export function main() {
}); });
it("should instantiate directives that depend on pre built objects", function () { it("should instantiate directives that depend on pre built objects", function () {
var view = new DummyView(); var protoView = new AppProtoView(null, null);
var inj = injector([NeedsView], null, null, new PreBuiltObjects(null, view, null, null)); var inj = injector([NeedsProtoViewRef], null, null, new PreBuiltObjects(null, null, protoView));
expect(inj.get(NeedsView).view).toBe(view); expect(inj.get(NeedsProtoViewRef).protoViewRef).toEqual(new ProtoViewRef(protoView));
}); });
it("should instantiate directives that depend on the containing component", function () { it("should instantiate directives that depend on the containing component", function () {
@ -577,29 +578,6 @@ export function main() {
}); });
}); });
describe("pre built objects", function () {
it("should return view", function () {
var view = new DummyView();
var inj = injector([], null, null, new PreBuiltObjects(null, view, null, null));
expect(inj.get(AppView)).toEqual(view);
});
it("should return element", function () {
var element = new NgElement(null, null);
var inj = injector([], null, null, new PreBuiltObjects(null, null, element, null));
expect(inj.get(NgElement)).toEqual(element);
});
it("should return default ProtoView", function () {
var protoView = new AppProtoView(null, null);
var inj = injector([], null, null, new PreBuiltObjects(null, null, null, protoView));
expect(inj.get(AppProtoView)).toEqual(protoView);
});
});
describe("dynamicallyCreateComponent", () => { describe("dynamicallyCreateComponent", () => {
it("should create a component dynamically", () => { it("should create a component dynamically", () => {
var inj = injector([]); var inj = injector([]);
@ -700,7 +678,7 @@ export function main() {
}); });
}); });
describe("ElementRef", () => { describe("refs", () => {
it("should inject ElementRef", () => { it("should inject ElementRef", () => {
var inj = injector([NeedsElementRef]); var inj = injector([NeedsElementRef]);
expect(inj.get(NeedsElementRef).elementRef).toBeAnInstanceOf(ElementRef); expect(inj.get(NeedsElementRef).elementRef).toBeAnInstanceOf(ElementRef);
@ -712,7 +690,7 @@ export function main() {
var childView = new DummyView(); var childView = new DummyView();
childView.changeDetector = cd; childView.changeDetector = cd;
view.componentChildViews = [childView]; view.componentChildViews = [childView];
var inj = injector([NeedsChangeDetectorRef], null, null, new PreBuiltObjects(null, view, null, null)); var inj = injector([NeedsChangeDetectorRef], null, null, new PreBuiltObjects(null, view, null));
expect(inj.get(NeedsChangeDetectorRef).changeDetectorRef).toBe(cd.ref); expect(inj.get(NeedsChangeDetectorRef).changeDetectorRef).toBe(cd.ref);
}); });
@ -721,6 +699,13 @@ export function main() {
var inj = injector([NeedsViewContainer]); var inj = injector([NeedsViewContainer]);
expect(inj.get(NeedsViewContainer).viewContainer).toBeAnInstanceOf(ViewContainerRef); expect(inj.get(NeedsViewContainer).viewContainer).toBeAnInstanceOf(ViewContainerRef);
}); });
it("should inject ProtoViewRef", function () {
var protoView = new AppProtoView(null, null);
var inj = injector([NeedsProtoViewRef], null, null, new PreBuiltObjects(null, null, protoView));
expect(inj.get(NeedsProtoViewRef).protoViewRef).toEqual(new ProtoViewRef(protoView));
});
}); });
describe('directive queries', () => { describe('directive queries', () => {

View File

@ -33,7 +33,7 @@ import {If} from 'angular2/src/directives/if';
import {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref'; import {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref';
import {Compiler} from 'angular2/src/core/compiler/compiler'; import {Compiler} from 'angular2/src/core/compiler/compiler';
import {ElementRef} from 'angular2/src/core/compiler/element_injector'; import {ElementRef} from 'angular2/src/core/compiler/element_ref';
import {DirectDomRenderer} from 'angular2/src/render/dom/direct_dom_renderer'; import {DirectDomRenderer} from 'angular2/src/render/dom/direct_dom_renderer';
@ -851,7 +851,7 @@ class SimpleImperativeViewComponent {
done; done;
constructor(self:ElementRef, renderer:DirectDomRenderer) { constructor(self:ElementRef, renderer:DirectDomRenderer) {
renderer.setImperativeComponentRootNodes(self.hostView.render, self.boundElementIndex, [el('hello imp view')]); renderer.setImperativeComponentRootNodes(self.parentView.render, self.boundElementIndex, [el('hello imp view')]);
} }
} }

View File

@ -18,8 +18,9 @@ import {
import {MapWrapper} from 'angular2/src/facade/collection'; import {MapWrapper} from 'angular2/src/facade/collection';
import {IMPLEMENTS, isBlank, isPresent} from 'angular2/src/facade/lang'; import {IMPLEMENTS, isBlank, isPresent} from 'angular2/src/facade/lang';
import {ElementRef} from 'angular2/src/core/compiler/element_injector';
import {AppView, AppProtoView, AppViewContainer} from 'angular2/src/core/compiler/view'; import {AppView, AppProtoView, AppViewContainer} from 'angular2/src/core/compiler/view';
import {ProtoViewRef, ViewRef, internalView} from 'angular2/src/core/compiler/view_ref';
import {ElementRef} from 'angular2/src/core/compiler/element_ref';
import {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref'; import {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref';
import {AppViewManager} from 'angular2/src/core/compiler/view_manager'; import {AppViewManager} from 'angular2/src/core/compiler/view_manager';
@ -31,6 +32,10 @@ export function main() {
var view; var view;
var viewManager; var viewManager;
function wrapView(view:AppView):ViewRef {
return new ViewRef(view);
}
function createProtoView() { function createProtoView() {
return new AppProtoView(null, null); return new AppProtoView(null, null);
} }
@ -47,7 +52,7 @@ export function main() {
viewManager = new AppViewManagerSpy(); viewManager = new AppViewManagerSpy();
view = createView(); view = createView();
view.viewContainers = [null]; view.viewContainers = [null];
location = new ElementRef(null, view, 0, null, null, null); location = new ElementRef(wrapView(view), 0);
}); });
it('should return a 0 length if there is no underlying ViewContainerRef', () => { it('should return a 0 length if there is no underlying ViewContainerRef', () => {

View File

@ -19,9 +19,11 @@ import {IMPLEMENTS, isBlank, isPresent} from 'angular2/src/facade/lang';
import {MapWrapper, ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection'; import {MapWrapper, ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
import {AppProtoView, AppView, AppViewContainer} from 'angular2/src/core/compiler/view'; import {AppProtoView, AppView, AppViewContainer} from 'angular2/src/core/compiler/view';
import {Renderer, ViewRef, ProtoViewRef, RenderViewContainerRef} from 'angular2/src/render/api'; import {ProtoViewRef, ViewRef, internalView} from 'angular2/src/core/compiler/view_ref';
import {ElementRef} from 'angular2/src/core/compiler/element_ref';
import {Renderer, RenderViewRef, RenderProtoViewRef, RenderViewContainerRef} from 'angular2/src/render/api';
import {ElementBinder} from 'angular2/src/core/compiler/element_binder'; import {ElementBinder} from 'angular2/src/core/compiler/element_binder';
import {DirectiveBinding, ElementInjector, ElementRef} from 'angular2/src/core/compiler/element_injector'; import {DirectiveBinding, ElementInjector} from 'angular2/src/core/compiler/element_injector';
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader'; import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
import {Component} from 'angular2/src/core/annotations/annotations'; import {Component} from 'angular2/src/core/annotations/annotations';
import {AppViewManager} from 'angular2/src/core/compiler/view_manager'; import {AppViewManager} from 'angular2/src/core/compiler/view_manager';
@ -40,8 +42,16 @@ export function main() {
var createdViews; var createdViews;
var createdRenderViews; var createdRenderViews;
function wrapPv(protoView:AppProtoView):ProtoViewRef {
return new ProtoViewRef(protoView);
}
function wrapView(view:AppView):ViewRef {
return new ViewRef(view);
}
function elementRef(parentView, boundElementIndex) { function elementRef(parentView, boundElementIndex) {
return new ElementRef(null, parentView, boundElementIndex, null, null, null); return new ElementRef(parentView, boundElementIndex);
} }
function createDirectiveBinding(type) { function createDirectiveBinding(type) {
@ -130,7 +140,7 @@ export function main() {
var createRenderViewRefs = function(renderPvRef) { var createRenderViewRefs = function(renderPvRef) {
var res = []; var res = [];
for (var i=0; i<renderPvRef.nestedComponentCount+1; i++) { for (var i=0; i<renderPvRef.nestedComponentCount+1; i++) {
var renderViewRef = new ViewRef(); var renderViewRef = new RenderViewRef();
ListWrapper.push(res, renderViewRef); ListWrapper.push(res, renderViewRef);
ListWrapper.push(createdRenderViews, renderViewRef); ListWrapper.push(createdRenderViews, renderViewRef);
} }
@ -155,13 +165,13 @@ export function main() {
hostView = createView(createProtoView( hostView = createView(createProtoView(
[createComponentElBinder(null)] [createComponentElBinder(null)]
)); ));
hostView.render = new ViewRef(); hostView.render = new RenderViewRef();
componentProtoView = createProtoView(); componentProtoView = createProtoView();
}); });
it('should create the view', () => { it('should create the view', () => {
expect( expect(
manager.createDynamicComponentView(elementRef(hostView, 0), componentProtoView, null, null) internalView(manager.createDynamicComponentView(elementRef(wrapView(hostView), 0), wrapPv(componentProtoView), null, null))
).toBe(createdViews[0]); ).toBe(createdViews[0]);
expect(createdViews[0].proto).toBe(componentProtoView); expect(createdViews[0].proto).toBe(componentProtoView);
}); });
@ -173,36 +183,36 @@ export function main() {
return createdView; return createdView;
}); });
expect( expect(
manager.createDynamicComponentView(elementRef(hostView, 0), componentProtoView, null, null) internalView(manager.createDynamicComponentView(elementRef(wrapView(hostView), 0), wrapPv(componentProtoView), null, null))
).toBe(createdView); ).toBe(createdView);
expect(utils.spy('createView')).not.toHaveBeenCalled(); expect(utils.spy('createView')).not.toHaveBeenCalled();
}); });
it('should attach the view', () => { it('should attach the view', () => {
manager.createDynamicComponentView(elementRef(hostView, 0), componentProtoView, null, null) manager.createDynamicComponentView(elementRef(wrapView(hostView), 0), wrapPv(componentProtoView), null, null)
expect(utils.spy('attachComponentView')).toHaveBeenCalledWith(hostView, 0, createdViews[0]); expect(utils.spy('attachComponentView')).toHaveBeenCalledWith(hostView, 0, createdViews[0]);
}); });
it('should hydrate the dynamic component', () => { it('should hydrate the dynamic component', () => {
var injector = new Injector([], null, false); var injector = new Injector([], null, false);
var componentBinding = bind(SomeComponent).toClass(SomeComponent); var componentBinding = bind(SomeComponent).toClass(SomeComponent);
manager.createDynamicComponentView(elementRef(hostView, 0), componentProtoView, componentBinding, injector); manager.createDynamicComponentView(elementRef(wrapView(hostView), 0), wrapPv(componentProtoView), componentBinding, injector);
expect(utils.spy('hydrateDynamicComponentInElementInjector')).toHaveBeenCalledWith(hostView, 0, componentBinding, injector); expect(utils.spy('hydrateDynamicComponentInElementInjector')).toHaveBeenCalledWith(hostView, 0, componentBinding, injector);
}); });
it('should hydrate the view', () => { it('should hydrate the view', () => {
manager.createDynamicComponentView(elementRef(hostView, 0), componentProtoView, null, null); manager.createDynamicComponentView(elementRef(wrapView(hostView), 0), wrapPv(componentProtoView), null, null);
expect(utils.spy('hydrateComponentView')).toHaveBeenCalledWith(hostView, 0); expect(utils.spy('hydrateComponentView')).toHaveBeenCalledWith(hostView, 0);
}); });
it('should create and set the render view', () => { it('should create and set the render view', () => {
manager.createDynamicComponentView(elementRef(hostView, 0), componentProtoView, null, null); manager.createDynamicComponentView(elementRef(wrapView(hostView), 0), wrapPv(componentProtoView), null, null);
expect(renderer.spy('createDynamicComponentView')).toHaveBeenCalledWith(hostView.render, 0, componentProtoView.render); expect(renderer.spy('createDynamicComponentView')).toHaveBeenCalledWith(hostView.render, 0, componentProtoView.render);
expect(createdViews[0].render).toBe(createdRenderViews[0]); expect(createdViews[0].render).toBe(createdRenderViews[0]);
}); });
it('should set the event dispatcher', () => { it('should set the event dispatcher', () => {
manager.createDynamicComponentView(elementRef(hostView, 0), componentProtoView, null, null); manager.createDynamicComponentView(elementRef(wrapView(hostView), 0), wrapPv(componentProtoView), null, null);
var cmpView = createdViews[0]; var cmpView = createdViews[0];
expect(renderer.spy('setEventDispatcher')).toHaveBeenCalledWith(cmpView.render, cmpView); expect(renderer.spy('setEventDispatcher')).toHaveBeenCalledWith(cmpView.render, cmpView);
}); });
@ -216,7 +226,7 @@ export function main() {
)); ));
var componentProtoView = createProtoView(); var componentProtoView = createProtoView();
expect( expect(
() => manager.createDynamicComponentView(elementRef(hostView, 0), componentProtoView, null, null) () => manager.createDynamicComponentView(elementRef(wrapView(hostView), 0), wrapPv(componentProtoView), null, null)
).toThrowError('There is no dynamic component directive at element 0'); ).toThrowError('There is no dynamic component directive at element 0');
}); });
@ -226,7 +236,7 @@ export function main() {
)); ));
var componentProtoView = createProtoView(); var componentProtoView = createProtoView();
expect( expect(
() => manager.createDynamicComponentView(elementRef(hostView, 0), componentProtoView, null, null) () => manager.createDynamicComponentView(elementRef(wrapView(hostView), 0), wrapPv(componentProtoView), null, null)
).toThrowError('There is no dynamic component directive at element 0'); ).toThrowError('There is no dynamic component directive at element 0');
}); });
@ -246,7 +256,7 @@ export function main() {
hostView = createView(createProtoView( hostView = createView(createProtoView(
[createComponentElBinder(null)] [createComponentElBinder(null)]
)); ));
hostView.render = new ViewRef(); hostView.render = new RenderViewRef();
nestedProtoView = createProtoView(); nestedProtoView = createProtoView();
componentProtoView = createProtoView([ componentProtoView = createProtoView([
createComponentElBinder(nestedProtoView) createComponentElBinder(nestedProtoView)
@ -254,23 +264,23 @@ export function main() {
}); });
it('should create the view', () => { it('should create the view', () => {
manager.createDynamicComponentView(elementRef(hostView, 0), componentProtoView, null, null); manager.createDynamicComponentView(elementRef(wrapView(hostView), 0), wrapPv(componentProtoView), null, null);
expect(createdViews[0].proto).toBe(componentProtoView); expect(createdViews[0].proto).toBe(componentProtoView);
expect(createdViews[1].proto).toBe(nestedProtoView); expect(createdViews[1].proto).toBe(nestedProtoView);
}); });
it('should hydrate the view', () => { it('should hydrate the view', () => {
manager.createDynamicComponentView(elementRef(hostView, 0), componentProtoView, null, null); manager.createDynamicComponentView(elementRef(wrapView(hostView), 0), wrapPv(componentProtoView), null, null);
expect(utils.spy('hydrateComponentView')).toHaveBeenCalledWith(createdViews[0], 0); expect(utils.spy('hydrateComponentView')).toHaveBeenCalledWith(createdViews[0], 0);
}); });
it('should set the render view', () => { it('should set the render view', () => {
manager.createDynamicComponentView(elementRef(hostView, 0), componentProtoView, null, null); manager.createDynamicComponentView(elementRef(wrapView(hostView), 0), wrapPv(componentProtoView), null, null);
expect(createdViews[1].render).toBe(createdRenderViews[1]) expect(createdViews[1].render).toBe(createdRenderViews[1])
}); });
it('should set the event dispatcher', () => { it('should set the event dispatcher', () => {
manager.createDynamicComponentView(elementRef(hostView, 0), componentProtoView, null, null); manager.createDynamicComponentView(elementRef(wrapView(hostView), 0), wrapPv(componentProtoView), null, null);
var cmpView = createdViews[1]; var cmpView = createdViews[1];
expect(renderer.spy('setEventDispatcher')).toHaveBeenCalledWith(cmpView.render, cmpView); expect(renderer.spy('setEventDispatcher')).toHaveBeenCalledWith(cmpView.render, cmpView);
}); });
@ -299,7 +309,7 @@ export function main() {
)); ));
parentView = createView(); parentView = createView();
utils.attachComponentView(parentHostView, 0, parentView); utils.attachComponentView(parentHostView, 0, parentView);
parentView.render = new ViewRef(); parentView.render = new RenderViewRef();
hostProtoView = createProtoView( hostProtoView = createProtoView(
[createComponentElBinder(null)] [createComponentElBinder(null)]
); );
@ -307,26 +317,26 @@ export function main() {
it('should create the view', () => { it('should create the view', () => {
expect( expect(
manager.createInPlaceHostView(elementRef(parentHostView, 0), null, hostProtoView, null) internalView(manager.createInPlaceHostView(elementRef(wrapView(parentHostView), 0), null, wrapPv(hostProtoView), null))
).toBe(createdViews[0]); ).toBe(createdViews[0]);
expect(createdViews[0].proto).toBe(hostProtoView); expect(createdViews[0].proto).toBe(hostProtoView);
}); });
it('should attachAndHydrate the view', () => { it('should attachAndHydrate the view', () => {
var injector = new Injector([], null, false); var injector = new Injector([], null, false);
manager.createInPlaceHostView(elementRef(parentHostView, 0), null, hostProtoView, injector); manager.createInPlaceHostView(elementRef(wrapView(parentHostView), 0), null, wrapPv(hostProtoView), injector);
expect(utils.spy('attachAndHydrateInPlaceHostView')).toHaveBeenCalledWith(parentHostView, 0, createdViews[0], injector); expect(utils.spy('attachAndHydrateInPlaceHostView')).toHaveBeenCalledWith(parentHostView, 0, createdViews[0], injector);
}); });
it('should create and set the render view', () => { it('should create and set the render view', () => {
var elementOrSelector = 'someSelector'; var elementOrSelector = 'someSelector';
manager.createInPlaceHostView(elementRef(parentHostView, 0), elementOrSelector, hostProtoView, null) manager.createInPlaceHostView(elementRef(wrapView(parentHostView), 0), elementOrSelector, wrapPv(hostProtoView), null)
expect(renderer.spy('createInPlaceHostView')).toHaveBeenCalledWith(parentView.render, elementOrSelector, hostProtoView.render); expect(renderer.spy('createInPlaceHostView')).toHaveBeenCalledWith(parentView.render, elementOrSelector, hostProtoView.render);
expect(createdViews[0].render).toBe(createdRenderViews[0]); expect(createdViews[0].render).toBe(createdRenderViews[0]);
}); });
it('should set the event dispatcher', () => { it('should set the event dispatcher', () => {
manager.createInPlaceHostView(elementRef(parentHostView, 0), null, hostProtoView, null); manager.createInPlaceHostView(elementRef(wrapView(parentHostView), 0), null, wrapPv(hostProtoView), null);
var cmpView = createdViews[0]; var cmpView = createdViews[0];
expect(renderer.spy('setEventDispatcher')).toHaveBeenCalledWith(cmpView.render, cmpView); expect(renderer.spy('setEventDispatcher')).toHaveBeenCalledWith(cmpView.render, cmpView);
}); });
@ -344,32 +354,32 @@ export function main() {
)); ));
parentView = createView(); parentView = createView();
utils.attachComponentView(parentHostView, 0, parentView); utils.attachComponentView(parentHostView, 0, parentView);
parentView.render = new ViewRef(); parentView.render = new RenderViewRef();
hostProtoView = createProtoView( hostProtoView = createProtoView(
[createComponentElBinder(null)] [createComponentElBinder(null)]
); );
hostView = manager.createInPlaceHostView(elementRef(parentHostView, 0), null, hostProtoView, null); hostView = internalView(manager.createInPlaceHostView(elementRef(wrapView(parentHostView), 0), null, wrapPv(hostProtoView), null));
hostRenderViewRef = hostView.render; hostRenderViewRef = hostView.render;
}); });
it('should dehydrate', () => { it('should dehydrate', () => {
manager.destroyInPlaceHostView(elementRef(parentHostView, 0), hostView); manager.destroyInPlaceHostView(elementRef(wrapView(parentHostView), 0), wrapView(hostView));
expect(utils.spy('detachInPlaceHostView')).toHaveBeenCalledWith(parentView, hostView); expect(utils.spy('detachInPlaceHostView')).toHaveBeenCalledWith(parentView, hostView);
}); });
it('should detach', () => { it('should detach', () => {
manager.destroyInPlaceHostView(elementRef(parentHostView, 0), hostView); manager.destroyInPlaceHostView(elementRef(wrapView(parentHostView), 0), wrapView(hostView));
expect(utils.spy('dehydrateView')).toHaveBeenCalledWith(hostView); expect(utils.spy('dehydrateView')).toHaveBeenCalledWith(hostView);
}); });
it('should destroy and clear the render view', () => { it('should destroy and clear the render view', () => {
manager.destroyInPlaceHostView(elementRef(parentHostView, 0), hostView); manager.destroyInPlaceHostView(elementRef(wrapView(parentHostView), 0), wrapView(hostView));
expect(renderer.spy('destroyInPlaceHostView')).toHaveBeenCalledWith(parentView.render, hostRenderViewRef); expect(renderer.spy('destroyInPlaceHostView')).toHaveBeenCalledWith(parentView.render, hostRenderViewRef);
expect(hostView.render).toBe(null); expect(hostView.render).toBe(null);
}); });
it('should return the view to the pool', () => { it('should return the view to the pool', () => {
manager.destroyInPlaceHostView(elementRef(parentHostView, 0), hostView); manager.destroyInPlaceHostView(elementRef(wrapView(parentHostView), 0), wrapView(hostView));
expect(viewPool.spy('returnView')).toHaveBeenCalledWith(hostView); expect(viewPool.spy('returnView')).toHaveBeenCalledWith(hostView);
}); });
}); });
@ -388,42 +398,42 @@ export function main() {
parentView = createView(createProtoView( parentView = createView(createProtoView(
[createEmptyElBinder()] [createEmptyElBinder()]
)); ));
parentView.render = new ViewRef(); parentView.render = new RenderViewRef();
childProtoView = createProtoView(); childProtoView = createProtoView();
}); });
it('should create a ViewContainerRef if not yet existing', () => { it('should create a ViewContainerRef if not yet existing', () => {
manager.createViewInContainer(elementRef(parentView, 0), 0, childProtoView, null); manager.createViewInContainer(elementRef(wrapView(parentView), 0), 0, wrapPv(childProtoView), null);
expect(parentView.viewContainers[0]).toBeTruthy(); expect(parentView.viewContainers[0]).toBeTruthy();
}); });
it('should create the view', () => { it('should create the view', () => {
expect( expect(
manager.createViewInContainer(elementRef(parentView, 0), 0, childProtoView, null) internalView(manager.createViewInContainer(elementRef(wrapView(parentView), 0), 0, wrapPv(childProtoView), null))
).toBe(createdViews[0]); ).toBe(createdViews[0]);
expect(createdViews[0].proto).toBe(childProtoView); expect(createdViews[0].proto).toBe(childProtoView);
}); });
it('should attach the view', () => { it('should attach the view', () => {
manager.createViewInContainer(elementRef(parentView, 0), 0, childProtoView, null) manager.createViewInContainer(elementRef(wrapView(parentView), 0), 0, wrapPv(childProtoView), null)
expect(utils.spy('attachViewInContainer')).toHaveBeenCalledWith(parentView, 0, 0, createdViews[0]); expect(utils.spy('attachViewInContainer')).toHaveBeenCalledWith(parentView, 0, 0, createdViews[0]);
}); });
it('should hydrate the view', () => { it('should hydrate the view', () => {
var injector = new Injector([], null, false); var injector = new Injector([], null, false);
manager.createViewInContainer(elementRef(parentView, 0), 0, childProtoView, injector); manager.createViewInContainer(elementRef(wrapView(parentView), 0), 0, wrapPv(childProtoView), injector);
expect(utils.spy('hydrateViewInContainer')).toHaveBeenCalledWith(parentView, 0, 0, injector); expect(utils.spy('hydrateViewInContainer')).toHaveBeenCalledWith(parentView, 0, 0, injector);
}); });
it('should create and set the render view', () => { it('should create and set the render view', () => {
manager.createViewInContainer(elementRef(parentView, 0), 0, childProtoView, null); manager.createViewInContainer(elementRef(wrapView(parentView), 0), 0, wrapPv(childProtoView), null);
expect(renderer.spy('createViewInContainer')).toHaveBeenCalledWith( expect(renderer.spy('createViewInContainer')).toHaveBeenCalledWith(
new RenderViewContainerRef(parentView.render, 0), 0, childProtoView.render); new RenderViewContainerRef(parentView.render, 0), 0, childProtoView.render);
expect(createdViews[0].render).toBe(createdRenderViews[0]); expect(createdViews[0].render).toBe(createdRenderViews[0]);
}); });
it('should set the event dispatcher', () => { it('should set the event dispatcher', () => {
manager.createViewInContainer(elementRef(parentView, 0), 0, childProtoView, null); manager.createViewInContainer(elementRef(wrapView(parentView), 0), 0, wrapPv(childProtoView), null);
var childView = createdViews[0]; var childView = createdViews[0];
expect(renderer.spy('setEventDispatcher')).toHaveBeenCalledWith(childView.render, childView); expect(renderer.spy('setEventDispatcher')).toHaveBeenCalledWith(childView.render, childView);
}); });
@ -439,29 +449,29 @@ export function main() {
parentView = createView(createProtoView( parentView = createView(createProtoView(
[createEmptyElBinder()] [createEmptyElBinder()]
)); ));
parentView.render = new ViewRef(); parentView.render = new RenderViewRef();
childProtoView = createProtoView(); childProtoView = createProtoView();
childView = manager.createViewInContainer(elementRef(parentView, 0), 0, childProtoView, null); childView = internalView(manager.createViewInContainer(elementRef(wrapView(parentView), 0), 0, wrapPv(childProtoView), null));
}); });
it('should dehydrate', () => { it('should dehydrate', () => {
manager.destroyViewInContainer(elementRef(parentView, 0), 0); manager.destroyViewInContainer(elementRef(wrapView(parentView), 0), 0);
expect(utils.spy('dehydrateView')).toHaveBeenCalledWith(parentView.viewContainers[0].views[0]); expect(utils.spy('dehydrateView')).toHaveBeenCalledWith(parentView.viewContainers[0].views[0]);
}); });
it('should detach', () => { it('should detach', () => {
manager.destroyViewInContainer(elementRef(parentView, 0), 0); manager.destroyViewInContainer(elementRef(wrapView(parentView), 0), 0);
expect(utils.spy('detachViewInContainer')).toHaveBeenCalledWith(parentView, 0, 0); expect(utils.spy('detachViewInContainer')).toHaveBeenCalledWith(parentView, 0, 0);
}); });
it('should destroy and clear the render view', () => { it('should destroy and clear the render view', () => {
manager.destroyViewInContainer(elementRef(parentView, 0), 0); manager.destroyViewInContainer(elementRef(wrapView(parentView), 0), 0);
expect(renderer.spy('destroyViewInContainer')).toHaveBeenCalledWith(new RenderViewContainerRef(parentView.render, 0), 0); expect(renderer.spy('destroyViewInContainer')).toHaveBeenCalledWith(new RenderViewContainerRef(parentView.render, 0), 0);
expect(childView.render).toBe(null); expect(childView.render).toBe(null);
}); });
it('should return the view to the pool', () => { it('should return the view to the pool', () => {
manager.destroyViewInContainer(elementRef(parentView, 0), 0); manager.destroyViewInContainer(elementRef(wrapView(parentView), 0), 0);
expect(viewPool.spy('returnView')).toHaveBeenCalledWith(childView); expect(viewPool.spy('returnView')).toHaveBeenCalledWith(childView);
}); });
}); });
@ -472,29 +482,29 @@ export function main() {
parentView = createView(createProtoView( parentView = createView(createProtoView(
[createEmptyElBinder()] [createEmptyElBinder()]
)); ));
parentView.render = new ViewRef(); parentView.render = new RenderViewRef();
childProtoView = createProtoView(); childProtoView = createProtoView();
childView = manager.createViewInContainer(elementRef(parentView, 0), 0, childProtoView, null); childView = internalView(manager.createViewInContainer(elementRef(wrapView(parentView), 0), 0, wrapPv(childProtoView), null));
}); });
it('should dehydrate', () => { it('should dehydrate', () => {
manager.destroyInPlaceHostView(null, parentView); manager.destroyInPlaceHostView(null, wrapView(parentView));
expect(utils.spy('dehydrateView')).toHaveBeenCalledWith(parentView.viewContainers[0].views[0]); expect(utils.spy('dehydrateView')).toHaveBeenCalledWith(parentView.viewContainers[0].views[0]);
}); });
it('should detach', () => { it('should detach', () => {
manager.destroyInPlaceHostView(null, parentView); manager.destroyInPlaceHostView(null, wrapView(parentView));
expect(utils.spy('detachViewInContainer')).toHaveBeenCalledWith(parentView, 0, 0); expect(utils.spy('detachViewInContainer')).toHaveBeenCalledWith(parentView, 0, 0);
}); });
it('should not destroy but clear the render view', () => { it('should not destroy but clear the render view', () => {
manager.destroyInPlaceHostView(null, parentView); manager.destroyInPlaceHostView(null, wrapView(parentView));
expect(renderer.spy('destroyViewInContainer')).not.toHaveBeenCalled(); expect(renderer.spy('destroyViewInContainer')).not.toHaveBeenCalled();
expect(childView.render).toBe(null); expect(childView.render).toBe(null);
}); });
it('should return the view to the pool', () => { it('should return the view to the pool', () => {
manager.destroyInPlaceHostView(null, parentView); manager.destroyInPlaceHostView(null, wrapView(parentView));
expect(viewPool.spy('returnView')).toHaveBeenCalledWith(childView); expect(viewPool.spy('returnView')).toHaveBeenCalledWith(childView);
}); });
@ -513,7 +523,7 @@ export function main() {
}); });
} }
class MockProtoViewRef extends ProtoViewRef { class MockProtoViewRef extends RenderProtoViewRef {
nestedComponentCount:number; nestedComponentCount:number;
constructor(nestedComponentCount:number) { constructor(nestedComponentCount:number) {
super(); super();

View File

@ -15,7 +15,7 @@ import {DOM} from 'angular2/src/dom/dom_adapter';
import {Decorator, Component} from 'angular2/src/core/annotations/annotations'; import {Decorator, Component} from 'angular2/src/core/annotations/annotations';
import {View} from 'angular2/src/core/annotations/view'; import {View} from 'angular2/src/core/annotations/view';
import {NgElement} from 'angular2/src/core/compiler/ng_element'; import {ElementRef} from 'angular2/src/core/compiler/element_ref';
import {NonBindable} from 'angular2/src/directives/non_bindable'; import {NonBindable} from 'angular2/src/directives/non_bindable';
@ -67,7 +67,7 @@ class TestComponent {
selector: '[test-dec]' selector: '[test-dec]'
}) })
class TestDecorator { class TestDecorator {
constructor(el: NgElement) { constructor(el: ElementRef) {
DOM.addClass(el.domElement, 'compiled'); DOM.addClass(el.domElement, 'compiled');
} }
} }

View File

@ -6,7 +6,7 @@ import {DOM} from 'angular2/src/dom/dom_adapter';
import {Parser, Lexer} from 'angular2/change_detection'; import {Parser, Lexer} from 'angular2/change_detection';
import {DirectDomRenderer} from 'angular2/src/render/dom/direct_dom_renderer'; import {DirectDomRenderer} from 'angular2/src/render/dom/direct_dom_renderer';
import {Compiler} from 'angular2/src/render/dom/compiler/compiler'; import {Compiler} from 'angular2/src/render/dom/compiler/compiler';
import {ProtoViewRef, ProtoViewDto, ViewDefinition, RenderViewContainerRef, EventDispatcher, DirectiveMetadata} from 'angular2/src/render/api'; import {RenderProtoViewRef, ProtoViewDto, ViewDefinition, RenderViewContainerRef, EventDispatcher, DirectiveMetadata} from 'angular2/src/render/api';
import {DefaultStepFactory} from 'angular2/src/render/dom/compiler/compile_step_factory'; import {DefaultStepFactory} from 'angular2/src/render/dom/compiler/compile_step_factory';
import {TemplateLoader} from 'angular2/src/render/dom/compiler/template_loader'; import {TemplateLoader} from 'angular2/src/render/dom/compiler/template_loader';
import {UrlResolver} from 'angular2/src/services/url_resolver'; import {UrlResolver} from 'angular2/src/services/url_resolver';

View File

@ -349,7 +349,7 @@ export function main() {
}); });
})); }));
//Implement once NgElement support changing a class //Implement once ElementRef support changing a class
//it("should redistribute when a class has been added or removed"); //it("should redistribute when a class has been added or removed");
//it('should not lose focus', () => { //it('should not lose focus', () => {
// var temp = `<simple>aaa<input type="text" id="focused-input" ng-class="{'aClass' : showClass}"> bbb</simple>`; // var temp = `<simple>aaa<input type="text" id="focused-input" ng-class="{'aClass' : showClass}"> bbb</simple>`;

View File

@ -1,22 +1,14 @@
import {AsyncTestCompleter, inject, ddescribe, describe, it, iit, xit, expect, SpyObject} from 'angular2/test_lib'; import {
AsyncTestCompleter, inject, ddescribe, describe, it, iit, xit, expect, SpyObject,
proxy
} from 'angular2/test_lib';
import {DOM, DomAdapter} from 'angular2/src/dom/dom_adapter'; import {DOM, DomAdapter} from 'angular2/src/dom/dom_adapter';
import {NgElement} from 'angular2/src/core/compiler/ng_element'; import {ElementRef} from 'angular2/src/core/compiler/element_ref';
import {Ruler, Rectangle} from 'angular2/src/services/ruler'; import {Ruler, Rectangle} from 'angular2/src/services/ruler';
import {createRectangle} from './rectangle_mock'; import {createRectangle} from './rectangle_mock';
import {IMPLEMENTS} from 'angular2/src/facade/lang';
class DomAdapterMock extends DomAdapter {
rect;
constructor(rect) {
super();
this.rect = rect;
}
getBoundingClientRect(elm) {
return this.rect;
}
}
function assertDimensions(rect: Rectangle, left, right, top, bottom, width, height) { function assertDimensions(rect: Rectangle, left, right, top, bottom, width, height) {
expect(rect.left).toEqual(left); expect(rect.left).toEqual(left);
@ -31,11 +23,14 @@ export function main() {
describe('ruler service', () => { describe('ruler service', () => {
it('should allow measuring NgElements', it('should allow measuring ElementRefs',
inject([AsyncTestCompleter], (async) => { inject([AsyncTestCompleter], (async) => {
var ruler = new Ruler(new DomAdapterMock(createRectangle(10, 20, 200, 100))); var ruler = new Ruler(SpyObject.stub(new SpyDomAdapter(), {
'getBoundingClientRect': createRectangle(10, 20, 200, 100)
}));
ruler.measure(new FakeNgElement(null)).then((rect) => { var elRef = new SpyElementRef();
ruler.measure(elRef).then((rect) => {
assertDimensions(rect, 10, 210, 20, 120, 200, 100); assertDimensions(rect, 10, 210, 20, 120, 200, 100);
async.done(); async.done();
}); });
@ -45,8 +40,9 @@ export function main() {
it('should return 0 for all rectangle values while measuring elements in a document fragment', it('should return 0 for all rectangle values while measuring elements in a document fragment',
inject([AsyncTestCompleter], (async) => { inject([AsyncTestCompleter], (async) => {
var ruler = new Ruler(DOM); var ruler = new Ruler(DOM);
var elRef = new SpyElementRef();
ruler.measure(new FakeNgElement(DOM.createElement('div'))).then((rect) => { elRef.domElement = DOM.createElement('div');
ruler.measure(elRef).then((rect) => {
//here we are using an element created in a doc fragment so all the measures will come back as 0 //here we are using an element created in a doc fragment so all the measures will come back as 0
assertDimensions(rect, 0, 0, 0, 0, 0, 0); assertDimensions(rect, 0, 0, 0, 0, 0, 0);
async.done(); async.done();
@ -56,15 +52,17 @@ export function main() {
}); });
} }
class FakeNgElement extends NgElement { @proxy
_domElement; @IMPLEMENTS(ElementRef)
class SpyElementRef extends SpyObject {
constructor(domElement) { domElement;
super(null, null); constructor(){super(ElementRef);}
this._domElement = domElement; noSuchMethod(m){return super.noSuchMethod(m)}
} }
get domElement() { @proxy
return this._domElement; @IMPLEMENTS(DomAdapter)
} class SpyDomAdapter extends SpyObject {
constructor(){super(DomAdapter);}
noSuchMethod(m){return super.noSuchMethod(m)}
} }

View File

@ -1,4 +1,4 @@
import {bootstrap, Component, Viewport, View, ViewContainerRef, Compiler, NgElement, Decorator} from 'angular2/angular2'; import {bootstrap, Component, Viewport, View, ViewContainerRef, Compiler, Decorator} from 'angular2/angular2';
import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle'; import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
import {reflector} from 'angular2/src/reflection/reflection'; import {reflector} from 'angular2/src/reflection/reflection';

View File

@ -1,4 +1,4 @@
import {Component, Decorator, View, NgElement} from 'angular2/angular2'; import {Component, Decorator, View, ElementRef} from 'angular2/angular2';
import {Injectable} from 'angular2/di'; import {Injectable} from 'angular2/di';
// Angular 2.0 supports 3 basic types of directives: // Angular 2.0 supports 3 basic types of directives:
@ -46,9 +46,9 @@ export class HelloCmp {
selector: '[red]' selector: '[red]'
}) })
class RedDec { class RedDec {
// NgElement is always injectable and it wraps the element on which the // ElementRef is always injectable and it wraps the element on which the
// directive was found by the compiler. // directive was found by the compiler.
constructor(el: NgElement) { constructor(el: ElementRef) {
el.domElement.style.color = 'red'; el.domElement.style.color = 'red';
} }
} }