test(ivy): content projection canonical example (#21674)
PR Close #21674
This commit is contained in:
parent
acf381bcb7
commit
1e9cd95f5c
|
@ -87,3 +87,4 @@ export {
|
||||||
defineDirective,
|
defineDirective,
|
||||||
};
|
};
|
||||||
export {createComponentRef, detectChanges, getHostElement, markDirty, renderComponent};
|
export {createComponentRef, detectChanges, getHostElement, markDirty, renderComponent};
|
||||||
|
export {CssSelector} from './interfaces/projection';
|
||||||
|
|
|
@ -243,7 +243,7 @@ export function createLNode(
|
||||||
}
|
}
|
||||||
if (index != null) {
|
if (index != null) {
|
||||||
// We are Element or Container
|
// We are Element or Container
|
||||||
ngDevMode && assertEqual(data.length, index, 'data.length not in sequence');
|
ngDevMode && assertDataNext(index);
|
||||||
data[index] = node;
|
data[index] = node;
|
||||||
|
|
||||||
// Every node adds a value to the static data array to avoid a sparse array
|
// Every node adds a value to the static data array to avoid a sparse array
|
||||||
|
@ -1264,7 +1264,7 @@ export const componentRefresh:
|
||||||
*
|
*
|
||||||
* @param selectors
|
* @param selectors
|
||||||
*/
|
*/
|
||||||
export function projectionDef(selectors?: CssSelector[]): LNode[][] {
|
export function projectionDef(index: number, selectors?: CssSelector[]): void {
|
||||||
const noOfNodeBuckets = selectors ? selectors.length + 1 : 1;
|
const noOfNodeBuckets = selectors ? selectors.length + 1 : 1;
|
||||||
const distributedNodes = new Array<LNode[]>(noOfNodeBuckets);
|
const distributedNodes = new Array<LNode[]>(noOfNodeBuckets);
|
||||||
for (let i = 0; i < noOfNodeBuckets; i++) {
|
for (let i = 0; i < noOfNodeBuckets; i++) {
|
||||||
|
@ -1305,7 +1305,8 @@ export function projectionDef(selectors?: CssSelector[]): LNode[][] {
|
||||||
componentChild = componentChild.next;
|
componentChild = componentChild.next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return distributedNodes;
|
ngDevMode && assertDataNext(index);
|
||||||
|
data[index] = distributedNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1891,3 +1892,7 @@ function assertDataInRange(index: number, arr?: any[]) {
|
||||||
if (arr == null) arr = data;
|
if (arr == null) arr = data;
|
||||||
assertLessThan(index, arr ? arr.length : 0, 'data.length');
|
assertLessThan(index, arr ? arr.length : 0, 'data.length');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function assertDataNext(index: number) {
|
||||||
|
assertEqual(data.length, index, 'data.length not in sequence');
|
||||||
|
}
|
|
@ -164,6 +164,69 @@ describe('compiler specification', () => {
|
||||||
expect(renderComp(MyComponent)).toEqual('<child some-directive="">child-view</child>!');
|
expect(renderComp(MyComponent)).toEqual('<child some-directive="">child-view</child>!');
|
||||||
expect(log).toEqual(['ChildComponent', 'SomeDirective']);
|
expect(log).toEqual(['ChildComponent', 'SomeDirective']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should support content projection', () => {
|
||||||
|
@Component({selector: 'simple', template: `<div><ng-content></ng-content></div>`})
|
||||||
|
class SimpleComponent {
|
||||||
|
static ngComponentDef = r3.defineComponent({
|
||||||
|
tag: 'simple',
|
||||||
|
factory: () => new SimpleComponent(),
|
||||||
|
template: function(ctx: SimpleComponent, cm: boolean) {
|
||||||
|
if (cm) {
|
||||||
|
r3.pD(0);
|
||||||
|
r3.E(0, 'div');
|
||||||
|
r3.P(2, 0);
|
||||||
|
r3.e();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'complex',
|
||||||
|
template: `
|
||||||
|
<div id="first"><ng-content select="span[title=toFirst]"></ng-content></div>
|
||||||
|
<div id="second"><ng-content select="span[title=toSecond]"></ng-content></div>`
|
||||||
|
})
|
||||||
|
class ComplexComponent {
|
||||||
|
static ngComponentDef = r3.defineComponent({
|
||||||
|
tag: 'complex',
|
||||||
|
factory: () => new ComplexComponent(),
|
||||||
|
template: function(ctx: ComplexComponent, cm: boolean) {
|
||||||
|
if (cm) {
|
||||||
|
r3.pD(0, pD_0);
|
||||||
|
r3.E(1, 'div', ['id', 'first']);
|
||||||
|
r3.P(2, 0, 1);
|
||||||
|
r3.e();
|
||||||
|
r3.E(3, 'div', ['id', 'second']);
|
||||||
|
r3.P(4, 0, 2);
|
||||||
|
r3.e();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const pD_0: r3.CssSelector[] =
|
||||||
|
[[[['span', 'title', 'toFirst'], null]], [[['span', 'title', 'toSecond'], null]]];
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'my-app',
|
||||||
|
template: `<simple>content</simple>
|
||||||
|
<complex></complex>`
|
||||||
|
})
|
||||||
|
class MyApp {
|
||||||
|
static ngComponentDef = r3.defineComponent({
|
||||||
|
tag: 'my-app',
|
||||||
|
factory: () => new MyApp(),
|
||||||
|
template: function(ctx: MyApp, cm: boolean) {
|
||||||
|
if (cm) {
|
||||||
|
r3.E(0, SimpleComponent);
|
||||||
|
r3.T(2, 'content');
|
||||||
|
r3.e();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('local references', () => {
|
describe('local references', () => {
|
||||||
|
@ -424,7 +487,7 @@ xdescribe('NgModule', () => {
|
||||||
factory: () => new MyModule(inject(Toast)),
|
factory: () => new MyModule(inject(Toast)),
|
||||||
provider: [
|
provider: [
|
||||||
{provide: Toast, deps: [String]}, // If Toast has metadata generate this line
|
{provide: Toast, deps: [String]}, // If Toast has metadata generate this line
|
||||||
Toast, // If toast has not metadata generate this line.
|
Toast, // If Toast has no metadata generate this line.
|
||||||
{provide: String, useValue: 'Hello'}
|
{provide: String, useValue: 'Hello'}
|
||||||
],
|
],
|
||||||
imports: [CommonModule]
|
imports: [CommonModule]
|
||||||
|
|
|
@ -18,7 +18,7 @@ describe('content projection', () => {
|
||||||
*/
|
*/
|
||||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||||
if (cm) {
|
if (cm) {
|
||||||
m(0, pD());
|
pD(0);
|
||||||
E(1, 'div');
|
E(1, 'div');
|
||||||
{ P(2, 0); }
|
{ P(2, 0); }
|
||||||
e();
|
e();
|
||||||
|
@ -44,7 +44,7 @@ describe('content projection', () => {
|
||||||
it('should project content when root.', () => {
|
it('should project content when root.', () => {
|
||||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||||
if (cm) {
|
if (cm) {
|
||||||
m(0, pD());
|
pD(0);
|
||||||
P(1, 0);
|
P(1, 0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -64,7 +64,7 @@ describe('content projection', () => {
|
||||||
it('should re-project content when root.', () => {
|
it('should re-project content when root.', () => {
|
||||||
const GrandChild = createComponent('grand-child', function(ctx: any, cm: boolean) {
|
const GrandChild = createComponent('grand-child', function(ctx: any, cm: boolean) {
|
||||||
if (cm) {
|
if (cm) {
|
||||||
m(0, pD());
|
pD(0);
|
||||||
E(1, 'div');
|
E(1, 'div');
|
||||||
{ P(2, 0); }
|
{ P(2, 0); }
|
||||||
e();
|
e();
|
||||||
|
@ -72,7 +72,7 @@ describe('content projection', () => {
|
||||||
});
|
});
|
||||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||||
if (cm) {
|
if (cm) {
|
||||||
m(0, pD());
|
pD(0);
|
||||||
E(1, GrandChild);
|
E(1, GrandChild);
|
||||||
{ P(3, 0); }
|
{ P(3, 0); }
|
||||||
e();
|
e();
|
||||||
|
@ -102,7 +102,7 @@ describe('content projection', () => {
|
||||||
it('should project content with container.', () => {
|
it('should project content with container.', () => {
|
||||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||||
if (cm) {
|
if (cm) {
|
||||||
m(0, pD());
|
pD(0);
|
||||||
E(1, 'div');
|
E(1, 'div');
|
||||||
{ P(2, 0); }
|
{ P(2, 0); }
|
||||||
e();
|
e();
|
||||||
|
@ -144,7 +144,7 @@ describe('content projection', () => {
|
||||||
it('should project content with container into root', () => {
|
it('should project content with container into root', () => {
|
||||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||||
if (cm) {
|
if (cm) {
|
||||||
m(0, pD());
|
pD(0);
|
||||||
P(1, 0);
|
P(1, 0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -182,7 +182,7 @@ describe('content projection', () => {
|
||||||
it('should project content with container and if-else.', () => {
|
it('should project content with container and if-else.', () => {
|
||||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||||
if (cm) {
|
if (cm) {
|
||||||
m(0, pD());
|
pD(0);
|
||||||
E(1, 'div');
|
E(1, 'div');
|
||||||
{ P(2, 0); }
|
{ P(2, 0); }
|
||||||
e();
|
e();
|
||||||
|
@ -240,7 +240,7 @@ describe('content projection', () => {
|
||||||
*/
|
*/
|
||||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||||
if (cm) {
|
if (cm) {
|
||||||
m(0, pD());
|
pD(0);
|
||||||
E(1, 'div');
|
E(1, 'div');
|
||||||
{ C(2); }
|
{ C(2); }
|
||||||
e();
|
e();
|
||||||
|
@ -295,7 +295,7 @@ describe('content projection', () => {
|
||||||
*/
|
*/
|
||||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||||
if (cm) {
|
if (cm) {
|
||||||
m(0, pD());
|
pD(0);
|
||||||
E(1, 'div');
|
E(1, 'div');
|
||||||
{ C(2); }
|
{ C(2); }
|
||||||
e();
|
e();
|
||||||
|
@ -342,7 +342,7 @@ describe('content projection', () => {
|
||||||
*/
|
*/
|
||||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||||
if (cm) {
|
if (cm) {
|
||||||
m(0, pD());
|
pD(0);
|
||||||
E(1, 'div');
|
E(1, 'div');
|
||||||
{ P(2, 0); }
|
{ P(2, 0); }
|
||||||
e();
|
e();
|
||||||
|
@ -389,7 +389,7 @@ describe('content projection', () => {
|
||||||
*/
|
*/
|
||||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||||
if (cm) {
|
if (cm) {
|
||||||
m(0, pD());
|
pD(0);
|
||||||
P(1, 0);
|
P(1, 0);
|
||||||
E(2, 'div');
|
E(2, 'div');
|
||||||
{ C(3); }
|
{ C(3); }
|
||||||
|
@ -439,8 +439,7 @@ describe('content projection', () => {
|
||||||
*/
|
*/
|
||||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||||
if (cm) {
|
if (cm) {
|
||||||
m(0,
|
pD(0, [[[['span', 'title', 'toFirst'], null]], [[['span', 'title', 'toSecond'], null]]]);
|
||||||
pD([[[['span', 'title', 'toFirst'], null]], [[['span', 'title', 'toSecond'], null]]]));
|
|
||||||
E(1, 'div', ['id', 'first']);
|
E(1, 'div', ['id', 'first']);
|
||||||
{ P(2, 0, 1); }
|
{ P(2, 0, 1); }
|
||||||
e();
|
e();
|
||||||
|
@ -486,8 +485,7 @@ describe('content projection', () => {
|
||||||
*/
|
*/
|
||||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||||
if (cm) {
|
if (cm) {
|
||||||
m(0,
|
pD(0, [[[['span', 'class', 'toFirst'], null]], [[['span', 'class', 'toSecond'], null]]]);
|
||||||
pD([[[['span', 'class', 'toFirst'], null]], [[['span', 'class', 'toSecond'], null]]]));
|
|
||||||
E(1, 'div', ['id', 'first']);
|
E(1, 'div', ['id', 'first']);
|
||||||
{ P(2, 0, 1); }
|
{ P(2, 0, 1); }
|
||||||
e();
|
e();
|
||||||
|
@ -533,8 +531,7 @@ describe('content projection', () => {
|
||||||
*/
|
*/
|
||||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||||
if (cm) {
|
if (cm) {
|
||||||
m(0,
|
pD(0, [[[['span', 'class', 'toFirst'], null]], [[['span', 'class', 'toSecond'], null]]]);
|
||||||
pD([[[['span', 'class', 'toFirst'], null]], [[['span', 'class', 'toSecond'], null]]]));
|
|
||||||
E(1, 'div', ['id', 'first']);
|
E(1, 'div', ['id', 'first']);
|
||||||
{ P(2, 0, 1); }
|
{ P(2, 0, 1); }
|
||||||
e();
|
e();
|
||||||
|
@ -580,7 +577,7 @@ describe('content projection', () => {
|
||||||
*/
|
*/
|
||||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||||
if (cm) {
|
if (cm) {
|
||||||
m(0, pD([[[['span'], null]], [[['span', 'class', 'toSecond'], null]]]));
|
pD(0, [[[['span'], null]], [[['span', 'class', 'toSecond'], null]]]);
|
||||||
E(1, 'div', ['id', 'first']);
|
E(1, 'div', ['id', 'first']);
|
||||||
{ P(2, 0, 1); }
|
{ P(2, 0, 1); }
|
||||||
e();
|
e();
|
||||||
|
@ -626,7 +623,7 @@ describe('content projection', () => {
|
||||||
*/
|
*/
|
||||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||||
if (cm) {
|
if (cm) {
|
||||||
m(0, pD([[[['span', 'class', 'toFirst'], null]]]));
|
pD(0, [[[['span', 'class', 'toFirst'], null]]]);
|
||||||
E(1, 'div', ['id', 'first']);
|
E(1, 'div', ['id', 'first']);
|
||||||
{ P(2, 0, 1); }
|
{ P(2, 0, 1); }
|
||||||
e();
|
e();
|
||||||
|
@ -673,7 +670,7 @@ describe('content projection', () => {
|
||||||
*/
|
*/
|
||||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||||
if (cm) {
|
if (cm) {
|
||||||
m(0, pD([[[['span', 'class', 'toSecond'], null]]]));
|
pD(0, [[[['span', 'class', 'toSecond'], null]]]);
|
||||||
E(1, 'div', ['id', 'first']);
|
E(1, 'div', ['id', 'first']);
|
||||||
{ P(2, 0); }
|
{ P(2, 0); }
|
||||||
e();
|
e();
|
||||||
|
@ -727,7 +724,7 @@ describe('content projection', () => {
|
||||||
*/
|
*/
|
||||||
const GrandChild = createComponent('grand-child', function(ctx: any, cm: boolean) {
|
const GrandChild = createComponent('grand-child', function(ctx: any, cm: boolean) {
|
||||||
if (cm) {
|
if (cm) {
|
||||||
m(0, pD([[[['span'], null]]]));
|
pD(0, [[[['span'], null]]]);
|
||||||
P(1, 0, 1);
|
P(1, 0, 1);
|
||||||
E(2, 'hr');
|
E(2, 'hr');
|
||||||
e();
|
e();
|
||||||
|
@ -743,7 +740,7 @@ describe('content projection', () => {
|
||||||
*/
|
*/
|
||||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||||
if (cm) {
|
if (cm) {
|
||||||
m(0, pD());
|
pD(0);
|
||||||
E(1, GrandChild);
|
E(1, GrandChild);
|
||||||
{
|
{
|
||||||
P(3, 0);
|
P(3, 0);
|
||||||
|
@ -793,7 +790,7 @@ describe('content projection', () => {
|
||||||
*/
|
*/
|
||||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||||
if (cm) {
|
if (cm) {
|
||||||
m(0, pD([[[['div'], null]]]));
|
pD(0, [[[['div'], null]]]);
|
||||||
E(1, 'span');
|
E(1, 'span');
|
||||||
{ P(2, 0, 1); }
|
{ P(2, 0, 1); }
|
||||||
e();
|
e();
|
||||||
|
|
Loading…
Reference in New Issue