[FIX] t-slot: correct parented relationship with nested slots

Closes #506
This commit is contained in:
Aaron Bohy
2019-11-28 09:47:51 +01:00
committed by Géry Debongnie
parent 6c8b401092
commit 85d4393242
4 changed files with 38 additions and 7 deletions
+1 -1
View File
@@ -206,7 +206,7 @@ QWeb.addDirective({
ctx.addLine(`result = {}`); ctx.addLine(`result = {}`);
} }
ctx.addLine( ctx.addLine(
`slot${slotKey}.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: ${parentNode}, vars: extra.vars, parent: owner}));` `slot${slotKey}.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: ${parentNode}, vars: extra.vars, parent: extra.parent || owner}));`
); );
if (!ctx.parentNode) { if (!ctx.parentNode) {
ctx.addLine(`utils.defineProxy(result, ${parentNode}[0]);`); ctx.addLine(`utils.defineProxy(result, ${parentNode}[0]);`);
@@ -1341,14 +1341,14 @@ exports[`t-slot directive can define and call slots 2`] = `
c8.push(vn9); c8.push(vn9);
const slot10 = this.constructor.slots[context.__owl__.slotId + '_' + 'header']; const slot10 = this.constructor.slots[context.__owl__.slotId + '_' + 'header'];
if (slot10) { if (slot10) {
slot10.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: c9, vars: extra.vars, parent: owner})); slot10.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: c9, vars: extra.vars, parent: extra.parent || owner}));
} }
let c11 = [], p11 = {key:11}; let c11 = [], p11 = {key:11};
var vn11 = h('div', p11, c11); var vn11 = h('div', p11, c11);
c8.push(vn11); c8.push(vn11);
const slot12 = this.constructor.slots[context.__owl__.slotId + '_' + 'footer']; const slot12 = this.constructor.slots[context.__owl__.slotId + '_' + 'footer'];
if (slot12) { if (slot12) {
slot12.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: c11, vars: extra.vars, parent: owner})); slot12.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: c11, vars: extra.vars, parent: extra.parent || owner}));
} }
return vn8; return vn8;
}" }"
@@ -1489,7 +1489,7 @@ exports[`t-slot directive slots are rendered with proper context, part 2 1`] = `
var vn14 = h('a', p14, c14); var vn14 = h('a', p14, c14);
const slot15 = this.constructor.slots[context.__owl__.slotId + '_' + 'default']; const slot15 = this.constructor.slots[context.__owl__.slotId + '_' + 'default'];
if (slot15) { if (slot15) {
slot15.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: c14, vars: extra.vars, parent: owner})); slot15.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: c14, vars: extra.vars, parent: extra.parent || owner}));
} }
return vn14; return vn14;
}" }"
@@ -1589,7 +1589,7 @@ exports[`t-slot directive slots are rendered with proper context, part 3 1`] = `
var vn14 = h('a', p14, c14); var vn14 = h('a', p14, c14);
const slot15 = this.constructor.slots[context.__owl__.slotId + '_' + 'default']; const slot15 = this.constructor.slots[context.__owl__.slotId + '_' + 'default'];
if (slot15) { if (slot15) {
slot15.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: c14, vars: extra.vars, parent: owner})); slot15.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: c14, vars: extra.vars, parent: extra.parent || owner}));
} }
return vn14; return vn14;
}" }"
@@ -1745,7 +1745,7 @@ exports[`t-slot directive template can just return a slot 1`] = `
if (slot10) { if (slot10) {
let children11= [] let children11= []
result = {} result = {}
slot10.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: children11, vars: extra.vars, parent: owner})); slot10.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: children11, vars: extra.vars, parent: extra.parent || owner}));
utils.defineProxy(result, children11[0]); utils.defineProxy(result, children11[0]);
} }
return result; return result;
+31
View File
@@ -4069,6 +4069,37 @@ describe("t-slot directive", () => {
expect(childrenChildren[0]).toBeInstanceOf(GrandChild); expect(childrenChildren[0]).toBeInstanceOf(GrandChild);
}); });
test("nested slots: evaluation context and parented relationship", async () => {
let slot;
class Slot extends Component<any, any> {
static template = xml`<span t-esc="props.val"/>`;
constructor(parent, props) {
super(parent, props);
slot = this;
}
}
class GrandChild extends Component<any, any> {
static template = xml`<div><t t-slot="default"/></div>`;
}
class Child extends Component<any, any> {
static components = { GrandChild };
static template = xml`
<GrandChild>
<t t-slot="default"/>
</GrandChild>`;
}
class Parent extends Component<any, any> {
static components = { Child, Slot };
static template = xml`<Child><Slot val="state.val"/></Child>`;
state = useState({ val: 3 });
}
const parent = new Parent();
await parent.mount(fixture);
expect(fixture.innerHTML).toBe("<div><span>3</span></div>");
expect(slot.__owl__.parent).toBeInstanceOf(GrandChild);
});
test("slot are properly rendered if inner props are changed", async () => { test("slot are properly rendered if inner props are changed", async () => {
env.qweb.addTemplates(` env.qweb.addTemplates(`
<templates> <templates>
+1 -1
View File
@@ -14,7 +14,7 @@ exports[`Link component can render simple cases 1`] = `
p8.on['click'] = extra.handlers['click' + 8]; p8.on['click'] = extra.handlers['click' + 8];
const slot9 = this.constructor.slots[context.__owl__.slotId + '_' + 'default']; const slot9 = this.constructor.slots[context.__owl__.slotId + '_' + 'default'];
if (slot9) { if (slot9) {
slot9.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: c8, vars: extra.vars, parent: owner})); slot9.call(this, context.__owl__.parent, Object.assign({}, extra, {parentNode: c8, vars: extra.vars, parent: extra.parent || owner}));
} }
return vn8; return vn8;
}" }"