Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/twbs/bootstrap.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/js
diff options
context:
space:
mode:
authorGeoSot <geo.sotis@gmail.com>2022-09-14 16:24:37 +0300
committerGitHub <noreply@github.com>2022-09-14 16:24:37 +0300
commit3bd57564140ef3953582a80e8f1084d81bdb5977 (patch)
tree1c3b3af0e793bffce5226cf6a2fe20f885e807cc /js
parent4600a2540463b9ea5a3c505de92d1c0252c01fd5 (diff)
fix: add trick to support tooltip selector usage on dynamic created tooltips that utilize `title` attribute (#36914)
Diffstat (limited to 'js')
-rw-r--r--js/src/tooltip.js49
-rw-r--r--js/tests/visual/tooltip.html54
2 files changed, 58 insertions, 45 deletions
diff --git a/js/src/tooltip.js b/js/src/tooltip.js
index e30701efcc..86c6056d82 100644
--- a/js/src/tooltip.js
+++ b/js/src/tooltip.js
@@ -121,6 +121,10 @@ class Tooltip extends BaseComponent {
this.tip = null
this._setListeners()
+
+ if (!this._config.selector) {
+ this._fixTitle()
+ }
}
// Getters
@@ -149,25 +153,12 @@ class Tooltip extends BaseComponent {
this._isEnabled = !this._isEnabled
}
- toggle(event) {
+ toggle() {
if (!this._isEnabled) {
return
}
- if (event) {
- const context = this._initializeOnDelegatedTarget(event)
-
- context._activeTrigger.click = !context._activeTrigger.click
-
- if (context._isWithActiveTrigger()) {
- context._enter()
- } else {
- context._leave()
- }
-
- return
- }
-
+ this._activeTrigger.click = !this._activeTrigger.click
if (this._isShown()) {
this._leave()
return
@@ -185,8 +176,8 @@ class Tooltip extends BaseComponent {
this.tip.remove()
}
- if (this._config.originalTitle) {
- this._element.setAttribute('title', this._config.originalTitle)
+ if (this._element.getAttribute('data-bs-original-title')) {
+ this._element.setAttribute('title', this._element.getAttribute('data-bs-original-title'))
}
this._disposePopper()
@@ -375,7 +366,7 @@ class Tooltip extends BaseComponent {
}
_getTitle() {
- return this._resolvePossibleFunction(this._config.title) || this._config.originalTitle
+ return this._resolvePossibleFunction(this._config.title) || this._element.getAttribute('data-bs-original-title')
}
// Private
@@ -469,7 +460,10 @@ class Tooltip extends BaseComponent {
for (const trigger of triggers) {
if (trigger === 'click') {
- EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK), this._config.selector, event => this.toggle(event))
+ EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK), this._config.selector, event => {
+ const context = this._initializeOnDelegatedTarget(event)
+ context.toggle()
+ })
} else if (trigger !== TRIGGER_MANUAL) {
const eventIn = trigger === TRIGGER_HOVER ?
this.constructor.eventName(EVENT_MOUSEENTER) :
@@ -500,20 +494,10 @@ class Tooltip extends BaseComponent {
}
EventHandler.on(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler)
-
- if (this._config.selector) {
- this._config = {
- ...this._config,
- trigger: 'manual',
- selector: ''
- }
- } else {
- this._fixTitle()
- }
}
_fixTitle() {
- const title = this._config.originalTitle
+ const title = this._element.getAttribute('title')
if (!title) {
return
@@ -523,6 +507,7 @@ class Tooltip extends BaseComponent {
this._element.setAttribute('aria-label', title)
}
+ this._element.setAttribute('data-bs-original-title', title) // DO NOT USE IT. Is only for backwards compatibility
this._element.removeAttribute('title')
}
@@ -593,7 +578,6 @@ class Tooltip extends BaseComponent {
}
}
- config.originalTitle = this._element.getAttribute('title') || ''
if (typeof config.title === 'number') {
config.title = config.title.toString()
}
@@ -614,6 +598,9 @@ class Tooltip extends BaseComponent {
}
}
+ config.selector = false
+ config.trigger = 'manual'
+
// 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)`
diff --git a/js/tests/visual/tooltip.html b/js/tests/visual/tooltip.html
index 779ac1aaf5..9a65640b44 100644
--- a/js/tests/visual/tooltip.html
+++ b/js/tests/visual/tooltip.html
@@ -66,42 +66,68 @@
<div id="shadow" class="pt-5"></div>
</div>
<div id="customContainer"></div>
+
+ <div class="row mt-4 border-top">
+ <hr>
+ <div class="h4">Test Selector triggered tooltips</div>
+ <div id="wrapperTriggeredBySelector">
+ <div class="py-2 selectorButtonsBlock">
+ <button type="button" class="btn btn-secondary bs-dynamic-tooltip" title="random title">Using title</button>
+ <button type="button" class="btn btn-secondary bs-dynamic-tooltip" data-bs-title="random title">Using bs-title</button>
+ </div>
+
+ </div>
+ <div class="mt-3">
+ <button type="button" class="btn btn-primary" onclick="duplicateButtons()">Duplicate above two buttons</button>
+ </div>
+ </div>
</div>
<script src="../../../dist/js/bootstrap.bundle.js"></script>
<script>
if (typeof document.body.attachShadow === 'function') {
- var shadowRoot = document.getElementById('shadow').attachShadow({ mode: 'open' })
+ const shadowRoot = document.getElementById('shadow').attachShadow({ mode: 'open' })
shadowRoot.innerHTML =
- '<button type="button" class="btn btn-secondary" data-bs-toggle="tooltip" data-bs-placement="top" title="Tooltip on top in a shadow dom">' +
+ '<button id="firstShadowTooltip" type="button" class="btn btn-secondary" data-bs-toggle="tooltip" data-bs-placement="top" title="Tooltip on top in a shadow dom">' +
' Tooltip on top in a shadow dom' +
'</button>' +
- '<button id="secondTooltip" type="button" class="btn btn-secondary" data-bs-toggle="tooltip" data-bs-placement="top" title="Tooltip on top in a shadow dom with container option">' +
+ '<button id="secondShadowTooltip" type="button" class="btn btn-secondary" data-bs-toggle="tooltip" data-bs-placement="top" title="Tooltip on top in a shadow dom with container option">' +
' Tooltip on top in a shadow dom' +
'</button>'
- var firstChildTooltip = new bootstrap.Tooltip(shadowRoot.firstChild)
- var secondChildTooltip = new bootstrap.Tooltip(shadowRoot.getElementById('secondTooltip'), {
+ new bootstrap.Tooltip(shadowRoot.firstChild)
+ new bootstrap.Tooltip(shadowRoot.getElementById('secondShadowTooltip'), {
container: shadowRoot
})
}
- var tooltipElements = document.querySelectorAll('[data-bs-toggle="tooltip"]')
- for (const tooltipEl of tooltipElements) {
- new bootstrap.Tooltip(tooltipEl)
- }
- var tooltipElement = document.getElementById('tooltipElement')
- var tooltipElementInstance = new bootstrap.Tooltip(tooltipElement, {
- container: document.getElementById('customContainer')
+ new bootstrap.Tooltip('#tooltipElement', {
+ container: '#customContainer'
})
- var target = document.getElementById('target')
- var targetTooltip = new bootstrap.Tooltip(target, {
+ const targetTooltip = new bootstrap.Tooltip('#target', {
placement : 'top',
trigger : 'manual'
})
targetTooltip.show()
+
+ document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach(tooltipEl=> new bootstrap.Tooltip(tooltipEl))
</script>
+
+ <script>
+ new bootstrap.Tooltip('#wrapperTriggeredBySelector', {
+ animation: false,
+ selector: '.bs-dynamic-tooltip'
+ })
+
+ function duplicateButtons() {
+ const buttonsBlock = document.querySelector('.selectorButtonsBlock')// get first
+ const buttonsBlockClone = buttonsBlock.cloneNode(true)
+ buttonsBlockClone.innerHTML+= new Date().toLocaleString()
+ document.querySelector('#wrapperTriggeredBySelector').append(buttonsBlockClone)
+ }
+ </script>
+
</body>
</html>