Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix tooltip selector usage #36914

Merged
merged 1 commit into from Sep 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
49 changes: 18 additions & 31 deletions js/src/tooltip.js
Expand Up @@ -121,6 +121,10 @@ class Tooltip extends BaseComponent {
this.tip = null

this._setListeners()

if (!this._config.selector) {
this._fixTitle()
}
}

// Getters
Expand Down Expand Up @@ -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
Expand All @@ -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()
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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) :
Expand Down Expand Up @@ -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
Expand All @@ -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')
}

Expand Down Expand Up @@ -593,7 +578,6 @@ class Tooltip extends BaseComponent {
}
}

config.originalTitle = this._element.getAttribute('title') || ''
if (typeof config.title === 'number') {
config.title = config.title.toString()
}
Expand All @@ -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)`
Expand Down
54 changes: 40 additions & 14 deletions js/tests/visual/tooltip.html
Expand Up @@ -66,42 +66,68 @@ <h1>Tooltip <small>Bootstrap Visual Test</small></h1>
<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>