diff --git a/js/src/tooltip.js b/js/src/tooltip.js index e9f9bfff1b..857f72c8ad 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -283,6 +283,10 @@ class Tooltip extends BaseComponent { EventHandler.trigger(this._element, this.constructor.Event.INSERTED) + if (this._popper) { + this._popper.destroy() + } + this._popper = Popper.createPopper(this._element, tip, this._getPopperConfig(attachment)) tip.classList.add(CLASS_NAME_SHOW) @@ -650,7 +654,7 @@ class Tooltip extends BaseComponent { if (event) { context._activeTrigger[ event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER - ] = false + ] = context._element.contains(event.relatedTarget) } if (context._isWithActiveTrigger()) { diff --git a/js/tests/unit/tooltip.spec.js b/js/tests/unit/tooltip.spec.js index 41f73d6d8a..1cb301c151 100644 --- a/js/tests/unit/tooltip.spec.js +++ b/js/tests/unit/tooltip.spec.js @@ -708,8 +708,9 @@ describe('Tooltip', () => { tooltipEl.dispatchEvent(createEvent('mouseover')) }) - it('should not hide tooltip if leave event occurs and enter event occurs during hide transition', done => { - fixtureEl.innerHTML = '' + it('should properly maintain tooltip state if leave event occurs and enter event occurs during hide transition', done => { + // Style this tooltip to give it plenty of room for popper to do what it wants + fixtureEl.innerHTML = 'Trigger' const tooltipEl = fixtureEl.querySelector('a') const tooltip = new Tooltip(tooltipEl) @@ -721,6 +722,7 @@ describe('Tooltip', () => { setTimeout(() => { expect(tooltip._popper).not.toBeNull() + expect(tooltip.getTipElement().getAttribute('data-popper-placement')).toBe('top') tooltipEl.dispatchEvent(createEvent('mouseout')) setTimeout(() => { @@ -730,6 +732,7 @@ describe('Tooltip', () => { setTimeout(() => { expect(tooltip._popper).not.toBeNull() + expect(tooltip.getTipElement().getAttribute('data-popper-placement')).toBe('top') done() }, 200) }, 0)