diff --git a/js/src/toast.js b/js/src/toast.js index 623e8977147d..cca6d553b07e 100644 --- a/js/src/toast.js +++ b/js/src/toast.js @@ -91,6 +91,8 @@ class Toast { return } + this._clearTimeout() + if (this._config.animation) { this._element.classList.add(CLASS_NAME_FADE) } @@ -149,8 +151,7 @@ class Toast { } dispose() { - clearTimeout(this._timeout) - this._timeout = null + this._clearTimeout() if (this._element.classList.contains(CLASS_NAME_SHOW)) { this._element.classList.remove(CLASS_NAME_SHOW) @@ -186,6 +187,11 @@ class Toast { ) } + _clearTimeout() { + clearTimeout(this._timeout) + this._timeout = null + } + // Static static jQueryInterface(config) { diff --git a/js/tests/unit/toast.spec.js b/js/tests/unit/toast.spec.js index ee623c8ccc5d..031c841afa08 100644 --- a/js/tests/unit/toast.spec.js +++ b/js/tests/unit/toast.spec.js @@ -170,6 +170,33 @@ describe('Toast', () => { toast.show() }) + + it('should clear timeout if toast is shown again before it is hidden', done => { + fixtureEl.innerHTML = [ + '
', + '
', + ' a simple toast', + '
', + '
' + ].join('') + + const toastEl = fixtureEl.querySelector('.toast') + const toast = new Toast(toastEl) + + setTimeout(() => { + toast._config.autohide = false + toastEl.addEventListener('shown.bs.toast', () => { + expect(toast._clearTimeout).toHaveBeenCalled() + expect(toast._timeout).toBeNull() + done() + }) + toast.show() + }, toast._config.delay / 2) + + spyOn(toast, '_clearTimeout').and.callThrough() + + toast.show() + }) }) describe('hide', () => {