Skip to content

Commit a622358

Browse files
rinicktmorehouse
authored andcommitted
perf(modal): optimize model.resetScrollbar, resolves #1831 (#1837)
* modal resetScrollbar should revert the change only when the change was done in the first place, resolves #1831 * add test to show modal * add test to hide modal * fix modal hide test * add test for fixed and sticky content
1 parent 845141d commit a622358

File tree

3 files changed

+52
-20
lines changed

3 files changed

+52
-20
lines changed

src/components/modal/fixtures/modal.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,12 @@
2727

2828
</b-modal>
2929

30+
<b-btn ref="modalButton2" v-b-modal.modal2>Launch demo modal</b-btn>
31+
32+
<!-- Modal Component -->
33+
<b-modal ref="modal2"
34+
id="modal2">
35+
<b-navbar sticky>
36+
<b-navbar fixed="top">
37+
</b-modal>
3038
</div>

src/components/modal/modal.js

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -762,13 +762,16 @@ export default {
762762
const computedStyle = window.getComputedStyle
763763
const body = document.body
764764
const scrollbarWidth = this.scrollbarWidth
765+
this._marginChangedForScroll = []
766+
this._paddingChangedForScroll = []
765767
// Adjust fixed content padding
766768
selectAll(Selector.FIXED_CONTENT).forEach(el => {
767769
const actualPadding = el.style.paddingRight
768770
const calculatedPadding = computedStyle(el).paddingRight || 0
769771
setAttr(el, 'data-padding-right', actualPadding)
770772
el.style.paddingRight = `${parseFloat(calculatedPadding) +
771773
scrollbarWidth}px`
774+
this._paddingChangedForScroll.push(el)
772775
})
773776
// Adjust sticky content margin
774777
selectAll(Selector.STICKY_CONTENT).forEach(el => {
@@ -777,6 +780,7 @@ export default {
777780
setAttr(el, 'data-margin-right', actualMargin)
778781
el.style.marginRight = `${parseFloat(calculatedMargin) -
779782
scrollbarWidth}px`
783+
this._marginChangedForScroll.push(el)
780784
})
781785
// Adjust navbar-toggler margin
782786
selectAll(Selector.NAVBAR_TOGGLER).forEach(el => {
@@ -785,6 +789,7 @@ export default {
785789
setAttr(el, 'data-margin-right', actualMargin)
786790
el.style.marginRight = `${parseFloat(calculatedMargin) +
787791
scrollbarWidth}px`
792+
this._marginChangedForScroll.push(el)
788793
})
789794
// Adjust body padding
790795
const actualPadding = body.style.paddingRight
@@ -795,27 +800,29 @@ export default {
795800
}
796801
},
797802
resetScrollbar () {
798-
// Restore fixed content padding
799-
selectAll(Selector.FIXED_CONTENT).forEach(el => {
800-
if (hasAttr(el, 'data-padding-right')) {
801-
el.style.paddingRight = getAttr(el, 'data-padding-right') || ''
802-
removeAttr(el, 'data-padding-right')
803-
}
804-
})
805-
// Restore sticky content and navbar-toggler margin
806-
selectAll(
807-
`${Selector.STICKY_CONTENT}, ${Selector.NAVBAR_TOGGLER}`
808-
).forEach(el => {
809-
if (hasAttr(el, 'data-margin-right')) {
810-
el.style.marginRight = getAttr(el, 'data-margin-right') || ''
811-
removeAttr(el, 'data-margin-right')
803+
if (this._marginChangedForScroll && this._paddingChangedForScroll) {
804+
// Restore fixed content padding
805+
this._paddingChangedForScroll.forEach(el => {
806+
if (hasAttr(el, 'data-padding-right')) {
807+
el.style.paddingRight = getAttr(el, 'data-padding-right') || ''
808+
removeAttr(el, 'data-padding-right')
809+
}
810+
})
811+
// Restore sticky content and navbar-toggler margin
812+
this._marginChangedForScroll.forEach(el => {
813+
if (hasAttr(el, 'data-margin-right')) {
814+
el.style.marginRight = getAttr(el, 'data-margin-right') || ''
815+
removeAttr(el, 'data-margin-right')
816+
}
817+
})
818+
this._paddingChangedForScroll = null
819+
this._marginChangedForScroll = null
820+
// Restore body padding
821+
const body = document.body
822+
if (hasAttr(body, 'data-padding-right')) {
823+
body.style.paddingRight = getAttr(body, 'data-padding-right') || ''
824+
removeAttr(body, 'data-padding-right')
812825
}
813-
})
814-
// Restore body padding
815-
const body = document.body
816-
if (hasAttr(body, 'data-padding-right')) {
817-
body.style.paddingRight = getAttr(body, 'data-padding-right') || ''
818-
removeAttr(body, 'data-padding-right')
819826
}
820827
}
821828
},

src/components/modal/modal.spec.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,21 @@ describe('modal', async () => {
1717
await nextTick()
1818
expect(app.$refs.button).not.toHaveProperty('__BV_boundEventListeners__.click')
1919
})
20+
21+
it('Should show hide modal', async () => {
22+
const { app: { $refs } } = window
23+
const { modalButton2, modal2 } = $refs
24+
25+
// show the modal
26+
modalButton2.click()
27+
await nextTick()
28+
expect(Array.isArray(modal2._marginChangedForScroll)).toBe(true)
29+
30+
// hide the modal
31+
modal2.hide()
32+
await nextTick()
33+
// manually run resetScrollbar because JSDOM doesn't support it
34+
modal2.resetScrollbar()
35+
expect(modal2._marginChangedForScroll).toBe(null)
36+
})
2037
})

0 commit comments

Comments
 (0)