diff options
| author | XhmikosR <[email protected]> | 2021-08-18 07:29:56 +0300 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-08-18 07:29:56 +0300 |
| commit | 433a148c9e61aa942801fd8101dfa5c4045fdaed (patch) | |
| tree | f41db59fd06019169df5ea0338213ec0e298f226 /js/src/toast.js | |
| parent | b97cfa163b5098db70e03b27c91fca5dde9c267e (diff) | |
| parent | 18b3e1ac71f73d006756684a285c5a818e2d1454 (diff) | |
| download | bootstrap-global-focus-vars.tar.xz bootstrap-global-focus-vars.zip | |
Merge branch 'main' into global-focus-varsglobal-focus-vars
Diffstat (limited to 'js/src/toast.js')
| -rw-r--r-- | js/src/toast.js | 115 |
1 files changed, 69 insertions, 46 deletions
diff --git a/js/src/toast.js b/js/src/toast.js index 2f451aab7..442200738 100644 --- a/js/src/toast.js +++ b/js/src/toast.js @@ -1,21 +1,19 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v5.0.0-beta2): toast.js + * Bootstrap (v5.1.0): toast.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ import { defineJQueryPlugin, - emulateTransitionEnd, - getTransitionDurationFromElement, reflow, typeCheckConfig } from './util/index' -import Data from './dom/data' import EventHandler from './dom/event-handler' import Manipulator from './dom/manipulator' import BaseComponent from './base-component' +import { enableDismissTrigger } from './util/component-functions' /** * ------------------------------------------------------------------------ @@ -27,14 +25,17 @@ const NAME = 'toast' const DATA_KEY = 'bs.toast' const EVENT_KEY = `.${DATA_KEY}` -const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}` +const EVENT_MOUSEOVER = `mouseover${EVENT_KEY}` +const EVENT_MOUSEOUT = `mouseout${EVENT_KEY}` +const EVENT_FOCUSIN = `focusin${EVENT_KEY}` +const EVENT_FOCUSOUT = `focusout${EVENT_KEY}` const EVENT_HIDE = `hide${EVENT_KEY}` const EVENT_HIDDEN = `hidden${EVENT_KEY}` const EVENT_SHOW = `show${EVENT_KEY}` const EVENT_SHOWN = `shown${EVENT_KEY}` const CLASS_NAME_FADE = 'fade' -const CLASS_NAME_HIDE = 'hide' +const CLASS_NAME_HIDE = 'hide' // @deprecated - kept here only for backwards compatibility const CLASS_NAME_SHOW = 'show' const CLASS_NAME_SHOWING = 'showing' @@ -50,8 +51,6 @@ const Default = { delay: 5000 } -const SELECTOR_DATA_DISMISS = '[data-bs-dismiss="toast"]' - /** * ------------------------------------------------------------------------ * Class Definition @@ -64,6 +63,8 @@ class Toast extends BaseComponent { this._config = this._getConfig(config) this._timeout = null + this._hasMouseInteraction = false + this._hasKeyboardInteraction = false this._setListeners() } @@ -77,8 +78,8 @@ class Toast extends BaseComponent { return Default } - static get DATA_KEY() { - return DATA_KEY + static get NAME() { + return NAME } // Public @@ -98,28 +99,17 @@ class Toast extends BaseComponent { const complete = () => { this._element.classList.remove(CLASS_NAME_SHOWING) - this._element.classList.add(CLASS_NAME_SHOW) - EventHandler.trigger(this._element, EVENT_SHOWN) - if (this._config.autohide) { - this._timeout = setTimeout(() => { - this.hide() - }, this._config.delay) - } + this._maybeScheduleHide() } - this._element.classList.remove(CLASS_NAME_HIDE) + this._element.classList.remove(CLASS_NAME_HIDE) // @deprecated reflow(this._element) + this._element.classList.add(CLASS_NAME_SHOW) this._element.classList.add(CLASS_NAME_SHOWING) - if (this._config.animation) { - const transitionDuration = getTransitionDurationFromElement(this._element) - EventHandler.one(this._element, 'transitionend', complete) - emulateTransitionEnd(this._element, transitionDuration) - } else { - complete() - } + this._queueCallback(complete, this._element, this._config.animation) } hide() { @@ -134,19 +124,14 @@ class Toast extends BaseComponent { } const complete = () => { - this._element.classList.add(CLASS_NAME_HIDE) + this._element.classList.add(CLASS_NAME_HIDE) // @deprecated + this._element.classList.remove(CLASS_NAME_SHOWING) + this._element.classList.remove(CLASS_NAME_SHOW) EventHandler.trigger(this._element, EVENT_HIDDEN) } - this._element.classList.remove(CLASS_NAME_SHOW) - if (this._config.animation) { - const transitionDuration = getTransitionDurationFromElement(this._element) - - EventHandler.one(this._element, 'transitionend', complete) - emulateTransitionEnd(this._element, transitionDuration) - } else { - complete() - } + this._element.classList.add(CLASS_NAME_SHOWING) + this._queueCallback(complete, this._element, this._config.animation) } dispose() { @@ -156,10 +141,7 @@ class Toast extends BaseComponent { this._element.classList.remove(CLASS_NAME_SHOW) } - EventHandler.off(this._element, EVENT_CLICK_DISMISS) - super.dispose() - this._config = null } // Private @@ -176,8 +158,52 @@ class Toast extends BaseComponent { return config } + _maybeScheduleHide() { + if (!this._config.autohide) { + return + } + + if (this._hasMouseInteraction || this._hasKeyboardInteraction) { + return + } + + this._timeout = setTimeout(() => { + this.hide() + }, this._config.delay) + } + + _onInteraction(event, isInteracting) { + switch (event.type) { + case 'mouseover': + case 'mouseout': + this._hasMouseInteraction = isInteracting + break + case 'focusin': + case 'focusout': + this._hasKeyboardInteraction = isInteracting + break + default: + break + } + + if (isInteracting) { + this._clearTimeout() + return + } + + const nextElement = event.relatedTarget + if (this._element === nextElement || this._element.contains(nextElement)) { + return + } + + this._maybeScheduleHide() + } + _setListeners() { - EventHandler.on(this._element, EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, () => this.hide()) + EventHandler.on(this._element, EVENT_MOUSEOVER, event => this._onInteraction(event, true)) + EventHandler.on(this._element, EVENT_MOUSEOUT, event => this._onInteraction(event, false)) + EventHandler.on(this._element, EVENT_FOCUSIN, event => this._onInteraction(event, true)) + EventHandler.on(this._element, EVENT_FOCUSOUT, event => this._onInteraction(event, false)) } _clearTimeout() { @@ -189,12 +215,7 @@ class Toast extends BaseComponent { static jQueryInterface(config) { return this.each(function () { - let data = Data.getData(this, DATA_KEY) - const _config = typeof config === 'object' && config - - if (!data) { - data = new Toast(this, _config) - } + const data = Toast.getOrCreateInstance(this, config) if (typeof config === 'string') { if (typeof data[config] === 'undefined') { @@ -207,6 +228,8 @@ class Toast extends BaseComponent { } } +enableDismissTrigger(Toast) + /** * ------------------------------------------------------------------------ * jQuery @@ -214,6 +237,6 @@ class Toast extends BaseComponent { * add .Toast to jQuery only if jQuery is present */ -defineJQueryPlugin(NAME, Toast) +defineJQueryPlugin(Toast) export default Toast |
