From 6f65df4faea2694840572626f8a02f4399bd0dca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Broutier?= Date: Thu, 15 Sep 2022 12:30:51 +0200 Subject: [PATCH] Fix modal event listeners (#37128) * Fix modal event listeners (#37126) Co-authored-by: GeoSot --- js/src/modal.js | 4 ++-- js/tests/unit/modal.spec.js | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/js/src/modal.js b/js/src/modal.js index c977225388dd..a39597b3a8ef 100644 --- a/js/src/modal.js +++ b/js/src/modal.js @@ -223,9 +223,9 @@ class Modal extends BaseComponent { }) EventHandler.on(this._element, EVENT_MOUSEDOWN_DISMISS, event => { + // a bad trick to segregate clicks that may start inside dialog but end outside, and avoid listen to scrollbar clicks EventHandler.one(this._element, EVENT_CLICK_DISMISS, event2 => { - // a bad trick to segregate clicks that may start inside dialog but end outside, and avoid listen to scrollbar clicks - if (this._dialog.contains(event.target) || this._dialog.contains(event2.target)) { + if (this._element !== event.target || this._element !== event2.target) { return } diff --git a/js/tests/unit/modal.spec.js b/js/tests/unit/modal.spec.js index e774fc4e8e55..fdee29e95abd 100644 --- a/js/tests/unit/modal.spec.js +++ b/js/tests/unit/modal.spec.js @@ -734,6 +734,36 @@ describe('Modal', () => { }) }) + it('should not close modal when clicking on an element removed from modal content', () => { + return new Promise(resolve => { + fixtureEl.innerHTML = [ + '' + ].join('') + + const modalEl = fixtureEl.querySelector('.modal') + const buttonEl = modalEl.querySelector('.btn') + const modal = new Modal(modalEl) + + const spy = spyOn(modal, 'hide') + buttonEl.addEventListener('click', () => { + buttonEl.remove() + }) + + modalEl.addEventListener('shown.bs.modal', () => { + modalEl.dispatchEvent(createEvent('mousedown')) + buttonEl.click() + expect(spy).not.toHaveBeenCalled() + resolve() + }) + + modal.show() + }) + }) + it('should do nothing is the modal is not shown', () => { fixtureEl.innerHTML = ''