Skip to content

Commit e85aba3

Browse files
committed
cacdead feat(core): introduce template context
1 parent e9906cc commit e85aba3

40 files changed

+597
-495
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ tmp
2121
*.js.deps
2222
*.js.map
2323

24+
# Files created by the template compiler
25+
**/*.ngfactory.ts
26+
2427
# Or type definitions we mirror from github
2528
# (NB: these lines are removed in publish-build-artifacts.sh)
2629

BUILD_INFO

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
Fri Apr 29 03:19:14 UTC 2016
2-
30de2db3496cc51407fde1c55dee6a2ba8ce610d
1+
Fri Apr 29 08:39:29 UTC 2016
2+
cacdead96dcfbb80dff899b5f5143b7c28c4d6dd

lib/src/common/directives/ng_for.dart

+38-19
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,28 @@ import "../../core/change_detection/differs/default_iterable_differ.dart"
1717
show DefaultIterableDiffer, CollectionChangeRecord;
1818
import "../../facade/exceptions.dart" show BaseException;
1919

20+
class NgForRow {
21+
dynamic $implicit;
22+
num index;
23+
num count;
24+
NgForRow(this.$implicit, this.index, this.count) {}
25+
bool get first {
26+
return identical(this.index, 0);
27+
}
28+
29+
bool get last {
30+
return identical(this.index, this.count - 1);
31+
}
32+
33+
bool get even {
34+
return identical(this.index % 2, 0);
35+
}
36+
37+
bool get odd {
38+
return !this.even;
39+
}
40+
}
41+
2042
/**
2143
* The `NgFor` directive instantiates a template once per item from an iterable. The context for
2244
* each instantiated template inherits from the outer context with the given loop variable set
@@ -73,7 +95,7 @@ import "../../facade/exceptions.dart" show BaseException;
7395
inputs: const ["ngForTrackBy", "ngForOf", "ngForTemplate"])
7496
class NgFor implements DoCheck {
7597
ViewContainerRef _viewContainer;
76-
TemplateRef _templateRef;
98+
TemplateRef<NgForRow> _templateRef;
7799
IterableDiffers _iterableDiffers;
78100
ChangeDetectorRef _cdr;
79101
/** @internal */
@@ -98,7 +120,7 @@ class NgFor implements DoCheck {
98120
}
99121
}
100122

