diff --git a/js/src/modal.js b/js/src/modal.js index ae7369a529..054750c5f7 100644 --- a/js/src/modal.js +++ b/js/src/modal.js @@ -30,7 +30,6 @@ const EVENT_HIDDEN = `hidden${EVENT_KEY}` const EVENT_SHOW = `show${EVENT_KEY}` const EVENT_SHOWN = `shown${EVENT_KEY}` const EVENT_RESIZE = `resize${EVENT_KEY}` -const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}` const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}` const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` @@ -115,7 +114,7 @@ class Modal extends BaseComponent { this._toggleEscapeEventListener(true) this._toggleResizeEventListener(true) - this._showBackdrop(() => this._showElement(relatedTarget)) + this._backdrop.show(() => this._showElement(relatedTarget)) } hide() { @@ -158,9 +157,22 @@ class Modal extends BaseComponent { // Private _initializeBackDrop() { + const clickCallback = () => { + if (this._config.backdrop === 'static') { + this._triggerBackdropTransition() + return + } + + this.hide() + } + + // 'static' option will be translated to true, and booleans will keep their value + const isVisible = Boolean(this._config.backdrop) + return new Backdrop({ - isVisible: Boolean(this._config.backdrop), // 'static' option will be translated to true, and booleans will keep their value - isAnimated: this._isAnimated() + isVisible, + isAnimated: this._isAnimated(), + clickCallback: isVisible ? clickCallback : null }) } @@ -250,25 +262,6 @@ class Modal extends BaseComponent { }) } - _showBackdrop(callback) { - EventHandler.on(this._element, EVENT_CLICK_DISMISS, event => { - if (event.target !== event.currentTarget) { - return - } - - if (this._config.backdrop === true) { - this.hide() - return - } - - if (this._config.backdrop === 'static') { - this._triggerBackdropTransition() - } - }) - - this._backdrop.show(callback) - } - _isAnimated() { return this._element.classList.contains(CLASS_NAME_FADE) } diff --git a/js/tests/unit/modal.spec.js b/js/tests/unit/modal.spec.js index bf796411b5..5d3f5cd9dc 100644 --- a/js/tests/unit/modal.spec.js +++ b/js/tests/unit/modal.spec.js @@ -642,8 +642,11 @@ describe('Modal', () => { modalEl.addEventListener('shown.bs.modal', () => { const spy = spyOn(modal, '_queueCallback').and.callThrough() - modalEl.click() - modalEl.click() + const mouseOverEvent = createEvent('mousedown') + const backdrop = document.querySelector('.modal-backdrop') + + backdrop.dispatchEvent(mouseOverEvent) + backdrop.dispatchEvent(mouseOverEvent) setTimeout(() => { expect(spy).toHaveBeenCalledTimes(1) @@ -710,9 +713,9 @@ describe('Modal', () => { const modalEl = fixtureEl.querySelector('.modal') const modal = new Modal(modalEl) - modalEl.addEventListener('shown.bs.modal', () => { - modalEl.click() + const mouseOverEvent = createEvent('mousedown') + document.querySelector('.modal-backdrop').dispatchEvent(mouseOverEvent) }) modalEl.addEventListener('hidden.bs.modal', () => { diff --git a/scss/_modal.scss b/scss/_modal.scss index 803b4d8117..ac116171aa 100644 --- a/scss/_modal.scss +++ b/scss/_modal.scss @@ -15,6 +15,7 @@ height: 100%; overflow-x: hidden; overflow-y: auto; + pointer-events: none; // Prevent Chrome on Windows from adding a focus outline. For details, see // https://github.com/twbs/bootstrap/pull/10951. outline: 0;