[IMP] component: add support for default slot

closes #180
This commit is contained in:
Géry Debongnie
2019-06-15 14:47:05 +02:00
parent 60917bb102
commit 5ff501f8b8
3 changed files with 61 additions and 10 deletions
+15
View File
@@ -928,6 +928,21 @@ is not allowed. A workaround could be to wrap the content in a div:
</div>
```
Default slot: the first element inside the widget which is not a named slot will
be considered the `default` slot. For example:
```xml
<div t-name="Parent">
<t t-widget="Child">
<span>some content</span>
</t>
</div>
<div t-name="Child">
<t t-slot="default"/>
</div>
```
### Asynchronous Rendering
Working with asynchronous code always adds a lot of complexity to a system. Whenever
+23 -10
View File
@@ -508,7 +508,11 @@ QWeb.addDirective({
ctx.addLine(`let _${dummyID}_index = c${ctx.parentNode}.length;`);
if (async) {
ctx.addLine(`const patchQueue${widgetID} = [];`);
ctx.addLine(`c${ctx.parentNode}.push(w${widgetID} && w${widgetID}.__owl__.pvnode || null);`);
ctx.addLine(
`c${
ctx.parentNode
}.push(w${widgetID} && w${widgetID}.__owl__.pvnode || null);`
);
} else {
ctx.addLine(`c${ctx.parentNode}.push(null);`);
}
@@ -543,17 +547,26 @@ QWeb.addDirective({
);
// SLOTS
const slotNodes = node.querySelectorAll("[t-set]");
if (slotNodes.length) {
if (node.childElementCount) {
const clone = <Element>node.cloneNode(true);
const slotNodes = clone.querySelectorAll("[t-set]");
const slotId = qweb.nextSlotId++;
for (let i = 0, length = slotNodes.length; i < length; i++) {
const slotNode = slotNodes[i];
const key = slotNode.getAttribute("t-set")!;
slotNode.removeAttribute("t-set");
const slotFn = qweb._compile(`slot_${key}_template`, slotNode);
qweb.slots[`${slotId}_${key}`] = slotFn.bind(qweb);
}
ctx.addLine(`w${widgetID}.__owl__.slotId = ${slotId};`);
if (slotNodes.length) {
for (let i = 0, length = slotNodes.length; i < length; i++) {
const slotNode = slotNodes[i];
slotNode.parentElement!.removeChild(slotNode);
const key = slotNode.getAttribute("t-set")!;
slotNode.removeAttribute("t-set");
const slotFn = qweb._compile(`slot_${key}_template`, slotNode);
qweb.slots[`${slotId}_${key}`] = slotFn.bind(qweb);
}
}
if (clone.childElementCount) {
const content = clone.children[0];
const slotFn = qweb._compile(`slot_default_template`, content);
qweb.slots[`${slotId}_default`] = slotFn.bind(qweb);
}
}
ctx.addLine(`def${defID} = w${widgetID}._prepare();`);
+23
View File
@@ -3148,4 +3148,27 @@ describe("t-model directive", () => {
expect(comp.state.number).toBe("invalid");
expect(fixture.innerHTML).toBe("<div><input><span>invalid</span></div>");
});
test("content is the default slot", async () => {
env.qweb.addTemplates(`
<templates>
<div t-name="Parent">
<t t-widget="Dialog">
<span>sts rocks</span>
</t>
</div>
<div t-name="Dialog"><t t-slot="default"/></div>
</templates>
`);
class Dialog extends Widget {}
class Parent extends Widget {
widgets = { Dialog };
}
const parent = new Parent(env);
await parent.mount(fixture);
expect(fixture.innerHTML).toBe(
"<div><div><span>sts rocks</span></div></div>"
);
});
});