},
{
"path": "./dist/js/bootstrap.bundle.js",
- "maxSize": "82.5 kB"
+ "maxSize": "82.75 kB"
},
{
"path": "./dist/js/bootstrap.bundle.min.js",
},
{
"path": "./dist/js/bootstrap.js",
- "maxSize": "53.75 kB"
+ "maxSize": "54.0 kB"
},
{
"path": "./dist/js/bootstrap.min.js",
}, this._element, this._isAnimated())
}
+ dispose() {
+ // If disposed while still open, close the native <dialog> and restore body
+ // scroll. Otherwise `dialog-open` (overflow: hidden) would stay stuck on the
+ // body — e.g. when an SPA tears the component down mid-navigation.
+ if (this._element.open) {
+ this._closeAndCleanup()
+ }
+
+ super.dispose()
+ }
+
// Protected — hooks for subclasses to override
_getShowOptions() {
EventHandler.one(target, EVENT_HIDDEN, () => {
if (isVisible(this)) {
- this.focus()
+ this.focus({ preventScroll: true })
}
})
})
EventHandler.one(target, EVENT_HIDDEN, () => {
if (isVisible(this)) {
- this.focus()
+ this.focus({ preventScroll: true })
}
})
expect(Dialog.getInstance(dialogEl)).toBeNull()
expect(spyOff).toHaveBeenCalled()
})
+
+ it('should close the dialog and restore body scroll when disposed while open', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = '<dialog class="dialog" id="exampleDialog"></dialog>'
+
+ const dialogEl = fixtureEl.querySelector('.dialog')
+ const dialog = new Dialog(dialogEl)
+
+ dialogEl.addEventListener('shown.bs.dialog', () => {
+ expect(dialogEl.open).toBeTrue()
+ expect(document.body.classList.contains('dialog-open')).toBeTrue()
+
+ dialog.dispose()
+
+ expect(dialogEl.open).toBeFalse()
+ expect(document.body.classList.contains('dialog-open')).toBeFalse()
+ resolve()
+ })
+
+ dialog.show()
+ })
+ })
})
describe('data-api', () => {
const hideListener = () => {
setTimeout(() => {
- expect(spy).toHaveBeenCalled()
+ expect(spy).toHaveBeenCalledWith({ preventScroll: true })
resolve()
}, 20)
}
expect(Drawer.getInstance(drawerEl)).toBeNull()
expect(spyOff).toHaveBeenCalled()
})
+
+ it('should close the drawer and restore body scroll when disposed while open', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = '<dialog class="drawer"></dialog>'
+
+ const drawerEl = fixtureEl.querySelector('dialog')
+ const drawer = new Drawer(drawerEl)
+
+ drawerEl.addEventListener('shown.bs.drawer', () => {
+ expect(drawerEl.open).toBeTrue()
+ expect(document.body.classList.contains('dialog-open')).toBeTrue()
+
+ drawer.dispose()
+
+ expect(drawerEl.open).toBeFalse()
+ expect(document.body.classList.contains('dialog-open')).toBeFalse()
+ resolve()
+ })
+
+ drawer.show()
+ })
+ })
})
describe('data-api', () => {
})
drawerEl.addEventListener('hidden.bs.drawer', () => {
setTimeout(() => {
- expect(spy).toHaveBeenCalled()
+ expect(spy).toHaveBeenCalledWith({ preventScroll: true })
resolve()
}, 5)
})