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) {
|
||||
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++;
|
||||
ctx.addLine(`w${componentID}.__owl__.slotId = ${slotId};`);
|
||||
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`] = `
|
||||
"function anonymous(context, extra
|
||||
) {
|
||||
|
||||
@@ -873,4 +873,28 @@ describe("t-slot directive", () => {
|
||||
await parent.mount(fixture);
|
||||
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