Skip to content

Commit 0f774df

Browse files
committed
fix(compiler): project using the right directive as component.
Closes angular#8344
1 parent 351f24e commit 0f774df

File tree

7 files changed

+41
-19
lines changed

7 files changed

+41
-19
lines changed

modules/angular2/src/compiler/template_ast.ts

-13
Original file line numberDiff line numberDiff line change
@@ -116,19 +116,6 @@ export class ElementAst implements TemplateAst {
116116
visit(visitor: TemplateAstVisitor, context: any): any {
117117
return visitor.visitElement(this, context);
118118
}
119-
120-
/**
121-
* Get the component associated with this element, if any.
122-
*/
123-
getComponent(): CompileDirectiveMetadata {
124-
for (var i = 0; i < this.directives.length; i++) {
125-
var dirAst = this.directives[i];
126-
if (dirAst.directive.isComponent) {
127-
return dirAst.directive;
128-
}
129-
}
130-
return null;
131-
}
132119
}
133120

134121
/**

modules/angular2/src/compiler/template_parser.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -847,8 +847,9 @@ class ElementContext {
847847
providerContext: ProviderElementContext): ElementContext {
848848
var matcher = new SelectorMatcher();
849849
var wildcardNgContentIndex = null;
850-
if (directives.length > 0 && directives[0].directive.isComponent) {
851-
var ngContentSelectors = directives[0].directive.template.ngContentSelectors;
850+
var component = directives.find(directive => directive.directive.isComponent);
851+
if (isPresent(component)) {
852+
var ngContentSelectors = component.directive.template.ngContentSelectors;
852853
for (var i = 0; i < ngContentSelectors.length; i++) {
853854
var selector = ngContentSelectors[i];
854855
if (StringWrapper.equals(selector, '*')) {

modules/angular2/src/compiler/view_compiler/view_builder.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,8 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
200200

201201
var renderNode = o.THIS_EXPR.prop(fieldName);
202202

203-
var component = ast.getComponent();
204203
var directives = ast.directives.map(directiveAst => directiveAst.directive);
204+
var component = directives.find(directive => directive.isComponent);
205205
var htmlAttrs = _readHtmlAttrs(ast.attrs);
206206
var attrNameAndValues = _mergeHtmlAndDirectiveAttrs(htmlAttrs, directives);
207207
for (var i = 0; i < attrNameAndValues.length; i++) {

modules/angular2/src/core/linker/view_utils.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,8 @@ export function castByValue<T>(input: any, value: T): T {
156156
return <T>input;
157157
}
158158

159-
export const EMPTY_ARRAY = CONST_EXPR([]);
160-
export const EMPTY_MAP = CONST_EXPR({});
159+
export const EMPTY_ARRAY = /*@ts2dart_const*/[];
160+
export const EMPTY_MAP = /*@ts2dart_const*/ {};
161161

162162
export function pureProxy1<P0, R>(fn: (p0: P0) => R): (p0: P0) => R {
163163
var result: R;

modules/angular2/test/compiler/template_parser_spec.ts

+14
Original file line numberDiff line numberDiff line change
@@ -1027,6 +1027,14 @@ There is no directive with "exportAs" set to "dirA" ("<div [ERROR ->]#a="dirA"><
10271027
})
10281028
}
10291029

1030+
function createDir(selector: string): CompileDirectiveMetadata {
1031+
return CompileDirectiveMetadata.create({
1032+
selector: selector,
1033+
type:
1034+
new CompileTypeMetadata({moduleUrl: someModuleUrl, name: `SomeDir${compCounter++}`})
1035+
})
1036+
}
1037+
10301038
describe('project text nodes', () => {
10311039
it('should project text nodes with wildcard selector', () => {
10321040
expect(humanizeContentProjection(parse('<div>hello</div>', [createComp('div', ['*'])])))
@@ -1140,6 +1148,12 @@ There is no directive with "exportAs" set to "dirA" ("<div [ERROR ->]#a="dirA"><
11401148
.toEqual([['div', null], ['template', 1], ['a', null]]);
11411149
});
11421150
});
1151+
1152+
it('should support other directives before the component', () => {
1153+
expect(humanizeContentProjection(
1154+
parse('<div>hello</div>', [createDir('div'), createComp('div', ['*'])])))
1155+
.toEqual([['div', null], ['#text(hello)', 0]]);
1156+
});
11431157
});
11441158

11451159
describe('splitClasses', () => {

modules/angular2/test/core/linker/regression_integration_spec.ts

+21
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import {
3333
OpaqueToken,
3434
Injector
3535
} from 'angular2/core';
36+
import {NgIf, NgClass} from 'angular2/common';
3637
import {CompilerConfig} from 'angular2/compiler';
3738

3839
export function main() {
@@ -170,6 +171,22 @@ function declareTests(isJit: boolean) {
170171
});
171172
}));
172173

174+
it('should support ngClass before a component and content projection inside of an ngIf',
175+
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
176+
tcb.overrideView(
177+
MyComp, new ViewMetadata({
178+
template: `A<cmp-content *ngIf="true" [ngClass]="'red'">B</cmp-content>C`,
179+
directives: [NgClass, NgIf, CmpWithNgContent]
180+
}))
181+
.createAsync(MyComp)
182+
.then((fixture) => {
183+
fixture.detectChanges();
184+
expect(fixture.nativeElement).toHaveText('ABC');
185+
async.done();
186+
});
187+
}));
188+
189+
173190
});
174191
}
175192

@@ -187,3 +204,7 @@ class PlatformPipe implements PipeTransform {
187204
class CustomPipe implements PipeTransform {
188205
transform(value: any): any { return 'someCustomPipe'; }
189206
}
207+
208+
@Component({selector: 'cmp-content', template: `<ng-content></ng-content>`})
209+
class CmpWithNgContent {
210+
}

tools/public_api_guard/public_api_spec.ts

-1
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,6 @@ const COMPILER = [
850850
'DirectiveAst.visit(visitor:TemplateAstVisitor, context:any):any',
851851
'ElementAst',
852852
'ElementAst.constructor(name:string, attrs:AttrAst[], inputs:BoundElementPropertyAst[], outputs:BoundEventAst[], references:ReferenceAst[], directives:DirectiveAst[], providers:ProviderAst[], hasViewContainer:boolean, children:TemplateAst[], ngContentIndex:number, sourceSpan:ParseSourceSpan)',
853-
'ElementAst.getComponent():CompileDirectiveMetadata',
854853
'ElementAst.visit(visitor:TemplateAstVisitor, context:any):any',
855854
'EmbeddedTemplateAst',
856855
'EmbeddedTemplateAst.constructor(attrs:AttrAst[], outputs:BoundEventAst[], references:ReferenceAst[], variables:VariableAst[], directives:DirectiveAst[], providers:ProviderAst[], hasViewContainer:boolean, children:TemplateAst[], ngContentIndex:number, sourceSpan:ParseSourceSpan)',

0 commit comments

Comments
 (0)