From e6c8bde808ddaae7dd42fb2c2c4aae09ad8223c8 Mon Sep 17 00:00:00 2001
From: Victor Berchet
Date: Thu, 12 Feb 2015 14:44:59 +0100
Subject: [PATCH] feat(Compiler): Multiple template per component
fixes #596
- TemplateConfig becomes Template
- introduce a TemplateResolver to pick the cmp template,
- @Component and @Template are disociated
---
modules/angular2/core.js | 2 +-
.../src/core/annotations/annotations.js | 5 -
.../{template_config.js => template.js} | 16 +-
modules/angular2/src/core/application.js | 4 +-
.../angular2/src/core/compiler/compiler.js | 90 ++++--
.../src/core/compiler/directive_metadata.js | 8 +-
.../compiler/directive_metadata_reader.js | 33 +--
.../src/core/compiler/template_loader.js | 24 +-
.../src/core/compiler/template_resolver.js | 38 +++
modules/angular2/src/forms/directives.js | 8 +-
.../angular2/test/core/application_spec.js | 38 +--
.../test/core/compiler/compiler_spec.js | 263 +++++++++---------
.../directive_metadata_reader_spec.js | 73 ++---
.../test/core/compiler/integration_spec.js | 144 +++++++---
.../pipeline/directive_parser_spec.js | 15 +-
.../pipeline/element_binder_builder_spec.js | 4 +-
.../pipeline/shadow_dom_transformer_spec.js | 2 +-
.../shadow_dom_emulation_integration_spec.js | 139 ++++-----
.../core/compiler/template_loader_spec.js | 57 ++--
.../angular2/test/core/compiler/view_spec.js | 6 +-
.../angular2/test/directives/foreach_spec.js | 55 +++-
modules/angular2/test/directives/if_spec.js | 55 +++-
.../test/directives/non_bindable_spec.js | 54 +++-
.../angular2/test/directives/switch_spec.js | 54 +++-
.../angular2/test/forms/integration_spec.js | 65 +++--
.../src/compiler/compiler_benchmark.js | 54 ++--
.../src/naive_infinite_scroll/app.js | 39 ++-
.../src/naive_infinite_scroll/cells.js | 76 ++---
.../src/naive_infinite_scroll/index.js | 17 +-
.../src/naive_infinite_scroll/scroll_area.js | 34 +--
.../src/naive_infinite_scroll/scroll_item.js | 94 +++----
modules/benchmarks/src/tree/tree_benchmark.js | 42 +--
modules/examples/src/gestures/index.js | 10 +-
.../examples/src/hello_world/index_common.js | 28 +-
.../examples/src/hello_world/index_static.js | 31 ++-
35 files changed, 953 insertions(+), 724 deletions(-)
rename modules/angular2/src/core/annotations/{template_config.js => template.js} (68%)
create mode 100644 modules/angular2/src/core/compiler/template_resolver.js
diff --git a/modules/angular2/core.js b/modules/angular2/core.js
index e1fa6186012..19d67746864 100644
--- a/modules/angular2/core.js
+++ b/modules/angular2/core.js
@@ -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';
diff --git a/modules/angular2/src/core/annotations/annotations.js b/modules/angular2/src/core/annotations/annotations.js
index b02d6d6b85e..b0a4e0882a2 100644
--- a/modules/angular2/src/core/annotations/annotations.js
+++ b/modules/angular2/src/core/annotations/annotations.js
@@ -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;
diff --git a/modules/angular2/src/core/annotations/template_config.js b/modules/angular2/src/core/annotations/template.js
similarity index 68%
rename from modules/angular2/src/core/annotations/template_config.js
rename to modules/angular2/src/core/annotations/template.js
index edd6e958783..0e1b23eb868 100644
--- a/modules/angular2/src/core/annotations/template_config.js
+++ b/modules/angular2/src/core/annotations/template.js
@@ -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;
formatters:any; //List;
- source:any;//List;
+ source:any;//List;
+ locale:any; //string
+ device:any; //string
@CONST()
constructor({
url,
inline,
directives,
formatters,
- source
+ source,
+ locale,
+ device
}: {
url: string,
inline: string,
directives: List,
formatters: List,
- source: List
+ source: List,
+ 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;
}
}
diff --git a/modules/angular2/src/core/application.js b/modules/angular2/src/core/application.js
index 60f11d3a63a..a55b3075081 100644
--- a/modules/angular2/src/core/application.js
+++ b/modules/angular2/src/core/application.js
@@ -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 {
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'),
diff --git a/modules/angular2/src/core/compiler/compiler.js b/modules/angular2/src/core/compiler/compiler.js
index 18257083d57..e7d68a2706b 100644
--- a/modules/angular2/src/core/compiler/compiler.js
+++ b/modules/angular2/src/core/compiler/compiler.js
@@ -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;
_shadowDomStrategy: ShadowDomStrategy;
_shadowDomDirectives: List;
+ _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 {
- 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 {
+ // 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 {
- var protoView = this._compile(this._reader.read(component), templateRoot);
+ compile(component: Type):Promise {
+ var protoView = this._compile(component);
return PromiseWrapper.isPromise(protoView) ? protoView : PromiseWrapper.resolve(protoView);
}
// TODO(vicb): union type return ProtoView or Promise
- _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
- _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)
- {
- var protoView = this._compile(ce.componentDirective);
+ _compileNestedProtoView(ce: CompileElement, promises: List) {
+ 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 {
+ if (isBlank(template.directives)) return [];
+
+ var directives = [];
+ this._flattenList(template.directives, directives);
+
+ return directives;
+ }
+
+ _flattenList(tree:List, out:List) {
+ 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);
+ }
+ }
+ }
+
}
+
+
diff --git a/modules/angular2/src/core/compiler/directive_metadata.js b/modules/angular2/src/core/compiler/directive_metadata.js
index b300266c64f..43ac0f8effb 100644
--- a/modules/angular2/src/core/compiler/directive_metadata.js
+++ b/modules/angular2/src/core/compiler/directive_metadata.js
@@ -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;
- constructor(type:Type,
- annotation:Directive,
- componentDirectives:List) {
+ constructor(type:Type, annotation:Directive) {
this.annotation = annotation;
this.type = type;
- this.componentDirectives = componentDirectives;
}
}
diff --git a/modules/angular2/src/core/compiler/directive_metadata_reader.js b/modules/angular2/src/core/compiler/directive_metadata_reader.js
index 5771c2da6f5..7aa40984ca3 100644
--- a/modules/angular2/src/core/compiler/directive_metadata_reader.js
+++ b/modules/angular2/src/core/compiler/directive_metadata_reader.js
@@ -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 {
- var template = annotation.template;
- var result:List = ListWrapper.create();
- if (isPresent(template) && isPresent(template.directives)) {
- this._buildList(result, template.directives);
- }
- return result;
- }
-
- _buildList(out:List, tree:List) {
- 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);
- }
- }
- }
}
diff --git a/modules/angular2/src/core/compiler/template_loader.js b/modules/angular2/src/core/compiler/template_loader.js
index 3e5991299fe..2c2986ba203 100644
--- a/modules/angular2/src/core/compiler/template_loader.js
+++ b/modules/angular2/src/core/compiler/template_loader.js
@@ -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
- 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`);
}
}
diff --git a/modules/angular2/src/core/compiler/template_resolver.js b/modules/angular2/src/core/compiler/template_resolver.js
new file mode 100644
index 00000000000..eea8138f7cb
--- /dev/null
+++ b/modules/angular2/src/core/compiler/template_resolver.js
@@ -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)}`);
+ }
+}
diff --git a/modules/angular2/src/forms/directives.js b/modules/angular2/src/forms/directives.js
index a037d4951c7..987d26127c1 100644
--- a/modules/angular2/src/forms/directives.js
+++ b/modules/angular2/src/forms/directives.js
@@ -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: ''
- })
+ }
})
+@Template({inline: ''})
export class NewControlGroupDirective extends ControlGroupDirectiveBase {
_initData:any;
_controlGroup:ControlGroup;
diff --git a/modules/angular2/test/core/application_spec.js b/modules/angular2/test/core/application_spec.js
index 827c6203314..ae0e27108cf 100644
--- a/modules/angular2/test/core/application_spec.js
+++ b/modules/angular2/test/core/application_spec.js
@@ -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;
diff --git a/modules/angular2/test/core/compiler/compiler_spec.js b/modules/angular2/test/core/compiler/compiler_spec.js
index 0c23d043b57..90cd7f6a8fe 100644
--- a/modules/angular2/test/core/compiler/compiler_spec.js
+++ b/modules/angular2/test/core/compiler/compiler_spec.js
@@ -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('
')).then( (protoView) => {
+ tplResolver.setTemplate(MainComponent, new Template({inline: '
'}));
+ compiler.compile(MainComponent).then( (protoView) => {
expect(protoView).toBe(rootProtoView);
done();
});
});
- it('should use the given element', (done) => {
- var element = el('
');
+ 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('
');
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: '
'}));
+ 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('
');
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: '
'}));
+ 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('');
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: ''}));
+ 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: '
'
- })
-})
+@Component()
+@Template({inline: '
'})
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: '
'
- }),
- selector: 'rec-comp'
-})
+@Component({selector: 'rec-comp'})
+@Template({inline: '
'})
class RecursiveComponent {}
class TestableCompiler extends Compiler {
steps:List;
- constructor(reader:DirectiveMetadataReader, steps:List, loader: TemplateLoader) {
+ constructor(reader:DirectiveMetadataReader, steps:List, 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 {
+ createSteps(component:Type, template: Template):List {
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;
_asyncCmp: List;
_errorCmp: List;
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);
}
}
diff --git a/modules/angular2/test/core/compiler/directive_metadata_reader_spec.js b/modules/angular2/test/core/compiler/directive_metadata_reader_spec.js
index a34b7bbb12e..25ecc4d5759 100644
--- a/modules/angular2/test/core/compiler/directive_metadata_reader_spec.js
+++ b/modules/angular2/test/core/compiler/directive_metadata_reader_spec.js
@@ -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]);
- });
- });
});
}
diff --git a/modules/angular2/test/core/compiler/integration_spec.js b/modules/angular2/test/core/compiler/integration_spec.js
index 02a307fbd92..66a4311d918 100644
--- a/modules/angular2/test/core/compiler/integration_spec.js
+++ b/modules/angular2/test/core/compiler/integration_spec.js
@@ -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('{{ctxProp}}
')).then((pv) => {
+ tplResolver.setTemplate(MyComp, new Template({inline: '{{ctxProp}}
'}));
+
+ 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('
')).then((pv) => {
+ tplResolver.setTemplate(MyComp, new Template({inline: '
'}));
+
+ compiler.compile(MyComp).then((pv) => {
createView(pv);
ctx.ctxProp = 'Hello World!';
@@ -73,7 +79,9 @@ export function main() {
'
' +
'
' +
''
- 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(' ')).then((pv) => {
+ tplResolver.setTemplate(MyComp, new Template({
+ inline: ' ',
+ 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(' ')).then((pv) => {
+ tplResolver.setTemplate(MyComp,
+ new Template({
+ inline: ' ',
+ 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 `` elements.', (done) => {
- compiler.compile(MyComp, el('{{greeting}}
')).then((pv) => {
+ tplResolver.setTemplate(MyComp,
+ new Template({
+ inline: '{{greeting}}
',
+ 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('{{greeting}}
')).then((pv) => {
+ tplResolver.setTemplate(MyComp, new Template({
+ inline: '{{greeting}}
',
+ 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('
')).then((pv) => {
+ tplResolver.setTemplate(MyComp, new Template({
+ inline: '
',
+ 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('
');
+ tplResolver.setTemplate(MyComp, new Template({
+ inline: '
',
+ 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(' ')).then((pv) => {
+ tplResolver.setTemplate(MyComp, new Template({
+ inline: ' ',
+ 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('
');
- var div = el('
');
- DOM.appendChild(div, el('Hello '));
- DOM.appendChild(element, div);
+ tplResolver.setTemplate(MyComp,
+ new Template({inline: '
Hello
'}));
- 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(' ')).then((pv) => {
+ tplResolver.setTemplate(MyComp, new Template({
+ inline: ' ',
+ 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);
+ }
+}
diff --git a/modules/angular2/test/core/compiler/pipeline/directive_parser_spec.js b/modules/angular2/test/core/compiler/pipeline/directive_parser_spec.js
index 3e5ea262ad3..57430dfb77a 100644
--- a/modules/angular2/test/core/compiler/pipeline/directive_parser_spec.js
+++ b/modules/angular2/test/core/compiler/pipeline/directive_parser_spec.js
@@ -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 {}
diff --git a/modules/angular2/test/core/compiler/pipeline/element_binder_builder_spec.js b/modules/angular2/test/core/compiler/pipeline/element_binder_builder_spec.js
index af503e339e2..4d48fdedd87 100644
--- a/modules/angular2/test/core/compiler/pipeline/element_binder_builder_spec.js
+++ b/modules/angular2/test/core/compiler/pipeline/element_binder_builder_spec.js
@@ -405,9 +405,7 @@ class SomeViewportDirectiveWithBinding {
class SomeComponentDirective {
}
-@Component({
- bind: {'boundprop3': 'compProp'}
-})
+@Component({bind: {'boundprop3': 'compProp'}})
class SomeComponentDirectiveWithBinding {
compProp;
constructor() {
diff --git a/modules/angular2/test/core/compiler/pipeline/shadow_dom_transformer_spec.js b/modules/angular2/test/core/compiler/pipeline/shadow_dom_transformer_spec.js
index 8eabb5ad934..ff9d1c2e910 100644
--- a/modules/angular2/test/core/compiler/pipeline/shadow_dom_transformer_spec.js
+++ b/modules/angular2/test/core/compiler/pipeline/shadow_dom_transformer_spec.js
@@ -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]);
diff --git a/modules/angular2/test/core/compiler/shadow_dom/shadow_dom_emulation_integration_spec.js b/modules/angular2/test/core/compiler/shadow_dom/shadow_dom_emulation_integration_spec.js
index eaf14fcae42..147450ed803 100644
--- a/modules/angular2/test/core/compiler/shadow_dom/shadow_dom_emulation_integration_spec.js
+++ b/modules/angular2/test/core/compiler/shadow_dom/shadow_dom_emulation_integration_spec.js
@@ -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, 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() {
'A
' +
'';
- compile(temp, (view, lc) => {
+ compile(temp, [MultipleContentTagsComponent], (view, lc) => {
expect(view.nodes).toHaveText('(A, BC)');
done();
});
@@ -71,7 +77,7 @@ export function main() {
'C
' +
'';
- compile(temp, (view, lc) => {
+ compile(temp, [MultipleContentTagsComponent], (view, lc) => {
expect(view.nodes).toHaveText('(, BAC)');
done();
});
@@ -83,7 +89,7 @@ export function main() {
'B
' +
'';
- 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() {
'B
' +
'';
- 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() {
'B
' +
'';
- compile(temp, (view, lc) => {
+ compile(temp, [OuterWithIndirectNestedComponent], (view, lc) => {
expect(view.nodes).toHaveText('OUTER(SIMPLE(AB))');
done();
@@ -147,7 +153,7 @@ export function main() {
'C
' +
'';
- 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( )'
- })
-})
+@Component({selector: 'simple'})
+@Template({inline: 'SIMPLE( )'})
class Simple {
}
-@Component({
- selector: 'multiple-content-tags',
- template: new TemplateConfig({
- inline: '( , )'
- })
+@Component({selector: 'multiple-content-tags'})
+@Template({
+ inline: '( , )'
})
class MultipleContentTagsComponent {
}
-@Component({
- selector: 'conditional-content',
- template: new TemplateConfig({
- inline: '',
- directives: [AutoViewportDirective]
- })
+@Component({selector: 'conditional-content'})
+@Template({
+ inline: '',
+ 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(
)',
- directives: [Simple]
- })
+@Component({selector: 'outer-with-indirect-nested'})
+@Template({
+ inline: 'OUTER(
)',
+ directives: [Simple]
})
class OuterWithIndirectNestedComponent {
}
-@Component({
- selector: 'outer',
- template: new TemplateConfig({
- inline: 'OUTER( )',
- directives: [InnerComponent]
- })
+@Component({selector: 'outer'})
+@Template({
+ inline: 'OUTER( )',
+ directives: [InnerComponent]
})
class OuterComponent {
}
-@Component({
- selector: 'inner',
- template: new TemplateConfig({
- inline: 'INNER( )',
- directives: [InnerInnerComponent]
- })
+@Component({selector: 'inner'})
+@Template({
+ inline: 'INNER( )',
+ directives: [InnerInnerComponent]
})
class InnerComponent {
}
-@Component({
- selector: 'innerinner',
- template: new TemplateConfig({
- inline: 'INNERINNER( , )'
- })
+@Component({selector: 'innerinner'})
+@Template({
+ inline: 'INNERINNER( , )'
})
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);
+ }
+}
diff --git a/modules/angular2/test/core/compiler/template_loader_spec.js b/modules/angular2/test/core/compiler/template_loader_spec.js
index d48742309bd..2217de9557d 100644
--- a/modules/angular2/test/core/compiler/template_loader_spec.js
+++ b/modules/angular2/test/core/compiler/template_loader_spec.js
@@ -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 {
}
diff --git a/modules/angular2/test/core/compiler/view_spec.js b/modules/angular2/test/core/compiler/view_spec.js
index 24326ddb98e..89dd9f961ca 100644
--- a/modules/angular2/test/core/compiler/view_spec.js
+++ b/modules/angular2/test/core/compiler/view_spec.js
@@ -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) {
diff --git a/modules/angular2/test/directives/foreach_spec.js b/modules/angular2/test/directives/foreach_spec.js
index 40ecfdc4ed0..0277316ba02 100644
--- a/modules/angular2/test/directives/foreach_spec.js
+++ b/modules/angular2/test/directives/foreach_spec.js
@@ -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 = '{{item.toString()}};
';
@@ -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);
+ }
+}
diff --git a/modules/angular2/test/directives/if_spec.js b/modules/angular2/test/directives/if_spec.js
index 2ebf3f3d1d9..ead5adeddc8 100644
--- a/modules/angular2/test/directives/if_spec.js
+++ b/modules/angular2/test/directives/if_spec.js
@@ -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);
+ }
+}
diff --git a/modules/angular2/test/directives/non_bindable_spec.js b/modules/angular2/test/directives/non_bindable_spec.js
index 4c63974f0f6..3699374b797 100644
--- a/modules/angular2/test/directives/non_bindable_spec.js
+++ b/modules/angular2/test/directives/non_bindable_spec.js
@@ -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);
+ }
+}
diff --git a/modules/angular2/test/directives/switch_spec.js b/modules/angular2/test/directives/switch_spec.js
index 897c136d7a3..509b904b4e8 100644
--- a/modules/angular2/test/directives/switch_spec.js
+++ b/modules/angular2/test/directives/switch_spec.js
@@ -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);
+ }
+}
diff --git a/modules/angular2/test/forms/integration_spec.js b/modules/angular2/test/forms/integration_spec.js
index 864eb85e129..478966bdeee 100644
--- a/modules/angular2/test/forms/integration_spec.js
+++ b/modules/angular2/test/forms/integration_spec.js
@@ -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();
}
-}
\ No newline at end of file
+}
+
+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);
+ }
+}
diff --git a/modules/benchmarks/src/compiler/compiler_benchmark.js b/modules/benchmarks/src/compiler/compiler_benchmark.js
index a588fc7cd77..5134b1e0238 100644
--- a/modules/benchmarks/src/compiler/compiler_benchmark.js
+++ b/modules/benchmarks/src/compiler/compiler_benchmark.js
@@ -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 { return new App(); },
'parameters': [],
'annotations': [
- new Component({
- selector: 'scroll-app',
- template: new TemplateConfig({
- directives: [ScrollAreaComponent, If, Foreach],
- inline: `
-
-
-
-
- Run
- Reset
-
+ new Component({selector: 'scroll-app'}),
+ new Template({
+ directives: [ScrollAreaComponent, If, Foreach],
+ inline: `
+
+
+
+
+ Run
+ Reset
-
-
Following tables are only here to add weight to the UI:
-
-
-
`
- })
- })
- ]
+
+
+
Following tables are only here to add weight to the UI:
+
+
+
`
+ })]
});
}
diff --git a/modules/benchmarks/src/naive_infinite_scroll/cells.js b/modules/benchmarks/src/naive_infinite_scroll/cells.js
index 506d8390b18..921e5646d22 100644
--- a/modules/benchmarks/src/naive_infinite_scroll/cells.js
+++ b/modules/benchmarks/src/naive_infinite_scroll/cells.js
@@ -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: `
{{company.name}}
`
- }),
bind: {
'cell-width': 'width',
'company': 'company'
}
+ }),
+ new Template({
+ directives: [],
+ inline: `
{{company.name}}
`
})
]
});
@@ -121,14 +121,14 @@ export function setupReflectorForCells() {
'annotations': [
new Component({
selector: 'opportunity-name',
- template: new TemplateConfig({
- directives: [],
- inline: `
{{opportunity.name}}
`
- }),
bind: {
'cell-width': 'width',
'opportunity': 'opportunity'
}
+ }),
+ new Template({
+ directives: [],
+ inline: `
{{opportunity.name}}
`
})
]
});
@@ -139,14 +139,14 @@ export function setupReflectorForCells() {
'annotations': [
new Component({
selector: 'offering-name',
- template: new TemplateConfig({
- directives: [],
- inline: `
{{offering.name}}
`
- }),
bind: {
'cell-width': 'width',
'offering': 'offering'
}
+ }),
+ new Template({
+ directives: [],
+ inline: `
{{offering.name}}
`
})
]
});
@@ -157,22 +157,22 @@ export function setupReflectorForCells() {
'annotations': [
new Component({
selector: 'stage-buttons',
- template: new TemplateConfig({
- directives: [Foreach],
- inline: `
-
-
- {{stage.name}}
-
-
`
- }),
bind: {
'cell-width': 'width',
'offering': 'offering'
}
+ }),
+ new Template({
+ directives: [Foreach],
+ inline: `
+
+
+ {{stage.name}}
+
+
`
})
]
});
@@ -183,19 +183,19 @@ export function setupReflectorForCells() {
'annotations': [
new Component({
selector: 'account-cell',
- template: new TemplateConfig({
- directives: [],
- inline: `
-
`
- }),
bind: {
'cell-width': 'width',
'account': 'account'
}
+ }),
+ new Template({
+ directives: [],
+ inline: `
+
`
})
]
});
@@ -206,14 +206,14 @@ export function setupReflectorForCells() {
'annotations': [
new Component({
selector: 'formatted-cell',
- template: new TemplateConfig({
- directives: [],
- inline: `
{{formattedValue}}
`
- }),
bind: {
'cell-width': 'width',
'value': 'value'
}
+ }),
+ new Template({
+ directives: [],
+ inline: `
{{formattedValue}}
`
})
]
});
diff --git a/modules/benchmarks/src/naive_infinite_scroll/index.js b/modules/benchmarks/src/naive_infinite_scroll/index.js
index c14a1123ea2..1783ae6bb8b 100644
--- a/modules/benchmarks/src/naive_infinite_scroll/index.js
+++ b/modules/benchmarks/src/naive_infinite_scroll/index.js
@@ -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": [],
diff --git a/modules/benchmarks/src/naive_infinite_scroll/scroll_area.js b/modules/benchmarks/src/naive_infinite_scroll/scroll_area.js
index 158b788d04d..7120ec6433c 100644
--- a/modules/benchmarks/src/naive_infinite_scroll/scroll_area.js
+++ b/modules/benchmarks/src/naive_infinite_scroll/scroll_area.js
@@ -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: `
-
-
`
})
]
});
diff --git a/modules/benchmarks/src/naive_infinite_scroll/scroll_item.js b/modules/benchmarks/src/naive_infinite_scroll/scroll_item.js
index 060ae69ab8f..73a2fda37fa 100644
--- a/modules/benchmarks/src/naive_infinite_scroll/scroll_item.js
+++ b/modules/benchmarks/src/naive_infinite_scroll/scroll_item.js
@@ -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: `
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
`
- }),
bind: {
'offering': 'offering'
}
+ }),
+ new Template({
+ directives: [
+ CompanyNameComponent,
+ OpportunityNameComponent,
+ OfferingNameComponent,
+ StageButtonsComponent,
+ AccountCellComponent,
+ FormattedCellComponent
+ ],
+ inline: `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
`
})
]
});
diff --git a/modules/benchmarks/src/tree/tree_benchmark.js b/modules/benchmarks/src/tree/tree_benchmark.js
index b6e35d5a3d2..976360a1318 100644
--- a/modules/benchmarks/src/tree/tree_benchmark.js
+++ b/modules/benchmarks/src/tree/tree_benchmark.js
@@ -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: `
`
- })
- })]
+ })]
});
reflector.registerType(TreeComponent, {
'factory': () => new TreeComponent(),
'parameters': [],
- 'annotations' : [new Component({
- selector: 'tree',
- bind: {
- 'data': 'data'
- },
- template: new TemplateConfig({
- directives: [TreeComponent, NgIf],
- inline: `
{{data.value}} `
- })
- })]
+ 'annotations' : [
+ new Component({
+ selector: 'tree',
+ bind: {'data': 'data'}
+ }),
+ new Template({
+ directives: [TreeComponent, NgIf],
+ inline: `
{{data.value}} `
+ })]
});
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': [],
diff --git a/modules/examples/src/gestures/index.js b/modules/examples/src/gestures/index.js
index 6e82ec6e2fb..5b44d2b6cb7 100644
--- a/modules/examples/src/gestures/index.js
+++ b/modules/examples/src/gestures/index.js
@@ -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;
diff --git a/modules/examples/src/hello_world/index_common.js b/modules/examples/src/hello_world/index_common.js
index afe32db9c1d..3ed4672da7a 100644
--- a/modules/examples/src/hello_world/index_common.js
+++ b/modules/examples/src/hello_world/index_common.js
@@ -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: `
{{greeting}} world !
-
change greeting `,
- // 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: `
{{greeting}} world !
+
change greeting `,
+ // 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;
diff --git a/modules/examples/src/hello_world/index_static.js b/modules/examples/src/hello_world/index_static.js
index 7f5e4e7969e..9f425ae1be7 100644
--- a/modules/examples/src/hello_world/index_static.js
+++ b/modules/examples/src/hello_world/index_static.js
@@ -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: `
{{greeting}} world !
-
change greeting `})
- })]
+
change greeting `
+ })]
});
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": [],