aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/twbs/bootstrap/js/src/modal.js
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/twbs/bootstrap/js/src/modal.js')
-rw-r--r--vendor/twbs/bootstrap/js/src/modal.js548
1 files changed, 178 insertions, 370 deletions
diff --git a/vendor/twbs/bootstrap/js/src/modal.js b/vendor/twbs/bootstrap/js/src/modal.js
index 2e3017024..00df5c482 100644
--- a/vendor/twbs/bootstrap/js/src/modal.js
+++ b/vendor/twbs/bootstrap/js/src/modal.js
@@ -1,12 +1,26 @@
/**
* --------------------------------------------------------------------------
- * Bootstrap (v4.6.0): modal.js
+ * Bootstrap (v5.1.3): modal.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
-import $ from 'jquery'
-import Util from './util'
+import {
+ defineJQueryPlugin,
+ getElementFromSelector,
+ isRTL,
+ isVisible,
+ reflow,
+ typeCheckConfig
+} from './util/index'
+import EventHandler from './dom/event-handler'
+import Manipulator from './dom/manipulator'
+import SelectorEngine from './dom/selector-engine'
+import ScrollBarHelper from './util/scrollbar'
+import BaseComponent from './base-component'
+import Backdrop from './util/backdrop'
+import FocusTrap from './util/focustrap'
+import { enableDismissTrigger } from './util/component-functions'
/**
* ------------------------------------------------------------------------
@@ -15,25 +29,21 @@ import Util from './util'
*/
const NAME = 'modal'
-const VERSION = '4.6.0'
const DATA_KEY = 'bs.modal'
const EVENT_KEY = `.${DATA_KEY}`
const DATA_API_KEY = '.data-api'
-const JQUERY_NO_CONFLICT = $.fn[NAME]
-const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key
+const ESCAPE_KEY = 'Escape'
const Default = {
backdrop: true,
keyboard: true,
- focus: true,
- show: true
+ focus: true
}
const DefaultType = {
backdrop: '(boolean|string)',
keyboard: 'boolean',
- focus: 'boolean',
- show: 'boolean'
+ focus: 'boolean'
}
const EVENT_HIDE = `hide${EVENT_KEY}`
@@ -41,7 +51,6 @@ const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`
const EVENT_HIDDEN = `hidden${EVENT_KEY}`
const EVENT_SHOW = `show${EVENT_KEY}`
const EVENT_SHOWN = `shown${EVENT_KEY}`
-const EVENT_FOCUSIN = `focusin${EVENT_KEY}`
const EVENT_RESIZE = `resize${EVENT_KEY}`
const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`
const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`
@@ -49,20 +58,15 @@ const EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY}`
const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
-const CLASS_NAME_SCROLLABLE = 'modal-dialog-scrollable'
-const CLASS_NAME_SCROLLBAR_MEASURER = 'modal-scrollbar-measure'
-const CLASS_NAME_BACKDROP = 'modal-backdrop'
const CLASS_NAME_OPEN = 'modal-open'
const CLASS_NAME_FADE = 'fade'
const CLASS_NAME_SHOW = 'show'
const CLASS_NAME_STATIC = 'modal-static'
+const OPEN_SELECTOR = '.modal.show'
const SELECTOR_DIALOG = '.modal-dialog'
const SELECTOR_MODAL_BODY = '.modal-body'
-const SELECTOR_DATA_TOGGLE = '[data-toggle="modal"]'
-const SELECTOR_DATA_DISMISS = '[data-dismiss="modal"]'
-const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'
-const SELECTOR_STICKY_CONTENT = '.sticky-top'
+const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="modal"]'
/**
* ------------------------------------------------------------------------
@@ -70,29 +74,30 @@ const SELECTOR_STICKY_CONTENT = '.sticky-top'
* ------------------------------------------------------------------------
*/
-class Modal {
+class Modal extends BaseComponent {
constructor(element, config) {
+ super(element)
+
this._config = this._getConfig(config)
- this._element = element
- this._dialog = element.querySelector(SELECTOR_DIALOG)
- this._backdrop = null
+ this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element)
+ this._backdrop = this._initializeBackDrop()
+ this._focustrap = this._initializeFocusTrap()
this._isShown = false
- this._isBodyOverflowing = false
this._ignoreBackdropClick = false
this._isTransitioning = false
- this._scrollbarWidth = 0
+ this._scrollBar = new ScrollBarHelper()
}
// Getters
- static get VERSION() {
- return VERSION
- }
-
static get Default() {
return Default
}
+ static get NAME() {
+ return NAME
+ }
+
// Public
toggle(relatedTarget) {
@@ -104,39 +109,32 @@ class Modal {
return
}
- if ($(this._element).hasClass(CLASS_NAME_FADE)) {
- this._isTransitioning = true
- }
-
- const showEvent = $.Event(EVENT_SHOW, {
+ const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, {
relatedTarget
})
- $(this._element).trigger(showEvent)
-
- if (this._isShown || showEvent.isDefaultPrevented()) {
+ if (showEvent.defaultPrevented) {
return
}
this._isShown = true
- this._checkScrollbar()
- this._setScrollbar()
+ if (this._isAnimated()) {
+ this._isTransitioning = true
+ }
+
+ this._scrollBar.hide()
+
+ document.body.classList.add(CLASS_NAME_OPEN)
this._adjustDialog()
this._setEscapeEvent()
this._setResizeEvent()
- $(this._element).on(
- EVENT_CLICK_DISMISS,
- SELECTOR_DATA_DISMISS,
- event => this.hide(event)
- )
-
- $(this._dialog).on(EVENT_MOUSEDOWN_DISMISS, () => {
- $(this._element).one(EVENT_MOUSEUP_DISMISS, event => {
- if ($(event.target).is(this._element)) {
+ EventHandler.on(this._dialog, EVENT_MOUSEDOWN_DISMISS, () => {
+ EventHandler.one(this._element, EVENT_MOUSEUP_DISMISS, event => {
+ if (event.target === this._element) {
this._ignoreBackdropClick = true
}
})
@@ -145,73 +143,44 @@ class Modal {
this._showBackdrop(() => this._showElement(relatedTarget))
}
- hide(event) {
- if (event) {
- event.preventDefault()
- }
-
+ hide() {
if (!this._isShown || this._isTransitioning) {
return
}
- const hideEvent = $.Event(EVENT_HIDE)
-
- $(this._element).trigger(hideEvent)
+ const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE)
- if (!this._isShown || hideEvent.isDefaultPrevented()) {
+ if (hideEvent.defaultPrevented) {
return
}
this._isShown = false
- const transition = $(this._element).hasClass(CLASS_NAME_FADE)
+ const isAnimated = this._isAnimated()
- if (transition) {
+ if (isAnimated) {
this._isTransitioning = true
}
this._setEscapeEvent()
this._setResizeEvent()
- $(document).off(EVENT_FOCUSIN)
+ this._focustrap.deactivate()
- $(this._element).removeClass(CLASS_NAME_SHOW)
+ this._element.classList.remove(CLASS_NAME_SHOW)
- $(this._element).off(EVENT_CLICK_DISMISS)
- $(this._dialog).off(EVENT_MOUSEDOWN_DISMISS)
+ EventHandler.off(this._element, EVENT_CLICK_DISMISS)
+ EventHandler.off(this._dialog, EVENT_MOUSEDOWN_DISMISS)
- if (transition) {
- const transitionDuration = Util.getTransitionDurationFromElement(this._element)
-
- $(this._element)
- .one(Util.TRANSITION_END, event => this._hideModal(event))
- .emulateTransitionEnd(transitionDuration)
- } else {
- this._hideModal()
- }
+ this._queueCallback(() => this._hideModal(), this._element, isAnimated)
}
dispose() {
- [window, this._element, this._dialog]
- .forEach(htmlElement => $(htmlElement).off(EVENT_KEY))
-
- /**
- * `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API`
- * Do not move `document` in `htmlElements` array
- * It will remove `EVENT_CLICK_DATA_API` event that should remain
- */
- $(document).off(EVENT_FOCUSIN)
-
- $.removeData(this._element, DATA_KEY)
-
- this._config = null
- this._element = null
- this._dialog = null
- this._backdrop = null
- this._isShown = null
- this._isBodyOverflowing = null
- this._ignoreBackdropClick = null
- this._isTransitioning = null
- this._scrollbarWidth = null
+ [window, this._dialog]
+ .forEach(htmlElement => EventHandler.off(htmlElement, EVENT_KEY))
+
+ this._backdrop.dispose()
+ this._focustrap.deactivate()
+ super.dispose()
}
handleUpdate() {
@@ -220,134 +189,88 @@ class Modal {
// Private
+ _initializeBackDrop() {
+ return new Backdrop({
+ isVisible: Boolean(this._config.backdrop), // 'static' option will be translated to true, and booleans will keep their value
+ isAnimated: this._isAnimated()
+ })
+ }
+
+ _initializeFocusTrap() {
+ return new FocusTrap({
+ trapElement: this._element
+ })
+ }
+
_getConfig(config) {
config = {
...Default,
- ...config
+ ...Manipulator.getDataAttributes(this._element),
+ ...(typeof config === 'object' ? config : {})
}
- Util.typeCheckConfig(NAME, config, DefaultType)
+ typeCheckConfig(NAME, config, DefaultType)
return config
}
- _triggerBackdropTransition() {
- const hideEventPrevented = $.Event(EVENT_HIDE_PREVENTED)
-
- $(this._element).trigger(hideEventPrevented)
- if (hideEventPrevented.isDefaultPrevented()) {
- return
- }
-
- const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight
-
- if (!isModalOverflowing) {
- this._element.style.overflowY = 'hidden'
- }
-
- this._element.classList.add(CLASS_NAME_STATIC)
-
- const modalTransitionDuration = Util.getTransitionDurationFromElement(this._dialog)
- $(this._element).off(Util.TRANSITION_END)
-
- $(this._element).one(Util.TRANSITION_END, () => {
- this._element.classList.remove(CLASS_NAME_STATIC)
- if (!isModalOverflowing) {
- $(this._element).one(Util.TRANSITION_END, () => {
- this._element.style.overflowY = ''
- })
- .emulateTransitionEnd(this._element, modalTransitionDuration)
- }
- })
- .emulateTransitionEnd(modalTransitionDuration)
- this._element.focus()
- }
-
_showElement(relatedTarget) {
- const transition = $(this._element).hasClass(CLASS_NAME_FADE)
- const modalBody = this._dialog ? this._dialog.querySelector(SELECTOR_MODAL_BODY) : null
+ const isAnimated = this._isAnimated()
+ const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog)
- if (!this._element.parentNode ||
- this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
+ if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
// Don't move modal's DOM position
- document.body.appendChild(this._element)
+ document.body.append(this._element)
}
this._element.style.display = 'block'
this._element.removeAttribute('aria-hidden')
this._element.setAttribute('aria-modal', true)
this._element.setAttribute('role', 'dialog')
+ this._element.scrollTop = 0
- if ($(this._dialog).hasClass(CLASS_NAME_SCROLLABLE) && modalBody) {
+ if (modalBody) {
modalBody.scrollTop = 0
- } else {
- this._element.scrollTop = 0
}
- if (transition) {
- Util.reflow(this._element)
+ if (isAnimated) {
+ reflow(this._element)
}
- $(this._element).addClass(CLASS_NAME_SHOW)
-
- if (this._config.focus) {
- this._enforceFocus()
- }
-
- const shownEvent = $.Event(EVENT_SHOWN, {
- relatedTarget
- })
+ this._element.classList.add(CLASS_NAME_SHOW)
const transitionComplete = () => {
if (this._config.focus) {
- this._element.focus()
+ this._focustrap.activate()
}
this._isTransitioning = false
- $(this._element).trigger(shownEvent)
- }
-
- if (transition) {
- const transitionDuration = Util.getTransitionDurationFromElement(this._dialog)
-
- $(this._dialog)
- .one(Util.TRANSITION_END, transitionComplete)
- .emulateTransitionEnd(transitionDuration)
- } else {
- transitionComplete()
+ EventHandler.trigger(this._element, EVENT_SHOWN, {
+ relatedTarget
+ })
}
- }
- _enforceFocus() {
- $(document)
- .off(EVENT_FOCUSIN) // Guard against infinite focus loop
- .on(EVENT_FOCUSIN, event => {
- if (document !== event.target &&
- this._element !== event.target &&
- $(this._element).has(event.target).length === 0) {
- this._element.focus()
- }
- })
+ this._queueCallback(transitionComplete, this._dialog, isAnimated)
}
_setEscapeEvent() {
if (this._isShown) {
- $(this._element).on(EVENT_KEYDOWN_DISMISS, event => {
- if (this._config.keyboard && event.which === ESCAPE_KEYCODE) {
+ EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {
+ if (this._config.keyboard && event.key === ESCAPE_KEY) {
event.preventDefault()
this.hide()
- } else if (!this._config.keyboard && event.which === ESCAPE_KEYCODE) {
+ } else if (!this._config.keyboard && event.key === ESCAPE_KEY) {
this._triggerBackdropTransition()
}
})
- } else if (!this._isShown) {
- $(this._element).off(EVENT_KEYDOWN_DISMISS)
+ } else {
+ EventHandler.off(this._element, EVENT_KEYDOWN_DISMISS)
}
}
_setResizeEvent() {
if (this._isShown) {
- $(window).on(EVENT_RESIZE, event => this.handleUpdate(event))
+ EventHandler.on(window, EVENT_RESIZE, () => this._adjustDialog())
} else {
- $(window).off(EVENT_RESIZE)
+ EventHandler.off(window, EVENT_RESIZE)
}
}
@@ -357,110 +280,85 @@ class Modal {
this._element.removeAttribute('aria-modal')
this._element.removeAttribute('role')
this._isTransitioning = false
- this._showBackdrop(() => {
- $(document.body).removeClass(CLASS_NAME_OPEN)
+ this._backdrop.hide(() => {
+ document.body.classList.remove(CLASS_NAME_OPEN)
this._resetAdjustments()
- this._resetScrollbar()
- $(this._element).trigger(EVENT_HIDDEN)
+ this._scrollBar.reset()
+ EventHandler.trigger(this._element, EVENT_HIDDEN)
})
}
- _removeBackdrop() {
- if (this._backdrop) {
- $(this._backdrop).remove()
- this._backdrop = null
- }
- }
-
_showBackdrop(callback) {
- const animate = $(this._element).hasClass(CLASS_NAME_FADE) ?
- CLASS_NAME_FADE : ''
-
- if (this._isShown && this._config.backdrop) {
- this._backdrop = document.createElement('div')
- this._backdrop.className = CLASS_NAME_BACKDROP
-
- if (animate) {
- this._backdrop.classList.add(animate)
- }
-
- $(this._backdrop).appendTo(document.body)
-
- $(this._element).on(EVENT_CLICK_DISMISS, event => {
- if (this._ignoreBackdropClick) {
- this._ignoreBackdropClick = false
- return
- }
-
- if (event.target !== event.currentTarget) {
- return
- }
-
- if (this._config.backdrop === 'static') {
- this._triggerBackdropTransition()
- } else {
- this.hide()
- }
- })
-
- if (animate) {
- Util.reflow(this._backdrop)
+ EventHandler.on(this._element, EVENT_CLICK_DISMISS, event => {
+ if (this._ignoreBackdropClick) {
+ this._ignoreBackdropClick = false
+ return
}
- $(this._backdrop).addClass(CLASS_NAME_SHOW)
-
- if (!callback) {
+ if (event.target !== event.currentTarget) {
return
}
- if (!animate) {
- callback()
- return
+ if (this._config.backdrop === true) {
+ this.hide()
+ } else if (this._config.backdrop === 'static') {
+ this._triggerBackdropTransition()
}
+ })
- const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)
+ this._backdrop.show(callback)
+ }
- $(this._backdrop)
- .one(Util.TRANSITION_END, callback)
- .emulateTransitionEnd(backdropTransitionDuration)
- } else if (!this._isShown && this._backdrop) {
- $(this._backdrop).removeClass(CLASS_NAME_SHOW)
+ _isAnimated() {
+ return this._element.classList.contains(CLASS_NAME_FADE)
+ }
- const callbackRemove = () => {
- this._removeBackdrop()
- if (callback) {
- callback()
- }
- }
+ _triggerBackdropTransition() {
+ const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED)
+ if (hideEvent.defaultPrevented) {
+ return
+ }
- if ($(this._element).hasClass(CLASS_NAME_FADE)) {
- const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)
+ const { classList, scrollHeight, style } = this._element
+ const isModalOverflowing = scrollHeight > document.documentElement.clientHeight
- $(this._backdrop)
- .one(Util.TRANSITION_END, callbackRemove)
- .emulateTransitionEnd(backdropTransitionDuration)
- } else {
- callbackRemove()
- }
- } else if (callback) {
- callback()
+ // return if the following background transition hasn't yet completed
+ if ((!isModalOverflowing && style.overflowY === 'hidden') || classList.contains(CLASS_NAME_STATIC)) {
+ return
+ }
+
+ if (!isModalOverflowing) {
+ style.overflowY = 'hidden'
}
+
+ classList.add(CLASS_NAME_STATIC)
+ this._queueCallback(() => {
+ classList.remove(CLASS_NAME_STATIC)
+ if (!isModalOverflowing) {
+ this._queueCallback(() => {
+ style.overflowY = ''
+ }, this._dialog)
+ }
+ }, this._dialog)
+
+ this._element.focus()
}
// ----------------------------------------------------------------------
// the following methods are used to handle overflowing modals
- // todo (fat): these should probably be refactored out of modal.js
// ----------------------------------------------------------------------
_adjustDialog() {
const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight
+ const scrollbarWidth = this._scrollBar.getWidth()
+ const isBodyOverflowing = scrollbarWidth > 0
- if (!this._isBodyOverflowing && isModalOverflowing) {
- this._element.style.paddingLeft = `${this._scrollbarWidth}px`
+ if ((!isBodyOverflowing && isModalOverflowing && !isRTL()) || (isBodyOverflowing && !isModalOverflowing && isRTL())) {
+ this._element.style.paddingLeft = `${scrollbarWidth}px`
}
- if (this._isBodyOverflowing && !isModalOverflowing) {
- this._element.style.paddingRight = `${this._scrollbarWidth}px`
+ if ((isBodyOverflowing && !isModalOverflowing && !isRTL()) || (!isBodyOverflowing && isModalOverflowing && isRTL())) {
+ this._element.style.paddingRight = `${scrollbarWidth}px`
}
}
@@ -469,106 +367,21 @@ class Modal {
this._element.style.paddingRight = ''
}
- _checkScrollbar() {
- const rect = document.body.getBoundingClientRect()
- this._isBodyOverflowing = Math.round(rect.left + rect.right) < window.innerWidth
- this._scrollbarWidth = this._getScrollbarWidth()
- }
-
- _setScrollbar() {
- if (this._isBodyOverflowing) {
- // Note: DOMNode.style.paddingRight returns the actual value or '' if not set
- // while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set
- const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT))
- const stickyContent = [].slice.call(document.querySelectorAll(SELECTOR_STICKY_CONTENT))
-
- // Adjust fixed content padding
- $(fixedContent).each((index, element) => {
- const actualPadding = element.style.paddingRight
- const calculatedPadding = $(element).css('padding-right')
- $(element)
- .data('padding-right', actualPadding)
- .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)
- })
-
- // Adjust sticky content margin
- $(stickyContent).each((index, element) => {
- const actualMargin = element.style.marginRight
- const calculatedMargin = $(element).css('margin-right')
- $(element)
- .data('margin-right', actualMargin)
- .css('margin-right', `${parseFloat(calculatedMargin) - this._scrollbarWidth}px`)
- })
-
- // Adjust body padding
- const actualPadding = document.body.style.paddingRight
- const calculatedPadding = $(document.body).css('padding-right')
- $(document.body)
- .data('padding-right', actualPadding)
- .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)
- }
-
- $(document.body).addClass(CLASS_NAME_OPEN)
- }
-
- _resetScrollbar() {
- // Restore fixed content padding
- const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT))
- $(fixedContent).each((index, element) => {
- const padding = $(element).data('padding-right')
- $(element).removeData('padding-right')
- element.style.paddingRight = padding ? padding : ''
- })
-
- // Restore sticky content
- const elements = [].slice.call(document.querySelectorAll(`${SELECTOR_STICKY_CONTENT}`))
- $(elements).each((index, element) => {
- const margin = $(element).data('margin-right')
- if (typeof margin !== 'undefined') {
- $(element).css('margin-right', margin).removeData('margin-right')
- }
- })
-
- // Restore body padding
- const padding = $(document.body).data('padding-right')
- $(document.body).removeData('padding-right')
- document.body.style.paddingRight = padding ? padding : ''
- }
-
- _getScrollbarWidth() { // thx d.walsh
- const scrollDiv = document.createElement('div')
- scrollDiv.className = CLASS_NAME_SCROLLBAR_MEASURER
- document.body.appendChild(scrollDiv)
- const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth
- document.body.removeChild(scrollDiv)
- return scrollbarWidth
- }
-
// Static
- static _jQueryInterface(config, relatedTarget) {
+ static jQueryInterface(config, relatedTarget) {
return this.each(function () {
- let data = $(this).data(DATA_KEY)
- const _config = {
- ...Default,
- ...$(this).data(),
- ...(typeof config === 'object' && config ? config : {})
- }
+ const data = Modal.getOrCreateInstance(this, config)
- if (!data) {
- data = new Modal(this, _config)
- $(this).data(DATA_KEY, data)
+ if (typeof config !== 'string') {
+ return
}
- if (typeof config === 'string') {
- if (typeof data[config] === 'undefined') {
- throw new TypeError(`No method named "${config}"`)
- }
-
- data[config](relatedTarget)
- } else if (_config.show) {
- data.show(relatedTarget)
+ if (typeof data[config] === 'undefined') {
+ throw new TypeError(`No method named "${config}"`)
}
+
+ data[config](relatedTarget)
})
}
}
@@ -579,51 +392,46 @@ class Modal {
* ------------------------------------------------------------------------
*/
-$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
- let target
- const selector = Util.getSelectorFromElement(this)
-
- if (selector) {
- target = document.querySelector(selector)
- }
-
- const config = $(target).data(DATA_KEY) ?
- 'toggle' : {
- ...$(target).data(),
- ...$(this).data()
- }
+EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
+ const target = getElementFromSelector(this)
- if (this.tagName === 'A' || this.tagName === 'AREA') {
+ if (['A', 'AREA'].includes(this.tagName)) {
event.preventDefault()
}
- const $target = $(target).one(EVENT_SHOW, showEvent => {
- if (showEvent.isDefaultPrevented()) {
- // Only register focus restorer if modal will actually get shown
+ EventHandler.one(target, EVENT_SHOW, showEvent => {
+ if (showEvent.defaultPrevented) {
+ // only register focus restorer if modal will actually get shown
return
}
- $target.one(EVENT_HIDDEN, () => {
- if ($(this).is(':visible')) {
+ EventHandler.one(target, EVENT_HIDDEN, () => {
+ if (isVisible(this)) {
this.focus()
}
})
})
- Modal._jQueryInterface.call($(target), config, this)
+ // avoid conflict when clicking moddal toggler while another one is open
+ const allReadyOpen = SelectorEngine.findOne(OPEN_SELECTOR)
+ if (allReadyOpen) {
+ Modal.getInstance(allReadyOpen).hide()
+ }
+
+ const data = Modal.getOrCreateInstance(target)
+
+ data.toggle(this)
})
+enableDismissTrigger(Modal)
+
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
+ * add .Modal to jQuery only if jQuery is present
*/
-$.fn[NAME] = Modal._jQueryInterface
-$.fn[NAME].Constructor = Modal
-$.fn[NAME].noConflict = () => {
- $.fn[NAME] = JQUERY_NO_CONFLICT
- return Modal._jQueryInterface
-}
+defineJQueryPlugin(Modal)
export default Modal