fix(compiler): project using the right directive as component.
Closes #8344
This commit is contained in:
parent
351f24e8eb
commit
0f774df811
@ -116,19 +116,6 @@ export class ElementAst implements TemplateAst {
|
|||||||
visit(visitor: TemplateAstVisitor, context: any): any {
|
visit(visitor: TemplateAstVisitor, context: any): any {
|
||||||
return visitor.visitElement(this, context);
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -847,8 +847,9 @@ class ElementContext {
|
|||||||
providerContext: ProviderElementContext): ElementContext {
|
providerContext: ProviderElementContext): ElementContext {
|
||||||
var matcher = new SelectorMatcher();
|
var matcher = new SelectorMatcher();
|
||||||
var wildcardNgContentIndex = null;
|
var wildcardNgContentIndex = null;
|
||||||
if (directives.length > 0 && directives[0].directive.isComponent) {
|
var component = directives.find(directive => directive.directive.isComponent);
|
||||||
var ngContentSelectors = directives[0].directive.template.ngContentSelectors;
|
if (isPresent(component)) {
|
||||||
|
var ngContentSelectors = component.directive.template.ngContentSelectors;
|
||||||
for (var i = 0; i < ngContentSelectors.length; i++) {
|
for (var i = 0; i < ngContentSelectors.length; i++) {
|
||||||
var selector = ngContentSelectors[i];
|
var selector = ngContentSelectors[i];
|
||||||
if (StringWrapper.equals(selector, '*')) {
|
if (StringWrapper.equals(selector, '*')) {
|
||||||
|
@ -200,8 +200,8 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
|
|||||||
|
|
||||||
var renderNode = o.THIS_EXPR.prop(fieldName);
|
var renderNode = o.THIS_EXPR.prop(fieldName);
|
||||||
|
|
||||||
var component = ast.getComponent();
|
|
||||||
var directives = ast.directives.map(directiveAst => directiveAst.directive);
|
var directives = ast.directives.map(directiveAst => directiveAst.directive);
|
||||||
|
var component = directives.find(directive => directive.isComponent);
|
||||||
var htmlAttrs = _readHtmlAttrs(ast.attrs);
|
var htmlAttrs = _readHtmlAttrs(ast.attrs);
|
||||||
var attrNameAndValues = _mergeHtmlAndDirectiveAttrs(htmlAttrs, directives);
|
var attrNameAndValues = _mergeHtmlAndDirectiveAttrs(htmlAttrs, directives);
|
||||||
for (var i = 0; i < attrNameAndValues.length; i++) {
|
for (var i = 0; i < attrNameAndValues.length; i++) {
|
||||||
|
@ -156,8 +156,8 @@ export function castByValue<T>(input: any, value: T): T {
|
|||||||
return <T>input;
|
return <T>input;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const EMPTY_ARRAY = CONST_EXPR([]);
|
export const EMPTY_ARRAY = /*@ts2dart_const*/[];
|
||||||
export const EMPTY_MAP = CONST_EXPR({});
|
export const EMPTY_MAP = /*@ts2dart_const*/ {};
|
||||||
|
|
||||||
export function pureProxy1<P0, R>(fn: (p0: P0) => R): (p0: P0) => R {
|
export function pureProxy1<P0, R>(fn: (p0: P0) => R): (p0: P0) => R {
|
||||||
var result: R;
|
var result: R;
|
||||||
|
@ -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', () => {
|
describe('project text nodes', () => {
|
||||||
it('should project text nodes with wildcard selector', () => {
|
it('should project text nodes with wildcard selector', () => {
|
||||||
expect(humanizeContentProjection(parse('<div>hello</div>', [createComp('div', ['*'])])))
|
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]]);
|
.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', () => {
|
describe('splitClasses', () => {
|
||||||
|
@ -33,6 +33,7 @@ import {
|
|||||||
OpaqueToken,
|
OpaqueToken,
|
||||||
Injector
|
Injector
|
||||||
} from 'angular2/core';
|
} from 'angular2/core';
|
||||||
|
import {NgIf, NgClass} from 'angular2/common';
|
||||||
import {CompilerConfig} from 'angular2/compiler';
|
import {CompilerConfig} from 'angular2/compiler';
|
||||||
|
|
||||||
export function main() {
|
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 {
|
class CustomPipe implements PipeTransform {
|
||||||
transform(value: any): any { return 'someCustomPipe'; }
|
transform(value: any): any { return 'someCustomPipe'; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Component({selector: 'cmp-content', template: `<ng-content></ng-content>`})
|
||||||
|
class CmpWithNgContent {
|
||||||
|
}
|
||||||
|
@ -850,7 +850,6 @@ const COMPILER = [
|
|||||||
'DirectiveAst.visit(visitor:TemplateAstVisitor, context:any):any',
|
'DirectiveAst.visit(visitor:TemplateAstVisitor, context:any):any',
|
||||||
'ElementAst',
|
'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.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',
|
'ElementAst.visit(visitor:TemplateAstVisitor, context:any):any',
|
||||||
'EmbeddedTemplateAst',
|
'EmbeddedTemplateAst',
|
||||||
'EmbeddedTemplateAst.constructor(attrs:AttrAst[], outputs:BoundEventAst[], references:ReferenceAst[], variables:VariableAst[], directives:DirectiveAst[], providers:ProviderAst[], hasViewContainer:boolean, children:TemplateAst[], ngContentIndex:number, sourceSpan:ParseSourceSpan)',
|
'EmbeddedTemplateAst.constructor(attrs:AttrAst[], outputs:BoundEventAst[], references:ReferenceAst[], variables:VariableAst[], directives:DirectiveAst[], providers:ProviderAst[], hasViewContainer:boolean, children:TemplateAst[], ngContentIndex:number, sourceSpan:ParseSourceSpan)',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user