[FIX] web,mass_mailing: bind the wysiwyg iframe document to hotkey service
Before this commit When the user hit ctrl+k on a mass mailing, no command palette nor link dialog was opening. This was due to the fact that the hotkey service would not react to hotkeys being pressed from inside of an iframe element. After this commit One can now register an iframe to the hotkey service to let it react to hotkeys being pressed from within the registered iframes. task-2738457 closes odoo/odoo#91102 Forward-port-of: #89940 Forward-port-of: #82994 Signed-off-by: David Monjoie (dmo) <dmo@odoo.com>
This commit is contained in:
@@ -331,6 +331,9 @@ var MassMailingFieldHtml = FieldHtml.extend({
|
||||
* @override
|
||||
*/
|
||||
_onLoadWysiwyg: function () {
|
||||
// Let the global hotkey manager know about our iframe.
|
||||
this.call('hotkey', 'registerIframe', this.wysiwyg.$iframe[0]);
|
||||
|
||||
if (this.snippetsLoaded) {
|
||||
this._onSnippetsLoaded(this.snippetsLoaded);
|
||||
}
|
||||
|
||||
@@ -33,10 +33,14 @@ export const hotkeyService = {
|
||||
let nextToken = 0;
|
||||
let overlaysVisible = false;
|
||||
|
||||
browser.addEventListener("keydown", onKeydown);
|
||||
browser.addEventListener("keyup", removeHotkeyOverlays);
|
||||
browser.addEventListener("blur", removeHotkeyOverlays);
|
||||
browser.addEventListener("click", removeHotkeyOverlays);
|
||||
addListeners(browser);
|
||||
|
||||
function addListeners(target) {
|
||||
target.addEventListener("keydown", onKeydown);
|
||||
target.addEventListener("keyup", removeHotkeyOverlays);
|
||||
target.addEventListener("blur", removeHotkeyOverlays);
|
||||
target.addEventListener("click", removeHotkeyOverlays);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for keydown events.
|
||||
@@ -376,6 +380,12 @@ export const hotkeyService = {
|
||||
unregisterHotkey(token);
|
||||
};
|
||||
},
|
||||
/**
|
||||
* @param {HTMLIFrameElement} iframe
|
||||
*/
|
||||
registerIframe(iframe) {
|
||||
addListeners(iframe.contentWindow);
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
@@ -9,6 +9,7 @@ import { makeTestEnv } from "../../helpers/mock_env";
|
||||
import {
|
||||
destroy,
|
||||
getFixture,
|
||||
makeDeferred,
|
||||
mount,
|
||||
nextTick,
|
||||
patchWithCleanup,
|
||||
@@ -842,3 +843,34 @@ QUnit.test("ignore numpad keys", async (assert) => {
|
||||
await nextTick();
|
||||
assert.verifySteps(["1"]);
|
||||
});
|
||||
|
||||
QUnit.test("within iframes", async (assert) => {
|
||||
assert.expect(5);
|
||||
env.services.hotkey.add("enter", () => assert.step("called"));
|
||||
await nextTick();
|
||||
|
||||
// Dispatch directly to target to show that the hotkey service works as expected
|
||||
target.dispatchEvent(new KeyboardEvent("keydown", { key: "Enter", bubbles: true }));
|
||||
await nextTick();
|
||||
assert.verifySteps(["called"]);
|
||||
|
||||
// Append an iframe to target and wait until it is fully loaded.
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.srcdoc = "<h1>Hello world!</h1>";
|
||||
const def = makeDeferred();
|
||||
iframe.onload = def.resolve;
|
||||
target.appendChild(iframe);
|
||||
await def;
|
||||
|
||||
// Dispatch an hotkey from within the iframe
|
||||
const h1 = iframe.contentDocument.querySelector("h1");
|
||||
h1.dispatchEvent(new KeyboardEvent("keydown", { key: "Enter", bubbles: true }));
|
||||
await nextTick();
|
||||
assert.verifySteps([]);
|
||||
|
||||
// Register the iframe to the hotkey service
|
||||
env.services.hotkey.registerIframe(iframe);
|
||||
h1.dispatchEvent(new KeyboardEvent("keydown", { key: "Enter", bubbles: true }));
|
||||
await nextTick();
|
||||
assert.verifySteps(["called"]);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user