mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[IMP] qweb: t-on with t-widget: allow to bind args
This commit is contained in:
committed by
Géry Debongnie
parent
1c290c1172
commit
32921ecc20
+14
-6
@@ -183,7 +183,7 @@ QWeb.addDirective({
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const T_WIDGET_MODS_CODE = Object.assign({}, MODS_CODE, {
|
||||
self: "if (e.target !== vn.elm) {return}",
|
||||
self: "if (e.target !== vn.elm) {return}"
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -359,7 +359,7 @@ QWeb.addDirective({
|
||||
let keepAlive = node.getAttribute("t-keepalive") ? true : false;
|
||||
|
||||
// t-on- events and t-transition
|
||||
const events: [string, string[], string][] = [];
|
||||
const events: [string, string[], string, string][] = [];
|
||||
let transition: string = "";
|
||||
const attributes = (<Element>node).attributes;
|
||||
const props: { [key: string]: string } = {};
|
||||
@@ -368,7 +368,12 @@ QWeb.addDirective({
|
||||
const value = attributes[i].textContent!;
|
||||
if (name.startsWith("t-on-")) {
|
||||
const [eventName, ...mods] = name.slice(5).split(".");
|
||||
events.push([eventName, mods, value]);
|
||||
let extraArgs;
|
||||
let handlerName = value.replace(/\(.*\)/, function(args) {
|
||||
extraArgs = args.slice(1, -1);
|
||||
return "";
|
||||
});
|
||||
events.push([eventName, mods, handlerName, extraArgs]);
|
||||
} else if (name === "t-transition") {
|
||||
transition = value;
|
||||
} else if (!name.startsWith("t-")) {
|
||||
@@ -462,7 +467,10 @@ QWeb.addDirective({
|
||||
updateClassCode = `let cl=w${widgetID}.el.classList;for (let k in ${attVar}) {if (${attVar}[k]) {cl.add(k)} else {cl.remove(k)}}`;
|
||||
}
|
||||
let eventsCode = events
|
||||
.map(function([eventName, mods, handlerName]) {
|
||||
.map(function([eventName, mods, handlerName, extraArgs]) {
|
||||
let params = extraArgs
|
||||
? `owner, ${ctx.formatExpression(extraArgs)}`
|
||||
: "owner";
|
||||
let handler;
|
||||
if (mods.length > 0) {
|
||||
handler = `function (e) {`;
|
||||
@@ -471,9 +479,9 @@ QWeb.addDirective({
|
||||
return T_WIDGET_MODS_CODE[mod];
|
||||
})
|
||||
.join("");
|
||||
handler += `owner['${handlerName}'].call(owner, e);}`;
|
||||
handler += `owner['${handlerName}'].call(${params}, e);}`;
|
||||
} else {
|
||||
handler = `owner['${handlerName}'].bind(owner)`;
|
||||
handler = `owner['${handlerName}'].bind(${params})`;
|
||||
}
|
||||
return `vn.elm.addEventListener('${eventName}', ${handler});`;
|
||||
})
|
||||
|
||||
@@ -222,6 +222,166 @@ exports[`composition t-widget with dynamic value 2 1`] = `
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`other directives with t-widget t-on with handler bound to argument 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=>{vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', owner['onEv'].bind(owner, 3));}};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;
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`other directives with t-widget t-on with handler bound to empty object (with non empty inner string) 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=>{vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', owner['onEv'].bind(owner, {}));}};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;
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`other directives with t-widget t-on with handler bound to empty object 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=>{vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', owner['onEv'].bind(owner, {}));}};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;
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`other directives with t-widget t-on with handler bound to object 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=>{vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', owner['onEv'].bind(owner, {val: 3}));}};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;
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`other directives with t-widget t-on with prevent and self modifiers (order matters) 1`] = `
|
||||
"function anonymous(context,extra
|
||||
) {
|
||||
|
||||
@@ -1173,7 +1173,7 @@ exports[`t-on can bind handlers with arguments 1`] = `
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`t-on can bind handlers with empty object (with non empty inner string 1`] = `
|
||||
exports[`t-on can bind handlers with empty object (with non empty inner string) 1`] = `
|
||||
"function anonymous(context,extra
|
||||
) {
|
||||
let owner = context;
|
||||
|
||||
@@ -1476,6 +1476,94 @@ describe("other directives with t-widget", () => {
|
||||
expect(widget.n).toBe(1);
|
||||
});
|
||||
|
||||
test("t-on with handler bound to argument", async () => {
|
||||
expect.assertions(3);
|
||||
env.qweb.addTemplates(`
|
||||
<templates>
|
||||
<div t-name="ParentWidget"><t t-widget="child" t-on-ev="onEv(3)"/></div>
|
||||
</templates>
|
||||
`);
|
||||
class ParentWidget extends Widget {
|
||||
widgets = { child: Child };
|
||||
onEv(n, ev) {
|
||||
expect(n).toBe(3);
|
||||
expect(ev.detail).toBe(43);
|
||||
}
|
||||
}
|
||||
class Child extends Widget {}
|
||||
const widget = new ParentWidget(env);
|
||||
await widget.mount(fixture);
|
||||
let child = children(widget)[0];
|
||||
child.trigger("ev", 43);
|
||||
expect(env.qweb.templates.ParentWidget.fn.toString()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("t-on with handler bound to object", async () => {
|
||||
expect.assertions(3);
|
||||
env.qweb.addTemplates(`
|
||||
<templates>
|
||||
<div t-name="ParentWidget"><t t-widget="child" t-on-ev="onEv({val: 3})"/></div>
|
||||
</templates>
|
||||
`);
|
||||
class ParentWidget extends Widget {
|
||||
widgets = { child: Child };
|
||||
onEv(o, ev) {
|
||||
expect(o).toEqual({ val: 3 });
|
||||
expect(ev.detail).toBe(43);
|
||||
}
|
||||
}
|
||||
class Child extends Widget {}
|
||||
const widget = new ParentWidget(env);
|
||||
await widget.mount(fixture);
|
||||
let child = children(widget)[0];
|
||||
child.trigger("ev", 43);
|
||||
expect(env.qweb.templates.ParentWidget.fn.toString()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("t-on with handler bound to empty object", async () => {
|
||||
expect.assertions(3);
|
||||
env.qweb.addTemplates(`
|
||||
<templates>
|
||||
<div t-name="ParentWidget"><t t-widget="child" t-on-ev="onEv({})"/></div>
|
||||
</templates>
|
||||
`);
|
||||
class ParentWidget extends Widget {
|
||||
widgets = { child: Child };
|
||||
onEv(o, ev) {
|
||||
expect(o).toEqual({});
|
||||
expect(ev.detail).toBe(43);
|
||||
}
|
||||
}
|
||||
class Child extends Widget {}
|
||||
const widget = new ParentWidget(env);
|
||||
await widget.mount(fixture);
|
||||
let child = children(widget)[0];
|
||||
child.trigger("ev", 43);
|
||||
expect(env.qweb.templates.ParentWidget.fn.toString()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("t-on with handler bound to empty object (with non empty inner string)", async () => {
|
||||
expect.assertions(3);
|
||||
env.qweb.addTemplates(`
|
||||
<templates>
|
||||
<div t-name="ParentWidget"><t t-widget="child" t-on-ev="onEv({ })"/></div>
|
||||
</templates>
|
||||
`);
|
||||
class ParentWidget extends Widget {
|
||||
widgets = { child: Child };
|
||||
onEv(o, ev) {
|
||||
expect(o).toEqual({});
|
||||
expect(ev.detail).toBe(43);
|
||||
}
|
||||
}
|
||||
class Child extends Widget {}
|
||||
const widget = new ParentWidget(env);
|
||||
await widget.mount(fixture);
|
||||
let child = children(widget)[0];
|
||||
child.trigger("ev", 43);
|
||||
expect(env.qweb.templates.ParentWidget.fn.toString()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("t-on with stop and/or prevent modifiers", async () => {
|
||||
expect.assertions(7);
|
||||
env.qweb.addTemplates(`
|
||||
|
||||
+1
-1
@@ -896,7 +896,7 @@ describe("t-on", () => {
|
||||
(<HTMLElement>node).click();
|
||||
});
|
||||
|
||||
test("can bind handlers with empty object (with non empty inner string", () => {
|
||||
test("can bind handlers with empty object (with non empty inner string)", () => {
|
||||
expect.assertions(2);
|
||||
qweb.addTemplate(
|
||||
"test",
|
||||
|
||||
Reference in New Issue
Block a user