diff options
Diffstat (limited to 'vendor/twbs/bootstrap/js/src/tooltip.js')
-rw-r--r-- | vendor/twbs/bootstrap/js/src/tooltip.js | 116 |
1 files changed, 66 insertions, 50 deletions
diff --git a/vendor/twbs/bootstrap/js/src/tooltip.js b/vendor/twbs/bootstrap/js/src/tooltip.js index cd4a2878e..a26b8ada6 100644 --- a/vendor/twbs/bootstrap/js/src/tooltip.js +++ b/vendor/twbs/bootstrap/js/src/tooltip.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v5.0.2): tooltip.js + * Bootstrap (v5.1.2): tooltip.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ @@ -17,10 +17,7 @@ import { noop, typeCheckConfig } from './util/index' -import { - DefaultAllowlist, - sanitizeHtml -} from './util/sanitizer' +import { DefaultAllowlist, sanitizeHtml } from './util/sanitizer' import Data from './dom/data' import EventHandler from './dom/event-handler' import Manipulator from './dom/manipulator' @@ -37,7 +34,6 @@ const NAME = 'tooltip' const DATA_KEY = 'bs.tooltip' const EVENT_KEY = `.${DATA_KEY}` const CLASS_PREFIX = 'bs-tooltip' -const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\s)${CLASS_PREFIX}\\S+`, 'g') const DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn']) const DefaultType = { @@ -112,6 +108,9 @@ const HOVER_STATE_SHOW = 'show' const HOVER_STATE_OUT = 'out' const SELECTOR_TOOLTIP_INNER = '.tooltip-inner' +const SELECTOR_MODAL = `.${CLASS_NAME_MODAL}` + +const EVENT_MODAL_HIDE = 'hide.bs.modal' const TRIGGER_HOVER = 'hover' const TRIGGER_FOCUS = 'focus' @@ -206,16 +205,13 @@ class Tooltip extends BaseComponent { dispose() { clearTimeout(this._timeout) - EventHandler.off(this._element.closest(`.${CLASS_NAME_MODAL}`), 'hide.bs.modal', this._hideModalHandler) + EventHandler.off(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler) if (this.tip) { this.tip.remove() } - if (this._popper) { - this._popper.destroy() - } - + this._disposePopper() super.dispose() } @@ -238,14 +234,20 @@ class Tooltip extends BaseComponent { return } + // A trick to recreate a tooltip in case a new title is given by using the NOT documented `data-bs-original-title` + // This will be removed later in favor of a `setContent` method + if (this.constructor.NAME === 'tooltip' && this.tip && this.getTitle() !== this.tip.querySelector(SELECTOR_TOOLTIP_INNER).innerHTML) { + this._disposePopper() + this.tip.remove() + this.tip = null + } + const tip = this.getTipElement() const tipId = getUID(this.constructor.NAME) tip.setAttribute('id', tipId) this._element.setAttribute('aria-describedby', tipId) - this.setContent() - if (this._config.animation) { tip.classList.add(CLASS_NAME_FADE) } @@ -261,7 +263,7 @@ class Tooltip extends BaseComponent { Data.set(tip, this.constructor.DATA_KEY, this) if (!this._element.ownerDocument.documentElement.contains(this.tip)) { - container.appendChild(tip) + container.append(tip) EventHandler.trigger(this._element, this.constructor.Event.INSERTED) } @@ -273,7 +275,7 @@ class Tooltip extends BaseComponent { tip.classList.add(CLASS_NAME_SHOW) - const customClass = typeof this._config.customClass === 'function' ? this._config.customClass() : this._config.customClass + const customClass = this._resolvePossibleFunction(this._config.customClass) if (customClass) { tip.classList.add(...customClass.split(' ')) } @@ -322,10 +324,7 @@ class Tooltip extends BaseComponent { this._element.removeAttribute('aria-describedby') EventHandler.trigger(this._element, this.constructor.Event.HIDDEN) - if (this._popper) { - this._popper.destroy() - this._popper = null - } + this._disposePopper() } const hideEvent = EventHandler.trigger(this._element, this.constructor.Event.HIDE) @@ -371,14 +370,28 @@ class Tooltip extends BaseComponent { const element = document.createElement('div') element.innerHTML = this._config.template - this.tip = element.children[0] + const tip = element.children[0] + this.setContent(tip) + tip.classList.remove(CLASS_NAME_FADE, CLASS_NAME_SHOW) + + this.tip = tip return this.tip } - setContent() { - const tip = this.getTipElement() - this.setElementContent(SelectorEngine.findOne(SELECTOR_TOOLTIP_INNER, tip), this.getTitle()) - tip.classList.remove(CLASS_NAME_FADE, CLASS_NAME_SHOW) + setContent(tip) { + this._sanitizeAndSetContent(tip, this.getTitle(), SELECTOR_TOOLTIP_INNER) + } + + _sanitizeAndSetContent(template, content, selector) { + const templateElement = SelectorEngine.findOne(selector, template) + + if (!content && templateElement) { + templateElement.remove() + return + } + + // we use append for html objects to maintain js events + this.setElementContent(templateElement, content) } setElementContent(element, content) { @@ -393,7 +406,7 @@ class Tooltip extends BaseComponent { if (this._config.html) { if (content.parentNode !== element) { element.innerHTML = '' - element.appendChild(content) + element.append(content) } } else { element.textContent = content.textContent @@ -414,15 +427,9 @@ class Tooltip extends BaseComponent { } getTitle() { - let title = this._element.getAttribute('data-bs-original-title') - - if (!title) { - title = typeof this._config.title === 'function' ? - this._config.title.call(this._element) : - this._config.title - } + const title = this._element.getAttribute('data-bs-original-title') || this._config.title - return title + return this._resolvePossibleFunction(title) } updateAttachment(attachment) { @@ -440,15 +447,7 @@ class Tooltip extends BaseComponent { // Private _initializeOnDelegatedTarget(event, context) { - const dataKey = this.constructor.DATA_KEY - context = context || Data.get(event.delegateTarget, dataKey) - - if (!context) { - context = new this.constructor(event.delegateTarget, this._getDelegateConfig()) - Data.set(event.delegateTarget, dataKey, context) - } - - return context + return context || this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig()) } _getOffset() { @@ -465,6 +464,10 @@ class Tooltip extends BaseComponent { return offset } + _resolvePossibleFunction(content) { + return typeof content === 'function' ? content.call(this._element) : content + } + _getPopperConfig(attachment) { const defaultBsPopperConfig = { placement: attachment, @@ -514,7 +517,7 @@ class Tooltip extends BaseComponent { } _addAttachmentClass(attachment) { - this.getTipElement().classList.add(`${CLASS_PREFIX}-${this.updateAttachment(attachment)}`) + this.getTipElement().classList.add(`${this._getBasicClassPrefix()}-${this.updateAttachment(attachment)}`) } _getAttachment(placement) { @@ -546,7 +549,7 @@ class Tooltip extends BaseComponent { } } - EventHandler.on(this._element.closest(`.${CLASS_NAME_MODAL}`), 'hide.bs.modal', this._hideModalHandler) + EventHandler.on(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler) if (this._config.selector) { this._config = { @@ -686,26 +689,32 @@ class Tooltip extends BaseComponent { _getDelegateConfig() { const config = {} - if (this._config) { - for (const key in this._config) { - if (this.constructor.Default[key] !== this._config[key]) { - config[key] = this._config[key] - } + for (const key in this._config) { + if (this.constructor.Default[key] !== this._config[key]) { + config[key] = this._config[key] } } + // In the future can be replaced with: + // const keysWithDifferentValues = Object.entries(this._config).filter(entry => this.constructor.Default[entry[0]] !== this._config[entry[0]]) + // `Object.fromEntries(keysWithDifferentValues)` return config } _cleanTipClass() { const tip = this.getTipElement() - const tabClass = tip.getAttribute('class').match(BSCLS_PREFIX_REGEX) + const basicClassPrefixRegex = new RegExp(`(^|\\s)${this._getBasicClassPrefix()}\\S+`, 'g') + const tabClass = tip.getAttribute('class').match(basicClassPrefixRegex) if (tabClass !== null && tabClass.length > 0) { tabClass.map(token => token.trim()) .forEach(tClass => tip.classList.remove(tClass)) } } + _getBasicClassPrefix() { + return CLASS_PREFIX + } + _handlePopperPlacementChange(popperData) { const { state } = popperData @@ -718,6 +727,13 @@ class Tooltip extends BaseComponent { this._addAttachmentClass(this._getAttachment(state.placement)) } + _disposePopper() { + if (this._popper) { + this._popper.destroy() + this._popper = null + } + } + // Static static jQueryInterface(config) { |