]> git.ipfire.org Git - thirdparty/bootstrap.git/commitdiff
Fix modal event listeners (#37128)
authorJérémie Broutier <jeremie.broutier@posteo.net>
Thu, 15 Sep 2022 10:30:51 +0000 (12:30 +0200)
committerGitHub <noreply@github.com>
Thu, 15 Sep 2022 10:30:51 +0000 (13:30 +0300)
* Fix modal event listeners (#37126)

Co-authored-by: GeoSot <geo.sotis@gmail.com>
js/src/modal.js
js/tests/unit/modal.spec.js

index c977225388ddab54030dc5b93580effa318d2753..a39597b3a8ef5c86bb1cd03c0791c7f039eeb66c 100644 (file)
@@ -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
         }
 
index e774fc4e8e55ea4a81ba252b32c8513f5d1802b3..fdee29e95abd2125d8d7ef5dd27c14f5c91bc632 100644 (file)
@@ -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 = [
+          '<div class="modal">',
+          ' <div class="modal-dialog">',
+          '   <button class="btn">BTN</button>',
+          ' </div>',
+          '</div>'
+        ].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 = '<div class="modal"><div class="modal-dialog"></div></div>'