fix(ivy): "select" attribute on <ng-content> should not be case-sensitive (FW-789) (#27500)

While generating attributes for `projection` instruction, we checked whether attribute name is equal to 'select' in lower case. However in other cases we treat 'select' attribute name as case-insensitive. This PR makes 'select' attribute consistently case-insensitive.

PR Close #27500
This commit is contained in:
Andrew Kushnir 2018-12-05 21:17:35 -08:00 committed by Igor Minar
parent c71d7b5633
commit cad67148b1
3 changed files with 25 additions and 22 deletions

View File

@ -1026,7 +1026,7 @@ describe('compiler compliance', () => {
selector: 'complex', selector: 'complex',
template: \` template: \`
<div id="first"><ng-content select="span[title=toFirst]"></ng-content></div> <div id="first"><ng-content select="span[title=toFirst]"></ng-content></div>
<div id="second"><ng-content select="span[title=toSecond]"></ng-content></div>\` <div id="second"><ng-content SELECT="span[title=toSecond]"></ng-content></div>\`
}) })
export class ComplexComponent { } export class ComplexComponent { }
@ -1104,7 +1104,7 @@ describe('compiler compliance', () => {
@Component({ @Component({
template: \` template: \`
<div id="second" *ngIf="visible"> <div id="second" *ngIf="visible">
<ng-content select="span[title=toFirst]"></ng-content> <ng-content SELECT="span[title=toFirst]"></ng-content>
</div> </div>
<div id="third" *ngIf="visible"> <div id="third" *ngIf="visible">
No ng-content, no instructions generated. No ng-content, no instructions generated.

View File

@ -59,7 +59,11 @@ export function renderFlagCheckIfStmt(
} }
// Default selector used by `<ng-content>` if none specified // Default selector used by `<ng-content>` if none specified
const DEFAULT_CONTENT_SELECTOR = '*'; const DEFAULT_NG_CONTENT_SELECTOR = '*';
// Selector attribute name of `<ng-content>`
const NG_CONTENT_SELECT_ATTR = 'select';
export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver { export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver {
private _dataIndex = 0; private _dataIndex = 0;
private _bindingContext = 0; private _bindingContext = 0;
@ -411,7 +415,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
visitContent(ngContent: t.Content) { visitContent(ngContent: t.Content) {
this._hasNgContent = true; this._hasNgContent = true;
const slot = this.allocateDataSlot(); const slot = this.allocateDataSlot();
let selectorIndex = ngContent.selector === DEFAULT_CONTENT_SELECTOR ? let selectorIndex = ngContent.selector === DEFAULT_NG_CONTENT_SELECTOR ?
0 : 0 :
this._ngContentSelectors.push(ngContent.selector); this._ngContentSelectors.push(ngContent.selector);
const parameters: o.Expression[] = [o.literal(slot)]; const parameters: o.Expression[] = [o.literal(slot)];
@ -419,9 +423,9 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
const attributeAsList: string[] = []; const attributeAsList: string[] = [];
ngContent.attributes.forEach((attribute) => { ngContent.attributes.forEach((attribute) => {
const name = attribute.name; const {name, value} = attribute;
if (name !== 'select') { if (name.toLowerCase() !== NG_CONTENT_SELECT_ATTR) {
attributeAsList.push(name, attribute.value); attributeAsList.push(name, value);
} }
}); });

View File

@ -81,8 +81,7 @@ describe('projection', () => {
expect(main.nativeElement).toHaveText(''); expect(main.nativeElement).toHaveText('');
}); });
fixmeIvy('FW-789: select attribute on <ng-content> should not be case-sensitive') fixmeIvy('unknown').it('should support multiple content tags', () => {
.it('should support multiple content tags', () => {
TestBed.configureTestingModule({declarations: [MultipleContentTagsComponent]}); TestBed.configureTestingModule({declarations: [MultipleContentTagsComponent]});
TestBed.overrideComponent(MainComp, { TestBed.overrideComponent(MainComp, {
set: { set: {