[FIX] web: autofocus conditional element

Before this commit, useAutofocus hook used the effect dependency
to check if the target is in dom but this dependency is computed
in onWillPatch and can be outdated when checking it in onPatched.

Now, the target isn't a dependency anymore and is computed just
before the check.

Part-of: odoo/odoo#76472
This commit is contained in:
Michael (mcm)
2021-11-02 10:45:14 +00:00
parent 2997249ff0
commit 3ef8083dcb
2 changed files with 72 additions and 3 deletions
+3 -2
View File
@@ -42,7 +42,8 @@ export function useAutofocus(params = {}) {
const selector = params.selector || "[autofocus]";
let forceFocusCount = 0;
useEffect(
function autofocus(target) {
function autofocus() {
const target = comp.el.querySelector(selector);
if (target) {
target.focus();
if (["INPUT", "TEXTAREA"].includes(target.tagName)) {
@@ -51,7 +52,7 @@ export function useAutofocus(params = {}) {
}
}
},
() => [comp.el.querySelector(selector), forceFocusCount]
() => [forceFocusCount]
);
return function focusOnUpdate() {
@@ -1,6 +1,7 @@
/** @odoo-module **/
import { useBus, useEffect, useListener, useService } from "@web/core/utils/hooks";
import { uiService } from "@web/core/ui/ui_service";
import { useAutofocus, useBus, useEffect, useListener, useService } from "@web/core/utils/hooks";
import { registry } from "@web/core/registry";
import { makeTestEnv } from "../../helpers/mock_env";
import { click, getFixture, nextTick } from "../../helpers/utils";
@@ -11,6 +12,73 @@ const serviceRegistry = registry.category("services");
QUnit.module("utils", () => {
QUnit.module("Hooks", () => {
QUnit.module("useAutofocus");
QUnit.test("useAutofocus: simple usecase", async function (assert) {
class MyComponent extends Component {
setup() {
useAutofocus();
}
}
MyComponent.template = tags.xml`
<span>
<input type="text" autofocus="" />
</span>
`;
registry.category("services").add("ui", uiService);
const env = await makeTestEnv();
const target = getFixture();
const comp = await mount(MyComponent, { env, target });
await nextTick();
assert.strictEqual(document.activeElement, comp.el.querySelector("input"));
comp.render();
await nextTick();
assert.strictEqual(document.activeElement, comp.el.querySelector("input"));
comp.destroy();
});
QUnit.test("useAutofocus: conditional autofocus", async function (assert) {
class MyComponent extends Component {
setup() {
this.forceFocus = useAutofocus();
this.showInput = true;
}
}
MyComponent.template = tags.xml`
<span>
<input t-if="showInput" type="text" autofocus="" />
</span>
`;
registry.category("services").add("ui", uiService);
const env = await makeTestEnv();
const target = getFixture();
const comp = await mount(MyComponent, { env, target });
await nextTick();
assert.strictEqual(document.activeElement, comp.el.querySelector("input"));
comp.showInput = false;
comp.forceFocus();
comp.render();
await nextTick();
assert.notStrictEqual(document.activeElement, comp.el.querySelector("input"));
comp.showInput = true;
comp.forceFocus();
comp.render();
await nextTick();
assert.strictEqual(document.activeElement, comp.el.querySelector("input"));
comp.destroy();
});
QUnit.module("useBus");
QUnit.test("useBus hook: simple usecase", async function (assert) {