From 37b275d40eef79d7ae1a3d00512eb6a96c8a34fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Fri, 25 Jan 2019 15:44:32 +0100 Subject: [PATCH] fix issue with mounted widget without proper vnode --- web/static/src/ts/core/Widget.ts | 5 +-- web/static/src/ts/core/qweb_vdom.ts | 2 +- web/static/tests/widget.test.ts | 51 +++++++++++++++++++---------- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/web/static/src/ts/core/Widget.ts b/web/static/src/ts/core/Widget.ts index 2452d5d5..29462f47 100644 --- a/web/static/src/ts/core/Widget.ts +++ b/web/static/src/ts/core/Widget.ts @@ -133,8 +133,9 @@ export class Widget { return Promise.all(promises).then(() => vnode); } - _mount(el: HTMLElement) { - this.el = el; + _mount(vnode: VNode) { + this.el = vnode.elm; + this._.vnode = vnode; if (this._.parent) { if (this._.parent._.isMounted) { this._.isMounted = true; diff --git a/web/static/src/ts/core/qweb_vdom.ts b/web/static/src/ts/core/qweb_vdom.ts index 1635ff2b..3f2d78c9 100644 --- a/web/static/src/ts/core/qweb_vdom.ts +++ b/web/static/src/ts/core/qweb_vdom.ts @@ -685,7 +685,7 @@ const widgetDirective: Directive = { `let _${widgetID} = new context.widgets['${value}'](context, ${props})` ); ctx.addLine( - `let def${defID} = _${widgetID}._start().then(() => _${widgetID}._render()).then(vnode=>{Object.assign(_${dummyID}, vnode);_${dummyID}.key="${dummyID}";_${dummyID}.data.hook = {create(_,vn){_${widgetID}._mount(vn.elm)}}})` + `let def${defID} = _${widgetID}._start().then(() => _${widgetID}._render()).then(vnode=>{Object.assign(_${dummyID}, vnode);_${dummyID}.key="${dummyID}";_${dummyID}.data.hook = {create(_,vn){_${widgetID}._mount(vn)}}})` ); ctx.addLine(`extra.promises.push(def${defID})`); diff --git a/web/static/tests/widget.test.ts b/web/static/tests/widget.test.ts index 8b1e81de..46dd78af 100644 --- a/web/static/tests/widget.test.ts +++ b/web/static/tests/widget.test.ts @@ -1,6 +1,6 @@ -import { Widget, WEnv } from "../src/ts/core/widget"; -import { idGenerator } from "../src/ts/core/utils"; import { QWeb } from "../src/ts/core/qweb_vdom"; +import { idGenerator } from "../src/ts/core/utils"; +import { WEnv, Widget } from "../src/ts/core/widget"; //------------------------------------------------------------------------------ // Setup and helpers @@ -31,6 +31,19 @@ function nextTick(): Promise { return Promise.resolve(); } +// Test widget +class Counter extends Widget { + name = "counter"; + template = `
`; + state = { + counter: 0 + }; + + inc() { + this.updateState({ counter: this.state.counter + 1 }); + } +} + //------------------------------------------------------------------------------ // Tests //------------------------------------------------------------------------------ @@ -48,22 +61,6 @@ describe("basic widget properties", () => { }); test("can be clicked on and updated", async () => { - const template = ` -
- `; - - class Counter extends Widget { - name = "counter"; - template = template; - state = { - counter: 0 - }; - - inc() { - this.updateState({ counter: this.state.counter + 1 }); - } - } - const counter = new Counter(env); const target = document.createElement("div"); await counter.mount(target); @@ -280,4 +277,22 @@ describe("composition", () => { await widget.mount(fixture); expect(widget.refs.mywidgetb instanceof WidgetB).toBe(true); }); + + test("modifying a sub widget", async () => { + class ParentWidget extends Widget { + template = `
`; + widgets = { Counter }; + } + const widget = new ParentWidget(env); + await widget.mount(fixture); + expect(fixture.innerHTML).toBe( + "
0
" + ); + const button = fixture.getElementsByTagName("button")[0]; + await button.click(); + await nextTick(); + expect(fixture.innerHTML).toBe( + "
1
" + ); + }); });