Skip to content

Commit

Permalink
fix(ivy): add unparsed selectors to the projectionDef instruction (#…
Browse files Browse the repository at this point in the history
…23375)

PR Close #23375
  • Loading branch information
vicb authored and IgorMinar committed Apr 14, 2018
1 parent ac683d7 commit 80e483c
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 24 deletions.
44 changes: 28 additions & 16 deletions packages/compiler/src/render3/r3_view_compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -471,20 +471,31 @@ class TemplateDefinitionBuilder implements TemplateAstVisitor, LocalResolver {
if (this.ngContentSelectors && this.ngContentSelectors.length > 0) {
const contentProjections = getContentProjection(nodes, this.ngContentSelectors);
this._contentProjections = contentProjections;

if (contentProjections.size > 0) {
const infos: R3CssSelectorList[] = [];
const selectors: string[] = [];

Array.from(contentProjections.values()).forEach(info => {
if (info.selector) {
infos[info.index - 1] = info.selector;
selectors[info.index - 1] = info.selector;
}
});

const projectionIndex = this._projectionDefinitionIndex = this.allocateDataSlot();
const parameters: o.Expression[] = [o.literal(projectionIndex)];
!infos.some(value => !value) || error(`content project information skipped an index`);
if (infos.length > 1) {
parameters.push(this.outputCtx.constantPool.getConstLiteral(
asLiteral(infos), /* forceShared */ true));

if (selectors.some(value => !value)) {
error(`content project information skipped an index`);
}

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);
}
}
Expand Down Expand Up @@ -1016,7 +1027,7 @@ type HostBindings = {

// Turn a directive selector into an R3-compatible selector for directive def
function createDirectiveSelector(selector: string): o.Expression {
return asLiteral(parseSelectorsToR3Selector(CssSelector.parse(selector)));
return asLiteral(parseSelectorToR3Selector(selector));
}

function createHostAttributesArray(
Expand Down Expand Up @@ -1186,7 +1197,7 @@ function invalid<T>(arg: o.Expression | o.Statement | TemplateAst): never {

interface NgContentInfo {
index: number;
selector?: R3CssSelectorList;
selector?: string;
}

class ContentProjectionVisitor extends RecursiveTemplateAstVisitor {
Expand All @@ -1198,15 +1209,15 @@ class ContentProjectionVisitor extends RecursiveTemplateAstVisitor {
}

visitNgContent(ngContent: NgContentAst) {
const selectorText = this.ngContentSelectors[ngContent.index];
selectorText != null ||
error(`could not find selector for index ${ngContent.index} in ${ngContent}`);
if (!selectorText || selectorText === '*') {
const selector = this.ngContentSelectors[ngContent.index];
if (selector == null) {
error(`could not find selector for index ${ngContent.index} in ${ngContent}`);
}

if (!selector || selector === '*') {
this.projectionMap.set(ngContent, {index: 0});
} else {
const cssSelectors = CssSelector.parse(selectorText);
this.projectionMap.set(
ngContent, {index: this.index++, selector: parseSelectorsToR3Selector(cssSelectors)});
this.projectionMap.set(ngContent, {index: this.index++, selector});
}
}
}
Expand Down Expand Up @@ -1278,7 +1289,8 @@ function parserSelectorToR3Selector(selector: CssSelector): R3CssSelector {
return positive.concat(...negative);
}

function parseSelectorsToR3Selector(selectors: CssSelector[]): R3CssSelectorList {
function parseSelectorToR3Selector(selector: string): R3CssSelectorList {
const selectors = CssSelector.parse(selector);
return selectors.map(parserSelectorToR3Selector);
}

Expand Down
17 changes: 9 additions & 8 deletions packages/compiler/test/render3/r3_compiler_compliance_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ describe('compiler compliance', () => {
@Directive({selector: 'div.foo[some-directive]:not([title]):not(.baz)'})
export class SomeDirective {}
@Directive({selector: ':not(span[title]):not(.baz)'})
export class OtherDirective {}
Expand Down Expand Up @@ -601,20 +601,21 @@ describe('compiler compliance', () => {

const ComplexComponentDefinition = `
const $c1$ = [[['span', 'title', 'tofirst']], [['span', 'title', 'tosecond']]];
const $c2$ = ['id','first'];
const $c3$ = ['id','second'];
const $c2$ = ['span[title=toFirst]', 'span[title=toSecond]'];
const $c3$ = ['id','first'];
const $c4$ = ['id','second'];
static ngComponentDef = $r3$.ɵdefineComponent({
type: ComplexComponent,
selectors: [['complex']],
factory: function ComplexComponent_Factory() { return new ComplexComponent(); },
template: function ComplexComponent_Template(rf: IDENT, ctx: IDENT) {
if (rf & 1) {
$r3$.ɵpD(0, $c1$);
$r3$.ɵE(1, 'div', $c2$);
$r3$.ɵpD(0, $c1$, $c2$);
$r3$.ɵE(1, 'div', $c3$);
$r3$.ɵP(2, 0, 1);
$r3$.ɵe();
$r3$.ɵE(3, 'div', $c3$);
$r3$.ɵE(3, 'div', $c4$);
$r3$.ɵP(4, 0, 2);
$r3$.ɵe();
}
Expand Down Expand Up @@ -783,7 +784,7 @@ describe('compiler compliance', () => {
}
@Component({
selector: 'my-app',
selector: 'my-app',
template: '{{name | myPipe:size | myPurePipe:size }}<p>{{ name | myPurePipe:size }}</p>'
})
export class MyApp {
Expand All @@ -805,7 +806,7 @@ describe('compiler compliance', () => {

const MyPurePipeDefinition = `
static ngPipeDef = $r3$.ɵdefinePipe({
name: 'myPurePipe',
name: 'myPurePipe',
type: MyPurePipe,
factory: function MyPurePipe_Factory() { return new MyPurePipe(); },
pure: true
Expand Down

0 comments on commit 80e483c

Please sign in to comment.