fix(ivy): add unparsed selectors to the `projectionDef` instruction (#23375)
PR Close #23375
This commit is contained in:
parent
ac683d7abb
commit
80e483ceac
|
@ -471,20 +471,31 @@ class TemplateDefinitionBuilder implements TemplateAstVisitor, LocalResolver {
|
||||||
if (this.ngContentSelectors && this.ngContentSelectors.length > 0) {
|
if (this.ngContentSelectors && this.ngContentSelectors.length > 0) {
|
||||||
const contentProjections = getContentProjection(nodes, this.ngContentSelectors);
|
const contentProjections = getContentProjection(nodes, this.ngContentSelectors);
|
||||||
this._contentProjections = contentProjections;
|
this._contentProjections = contentProjections;
|
||||||
|
|
||||||
if (contentProjections.size > 0) {
|
if (contentProjections.size > 0) {
|
||||||
const infos: R3CssSelectorList[] = [];
|
const selectors: string[] = [];
|
||||||
|
|
||||||
Array.from(contentProjections.values()).forEach(info => {
|
Array.from(contentProjections.values()).forEach(info => {
|
||||||
if (info.selector) {
|
if (info.selector) {
|
||||||
infos[info.index - 1] = info.selector;
|
selectors[info.index - 1] = info.selector;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const projectionIndex = this._projectionDefinitionIndex = this.allocateDataSlot();
|
const projectionIndex = this._projectionDefinitionIndex = this.allocateDataSlot();
|
||||||
const parameters: o.Expression[] = [o.literal(projectionIndex)];
|
const parameters: o.Expression[] = [o.literal(projectionIndex)];
|
||||||
!infos.some(value => !value) || error(`content project information skipped an index`);
|
|
||||||
if (infos.length > 1) {
|
if (selectors.some(value => !value)) {
|
||||||
parameters.push(this.outputCtx.constantPool.getConstLiteral(
|
error(`content project information skipped an index`);
|
||||||
asLiteral(infos), /* forceShared */ true));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (selectors.length > 1) {
|
||||||
|
const r3Selectors = selectors.map(s => parseSelectorToR3Selector(s));
|
||||||
|
// `projectionDef` needs both the parsed and raw value of the selectors
|
||||||
|
const parsed = this.outputCtx.constantPool.getConstLiteral(asLiteral(r3Selectors), true);
|
||||||
|
const unParsed = this.outputCtx.constantPool.getConstLiteral(asLiteral(selectors), true);
|
||||||
|
parameters.push(parsed, unParsed);
|
||||||
|
}
|
||||||
|
|
||||||
this.instruction(this._creationMode, null, R3.projectionDef, ...parameters);
|
this.instruction(this._creationMode, null, R3.projectionDef, ...parameters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1016,7 +1027,7 @@ type HostBindings = {
|
||||||
|
|
||||||
// Turn a directive selector into an R3-compatible selector for directive def
|
// Turn a directive selector into an R3-compatible selector for directive def
|
||||||
function createDirectiveSelector(selector: string): o.Expression {
|
function createDirectiveSelector(selector: string): o.Expression {
|
||||||
return asLiteral(parseSelectorsToR3Selector(CssSelector.parse(selector)));
|
return asLiteral(parseSelectorToR3Selector(selector));
|
||||||
}
|
}
|
||||||
|
|
||||||
function createHostAttributesArray(
|
function createHostAttributesArray(
|
||||||
|
@ -1186,7 +1197,7 @@ function invalid<T>(arg: o.Expression | o.Statement | TemplateAst): never {
|
||||||
|
|
||||||
interface NgContentInfo {
|
interface NgContentInfo {
|
||||||
index: number;
|
index: number;
|
||||||
selector?: R3CssSelectorList;
|
selector?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ContentProjectionVisitor extends RecursiveTemplateAstVisitor {
|
class ContentProjectionVisitor extends RecursiveTemplateAstVisitor {
|
||||||
|
@ -1198,15 +1209,15 @@ class ContentProjectionVisitor extends RecursiveTemplateAstVisitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
visitNgContent(ngContent: NgContentAst) {
|
visitNgContent(ngContent: NgContentAst) {
|
||||||
const selectorText = this.ngContentSelectors[ngContent.index];
|
const selector = this.ngContentSelectors[ngContent.index];
|
||||||
selectorText != null ||
|
if (selector == null) {
|
||||||
error(`could not find selector for index ${ngContent.index} in ${ngContent}`);
|
error(`could not find selector for index ${ngContent.index} in ${ngContent}`);
|
||||||
if (!selectorText || selectorText === '*') {
|
}
|
||||||
|
|
||||||
|
if (!selector || selector === '*') {
|
||||||
this.projectionMap.set(ngContent, {index: 0});
|
this.projectionMap.set(ngContent, {index: 0});
|
||||||
} else {
|
} else {
|
||||||
const cssSelectors = CssSelector.parse(selectorText);
|
this.projectionMap.set(ngContent, {index: this.index++, selector});
|
||||||
this.projectionMap.set(
|
|
||||||
ngContent, {index: this.index++, selector: parseSelectorsToR3Selector(cssSelectors)});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1278,7 +1289,8 @@ function parserSelectorToR3Selector(selector: CssSelector): R3CssSelector {
|
||||||
return positive.concat(...negative);
|
return positive.concat(...negative);
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseSelectorsToR3Selector(selectors: CssSelector[]): R3CssSelectorList {
|
function parseSelectorToR3Selector(selector: string): R3CssSelectorList {
|
||||||
|
const selectors = CssSelector.parse(selector);
|
||||||
return selectors.map(parserSelectorToR3Selector);
|
return selectors.map(parserSelectorToR3Selector);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -601,8 +601,9 @@ describe('compiler compliance', () => {
|
||||||
|
|
||||||
const ComplexComponentDefinition = `
|
const ComplexComponentDefinition = `
|
||||||
const $c1$ = [[['span', 'title', 'tofirst']], [['span', 'title', 'tosecond']]];
|
const $c1$ = [[['span', 'title', 'tofirst']], [['span', 'title', 'tosecond']]];
|
||||||
const $c2$ = ['id','first'];
|
const $c2$ = ['span[title=toFirst]', 'span[title=toSecond]'];
|
||||||
const $c3$ = ['id','second'];
|
const $c3$ = ['id','first'];
|
||||||
|
const $c4$ = ['id','second'];
|
||||||
…
|
…
|
||||||
static ngComponentDef = $r3$.ɵdefineComponent({
|
static ngComponentDef = $r3$.ɵdefineComponent({
|
||||||
type: ComplexComponent,
|
type: ComplexComponent,
|
||||||
|
@ -610,11 +611,11 @@ describe('compiler compliance', () => {
|
||||||
factory: function ComplexComponent_Factory() { return new ComplexComponent(); },
|
factory: function ComplexComponent_Factory() { return new ComplexComponent(); },
|
||||||
template: function ComplexComponent_Template(rf: IDENT, ctx: IDENT) {
|
template: function ComplexComponent_Template(rf: IDENT, ctx: IDENT) {
|
||||||
if (rf & 1) {
|
if (rf & 1) {
|
||||||
$r3$.ɵpD(0, $c1$);
|
$r3$.ɵpD(0, $c1$, $c2$);
|
||||||
$r3$.ɵE(1, 'div', $c2$);
|
$r3$.ɵE(1, 'div', $c3$);
|
||||||
$r3$.ɵP(2, 0, 1);
|
$r3$.ɵP(2, 0, 1);
|
||||||
$r3$.ɵe();
|
$r3$.ɵe();
|
||||||
$r3$.ɵE(3, 'div', $c3$);
|
$r3$.ɵE(3, 'div', $c4$);
|
||||||
$r3$.ɵP(4, 0, 2);
|
$r3$.ɵP(4, 0, 2);
|
||||||
$r3$.ɵe();
|
$r3$.ɵe();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue