diff --git a/js/src/tooltip.js b/js/src/tooltip.js index d0b43dd046..b09ab0d0ca 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -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` } } ] diff --git a/js/tests/unit/popover.spec.js b/js/tests/unit/popover.spec.js index ba23ec0241..606d7370c7 100644 --- a/js/tests/unit/popover.spec.js +++ b/js/tests/unit/popover.spec.js @@ -155,6 +155,22 @@ describe('Popover', () => { popover.show() }) + it('"setContent" should keep the initial template', () => { + fixtureEl.innerHTML = 'BS twitter' + + 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 = 'BS twitter' diff --git a/js/tests/unit/tooltip.spec.js b/js/tests/unit/tooltip.spec.js index 19eeca2f52..d261986c37 100644 --- a/js/tests/unit/tooltip.spec.js +++ b/js/tests/unit/tooltip.spec.js @@ -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 = '' + + 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', () => {