[FIX] events: correctly call handlers in iframes

Previously, event handlers would not work when an app was mounted in an
iframe, this is caused by a guard in the event handler that checks that
the target element is still in the document, but it doesn't check
against the correct document in the case of an iframe.

This commit changes the check to check against the target's
ownerDocument.
This commit is contained in:
Samuel Degueldre
2022-09-06 11:56:58 +02:00
committed by Géry Debongnie
parent c1afaeb92a
commit 8fe4c0c76e
3 changed files with 34 additions and 2 deletions
+2 -2
View File
@@ -27,8 +27,8 @@ function createElementHandler(evName: string, capture: boolean = false): EventHa
}
function listener(ev: Event) {
const currentTarget = ev.currentTarget;
if (!currentTarget || !document.contains(currentTarget as HTMLElement)) return;
const currentTarget = ev.currentTarget as HTMLElement;
if (!currentTarget || !currentTarget.ownerDocument.contains(currentTarget)) return;
const data = (currentTarget as any)[eventKey];
if (!data) return;
config.mainEventHandler(data, ev, currentTarget);
@@ -58,6 +58,20 @@ exports[`event handling handler receive the event as argument 2`] = `
}"
`;
exports[`event handling handler works when app is mounted in an iframe 1`] = `
"function anonymous(app, bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<span block-handler-0=\\"click\\">click me</span>\`);
return function template(ctx, node, key = \\"\\") {
let hdlr1 = [ctx['inc'], ctx];
return block1([hdlr1]);
}
}"
`;
exports[`event handling input blur event is not called if component is destroyed 1`] = `
"function anonymous(app, bdom, helpers
) {
+18
View File
@@ -171,4 +171,22 @@ describe("event handling", () => {
// input is removed when component is destroyed => nothing should happen
expect([]).toBeLogged();
});
test("handler works when app is mounted in an iframe", async () => {
let clickCount = 0;
class Parent extends Component {
static template = xml`<span t-on-click="inc">click me</span>`;
inc() {
clickCount++;
}
}
const iframe = document.createElement("iframe");
fixture.appendChild(iframe);
const iframeDoc = iframe.contentDocument!;
await mount(Parent, iframeDoc.body);
expect(clickCount).toBe(0);
iframeDoc.querySelector("span")!.click();
expect(clickCount).toBe(1);
});
});