diff options
Diffstat (limited to 'vendor/twbs/bootstrap/js/src/modal.js')
-rw-r--r-- | vendor/twbs/bootstrap/js/src/modal.js | 911 |
1 files changed, 463 insertions, 448 deletions
diff --git a/vendor/twbs/bootstrap/js/src/modal.js b/vendor/twbs/bootstrap/js/src/modal.js index ddcf370b6..99fe1bf2d 100644 --- a/vendor/twbs/bootstrap/js/src/modal.js +++ b/vendor/twbs/bootstrap/js/src/modal.js @@ -1,579 +1,594 @@ -import $ from 'jquery' -import Util from './util' - /** * -------------------------------------------------------------------------- - * Bootstrap (v4.1.3): modal.js + * Bootstrap (v4.3.1): modal.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * -------------------------------------------------------------------------- */ -const Modal = (($) => { - /** - * ------------------------------------------------------------------------ - * Constants - * ------------------------------------------------------------------------ - */ - - const NAME = 'modal' - const VERSION = '4.1.3' - 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 Default = { - backdrop : true, - keyboard : true, - focus : true, - show : true - } +import $ from 'jquery' +import Util from './util' - const DefaultType = { - backdrop : '(boolean|string)', - keyboard : 'boolean', - focus : 'boolean', - show : 'boolean' - } +/** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + +const NAME = 'modal' +const VERSION = '4.3.1' +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 Default = { + backdrop : true, + keyboard : true, + focus : true, + show : true +} + +const DefaultType = { + backdrop : '(boolean|string)', + keyboard : 'boolean', + focus : 'boolean', + show : 'boolean' +} + +const Event = { + HIDE : `hide${EVENT_KEY}`, + HIDDEN : `hidden${EVENT_KEY}`, + SHOW : `show${EVENT_KEY}`, + SHOWN : `shown${EVENT_KEY}`, + FOCUSIN : `focusin${EVENT_KEY}`, + RESIZE : `resize${EVENT_KEY}`, + CLICK_DISMISS : `click.dismiss${EVENT_KEY}`, + KEYDOWN_DISMISS : `keydown.dismiss${EVENT_KEY}`, + MOUSEUP_DISMISS : `mouseup.dismiss${EVENT_KEY}`, + MOUSEDOWN_DISMISS : `mousedown.dismiss${EVENT_KEY}`, + CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}` +} + +const ClassName = { + SCROLLABLE : 'modal-dialog-scrollable', + SCROLLBAR_MEASURER : 'modal-scrollbar-measure', + BACKDROP : 'modal-backdrop', + OPEN : 'modal-open', + FADE : 'fade', + SHOW : 'show' +} + +const Selector = { + DIALOG : '.modal-dialog', + MODAL_BODY : '.modal-body', + DATA_TOGGLE : '[data-toggle="modal"]', + DATA_DISMISS : '[data-dismiss="modal"]', + FIXED_CONTENT : '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top', + STICKY_CONTENT : '.sticky-top' +} + +/** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ - const Event = { - HIDE : `hide${EVENT_KEY}`, - HIDDEN : `hidden${EVENT_KEY}`, - SHOW : `show${EVENT_KEY}`, - SHOWN : `shown${EVENT_KEY}`, - FOCUSIN : `focusin${EVENT_KEY}`, - RESIZE : `resize${EVENT_KEY}`, - CLICK_DISMISS : `click.dismiss${EVENT_KEY}`, - KEYDOWN_DISMISS : `keydown.dismiss${EVENT_KEY}`, - MOUSEUP_DISMISS : `mouseup.dismiss${EVENT_KEY}`, - MOUSEDOWN_DISMISS : `mousedown.dismiss${EVENT_KEY}`, - CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}` +class Modal { + constructor(element, config) { + this._config = this._getConfig(config) + this._element = element + this._dialog = element.querySelector(Selector.DIALOG) + this._backdrop = null + this._isShown = false + this._isBodyOverflowing = false + this._ignoreBackdropClick = false + this._isTransitioning = false + this._scrollbarWidth = 0 } - const ClassName = { - SCROLLBAR_MEASURER : 'modal-scrollbar-measure', - BACKDROP : 'modal-backdrop', - OPEN : 'modal-open', - FADE : 'fade', - SHOW : 'show' + // Getters + + static get VERSION() { + return VERSION } - const Selector = { - DIALOG : '.modal-dialog', - DATA_TOGGLE : '[data-toggle="modal"]', - DATA_DISMISS : '[data-dismiss="modal"]', - FIXED_CONTENT : '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top', - STICKY_CONTENT : '.sticky-top' + static get Default() { + return Default } - /** - * ------------------------------------------------------------------------ - * Class Definition - * ------------------------------------------------------------------------ - */ - - class Modal { - constructor(element, config) { - this._config = this._getConfig(config) - this._element = element - this._dialog = element.querySelector(Selector.DIALOG) - this._backdrop = null - this._isShown = false - this._isBodyOverflowing = false - this._ignoreBackdropClick = false - this._scrollbarWidth = 0 - } + // Public - // Getters + toggle(relatedTarget) { + return this._isShown ? this.hide() : this.show(relatedTarget) + } - static get VERSION() { - return VERSION + show(relatedTarget) { + if (this._isShown || this._isTransitioning) { + return } - static get Default() { - return Default + if ($(this._element).hasClass(ClassName.FADE)) { + this._isTransitioning = true } - // Public + const showEvent = $.Event(Event.SHOW, { + relatedTarget + }) - toggle(relatedTarget) { - return this._isShown ? this.hide() : this.show(relatedTarget) + $(this._element).trigger(showEvent) + + if (this._isShown || showEvent.isDefaultPrevented()) { + return } - show(relatedTarget) { - if (this._isTransitioning || this._isShown) { - return - } + this._isShown = true - if ($(this._element).hasClass(ClassName.FADE)) { - this._isTransitioning = true - } + this._checkScrollbar() + this._setScrollbar() - const showEvent = $.Event(Event.SHOW, { - relatedTarget - }) + this._adjustDialog() - $(this._element).trigger(showEvent) + this._setEscapeEvent() + this._setResizeEvent() - if (this._isShown || showEvent.isDefaultPrevented()) { - return - } + $(this._element).on( + Event.CLICK_DISMISS, + Selector.DATA_DISMISS, + (event) => this.hide(event) + ) - this._isShown = true + $(this._dialog).on(Event.MOUSEDOWN_DISMISS, () => { + $(this._element).one(Event.MOUSEUP_DISMISS, (event) => { + if ($(event.target).is(this._element)) { + this._ignoreBackdropClick = true + } + }) + }) - this._checkScrollbar() - this._setScrollbar() + this._showBackdrop(() => this._showElement(relatedTarget)) + } - this._adjustDialog() + hide(event) { + if (event) { + event.preventDefault() + } - $(document.body).addClass(ClassName.OPEN) + if (!this._isShown || this._isTransitioning) { + return + } - this._setEscapeEvent() - this._setResizeEvent() + const hideEvent = $.Event(Event.HIDE) - $(this._element).on( - Event.CLICK_DISMISS, - Selector.DATA_DISMISS, - (event) => this.hide(event) - ) + $(this._element).trigger(hideEvent) - $(this._dialog).on(Event.MOUSEDOWN_DISMISS, () => { - $(this._element).one(Event.MOUSEUP_DISMISS, (event) => { - if ($(event.target).is(this._element)) { - this._ignoreBackdropClick = true - } - }) - }) - - this._showBackdrop(() => this._showElement(relatedTarget)) + if (!this._isShown || hideEvent.isDefaultPrevented()) { + return } - hide(event) { - if (event) { - event.preventDefault() - } - - if (this._isTransitioning || !this._isShown) { - return - } + this._isShown = false + const transition = $(this._element).hasClass(ClassName.FADE) - const hideEvent = $.Event(Event.HIDE) + if (transition) { + this._isTransitioning = true + } - $(this._element).trigger(hideEvent) + this._setEscapeEvent() + this._setResizeEvent() - if (!this._isShown || hideEvent.isDefaultPrevented()) { - return - } + $(document).off(Event.FOCUSIN) - this._isShown = false - const transition = $(this._element).hasClass(ClassName.FADE) + $(this._element).removeClass(ClassName.SHOW) - if (transition) { - this._isTransitioning = true - } + $(this._element).off(Event.CLICK_DISMISS) + $(this._dialog).off(Event.MOUSEDOWN_DISMISS) - this._setEscapeEvent() - this._setResizeEvent() - $(document).off(Event.FOCUSIN) + if (transition) { + const transitionDuration = Util.getTransitionDurationFromElement(this._element) - $(this._element).removeClass(ClassName.SHOW) + $(this._element) + .one(Util.TRANSITION_END, (event) => this._hideModal(event)) + .emulateTransitionEnd(transitionDuration) + } else { + this._hideModal() + } + } - $(this._element).off(Event.CLICK_DISMISS) - $(this._dialog).off(Event.MOUSEDOWN_DISMISS) + 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 + } + handleUpdate() { + this._adjustDialog() + } - if (transition) { - const transitionDuration = Util.getTransitionDurationFromElement(this._element) + // Private - $(this._element) - .one(Util.TRANSITION_END, (event) => this._hideModal(event)) - .emulateTransitionEnd(transitionDuration) - } else { - this._hideModal() - } + _getConfig(config) { + config = { + ...Default, + ...config } + Util.typeCheckConfig(NAME, config, DefaultType) + return config + } - dispose() { - $.removeData(this._element, DATA_KEY) - - $(window, document, this._element, this._backdrop).off(EVENT_KEY) - - this._config = null - this._element = null - this._dialog = null - this._backdrop = null - this._isShown = null - this._isBodyOverflowing = null - this._ignoreBackdropClick = null - this._scrollbarWidth = null - } + _showElement(relatedTarget) { + const transition = $(this._element).hasClass(ClassName.FADE) - handleUpdate() { - this._adjustDialog() + if (!this._element.parentNode || + this._element.parentNode.nodeType !== Node.ELEMENT_NODE) { + // Don't move modal's DOM position + document.body.appendChild(this._element) } - // Private + this._element.style.display = 'block' + this._element.removeAttribute('aria-hidden') + this._element.setAttribute('aria-modal', true) - _getConfig(config) { - config = { - ...Default, - ...config - } - Util.typeCheckConfig(NAME, config, DefaultType) - return config + if ($(this._dialog).hasClass(ClassName.SCROLLABLE)) { + this._dialog.querySelector(Selector.MODAL_BODY).scrollTop = 0 + } else { + this._element.scrollTop = 0 } - _showElement(relatedTarget) { - const transition = $(this._element).hasClass(ClassName.FADE) - - if (!this._element.parentNode || - this._element.parentNode.nodeType !== Node.ELEMENT_NODE) { - // Don't move modal's DOM position - document.body.appendChild(this._element) - } + if (transition) { + Util.reflow(this._element) + } - this._element.style.display = 'block' - this._element.removeAttribute('aria-hidden') - this._element.scrollTop = 0 + $(this._element).addClass(ClassName.SHOW) - if (transition) { - Util.reflow(this._element) - } + if (this._config.focus) { + this._enforceFocus() + } - $(this._element).addClass(ClassName.SHOW) + const shownEvent = $.Event(Event.SHOWN, { + relatedTarget + }) + const transitionComplete = () => { if (this._config.focus) { - this._enforceFocus() + this._element.focus() } + this._isTransitioning = false + $(this._element).trigger(shownEvent) + } - const shownEvent = $.Event(Event.SHOWN, { - relatedTarget - }) + if (transition) { + const transitionDuration = Util.getTransitionDurationFromElement(this._dialog) + + $(this._dialog) + .one(Util.TRANSITION_END, transitionComplete) + .emulateTransitionEnd(transitionDuration) + } else { + transitionComplete() + } + } - const transitionComplete = () => { - if (this._config.focus) { + _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._isTransitioning = false - $(this._element).trigger(shownEvent) - } - - if (transition) { - const transitionDuration = Util.getTransitionDurationFromElement(this._element) + }) + } - $(this._dialog) - .one(Util.TRANSITION_END, transitionComplete) - .emulateTransitionEnd(transitionDuration) - } else { - transitionComplete() - } + _setEscapeEvent() { + if (this._isShown && this._config.keyboard) { + $(this._element).on(Event.KEYDOWN_DISMISS, (event) => { + if (event.which === ESCAPE_KEYCODE) { + event.preventDefault() + this.hide() + } + }) + } else if (!this._isShown) { + $(this._element).off(Event.KEYDOWN_DISMISS) } + } - _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() - } - }) + _setResizeEvent() { + if (this._isShown) { + $(window).on(Event.RESIZE, (event) => this.handleUpdate(event)) + } else { + $(window).off(Event.RESIZE) } + } - _setEscapeEvent() { - if (this._isShown && this._config.keyboard) { - $(this._element).on(Event.KEYDOWN_DISMISS, (event) => { - if (event.which === ESCAPE_KEYCODE) { - event.preventDefault() - this.hide() - } - }) - } else if (!this._isShown) { - $(this._element).off(Event.KEYDOWN_DISMISS) - } + _hideModal() { + this._element.style.display = 'none' + this._element.setAttribute('aria-hidden', true) + this._element.removeAttribute('aria-modal') + this._isTransitioning = false + this._showBackdrop(() => { + $(document.body).removeClass(ClassName.OPEN) + this._resetAdjustments() + this._resetScrollbar() + $(this._element).trigger(Event.HIDDEN) + }) + } + + _removeBackdrop() { + if (this._backdrop) { + $(this._backdrop).remove() + this._backdrop = null } + } - _setResizeEvent() { - if (this._isShown) { - $(window).on(Event.RESIZE, (event) => this.handleUpdate(event)) - } else { - $(window).off(Event.RESIZE) + _showBackdrop(callback) { + const animate = $(this._element).hasClass(ClassName.FADE) + ? ClassName.FADE : '' + + if (this._isShown && this._config.backdrop) { + this._backdrop = document.createElement('div') + this._backdrop.className = ClassName.BACKDROP + + if (animate) { + this._backdrop.classList.add(animate) } - } - _hideModal() { - this._element.style.display = 'none' - this._element.setAttribute('aria-hidden', true) - this._isTransitioning = false - this._showBackdrop(() => { - $(document.body).removeClass(ClassName.OPEN) - this._resetAdjustments() - this._resetScrollbar() - $(this._element).trigger(Event.HIDDEN) + $(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._element.focus() + } else { + this.hide() + } }) - } - _removeBackdrop() { - if (this._backdrop) { - $(this._backdrop).remove() - this._backdrop = null + if (animate) { + Util.reflow(this._backdrop) } - } - _showBackdrop(callback) { - const animate = $(this._element).hasClass(ClassName.FADE) - ? ClassName.FADE : '' + $(this._backdrop).addClass(ClassName.SHOW) - if (this._isShown && this._config.backdrop) { - this._backdrop = document.createElement('div') - this._backdrop.className = ClassName.BACKDROP + if (!callback) { + return + } - if (animate) { - this._backdrop.classList.add(animate) - } + if (!animate) { + callback() + return + } - $(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._element.focus() - } else { - this.hide() - } - }) - - if (animate) { - Util.reflow(this._backdrop) - } + const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop) - $(this._backdrop).addClass(ClassName.SHOW) + $(this._backdrop) + .one(Util.TRANSITION_END, callback) + .emulateTransitionEnd(backdropTransitionDuration) + } else if (!this._isShown && this._backdrop) { + $(this._backdrop).removeClass(ClassName.SHOW) - if (!callback) { - return - } - - if (!animate) { + const callbackRemove = () => { + this._removeBackdrop() + if (callback) { callback() - return } + } + if ($(this._element).hasClass(ClassName.FADE)) { const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop) $(this._backdrop) - .one(Util.TRANSITION_END, callback) + .one(Util.TRANSITION_END, callbackRemove) .emulateTransitionEnd(backdropTransitionDuration) - } else if (!this._isShown && this._backdrop) { - $(this._backdrop).removeClass(ClassName.SHOW) - - const callbackRemove = () => { - this._removeBackdrop() - if (callback) { - callback() - } - } - - if ($(this._element).hasClass(ClassName.FADE)) { - const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop) - - $(this._backdrop) - .one(Util.TRANSITION_END, callbackRemove) - .emulateTransitionEnd(backdropTransitionDuration) - } else { - callbackRemove() - } - } else if (callback) { - callback() + } else { + callbackRemove() } + } else if (callback) { + callback() } + } - // ---------------------------------------------------------------------- - // 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 + // ---------------------------------------------------------------------- + // the following methods are used to handle overflowing modals + // todo (fat): these should probably be refactored out of modal.js + // ---------------------------------------------------------------------- - if (!this._isBodyOverflowing && isModalOverflowing) { - this._element.style.paddingLeft = `${this._scrollbarWidth}px` - } + _adjustDialog() { + const isModalOverflowing = + this._element.scrollHeight > document.documentElement.clientHeight - if (this._isBodyOverflowing && !isModalOverflowing) { - this._element.style.paddingRight = `${this._scrollbarWidth}px` - } + if (!this._isBodyOverflowing && isModalOverflowing) { + this._element.style.paddingLeft = `${this._scrollbarWidth}px` } - _resetAdjustments() { - this._element.style.paddingLeft = '' - this._element.style.paddingRight = '' + if (this._isBodyOverflowing && !isModalOverflowing) { + this._element.style.paddingRight = `${this._scrollbarWidth}px` } + } - _checkScrollbar() { - const rect = document.body.getBoundingClientRect() - this._isBodyOverflowing = rect.left + rect.right < window.innerWidth - this._scrollbarWidth = this._getScrollbarWidth() - } + _resetAdjustments() { + this._element.style.paddingLeft = '' + this._element.style.paddingRight = '' + } - _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`) - } - } + _checkScrollbar() { + const rect = document.body.getBoundingClientRect() + this._isBodyOverflowing = rect.left + rect.right < window.innerWidth + this._scrollbarWidth = this._getScrollbarWidth() + } - _resetScrollbar() { - // Restore fixed content padding + _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 padding = $(element).data('padding-right') - $(element).removeData('padding-right') - element.style.paddingRight = padding ? padding : '' + const actualPadding = element.style.paddingRight + const calculatedPadding = $(element).css('padding-right') + $(element) + .data('padding-right', actualPadding) + .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`) }) - // 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') - } + // 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`) }) - // Restore body padding - const padding = $(document.body).data('padding-right') - $(document.body).removeData('padding-right') - document.body.style.paddingRight = padding ? padding : '' + // 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`) } - _getScrollbarWidth() { // thx d.walsh - const scrollDiv = document.createElement('div') - scrollDiv.className = ClassName.SCROLLBAR_MEASURER - document.body.appendChild(scrollDiv) - const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth - document.body.removeChild(scrollDiv) - return scrollbarWidth - } + $(document.body).addClass(ClassName.OPEN) + } - // Static + _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 : '' + }) - static _jQueryInterface(config, relatedTarget) { - return this.each(function () { - let data = $(this).data(DATA_KEY) - const _config = { - ...Default, - ...$(this).data(), - ...typeof config === 'object' && config ? config : {} - } + // 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') + } + }) - if (!data) { - data = new Modal(this, _config) - $(this).data(DATA_KEY, data) - } + // 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 = ClassName.SCROLLBAR_MEASURER + document.body.appendChild(scrollDiv) + const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth + document.body.removeChild(scrollDiv) + return scrollbarWidth + } + + // Static + + static _jQueryInterface(config, relatedTarget) { + return this.each(function () { + let data = $(this).data(DATA_KEY) + const _config = { + ...Default, + ...$(this).data(), + ...typeof config === 'object' && config ? config : {} + } + + if (!data) { + data = new Modal(this, _config) + $(this).data(DATA_KEY, data) + } - 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 config === 'string') { + if (typeof data[config] === 'undefined') { + throw new TypeError(`No method named "${config}"`) } - }) - } + data[config](relatedTarget) + } else if (_config.show) { + data.show(relatedTarget) + } + }) } +} - /** - * ------------------------------------------------------------------------ - * Data Api implementation - * ------------------------------------------------------------------------ - */ +/** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + +$(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { + let target + const selector = Util.getSelectorFromElement(this) - $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { - let target - const selector = Util.getSelectorFromElement(this) + if (selector) { + target = document.querySelector(selector) + } - if (selector) { - target = document.querySelector(selector) + const config = $(target).data(DATA_KEY) + ? 'toggle' : { + ...$(target).data(), + ...$(this).data() } - const config = $(target).data(DATA_KEY) - ? 'toggle' : { - ...$(target).data(), - ...$(this).data() - } + if (this.tagName === 'A' || this.tagName === 'AREA') { + event.preventDefault() + } - if (this.tagName === 'A' || this.tagName === 'AREA') { - event.preventDefault() + const $target = $(target).one(Event.SHOW, (showEvent) => { + if (showEvent.isDefaultPrevented()) { + // Only register focus restorer if modal will actually get shown + return } - const $target = $(target).one(Event.SHOW, (showEvent) => { - if (showEvent.isDefaultPrevented()) { - // Only register focus restorer if modal will actually get shown - return + $target.one(Event.HIDDEN, () => { + if ($(this).is(':visible')) { + this.focus() } - - $target.one(Event.HIDDEN, () => { - if ($(this).is(':visible')) { - this.focus() - } - }) }) - - Modal._jQueryInterface.call($(target), config, this) }) - /** - * ------------------------------------------------------------------------ - * jQuery - * ------------------------------------------------------------------------ - */ - - $.fn[NAME] = Modal._jQueryInterface - $.fn[NAME].Constructor = Modal - $.fn[NAME].noConflict = function () { - $.fn[NAME] = JQUERY_NO_CONFLICT - return Modal._jQueryInterface - } + Modal._jQueryInterface.call($(target), config, this) +}) + +/** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + */ - return Modal -})($) +$.fn[NAME] = Modal._jQueryInterface +$.fn[NAME].Constructor = Modal +$.fn[NAME].noConflict = () => { + $.fn[NAME] = JQUERY_NO_CONFLICT + return Modal._jQueryInterface +} export default Modal |