diff --git a/README.md b/README.md index 46164b2e..76c9f8a3 100644 --- a/README.md +++ b/README.md @@ -48,4 +48,7 @@ Before even thinking about using this in a real scenario: - style is props? difference between props and attrs - text node - t-extend??? -- improve qweb generated code: do not assign object/array if no props/attrs/children \ No newline at end of file +- improve qweb generated code: do not assign object/array if no props/attrs/children +- improve qweb gen code: when building a vnode, propagate a structure with + children/attrs/hooks, fill it properly by each directive, then and only + then create node with minimal code \ No newline at end of file diff --git a/demo/src/Counter.ts b/demo/src/Counter.ts index 16cb0a41..656c6da9 100644 --- a/demo/src/Counter.ts +++ b/demo/src/Counter.ts @@ -1,7 +1,7 @@ import Widget from "../../src/core/widget"; const template = ` -
+
Value: diff --git a/demo/src/RootWidget.ts b/demo/src/RootWidget.ts index 34364d4e..78f137d4 100644 --- a/demo/src/RootWidget.ts +++ b/demo/src/RootWidget.ts @@ -2,7 +2,7 @@ import Widget from "../../src/core/widget"; import Counter from "./Counter"; const template = ` -
+
Root Widget diff --git a/src/core/qweb_vdom.ts b/src/core/qweb_vdom.ts index 5631d6f5..fd1c8e00 100644 --- a/src/core/qweb_vdom.ts +++ b/src/core/qweb_vdom.ts @@ -100,6 +100,7 @@ export default class QWeb { ifDirective, callDirective, onDirective, + refDirective, widgetDirective ].forEach(d => this.addDirective(d)); } @@ -653,6 +654,17 @@ const onDirective: Directive = { } }; +const refDirective: Directive = { + name: "ref", + priority: 95, + atNodeCreation({ ctx, node, nodeID }) { + let ref = node.getAttribute("t-ref"); + ctx.addLine(`p${ctx.parentNode}.hook = { + create: (_, n) => context.refs['${ref}'] = n.elm, + }`); + } +}; + const widgetDirective: Directive = { name: "widget", priority: 100, @@ -671,7 +683,6 @@ const widgetDirective: Directive = { ); ctx.addLine(`context._TEMP.push(def${defID})`); - // split into extra directive? let ref = node.getAttribute("t-ref"); if (ref) { ctx.addLine(`context.refs['${ref}'] = _${widgetID}`); diff --git a/tests/qweb_vdom.test.ts b/tests/qweb_vdom.test.ts index 24a2c8a9..64e24aeb 100644 --- a/tests/qweb_vdom.test.ts +++ b/tests/qweb_vdom.test.ts @@ -69,7 +69,7 @@ describe("error handling", () => { test("template with text node and tag", () => { const qweb = new QWeb(); - qweb.addTemplate("test", `textother node`); + qweb.addTemplate("test", `textother node`); expect(() => renderToString(qweb, "test")).toThrow( "A template should not have more than one root node" @@ -652,3 +652,14 @@ describe("t-on", () => { expect(a).toBe(6); }); }); + + +describe("t-ref", () => { + test("can get a ref on a node", () => { + const qweb = new QWeb(); + qweb.addTemplate("test", `
`); + let refs: any = {}; + renderToDOM(qweb, "test", { refs}); + expect(refs.myspan.tagName).toBe('SPAN'); + }); +}); diff --git a/tests/widget.test.ts b/tests/widget.test.ts index cb691b4b..d8607c77 100644 --- a/tests/widget.test.ts +++ b/tests/widget.test.ts @@ -120,21 +120,34 @@ describe("destroy method", () => { }); describe("composition", () => { + + class WidgetB extends Widget { + template= `
world
`; + } + + class WidgetA extends Widget { + name="a"; + template= `
Hello
`; + widgets = {b: WidgetB} + } + test("a widget with a sub widget", async () => { - class WidgetB extends Widget { - template= `
world
`; - } - - class WidgetA extends Widget { - name="a"; - template= `
Hello
`; - widgets = {b: WidgetB} - } - const widget = makeWidget(WidgetA); const target = document.createElement("div"); await widget.mount(target); expect(target.innerHTML).toBe("
Hello
world
"); }); + + test("t-refs on widget are widgets", async () => { + class WidgetC extends Widget { + name="a"; + template= `
Hello
`; + widgets = {b: WidgetB} + } + const widget = makeWidget(WidgetC); + const target = document.createElement("div"); + await widget.mount(target); + expect(widget.refs.mywidgetb instanceof WidgetB).toBe(true); + }); });