mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[FIX] slots: better heuristic to determine named slot content
Unfortunately, we chose to use the directive `t-set` to define sub slot contents in a template. The goal was to reuse a directive for a similar use case: defining sub template is almost the same as defining a slot content. Obviously, this introduces a name conflict: the inner content of a component cannot use t-set t-value anymore (nor t-set with a body value), since they are interpreted as slot names. We mitigate the issue here by only interpreting as slot content the `t-set` statement located immediately below the parent component tag name and with a body content. However, a real fix need to introduce an additional directive to resolve the ambiguity.
This commit is contained in:
@@ -400,7 +400,12 @@ QWeb.addDirective({
|
|||||||
|
|
||||||
if (hasSlots) {
|
if (hasSlots) {
|
||||||
const clone = <Element>node.cloneNode(true);
|
const clone = <Element>node.cloneNode(true);
|
||||||
const slotNodes = clone.querySelectorAll("[t-set]");
|
const slotNodes: Element[] = [];
|
||||||
|
for (let el of clone.children) {
|
||||||
|
if (el.getAttribute("t-set") && el.hasChildNodes()) {
|
||||||
|
slotNodes.push(el);
|
||||||
|
}
|
||||||
|
}
|
||||||
const slotId = QWeb.nextSlotId++;
|
const slotId = QWeb.nextSlotId++;
|
||||||
ctx.addLine(`w${componentID}.__owl__.slotId = ${slotId};`);
|
ctx.addLine(`w${componentID}.__owl__.slotId = ${slotId};`);
|
||||||
if (slotNodes.length) {
|
if (slotNodes.length) {
|
||||||
|
|||||||
@@ -469,6 +469,21 @@ exports[`t-slot directive slots are rendered with proper context, part 4 2`] = `
|
|||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`t-slot directive t-set t-value in a slot 1`] = `
|
||||||
|
"function anonymous(context, extra
|
||||||
|
) {
|
||||||
|
// Template name: \\"__template__1\\"
|
||||||
|
let h = this.h;
|
||||||
|
let c4 = [], p4 = {key:4};
|
||||||
|
let vn4 = h('span', p4, c4);
|
||||||
|
const slot5 = this.constructor.slots[context.__owl__.slotId + '_' + 'default'];
|
||||||
|
if (slot5) {
|
||||||
|
slot5.call(this, context.__owl__.scope, Object.assign({}, extra, {parentNode: c4, parent: extra.parent || context}));
|
||||||
|
}
|
||||||
|
return vn4;
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`t-slot directive template can just return a slot 1`] = `
|
exports[`t-slot directive template can just return a slot 1`] = `
|
||||||
"function anonymous(context, extra
|
"function anonymous(context, extra
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -873,4 +873,28 @@ describe("t-slot directive", () => {
|
|||||||
await parent.mount(fixture);
|
await parent.mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><div><span><p>heyaaron</p></span></div></div>");
|
expect(fixture.innerHTML).toBe("<div><div><span><p>heyaaron</p></span></div></div>");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("t-set t-value in a slot", async () => {
|
||||||
|
class Dialog extends Component {
|
||||||
|
static template = xml`
|
||||||
|
<span>
|
||||||
|
<t t-slot="default"/>
|
||||||
|
</span>`;
|
||||||
|
}
|
||||||
|
class Parent extends Component {
|
||||||
|
static template = xml`
|
||||||
|
<div>
|
||||||
|
<Dialog>
|
||||||
|
<t t-set="rainbow" t-value="'dash'"/>
|
||||||
|
<t t-esc="rainbow"/>
|
||||||
|
</Dialog>
|
||||||
|
</div>`;
|
||||||
|
static components = { Dialog };
|
||||||
|
}
|
||||||
|
const parent = new Parent();
|
||||||
|
await parent.mount(fixture);
|
||||||
|
|
||||||
|
expect(fixture.innerHTML).toBe("<div><span>dash</span></div>");
|
||||||
|
expect(env.qweb.templates[Dialog.template].fn.toString()).toMatchSnapshot();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user