refactor(core): store locals in main array in rederer3 (#20855)
PR Close #20855
This commit is contained in:
@ -19,8 +19,8 @@ describe('content projection', () => {
|
||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||
if (cm) {
|
||||
m(0, dP());
|
||||
E(0, 'div');
|
||||
{ P(1, 0); }
|
||||
E(1, 'div');
|
||||
{ P(2, 0); }
|
||||
e();
|
||||
}
|
||||
});
|
||||
@ -47,7 +47,7 @@ describe('content projection', () => {
|
||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||
if (cm) {
|
||||
m(0, dP());
|
||||
P(0, 0);
|
||||
P(1, 0);
|
||||
}
|
||||
});
|
||||
const Parent = createComponent('parent', function(ctx: any, cm: boolean) {
|
||||
@ -69,21 +69,21 @@ describe('content projection', () => {
|
||||
const GrandChild = createComponent('grand-child', function(ctx: any, cm: boolean) {
|
||||
if (cm) {
|
||||
m(0, dP());
|
||||
E(0, 'div');
|
||||
{ P(1, 0); }
|
||||
E(1, 'div');
|
||||
{ P(2, 0); }
|
||||
e();
|
||||
}
|
||||
});
|
||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||
if (cm) {
|
||||
m(0, dP());
|
||||
E(0, GrandChild.ngComponentDef);
|
||||
E(1, GrandChild.ngComponentDef);
|
||||
{
|
||||
D(0, GrandChild.ngComponentDef.n(), GrandChild.ngComponentDef);
|
||||
P(1, 0);
|
||||
P(2, 0);
|
||||
}
|
||||
e();
|
||||
GrandChild.ngComponentDef.r(0, 0);
|
||||
GrandChild.ngComponentDef.r(0, 1);
|
||||
}
|
||||
});
|
||||
const Parent = createComponent('parent', function(ctx: any, cm: boolean) {
|
||||
@ -109,8 +109,8 @@ describe('content projection', () => {
|
||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||
if (cm) {
|
||||
m(0, dP());
|
||||
E(0, 'div');
|
||||
{ P(1, 0); }
|
||||
E(1, 'div');
|
||||
{ P(2, 0); }
|
||||
e();
|
||||
}
|
||||
});
|
||||
@ -148,12 +148,53 @@ describe('content projection', () => {
|
||||
expect(toHtml(parent)).toEqual('<child><div>()</div></child>');
|
||||
});
|
||||
|
||||
it('should project content with container into root', () => {
|
||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||
if (cm) {
|
||||
m(0, dP());
|
||||
P(1, 0);
|
||||
}
|
||||
});
|
||||
const Parent = createComponent('parent', function(ctx: {value: any}, cm: boolean) {
|
||||
if (cm) {
|
||||
E(0, Child.ngComponentDef);
|
||||
{
|
||||
D(0, Child.ngComponentDef.n(), Child.ngComponentDef);
|
||||
C(1);
|
||||
c();
|
||||
}
|
||||
e();
|
||||
}
|
||||
rC(1);
|
||||
{
|
||||
if (ctx.value) {
|
||||
if (V(0)) {
|
||||
T(0, 'content');
|
||||
}
|
||||
v();
|
||||
}
|
||||
}
|
||||
rc();
|
||||
Child.ngComponentDef.r(0, 0);
|
||||
});
|
||||
const parent = renderComponent(Parent);
|
||||
expect(toHtml(parent)).toEqual('<child></child>');
|
||||
|
||||
parent.value = true;
|
||||
detectChanges(parent);
|
||||
expect(toHtml(parent)).toEqual('<child>content</child>');
|
||||
|
||||
parent.value = false;
|
||||
detectChanges(parent);
|
||||
expect(toHtml(parent)).toEqual('<child></child>');
|
||||
});
|
||||
|
||||
it('should project content with container and if-else.', () => {
|
||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||
if (cm) {
|
||||
m(0, dP());
|
||||
E(0, 'div');
|
||||
{ P(1, 0); }
|
||||
E(1, 'div');
|
||||
{ P(2, 0); }
|
||||
e();
|
||||
}
|
||||
});
|
||||
@ -211,14 +252,14 @@ describe('content projection', () => {
|
||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||
if (cm) {
|
||||
m(0, dP());
|
||||
E(0, 'div');
|
||||
E(1, 'div');
|
||||
{
|
||||
C(1);
|
||||
C(2);
|
||||
c();
|
||||
}
|
||||
e();
|
||||
}
|
||||
rC(1);
|
||||
rC(2);
|
||||
{
|
||||
if (!ctx.skipContent) {
|
||||
if (V(0)) {
|
||||
@ -268,14 +309,14 @@ describe('content projection', () => {
|
||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||
if (cm) {
|
||||
m(0, dP());
|
||||
E(0, 'div');
|
||||
E(1, 'div');
|
||||
{
|
||||
C(1);
|
||||
C(2);
|
||||
c();
|
||||
}
|
||||
e();
|
||||
}
|
||||
rC(1);
|
||||
rC(2);
|
||||
{
|
||||
if (!ctx.skipContent) {
|
||||
if (V(0)) {
|
||||
@ -317,11 +358,11 @@ describe('content projection', () => {
|
||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||
if (cm) {
|
||||
m(0, dP());
|
||||
E(0, 'div');
|
||||
{ P(1, 0); }
|
||||
E(1, 'div');
|
||||
{ P(2, 0); }
|
||||
e();
|
||||
E(2, 'span');
|
||||
{ P(3, 0); }
|
||||
E(3, 'span');
|
||||
{ P(4, 0); }
|
||||
e();
|
||||
}
|
||||
});
|
||||
@ -366,15 +407,15 @@ describe('content projection', () => {
|
||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||
if (cm) {
|
||||
m(0, dP());
|
||||
P(0, 0);
|
||||
E(1, 'div');
|
||||
P(1, 0);
|
||||
E(2, 'div');
|
||||
{
|
||||
C(2);
|
||||
C(3);
|
||||
c();
|
||||
}
|
||||
e();
|
||||
}
|
||||
rC(2);
|
||||
rC(3);
|
||||
{
|
||||
if (ctx.show) {
|
||||
if (V(0)) {
|
||||
@ -419,11 +460,11 @@ describe('content projection', () => {
|
||||
if (cm) {
|
||||
m(0,
|
||||
dP([[[['span', 'title', 'toFirst'], null]], [[['span', 'title', 'toSecond'], null]]]));
|
||||
E(0, 'div', ['id', 'first']);
|
||||
{ P(1, 0, 1); }
|
||||
E(1, 'div', ['id', 'first']);
|
||||
{ P(2, 0, 1); }
|
||||
e();
|
||||
E(2, 'div', ['id', 'second']);
|
||||
{ P(3, 0, 2); }
|
||||
E(3, 'div', ['id', 'second']);
|
||||
{ P(4, 0, 2); }
|
||||
e();
|
||||
}
|
||||
});
|
||||
@ -466,11 +507,11 @@ describe('content projection', () => {
|
||||
if (cm) {
|
||||
m(0,
|
||||
dP([[[['span', 'class', 'toFirst'], null]], [[['span', 'class', 'toSecond'], null]]]));
|
||||
E(0, 'div', ['id', 'first']);
|
||||
{ P(1, 0, 1); }
|
||||
E(1, 'div', ['id', 'first']);
|
||||
{ P(2, 0, 1); }
|
||||
e();
|
||||
E(2, 'div', ['id', 'second']);
|
||||
{ P(3, 0, 2); }
|
||||
E(3, 'div', ['id', 'second']);
|
||||
{ P(4, 0, 2); }
|
||||
e();
|
||||
}
|
||||
});
|
||||
@ -513,11 +554,11 @@ describe('content projection', () => {
|
||||
if (cm) {
|
||||
m(0,
|
||||
dP([[[['span', 'class', 'toFirst'], null]], [[['span', 'class', 'toSecond'], null]]]));
|
||||
E(0, 'div', ['id', 'first']);
|
||||
{ P(1, 0, 1); }
|
||||
E(1, 'div', ['id', 'first']);
|
||||
{ P(2, 0, 1); }
|
||||
e();
|
||||
E(2, 'div', ['id', 'second']);
|
||||
{ P(3, 0, 2); }
|
||||
E(3, 'div', ['id', 'second']);
|
||||
{ P(4, 0, 2); }
|
||||
e();
|
||||
}
|
||||
});
|
||||
@ -559,11 +600,11 @@ describe('content projection', () => {
|
||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||
if (cm) {
|
||||
m(0, dP([[[['span'], null]], [[['span', 'class', 'toSecond'], null]]]));
|
||||
E(0, 'div', ['id', 'first']);
|
||||
{ P(1, 0, 1); }
|
||||
E(1, 'div', ['id', 'first']);
|
||||
{ P(2, 0, 1); }
|
||||
e();
|
||||
E(2, 'div', ['id', 'second']);
|
||||
{ P(3, 0, 2); }
|
||||
E(3, 'div', ['id', 'second']);
|
||||
{ P(4, 0, 2); }
|
||||
e();
|
||||
}
|
||||
});
|
||||
@ -605,11 +646,11 @@ describe('content projection', () => {
|
||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||
if (cm) {
|
||||
m(0, dP([[[['span', 'class', 'toFirst'], null]]]));
|
||||
E(0, 'div', ['id', 'first']);
|
||||
{ P(1, 0, 1); }
|
||||
E(1, 'div', ['id', 'first']);
|
||||
{ P(2, 0, 1); }
|
||||
e();
|
||||
E(2, 'div', ['id', 'second']);
|
||||
{ P(3, 0); }
|
||||
E(3, 'div', ['id', 'second']);
|
||||
{ P(4, 0); }
|
||||
e();
|
||||
}
|
||||
});
|
||||
@ -652,11 +693,11 @@ describe('content projection', () => {
|
||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||
if (cm) {
|
||||
m(0, dP([[[['span', 'class', 'toSecond'], null]]]));
|
||||
E(0, 'div', ['id', 'first']);
|
||||
{ P(1, 0); }
|
||||
E(1, 'div', ['id', 'first']);
|
||||
{ P(2, 0); }
|
||||
e();
|
||||
E(2, 'div', ['id', 'second']);
|
||||
{ P(3, 0, 1); }
|
||||
E(3, 'div', ['id', 'second']);
|
||||
{ P(4, 0, 1); }
|
||||
e();
|
||||
}
|
||||
});
|
||||
@ -706,10 +747,10 @@ describe('content projection', () => {
|
||||
const GrandChild = createComponent('grand-child', function(ctx: any, cm: boolean) {
|
||||
if (cm) {
|
||||
m(0, dP([[[['span'], null]]]));
|
||||
P(0, 0, 1);
|
||||
E(1, 'hr');
|
||||
P(1, 0, 1);
|
||||
E(2, 'hr');
|
||||
e();
|
||||
P(2, 0, 0);
|
||||
P(3, 0, 0);
|
||||
}
|
||||
});
|
||||
|
||||
@ -722,16 +763,16 @@ describe('content projection', () => {
|
||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||
if (cm) {
|
||||
m(0, dP());
|
||||
E(0, GrandChild.ngComponentDef);
|
||||
E(1, GrandChild.ngComponentDef);
|
||||
{
|
||||
D(0, GrandChild.ngComponentDef.n(), GrandChild.ngComponentDef);
|
||||
P(1, 0);
|
||||
E(2, 'span');
|
||||
{ T(3, 'in child template'); }
|
||||
P(2, 0);
|
||||
E(3, 'span');
|
||||
{ T(4, 'in child template'); }
|
||||
e();
|
||||
}
|
||||
e();
|
||||
GrandChild.ngComponentDef.r(0, 0);
|
||||
GrandChild.ngComponentDef.r(0, 1);
|
||||
}
|
||||
});
|
||||
|
||||
@ -772,8 +813,8 @@ describe('content projection', () => {
|
||||
const Child = createComponent('child', function(ctx: any, cm: boolean) {
|
||||
if (cm) {
|
||||
m(0, dP([[[['div'], null]]]));
|
||||
E(0, 'span');
|
||||
{ P(1, 0, 1); }
|
||||
E(1, 'span');
|
||||
{ P(2, 0, 1); }
|
||||
e();
|
||||
}
|
||||
});
|
||||
|
@ -10,7 +10,7 @@ import {ElementRef, TemplateRef, ViewContainerRef} from '@angular/core';
|
||||
|
||||
import {bloomFindPossibleInjector} from '../../src/render3/di';
|
||||
import {C, D, E, PublicFeature, T, V, b, b2, c, defineDirective, e, inject, injectElementRef, injectTemplateRef, injectViewContainerRef, rC, rc, t, v} from '../../src/render3/index';
|
||||
import {bloomAdd, createNode, createViewState, enterView, getOrCreateNodeInjector, leaveView} from '../../src/render3/instructions';
|
||||
import {bloomAdd, createLNode, createViewState, enterView, getOrCreateNodeInjector, leaveView} from '../../src/render3/instructions';
|
||||
import {LNodeFlags, LNodeInjector} from '../../src/render3/interfaces';
|
||||
|
||||
import {renderToHtml} from './render_util';
|
||||
@ -321,7 +321,7 @@ describe('di', () => {
|
||||
const contentView = createViewState(-1, null !);
|
||||
const oldView = enterView(contentView, null !);
|
||||
try {
|
||||
const parent = createNode(0, LNodeFlags.Element, null, null);
|
||||
const parent = createLNode(0, LNodeFlags.Element, null, null);
|
||||
|
||||
// Simulate the situation where the previous parent is not initialized.
|
||||
// This happens on first bootstrap because we don't init existing values
|
||||
|
@ -589,4 +589,54 @@ describe('iv integration test', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('template data', () => {
|
||||
|
||||
it('should re-use template data and node data', () => {
|
||||
/**
|
||||
* % if (condition) {
|
||||
* <div></div>
|
||||
* % }
|
||||
*/
|
||||
function Template(ctx: any, cm: boolean) {
|
||||
if (cm) {
|
||||
C(0);
|
||||
c();
|
||||
}
|
||||
rC(0);
|
||||
{
|
||||
if (ctx.condition) {
|
||||
if (V(0)) {
|
||||
E(0, 'div');
|
||||
{}
|
||||
e();
|
||||
}
|
||||
v();
|
||||
}
|
||||
}
|
||||
rc();
|
||||
}
|
||||
|
||||
expect((Template as any).ngStaticData).toBeUndefined();
|
||||
|
||||
renderToHtml(Template, {condition: true});
|
||||
|
||||
const oldTemplateData = (Template as any).ngStaticData;
|
||||
const oldContainerData = (oldTemplateData as any)[0];
|
||||
const oldElementData = oldContainerData.containerStatic[0][0];
|
||||
expect(oldContainerData).not.toBeNull();
|
||||
expect(oldElementData).not.toBeNull();
|
||||
|
||||
renderToHtml(Template, {condition: false});
|
||||
renderToHtml(Template, {condition: true});
|
||||
|
||||
const newTemplateData = (Template as any).ngStaticData;
|
||||
const newContainerData = (oldTemplateData as any)[0];
|
||||
const newElementData = oldContainerData.containerStatic[0][0];
|
||||
expect(newTemplateData === oldTemplateData).toBe(true);
|
||||
expect(newContainerData === oldContainerData).toBe(true);
|
||||
expect(newElementData === oldElementData).toBe(true);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -6,11 +6,18 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {CSSSelector, CSSSelectorWithNegations, NodeBindings, SimpleCSSSelector} from '../../src/render3/interfaces';
|
||||
import {CSSSelector, CSSSelectorWithNegations, LNodeStatic, SimpleCSSSelector} from '../../src/render3/interfaces';
|
||||
import {isNodeMatchingSelector, isNodeMatchingSelectorWithNegations, isNodeMatchingSimpleSelector} from '../../src/render3/node_selector_matcher';
|
||||
|
||||
function testLStaticData(tagName: string, attrs: string[] | null): NodeBindings {
|
||||
return {tagName, attrs, initialInputs: undefined, inputs: undefined, outputs: undefined};
|
||||
function testLStaticData(tagName: string, attrs: string[] | null): LNodeStatic {
|
||||
return {
|
||||
tagName,
|
||||
attrs,
|
||||
initialInputs: undefined,
|
||||
inputs: undefined,
|
||||
outputs: undefined,
|
||||
containerStatic: null
|
||||
};
|
||||
}
|
||||
|
||||
describe('css selector matching', () => {
|
||||
|
@ -28,6 +28,17 @@ describe('outputs', () => {
|
||||
});
|
||||
}
|
||||
|
||||
let otherDir: OtherDir;
|
||||
|
||||
class OtherDir {
|
||||
changeStream = new EventEmitter();
|
||||
|
||||
static ngDirectiveDef = defineDirective({
|
||||
type: OtherDir,
|
||||
factory: () => otherDir = new OtherDir,
|
||||
outputs: {changeStream: 'change'}
|
||||
});
|
||||
}
|
||||
|
||||
it('should call component output function when event is emitted', () => {
|
||||
/** <button-toggle (change)="onChange()"></button-toggle> */
|
||||
@ -328,15 +339,6 @@ describe('outputs', () => {
|
||||
});
|
||||
|
||||
it('should work with two outputs of the same name', () => {
|
||||
let otherDir: OtherDir;
|
||||
|
||||
class OtherDir {
|
||||
change = new EventEmitter();
|
||||
|
||||
static ngDirectiveDef = defineDirective(
|
||||
{type: OtherDir, factory: () => otherDir = new OtherDir, outputs: {change: 'change'}});
|
||||
}
|
||||
|
||||
/** <button-toggle (change)="onChange()" otherDir></button-toggle> */
|
||||
function Template(ctx: any, cm: boolean) {
|
||||
if (cm) {
|
||||
@ -357,7 +359,7 @@ describe('outputs', () => {
|
||||
buttonToggle !.change.next();
|
||||
expect(counter).toEqual(1);
|
||||
|
||||
otherDir !.change.next();
|
||||
otherDir !.changeStream.next();
|
||||
expect(counter).toEqual(2);
|
||||
});
|
||||
|
||||
@ -397,4 +399,67 @@ describe('outputs', () => {
|
||||
expect(counter).toEqual(1);
|
||||
});
|
||||
|
||||
it('should work with outputs at same index in if block', () => {
|
||||
/**
|
||||
* <button (click)="onClick()">Click me</button> // outputs: null
|
||||
* % if (condition) {
|
||||
* <button-toggle (change)="onChange()"></button-toggle> // outputs: {change: [0, 'change']}
|
||||
* % } else {
|
||||
* <div otherDir (change)="onChange()"></div> // outputs: {change: [0,
|
||||
* 'changeStream']}
|
||||
* % }
|
||||
*/
|
||||
function Template(ctx: any, cm: boolean) {
|
||||
if (cm) {
|
||||
E(0, 'button');
|
||||
{
|
||||
L('click', ctx.onClick.bind(ctx));
|
||||
T(1, 'Click me');
|
||||
}
|
||||
e();
|
||||
C(2);
|
||||
c();
|
||||
}
|
||||
rC(2);
|
||||
{
|
||||
if (ctx.condition) {
|
||||
if (V(0)) {
|
||||
E(0, ButtonToggle.ngComponentDef);
|
||||
{
|
||||
D(0, ButtonToggle.ngComponentDef.n(), ButtonToggle.ngComponentDef);
|
||||
L('change', ctx.onChange.bind(ctx));
|
||||
}
|
||||
e();
|
||||
}
|
||||
v();
|
||||
} else {
|
||||
if (V(1)) {
|
||||
E(0, 'div');
|
||||
{
|
||||
D(0, OtherDir.ngDirectiveDef.n(), OtherDir.ngDirectiveDef);
|
||||
L('change', ctx.onChange.bind(ctx));
|
||||
}
|
||||
e();
|
||||
}
|
||||
v();
|
||||
}
|
||||
}
|
||||
rc();
|
||||
}
|
||||
|
||||
let counter = 0;
|
||||
const ctx = {condition: true, onChange: () => counter++, onClick: () => {}};
|
||||
renderToHtml(Template, ctx);
|
||||
|
||||
buttonToggle !.change.next();
|
||||
expect(counter).toEqual(1);
|
||||
|
||||
ctx.condition = false;
|
||||
renderToHtml(Template, ctx);
|
||||
expect(counter).toEqual(1);
|
||||
|
||||
otherDir !.changeStream.next();
|
||||
expect(counter).toEqual(2);
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -239,6 +239,73 @@ describe('elementProperty', () => {
|
||||
renderToHtml(Template, ctx);
|
||||
expect(otherDir !.id).toEqual(2);
|
||||
});
|
||||
|
||||
it('should support unrelated element properties at same index in if-else block', () => {
|
||||
let idDir: IdDir;
|
||||
|
||||
class IdDir {
|
||||
idNumber: number;
|
||||
|
||||
static ngDirectiveDef = defineDirective(
|
||||
{type: IdDir, factory: () => idDir = new IdDir(), inputs: {idNumber: 'id'}});
|
||||
}
|
||||
|
||||
/**
|
||||
* <button idDir [id]="id1">Click me</button> // inputs: {'id': [0, 'idNumber']}
|
||||
* % if (condition) {
|
||||
* <button [id]="id2">Click me too</button> // inputs: null
|
||||
* % } else {
|
||||
* <button otherDir [id]="id3">Click me too</button> // inputs: {'id': [0, 'id']}
|
||||
* % }
|
||||
*/
|
||||
function Template(ctx: any, cm: boolean) {
|
||||
if (cm) {
|
||||
E(0, 'button');
|
||||
{
|
||||
D(0, IdDir.ngDirectiveDef.n(), IdDir.ngDirectiveDef);
|
||||
T(1, 'Click me');
|
||||
}
|
||||
e();
|
||||
C(2);
|
||||
c();
|
||||
}
|
||||
p(0, 'id', b(ctx.id1));
|
||||
rC(2);
|
||||
{
|
||||
if (ctx.condition) {
|
||||
if (V(0)) {
|
||||
E(0, 'button');
|
||||
{ T(1, 'Click me too'); }
|
||||
e();
|
||||
}
|
||||
p(0, 'id', b(ctx.id2));
|
||||
v();
|
||||
} else {
|
||||
if (V(1)) {
|
||||
E(0, 'button');
|
||||
{
|
||||
D(0, OtherDir.ngDirectiveDef.n(), OtherDir.ngDirectiveDef);
|
||||
T(1, 'Click me too');
|
||||
}
|
||||
e();
|
||||
}
|
||||
p(0, 'id', b(ctx.id3));
|
||||
v();
|
||||
}
|
||||
}
|
||||
rc();
|
||||
}
|
||||
|
||||
expect(renderToHtml(Template, {condition: true, id1: 'one', id2: 'two', id3: 'three'}))
|
||||
.toEqual(`<button>Click me</button><button id="two">Click me too</button>`);
|
||||
expect(idDir !.idNumber).toEqual('one');
|
||||
|
||||
expect(renderToHtml(Template, {condition: false, id1: 'four', id2: 'two', id3: 'three'}))
|
||||
.toEqual(`<button>Click me</button><button>Click me too</button>`);
|
||||
expect(idDir !.idNumber).toEqual('four');
|
||||
expect(otherDir !.id).toEqual('three');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('attributes and input properties', () => {
|
||||
@ -382,6 +449,58 @@ describe('elementProperty', () => {
|
||||
expect(dirB !.roleB).toEqual('listbox');
|
||||
});
|
||||
|
||||
it('should support attributes at same index inside an if-else block', () => {
|
||||
/**
|
||||
* <div role="listbox" myDir></div> // initialInputs: [['role', 'listbox']]
|
||||
*
|
||||
* % if (condition) {
|
||||
* <div role="button" myDirB></div> // initialInputs: [['role', 'button']]
|
||||
* % } else {
|
||||
* <div role="menu"></div> // initialInputs: [null]
|
||||
* % }
|
||||
*/
|
||||
function Template(ctx: any, cm: boolean) {
|
||||
if (cm) {
|
||||
E(0, 'div', ['role', 'listbox']);
|
||||
{ D(0, MyDir.ngDirectiveDef.n(), MyDir.ngDirectiveDef); }
|
||||
e();
|
||||
C(1);
|
||||
c();
|
||||
}
|
||||
rC(1);
|
||||
{
|
||||
if (ctx.condition) {
|
||||
if (V(0)) {
|
||||
E(0, 'div', ['role', 'button']);
|
||||
{ D(0, MyDirB.ngDirectiveDef.n(), MyDirB.ngDirectiveDef); }
|
||||
e();
|
||||
}
|
||||
v();
|
||||
} else {
|
||||
if (V(1)) {
|
||||
E(0, 'div', ['role', 'menu']);
|
||||
{}
|
||||
e();
|
||||
}
|
||||
v();
|
||||
}
|
||||
}
|
||||
rc();
|
||||
}
|
||||
|
||||
expect(renderToHtml(Template, {
|
||||
condition: true
|
||||
})).toEqual(`<div role="listbox"></div><div role="button"></div>`);
|
||||
expect(myDir !.role).toEqual('listbox');
|
||||
expect(dirB !.roleB).toEqual('button');
|
||||
expect((dirB !as any).role).toBeUndefined();
|
||||
|
||||
expect(renderToHtml(Template, {
|
||||
condition: false
|
||||
})).toEqual(`<div role="listbox"></div><div role="menu"></div>`);
|
||||
expect(myDir !.role).toEqual('listbox');
|
||||
});
|
||||
|
||||
it('should process attributes properly inside a for loop', () => {
|
||||
|
||||
class Comp {
|
||||
|
@ -31,10 +31,10 @@ describe('query', () => {
|
||||
if (cm) {
|
||||
m(0, Q(Child, false));
|
||||
m(1, Q(Child, true));
|
||||
E(0, Child.ngComponentDef);
|
||||
E(2, Child.ngComponentDef);
|
||||
{
|
||||
child1 = D(0, Child.ngComponentDef.n(), Child.ngComponentDef);
|
||||
E(1, Child.ngComponentDef);
|
||||
E(3, Child.ngComponentDef);
|
||||
{ child2 = D(1, Child.ngComponentDef.n(), Child.ngComponentDef); }
|
||||
e();
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import {ComponentTemplate, ComponentType, PublicFeature, defineComponent, renderComponent as _renderComponent} from '../../src/render3/index';
|
||||
import {NG_HOST_SYMBOL, createNode, createViewState, renderTemplate} from '../../src/render3/instructions';
|
||||
import {NG_HOST_SYMBOL, createLNode, createViewState, renderTemplate} from '../../src/render3/instructions';
|
||||
import {LElement, LNodeFlags} from '../../src/render3/interfaces';
|
||||
import {RElement, RText, Renderer3} from '../../src/render3/renderer';
|
||||
import {getRenderer2} from './imported_renderer2';
|
||||
@ -37,7 +37,7 @@ export function resetDOM() {
|
||||
requestAnimationFrame.queue = [];
|
||||
containerEl = document.createElement('div');
|
||||
containerEl.setAttribute('host', '');
|
||||
host = createNode(null, LNodeFlags.Element, containerEl, createViewState(-1, activeRenderer));
|
||||
host = createLNode(null, LNodeFlags.Element, containerEl, createViewState(-1, activeRenderer));
|
||||
// TODO: assert that the global state is clean (e.g. ngData, previousOrParentNode, etc)
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user