From 48a95f7280735d6f8962fe8b17975b03e351710c Mon Sep 17 00:00:00 2001 From: alpadev <2838324+alpadev@users.noreply.github.com> Date: Tue, 2 Mar 2021 15:55:44 +0100 Subject: refactor: use a Map instead of an Object in dom/data (#32180) Co-authored-by: XhmikosR Co-authored-by: Rohit Sharma --- js/src/tooltip.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index d35b5e0ab..6f33245f8 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -275,7 +275,7 @@ class Tooltip extends BaseComponent { this._addAttachmentClass(attachment) const container = this._getContainer() - Data.setData(tip, this.constructor.DATA_KEY, this) + Data.set(tip, this.constructor.DATA_KEY, this) if (!this._element.ownerDocument.documentElement.contains(this.tip)) { container.appendChild(tip) @@ -465,11 +465,11 @@ class Tooltip extends BaseComponent { _initializeOnDelegatedTarget(event, context) { const dataKey = this.constructor.DATA_KEY - context = context || Data.getData(event.delegateTarget, dataKey) + context = context || Data.get(event.delegateTarget, dataKey) if (!context) { context = new this.constructor(event.delegateTarget, this._getDelegateConfig()) - Data.setData(event.delegateTarget, dataKey, context) + Data.set(event.delegateTarget, dataKey, context) } return context @@ -761,7 +761,7 @@ class Tooltip extends BaseComponent { static jQueryInterface(config) { return this.each(function () { - let data = Data.getData(this, DATA_KEY) + let data = Data.get(this, DATA_KEY) const _config = typeof config === 'object' && config if (!data && /dispose|hide/.test(config)) { -- cgit v1.2.3 From d491c29aa005177ef148c40d4b7b0a3decc7edef Mon Sep 17 00:00:00 2001 From: Ryan Berliner Date: Sat, 6 Mar 2021 03:35:28 +0200 Subject: prevent tooltip from being deleted on quick re-activations --- js/src/tooltip.js | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index 6f33245f8..e9f9bfff1 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -329,6 +329,10 @@ class Tooltip extends BaseComponent { const tip = this.getTipElement() const complete = () => { + if (this._isWithActiveTrigger()) { + return + } + if (this._hoverState !== HOVER_STATE_SHOW && tip.parentNode) { tip.parentNode.removeChild(tip) } -- cgit v1.2.3 From 6ef70b342c27445685715f51cfcafb719356870f Mon Sep 17 00:00:00 2001 From: Ryan Berliner Date: Sat, 6 Mar 2021 23:57:23 +0200 Subject: prevent quick interactions from misplacing tooltips --- js/src/tooltip.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index e9f9bfff1..857f72c8a 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -283,6 +283,10 @@ class Tooltip extends BaseComponent { EventHandler.trigger(this._element, this.constructor.Event.INSERTED) + if (this._popper) { + this._popper.destroy() + } + this._popper = Popper.createPopper(this._element, tip, this._getPopperConfig(attachment)) tip.classList.add(CLASS_NAME_SHOW) @@ -650,7 +654,7 @@ class Tooltip extends BaseComponent { if (event) { context._activeTrigger[ event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER - ] = false + ] = context._element.contains(event.relatedTarget) } if (context._isWithActiveTrigger()) { -- cgit v1.2.3 From 72d23135799059d4282ea5764455f92f39ced5a5 Mon Sep 17 00:00:00 2001 From: Ryan Berliner Date: Sun, 7 Mar 2021 08:28:41 -0500 Subject: reuse existing popper on show during tooltip fadeout --- js/src/tooltip.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index 857f72c8a..de7dcca69 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -284,11 +284,11 @@ class Tooltip extends BaseComponent { EventHandler.trigger(this._element, this.constructor.Event.INSERTED) if (this._popper) { - this._popper.destroy() + this._popper.update() + } else { + this._popper = Popper.createPopper(this._element, tip, this._getPopperConfig(attachment)) } - this._popper = Popper.createPopper(this._element, tip, this._getPopperConfig(attachment)) - tip.classList.add(CLASS_NAME_SHOW) const customClass = typeof this.config.customClass === 'function' ? this.config.customClass() : this.config.customClass -- cgit v1.2.3 From 99b2c0b390660b2032c3129b8ebff02fa1e034c9 Mon Sep 17 00:00:00 2001 From: Ryan Berliner Date: Sun, 7 Mar 2021 17:09:17 +0200 Subject: only trigger tooltip inserted event on true dom insert --- js/src/tooltip.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index de7dcca69..979bd0773 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -279,10 +279,9 @@ class Tooltip extends BaseComponent { if (!this._element.ownerDocument.documentElement.contains(this.tip)) { container.appendChild(tip) + EventHandler.trigger(this._element, this.constructor.Event.INSERTED) } - EventHandler.trigger(this._element, this.constructor.Event.INSERTED) - if (this._popper) { this._popper.update() } else { -- cgit v1.2.3 From 220139a89ffc3864bbb6e1b35471667318eadc1f Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Tue, 23 Mar 2021 18:26:54 +0200 Subject: Release v5.0.0-beta3 (#33439) --- js/src/tooltip.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index 979bd0773..4fea1c964 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v5.0.0-beta2): tooltip.js + * Bootstrap (v5.0.0-beta3): tooltip.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ -- cgit v1.2.3 From b2bc159d722a640b684f12a1171d70c8d5284b4e Mon Sep 17 00:00:00 2001 From: Rohit Sharma Date: Sat, 27 Mar 2021 21:38:45 +0530 Subject: Use cached `noop` function everywhere --- js/src/tooltip.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index 4fea1c964..a66e1ad41 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -301,7 +301,7 @@ class Tooltip extends BaseComponent { // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html if ('ontouchstart' in document.documentElement) { [].concat(...document.body.children).forEach(element => { - EventHandler.on(element, 'mouseover', noop()) + EventHandler.on(element, 'mouseover', noop) }) } -- cgit v1.2.3 From 566451230f5c87c3d7515af02995895df610b8ac Mon Sep 17 00:00:00 2001 From: GeoSot Date: Sun, 11 Apr 2021 09:54:48 +0300 Subject: Remove element event listeners through base component (#33429) After some research, I found out that EventHandler saves all the custom events per element using namespace, and is capable of removing handlers using only the element and its namespace (`DATA_KEY`). So, probably is better to utilize the base-component to do the same job. --- js/src/tooltip.js | 1 - 1 file changed, 1 deletion(-) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index a66e1ad41..2bfa42fc7 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -215,7 +215,6 @@ class Tooltip extends BaseComponent { dispose() { clearTimeout(this._timeout) - EventHandler.off(this._element, this.constructor.EVENT_KEY) EventHandler.off(this._element.closest(`.${CLASS_NAME_MODAL}`), 'hide.bs.modal', this._hideModalHandler) if (this.tip && this.tip.parentNode) { -- cgit v1.2.3 From a22f4d3cfd46ad040e0eb636c378fdb832704e07 Mon Sep 17 00:00:00 2001 From: Rohit Sharma Date: Mon, 19 Apr 2021 22:28:45 +0530 Subject: Don't change the value for `altBoundary` option (#33684) - Since bootstrap is not changing the default value of `elementContext` option, changing the value of `altBoundary` option is not needed for any modifier in real Co-authored-by: XhmikosR --- js/src/tooltip.js | 1 - 1 file changed, 1 deletion(-) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index 2bfa42fc7..ecea04390 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -502,7 +502,6 @@ class Tooltip extends BaseComponent { { name: 'flip', options: { - altBoundary: true, fallbackPlacements: this.config.fallbackPlacements } }, -- cgit v1.2.3 From bf0936748602c8109fd916c64b4560799fa1c3f8 Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Wed, 5 May 2021 22:32:12 +0300 Subject: Release v5.0.0 (#33647) * Bump version to 5.0.0 * Fix npm tag * Dist --- js/src/tooltip.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index ecea04390..37ef8cb89 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v5.0.0-beta3): tooltip.js + * Bootstrap (v5.0.0): tooltip.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ -- cgit v1.2.3 From 90b1a6907ed7bb3397fe6bd223f09eb12122d7a3 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Sun, 11 Apr 2021 02:27:18 +0300 Subject: Merge js-components 'transitionend' listener callbacks into one method --- js/src/tooltip.js | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index 37ef8cb89..65eb7a11c 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -9,9 +9,7 @@ import * as Popper from '@popperjs/core' import { defineJQueryPlugin, - emulateTransitionEnd, findShadowRoot, - getTransitionDurationFromElement, getUID, isElement, isRTL, @@ -315,13 +313,8 @@ class Tooltip extends BaseComponent { } } - if (this.tip.classList.contains(CLASS_NAME_FADE)) { - const transitionDuration = getTransitionDurationFromElement(this.tip) - EventHandler.one(this.tip, 'transitionend', complete) - emulateTransitionEnd(this.tip, transitionDuration) - } else { - complete() - } + const isAnimated = this.tip.classList.contains(CLASS_NAME_FADE) + this._queueCallback(complete, this.tip, isAnimated) } hide() { @@ -367,15 +360,8 @@ class Tooltip extends BaseComponent { this._activeTrigger[TRIGGER_FOCUS] = false this._activeTrigger[TRIGGER_HOVER] = false - if (this.tip.classList.contains(CLASS_NAME_FADE)) { - const transitionDuration = getTransitionDurationFromElement(tip) - - EventHandler.one(tip, 'transitionend', complete) - emulateTransitionEnd(tip, transitionDuration) - } else { - complete() - } - + const isAnimated = this.tip.classList.contains(CLASS_NAME_FADE) + this._queueCallback(complete, this.tip, isAnimated) this._hoverState = '' } -- cgit v1.2.3 From 03842b5f259d6007db02c465e6c55929e551e9cd Mon Sep 17 00:00:00 2001 From: GeoSot Date: Tue, 11 May 2021 09:04:42 +0300 Subject: Refactor: move disposing properties into the base class (#33740) Moves more functionality to `base-component`, transferring the responsibility of disposal to parent class. Each component, dusting disposal, sets its protected properties to `null`. So the same can be done in one place for all children components . --- js/src/tooltip.js | 7 ------- 1 file changed, 7 deletions(-) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index 65eb7a11c..7226d3123 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -219,17 +219,10 @@ class Tooltip extends BaseComponent { this.tip.parentNode.removeChild(this.tip) } - this._isEnabled = null - this._timeout = null - this._hoverState = null - this._activeTrigger = null if (this._popper) { this._popper.destroy() } - this._popper = null - this.config = null - this.tip = null super.dispose() } -- cgit v1.2.3 From 9fe36edf683af02574bf6bbd6c9b27de93bd31b1 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Tue, 11 May 2021 10:49:30 +0300 Subject: Extract static `DATA_KEY` & `EVENT_KEY` to base-component (#33635) * Force each plugin that extends base-components to implement a static method `NAME()` * Remove redundant `NAME` argument from 'Utils.defineJQueryPlugin' & fix test --- js/src/tooltip.js | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index 7226d3123..632115d72 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -155,18 +155,10 @@ class Tooltip extends BaseComponent { return NAME } - static get DATA_KEY() { - return DATA_KEY - } - static get Event() { return Event } - static get EVENT_KEY() { - return EVENT_KEY - } - static get DefaultType() { return DefaultType } @@ -774,6 +766,6 @@ class Tooltip extends BaseComponent { * add .Tooltip to jQuery only if jQuery is present */ -defineJQueryPlugin(NAME, Tooltip) +defineJQueryPlugin(Tooltip) export default Tooltip -- cgit v1.2.3 From 9a9e22475c9c9d6a4a621daeba5bbfbe8dd280a7 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Wed, 12 May 2021 12:15:59 +0300 Subject: Popover/Tooltip: streamline config property to start with underscore (#33381) --- js/src/tooltip.js | 74 +++++++++++++++++++++++++++---------------------------- 1 file changed, 37 insertions(+), 37 deletions(-) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index 632115d72..e44057382 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -139,7 +139,7 @@ class Tooltip extends BaseComponent { this._popper = null // Protected - this.config = this._getConfig(config) + this._config = this._getConfig(config) this.tip = null this._setListeners() @@ -245,13 +245,13 @@ class Tooltip extends BaseComponent { this.setContent() - if (this.config.animation) { + if (this._config.animation) { tip.classList.add(CLASS_NAME_FADE) } - const placement = typeof this.config.placement === 'function' ? - this.config.placement.call(this, tip, this._element) : - this.config.placement + const placement = typeof this._config.placement === 'function' ? + this._config.placement.call(this, tip, this._element) : + this._config.placement const attachment = this._getAttachment(placement) this._addAttachmentClass(attachment) @@ -272,7 +272,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 = typeof this._config.customClass === 'function' ? this._config.customClass() : this._config.customClass if (customClass) { tip.classList.add(...customClass.split(' ')) } @@ -368,7 +368,7 @@ class Tooltip extends BaseComponent { } const element = document.createElement('div') - element.innerHTML = this.config.template + element.innerHTML = this._config.template this.tip = element.children[0] return this.tip @@ -391,7 +391,7 @@ class Tooltip extends BaseComponent { } // content is a DOM node or a jQuery - if (this.config.html) { + if (this._config.html) { if (content.parentNode !== element) { element.innerHTML = '' element.appendChild(content) @@ -403,9 +403,9 @@ class Tooltip extends BaseComponent { return } - if (this.config.html) { - if (this.config.sanitize) { - content = sanitizeHtml(content, this.config.allowList, this.config.sanitizeFn) + if (this._config.html) { + if (this._config.sanitize) { + content = sanitizeHtml(content, this._config.allowList, this._config.sanitizeFn) } element.innerHTML = content @@ -418,9 +418,9 @@ class Tooltip extends BaseComponent { 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 + title = typeof this._config.title === 'function' ? + this._config.title.call(this._element) : + this._config.title } return title @@ -453,7 +453,7 @@ class Tooltip extends BaseComponent { } _getOffset() { - const { offset } = this.config + const { offset } = this._config if (typeof offset === 'string') { return offset.split(',').map(val => Number.parseInt(val, 10)) @@ -473,7 +473,7 @@ class Tooltip extends BaseComponent { { name: 'flip', options: { - fallbackPlacements: this.config.fallbackPlacements + fallbackPlacements: this._config.fallbackPlacements } }, { @@ -485,7 +485,7 @@ class Tooltip extends BaseComponent { { name: 'preventOverflow', options: { - boundary: this.config.boundary + boundary: this._config.boundary } }, { @@ -510,7 +510,7 @@ class Tooltip extends BaseComponent { return { ...defaultBsPopperConfig, - ...(typeof this.config.popperConfig === 'function' ? this.config.popperConfig(defaultBsPopperConfig) : this.config.popperConfig) + ...(typeof this._config.popperConfig === 'function' ? this._config.popperConfig(defaultBsPopperConfig) : this._config.popperConfig) } } @@ -519,15 +519,15 @@ class Tooltip extends BaseComponent { } _getContainer() { - if (this.config.container === false) { + if (this._config.container === false) { return document.body } - if (isElement(this.config.container)) { - return this.config.container + if (isElement(this._config.container)) { + return this._config.container } - return SelectorEngine.findOne(this.config.container) + return SelectorEngine.findOne(this._config.container) } _getAttachment(placement) { @@ -535,11 +535,11 @@ class Tooltip extends BaseComponent { } _setListeners() { - const triggers = this.config.trigger.split(' ') + const triggers = this._config.trigger.split(' ') triggers.forEach(trigger => { if (trigger === 'click') { - EventHandler.on(this._element, this.constructor.Event.CLICK, this.config.selector, event => this.toggle(event)) + EventHandler.on(this._element, this.constructor.Event.CLICK, this._config.selector, event => this.toggle(event)) } else if (trigger !== TRIGGER_MANUAL) { const eventIn = trigger === TRIGGER_HOVER ? this.constructor.Event.MOUSEENTER : @@ -548,8 +548,8 @@ class Tooltip extends BaseComponent { this.constructor.Event.MOUSELEAVE : this.constructor.Event.FOCUSOUT - EventHandler.on(this._element, eventIn, this.config.selector, event => this._enter(event)) - EventHandler.on(this._element, eventOut, this.config.selector, event => this._leave(event)) + EventHandler.on(this._element, eventIn, this._config.selector, event => this._enter(event)) + EventHandler.on(this._element, eventOut, this._config.selector, event => this._leave(event)) } }) @@ -561,9 +561,9 @@ class Tooltip extends BaseComponent { EventHandler.on(this._element.closest(`.${CLASS_NAME_MODAL}`), 'hide.bs.modal', this._hideModalHandler) - if (this.config.selector) { - this.config = { - ...this.config, + if (this._config.selector) { + this._config = { + ...this._config, trigger: 'manual', selector: '' } @@ -604,7 +604,7 @@ class Tooltip extends BaseComponent { context._hoverState = HOVER_STATE_SHOW - if (!context.config.delay || !context.config.delay.show) { + if (!context._config.delay || !context._config.delay.show) { context.show() return } @@ -613,7 +613,7 @@ class Tooltip extends BaseComponent { if (context._hoverState === HOVER_STATE_SHOW) { context.show() } - }, context.config.delay.show) + }, context._config.delay.show) } _leave(event, context) { @@ -633,7 +633,7 @@ class Tooltip extends BaseComponent { context._hoverState = HOVER_STATE_OUT - if (!context.config.delay || !context.config.delay.hide) { + if (!context._config.delay || !context._config.delay.hide) { context.hide() return } @@ -642,7 +642,7 @@ class Tooltip extends BaseComponent { if (context._hoverState === HOVER_STATE_OUT) { context.hide() } - }, context.config.delay.hide) + }, context._config.delay.hide) } _isWithActiveTrigger() { @@ -701,10 +701,10 @@ 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] + if (this._config) { + for (const key in this._config) { + if (this.constructor.Default[key] !== this._config[key]) { + config[key] = this._config[key] } } } -- cgit v1.2.3 From 6e1c9096f08ed21063fd6ba16aa998a3ac4149f9 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Thu, 13 May 2021 18:17:20 +0300 Subject: Move get element functionality to a helper (#33327) Looking around on js components I found out many checks, different expressed but with same purpose. Some of them are trying to parse string to element, others, jQuery element to js simple nodeElement etc With this Pr, I am trying to give a standard way to parse an element So this pr: * Creates `getElement` helper that tries to parse an argument to element or null * Changes `isElement` to make explicit checks and return Boolean * fixes tests deficiencies --- js/src/tooltip.js | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index e44057382..fb4657839 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -10,6 +10,7 @@ import * as Popper from '@popperjs/core' import { defineJQueryPlugin, findShadowRoot, + getElement, getUID, isElement, isRTL, @@ -256,7 +257,7 @@ class Tooltip extends BaseComponent { const attachment = this._getAttachment(placement) this._addAttachmentClass(attachment) - const container = this._getContainer() + const { container } = this._config Data.set(tip, this.constructor.DATA_KEY, this) if (!this._element.ownerDocument.documentElement.contains(this.tip)) { @@ -385,10 +386,8 @@ class Tooltip extends BaseComponent { return } - if (typeof content === 'object' && isElement(content)) { - if (content.jquery) { - content = content[0] - } + if (isElement(content)) { + content = getElement(content) // content is a DOM node or a jQuery if (this._config.html) { @@ -518,18 +517,6 @@ class Tooltip extends BaseComponent { this.getTipElement().classList.add(`${CLASS_PREFIX}-${this.updateAttachment(attachment)}`) } - _getContainer() { - if (this._config.container === false) { - return document.body - } - - if (isElement(this._config.container)) { - return this._config.container - } - - return SelectorEngine.findOne(this._config.container) - } - _getAttachment(placement) { return AttachmentMap[placement.toUpperCase()] } @@ -664,16 +651,14 @@ class Tooltip extends BaseComponent { } }) - if (config && typeof config.container === 'object' && config.container.jquery) { - config.container = config.container[0] - } - config = { ...this.constructor.Default, ...dataAttributes, ...(typeof config === 'object' && config ? config : {}) } + config.container = config.container === false ? document.body : getElement(config.container) + if (typeof config.delay === 'number') { config.delay = { show: config.delay, -- cgit v1.2.3 From 58b1be927f43c779377e478df2d119f2ddf956ca Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Thu, 13 May 2021 19:22:20 +0300 Subject: Release v5.0.1 (#33972) * Bump version to 5.0.1. * Dist --- js/src/tooltip.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index fb4657839..d164da2b3 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v5.0.0): tooltip.js + * Bootstrap (v5.0.1): tooltip.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ -- cgit v1.2.3 From 9e4f87ae8f2e32bb31795ece8f9ab3e7b823dd7d Mon Sep 17 00:00:00 2001 From: GeoSot Date: Thu, 20 May 2021 16:16:55 +0300 Subject: Allow use of `dispose/hide` methods on Tooltip & Popover from jQueryInterface, when component does not exists. (#33371) --- js/src/tooltip.js | 4 ---- 1 file changed, 4 deletions(-) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index d164da2b3..84379c88f 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -725,10 +725,6 @@ class Tooltip extends BaseComponent { let data = Data.get(this, DATA_KEY) const _config = typeof config === 'object' && config - if (!data && /dispose|hide/.test(config)) { - return - } - if (!data) { data = new Tooltip(this, _config) } -- cgit v1.2.3 From 544d9ac3cf5b7a501524c1bab9570f4b46b8e7e4 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Tue, 25 May 2021 18:30:38 +0300 Subject: Change `element.parentNode.removeChild(element)` to `element.remove()` (#34071) --- js/src/tooltip.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index 84379c88f..2eb91965b 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -208,8 +208,8 @@ class Tooltip extends BaseComponent { EventHandler.off(this._element.closest(`.${CLASS_NAME_MODAL}`), 'hide.bs.modal', this._hideModalHandler) - if (this.tip && this.tip.parentNode) { - this.tip.parentNode.removeChild(this.tip) + if (this.tip) { + this.tip.remove() } if (this._popper) { @@ -314,8 +314,8 @@ class Tooltip extends BaseComponent { return } - if (this._hoverState !== HOVER_STATE_SHOW && tip.parentNode) { - tip.parentNode.removeChild(tip) + if (this._hoverState !== HOVER_STATE_SHOW) { + tip.remove() } this._cleanTipClass() -- cgit v1.2.3 From c98657b8303150bfda3bdea750055b83a29b27a3 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Thu, 3 Jun 2021 18:53:27 +0300 Subject: Add `getOrCreateInstance` method in base-component (#33276) Co-authored-by: Rohit Sharma Co-authored-by: XhmikosR --- js/src/tooltip.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index 2eb91965b..78b7c478b 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -722,12 +722,7 @@ class Tooltip extends BaseComponent { static jQueryInterface(config) { return this.each(function () { - let data = Data.get(this, DATA_KEY) - const _config = typeof config === 'object' && config - - if (!data) { - data = new Tooltip(this, _config) - } + const data = Tooltip.getOrCreateInstance(this, config) if (typeof config === 'string') { if (typeof data[config] === 'undefined') { -- cgit v1.2.3 From 688bce4fa695cc360a0d084e34f029b0c192b223 Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Tue, 22 Jun 2021 21:29:16 +0300 Subject: Release v5.0.2 (#34276) * Bump version to v5.0.2. * Dist --- js/src/tooltip.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index 78b7c478b..cd4a2878e 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v5.0.1): tooltip.js + * Bootstrap (v5.0.2): tooltip.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ -- cgit v1.2.3 From c4e189df40ffced65848d440e8e95892360445ba Mon Sep 17 00:00:00 2001 From: GeoSot Date: Thu, 10 Jun 2021 10:48:35 +0300 Subject: use a class private getter to decouple same methods usage --- js/src/tooltip.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index cd4a2878e..cdc9b1e5d 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -37,7 +37,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 = { @@ -514,7 +513,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) { @@ -699,13 +698,18 @@ class Tooltip extends BaseComponent { _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 -- cgit v1.2.3 From 92c7056619293a581626c37ef2c0095c6f1abceb Mon Sep 17 00:00:00 2001 From: GeoSot Date: Thu, 10 Jun 2021 10:52:35 +0300 Subject: `_getDelegateConfig()`: add a comment and remove an unneeded config check --- js/src/tooltip.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index cdc9b1e5d..d69a80e27 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -685,14 +685,15 @@ 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 } -- cgit v1.2.3 From 3716603dbc3dc1b612c4ef6c83860195312f2532 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Thu, 10 Jun 2021 10:53:59 +0300 Subject: Use `getOrCreateInstance` on `_initializeOnDelegatedTarget` --- js/src/tooltip.js | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index d69a80e27..6dc7a0350 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -439,15 +439,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() { -- cgit v1.2.3 From a97fd1cd2420a4c07589689593385484bd38fb50 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Thu, 10 Jun 2021 10:55:34 +0300 Subject: use one private method to resolve string or function --- js/src/tooltip.js | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index 6dc7a0350..5746ec6ba 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -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' @@ -272,7 +269,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(' ')) } @@ -413,15 +410,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) { @@ -456,6 +447,10 @@ class Tooltip extends BaseComponent { return offset } + _resolvePossibleFunction(content) { + return typeof content === 'function' ? content.call(this._element) : content + } + _getPopperConfig(attachment) { const defaultBsPopperConfig = { placement: attachment, -- cgit v1.2.3 From 9c3ceaa25b0fcb9b5bd9ff688235e4f3b741026a Mon Sep 17 00:00:00 2001 From: GeoSot Date: Thu, 10 Jun 2021 10:58:41 +0300 Subject: popover: Move common code in tooltip's `getTipElement()` --- js/src/tooltip.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index 5746ec6ba..fa364a1e6 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -367,7 +367,10 @@ class Tooltip extends BaseComponent { const element = document.createElement('div') element.innerHTML = this._config.template - this.tip = element.children[0] + const tip = element.children[0] + tip.classList.remove(CLASS_NAME_FADE, CLASS_NAME_SHOW) + + this.tip = tip return this.tip } -- cgit v1.2.3 From da2db218edfc0746c169b567e6a13c9f8e945dda Mon Sep 17 00:00:00 2001 From: GeoSot Date: Thu, 10 Jun 2021 11:00:05 +0300 Subject: Use on private method to set content & cleanup template --- js/src/tooltip.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index fa364a1e6..e09a53b5c 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -376,8 +376,18 @@ class Tooltip extends BaseComponent { setContent() { const tip = this.getTipElement() - this.setElementContent(SelectorEngine.findOne(SELECTOR_TOOLTIP_INNER, tip), this.getTitle()) - tip.classList.remove(CLASS_NAME_FADE, CLASS_NAME_SHOW) + this._sanitizeAndSetContent(tip, this.getTitle(), SELECTOR_TOOLTIP_INNER) + } + + _sanitizeAndSetContent(template, content, selector) { + const templateElement = SelectorEngine.findOne(selector, template) + if (!content) { + templateElement.remove() + return + } + + // we use append for html objects to maintain js events + this.setElementContent(templateElement, content) } setElementContent(element, content) { -- cgit v1.2.3 From 6d707f4801750f1454351d6afe93a80ce4516d1a Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Fri, 30 Jul 2021 01:23:00 +0300 Subject: Enable a few eslint-config-xo rules (#34620) * unicorn/prefer-dom-node-append * unicorn/prefer-dom-node-remove --- js/src/tooltip.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index e09a53b5c..0adde623f 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -257,7 +257,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) } @@ -402,7 +402,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 -- cgit v1.2.3 From 742269a73494300c149ca916328f3762cae616cc Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Fri, 30 Jul 2021 01:32:07 +0300 Subject: tooltip: move repeated strings to constants (#34619) --- js/src/tooltip.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index 0adde623f..f932a9ff9 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -108,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' @@ -202,7 +205,7 @@ 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() @@ -545,7 +548,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 = { -- cgit v1.2.3 From a6a2d1e2df4f97486d1715a709f40f85193c4ef6 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Tue, 3 Aug 2021 11:59:33 +0300 Subject: Regression on tooltip template creation process. (#34628) * Regression on tooltip template creation process. * check if template content does not exist, or given argument is empty * call `setContent()` once. --- js/src/tooltip.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index f932a9ff9..2632e46e0 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -243,8 +243,6 @@ class Tooltip extends BaseComponent { tip.setAttribute('id', tipId) this._element.setAttribute('aria-describedby', tipId) - this.setContent() - if (this._config.animation) { tip.classList.add(CLASS_NAME_FADE) } @@ -371,20 +369,21 @@ class Tooltip extends BaseComponent { element.innerHTML = this._config.template 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() + setContent(tip) { this._sanitizeAndSetContent(tip, this.getTitle(), SELECTOR_TOOLTIP_INNER) } _sanitizeAndSetContent(template, content, selector) { const templateElement = SelectorEngine.findOne(selector, template) - if (!content) { + + if (!content && templateElement) { templateElement.remove() return } -- cgit v1.2.3 From f20fece3a8cdd0e76a42c2737524b7652bf54d26 Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Wed, 4 Aug 2021 18:41:51 +0300 Subject: Prepare v5.1.0. (#34674) --- js/src/tooltip.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/tooltip.js') diff --git a/js/src/tooltip.js b/js/src/tooltip.js index 2632e46e0..288146472 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v5.0.2): tooltip.js + * Bootstrap (v5.1.0): tooltip.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ -- cgit v1.2.3