101-
set ngForTemplate(TemplateRef value) {
123+
set ngForTemplate(TemplateRef<NgForRow> value) {
102124
if (isPresent(value)) {
103125
this._templateRef = value;
104126
}
@@ -132,22 +154,20 @@ class NgFor implements DoCheck {
132154
this._perViewChange(insertTuples[i].view, insertTuples[i].record);
133155
}
134156
for (var i = 0, ilen = this._viewContainer.length; i < ilen; i++) {
135-
var viewRef = (this._viewContainer.get(i) as EmbeddedViewRef);
136-
viewRef.setLocal("first", identical(i, 0));
137-
viewRef.setLocal("last", identical(i, ilen - 1));
157+
var viewRef = (this._viewContainer.get(i) as EmbeddedViewRef<NgForRow>);
158+
viewRef.context.index = i;
159+
viewRef.context.count = ilen;
138160
}
139161
changes.forEachIdentityChange((record) {
140-
var viewRef =
141-
(this._viewContainer.get(record.currentIndex) as EmbeddedViewRef);
142-
viewRef.setLocal("\$implicit", record.item);
162+
var viewRef = (this._viewContainer.get(record.currentIndex)
163+
as EmbeddedViewRef<NgForRow>);
164+
viewRef.context.$implicit = record.item;
143165
});
144166
}
145167

146-
_perViewChange(EmbeddedViewRef view, CollectionChangeRecord record) {
147-
view.setLocal("\$implicit", record.item);
148-
view.setLocal("index", record.currentIndex);
149-
view.setLocal("even", (record.currentIndex % 2 == 0));
150-
view.setLocal("odd", (record.currentIndex % 2 == 1));
168+
_perViewChange(
169+
EmbeddedViewRef<NgForRow> view, CollectionChangeRecord record) {
170+
view.context.$implicit = record.item;
151171
}
152172

153173
List<RecordViewTuple> _bulkRemove(List<RecordViewTuple> tuples) {
@@ -159,7 +179,7 @@ class NgFor implements DoCheck {
159179
// separate moved views from removed views.
160180
if (isPresent(tuple.record.currentIndex)) {
161181
tuple.view = (this._viewContainer.detach(tuple.record.previousIndex)
162-
as EmbeddedViewRef);
182+
as EmbeddedViewRef<NgForRow>);
163183
movedTuples.add(tuple);
164184
} else {
165185
this._viewContainer.remove(tuple.record.previousIndex);
@@ -175,19 +195,18 @@ class NgFor implements DoCheck {
175195
if (isPresent(tuple.view)) {
176196
this._viewContainer.insert(tuple.view, tuple.record.currentIndex);
177197
} else {
178-
tuple.view = this
179-
._viewContainer
180-
.createEmbeddedView(this._templateRef, tuple.record.currentIndex);
198+
tuple.view = this._viewContainer.createEmbeddedView(this._templateRef,
199+
new NgForRow(null, null, null), tuple.record.currentIndex);
181200
}
182201
}
183202
return tuples;
184203
}
185204
}
186205

187206
class RecordViewTuple {
188-
EmbeddedViewRef view;
207+
EmbeddedViewRef<NgForRow> view;
189208
dynamic record;
190-
RecordViewTuple(dynamic record, EmbeddedViewRef view) {
209+
RecordViewTuple(dynamic record, EmbeddedViewRef<NgForRow> view) {
191210
this.record = record;
192211
this.view = view;
193212
}

lib/src/common/directives/ng_if.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import "package:angular2/src/facade/lang.dart" show isBlank;
2929
@Directive(selector: "[ngIf]", inputs: const ["ngIf"])
3030
class NgIf {
3131
ViewContainerRef _viewContainer;
32-
TemplateRef _templateRef;
32+
TemplateRef<Object> _templateRef;
3333
bool _prevCondition = null;
3434
NgIf(this._viewContainer, this._templateRef) {}
3535
set ngIf(dynamic newCondition) {

lib/src/common/directives/ng_plural.dart

+2-2
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ class NgPluralCase {
8080
String value;
8181
/** @internal */
8282
SwitchView _view;
83-
NgPluralCase(@Attribute("ngPluralCase") this.value, TemplateRef template,
84-
ViewContainerRef viewContainer) {
83+
NgPluralCase(@Attribute("ngPluralCase") this.value,
84+
TemplateRef<Object> template, ViewContainerRef viewContainer) {
8585
this._view = new SwitchView(viewContainer, template);
8686
}
8787
}

lib/src/common/directives/ng_switch.dart

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const _WHEN_DEFAULT = const Object();
99

1010
class SwitchView {
1111
ViewContainerRef _viewContainerRef;
12-
TemplateRef _templateRef;
12+
TemplateRef<Object> _templateRef;
1313
SwitchView(this._viewContainerRef, this._templateRef) {}
1414
void create() {
1515
this._viewContainerRef.createEmbeddedView(this._templateRef);
@@ -179,7 +179,7 @@ class NgSwitchWhen {
179179
/** @internal */
180180
SwitchView _view;
181181
NgSwitch _switch;
182-
NgSwitchWhen(ViewContainerRef viewContainer, TemplateRef templateRef,
182+
NgSwitchWhen(ViewContainerRef viewContainer, TemplateRef<Object> templateRef,
183183
@Host() NgSwitch ngSwitch) {
184184
this._switch = ngSwitch;
185185
this._view = new SwitchView(viewContainer, templateRef);
@@ -198,8 +198,8 @@ class NgSwitchWhen {
198198
*/
199199
@Directive(selector: "[ngSwitchDefault]")
200200
class NgSwitchDefault {
201-
NgSwitchDefault(ViewContainerRef viewContainer, TemplateRef templateRef,
202-
@Host() NgSwitch sswitch) {
201+
NgSwitchDefault(ViewContainerRef viewContainer,
202+
TemplateRef<Object> templateRef, @Host() NgSwitch sswitch) {
203203
sswitch._registerView(
204204
_WHEN_DEFAULT, new SwitchView(viewContainer, templateRef));
205205
}

lib/src/common/directives/ng_template_outlet.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class NgTemplateOutlet {
1616
ViewRef _insertedViewRef;
1717
NgTemplateOutlet(this._viewContainerRef) {}
1818
@Input()
19-
set ngTemplateOutlet(TemplateRef templateRef) {
19+
set ngTemplateOutlet(TemplateRef<Object> templateRef) {
2020
if (isPresent(this._insertedViewRef)) {
2121
this
2222
._viewContainerRef

lib/src/compiler/compile_metadata.dart

+8-3
Original file line numberDiff line numberDiff line change
@@ -445,13 +445,15 @@ class CompileTemplateMetadata {
445445
List<String> styles;
446446
List<String> styleUrls;
447447
List<String> ngContentSelectors;
448+
String baseUrl;
448449
CompileTemplateMetadata(
449450
{encapsulation,
450451
template,
451452
templateUrl,
452453
styles,
453454
styleUrls,
454-
ngContentSelectors}) {
455+
ngContentSelectors,
456+
baseUrl}) {
455457
this.encapsulation =
456458
isPresent(encapsulation) ? encapsulation : ViewEncapsulation.Emulated;
457459
this.template = template;
@@ -460,6 +462,7 @@ class CompileTemplateMetadata {
460462
this.styleUrls = isPresent(styleUrls) ? styleUrls : [];
461463
this.ngContentSelectors =
462464
isPresent(ngContentSelectors) ? ngContentSelectors : [];
465+
this.baseUrl = baseUrl;
463466
}
464467
static CompileTemplateMetadata fromJson(Map<String, dynamic> data) {
465468
return new CompileTemplateMetadata(
@@ -470,7 +473,8 @@ class CompileTemplateMetadata {
470473
templateUrl: data["templateUrl"],
471474
styles: data["styles"],
472475
styleUrls: data["styleUrls"],
473-
ngContentSelectors: data["ngContentSelectors"]);
476+
ngContentSelectors: data["ngContentSelectors"],
477+
baseUrl: data["baseUrl"]);
474478
}
475479

476480
Map<String, dynamic> toJson() {
@@ -482,7 +486,8 @@ class CompileTemplateMetadata {
482486
"templateUrl": this.templateUrl,
483487
"styles": this.styles,
484488
"styleUrls": this.styleUrls,
485-
"ngContentSelectors": this.ngContentSelectors
489+
"ngContentSelectors": this.ngContentSelectors,
490+
"baseUrl": this.baseUrl
486491
};
487492
}
488493
}

lib/src/compiler/directive_normalizer.dart

+4-5
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,10 @@ class DirectiveNormalizer {
6868
CompileTypeMetadata directiveType, CompileTemplateMetadata template) {
6969
if (isPresent(template.template)) {
7070
return PromiseWrapper.resolve(this.normalizeLoadedTemplate(
71-
directiveType, template, template.template, directiveType.moduleUrl));
71+
directiveType, template, template.template, template.baseUrl));
7272
} else if (isPresent(template.templateUrl)) {
73-
var sourceAbsUrl = this
74-
._urlResolver
75-
.resolve(directiveType.moduleUrl, template.templateUrl);
73+
var sourceAbsUrl =
74+
this._urlResolver.resolve(template.baseUrl, template.templateUrl);
7675
return this._xhr.get(sourceAbsUrl).then((templateContent) => this
7776
.normalizeLoadedTemplate(
7877
directiveType, template, templateContent, sourceAbsUrl));
@@ -106,7 +105,7 @@ ${ errorString}''');
106105
..addAll(templateMeta.styleUrls
107106
.where(isStyleUrlResolvable)
108107
.toList()
109-
.map((url) => this._urlResolver.resolve(directiveType.moduleUrl, url))
108+
.map((url) => this._urlResolver.resolve(templateMeta.baseUrl, url))
110109
.toList()));
111110
var allResolvedStyles = allStyles.map((style) {
112111
var styleWithImports =

lib/src/compiler/metadata_resolver.dart

+13-10
Original file line numberDiff line numberDiff line change
@@ -87,22 +87,22 @@ class CompileMetadataResolver {
8787
var meta = this._directiveCache[directiveType];
8888
if (isBlank(meta)) {
8989
var dirMeta = this._directiveResolver.resolve(directiveType);
90-
var moduleUrl = staticTypeModuleUrl(directiveType);
9190
var templateMeta = null;
9291
var changeDetectionStrategy = null;
9392
var viewProviders = [];
9493
if (dirMeta is md.ComponentMetadata) {
9594
assertArrayOfStrings("styles", dirMeta.styles);
9695
var cmpMeta = (dirMeta as md.ComponentMetadata);
97-
moduleUrl = calcModuleUrl(this._reflector, directiveType, cmpMeta);
9896
var viewMeta = this._viewResolver.resolve(directiveType);
9997
assertArrayOfStrings("styles", viewMeta.styles);
10098
templateMeta = new cpl.CompileTemplateMetadata(
10199
encapsulation: viewMeta.encapsulation,
102100
template: viewMeta.template,
103101
templateUrl: viewMeta.templateUrl,
104102
styles: viewMeta.styles,
105-
styleUrls: viewMeta.styleUrls);
103+
styleUrls: viewMeta.styleUrls,
104+
baseUrl:
105+
calcTemplateBaseUrl(this._reflector, directiveType, cmpMeta));
106106
changeDetectionStrategy = cmpMeta.changeDetection;
107107
if (isPresent(dirMeta.viewProviders)) {
108108
viewProviders = this.getProvidersMetadata(dirMeta.viewProviders);
@@ -122,7 +122,8 @@ class CompileMetadataResolver {
122122
selector: dirMeta.selector,
123123
exportAs: dirMeta.exportAs,
124124
isComponent: isPresent(templateMeta),
125-
type: this.getTypeMetadata(directiveType, moduleUrl),
125+
type: this.getTypeMetadata(
126+
directiveType, staticTypeModuleUrl(directiveType)),
126127
template: templateMeta,
127128
changeDetection: changeDetectionStrategy,
128129
inputs: dirMeta.inputs,
@@ -414,15 +415,17 @@ String staticTypeModuleUrl(dynamic value) {
414415
return isStaticType(value) ? value["moduleId"] : null;
415416
}
416417

417-
String calcModuleUrl(
418-
ReflectorReader reflector, Type type, md.ComponentMetadata cmpMetadata) {
419-
var moduleId = cmpMetadata.moduleId;
420-
if (isPresent(moduleId)) {
418+
String calcTemplateBaseUrl(
419+
ReflectorReader reflector, dynamic type, md.ComponentMetadata cmpMetadata) {
420+
if (isStaticType(type)) {
421+
return type["filePath"];
422+
}
423+
if (isPresent(cmpMetadata.moduleId)) {
424+
var moduleId = cmpMetadata.moduleId;
421425
var scheme = getUrlScheme(moduleId);
422426
return isPresent(scheme) && scheme.length > 0
423427
? moduleId
424428
: '''package:${ moduleId}${ MODULE_SUFFIX}''';
425-
} else {
426-
return reflector.importUri(type);
427429
}
430+
return reflector.importUri(type);
428431
}

lib/src/compiler/output/interpretive_view.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class _InterpretiveAppView extends AppView<dynamic> implements DynamicInstance {
2929
_InterpretiveAppView(
3030
List<dynamic> args, this.props, this.getters, this.methods)
3131
: super(args[0], args[1], args[2], args[3], args[4], args[5], args[6],
32-
args[7], args[8]) {
32+
args[7]) {
3333
/* super call moved to initializer */;
3434
}
3535
AppElement createInternal(dynamic /* String | dynamic */ rootSelector) {

0 commit comments

Comments
 (0)