From 6885d65578b4938f3a8fdf1de65946c79415b94d Mon Sep 17 00:00:00 2001 From: Johann-S Date: Sun, 18 Aug 2019 22:05:20 +0200 Subject: [PATCH] dropdown - destroy old popper.js references --- js/src/dropdown/dropdown.js | 12 +++++----- js/src/dropdown/dropdown.spec.js | 38 ++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/js/src/dropdown/dropdown.js b/js/src/dropdown/dropdown.js index fbf782a0e1..fc51f443cf 100644 --- a/js/src/dropdown/dropdown.js +++ b/js/src/dropdown/dropdown.js @@ -155,10 +155,6 @@ class Dropdown { // Disable totally Popper.js for Dropdown in Navbar if (!this._inNavbar) { - /** - * Check for Popper dependency - * Popper - https://popper.js.org - */ if (typeof Popper === 'undefined') { throw new TypeError('Bootstrap\'s dropdowns require Popper.js (https://popper.js.org)') } @@ -251,7 +247,7 @@ class Dropdown { EventHandler.off(this._element, EVENT_KEY) this._element = null this._menu = null - if (this._popper !== null) { + if (this._popper) { this._popper.destroy() this._popper = null } @@ -259,7 +255,7 @@ class Dropdown { update() { this._inNavbar = this._detectNavbar() - if (this._popper !== null) { + if (this._popper) { this._popper.scheduleUpdate() } } @@ -440,6 +436,10 @@ class Dropdown { toggles[i].setAttribute('aria-expanded', 'false') + if (context._popper) { + context._popper.destroy() + } + dropdownMenu.classList.remove(ClassName.SHOW) parent.classList.remove(ClassName.SHOW) EventHandler.trigger(parent, Event.HIDDEN, relatedTarget) diff --git a/js/src/dropdown/dropdown.spec.js b/js/src/dropdown/dropdown.spec.js index 963b8d9161..b025ed4232 100644 --- a/js/src/dropdown/dropdown.spec.js +++ b/js/src/dropdown/dropdown.spec.js @@ -147,6 +147,44 @@ describe('Dropdown', () => { dropdown.toggle() }) + it('should destroy old popper references on toggle', done => { + fixtureEl.innerHTML = [ + '', + '' + ].join('') + + const btnDropdown1 = fixtureEl.querySelector('.firstBtn') + const btnDropdown2 = fixtureEl.querySelector('.secondBtn') + const firstDropdownEl = fixtureEl.querySelector('.first') + const secondDropdownEl = fixtureEl.querySelector('.second') + const dropdown1 = new Dropdown(btnDropdown1) + const dropdown2 = new Dropdown(btnDropdown2) + + firstDropdownEl.addEventListener('shown.bs.dropdown', () => { + expect(firstDropdownEl.classList.contains('show')).toEqual(true) + spyOn(dropdown1._popper, 'destroy') + dropdown2.toggle() + done() + }) + + secondDropdownEl.addEventListener('shown.bs.dropdown', () => { + expect(dropdown1._popper.destroy).toHaveBeenCalled() + done() + }) + + dropdown1.toggle() + }) + it('should toggle a dropdown and add/remove event listener on mobile', done => { fixtureEl.innerHTML = [ '