[FIX] web: correctly restore focus with ConfirmationDialog
When a dialog is closed, the focus is meant to be restored to the previous focused element. Before this commit, it did not work for the ConfirmationDialog when the confirm button was clicked. This was because the focus was lost **before** the dialog was closed (because the confirm button is disabled when clicked), and thus the previous focused element was not in the el of the dialog anymore, and thus the focus was not restored. closes odoo/odoo#134456 Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
@@ -77,7 +77,19 @@ export function useActiveElement(refName) {
|
||||
return () => {
|
||||
uiService.deactivateElement(el);
|
||||
el.removeEventListener("keydown", trapFocus);
|
||||
if (el.contains(document.activeElement)) {
|
||||
|
||||
/**
|
||||
* In some cases, the current active element is not
|
||||
* anymore in el (e.g. with ConfirmationDialog, the
|
||||
* confirm button is disabled when clicked, so the
|
||||
* focus is lost). In that case, we also want to restore
|
||||
* the focus to the previous active element so we
|
||||
* check if the current active element is the body
|
||||
*/
|
||||
if (
|
||||
el.contains(document.activeElement) ||
|
||||
document.activeElement === document.body
|
||||
) {
|
||||
oldActiveElement.focus();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -5,8 +5,17 @@ import { uiService } from "@web/core/ui/ui_service";
|
||||
import { hotkeyService } from "@web/core/hotkeys/hotkey_service";
|
||||
import { ConfirmationDialog } from "@web/core/confirmation_dialog/confirmation_dialog";
|
||||
import { makeDialogTestEnv } from "../helpers/mock_env";
|
||||
import { click, getFixture, makeDeferred, mount, nextTick, triggerHotkey } from "../helpers/utils";
|
||||
import {
|
||||
click,
|
||||
destroy,
|
||||
getFixture,
|
||||
makeDeferred,
|
||||
mount,
|
||||
nextTick,
|
||||
triggerHotkey,
|
||||
} from "../helpers/utils";
|
||||
import { makeFakeDialogService } from "../helpers/mock_services";
|
||||
import { Component, xml } from "@odoo/owl";
|
||||
|
||||
const serviceRegistry = registry.category("services");
|
||||
let target;
|
||||
@@ -193,4 +202,41 @@ QUnit.module("Components", (hooks) => {
|
||||
await nextTick();
|
||||
assert.verifySteps(["close"]);
|
||||
});
|
||||
|
||||
QUnit.test("Focus is correctly restored after confirmation", async function (assert) {
|
||||
const env = await makeDialogTestEnv();
|
||||
|
||||
class MyComp extends Component {}
|
||||
MyComp.template = xml`<div class="my-comp"><input type="text" class="my-input"/></div>`;
|
||||
|
||||
await mount(MyComp, target, { env });
|
||||
target.querySelector(".my-input").focus();
|
||||
assert.strictEqual(document.activeElement, target.querySelector(".my-input"));
|
||||
|
||||
const comp = await mount(ConfirmationDialog, target, {
|
||||
env,
|
||||
props: {
|
||||
body: "Some content",
|
||||
title: "Confirmation",
|
||||
confirm: () => {},
|
||||
close: () => {},
|
||||
},
|
||||
});
|
||||
assert.strictEqual(
|
||||
document.activeElement,
|
||||
target.querySelector(".modal-footer .btn-primary")
|
||||
);
|
||||
await click(target, ".modal-footer .btn-primary");
|
||||
assert.strictEqual(
|
||||
document.activeElement,
|
||||
document.body,
|
||||
"As the button is disabled, the focus is now on the body"
|
||||
);
|
||||
destroy(comp);
|
||||
assert.strictEqual(
|
||||
document.activeElement,
|
||||
target.querySelector(".my-input"),
|
||||
"After destruction of the dialog, the focus is restored to the input"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user