]> git.ipfire.org Git - thirdparty/bootstrap.git/commitdiff
fix: add trick to support tooltip selector usage on dynamic created tooltips that...
authorGeoSot <geo.sotis@gmail.com>
Wed, 14 Sep 2022 13:24:37 +0000 (16:24 +0300)
committerGitHub <noreply@github.com>
Wed, 14 Sep 2022 13:24:37 +0000 (16:24 +0300)
js/src/tooltip.js
js/tests/visual/tooltip.html

index e30701efcc166b1f7b3da2e2c41a9d906b62b357..86c6056d82145820471682cd2f12bfd423f05600 100644 (file)
@@ -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)`
index 779ac1aaf57c16bb4cec816570c99cdd1651df54..9a65640b44ff5edc36e2e366bbca0a147b6c46be 100644 (file)
         <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>