mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[IMP] qweb: add support for event capture
In this commit, we uses the "!" as suffix to designate an event that should be captured. This is inspired by the Vue source code. This solves the issue of communicating additional information to the underlying virtual dom. However, this will most likely disappear when we rewrite the vdom as a virtual block system. closes #650
This commit is contained in:
@@ -299,6 +299,8 @@ QWeb.addDirective({
|
||||
}
|
||||
let eventsCode = events
|
||||
.map(function([name, value]) {
|
||||
const capture = name.match(/\.capture/);
|
||||
name = capture ? name.replace(/\.capture/, "") : name;
|
||||
const { event, handler } = makeHandlerCode(
|
||||
ctx,
|
||||
name,
|
||||
@@ -306,6 +308,9 @@ QWeb.addDirective({
|
||||
false,
|
||||
T_COMPONENT_MODS_CODE
|
||||
);
|
||||
if (capture) {
|
||||
return `vn.elm.addEventListener('${event}', ${handler}, true);`;
|
||||
}
|
||||
return `vn.elm.addEventListener('${event}', ${handler});`;
|
||||
})
|
||||
.join("");
|
||||
|
||||
@@ -40,7 +40,10 @@ export function makeHandlerCode(
|
||||
putInCache: boolean,
|
||||
modcodes = MODS_CODE
|
||||
): HandlerInfo {
|
||||
const [event, ...mods] = fullName.slice(5).split(".");
|
||||
let [event, ...mods] = fullName.slice(5).split(".");
|
||||
if (mods.includes("capture")) {
|
||||
event = "!" + event;
|
||||
}
|
||||
if (!event) {
|
||||
throw new Error("Missing event name with t-on directive");
|
||||
}
|
||||
|
||||
+18
-6
@@ -70,8 +70,12 @@ function handleEvent(event: Event, vnode: VNode) {
|
||||
on = (vnode.data as VNodeData).on;
|
||||
|
||||
// call event handler(s) if exists
|
||||
if (on && on[name]) {
|
||||
invokeHandler(on[name], vnode, event);
|
||||
if (on) {
|
||||
if (on[name]) {
|
||||
invokeHandler(on[name], vnode, event);
|
||||
} else if (on["!" + name]) {
|
||||
invokeHandler(on["!" + name], vnode, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,13 +104,17 @@ function updateEventListeners(oldVnode: VNode, vnode?: VNode): void {
|
||||
if (!on) {
|
||||
for (name in oldOn) {
|
||||
// remove listener if element was changed or existing listeners removed
|
||||
oldElm.removeEventListener(name, oldListener, false);
|
||||
const capture = name.charAt(0) === "!";
|
||||
name = capture ? name.slice(1) : name;
|
||||
oldElm.removeEventListener(name, oldListener, capture);
|
||||
}
|
||||
} else {
|
||||
for (name in oldOn) {
|
||||
// remove listener if existing listener removed
|
||||
if (!on[name]) {
|
||||
oldElm.removeEventListener(name, oldListener, false);
|
||||
const capture = name.charAt(0) === "!";
|
||||
name = capture ? name.slice(1) : name;
|
||||
oldElm.removeEventListener(name, oldListener, capture);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -123,13 +131,17 @@ function updateEventListeners(oldVnode: VNode, vnode?: VNode): void {
|
||||
if (!oldOn) {
|
||||
for (name in on) {
|
||||
// add listener if element was changed or new listeners added
|
||||
elm.addEventListener(name, listener, false);
|
||||
const capture = name.charAt(0) === "!";
|
||||
name = capture ? name.slice(1) : name;
|
||||
elm.addEventListener(name, listener, capture);
|
||||
}
|
||||
} else {
|
||||
for (name in on) {
|
||||
// add listener if new listener added
|
||||
if (!oldOn[name]) {
|
||||
elm.addEventListener(name, listener, false);
|
||||
const capture = name.charAt(0) === "!";
|
||||
name = capture ? name.slice(1) : name;
|
||||
elm.addEventListener(name, listener, capture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user