feat(Compiler): Multiple template per component
fixes #596 - TemplateConfig becomes Template - introduce a TemplateResolver to pick the cmp template, - @Component and @Template are disociated
This commit is contained in:
parent
52b062621d
commit
e6c8bde808
|
@ -1,7 +1,7 @@
|
|||
export * from './src/core/annotations/annotations';
|
||||
export * from './src/core/annotations/visibility';
|
||||
export * from './src/core/compiler/interfaces';
|
||||
export * from './src/core/annotations/template_config';
|
||||
export * from './src/core/annotations/template';
|
||||
export * from './src/core/application';
|
||||
|
||||
export * from './src/core/compiler/compiler';
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import {ABSTRACT, CONST, normalizeBlank, isPresent} from 'angular2/src/facade/lang';
|
||||
import {ListWrapper, List} from 'angular2/src/facade/collection';
|
||||
import {TemplateConfig} from './template_config';
|
||||
|
||||
@ABSTRACT()
|
||||
export class Directive {
|
||||
|
@ -38,7 +37,6 @@ export class Directive {
|
|||
|
||||
export class Component extends Directive {
|
||||
//TODO: vsavkin: uncomment it once the issue with defining fields in a sublass works
|
||||
template:any; //TemplateConfig;
|
||||
lightDomServices:any; //List;
|
||||
shadowDomServices:any; //List;
|
||||
componentServices:any; //List;
|
||||
|
@ -48,7 +46,6 @@ export class Component extends Directive {
|
|||
constructor({
|
||||
selector,
|
||||
bind,
|
||||
template,
|
||||
lightDomServices,
|
||||
shadowDomServices,
|
||||
componentServices,
|
||||
|
@ -57,7 +54,6 @@ export class Component extends Directive {
|
|||
}:{
|
||||
selector:String,
|
||||
bind:Object,
|
||||
template:TemplateConfig,
|
||||
lightDomServices:List,
|
||||
shadowDomServices:List,
|
||||
componentServices:List,
|
||||
|
@ -73,7 +69,6 @@ export class Component extends Directive {
|
|||
lifecycle: lifecycle
|
||||
});
|
||||
|
||||
this.template = template;
|
||||
this.lightDomServices = lightDomServices;
|
||||
this.shadowDomServices = shadowDomServices;
|
||||
this.componentServices = componentServices;
|
||||
|
|
|
@ -1,25 +1,31 @@
|
|||
import {ABSTRACT, CONST, Type} from 'angular2/src/facade/lang';
|
||||
import {List} from 'angular2/src/facade/collection';
|
||||
|
||||
export class TemplateConfig {
|
||||
export class Template {
|
||||
url:any; //string;
|
||||
inline:any; //string;
|
||||
directives:any; //List<Type>;
|
||||
formatters:any; //List<Type>;
|
||||
source:any;//List<TemplateConfig>;
|
||||
source:any;//List<Template>;
|
||||
locale:any; //string
|
||||
device:any; //string
|
||||
@CONST()
|
||||
constructor({
|
||||
url,
|
||||
inline,
|
||||
directives,
|
||||
formatters,
|
||||
source
|
||||
source,
|
||||
locale,
|
||||
device
|
||||
}: {
|
||||
url: string,
|
||||
inline: string,
|
||||
directives: List<Type>,
|
||||
formatters: List<Type>,
|
||||
source: List<TemplateConfig>
|
||||
source: List<Template>,
|
||||
locale: string,
|
||||
device: string
|
||||
})
|
||||
{
|
||||
this.url = url;
|
||||
|
@ -27,5 +33,7 @@ export class TemplateConfig {
|
|||
this.directives = directives;
|
||||
this.formatters = formatters;
|
||||
this.source = source;
|
||||
this.locale = locale;
|
||||
this.device = device;
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ import {ProtoView} from './compiler/view';
|
|||
import {Reflector, reflector} from 'angular2/src/reflection/reflection';
|
||||
import {Parser, Lexer, ChangeDetection, dynamicChangeDetection, jitChangeDetection} from 'angular2/change_detection';
|
||||
import {TemplateLoader} from './compiler/template_loader';
|
||||
import {TemplateResolver} from './compiler/template_resolver';
|
||||
import {DirectiveMetadataReader} from './compiler/directive_metadata_reader';
|
||||
import {DirectiveMetadata} from './compiler/directive_metadata';
|
||||
import {List, ListWrapper} from 'angular2/src/facade/collection';
|
||||
|
@ -28,6 +29,7 @@ var _rootBindings = [
|
|||
Compiler,
|
||||
CompilerCache,
|
||||
TemplateLoader,
|
||||
TemplateResolver,
|
||||
DirectiveMetadataReader,
|
||||
Parser,
|
||||
Lexer,
|
||||
|
@ -62,7 +64,7 @@ function _injectorBindings(appComponentType): List<Binding> {
|
|||
|
||||
bind(appViewToken).toAsyncFactory((changeDetection, compiler, injector, appElement,
|
||||
appComponentAnnotatedType, strategy, eventManager) => {
|
||||
return compiler.compile(appComponentAnnotatedType.type, null).then(
|
||||
return compiler.compile(appComponentAnnotatedType.type).then(
|
||||
(protoView) => {
|
||||
var appProtoView = ProtoView.createRootProtoView(protoView, appElement,
|
||||
appComponentAnnotatedType, changeDetection.createProtoChangeDetector('root'),
|
||||
|
|
|
@ -11,8 +11,10 @@ import {CompilePipeline} from './pipeline/compile_pipeline';
|
|||
import {CompileElement} from './pipeline/compile_element';
|
||||
import {createDefaultSteps} from './pipeline/default_steps';
|
||||
import {TemplateLoader} from './template_loader';
|
||||
import {TemplateResolver} from './template_resolver';
|
||||
import {DirectiveMetadata} from './directive_metadata';
|
||||
import {Component} from '../annotations/annotations';
|
||||
import {Template} from '../annotations/template';
|
||||
import {Content} from './shadow_dom_emulation/content_tag';
|
||||
import {ShadowDomStrategy} from './shadow_dom_strategy';
|
||||
import {CompileStep} from './pipeline/compile_step';
|
||||
|
@ -55,13 +57,15 @@ export class Compiler {
|
|||
_compiling:Map<Type, Promise>;
|
||||
_shadowDomStrategy: ShadowDomStrategy;
|
||||
_shadowDomDirectives: List<DirectiveMetadata>;
|
||||
_templateResolver: TemplateResolver;
|
||||
|
||||
constructor(changeDetection:ChangeDetection,
|
||||
templateLoader:TemplateLoader,
|
||||
reader: DirectiveMetadataReader,
|
||||
parser:Parser,
|
||||
cache:CompilerCache,
|
||||
shadowDomStrategy: ShadowDomStrategy) {
|
||||
shadowDomStrategy: ShadowDomStrategy,
|
||||
templateResolver: TemplateResolver) {
|
||||
this._changeDetection = changeDetection;
|
||||
this._reader = reader;
|
||||
this._parser = parser;
|
||||
|
@ -74,32 +78,38 @@ export class Compiler {
|
|||
for (var i = 0; i < types.length; i++) {
|
||||
ListWrapper.push(this._shadowDomDirectives, reader.read(types[i]));
|
||||
}
|
||||
this._templateResolver = templateResolver;
|
||||
}
|
||||
|
||||
createSteps(component:DirectiveMetadata):List<CompileStep> {
|
||||
var directives = []
|
||||
var cmpDirectives = ListWrapper.map(component.componentDirectives, (d) => this._reader.read(d));
|
||||
directives = ListWrapper.concat(directives, cmpDirectives);
|
||||
directives = ListWrapper.concat(directives, this._shadowDomDirectives);
|
||||
return createDefaultSteps(this._changeDetection, this._parser, component, directives,
|
||||
createSteps(component:Type, template: Template):List<CompileStep> {
|
||||
// Merge directive metadata (from the template and from the shadow dom strategy)
|
||||
var dirMetadata = [];
|
||||
var tplMetadata = ListWrapper.map(this._flattenDirectives(template),
|
||||
(d) => this._reader.read(d));
|
||||
dirMetadata = ListWrapper.concat(dirMetadata, tplMetadata);
|
||||
dirMetadata = ListWrapper.concat(dirMetadata, this._shadowDomDirectives);
|
||||
|
||||
var cmpMetadata = this._reader.read(component);
|
||||
|
||||
return createDefaultSteps(this._changeDetection, this._parser, cmpMetadata, dirMetadata,
|
||||
this._shadowDomStrategy);
|
||||
}
|
||||
|
||||
compile(component:Type, templateRoot:Element = null):Promise<ProtoView> {
|
||||
var protoView = this._compile(this._reader.read(component), templateRoot);
|
||||
compile(component: Type):Promise<ProtoView> {
|
||||
var protoView = this._compile(component);
|
||||
return PromiseWrapper.isPromise(protoView) ? protoView : PromiseWrapper.resolve(protoView);
|
||||
}
|
||||
|
||||
// TODO(vicb): union type return ProtoView or Promise<ProtoView>
|
||||
_compile(cmpMetadata: DirectiveMetadata, templateRoot:Element = null) {
|
||||
var protoView = this._compilerCache.get(cmpMetadata.type);
|
||||
_compile(component: Type) {
|
||||
var protoView = this._compilerCache.get(component);
|
||||
if (isPresent(protoView)) {
|
||||
// The component has already been compiled into a ProtoView,
|
||||
// returns a resolved Promise.
|
||||
return protoView;
|
||||
}
|
||||
|
||||
var pvPromise = MapWrapper.get(this._compiling, cmpMetadata.type);
|
||||
var pvPromise = MapWrapper.get(this._compiling, component);
|
||||
if (isPresent(pvPromise)) {
|
||||
// The component is already being compiled, attach to the existing Promise
|
||||
// instead of re-compiling the component.
|
||||
|
@ -107,30 +117,32 @@ export class Compiler {
|
|||
return pvPromise;
|
||||
}
|
||||
|
||||
var template = isBlank(templateRoot) ? this._templateLoader.load(cmpMetadata) : templateRoot;
|
||||
var template = this._templateResolver.resolve(component);
|
||||
|
||||
if (PromiseWrapper.isPromise(template)) {
|
||||
pvPromise = PromiseWrapper.then(template,
|
||||
(el) => this._compileTemplate(el, cmpMetadata),
|
||||
(_) => { throw new BaseException(`Failed to load the template for ${stringify(cmpMetadata.type)}`); }
|
||||
var tplElement = this._templateLoader.load(template);
|
||||
|
||||
if (PromiseWrapper.isPromise(tplElement)) {
|
||||
pvPromise = PromiseWrapper.then(tplElement,
|
||||
(el) => this._compileTemplate(template, el, component),
|
||||
(_) => { throw new BaseException(`Failed to load the template for ${stringify(component)}`); }
|
||||
);
|
||||
MapWrapper.set(this._compiling, cmpMetadata.type, pvPromise);
|
||||
MapWrapper.set(this._compiling, component, pvPromise);
|
||||
return pvPromise;
|
||||
}
|
||||
|
||||
return this._compileTemplate(template, cmpMetadata);
|
||||
return this._compileTemplate(template, tplElement, component);
|
||||
}
|
||||
|
||||
// TODO(vicb): union type return ProtoView or Promise<ProtoView>
|
||||
_compileTemplate(template: Element, cmpMetadata) {
|
||||
var pipeline = new CompilePipeline(this.createSteps(cmpMetadata));
|
||||
var compileElements = pipeline.process(template);
|
||||
_compileTemplate(template: Template, tplElement: Element, component: Type) {
|
||||
var pipeline = new CompilePipeline(this.createSteps(component, template));
|
||||
var compileElements = pipeline.process(tplElement);
|
||||
var protoView = compileElements[0].inheritedProtoView;
|
||||
|
||||
// Populate the cache before compiling the nested components,
|
||||
// so that components can reference themselves in their template.
|
||||
this._compilerCache.set(cmpMetadata.type, protoView);
|
||||
MapWrapper.delete(this._compiling, cmpMetadata.type);
|
||||
this._compilerCache.set(component, protoView);
|
||||
MapWrapper.delete(this._compiling, component);
|
||||
|
||||
// Compile all the components from the template
|
||||
var nestedPVPromises = [];
|
||||
|
@ -146,7 +158,7 @@ export class Compiler {
|
|||
// The promise will resolved after nested ProtoViews are compiled.
|
||||
return PromiseWrapper.then(PromiseWrapper.all(nestedPVPromises),
|
||||
(_) => protoView,
|
||||
(e) => { throw new BaseException(`${e.message} -> Failed to compile ${stringify(cmpMetadata.type)}`); }
|
||||
(e) => { throw new BaseException(`${e.message} -> Failed to compile ${stringify(component)}`); }
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -154,9 +166,8 @@ export class Compiler {
|
|||
return protoView;
|
||||
}
|
||||
|
||||
_compileNestedProtoView(ce: CompileElement, promises: List<Promise>)
|
||||
{
|
||||
var protoView = this._compile(ce.componentDirective);
|
||||
_compileNestedProtoView(ce: CompileElement, promises: List<Promise>) {
|
||||
var protoView = this._compile(ce.componentDirective.type);
|
||||
|
||||
if (PromiseWrapper.isPromise(protoView)) {
|
||||
ListWrapper.push(promises, protoView);
|
||||
|
@ -167,4 +178,27 @@ export class Compiler {
|
|||
ce.inheritedElementBinder.nestedProtoView = protoView;
|
||||
}
|
||||
}
|
||||
|
||||
_flattenDirectives(template: Template):List<Type> {
|
||||
if (isBlank(template.directives)) return [];
|
||||
|
||||
var directives = [];
|
||||
this._flattenList(template.directives, directives);
|
||||
|
||||
return directives;
|
||||
}
|
||||
|
||||
_flattenList(tree:List<any>, out:List<Type>) {
|
||||
for (var i = 0; i < tree.length; i++) {
|
||||
var item = tree[i];
|
||||
if (ListWrapper.isList(item)) {
|
||||
this._flattenList(item, out);
|
||||
} else {
|
||||
ListWrapper.push(out, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import {Type} from 'angular2/src/facade/lang';
|
||||
import {Directive} from 'angular2/src/core/annotations/annotations'
|
||||
import {List} from 'angular2/src/facade/collection'
|
||||
import {ShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
||||
|
||||
/**
|
||||
* Combination of a type with the Directive annotation
|
||||
|
@ -9,13 +7,9 @@ import {ShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy'
|
|||
export class DirectiveMetadata {
|
||||
type:Type;
|
||||
annotation:Directive;
|
||||
componentDirectives:List<Type>;
|
||||
|
||||
constructor(type:Type,
|
||||
annotation:Directive,
|
||||
componentDirectives:List<Type>) {
|
||||
constructor(type:Type, annotation:Directive) {
|
||||
this.annotation = annotation;
|
||||
this.type = type;
|
||||
this.componentDirectives = componentDirectives;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
import {Type, isPresent, BaseException, stringify} from 'angular2/src/facade/lang';
|
||||
import {List, ListWrapper} from 'angular2/src/facade/collection';
|
||||
import {Directive, Component} from '../annotations/annotations';
|
||||
import {Directive} from '../annotations/annotations';
|
||||
import {DirectiveMetadata} from './directive_metadata';
|
||||
import {reflector} from 'angular2/src/reflection/reflection';
|
||||
import {ShadowDom, ShadowDomStrategy, ShadowDomNative} from './shadow_dom_strategy';
|
||||
|
||||
export class DirectiveMetadataReader {
|
||||
read(type:Type):DirectiveMetadata {
|
||||
|
@ -12,39 +10,12 @@ export class DirectiveMetadataReader {
|
|||
for (var i=0; i<annotations.length; i++) {
|
||||
var annotation = annotations[i];
|
||||
|
||||
if (annotation instanceof Component) {
|
||||
return new DirectiveMetadata(
|
||||
type,
|
||||
annotation,
|
||||
this.componentDirectivesMetadata(annotation)
|
||||
);
|
||||
}
|
||||
|
||||
if (annotation instanceof Directive) {
|
||||
return new DirectiveMetadata(type, annotation, null);
|
||||
return new DirectiveMetadata(type, annotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new BaseException(`No Directive annotation found on ${stringify(type)}`);
|
||||
}
|
||||
|
||||
componentDirectivesMetadata(annotation:Component):List<Type> {
|
||||
var template = annotation.template;
|
||||
var result:List<Type> = ListWrapper.create();
|
||||
if (isPresent(template) && isPresent(template.directives)) {
|
||||
this._buildList(result, template.directives);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
_buildList(out:List<Type>, tree:List<any>) {
|
||||
for (var i = 0; i < tree.length; i++) {
|
||||
var item = tree[i];
|
||||
if (ListWrapper.isList(item)) {
|
||||
this._buildList(out, item);
|
||||
} else {
|
||||
ListWrapper.push(out, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
|
||||
import {isBlank, isPresent, BaseException, stringify} from 'angular2/src/facade/lang';
|
||||
import {TemplateElement, DOM, Element} from 'angular2/src/facade/dom';
|
||||
import {DOM, Element} from 'angular2/src/facade/dom';
|
||||
import {StringMapWrapper} from 'angular2/src/facade/collection';
|
||||
|
||||
import {TemplateConfig} from 'angular2/src/core/annotations/template_config';
|
||||
import {Component} from 'angular2/src/core/annotations/annotations';
|
||||
|
||||
import {DirectiveMetadata} from 'angular2/src/core/compiler/directive_metadata';
|
||||
|
||||
import {XHR} from './xhr/xhr';
|
||||
|
||||
import {Template} from 'angular2/src/core/annotations/template';
|
||||
|
||||
/**
|
||||
* Strategy to load component templates.
|
||||
*/
|
||||
|
@ -23,16 +20,13 @@ export class TemplateLoader {
|
|||
}
|
||||
|
||||
// TODO(vicb): union type: return an Element or a Promise<Element>
|
||||
load(cmpMetadata: DirectiveMetadata) {
|
||||
var annotation:Component = cmpMetadata.annotation;
|
||||
var tplConfig:TemplateConfig = annotation.template;
|
||||
|
||||
if (isPresent(tplConfig.inline)) {
|
||||
return DOM.createTemplate(tplConfig.inline);
|
||||
load(template: Template) {
|
||||
if (isPresent(template.inline)) {
|
||||
return DOM.createTemplate(template.inline);
|
||||
}
|
||||
|
||||
if (isPresent(tplConfig.url)) {
|
||||
var url = tplConfig.url;
|
||||
if (isPresent(template.url)) {
|
||||
var url = template.url;
|
||||
var promise = StringMapWrapper.get(this._cache, url);
|
||||
|
||||
if (isBlank(promise)) {
|
||||
|
@ -46,6 +40,6 @@ export class TemplateLoader {
|
|||
return promise;
|
||||
}
|
||||
|
||||
throw new BaseException(`No template configured for component ${stringify(cmpMetadata.type)}`);
|
||||
throw new BaseException(`Templates should have either their url or inline property set`);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
import {Template} from 'angular2/src/core/annotations/template';
|
||||
|
||||
import {Type, stringify, isBlank, BaseException} from 'angular2/src/facade/lang';
|
||||
import {Map, MapWrapper, List, ListWrapper} from 'angular2/src/facade/collection';
|
||||
|
||||
import {reflector} from 'angular2/src/reflection/reflection';
|
||||
|
||||
|
||||
export class TemplateResolver {
|
||||
_cache: Map;
|
||||
|
||||
constructor() {
|
||||
this._cache = MapWrapper.create();
|
||||
}
|
||||
|
||||
resolve(component: Type): Template {
|
||||
var template = MapWrapper.get(this._cache, component);
|
||||
|
||||
if (isBlank(template)) {
|
||||
template = this._resolve(component);
|
||||
MapWrapper.set(this._cache, component, template);
|
||||
}
|
||||
|
||||
return template;
|
||||
}
|
||||
|
||||
_resolve(component: Type) {
|
||||
var annotations = reflector.annotations(component);
|
||||
for (var i = 0; i < annotations.length; i++) {
|
||||
var annotation = annotations[i];
|
||||
if (annotation instanceof Template) {
|
||||
return annotation;
|
||||
}
|
||||
}
|
||||
|
||||
throw new BaseException(`No template found for ${stringify(component)}`);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
import {TemplateConfig, Component, Decorator, NgElement, Ancestor, onChange} from 'angular2/core';
|
||||
import {Template, Component, Decorator, NgElement, Ancestor, onChange} from 'angular2/core';
|
||||
import {DOM} from 'angular2/src/facade/dom';
|
||||
import {isBlank, isPresent, CONST} from 'angular2/src/facade/lang';
|
||||
import {StringMapWrapper, ListWrapper} from 'angular2/src/facade/collection';
|
||||
|
@ -164,11 +164,9 @@ export class ControlGroupDirective extends ControlGroupDirectiveBase {
|
|||
selector: '[new-control-group]',
|
||||
bind: {
|
||||
'new-control-group' : 'initData'
|
||||
},
|
||||
template: new TemplateConfig({
|
||||
inline: '<content>'
|
||||
})
|
||||
}
|
||||
})
|
||||
@Template({inline: '<content>'})
|
||||
export class NewControlGroupDirective extends ControlGroupDirectiveBase {
|
||||
_initData:any;
|
||||
_controlGroup:ControlGroup;
|
||||
|
|
|
@ -6,16 +6,11 @@ import {DOM} from 'angular2/src/facade/dom';
|
|||
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||
import {PromiseWrapper} from 'angular2/src/facade/async';
|
||||
import {bind, Inject} from 'angular2/di';
|
||||
import {TemplateConfig} from 'angular2/src/core/annotations/template_config';
|
||||
import {Template} from 'angular2/src/core/annotations/template';
|
||||
import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
|
||||
|
||||
@Component({
|
||||
selector: 'hello-app',
|
||||
template: new TemplateConfig({
|
||||
inline: '{{greeting}} world!',
|
||||
directives: []
|
||||
})
|
||||
})
|
||||
@Component({selector: 'hello-app'})
|
||||
@Template({inline: '{{greeting}} world!'})
|
||||
class HelloRootCmp {
|
||||
greeting:string;
|
||||
constructor() {
|
||||
|
@ -23,13 +18,8 @@ class HelloRootCmp {
|
|||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'hello-app-2',
|
||||
template: new TemplateConfig({
|
||||
inline: '{{greeting}} world, again!',
|
||||
directives: []
|
||||
})
|
||||
})
|
||||
@Component({selector: 'hello-app-2'})
|
||||
@Template({inline: '{{greeting}} world, again!'})
|
||||
class HelloRootCmp2 {
|
||||
greeting:string;
|
||||
constructor() {
|
||||
|
@ -37,13 +27,8 @@ class HelloRootCmp2 {
|
|||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'hello-app',
|
||||
template: new TemplateConfig({
|
||||
inline: '',
|
||||
directives: []
|
||||
})
|
||||
})
|
||||
@Component({selector: 'hello-app'})
|
||||
@Template({inline: ''})
|
||||
class HelloRootCmp3 {
|
||||
appBinding;
|
||||
|
||||
|
@ -52,13 +37,8 @@ class HelloRootCmp3 {
|
|||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'hello-app',
|
||||
template: new TemplateConfig({
|
||||
inline: '',
|
||||
directives: []
|
||||
})
|
||||
})
|
||||
@Component({selector: 'hello-app'})
|
||||
@Template({inline: ''})
|
||||
class HelloRootCmp4 {
|
||||
lc;
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import {describe, beforeEach, it, expect, ddescribe, iit, el, IS_DARTIUM} from 'angular2/test_lib';
|
||||
|
||||
import {DOM, Element, TemplateElement} from 'angular2/src/facade/dom';
|
||||
import {List, ListWrapper, Map, MapWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
|
||||
import {Type, isBlank, stringify} from 'angular2/src/facade/lang';
|
||||
import {Type, isBlank, stringify, isPresent} from 'angular2/src/facade/lang';
|
||||
import {PromiseWrapper} from 'angular2/src/facade/async';
|
||||
|
||||
import {Compiler, CompilerCache} from 'angular2/src/core/compiler/compiler';
|
||||
|
@ -9,39 +10,39 @@ import {ProtoView} from 'angular2/src/core/compiler/view';
|
|||
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
||||
import {DirectiveMetadata} from 'angular2/src/core/compiler/directive_metadata';
|
||||
import {Component} from 'angular2/src/core/annotations/annotations';
|
||||
import {TemplateConfig} from 'angular2/src/core/annotations/template_config';
|
||||
import {Template} from 'angular2/src/core/annotations/template';
|
||||
import {CompileElement} from 'angular2/src/core/compiler/pipeline/compile_element';
|
||||
import {CompileStep} from 'angular2/src/core/compiler/pipeline/compile_step'
|
||||
import {CompileControl} from 'angular2/src/core/compiler/pipeline/compile_control';
|
||||
import {TemplateLoader} from 'angular2/src/core/compiler/template_loader';
|
||||
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
|
||||
|
||||
import {Lexer, Parser, dynamicChangeDetection} from 'angular2/change_detection';
|
||||
import {ShadowDomStrategy, NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
||||
import {XHRMock} from 'angular2/src/mock/xhr_mock';
|
||||
|
||||
export function main() {
|
||||
describe('compiler', function() {
|
||||
var reader;
|
||||
|
||||
beforeEach( () => {
|
||||
reader = new DirectiveMetadataReader();
|
||||
});
|
||||
|
||||
var syncTemplateLoader = new FakeTemplateLoader();
|
||||
syncTemplateLoader.forceSync();
|
||||
var asyncTemplateLoader = new FakeTemplateLoader();
|
||||
asyncTemplateLoader.forceAsync();
|
||||
|
||||
StringMapWrapper.forEach({
|
||||
'(sync TemplateLoader)': syncTemplateLoader,
|
||||
'(async TemplateLoader)': asyncTemplateLoader
|
||||
}, (templateLoader, name) => {
|
||||
'(sync TemplateLoader)': true,
|
||||
'(async TemplateLoader)': false
|
||||
}, (sync, name) => {
|
||||
var reader, tplResolver;
|
||||
|
||||
beforeEach(() => {
|
||||
reader = new DirectiveMetadataReader();
|
||||
tplResolver = new FakeTemplateResolver();
|
||||
if (sync) {
|
||||
tplResolver.forceSync();
|
||||
} else {
|
||||
tplResolver.forceAsync();
|
||||
}
|
||||
});
|
||||
|
||||
describe(name, () => {
|
||||
|
||||
function createCompiler(processClosure) {
|
||||
var steps = [new MockStep(processClosure)];
|
||||
return new TestableCompiler(reader, steps, templateLoader);
|
||||
return new TestableCompiler(reader, steps, new FakeTemplateLoader(), tplResolver);
|
||||
}
|
||||
|
||||
it('should run the steps and return the ProtoView of the root element', (done) => {
|
||||
|
@ -49,43 +50,35 @@ export function main() {
|
|||
var compiler = createCompiler( (parent, current, control) => {
|
||||
current.inheritedProtoView = rootProtoView;
|
||||
});
|
||||
compiler.compile(MainComponent, el('<div></div>')).then( (protoView) => {
|
||||
tplResolver.setTemplate(MainComponent, new Template({inline: '<div></div>'}));
|
||||
compiler.compile(MainComponent).then( (protoView) => {
|
||||
expect(protoView).toBe(rootProtoView);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should use the given element', (done) => {
|
||||
var element = el('<div></div>');
|
||||
it('should use the inline template', (done) => {
|
||||
var compiler = createCompiler( (parent, current, control) => {
|
||||
current.inheritedProtoView = new ProtoView(current.element, null, null);
|
||||
});
|
||||
compiler.compile(MainComponent, element).then( (protoView) => {
|
||||
expect(protoView.element).toBe(element);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should use the inline template if no element is given explicitly', (done) => {
|
||||
var compiler = createCompiler( (parent, current, control) => {
|
||||
current.inheritedProtoView = new ProtoView(current.element, null, null);
|
||||
});
|
||||
compiler.compile(MainComponent, null).then( (protoView) => {
|
||||
compiler.compile(MainComponent).then( (protoView) => {
|
||||
expect(DOM.getInnerHTML(protoView.element)).toEqual('inline component');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should load nested components', (done) => {
|
||||
var mainEl = el('<div></div>');
|
||||
var compiler = createCompiler( (parent, current, control) => {
|
||||
current.inheritedProtoView = new ProtoView(current.element, null, null);
|
||||
current.inheritedElementBinder = current.inheritedProtoView.bindElement(null);
|
||||
if (current.element === mainEl) {
|
||||
if (DOM.hasClass(current.element, 'nested')) {
|
||||
current.componentDirective = reader.read(NestedComponent);
|
||||
current.inheritedProtoView = parent.inheritedProtoView;
|
||||
current.inheritedElementBinder = current.inheritedProtoView.bindElement(null);
|
||||
} else {
|
||||
current.inheritedProtoView = new ProtoView(current.element, null, null);
|
||||
}
|
||||
});
|
||||
compiler.compile(MainComponent, mainEl).then( (protoView) => {
|
||||
tplResolver.setTemplate(MainComponent, new Template({inline: '<div class="nested"></div>'}));
|
||||
compiler.compile(MainComponent).then( (protoView) => {
|
||||
var nestedView = protoView.elementBinders[0].nestedProtoView;
|
||||
expect(DOM.getInnerHTML(nestedView.element)).toEqual('nested component');
|
||||
done();
|
||||
|
@ -93,14 +86,14 @@ export function main() {
|
|||
});
|
||||
|
||||
it('should cache compiled components', (done) => {
|
||||
var element = el('<div></div>');
|
||||
var compiler = createCompiler( (parent, current, control) => {
|
||||
current.inheritedProtoView = new ProtoView(current.element, null, null);
|
||||
});
|
||||
var firstProtoView;
|
||||
compiler.compile(MainComponent, element).then( (protoView) => {
|
||||
tplResolver.setTemplate(MainComponent, new Template({inline: '<div></div>'}));
|
||||
compiler.compile(MainComponent).then( (protoView) => {
|
||||
firstProtoView = protoView;
|
||||
return compiler.compile(MainComponent, element);
|
||||
return compiler.compile(MainComponent);
|
||||
}).then( (protoView) => {
|
||||
expect(firstProtoView).toBe(protoView);
|
||||
done();
|
||||
|
@ -109,7 +102,6 @@ export function main() {
|
|||
|
||||
it('should re-use components being compiled', (done) => {
|
||||
var nestedElBinders = [];
|
||||
var mainEl = el('<div><div class="nested"></div><div class="nested"></div></div>');
|
||||
var compiler = createCompiler( (parent, current, control) => {
|
||||
if (DOM.hasClass(current.element, 'nested')) {
|
||||
current.inheritedProtoView = new ProtoView(current.element, null, null);
|
||||
|
@ -118,7 +110,9 @@ export function main() {
|
|||
ListWrapper.push(nestedElBinders, current.inheritedElementBinder);
|
||||
}
|
||||
});
|
||||
compiler.compile(MainComponent, mainEl).then( (protoView) => {
|
||||
tplResolver.setTemplate(MainComponent,
|
||||
new Template({inline: '<div><div class="nested"></div><div class="nested"></div></div>'}));
|
||||
compiler.compile(MainComponent).then( (protoView) => {
|
||||
expect(nestedElBinders[0].nestedProtoView).toBe(nestedElBinders[1].nestedProtoView);
|
||||
done();
|
||||
});
|
||||
|
@ -130,7 +124,7 @@ export function main() {
|
|||
current.inheritedElementBinder = current.inheritedProtoView.bindElement(null);
|
||||
current.componentDirective = reader.read(RecursiveComponent);
|
||||
});
|
||||
compiler.compile(RecursiveComponent, null).then( (protoView) => {
|
||||
compiler.compile(RecursiveComponent).then( (protoView) => {
|
||||
expect(protoView.elementBinders[0].nestedProtoView).toBe(protoView);
|
||||
done();
|
||||
});
|
||||
|
@ -139,12 +133,14 @@ export function main() {
|
|||
});
|
||||
|
||||
describe('(mixed async, sync TemplateLoader)', () => {
|
||||
function createCompiler(processClosure, templateLoader: TemplateLoader) {
|
||||
var reader = new DirectiveMetadataReader();
|
||||
|
||||
function createCompiler(processClosure, resolver: TemplateResolver) {
|
||||
var steps = [new MockStep(processClosure)];
|
||||
return new TestableCompiler(reader, steps, templateLoader);
|
||||
return new TestableCompiler(reader, steps, new FakeTemplateLoader(), resolver);
|
||||
}
|
||||
|
||||
function createNestedComponentSpec(name, loader: TemplateLoader, error:string = null) {
|
||||
function createNestedComponentSpec(name, resolver: TemplateResolver, error:string = null) {
|
||||
it(`should load nested components ${name}`, (done) => {
|
||||
|
||||
var compiler = createCompiler((parent, current, control) => {
|
||||
|
@ -155,7 +151,7 @@ export function main() {
|
|||
} else {
|
||||
current.inheritedProtoView = new ProtoView(current.element, null, null);
|
||||
}
|
||||
}, loader);
|
||||
}, resolver);
|
||||
|
||||
PromiseWrapper.then(compiler.compile(ParentComponent),
|
||||
function(protoView) {
|
||||
|
@ -172,89 +168,77 @@ export function main() {
|
|||
});
|
||||
}
|
||||
|
||||
var loader = new FakeTemplateLoader();
|
||||
loader.setSync(ParentComponent);
|
||||
loader.setSync(NestedComponent);
|
||||
createNestedComponentSpec('(sync -> sync)', loader);
|
||||
var resolver = new FakeTemplateResolver();
|
||||
resolver.setSync(ParentComponent);
|
||||
resolver.setSync(NestedComponent);
|
||||
createNestedComponentSpec('(sync -> sync)', resolver);
|
||||
|
||||
loader = new FakeTemplateLoader();
|
||||
loader.setAsync(ParentComponent);
|
||||
loader.setSync(NestedComponent);
|
||||
createNestedComponentSpec('(async -> sync)', loader);
|
||||
resolver = new FakeTemplateResolver();
|
||||
resolver.setAsync(ParentComponent);
|
||||
resolver.setSync(NestedComponent);
|
||||
createNestedComponentSpec('(async -> sync)', resolver);
|
||||
|
||||
loader = new FakeTemplateLoader();
|
||||
loader.setSync(ParentComponent);
|
||||
loader.setAsync(NestedComponent);
|
||||
createNestedComponentSpec('(sync -> async)', loader);
|
||||
resolver = new FakeTemplateResolver();
|
||||
resolver.setSync(ParentComponent);
|
||||
resolver.setAsync(NestedComponent);
|
||||
createNestedComponentSpec('(sync -> async)', resolver);
|
||||
|
||||
loader = new FakeTemplateLoader();
|
||||
loader.setAsync(ParentComponent);
|
||||
loader.setAsync(NestedComponent);
|
||||
createNestedComponentSpec('(async -> async)', loader);
|
||||
resolver = new FakeTemplateResolver();
|
||||
resolver.setAsync(ParentComponent);
|
||||
resolver.setAsync(NestedComponent);
|
||||
createNestedComponentSpec('(async -> async)', resolver);
|
||||
|
||||
loader = new FakeTemplateLoader();
|
||||
loader.setError(ParentComponent);
|
||||
loader.setSync(NestedComponent);
|
||||
createNestedComponentSpec('(error -> sync)', loader,
|
||||
resolver = new FakeTemplateResolver();
|
||||
resolver.setError(ParentComponent);
|
||||
resolver.setSync(NestedComponent);
|
||||
createNestedComponentSpec('(error -> sync)', resolver,
|
||||
'Failed to load the template for ParentComponent');
|
||||
|
||||
// TODO(vicb): Check why errors this fails with Dart
|
||||
// TODO(vicb): The Promise is rejected with the correct error but an exc is thrown before
|
||||
//loader = new FakeTemplateLoader();
|
||||
//loader.setSync(ParentComponent);
|
||||
//loader.setError(NestedComponent);
|
||||
//createNestedComponentSpec('(sync -> error)', loader,
|
||||
//resolver = new FakeTemplateResolver();
|
||||
//resolver.setSync(ParentComponent);
|
||||
//resolver.setError(NestedComponent);
|
||||
//createNestedComponentSpec('(sync -> error)', resolver,
|
||||
// 'Failed to load the template for NestedComponent -> Failed to compile ParentComponent');
|
||||
//
|
||||
//loader = new FakeTemplateLoader();
|
||||
//loader.setAsync(ParentComponent);
|
||||
//loader.setError(NestedComponent);
|
||||
//createNestedComponentSpec('(async -> error)', loader,
|
||||
//resolver = new FakeTemplateResolver();
|
||||
//resolver.setAsync(ParentComponent);
|
||||
//resolver.setError(NestedComponent);
|
||||
//createNestedComponentSpec('(async -> error)', resolver,
|
||||
// 'Failed to load the template for NestedComponent -> Failed to compile ParentComponent');
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@Component({
|
||||
template: new TemplateConfig({
|
||||
inline: '<div class="parent"></div>'
|
||||
})
|
||||
})
|
||||
@Component()
|
||||
@Template({inline: '<div class="parent"></div>'})
|
||||
class ParentComponent {}
|
||||
|
||||
@Component({
|
||||
template: new TemplateConfig({
|
||||
inline: 'inline component'
|
||||
})
|
||||
})
|
||||
@Component()
|
||||
@Template({inline: 'inline component'})
|
||||
class MainComponent {}
|
||||
|
||||
@Component({
|
||||
template: new TemplateConfig({
|
||||
inline: 'nested component'
|
||||
})
|
||||
})
|
||||
@Component()
|
||||
@Template({inline: 'nested component'})
|
||||
class NestedComponent {}
|
||||
|
||||
@Component({
|
||||
template: new TemplateConfig({
|
||||
inline: '<div rec-comp></div>'
|
||||
}),
|
||||
selector: 'rec-comp'
|
||||
})
|
||||
@Component({selector: 'rec-comp'})
|
||||
@Template({inline: '<div rec-comp></div>'})
|
||||
class RecursiveComponent {}
|
||||
|
||||
class TestableCompiler extends Compiler {
|
||||
steps:List;
|
||||
|
||||
constructor(reader:DirectiveMetadataReader, steps:List<CompileStep>, loader: TemplateLoader) {
|
||||
constructor(reader:DirectiveMetadataReader, steps:List<CompileStep>, loader: TemplateLoader,
|
||||
resolver: TemplateResolver) {
|
||||
super(dynamicChangeDetection, loader, reader, new Parser(new Lexer()), new CompilerCache(),
|
||||
new NativeShadowDomStrategy());
|
||||
new NativeShadowDomStrategy(), resolver);
|
||||
this.steps = steps;
|
||||
}
|
||||
|
||||
createSteps(component):List<CompileStep> {
|
||||
createSteps(component:Type, template: Template):List<CompileStep> {
|
||||
return this.steps;
|
||||
}
|
||||
}
|
||||
|
@ -271,19 +255,70 @@ class MockStep extends CompileStep {
|
|||
}
|
||||
|
||||
class FakeTemplateLoader extends TemplateLoader {
|
||||
constructor() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
load(template: Template) {
|
||||
if (isPresent(template.inline)) {
|
||||
return DOM.createTemplate(template.inline);
|
||||
}
|
||||
|
||||
if (isPresent(template.url)) {
|
||||
var tplElement = DOM.createTemplate(template.url);
|
||||
return PromiseWrapper.resolve(tplElement);
|
||||
}
|
||||
|
||||
return PromiseWrapper.reject('Fail to load');
|
||||
}
|
||||
}
|
||||
|
||||
class FakeTemplateResolver extends TemplateResolver {
|
||||
_forceSync: boolean;
|
||||
_forceAsync: boolean;
|
||||
_cmpTemplates: Map;
|
||||
_syncCmp: List<Type>;
|
||||
_asyncCmp: List<Type>;
|
||||
_errorCmp: List<Type>;
|
||||
|
||||
constructor() {
|
||||
super (new XHRMock());
|
||||
super();
|
||||
this._forceSync = false;
|
||||
this._forceAsync = false;
|
||||
this._syncCmp = [];
|
||||
this._asyncCmp = [];
|
||||
this._errorCmp = [];
|
||||
this._cmpTemplates = MapWrapper.create();
|
||||
}
|
||||
|
||||
resolve(component: Type): Template {
|
||||
var template = MapWrapper.get(this._cmpTemplates, component);
|
||||
if (isBlank(template)) {
|
||||
template = super.resolve(component);
|
||||
}
|
||||
|
||||
var html = template.inline;
|
||||
|
||||
if (isBlank(template.inline)) {
|
||||
throw 'The tested component must define an inline template';
|
||||
}
|
||||
|
||||
if (ListWrapper.contains(this._errorCmp, component)) {
|
||||
return new Template({url: null, inline: null});
|
||||
}
|
||||
|
||||
if (ListWrapper.contains(this._syncCmp, component)) {
|
||||
return new Template({inline: html});
|
||||
}
|
||||
|
||||
if (ListWrapper.contains(this._asyncCmp, component)) {
|
||||
return new Template({url: html});
|
||||
}
|
||||
|
||||
if (this._forceSync) return new Template({inline: html});
|
||||
if (this._forceAsync) return new Template({url: html});
|
||||
|
||||
throw 'No template';
|
||||
}
|
||||
|
||||
forceSync() {
|
||||
|
@ -308,31 +343,7 @@ class FakeTemplateLoader extends TemplateLoader {
|
|||
ListWrapper.push(this._errorCmp, component);
|
||||
}
|
||||
|
||||
load(cmpMetadata: DirectiveMetadata) {
|
||||
var annotation:Component = cmpMetadata.annotation;
|
||||
var tplConfig:TemplateConfig = annotation.template;
|
||||
|
||||
if (isBlank(tplConfig.inline)) {
|
||||
throw 'The component must define an inline template';
|
||||
}
|
||||
|
||||
var template = DOM.createTemplate(tplConfig.inline);
|
||||
|
||||
if (ListWrapper.contains(this._errorCmp, cmpMetadata.type)) {
|
||||
return PromiseWrapper.reject('Fail to load');
|
||||
}
|
||||
|
||||
if (ListWrapper.contains(this._syncCmp, cmpMetadata.type)) {
|
||||
return template;
|
||||
}
|
||||
|
||||
if (ListWrapper.contains(this._asyncCmp, cmpMetadata.type)) {
|
||||
return PromiseWrapper.resolve(template);
|
||||
}
|
||||
|
||||
if (this._forceSync) return template;
|
||||
if (this._forceAsync) return PromiseWrapper.resolve(template);
|
||||
|
||||
throw `No template configured for ${stringify(cmpMetadata.type)}`;
|
||||
setTemplate(component: Type, template: Template) {
|
||||
MapWrapper.set(this._cmpTemplates, component, template);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,43 +1,25 @@
|
|||
import {ddescribe, describe, it, iit, expect, beforeEach} from 'angular2/test_lib';
|
||||
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
||||
import {Decorator, Component} from 'angular2/src/core/annotations/annotations';
|
||||
import {TemplateConfig} from 'angular2/src/core/annotations/template_config';
|
||||
import {Decorator, Component, Viewport} from 'angular2/src/core/annotations/annotations';
|
||||
import {Template} from 'angular2/src/core/annotations/template';
|
||||
import {DirectiveMetadata} from 'angular2/src/core/compiler/directive_metadata';
|
||||
import {ShadowDomStrategy, NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
||||
import {CONST} from 'angular2/src/facade/lang';
|
||||
import {If, Foreach} from 'angular2/directives';
|
||||
|
||||
|
||||
@Decorator({
|
||||
selector: 'someSelector'
|
||||
})
|
||||
class SomeDirective {
|
||||
}
|
||||
@Decorator({selector: 'someDecorator'})
|
||||
class SomeDecorator {}
|
||||
|
||||
@Component({selector: 'someComponent'})
|
||||
class SomeComponent {}
|
||||
|
||||
@Viewport({selector: 'someViewport'})
|
||||
class SomeViewport {}
|
||||
|
||||
class SomeDirectiveWithoutAnnotation {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'withoutDirectives'
|
||||
})
|
||||
class ComponentWithoutDirectives {}
|
||||
|
||||
@Component({
|
||||
selector: 'withDirectives',
|
||||
template: new TemplateConfig({
|
||||
directives: [ComponentWithoutDirectives]
|
||||
})
|
||||
})
|
||||
class ComponentWithDirectives {}
|
||||
|
||||
@Component({
|
||||
selector: 'withDirectivesTree',
|
||||
template: new TemplateConfig({
|
||||
directives: [[SomeDirective, [Foreach, If]], ComponentWithoutDirectives]
|
||||
})
|
||||
})
|
||||
class ComponentWithDirectivesTree {}
|
||||
|
||||
export function main() {
|
||||
describe("DirectiveMetadataReader", () => {
|
||||
var reader;
|
||||
|
@ -46,10 +28,22 @@ export function main() {
|
|||
reader = new DirectiveMetadataReader();
|
||||
});
|
||||
|
||||
it('should read out the annotation', () => {
|
||||
var directiveMetadata = reader.read(SomeDirective);
|
||||
it('should read out the Decorator annotation', () => {
|
||||
var directiveMetadata = reader.read(SomeDecorator);
|
||||
expect(directiveMetadata).toEqual(
|
||||
new DirectiveMetadata(SomeDirective, new Decorator({selector: 'someSelector'}), null));
|
||||
new DirectiveMetadata(SomeDecorator, new Decorator({selector: 'someDecorator'})));
|
||||
});
|
||||
|
||||
it('should read out the Viewport annotation', () => {
|
||||
var directiveMetadata = reader.read(SomeViewport);
|
||||
expect(directiveMetadata).toEqual(
|
||||
new DirectiveMetadata(SomeViewport, new Viewport({selector: 'someViewport'})));
|
||||
});
|
||||
|
||||
it('should read out the Component annotation', () => {
|
||||
var directiveMetadata = reader.read(SomeComponent);
|
||||
expect(directiveMetadata).toEqual(
|
||||
new DirectiveMetadata(SomeComponent, new Component({selector: 'someComponent'})));
|
||||
});
|
||||
|
||||
it('should throw if not matching annotation is found', () => {
|
||||
|
@ -57,22 +51,5 @@ export function main() {
|
|||
reader.read(SomeDirectiveWithoutAnnotation);
|
||||
}).toThrowError('No Directive annotation found on SomeDirectiveWithoutAnnotation');
|
||||
});
|
||||
|
||||
describe("componentDirectives", () => {
|
||||
it("should return an empty list when no directives specified", () => {
|
||||
var cmp = reader.read(ComponentWithoutDirectives);
|
||||
expect(cmp.componentDirectives).toEqual([]);
|
||||
});
|
||||
|
||||
it("should return a list of directives specified in the template config", () => {
|
||||
var cmp = reader.read(ComponentWithDirectives);
|
||||
expect(cmp.componentDirectives).toEqual([ComponentWithoutDirectives]);
|
||||
});
|
||||
|
||||
it("should return a list of directives specified in the template config as a tree", () => {
|
||||
var cmp = reader.read(ComponentWithDirectivesTree);
|
||||
expect(cmp.componentDirectives).toEqual([SomeDirective, Foreach, If, ComponentWithoutDirectives]);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import {describe, xit, it, expect, beforeEach, ddescribe, iit, el} from 'angular2/test_lib';
|
||||
|
||||
import {DOM} from 'angular2/src/facade/dom';
|
||||
import {Map, MapWrapper} from 'angular2/src/facade/collection';
|
||||
import {Type, isPresent} from 'angular2/src/facade/lang';
|
||||
|
||||
import {Injector} from 'angular2/di';
|
||||
import {Lexer, Parser, ChangeDetector, dynamicChangeDetection} from 'angular2/change_detection';
|
||||
|
@ -9,27 +11,27 @@ import {Compiler, CompilerCache} from 'angular2/src/core/compiler/compiler';
|
|||
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
||||
import {NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
||||
import {TemplateLoader} from 'angular2/src/core/compiler/template_loader';
|
||||
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
|
||||
import {BindingPropagationConfig} from 'angular2/src/core/compiler/binding_propagation_config';
|
||||
|
||||
import {Decorator, Component, Viewport} from 'angular2/src/core/annotations/annotations';
|
||||
import {TemplateConfig} from 'angular2/src/core/annotations/template_config';
|
||||
import {Template} from 'angular2/src/core/annotations/template';
|
||||
|
||||
import {ViewContainer} from 'angular2/src/core/compiler/view_container';
|
||||
import {MapWrapper} from 'angular2/src/facade/collection';
|
||||
|
||||
import {XHRMock} from 'angular2/src/mock/xhr_mock';
|
||||
|
||||
export function main() {
|
||||
describe('integration tests', function() {
|
||||
var compiler;
|
||||
var compiler, tplResolver;
|
||||
|
||||
beforeEach( () => {
|
||||
tplResolver = new FakeTemplateResolver();
|
||||
compiler = new Compiler(dynamicChangeDetection,
|
||||
new TemplateLoader(new XHRMock()),
|
||||
new TemplateLoader(null),
|
||||
new DirectiveMetadataReader(),
|
||||
new Parser(new Lexer()),
|
||||
new CompilerCache(),
|
||||
new NativeShadowDomStrategy()
|
||||
new NativeShadowDomStrategy(),
|
||||
tplResolver
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -43,7 +45,9 @@ export function main() {
|
|||
}
|
||||
|
||||
it('should consume text node changes', (done) => {
|
||||
compiler.compile(MyComp, el('<div>{{ctxProp}}</div>')).then((pv) => {
|
||||
tplResolver.setTemplate(MyComp, new Template({inline: '<div>{{ctxProp}}</div>'}));
|
||||
|
||||
compiler.compile(MyComp).then((pv) => {
|
||||
createView(pv);
|
||||
ctx.ctxProp = 'Hello World!';
|
||||
|
||||
|
@ -54,7 +58,9 @@ export function main() {
|
|||
});
|
||||
|
||||
it('should consume element binding changes', (done) => {
|
||||
compiler.compile(MyComp, el('<div [id]="ctxProp"></div>')).then((pv) => {
|
||||
tplResolver.setTemplate(MyComp, new Template({inline: '<div [id]="ctxProp"></div>'}));
|
||||
|
||||
compiler.compile(MyComp).then((pv) => {
|
||||
createView(pv);
|
||||
|
||||
ctx.ctxProp = 'Hello World!';
|
||||
|
@ -73,7 +79,9 @@ export function main() {
|
|||
'<div my-dir elprop="Hi {{\'there!\'}}"></div>' +
|
||||
'<div my-dir elprop="One more {{ctxProp}}"></div>' +
|
||||
'</div>'
|
||||
compiler.compile(MyComp, el(tpl)).then((pv) => {
|
||||
tplResolver.setTemplate(MyComp, new Template({inline: tpl, directives: [MyDir]}));
|
||||
|
||||
compiler.compile(MyComp).then((pv) => {
|
||||
createView(pv);
|
||||
|
||||
ctx.ctxProp = 'Hello World!';
|
||||
|
@ -88,7 +96,12 @@ export function main() {
|
|||
});
|
||||
|
||||
it('should support nested components.', (done) => {
|
||||
compiler.compile(MyComp, el('<child-cmp></child-cmp>')).then((pv) => {
|
||||
tplResolver.setTemplate(MyComp, new Template({
|
||||
inline: '<child-cmp></child-cmp>',
|
||||
directives: [ChildComp]
|
||||
}));
|
||||
|
||||
compiler.compile(MyComp).then((pv) => {
|
||||
createView(pv);
|
||||
|
||||
cd.detectChanges();
|
||||
|
@ -100,7 +113,13 @@ export function main() {
|
|||
|
||||
// GH issue 328 - https://github.com/angular/angular/issues/328
|
||||
it('should support different directive types on a single node', (done) => {
|
||||
compiler.compile(MyComp, el('<child-cmp my-dir [elprop]="ctxProp"></child-cmp>')).then((pv) => {
|
||||
tplResolver.setTemplate(MyComp,
|
||||
new Template({
|
||||
inline: '<child-cmp my-dir [elprop]="ctxProp"></child-cmp>',
|
||||
directives: [MyDir, ChildComp]
|
||||
}));
|
||||
|
||||
compiler.compile(MyComp).then((pv) => {
|
||||
createView(pv);
|
||||
|
||||
ctx.ctxProp = 'Hello World!';
|
||||
|
@ -115,7 +134,13 @@ export function main() {
|
|||
});
|
||||
|
||||
it('should support template directives via `<template>` elements.', (done) => {
|
||||
compiler.compile(MyComp, el('<div><template some-tmplate var-greeting="some-tmpl"><copy-me>{{greeting}}</copy-me></template></div>')).then((pv) => {
|
||||
tplResolver.setTemplate(MyComp,
|
||||
new Template({
|
||||
inline: '<div><template some-viewport var-greeting="some-tmpl"><copy-me>{{greeting}}</copy-me></template></div>',
|
||||
directives: [SomeViewport]
|
||||
}));
|
||||
|
||||
compiler.compile(MyComp).then((pv) => {
|
||||
createView(pv);
|
||||
|
||||
cd.detectChanges();
|
||||
|
@ -130,7 +155,12 @@ export function main() {
|
|||
});
|
||||
|
||||
it('should support template directives via `template` attribute.', (done) => {
|
||||
compiler.compile(MyComp, el('<div><copy-me template="some-tmplate: var greeting=some-tmpl">{{greeting}}</copy-me></div>')).then((pv) => {
|
||||
tplResolver.setTemplate(MyComp, new Template({
|
||||
inline: '<div><copy-me template="some-viewport: var greeting=some-tmpl">{{greeting}}</copy-me></div>',
|
||||
directives: [SomeViewport]
|
||||
}));
|
||||
|
||||
compiler.compile(MyComp).then((pv) => {
|
||||
createView(pv);
|
||||
|
||||
cd.detectChanges();
|
||||
|
@ -145,7 +175,12 @@ export function main() {
|
|||
});
|
||||
|
||||
it('should assign the component instance to a var-', (done) => {
|
||||
compiler.compile(MyComp, el('<p><child-cmp var-alice></child-cmp></p>')).then((pv) => {
|
||||
tplResolver.setTemplate(MyComp, new Template({
|
||||
inline: '<p><child-cmp var-alice></child-cmp></p>',
|
||||
directives: [ChildComp]
|
||||
}));
|
||||
|
||||
compiler.compile(MyComp).then((pv) => {
|
||||
createView(pv);
|
||||
|
||||
expect(view.contextWithLocals).not.toBe(null);
|
||||
|
@ -156,9 +191,12 @@ export function main() {
|
|||
});
|
||||
|
||||
it('should assign two component instances each with a var-', (done) => {
|
||||
var element = el('<p><child-cmp var-alice></child-cmp><child-cmp var-bob></p>');
|
||||
tplResolver.setTemplate(MyComp, new Template({
|
||||
inline: '<p><child-cmp var-alice></child-cmp><child-cmp var-bob></p>',
|
||||
directives: [ChildComp]
|
||||
}));
|
||||
|
||||
compiler.compile(MyComp, element).then((pv) => {
|
||||
compiler.compile(MyComp).then((pv) => {
|
||||
createView(pv);
|
||||
|
||||
expect(view.contextWithLocals).not.toBe(null);
|
||||
|
@ -171,7 +209,12 @@ export function main() {
|
|||
});
|
||||
|
||||
it('should assign the component instance to a var- with shorthand syntax', (done) => {
|
||||
compiler.compile(MyComp, el('<child-cmp #alice></child-cmp>')).then((pv) => {
|
||||
tplResolver.setTemplate(MyComp, new Template({
|
||||
inline: '<child-cmp #alice></child-cmp>',
|
||||
directives: [ChildComp]
|
||||
}));
|
||||
|
||||
compiler.compile(MyComp).then((pv) => {
|
||||
createView(pv);
|
||||
|
||||
expect(view.contextWithLocals).not.toBe(null);
|
||||
|
@ -182,13 +225,10 @@ export function main() {
|
|||
});
|
||||
|
||||
it('should assign the element instance to a user-defined variable', (done) => {
|
||||
// How is this supposed to work?
|
||||
var element = el('<p></p>');
|
||||
var div = el('<div var-alice></div>');
|
||||
DOM.appendChild(div, el('<i>Hello</i>'));
|
||||
DOM.appendChild(element, div);
|
||||
tplResolver.setTemplate(MyComp,
|
||||
new Template({inline: '<p><div var-alice><i>Hello</i></div></p>'}));
|
||||
|
||||
compiler.compile(MyComp, element).then((pv) => {
|
||||
compiler.compile(MyComp).then((pv) => {
|
||||
createView(pv);
|
||||
expect(view.contextWithLocals).not.toBe(null);
|
||||
|
||||
|
@ -201,7 +241,12 @@ export function main() {
|
|||
});
|
||||
|
||||
it('should provide binding configuration config to the component', (done) => {
|
||||
compiler.compile(MyComp, el('<push-cmp #cmp></push-cmp>')).then((pv) => {
|
||||
tplResolver.setTemplate(MyComp, new Template({
|
||||
inline: '<push-cmp #cmp></push-cmp>',
|
||||
directives: [[[PushBasedComp]]]
|
||||
}));
|
||||
|
||||
compiler.compile(MyComp).then((pv) => {
|
||||
createView(pv);
|
||||
|
||||
var cmp = view.contextWithLocals.get('cmp');
|
||||
|
@ -234,12 +279,8 @@ class MyDir {
|
|||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'push-cmp',
|
||||
template: new TemplateConfig({
|
||||
inline: '{{field}}'
|
||||
})
|
||||
})
|
||||
@Component({selector: 'push-cmp'})
|
||||
@Template({inline: '{{field}}'})
|
||||
class PushBasedComp {
|
||||
numberOfChecks:number;
|
||||
bpc:BindingPropagationConfig;
|
||||
|
@ -260,11 +301,7 @@ class PushBasedComp {
|
|||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
template: new TemplateConfig({
|
||||
directives: [MyDir, [[ChildComp], SomeViewport, PushBasedComp]]
|
||||
})
|
||||
})
|
||||
@Component()
|
||||
class MyComp {
|
||||
ctxProp:string;
|
||||
constructor() {
|
||||
|
@ -274,11 +311,11 @@ class MyComp {
|
|||
|
||||
@Component({
|
||||
selector: 'child-cmp',
|
||||
componentServices: [MyService],
|
||||
template: new TemplateConfig({
|
||||
directives: [MyDir],
|
||||
inline: '{{ctxProp}}'
|
||||
})
|
||||
componentServices: [MyService]
|
||||
})
|
||||
@Template({
|
||||
directives: [MyDir],
|
||||
inline: '{{ctxProp}}'
|
||||
})
|
||||
class ChildComp {
|
||||
ctxProp:string;
|
||||
|
@ -290,7 +327,7 @@ class ChildComp {
|
|||
}
|
||||
|
||||
@Viewport({
|
||||
selector: '[some-tmplate]'
|
||||
selector: '[some-viewport]'
|
||||
})
|
||||
class SomeViewport {
|
||||
constructor(container: ViewContainer) {
|
||||
|
@ -305,3 +342,26 @@ class MyService {
|
|||
this.greeting = 'hello';
|
||||
}
|
||||
}
|
||||
|
||||
class FakeTemplateResolver extends TemplateResolver {
|
||||
_cmpTemplates: Map;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._cmpTemplates = MapWrapper.create();
|
||||
}
|
||||
|
||||
setTemplate(component: Type, template: Template) {
|
||||
MapWrapper.set(this._cmpTemplates, component, template);
|
||||
}
|
||||
|
||||
resolve(component: Type): Template {
|
||||
var override = MapWrapper.get(this._cmpTemplates, component);
|
||||
|
||||
if (isPresent(override)) {
|
||||
return override;
|
||||
}
|
||||
|
||||
return super.resolve(component);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import {CompileControl} from 'angular2/src/core/compiler/pipeline/compile_contro
|
|||
import {DOM} from 'angular2/src/facade/dom';
|
||||
import {NativeShadowDomStrategy, ShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
||||
import {Component, Decorator, Viewport} from 'angular2/src/core/annotations/annotations';
|
||||
import {TemplateConfig} from 'angular2/src/core/annotations/template_config';
|
||||
import {Template} from 'angular2/src/core/annotations/template';
|
||||
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
||||
import {Lexer, Parser} from 'angular2/change_detection';
|
||||
|
||||
|
@ -235,19 +235,14 @@ class SomeViewport {}
|
|||
})
|
||||
class SomeViewport2 {}
|
||||
|
||||
@Component({
|
||||
selector: '[some-comp]'
|
||||
})
|
||||
@Component({selector: '[some-comp]'})
|
||||
class SomeComponent {}
|
||||
|
||||
@Component({
|
||||
selector: '[some-comp2]'
|
||||
})
|
||||
@Component({selector: '[some-comp2]'})
|
||||
class SomeComponent2 {}
|
||||
|
||||
@Component({
|
||||
template: new TemplateConfig({
|
||||
@Component()
|
||||
@Template({
|
||||
directives: [SomeDecorator, SomeViewport, SomeViewport2, SomeComponent, SomeComponent2]
|
||||
})
|
||||
})
|
||||
class MyComp {}
|
||||
|
|
|
@ -405,9 +405,7 @@ class SomeViewportDirectiveWithBinding {
|
|||
class SomeComponentDirective {
|
||||
}
|
||||
|
||||
@Component({
|
||||
bind: {'boundprop3': 'compProp'}
|
||||
})
|
||||
@Component({bind: {'boundprop3': 'compProp'}})
|
||||
class SomeComponentDirectiveWithBinding {
|
||||
compProp;
|
||||
constructor() {
|
||||
|
|
|
@ -14,7 +14,7 @@ export function main() {
|
|||
describe('ShadowDomTransformer', () => {
|
||||
function createPipeline(selector, strategy:ShadowDomStrategy, styleHost) {
|
||||
var component = new Component({selector: selector});
|
||||
var meta = new DirectiveMetadata(null, component, null);
|
||||
var meta = new DirectiveMetadata(null, component);
|
||||
var transformer = new ShadowDomTransformer(meta, strategy, styleHost);
|
||||
transformer.clearCache();
|
||||
return new CompilePipeline([transformer]);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import {describe, xit, it, expect, beforeEach, ddescribe, iit, el} from 'angular2/test_lib';
|
||||
|
||||
import {DOM} from 'angular2/src/facade/dom';
|
||||
import {StringMapWrapper, MapWrapper, List} from 'angular2/src/facade/collection';
|
||||
import {isPresent, Type} from 'angular2/src/facade/lang';
|
||||
|
||||
import {Injector} from 'angular2/di';
|
||||
import {Lexer, Parser, ChangeDetector, dynamicChangeDetection} from 'angular2/change_detection';
|
||||
|
@ -12,14 +14,12 @@ import {ShadowDomStrategy,
|
|||
NativeShadowDomStrategy,
|
||||
EmulatedShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
||||
import {TemplateLoader} from 'angular2/src/core/compiler/template_loader';
|
||||
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
|
||||
|
||||
import {Decorator, Component, Viewport} from 'angular2/src/core/annotations/annotations';
|
||||
import {TemplateConfig} from 'angular2/src/core/annotations/template_config';
|
||||
import {Template} from 'angular2/src/core/annotations/template';
|
||||
|
||||
import {ViewContainer} from 'angular2/src/core/compiler/view_container';
|
||||
import {StringMapWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
||||
|
||||
import {XHRMock} from 'angular2/src/mock/xhr_mock';
|
||||
|
||||
export function main() {
|
||||
describe('integration tests', function() {
|
||||
|
@ -31,22 +31,28 @@ export function main() {
|
|||
(strategy, name) => {
|
||||
|
||||
describe(`${name} shadow dom strategy`, () => {
|
||||
var compiler;
|
||||
var compiler, tplResolver;
|
||||
|
||||
beforeEach( () => {
|
||||
beforeEach(() => {
|
||||
tplResolver = new FakeTemplateResolver();
|
||||
compiler = new Compiler(dynamicChangeDetection,
|
||||
new TemplateLoader(new XHRMock()),
|
||||
new TemplateLoader(null),
|
||||
new DirectiveMetadataReader(),
|
||||
new Parser(new Lexer()),
|
||||
new CompilerCache(),
|
||||
strategy
|
||||
strategy,
|
||||
tplResolver
|
||||
);
|
||||
});
|
||||
|
||||
function compile(template, assertions) {
|
||||
compiler.compile(MyComp, el(template)).
|
||||
then(createView).
|
||||
then((view) => {
|
||||
function compile(template, directives: List<Type>, assertions) {
|
||||
tplResolver.setTemplate(MyComp, new Template({
|
||||
inline: template,
|
||||
directives: directives
|
||||
}));
|
||||
compiler.compile(MyComp)
|
||||
.then(createView)
|
||||
.then((view) => {
|
||||
var lc = new LifeCycle(view.changeDetector, false);
|
||||
assertions(view, lc);
|
||||
});
|
||||
|
@ -59,7 +65,7 @@ export function main() {
|
|||
'<div class="left">A</div>' +
|
||||
'</multiple-content-tags>';
|
||||
|
||||
compile(temp, (view, lc) => {
|
||||
compile(temp, [MultipleContentTagsComponent], (view, lc) => {
|
||||
expect(view.nodes).toHaveText('(A, BC)');
|
||||
done();
|
||||
});
|
||||
|
@ -71,7 +77,7 @@ export function main() {
|
|||
'<div>C</div>' +
|
||||
'</multiple-content-tags>';
|
||||
|
||||
compile(temp, (view, lc) => {
|
||||
compile(temp, [MultipleContentTagsComponent], (view, lc) => {
|
||||
expect(view.nodes).toHaveText('(, BAC)');
|
||||
done();
|
||||
});
|
||||
|
@ -83,7 +89,7 @@ export function main() {
|
|||
'<div>B</div>' +
|
||||
'</multiple-content-tags>';
|
||||
|
||||
compile(temp, (view, lc) => {
|
||||
compile(temp, [MultipleContentTagsComponent, ManualViewportDirective], (view, lc) => {
|
||||
var dir = view.elementInjectors[1].get(ManualViewportDirective);
|
||||
|
||||
expect(view.nodes).toHaveText('(, B)');
|
||||
|
@ -108,7 +114,7 @@ export function main() {
|
|||
'<div>B</div>' +
|
||||
'</multiple-content-tags>';
|
||||
|
||||
compile(temp, (view, lc) => {
|
||||
compile(temp, [MultipleContentTagsComponent, ManualViewportDirective], (view, lc) => {
|
||||
var dir = view.elementInjectors[1].get(ManualViewportDirective);
|
||||
|
||||
expect(view.nodes).toHaveText('(, B)');
|
||||
|
@ -133,7 +139,7 @@ export function main() {
|
|||
'<div>B</div>' +
|
||||
'</outer-with-indirect-nested>';
|
||||
|
||||
compile(temp, (view, lc) => {
|
||||
compile(temp, [OuterWithIndirectNestedComponent], (view, lc) => {
|
||||
expect(view.nodes).toHaveText('OUTER(SIMPLE(AB))');
|
||||
|
||||
done();
|
||||
|
@ -147,7 +153,7 @@ export function main() {
|
|||
'<div>C</div>' +
|
||||
'</outer>';
|
||||
|
||||
compile(temp, (view, lc) => {
|
||||
compile(temp, [OuterComponent, ManualViewportDirective], (view, lc) => {
|
||||
var dir = view.elementInjectors[1].get(ManualViewportDirective);
|
||||
|
||||
expect(view.nodes).toHaveText('OUTER(INNER(INNERINNER(,BC)))');
|
||||
|
@ -257,31 +263,23 @@ class AutoViewportDirective {
|
|||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'simple',
|
||||
template: new TemplateConfig({
|
||||
inline: 'SIMPLE(<content></content>)'
|
||||
})
|
||||
})
|
||||
@Component({selector: 'simple'})
|
||||
@Template({inline: 'SIMPLE(<content></content>)'})
|
||||
class Simple {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'multiple-content-tags',
|
||||
template: new TemplateConfig({
|
||||
inline: '(<content select=".left"></content>, <content></content>)'
|
||||
})
|
||||
@Component({selector: 'multiple-content-tags'})
|
||||
@Template({
|
||||
inline: '(<content select=".left"></content>, <content></content>)'
|
||||
})
|
||||
class MultipleContentTagsComponent {
|
||||
}
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'conditional-content',
|
||||
template: new TemplateConfig({
|
||||
inline: '<div>(<div template="auto: cond"><content select=".left"></content></div>, <content></content>)</div>',
|
||||
directives: [AutoViewportDirective]
|
||||
})
|
||||
@Component({selector: 'conditional-content'})
|
||||
@Template({
|
||||
inline: '<div>(<div template="auto: cond"><content select=".left"></content></div>, <content></content>)</div>',
|
||||
directives: [AutoViewportDirective]
|
||||
})
|
||||
class ConditionalContentComponent {
|
||||
cond:boolean;
|
||||
|
@ -294,52 +292,42 @@ class ConditionalContentComponent {
|
|||
hideLeft() { this.cond = false; }
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'outer-with-indirect-nested',
|
||||
template: new TemplateConfig({
|
||||
inline: 'OUTER(<simple><div><content></content></div></simple>)',
|
||||
directives: [Simple]
|
||||
})
|
||||
@Component({selector: 'outer-with-indirect-nested'})
|
||||
@Template({
|
||||
inline: 'OUTER(<simple><div><content></content></div></simple>)',
|
||||
directives: [Simple]
|
||||
})
|
||||
class OuterWithIndirectNestedComponent {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'outer',
|
||||
template: new TemplateConfig({
|
||||
inline: 'OUTER(<inner><content></content></inner>)',
|
||||
directives: [InnerComponent]
|
||||
})
|
||||
@Component({selector: 'outer'})
|
||||
@Template({
|
||||
inline: 'OUTER(<inner><content></content></inner>)',
|
||||
directives: [InnerComponent]
|
||||
})
|
||||
class OuterComponent {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'inner',
|
||||
template: new TemplateConfig({
|
||||
inline: 'INNER(<innerinner><content></content></innerinner>)',
|
||||
directives: [InnerInnerComponent]
|
||||
})
|
||||
@Component({selector: 'inner'})
|
||||
@Template({
|
||||
inline: 'INNER(<innerinner><content></content></innerinner>)',
|
||||
directives: [InnerInnerComponent]
|
||||
})
|
||||
class InnerComponent {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'innerinner',
|
||||
template: new TemplateConfig({
|
||||
inline: 'INNERINNER(<content select=".left"></content>,<content></content>)'
|
||||
})
|
||||
@Component({selector: 'innerinner'})
|
||||
@Template({
|
||||
inline: 'INNERINNER(<content select=".left"></content>,<content></content>)'
|
||||
})
|
||||
class InnerInnerComponent {
|
||||
}
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'my-comp',
|
||||
template: new TemplateConfig({
|
||||
directives: [MultipleContentTagsComponent, ManualViewportDirective,
|
||||
ConditionalContentComponent, OuterWithIndirectNestedComponent, OuterComponent]
|
||||
})
|
||||
@Component({selector: 'my-comp'})
|
||||
@Template({
|
||||
directives: [MultipleContentTagsComponent, ManualViewportDirective,
|
||||
ConditionalContentComponent, OuterWithIndirectNestedComponent, OuterComponent]
|
||||
})
|
||||
class MyComp {
|
||||
}
|
||||
|
@ -349,3 +337,26 @@ function createView(pv) {
|
|||
view.hydrate(new Injector([]), null, {});
|
||||
return view;
|
||||
}
|
||||
|
||||
class FakeTemplateResolver extends TemplateResolver {
|
||||
_cmpTemplates: Map;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._cmpTemplates = MapWrapper.create();
|
||||
}
|
||||
|
||||
setTemplate(component: Type, template: Template) {
|
||||
MapWrapper.set(this._cmpTemplates, component, template);
|
||||
}
|
||||
|
||||
resolve(component: Type): Template {
|
||||
var override = MapWrapper.get(this._cmpTemplates, component);
|
||||
|
||||
if (isPresent(override)) {
|
||||
return override;
|
||||
}
|
||||
|
||||
return super.resolve(component);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
import {describe, it, expect, beforeEach, ddescribe, iit, xit, el} from 'angular2/test_lib';
|
||||
|
||||
import {TemplateLoader} from 'angular2/src/core/compiler/template_loader';
|
||||
import {Component} from 'angular2/src/core/annotations/annotations';
|
||||
import {TemplateConfig} from 'angular2/src/core/annotations/template_config';
|
||||
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
|
||||
import {DirectiveMetadata} from 'angular2/src/core/compiler/directive_metadata';
|
||||
|
||||
import {Component} from 'angular2/src/core/annotations/annotations';
|
||||
import {Template} from 'angular2/src/core/annotations/template';
|
||||
|
||||
import {PromiseWrapper} from 'angular2/src/facade/async';
|
||||
import {Type, stringify, isPresent} from 'angular2/src/facade/lang';
|
||||
import {Map, MapWrapper} from 'angular2/src/facade/collection';
|
||||
|
||||
import {XHRMock} from 'angular2/src/mock/xhr_mock';
|
||||
|
||||
|
@ -17,25 +22,16 @@ export function main() {
|
|||
loader = new TemplateLoader(xhr);
|
||||
});
|
||||
|
||||
function createMetadata({inline = null, url = null}={}) {
|
||||
var config = new TemplateConfig({url: url, inline: inline});
|
||||
var component = new Component({template: config});
|
||||
return new DirectiveMetadata(FakeComponent, component, null);
|
||||
}
|
||||
|
||||
it('should load inline templates synchronously', () => {
|
||||
var template = 'inline template';
|
||||
var md = createMetadata({inline: template});
|
||||
expect(loader.load(md).content).toHaveText(template);
|
||||
var template = new Template({inline: 'inline template'});
|
||||
expect(loader.load(template).content).toHaveText('inline template');
|
||||
});
|
||||
|
||||
it('should load templates through XHR', (done) => {
|
||||
var url = '/foo';
|
||||
var template = 'xhr template';
|
||||
xhr.expect(url, template);
|
||||
var md = createMetadata({url: '/foo'});
|
||||
loader.load(md).then((el) => {
|
||||
expect(el.content).toHaveText(template);
|
||||
xhr.expect('/foo', 'xhr template');
|
||||
var template = new Template({url: '/foo'});
|
||||
loader.load(template).then((el) => {
|
||||
expect(el.content).toHaveText('xhr template');
|
||||
done();
|
||||
});
|
||||
xhr.flush();
|
||||
|
@ -43,34 +39,31 @@ export function main() {
|
|||
|
||||
it('should cache template loaded through XHR', (done) => {
|
||||
var firstEl;
|
||||
var url = '/foo';
|
||||
var template = 'xhr template';
|
||||
xhr.expect(url, template);
|
||||
var md = createMetadata({url: '/foo'});
|
||||
loader.load(md)
|
||||
xhr.expect('/foo', 'xhr template');
|
||||
var template = new Template({url: '/foo'});
|
||||
loader.load(template)
|
||||
.then((el) => {
|
||||
firstEl = el;
|
||||
return loader.load(md);
|
||||
return loader.load(template);
|
||||
})
|
||||
.then((el) =>{
|
||||
expect(el).toBe(firstEl);
|
||||
expect(el.content).toHaveText(template);
|
||||
expect(el.content).toHaveText('xhr template');
|
||||
done();
|
||||
});
|
||||
xhr.flush();
|
||||
});
|
||||
|
||||
it('should throw when no template is defined', () => {
|
||||
var md = createMetadata();
|
||||
expect(() => loader.load(md))
|
||||
.toThrowError('No template configured for component FakeComponent');
|
||||
var template = new Template({inline: null, url: null});
|
||||
expect(() => loader.load(template))
|
||||
.toThrowError('Templates should have either their url or inline property set');
|
||||
});
|
||||
|
||||
it('should return a rejected Promise when xhr loading fails', (done) => {
|
||||
var url = '/foo';
|
||||
xhr.expect(url, null);
|
||||
var md = createMetadata({url: '/foo'});
|
||||
PromiseWrapper.then(loader.load(md),
|
||||
xhr.expect('/foo', null);
|
||||
var template = new Template({url: '/foo'});
|
||||
PromiseWrapper.then(loader.load(template),
|
||||
function(_) { throw 'Unexpected response'; },
|
||||
function(error) {
|
||||
expect(error).toEqual('Failed to load /foo');
|
||||
|
@ -83,5 +76,5 @@ export function main() {
|
|||
});
|
||||
}
|
||||
|
||||
class FakeComponent {
|
||||
class SomeComponent {
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_meta
|
|||
import {Component, Decorator, Viewport, Directive, onChange} from 'angular2/src/core/annotations/annotations';
|
||||
import {Lexer, Parser, DynamicProtoChangeDetector,
|
||||
ChangeDetector} from 'angular2/change_detection';
|
||||
import {TemplateConfig} from 'angular2/src/core/annotations/template_config';
|
||||
import {Template} from 'angular2/src/core/annotations/template';
|
||||
import {EventEmitter} from 'angular2/src/core/annotations/events';
|
||||
import {List, MapWrapper} from 'angular2/src/facade/collection';
|
||||
import {DOM, Element} from 'angular2/src/facade/dom';
|
||||
|
@ -649,9 +649,7 @@ class DirectiveImplementingOnChange {
|
|||
|
||||
class SomeService {}
|
||||
|
||||
@Component({
|
||||
componentServices: [SomeService]
|
||||
})
|
||||
@Component({componentServices: [SomeService]})
|
||||
class SomeComponent {
|
||||
service: SomeService;
|
||||
constructor(service: SomeService) {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import {describe, xit, it, expect, beforeEach, ddescribe, iit, el} from 'angular2/test_lib';
|
||||
|
||||
import {DOM} from 'angular2/src/facade/dom';
|
||||
import {Map, MapWrapper, ListWrapper} from 'angular2/src/facade/collection';
|
||||
import {Type, isPresent} from 'angular2/src/facade/lang';
|
||||
|
||||
import {Injector} from 'angular2/di';
|
||||
import {Lexer, Parser, ChangeDetector, dynamicChangeDetection} from 'angular2/change_detection';
|
||||
|
@ -8,20 +10,23 @@ import {Lexer, Parser, ChangeDetector, dynamicChangeDetection} from 'angular2/ch
|
|||
import {Compiler, CompilerCache} from 'angular2/src/core/compiler/compiler';
|
||||
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
||||
import {NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
||||
import {TemplateLoader} from 'angular2/src/core/compiler/template_loader';
|
||||
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
|
||||
|
||||
import {Decorator, Component, Viewport} from 'angular2/src/core/annotations/annotations';
|
||||
import {TemplateConfig} from 'angular2/src/core/annotations/template_config';
|
||||
import {Template} from 'angular2/src/core/annotations/template';
|
||||
|
||||
import {ViewContainer} from 'angular2/src/core/compiler/view_container';
|
||||
import {MapWrapper, ListWrapper} from 'angular2/src/facade/collection';
|
||||
import {Foreach} from 'angular2/src/directives/foreach';
|
||||
|
||||
export function main() {
|
||||
describe('foreach', () => {
|
||||
var view, cd, compiler, component;
|
||||
var view, cd, compiler, component, tplResolver;
|
||||
beforeEach(() => {
|
||||
compiler = new Compiler(dynamicChangeDetection, null, new DirectiveMetadataReader(),
|
||||
new Parser(new Lexer()), new CompilerCache(), new NativeShadowDomStrategy());
|
||||
tplResolver = new FakeTemplateResolver();
|
||||
compiler = new Compiler(dynamicChangeDetection, new TemplateLoader(null),
|
||||
new DirectiveMetadataReader(), new Parser(new Lexer()), new CompilerCache(),
|
||||
new NativeShadowDomStrategy(), tplResolver);
|
||||
});
|
||||
|
||||
function createView(pv) {
|
||||
|
@ -31,8 +36,13 @@ export function main() {
|
|||
cd = view.changeDetector;
|
||||
}
|
||||
|
||||
function compileWithTemplate(template) {
|
||||
return compiler.compile(TestComponent, el(template));
|
||||
function compileWithTemplate(html) {
|
||||
var template = new Template({
|
||||
inline: html,
|
||||
directives: [Foreach]
|
||||
});
|
||||
tplResolver.setTemplate(TestComponent, template);
|
||||
return compiler.compile(TestComponent);
|
||||
}
|
||||
|
||||
var TEMPLATE = '<div><copy-me template="foreach #item in items">{{item.toString()}};</copy-me></div>';
|
||||
|
@ -217,13 +227,7 @@ class Foo {
|
|||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'test-cmp',
|
||||
template: new TemplateConfig({
|
||||
inline: '', // each test swaps with a custom template.
|
||||
directives: [Foreach]
|
||||
})
|
||||
})
|
||||
@Component({selector: 'test-cmp'})
|
||||
class TestComponent {
|
||||
items: any;
|
||||
item: any;
|
||||
|
@ -231,3 +235,26 @@ class TestComponent {
|
|||
this.items = [1, 2];
|
||||
}
|
||||
}
|
||||
|
||||
class FakeTemplateResolver extends TemplateResolver {
|
||||
_cmpTemplates: Map;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._cmpTemplates = MapWrapper.create();
|
||||
}
|
||||
|
||||
setTemplate(component: Type, template: Template) {
|
||||
MapWrapper.set(this._cmpTemplates, component, template);
|
||||
}
|
||||
|
||||
resolve(component: Type): Template {
|
||||
var override = MapWrapper.get(this._cmpTemplates, component);
|
||||
|
||||
if (isPresent(override)) {
|
||||
return override;
|
||||
}
|
||||
|
||||
return super.resolve(component);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import {describe, xit, it, expect, beforeEach, ddescribe, iit, el, IS_DARTIUM} from 'angular2/test_lib';
|
||||
|
||||
import {DOM} from 'angular2/src/facade/dom';
|
||||
import {Map, MapWrapper} from 'angular2/src/facade/collection';
|
||||
import {Type, isPresent} from 'angular2/src/facade/lang';
|
||||
|
||||
import {Injector} from 'angular2/di';
|
||||
import {Lexer, Parser, ChangeDetector, dynamicChangeDetection} from 'angular2/change_detection';
|
||||
|
@ -8,18 +10,23 @@ import {Lexer, Parser, ChangeDetector, dynamicChangeDetection} from 'angular2/ch
|
|||
import {Compiler, CompilerCache} from 'angular2/src/core/compiler/compiler';
|
||||
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
||||
import {NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
||||
import {TemplateLoader} from 'angular2/src/core/compiler/template_loader';
|
||||
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
|
||||
|
||||
import {Component} from 'angular2/src/core/annotations/annotations';
|
||||
import {TemplateConfig} from 'angular2/src/core/annotations/template_config';
|
||||
import {Template} from 'angular2/src/core/annotations/template';
|
||||
|
||||
import {If} from 'angular2/src/directives/if';
|
||||
|
||||
export function main() {
|
||||
describe('if directive', () => {
|
||||
var view, cd, compiler, component;
|
||||
var view, cd, compiler, component, tplResolver;
|
||||
|
||||
beforeEach(() => {
|
||||
compiler = new Compiler(dynamicChangeDetection, null, new DirectiveMetadataReader(),
|
||||
new Parser(new Lexer()), new CompilerCache(), new NativeShadowDomStrategy());
|
||||
tplResolver = new FakeTemplateResolver();
|
||||
compiler = new Compiler(dynamicChangeDetection, new TemplateLoader(null),
|
||||
new DirectiveMetadataReader(), new Parser(new Lexer()), new CompilerCache(),
|
||||
new NativeShadowDomStrategy(), tplResolver);
|
||||
});
|
||||
|
||||
function createView(pv) {
|
||||
|
@ -29,8 +36,13 @@ export function main() {
|
|||
cd = view.changeDetector;
|
||||
}
|
||||
|
||||
function compileWithTemplate(template) {
|
||||
return compiler.compile(TestComponent, el(template));
|
||||
function compileWithTemplate(html) {
|
||||
var template = new Template({
|
||||
inline: html,
|
||||
directives: [If]
|
||||
});
|
||||
tplResolver.setTemplate(TestComponent, template);
|
||||
return compiler.compile(TestComponent);
|
||||
}
|
||||
|
||||
it('should work in a template attribute', (done) => {
|
||||
|
@ -188,13 +200,7 @@ export function main() {
|
|||
});
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'test-cmp',
|
||||
template: new TemplateConfig({
|
||||
inline: '', // each test swaps with a custom template.
|
||||
directives: [If]
|
||||
})
|
||||
})
|
||||
@Component({selector: 'test-cmp'})
|
||||
class TestComponent {
|
||||
booleanCondition: boolean;
|
||||
numberCondition: number;
|
||||
|
@ -213,3 +219,26 @@ class TestComponent {
|
|||
this.nullCondition = null;
|
||||
}
|
||||
}
|
||||
|
||||
class FakeTemplateResolver extends TemplateResolver {
|
||||
_cmpTemplates: Map;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._cmpTemplates = MapWrapper.create();
|
||||
}
|
||||
|
||||
setTemplate(component: Type, template: Template) {
|
||||
MapWrapper.set(this._cmpTemplates, component, template);
|
||||
}
|
||||
|
||||
resolve(component: Type): Template {
|
||||
var override = MapWrapper.get(this._cmpTemplates, component);
|
||||
|
||||
if (isPresent(override)) {
|
||||
return override;
|
||||
}
|
||||
|
||||
return super.resolve(component);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +1,27 @@
|
|||
import {describe, xit, it, expect, beforeEach, ddescribe, iit, el} from 'angular2/test_lib';
|
||||
import {DOM} from 'angular2/src/facade/dom';
|
||||
import {Map, MapWrapper} from 'angular2/src/facade/collection';
|
||||
import {Type, isPresent} from 'angular2/src/facade/lang';
|
||||
import {Injector} from 'angular2/di';
|
||||
import {Lexer, Parser, ChangeDetector, dynamicChangeDetection} from 'angular2/change_detection';
|
||||
import {Compiler, CompilerCache} from 'angular2/src/core/compiler/compiler';
|
||||
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
||||
import {NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
||||
import {Decorator, Component} from 'angular2/src/core/annotations/annotations';
|
||||
import {TemplateConfig} from 'angular2/src/core/annotations/template_config';
|
||||
import {Template} from 'angular2/src/core/annotations/template';
|
||||
import {TemplateLoader} from 'angular2/src/core/compiler/template_loader';
|
||||
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
|
||||
import {NgElement} from 'angular2/src/core/dom/element';
|
||||
import {NonBindable} from 'angular2/src/directives/non_bindable';
|
||||
|
||||
export function main() {
|
||||
describe('non-bindable', () => {
|
||||
var view, cd, compiler, component;
|
||||
var view, cd, compiler, component, tplResolver;
|
||||
beforeEach(() => {
|
||||
compiler = new Compiler(dynamicChangeDetection,
|
||||
null, new DirectiveMetadataReader(), new Parser(new Lexer()), new CompilerCache(), new NativeShadowDomStrategy());
|
||||
tplResolver = new FakeTemplateResolver();
|
||||
compiler = new Compiler(dynamicChangeDetection, new TemplateLoader(null),
|
||||
new DirectiveMetadataReader(), new Parser(new Lexer()), new CompilerCache(),
|
||||
new NativeShadowDomStrategy(), tplResolver);
|
||||
});
|
||||
|
||||
function createView(pv) {
|
||||
|
@ -25,8 +31,13 @@ export function main() {
|
|||
cd = view.changeDetector;
|
||||
}
|
||||
|
||||
function compileWithTemplate(template) {
|
||||
return compiler.compile(TestComponent, el(template));
|
||||
function compileWithTemplate(html) {
|
||||
var template = new Template({
|
||||
inline: html,
|
||||
directives: [NonBindable, TestDecorator]
|
||||
});
|
||||
tplResolver.setTemplate(TestComponent, template);
|
||||
return compiler.compile(TestComponent);
|
||||
}
|
||||
|
||||
it('should not interpolate children', (done) => {
|
||||
|
@ -63,13 +74,7 @@ export function main() {
|
|||
})
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'test-cmp',
|
||||
template: new TemplateConfig({
|
||||
inline: '', // each test swaps with a custom template.
|
||||
directives: [NonBindable, TestDecorator]
|
||||
})
|
||||
})
|
||||
@Component({selector: 'test-cmp'})
|
||||
class TestComponent {
|
||||
text: string;
|
||||
constructor() {
|
||||
|
@ -85,3 +90,26 @@ class TestDecorator {
|
|||
DOM.addClass(el.domElement, 'compiled');
|
||||
}
|
||||
}
|
||||
|
||||
class FakeTemplateResolver extends TemplateResolver {
|
||||
_cmpTemplates: Map;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._cmpTemplates = MapWrapper.create();
|
||||
}
|
||||
|
||||
setTemplate(component: Type, template: Template) {
|
||||
MapWrapper.set(this._cmpTemplates, component, template);
|
||||
}
|
||||
|
||||
resolve(component: Type): Template {
|
||||
var override = MapWrapper.get(this._cmpTemplates, component);
|
||||
|
||||
if (isPresent(override)) {
|
||||
return override;
|
||||
}
|
||||
|
||||
return super.resolve(component);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +1,26 @@
|
|||
import {describe, xit, it, expect, beforeEach, ddescribe, iit, el} from 'angular2/test_lib';
|
||||
import {DOM} from 'angular2/src/facade/dom';
|
||||
import {Map, MapWrapper} from 'angular2/src/facade/collection';
|
||||
import {Type, isPresent} from 'angular2/src/facade/lang';
|
||||
import {Injector} from 'angular2/di';
|
||||
import {Lexer, Parser, dynamicChangeDetection} from 'angular2/change_detection';
|
||||
import {Compiler, CompilerCache} from 'angular2/src/core/compiler/compiler';
|
||||
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
||||
import {NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
||||
import {Component} from 'angular2/src/core/annotations/annotations';
|
||||
import {TemplateConfig} from 'angular2/src/core/annotations/template_config';
|
||||
import {Template} from 'angular2/src/core/annotations/template';
|
||||
import {TemplateLoader} from 'angular2/core';
|
||||
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
|
||||
import {Switch, SwitchWhen, SwitchDefault} from 'angular2/src/directives/switch';
|
||||
|
||||
export function main() {
|
||||
describe('switch', () => {
|
||||
var view, cd, compiler, component;
|
||||
var view, cd, compiler, component, tplResolver;
|
||||
beforeEach(() => {
|
||||
compiler = new Compiler(dynamicChangeDetection, null, new DirectiveMetadataReader(),
|
||||
new Parser(new Lexer()), new CompilerCache(), new NativeShadowDomStrategy());
|
||||
tplResolver = new FakeTemplateResolver();
|
||||
compiler = new Compiler(dynamicChangeDetection, new TemplateLoader(null),
|
||||
new DirectiveMetadataReader(), new Parser(new Lexer()), new CompilerCache(),
|
||||
new NativeShadowDomStrategy(), tplResolver);
|
||||
});
|
||||
|
||||
function createView(pv) {
|
||||
|
@ -24,8 +30,13 @@ export function main() {
|
|||
cd = view.changeDetector;
|
||||
}
|
||||
|
||||
function compileWithTemplate(template) {
|
||||
return compiler.compile(TestComponent, el(template));
|
||||
function compileWithTemplate(html) {
|
||||
var template = new Template({
|
||||
inline: html,
|
||||
directives: [Switch, SwitchWhen, SwitchDefault]
|
||||
});
|
||||
tplResolver.setTemplate(TestComponent, template);
|
||||
return compiler.compile(TestComponent);
|
||||
}
|
||||
|
||||
describe('switch value changes', () => {
|
||||
|
@ -143,13 +154,7 @@ export function main() {
|
|||
});
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'test-cmp',
|
||||
template: new TemplateConfig({
|
||||
inline: '', // each test swaps with a custom template.
|
||||
directives: [Switch, SwitchWhen, SwitchDefault]
|
||||
})
|
||||
})
|
||||
@Component({selector: 'test-cmp'})
|
||||
class TestComponent {
|
||||
switchValue: any;
|
||||
when1: any;
|
||||
|
@ -161,3 +166,26 @@ class TestComponent {
|
|||
this.when2 = null;
|
||||
}
|
||||
}
|
||||
|
||||
class FakeTemplateResolver extends TemplateResolver {
|
||||
_cmpTemplates: Map;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._cmpTemplates = MapWrapper.create();
|
||||
}
|
||||
|
||||
setTemplate(component: Type, template: Template) {
|
||||
MapWrapper.set(this._cmpTemplates, component, template);
|
||||
}
|
||||
|
||||
resolve(component: Type): Template {
|
||||
var override = MapWrapper.get(this._cmpTemplates, component);
|
||||
|
||||
if (isPresent(override)) {
|
||||
return override;
|
||||
}
|
||||
|
||||
return super.resolve(component);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,31 +5,44 @@ import {Lexer, Parser, ChangeDetector, dynamicChangeDetection} from 'angular2/ch
|
|||
import {Compiler, CompilerCache} from 'angular2/src/core/compiler/compiler';
|
||||
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
||||
import {NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
||||
import {Injector} from 'angular2/di';
|
||||
import {DOM} from 'angular2/src/facade/dom';
|
||||
import {TemplateLoader} from 'angular2/src/core/compiler/template_loader';
|
||||
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
|
||||
|
||||
import {Component, Decorator, TemplateConfig} from 'angular2/core';
|
||||
import {Injector} from 'angular2/di';
|
||||
|
||||
import {DOM} from 'angular2/src/facade/dom';
|
||||
import {Map, MapWrapper} from 'angular2/src/facade/collection';
|
||||
import {Type, isPresent} from 'angular2/src/facade/lang';
|
||||
|
||||
import {Component, Decorator, Template} from 'angular2/core';
|
||||
import {ControlGroupDirective, ControlNameDirective,
|
||||
ControlDirective, NewControlGroupDirective,
|
||||
Control, ControlGroup, ControlValueAccessor} from 'angular2/forms';
|
||||
|
||||
import {TemplateLoader} from 'angular2/src/core/compiler/template_loader';
|
||||
import {XHRMock} from 'angular2/src/mock/xhr_mock';
|
||||
|
||||
export function main() {
|
||||
function detectChanges(view) {
|
||||
view.changeDetector.detectChanges();
|
||||
}
|
||||
|
||||
function compile(componentType, template, context, callback) {
|
||||
var tplResolver = new FakeTemplateResolver();
|
||||
|
||||
var compiler = new Compiler(dynamicChangeDetection,
|
||||
new TemplateLoader(new XHRMock()),
|
||||
new TemplateLoader(null),
|
||||
new DirectiveMetadataReader(),
|
||||
new Parser(new Lexer()),
|
||||
new CompilerCache(),
|
||||
new NativeShadowDomStrategy());
|
||||
new NativeShadowDomStrategy(),
|
||||
tplResolver
|
||||
);
|
||||
|
||||
compiler.compile(componentType, el(template)).then((pv) => {
|
||||
tplResolver.setTemplate(componentType, new Template({
|
||||
inline: template,
|
||||
directives: [ControlGroupDirective, ControlNameDirective, ControlDirective,
|
||||
NewControlGroupDirective, WrappedValue]
|
||||
}));
|
||||
|
||||
compiler.compile(componentType).then((pv) => {
|
||||
var view = pv.instantiate(null, null);
|
||||
view.hydrate(new Injector([]), null, context);
|
||||
detectChanges(view);
|
||||
|
@ -198,14 +211,7 @@ export function main() {
|
|||
});
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: "my-comp",
|
||||
template: new TemplateConfig({
|
||||
inline: "",
|
||||
directives: [ControlGroupDirective, ControlNameDirective,
|
||||
ControlDirective, NewControlGroupDirective, WrappedValue]
|
||||
})
|
||||
})
|
||||
@Component({selector: "my-comp"})
|
||||
class MyComp {
|
||||
form:ControlGroup;
|
||||
name:string;
|
||||
|
@ -233,4 +239,27 @@ class WrappedValue {
|
|||
constructor(cd:ControlNameDirective) {
|
||||
cd.valueAccessor = new WrappedValueAccessor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class FakeTemplateResolver extends TemplateResolver {
|
||||
_cmpTemplates: Map;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._cmpTemplates = MapWrapper.create();
|
||||
}
|
||||
|
||||
setTemplate(component: Type, template: Template) {
|
||||
MapWrapper.set(this._cmpTemplates, component, template);
|
||||
}
|
||||
|
||||
resolve(component: Type): Template {
|
||||
var override = MapWrapper.get(this._cmpTemplates, component);
|
||||
|
||||
if (isPresent(override)) {
|
||||
return override;
|
||||
}
|
||||
|
||||
return super.resolve(component);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,19 +11,18 @@ import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_meta
|
|||
|
||||
import {Component} from 'angular2/src/core/annotations/annotations';
|
||||
import {Decorator} from 'angular2/src/core/annotations/annotations';
|
||||
import {TemplateConfig} from 'angular2/src/core/annotations/template_config';
|
||||
import {Template} from 'angular2/src/core/annotations/template';
|
||||
import {TemplateLoader} from 'angular2/src/core/compiler/template_loader';
|
||||
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
|
||||
|
||||
import {reflector} from 'angular2/src/reflection/reflection';
|
||||
import {getIntParameter, bindAction} from 'angular2/src/test_lib/benchmark_util';
|
||||
|
||||
import {XHRImpl} from 'angular2/src/core/compiler/xhr/xhr_impl';
|
||||
|
||||
function setupReflector() {
|
||||
reflector.registerType(BenchmarkComponent, {
|
||||
"factory": () => new BenchmarkComponent(),
|
||||
"parameters": [],
|
||||
"annotations" : [new Component({template: new TemplateConfig({directives: [Dir0, Dir1, Dir2, Dir3, Dir4]})})]
|
||||
"annotations" : [new Component()]
|
||||
});
|
||||
|
||||
reflector.registerType(Dir0, {
|
||||
|
@ -83,37 +82,36 @@ export function main() {
|
|||
setupReflector();
|
||||
var reader = new DirectiveMetadataReader();
|
||||
var cache = new CompilerCache();
|
||||
var compiler = new Compiler(dynamicChangeDetection, new TemplateLoader(new XHRImpl()),
|
||||
reader, new Parser(new Lexer()), cache, new NativeShadowDomStrategy());
|
||||
var templateNoBindings = loadTemplate('templateNoBindings', count);
|
||||
var templateWithBindings = loadTemplate('templateWithBindings', count);
|
||||
var templateResolver = new FakeTemplateResolver();
|
||||
var compiler = new Compiler(dynamicChangeDetection, new TemplateLoader(null),
|
||||
reader, new Parser(new Lexer()), cache, new NativeShadowDomStrategy(), templateResolver);
|
||||
var templateNoBindings = createTemplateHtml('templateNoBindings', count);
|
||||
var templateWithBindings = createTemplateHtml('templateWithBindings', count);
|
||||
|
||||
function compileNoBindings() {
|
||||
// Need to clone every time as the compiler might modify the template!
|
||||
var cloned = DOM.clone(templateNoBindings);
|
||||
templateResolver.setTemplateHtml(templateNoBindings);
|
||||
cache.clear();
|
||||
compiler.compile(BenchmarkComponent, cloned);
|
||||
compiler.compile(BenchmarkComponent);
|
||||
}
|
||||
|
||||
function compileWithBindings() {
|
||||
// Need to clone every time as the compiler might modify the template!
|
||||
var cloned = DOM.clone(templateWithBindings);
|
||||
templateResolver.setTemplateHtml(templateWithBindings);
|
||||
cache.clear();
|
||||
compiler.compile(BenchmarkComponent, cloned);
|
||||
compiler.compile(BenchmarkComponent);
|
||||
}
|
||||
|
||||
bindAction('#compileNoBindings', compileNoBindings);
|
||||
bindAction('#compileWithBindings', compileWithBindings);
|
||||
}
|
||||
|
||||
function loadTemplate(templateId, repeatCount) {
|
||||
function createTemplateHtml(templateId, repeatCount) {
|
||||
var template = DOM.querySelectorAll(document, `#${templateId}`)[0];
|
||||
var content = DOM.getInnerHTML(template);
|
||||
var result = '';
|
||||
for (var i=0; i<repeatCount; i++) {
|
||||
result += content;
|
||||
}
|
||||
return DOM.createTemplate(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Decorator({
|
||||
|
@ -164,10 +162,24 @@ class Dir4 {
|
|||
constructor(dir3:Dir3) {}
|
||||
}
|
||||
|
||||
@Component({
|
||||
template: new TemplateConfig({
|
||||
directives: [Dir0, Dir1, Dir2, Dir3, Dir4]
|
||||
})
|
||||
})
|
||||
@Component()
|
||||
class BenchmarkComponent {}
|
||||
|
||||
class FakeTemplateResolver extends TemplateResolver {
|
||||
_template: Template;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
setTemplateHtml(html: string) {
|
||||
this._template = new Template({
|
||||
inline: html,
|
||||
directives: [Dir0, Dir1, Dir2, Dir3, Dir4]
|
||||
});
|
||||
}
|
||||
|
||||
resolve(component: Type): Template {
|
||||
return this._template;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import {int, isPresent} from 'angular2/src/facade/lang';
|
||||
import {reflector} from 'angular2/src/reflection/reflection';
|
||||
import {getIntParameter, bindAction} from 'angular2/src/test_lib/benchmark_util';
|
||||
import {bootstrap, Component, Viewport, TemplateConfig, ViewContainer, Compiler}
|
||||
import {bootstrap, Component, Viewport, Template, ViewContainer, Compiler}
|
||||
from 'angular2/angular2';
|
||||
import {PromiseWrapper} from 'angular2/src/facade/async';
|
||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||
|
@ -83,26 +83,23 @@ export function setupReflectorForApp() {
|
|||
'factory': () => { return new App(); },
|
||||
'parameters': [],
|
||||
'annotations': [
|
||||
new Component({
|
||||
selector: 'scroll-app',
|
||||
template: new TemplateConfig({
|
||||
directives: [ScrollAreaComponent, If, Foreach],
|
||||
inline: `
|
||||
<div>
|
||||
<div style="display: flex">
|
||||
<scroll-area id="testArea"></scroll-area>
|
||||
<div style="padding-left: 20px">
|
||||
<button id="run-btn">Run</button>
|
||||
<button id="reset-btn">Reset</button>
|
||||
</div>
|
||||
new Component({selector: 'scroll-app'}),
|
||||
new Template({
|
||||
directives: [ScrollAreaComponent, If, Foreach],
|
||||
inline: `
|
||||
<div>
|
||||
<div style="display: flex">
|
||||
<scroll-area id="testArea"></scroll-area>
|
||||
<div style="padding-left: 20px">
|
||||
<button id="run-btn">Run</button>
|
||||
<button id="reset-btn">Reset</button>
|
||||
</div>
|
||||
<div template="if scrollAreas.length > 0">
|
||||
<p>Following tables are only here to add weight to the UI:</p>
|
||||
<scroll-area template="foreach #scrollArea in scrollAreas"></scroll-area>
|
||||
</div>
|
||||
</div>`
|
||||
})
|
||||
})
|
||||
]
|
||||
</div>
|
||||
<div template="if scrollAreas.length > 0">
|
||||
<p>Following tables are only here to add weight to the UI:</p>
|
||||
<scroll-area template="foreach #scrollArea in scrollAreas"></scroll-area>
|
||||
</div>
|
||||
</div>`
|
||||
})]
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import {int} from 'angular2/src/facade/lang';
|
||||
import {reflector} from 'angular2/src/reflection/reflection';
|
||||
import {getIntParameter, bindAction} from 'angular2/src/test_lib/benchmark_util';
|
||||
import {bootstrap, Component, Viewport, TemplateConfig, ViewContainer, Compiler}
|
||||
import {bootstrap, Component, Viewport, Template, ViewContainer, Compiler}
|
||||
from 'angular2/angular2';
|
||||
import {PromiseWrapper} from 'angular2/src/facade/async';
|
||||
import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
||||
|
@ -103,14 +103,14 @@ export function setupReflectorForCells() {
|
|||
'annotations': [
|
||||
new Component({
|
||||
selector: 'company-name',
|
||||
template: new TemplateConfig({
|
||||
directives: [],
|
||||
inline: `<div [style]="style">{{company.name}}</div>`
|
||||
}),
|
||||
bind: {
|
||||
'cell-width': 'width',
|
||||
'company': 'company'
|
||||
}
|
||||
}),
|
||||
new Template({
|
||||
directives: [],
|
||||
inline: `<div [style]="style">{{company.name}}</div>`
|
||||
})
|
||||
]
|
||||
});
|
||||
|
@ -121,14 +121,14 @@ export function setupReflectorForCells() {
|
|||
'annotations': [
|
||||
new Component({
|
||||
selector: 'opportunity-name',
|
||||
template: new TemplateConfig({
|
||||
directives: [],
|
||||
inline: `<div [style]="style">{{opportunity.name}}</div>`
|
||||
}),
|
||||
bind: {
|
||||
'cell-width': 'width',
|
||||
'opportunity': 'opportunity'
|
||||
}
|
||||
}),
|
||||
new Template({
|
||||
directives: [],
|
||||
inline: `<div [style]="style">{{opportunity.name}}</div>`
|
||||
})
|
||||
]
|
||||
});
|
||||
|
@ -139,14 +139,14 @@ export function setupReflectorForCells() {
|
|||
'annotations': [
|
||||
new Component({
|
||||
selector: 'offering-name',
|
||||
template: new TemplateConfig({
|
||||
directives: [],
|
||||
inline: `<div [style]="style">{{offering.name}}</div>`
|
||||
}),
|
||||
bind: {
|
||||
'cell-width': 'width',
|
||||
'offering': 'offering'
|
||||
}
|
||||
}),
|
||||
new Template({
|
||||
directives: [],
|
||||
inline: `<div [style]="style">{{offering.name}}</div>`
|
||||
})
|
||||
]
|
||||
});
|
||||
|
@ -157,22 +157,22 @@ export function setupReflectorForCells() {
|
|||
'annotations': [
|
||||
new Component({
|
||||
selector: 'stage-buttons',
|
||||
template: new TemplateConfig({
|
||||
directives: [Foreach],
|
||||
inline: `
|
||||
<div [style]="style">
|
||||
<button template="foreach #stage in stages"
|
||||
[disabled]="stage.isDisabled"
|
||||
[style]="stage.style"
|
||||
on-click="setStage(stage)">
|
||||
{{stage.name}}
|
||||
</button>
|
||||
</div>`
|
||||
}),
|
||||
bind: {
|
||||
'cell-width': 'width',
|
||||
'offering': 'offering'
|
||||
}
|
||||
}),
|
||||
new Template({
|
||||
directives: [Foreach],
|
||||
inline: `
|
||||
<div [style]="style">
|
||||
<button template="foreach #stage in stages"
|
||||
[disabled]="stage.isDisabled"
|
||||
[style]="stage.style"
|
||||
on-click="setStage(stage)">
|
||||
{{stage.name}}
|
||||
</button>
|
||||
</div>`
|
||||
})
|
||||
]
|
||||
});
|
||||
|
@ -183,19 +183,19 @@ export function setupReflectorForCells() {
|
|||
'annotations': [
|
||||
new Component({
|
||||
selector: 'account-cell',
|
||||
template: new TemplateConfig({
|
||||
directives: [],
|
||||
inline: `
|
||||
<div [style]="style">
|
||||
<a href="/account/{{account.accountId}}">
|
||||
{{account.accountId}}
|
||||
</a>
|
||||
</div>`
|
||||
}),
|
||||
bind: {
|
||||
'cell-width': 'width',
|
||||
'account': 'account'
|
||||
}
|
||||
}),
|
||||
new Template({
|
||||
directives: [],
|
||||
inline: `
|
||||
<div [style]="style">
|
||||
<a href="/account/{{account.accountId}}">
|
||||
{{account.accountId}}
|
||||
</a>
|
||||
</div>`
|
||||
})
|
||||
]
|
||||
});
|
||||
|
@ -206,14 +206,14 @@ export function setupReflectorForCells() {
|
|||
'annotations': [
|
||||
new Component({
|
||||
selector: 'formatted-cell',
|
||||
template: new TemplateConfig({
|
||||
directives: [],
|
||||
inline: `<div [style]="style">{{formattedValue}}</div>`
|
||||
}),
|
||||
bind: {
|
||||
'cell-width': 'width',
|
||||
'value': 'value'
|
||||
}
|
||||
}),
|
||||
new Template({
|
||||
directives: [],
|
||||
inline: `<div [style]="style">{{formattedValue}}</div>`
|
||||
})
|
||||
]
|
||||
});
|
||||
|
|
|
@ -4,13 +4,14 @@ import {MapWrapper} from 'angular2/src/facade/collection';
|
|||
|
||||
import {Parser, Lexer, ChangeDetector, ChangeDetection}
|
||||
from 'angular2/change_detection';
|
||||
import {bootstrap, Component, Viewport, TemplateConfig, ViewContainer, Compiler}
|
||||
import {bootstrap, Component, Viewport, Template, ViewContainer, Compiler}
|
||||
from 'angular2/angular2';
|
||||
import {reflector} from 'angular2/src/reflection/reflection';
|
||||
import {CompilerCache} from 'angular2/src/core/compiler/compiler';
|
||||
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
||||
import {ShadowDomStrategy, NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
||||
import {TemplateLoader} from 'angular2/src/core/compiler/template_loader';
|
||||
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
|
||||
import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
|
||||
import {XHR} from 'angular2/src/core/compiler/xhr/xhr';
|
||||
import {XHRImpl} from 'angular2/src/core/compiler/xhr/xhr_impl';
|
||||
|
@ -172,10 +173,12 @@ export function setupReflectorForAngular() {
|
|||
});
|
||||
|
||||
reflector.registerType(Compiler, {
|
||||
"factory": (changeDetection, templateLoader, reader, parser, compilerCache, shadowDomStrategy) =>
|
||||
new Compiler(changeDetection, templateLoader, reader, parser, compilerCache, shadowDomStrategy),
|
||||
"factory": (changeDetection, templateLoader, reader, parser, compilerCache, shadowDomStrategy,
|
||||
resolver) =>
|
||||
new Compiler(changeDetection, templateLoader, reader, parser, compilerCache, shadowDomStrategy,
|
||||
resolver),
|
||||
"parameters": [[ChangeDetection], [TemplateLoader], [DirectiveMetadataReader], [Parser],
|
||||
[CompilerCache], [ShadowDomStrategy]],
|
||||
[CompilerCache], [ShadowDomStrategy], [TemplateResolver]],
|
||||
"annotations": []
|
||||
});
|
||||
|
||||
|
@ -197,6 +200,12 @@ export function setupReflectorForAngular() {
|
|||
"annotations": []
|
||||
});
|
||||
|
||||
reflector.registerType(TemplateResolver, {
|
||||
"factory": () => new TemplateResolver(),
|
||||
"parameters": [],
|
||||
"annotations": []
|
||||
});
|
||||
|
||||
reflector.registerType(XHR, {
|
||||
"factory": () => new XHRImpl(),
|
||||
"parameters": [],
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import {int, FINAL} from 'angular2/src/facade/lang';
|
||||
import {reflector} from 'angular2/src/reflection/reflection';
|
||||
import {getIntParameter, bindAction} from 'angular2/src/test_lib/benchmark_util';
|
||||
import {Component, Viewport, TemplateConfig, ViewContainer, Compiler}
|
||||
import {Component, Viewport, Template, ViewContainer, Compiler}
|
||||
from 'angular2/angular2';
|
||||
import {PromiseWrapper} from 'angular2/src/facade/async';
|
||||
import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
||||
|
@ -67,23 +67,23 @@ export function setupReflectorForScrollArea() {
|
|||
'annotations': [
|
||||
new Component({
|
||||
selector: 'scroll-area',
|
||||
template: new TemplateConfig({
|
||||
directives: [ScrollItemComponent, Foreach],
|
||||
inline: `
|
||||
<div>
|
||||
<div id="scrollDiv"
|
||||
[style]="scrollDivStyle"
|
||||
on-scroll="onScroll($event)">
|
||||
<div id="padding"></div>
|
||||
<div id="inner">
|
||||
<scroll-item
|
||||
template="foreach #item in visibleItems"
|
||||
[offering]="item">
|
||||
</scroll-item>
|
||||
</div>
|
||||
}),
|
||||
new Template({
|
||||
directives: [ScrollItemComponent, Foreach],
|
||||
inline: `
|
||||
<div>
|
||||
<div id="scrollDiv"
|
||||
[style]="scrollDivStyle"
|
||||
on-scroll="onScroll($event)">
|
||||
<div id="padding"></div>
|
||||
<div id="inner">
|
||||
<scroll-item
|
||||
template="foreach #item in visibleItems"
|
||||
[offering]="item">
|
||||
</scroll-item>
|
||||
</div>
|
||||
</div>`
|
||||
})
|
||||
</div>
|
||||
</div>`
|
||||
})
|
||||
]
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {int} from 'angular2/src/facade/lang';
|
||||
import {reflector} from 'angular2/src/reflection/reflection';
|
||||
import {Component, Viewport, TemplateConfig, ViewContainer, Compiler}
|
||||
import {Component, Viewport, Template, ViewContainer, Compiler}
|
||||
from 'angular2/angular2';
|
||||
import {PromiseWrapper} from 'angular2/src/facade/async';
|
||||
import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
||||
|
@ -51,55 +51,55 @@ export function setupReflectorForScrollItem() {
|
|||
'annotations': [
|
||||
new Component({
|
||||
selector: 'scroll-item',
|
||||
template: new TemplateConfig({
|
||||
directives: [
|
||||
CompanyNameComponent,
|
||||
OpportunityNameComponent,
|
||||
OfferingNameComponent,
|
||||
StageButtonsComponent,
|
||||
AccountCellComponent,
|
||||
FormattedCellComponent
|
||||
],
|
||||
inline: `
|
||||
<div [style]="itemStyle">
|
||||
<company-name [company]="offering.company"
|
||||
[cell-width]="companyNameWidth">
|
||||
</company-name>
|
||||
<opportunity-name [opportunity]="offering.opportunity"
|
||||
[cell-width]="opportunityNameWidth">
|
||||
</opportunity-name>
|
||||
<offering-name [offering]="offering"
|
||||
[cell-width]="offeringNameWidth">
|
||||
</offering-name>
|
||||
<account-cell [account]="offering.account"
|
||||
[cell-width]="accountCellWidth">
|
||||
</account-cell>
|
||||
<formatted-cell [value]="offering.basePoints"
|
||||
[cell-width]="basePointsWidth">
|
||||
</formatted-cell>
|
||||
<formatted-cell [value]="offering.kickerPoints"
|
||||
[cell-width]="kickerPointsWidth">
|
||||
</formatted-cell>
|
||||
<stage-buttons [offering]="offering"
|
||||
[cell-width]="stageButtonsWidth">
|
||||
</stage-buttons>
|
||||
<formatted-cell [value]="offering.bundles"
|
||||
[cell-width]="bundlesWidth">
|
||||
</formatted-cell>
|
||||
<formatted-cell [value]="offering.dueDate"
|
||||
[cell-width]="dueDateWidth">
|
||||
</formatted-cell>
|
||||
<formatted-cell [value]="offering.endDate"
|
||||
[cell-width]="endDateWidth">
|
||||
</formatted-cell>
|
||||
<formatted-cell [value]="offering.aatStatus"
|
||||
[cell-width]="aatStatusWidth">
|
||||
</formatted-cell>
|
||||
</div>`
|
||||
}),
|
||||
bind: {
|
||||
'offering': 'offering'
|
||||
}
|
||||
}),
|
||||
new Template({
|
||||
directives: [
|
||||
CompanyNameComponent,
|
||||
OpportunityNameComponent,
|
||||
OfferingNameComponent,
|
||||
StageButtonsComponent,
|
||||
AccountCellComponent,
|
||||
FormattedCellComponent
|
||||
],
|
||||
inline: `
|
||||
<div [style]="itemStyle">
|
||||
<company-name [company]="offering.company"
|
||||
[cell-width]="companyNameWidth">
|
||||
</company-name>
|
||||
<opportunity-name [opportunity]="offering.opportunity"
|
||||
[cell-width]="opportunityNameWidth">
|
||||
</opportunity-name>
|
||||
<offering-name [offering]="offering"
|
||||
[cell-width]="offeringNameWidth">
|
||||
</offering-name>
|
||||
<account-cell [account]="offering.account"
|
||||
[cell-width]="accountCellWidth">
|
||||
</account-cell>
|
||||
<formatted-cell [value]="offering.basePoints"
|
||||
[cell-width]="basePointsWidth">
|
||||
</formatted-cell>
|
||||
<formatted-cell [value]="offering.kickerPoints"
|
||||
[cell-width]="kickerPointsWidth">
|
||||
</formatted-cell>
|
||||
<stage-buttons [offering]="offering"
|
||||
[cell-width]="stageButtonsWidth">
|
||||
</stage-buttons>
|
||||
<formatted-cell [value]="offering.bundles"
|
||||
[cell-width]="bundlesWidth">
|
||||
</formatted-cell>
|
||||
<formatted-cell [value]="offering.dueDate"
|
||||
[cell-width]="dueDateWidth">
|
||||
</formatted-cell>
|
||||
<formatted-cell [value]="offering.endDate"
|
||||
[cell-width]="endDateWidth">
|
||||
</formatted-cell>
|
||||
<formatted-cell [value]="offering.aatStatus"
|
||||
[cell-width]="aatStatusWidth">
|
||||
</formatted-cell>
|
||||
</div>`
|
||||
})
|
||||
]
|
||||
});
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import {Parser, Lexer, ChangeDetector, ChangeDetection, jitChangeDetection}
|
||||
from 'angular2/change_detection';
|
||||
|
||||
import {bootstrap, Component, Viewport, TemplateConfig, ViewContainer, Compiler} from 'angular2/angular2';
|
||||
import {bootstrap, Component, Viewport, Template, ViewContainer, Compiler} from 'angular2/angular2';
|
||||
|
||||
import {CompilerCache} from 'angular2/src/core/compiler/compiler';
|
||||
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
||||
import {TemplateLoader} from 'angular2/src/core/compiler/template_loader';
|
||||
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
|
||||
import {ShadowDomStrategy, NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
||||
import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
|
||||
|
||||
|
@ -24,28 +25,26 @@ function setupReflector() {
|
|||
reflector.registerType(AppComponent, {
|
||||
'factory': () => new AppComponent(),
|
||||
'parameters': [],
|
||||
'annotations' : [new Component({
|
||||
selector: 'app',
|
||||
template: new TemplateConfig({
|
||||
'annotations' : [
|
||||
new Component({selector: 'app'}),
|
||||
new Template({
|
||||
directives: [TreeComponent],
|
||||
inline: `<tree [data]='initData'></tree>`
|
||||
})
|
||||
})]
|
||||
})]
|
||||
});
|
||||
|
||||
reflector.registerType(TreeComponent, {
|
||||
'factory': () => new TreeComponent(),
|
||||
'parameters': [],
|
||||
'annotations' : [new Component({
|
||||
selector: 'tree',
|
||||
bind: {
|
||||
'data': 'data'
|
||||
},
|
||||
template: new TemplateConfig({
|
||||
directives: [TreeComponent, NgIf],
|
||||
inline: `<span> {{data.value}} <span template='ng-if data.right != null'><tree [data]='data.right'></tree></span><span template='ng-if data.left != null'><tree [data]='data.left'></tree></span></span>`
|
||||
})
|
||||
})]
|
||||
'annotations' : [
|
||||
new Component({
|
||||
selector: 'tree',
|
||||
bind: {'data': 'data'}
|
||||
}),
|
||||
new Template({
|
||||
directives: [TreeComponent, NgIf],
|
||||
inline: `<span> {{data.value}} <span template='ng-if data.right != null'><tree [data]='data.right'></tree></span><span template='ng-if data.left != null'><tree [data]='data.left'></tree></span></span>`
|
||||
})]
|
||||
});
|
||||
|
||||
reflector.registerType(NgIf, {
|
||||
|
@ -60,9 +59,10 @@ function setupReflector() {
|
|||
});
|
||||
|
||||
reflector.registerType(Compiler, {
|
||||
'factory': (cd, templateLoader, reader, parser, compilerCache, strategy) => new Compiler(cd, templateLoader, reader, parser, compilerCache, strategy),
|
||||
'factory': (cd, templateLoader, reader, parser, compilerCache, strategy, resolver) =>
|
||||
new Compiler(cd, templateLoader, reader, parser, compilerCache, strategy, resolver),
|
||||
'parameters': [[ChangeDetection], [TemplateLoader], [DirectiveMetadataReader],
|
||||
[Parser], [CompilerCache], [ShadowDomStrategy]],
|
||||
[Parser], [CompilerCache], [ShadowDomStrategy], [TemplateResolver]],
|
||||
'annotations': []
|
||||
});
|
||||
|
||||
|
@ -84,6 +84,12 @@ function setupReflector() {
|
|||
'annotations': []
|
||||
});
|
||||
|
||||
reflector.registerType(TemplateResolver, {
|
||||
'factory': () => new TemplateResolver(),
|
||||
'parameters': [],
|
||||
'annotations': []
|
||||
});
|
||||
|
||||
reflector.registerType(XHR, {
|
||||
'factory': () => new XHRImpl(),
|
||||
'parameters': [],
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
import {bootstrap, Component, TemplateConfig} from 'angular2/core';
|
||||
import {bootstrap, Component, Template} from 'angular2/core';
|
||||
import {reflector} from 'angular2/src/reflection/reflection';
|
||||
import {ReflectionCapabilities} from 'angular2/src/reflection/reflection_capabilities';
|
||||
|
||||
@Component({
|
||||
selector: 'gestures-app',
|
||||
template: new TemplateConfig({
|
||||
url: 'template.html'
|
||||
})
|
||||
})
|
||||
@Component({selector: 'gestures-app'})
|
||||
@Template({url: 'template.html'})
|
||||
class GesturesCmp {
|
||||
swipeDirection: string;
|
||||
pinchScale: number;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {bootstrap, Component, Decorator, TemplateConfig, NgElement} from 'angular2/angular2';
|
||||
import {bootstrap, Component, Decorator, Template, NgElement} from 'angular2/angular2';
|
||||
|
||||
// Angular 2.0 supports 3 basic types of directives:
|
||||
// - Component - the basic building blocks of Angular 2.0 apps. Backed by
|
||||
|
@ -15,19 +15,19 @@ import {bootstrap, Component, Decorator, TemplateConfig, NgElement} from 'angula
|
|||
selector: 'hello-app',
|
||||
// These are services that would be created if a class in the component's
|
||||
// template tries to inject them.
|
||||
componentServices: [GreetingService],
|
||||
template: new TemplateConfig({
|
||||
// The template for the component.
|
||||
// Expressions in the template (like {{greeting}}) are evaluated in the
|
||||
// context of the HelloCmp class below.
|
||||
inline: `<div class="greeting">{{greeting}} <span red>world</span>!</div>
|
||||
<button class="changeButton" (click)="changeGreeting()">change greeting</button>`,
|
||||
// All directives used in the template need to be specified. This allows for
|
||||
// modularity (RedDec can only be used in this template)
|
||||
// and better tooling (the template can be invalidated if the attribute is
|
||||
// misspelled).
|
||||
directives: [RedDec]
|
||||
})
|
||||
componentServices: [GreetingService]
|
||||
})
|
||||
// The template for the component.
|
||||
@Template({
|
||||
// Expressions in the template (like {{greeting}}) are evaluated in the
|
||||
// context of the HelloCmp class below.
|
||||
inline: `<div class="greeting">{{greeting}} <span red>world</span>!</div>
|
||||
<button class="changeButton" (click)="changeGreeting()">change greeting</button>`,
|
||||
// All directives used in the template need to be specified. This allows for
|
||||
// modularity (RedDec can only be used in this template)
|
||||
// and better tooling (the template can be invalidated if the attribute is
|
||||
// misspelled).
|
||||
directives: [RedDec]
|
||||
})
|
||||
class HelloCmp {
|
||||
greeting: string;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import * as app from './index_common';
|
||||
|
||||
import {Component, Decorator, TemplateConfig, NgElement} from 'angular2/angular2';
|
||||
import {Component, Decorator, Template, NgElement} from 'angular2/angular2';
|
||||
import {Lexer, Parser, ChangeDetection, ChangeDetector} from 'angular2/change_detection';
|
||||
import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
|
||||
|
||||
|
@ -8,6 +8,7 @@ import {Compiler, CompilerCache} from 'angular2/src/core/compiler/compiler';
|
|||
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
||||
import {ShadowDomStrategy, NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
||||
import {TemplateLoader} from 'angular2/src/core/compiler/template_loader';
|
||||
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
|
||||
import {XHR} from 'angular2/src/core/compiler/xhr/xhr';
|
||||
import {XHRImpl} from 'angular2/src/core/compiler/xhr/xhr_impl';
|
||||
|
||||
|
@ -17,14 +18,16 @@ function setup() {
|
|||
reflector.registerType(app.HelloCmp, {
|
||||
"factory": (service) => new app.HelloCmp(service),
|
||||
"parameters": [[app.GreetingService]],
|
||||
"annotations" : [new Component({
|
||||
selector: 'hello-app',
|
||||
componentServices: [app.GreetingService],
|
||||
template: new TemplateConfig({
|
||||
"annotations" : [
|
||||
new Component({
|
||||
selector: 'hello-app',
|
||||
componentServices: [app.GreetingService]
|
||||
}),
|
||||
new Template({
|
||||
directives: [app.RedDec],
|
||||
inline: `<div class="greeting">{{greeting}} <span red>world</span>!</div>
|
||||
<button class="changeButton" (click)="changeGreeting()">change greeting</button>`})
|
||||
})]
|
||||
<button class="changeButton" (click)="changeGreeting()">change greeting</button>`
|
||||
})]
|
||||
});
|
||||
|
||||
reflector.registerType(app.RedDec, {
|
||||
|
@ -40,10 +43,12 @@ function setup() {
|
|||
});
|
||||
|
||||
reflector.registerType(Compiler, {
|
||||
"factory": (changeDetection, templateLoader, reader, parser, compilerCache, shadowDomStrategy) =>
|
||||
new Compiler(changeDetection, templateLoader, reader, parser, compilerCache, shadowDomStrategy),
|
||||
"factory": (changeDetection, templateLoader, reader, parser, compilerCache, shadowDomStrategy,
|
||||
resolver) =>
|
||||
new Compiler(changeDetection, templateLoader, reader, parser, compilerCache, shadowDomStrategy,
|
||||
resolver),
|
||||
"parameters": [[ChangeDetection], [TemplateLoader], [DirectiveMetadataReader], [Parser],
|
||||
[CompilerCache], [ShadowDomStrategy]],
|
||||
[CompilerCache], [ShadowDomStrategy], [TemplateResolver]],
|
||||
"annotations": []
|
||||
});
|
||||
|
||||
|
@ -65,6 +70,12 @@ function setup() {
|
|||
"annotations": []
|
||||
});
|
||||
|
||||
reflector.registerType(TemplateResolver, {
|
||||
"factory": () => new TemplateResolver(),
|
||||
"parameters": [],
|
||||
"annotations": []
|
||||
});
|
||||
|
||||
reflector.registerType(XHR, {
|
||||
"factory": () => new XHRImpl(),
|
||||
"parameters": [],
|
||||
|
|
Loading…
Reference in New Issue