refactor(ViewPort): @Template -> @Viewport, ViewPort -> ViewContainer

fixes #595
This commit is contained in:
Victor Berchet 2015-02-12 11:54:22 +01:00
parent 3519714f64
commit 6d23d00057
36 changed files with 408 additions and 376 deletions

View File

@ -8,7 +8,7 @@ export * from './src/core/compiler/compiler';
export * from './src/core/compiler/template_loader';
export * from './src/core/compiler/view';
export * from './src/core/compiler/viewport';
export * from './src/core/compiler/view_container';
export * from './src/core/compiler/binding_propagation_config';
export * from './src/core/dom/element';

View File

@ -10,7 +10,7 @@ There are three different kinds of directives (described in mored detailed in la
1. *Decorators*: can be placed on any DOM element and can be combined with other directives.
2. *Components*: Components have encapsulated view and can configure injectors.
3. *Instantiator*: Is responsible for adding or removing child views in parent view. (i.e. foreach, if)
3. *Viewport*: Is responsible for adding or removing child views in parent view. (i.e. foreach, if)
@ -164,43 +164,43 @@ Example of usage:
## Instantiator
## Viewport
Instantiator is a directive which can controll instantiation of child views which are then inserted into the DOM. (Examples are `if` and `foreach`.)
Viewport is a directive which can controll instantiation of child views which are then inserted into the DOM. (Examples are `if` and `foreach`.)
* Instantiators can only be placed on `<template>` elements (or the short hand version which uses `<element template>` attribute.)
* Only one instantiator can be present per DOM template element.
* The instantiator is is created over the `template` element. This is known as the `ViewPort`.
* Instantiator can insert child views into the `ViewPort`. The child views show up as siblings of the `ViewPort` in the DOM.
* Viewports can only be placed on `<template>` elements (or the short hand version which uses `<element template>` attribute.)
* Only one viewport can be present per DOM template element.
* The viewport is is created over the `template` element. This is known as the `ViewContainer`.
* Viewport can insert child views into the `ViewContainer`. The child views show up as siblings of the `Viewport` in the DOM.
>> TODO(misko): Relationship with Injection
>> TODO(misko): Instantiator can not be injected into child Views
```
@Instantiator({
@Viewport({
selector: '[if]',
bind: {
'if': 'condition'
}
})
export class If {
viewPort: ViewPort;
viewContainer: ViewContainer;
view: View;
constructor(viewPort: ViewPort) {
this.viewPort = viewPort;
this.view` = null;
constructor(viewContainer: ViewContainer) {
this.viewContainer = viewContainer;
this.view = null;
}
set condition(value) {
if (value) {
if (this.view == null) {
this.view = this.viewPort.create();
if (this.view === null) {
this.view = this.viewContainer.create();
}
} else {
if (this.view != null) {
this.viewPort.remove(this.view);
if (this.view !== null) {
this.viewContainer.remove(this.view);
this.view = null;
}
}

View File

@ -2,13 +2,25 @@
## Overview
This document explains the concept of a View. View is a core primitive used by angular to render the DOM tree. ViewPort is location in a View which can accept child Views. Views for a tree structure which mimics the DOM tree.
This document explains the concept of a View.
A View is a core primitive used by angular to render the DOM tree.
A ViewPort is location in a View which can accept child Views.
Every ViewPort has an associated ViewContainer than can contain any number of child Views.
Views form a tree structure which mimics the DOM tree.
* View is a core rendering construct. A running application is just a collection of Views which are nested in a tree like structure. The View tree is a simplified version of the DOM tree. A View can have a single DOM Element or large DOM structures. The key is that the DOM tree in the View can not undergo structural changes (only property changes).
* Views represent a running instance of a DOM Template. This implies that while elements in a View can change properties, they can not change structurally. (Structural changes such as, adding or removing elements requires adding or removing child Views into ViewPorts.)
* View can have zero or more ViewPorts. A ViewPort is a marker in the DOM which allows the insertion of child Views.
* Views are created from a ProtoView. A ProtoView is a compiled DOM Template which is efficient at creating Views.
* View contains a context object. The context represents the object instance against which all expressions are evaluated against.
* View is a core rendering construct. A running application is just a collection of Views which are
nested in a tree like structure. The View tree is a simplified version of the DOM tree. A View can
have a single DOM Element or large DOM structures. The key is that the DOM tree in the View can
not undergo structural changes (only property changes).
* Views represent a running instance of a DOM Template. This implies that while elements in a View
can change properties, they can not change structurally. (Structural changes such as, adding or
removing elements requires adding or removing child Views into ViewContainers).
* View can have zero or more ViewPorts. A ViewPort is a marker in the DOM which allows
the insertion of child Views.
* Views are created from a ProtoView. A ProtoView is a compiled DOM Template which is efficient at
creating Views.
* View contains a context object. The context represents the object instance against which all
expressions are evaluated.
* View contains a ChangeDetector for looking for detecting changes to the model.
* View contains ElementInjector for creating Directives.
@ -39,7 +51,10 @@ And assume following HTML Template:
</div>
```
The above template is compiled by the Compiler to create a ProtoView. The ProtoView is than used to create an instance of the View. The instantiation process involves cloning the above template and locating all of the elements which contain bindings and finally instantiating the Directives associated with the template. (See compilation for more details.)
The above template is compiled by the Compiler to create a ProtoView. The ProtoView is than used to
create an instance of the View. The instantiation process involves cloning the above template and
locating all of the elements which contain bindings and finally instantiating the Directives
associated with the template. (See compilation for more details.)
```
<div> | viewA(greeter)
@ -66,12 +81,14 @@ Note:
* View knows which expressions need to be watched.
* View knows what needs to be updated if the watched expression changes.
* All DOM elements are owned by single instance of the view.
* The structure of the DOM can not change during runtime. To Allow structural changes to DOM we need to understand Composed View.
* The structure of the DOM can not change during runtime. To Allow structural changes to DOM we need
to understand Composed View.
## Composed View
An important part of an application is to be able to change the DOM structure to render data for the user. In Angular this is done by inserting child views into the ViewPort.
An important part of an application is to be able to change the DOM structure to render data for the
user. In Angular this is done by inserting child views into the ViewPort.
Let's start with a Template such as:
@ -106,10 +123,12 @@ The next step is to compose these two ProtoViews into actual view which is rende
</ul> | viewA(SomeContexnt)
```
*Step2:* Instantiate `Foreach` directive which will receive the `ViewPort`. (The ViewPort has reference to `protoViewA`).
*Step2:* Instantiate `Foreach` directive which will receive the `ViewContainer`. (The ViewContainer
has a reference to `protoViewA`).
*Step3:* As the `Foreach` unrolls it asks the `ViewPort` to instantiate `protoViewB` and insert it after the `ViewPort` anchor. This is repeated for each `person` in `people`. Notice that
*Step3:* As the `Foreach` unrolls it asks the `ViewContainer` to instantiate `protoViewB` and insert
it after the `ViewPort` anchor. This is repeated for each `person` in `people`. Notice that
```
<ul> | viewA(someContext)
@ -119,7 +138,10 @@ The next step is to compose these two ProtoViews into actual view which is rende
</ul> | viewA(lomeContexnt)
```
*Step4:* All of the bindings in the child Views are updated. Notice that in the case of `Foreach` the evaluation context for the `viewB0` and `viewB1` are `locals0` and `locals1` respectively. Locals allow the introduction of new local variables visible only within the scope of the View, and delegate any unknown references to the parent context.
*Step4:* All of the bindings in the child Views are updated. Notice that in the case of `Foreach`
the evaluation context for the `viewB0` and `viewB1` are `locals0` and `locals1` respectively.
Locals allow the introduction of new local variables visible only within the scope of the View, and
delegate any unknown references to the parent context.
```
<ul> | viewA
@ -129,11 +151,18 @@ The next step is to compose these two ProtoViews into actual view which is rende
</ul> | viewA
```
Each View can have zero or more ViewPorts. By inserting and removing child Views to and from the ViewPort, the application can mutate the DOM structure to any desirable state. A View contain individual nodes or complex DOM structure. The insertion points for the child Views, known as ViewPorts, contain a DOM element which acts as an anchor. The anchor is either a `template` or a `script` element depending on your browser. It is used to identify where the child Views will be inserted.
Each View can have zero or more ViewPorts. By inserting and removing child Views to and from the
ViewContainers, the application can mutate the DOM structure to any desirable state. A View contain
individual nodes or complex DOM structure. The insertion points for the child Views, known as
ViewContainers, contain a DOM element which acts as an anchor. The anchor is either a `template` or
a `script` element depending on your browser. It is used to identify where the child Views will be
inserted.
## Component Views
A View can also contain Components. Components contain Shadow DOM for encapsulating their internal rendering state. Unlike ViewPorts which can contain zero or more Views, the Component always contain exactly one Shadow View.
A View can also contain Components. Components contain Shadow DOM for encapsulating their internal
rendering state. Unlike ViewPorts which can contain zero or more Views, the Component always contain
exactly one Shadow View.
```
<div> | viewA
@ -176,7 +205,8 @@ And assume following HTML Template:
</div> | viewA(greeter)
```
The above UI is built using a single View, and hence single context `greeter`. It can be expressed in this pseudo-code.
The above UI is built using a single View, and hence single context `greeter`. It can be expressed
in this pseudo-code.
```
var greeter = new Greeter();
@ -185,14 +215,16 @@ var greeter = new Greeter();
The View contains two bindings:
1. `greeting`: This is bound to the `greeting` property on the `Greeter` instance.
2. `name.value`: This poses a problem. There is no `name` property on `Greeter` instance. To solve this we wrap the `Greeter` instance in the `Local` instance like so:
2. `name.value`: This poses a problem. There is no `name` property on `Greeter` instance. To solve
this we wrap the `Greeter` instance in the `Local` instance like so:
```
var greeter = new Locals(new Greeter(), {name: ref_to_input_element })
```
By wrapping the `Greeter` instance into the `Locals` we allow the view to introduce variables which are in addition to
the `Greeter` instance. During the resolution of the expressions we first check the locals, and then `Greeter` instance.
By wrapping the `Greeter` instance into the `Locals` we allow the view to introduce variables which
are in addition to the `Greeter` instance. During the resolution of the expressions we first check
the locals, and then `Greeter` instance.
@ -201,9 +233,14 @@ the `Greeter` instance. During the resolution of the expressions we first check
Views transition through a particular set of states:
1. View is created from the ProtoView.
2. View can be attached to an existing ViewPort.
3. Upon attaching View to the ViewPort the View needs to be hydrated. The hydration process involves instantiating all of the Directives associated with the current View.
4. At this point the view is ready and renderable. Multiple changes can be delivered to the Directives from the ChangeDetection.
5. At some point the View can be removed. At this point all of the directives are destroyed during the dehydration precess and the view becomes inactive.
6. The View has to wait until it is detached from the DOM. The delay in detaching could be caused because an animation is animating the view away.
7. After the View is detached from the DOM it is ready to be reused. The view reuse allows the application to be faster in subsequent renderings.
2. View can be attached to an existing ViewContainer.
3. Upon attaching View to the ViewContainer the View needs to be hydrated. The hydration process
involves instantiating all of the Directives associated with the current View.
4. At this point the view is ready and renderable. Multiple changes can be delivered to the
Directives from the ChangeDetection.
5. At some point the View can be removed. At this point all of the directives are destroyed during
the dehydration process and the view becomes inactive.
6. The View has to wait until it is detached from the DOM. The delay in detaching could be caused
because an animation is animating the view away.
7. After the View is detached from the DOM it is ready to be reused. The view reuse allows the
application to be faster in subsequent renderings.

View File

@ -111,7 +111,7 @@ export class Decorator extends Directive {
}
}
export class Template extends Directive {
export class Viewport extends Directive {
@CONST()
constructor({
selector,

View File

@ -8,16 +8,17 @@ import {ProtoView} from './view';
export class ElementBinder {
protoElementInjector:ProtoElementInjector;
componentDirective:DirectiveMetadata;
templateDirective:DirectiveMetadata;
viewportDirective:DirectiveMetadata;
textNodeIndices:List<int>;
hasElementPropertyBindings:boolean;
nestedProtoView: ProtoView;
events:Map;
constructor(
protoElementInjector: ProtoElementInjector, componentDirective:DirectiveMetadata, templateDirective:DirectiveMetadata) {
protoElementInjector: ProtoElementInjector, componentDirective:DirectiveMetadata,
viewportDirective:DirectiveMetadata) {
this.protoElementInjector = protoElementInjector;
this.componentDirective = componentDirective;
this.templateDirective = templateDirective;
this.viewportDirective = viewportDirective;
// updated later when events are bound
this.events = null;
// updated later when text nodes are bound

View File

@ -6,7 +6,7 @@ import {Parent, Ancestor} from 'angular2/src/core/annotations/visibility';
import {EventEmitter} from 'angular2/src/core/annotations/events';
import {View, ProtoView} from 'angular2/src/core/compiler/view';
import {LightDom, SourceLightDom, DestinationLightDom} from 'angular2/src/core/compiler/shadow_dom_emulation/light_dom';
import {ViewPort} from 'angular2/src/core/compiler/viewport';
import {ViewContainer} from 'angular2/src/core/compiler/view_container';
import {NgElement} from 'angular2/src/core/dom/element';
import {Directive, onChange, onDestroy} from 'angular2/src/core/annotations/annotations'
import {BindingPropagationConfig} from 'angular2/src/core/compiler/binding_propagation_config'
@ -22,7 +22,7 @@ var _staticKeys;
class StaticKeys {
viewId:number;
ngElementId:number;
viewPortId:number;
viewContainerId:number;
destinationLightDomId:number;
sourceLightDomId:number;
bindingPropagationConfigId:number;
@ -31,7 +31,7 @@ class StaticKeys {
//TODO: vsavkin Key.annotate(Key.get(View), 'static')
this.viewId = Key.get(View).id;
this.ngElementId = Key.get(NgElement).id;
this.viewPortId = Key.get(ViewPort).id;
this.viewContainerId = Key.get(ViewContainer).id;
this.destinationLightDomId = Key.get(DestinationLightDom).id;
this.sourceLightDomId = Key.get(SourceLightDom).id;
this.bindingPropagationConfigId = Key.get(BindingPropagationConfig).id;
@ -152,14 +152,14 @@ export class DirectiveBinding extends Binding {
export class PreBuiltObjects {
view:View;
element:NgElement;
viewPort:ViewPort;
viewContainer:ViewContainer;
lightDom:LightDom;
bindingPropagationConfig:BindingPropagationConfig;
constructor(view, element:NgElement, viewPort:ViewPort, lightDom:LightDom,
constructor(view, element:NgElement, viewContainer:ViewContainer, lightDom:LightDom,
bindingPropagationConfig:BindingPropagationConfig) {
this.view = view;
this.element = element;
this.viewPort = viewPort;
this.viewContainer = viewContainer;
this.lightDom = lightDom;
this.bindingPropagationConfig = bindingPropagationConfig;
}
@ -557,7 +557,7 @@ export class ElementInjector extends TreeNode {
var staticKeys = StaticKeys.instance();
if (keyId === staticKeys.viewId) return this._preBuiltObjects.view;
if (keyId === staticKeys.ngElementId) return this._preBuiltObjects.element;
if (keyId === staticKeys.viewPortId) return this._preBuiltObjects.viewPort;
if (keyId === staticKeys.viewContainerId) return this._preBuiltObjects.viewContainer;
if (keyId === staticKeys.bindingPropagationConfigId) return this._preBuiltObjects.bindingPropagationConfig;
if (keyId === staticKeys.destinationLightDomId) {
var p:ElementInjector = this.directParent();

View File

@ -2,9 +2,7 @@ import {List, Map, ListWrapper, MapWrapper} from 'angular2/src/facade/collection
import {Element, DOM} from 'angular2/src/facade/dom';
import {int, isBlank, isPresent, Type} from 'angular2/src/facade/lang';
import {DirectiveMetadata} from '../directive_metadata';
import {Decorator} from '../../annotations/annotations';
import {Component} from '../../annotations/annotations';
import {Template} from '../../annotations/annotations';
import {Decorator, Component, Viewport} from '../../annotations/annotations';
import {ElementBinder} from '../element_binder';
import {ProtoElementInjector} from '../element_injector';
import {ProtoView} from '../view';
@ -29,7 +27,7 @@ export class CompileElement {
/// Template name is how it is reffered to it in template
variableBindings:Map;
decoratorDirectives:List<DirectiveMetadata>;
templateDirective:DirectiveMetadata;
viewportDirective:DirectiveMetadata;
componentDirective:DirectiveMetadata;
_allDirectives:List<DirectiveMetadata>;
isViewRoot:boolean;
@ -50,7 +48,7 @@ export class CompileElement {
this.eventBindings = null;
this.variableBindings = null;
this.decoratorDirectives = null;
this.templateDirective = null;
this.viewportDirective = null;
this.componentDirective = null;
this._allDirectives = null;
this.isViewRoot = false;
@ -141,8 +139,8 @@ export class CompileElement {
if (!annotation.compileChildren) {
this.compileChildren = false;
}
} else if (annotation instanceof Template) {
this.templateDirective = directive;
} else if (annotation instanceof Viewport) {
this.viewportDirective = directive;
} else if (annotation instanceof Component) {
this.componentDirective = directive;
}
@ -156,8 +154,8 @@ export class CompileElement {
if (isPresent(this.componentDirective)) {
ListWrapper.push(directives, this.componentDirective);
}
if (isPresent(this.templateDirective)) {
ListWrapper.push(directives, this.templateDirective);
if (isPresent(this.viewportDirective)) {
ListWrapper.push(directives, this.viewportDirective);
}
if (isPresent(this.decoratorDirectives)) {
directives = ListWrapper.concat(directives, this.decoratorDirectives);

View File

@ -5,8 +5,7 @@ import {SelectorMatcher} from '../selector';
import {CssSelector} from '../selector';
import {DirectiveMetadata} from '../directive_metadata';
import {Template} from '../../annotations/annotations';
import {Component} from '../../annotations/annotations';
import {Component, Viewport} from '../../annotations/annotations';
import {CompileStep} from './compile_step';
import {CompileElement} from './compile_element';
import {CompileControl} from './compile_control';
@ -70,10 +69,10 @@ export class DirectiveParser extends CompileStep {
// only be present on <template> elements any more!
var isTemplateElement = current.element instanceof TemplateElement;
this._selectorMatcher.match(cssSelector, (directive) => {
if (directive.annotation instanceof Template) {
if (directive.annotation instanceof Viewport) {
if (!isTemplateElement) {
throw new BaseException('Template directives need to be placed on <template> elements or elements with template attribute!');
} else if (isPresent(current.templateDirective)) {
throw new BaseException('Viewport directives need to be placed on <template> elements or elements with template attribute!');
} else if (isPresent(current.viewportDirective)) {
throw new BaseException('Only one template directive per element is allowed!');
}
} else if (isTemplateElement) {

View File

@ -78,7 +78,7 @@ function styleSetterFactory(styleName:string, stylesuffix:string) {
* - CompileElement#eventBindings
* - CompileElement#decoratorDirectives
* - CompileElement#componentDirective
* - CompileElement#templateDirective
* - CompileElement#viewportDirective
*
* Note: This actually only needs the CompileElements with the flags
* `hasBindings` and `isViewRoot`,
@ -105,7 +105,7 @@ export class ElementBinderBuilder extends CompileStep {
current.inheritedProtoElementInjector : null;
elementBinder = protoView.bindElement(currentProtoElementInjector,
current.componentDirective, current.templateDirective);
current.componentDirective, current.viewportDirective);
if (isPresent(current.textNodeBindings)) {
this._bindTextNodes(protoView, current);

View File

@ -22,7 +22,7 @@ const NG_BINDING_CLASS = 'ng-binding';
* - CompileElement#eventBindings
* - CompileElement#decoratorDirectives
* - CompileElement#componentDirective
* - CompileElement#templateDirective
* - CompileElement#viewportDirective
*/
export class ElementBindingMarker extends CompileStep {
process(parent:CompileElement, current:CompileElement, control:CompileControl) {
@ -36,7 +36,7 @@ export class ElementBindingMarker extends CompileStep {
(isPresent(current.variableBindings) && MapWrapper.size(current.variableBindings)>0) ||
(isPresent(current.eventBindings) && MapWrapper.size(current.eventBindings)>0) ||
(isPresent(current.decoratorDirectives) && current.decoratorDirectives.length > 0) ||
isPresent(current.templateDirective) ||
isPresent(current.viewportDirective) ||
isPresent(current.componentDirective);
if (hasBindings) {

View File

@ -23,7 +23,7 @@ import {DirectiveMetadata} from '../directive_metadata';
* - CompileElement#inheritedProtoView
* - CompileElement#decoratorDirectives
* - CompileElement#componentDirective
* - CompileElement#templateDirective
* - CompileElement#viewportDirective
*/
export class ProtoElementInjectorBuilder extends CompileStep {
// public so that we can overwrite it in tests
@ -52,8 +52,8 @@ export class ProtoElementInjectorBuilder extends CompileStep {
);
current.distanceToParentInjector = 0;
// Template directives are treated differently than other element with var- definitions.
if (isPresent(current.variableBindings) && !isPresent(current.templateDirective)) {
// Viewport directives are treated differently than other element with var- definitions.
if (isPresent(current.variableBindings) && !isPresent(current.viewportDirective)) {
current.inheritedProtoElementInjector.exportComponent = hasComponent;
current.inheritedProtoElementInjector.exportElement = !hasComponent;

View File

@ -4,7 +4,7 @@ import {isBlank, isPresent} from 'angular2/src/facade/lang';
import {View} from '../view';
import {ElementInjector} from '../element_injector';
import {ViewPort} from '../viewport';
import {ViewContainer} from '../view_container';
import {Content} from './content_tag';
export class SourceLightDom {}
@ -60,9 +60,9 @@ export class LightDom {
if (ei.hasDirective(Content)) {
ListWrapper.push(acc, ei.get(Content));
} else if (ei.hasPreBuiltObject(ViewPort)) {
var vp = ei.get(ViewPort);
ListWrapper.forEach(vp.contentTagContainers(), (view) => {
} else if (ei.hasPreBuiltObject(ViewContainer)) {
var vc = ei.get(ViewContainer);
ListWrapper.forEach(vc.contentTagContainers(), (view) => {
this._collectAllContentTags(view, acc);
});
}
@ -71,7 +71,7 @@ export class LightDom {
}
// Collects the nodes of the light DOM by merging:
// - nodes from enclosed ViewPorts,
// - nodes from enclosed ViewContainers,
// - nodes from enclosed content tags,
// - plain DOM nodes
expandedDomNodes():List {
@ -83,9 +83,9 @@ export class LightDom {
var root = roots[i];
var ei = root.injector;
if (isPresent(ei) && ei.hasPreBuiltObject(ViewPort)) {
var vp = root.injector.get(ViewPort);
res = ListWrapper.concat(res, vp.nodes());
if (isPresent(ei) && ei.hasPreBuiltObject(ViewContainer)) {
var vc = root.injector.get(ViewContainer);
res = ListWrapper.concat(res, vc.nodes());
} else if (isPresent(ei) && ei.hasDirective(Content)) {
var content = root.injector.get(Content);

View File

@ -11,7 +11,7 @@ import {SetterFn} from 'angular2/src/reflection/types';
import {FIELD, IMPLEMENTS, int, isPresent, isBlank, BaseException} from 'angular2/src/facade/lang';
import {Injector} from 'angular2/di';
import {NgElement} from 'angular2/src/core/dom/element';
import {ViewPort} from './viewport';
import {ViewContainer} from './view_container';
import {Content} from './shadow_dom_emulation/content_tag';
import {LightDom, DestinationLightDom} from './shadow_dom_emulation/light_dom';
import {ShadowDomStrategy} from './shadow_dom_strategy';
@ -42,7 +42,7 @@ export class View {
/// to keep track of the nodes.
nodes:List<Node>;
componentChildViews: List<View>;
viewPorts: List<ViewPort>;
viewContainers: List<ViewContainer>;
preBuiltObjects: List<PreBuiltObjects>;
proto: ProtoView;
context: any;
@ -57,7 +57,7 @@ export class View {
this.textNodes = null;
this.bindElements = null;
this.componentChildViews = null;
this.viewPorts = null;
this.viewContainers = null;
this.preBuiltObjects = null;
this.context = null;
this.contextWithLocals = (MapWrapper.size(protoContextLocals) > 0)
@ -65,12 +65,13 @@ export class View {
: null;
}
init(elementInjectors:List, rootElementInjectors:List, textNodes: List, bindElements:List, viewPorts:List, preBuiltObjects:List, componentChildViews:List) {
init(elementInjectors:List, rootElementInjectors:List, textNodes: List, bindElements:List,
viewContainers:List, preBuiltObjects:List, componentChildViews:List) {
this.elementInjectors = elementInjectors;
this.rootElementInjectors = rootElementInjectors;
this.textNodes = textNodes;
this.bindElements = bindElements;
this.viewPorts = viewPorts;
this.viewContainers = viewContainers;
this.preBuiltObjects = preBuiltObjects;
this.componentChildViews = componentChildViews;
}
@ -117,7 +118,7 @@ export class View {
*
* - all element injectors are empty.
* - all appInjectors are released.
* - all viewports are empty.
* - all viewcontainers are empty.
* - all context locals are set to null.
* - the view context is null.
*
@ -129,9 +130,9 @@ export class View {
if (this.hydrated()) throw new BaseException('The view is already hydrated.');
this._hydrateContext(context);
// viewPorts
for (var i = 0; i < this.viewPorts.length; i++) {
this.viewPorts[i].hydrate(appInjector, hostElementInjector);
// viewContainers
for (var i = 0; i < this.viewContainers.length; i++) {
this.viewContainers[i].hydrate(appInjector, hostElementInjector);
}
var binders = this.proto.elementBinders;
@ -201,10 +202,10 @@ export class View {
}
}
// viewPorts
if (isPresent(this.viewPorts)) {
for (var i = 0; i < this.viewPorts.length; i++) {
this.viewPorts[i].dehydrate();
// viewContainers
if (isPresent(this.viewContainers)) {
for (var i = 0; i < this.viewContainers.length; i++) {
this.viewContainers[i].dehydrate();
}
}
@ -341,7 +342,7 @@ export class ProtoView {
var textNodes = [];
var elementsWithPropertyBindings = [];
var preBuiltObjects = ListWrapper.createFixedSize(binders.length);
var viewPorts = [];
var viewContainers = [];
var componentChildViews = [];
for (var i = 0; i < binders.length; i++) {
@ -399,18 +400,18 @@ export class ProtoView {
ListWrapper.push(componentChildViews, childView);
}
// viewPorts
var viewPort = null;
if (isPresent(binder.templateDirective)) {
// viewContainers
var viewContainer = null;
if (isPresent(binder.viewportDirective)) {
var destLightDom = this._directParentElementLightDom(protoElementInjector, preBuiltObjects);
viewPort = new ViewPort(view, element, binder.nestedProtoView, elementInjector,
viewContainer = new ViewContainer(view, element, binder.nestedProtoView, elementInjector,
eventManager, destLightDom);
ListWrapper.push(viewPorts, viewPort);
ListWrapper.push(viewContainers, viewContainer);
}
// preBuiltObjects
if (isPresent(elementInjector)) {
preBuiltObjects[i] = new PreBuiltObjects(view, new NgElement(element), viewPort,
preBuiltObjects[i] = new PreBuiltObjects(view, new NgElement(element), viewContainer,
lightDom, bindingPropagationConfig);
}
@ -426,7 +427,7 @@ export class ProtoView {
}
view.init(elementInjectors, rootElementInjectors, textNodes, elementsWithPropertyBindings,
viewPorts, preBuiltObjects, componentChildViews);
viewContainers, preBuiltObjects, componentChildViews);
return view;
}
@ -461,8 +462,8 @@ export class ProtoView {
}
bindElement(protoElementInjector:ProtoElementInjector,
componentDirective:DirectiveMetadata = null, templateDirective:DirectiveMetadata = null):ElementBinder {
var elBinder = new ElementBinder(protoElementInjector, componentDirective, templateDirective);
componentDirective:DirectiveMetadata = null, viewportDirective:DirectiveMetadata = null):ElementBinder {
var elBinder = new ElementBinder(protoElementInjector, componentDirective, viewportDirective);
ListWrapper.push(this.elementBinders, elBinder);
return elBinder;
}

View File

@ -7,7 +7,7 @@ import {ElementInjector} from 'angular2/src/core/compiler/element_injector';
import {isPresent, isBlank} from 'angular2/src/facade/lang';
import {EventManager} from 'angular2/src/core/events/event_manager';
export class ViewPort {
export class ViewContainer {
parentView: View;
templateElement: Element;
defaultProtoView: ProtoView;
@ -71,7 +71,7 @@ export class ViewPort {
// to the methods below.
create(atIndex=-1): View {
if (!this.hydrated()) throw new BaseException(
'Cannot create views on a dehydrated view port');
'Cannot create views on a dehydrated ViewContainer');
// TODO(rado): replace with viewFactory.
var newView = this.defaultProtoView.instantiate(this.hostElementInjector, this._eventManager);
newView.hydrate(this.appInjector, this.hostElementInjector, this.parentView.context);
@ -82,7 +82,7 @@ export class ViewPort {
if (atIndex == -1) atIndex = this._views.length;
ListWrapper.insert(this._views, atIndex, view);
if (isBlank(this._lightDom)) {
ViewPort.moveViewNodesAfterSibling(this._siblingToInsertAfter(atIndex), view);
ViewContainer.moveViewNodesAfterSibling(this._siblingToInsertAfter(atIndex), view);
} else {
this._lightDom.redistribute();
}
@ -109,7 +109,7 @@ export class ViewPort {
var detachedView = this.get(atIndex);
ListWrapper.removeAt(this._views, atIndex);
if (isBlank(this._lightDom)) {
ViewPort.removeViewNodesFromParent(this.templateElement.parentNode, detachedView);
ViewContainer.removeViewNodesFromParent(this.templateElement.parentNode, detachedView);
} else {
this._lightDom.redistribute();
}

View File

@ -1,11 +1,11 @@
import {Template, onChange} from 'angular2/src/core/annotations/annotations';
import {Viewport, onChange} from 'angular2/src/core/annotations/annotations';
import {OnChange} from 'angular2/src/core/compiler/interfaces';
import {ViewPort} from 'angular2/src/core/compiler/viewport';
import {ViewContainer} from 'angular2/src/core/compiler/view_container';
import {View} from 'angular2/src/core/compiler/view';
import {isPresent, isBlank} from 'angular2/src/facade/lang';
import {ListWrapper} from 'angular2/src/facade/collection';
@Template({
@Viewport({
selector: '[foreach][in]',
lifecycle: [onChange],
bind: {
@ -13,16 +13,16 @@ import {ListWrapper} from 'angular2/src/facade/collection';
}
})
export class Foreach extends OnChange {
viewPort: ViewPort;
viewContainer: ViewContainer;
iterable;
constructor(viewPort: ViewPort) {
constructor(viewContainer: ViewContainer) {
super();
this.viewPort = viewPort;
this.viewContainer = viewContainer;
}
onChange(changes) {
var iteratorChanges = changes['iterable'];
if (isBlank(iteratorChanges) || isBlank(iteratorChanges.currentValue)) {
this.viewPort.clear();
this.viewContainer.clear();
return;
}
@ -37,13 +37,13 @@ export class Foreach extends OnChange {
(movedRecord) => ListWrapper.push(recordViewTuples, new RecordViewTuple(movedRecord, null))
);
var insertTuples = Foreach.bulkRemove(recordViewTuples, this.viewPort);
var insertTuples = Foreach.bulkRemove(recordViewTuples, this.viewContainer);
iteratorChanges.currentValue.forEachAddedItem(
(addedRecord) => ListWrapper.push(insertTuples, new RecordViewTuple(addedRecord, null))
);
Foreach.bulkInsert(insertTuples, this.viewPort);
Foreach.bulkInsert(insertTuples, this.viewContainer);
for (var i = 0; i < insertTuples.length; i++) {
this.perViewChange(insertTuples[i].view, insertTuples[i].record);
@ -55,30 +55,30 @@ export class Foreach extends OnChange {
view.setLocal('index', record.currentIndex);
}
static bulkRemove(tuples, viewPort) {
static bulkRemove(tuples, viewContainer) {
tuples.sort((a, b) => a.record.previousIndex - b.record.previousIndex);
var movedTuples = [];
for (var i = tuples.length - 1; i >= 0; i--) {
var tuple = tuples[i];
// separate moved views from removed views.
if (isPresent(tuple.record.currentIndex)) {
tuple.view = viewPort.detach(tuple.record.previousIndex);
tuple.view = viewContainer.detach(tuple.record.previousIndex);
ListWrapper.push(movedTuples, tuple);
} else {
viewPort.remove(tuple.record.previousIndex);
viewContainer.remove(tuple.record.previousIndex);
}
}
return movedTuples;
}
static bulkInsert(tuples, viewPort) {
static bulkInsert(tuples, viewContainer) {
tuples.sort((a, b) => a.record.currentIndex - b.record.currentIndex);
for (var i = 0; i < tuples.length; i++) {
var tuple = tuples[i];
if (isPresent(tuple.view)) {
viewPort.insert(tuple.view, tuple.record.currentIndex);
viewContainer.insert(tuple.view, tuple.record.currentIndex);
} else {
tuple.view = viewPort.create(tuple.record.currentIndex);
tuple.view = viewContainer.create(tuple.record.currentIndex);
}
}
return tuples;

View File

@ -1,29 +1,29 @@
import {Template} from 'angular2/src/core/annotations/annotations';
import {ViewPort} from 'angular2/src/core/compiler/viewport';
import {Viewport} from 'angular2/src/core/annotations/annotations';
import {ViewContainer} from 'angular2/src/core/compiler/view_container';
import {isBlank} from 'angular2/src/facade/lang';
@Template({
@Viewport({
selector: '[if]',
bind: {
'if': 'condition'
}
})
export class If {
viewPort: ViewPort;
viewContainer: ViewContainer;
prevCondition: boolean;
constructor(viewPort: ViewPort) {
this.viewPort = viewPort;
constructor(viewContainer: ViewContainer) {
this.viewContainer = viewContainer;
this.prevCondition = null;
}
set condition(newCondition) {
if (newCondition && (isBlank(this.prevCondition) || !this.prevCondition)) {
this.prevCondition = true;
this.viewPort.create();
this.viewContainer.create();
} else if (!newCondition && (isBlank(this.prevCondition) || this.prevCondition)) {
this.prevCondition = false;
this.viewPort.clear();
this.viewContainer.clear();
}
}
}

View File

@ -1,8 +1,8 @@
import {Decorator, Template} from 'angular2/src/core/annotations/annotations';
import {ViewPort} from 'angular2/src/core/compiler/viewport';
import {Decorator, Viewport} from 'angular2/src/core/annotations/annotations';
import {ViewContainer} from 'angular2/src/core/compiler/view_container';
import {NgElement} from 'angular2/src/core/dom/element';
import {DOM} from 'angular2/src/facade/dom';
import {isPresent, isBlank} from 'angular2/src/facade/lang';
import {isPresent, isBlank, normalizeBlank} from 'angular2/src/facade/lang';
import {ListWrapper, List, MapWrapper, Map} from 'angular2/src/facade/collection';
import {Parent} from 'angular2/src/core/annotations/visibility';
@ -40,89 +40,89 @@ import {Parent} from 'angular2/src/core/annotations/visibility';
export class Switch {
_switchValue: any;
_useDefault: boolean;
_valueViewPorts: Map;
_activeViewPorts: List;
_valueViewContainers: Map;
_activeViewContainers: List<ViewContainer>;
constructor() {
this._valueViewPorts = MapWrapper.create();
this._activeViewPorts = ListWrapper.create();
this._valueViewContainers = MapWrapper.create();
this._activeViewContainers = ListWrapper.create();
this._useDefault = false;
}
set value(value) {
// Remove the currently active viewports
this._removeAllActiveViewPorts();
// Empty the currently active ViewContainers
this._emptyAllActiveViewContainers();
// Add the viewports matching the value (with a fallback to default)
// Add the ViewContainers matching the value (with a fallback to default)
this._useDefault = false;
var viewPorts = MapWrapper.get(this._valueViewPorts, value);
if (isBlank(viewPorts)) {
var containers = MapWrapper.get(this._valueViewContainers, value);
if (isBlank(containers)) {
this._useDefault = true;
viewPorts = MapWrapper.get(this._valueViewPorts, _whenDefault);
containers = normalizeBlank(MapWrapper.get(this._valueViewContainers, _whenDefault));
}
this._activateViewPorts(viewPorts);
this._activateViewContainers(containers);
this._switchValue = value;
}
_onWhenValueChanged(oldWhen, newWhen, viewPort: ViewPort) {
this._deregisterViewPort(oldWhen, viewPort);
this._registerViewPort(newWhen, viewPort);
_onWhenValueChanged(oldWhen, newWhen, viewContainer: ViewContainer) {
this._deregisterViewContainer(oldWhen, viewContainer);
this._registerViewContainer(newWhen, viewContainer);
if (oldWhen === this._switchValue) {
viewPort.remove();
ListWrapper.remove(this._activeViewPorts, viewPort);
viewContainer.remove();
ListWrapper.remove(this._activeViewContainers, viewContainer);
} else if (newWhen === this._switchValue) {
if (this._useDefault) {
this._useDefault = false;
this._removeAllActiveViewPorts();
this._emptyAllActiveViewContainers();
}
viewPort.create();
ListWrapper.push(this._activeViewPorts, viewPort);
viewContainer.create();
ListWrapper.push(this._activeViewContainers, viewContainer);
}
// Switch to default when there is no more active viewports
if (this._activeViewPorts.length === 0 && !this._useDefault) {
// Switch to default when there is no more active ViewContainers
if (this._activeViewContainers.length === 0 && !this._useDefault) {
this._useDefault = true;
this._activateViewPorts(MapWrapper.get(this._valueViewPorts, _whenDefault));
this._activateViewContainers(MapWrapper.get(this._valueViewContainers, _whenDefault));
}
}
_removeAllActiveViewPorts() {
var activeViewPorts = this._activeViewPorts;
for (var i = 0; i < activeViewPorts.length; i++) {
activeViewPorts[i].remove();
_emptyAllActiveViewContainers() {
var activeContainers = this._activeViewContainers;
for (var i = 0; i < activeContainers.length; i++) {
activeContainers[i].remove();
}
this._activeViewPorts = ListWrapper.create();
this._activeViewContainers = ListWrapper.create();
}
_activateViewPorts(viewPorts) {
// TODO(vicb): assert(this._activeViewPorts.length === 0);
if (isPresent(viewPorts)) {
for (var i = 0; i < viewPorts.length; i++) {
viewPorts[i].create();
_activateViewContainers(containers: List<ViewContainer>) {
// TODO(vicb): assert(this._activeViewContainers.length === 0);
if (isPresent(containers)) {
for (var i = 0; i < containers.length; i++) {
containers[i].create();
}
this._activeViewPorts = viewPorts;
this._activeViewContainers = containers;
}
}
_registerViewPort(value, viewPort: ViewPort) {
var viewPorts = MapWrapper.get(this._valueViewPorts, value);
if (isBlank(viewPorts)) {
viewPorts = ListWrapper.create();
MapWrapper.set(this._valueViewPorts, value, viewPorts);
_registerViewContainer(value, container: ViewContainer) {
var containers = MapWrapper.get(this._valueViewContainers, value);
if (isBlank(containers)) {
containers = ListWrapper.create();
MapWrapper.set(this._valueViewContainers, value, containers);
}
ListWrapper.push(viewPorts, viewPort);
ListWrapper.push(containers, container);
}
_deregisterViewPort(value, viewPort: ViewPort) {
_deregisterViewContainer(value, container: ViewContainer) {
// `_whenDefault` is used a marker for non-registered whens
if (value == _whenDefault) return;
var viewPorts = MapWrapper.get(this._valueViewPorts, value);
if (viewPorts.length == 1) {
MapWrapper.delete(this._valueViewPorts, value);
var containers = MapWrapper.get(this._valueViewContainers, value);
if (containers.length == 1) {
MapWrapper.delete(this._valueViewContainers, value);
} else {
ListWrapper.remove(viewPorts, viewPort);
ListWrapper.remove(containers, container);
}
}
}
@ -142,7 +142,7 @@ export class Switch {
* <template [switch-when]="'stringValue'">...</template>
* ```
*/
@Template({
@Viewport({
selector: '[switch-when]',
bind: {
'switch-when' : 'when'
@ -151,17 +151,17 @@ export class Switch {
export class SwitchWhen {
_value: any;
_switch: Switch;
_viewPort: ViewPort;
_viewContainer: ViewContainer;
constructor(el: NgElement, viewPort: ViewPort, @Parent() sswitch: Switch) {
constructor(el: NgElement, viewContainer: ViewContainer, @Parent() sswitch: Switch) {
// `_whenDefault` is used as a marker for a not yet initialized value
this._value = _whenDefault;
this._switch = sswitch;
this._viewPort = viewPort;
this._viewContainer = viewContainer;
}
set when(value) {
this._switch._onWhenValueChanged(this._value, value, this._viewPort);
this._switch._onWhenValueChanged(this._value, value, this._viewContainer);
this._value = value;
}
}
@ -178,12 +178,12 @@ export class SwitchWhen {
* <template [switch-default]>...</template>
* ```
*/
@Template({
@Viewport({
selector: '[switch-default]'
})
export class SwitchDefault {
constructor(viewPort: ViewPort, @Parent() sswitch: Switch) {
sswitch._registerViewPort(_whenDefault, viewPort);
constructor(viewContainer: ViewContainer, @Parent() sswitch: Switch) {
sswitch._registerViewContainer(_whenDefault, viewContainer);
}
}

View File

@ -8,7 +8,7 @@ import {onDestroy} from 'angular2/src/core/annotations/annotations';
import {Injector, Inject, bind} from 'angular2/di';
import {View} from 'angular2/src/core/compiler/view';
import {ProtoRecordRange} from 'angular2/change_detection';
import {ViewPort} from 'angular2/src/core/compiler/viewport';
import {ViewContainer} from 'angular2/src/core/compiler/view_container';
import {NgElement} from 'angular2/src/core/dom/element';
import {LightDom, SourceLightDom, DestinationLightDom} from 'angular2/src/core/compiler/shadow_dom_emulation/light_dom';
import {Directive} from 'angular2/src/core/annotations/annotations';
@ -409,11 +409,11 @@ export function main() {
expect(inj.get(NgElement)).toEqual(element);
});
it('should return viewPort', function () {
var viewPort = new ViewPort(null, null, null, null, null);
var inj = injector([], null, null, new PreBuiltObjects(null, null, viewPort, null, null));
it('should return viewContainer', function () {
var viewContainer = new ViewContainer(null, null, null, null, null);
var inj = injector([], null, null, new PreBuiltObjects(null, null, viewContainer, null, null));
expect(inj.get(ViewPort)).toEqual(viewPort);
expect(inj.get(ViewContainer)).toEqual(viewContainer);
});
it('should return bindingPropagationConfig', function () {

View File

@ -11,10 +11,10 @@ import {NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_str
import {TemplateLoader} from 'angular2/src/core/compiler/template_loader';
import {BindingPropagationConfig} from 'angular2/src/core/compiler/binding_propagation_config';
import {Decorator, Component, Template} from 'angular2/src/core/annotations/annotations';
import {Decorator, Component, Viewport} from 'angular2/src/core/annotations/annotations';
import {TemplateConfig} from 'angular2/src/core/annotations/template_config';
import {ViewPort} from 'angular2/src/core/compiler/viewport';
import {ViewContainer} from 'angular2/src/core/compiler/view_container';
import {MapWrapper} from 'angular2/src/facade/collection';
import {XHRMock} from 'angular2/src/mock/xhr_mock';
@ -262,7 +262,7 @@ class PushBasedComp {
@Component({
template: new TemplateConfig({
directives: [MyDir, [[ChildComp], SomeTemplate, PushBasedComp]]
directives: [MyDir, [[ChildComp], SomeViewport, PushBasedComp]]
})
})
class MyComp {
@ -289,13 +289,13 @@ class ChildComp {
}
}
@Template({
@Viewport({
selector: '[some-tmplate]'
})
class SomeTemplate {
constructor(viewPort: ViewPort) {
viewPort.create().setLocal('some-tmpl', 'hello');
viewPort.create().setLocal('some-tmpl', 'again');
class SomeViewport {
constructor(container: ViewContainer) {
container.create().setLocal('some-tmpl', 'hello');
container.create().setLocal('some-tmpl', 'again');
}
}

View File

@ -8,9 +8,7 @@ import {CompileElement} from 'angular2/src/core/compiler/pipeline/compile_elemen
import {CompileControl} from 'angular2/src/core/compiler/pipeline/compile_control';
import {DOM} from 'angular2/src/facade/dom';
import {NativeShadowDomStrategy, ShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
import {Component} from 'angular2/src/core/annotations/annotations';
import {Decorator} from 'angular2/src/core/annotations/annotations';
import {Template} from 'angular2/src/core/annotations/annotations';
import {Component, Decorator, Viewport} from 'angular2/src/core/annotations/annotations';
import {TemplateConfig} from 'angular2/src/core/annotations/template_config';
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
import {Lexer, Parser} from 'angular2/change_detection';
@ -25,8 +23,8 @@ export function main() {
SomeDecorator,
SomeDecoratorIgnoringChildren,
SomeDecoratorWithBinding,
SomeTemplate,
SomeTemplate2,
SomeViewport,
SomeViewport2,
SomeComponent,
SomeComponent2
];
@ -55,7 +53,7 @@ export function main() {
var results = createPipeline().process(el('<div></div>'));
expect(results[0].decoratorDirectives).toBe(null);
expect(results[0].componentDirective).toBe(null);
expect(results[0].templateDirective).toBe(null);
expect(results[0].viewportDirective).toBe(null);
});
describe('component directives', () => {
@ -105,10 +103,10 @@ export function main() {
});
});
describe('template directives', () => {
describe('viewport directives', () => {
it('should detect them in attributes', () => {
var results = createPipeline().process(el('<template some-templ></template>'));
expect(results[0].templateDirective).toEqual(reader.read(SomeTemplate));
expect(results[0].viewportDirective).toEqual(reader.read(SomeViewport));
});
it('should detect them in property bindings', () => {
@ -116,7 +114,7 @@ export function main() {
'some-templ': 'someExpr'
}});
var results = pipeline.process(el('<template></template>'));
expect(results[0].templateDirective).toEqual(reader.read(SomeTemplate));
expect(results[0].viewportDirective).toEqual(reader.read(SomeViewport));
});
it('should detect them in variable bindings', () => {
@ -124,10 +122,10 @@ export function main() {
'some-templ': 'someExpr'
}});
var results = pipeline.process(el('<template></template>'));
expect(results[0].templateDirective).toEqual(reader.read(SomeTemplate));
expect(results[0].viewportDirective).toEqual(reader.read(SomeViewport));
});
it('should not allow multiple template directives on the same element', () => {
it('should not allow multiple viewport directives on the same element', () => {
expect( () => {
createPipeline().process(
el('<template some-templ some-templ2></template>')
@ -135,12 +133,12 @@ export function main() {
}).toThrowError('Only one template directive per element is allowed!');
});
it('should not allow template directives on non <template> elements', () => {
it('should not allow viewport directives on non <template> elements', () => {
expect( () => {
createPipeline().process(
el('<div some-templ></div>')
);
}).toThrowError('Template directives need to be placed on <template> elements or elements with template attribute!');
}).toThrowError('Viewport directives need to be placed on <template> elements or elements with template attribute!');
});
});
@ -227,15 +225,15 @@ class SomeDecoratorIgnoringChildren {
})
class SomeDecoratorWithBinding {}
@Template({
@Viewport({
selector: '[some-templ]'
})
class SomeTemplate {}
class SomeViewport {}
@Template({
@Viewport({
selector: '[some-templ2]'
})
class SomeTemplate2 {}
class SomeViewport2 {}
@Component({
selector: '[some-comp]'
@ -249,7 +247,7 @@ class SomeComponent2 {}
@Component({
template: new TemplateConfig({
directives: [SomeDecorator, SomeTemplate, SomeTemplate2, SomeComponent, SomeComponent2]
directives: [SomeDecorator, SomeViewport, SomeViewport2, SomeComponent, SomeComponent2]
})
})
class MyComp {}

View File

@ -10,9 +10,7 @@ import {CompileStep} from 'angular2/src/core/compiler/pipeline/compile_step'
import {CompileControl} from 'angular2/src/core/compiler/pipeline/compile_control';
import {NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
import {Decorator} from 'angular2/src/core/annotations/annotations';
import {Template} from 'angular2/src/core/annotations/annotations';
import {Component} from 'angular2/src/core/annotations/annotations';
import {Decorator, Component, Viewport} from 'angular2/src/core/annotations/annotations';
import {ProtoView, ElementPropertyMemento, DirectivePropertyMemento} from 'angular2/src/core/compiler/view';
import {ProtoElementInjector} from 'angular2/src/core/compiler/element_injector';
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
@ -150,12 +148,12 @@ export function main() {
});
it('should store the template directive', () => {
var directives = [SomeTemplateDirective];
var directives = [SomeViewportDirective];
var pipeline = createPipeline({protoElementInjector: null, directives: directives});
var results = pipeline.process(el('<div viewroot directives></div>'));
var pv = results[0].inheritedProtoView;
expect(pv.elementBinders[0].templateDirective.type).toBe(SomeTemplateDirective);
expect(pv.elementBinders[0].viewportDirective.type).toBe(SomeViewportDirective);
});
it('should bind text nodes', () => {
@ -283,7 +281,7 @@ export function main() {
'boundprop3': 'prop3'
});
var directives = [SomeComponentDirectiveWithBinding,
SomeTemplateDirectiveWithBinding,
SomeViewportDirectiveWithBinding,
SomeDecoratorDirectiveWith2Bindings];
var protoElementInjector = new ProtoElementInjector(null, 0, directives, true);
var pipeline = createPipeline({
@ -304,7 +302,7 @@ export function main() {
expect(view.elementInjectors[0].get(SomeDecoratorDirectiveWith2Bindings).decorProp).toBe('a');
expect(view.elementInjectors[0].get(SomeDecoratorDirectiveWith2Bindings).decorProp2).toBe('b');
expect(view.elementInjectors[0].get(SomeTemplateDirectiveWithBinding).templProp).toBe('b');
expect(view.elementInjectors[0].get(SomeViewportDirectiveWithBinding).templProp).toBe('b');
expect(view.elementInjectors[0].get(SomeComponentDirectiveWithBinding).compProp).toBe('c');
});
@ -389,14 +387,14 @@ class SomeDecoratorDirectiveWith2Bindings {
}
}
@Template()
class SomeTemplateDirective {
@Viewport()
class SomeViewportDirective {
}
@Template({
@Viewport({
bind: {'boundprop2': 'templProp'}
})
class SomeTemplateDirectiveWithBinding {
class SomeViewportDirectiveWithBinding {
templProp;
constructor() {
this.templProp = null;

View File

@ -9,7 +9,7 @@ import {CompileElement} from 'angular2/src/core/compiler/pipeline/compile_elemen
import {CompileStep} from 'angular2/src/core/compiler/pipeline/compile_step'
import {CompileControl} from 'angular2/src/core/compiler/pipeline/compile_control';
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
import {Template, Decorator, Component} from 'angular2/src/core/annotations/annotations';
import {Viewport, Decorator, Component} from 'angular2/src/core/annotations/annotations';
export function main() {
describe('ElementBindingMarker', () => {
@ -90,7 +90,7 @@ export function main() {
it('should mark elements with template directives', () => {
var results = createPipeline({
directives: [SomeTemplateDirective]
directives: [SomeViewportDirective]
}).process(el('<div></div>'));
assertBinding(results[0], true);
});
@ -121,8 +121,8 @@ class MockStep extends CompileStep {
}
}
@Template()
class SomeTemplateDirective {}
@Viewport()
class SomeViewportDirective {}
@Component()
class SomeComponentDirective {}

View File

@ -10,7 +10,7 @@ import {CompileStep} from 'angular2/src/core/compiler/pipeline/compile_step'
import {CompileControl} from 'angular2/src/core/compiler/pipeline/compile_control';
import {ProtoView} from 'angular2/src/core/compiler/view';
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
import {Template, Decorator, Component} from 'angular2/src/core/annotations/annotations';
import {Viewport, Decorator, Component} from 'angular2/src/core/annotations/annotations';
import {ProtoElementInjector} from 'angular2/src/core/compiler/element_injector';
export function main() {
@ -68,7 +68,7 @@ export function main() {
});
it('should create a ProtoElementInjector for elements directives', () => {
var directives = [SomeComponentDirective, SomeTemplateDirective, SomeDecoratorDirective];
var directives = [SomeComponentDirective, SomeViewportDirective, SomeDecoratorDirective];
var results = createPipeline(directives).process(el('<div directives></div>'));
var creationArgs = getCreationArgs(results[0].inheritedProtoElementInjector);
var boundDirectives = creationArgs['bindings'].map((b) => b.key.token);
@ -203,8 +203,8 @@ class MockStep extends CompileStep {
class SomeComponentService {}
@Template()
class SomeTemplateDirective {}
@Viewport()
class SomeViewportDirective {}
@Component({
componentServices: [SomeComponentService]

View File

@ -6,7 +6,7 @@ import {Content} from 'angular2/src/core/compiler/shadow_dom_emulation/content_t
import {NgElement} from 'angular2/src/core/dom/element';
import {LightDom} from 'angular2/src/core/compiler/shadow_dom_emulation/light_dom';
import {View} from 'angular2/src/core/compiler/view';
import {ViewPort} from 'angular2/src/core/compiler/viewport';
import {ViewContainer} from 'angular2/src/core/compiler/view_container';
import {ElementInjector} from 'angular2/src/core/compiler/element_injector';
import {ProtoRecordRange} from 'angular2/change_detection';
@ -14,12 +14,12 @@ import {ProtoRecordRange} from 'angular2/change_detection';
@IMPLEMENTS(ElementInjector)
class FakeElementInjector {
content;
viewPort;
viewContainer;
element;
constructor(content = null, viewPort = null, element = null) {
constructor(content = null, viewContainer = null, element = null) {
this.content = content;
this.viewPort = viewPort;
this.viewContainer = viewContainer;
this.element = element;
}
@ -28,7 +28,7 @@ class FakeElementInjector {
}
hasPreBuiltObject(type) {
return this.viewPort != null;
return this.viewContainer != null;
}
forElement(n) {
@ -37,7 +37,7 @@ class FakeElementInjector {
get(t) {
if (t === Content) return this.content;
if (t === ViewPort) return this.viewPort;
if (t === ViewContainer) return this.viewContainer;
return null;
}
@ -61,8 +61,8 @@ class FakeView {
}
@proxy
@IMPLEMENTS(ViewPort)
class FakeViewPort {
@IMPLEMENTS(ViewContainer)
class FakeViewContainer {
_nodes;
_contentTagContainers;
@ -128,9 +128,9 @@ export function main() {
expect(lightDom.contentTags()).toEqual([tag]);
});
it("should collect content tags from view ports", () => {
it("should collect content tags from ViewContainers", () => {
var tag = new FakeContentTag();
var vp = new FakeViewPort(null, [
var vp = new FakeViewContainer(null, [
new FakeView([new FakeElementInjector(tag, null)])
]);
@ -149,13 +149,13 @@ export function main() {
expect(toHtml(lightDom.expandedDomNodes())).toEqual(["<a></a>"]);
});
it("should include view port nodes", () => {
it("should include ViewContainer nodes", () => {
var lightDomEl = el("<div><template></template></div>")
var lightDomView = new FakeView([
new FakeElementInjector(
null,
new FakeViewPort([el("<a></a>")]),
new FakeViewContainer([el("<a></a>")]),
DOM.firstChild(lightDomEl))]);
var lightDom = new LightDom(

View File

@ -13,10 +13,10 @@ import {ShadowDomStrategy,
EmulatedShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
import {TemplateLoader} from 'angular2/src/core/compiler/template_loader';
import {Decorator, Component, Template} from 'angular2/src/core/annotations/annotations';
import {Decorator, Component, Viewport} from 'angular2/src/core/annotations/annotations';
import {TemplateConfig} from 'angular2/src/core/annotations/template_config';
import {ViewPort} from 'angular2/src/core/compiler/viewport';
import {ViewContainer} from 'angular2/src/core/compiler/view_container';
import {StringMapWrapper, MapWrapper} from 'angular2/src/facade/collection';
import {XHRMock} from 'angular2/src/mock/xhr_mock';
@ -77,14 +77,14 @@ export function main() {
});
});
it("should redistribute direct child viewports when the light dom changes", (done) => {
it("should redistribute direct child viewcontainers when the light dom changes", (done) => {
var temp = '<multiple-content-tags>' +
'<div><div template="manual" class="left">A</div></div>' +
'<div>B</div>' +
'</multiple-content-tags>';
compile(temp, (view, lc) => {
var dir = view.elementInjectors[1].get(ManualTemplateDirective);
var dir = view.elementInjectors[1].get(ManualViewportDirective);
expect(view.nodes).toHaveText('(, B)');
@ -109,7 +109,7 @@ export function main() {
'</multiple-content-tags>';
compile(temp, (view, lc) => {
var dir = view.elementInjectors[1].get(ManualTemplateDirective);
var dir = view.elementInjectors[1].get(ManualViewportDirective);
expect(view.nodes).toHaveText('(, B)');
@ -148,7 +148,7 @@ export function main() {
'</outer>';
compile(temp, (view, lc) => {
var dir = view.elementInjectors[1].get(ManualTemplateDirective);
var dir = view.elementInjectors[1].get(ManualViewportDirective);
expect(view.nodes).toHaveText('OUTER(INNER(INNERINNER(,BC)))');
@ -223,36 +223,36 @@ class TestDirectiveMetadataReader extends DirectiveMetadataReader {
}
}
@Template({
@Viewport({
selector: '[manual]'
})
class ManualTemplateDirective {
viewPort;
constructor(viewPort:ViewPort) {
this.viewPort = viewPort;
class ManualViewportDirective {
viewContainer;
constructor(viewContainer:ViewContainer) {
this.viewContainer = viewContainer;
}
show() { this.viewPort.create(); }
hide() { this.viewPort.remove(0); }
show() { this.viewContainer.create(); }
hide() { this.viewContainer.remove(0); }
}
@Template({
@Viewport({
selector: '[auto]',
bind: {
'auto': 'auto'
}
})
class AutoTemplateDirective {
viewPort;
constructor(viewPort:ViewPort) {
this.viewPort = viewPort;
class AutoViewportDirective {
viewContainer;
constructor(viewContainer:ViewContainer) {
this.viewContainer = viewContainer;
}
set auto(newValue:boolean) {
if (newValue) {
this.viewPort.create();
this.viewContainer.create();
} else {
this.viewPort.remove(0);
this.viewContainer.remove(0);
}
}
}
@ -280,7 +280,7 @@ class MultipleContentTagsComponent {
selector: 'conditional-content',
template: new TemplateConfig({
inline: '<div>(<div template="auto: cond"><content select=".left"></content></div>, <content></content>)</div>',
directives: [AutoTemplateDirective]
directives: [AutoViewportDirective]
})
})
class ConditionalContentComponent {
@ -337,7 +337,7 @@ class InnerInnerComponent {
@Component({
selector: 'my-comp',
template: new TemplateConfig({
directives: [MultipleContentTagsComponent, ManualTemplateDirective,
directives: [MultipleContentTagsComponent, ManualViewportDirective,
ConditionalContentComponent, OuterWithIndirectNestedComponent, OuterComponent]
})
})

View File

@ -1,6 +1,6 @@
import {describe, xit, it, expect, beforeEach, ddescribe, iit, el, proxy} from 'angular2/test_lib';
import {View, ProtoView} from 'angular2/src/core/compiler/view';
import {ViewPort} from 'angular2/src/core/compiler/viewport';
import {ViewContainer} from 'angular2/src/core/compiler/view_container';
import {IMPLEMENTS} from 'angular2/src/facade/lang';
import {DOM, Node} from 'angular2/src/facade/dom';
import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
@ -61,8 +61,8 @@ class HydrateAwareFakeView {
}
export function main() {
describe('viewport', () => {
var viewPort, parentView, protoView, dom, customViewWithOneNode,
describe('ViewContainer', () => {
var viewContainer, parentView, protoView, dom, customViewWithOneNode,
customViewWithTwoNodes, elementInjector;
beforeEach(() => {
@ -71,19 +71,19 @@ export function main() {
parentView = createView([dom.childNodes[0]]);
protoView = new ProtoView(el('<div>hi</div>'), new DynamicProtoChangeDetector(), new NativeShadowDomStrategy());
elementInjector = new ElementInjector(null, null, null, null);
viewPort = new ViewPort(parentView, insertionElement, protoView, elementInjector, null);
viewContainer = new ViewContainer(parentView, insertionElement, protoView, elementInjector, null);
customViewWithOneNode = createView([el('<div>single</div>')]);
customViewWithTwoNodes = createView([el('<div>one</div>'), el('<div>two</div>')]);
});
describe('when dehydrated', () => {
it('should throw if create is called', () => {
expect(() => viewPort.create()).toThrowError();
expect(() => viewContainer.create()).toThrowError();
});
});
describe('when hydrated', () => {
function textInViewPort() {
function textInViewContainer() {
var out = '';
// skipping starting filler, insert-me and final filler.
for (var i = 2; i < dom.childNodes.length - 1; i++) {
@ -94,84 +94,84 @@ export function main() {
}
beforeEach(() => {
viewPort.hydrate(new Injector([]), null);
viewContainer.hydrate(new Injector([]), null);
var fillerView = createView([el('<filler>filler</filler>')]);
viewPort.insert(fillerView);
viewContainer.insert(fillerView);
});
it('should create new views from protoView', () => {
viewPort.create();
expect(textInViewPort()).toEqual('filler hi');
expect(viewPort.length).toBe(2);
viewContainer.create();
expect(textInViewContainer()).toEqual('filler hi');
expect(viewContainer.length).toBe(2);
});
it('should create new views from protoView at index', () => {
viewPort.create(0);
expect(textInViewPort()).toEqual('hi filler');
expect(viewPort.length).toBe(2);
viewContainer.create(0);
expect(textInViewContainer()).toEqual('hi filler');
expect(viewContainer.length).toBe(2);
});
it('should insert new views at the end by default', () => {
viewPort.insert(customViewWithOneNode);
expect(textInViewPort()).toEqual('filler single');
expect(viewPort.get(1)).toBe(customViewWithOneNode);
expect(viewPort.length).toBe(2);
viewContainer.insert(customViewWithOneNode);
expect(textInViewContainer()).toEqual('filler single');
expect(viewContainer.get(1)).toBe(customViewWithOneNode);
expect(viewContainer.length).toBe(2);
});
it('should insert new views at the given index', () => {
viewPort.insert(customViewWithOneNode, 0);
expect(textInViewPort()).toEqual('single filler');
expect(viewPort.get(0)).toBe(customViewWithOneNode);
expect(viewPort.length).toBe(2);
viewContainer.insert(customViewWithOneNode, 0);
expect(textInViewContainer()).toEqual('single filler');
expect(viewContainer.get(0)).toBe(customViewWithOneNode);
expect(viewContainer.length).toBe(2);
});
it('should remove the last view by default', () => {
viewPort.insert(customViewWithOneNode);
viewContainer.insert(customViewWithOneNode);
viewPort.remove();
viewContainer.remove();
expect(textInViewPort()).toEqual('filler');
expect(viewPort.length).toBe(1);
expect(textInViewContainer()).toEqual('filler');
expect(viewContainer.length).toBe(1);
});
it('should remove the view at a given index', () => {
viewPort.insert(customViewWithOneNode);
viewPort.insert(customViewWithTwoNodes);
viewContainer.insert(customViewWithOneNode);
viewContainer.insert(customViewWithTwoNodes);
viewPort.remove(1);
viewContainer.remove(1);
expect(textInViewPort()).toEqual('filler one two');
expect(viewPort.get(1)).toBe(customViewWithTwoNodes);
expect(viewPort.length).toBe(2);
expect(textInViewContainer()).toEqual('filler one two');
expect(viewContainer.get(1)).toBe(customViewWithTwoNodes);
expect(viewContainer.length).toBe(2);
});
it('should detach the last view by default', () => {
viewPort.insert(customViewWithOneNode);
expect(viewPort.length).toBe(2);
viewContainer.insert(customViewWithOneNode);
expect(viewContainer.length).toBe(2);
var detachedView = viewPort.detach();
var detachedView = viewContainer.detach();
expect(detachedView).toBe(customViewWithOneNode);
expect(textInViewPort()).toEqual('filler');
expect(viewPort.length).toBe(1);
expect(textInViewContainer()).toEqual('filler');
expect(viewContainer.length).toBe(1);
});
it('should detach the view at a given index', () => {
viewPort.insert(customViewWithOneNode);
viewPort.insert(customViewWithTwoNodes);
expect(viewPort.length).toBe(3);
viewContainer.insert(customViewWithOneNode);
viewContainer.insert(customViewWithTwoNodes);
expect(viewContainer.length).toBe(3);
var detachedView = viewPort.detach(1);
var detachedView = viewContainer.detach(1);
expect(detachedView).toBe(customViewWithOneNode);
expect(textInViewPort()).toEqual('filler one two');
expect(viewPort.length).toBe(2);
expect(textInViewContainer()).toEqual('filler one two');
expect(viewContainer.length).toBe(2);
});
it('should keep views hydration state during insert', () => {
var hydratedView = new HydrateAwareFakeView(true);
var dehydratedView = new HydrateAwareFakeView(false);
viewPort.insert(hydratedView);
viewPort.insert(dehydratedView);
viewContainer.insert(hydratedView);
viewContainer.insert(dehydratedView);
expect(hydratedView.hydrated()).toBe(true);
expect(dehydratedView.hydrated()).toBe(false);
@ -179,8 +179,8 @@ export function main() {
it('should dehydrate on remove', () => {
var hydratedView = new HydrateAwareFakeView(true);
viewPort.insert(hydratedView);
viewPort.remove();
viewContainer.insert(hydratedView);
viewContainer.remove();
expect(hydratedView.hydrated()).toBe(false);
});
@ -188,21 +188,21 @@ export function main() {
it('should keep views hydration state during detach', () => {
var hydratedView = new HydrateAwareFakeView(true);
var dehydratedView = new HydrateAwareFakeView(false);
viewPort.insert(hydratedView);
viewPort.insert(dehydratedView);
viewContainer.insert(hydratedView);
viewContainer.insert(dehydratedView);
expect(viewPort.detach().hydrated()).toBe(false);
expect(viewPort.detach().hydrated()).toBe(true);
expect(viewContainer.detach().hydrated()).toBe(false);
expect(viewContainer.detach().hydrated()).toBe(true);
});
it('should support adding/removing views with more than one node', () => {
viewPort.insert(customViewWithTwoNodes);
viewPort.insert(customViewWithOneNode);
viewContainer.insert(customViewWithTwoNodes);
viewContainer.insert(customViewWithOneNode);
expect(textInViewPort()).toEqual('filler one two single');
expect(textInViewContainer()).toEqual('filler one two single');
viewPort.remove(1);
expect(textInViewPort()).toEqual('filler single');
viewContainer.remove(1);
expect(textInViewContainer()).toEqual('filler single');
});
});
@ -210,7 +210,7 @@ export function main() {
var fancyView;
beforeEach(() => {
var parser = new Parser(new Lexer());
viewPort.hydrate(new Injector([]), null);
viewContainer.hydrate(new Injector([]), null);
var pv = new ProtoView(el('<div class="ng-binding">{{}}</div>'),
new DynamicProtoChangeDetector(), new NativeShadowDomStrategy());
@ -220,7 +220,7 @@ export function main() {
});
it('hydrating should update rootElementInjectors and parent change detector', () => {
viewPort.insert(fancyView);
viewContainer.insert(fancyView);
ListWrapper.forEach(fancyView.rootElementInjectors, (inj) =>
expect(inj.parent).toBe(elementInjector));
@ -228,12 +228,12 @@ export function main() {
});
it('dehydrating should update rootElementInjectors and parent change detector', () => {
viewPort.insert(fancyView);
viewPort.remove();
viewContainer.insert(fancyView);
viewContainer.remove();
ListWrapper.forEach(fancyView.rootElementInjectors, (inj) =>
expect(inj.parent).toBe(null));
expect(parentView.changeDetector.children.length).toBe(0);
expect(viewPort.length).toBe(0);
expect(viewContainer.length).toBe(0);
});
});
});

View File

@ -3,7 +3,7 @@ import {ProtoView, ElementPropertyMemento, DirectivePropertyMemento} from 'angul
import {ProtoElementInjector, ElementInjector, DirectiveBinding} from 'angular2/src/core/compiler/element_injector';
import {EmulatedShadowDomStrategy, NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
import {Component, Decorator, Template, Directive, onChange} from 'angular2/src/core/annotations/annotations';
import {Component, Decorator, Viewport, Directive, onChange} from 'angular2/src/core/annotations/annotations';
import {Lexer, Parser, DynamicProtoChangeDetector,
ChangeDetector} from 'angular2/change_detection';
import {TemplateConfig} from 'angular2/src/core/annotations/template_config';
@ -13,14 +13,14 @@ import {DOM, Element} from 'angular2/src/facade/dom';
import {int, IMPLEMENTS} from 'angular2/src/facade/lang';
import {Injector} from 'angular2/di';
import {View} from 'angular2/src/core/compiler/view';
import {ViewPort} from 'angular2/src/core/compiler/viewport';
import {ViewContainer} from 'angular2/src/core/compiler/view_container';
import {reflector} from 'angular2/src/reflection/reflection';
import {VmTurnZone} from 'angular2/src/core/zone/vm_turn_zone';
import {EventManager} from 'angular2/src/core/events/event_manager';
@proxy
@IMPLEMENTS(ViewPort)
class FakeViewPort {
@IMPLEMENTS(ViewContainer)
class FakeViewContainer {
templateElement;
constructor(templateElement) {
@ -42,7 +42,7 @@ class FakeView {
export function main() {
describe('view', function() {
var parser, someComponentDirective, someTemplateDirective;
var parser, someComponentDirective, someViewportDirective;
function createView(protoView, eventManager: EventManager = null) {
var ctx = new MyEvaluationContext();
@ -54,7 +54,7 @@ export function main() {
beforeEach(() => {
parser = new Parser(new Lexer());
someComponentDirective = new DirectiveMetadataReader().read(SomeComponent);
someTemplateDirective = new DirectiveMetadataReader().read(SomeTemplate);
someViewportDirective = new DirectiveMetadataReader().read(SomeViewport);
});
describe('instantiated from protoView', () => {
@ -409,30 +409,30 @@ export function main() {
});
describe('with template views', () => {
function createViewWithTemplate() {
function createViewWithViewport() {
var templateProtoView = new ProtoView(
el('<div id="1"></div>'), new DynamicProtoChangeDetector(), null);
var pv = new ProtoView(el('<someTmpl class="ng-binding"></someTmpl>'),
new DynamicProtoChangeDetector(), new NativeShadowDomStrategy());
var binder = pv.bindElement(new ProtoElementInjector(null, 0, [SomeTemplate]));
binder.templateDirective = someTemplateDirective;
var binder = pv.bindElement(new ProtoElementInjector(null, 0, [SomeViewport]));
binder.viewportDirective = someViewportDirective;
binder.nestedProtoView = templateProtoView;
return createView(pv);
}
it('should create a viewPort for the template directive', () => {
var view = createViewWithTemplate();
it('should create a ViewContainer for the Viewport directive', () => {
var view = createViewWithViewport();
var tmplComp = view.rootElementInjectors[0].get(SomeTemplate);
expect(tmplComp.viewPort).not.toBe(null);
var tmplComp = view.rootElementInjectors[0].get(SomeViewport);
expect(tmplComp.viewContainer).not.toBe(null);
});
it('dehydration should dehydrate viewports', () => {
var view = createViewWithTemplate();
it('dehydration should dehydrate viewcontainers', () => {
var view = createViewWithViewport();
var tmplComp = view.rootElementInjectors[0].get(SomeTemplate);
expect(tmplComp.viewPort.hydrated()).toBe(false);
var tmplComp = view.rootElementInjectors[0].get(SomeViewport);
expect(tmplComp.viewContainer.hydrated()).toBe(false);
});
});
@ -671,13 +671,13 @@ class ServiceDependentDecorator {
}
}
@Template({
@Viewport({
selector: 'someTmpl'
})
class SomeTemplate {
viewPort: ViewPort;
constructor(viewPort: ViewPort) {
this.viewPort = viewPort;
class SomeViewport {
viewContainer: ViewContainer;
constructor(viewContainer: ViewContainer) {
this.viewContainer = viewContainer;
}
}

View File

@ -9,10 +9,10 @@ import {Compiler, CompilerCache} from 'angular2/src/core/compiler/compiler';
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
import {NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
import {Decorator, Component, Template} from 'angular2/src/core/annotations/annotations';
import {Decorator, Component, Viewport} from 'angular2/src/core/annotations/annotations';
import {TemplateConfig} from 'angular2/src/core/annotations/template_config';
import {ViewPort} from 'angular2/src/core/compiler/viewport';
import {ViewContainer} from 'angular2/src/core/compiler/view_container';
import {MapWrapper, ListWrapper} from 'angular2/src/facade/collection';
import {Foreach} from 'angular2/src/directives/foreach';

View File

@ -1,7 +1,7 @@
import {int, isPresent} from 'angular2/src/facade/lang';
import {reflector} from 'angular2/src/reflection/reflection';
import {getIntParameter, bindAction} from 'angular2/src/test_lib/benchmark_util';
import {bootstrap, Component, Template, TemplateConfig, ViewPort, Compiler}
import {bootstrap, Component, Viewport, TemplateConfig, ViewContainer, Compiler}
from 'angular2/angular2';
import {PromiseWrapper} from 'angular2/src/facade/async';
import {ListWrapper} from 'angular2/src/facade/collection';

View File

@ -1,7 +1,7 @@
import {int} from 'angular2/src/facade/lang';
import {reflector} from 'angular2/src/reflection/reflection';
import {getIntParameter, bindAction} from 'angular2/src/test_lib/benchmark_util';
import {bootstrap, Component, Template, TemplateConfig, ViewPort, Compiler}
import {bootstrap, Component, Viewport, TemplateConfig, ViewContainer, Compiler}
from 'angular2/angular2';
import {PromiseWrapper} from 'angular2/src/facade/async';
import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';

View File

@ -4,7 +4,7 @@ import {MapWrapper} from 'angular2/src/facade/collection';
import {Parser, Lexer, ChangeDetector, ChangeDetection}
from 'angular2/change_detection';
import {bootstrap, Component, Template, TemplateConfig, ViewPort, Compiler}
import {bootstrap, Component, Viewport, TemplateConfig, ViewContainer, Compiler}
from 'angular2/angular2';
import {reflector} from 'angular2/src/reflection/reflection';
import {CompilerCache} from 'angular2/src/core/compiler/compiler';
@ -151,8 +151,8 @@ export function setupReflector() {
export function setupReflectorForAngular() {
reflector.registerType(If, {
'factory': (vp) => new If(vp),
'parameters': [[ViewPort]],
'annotations' : [new Template({
'parameters': [[ViewContainer]],
'annotations' : [new Viewport({
selector: '[if]',
bind: {
'if': 'condition'
@ -162,8 +162,8 @@ export function setupReflectorForAngular() {
reflector.registerType(Foreach, {
'factory': (vp) => new Foreach(vp),
'parameters': [[ViewPort]],
'annotations' : [new Template({
'parameters': [[ViewContainer]],
'annotations' : [new Viewport({
selector: '[foreach]',
bind: {
'in': 'iterable[]'

View File

@ -1,7 +1,7 @@
import {int, FINAL} from 'angular2/src/facade/lang';
import {reflector} from 'angular2/src/reflection/reflection';
import {getIntParameter, bindAction} from 'angular2/src/test_lib/benchmark_util';
import {Component, Template, TemplateConfig, ViewPort, Compiler}
import {Component, Viewport, TemplateConfig, ViewContainer, Compiler}
from 'angular2/angular2';
import {PromiseWrapper} from 'angular2/src/facade/async';
import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';

View File

@ -1,6 +1,6 @@
import {int} from 'angular2/src/facade/lang';
import {reflector} from 'angular2/src/reflection/reflection';
import {Component, Template, TemplateConfig, ViewPort, Compiler}
import {Component, Viewport, TemplateConfig, ViewContainer, Compiler}
from 'angular2/angular2';
import {PromiseWrapper} from 'angular2/src/facade/async';
import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';

View File

@ -1,7 +1,7 @@
import {Parser, Lexer, ChangeDetector, ChangeDetection, jitChangeDetection}
from 'angular2/change_detection';
import {bootstrap, Component, Template, TemplateConfig, ViewPort, Compiler} from 'angular2/angular2';
import {bootstrap, Component, Viewport, TemplateConfig, ViewContainer, Compiler} from 'angular2/angular2';
import {CompilerCache} from 'angular2/src/core/compiler/compiler';
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
@ -50,8 +50,8 @@ function setupReflector() {
reflector.registerType(NgIf, {
'factory': (vp) => new NgIf(vp),
'parameters': [[ViewPort]],
'annotations' : [new Template({
'parameters': [[ViewContainer]],
'annotations' : [new Viewport({
selector: '[ng-if]',
bind: {
'ng-if': 'ngIf'
@ -335,16 +335,16 @@ class AppComponent {
// TODO: Move this into a reusable directive in the 'core' module!
class NgIf {
_viewPort:ViewPort;
constructor(viewPort:ViewPort) {
this._viewPort = viewPort;
_viewContainer:ViewContainer;
constructor(viewContainer:ViewContainer) {
this._viewContainer = viewContainer;
}
set ngIf(value:boolean) {
if (this._viewPort.length > 0) {
this._viewPort.remove(0);
if (this._viewContainer.length > 0) {
this._viewContainer.remove(0);
}
if (value) {
this._viewPort.create();
this._viewContainer.create();
}
}
}

View File

@ -4,7 +4,7 @@ import {bootstrap, Component, Decorator, TemplateConfig, NgElement} from 'angula
// - Component - the basic building blocks of Angular 2.0 apps. Backed by
// ShadowDom.(http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
// - Decorator - add behavior to existing elements.
// - Template - allow for stamping out of a html template (not in this demo).
// - Viewport - allow for stamping out of a html template (not in this demo).
// @Component is AtScript syntax to annotate the HelloCmp class as an Angular
// 2.0 component.
@ -40,7 +40,7 @@ class HelloCmp {
}
// Decorators are light-weight. They don't allow for templates, or new
// expression contexts (use @Component or @Template for those needs).
// expression contexts (use @Component or @Viewport for those needs).
@Decorator({
selector: '[red]'
})