From 09f8d8f7ba977d881f4b6ef7907e66f0098b1743 Mon Sep 17 00:00:00 2001 From: Tobias Bosch Date: Tue, 28 Apr 2015 11:20:01 -0700 Subject: [PATCH] refactor(core): introduce `ViewRef` and `ProtoViewRef` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- modules/angular2/core.js | 8 +- .../src/core/annotations/annotations.js | 2 +- modules/angular2/src/core/application.js | 32 ++++- .../angular2/src/core/application_tokens.js | 1 - .../angular2/src/core/compiler/compiler.js | 14 ++- .../core/compiler/dynamic_component_loader.js | 54 ++++----- .../src/core/compiler/element_injector.js | 63 +++------- .../angular2/src/core/compiler/element_ref.js | 40 +++++++ .../angular2/src/core/compiler/ng_element.js | 34 ------ modules/angular2/src/core/compiler/view.js | 6 +- .../src/core/compiler/view_container_ref.js | 52 ++++----- .../src/core/compiler/view_manager.js | 81 ++++++++----- .../src/core/compiler/view_manager_utils.js | 29 +++-- .../angular2/src/core/compiler/view_ref.js | 43 +++++++ modules/angular2/src/directives/class.js | 4 +- modules/angular2/src/directives/for.js | 4 +- modules/angular2/src/forms/directives.js | 4 +- modules/angular2/src/render/api.js | 48 ++++---- .../src/render/dom/direct_dom_renderer.js | 26 ++--- modules/angular2/src/router/router_link.js | 6 +- modules/angular2/src/services/ruler.js | 4 +- modules/angular2/src/test_lib/test_bed.js | 3 +- modules/angular2/src/test_lib/test_lib.es6 | 10 +- .../test/core/compiler/compiler_spec.js | 47 ++++---- .../compiler/dynamic_component_loader_spec.js | 4 +- .../core/compiler/element_injector_spec.js | 61 ++++------ .../test/core/compiler/integration_spec.js | 4 +- .../core/compiler/view_container_ref_spec.js | 9 +- .../test/core/compiler/view_manager_spec.js | 110 ++++++++++-------- .../test/directives/non_bindable_spec.js | 4 +- .../test/render/dom/integration_testbed.js | 2 +- .../shadow_dom_emulation_integration_spec.js | 2 +- modules/angular2/test/services/ruler_spec.js | 58 +++++---- modules/benchmarks/src/tree/tree_benchmark.js | 2 +- .../examples/src/hello_world/index_common.js | 6 +- 35 files changed, 473 insertions(+), 404 deletions(-) create mode 100644 modules/angular2/src/core/compiler/element_ref.js delete mode 100644 modules/angular2/src/core/compiler/ng_element.js create mode 100644 modules/angular2/src/core/compiler/view_ref.js diff --git a/modules/angular2/core.js b/modules/angular2/core.js index ef9a5665c5..6e164a4d13 100644 --- a/modules/angular2/core.js +++ b/modules/angular2/core.js @@ -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_unscoped_shadow_dom_strategy'; export * from './src/core/compiler/dynamic_component_loader'; -export {ElementRef, ComponentRef} from './src/core/compiler/element_injector'; -export * from './src/core/compiler/view'; -export * from './src/core/compiler/view_container_ref'; - -export * from './src/core/compiler/ng_element'; +export {ViewRef, ProtoViewRef} from './src/core/compiler/view_ref'; +export {ViewContainerRef} from './src/core/compiler/view_container_ref'; +export {ElementRef} from './src/core/compiler/element_ref'; diff --git a/modules/angular2/src/core/annotations/annotations.js b/modules/angular2/src/core/annotations/annotations.js index a981c71698..d700538d1a 100644 --- a/modules/angular2/src/core/annotations/annotations.js +++ b/modules/angular2/src/core/annotations/annotations.js @@ -54,7 +54,7 @@ import {DEFAULT} from 'angular2/change_detection'; * - `@Descendants query:Query`: A live collection of any child directives (will be implemented in later relaese). * * 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 * - `bindingPropagation: BindingPropagation` to control change detection in a more granular way. * diff --git a/modules/angular2/src/core/application.js b/modules/angular2/src/core/application.js index 1755b6d707..fb5be79b92 100644 --- a/modules/angular2/src/core/application.js +++ b/modules/angular2/src/core/application.js @@ -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 rvf from 'angular2/src/render/dom/view/view_factory'; import * as rvh from 'angular2/src/render/dom/view/view_hydrator'; +import {internalView} from 'angular2/src/core/compiler/view_ref'; import { appComponentRefToken, - appChangeDetectorToken, appElementToken, appComponentAnnotatedTypeToken, appDocumentToken, @@ -80,8 +80,6 @@ function _injectorBindings(appComponentType): List { }, [DynamicComponentLoader, Injector, appElementToken, appComponentAnnotatedTypeToken, Testability, TestabilityRegistry]), - bind(appChangeDetectorToken).toFactory((ref) => ref.hostView.changeDetector, - [appComponentRefToken]), bind(appComponentType).toFactory((ref) => ref.instance, [appComponentRefToken]), bind(LifeCycle).toFactory((exceptionHandler) => new LifeCycle(exceptionHandler, null, assertionsEnabled()),[ExceptionHandler]), @@ -253,7 +251,7 @@ function _createVmZone(givenReporter:Function): VmTurnZone { */ export function bootstrap(appComponentType: Type, componentInjectableBindings: List = null, - errorReporter: Function = null): Promise { + errorReporter: Function = null): Promise { BrowserDomAdapter.makeCurrent(); var bootstrapProcess = PromiseWrapper.completer(); @@ -266,13 +264,13 @@ export function bootstrap(appComponentType: Type, PromiseWrapper.then(appInjector.asyncGet(appComponentRefToken), (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 var lc = appInjector.get(LifeCycle); lc.registerWith(zone, appChangeDetector); lc.tick(); //the first tick that will bootstrap the app - bootstrapProcess.resolve(componentRef); + bootstrapProcess.resolve(new ApplicationRef(componentRef, appInjector)); }, (err) => { @@ -283,6 +281,28 @@ export function bootstrap(appComponentType: Type, 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, zone: VmTurnZone): Injector { if (isBlank(_rootInjector)) _rootInjector = Injector.resolveAndCreate(_rootBindings); var mergedBindings = isPresent(bindings) ? diff --git a/modules/angular2/src/core/application_tokens.js b/modules/angular2/src/core/application_tokens.js index c14a620dd1..01acce0f70 100644 --- a/modules/angular2/src/core/application_tokens.js +++ b/modules/angular2/src/core/application_tokens.js @@ -1,7 +1,6 @@ import {OpaqueToken} from 'angular2/di'; export var appComponentRefToken:OpaqueToken = new OpaqueToken('ComponentRef'); -export var appChangeDetectorToken:OpaqueToken = new OpaqueToken('AppChangeDetector'); export var appElementToken:OpaqueToken = new OpaqueToken('AppElement'); export var appComponentAnnotatedTypeToken:OpaqueToken = new OpaqueToken('AppComponentAnnotatedType'); export var appDocumentToken:OpaqueToken = new OpaqueToken('AppDocument'); diff --git a/modules/angular2/src/core/compiler/compiler.js b/modules/angular2/src/core/compiler/compiler.js index 4573b8a789..0985fcf1f6 100644 --- a/modules/angular2/src/core/compiler/compiler.js +++ b/modules/angular2/src/core/compiler/compiler.js @@ -6,6 +6,7 @@ import {List, ListWrapper, Map, MapWrapper} from 'angular2/src/facade/collection import {DirectiveMetadataReader} from './directive_metadata_reader'; import {Component, Viewport, DynamicComponent, Decorator} from '../annotations/annotations'; import {AppProtoView} from './view'; +import {ProtoViewRef} from './view_ref'; import {DirectiveBinding} from './element_injector'; import {TemplateResolver} from './template_resolver'; import {View} from '../annotations/view'; @@ -87,21 +88,26 @@ export class Compiler { // Create a hostView as if the compiler encountered . // Used for bootstrapping. - compileInHost(componentTypeOrBinding:any):Promise { + compileInHost(componentTypeOrBinding:any):Promise { var componentBinding = this._bindDirective(componentTypeOrBinding); this._assertTypeIsComponent(componentBinding); - + var directiveMetadata = Compiler.buildRenderDirective(componentBinding); return this._renderer.createHostProtoView(directiveMetadata).then( (hostRenderPv) => { return this._compileNestedProtoViews(null, hostRenderPv, [componentBinding], true); + }).then( (appProtoView) => { + return new ProtoViewRef(appProtoView); }); } - compile(component: Type):Promise { + compile(component: Type):Promise { var componentBinding = this._bindDirective(component); this._assertTypeIsComponent(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 diff --git a/modules/angular2/src/core/compiler/dynamic_component_loader.js b/modules/angular2/src/core/compiler/dynamic_component_loader.js index 1195748b7b..667d479d9c 100644 --- a/modules/angular2/src/core/compiler/dynamic_component_loader.js +++ b/modules/angular2/src/core/compiler/dynamic_component_loader.js @@ -2,9 +2,8 @@ import {Key, Injector, Injectable, ResolvedBinding, Binding, bind} from 'angular import {Compiler} from './compiler'; import {Type, BaseException, stringify, isPresent} from 'angular2/src/facade/lang'; import {Promise} from 'angular2/src/facade/async'; -import {AppViewManager} from 'angular2/src/core/compiler/view_manager'; -import {ElementRef} from './element_injector'; -import {AppView} from './view'; +import {AppViewManager, ComponentCreateResult} from 'angular2/src/core/compiler/view_manager'; +import {ElementRef} from './element_ref'; /** * @exportedAs angular2/view @@ -12,22 +11,16 @@ import {AppView} from './view'; export class ComponentRef { location:ElementRef; instance:any; - componentView:AppView; _dispose:Function; - constructor(location:ElementRef, instance:any, componentView:AppView, dispose:Function){ + constructor(location:ElementRef, instance:any, dispose:Function) { this.location = location; this.instance = instance; - this.componentView = componentView; this._dispose = dispose; } - get injector() { - return this.location.injector; - } - get hostView() { - return this.location.hostView; + return this.location.parentView; } dispose() { @@ -58,12 +51,12 @@ export class DynamicComponentLoader { */ loadIntoExistingLocation(typeOrBinding, location:ElementRef, injector:Injector = null):Promise { var binding = this._getBinding(typeOrBinding); - return this._compiler.compile(binding.token).then(componentProtoView => { - var componentView = this._viewManager.createDynamicComponentView( - location, componentProtoView, binding, injector); - + return this._compiler.compile(binding.token).then(componentProtoViewRef => { + this._viewManager.createDynamicComponentView( + location, componentProtoViewRef, binding, injector); + var component = this._viewManager.getComponent(location); 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, injector:Injector = null):Promise { - return this._compiler.compileInHost(this._getBinding(typeOrBinding)).then(hostProtoView => { - var hostView = this._viewManager.createInPlaceHostView( - parentComponentLocation, elementOrSelector, hostProtoView, injector); + return this._compiler.compileInHost(this._getBinding(typeOrBinding)).then(hostProtoViewRef => { + var hostViewRef = this._viewManager.createInPlaceHostView( + 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 = () => { - 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 { var binding = this._getBinding(typeOrBinding); - return this._compiler.compileInHost(binding).then(hostProtoView => { - var hostView = location.viewContainer.create(-1, hostProtoView, injector); + return this._compiler.compileInHost(binding).then(hostProtoViewRef => { + 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 index = location.viewContainer.indexOf(hostView); - location.viewContainer.remove(index); + var index = viewContainer.indexOf(hostViewRef); + viewContainer.remove(index); }; - return new ComponentRef(newLocation, component, hostView.componentChildViews[0], dispose); + return new ComponentRef(newLocation, component, dispose); }); } diff --git a/modules/angular2/src/core/compiler/element_injector.js b/modules/angular2/src/core/compiler/element_injector.js index 07c3d7f569..d5d4f8c9ac 100644 --- a/modules/angular2/src/core/compiler/element_injector.js +++ b/modules/angular2/src/core/compiler/element_injector.js @@ -6,10 +6,11 @@ import {Injector, Key, Dependency, bind, Binding, ResolvedBinding, NoBindingErro AbstractBindingError, CyclicDependencyError} from 'angular2/di'; import {Parent, Ancestor} from 'angular2/src/core/annotations/visibility'; 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 {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref'; -import {NgElement} from 'angular2/src/core/compiler/ng_element'; +import {ViewContainerRef} from './view_container_ref'; +import {ElementRef} from './element_ref'; +import {ProtoViewRef, ViewRef} from './view_ref'; import {Directive, Component, onChange, onDestroy, onAllChangesDone} from 'angular2/src/core/annotations/annotations'; import {ChangeDetector, ChangeDetectorRef} from 'angular2/change_detection'; import {QueryList} from './query_list'; @@ -23,30 +24,9 @@ var _undefined = new Object(); 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 { viewManagerId:number; - viewId:number; - ngElementId:number; - defaultProtoViewId:number; + protoViewId:number; viewContainerId:number; changeDetectorRefId:number; elementRefId:number; @@ -54,9 +34,7 @@ class StaticKeys { constructor() { //TODO: vsavkin Key.annotate(Key.get(AppView), 'static') this.viewManagerId = Key.get(avmModule.AppViewManager).id; - this.defaultProtoViewId = Key.get(viewModule.AppProtoView).id; - this.viewId = Key.get(viewModule.AppView).id; - this.ngElementId = Key.get(NgElement).id; + this.protoViewId = Key.get(ProtoViewRef).id; this.viewContainerId = Key.get(ViewContainerRef).id; this.changeDetectorRefId = Key.get(ChangeDetectorRef).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. export class PreBuiltObjects { viewManager:avmModule.AppViewManager; - defaultProtoView:viewModule.AppProtoView; + protoView:viewModule.AppProtoView; view:viewModule.AppView; - element:NgElement; - constructor(viewManager:avmModule.AppViewManager, view:viewModule.AppView, element:NgElement, defaultProtoView:viewModule.AppProtoView) { + constructor(viewManager:avmModule.AppViewManager, view:viewModule.AppView, protoView:viewModule.AppProtoView) { this.viewManager = viewManager; this.view = view; - this.defaultProtoView = defaultProtoView; - this.element = element; + this.protoView = protoView; } } @@ -649,11 +625,6 @@ export class ElementInjector extends TreeNode { return this._proto.eventEmitterAccessors; } - /** Gets the NgElement associated with this ElementInjector */ - getNgElement() { - return this._preBuiltObjects.element; - } - getComponent() { if (this._proto._binding0IsComponent) { return this._obj0; @@ -663,8 +634,11 @@ export class ElementInjector extends TreeNode { } getElementRef() { - return new ElementRef(this, this._preBuiltObjects.view, this._proto.index, this._lightDomAppInjector, - this._preBuiltObjects.viewManager, this._preBuiltObjects.defaultProtoView); + return new ElementRef(new ViewRef(this._preBuiltObjects.view), this._proto.index); + } + + getViewContainerRef() { + return new ViewContainerRef(this._preBuiltObjects.viewManager, this.getElementRef(), new ProtoViewRef(this._preBuiltObjects.protoView)); } getDynamicallyLoadedComponent() { @@ -742,7 +716,10 @@ export class ElementInjector extends TreeNode { return this.getElementRef(); } 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); } @@ -914,11 +891,7 @@ export class ElementInjector extends TreeNode { _getPreBuiltObjectByKeyId(keyId:int) { var staticKeys = StaticKeys.instance(); - // TODO: AppView should not be injectable. Remove it. 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 return _undefined; diff --git a/modules/angular2/src/core/compiler/element_ref.js b/modules/angular2/src/core/compiler/element_ref.js new file mode 100644 index 0000000000..81f9a98d97 --- /dev/null +++ b/modules/angular2/src/core/compiler/element_ref.js @@ -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)); + } +} diff --git a/modules/angular2/src/core/compiler/ng_element.js b/modules/angular2/src/core/compiler/ng_element.js deleted file mode 100644 index 1a6511c9f4..0000000000 --- a/modules/angular2/src/core/compiler/ng_element.js +++ /dev/null @@ -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)); - } -} diff --git a/modules/angular2/src/core/compiler/view.js b/modules/angular2/src/core/compiler/view.js index d0afa94f52..c8a3a0fbc6 100644 --- a/modules/angular2/src/core/compiler/view.js +++ b/modules/angular2/src/core/compiler/view.js @@ -25,7 +25,7 @@ export class AppViewContainer { // TODO(tbosch): this is not supported in dart2js (no '.' is allowed) // @IMPLEMENTS(renderApi.EventDispatcher) export class AppView { - render:renderApi.ViewRef; + render:renderApi.RenderViewRef; /// This list matches the _nodes list. It is sparse, since only Elements have ElementInjector rootElementInjectors:List; elementInjectors:List; @@ -171,10 +171,10 @@ export class AppProtoView { _directiveRecordsMap:Map; _directiveRecords:List; - render:renderApi.ProtoViewRef; + render:renderApi.RenderProtoViewRef; constructor( - render:renderApi.ProtoViewRef, + render:renderApi.RenderProtoViewRef, protoChangeDetector:ProtoChangeDetector) { this.render = render; this.elementBinders = []; diff --git a/modules/angular2/src/core/compiler/view_container_ref.js b/modules/angular2/src/core/compiler/view_container_ref.js index 41bc7c3333..6127db7d74 100644 --- a/modules/angular2/src/core/compiler/view_container_ref.js +++ b/modules/angular2/src/core/compiler/view_container_ref.js @@ -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 * as eiModule from 'angular2/src/core/compiler/element_injector'; import {isPresent, isBlank} from 'angular2/src/facade/lang'; -import * as viewModule from './view'; import * as avmModule from './view_manager'; -/** - * @exportedAs angular2/view - */ +import {ElementRef} from './element_ref'; +import {ViewRef, ProtoViewRef, internalView} from './view_ref'; + export class ViewContainerRef { _viewManager: avmModule.AppViewManager; - _location: eiModule.ElementRef; - _defaultProtoView: viewModule.AppProtoView; + _element: ElementRef; + _defaultProtoViewRef: ProtoViewRef; constructor(viewManager: avmModule.AppViewManager, - location: eiModule.ElementRef, - defaultProtoView: viewModule.AppProtoView) { + element: ElementRef, + defaultProtoViewRef: ProtoViewRef) { this._viewManager = viewManager; - this._location = location; - this._defaultProtoView = defaultProtoView; + this._element = element; + this._defaultProtoViewRef = defaultProtoViewRef; } _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 : []; } @@ -33,8 +31,8 @@ export class ViewContainerRef { } } - get(index: number): viewModule.AppView { - return this._getViews()[index]; + get(index: number): ViewRef { + return new ViewRef(this._getViews()[index]); } get length() /* :int */ { @@ -43,26 +41,26 @@ export class ViewContainerRef { // TODO(rado): profile and decide whether bounds checks should be added // 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 (isBlank(protoView)) { - protoView = this._defaultProtoView; + if (isBlank(protoViewRef)) { + 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; - return this._viewManager.attachViewInContainer(this._location, atIndex, view); + return this._viewManager.attachViewInContainer(this._element, atIndex, viewRef); } - indexOf(view:viewModule.AppView) { - return ListWrapper.indexOf(this._getViews(), view); + indexOf(viewRef:ViewRef) { + return ListWrapper.indexOf(this._getViews(), internalView(viewRef)); } remove(atIndex:number=-1):void { 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. } @@ -70,8 +68,8 @@ export class ViewContainerRef { * 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. */ - detach(atIndex:number=-1): viewModule.AppView { + detach(atIndex:number=-1): ViewRef { if (atIndex == -1) atIndex = this.length - 1; - return this._viewManager.detachViewInContainer(this._location, atIndex); + return this._viewManager.detachViewInContainer(this._element, atIndex); } -} +} \ No newline at end of file diff --git a/modules/angular2/src/core/compiler/view_manager.js b/modules/angular2/src/core/compiler/view_manager.js index 90a614d3c4..787d51b1b0 100644 --- a/modules/angular2/src/core/compiler/view_manager.js +++ b/modules/angular2/src/core/compiler/view_manager.js @@ -1,9 +1,11 @@ import {Injector, Injectable, Binding} from 'angular2/di'; import {ListWrapper, MapWrapper, Map, StringMapWrapper, List} from 'angular2/src/facade/collection'; import {isPresent, isBlank, BaseException} from 'angular2/src/facade/lang'; -import * as eli from './element_injector'; 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 {AppViewPool} from './view_pool'; @@ -24,9 +26,21 @@ export class AppViewManager { this._utils = utils; } - createDynamicComponentView(hostLocation:eli.ElementRef, - componentProtoView:viewModule.AppProtoView, componentBinding:Binding, injector:Injector):viewModule.AppView { - var hostView = hostLocation.hostView; + getViewContainer(location:ElementRef):ViewContainerRef { + var hostView = internalView(location.parentView); + 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 binder = hostView.proto.elementBinders[boundElementIndex]; if (!binder.hasDynamicComponent()) { @@ -39,34 +53,36 @@ export class AppViewManager { this._utils.attachComponentView(hostView, boundElementIndex, componentView); this._utils.hydrateDynamicComponentInElementInjector(hostView, boundElementIndex, componentBinding, injector); this._utils.hydrateComponentView(hostView, boundElementIndex); - this._viewHydrateRecurse(componentView, renderViewRefs, 1); - return componentView; + + return new ViewRef(componentView); } - createInPlaceHostView(parentComponentLocation:eli.ElementRef, - hostElementSelector, hostProtoView:viewModule.AppProtoView, injector:Injector):viewModule.AppView { + createInPlaceHostView(parentComponentLocation:ElementRef, + hostElementSelector, hostProtoViewRef:ProtoViewRef, injector:Injector):ViewRef { + var hostProtoView = internalProtoView(hostProtoViewRef); var parentComponentHostView = null; var parentComponentBoundElementIndex = null; var parentRenderViewRef = null; if (isPresent(parentComponentLocation)) { - parentComponentHostView = parentComponentLocation.hostView; + parentComponentHostView = internalView(parentComponentLocation.parentView); parentComponentBoundElementIndex = parentComponentLocation.boundElementIndex; parentRenderViewRef = parentComponentHostView.componentChildViews[parentComponentBoundElementIndex].render; } 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]; this._utils.attachAndHydrateInPlaceHostView(parentComponentHostView, parentComponentBoundElementIndex, hostView, injector); 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 parentRenderViewRef = null; if (isPresent(parentComponentLocation)) { - parentView = parentComponentLocation.hostView.componentChildViews[parentComponentLocation.boundElementIndex]; + parentView = internalView(parentComponentLocation.parentView).componentChildViews[parentComponentLocation.boundElementIndex]; parentRenderViewRef = parentView.render; } var hostViewRenderRef = hostView.render; @@ -76,10 +92,12 @@ export class AppViewManager { this._destroyView(hostView); } - createViewInContainer(viewContainerLocation:eli.ElementRef, - atIndex:number, protoView:viewModule.AppProtoView, injector:Injector = null):viewModule.AppView { - var parentView = viewContainerLocation.hostView; - var boundElementIndex:number = viewContainerLocation.boundElementIndex; + createViewInContainer(viewContainerLocation:ElementRef, + atIndex:number, protoViewRef:ProtoViewRef, injector:Injector = null):ViewRef { + var protoView = internalProtoView(protoViewRef); + var parentView = internalView(viewContainerLocation.parentView); + var boundElementIndex = viewContainerLocation.boundElementIndex; + var view = this._createViewRecurse(protoView); var renderViewRefs = this._renderer.createViewInContainer(this._getRenderViewContainerRef(parentView, boundElementIndex), atIndex, view.proto.render); view.render = renderViewRefs[0]; @@ -87,12 +105,12 @@ export class AppViewManager { this._utils.attachViewInContainer(parentView, boundElementIndex, atIndex, view); this._utils.hydrateViewInContainer(parentView, boundElementIndex, atIndex, injector); this._viewHydrateRecurse(view, renderViewRefs, 1); - return view; + return new ViewRef(view); } - destroyViewInContainer(viewContainerLocation:eli.ElementRef, atIndex:number) { - var parentView = viewContainerLocation.hostView; - var boundElementIndex:number = viewContainerLocation.boundElementIndex; + destroyViewInContainer(viewContainerLocation:ElementRef, atIndex:number) { + var parentView = internalView(viewContainerLocation.parentView); + var boundElementIndex = viewContainerLocation.boundElementIndex; var viewContainer = parentView.viewContainers[boundElementIndex]; var view = viewContainer.views[atIndex]; this._viewDehydrateRecurse(view); @@ -101,22 +119,23 @@ export class AppViewManager { this._destroyView(view); } - attachViewInContainer(viewContainerLocation:eli.ElementRef, atIndex:number, view:viewModule.AppView):viewModule.AppView { - var parentView = viewContainerLocation.hostView; - var boundElementIndex:number = viewContainerLocation.boundElementIndex; + attachViewInContainer(viewContainerLocation:ElementRef, atIndex:number, viewRef:ViewRef):ViewRef { + var view = internalView(viewRef); + var parentView = internalView(viewContainerLocation.parentView); + var boundElementIndex = viewContainerLocation.boundElementIndex; this._utils.attachViewInContainer(parentView, boundElementIndex, atIndex, view); this._renderer.insertViewIntoContainer(this._getRenderViewContainerRef(parentView, boundElementIndex), atIndex, view.render); - return view; + return viewRef; } - detachViewInContainer(viewContainerLocation:eli.ElementRef, atIndex:number):viewModule.AppView { - var parentView = viewContainerLocation.hostView; - var boundElementIndex:number = viewContainerLocation.boundElementIndex; + detachViewInContainer(viewContainerLocation:ElementRef, atIndex:number):ViewRef { + var parentView = internalView(viewContainerLocation.parentView); + var boundElementIndex = viewContainerLocation.boundElementIndex; var viewContainer = parentView.viewContainers[boundElementIndex]; var view = viewContainer.views[atIndex]; this._utils.detachViewInContainer(parentView, boundElementIndex, atIndex); this._renderer.detachViewFromContainer(this._getRenderViewContainerRef(parentView, boundElementIndex), atIndex); - return view; + return new ViewRef(view); } _getRenderViewContainerRef(parentView:viewModule.AppView, boundElementIndex:number) { @@ -145,7 +164,7 @@ export class AppViewManager { _viewHydrateRecurse( view:viewModule.AppView, - renderComponentViewRefs:List, + renderComponentViewRefs:List, renderComponentIndex:number):number { this._renderer.setEventDispatcher(view.render, view); diff --git a/modules/angular2/src/core/compiler/view_manager_utils.js b/modules/angular2/src/core/compiler/view_manager_utils.js index d9869264a7..c3396b2d27 100644 --- a/modules/angular2/src/core/compiler/view_manager_utils.js +++ b/modules/angular2/src/core/compiler/view_manager_utils.js @@ -2,7 +2,6 @@ import {Injectable, Injector, Binding} from 'angular2/di'; import {ListWrapper, MapWrapper, Map, StringMapWrapper, List} from 'angular2/src/facade/collection'; import * as eli from './element_injector'; 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 avmModule from './view_manager'; import {Renderer} from 'angular2/src/render/api'; @@ -17,6 +16,16 @@ export class AppViewManagerUtils { 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 { var view = new viewModule.AppView(renderer, protoView, protoView.protoLocals); var changeDetector = protoView.protoChangeDetector.instantiate(view, protoView.bindings, @@ -48,7 +57,7 @@ export class AppViewManagerUtils { // preBuiltObjects if (isPresent(elementInjector)) { 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) { var elementInjector = hostView.elementInjectors[boundElementIndex]; var componentView = hostView.componentChildViews[boundElementIndex]; - var binder = hostView.proto.elementBinders[boundElementIndex]; - var component; - if (binder.hasDynamicComponent()) { - component = elementInjector.getDynamicallyLoadedComponent(); - } else { - component = elementInjector.getComponent(); - } + var component = this.getComponentInstance(hostView, boundElementIndex); this._hydrateView( 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); var viewContainer = parentView.viewContainers[boundElementIndex]; 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 view = viewContainer.views[atIndex]; var elementInjector = parentView.elementInjectors[boundElementIndex]; @@ -203,7 +208,7 @@ export class AppViewManagerUtils { if (elementInjector.isExportingComponent()) { view.locals.set(exportImplicitName, elementInjector.getComponent()); } else if (elementInjector.isExportingElement()) { - view.locals.set(exportImplicitName, elementInjector.getNgElement().domElement); + view.locals.set(exportImplicitName, elementInjector.getElementRef().domElement); } } } diff --git a/modules/angular2/src/core/compiler/view_ref.js b/modules/angular2/src/core/compiler/view_ref.js new file mode 100644 index 0000000000..9aaa34d7bf --- /dev/null +++ b/modules/angular2/src/core/compiler/view_ref.js @@ -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; + } +} diff --git a/modules/angular2/src/directives/class.js b/modules/angular2/src/directives/class.js index 7edffd3e23..55b841c873 100644 --- a/modules/angular2/src/directives/class.js +++ b/modules/angular2/src/directives/class.js @@ -1,7 +1,7 @@ import {Decorator} from 'angular2/src/core/annotations/annotations'; import {isPresent} from 'angular2/src/facade/lang'; 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({ selector: '[class]', @@ -11,7 +11,7 @@ import {NgElement} from 'angular2/src/core/compiler/ng_element'; }) export class CSSClass { _domEl; - constructor(ngEl: NgElement) { + constructor(ngEl: ElementRef) { this._domEl = ngEl.domElement; } diff --git a/modules/angular2/src/directives/for.js b/modules/angular2/src/directives/for.js index c9b9514f0d..08728598d2 100644 --- a/modules/angular2/src/directives/for.js +++ b/modules/angular2/src/directives/for.js @@ -1,6 +1,6 @@ import {Viewport} from 'angular2/src/core/annotations/annotations'; 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 {ListWrapper} from 'angular2/src/facade/collection'; @@ -114,7 +114,7 @@ export class For { } class RecordViewTuple { - view: AppView; + view: ViewRef; record: any; constructor(record, view) { this.record = record; diff --git a/modules/angular2/src/forms/directives.js b/modules/angular2/src/forms/directives.js index d28c5248fe..2670887fc3 100644 --- a/modules/angular2/src/forms/directives.js +++ b/modules/angular2/src/forms/directives.js @@ -1,6 +1,6 @@ import {Decorator, onChange} from 'angular2/src/core/annotations/annotations'; 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 {Renderer} from 'angular2/src/render/api'; import {isPresent, isString} from 'angular2/src/facade/lang'; @@ -83,7 +83,7 @@ export class CheckboxControlValueAccessor { } writeValue(value) { - this._renderer.setElementProperty(this._elementRef.hostView.render, this._elementRef.boundElementIndex, + this._renderer.setElementProperty(this._elementRef.parentView.render, this._elementRef.boundElementIndex, 'checked', value) } } diff --git a/modules/angular2/src/render/api.js b/modules/angular2/src/render/api.js index 110ef5aedd..349986a256 100644 --- a/modules/angular2/src/render/api.js +++ b/modules/angular2/src/render/api.js @@ -95,7 +95,7 @@ export class ProtoViewDto { // inside of a component view static get EMBEDDED_VIEW_TYPE() { return 1; } - render: ProtoViewRef; + render: RenderProtoViewRef; elementBinders:List; variableBindings: Map; type: number; @@ -133,15 +133,15 @@ export class DirectiveMetadata { } // An opaque reference to a RenderProtoView -export class ProtoViewRef {} +export class RenderProtoViewRef {} // An opaque reference to a RenderView -export class ViewRef {} +export class RenderViewRef {} export class RenderViewContainerRef { - view:ViewRef; + view:RenderViewRef; elementIndex:number; - constructor(view:ViewRef, elementIndex: number) { + constructor(view:RenderViewRef, elementIndex: number) { this.view = view; this.elementIndex = elementIndex; } @@ -186,19 +186,19 @@ export class Renderer { * Sets the preset nested components, * 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. - * @param {List} protoViewRefs + * @param {List} protoViewRefs * RenderProtoView for every element with a component in this protoView or in a view container's protoView */ - mergeChildComponentProtoViews(protoViewRef:ProtoViewRef, componentProtoViewRefs:List) { return null; } + mergeChildComponentProtoViews(protoViewRef:RenderProtoViewRef, componentProtoViewRefs:List) { return null; } /** * Creates a view and inserts it into a ViewContainer. * @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 - * @return {List} the view and all of its nested child component views + * @return {List} the view and all of its nested child component views */ - createViewInContainer(vcRef:RenderViewContainerRef, atIndex:number, protoViewRef:ProtoViewRef):List { return null; } + createViewInContainer(vcRef:RenderViewContainerRef, atIndex:number, protoViewRef:RenderProtoViewRef):List { return null; } /** * Destroys the view in the given ViewContainer @@ -208,7 +208,7 @@ export class Renderer { /** * 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 @@ -220,53 +220,53 @@ export class Renderer { * installs it as a shadow view for an element. * * Note: only allowed if there is a dynamic component directive at this place. - * @param {ViewRef} hostView + * @param {RenderViewRef} hostView * @param {number} elementIndex - * @param {ProtoViewRef} componentProtoViewRef A ProtoViewRef of type ProtoViewDto.COMPONENT_VIEW_TYPE - * @return {List} the view and all of its nested child component views + * @param {RenderProtoViewRef} componentProtoViewRef A RenderProtoViewRef of type ProtoViewDto.COMPONENT_VIEW_TYPE + * @return {List} the view and all of its nested child component views */ - createDynamicComponentView(hostViewRef:ViewRef, elementIndex:number, componentProtoViewRef:ProtoViewRef):List { return null; } + createDynamicComponentView(hostViewRef:RenderViewRef, elementIndex:number, componentProtoViewRef:RenderProtoViewRef):List { return null; } /** * Destroys the component view at the given index * * 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. - * @param {ViewRef} parentViewRef (might be null) + * @param {RenderViewRef} parentViewRef (might be null) * @param {any} hostElementSelector element or css selector for the host element - * @param {ProtoViewRef} hostProtoView a ProtoViewRef of type ProtoViewDto.HOST_VIEW_TYPE - * @return {List} the view and all of its nested child component views + * @param {RenderProtoViewRef} hostProtoView a RenderProtoViewRef of type ProtoViewDto.HOST_VIEW_TYPE + * @return {List} the view and all of its nested child component views */ - createInPlaceHostView(parentViewRef:ViewRef, hostElementSelector, hostProtoViewRef:ProtoViewRef):List { return null; } + createInPlaceHostView(parentViewRef:RenderViewRef, hostElementSelector, hostProtoViewRef:RenderProtoViewRef):List { return null; } /** * 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. * Note: This will fail if the property was not mentioned previously as a host property * 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. * Note: This needs to be separate from setElementProperty as we don't have ElementBinders * 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 * 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 diff --git a/modules/angular2/src/render/dom/direct_dom_renderer.js b/modules/angular2/src/render/dom/direct_dom_renderer.js index 31a948e5ec..132a147d0c 100644 --- a/modules/angular2/src/render/dom/direct_dom_renderer.js +++ b/modules/angular2/src/render/dom/direct_dom_renderer.js @@ -45,7 +45,7 @@ function _collectComponentChildViewRefs(view, target = null) { // public so that the compiler can use it. -export class DirectDomProtoViewRef extends api.ProtoViewRef { +export class DirectDomProtoViewRef extends api.RenderProtoViewRef { 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; constructor(delegate:RenderView) { @@ -95,13 +95,13 @@ export class DirectDomRenderer extends api.Renderer { return this._compiler.compile(view); } - mergeChildComponentProtoViews(protoViewRef:api.ProtoViewRef, protoViewRefs:List) { + mergeChildComponentProtoViews(protoViewRef:api.RenderProtoViewRef, protoViewRefs:List) { _resolveProtoView(protoViewRef).mergeChildComponentProtoViews( ListWrapper.map(protoViewRefs, _resolveProtoView) ); } - createViewInContainer(vcRef:api.RenderViewContainerRef, atIndex:number, protoViewRef:api.ProtoViewRef):List { + createViewInContainer(vcRef:api.RenderViewContainerRef, atIndex:number, protoViewRef:api.RenderProtoViewRef):List { var view = this._viewFactory.getView(_resolveProtoView(protoViewRef)); var vc = _resolveViewContainer(vcRef); this._viewHydrator.hydrateViewInViewContainer(vc, view); @@ -116,7 +116,7 @@ export class DirectDomRenderer extends api.Renderer { 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); } @@ -124,14 +124,14 @@ export class DirectDomRenderer extends api.Renderer { _resolveViewContainer(vcRef).detach(atIndex); } - createDynamicComponentView(hostViewRef:api.ViewRef, elementIndex:number, componentViewRef:api.ProtoViewRef):List { + createDynamicComponentView(hostViewRef:api.RenderViewRef, elementIndex:number, componentViewRef:api.RenderProtoViewRef):List { var hostView = _resolveView(hostViewRef); var componentView = this._viewFactory.getView(_resolveProtoView(componentViewRef)); this._viewHydrator.hydrateDynamicComponentView(hostView, elementIndex, componentView); return _collectComponentChildViewRefs(componentView); } - destroyDynamicComponentView(hostViewRef:api.ViewRef, elementIndex:number):void { + destroyDynamicComponentView(hostViewRef:api.RenderViewRef, elementIndex:number):void { throw new BaseException('Not supported yet'); // Something along these lines: // var hostView = _resolveView(hostViewRef); @@ -139,7 +139,7 @@ export class DirectDomRenderer extends api.Renderer { // this._viewHydrator.dehydrateDynamicComponentView(hostView, componentView); } - createInPlaceHostView(parentViewRef:api.ViewRef, hostElementSelector, hostProtoViewRef:api.ProtoViewRef):List { + createInPlaceHostView(parentViewRef:api.RenderViewRef, hostElementSelector, hostProtoViewRef:api.RenderProtoViewRef):List { var parentView = _resolveView(parentViewRef); var hostView = this._viewFactory.createInPlaceHostView(hostElementSelector, _resolveProtoView(hostProtoViewRef)); 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. */ - destroyInPlaceHostView(parentViewRef:api.ViewRef, hostViewRef:api.ViewRef):void { + destroyInPlaceHostView(parentViewRef:api.RenderViewRef, hostViewRef:api.RenderViewRef):void { var parentView = _resolveView(parentViewRef); var hostView = _resolveView(hostViewRef); 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 hostElement = parentView.boundElements[elementIndex]; var componentView = parentView.componentChildViews[elementIndex]; @@ -170,15 +170,15 @@ export class DirectDomRenderer extends api.Renderer { 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); } - setText(viewRef:api.ViewRef, textNodeIndex:number, text:string):void { + setText(viewRef:api.RenderViewRef, textNodeIndex:number, text:string):void { _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); } } diff --git a/modules/angular2/src/router/router_link.js b/modules/angular2/src/router/router_link.js index 27559b62eb..3991c577f2 100644 --- a/modules/angular2/src/router/router_link.js +++ b/modules/angular2/src/router/router_link.js @@ -1,5 +1,5 @@ import {Decorator} from 'angular2/annotations'; -import {NgElement} from 'angular2/core'; +import {ElementRef} from 'angular2/core'; import {isPresent} from 'angular2/src/facade/lang'; import {DOM} from 'angular2/src/dom/dom_adapter'; @@ -41,8 +41,8 @@ export class RouterLink { _router:Router; //TODO: handle click events - constructor(ngEl:NgElement, router:Router) { - this._domEl = ngEl.domElement; + constructor(elementRef:ElementRef, router:Router) { + this._domEl = elementRef.domElement; this._router = router; } diff --git a/modules/angular2/src/services/ruler.js b/modules/angular2/src/services/ruler.js index 40136dee25..19b617829c 100644 --- a/modules/angular2/src/services/ruler.js +++ b/modules/angular2/src/services/ruler.js @@ -1,6 +1,6 @@ import {Promise, PromiseWrapper} from 'angular2/src/facade/async'; 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 { left; @@ -25,7 +25,7 @@ export class Ruler { this.domAdapter = domAdapter; } - measure(el:NgElement): Promise { + measure(el:ElementRef): Promise { var clntRect = this.domAdapter.getBoundingClientRect(el.domElement); //even if getBoundingClientRect is synchronous we use async API in preparation for further changes diff --git a/modules/angular2/src/test_lib/test_bed.js b/modules/angular2/src/test_lib/test_bed.js index 067dc8af1e..d20a47cd08 100644 --- a/modules/angular2/src/test_lib/test_bed.js +++ b/modules/angular2/src/test_lib/test_bed.js @@ -9,6 +9,7 @@ import {View} from 'angular2/src/core/annotations/view'; import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver'; 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 {queryView, viewRootNodes, el} from './utils'; @@ -103,7 +104,7 @@ export class ViewProxy { constructor(componentRef: ComponentRef) { this._componentRef = componentRef; - this._view = componentRef.hostView.componentChildViews[0]; + this._view = internalView(componentRef.hostView).componentChildViews[0]; } get context(): any { diff --git a/modules/angular2/src/test_lib/test_lib.es6 b/modules/angular2/src/test_lib/test_lib.es6 index 1d3f2f5845..68a6e60776 100644 --- a/modules/angular2/src/test_lib/test_lib.es6 +++ b/modules/angular2/src/test_lib/test_lib.es6 @@ -276,7 +276,15 @@ export class SpyObject { constructor(type = null) { if (type) { 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') { this.spy(prop); } diff --git a/modules/angular2/test/core/compiler/compiler_spec.js b/modules/angular2/test/core/compiler/compiler_spec.js index cad4a8b552..bcf05b4d40 100644 --- a/modules/angular2/test/core/compiler/compiler_spec.js +++ b/modules/angular2/test/core/compiler/compiler_spec.js @@ -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 {Attribute} from 'angular2/src/core/annotations/di'; 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 {TemplateResolver} from 'angular2/src/core/compiler/template_resolver'; import {ComponentUrlMapper, RuntimeComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper'; @@ -70,7 +71,7 @@ export function main() { function captureTemplate(template:View):Promise { tplResolver.setView(MainComponent, template); var compiler = createCompiler([createRenderProtoView()], [createProtoView()]); - return compiler.compile(MainComponent).then( (protoView) => { + return compiler.compile(MainComponent).then( (_) => { expect(renderCompileRequests.length).toBe(1); return renderCompileRequests[0]; }); @@ -226,7 +227,7 @@ export function main() { var renderProtoView = createRenderProtoView(); var expectedProtoView = createProtoView(); var compiler = createCompiler([renderProtoView], [expectedProtoView]); - compiler.compile(MainComponent).then( (protoView) => { + compiler.compile(MainComponent).then( (_) => { var request = protoViewFactory.requests[0]; expect(request[1]).toBe(renderProtoView); async.done(); @@ -236,7 +237,7 @@ export function main() { it('should pass the component binding', inject([AsyncTestCompleter], (async) => { tplResolver.setView(MainComponent, new View({template: '
'})); var compiler = createCompiler([createRenderProtoView()], [createProtoView()]); - compiler.compile(MainComponent).then( (protoView) => { + compiler.compile(MainComponent).then( (_) => { var request = protoViewFactory.requests[0]; expect(request[0].key.token).toBe(MainComponent); async.done(); @@ -251,7 +252,7 @@ export function main() { }) ); var compiler = createCompiler([createRenderProtoView()], [createProtoView()]); - compiler.compile(MainComponent).then( (protoView) => { + compiler.compile(MainComponent).then( (_) => { var request = protoViewFactory.requests[0]; var binding = request[2][0]; expect(binding.key.token).toBe(SomeDecoratorDirective); @@ -264,8 +265,8 @@ export function main() { var renderProtoView = createRenderProtoView(); var expectedProtoView = createProtoView(); var compiler = createCompiler([renderProtoView], [expectedProtoView]); - compiler.compile(MainComponent).then( (protoView) => { - expect(protoView).toBe(expectedProtoView); + compiler.compile(MainComponent).then( (protoViewRef) => { + expect(internalProtoView(protoViewRef)).toBe(expectedProtoView); async.done(); }); })); @@ -286,8 +287,8 @@ export function main() { ], [mainProtoView, nestedProtoView] ); - compiler.compile(MainComponent).then( (protoView) => { - expect(protoView).toBe(mainProtoView); + compiler.compile(MainComponent).then( (protoViewRef) => { + expect(internalProtoView(protoViewRef)).toBe(mainProtoView); expect(mainProtoView.elementBinders[0].nestedProtoView).toBe(nestedProtoView); // parentProtoView of nested components has to be null as components can // be used by multiple other components. @@ -319,8 +320,8 @@ export function main() { ], [mainProtoView, viewportProtoView, nestedProtoView] ); - compiler.compile(MainComponent).then( (protoView) => { - expect(protoView).toBe(mainProtoView); + compiler.compile(MainComponent).then( (protoViewRef) => { + expect(internalProtoView(protoViewRef)).toBe(mainProtoView); expect(mainProtoView.elementBinders[0].nestedProtoView).toBe(viewportProtoView); expect(viewportProtoView.parentProtoView).toBe(mainProtoView); expect(viewportProtoView.elementBinders[0].nestedProtoView).toBe(nestedProtoView); @@ -337,11 +338,11 @@ export function main() { var renderProtoView = createRenderProtoView(); var expectedProtoView = createProtoView(); var compiler = createCompiler([renderProtoView], [expectedProtoView]); - compiler.compile(MainComponent).then( (protoView) => { - expect(protoView).toBe(expectedProtoView); + compiler.compile(MainComponent).then( (protoViewRef) => { + expect(internalProtoView(protoViewRef)).toBe(expectedProtoView); return compiler.compile(MainComponent); - }).then( (protoView) => { - expect(protoView).toBe(expectedProtoView); + }).then( (protoViewRef) => { + expect(internalProtoView(protoViewRef)).toBe(expectedProtoView); async.done(); }); })); @@ -355,9 +356,9 @@ export function main() { PromiseWrapper.all([ compiler.compile(MainComponent), compiler.compile(MainComponent) - ]).then( (protoViews) => { - expect(protoViews[0]).toBe(expectedProtoView); - expect(protoViews[1]).toBe(expectedProtoView); + ]).then( (protoViewRefs) => { + expect(internalProtoView(protoViewRefs[0])).toBe(expectedProtoView); + expect(internalProtoView(protoViewRefs[1])).toBe(expectedProtoView); async.done(); }); })); @@ -373,8 +374,8 @@ export function main() { ])], [mainProtoView] ); - compiler.compile(MainComponent).then( (protoView) => { - expect(protoView).toBe(mainProtoView); + compiler.compile(MainComponent).then( (protoViewRef) => { + expect(internalProtoView(protoViewRef)).toBe(mainProtoView); expect(mainProtoView.elementBinders[0].nestedProtoView).toBe(mainProtoView); async.done(); }); @@ -397,8 +398,8 @@ export function main() { ], [rootProtoView, mainProtoView] ); - compiler.compileInHost(MainComponent).then( (protoView) => { - expect(protoView).toBe(rootProtoView); + compiler.compileInHost(MainComponent).then( (protoViewRef) => { + expect(internalProtoView(protoViewRef)).toBe(rootProtoView); expect(rootProtoView.elementBinders[0].nestedProtoView).toBe(mainProtoView); async.done(); }); @@ -416,8 +417,8 @@ export function main() { [], [mainProtoView] ); - compiler.compile(MainComponent).then( (protoView) => { - expect(protoView).toBe(mainProtoView); + compiler.compile(MainComponent).then( (protoViewRef) => { + expect(internalProtoView(protoViewRef)).toBe(mainProtoView); expect(renderer.spy('createImperativeComponentProtoView')).toHaveBeenCalledWith('some-renderer'); async.done(); }); diff --git a/modules/angular2/test/core/compiler/dynamic_component_loader_spec.js b/modules/angular2/test/core/compiler/dynamic_component_loader_spec.js index 70620dfab5..47ea8f882f 100644 --- a/modules/angular2/test/core/compiler/dynamic_component_loader_spec.js +++ b/modules/angular2/test/core/compiler/dynamic_component_loader_spec.js @@ -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 {View} from 'angular2/src/core/annotations/view'; 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 {DirectDomRenderer} from 'angular2/src/render/dom/direct_dom_renderer'; import {DOM} from 'angular2/src/dom/dom_adapter'; @@ -207,7 +207,7 @@ class ImperativeViewComponentUsingNgComponent { constructor(self:ElementRef, dynamicComponentLoader:DynamicComponentLoader, renderer:DirectDomRenderer) { var div = el('
'); - renderer.setImperativeComponentRootNodes(self.hostView.render, self.boundElementIndex, [div]); + renderer.setImperativeComponentRootNodes(self.parentView.render, self.boundElementIndex, [div]); this.done = dynamicComponentLoader.loadIntoNewLocation(ChildComp, self, div, null); } } diff --git a/modules/angular2/test/core/compiler/element_injector_spec.js b/modules/angular2/test/core/compiler/element_injector_spec.js index 825ca7a6dc..6fa06235ac 100644 --- a/modules/angular2/test/core/compiler/element_injector_spec.js +++ b/modules/angular2/test/core/compiler/element_injector_spec.js @@ -1,7 +1,7 @@ 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 {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'; import {Parent, Ancestor} from 'angular2/src/core/annotations/visibility'; 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 {AppProtoView, AppView} from 'angular2/src/core/compiler/view'; 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 {DynamicChangeDetector, ChangeDetectorRef, Parser, Lexer} from 'angular2/change_detection'; 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 { changeDetectorRef; constructor(cdr:ChangeDetectorRef) { @@ -150,13 +158,6 @@ class B_Needs_A { constructor(dep){} } -class NeedsView { - view:any; - constructor(@Inject(AppView) view) { - this.view = view; - } -} - class DirectiveWithDestroy { onDestroyCounter:number; @@ -181,7 +182,7 @@ class TestNode extends TreeNode { } export function main() { - var defaultPreBuiltObjects = new PreBuiltObjects(null, null, null, null); + var defaultPreBuiltObjects = new PreBuiltObjects(null, null, null); var appInjector = Injector.resolveAndCreate([]); function humanize(tree, names:List) { @@ -453,10 +454,10 @@ export function main() { }); it("should instantiate directives that depend on pre built objects", function () { - var view = new DummyView(); - var inj = injector([NeedsView], null, null, new PreBuiltObjects(null, view, null, null)); + var protoView = new AppProtoView(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 () { @@ -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", () => { it("should create a component dynamically", () => { var inj = injector([]); @@ -700,7 +678,7 @@ export function main() { }); }); - describe("ElementRef", () => { + describe("refs", () => { it("should inject ElementRef", () => { var inj = injector([NeedsElementRef]); expect(inj.get(NeedsElementRef).elementRef).toBeAnInstanceOf(ElementRef); @@ -712,7 +690,7 @@ export function main() { var childView = new DummyView(); childView.changeDetector = cd; 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); }); @@ -721,6 +699,13 @@ export function main() { var inj = injector([NeedsViewContainer]); 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', () => { diff --git a/modules/angular2/test/core/compiler/integration_spec.js b/modules/angular2/test/core/compiler/integration_spec.js index 6ba577df23..a365d7b885 100644 --- a/modules/angular2/test/core/compiler/integration_spec.js +++ b/modules/angular2/test/core/compiler/integration_spec.js @@ -33,7 +33,7 @@ import {If} from 'angular2/src/directives/if'; import {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref'; 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'; @@ -851,7 +851,7 @@ class SimpleImperativeViewComponent { done; 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')]); } } diff --git a/modules/angular2/test/core/compiler/view_container_ref_spec.js b/modules/angular2/test/core/compiler/view_container_ref_spec.js index ad6bc45ed2..d132c2d30b 100644 --- a/modules/angular2/test/core/compiler/view_container_ref_spec.js +++ b/modules/angular2/test/core/compiler/view_container_ref_spec.js @@ -18,8 +18,9 @@ import { import {MapWrapper} from 'angular2/src/facade/collection'; 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 {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 {AppViewManager} from 'angular2/src/core/compiler/view_manager'; @@ -31,6 +32,10 @@ export function main() { var view; var viewManager; + function wrapView(view:AppView):ViewRef { + return new ViewRef(view); + } + function createProtoView() { return new AppProtoView(null, null); } @@ -47,7 +52,7 @@ export function main() { viewManager = new AppViewManagerSpy(); view = createView(); 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', () => { diff --git a/modules/angular2/test/core/compiler/view_manager_spec.js b/modules/angular2/test/core/compiler/view_manager_spec.js index ffcad16041..a54c0f5a8c 100644 --- a/modules/angular2/test/core/compiler/view_manager_spec.js +++ b/modules/angular2/test/core/compiler/view_manager_spec.js @@ -19,9 +19,11 @@ import {IMPLEMENTS, isBlank, isPresent} from 'angular2/src/facade/lang'; import {MapWrapper, ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection'; 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 {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 {Component} from 'angular2/src/core/annotations/annotations'; import {AppViewManager} from 'angular2/src/core/compiler/view_manager'; @@ -40,8 +42,16 @@ export function main() { var createdViews; var createdRenderViews; + function wrapPv(protoView:AppProtoView):ProtoViewRef { + return new ProtoViewRef(protoView); + } + + function wrapView(view:AppView):ViewRef { + return new ViewRef(view); + } + function elementRef(parentView, boundElementIndex) { - return new ElementRef(null, parentView, boundElementIndex, null, null, null); + return new ElementRef(parentView, boundElementIndex); } function createDirectiveBinding(type) { @@ -130,7 +140,7 @@ export function main() { var createRenderViewRefs = function(renderPvRef) { var res = []; for (var i=0; i { expect( - manager.createDynamicComponentView(elementRef(hostView, 0), componentProtoView, null, null) + internalView(manager.createDynamicComponentView(elementRef(wrapView(hostView), 0), wrapPv(componentProtoView), null, null)) ).toBe(createdViews[0]); expect(createdViews[0].proto).toBe(componentProtoView); }); @@ -173,36 +183,36 @@ export function main() { return createdView; }); expect( - manager.createDynamicComponentView(elementRef(hostView, 0), componentProtoView, null, null) + internalView(manager.createDynamicComponentView(elementRef(wrapView(hostView), 0), wrapPv(componentProtoView), null, null)) ).toBe(createdView); expect(utils.spy('createView')).not.toHaveBeenCalled(); }); 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]); }); it('should hydrate the dynamic component', () => { var injector = new Injector([], null, false); 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); }); 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); }); 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(createdViews[0].render).toBe(createdRenderViews[0]); }); 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]; expect(renderer.spy('setEventDispatcher')).toHaveBeenCalledWith(cmpView.render, cmpView); }); @@ -216,7 +226,7 @@ export function main() { )); var componentProtoView = createProtoView(); 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'); }); @@ -226,7 +236,7 @@ export function main() { )); var componentProtoView = createProtoView(); 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'); }); @@ -246,7 +256,7 @@ export function main() { hostView = createView(createProtoView( [createComponentElBinder(null)] )); - hostView.render = new ViewRef(); + hostView.render = new RenderViewRef(); nestedProtoView = createProtoView(); componentProtoView = createProtoView([ createComponentElBinder(nestedProtoView) @@ -254,23 +264,23 @@ export function main() { }); 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[1].proto).toBe(nestedProtoView); }); 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); }); 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]) }); 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]; expect(renderer.spy('setEventDispatcher')).toHaveBeenCalledWith(cmpView.render, cmpView); }); @@ -299,7 +309,7 @@ export function main() { )); parentView = createView(); utils.attachComponentView(parentHostView, 0, parentView); - parentView.render = new ViewRef(); + parentView.render = new RenderViewRef(); hostProtoView = createProtoView( [createComponentElBinder(null)] ); @@ -307,26 +317,26 @@ export function main() { it('should create the view', () => { expect( - manager.createInPlaceHostView(elementRef(parentHostView, 0), null, hostProtoView, null) + internalView(manager.createInPlaceHostView(elementRef(wrapView(parentHostView), 0), null, wrapPv(hostProtoView), null)) ).toBe(createdViews[0]); expect(createdViews[0].proto).toBe(hostProtoView); }); it('should attachAndHydrate the view', () => { 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); }); it('should create and set the render view', () => { 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(createdViews[0].render).toBe(createdRenderViews[0]); }); 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]; expect(renderer.spy('setEventDispatcher')).toHaveBeenCalledWith(cmpView.render, cmpView); }); @@ -344,32 +354,32 @@ export function main() { )); parentView = createView(); utils.attachComponentView(parentHostView, 0, parentView); - parentView.render = new ViewRef(); + parentView.render = new RenderViewRef(); hostProtoView = createProtoView( [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; }); it('should dehydrate', () => { - manager.destroyInPlaceHostView(elementRef(parentHostView, 0), hostView); + manager.destroyInPlaceHostView(elementRef(wrapView(parentHostView), 0), wrapView(hostView)); expect(utils.spy('detachInPlaceHostView')).toHaveBeenCalledWith(parentView, hostView); }); it('should detach', () => { - manager.destroyInPlaceHostView(elementRef(parentHostView, 0), hostView); + manager.destroyInPlaceHostView(elementRef(wrapView(parentHostView), 0), wrapView(hostView)); expect(utils.spy('dehydrateView')).toHaveBeenCalledWith(hostView); }); 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(hostView.render).toBe(null); }); 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); }); }); @@ -388,42 +398,42 @@ export function main() { parentView = createView(createProtoView( [createEmptyElBinder()] )); - parentView.render = new ViewRef(); + parentView.render = new RenderViewRef(); childProtoView = createProtoView(); }); 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(); }); it('should create the view', () => { expect( - manager.createViewInContainer(elementRef(parentView, 0), 0, childProtoView, null) + internalView(manager.createViewInContainer(elementRef(wrapView(parentView), 0), 0, wrapPv(childProtoView), null)) ).toBe(createdViews[0]); expect(createdViews[0].proto).toBe(childProtoView); }); 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]); }); it('should hydrate the view', () => { 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); }); 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( new RenderViewContainerRef(parentView.render, 0), 0, childProtoView.render); expect(createdViews[0].render).toBe(createdRenderViews[0]); }); 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]; expect(renderer.spy('setEventDispatcher')).toHaveBeenCalledWith(childView.render, childView); }); @@ -439,29 +449,29 @@ export function main() { parentView = createView(createProtoView( [createEmptyElBinder()] )); - parentView.render = new ViewRef(); + parentView.render = new RenderViewRef(); 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', () => { - manager.destroyViewInContainer(elementRef(parentView, 0), 0); + manager.destroyViewInContainer(elementRef(wrapView(parentView), 0), 0); expect(utils.spy('dehydrateView')).toHaveBeenCalledWith(parentView.viewContainers[0].views[0]); }); it('should detach', () => { - manager.destroyViewInContainer(elementRef(parentView, 0), 0); + manager.destroyViewInContainer(elementRef(wrapView(parentView), 0), 0); expect(utils.spy('detachViewInContainer')).toHaveBeenCalledWith(parentView, 0, 0); }); 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(childView.render).toBe(null); }); 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); }); }); @@ -472,29 +482,29 @@ export function main() { parentView = createView(createProtoView( [createEmptyElBinder()] )); - parentView.render = new ViewRef(); + parentView.render = new RenderViewRef(); 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', () => { - manager.destroyInPlaceHostView(null, parentView); + manager.destroyInPlaceHostView(null, wrapView(parentView)); expect(utils.spy('dehydrateView')).toHaveBeenCalledWith(parentView.viewContainers[0].views[0]); }); it('should detach', () => { - manager.destroyInPlaceHostView(null, parentView); + manager.destroyInPlaceHostView(null, wrapView(parentView)); expect(utils.spy('detachViewInContainer')).toHaveBeenCalledWith(parentView, 0, 0); }); 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(childView.render).toBe(null); }); it('should return the view to the pool', () => { - manager.destroyInPlaceHostView(null, parentView); + manager.destroyInPlaceHostView(null, wrapView(parentView)); expect(viewPool.spy('returnView')).toHaveBeenCalledWith(childView); }); @@ -513,7 +523,7 @@ export function main() { }); } -class MockProtoViewRef extends ProtoViewRef { +class MockProtoViewRef extends RenderProtoViewRef { nestedComponentCount:number; constructor(nestedComponentCount:number) { super(); diff --git a/modules/angular2/test/directives/non_bindable_spec.js b/modules/angular2/test/directives/non_bindable_spec.js index 1b5797a42e..3a9af514fa 100644 --- a/modules/angular2/test/directives/non_bindable_spec.js +++ b/modules/angular2/test/directives/non_bindable_spec.js @@ -15,7 +15,7 @@ import {DOM} from 'angular2/src/dom/dom_adapter'; import {Decorator, Component} from 'angular2/src/core/annotations/annotations'; 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'; @@ -67,7 +67,7 @@ class TestComponent { selector: '[test-dec]' }) class TestDecorator { - constructor(el: NgElement) { + constructor(el: ElementRef) { DOM.addClass(el.domElement, 'compiled'); } } diff --git a/modules/angular2/test/render/dom/integration_testbed.js b/modules/angular2/test/render/dom/integration_testbed.js index 293be42c3c..03ca1a987c 100644 --- a/modules/angular2/test/render/dom/integration_testbed.js +++ b/modules/angular2/test/render/dom/integration_testbed.js @@ -6,7 +6,7 @@ import {DOM} from 'angular2/src/dom/dom_adapter'; import {Parser, Lexer} from 'angular2/change_detection'; import {DirectDomRenderer} from 'angular2/src/render/dom/direct_dom_renderer'; 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 {TemplateLoader} from 'angular2/src/render/dom/compiler/template_loader'; import {UrlResolver} from 'angular2/src/services/url_resolver'; diff --git a/modules/angular2/test/render/dom/shadow_dom_emulation_integration_spec.js b/modules/angular2/test/render/dom/shadow_dom_emulation_integration_spec.js index 33e30ef0d9..c8a811bd7d 100644 --- a/modules/angular2/test/render/dom/shadow_dom_emulation_integration_spec.js +++ b/modules/angular2/test/render/dom/shadow_dom_emulation_integration_spec.js @@ -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 not lose focus', () => { // var temp = `aaa bbb`; diff --git a/modules/angular2/test/services/ruler_spec.js b/modules/angular2/test/services/ruler_spec.js index c4c44cede4..a67d84d98c 100644 --- a/modules/angular2/test/services/ruler_spec.js +++ b/modules/angular2/test/services/ruler_spec.js @@ -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 {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 {createRectangle} from './rectangle_mock'; - -class DomAdapterMock extends DomAdapter { - rect; - constructor(rect) { - super(); - this.rect = rect; - } - - getBoundingClientRect(elm) { - return this.rect; - } -} +import {IMPLEMENTS} from 'angular2/src/facade/lang'; function assertDimensions(rect: Rectangle, left, right, top, bottom, width, height) { expect(rect.left).toEqual(left); @@ -31,11 +23,14 @@ export function main() { describe('ruler service', () => { - it('should allow measuring NgElements', + it('should allow measuring ElementRefs', 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); async.done(); }); @@ -45,8 +40,9 @@ export function main() { it('should return 0 for all rectangle values while measuring elements in a document fragment', inject([AsyncTestCompleter], (async) => { var ruler = new Ruler(DOM); - - ruler.measure(new FakeNgElement(DOM.createElement('div'))).then((rect) => { + var elRef = new SpyElementRef(); + 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 assertDimensions(rect, 0, 0, 0, 0, 0, 0); async.done(); @@ -56,15 +52,17 @@ export function main() { }); } -class FakeNgElement extends NgElement { - _domElement; +@proxy +@IMPLEMENTS(ElementRef) +class SpyElementRef extends SpyObject { + domElement; + constructor(){super(ElementRef);} + noSuchMethod(m){return super.noSuchMethod(m)} +} - constructor(domElement) { - super(null, null); - this._domElement = domElement; - } - - get domElement() { - return this._domElement; - } -} \ No newline at end of file +@proxy +@IMPLEMENTS(DomAdapter) +class SpyDomAdapter extends SpyObject { + constructor(){super(DomAdapter);} + noSuchMethod(m){return super.noSuchMethod(m)} +} diff --git a/modules/benchmarks/src/tree/tree_benchmark.js b/modules/benchmarks/src/tree/tree_benchmark.js index e5e13719c1..88283e9afe 100644 --- a/modules/benchmarks/src/tree/tree_benchmark.js +++ b/modules/benchmarks/src/tree/tree_benchmark.js @@ -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 {reflector} from 'angular2/src/reflection/reflection'; diff --git a/modules/examples/src/hello_world/index_common.js b/modules/examples/src/hello_world/index_common.js index 168aaa6442..5c2c29a119 100644 --- a/modules/examples/src/hello_world/index_common.js +++ b/modules/examples/src/hello_world/index_common.js @@ -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'; // Angular 2.0 supports 3 basic types of directives: @@ -46,9 +46,9 @@ export class HelloCmp { selector: '[red]' }) 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. - constructor(el: NgElement) { + constructor(el: ElementRef) { el.domElement.style.color = 'red'; } }