]> git.ipfire.org Git - thirdparty/bootstrap.git/commitdiff
Fix popover arrow & tooltip template after the `setContent` addition (#35441)
authorGeoSot <geo.sotis@gmail.com>
Wed, 1 Dec 2021 13:10:10 +0000 (15:10 +0200)
committerGitHub <noreply@github.com>
Wed, 1 Dec 2021 13:10:10 +0000 (15:10 +0200)
js/src/tooltip.js
js/tests/unit/popover.spec.js
js/tests/unit/tooltip.spec.js

index d0b43dd04680707c7906d633eebecd3f75d778ac..b09ab0d0cae495459c0e13a4b64357ac9a78d184 100644 (file)
@@ -38,7 +38,6 @@ const CLASS_NAME_SHOW = 'show'
 const HOVER_STATE_SHOW = 'show'
 const HOVER_STATE_OUT = 'out'
 
-const SELECTOR_TOOLTIP_ARROW = '.tooltip-arrow'
 const SELECTOR_TOOLTIP_INNER = '.tooltip-inner'
 const SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`
 
@@ -333,15 +332,23 @@ class Tooltip extends BaseComponent {
   }
 
   getTipElement() {
-    if (this.tip) {
-      return this.tip
+    if (!this.tip) {
+      this.tip = this._createTipElement(this._getContentForTemplate())
     }
 
-    const templateFactory = this._getTemplateFactory(this._getContentForTemplate())
+    return this.tip
+  }
+
+  _createTipElement(content) {
+    const tip = this._getTemplateFactory(content).toHtml()
+
+    // todo: remove this check on v6
+    if (!tip) {
+      return null
+    }
 
-    const tip = templateFactory.toHtml()
     tip.classList.remove(CLASS_NAME_FADE, CLASS_NAME_SHOW)
-    // todo on v6 the following can be done on css only
+    // todo: on v6 the following can be achieved with CSS only
     tip.classList.add(`bs-${this.constructor.NAME}-auto`)
 
     const tipId = getUID(this.constructor.NAME).toString()
@@ -352,8 +359,7 @@ class Tooltip extends BaseComponent {
       tip.classList.add(CLASS_NAME_FADE)
     }
 
-    this.tip = tip
-    return this.tip
+    return tip
   }
 
   setContent(content) {
@@ -361,11 +367,11 @@ class Tooltip extends BaseComponent {
     if (this.tip) {
       isShown = this.tip.classList.contains(CLASS_NAME_SHOW)
       this.tip.remove()
+      this.tip = null
     }
 
     this._disposePopper()
-
-    this.tip = this._getTemplateFactory(content).toHtml()
+    this.tip = this._createTipElement(content)
 
     if (isShown) {
       this.show()
@@ -446,7 +452,7 @@ class Tooltip extends BaseComponent {
         {
           name: 'arrow',
           options: {
-            element: SELECTOR_TOOLTIP_ARROW
+            element: `.${this.constructor.NAME}-arrow`
           }
         }
       ]
index ba23ec02416d1b6132f6b2b4516f80aca5320f62..606d7370c7c4af774a8722952ad746c0cf86377b 100644 (file)
@@ -155,6 +155,22 @@ describe('Popover', () => {
       popover.show()
     })
 
+    it('"setContent" should keep the initial template', () => {
+      fixtureEl.innerHTML = '<a href="#" title="Popover" data-bs-content="https://twitter.com/getbootstrap" data-bs-custom-class="custom-class">BS twitter</a>'
+
+      const popoverEl = fixtureEl.querySelector('a')
+      const popover = new Popover(popoverEl)
+
+      popover.setContent({ '.tooltip-inner': 'foo' })
+      const tip = popover.getTipElement()
+
+      expect(tip).toHaveClass('popover')
+      expect(tip).toHaveClass('bs-popover-auto')
+      expect(tip.querySelector('.popover-arrow')).not.toBeNull()
+      expect(tip.querySelector('.popover-header')).not.toBeNull()
+      expect(tip.querySelector('.popover-body')).not.toBeNull()
+    })
+
     it('should call setContent once', done => {
       fixtureEl.innerHTML = '<a href="#">BS twitter</a>'
 
index 19eeca2f52131aed381dcbd5cf815bd092677c33..d261986c374b87f9c8230968d5704884d92abc01 100644 (file)
@@ -1081,6 +1081,21 @@ describe('Tooltip', () => {
       expect(tip()).not.toHaveClass('show')
       expect(tip().querySelector('.tooltip-inner').textContent).toEqual('foo')
     })
+
+    it('"setContent" should keep the initial template', () => {
+      fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
+
+      const tooltipEl = fixtureEl.querySelector('a')
+      const tooltip = new Tooltip(tooltipEl)
+
+      tooltip.setContent({ '.tooltip-inner': 'foo' })
+      const tip = tooltip.getTipElement()
+
+      expect(tip).toHaveClass('tooltip')
+      expect(tip).toHaveClass('bs-tooltip-auto')
+      expect(tip.querySelector('.tooltip-arrow')).not.toBeNull()
+      expect(tip.querySelector('.tooltip-inner')).not.toBeNull()
+    })
   })
 
   describe('setContent', () => {