From 45a2b0122d976937b003b1f361cab05962c84bbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Wed, 12 Jun 2019 11:36:36 +0200 Subject: [PATCH] [FIX] qweb: add better support for template with only strings --- src/qweb_core.ts | 7 +++++-- src/qweb_directives.ts | 14 ++++++++++---- tests/__snapshots__/qweb.test.ts.snap | 25 +++++++++++++++++++++++++ tests/qweb.test.ts | 10 ++++++++++ 4 files changed, 50 insertions(+), 6 deletions(-) diff --git a/src/qweb_core.ts b/src/qweb_core.ts index 3652dc73..17e14942 100644 --- a/src/qweb_core.ts +++ b/src/qweb_core.ts @@ -329,13 +329,15 @@ export class QWeb { } if (ctx.parentNode) { ctx.addLine(`c${ctx.parentNode}.push({text: \`${text}\`});`); + } else if (ctx.parentTextNode) { + ctx.addLine(`vn${ctx.parentTextNode}.text += \`${text}\`;`); } else { // this is an unusual situation: this text node is the result of the // template rendering. let nodeID = ctx.generateID(); ctx.addLine(`var vn${nodeID} = {text: \`${text}\`};`); ctx.rootContext.rootNode = nodeID; - ctx.rootContext.parentNode = nodeID; + ctx.rootContext.parentTextNode = nodeID; } return; } @@ -620,6 +622,7 @@ export class Context { variables: { [key: string]: QWebVar } = {}; escaping: boolean = false; parentNode: number | null = null; + parentTextNode: number | null = null; rootNode: number | null = null; indentLevel: number = 0; rootContext: Context; @@ -644,7 +647,7 @@ export class Context { } withParent(node: number): Context { - if (this === this.rootContext && this.parentNode) { + if (this === this.rootContext && (this.parentNode || this.parentTextNode)) { throw new Error("A template should not have more than one root node"); } if (!this.rootContext.rootNode) { diff --git a/src/qweb_directives.ts b/src/qweb_directives.ts index 968e3b12..ba3afbda 100644 --- a/src/qweb_directives.ts +++ b/src/qweb_directives.ts @@ -44,11 +44,17 @@ function compileValueNode(value: any, node: Element, qweb: QWeb, ctx: Context) { exprID = value.id; } ctx.addIf(`${exprID} || ${exprID} === 0`); - if (!ctx.parentNode) { - throw new Error("Should not have a text node without a parent"); - } if (ctx.escaping) { - ctx.addLine(`c${ctx.parentNode}.push({text: ${exprID}});`); + if (ctx.parentTextNode) { + ctx.addLine(`vn${ctx.parentTextNode}.text += ${exprID};`); + } else if (ctx.parentNode) { + ctx.addLine(`c${ctx.parentNode}.push({text: ${exprID}});`); + } else { + let nodeID = ctx.generateID(); + ctx.rootContext.rootNode = nodeID; + ctx.rootContext.parentTextNode = nodeID; + ctx.addLine(`var vn${nodeID} = {text: ${exprID}};`); + } } else { let fragID = ctx.generateID(); ctx.addLine(`var frag${fragID} = this.utils.getFragment(${exprID})`); diff --git a/tests/__snapshots__/qweb.test.ts.snap b/tests/__snapshots__/qweb.test.ts.snap index 2a6346c4..e3139aa5 100644 --- a/tests/__snapshots__/qweb.test.ts.snap +++ b/tests/__snapshots__/qweb.test.ts.snap @@ -726,6 +726,18 @@ exports[`static templates empty div 1`] = ` }" `; +exports[`static templates simple dynamic value 1`] = ` +"function anonymous(context,extra +) { + var h = this.utils.h; + var _1 = context['text']; + if (_1 || _1 === 0) { + var vn2 = {text: _1}; + } + return vn2; +}" +`; + exports[`static templates simple string 1`] = ` "function anonymous(context,extra ) { @@ -735,6 +747,19 @@ exports[`static templates simple string 1`] = ` }" `; +exports[`static templates simple string, with some dynamic value 1`] = ` +"function anonymous(context,extra +) { + var h = this.utils.h; + var vn1 = {text: \`hello \`}; + var _2 = context['text']; + if (_2 || _2 === 0) { + vn1.text += _2; + } + return vn1; +}" +`; + exports[`t-call (template calling basic caller 1`] = ` "function anonymous(context,extra ) { diff --git a/tests/qweb.test.ts b/tests/qweb.test.ts index 0d3b26d1..61d03aac 100644 --- a/tests/qweb.test.ts +++ b/tests/qweb.test.ts @@ -24,6 +24,16 @@ describe("static templates", () => { expect(renderToString(qweb, "test")).toBe("hello vdom"); }); + test("simple dynamic value", () => { + qweb.addTemplate("test", ""); + expect(renderToString(qweb, "test", {text: "hello vdom"})).toBe("hello vdom"); + }); + + test("simple string, with some dynamic value", () => { + qweb.addTemplate("test", "hello "); + expect(renderToString(qweb, "test", {text: "vdom"})).toBe("hello vdom"); + }); + test("empty div", () => { qweb.addTemplate("test", "
"); expect(renderToString(qweb, "test")).toBe("
");