From 75f6450ebca7ffdb9ed60ab678943ffadfb7c284 Mon Sep 17 00:00:00 2001 From: "Michael Mattiello (mcm)" Date: Tue, 13 Jul 2021 12:02:35 +0000 Subject: [PATCH] [FIX] web: remove tabindex on inactive modal In the case we have a legacy dialog calling a new dialog, tabindex set on the legacy dialog prevents the new dialog to get focused as well as its children. Because of this, we cannot select text or focus text input/area in the new dialog. closes odoo/odoo#73639 Signed-off-by: Aaron Bohy (aab) --- .../static/src/legacy/js/core/owl_dialog.js | 2 + .../tests/legacy/core/owl_dialog_tests.js | 104 ++++++++++++++++++ 2 files changed, 106 insertions(+) diff --git a/addons/web/static/src/legacy/js/core/owl_dialog.js b/addons/web/static/src/legacy/js/core/owl_dialog.js index aa2525d55fe..5939b18c098 100644 --- a/addons/web/static/src/legacy/js/core/owl_dialog.js +++ b/addons/web/static/src/legacy/js/core/owl_dialog.js @@ -199,6 +199,7 @@ odoo.define('web.OwlDialog', function (require) { // Legacy dialog activeDialog.$modal[0]; activeDialogEl.classList.add('o_inactive_modal'); + activeDialogEl.removeAttribute("tabindex"); } // Push dialog this.displayed.push(dialog); @@ -224,6 +225,7 @@ odoo.define('web.OwlDialog', function (require) { // Legacy dialog lastDialog.$modal[0]; modalEl.classList.remove('o_inactive_modal'); + modalEl.setAttribute("tabindex", "-1"); } else { document.body.classList.remove('modal-open'); } diff --git a/addons/web/static/tests/legacy/core/owl_dialog_tests.js b/addons/web/static/tests/legacy/core/owl_dialog_tests.js index be0c9468b10..70dc4149a0f 100644 --- a/addons/web/static/tests/legacy/core/owl_dialog_tests.js +++ b/addons/web/static/tests/legacy/core/owl_dialog_tests.js @@ -12,6 +12,7 @@ odoo.define('web.owl_dialog_tests', function (require) { const { makeLegacyDialogMappingTestEnv } = require('@web/../tests/helpers/legacy_env_utils'); const { Dialog: WowlDialog } = require("@web/core/dialog/dialog"); const { getFixture, nextTick, patchWithCleanup } = require("@web/../tests/helpers/utils"); + const { createWebClient, doAction } = require("@web/../tests/webclient/helpers"); const { Component, tags, useState, mount } = owl; const EscapeKey = { key: 'Escape', keyCode: 27, which: 27 }; @@ -402,4 +403,107 @@ odoo.define('web.owl_dialog_tests', function (require) { frontEndModal.destroy(); backEndModal.destroy(); }); + + QUnit.test("remove tabindex on inactive dialog", async (assert) => { + const serverData = { + actions: { + 1: { + id: 1, + flags: { initialDate: new Date(2020, 6, 13) }, + name: "Test", + res_model: "event", + type: "ir.actions.act_window", + views: [[false, "calendar"]], + }, + 2: { + id: 2, + name: "Test", + res_model: "event", + target: "new", + type: "ir.actions.act_window", + views: [[2, "form"]], + }, + }, + models: { + event: { + fields: { + id: { type: "integer" }, + display_name: { type: "char" }, + start: { type: "date" }, + }, + records: [{ id: 1, display_name: "Event 1", start: "2020-07-13" }], + methods: { + async check_access_rights() { + return true; + }, + async get_formview_id() { + return false; + }, + }, + }, + }, + views: { + "event,false,calendar": ``, + "event,false,search": ``, + "event,false,form": ` +
+ + +
+ `, + "event,2,form": `
`, + }, + }; + + const webClient = await createWebClient({ serverData }); + await doAction(webClient, 1); + + await testUtils.dom.click(webClient.el.querySelector(`.fc-event[data-event-id="1"]`)); + await testUtils.dom.click(webClient.el.querySelector(`.o_cw_popover_edit`)); + + assert.containsNone(webClient.el, ".o_dialog"); + assert.containsOnce(webClient.el, ".modal"); + assert.containsOnce(webClient.el, ".modal[tabindex='-1']"); + + assert.strictEqual( + webClient.el.querySelector(`.o_field_widget[name="display_name"]`).value, + "Event 1" + ); + await testUtils.fields.editInput( + webClient.el.querySelector(`.o_field_widget[name="display_name"]`), + "legacy" + ); + assert.strictEqual( + webClient.el.querySelector(`.o_field_widget[name="display_name"]`).value, + "legacy" + ); + + await testUtils.dom.click(webClient.el.querySelector(`button[name="2"]`)); + assert.containsOnce(webClient.el, ".o_dialog"); + assert.containsN(webClient.el, ".modal", 2); + assert.containsOnce(webClient.el, ".modal:not([tabindex='-1'])"); + assert.containsOnce(webClient.el, ".o_dialog .modal[tabindex='-1']"); + + assert.strictEqual( + webClient.el.querySelector(`.o_dialog .o_field_widget[name="display_name"]`).value, + "" + ); + await testUtils.fields.editInput( + webClient.el.querySelector(`.o_dialog .o_field_widget[name="display_name"]`), + "wowl" + ); + assert.strictEqual( + webClient.el.querySelector(`.o_dialog .o_field_widget[name="display_name"]`).value, + "wowl" + ); + + await testUtils.dom.click(webClient.el.querySelector(`.o_dialog .modal-header .close`)); + assert.containsNone(webClient.el, ".o_dialog"); + assert.containsOnce(webClient.el, ".modal"); + assert.containsOnce(webClient.el, ".modal[tabindex='-1']"); + + await testUtils.dom.click(webClient.el.querySelector(`.modal-header .close`)); + assert.containsNone(webClient.el, ".o_dialog"); + assert.containsNone(webClient.el, ".modal"); + }); });