diff --git a/modules/angular2/src/compiler/template_ast.ts b/modules/angular2/src/compiler/template_ast.ts index a0c00ecf8e..06d1e959ea 100644 --- a/modules/angular2/src/compiler/template_ast.ts +++ b/modules/angular2/src/compiler/template_ast.ts @@ -116,19 +116,6 @@ export class ElementAst implements TemplateAst { visit(visitor: TemplateAstVisitor, context: any): any { return visitor.visitElement(this, context); } - - /** - * Get the component associated with this element, if any. - */ - getComponent(): CompileDirectiveMetadata { - for (var i = 0; i < this.directives.length; i++) { - var dirAst = this.directives[i]; - if (dirAst.directive.isComponent) { - return dirAst.directive; - } - } - return null; - } } /** diff --git a/modules/angular2/src/compiler/template_parser.ts b/modules/angular2/src/compiler/template_parser.ts index 3e5655ca8f..a199a7fb52 100644 --- a/modules/angular2/src/compiler/template_parser.ts +++ b/modules/angular2/src/compiler/template_parser.ts @@ -847,8 +847,9 @@ class ElementContext { providerContext: ProviderElementContext): ElementContext { var matcher = new SelectorMatcher(); var wildcardNgContentIndex = null; - if (directives.length > 0 && directives[0].directive.isComponent) { - var ngContentSelectors = directives[0].directive.template.ngContentSelectors; + var component = directives.find(directive => directive.directive.isComponent); + if (isPresent(component)) { + var ngContentSelectors = component.directive.template.ngContentSelectors; for (var i = 0; i < ngContentSelectors.length; i++) { var selector = ngContentSelectors[i]; if (StringWrapper.equals(selector, '*')) { diff --git a/modules/angular2/src/compiler/view_compiler/view_builder.ts b/modules/angular2/src/compiler/view_compiler/view_builder.ts index 1b6ca5a1e0..f4a45bd014 100644 --- a/modules/angular2/src/compiler/view_compiler/view_builder.ts +++ b/modules/angular2/src/compiler/view_compiler/view_builder.ts @@ -200,8 +200,8 @@ class ViewBuilderVisitor implements TemplateAstVisitor { var renderNode = o.THIS_EXPR.prop(fieldName); - var component = ast.getComponent(); var directives = ast.directives.map(directiveAst => directiveAst.directive); + var component = directives.find(directive => directive.isComponent); var htmlAttrs = _readHtmlAttrs(ast.attrs); var attrNameAndValues = _mergeHtmlAndDirectiveAttrs(htmlAttrs, directives); for (var i = 0; i < attrNameAndValues.length; i++) { diff --git a/modules/angular2/src/core/linker/view_utils.ts b/modules/angular2/src/core/linker/view_utils.ts index 93b8b82f5a..33ab6d0ec4 100644 --- a/modules/angular2/src/core/linker/view_utils.ts +++ b/modules/angular2/src/core/linker/view_utils.ts @@ -156,8 +156,8 @@ export function castByValue<T>(input: any, value: T): T { return <T>input; } -export const EMPTY_ARRAY = CONST_EXPR([]); -export const EMPTY_MAP = CONST_EXPR({}); +export const EMPTY_ARRAY = /*@ts2dart_const*/[]; +export const EMPTY_MAP = /*@ts2dart_const*/ {}; export function pureProxy1<P0, R>(fn: (p0: P0) => R): (p0: P0) => R { var result: R; diff --git a/modules/angular2/test/compiler/template_parser_spec.ts b/modules/angular2/test/compiler/template_parser_spec.ts index f8232c31d7..f4a017ec6b 100644 --- a/modules/angular2/test/compiler/template_parser_spec.ts +++ b/modules/angular2/test/compiler/template_parser_spec.ts @@ -1027,6 +1027,14 @@ There is no directive with "exportAs" set to "dirA" ("<div [ERROR ->]#a="dirA">< }) } + function createDir(selector: string): CompileDirectiveMetadata { + return CompileDirectiveMetadata.create({ + selector: selector, + type: + new CompileTypeMetadata({moduleUrl: someModuleUrl, name: `SomeDir${compCounter++}`}) + }) + } + describe('project text nodes', () => { it('should project text nodes with wildcard selector', () => { 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">< .toEqual([['div', null], ['template', 1], ['a', null]]); }); }); + + it('should support other directives before the component', () => { + expect(humanizeContentProjection( + parse('<div>hello</div>', [createDir('div'), createComp('div', ['*'])]))) + .toEqual([['div', null], ['#text(hello)', 0]]); + }); }); describe('splitClasses', () => { diff --git a/modules/angular2/test/core/linker/regression_integration_spec.ts b/modules/angular2/test/core/linker/regression_integration_spec.ts index 233ca73a31..cdb5693e02 100644 --- a/modules/angular2/test/core/linker/regression_integration_spec.ts +++ b/modules/angular2/test/core/linker/regression_integration_spec.ts @@ -33,6 +33,7 @@ import { OpaqueToken, Injector } from 'angular2/core'; +import {NgIf, NgClass} from 'angular2/common'; import {CompilerConfig} from 'angular2/compiler'; export function main() { @@ -170,6 +171,22 @@ function declareTests(isJit: boolean) { }); })); + it('should support ngClass before a component and content projection inside of an ngIf', + inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => { + tcb.overrideView( + MyComp, new ViewMetadata({ + template: `A<cmp-content *ngIf="true" [ngClass]="'red'">B</cmp-content>C`, + directives: [NgClass, NgIf, CmpWithNgContent] + })) + .createAsync(MyComp) + .then((fixture) => { + fixture.detectChanges(); + expect(fixture.nativeElement).toHaveText('ABC'); + async.done(); + }); + })); + + }); } @@ -187,3 +204,7 @@ class PlatformPipe implements PipeTransform { class CustomPipe implements PipeTransform { transform(value: any): any { return 'someCustomPipe'; } } + +@Component({selector: 'cmp-content', template: `<ng-content></ng-content>`}) +class CmpWithNgContent { +} diff --git a/tools/public_api_guard/public_api_spec.ts b/tools/public_api_guard/public_api_spec.ts index 480d3b33de..f7975fa70d 100644 --- a/tools/public_api_guard/public_api_spec.ts +++ b/tools/public_api_guard/public_api_spec.ts @@ -850,7 +850,6 @@ const COMPILER = [ 'DirectiveAst.visit(visitor:TemplateAstVisitor, context:any):any', 'ElementAst', 'ElementAst.constructor(name:string, attrs:AttrAst[], inputs:BoundElementPropertyAst[], outputs:BoundEventAst[], references:ReferenceAst[], directives:DirectiveAst[], providers:ProviderAst[], hasViewContainer:boolean, children:TemplateAst[], ngContentIndex:number, sourceSpan:ParseSourceSpan)', - 'ElementAst.getComponent():CompileDirectiveMetadata', 'ElementAst.visit(visitor:TemplateAstVisitor, context:any):any', 'EmbeddedTemplateAst', 'EmbeddedTemplateAst.constructor(attrs:AttrAst[], outputs:BoundEventAst[], references:ReferenceAst[], variables:VariableAst[], directives:DirectiveAst[], providers:ProviderAst[], hasViewContainer:boolean, children:TemplateAst[], ngContentIndex:number, sourceSpan:ParseSourceSpan)',