refactor(ViewPort): @Template -> @Viewport, ViewPort -> ViewContainer
fixes #595
This commit is contained in:
parent
3519714f64
commit
6d23d00057
|
@ -8,7 +8,7 @@ export * from './src/core/compiler/compiler';
|
||||||
|
|
||||||
export * from './src/core/compiler/template_loader';
|
export * from './src/core/compiler/template_loader';
|
||||||
export * from './src/core/compiler/view';
|
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/compiler/binding_propagation_config';
|
||||||
|
|
||||||
export * from './src/core/dom/element';
|
export * from './src/core/dom/element';
|
||||||
|
|
|
@ -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.
|
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.
|
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.)
|
* Viewports 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.
|
* Only one viewport can be present per DOM template element.
|
||||||
* The instantiator is is created over the `template` element. This is known as the `ViewPort`.
|
* The viewport is is created over the `template` element. This is known as the `ViewContainer`.
|
||||||
* Instantiator can insert child views into the `ViewPort`. The child views show up as siblings of the `ViewPort` in the DOM.
|
* 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): Relationship with Injection
|
||||||
>> TODO(misko): Instantiator can not be injected into child Views
|
>> TODO(misko): Instantiator can not be injected into child Views
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
@Instantiator({
|
@Viewport({
|
||||||
selector: '[if]',
|
selector: '[if]',
|
||||||
bind: {
|
bind: {
|
||||||
'if': 'condition'
|
'if': 'condition'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
export class If {
|
export class If {
|
||||||
viewPort: ViewPort;
|
viewContainer: ViewContainer;
|
||||||
view: View;
|
view: View;
|
||||||
|
|
||||||
constructor(viewPort: ViewPort) {
|
constructor(viewContainer: ViewContainer) {
|
||||||
this.viewPort = viewPort;
|
this.viewContainer = viewContainer;
|
||||||
this.view` = null;
|
this.view = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
set condition(value) {
|
set condition(value) {
|
||||||
if (value) {
|
if (value) {
|
||||||
if (this.view == null) {
|
if (this.view === null) {
|
||||||
this.view = this.viewPort.create();
|
this.view = this.viewContainer.create();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (this.view != null) {
|
if (this.view !== null) {
|
||||||
this.viewPort.remove(this.view);
|
this.viewContainer.remove(this.view);
|
||||||
this.view = null;
|
this.view = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,25 @@
|
||||||
|
|
||||||
## Overview
|
## 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).
|
* View is a core rendering construct. A running application is just a collection of Views which are
|
||||||
* 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.)
|
nested in a tree like structure. The View tree is a simplified version of the DOM tree. A View can
|
||||||
* View can have zero or more ViewPorts. A ViewPort is a marker in the DOM which allows the insertion of child Views.
|
have a single DOM Element or large DOM structures. The key is that the DOM tree in the View can
|
||||||
* Views are created from a ProtoView. A ProtoView is a compiled DOM Template which is efficient at creating Views.
|
not undergo structural changes (only property changes).
|
||||||
* View contains a context object. The context represents the object instance against which all expressions are evaluated against.
|
* 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 a ChangeDetector for looking for detecting changes to the model.
|
||||||
* View contains ElementInjector for creating Directives.
|
* View contains ElementInjector for creating Directives.
|
||||||
|
|
||||||
|
@ -39,7 +51,10 @@ And assume following HTML Template:
|
||||||
</div>
|
</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)
|
<div> | viewA(greeter)
|
||||||
|
@ -66,12 +81,14 @@ Note:
|
||||||
* View knows which expressions need to be watched.
|
* View knows which expressions need to be watched.
|
||||||
* View knows what needs to be updated if the watched expression changes.
|
* View knows what needs to be updated if the watched expression changes.
|
||||||
* All DOM elements are owned by single instance of the view.
|
* 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
|
## 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:
|
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)
|
</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)
|
<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)
|
</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
|
<ul> | viewA
|
||||||
|
@ -129,11 +151,18 @@ The next step is to compose these two ProtoViews into actual view which is rende
|
||||||
</ul> | viewA
|
</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
|
## 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
|
<div> | viewA
|
||||||
|
@ -176,7 +205,8 @@ And assume following HTML Template:
|
||||||
</div> | viewA(greeter)
|
</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();
|
var greeter = new Greeter();
|
||||||
|
@ -185,14 +215,16 @@ var greeter = new Greeter();
|
||||||
The View contains two bindings:
|
The View contains two bindings:
|
||||||
|
|
||||||
1. `greeting`: This is bound to the `greeting` property on the `Greeter` instance.
|
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 })
|
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
|
By wrapping the `Greeter` instance into the `Locals` we allow the view to introduce variables which
|
||||||
the `Greeter` instance. During the resolution of the expressions we first check the locals, and then `Greeter` instance.
|
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:
|
Views transition through a particular set of states:
|
||||||
|
|
||||||
1. View is created from the ProtoView.
|
1. View is created from the ProtoView.
|
||||||
2. View can be attached to an existing ViewPort.
|
2. View can be attached to an existing ViewContainer.
|
||||||
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.
|
3. Upon attaching View to the ViewContainer the View needs to be hydrated. The hydration process
|
||||||
4. At this point the view is ready and renderable. Multiple changes can be delivered to the Directives from the ChangeDetection.
|
involves instantiating all of the Directives associated with the current View.
|
||||||
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.
|
4. At this point the view is ready and renderable. Multiple changes can be delivered to the
|
||||||
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.
|
Directives from the ChangeDetection.
|
||||||
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.
|
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.
|
||||||
|
|
|
@ -111,7 +111,7 @@ export class Decorator extends Directive {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Template extends Directive {
|
export class Viewport extends Directive {
|
||||||
@CONST()
|
@CONST()
|
||||||
constructor({
|
constructor({
|
||||||
selector,
|
selector,
|
||||||
|
|
|
@ -8,16 +8,17 @@ import {ProtoView} from './view';
|
||||||
export class ElementBinder {
|
export class ElementBinder {
|
||||||
protoElementInjector:ProtoElementInjector;
|
protoElementInjector:ProtoElementInjector;
|
||||||
componentDirective:DirectiveMetadata;
|
componentDirective:DirectiveMetadata;
|
||||||
templateDirective:DirectiveMetadata;
|
viewportDirective:DirectiveMetadata;
|
||||||
textNodeIndices:List<int>;
|
textNodeIndices:List<int>;
|
||||||
hasElementPropertyBindings:boolean;
|
hasElementPropertyBindings:boolean;
|
||||||
nestedProtoView: ProtoView;
|
nestedProtoView: ProtoView;
|
||||||
events:Map;
|
events:Map;
|
||||||
constructor(
|
constructor(
|
||||||
protoElementInjector: ProtoElementInjector, componentDirective:DirectiveMetadata, templateDirective:DirectiveMetadata) {
|
protoElementInjector: ProtoElementInjector, componentDirective:DirectiveMetadata,
|
||||||
|
viewportDirective:DirectiveMetadata) {
|
||||||
this.protoElementInjector = protoElementInjector;
|
this.protoElementInjector = protoElementInjector;
|
||||||
this.componentDirective = componentDirective;
|
this.componentDirective = componentDirective;
|
||||||
this.templateDirective = templateDirective;
|
this.viewportDirective = viewportDirective;
|
||||||
// updated later when events are bound
|
// updated later when events are bound
|
||||||
this.events = null;
|
this.events = null;
|
||||||
// updated later when text nodes are bound
|
// updated later when text nodes are bound
|
||||||
|
|
|
@ -6,7 +6,7 @@ import {Parent, Ancestor} from 'angular2/src/core/annotations/visibility';
|
||||||
import {EventEmitter} from 'angular2/src/core/annotations/events';
|
import {EventEmitter} from 'angular2/src/core/annotations/events';
|
||||||
import {View, ProtoView} from 'angular2/src/core/compiler/view';
|
import {View, ProtoView} from 'angular2/src/core/compiler/view';
|
||||||
import {LightDom, SourceLightDom, DestinationLightDom} from 'angular2/src/core/compiler/shadow_dom_emulation/light_dom';
|
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 {NgElement} from 'angular2/src/core/dom/element';
|
||||||
import {Directive, onChange, onDestroy} from 'angular2/src/core/annotations/annotations'
|
import {Directive, onChange, onDestroy} from 'angular2/src/core/annotations/annotations'
|
||||||
import {BindingPropagationConfig} from 'angular2/src/core/compiler/binding_propagation_config'
|
import {BindingPropagationConfig} from 'angular2/src/core/compiler/binding_propagation_config'
|
||||||
|
@ -22,7 +22,7 @@ var _staticKeys;
|
||||||
class StaticKeys {
|
class StaticKeys {
|
||||||
viewId:number;
|
viewId:number;
|
||||||
ngElementId:number;
|
ngElementId:number;
|
||||||
viewPortId:number;
|
viewContainerId:number;
|
||||||
destinationLightDomId:number;
|
destinationLightDomId:number;
|
||||||
sourceLightDomId:number;
|
sourceLightDomId:number;
|
||||||
bindingPropagationConfigId:number;
|
bindingPropagationConfigId:number;
|
||||||
|
@ -31,7 +31,7 @@ class StaticKeys {
|
||||||
//TODO: vsavkin Key.annotate(Key.get(View), 'static')
|
//TODO: vsavkin Key.annotate(Key.get(View), 'static')
|
||||||
this.viewId = Key.get(View).id;
|
this.viewId = Key.get(View).id;
|
||||||
this.ngElementId = Key.get(NgElement).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.destinationLightDomId = Key.get(DestinationLightDom).id;
|
||||||
this.sourceLightDomId = Key.get(SourceLightDom).id;
|
this.sourceLightDomId = Key.get(SourceLightDom).id;
|
||||||
this.bindingPropagationConfigId = Key.get(BindingPropagationConfig).id;
|
this.bindingPropagationConfigId = Key.get(BindingPropagationConfig).id;
|
||||||
|
@ -152,14 +152,14 @@ export class DirectiveBinding extends Binding {
|
||||||
export class PreBuiltObjects {
|
export class PreBuiltObjects {
|
||||||
view:View;
|
view:View;
|
||||||
element:NgElement;
|
element:NgElement;
|
||||||
viewPort:ViewPort;
|
viewContainer:ViewContainer;
|
||||||
lightDom:LightDom;
|
lightDom:LightDom;
|
||||||
bindingPropagationConfig:BindingPropagationConfig;
|
bindingPropagationConfig:BindingPropagationConfig;
|
||||||
constructor(view, element:NgElement, viewPort:ViewPort, lightDom:LightDom,
|
constructor(view, element:NgElement, viewContainer:ViewContainer, lightDom:LightDom,
|
||||||
bindingPropagationConfig:BindingPropagationConfig) {
|
bindingPropagationConfig:BindingPropagationConfig) {
|
||||||
this.view = view;
|
this.view = view;
|
||||||
this.element = element;
|
this.element = element;
|
||||||
this.viewPort = viewPort;
|
this.viewContainer = viewContainer;
|
||||||
this.lightDom = lightDom;
|
this.lightDom = lightDom;
|
||||||
this.bindingPropagationConfig = bindingPropagationConfig;
|
this.bindingPropagationConfig = bindingPropagationConfig;
|
||||||
}
|
}
|
||||||
|
@ -557,7 +557,7 @@ export class ElementInjector extends TreeNode {
|
||||||
var staticKeys = StaticKeys.instance();
|
var staticKeys = StaticKeys.instance();
|
||||||
if (keyId === staticKeys.viewId) return this._preBuiltObjects.view;
|
if (keyId === staticKeys.viewId) return this._preBuiltObjects.view;
|
||||||
if (keyId === staticKeys.ngElementId) return this._preBuiltObjects.element;
|
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.bindingPropagationConfigId) return this._preBuiltObjects.bindingPropagationConfig;
|
||||||
if (keyId === staticKeys.destinationLightDomId) {
|
if (keyId === staticKeys.destinationLightDomId) {
|
||||||
var p:ElementInjector = this.directParent();
|
var p:ElementInjector = this.directParent();
|
||||||
|
|
|
@ -2,9 +2,7 @@ import {List, Map, ListWrapper, MapWrapper} from 'angular2/src/facade/collection
|
||||||
import {Element, DOM} from 'angular2/src/facade/dom';
|
import {Element, DOM} from 'angular2/src/facade/dom';
|
||||||
import {int, isBlank, isPresent, Type} from 'angular2/src/facade/lang';
|
import {int, isBlank, isPresent, Type} from 'angular2/src/facade/lang';
|
||||||
import {DirectiveMetadata} from '../directive_metadata';
|
import {DirectiveMetadata} from '../directive_metadata';
|
||||||
import {Decorator} from '../../annotations/annotations';
|
import {Decorator, Component, Viewport} from '../../annotations/annotations';
|
||||||
import {Component} from '../../annotations/annotations';
|
|
||||||
import {Template} from '../../annotations/annotations';
|
|
||||||
import {ElementBinder} from '../element_binder';
|
import {ElementBinder} from '../element_binder';
|
||||||
import {ProtoElementInjector} from '../element_injector';
|
import {ProtoElementInjector} from '../element_injector';
|
||||||
import {ProtoView} from '../view';
|
import {ProtoView} from '../view';
|
||||||
|
@ -29,7 +27,7 @@ export class CompileElement {
|
||||||
/// Template name is how it is reffered to it in template
|
/// Template name is how it is reffered to it in template
|
||||||
variableBindings:Map;
|
variableBindings:Map;
|
||||||
decoratorDirectives:List<DirectiveMetadata>;
|
decoratorDirectives:List<DirectiveMetadata>;
|
||||||
templateDirective:DirectiveMetadata;
|
viewportDirective:DirectiveMetadata;
|
||||||
componentDirective:DirectiveMetadata;
|
componentDirective:DirectiveMetadata;
|
||||||
_allDirectives:List<DirectiveMetadata>;
|
_allDirectives:List<DirectiveMetadata>;
|
||||||
isViewRoot:boolean;
|
isViewRoot:boolean;
|
||||||
|
@ -50,7 +48,7 @@ export class CompileElement {
|
||||||
this.eventBindings = null;
|
this.eventBindings = null;
|
||||||
this.variableBindings = null;
|
this.variableBindings = null;
|
||||||
this.decoratorDirectives = null;
|
this.decoratorDirectives = null;
|
||||||
this.templateDirective = null;
|
this.viewportDirective = null;
|
||||||
this.componentDirective = null;
|
this.componentDirective = null;
|
||||||
this._allDirectives = null;
|
this._allDirectives = null;
|
||||||
this.isViewRoot = false;
|
this.isViewRoot = false;
|
||||||
|
@ -141,8 +139,8 @@ export class CompileElement {
|
||||||
if (!annotation.compileChildren) {
|
if (!annotation.compileChildren) {
|
||||||
this.compileChildren = false;
|
this.compileChildren = false;
|
||||||
}
|
}
|
||||||
} else if (annotation instanceof Template) {
|
} else if (annotation instanceof Viewport) {
|
||||||
this.templateDirective = directive;
|
this.viewportDirective = directive;
|
||||||
} else if (annotation instanceof Component) {
|
} else if (annotation instanceof Component) {
|
||||||
this.componentDirective = directive;
|
this.componentDirective = directive;
|
||||||
}
|
}
|
||||||
|
@ -156,8 +154,8 @@ export class CompileElement {
|
||||||
if (isPresent(this.componentDirective)) {
|
if (isPresent(this.componentDirective)) {
|
||||||
ListWrapper.push(directives, this.componentDirective);
|
ListWrapper.push(directives, this.componentDirective);
|
||||||
}
|
}
|
||||||
if (isPresent(this.templateDirective)) {
|
if (isPresent(this.viewportDirective)) {
|
||||||
ListWrapper.push(directives, this.templateDirective);
|
ListWrapper.push(directives, this.viewportDirective);
|
||||||
}
|
}
|
||||||
if (isPresent(this.decoratorDirectives)) {
|
if (isPresent(this.decoratorDirectives)) {
|
||||||
directives = ListWrapper.concat(directives, this.decoratorDirectives);
|
directives = ListWrapper.concat(directives, this.decoratorDirectives);
|
||||||
|
|
|
@ -5,8 +5,7 @@ import {SelectorMatcher} from '../selector';
|
||||||
import {CssSelector} from '../selector';
|
import {CssSelector} from '../selector';
|
||||||
|
|
||||||
import {DirectiveMetadata} from '../directive_metadata';
|
import {DirectiveMetadata} from '../directive_metadata';
|
||||||
import {Template} from '../../annotations/annotations';
|
import {Component, Viewport} from '../../annotations/annotations';
|
||||||
import {Component} from '../../annotations/annotations';
|
|
||||||
import {CompileStep} from './compile_step';
|
import {CompileStep} from './compile_step';
|
||||||
import {CompileElement} from './compile_element';
|
import {CompileElement} from './compile_element';
|
||||||
import {CompileControl} from './compile_control';
|
import {CompileControl} from './compile_control';
|
||||||
|
@ -70,10 +69,10 @@ export class DirectiveParser extends CompileStep {
|
||||||
// only be present on <template> elements any more!
|
// only be present on <template> elements any more!
|
||||||
var isTemplateElement = current.element instanceof TemplateElement;
|
var isTemplateElement = current.element instanceof TemplateElement;
|
||||||
this._selectorMatcher.match(cssSelector, (directive) => {
|
this._selectorMatcher.match(cssSelector, (directive) => {
|
||||||
if (directive.annotation instanceof Template) {
|
if (directive.annotation instanceof Viewport) {
|
||||||
if (!isTemplateElement) {
|
if (!isTemplateElement) {
|
||||||
throw new BaseException('Template directives need to be placed on <template> elements or elements with template attribute!');
|
throw new BaseException('Viewport directives need to be placed on <template> elements or elements with template attribute!');
|
||||||
} else if (isPresent(current.templateDirective)) {
|
} else if (isPresent(current.viewportDirective)) {
|
||||||
throw new BaseException('Only one template directive per element is allowed!');
|
throw new BaseException('Only one template directive per element is allowed!');
|
||||||
}
|
}
|
||||||
} else if (isTemplateElement) {
|
} else if (isTemplateElement) {
|
||||||
|
|
|
@ -78,7 +78,7 @@ function styleSetterFactory(styleName:string, stylesuffix:string) {
|
||||||
* - CompileElement#eventBindings
|
* - CompileElement#eventBindings
|
||||||
* - CompileElement#decoratorDirectives
|
* - CompileElement#decoratorDirectives
|
||||||
* - CompileElement#componentDirective
|
* - CompileElement#componentDirective
|
||||||
* - CompileElement#templateDirective
|
* - CompileElement#viewportDirective
|
||||||
*
|
*
|
||||||
* Note: This actually only needs the CompileElements with the flags
|
* Note: This actually only needs the CompileElements with the flags
|
||||||
* `hasBindings` and `isViewRoot`,
|
* `hasBindings` and `isViewRoot`,
|
||||||
|
@ -105,7 +105,7 @@ export class ElementBinderBuilder extends CompileStep {
|
||||||
current.inheritedProtoElementInjector : null;
|
current.inheritedProtoElementInjector : null;
|
||||||
|
|
||||||
elementBinder = protoView.bindElement(currentProtoElementInjector,
|
elementBinder = protoView.bindElement(currentProtoElementInjector,
|
||||||
current.componentDirective, current.templateDirective);
|
current.componentDirective, current.viewportDirective);
|
||||||
|
|
||||||
if (isPresent(current.textNodeBindings)) {
|
if (isPresent(current.textNodeBindings)) {
|
||||||
this._bindTextNodes(protoView, current);
|
this._bindTextNodes(protoView, current);
|
||||||
|
|
|
@ -22,7 +22,7 @@ const NG_BINDING_CLASS = 'ng-binding';
|
||||||
* - CompileElement#eventBindings
|
* - CompileElement#eventBindings
|
||||||
* - CompileElement#decoratorDirectives
|
* - CompileElement#decoratorDirectives
|
||||||
* - CompileElement#componentDirective
|
* - CompileElement#componentDirective
|
||||||
* - CompileElement#templateDirective
|
* - CompileElement#viewportDirective
|
||||||
*/
|
*/
|
||||||
export class ElementBindingMarker extends CompileStep {
|
export class ElementBindingMarker extends CompileStep {
|
||||||
process(parent:CompileElement, current:CompileElement, control:CompileControl) {
|
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.variableBindings) && MapWrapper.size(current.variableBindings)>0) ||
|
||||||
(isPresent(current.eventBindings) && MapWrapper.size(current.eventBindings)>0) ||
|
(isPresent(current.eventBindings) && MapWrapper.size(current.eventBindings)>0) ||
|
||||||
(isPresent(current.decoratorDirectives) && current.decoratorDirectives.length > 0) ||
|
(isPresent(current.decoratorDirectives) && current.decoratorDirectives.length > 0) ||
|
||||||
isPresent(current.templateDirective) ||
|
isPresent(current.viewportDirective) ||
|
||||||
isPresent(current.componentDirective);
|
isPresent(current.componentDirective);
|
||||||
|
|
||||||
if (hasBindings) {
|
if (hasBindings) {
|
||||||
|
|
|
@ -23,7 +23,7 @@ import {DirectiveMetadata} from '../directive_metadata';
|
||||||
* - CompileElement#inheritedProtoView
|
* - CompileElement#inheritedProtoView
|
||||||
* - CompileElement#decoratorDirectives
|
* - CompileElement#decoratorDirectives
|
||||||
* - CompileElement#componentDirective
|
* - CompileElement#componentDirective
|
||||||
* - CompileElement#templateDirective
|
* - CompileElement#viewportDirective
|
||||||
*/
|
*/
|
||||||
export class ProtoElementInjectorBuilder extends CompileStep {
|
export class ProtoElementInjectorBuilder extends CompileStep {
|
||||||
// public so that we can overwrite it in tests
|
// public so that we can overwrite it in tests
|
||||||
|
@ -52,8 +52,8 @@ export class ProtoElementInjectorBuilder extends CompileStep {
|
||||||
);
|
);
|
||||||
current.distanceToParentInjector = 0;
|
current.distanceToParentInjector = 0;
|
||||||
|
|
||||||
// Template directives are treated differently than other element with var- definitions.
|
// Viewport directives are treated differently than other element with var- definitions.
|
||||||
if (isPresent(current.variableBindings) && !isPresent(current.templateDirective)) {
|
if (isPresent(current.variableBindings) && !isPresent(current.viewportDirective)) {
|
||||||
current.inheritedProtoElementInjector.exportComponent = hasComponent;
|
current.inheritedProtoElementInjector.exportComponent = hasComponent;
|
||||||
current.inheritedProtoElementInjector.exportElement = !hasComponent;
|
current.inheritedProtoElementInjector.exportElement = !hasComponent;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import {isBlank, isPresent} from 'angular2/src/facade/lang';
|
||||||
|
|
||||||
import {View} from '../view';
|
import {View} from '../view';
|
||||||
import {ElementInjector} from '../element_injector';
|
import {ElementInjector} from '../element_injector';
|
||||||
import {ViewPort} from '../viewport';
|
import {ViewContainer} from '../view_container';
|
||||||
import {Content} from './content_tag';
|
import {Content} from './content_tag';
|
||||||
|
|
||||||
export class SourceLightDom {}
|
export class SourceLightDom {}
|
||||||
|
@ -60,9 +60,9 @@ export class LightDom {
|
||||||
if (ei.hasDirective(Content)) {
|
if (ei.hasDirective(Content)) {
|
||||||
ListWrapper.push(acc, ei.get(Content));
|
ListWrapper.push(acc, ei.get(Content));
|
||||||
|
|
||||||
} else if (ei.hasPreBuiltObject(ViewPort)) {
|
} else if (ei.hasPreBuiltObject(ViewContainer)) {
|
||||||
var vp = ei.get(ViewPort);
|
var vc = ei.get(ViewContainer);
|
||||||
ListWrapper.forEach(vp.contentTagContainers(), (view) => {
|
ListWrapper.forEach(vc.contentTagContainers(), (view) => {
|
||||||
this._collectAllContentTags(view, acc);
|
this._collectAllContentTags(view, acc);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ export class LightDom {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collects the nodes of the light DOM by merging:
|
// Collects the nodes of the light DOM by merging:
|
||||||
// - nodes from enclosed ViewPorts,
|
// - nodes from enclosed ViewContainers,
|
||||||
// - nodes from enclosed content tags,
|
// - nodes from enclosed content tags,
|
||||||
// - plain DOM nodes
|
// - plain DOM nodes
|
||||||
expandedDomNodes():List {
|
expandedDomNodes():List {
|
||||||
|
@ -83,9 +83,9 @@ export class LightDom {
|
||||||
var root = roots[i];
|
var root = roots[i];
|
||||||
var ei = root.injector;
|
var ei = root.injector;
|
||||||
|
|
||||||
if (isPresent(ei) && ei.hasPreBuiltObject(ViewPort)) {
|
if (isPresent(ei) && ei.hasPreBuiltObject(ViewContainer)) {
|
||||||
var vp = root.injector.get(ViewPort);
|
var vc = root.injector.get(ViewContainer);
|
||||||
res = ListWrapper.concat(res, vp.nodes());
|
res = ListWrapper.concat(res, vc.nodes());
|
||||||
|
|
||||||
} else if (isPresent(ei) && ei.hasDirective(Content)) {
|
} else if (isPresent(ei) && ei.hasDirective(Content)) {
|
||||||
var content = root.injector.get(Content);
|
var content = root.injector.get(Content);
|
||||||
|
|
|
@ -11,7 +11,7 @@ import {SetterFn} from 'angular2/src/reflection/types';
|
||||||
import {FIELD, IMPLEMENTS, int, isPresent, isBlank, BaseException} from 'angular2/src/facade/lang';
|
import {FIELD, IMPLEMENTS, int, isPresent, isBlank, BaseException} from 'angular2/src/facade/lang';
|
||||||
import {Injector} from 'angular2/di';
|
import {Injector} from 'angular2/di';
|
||||||
import {NgElement} from 'angular2/src/core/dom/element';
|
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 {Content} from './shadow_dom_emulation/content_tag';
|
||||||
import {LightDom, DestinationLightDom} from './shadow_dom_emulation/light_dom';
|
import {LightDom, DestinationLightDom} from './shadow_dom_emulation/light_dom';
|
||||||
import {ShadowDomStrategy} from './shadow_dom_strategy';
|
import {ShadowDomStrategy} from './shadow_dom_strategy';
|
||||||
|
@ -42,7 +42,7 @@ export class View {
|
||||||
/// to keep track of the nodes.
|
/// to keep track of the nodes.
|
||||||
nodes:List<Node>;
|
nodes:List<Node>;
|
||||||
componentChildViews: List<View>;
|
componentChildViews: List<View>;
|
||||||
viewPorts: List<ViewPort>;
|
viewContainers: List<ViewContainer>;
|
||||||
preBuiltObjects: List<PreBuiltObjects>;
|
preBuiltObjects: List<PreBuiltObjects>;
|
||||||
proto: ProtoView;
|
proto: ProtoView;
|
||||||
context: any;
|
context: any;
|
||||||
|
@ -57,7 +57,7 @@ export class View {
|
||||||
this.textNodes = null;
|
this.textNodes = null;
|
||||||
this.bindElements = null;
|
this.bindElements = null;
|
||||||
this.componentChildViews = null;
|
this.componentChildViews = null;
|
||||||
this.viewPorts = null;
|
this.viewContainers = null;
|
||||||
this.preBuiltObjects = null;
|
this.preBuiltObjects = null;
|
||||||
this.context = null;
|
this.context = null;
|
||||||
this.contextWithLocals = (MapWrapper.size(protoContextLocals) > 0)
|
this.contextWithLocals = (MapWrapper.size(protoContextLocals) > 0)
|
||||||
|
@ -65,12 +65,13 @@ export class View {
|
||||||
: null;
|
: 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.elementInjectors = elementInjectors;
|
||||||
this.rootElementInjectors = rootElementInjectors;
|
this.rootElementInjectors = rootElementInjectors;
|
||||||
this.textNodes = textNodes;
|
this.textNodes = textNodes;
|
||||||
this.bindElements = bindElements;
|
this.bindElements = bindElements;
|
||||||
this.viewPorts = viewPorts;
|
this.viewContainers = viewContainers;
|
||||||
this.preBuiltObjects = preBuiltObjects;
|
this.preBuiltObjects = preBuiltObjects;
|
||||||
this.componentChildViews = componentChildViews;
|
this.componentChildViews = componentChildViews;
|
||||||
}
|
}
|
||||||
|
@ -117,7 +118,7 @@ export class View {
|
||||||
*
|
*
|
||||||
* - all element injectors are empty.
|
* - all element injectors are empty.
|
||||||
* - all appInjectors are released.
|
* - all appInjectors are released.
|
||||||
* - all viewports are empty.
|
* - all viewcontainers are empty.
|
||||||
* - all context locals are set to null.
|
* - all context locals are set to null.
|
||||||
* - the view context is null.
|
* - the view context is null.
|
||||||
*
|
*
|
||||||
|
@ -129,9 +130,9 @@ export class View {
|
||||||
if (this.hydrated()) throw new BaseException('The view is already hydrated.');
|
if (this.hydrated()) throw new BaseException('The view is already hydrated.');
|
||||||
this._hydrateContext(context);
|
this._hydrateContext(context);
|
||||||
|
|
||||||
// viewPorts
|
// viewContainers
|
||||||
for (var i = 0; i < this.viewPorts.length; i++) {
|
for (var i = 0; i < this.viewContainers.length; i++) {
|
||||||
this.viewPorts[i].hydrate(appInjector, hostElementInjector);
|
this.viewContainers[i].hydrate(appInjector, hostElementInjector);
|
||||||
}
|
}
|
||||||
|
|
||||||
var binders = this.proto.elementBinders;
|
var binders = this.proto.elementBinders;
|
||||||
|
@ -201,10 +202,10 @@ export class View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// viewPorts
|
// viewContainers
|
||||||
if (isPresent(this.viewPorts)) {
|
if (isPresent(this.viewContainers)) {
|
||||||
for (var i = 0; i < this.viewPorts.length; i++) {
|
for (var i = 0; i < this.viewContainers.length; i++) {
|
||||||
this.viewPorts[i].dehydrate();
|
this.viewContainers[i].dehydrate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,7 +342,7 @@ export class ProtoView {
|
||||||
var textNodes = [];
|
var textNodes = [];
|
||||||
var elementsWithPropertyBindings = [];
|
var elementsWithPropertyBindings = [];
|
||||||
var preBuiltObjects = ListWrapper.createFixedSize(binders.length);
|
var preBuiltObjects = ListWrapper.createFixedSize(binders.length);
|
||||||
var viewPorts = [];
|
var viewContainers = [];
|
||||||
var componentChildViews = [];
|
var componentChildViews = [];
|
||||||
|
|
||||||
for (var i = 0; i < binders.length; i++) {
|
for (var i = 0; i < binders.length; i++) {
|
||||||
|
@ -399,18 +400,18 @@ export class ProtoView {
|
||||||
ListWrapper.push(componentChildViews, childView);
|
ListWrapper.push(componentChildViews, childView);
|
||||||
}
|
}
|
||||||
|
|
||||||
// viewPorts
|
// viewContainers
|
||||||
var viewPort = null;
|
var viewContainer = null;
|
||||||
if (isPresent(binder.templateDirective)) {
|
if (isPresent(binder.viewportDirective)) {
|
||||||
var destLightDom = this._directParentElementLightDom(protoElementInjector, preBuiltObjects);
|
var destLightDom = this._directParentElementLightDom(protoElementInjector, preBuiltObjects);
|
||||||
viewPort = new ViewPort(view, element, binder.nestedProtoView, elementInjector,
|
viewContainer = new ViewContainer(view, element, binder.nestedProtoView, elementInjector,
|
||||||
eventManager, destLightDom);
|
eventManager, destLightDom);
|
||||||
ListWrapper.push(viewPorts, viewPort);
|
ListWrapper.push(viewContainers, viewContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// preBuiltObjects
|
// preBuiltObjects
|
||||||
if (isPresent(elementInjector)) {
|
if (isPresent(elementInjector)) {
|
||||||
preBuiltObjects[i] = new PreBuiltObjects(view, new NgElement(element), viewPort,
|
preBuiltObjects[i] = new PreBuiltObjects(view, new NgElement(element), viewContainer,
|
||||||
lightDom, bindingPropagationConfig);
|
lightDom, bindingPropagationConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,7 +427,7 @@ export class ProtoView {
|
||||||
}
|
}
|
||||||
|
|
||||||
view.init(elementInjectors, rootElementInjectors, textNodes, elementsWithPropertyBindings,
|
view.init(elementInjectors, rootElementInjectors, textNodes, elementsWithPropertyBindings,
|
||||||
viewPorts, preBuiltObjects, componentChildViews);
|
viewContainers, preBuiltObjects, componentChildViews);
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
@ -461,8 +462,8 @@ export class ProtoView {
|
||||||
}
|
}
|
||||||
|
|
||||||
bindElement(protoElementInjector:ProtoElementInjector,
|
bindElement(protoElementInjector:ProtoElementInjector,
|
||||||
componentDirective:DirectiveMetadata = null, templateDirective:DirectiveMetadata = null):ElementBinder {
|
componentDirective:DirectiveMetadata = null, viewportDirective:DirectiveMetadata = null):ElementBinder {
|
||||||
var elBinder = new ElementBinder(protoElementInjector, componentDirective, templateDirective);
|
var elBinder = new ElementBinder(protoElementInjector, componentDirective, viewportDirective);
|
||||||
ListWrapper.push(this.elementBinders, elBinder);
|
ListWrapper.push(this.elementBinders, elBinder);
|
||||||
return elBinder;
|
return elBinder;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {ElementInjector} from 'angular2/src/core/compiler/element_injector';
|
||||||
import {isPresent, isBlank} from 'angular2/src/facade/lang';
|
import {isPresent, isBlank} from 'angular2/src/facade/lang';
|
||||||
import {EventManager} from 'angular2/src/core/events/event_manager';
|
import {EventManager} from 'angular2/src/core/events/event_manager';
|
||||||
|
|
||||||
export class ViewPort {
|
export class ViewContainer {
|
||||||
parentView: View;
|
parentView: View;
|
||||||
templateElement: Element;
|
templateElement: Element;
|
||||||
defaultProtoView: ProtoView;
|
defaultProtoView: ProtoView;
|
||||||
|
@ -71,7 +71,7 @@ export class ViewPort {
|
||||||
// to the methods below.
|
// to the methods below.
|
||||||
create(atIndex=-1): View {
|
create(atIndex=-1): View {
|
||||||
if (!this.hydrated()) throw new BaseException(
|
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.
|
// TODO(rado): replace with viewFactory.
|
||||||
var newView = this.defaultProtoView.instantiate(this.hostElementInjector, this._eventManager);
|
var newView = this.defaultProtoView.instantiate(this.hostElementInjector, this._eventManager);
|
||||||
newView.hydrate(this.appInjector, this.hostElementInjector, this.parentView.context);
|
newView.hydrate(this.appInjector, this.hostElementInjector, this.parentView.context);
|
||||||
|
@ -82,7 +82,7 @@ export class ViewPort {
|
||||||
if (atIndex == -1) atIndex = this._views.length;
|
if (atIndex == -1) atIndex = this._views.length;
|
||||||
ListWrapper.insert(this._views, atIndex, view);
|
ListWrapper.insert(this._views, atIndex, view);
|
||||||
if (isBlank(this._lightDom)) {
|
if (isBlank(this._lightDom)) {
|
||||||
ViewPort.moveViewNodesAfterSibling(this._siblingToInsertAfter(atIndex), view);
|
ViewContainer.moveViewNodesAfterSibling(this._siblingToInsertAfter(atIndex), view);
|
||||||
} else {
|
} else {
|
||||||
this._lightDom.redistribute();
|
this._lightDom.redistribute();
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ export class ViewPort {
|
||||||
var detachedView = this.get(atIndex);
|
var detachedView = this.get(atIndex);
|
||||||
ListWrapper.removeAt(this._views, atIndex);
|
ListWrapper.removeAt(this._views, atIndex);
|
||||||
if (isBlank(this._lightDom)) {
|
if (isBlank(this._lightDom)) {
|
||||||
ViewPort.removeViewNodesFromParent(this.templateElement.parentNode, detachedView);
|
ViewContainer.removeViewNodesFromParent(this.templateElement.parentNode, detachedView);
|
||||||
} else {
|
} else {
|
||||||
this._lightDom.redistribute();
|
this._lightDom.redistribute();
|
||||||
}
|
}
|
|
@ -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 {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 {View} from 'angular2/src/core/compiler/view';
|
||||||
import {isPresent, isBlank} from 'angular2/src/facade/lang';
|
import {isPresent, isBlank} from 'angular2/src/facade/lang';
|
||||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||||
|
|
||||||
@Template({
|
@Viewport({
|
||||||
selector: '[foreach][in]',
|
selector: '[foreach][in]',
|
||||||
lifecycle: [onChange],
|
lifecycle: [onChange],
|
||||||
bind: {
|
bind: {
|
||||||
|
@ -13,16 +13,16 @@ import {ListWrapper} from 'angular2/src/facade/collection';
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
export class Foreach extends OnChange {
|
export class Foreach extends OnChange {
|
||||||
viewPort: ViewPort;
|
viewContainer: ViewContainer;
|
||||||
iterable;
|
iterable;
|
||||||
constructor(viewPort: ViewPort) {
|
constructor(viewContainer: ViewContainer) {
|
||||||
super();
|
super();
|
||||||
this.viewPort = viewPort;
|
this.viewContainer = viewContainer;
|
||||||
}
|
}
|
||||||
onChange(changes) {
|
onChange(changes) {
|
||||||
var iteratorChanges = changes['iterable'];
|
var iteratorChanges = changes['iterable'];
|
||||||
if (isBlank(iteratorChanges) || isBlank(iteratorChanges.currentValue)) {
|
if (isBlank(iteratorChanges) || isBlank(iteratorChanges.currentValue)) {
|
||||||
this.viewPort.clear();
|
this.viewContainer.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,13 +37,13 @@ export class Foreach extends OnChange {
|
||||||
(movedRecord) => ListWrapper.push(recordViewTuples, new RecordViewTuple(movedRecord, null))
|
(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(
|
iteratorChanges.currentValue.forEachAddedItem(
|
||||||
(addedRecord) => ListWrapper.push(insertTuples, new RecordViewTuple(addedRecord, null))
|
(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++) {
|
for (var i = 0; i < insertTuples.length; i++) {
|
||||||
this.perViewChange(insertTuples[i].view, insertTuples[i].record);
|
this.perViewChange(insertTuples[i].view, insertTuples[i].record);
|
||||||
|
@ -55,30 +55,30 @@ export class Foreach extends OnChange {
|
||||||
view.setLocal('index', record.currentIndex);
|
view.setLocal('index', record.currentIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bulkRemove(tuples, viewPort) {
|
static bulkRemove(tuples, viewContainer) {
|
||||||
tuples.sort((a, b) => a.record.previousIndex - b.record.previousIndex);
|
tuples.sort((a, b) => a.record.previousIndex - b.record.previousIndex);
|
||||||
var movedTuples = [];
|
var movedTuples = [];
|
||||||
for (var i = tuples.length - 1; i >= 0; i--) {
|
for (var i = tuples.length - 1; i >= 0; i--) {
|
||||||
var tuple = tuples[i];
|
var tuple = tuples[i];
|
||||||
// separate moved views from removed views.
|
// separate moved views from removed views.
|
||||||
if (isPresent(tuple.record.currentIndex)) {
|
if (isPresent(tuple.record.currentIndex)) {
|
||||||
tuple.view = viewPort.detach(tuple.record.previousIndex);
|
tuple.view = viewContainer.detach(tuple.record.previousIndex);
|
||||||
ListWrapper.push(movedTuples, tuple);
|
ListWrapper.push(movedTuples, tuple);
|
||||||
} else {
|
} else {
|
||||||
viewPort.remove(tuple.record.previousIndex);
|
viewContainer.remove(tuple.record.previousIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return movedTuples;
|
return movedTuples;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bulkInsert(tuples, viewPort) {
|
static bulkInsert(tuples, viewContainer) {
|
||||||
tuples.sort((a, b) => a.record.currentIndex - b.record.currentIndex);
|
tuples.sort((a, b) => a.record.currentIndex - b.record.currentIndex);
|
||||||
for (var i = 0; i < tuples.length; i++) {
|
for (var i = 0; i < tuples.length; i++) {
|
||||||
var tuple = tuples[i];
|
var tuple = tuples[i];
|
||||||
if (isPresent(tuple.view)) {
|
if (isPresent(tuple.view)) {
|
||||||
viewPort.insert(tuple.view, tuple.record.currentIndex);
|
viewContainer.insert(tuple.view, tuple.record.currentIndex);
|
||||||
} else {
|
} else {
|
||||||
tuple.view = viewPort.create(tuple.record.currentIndex);
|
tuple.view = viewContainer.create(tuple.record.currentIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tuples;
|
return tuples;
|
||||||
|
|
|
@ -1,29 +1,29 @@
|
||||||
import {Template} from 'angular2/src/core/annotations/annotations';
|
import {Viewport} from 'angular2/src/core/annotations/annotations';
|
||||||
import {ViewPort} from 'angular2/src/core/compiler/viewport';
|
import {ViewContainer} from 'angular2/src/core/compiler/view_container';
|
||||||
import {isBlank} from 'angular2/src/facade/lang';
|
import {isBlank} from 'angular2/src/facade/lang';
|
||||||
|
|
||||||
@Template({
|
@Viewport({
|
||||||
selector: '[if]',
|
selector: '[if]',
|
||||||
bind: {
|
bind: {
|
||||||
'if': 'condition'
|
'if': 'condition'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
export class If {
|
export class If {
|
||||||
viewPort: ViewPort;
|
viewContainer: ViewContainer;
|
||||||
prevCondition: boolean;
|
prevCondition: boolean;
|
||||||
|
|
||||||
constructor(viewPort: ViewPort) {
|
constructor(viewContainer: ViewContainer) {
|
||||||
this.viewPort = viewPort;
|
this.viewContainer = viewContainer;
|
||||||
this.prevCondition = null;
|
this.prevCondition = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
set condition(newCondition) {
|
set condition(newCondition) {
|
||||||
if (newCondition && (isBlank(this.prevCondition) || !this.prevCondition)) {
|
if (newCondition && (isBlank(this.prevCondition) || !this.prevCondition)) {
|
||||||
this.prevCondition = true;
|
this.prevCondition = true;
|
||||||
this.viewPort.create();
|
this.viewContainer.create();
|
||||||
} else if (!newCondition && (isBlank(this.prevCondition) || this.prevCondition)) {
|
} else if (!newCondition && (isBlank(this.prevCondition) || this.prevCondition)) {
|
||||||
this.prevCondition = false;
|
this.prevCondition = false;
|
||||||
this.viewPort.clear();
|
this.viewContainer.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import {Decorator, Template} from 'angular2/src/core/annotations/annotations';
|
import {Decorator, Viewport} from 'angular2/src/core/annotations/annotations';
|
||||||
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 {NgElement} from 'angular2/src/core/dom/element';
|
||||||
import {DOM} from 'angular2/src/facade/dom';
|
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 {ListWrapper, List, MapWrapper, Map} from 'angular2/src/facade/collection';
|
||||||
import {Parent} from 'angular2/src/core/annotations/visibility';
|
import {Parent} from 'angular2/src/core/annotations/visibility';
|
||||||
|
|
||||||
|
@ -40,89 +40,89 @@ import {Parent} from 'angular2/src/core/annotations/visibility';
|
||||||
export class Switch {
|
export class Switch {
|
||||||
_switchValue: any;
|
_switchValue: any;
|
||||||
_useDefault: boolean;
|
_useDefault: boolean;
|
||||||
_valueViewPorts: Map;
|
_valueViewContainers: Map;
|
||||||
_activeViewPorts: List;
|
_activeViewContainers: List<ViewContainer>;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this._valueViewPorts = MapWrapper.create();
|
this._valueViewContainers = MapWrapper.create();
|
||||||
this._activeViewPorts = ListWrapper.create();
|
this._activeViewContainers = ListWrapper.create();
|
||||||
this._useDefault = false;
|
this._useDefault = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
set value(value) {
|
set value(value) {
|
||||||
// Remove the currently active viewports
|
// Empty the currently active ViewContainers
|
||||||
this._removeAllActiveViewPorts();
|
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;
|
this._useDefault = false;
|
||||||
var viewPorts = MapWrapper.get(this._valueViewPorts, value);
|
var containers = MapWrapper.get(this._valueViewContainers, value);
|
||||||
if (isBlank(viewPorts)) {
|
if (isBlank(containers)) {
|
||||||
this._useDefault = true;
|
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;
|
this._switchValue = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
_onWhenValueChanged(oldWhen, newWhen, viewPort: ViewPort) {
|
_onWhenValueChanged(oldWhen, newWhen, viewContainer: ViewContainer) {
|
||||||
this._deregisterViewPort(oldWhen, viewPort);
|
this._deregisterViewContainer(oldWhen, viewContainer);
|
||||||
this._registerViewPort(newWhen, viewPort);
|
this._registerViewContainer(newWhen, viewContainer);
|
||||||
|
|
||||||
if (oldWhen === this._switchValue) {
|
if (oldWhen === this._switchValue) {
|
||||||
viewPort.remove();
|
viewContainer.remove();
|
||||||
ListWrapper.remove(this._activeViewPorts, viewPort);
|
ListWrapper.remove(this._activeViewContainers, viewContainer);
|
||||||
} else if (newWhen === this._switchValue) {
|
} else if (newWhen === this._switchValue) {
|
||||||
if (this._useDefault) {
|
if (this._useDefault) {
|
||||||
this._useDefault = false;
|
this._useDefault = false;
|
||||||
this._removeAllActiveViewPorts();
|
this._emptyAllActiveViewContainers();
|
||||||
}
|
}
|
||||||
viewPort.create();
|
viewContainer.create();
|
||||||
ListWrapper.push(this._activeViewPorts, viewPort);
|
ListWrapper.push(this._activeViewContainers, viewContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch to default when there is no more active viewports
|
// Switch to default when there is no more active ViewContainers
|
||||||
if (this._activeViewPorts.length === 0 && !this._useDefault) {
|
if (this._activeViewContainers.length === 0 && !this._useDefault) {
|
||||||
this._useDefault = true;
|
this._useDefault = true;
|
||||||
this._activateViewPorts(MapWrapper.get(this._valueViewPorts, _whenDefault));
|
this._activateViewContainers(MapWrapper.get(this._valueViewContainers, _whenDefault));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_removeAllActiveViewPorts() {
|
_emptyAllActiveViewContainers() {
|
||||||
var activeViewPorts = this._activeViewPorts;
|
var activeContainers = this._activeViewContainers;
|
||||||
for (var i = 0; i < activeViewPorts.length; i++) {
|
for (var i = 0; i < activeContainers.length; i++) {
|
||||||
activeViewPorts[i].remove();
|
activeContainers[i].remove();
|
||||||
}
|
}
|
||||||
this._activeViewPorts = ListWrapper.create();
|
this._activeViewContainers = ListWrapper.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
_activateViewPorts(viewPorts) {
|
_activateViewContainers(containers: List<ViewContainer>) {
|
||||||
// TODO(vicb): assert(this._activeViewPorts.length === 0);
|
// TODO(vicb): assert(this._activeViewContainers.length === 0);
|
||||||
if (isPresent(viewPorts)) {
|
if (isPresent(containers)) {
|
||||||
for (var i = 0; i < viewPorts.length; i++) {
|
for (var i = 0; i < containers.length; i++) {
|
||||||
viewPorts[i].create();
|
containers[i].create();
|
||||||
}
|
}
|
||||||
this._activeViewPorts = viewPorts;
|
this._activeViewContainers = containers;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_registerViewPort(value, viewPort: ViewPort) {
|
_registerViewContainer(value, container: ViewContainer) {
|
||||||
var viewPorts = MapWrapper.get(this._valueViewPorts, value);
|
var containers = MapWrapper.get(this._valueViewContainers, value);
|
||||||
if (isBlank(viewPorts)) {
|
if (isBlank(containers)) {
|
||||||
viewPorts = ListWrapper.create();
|
containers = ListWrapper.create();
|
||||||
MapWrapper.set(this._valueViewPorts, value, viewPorts);
|
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
|
// `_whenDefault` is used a marker for non-registered whens
|
||||||
if (value == _whenDefault) return;
|
if (value == _whenDefault) return;
|
||||||
var viewPorts = MapWrapper.get(this._valueViewPorts, value);
|
var containers = MapWrapper.get(this._valueViewContainers, value);
|
||||||
if (viewPorts.length == 1) {
|
if (containers.length == 1) {
|
||||||
MapWrapper.delete(this._valueViewPorts, value);
|
MapWrapper.delete(this._valueViewContainers, value);
|
||||||
} else {
|
} else {
|
||||||
ListWrapper.remove(viewPorts, viewPort);
|
ListWrapper.remove(containers, container);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,7 +142,7 @@ export class Switch {
|
||||||
* <template [switch-when]="'stringValue'">...</template>
|
* <template [switch-when]="'stringValue'">...</template>
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
@Template({
|
@Viewport({
|
||||||
selector: '[switch-when]',
|
selector: '[switch-when]',
|
||||||
bind: {
|
bind: {
|
||||||
'switch-when' : 'when'
|
'switch-when' : 'when'
|
||||||
|
@ -151,17 +151,17 @@ export class Switch {
|
||||||
export class SwitchWhen {
|
export class SwitchWhen {
|
||||||
_value: any;
|
_value: any;
|
||||||
_switch: Switch;
|
_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
|
// `_whenDefault` is used as a marker for a not yet initialized value
|
||||||
this._value = _whenDefault;
|
this._value = _whenDefault;
|
||||||
this._switch = sswitch;
|
this._switch = sswitch;
|
||||||
this._viewPort = viewPort;
|
this._viewContainer = viewContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
set when(value) {
|
set when(value) {
|
||||||
this._switch._onWhenValueChanged(this._value, value, this._viewPort);
|
this._switch._onWhenValueChanged(this._value, value, this._viewContainer);
|
||||||
this._value = value;
|
this._value = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,12 +178,12 @@ export class SwitchWhen {
|
||||||
* <template [switch-default]>...</template>
|
* <template [switch-default]>...</template>
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
@Template({
|
@Viewport({
|
||||||
selector: '[switch-default]'
|
selector: '[switch-default]'
|
||||||
})
|
})
|
||||||
export class SwitchDefault {
|
export class SwitchDefault {
|
||||||
constructor(viewPort: ViewPort, @Parent() sswitch: Switch) {
|
constructor(viewContainer: ViewContainer, @Parent() sswitch: Switch) {
|
||||||
sswitch._registerViewPort(_whenDefault, viewPort);
|
sswitch._registerViewContainer(_whenDefault, viewContainer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ import {onDestroy} from 'angular2/src/core/annotations/annotations';
|
||||||
import {Injector, Inject, bind} from 'angular2/di';
|
import {Injector, Inject, bind} from 'angular2/di';
|
||||||
import {View} from 'angular2/src/core/compiler/view';
|
import {View} from 'angular2/src/core/compiler/view';
|
||||||
import {ProtoRecordRange} from 'angular2/change_detection';
|
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 {NgElement} from 'angular2/src/core/dom/element';
|
||||||
import {LightDom, SourceLightDom, DestinationLightDom} from 'angular2/src/core/compiler/shadow_dom_emulation/light_dom';
|
import {LightDom, SourceLightDom, DestinationLightDom} from 'angular2/src/core/compiler/shadow_dom_emulation/light_dom';
|
||||||
import {Directive} from 'angular2/src/core/annotations/annotations';
|
import {Directive} from 'angular2/src/core/annotations/annotations';
|
||||||
|
@ -409,11 +409,11 @@ export function main() {
|
||||||
expect(inj.get(NgElement)).toEqual(element);
|
expect(inj.get(NgElement)).toEqual(element);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return viewPort', function () {
|
it('should return viewContainer', function () {
|
||||||
var viewPort = new ViewPort(null, null, null, null, null);
|
var viewContainer = new ViewContainer(null, null, null, null, null);
|
||||||
var inj = injector([], null, null, new PreBuiltObjects(null, null, viewPort, 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 () {
|
it('should return bindingPropagationConfig', function () {
|
||||||
|
|
|
@ -11,10 +11,10 @@ import {NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_str
|
||||||
import {TemplateLoader} from 'angular2/src/core/compiler/template_loader';
|
import {TemplateLoader} from 'angular2/src/core/compiler/template_loader';
|
||||||
import {BindingPropagationConfig} from 'angular2/src/core/compiler/binding_propagation_config';
|
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 {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 {MapWrapper} from 'angular2/src/facade/collection';
|
||||||
|
|
||||||
import {XHRMock} from 'angular2/src/mock/xhr_mock';
|
import {XHRMock} from 'angular2/src/mock/xhr_mock';
|
||||||
|
@ -262,7 +262,7 @@ class PushBasedComp {
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
template: new TemplateConfig({
|
template: new TemplateConfig({
|
||||||
directives: [MyDir, [[ChildComp], SomeTemplate, PushBasedComp]]
|
directives: [MyDir, [[ChildComp], SomeViewport, PushBasedComp]]
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
class MyComp {
|
class MyComp {
|
||||||
|
@ -289,13 +289,13 @@ class ChildComp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Template({
|
@Viewport({
|
||||||
selector: '[some-tmplate]'
|
selector: '[some-tmplate]'
|
||||||
})
|
})
|
||||||
class SomeTemplate {
|
class SomeViewport {
|
||||||
constructor(viewPort: ViewPort) {
|
constructor(container: ViewContainer) {
|
||||||
viewPort.create().setLocal('some-tmpl', 'hello');
|
container.create().setLocal('some-tmpl', 'hello');
|
||||||
viewPort.create().setLocal('some-tmpl', 'again');
|
container.create().setLocal('some-tmpl', 'again');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {CompileControl} from 'angular2/src/core/compiler/pipeline/compile_control';
|
||||||
import {DOM} from 'angular2/src/facade/dom';
|
import {DOM} from 'angular2/src/facade/dom';
|
||||||
import {NativeShadowDomStrategy, ShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
import {NativeShadowDomStrategy, ShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
||||||
import {Component} from 'angular2/src/core/annotations/annotations';
|
import {Component, Decorator, Viewport} from 'angular2/src/core/annotations/annotations';
|
||||||
import {Decorator} from 'angular2/src/core/annotations/annotations';
|
|
||||||
import {Template} from 'angular2/src/core/annotations/annotations';
|
|
||||||
import {TemplateConfig} from 'angular2/src/core/annotations/template_config';
|
import {TemplateConfig} from 'angular2/src/core/annotations/template_config';
|
||||||
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
||||||
import {Lexer, Parser} from 'angular2/change_detection';
|
import {Lexer, Parser} from 'angular2/change_detection';
|
||||||
|
@ -25,8 +23,8 @@ export function main() {
|
||||||
SomeDecorator,
|
SomeDecorator,
|
||||||
SomeDecoratorIgnoringChildren,
|
SomeDecoratorIgnoringChildren,
|
||||||
SomeDecoratorWithBinding,
|
SomeDecoratorWithBinding,
|
||||||
SomeTemplate,
|
SomeViewport,
|
||||||
SomeTemplate2,
|
SomeViewport2,
|
||||||
SomeComponent,
|
SomeComponent,
|
||||||
SomeComponent2
|
SomeComponent2
|
||||||
];
|
];
|
||||||
|
@ -55,7 +53,7 @@ export function main() {
|
||||||
var results = createPipeline().process(el('<div></div>'));
|
var results = createPipeline().process(el('<div></div>'));
|
||||||
expect(results[0].decoratorDirectives).toBe(null);
|
expect(results[0].decoratorDirectives).toBe(null);
|
||||||
expect(results[0].componentDirective).toBe(null);
|
expect(results[0].componentDirective).toBe(null);
|
||||||
expect(results[0].templateDirective).toBe(null);
|
expect(results[0].viewportDirective).toBe(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('component directives', () => {
|
describe('component directives', () => {
|
||||||
|
@ -105,10 +103,10 @@ export function main() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('template directives', () => {
|
describe('viewport directives', () => {
|
||||||
it('should detect them in attributes', () => {
|
it('should detect them in attributes', () => {
|
||||||
var results = createPipeline().process(el('<template some-templ></template>'));
|
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', () => {
|
it('should detect them in property bindings', () => {
|
||||||
|
@ -116,7 +114,7 @@ export function main() {
|
||||||
'some-templ': 'someExpr'
|
'some-templ': 'someExpr'
|
||||||
}});
|
}});
|
||||||
var results = pipeline.process(el('<template></template>'));
|
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', () => {
|
it('should detect them in variable bindings', () => {
|
||||||
|
@ -124,10 +122,10 @@ export function main() {
|
||||||
'some-templ': 'someExpr'
|
'some-templ': 'someExpr'
|
||||||
}});
|
}});
|
||||||
var results = pipeline.process(el('<template></template>'));
|
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( () => {
|
expect( () => {
|
||||||
createPipeline().process(
|
createPipeline().process(
|
||||||
el('<template some-templ some-templ2></template>')
|
el('<template some-templ some-templ2></template>')
|
||||||
|
@ -135,12 +133,12 @@ export function main() {
|
||||||
}).toThrowError('Only one template directive per element is allowed!');
|
}).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( () => {
|
expect( () => {
|
||||||
createPipeline().process(
|
createPipeline().process(
|
||||||
el('<div some-templ></div>')
|
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 {}
|
class SomeDecoratorWithBinding {}
|
||||||
|
|
||||||
@Template({
|
@Viewport({
|
||||||
selector: '[some-templ]'
|
selector: '[some-templ]'
|
||||||
})
|
})
|
||||||
class SomeTemplate {}
|
class SomeViewport {}
|
||||||
|
|
||||||
@Template({
|
@Viewport({
|
||||||
selector: '[some-templ2]'
|
selector: '[some-templ2]'
|
||||||
})
|
})
|
||||||
class SomeTemplate2 {}
|
class SomeViewport2 {}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: '[some-comp]'
|
selector: '[some-comp]'
|
||||||
|
@ -249,7 +247,7 @@ class SomeComponent2 {}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
template: new TemplateConfig({
|
template: new TemplateConfig({
|
||||||
directives: [SomeDecorator, SomeTemplate, SomeTemplate2, SomeComponent, SomeComponent2]
|
directives: [SomeDecorator, SomeViewport, SomeViewport2, SomeComponent, SomeComponent2]
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
class MyComp {}
|
class MyComp {}
|
||||||
|
|
|
@ -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 {CompileControl} from 'angular2/src/core/compiler/pipeline/compile_control';
|
||||||
import {NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
import {NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
||||||
|
|
||||||
import {Decorator} from 'angular2/src/core/annotations/annotations';
|
import {Decorator, Component, Viewport} from 'angular2/src/core/annotations/annotations';
|
||||||
import {Template} from 'angular2/src/core/annotations/annotations';
|
|
||||||
import {Component} from 'angular2/src/core/annotations/annotations';
|
|
||||||
import {ProtoView, ElementPropertyMemento, DirectivePropertyMemento} from 'angular2/src/core/compiler/view';
|
import {ProtoView, ElementPropertyMemento, DirectivePropertyMemento} from 'angular2/src/core/compiler/view';
|
||||||
import {ProtoElementInjector} from 'angular2/src/core/compiler/element_injector';
|
import {ProtoElementInjector} from 'angular2/src/core/compiler/element_injector';
|
||||||
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
||||||
|
@ -150,12 +148,12 @@ export function main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should store the template directive', () => {
|
it('should store the template directive', () => {
|
||||||
var directives = [SomeTemplateDirective];
|
var directives = [SomeViewportDirective];
|
||||||
var pipeline = createPipeline({protoElementInjector: null, directives: directives});
|
var pipeline = createPipeline({protoElementInjector: null, directives: directives});
|
||||||
var results = pipeline.process(el('<div viewroot directives></div>'));
|
var results = pipeline.process(el('<div viewroot directives></div>'));
|
||||||
var pv = results[0].inheritedProtoView;
|
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', () => {
|
it('should bind text nodes', () => {
|
||||||
|
@ -283,7 +281,7 @@ export function main() {
|
||||||
'boundprop3': 'prop3'
|
'boundprop3': 'prop3'
|
||||||
});
|
});
|
||||||
var directives = [SomeComponentDirectiveWithBinding,
|
var directives = [SomeComponentDirectiveWithBinding,
|
||||||
SomeTemplateDirectiveWithBinding,
|
SomeViewportDirectiveWithBinding,
|
||||||
SomeDecoratorDirectiveWith2Bindings];
|
SomeDecoratorDirectiveWith2Bindings];
|
||||||
var protoElementInjector = new ProtoElementInjector(null, 0, directives, true);
|
var protoElementInjector = new ProtoElementInjector(null, 0, directives, true);
|
||||||
var pipeline = createPipeline({
|
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).decorProp).toBe('a');
|
||||||
expect(view.elementInjectors[0].get(SomeDecoratorDirectiveWith2Bindings).decorProp2).toBe('b');
|
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');
|
expect(view.elementInjectors[0].get(SomeComponentDirectiveWithBinding).compProp).toBe('c');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -389,14 +387,14 @@ class SomeDecoratorDirectiveWith2Bindings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Template()
|
@Viewport()
|
||||||
class SomeTemplateDirective {
|
class SomeViewportDirective {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Template({
|
@Viewport({
|
||||||
bind: {'boundprop2': 'templProp'}
|
bind: {'boundprop2': 'templProp'}
|
||||||
})
|
})
|
||||||
class SomeTemplateDirectiveWithBinding {
|
class SomeViewportDirectiveWithBinding {
|
||||||
templProp;
|
templProp;
|
||||||
constructor() {
|
constructor() {
|
||||||
this.templProp = null;
|
this.templProp = null;
|
||||||
|
|
|
@ -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 {CompileStep} from 'angular2/src/core/compiler/pipeline/compile_step'
|
||||||
import {CompileControl} from 'angular2/src/core/compiler/pipeline/compile_control';
|
import {CompileControl} from 'angular2/src/core/compiler/pipeline/compile_control';
|
||||||
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
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() {
|
export function main() {
|
||||||
describe('ElementBindingMarker', () => {
|
describe('ElementBindingMarker', () => {
|
||||||
|
@ -90,7 +90,7 @@ export function main() {
|
||||||
|
|
||||||
it('should mark elements with template directives', () => {
|
it('should mark elements with template directives', () => {
|
||||||
var results = createPipeline({
|
var results = createPipeline({
|
||||||
directives: [SomeTemplateDirective]
|
directives: [SomeViewportDirective]
|
||||||
}).process(el('<div></div>'));
|
}).process(el('<div></div>'));
|
||||||
assertBinding(results[0], true);
|
assertBinding(results[0], true);
|
||||||
});
|
});
|
||||||
|
@ -121,8 +121,8 @@ class MockStep extends CompileStep {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Template()
|
@Viewport()
|
||||||
class SomeTemplateDirective {}
|
class SomeViewportDirective {}
|
||||||
|
|
||||||
@Component()
|
@Component()
|
||||||
class SomeComponentDirective {}
|
class SomeComponentDirective {}
|
||||||
|
|
|
@ -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 {CompileControl} from 'angular2/src/core/compiler/pipeline/compile_control';
|
||||||
import {ProtoView} from 'angular2/src/core/compiler/view';
|
import {ProtoView} from 'angular2/src/core/compiler/view';
|
||||||
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
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';
|
import {ProtoElementInjector} from 'angular2/src/core/compiler/element_injector';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
|
@ -68,7 +68,7 @@ export function main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create a ProtoElementInjector for elements directives', () => {
|
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 results = createPipeline(directives).process(el('<div directives></div>'));
|
||||||
var creationArgs = getCreationArgs(results[0].inheritedProtoElementInjector);
|
var creationArgs = getCreationArgs(results[0].inheritedProtoElementInjector);
|
||||||
var boundDirectives = creationArgs['bindings'].map((b) => b.key.token);
|
var boundDirectives = creationArgs['bindings'].map((b) => b.key.token);
|
||||||
|
@ -203,8 +203,8 @@ class MockStep extends CompileStep {
|
||||||
|
|
||||||
class SomeComponentService {}
|
class SomeComponentService {}
|
||||||
|
|
||||||
@Template()
|
@Viewport()
|
||||||
class SomeTemplateDirective {}
|
class SomeViewportDirective {}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
componentServices: [SomeComponentService]
|
componentServices: [SomeComponentService]
|
||||||
|
|
|
@ -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 {NgElement} from 'angular2/src/core/dom/element';
|
||||||
import {LightDom} from 'angular2/src/core/compiler/shadow_dom_emulation/light_dom';
|
import {LightDom} from 'angular2/src/core/compiler/shadow_dom_emulation/light_dom';
|
||||||
import {View} from 'angular2/src/core/compiler/view';
|
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 {ElementInjector} from 'angular2/src/core/compiler/element_injector';
|
||||||
import {ProtoRecordRange} from 'angular2/change_detection';
|
import {ProtoRecordRange} from 'angular2/change_detection';
|
||||||
|
|
||||||
|
@ -14,12 +14,12 @@ import {ProtoRecordRange} from 'angular2/change_detection';
|
||||||
@IMPLEMENTS(ElementInjector)
|
@IMPLEMENTS(ElementInjector)
|
||||||
class FakeElementInjector {
|
class FakeElementInjector {
|
||||||
content;
|
content;
|
||||||
viewPort;
|
viewContainer;
|
||||||
element;
|
element;
|
||||||
|
|
||||||
constructor(content = null, viewPort = null, element = null) {
|
constructor(content = null, viewContainer = null, element = null) {
|
||||||
this.content = content;
|
this.content = content;
|
||||||
this.viewPort = viewPort;
|
this.viewContainer = viewContainer;
|
||||||
this.element = element;
|
this.element = element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ class FakeElementInjector {
|
||||||
}
|
}
|
||||||
|
|
||||||
hasPreBuiltObject(type) {
|
hasPreBuiltObject(type) {
|
||||||
return this.viewPort != null;
|
return this.viewContainer != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
forElement(n) {
|
forElement(n) {
|
||||||
|
@ -37,7 +37,7 @@ class FakeElementInjector {
|
||||||
|
|
||||||
get(t) {
|
get(t) {
|
||||||
if (t === Content) return this.content;
|
if (t === Content) return this.content;
|
||||||
if (t === ViewPort) return this.viewPort;
|
if (t === ViewContainer) return this.viewContainer;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,8 +61,8 @@ class FakeView {
|
||||||
}
|
}
|
||||||
|
|
||||||
@proxy
|
@proxy
|
||||||
@IMPLEMENTS(ViewPort)
|
@IMPLEMENTS(ViewContainer)
|
||||||
class FakeViewPort {
|
class FakeViewContainer {
|
||||||
_nodes;
|
_nodes;
|
||||||
_contentTagContainers;
|
_contentTagContainers;
|
||||||
|
|
||||||
|
@ -128,9 +128,9 @@ export function main() {
|
||||||
expect(lightDom.contentTags()).toEqual([tag]);
|
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 tag = new FakeContentTag();
|
||||||
var vp = new FakeViewPort(null, [
|
var vp = new FakeViewContainer(null, [
|
||||||
new FakeView([new FakeElementInjector(tag, null)])
|
new FakeView([new FakeElementInjector(tag, null)])
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -149,13 +149,13 @@ export function main() {
|
||||||
expect(toHtml(lightDom.expandedDomNodes())).toEqual(["<a></a>"]);
|
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 lightDomEl = el("<div><template></template></div>")
|
||||||
|
|
||||||
var lightDomView = new FakeView([
|
var lightDomView = new FakeView([
|
||||||
new FakeElementInjector(
|
new FakeElementInjector(
|
||||||
null,
|
null,
|
||||||
new FakeViewPort([el("<a></a>")]),
|
new FakeViewContainer([el("<a></a>")]),
|
||||||
DOM.firstChild(lightDomEl))]);
|
DOM.firstChild(lightDomEl))]);
|
||||||
|
|
||||||
var lightDom = new LightDom(
|
var lightDom = new LightDom(
|
||||||
|
|
|
@ -13,10 +13,10 @@ import {ShadowDomStrategy,
|
||||||
EmulatedShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
EmulatedShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
||||||
import {TemplateLoader} from 'angular2/src/core/compiler/template_loader';
|
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 {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 {StringMapWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
||||||
|
|
||||||
import {XHRMock} from 'angular2/src/mock/xhr_mock';
|
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>' +
|
var temp = '<multiple-content-tags>' +
|
||||||
'<div><div template="manual" class="left">A</div></div>' +
|
'<div><div template="manual" class="left">A</div></div>' +
|
||||||
'<div>B</div>' +
|
'<div>B</div>' +
|
||||||
'</multiple-content-tags>';
|
'</multiple-content-tags>';
|
||||||
|
|
||||||
compile(temp, (view, lc) => {
|
compile(temp, (view, lc) => {
|
||||||
var dir = view.elementInjectors[1].get(ManualTemplateDirective);
|
var dir = view.elementInjectors[1].get(ManualViewportDirective);
|
||||||
|
|
||||||
expect(view.nodes).toHaveText('(, B)');
|
expect(view.nodes).toHaveText('(, B)');
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ export function main() {
|
||||||
'</multiple-content-tags>';
|
'</multiple-content-tags>';
|
||||||
|
|
||||||
compile(temp, (view, lc) => {
|
compile(temp, (view, lc) => {
|
||||||
var dir = view.elementInjectors[1].get(ManualTemplateDirective);
|
var dir = view.elementInjectors[1].get(ManualViewportDirective);
|
||||||
|
|
||||||
expect(view.nodes).toHaveText('(, B)');
|
expect(view.nodes).toHaveText('(, B)');
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ export function main() {
|
||||||
'</outer>';
|
'</outer>';
|
||||||
|
|
||||||
compile(temp, (view, lc) => {
|
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)))');
|
expect(view.nodes).toHaveText('OUTER(INNER(INNERINNER(,BC)))');
|
||||||
|
|
||||||
|
@ -223,36 +223,36 @@ class TestDirectiveMetadataReader extends DirectiveMetadataReader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Template({
|
@Viewport({
|
||||||
selector: '[manual]'
|
selector: '[manual]'
|
||||||
})
|
})
|
||||||
class ManualTemplateDirective {
|
class ManualViewportDirective {
|
||||||
viewPort;
|
viewContainer;
|
||||||
constructor(viewPort:ViewPort) {
|
constructor(viewContainer:ViewContainer) {
|
||||||
this.viewPort = viewPort;
|
this.viewContainer = viewContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
show() { this.viewPort.create(); }
|
show() { this.viewContainer.create(); }
|
||||||
hide() { this.viewPort.remove(0); }
|
hide() { this.viewContainer.remove(0); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Template({
|
@Viewport({
|
||||||
selector: '[auto]',
|
selector: '[auto]',
|
||||||
bind: {
|
bind: {
|
||||||
'auto': 'auto'
|
'auto': 'auto'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
class AutoTemplateDirective {
|
class AutoViewportDirective {
|
||||||
viewPort;
|
viewContainer;
|
||||||
constructor(viewPort:ViewPort) {
|
constructor(viewContainer:ViewContainer) {
|
||||||
this.viewPort = viewPort;
|
this.viewContainer = viewContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
set auto(newValue:boolean) {
|
set auto(newValue:boolean) {
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
this.viewPort.create();
|
this.viewContainer.create();
|
||||||
} else {
|
} else {
|
||||||
this.viewPort.remove(0);
|
this.viewContainer.remove(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -280,7 +280,7 @@ class MultipleContentTagsComponent {
|
||||||
selector: 'conditional-content',
|
selector: 'conditional-content',
|
||||||
template: new TemplateConfig({
|
template: new TemplateConfig({
|
||||||
inline: '<div>(<div template="auto: cond"><content select=".left"></content></div>, <content></content>)</div>',
|
inline: '<div>(<div template="auto: cond"><content select=".left"></content></div>, <content></content>)</div>',
|
||||||
directives: [AutoTemplateDirective]
|
directives: [AutoViewportDirective]
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
class ConditionalContentComponent {
|
class ConditionalContentComponent {
|
||||||
|
@ -337,7 +337,7 @@ class InnerInnerComponent {
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-comp',
|
selector: 'my-comp',
|
||||||
template: new TemplateConfig({
|
template: new TemplateConfig({
|
||||||
directives: [MultipleContentTagsComponent, ManualTemplateDirective,
|
directives: [MultipleContentTagsComponent, ManualViewportDirective,
|
||||||
ConditionalContentComponent, OuterWithIndirectNestedComponent, OuterComponent]
|
ConditionalContentComponent, OuterWithIndirectNestedComponent, OuterComponent]
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import {describe, xit, it, expect, beforeEach, ddescribe, iit, el, proxy} from 'angular2/test_lib';
|
import {describe, xit, it, expect, beforeEach, ddescribe, iit, el, proxy} from 'angular2/test_lib';
|
||||||
import {View, ProtoView} from 'angular2/src/core/compiler/view';
|
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 {IMPLEMENTS} from 'angular2/src/facade/lang';
|
||||||
import {DOM, Node} from 'angular2/src/facade/dom';
|
import {DOM, Node} from 'angular2/src/facade/dom';
|
||||||
import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
||||||
|
@ -61,8 +61,8 @@ class HydrateAwareFakeView {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe('viewport', () => {
|
describe('ViewContainer', () => {
|
||||||
var viewPort, parentView, protoView, dom, customViewWithOneNode,
|
var viewContainer, parentView, protoView, dom, customViewWithOneNode,
|
||||||
customViewWithTwoNodes, elementInjector;
|
customViewWithTwoNodes, elementInjector;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
@ -71,19 +71,19 @@ export function main() {
|
||||||
parentView = createView([dom.childNodes[0]]);
|
parentView = createView([dom.childNodes[0]]);
|
||||||
protoView = new ProtoView(el('<div>hi</div>'), new DynamicProtoChangeDetector(), new NativeShadowDomStrategy());
|
protoView = new ProtoView(el('<div>hi</div>'), new DynamicProtoChangeDetector(), new NativeShadowDomStrategy());
|
||||||
elementInjector = new ElementInjector(null, null, null, null);
|
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>')]);
|
customViewWithOneNode = createView([el('<div>single</div>')]);
|
||||||
customViewWithTwoNodes = createView([el('<div>one</div>'), el('<div>two</div>')]);
|
customViewWithTwoNodes = createView([el('<div>one</div>'), el('<div>two</div>')]);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when dehydrated', () => {
|
describe('when dehydrated', () => {
|
||||||
it('should throw if create is called', () => {
|
it('should throw if create is called', () => {
|
||||||
expect(() => viewPort.create()).toThrowError();
|
expect(() => viewContainer.create()).toThrowError();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when hydrated', () => {
|
describe('when hydrated', () => {
|
||||||
function textInViewPort() {
|
function textInViewContainer() {
|
||||||
var out = '';
|
var out = '';
|
||||||
// skipping starting filler, insert-me and final filler.
|
// skipping starting filler, insert-me and final filler.
|
||||||
for (var i = 2; i < dom.childNodes.length - 1; i++) {
|
for (var i = 2; i < dom.childNodes.length - 1; i++) {
|
||||||
|
@ -94,84 +94,84 @@ export function main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
viewPort.hydrate(new Injector([]), null);
|
viewContainer.hydrate(new Injector([]), null);
|
||||||
var fillerView = createView([el('<filler>filler</filler>')]);
|
var fillerView = createView([el('<filler>filler</filler>')]);
|
||||||
viewPort.insert(fillerView);
|
viewContainer.insert(fillerView);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create new views from protoView', () => {
|
it('should create new views from protoView', () => {
|
||||||
viewPort.create();
|
viewContainer.create();
|
||||||
expect(textInViewPort()).toEqual('filler hi');
|
expect(textInViewContainer()).toEqual('filler hi');
|
||||||
expect(viewPort.length).toBe(2);
|
expect(viewContainer.length).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create new views from protoView at index', () => {
|
it('should create new views from protoView at index', () => {
|
||||||
viewPort.create(0);
|
viewContainer.create(0);
|
||||||
expect(textInViewPort()).toEqual('hi filler');
|
expect(textInViewContainer()).toEqual('hi filler');
|
||||||
expect(viewPort.length).toBe(2);
|
expect(viewContainer.length).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should insert new views at the end by default', () => {
|
it('should insert new views at the end by default', () => {
|
||||||
viewPort.insert(customViewWithOneNode);
|
viewContainer.insert(customViewWithOneNode);
|
||||||
expect(textInViewPort()).toEqual('filler single');
|
expect(textInViewContainer()).toEqual('filler single');
|
||||||
expect(viewPort.get(1)).toBe(customViewWithOneNode);
|
expect(viewContainer.get(1)).toBe(customViewWithOneNode);
|
||||||
expect(viewPort.length).toBe(2);
|
expect(viewContainer.length).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should insert new views at the given index', () => {
|
it('should insert new views at the given index', () => {
|
||||||
viewPort.insert(customViewWithOneNode, 0);
|
viewContainer.insert(customViewWithOneNode, 0);
|
||||||
expect(textInViewPort()).toEqual('single filler');
|
expect(textInViewContainer()).toEqual('single filler');
|
||||||
expect(viewPort.get(0)).toBe(customViewWithOneNode);
|
expect(viewContainer.get(0)).toBe(customViewWithOneNode);
|
||||||
expect(viewPort.length).toBe(2);
|
expect(viewContainer.length).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should remove the last view by default', () => {
|
it('should remove the last view by default', () => {
|
||||||
viewPort.insert(customViewWithOneNode);
|
viewContainer.insert(customViewWithOneNode);
|
||||||
|
|
||||||
viewPort.remove();
|
viewContainer.remove();
|
||||||
|
|
||||||
expect(textInViewPort()).toEqual('filler');
|
expect(textInViewContainer()).toEqual('filler');
|
||||||
expect(viewPort.length).toBe(1);
|
expect(viewContainer.length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should remove the view at a given index', () => {
|
it('should remove the view at a given index', () => {
|
||||||
viewPort.insert(customViewWithOneNode);
|
viewContainer.insert(customViewWithOneNode);
|
||||||
viewPort.insert(customViewWithTwoNodes);
|
viewContainer.insert(customViewWithTwoNodes);
|
||||||
|
|
||||||
viewPort.remove(1);
|
viewContainer.remove(1);
|
||||||
|
|
||||||
expect(textInViewPort()).toEqual('filler one two');
|
expect(textInViewContainer()).toEqual('filler one two');
|
||||||
expect(viewPort.get(1)).toBe(customViewWithTwoNodes);
|
expect(viewContainer.get(1)).toBe(customViewWithTwoNodes);
|
||||||
expect(viewPort.length).toBe(2);
|
expect(viewContainer.length).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should detach the last view by default', () => {
|
it('should detach the last view by default', () => {
|
||||||
viewPort.insert(customViewWithOneNode);
|
viewContainer.insert(customViewWithOneNode);
|
||||||
expect(viewPort.length).toBe(2);
|
expect(viewContainer.length).toBe(2);
|
||||||
|
|
||||||
var detachedView = viewPort.detach();
|
var detachedView = viewContainer.detach();
|
||||||
|
|
||||||
expect(detachedView).toBe(customViewWithOneNode);
|
expect(detachedView).toBe(customViewWithOneNode);
|
||||||
expect(textInViewPort()).toEqual('filler');
|
expect(textInViewContainer()).toEqual('filler');
|
||||||
expect(viewPort.length).toBe(1);
|
expect(viewContainer.length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should detach the view at a given index', () => {
|
it('should detach the view at a given index', () => {
|
||||||
viewPort.insert(customViewWithOneNode);
|
viewContainer.insert(customViewWithOneNode);
|
||||||
viewPort.insert(customViewWithTwoNodes);
|
viewContainer.insert(customViewWithTwoNodes);
|
||||||
expect(viewPort.length).toBe(3);
|
expect(viewContainer.length).toBe(3);
|
||||||
|
|
||||||
var detachedView = viewPort.detach(1);
|
var detachedView = viewContainer.detach(1);
|
||||||
expect(detachedView).toBe(customViewWithOneNode);
|
expect(detachedView).toBe(customViewWithOneNode);
|
||||||
expect(textInViewPort()).toEqual('filler one two');
|
expect(textInViewContainer()).toEqual('filler one two');
|
||||||
expect(viewPort.length).toBe(2);
|
expect(viewContainer.length).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should keep views hydration state during insert', () => {
|
it('should keep views hydration state during insert', () => {
|
||||||
var hydratedView = new HydrateAwareFakeView(true);
|
var hydratedView = new HydrateAwareFakeView(true);
|
||||||
var dehydratedView = new HydrateAwareFakeView(false);
|
var dehydratedView = new HydrateAwareFakeView(false);
|
||||||
viewPort.insert(hydratedView);
|
viewContainer.insert(hydratedView);
|
||||||
viewPort.insert(dehydratedView);
|
viewContainer.insert(dehydratedView);
|
||||||
|
|
||||||
expect(hydratedView.hydrated()).toBe(true);
|
expect(hydratedView.hydrated()).toBe(true);
|
||||||
expect(dehydratedView.hydrated()).toBe(false);
|
expect(dehydratedView.hydrated()).toBe(false);
|
||||||
|
@ -179,8 +179,8 @@ export function main() {
|
||||||
|
|
||||||
it('should dehydrate on remove', () => {
|
it('should dehydrate on remove', () => {
|
||||||
var hydratedView = new HydrateAwareFakeView(true);
|
var hydratedView = new HydrateAwareFakeView(true);
|
||||||
viewPort.insert(hydratedView);
|
viewContainer.insert(hydratedView);
|
||||||
viewPort.remove();
|
viewContainer.remove();
|
||||||
|
|
||||||
expect(hydratedView.hydrated()).toBe(false);
|
expect(hydratedView.hydrated()).toBe(false);
|
||||||
});
|
});
|
||||||
|
@ -188,21 +188,21 @@ export function main() {
|
||||||
it('should keep views hydration state during detach', () => {
|
it('should keep views hydration state during detach', () => {
|
||||||
var hydratedView = new HydrateAwareFakeView(true);
|
var hydratedView = new HydrateAwareFakeView(true);
|
||||||
var dehydratedView = new HydrateAwareFakeView(false);
|
var dehydratedView = new HydrateAwareFakeView(false);
|
||||||
viewPort.insert(hydratedView);
|
viewContainer.insert(hydratedView);
|
||||||
viewPort.insert(dehydratedView);
|
viewContainer.insert(dehydratedView);
|
||||||
|
|
||||||
expect(viewPort.detach().hydrated()).toBe(false);
|
expect(viewContainer.detach().hydrated()).toBe(false);
|
||||||
expect(viewPort.detach().hydrated()).toBe(true);
|
expect(viewContainer.detach().hydrated()).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support adding/removing views with more than one node', () => {
|
it('should support adding/removing views with more than one node', () => {
|
||||||
viewPort.insert(customViewWithTwoNodes);
|
viewContainer.insert(customViewWithTwoNodes);
|
||||||
viewPort.insert(customViewWithOneNode);
|
viewContainer.insert(customViewWithOneNode);
|
||||||
|
|
||||||
expect(textInViewPort()).toEqual('filler one two single');
|
expect(textInViewContainer()).toEqual('filler one two single');
|
||||||
|
|
||||||
viewPort.remove(1);
|
viewContainer.remove(1);
|
||||||
expect(textInViewPort()).toEqual('filler single');
|
expect(textInViewContainer()).toEqual('filler single');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -210,7 +210,7 @@ export function main() {
|
||||||
var fancyView;
|
var fancyView;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
var parser = new Parser(new Lexer());
|
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>'),
|
var pv = new ProtoView(el('<div class="ng-binding">{{}}</div>'),
|
||||||
new DynamicProtoChangeDetector(), new NativeShadowDomStrategy());
|
new DynamicProtoChangeDetector(), new NativeShadowDomStrategy());
|
||||||
|
@ -220,7 +220,7 @@ export function main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('hydrating should update rootElementInjectors and parent change detector', () => {
|
it('hydrating should update rootElementInjectors and parent change detector', () => {
|
||||||
viewPort.insert(fancyView);
|
viewContainer.insert(fancyView);
|
||||||
ListWrapper.forEach(fancyView.rootElementInjectors, (inj) =>
|
ListWrapper.forEach(fancyView.rootElementInjectors, (inj) =>
|
||||||
expect(inj.parent).toBe(elementInjector));
|
expect(inj.parent).toBe(elementInjector));
|
||||||
|
|
||||||
|
@ -228,12 +228,12 @@ export function main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dehydrating should update rootElementInjectors and parent change detector', () => {
|
it('dehydrating should update rootElementInjectors and parent change detector', () => {
|
||||||
viewPort.insert(fancyView);
|
viewContainer.insert(fancyView);
|
||||||
viewPort.remove();
|
viewContainer.remove();
|
||||||
ListWrapper.forEach(fancyView.rootElementInjectors, (inj) =>
|
ListWrapper.forEach(fancyView.rootElementInjectors, (inj) =>
|
||||||
expect(inj.parent).toBe(null));
|
expect(inj.parent).toBe(null));
|
||||||
expect(parentView.changeDetector.children.length).toBe(0);
|
expect(parentView.changeDetector.children.length).toBe(0);
|
||||||
expect(viewPort.length).toBe(0);
|
expect(viewContainer.length).toBe(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
|
@ -3,7 +3,7 @@ import {ProtoView, ElementPropertyMemento, DirectivePropertyMemento} from 'angul
|
||||||
import {ProtoElementInjector, ElementInjector, DirectiveBinding} from 'angular2/src/core/compiler/element_injector';
|
import {ProtoElementInjector, ElementInjector, DirectiveBinding} from 'angular2/src/core/compiler/element_injector';
|
||||||
import {EmulatedShadowDomStrategy, NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
import {EmulatedShadowDomStrategy, NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
||||||
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
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,
|
import {Lexer, Parser, DynamicProtoChangeDetector,
|
||||||
ChangeDetector} from 'angular2/change_detection';
|
ChangeDetector} from 'angular2/change_detection';
|
||||||
import {TemplateConfig} from 'angular2/src/core/annotations/template_config';
|
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 {int, IMPLEMENTS} from 'angular2/src/facade/lang';
|
||||||
import {Injector} from 'angular2/di';
|
import {Injector} from 'angular2/di';
|
||||||
import {View} from 'angular2/src/core/compiler/view';
|
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 {reflector} from 'angular2/src/reflection/reflection';
|
||||||
import {VmTurnZone} from 'angular2/src/core/zone/vm_turn_zone';
|
import {VmTurnZone} from 'angular2/src/core/zone/vm_turn_zone';
|
||||||
import {EventManager} from 'angular2/src/core/events/event_manager';
|
import {EventManager} from 'angular2/src/core/events/event_manager';
|
||||||
|
|
||||||
@proxy
|
@proxy
|
||||||
@IMPLEMENTS(ViewPort)
|
@IMPLEMENTS(ViewContainer)
|
||||||
class FakeViewPort {
|
class FakeViewContainer {
|
||||||
templateElement;
|
templateElement;
|
||||||
|
|
||||||
constructor(templateElement) {
|
constructor(templateElement) {
|
||||||
|
@ -42,7 +42,7 @@ class FakeView {
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe('view', function() {
|
describe('view', function() {
|
||||||
var parser, someComponentDirective, someTemplateDirective;
|
var parser, someComponentDirective, someViewportDirective;
|
||||||
|
|
||||||
function createView(protoView, eventManager: EventManager = null) {
|
function createView(protoView, eventManager: EventManager = null) {
|
||||||
var ctx = new MyEvaluationContext();
|
var ctx = new MyEvaluationContext();
|
||||||
|
@ -54,7 +54,7 @@ export function main() {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
parser = new Parser(new Lexer());
|
parser = new Parser(new Lexer());
|
||||||
someComponentDirective = new DirectiveMetadataReader().read(SomeComponent);
|
someComponentDirective = new DirectiveMetadataReader().read(SomeComponent);
|
||||||
someTemplateDirective = new DirectiveMetadataReader().read(SomeTemplate);
|
someViewportDirective = new DirectiveMetadataReader().read(SomeViewport);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('instantiated from protoView', () => {
|
describe('instantiated from protoView', () => {
|
||||||
|
@ -409,30 +409,30 @@ export function main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('with template views', () => {
|
describe('with template views', () => {
|
||||||
function createViewWithTemplate() {
|
function createViewWithViewport() {
|
||||||
var templateProtoView = new ProtoView(
|
var templateProtoView = new ProtoView(
|
||||||
el('<div id="1"></div>'), new DynamicProtoChangeDetector(), null);
|
el('<div id="1"></div>'), new DynamicProtoChangeDetector(), null);
|
||||||
var pv = new ProtoView(el('<someTmpl class="ng-binding"></someTmpl>'),
|
var pv = new ProtoView(el('<someTmpl class="ng-binding"></someTmpl>'),
|
||||||
new DynamicProtoChangeDetector(), new NativeShadowDomStrategy());
|
new DynamicProtoChangeDetector(), new NativeShadowDomStrategy());
|
||||||
var binder = pv.bindElement(new ProtoElementInjector(null, 0, [SomeTemplate]));
|
var binder = pv.bindElement(new ProtoElementInjector(null, 0, [SomeViewport]));
|
||||||
binder.templateDirective = someTemplateDirective;
|
binder.viewportDirective = someViewportDirective;
|
||||||
binder.nestedProtoView = templateProtoView;
|
binder.nestedProtoView = templateProtoView;
|
||||||
|
|
||||||
return createView(pv);
|
return createView(pv);
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should create a viewPort for the template directive', () => {
|
it('should create a ViewContainer for the Viewport directive', () => {
|
||||||
var view = createViewWithTemplate();
|
var view = createViewWithViewport();
|
||||||
|
|
||||||
var tmplComp = view.rootElementInjectors[0].get(SomeTemplate);
|
var tmplComp = view.rootElementInjectors[0].get(SomeViewport);
|
||||||
expect(tmplComp.viewPort).not.toBe(null);
|
expect(tmplComp.viewContainer).not.toBe(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dehydration should dehydrate viewports', () => {
|
it('dehydration should dehydrate viewcontainers', () => {
|
||||||
var view = createViewWithTemplate();
|
var view = createViewWithViewport();
|
||||||
|
|
||||||
var tmplComp = view.rootElementInjectors[0].get(SomeTemplate);
|
var tmplComp = view.rootElementInjectors[0].get(SomeViewport);
|
||||||
expect(tmplComp.viewPort.hydrated()).toBe(false);
|
expect(tmplComp.viewContainer.hydrated()).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -671,13 +671,13 @@ class ServiceDependentDecorator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Template({
|
@Viewport({
|
||||||
selector: 'someTmpl'
|
selector: 'someTmpl'
|
||||||
})
|
})
|
||||||
class SomeTemplate {
|
class SomeViewport {
|
||||||
viewPort: ViewPort;
|
viewContainer: ViewContainer;
|
||||||
constructor(viewPort: ViewPort) {
|
constructor(viewContainer: ViewContainer) {
|
||||||
this.viewPort = viewPort;
|
this.viewContainer = viewContainer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,10 @@ import {Compiler, CompilerCache} from 'angular2/src/core/compiler/compiler';
|
||||||
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
||||||
import {NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
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 {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 {MapWrapper, ListWrapper} from 'angular2/src/facade/collection';
|
||||||
import {Foreach} from 'angular2/src/directives/foreach';
|
import {Foreach} from 'angular2/src/directives/foreach';
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import {int, isPresent} from 'angular2/src/facade/lang';
|
import {int, isPresent} from 'angular2/src/facade/lang';
|
||||||
import {reflector} from 'angular2/src/reflection/reflection';
|
import {reflector} from 'angular2/src/reflection/reflection';
|
||||||
import {getIntParameter, bindAction} from 'angular2/src/test_lib/benchmark_util';
|
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';
|
from 'angular2/angular2';
|
||||||
import {PromiseWrapper} from 'angular2/src/facade/async';
|
import {PromiseWrapper} from 'angular2/src/facade/async';
|
||||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import {int} from 'angular2/src/facade/lang';
|
import {int} from 'angular2/src/facade/lang';
|
||||||
import {reflector} from 'angular2/src/reflection/reflection';
|
import {reflector} from 'angular2/src/reflection/reflection';
|
||||||
import {getIntParameter, bindAction} from 'angular2/src/test_lib/benchmark_util';
|
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';
|
from 'angular2/angular2';
|
||||||
import {PromiseWrapper} from 'angular2/src/facade/async';
|
import {PromiseWrapper} from 'angular2/src/facade/async';
|
||||||
import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
||||||
|
|
|
@ -4,7 +4,7 @@ import {MapWrapper} from 'angular2/src/facade/collection';
|
||||||
|
|
||||||
import {Parser, Lexer, ChangeDetector, ChangeDetection}
|
import {Parser, Lexer, ChangeDetector, ChangeDetection}
|
||||||
from 'angular2/change_detection';
|
from 'angular2/change_detection';
|
||||||
import {bootstrap, Component, Template, TemplateConfig, ViewPort, Compiler}
|
import {bootstrap, Component, Viewport, TemplateConfig, ViewContainer, Compiler}
|
||||||
from 'angular2/angular2';
|
from 'angular2/angular2';
|
||||||
import {reflector} from 'angular2/src/reflection/reflection';
|
import {reflector} from 'angular2/src/reflection/reflection';
|
||||||
import {CompilerCache} from 'angular2/src/core/compiler/compiler';
|
import {CompilerCache} from 'angular2/src/core/compiler/compiler';
|
||||||
|
@ -151,8 +151,8 @@ export function setupReflector() {
|
||||||
export function setupReflectorForAngular() {
|
export function setupReflectorForAngular() {
|
||||||
reflector.registerType(If, {
|
reflector.registerType(If, {
|
||||||
'factory': (vp) => new If(vp),
|
'factory': (vp) => new If(vp),
|
||||||
'parameters': [[ViewPort]],
|
'parameters': [[ViewContainer]],
|
||||||
'annotations' : [new Template({
|
'annotations' : [new Viewport({
|
||||||
selector: '[if]',
|
selector: '[if]',
|
||||||
bind: {
|
bind: {
|
||||||
'if': 'condition'
|
'if': 'condition'
|
||||||
|
@ -162,8 +162,8 @@ export function setupReflectorForAngular() {
|
||||||
|
|
||||||
reflector.registerType(Foreach, {
|
reflector.registerType(Foreach, {
|
||||||
'factory': (vp) => new Foreach(vp),
|
'factory': (vp) => new Foreach(vp),
|
||||||
'parameters': [[ViewPort]],
|
'parameters': [[ViewContainer]],
|
||||||
'annotations' : [new Template({
|
'annotations' : [new Viewport({
|
||||||
selector: '[foreach]',
|
selector: '[foreach]',
|
||||||
bind: {
|
bind: {
|
||||||
'in': 'iterable[]'
|
'in': 'iterable[]'
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import {int, FINAL} from 'angular2/src/facade/lang';
|
import {int, FINAL} from 'angular2/src/facade/lang';
|
||||||
import {reflector} from 'angular2/src/reflection/reflection';
|
import {reflector} from 'angular2/src/reflection/reflection';
|
||||||
import {getIntParameter, bindAction} from 'angular2/src/test_lib/benchmark_util';
|
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';
|
from 'angular2/angular2';
|
||||||
import {PromiseWrapper} from 'angular2/src/facade/async';
|
import {PromiseWrapper} from 'angular2/src/facade/async';
|
||||||
import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import {int} from 'angular2/src/facade/lang';
|
import {int} from 'angular2/src/facade/lang';
|
||||||
import {reflector} from 'angular2/src/reflection/reflection';
|
import {reflector} from 'angular2/src/reflection/reflection';
|
||||||
import {Component, Template, TemplateConfig, ViewPort, Compiler}
|
import {Component, Viewport, TemplateConfig, ViewContainer, Compiler}
|
||||||
from 'angular2/angular2';
|
from 'angular2/angular2';
|
||||||
import {PromiseWrapper} from 'angular2/src/facade/async';
|
import {PromiseWrapper} from 'angular2/src/facade/async';
|
||||||
import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import {Parser, Lexer, ChangeDetector, ChangeDetection, jitChangeDetection}
|
import {Parser, Lexer, ChangeDetector, ChangeDetection, jitChangeDetection}
|
||||||
from 'angular2/change_detection';
|
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 {CompilerCache} from 'angular2/src/core/compiler/compiler';
|
||||||
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
||||||
|
@ -50,8 +50,8 @@ function setupReflector() {
|
||||||
|
|
||||||
reflector.registerType(NgIf, {
|
reflector.registerType(NgIf, {
|
||||||
'factory': (vp) => new NgIf(vp),
|
'factory': (vp) => new NgIf(vp),
|
||||||
'parameters': [[ViewPort]],
|
'parameters': [[ViewContainer]],
|
||||||
'annotations' : [new Template({
|
'annotations' : [new Viewport({
|
||||||
selector: '[ng-if]',
|
selector: '[ng-if]',
|
||||||
bind: {
|
bind: {
|
||||||
'ng-if': 'ngIf'
|
'ng-if': 'ngIf'
|
||||||
|
@ -335,16 +335,16 @@ class AppComponent {
|
||||||
|
|
||||||
// TODO: Move this into a reusable directive in the 'core' module!
|
// TODO: Move this into a reusable directive in the 'core' module!
|
||||||
class NgIf {
|
class NgIf {
|
||||||
_viewPort:ViewPort;
|
_viewContainer:ViewContainer;
|
||||||
constructor(viewPort:ViewPort) {
|
constructor(viewContainer:ViewContainer) {
|
||||||
this._viewPort = viewPort;
|
this._viewContainer = viewContainer;
|
||||||
}
|
}
|
||||||
set ngIf(value:boolean) {
|
set ngIf(value:boolean) {
|
||||||
if (this._viewPort.length > 0) {
|
if (this._viewContainer.length > 0) {
|
||||||
this._viewPort.remove(0);
|
this._viewContainer.remove(0);
|
||||||
}
|
}
|
||||||
if (value) {
|
if (value) {
|
||||||
this._viewPort.create();
|
this._viewContainer.create();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import {bootstrap, Component, Decorator, TemplateConfig, NgElement} from 'angula
|
||||||
// - Component - the basic building blocks of Angular 2.0 apps. Backed by
|
// - Component - the basic building blocks of Angular 2.0 apps. Backed by
|
||||||
// ShadowDom.(http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
|
// ShadowDom.(http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
|
||||||
// - Decorator - add behavior to existing elements.
|
// - 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
|
// @Component is AtScript syntax to annotate the HelloCmp class as an Angular
|
||||||
// 2.0 component.
|
// 2.0 component.
|
||||||
|
@ -40,7 +40,7 @@ class HelloCmp {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decorators are light-weight. They don't allow for templates, or new
|
// 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({
|
@Decorator({
|
||||||
selector: '[red]'
|
selector: '[red]'
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue