From 187eb922c0ad1c049c5cbe541b22a83fc7c53f6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Mon, 3 Jun 2019 10:10:41 +0200 Subject: [PATCH] [IMP] component: define props as attribute (remove t-props) --- src/qweb_extensions.ts | 22 ++++-- tests/__snapshots__/component.test.ts.snap | 42 +---------- tests/component.test.ts | 84 ++++++---------------- tests/store.test.ts | 14 ++-- 4 files changed, 46 insertions(+), 116 deletions(-) diff --git a/src/qweb_extensions.ts b/src/qweb_extensions.ts index 1a09b417..b4085ffd 100644 --- a/src/qweb_extensions.ts +++ b/src/qweb_extensions.ts @@ -352,19 +352,25 @@ QWeb.addDirective({ ctx.rootContext.shouldDefineOwner = true; ctx.rootContext.shouldDefineQWeb = true; ctx.rootContext.shouldDefineUtils = true; - let props = node.getAttribute("t-props"); let keepAlive = node.getAttribute("t-keepalive") ? true : false; // t-on- events and t-transition const events: [string, string][] = []; let transition: string = ""; const attributes = (node).attributes; + const props: { [key: string]: string } = {}; for (let i = 0; i < attributes.length; i++) { const name = attributes[i].name; + const value = attributes[i].textContent!; if (name.startsWith("t-on-")) { - events.push([name.slice(5), attributes[i].textContent!]); + events.push([name.slice(5), value]); } else if (name === "t-transition") { - transition = attributes[i].textContent!; + transition = value; + } else if (!name.startsWith("t-")) { + if (name !== "class" && name !== "style") { + // this is a prop! + props[name] = ctx.formatExpression(value); + } } } @@ -372,9 +378,11 @@ QWeb.addDirective({ if (key) { key = ctx.formatExpression(key); } - if (props) { - props = ctx.formatExpression(props); - } + + // computing the props string representing the props object + let propStr = Object.keys(props) + .map(k => k + ":" + props[k]) + .join(","); let dummyID = ctx.generateID(); let defID = ctx.generateID(); let widgetID = ctx.generateID(); @@ -456,7 +464,7 @@ QWeb.addDirective({ ctx.addLine( `let w${widgetID} = ${templateID} in context.__owl__.cmap ? context.__owl__.children[context.__owl__.cmap[${templateID}]] : false;` ); - ctx.addLine(`let props${widgetID} = ${props || "{}"};`); + ctx.addLine(`let props${widgetID} = {${propStr}};`); ctx.addIf( `w${widgetID} && w${widgetID}.__owl__.renderPromise && !w${widgetID}.__owl__.vnode` ); diff --git a/tests/__snapshots__/component.test.ts.snap b/tests/__snapshots__/component.test.ts.snap index a57e3413..677b5690 100644 --- a/tests/__snapshots__/component.test.ts.snap +++ b/tests/__snapshots__/component.test.ts.snap @@ -237,7 +237,7 @@ exports[`random stuff/miscellaneous snapshotting compiled code 1`] = ` c1.push(null); let def3; let w4 = key5 in context.__owl__.cmap ? context.__owl__.children[context.__owl__.cmap[key5]] : false; - let props4 = {flag: context['state'].flag}; + let props4 = {flag:context['state'].flag}; if (w4 && w4.__owl__.renderPromise && !w4.__owl__.vnode) { if (utils.shallowEqual(props4, w4.__owl__.renderProps)) { def3 = w4.__owl__.renderPromise; @@ -262,43 +262,3 @@ exports[`random stuff/miscellaneous snapshotting compiled code 1`] = ` return vn1; }" `; - -exports[`random stuff/miscellaneous t-props should not be undefined (snapshotting) 1`] = ` -"function anonymous(context,extra -) { - let utils = this.utils; - let QWeb = this.constructor; - let owner = context; - var h = this.utils.h; - let c1 = [], p1 = {key:1}; - var vn1 = h('div', p1, c1); - //WIDGET - let _2_index = c1.length; - c1.push(null); - let def3; - let w4 = 4 in context.__owl__.cmap ? context.__owl__.children[context.__owl__.cmap[4]] : false; - let props4 = {}; - if (w4 && w4.__owl__.renderPromise && !w4.__owl__.vnode) { - if (utils.shallowEqual(props4, w4.__owl__.renderProps)) { - def3 = w4.__owl__.renderPromise; - } else { - w4.destroy(); - w4 = false; - } - } - if (!w4) { - let widgetKey4 = \`child\`; - let W4 = context.widgets && context.widgets[widgetKey4] || QWeb.widgets[widgetKey4]; - if (!W4) {throw new Error('Cannot find the definition of widget \\"' + widgetKey4 + '\\"')} - w4 = new W4(owner, props4); - context.__owl__.cmap[4] = w4.__owl__.id; - def3 = w4._prepare(); - def3 = def3.then(vnode=>{let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4._mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;}); - } else { - def3 = def3 || w4._updateProps(props4, extra.forceUpdate, extra.patchQueue); - def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;}); - } - extra.promises.push(def3); - return vn1; -}" -`; diff --git a/tests/component.test.ts b/tests/component.test.ts index 0bd3ed4c..f6f8e4fb 100644 --- a/tests/component.test.ts +++ b/tests/component.test.ts @@ -286,7 +286,7 @@ describe("lifecycle hooks", () => { env.qweb.addTemplate( "ParentWidget", - `
>
` + `
` ); class ParentWidget extends Widget { widgets = { child: ChildWidget }; @@ -300,7 +300,7 @@ describe("lifecycle hooks", () => { } env.qweb.addTemplate( "ChildWidget", - `
` + `
` ); class ChildWidget extends Widget { widgets = { childchild: ChildChildWidget }; @@ -453,7 +453,7 @@ describe("lifecycle hooks", () => { `
- +
` ); @@ -534,7 +534,7 @@ describe("lifecycle hooks", () => { let def = makeDeferred(); env.qweb.addTemplate( "Parent", - '' + '' ); class Parent extends Widget { state = { n: 1 }; @@ -586,7 +586,7 @@ describe("lifecycle hooks", () => { env.qweb.addTemplate( "Parent", - '
' + '
' ); class Parent extends Widget { state = { a: 1 }; @@ -629,7 +629,7 @@ describe("lifecycle hooks", () => { let shouldUpdate = false; env.qweb.addTemplate( "Parent", - `
` + `
` ); class Parent extends Widget { state = { val: 42 }; @@ -696,7 +696,7 @@ describe("lifecycle hooks", () => { "ParentWidget", `
- +
` ); class ParentWidget extends Widget { @@ -743,7 +743,7 @@ describe("lifecycle hooks", () => { "ParentWidget", `
- +
` ); class ParentWidget extends Widget { @@ -1153,7 +1153,7 @@ describe("composition", () => { `
- +
` ); @@ -1286,11 +1286,11 @@ describe("composition", () => { }); }); -describe("props evaluation (with t-props directive)", () => { +describe("props evaluation ", () => { test("explicit object prop", async () => { env.qweb.addTemplate( "Parent", - `
` + `
` ); class Parent extends Widget { widgets = { child: Child }; @@ -1311,37 +1311,13 @@ describe("props evaluation (with t-props directive)", () => { expect(fixture.innerHTML).toBe("
42
"); }); - test("object prop value", async () => { - env.qweb.addTemplate( - "Parent", - `
` - ); - class Parent extends Widget { - widgets = { child: Child }; - state = { val: 42 }; - } - - env.qweb.addTemplate("Child", ``); - class Child extends Widget { - state: { someval: number }; - constructor(parent: Parent, props: { val: number }) { - super(parent); - this.state = { someval: props.val }; - } - } - - const widget = new Parent(env); - await widget.mount(fixture); - expect(fixture.innerHTML).toBe("
42
"); - }); - test("accept ES6-like syntax for props (with getters)", async () => { env.qweb.addTemplate("Child", ``); class Child extends Widget {} env.qweb.addTemplate( "Parent", - `
` + `
` ); class Parent extends Widget { widgets = { child: Child }; @@ -1354,13 +1330,13 @@ describe("props evaluation (with t-props directive)", () => { expect(fixture.innerHTML).toBe("
hello aaron
"); }); - test("t-set works with t-props", async () => { + test("t-set works ", async () => { env.qweb.addTemplate( "Parent", `
- +
` ); class Parent extends Widget { @@ -1626,7 +1602,7 @@ describe("random stuff/miscellaneous", () => { // twice. env.qweb.addTemplate( "Parent", - `
` + `
` ); class Parent extends Widget { widgets = { child: Child }; @@ -1650,7 +1626,7 @@ describe("random stuff/miscellaneous", () => { test("snapshotting compiled code", async () => { env.qweb.addTemplate( "Parent", - `
` + `
` ); class Parent extends Widget { widgets = { child: Child }; @@ -1668,20 +1644,6 @@ describe("random stuff/miscellaneous", () => { expect(env.qweb.templates.Parent.fn.toString()).toMatchSnapshot(); }); - test("t-props should not be undefined (snapshotting)", async () => { - env.qweb.addTemplate("Parent", `
`); - class Parent extends Widget { - widgets = { child: Child }; - } - - env.qweb.addTemplate("Child", `abc`); - class Child extends Widget {} - - const widget = new Parent(env); - await widget.mount(fixture); - expect(env.qweb.templates.Parent.fn.toString()).toMatchSnapshot(); - }); - test("component semantics", async () => { let steps: string[] = []; let c: C; @@ -1863,7 +1825,7 @@ describe("async rendering", () => { let n = 0; env.qweb.addTemplate( "W", - `
` + `
` ); class W extends Widget { widgets = { Child }; @@ -1964,8 +1926,8 @@ describe("async rendering", () => { "Parent", `
- - + +
` ); class Parent extends Widget { @@ -2015,7 +1977,7 @@ describe("async rendering", () => { @@ -2059,7 +2021,7 @@ describe("async rendering", () => { env.qweb.addTemplate( "Parent", ` -
` +
` ); class Parent extends Widget { widgets = { Child }; @@ -2254,7 +2216,7 @@ describe("widget and observable state", () => { expect.assertions(1); env.qweb.addTemplate( "Parent", - `
` + `
` ); class Parent extends Widget { state = { obj: { coffee: 1 } }; @@ -2263,7 +2225,7 @@ describe("widget and observable state", () => { class Child extends Widget { constructor(parent, props) { super(parent, props); - props.coffee = 2; + props.obj.coffee = 2; } } const parent = new Parent(env); diff --git a/tests/store.test.ts b/tests/store.test.ts index 4f361703..2a0a81f4 100644 --- a/tests/store.test.ts +++ b/tests/store.test.ts @@ -414,7 +414,7 @@ describe("connecting a component to store", () => { `
- +
` ); @@ -557,7 +557,7 @@ describe("connecting a component to store", () => { "TodoList", `
- +
` ); @@ -618,7 +618,7 @@ describe("connecting a component to store", () => { "TodoList", `
- +
` ); @@ -650,7 +650,7 @@ describe("connecting a component to store", () => { env.qweb.addTemplate( "App", `
- +
` ); class App extends Component { @@ -728,7 +728,7 @@ describe("connecting a component to store", () => { env.qweb.addTemplate( "App", `
- +
` ); class App extends Component { @@ -797,7 +797,7 @@ describe("connecting a component to store", () => { env.qweb.addTemplate( "App", `
- +
` ); class App extends Component { @@ -876,7 +876,7 @@ describe("connecting a component to store", () => { "Parent", `
- +
` );