mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[IMP] component: define props as attribute (remove t-props)
This commit is contained in:
committed by
VincentSchippefilt
parent
466c12a0e6
commit
187eb922c0
+15
-7
@@ -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 = (<Element>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`
|
||||
);
|
||||
|
||||
@@ -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;
|
||||
}"
|
||||
`;
|
||||
|
||||
+23
-61
@@ -286,7 +286,7 @@ describe("lifecycle hooks", () => {
|
||||
|
||||
env.qweb.addTemplate(
|
||||
"ParentWidget",
|
||||
`<div>><t t-widget="child" t-props="{n:state.n}"/></div>`
|
||||
`<div><t t-widget="child" n="state.n"/></div>`
|
||||
);
|
||||
class ParentWidget extends Widget {
|
||||
widgets = { child: ChildWidget };
|
||||
@@ -300,7 +300,7 @@ describe("lifecycle hooks", () => {
|
||||
}
|
||||
env.qweb.addTemplate(
|
||||
"ChildWidget",
|
||||
`<div><t t-widget="childchild" t-props="{n:props.n}"/></div>`
|
||||
`<div><t t-widget="childchild" n="props.n"/></div>`
|
||||
);
|
||||
class ChildWidget extends Widget {
|
||||
widgets = { childchild: ChildChildWidget };
|
||||
@@ -453,7 +453,7 @@ describe("lifecycle hooks", () => {
|
||||
`
|
||||
<div>
|
||||
<div t-if="state.flag">
|
||||
<t t-widget="ChildWidget" t-props="{n: state.n}"/>
|
||||
<t t-widget="ChildWidget" n="state.n"/>
|
||||
</div>
|
||||
</div>`
|
||||
);
|
||||
@@ -534,7 +534,7 @@ describe("lifecycle hooks", () => {
|
||||
let def = makeDeferred();
|
||||
env.qweb.addTemplate(
|
||||
"Parent",
|
||||
'<span><t t-widget="Child" t-props="{n: state.n}"/></span>'
|
||||
'<span><t t-widget="Child" n="state.n"/></span>'
|
||||
);
|
||||
class Parent extends Widget {
|
||||
state = { n: 1 };
|
||||
@@ -586,7 +586,7 @@ describe("lifecycle hooks", () => {
|
||||
|
||||
env.qweb.addTemplate(
|
||||
"Parent",
|
||||
'<div><t t-widget="Child" t-props="{a:state.a}"/></div>'
|
||||
'<div><t t-widget="Child" a="state.a"/></div>'
|
||||
);
|
||||
class Parent extends Widget {
|
||||
state = { a: 1 };
|
||||
@@ -629,7 +629,7 @@ describe("lifecycle hooks", () => {
|
||||
let shouldUpdate = false;
|
||||
env.qweb.addTemplate(
|
||||
"Parent",
|
||||
`<div><t t-widget="Child" t-props="{val:state.val}"/></div>`
|
||||
`<div><t t-widget="Child" val="state.val"/></div>`
|
||||
);
|
||||
class Parent extends Widget {
|
||||
state = { val: 42 };
|
||||
@@ -696,7 +696,7 @@ describe("lifecycle hooks", () => {
|
||||
"ParentWidget",
|
||||
`
|
||||
<div>
|
||||
<t t-widget="child" t-props="{v: state.n}"/>
|
||||
<t t-widget="child" v="state.n"/>
|
||||
</div>`
|
||||
);
|
||||
class ParentWidget extends Widget {
|
||||
@@ -743,7 +743,7 @@ describe("lifecycle hooks", () => {
|
||||
"ParentWidget",
|
||||
`
|
||||
<div>
|
||||
<t t-if="state.flag" t-widget="child" t-props="{v: state.n}" t-keepalive="1"/>
|
||||
<t t-if="state.flag" t-widget="child" v="state.n" t-keepalive="1"/>
|
||||
</div>`
|
||||
);
|
||||
class ParentWidget extends Widget {
|
||||
@@ -1153,7 +1153,7 @@ describe("composition", () => {
|
||||
`
|
||||
<div>
|
||||
<t t-foreach="state.numbers" t-as="number">
|
||||
<t t-widget="ChildWidget" t-key="number" t-props="{n: number}"/>
|
||||
<t t-widget="ChildWidget" t-key="number" n="number"/>
|
||||
</t>
|
||||
</div>`
|
||||
);
|
||||
@@ -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",
|
||||
`<div><t t-widget="child" t-props="{value: state.val}"/></div>`
|
||||
`<div><t t-widget="child" value="state.val"/></div>`
|
||||
);
|
||||
class Parent extends Widget {
|
||||
widgets = { child: Child };
|
||||
@@ -1311,37 +1311,13 @@ describe("props evaluation (with t-props directive)", () => {
|
||||
expect(fixture.innerHTML).toBe("<div><span>42</span></div>");
|
||||
});
|
||||
|
||||
test("object prop value", async () => {
|
||||
env.qweb.addTemplate(
|
||||
"Parent",
|
||||
`<div><t t-widget="child" t-props="state"/></div>`
|
||||
);
|
||||
class Parent extends Widget {
|
||||
widgets = { child: Child };
|
||||
state = { val: 42 };
|
||||
}
|
||||
|
||||
env.qweb.addTemplate("Child", `<span><t t-esc="state.someval"/></span>`);
|
||||
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("<div><span>42</span></div>");
|
||||
});
|
||||
|
||||
test("accept ES6-like syntax for props (with getters)", async () => {
|
||||
env.qweb.addTemplate("Child", `<span><t t-esc="props.greetings"/></span>`);
|
||||
class Child extends Widget {}
|
||||
|
||||
env.qweb.addTemplate(
|
||||
"Parent",
|
||||
`<div><t t-widget="child" t-props="{greetings}"/></div>`
|
||||
`<div><t t-widget="child" greetings="greetings"/></div>`
|
||||
);
|
||||
class Parent extends Widget {
|
||||
widgets = { child: Child };
|
||||
@@ -1354,13 +1330,13 @@ describe("props evaluation (with t-props directive)", () => {
|
||||
expect(fixture.innerHTML).toBe("<div><span>hello aaron</span></div>");
|
||||
});
|
||||
|
||||
test("t-set works with t-props", async () => {
|
||||
test("t-set works ", async () => {
|
||||
env.qweb.addTemplate(
|
||||
"Parent",
|
||||
`
|
||||
<div>
|
||||
<t t-set="val" t-value="42"/>
|
||||
<t t-widget="child" t-props="{val:val}"/>
|
||||
<t t-widget="child" val="val"/>
|
||||
</div>`
|
||||
);
|
||||
class Parent extends Widget {
|
||||
@@ -1626,7 +1602,7 @@ describe("random stuff/miscellaneous", () => {
|
||||
// twice.
|
||||
env.qweb.addTemplate(
|
||||
"Parent",
|
||||
`<div><t t-widget="child" t-props="{flag:state.flag}"/></div>`
|
||||
`<div><t t-widget="child" flag="state.flag"/></div>`
|
||||
);
|
||||
class Parent extends Widget {
|
||||
widgets = { child: Child };
|
||||
@@ -1650,7 +1626,7 @@ describe("random stuff/miscellaneous", () => {
|
||||
test("snapshotting compiled code", async () => {
|
||||
env.qweb.addTemplate(
|
||||
"Parent",
|
||||
`<div><t t-widget="child" t-key="'somestring'" t-props="{flag:state.flag}"/></div>`
|
||||
`<div><t t-widget="child" t-key="'somestring'" flag="state.flag"/></div>`
|
||||
);
|
||||
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", `<div><t t-widget="child"/></div>`);
|
||||
class Parent extends Widget {
|
||||
widgets = { child: Child };
|
||||
}
|
||||
|
||||
env.qweb.addTemplate("Child", `<span>abc</span>`);
|
||||
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",
|
||||
`<div><t t-if="state.val > 1"><t t-widget="Child" t-props="{val: state.val}"/></t></div>`
|
||||
`<div><t t-if="state.val > 1"><t t-widget="Child" val="state.val"/></t></div>`
|
||||
);
|
||||
class W extends Widget {
|
||||
widgets = { Child };
|
||||
@@ -1964,8 +1926,8 @@ describe("async rendering", () => {
|
||||
"Parent",
|
||||
`
|
||||
<div>
|
||||
<t t-widget="ChildA" t-props="{val:state.valA}"/>
|
||||
<t t-if="state.flagB"><t t-widget="ChildB" t-props="{val:state.valB}"/></t>
|
||||
<t t-widget="ChildA" val="state.valA"/>
|
||||
<t t-if="state.flagB"><t t-widget="ChildB" val="state.valB"/></t>
|
||||
</div>`
|
||||
);
|
||||
class Parent extends Widget {
|
||||
@@ -2015,7 +1977,7 @@ describe("async rendering", () => {
|
||||
<ul>
|
||||
<t t-foreach="items" t-as="item">
|
||||
<li t-key="'li_'+item">
|
||||
<t t-widget="Child" t-props="{ item }"/>
|
||||
<t t-widget="Child" item="item"/>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
@@ -2059,7 +2021,7 @@ describe("async rendering", () => {
|
||||
env.qweb.addTemplate(
|
||||
"Parent",
|
||||
`
|
||||
<div><t t-if="state.flag"><t t-widget="Child" t-props="{val: state.val}"/></t></div>`
|
||||
<div><t t-if="state.flag"><t t-widget="Child" val="state.val"/></t></div>`
|
||||
);
|
||||
class Parent extends Widget {
|
||||
widgets = { Child };
|
||||
@@ -2254,7 +2216,7 @@ describe("widget and observable state", () => {
|
||||
expect.assertions(1);
|
||||
env.qweb.addTemplate(
|
||||
"Parent",
|
||||
`<div><t t-widget="Child" t-props="state.obj"/></div>`
|
||||
`<div><t t-widget="Child" obj="state.obj"/></div>`
|
||||
);
|
||||
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);
|
||||
|
||||
+7
-7
@@ -414,7 +414,7 @@ describe("connecting a component to store", () => {
|
||||
`
|
||||
<div>
|
||||
<t t-foreach="props.todos" t-as="todo" t-key="todo">
|
||||
<t t-widget="Todo" t-props="todo"/>
|
||||
<t t-widget="Todo" msg="todo.msg"/>
|
||||
</t>
|
||||
</div>`
|
||||
);
|
||||
@@ -557,7 +557,7 @@ describe("connecting a component to store", () => {
|
||||
"TodoList",
|
||||
`<div>
|
||||
<t t-foreach="props.todos" t-as="todo">
|
||||
<t t-widget="ConnectedTodo" t-props="todo"/>
|
||||
<t t-widget="ConnectedTodo" id="todo.id"/>
|
||||
</t>
|
||||
</div>`
|
||||
);
|
||||
@@ -618,7 +618,7 @@ describe("connecting a component to store", () => {
|
||||
"TodoList",
|
||||
`<div>
|
||||
<t t-foreach="props.todos" t-as="todo">
|
||||
<t t-widget="ConnectedTodo" t-props="todo"/>
|
||||
<t t-widget="ConnectedTodo" id="todo.id"/>
|
||||
</t>
|
||||
</div>`
|
||||
);
|
||||
@@ -650,7 +650,7 @@ describe("connecting a component to store", () => {
|
||||
env.qweb.addTemplate(
|
||||
"App",
|
||||
`<div>
|
||||
<t t-widget="ConnectedBeer" t-props="{id: state.beerId}"/>
|
||||
<t t-widget="ConnectedBeer" id="state.beerId"/>
|
||||
</div>`
|
||||
);
|
||||
class App extends Component<any, any, any> {
|
||||
@@ -728,7 +728,7 @@ describe("connecting a component to store", () => {
|
||||
env.qweb.addTemplate(
|
||||
"App",
|
||||
`<div>
|
||||
<t t-widget="ConnectedBeer" t-props="{id: state.beerId}"/>
|
||||
<t t-widget="ConnectedBeer" id="state.beerId"/>
|
||||
</div>`
|
||||
);
|
||||
class App extends Component<any, any, any> {
|
||||
@@ -797,7 +797,7 @@ describe("connecting a component to store", () => {
|
||||
env.qweb.addTemplate(
|
||||
"App",
|
||||
`<div>
|
||||
<t t-widget="ConnectedBeer" t-props="{id: state.beerId}"/>
|
||||
<t t-widget="ConnectedBeer" id="state.beerId"/>
|
||||
</div>`
|
||||
);
|
||||
class App extends Component<any, any, any> {
|
||||
@@ -876,7 +876,7 @@ describe("connecting a component to store", () => {
|
||||
"Parent",
|
||||
`
|
||||
<div>
|
||||
<t t-widget="Child" t-props="{key: props.current}"/>
|
||||
<t t-widget="Child" key="props.current"/>
|
||||
</div>
|
||||
`
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user