0
0
mirror of https://github.com/twbs/bootstrap.git synced 2025-01-18 10:52:19 +01:00

Refactor scrollbar.js to be used as a Class (#33947)

This commit is contained in:
GeoSot 2021-06-06 09:26:36 +03:00 committed by GitHub
parent 08139c2280
commit cb47b8c964
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 141 additions and 118 deletions

View File

@ -16,7 +16,7 @@ import {
import EventHandler from './dom/event-handler' import EventHandler from './dom/event-handler'
import Manipulator from './dom/manipulator' import Manipulator from './dom/manipulator'
import SelectorEngine from './dom/selector-engine' import SelectorEngine from './dom/selector-engine'
import { getWidth as getScrollBarWidth, hide as scrollBarHide, reset as scrollBarReset } from './util/scrollbar' import ScrollBarHelper from './util/scrollbar'
import BaseComponent from './base-component' import BaseComponent from './base-component'
import Backdrop from './util/backdrop' import Backdrop from './util/backdrop'
@ -83,6 +83,7 @@ class Modal extends BaseComponent {
this._isShown = false this._isShown = false
this._ignoreBackdropClick = false this._ignoreBackdropClick = false
this._isTransitioning = false this._isTransitioning = false
this._scrollBar = new ScrollBarHelper()
} }
// Getters // Getters
@ -120,7 +121,7 @@ class Modal extends BaseComponent {
this._isTransitioning = true this._isTransitioning = true
} }
scrollBarHide() this._scrollBar.hide()
document.body.classList.add(CLASS_NAME_OPEN) document.body.classList.add(CLASS_NAME_OPEN)
@ -301,7 +302,7 @@ class Modal extends BaseComponent {
this._backdrop.hide(() => { this._backdrop.hide(() => {
document.body.classList.remove(CLASS_NAME_OPEN) document.body.classList.remove(CLASS_NAME_OPEN)
this._resetAdjustments() this._resetAdjustments()
scrollBarReset() this._scrollBar.reset()
EventHandler.trigger(this._element, EVENT_HIDDEN) EventHandler.trigger(this._element, EVENT_HIDDEN)
}) })
} }
@ -368,7 +369,7 @@ class Modal extends BaseComponent {
_adjustDialog() { _adjustDialog() {
const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight
const scrollbarWidth = getScrollBarWidth() const scrollbarWidth = this._scrollBar.getWidth()
const isBodyOverflowing = scrollbarWidth > 0 const isBodyOverflowing = scrollbarWidth > 0
if ((!isBodyOverflowing && isModalOverflowing && !isRTL()) || (isBodyOverflowing && !isModalOverflowing && isRTL())) { if ((!isBodyOverflowing && isModalOverflowing && !isRTL()) || (isBodyOverflowing && !isModalOverflowing && isRTL())) {

View File

@ -12,7 +12,7 @@ import {
isVisible, isVisible,
typeCheckConfig typeCheckConfig
} from './util/index' } from './util/index'
import { hide as scrollBarHide, reset as scrollBarReset } from './util/scrollbar' import ScrollBarHelper from './util/scrollbar'
import EventHandler from './dom/event-handler' import EventHandler from './dom/event-handler'
import BaseComponent from './base-component' import BaseComponent from './base-component'
import SelectorEngine from './dom/selector-engine' import SelectorEngine from './dom/selector-engine'
@ -108,7 +108,7 @@ class Offcanvas extends BaseComponent {
this._backdrop.show() this._backdrop.show()
if (!this._config.scroll) { if (!this._config.scroll) {
scrollBarHide() new ScrollBarHelper().hide()
this._enforceFocusOnElement(this._element) this._enforceFocusOnElement(this._element)
} }
@ -148,7 +148,7 @@ class Offcanvas extends BaseComponent {
this._element.style.visibility = 'hidden' this._element.style.visibility = 'hidden'
if (!this._config.scroll) { if (!this._config.scroll) {
scrollBarReset() new ScrollBarHelper().reset()
} }
EventHandler.trigger(this._element, EVENT_HIDDEN) EventHandler.trigger(this._element, EVENT_HIDDEN)

View File

@ -7,78 +7,91 @@
import SelectorEngine from '../dom/selector-engine' import SelectorEngine from '../dom/selector-engine'
import Manipulator from '../dom/manipulator' import Manipulator from '../dom/manipulator'
import { isElement } from './index'
const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top' const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'
const SELECTOR_STICKY_CONTENT = '.sticky-top' const SELECTOR_STICKY_CONTENT = '.sticky-top'
const getWidth = () => { class ScrollBarHelper {
// https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes constructor() {
const documentWidth = document.documentElement.clientWidth this._element = document.body
return Math.abs(window.innerWidth - documentWidth)
}
const hide = (width = getWidth()) => {
_disableOverFlow()
// give padding to element to balances the hidden scrollbar width
_setElementAttributes('body', 'paddingRight', calculatedValue => calculatedValue + width)
// trick: We adjust positive paddingRight and negative marginRight to sticky-top elements, to keep shown fullwidth
_setElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight', calculatedValue => calculatedValue + width)
_setElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight', calculatedValue => calculatedValue - width)
}
const _disableOverFlow = () => {
const actualValue = document.body.style.overflow
if (actualValue) {
Manipulator.setDataAttribute(document.body, 'overflow', actualValue)
} }
document.body.style.overflow = 'hidden' getWidth() {
} // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes
const documentWidth = document.documentElement.clientWidth
return Math.abs(window.innerWidth - documentWidth)
}
const _setElementAttributes = (selector, styleProp, callback) => { hide() {
const scrollbarWidth = getWidth() const width = this.getWidth()
SelectorEngine.find(selector) this._disableOverFlow()
.forEach(element => { // give padding to element to balance the hidden scrollbar width
if (element !== document.body && window.innerWidth > element.clientWidth + scrollbarWidth) { this._setElementAttributes(this._element, 'paddingRight', calculatedValue => calculatedValue + width)
// trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth
this._setElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight', calculatedValue => calculatedValue + width)
this._setElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight', calculatedValue => calculatedValue - width)
}
_disableOverFlow() {
this._saveInitialAttribute(this._element, 'overflow')
this._element.style.overflow = 'hidden'
}
_setElementAttributes(selector, styleProp, callback) {
const scrollbarWidth = this.getWidth()
const manipulationCallBack = element => {
if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {
return return
} }
const actualValue = element.style[styleProp] this._saveInitialAttribute(element, styleProp)
if (actualValue) {
Manipulator.setDataAttribute(element, styleProp, actualValue)
}
const calculatedValue = window.getComputedStyle(element)[styleProp] const calculatedValue = window.getComputedStyle(element)[styleProp]
element.style[styleProp] = `${callback(Number.parseFloat(calculatedValue))}px` element.style[styleProp] = `${callback(Number.parseFloat(calculatedValue))}px`
})
}
const reset = () => {
_resetElementAttributes('body', 'overflow')
_resetElementAttributes('body', 'paddingRight')
_resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight')
_resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight')
}
const _resetElementAttributes = (selector, styleProp) => {
SelectorEngine.find(selector).forEach(element => {
const value = Manipulator.getDataAttribute(element, styleProp)
if (typeof value === 'undefined') {
element.style.removeProperty(styleProp)
} else {
Manipulator.removeDataAttribute(element, styleProp)
element.style[styleProp] = value
} }
})
this._applyManipulationCallback(selector, manipulationCallBack)
}
reset() {
this._resetElementAttributes(this._element, 'overflow')
this._resetElementAttributes(this._element, 'paddingRight')
this._resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight')
this._resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight')
}
_saveInitialAttribute(element, styleProp) {
const actualValue = element.style[styleProp]
if (actualValue) {
Manipulator.setDataAttribute(element, styleProp, actualValue)
}
}
_resetElementAttributes(selector, styleProp) {
const manipulationCallBack = element => {
const value = Manipulator.getDataAttribute(element, styleProp)
if (typeof value === 'undefined') {
element.style.removeProperty(styleProp)
} else {
Manipulator.removeDataAttribute(element, styleProp)
element.style[styleProp] = value
}
}
this._applyManipulationCallback(selector, manipulationCallBack)
}
_applyManipulationCallback(selector, callBack) {
if (isElement(selector)) {
callBack(selector)
} else {
SelectorEngine.find(selector, this._element).forEach(callBack)
}
}
isOverflowing() {
return this.getWidth() > 0
}
} }
const isBodyOverflowing = () => { export default ScrollBarHelper
return getWidth() > 0
}
export {
getWidth,
hide,
isBodyOverflowing,
reset
}

View File

@ -1,5 +1,6 @@
import Modal from '../../src/modal' import Modal from '../../src/modal'
import EventHandler from '../../src/dom/event-handler' import EventHandler from '../../src/dom/event-handler'
import ScrollBarHelper from '../../src/util/scrollbar'
/** Test helpers */ /** Test helpers */
import { clearBodyAndDocument, clearFixture, createEvent, getFixture, jQueryMock } from '../helpers/fixture' import { clearBodyAndDocument, clearFixture, createEvent, getFixture, jQueryMock } from '../helpers/fixture'
@ -58,25 +59,23 @@ describe('Modal', () => {
}) })
describe('toggle', () => { describe('toggle', () => {
it('should toggle a modal', done => { it('should call ScrollBarHelper to handle scrollBar on body', done => {
fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>' fixtureEl.innerHTML = [
'<div class="modal"><div class="modal-dialog"></div></div>'
].join('')
const initialOverFlow = document.body.style.overflow spyOn(ScrollBarHelper.prototype, 'hide').and.callThrough()
spyOn(ScrollBarHelper.prototype, 'reset').and.callThrough()
const modalEl = fixtureEl.querySelector('.modal') const modalEl = fixtureEl.querySelector('.modal')
const modal = new Modal(modalEl) const modal = new Modal(modalEl)
const originalPadding = '10px'
document.body.style.paddingRight = originalPadding
modalEl.addEventListener('shown.bs.modal', () => { modalEl.addEventListener('shown.bs.modal', () => {
expect(document.body.getAttribute('data-bs-padding-right')).toEqual(originalPadding, 'original body padding should be stored in data-bs-padding-right') expect(ScrollBarHelper.prototype.hide).toHaveBeenCalled()
expect(document.body.style.overflow).toEqual('hidden')
modal.toggle() modal.toggle()
}) })
modalEl.addEventListener('hidden.bs.modal', () => { modalEl.addEventListener('hidden.bs.modal', () => {
expect(document.body.getAttribute('data-bs-padding-right')).toBeNull() expect(ScrollBarHelper.prototype.reset).toHaveBeenCalled()
expect(document.body.style.overflow).toEqual(initialOverFlow)
done() done()
}) })

View File

@ -4,6 +4,7 @@ import EventHandler from '../../src/dom/event-handler'
/** Test helpers */ /** Test helpers */
import { clearBodyAndDocument, clearFixture, createEvent, getFixture, jQueryMock } from '../helpers/fixture' import { clearBodyAndDocument, clearFixture, createEvent, getFixture, jQueryMock } from '../helpers/fixture'
import { isVisible } from '../../src/util' import { isVisible } from '../../src/util'
import ScrollBarHelper from '../../src/util/scrollbar'
describe('Offcanvas', () => { describe('Offcanvas', () => {
let fixtureEl let fixtureEl
@ -159,36 +160,36 @@ describe('Offcanvas', () => {
it('if scroll is enabled, should allow body to scroll while offcanvas is open', done => { it('if scroll is enabled, should allow body to scroll while offcanvas is open', done => {
fixtureEl.innerHTML = '<div class="offcanvas"></div>' fixtureEl.innerHTML = '<div class="offcanvas"></div>'
spyOn(ScrollBarHelper.prototype, 'hide').and.callThrough()
spyOn(ScrollBarHelper.prototype, 'reset').and.callThrough()
const offCanvasEl = fixtureEl.querySelector('.offcanvas') const offCanvasEl = fixtureEl.querySelector('.offcanvas')
const offCanvas = new Offcanvas(offCanvasEl, { scroll: true }) const offCanvas = new Offcanvas(offCanvasEl, { scroll: true })
const initialOverFlow = document.body.style.overflow
offCanvasEl.addEventListener('shown.bs.offcanvas', () => { offCanvasEl.addEventListener('shown.bs.offcanvas', () => {
expect(document.body.style.overflow).toEqual(initialOverFlow) expect(ScrollBarHelper.prototype.hide).not.toHaveBeenCalled()
offCanvas.hide() offCanvas.hide()
}) })
offCanvasEl.addEventListener('hidden.bs.offcanvas', () => { offCanvasEl.addEventListener('hidden.bs.offcanvas', () => {
expect(document.body.style.overflow).toEqual(initialOverFlow) expect(ScrollBarHelper.prototype.reset).not.toHaveBeenCalled()
done() done()
}) })
offCanvas.show() offCanvas.show()
}) })
it('if scroll is disabled, should not allow body to scroll while offcanvas is open', done => { it('if scroll is disabled, should call ScrollBarHelper to handle scrollBar on body', done => {
fixtureEl.innerHTML = '<div class="offcanvas"></div>' fixtureEl.innerHTML = '<div class="offcanvas"></div>'
spyOn(ScrollBarHelper.prototype, 'hide').and.callThrough()
spyOn(ScrollBarHelper.prototype, 'reset').and.callThrough()
const offCanvasEl = fixtureEl.querySelector('.offcanvas') const offCanvasEl = fixtureEl.querySelector('.offcanvas')
const offCanvas = new Offcanvas(offCanvasEl, { scroll: false }) const offCanvas = new Offcanvas(offCanvasEl, { scroll: false })
const initialOverFlow = document.body.style.overflow
offCanvasEl.addEventListener('shown.bs.offcanvas', () => { offCanvasEl.addEventListener('shown.bs.offcanvas', () => {
expect(document.body.style.overflow).toEqual('hidden') expect(ScrollBarHelper.prototype.hide).toHaveBeenCalled()
offCanvas.hide() offCanvas.hide()
}) })
offCanvasEl.addEventListener('hidden.bs.offcanvas', () => { offCanvasEl.addEventListener('hidden.bs.offcanvas', () => {
expect(document.body.style.overflow).toEqual(initialOverFlow) expect(ScrollBarHelper.prototype.reset).toHaveBeenCalled()
done() done()
}) })
offCanvas.show() offCanvas.show()

View File

@ -1,6 +1,6 @@
import * as Scrollbar from '../../../src/util/scrollbar'
import { clearBodyAndDocument, clearFixture, getFixture } from '../../helpers/fixture' import { clearBodyAndDocument, clearFixture, getFixture } from '../../helpers/fixture'
import Manipulator from '../../../src/dom/manipulator' import Manipulator from '../../../src/dom/manipulator'
import ScrollBarHelper from '../../../src/util/scrollbar'
describe('ScrollBar', () => { describe('ScrollBar', () => {
let fixtureEl let fixtureEl
@ -55,7 +55,7 @@ describe('ScrollBar', () => {
fixtureEl.innerHTML = [ fixtureEl.innerHTML = [
'<div style="height: 110vh; width: 100%"></div>' '<div style="height: 110vh; width: 100%"></div>'
].join('') ].join('')
const result = Scrollbar.isBodyOverflowing() const result = new ScrollBarHelper().isOverflowing()
if (isScrollBarHidden()) { if (isScrollBarHidden()) {
expect(result).toEqual(false) expect(result).toEqual(false)
@ -70,7 +70,8 @@ describe('ScrollBar', () => {
fixtureEl.innerHTML = [ fixtureEl.innerHTML = [
'<div style="height: 110vh; width: 100%"></div>' '<div style="height: 110vh; width: 100%"></div>'
].join('') ].join('')
const result = Scrollbar.isBodyOverflowing() const scrollBar = new ScrollBarHelper()
const result = scrollBar.isOverflowing()
expect(result).toEqual(false) expect(result).toEqual(false)
}) })
@ -83,7 +84,7 @@ describe('ScrollBar', () => {
fixtureEl.innerHTML = [ fixtureEl.innerHTML = [
'<div style="height: 110vh; width: 100%"></div>' '<div style="height: 110vh; width: 100%"></div>'
].join('') ].join('')
const result = Scrollbar.getWidth() const result = new ScrollBarHelper().getWidth()
if (isScrollBarHidden()) { if (isScrollBarHidden()) {
expect(result).toBe(0) expect(result).toBe(0)
@ -99,7 +100,7 @@ describe('ScrollBar', () => {
'<div style="height: 110vh; width: 100%"></div>' '<div style="height: 110vh; width: 100%"></div>'
].join('') ].join('')
const result = Scrollbar.getWidth() const result = new ScrollBarHelper().getWidth()
expect(result).toEqual(0) expect(result).toEqual(0)
}) })
@ -119,10 +120,11 @@ describe('ScrollBar', () => {
const fixedEl2 = fixtureEl.querySelector('#fixed2') const fixedEl2 = fixtureEl.querySelector('#fixed2')
const originalPadding = getPaddingX(fixedEl) const originalPadding = getPaddingX(fixedEl)
const originalPadding2 = getPaddingX(fixedEl2) const originalPadding2 = getPaddingX(fixedEl2)
const expectedPadding = originalPadding + Scrollbar.getWidth() const scrollBar = new ScrollBarHelper()
const expectedPadding2 = originalPadding2 + Scrollbar.getWidth() const expectedPadding = originalPadding + scrollBar.getWidth()
const expectedPadding2 = originalPadding2 + scrollBar.getWidth()
Scrollbar.hide() scrollBar.hide()
let currentPadding = getPaddingX(fixedEl) let currentPadding = getPaddingX(fixedEl)
let currentPadding2 = getPaddingX(fixedEl2) let currentPadding2 = getPaddingX(fixedEl2)
@ -131,7 +133,7 @@ describe('ScrollBar', () => {
expect(currentPadding).toEqual(expectedPadding, 'fixed element padding should be adjusted while opening') expect(currentPadding).toEqual(expectedPadding, 'fixed element padding should be adjusted while opening')
expect(currentPadding2).toEqual(expectedPadding2, 'fixed element padding should be adjusted while opening') expect(currentPadding2).toEqual(expectedPadding2, 'fixed element padding should be adjusted while opening')
Scrollbar.reset() scrollBar.reset()
currentPadding = getPaddingX(fixedEl) currentPadding = getPaddingX(fixedEl)
currentPadding2 = getPaddingX(fixedEl2) currentPadding2 = getPaddingX(fixedEl2)
expect(getPaddingAttr(fixedEl)).toEqual(null, 'data-bs-padding-right should be cleared after closing') expect(getPaddingAttr(fixedEl)).toEqual(null, 'data-bs-padding-right should be cleared after closing')
@ -152,17 +154,17 @@ describe('ScrollBar', () => {
const stickyTopEl = fixtureEl.querySelector('.sticky-top') const stickyTopEl = fixtureEl.querySelector('.sticky-top')
const originalMargin = getMarginX(stickyTopEl) const originalMargin = getMarginX(stickyTopEl)
const originalPadding = getPaddingX(stickyTopEl) const originalPadding = getPaddingX(stickyTopEl)
const scrollBar = new ScrollBarHelper()
const expectedMargin = originalMargin - Scrollbar.getWidth() const expectedMargin = originalMargin - scrollBar.getWidth()
const expectedPadding = originalPadding + Scrollbar.getWidth() const expectedPadding = originalPadding + scrollBar.getWidth()
Scrollbar.hide() scrollBar.hide()
expect(getMarginAttr(stickyTopEl)).toEqual(`${originalMargin}px`, 'original sticky element margin should be stored in data-bs-margin-right') expect(getMarginAttr(stickyTopEl)).toEqual(`${originalMargin}px`, 'original sticky element margin should be stored in data-bs-margin-right')
expect(getMarginX(stickyTopEl)).toEqual(expectedMargin, 'sticky element margin should be adjusted while opening') expect(getMarginX(stickyTopEl)).toEqual(expectedMargin, 'sticky element margin should be adjusted while opening')
expect(getPaddingAttr(stickyTopEl)).toEqual(`${originalPadding}px`, 'original sticky element margin should be stored in data-bs-margin-right') expect(getPaddingAttr(stickyTopEl)).toEqual(`${originalPadding}px`, 'original sticky element margin should be stored in data-bs-margin-right')
expect(getPaddingX(stickyTopEl)).toEqual(expectedPadding, 'sticky element margin should be adjusted while opening') expect(getPaddingX(stickyTopEl)).toEqual(expectedPadding, 'sticky element margin should be adjusted while opening')
Scrollbar.reset() scrollBar.reset()
expect(getMarginAttr(stickyTopEl)).toEqual(null, 'data-bs-margin-right should be cleared after closing') expect(getMarginAttr(stickyTopEl)).toEqual(null, 'data-bs-margin-right should be cleared after closing')
expect(getMarginX(stickyTopEl)).toEqual(originalMargin, 'sticky element margin should be reset after closing') expect(getMarginX(stickyTopEl)).toEqual(originalMargin, 'sticky element margin should be reset after closing')
expect(getPaddingAttr(stickyTopEl)).toEqual(null, 'data-bs-margin-right should be cleared after closing') expect(getPaddingAttr(stickyTopEl)).toEqual(null, 'data-bs-margin-right should be cleared after closing')
@ -179,7 +181,8 @@ describe('ScrollBar', () => {
const originalMargin = getMarginX(stickyTopEl) const originalMargin = getMarginX(stickyTopEl)
const originalPadding = getPaddingX(stickyTopEl) const originalPadding = getPaddingX(stickyTopEl)
Scrollbar.hide() const scrollBar = new ScrollBarHelper()
scrollBar.hide()
const currentMargin = getMarginX(stickyTopEl) const currentMargin = getMarginX(stickyTopEl)
const currentPadding = getPaddingX(stickyTopEl) const currentPadding = getPaddingX(stickyTopEl)
@ -187,7 +190,7 @@ describe('ScrollBar', () => {
expect(currentMargin).toEqual(originalMargin, 'sticky element\'s margin should not be adjusted while opening') expect(currentMargin).toEqual(originalMargin, 'sticky element\'s margin should not be adjusted while opening')
expect(currentPadding).toEqual(originalPadding, 'sticky element\'s padding should not be adjusted while opening') expect(currentPadding).toEqual(originalPadding, 'sticky element\'s padding should not be adjusted while opening')
Scrollbar.reset() scrollBar.reset()
}) })
it('should not put data-attribute if element doesn\'t have the proper style property, should just remove style property if element didn\'t had one', () => { it('should not put data-attribute if element doesn\'t have the proper style property, should just remove style property if element didn\'t had one', () => {
@ -198,15 +201,16 @@ describe('ScrollBar', () => {
].join('') ].join('')
document.body.style.overflowY = 'scroll' document.body.style.overflowY = 'scroll'
const scrollBar = new ScrollBarHelper()
const hasPaddingAttr = el => el.hasAttribute('data-bs-padding-right') const hasPaddingAttr = el => el.hasAttribute('data-bs-padding-right')
const hasMarginAttr = el => el.hasAttribute('data-bs-margin-right') const hasMarginAttr = el => el.hasAttribute('data-bs-margin-right')
const stickyEl = fixtureEl.querySelector('#sticky') const stickyEl = fixtureEl.querySelector('#sticky')
const originalPadding = getPaddingX(stickyEl) const originalPadding = getPaddingX(stickyEl)
const originalMargin = getMarginX(stickyEl) const originalMargin = getMarginX(stickyEl)
const scrollBarWidth = Scrollbar.getWidth() const scrollBarWidth = scrollBar.getWidth()
Scrollbar.hide() scrollBar.hide()
expect(getPaddingX(stickyEl)).toEqual(scrollBarWidth + originalPadding) expect(getPaddingX(stickyEl)).toEqual(scrollBarWidth + originalPadding)
const expectedMargin = scrollBarWidth + originalMargin const expectedMargin = scrollBarWidth + originalMargin
@ -214,7 +218,7 @@ describe('ScrollBar', () => {
expect(hasMarginAttr(stickyEl)).toBeFalse() // We do not have to keep css margin expect(hasMarginAttr(stickyEl)).toBeFalse() // We do not have to keep css margin
expect(hasPaddingAttr(stickyEl)).toBeFalse() // We do not have to keep css padding expect(hasPaddingAttr(stickyEl)).toBeFalse() // We do not have to keep css padding
Scrollbar.reset() scrollBar.reset()
expect(getPaddingX(stickyEl)).toEqual(originalPadding) expect(getPaddingX(stickyEl)).toEqual(originalPadding)
expect(getPaddingX(stickyEl)).toEqual(originalPadding) expect(getPaddingX(stickyEl)).toEqual(originalPadding)
@ -224,13 +228,14 @@ describe('ScrollBar', () => {
it('should ignore other inline styles when trying to restore body defaults ', () => { it('should ignore other inline styles when trying to restore body defaults ', () => {
document.body.style.color = 'red' document.body.style.color = 'red'
const scrollBarWidth = Scrollbar.getWidth() const scrollBar = new ScrollBarHelper()
Scrollbar.hide() const scrollBarWidth = scrollBar.getWidth()
scrollBar.hide()
expect(getPaddingX(document.body)).toEqual(scrollBarWidth, 'body does not have inline padding set') expect(getPaddingX(document.body)).toEqual(scrollBarWidth, 'body does not have inline padding set')
expect(document.body.style.color).toEqual('red', 'body still has other inline styles set') expect(document.body.style.color).toEqual('red', 'body still has other inline styles set')
Scrollbar.reset() scrollBar.reset()
}) })
it('should hide scrollbar and reset it to its initial value', () => { it('should hide scrollbar and reset it to its initial value', () => {
@ -251,9 +256,10 @@ describe('ScrollBar', () => {
expect(originalPadding).toEqual(parseInt(inlineStylePadding)) // Respect only the inline style as it has prevails this of css expect(originalPadding).toEqual(parseInt(inlineStylePadding)) // Respect only the inline style as it has prevails this of css
const originalOverFlow = 'auto' const originalOverFlow = 'auto'
el.style.overflow = originalOverFlow el.style.overflow = originalOverFlow
const scrollBarWidth = Scrollbar.getWidth() const scrollBar = new ScrollBarHelper()
const scrollBarWidth = scrollBar.getWidth()
Scrollbar.hide() scrollBar.hide()
const currentPadding = getPaddingX(el) const currentPadding = getPaddingX(el)
@ -263,7 +269,7 @@ describe('ScrollBar', () => {
expect(getOverFlow(el)).toEqual('hidden') expect(getOverFlow(el)).toEqual('hidden')
expect(getOverFlowAttr(el)).toEqual(originalOverFlow) expect(getOverFlowAttr(el)).toEqual(originalOverFlow)
Scrollbar.reset() scrollBar.reset()
const currentPadding1 = getPaddingX(el) const currentPadding1 = getPaddingX(el)
expect(currentPadding1).toEqual(originalPadding) expect(currentPadding1).toEqual(originalPadding)
@ -285,9 +291,10 @@ describe('ScrollBar', () => {
const originalPadding = getPaddingX(el) const originalPadding = getPaddingX(el)
const originalOverFlow = 'scroll' const originalOverFlow = 'scroll'
el.style.overflow = originalOverFlow el.style.overflow = originalOverFlow
const scrollBarWidth = Scrollbar.getWidth() const scrollBar = new ScrollBarHelper()
const scrollBarWidth = scrollBar.getWidth()
Scrollbar.hide() scrollBar.hide()
const currentPadding = getPaddingX(el) const currentPadding = getPaddingX(el)
@ -297,7 +304,7 @@ describe('ScrollBar', () => {
expect(getOverFlow(el)).toEqual('hidden') expect(getOverFlow(el)).toEqual('hidden')
expect(getOverFlowAttr(el)).toEqual(originalOverFlow) expect(getOverFlowAttr(el)).toEqual(originalOverFlow)
Scrollbar.reset() scrollBar.reset()
const currentPadding1 = getPaddingX(el) const currentPadding1 = getPaddingX(el)
expect(currentPadding1).toEqual(originalPadding) expect(currentPadding1).toEqual(originalPadding)
@ -308,20 +315,22 @@ describe('ScrollBar', () => {
it('should not adjust the inline body padding when it does not overflow', () => { it('should not adjust the inline body padding when it does not overflow', () => {
const originalPadding = getPaddingX(document.body) const originalPadding = getPaddingX(document.body)
const scrollBar = new ScrollBarHelper()
// Hide scrollbars to prevent the body overflowing // Hide scrollbars to prevent the body overflowing
doc.style.overflowY = 'hidden' doc.style.overflowY = 'hidden'
doc.style.paddingRight = '0px' doc.style.paddingRight = '0px'
Scrollbar.hide() scrollBar.hide()
const currentPadding = getPaddingX(document.body) const currentPadding = getPaddingX(document.body)
expect(currentPadding).toEqual(originalPadding, 'body padding should not be adjusted') expect(currentPadding).toEqual(originalPadding, 'body padding should not be adjusted')
Scrollbar.reset() scrollBar.reset()
}) })
it('should not adjust the inline body padding when it does not overflow, even on a scaled display', () => { it('should not adjust the inline body padding when it does not overflow, even on a scaled display', () => {
const originalPadding = getPaddingX(document.body) const originalPadding = getPaddingX(document.body)
const scrollBar = new ScrollBarHelper()
// Remove body margins as would be done by Bootstrap css // Remove body margins as would be done by Bootstrap css
document.body.style.margin = '0' document.body.style.margin = '0'
@ -331,13 +340,13 @@ describe('ScrollBar', () => {
// Simulate a discrepancy between exact, i.e. floating point body width, and rounded body width // Simulate a discrepancy between exact, i.e. floating point body width, and rounded body width
// as it can occur when zooming or scaling the display to something else than 100% // as it can occur when zooming or scaling the display to something else than 100%
doc.style.paddingRight = '.48px' doc.style.paddingRight = '.48px'
Scrollbar.hide() scrollBar.hide()
const currentPadding = getPaddingX(document.body) const currentPadding = getPaddingX(document.body)
expect(currentPadding).toEqual(originalPadding, 'body padding should not be adjusted') expect(currentPadding).toEqual(originalPadding, 'body padding should not be adjusted')
Scrollbar.reset() scrollBar.reset()
}) })
}) })
}) })