mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
committed by
Géry Debongnie
parent
0ea1091692
commit
2beb12678e
@@ -719,6 +719,15 @@ the order may matter. For instance `t-on-click.prevent.self` will prevent all
|
||||
clicks while `t-on-click.self.prevent` will only prevent clicks on the element
|
||||
itself.
|
||||
|
||||
Finally, empty handlers are tolerated as they could be defined only to apply
|
||||
modifiers. For example,
|
||||
|
||||
```xml
|
||||
<button t-on-click.stop="">Do something</button>
|
||||
```
|
||||
|
||||
This will simply stop the propagation of the event.
|
||||
|
||||
### Form Input Bindings
|
||||
|
||||
It is very common to need to be able to read the value out of an html `input` (or
|
||||
|
||||
@@ -335,8 +335,10 @@ QWeb.addDirective({
|
||||
return T_COMPONENT_MODS_CODE[mod];
|
||||
})
|
||||
.join("");
|
||||
handler += `const fn = owner['${handlerValue}'];`;
|
||||
handler += `if (fn) { fn.call(${params}, e); } else { owner.${handlerValue}; }`;
|
||||
if (handlerValue) {
|
||||
handler += `const fn = owner['${handlerValue}'];`;
|
||||
handler += `if (fn) { fn.call(${params}, e); } else { owner.${handlerValue}; }`;
|
||||
}
|
||||
handler += `}`;
|
||||
return `vn.elm.addEventListener('${eventName}', ${handler});`;
|
||||
})
|
||||
|
||||
+17
-12
@@ -47,19 +47,24 @@ QWeb.addDirective({
|
||||
return MODS_CODE[mod];
|
||||
})
|
||||
.join("");
|
||||
if (!extraArgs) {
|
||||
handler += `const fn = context['${handlerName}'];`;
|
||||
handler += `if (fn) { fn.call(${params}, e); } else { context.${handlerName}; }`;
|
||||
handler += `}`;
|
||||
ctx.addLine(
|
||||
`extra.handlers['${eventName}' + ${nodeID}] = extra.handlers['${eventName}' + ${nodeID}] || ${handler};`
|
||||
);
|
||||
ctx.addLine(`p${nodeID}.on['${eventName}'] = extra.handlers['${eventName}' + ${nodeID}];`);
|
||||
if (handlerName) {
|
||||
if (!extraArgs) {
|
||||
handler += `const fn = context['${handlerName}'];`;
|
||||
handler += `if (fn) { fn.call(${params}, e); } else { context.${handlerName}; }`;
|
||||
handler += `}`;
|
||||
ctx.addLine(
|
||||
`extra.handlers['${eventName}' + ${nodeID}] = extra.handlers['${eventName}' + ${nodeID}] || ${handler};`
|
||||
);
|
||||
ctx.addLine(`p${nodeID}.on['${eventName}'] = extra.handlers['${eventName}' + ${nodeID}];`);
|
||||
} else {
|
||||
const handlerKey = `handler${ctx.generateID()}`;
|
||||
ctx.addLine(`const ${handlerKey} = context['${handlerName}'] && context['${handlerName}'].bind(${params});`);
|
||||
handler += `if (${handlerKey}) { ${handlerKey}(e); } else { context.${value}; }`;
|
||||
handler += `}`;
|
||||
ctx.addLine(`p${nodeID}.on['${eventName}'] = ${handler};`);
|
||||
}
|
||||
} else {
|
||||
const handlerKey = `handler${ctx.generateID()}`;
|
||||
ctx.addLine(`const ${handlerKey} = context['${handlerName}'] && context['${handlerName}'].bind(${params});`);
|
||||
handler += `if (${handlerKey}) { ${handlerKey}(e); } else { context.${value}; }`;
|
||||
handler += `}`;
|
||||
handler += "}";
|
||||
ctx.addLine(`p${nodeID}.on['${eventName}'] = ${handler};`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1058,6 +1058,48 @@ exports[`other directives with t-component t-on with inline statement 1`] = `
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`other directives with t-component t-on with no handler (only modifiers) 1`] = `
|
||||
"function anonymous(context,extra
|
||||
) {
|
||||
let utils = this.constructor.utils;
|
||||
let QWeb = this.constructor;
|
||||
let parent = context;
|
||||
let owner = context;
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
//COMPONENT
|
||||
let def3;
|
||||
let templateId4 = \`__5__\`;
|
||||
let w4 = templateId4 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[templateId4]] : false;
|
||||
let _2_index = c1.length;
|
||||
c1.push(null);
|
||||
let props4 = {};
|
||||
if (w4 && w4.__owl__.currentFiber && !w4.__owl__.vnode) {
|
||||
if (utils.shallowEqual(props4, w4.__owl__.currentFiber.props)) {
|
||||
def3 = w4.__owl__.currentFiber.promise;
|
||||
} else {
|
||||
w4.destroy();
|
||||
w4 = false;
|
||||
}
|
||||
}
|
||||
if (!w4) {
|
||||
let componentKey4 = \`ComponentA\`;
|
||||
let W4 = context.constructor.components[componentKey4] || QWeb.components[componentKey4]|| context['ComponentA'];
|
||||
if (!W4) {throw new Error('Cannot find the definition of component \\"' + componentKey4 + '\\"')}
|
||||
w4 = new W4(parent, props4);
|
||||
parent.__owl__.cmap[templateId4] = w4.__owl__.id;
|
||||
def3 = w4.__prepare(extra.fiber, undefined, undefined);
|
||||
def3 = def3.then(vnode=>{if (w4.__owl__.isDestroyed){return}vnode.data.hook = {create(_, vn){vn.elm.addEventListener('ev', function (e) {const fn = owner['onEv'];if (fn) { fn.call(owner, e); } else { owner.onEv; }});}};let pvnode=h(vnode.sel, {key: templateId4, 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.fiber, undefined, undefined);
|
||||
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-component t-on with prevent and self modifiers (order matters) 1`] = `
|
||||
"function anonymous(context,extra
|
||||
) {
|
||||
|
||||
@@ -2064,6 +2064,31 @@ describe("other directives with t-component", () => {
|
||||
expect(fixture.innerHTML).toBe('<div>1<span></span></div>');
|
||||
});
|
||||
|
||||
test("t-on with no handler (only modifiers)", async () => {
|
||||
expect.assertions(2);
|
||||
class ComponentB extends Component<any, any> {
|
||||
static template = xml`<span></span>`;
|
||||
}
|
||||
class ComponentA extends Component<any, any> {
|
||||
static template = xml`<p><ComponentB t-on-ev.prevent=""/></p>`;
|
||||
static components = { ComponentB };
|
||||
}
|
||||
class Parent extends Component<any, any> {
|
||||
static template = xml`<div><ComponentA t-on-ev="onEv"/></div>`;
|
||||
static components = { ComponentA };
|
||||
onEv(ev) {
|
||||
expect(ev.defaultPrevented).toBe(true);
|
||||
}
|
||||
}
|
||||
const parent = new Parent(env);
|
||||
await parent.mount(fixture);
|
||||
|
||||
let componentB = children(children(parent)[0])[0];
|
||||
componentB.trigger("ev");
|
||||
|
||||
expect(env.qweb.templates[Parent.template].fn.toString()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("t-if works with t-component", async () => {
|
||||
env.qweb.addTemplate("ParentWidget", `<div><t t-component="child" t-if="state.flag"/></div>`);
|
||||
class Child extends Widget {}
|
||||
|
||||
@@ -1789,6 +1789,22 @@ exports[`t-on t-on combined with t-raw 1`] = `
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`t-on t-on with empty handler (only modifiers) 1`] = `
|
||||
"function anonymous(context,extra
|
||||
) {
|
||||
let owner = context;
|
||||
var h = this.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
var vn1 = h('div', p1, c1);
|
||||
let c2 = [], p2 = {key:2,on:{}};
|
||||
var vn2 = h('button', p2, c2);
|
||||
c1.push(vn2);
|
||||
p2.on['click'] = function (e) {e.preventDefault();};
|
||||
c2.push({text: \`Button\`});
|
||||
return vn1;
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`t-on t-on with inline statement (function call) 1`] = `
|
||||
"function anonymous(context,extra
|
||||
) {
|
||||
|
||||
@@ -1213,6 +1213,24 @@ describe("t-on", () => {
|
||||
expect(steps).toEqual([1, 2]);
|
||||
});
|
||||
|
||||
test("t-on with empty handler (only modifiers)", () => {
|
||||
expect.assertions(2);
|
||||
qweb.addTemplate(
|
||||
"test",
|
||||
`<div>
|
||||
<button t-on-click.prevent="">Button</button>
|
||||
</div>`
|
||||
);
|
||||
const node = renderToDOM(qweb, "test", {}, { handlers: [] });
|
||||
|
||||
node.addEventListener('click', (e) => {
|
||||
expect(e.defaultPrevented).toBe(true);
|
||||
});
|
||||
|
||||
const button = (<HTMLElement>node).getElementsByTagName("button")[0];
|
||||
button.click();
|
||||
});
|
||||
|
||||
test("t-on combined with t-esc", async () => {
|
||||
expect.assertions(3);
|
||||
qweb.addTemplate("test", `<div><button t-on-click="onClick" t-esc="text"/></div>`);
|
||||
|
||||
Reference in New Issue
Block a user