[FIX] web: prevent dropdown closing on mouseup

Before this commit, selecting the whole content of the custom filter
input and releasing the cursor outside of the dropdown closed the
dropdown.

With this commit, the dropdown is kept open in this situation.

task - 2276544

closes odoo/odoo#57807

X-original-commit: 450e0ec45005c3d6c2e8475e134113a7d8515e9f
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
Co-authored-by: Mohammed Shekha <msh@odoo.com>
This commit is contained in:
Hardik Prajapati
2020-09-16 09:38:43 +00:00
committed by Aaron Bohy
co-authored by Mohammed Shekha
parent 2d930cbccf
commit ed53db792a
3 changed files with 53 additions and 2 deletions
@@ -121,7 +121,11 @@ odoo.define('web.DropdownMenu', function (require) {
* @param {MouseEvent} ev
*/
_onWindowClick(ev) {
if (this.state.open && !this.el.contains(ev.target)) {
if (
this.state.open &&
!this.el.contains(ev.target) &&
!this.el.contains(document.activeElement)
) {
this.state.open = false;
}
}
@@ -86,7 +86,11 @@ odoo.define('web.DropdownMenuItem', function (require) {
* @param {MouseEvent} ev
*/
_onWindowClick(ev) {
if (this.state.open && !this.el.contains(ev.target)) {
if (
this.state.open &&
!this.el.contains(ev.target) &&
!this.el.contains(document.activeElement)
) {
this.state.open = false;
}
}
@@ -339,5 +339,48 @@ odoo.define('web.dropdown_menu_tests', function (require) {
parent.destroy();
});
QUnit.test("dropdown doesn't get close on mousedown inside and mouseup outside dropdown", async function (assert) {
// In this test, we simulate a case where the user clicks inside a dropdown menu item
// (e.g. in the input of the 'Save current search' item in the Favorites menu), keeps
// the click pressed, moves the cursor outside the dropdown and releases the click
// (i.e. mousedown and focus inside the item, mouseup and click outside the dropdown).
// In this case, we want to keep the dropdown menu open.
assert.expect(5);
const items = this.items;
class Parent extends owl.Component {
constructor() {
super(...arguments);
this.items = items;
}
}
Parent.components = { DropdownMenu };
Parent.template = owl.tags.xml`
<div>
<DropdownMenu class="first" title="'First'" items="items"/>
</div>`;
const parent = new Parent();
await parent.mount(testUtils.prepareTarget(), { position: "first-child" });
const menu = parent.el.querySelector(".o_dropdown");
assert.doesNotHaveClass(menu, "show", "dropdown should not be open");
await testUtils.dom.click(menu.querySelector("button"));
assert.hasClass(menu, "show", "dropdown should be open");
const firstItemEl = menu.querySelector(".o_menu_item > a");
// open options menu
await testUtils.dom.click(firstItemEl);
assert.hasClass(firstItemEl.querySelector("i"), "o_icon_right fa fa-caret-down");
// force the focus inside the dropdown item and click outside
firstItemEl.parentElement.querySelector(".o_menu_item_options .o_item_option a").focus();
await testUtils.dom.triggerEvents(parent.el, "click");
assert.hasClass(menu, "show", "dropdown should still be open");
assert.hasClass(firstItemEl.querySelector("i"), "o_icon_right fa fa-caret-down");
parent.destroy();
});
});
});