]> git.ipfire.org Git - thirdparty/bootstrap.git/commitdiff
Remove unused FocusTrap and ScrollBarHelper utilities (#42595)
authorMark Otto <markd.otto@gmail.com>
Sun, 28 Jun 2026 15:37:02 +0000 (08:37 -0700)
committerGitHub <noreply@github.com>
Sun, 28 Jun 2026 15:37:02 +0000 (08:37 -0700)
Both became dead code with the Modal->Dialog / Offcanvas->Drawer rewrite:
the native <dialog> element provides the focus trap and top-layer
inerting, and the scroll lock is now :root.dialog-open in CSS. Nothing in
js/src imports either utility and neither is part of the public bundle
export — only their own unit specs referenced them.

Removes the source modules, their committed dist builds, and their specs.

js/dist/util/focustrap.js [deleted file]
js/dist/util/focustrap.js.map [deleted file]
js/dist/util/scrollbar.js [deleted file]
js/dist/util/scrollbar.js.map [deleted file]
js/src/util/focustrap.js [deleted file]
js/src/util/scrollbar.js [deleted file]
js/tests/unit/util/focustrap.spec.js [deleted file]
js/tests/unit/util/scrollbar.spec.js [deleted file]

diff --git a/js/dist/util/focustrap.js b/js/dist/util/focustrap.js
deleted file mode 100644 (file)
index 59beaf8..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*!
-  * Bootstrap focustrap.js v6.0.0-alpha1 (https://getbootstrap.com/)
-  * Copyright 2011-2026 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
-  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
-  */
-import EventHandler from '../dom/event-handler.js';
-import SelectorEngine from '../dom/selector-engine.js';
-import Config from './config.js';
-
-/**
- * --------------------------------------------------------------------------
- * Bootstrap util/focustrap.js
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
- * --------------------------------------------------------------------------
- */
-
-
-/**
- * Constants
- */
-
-const NAME = 'focustrap';
-const DATA_KEY = 'bs.focustrap';
-const EVENT_KEY = `.${DATA_KEY}`;
-const EVENT_FOCUSIN = `focusin${EVENT_KEY}`;
-const EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY}`;
-const TAB_KEY = 'Tab';
-const TAB_NAV_FORWARD = 'forward';
-const TAB_NAV_BACKWARD = 'backward';
-const Default = {
-  autofocus: true,
-  trapElement: null // The element to trap focus inside of
-};
-const DefaultType = {
-  autofocus: 'boolean',
-  trapElement: 'element'
-};
-
-/**
- * Class definition
- */
-
-class FocusTrap extends Config {
-  constructor(config) {
-    super();
-    this._config = this._getConfig(config);
-    this._isActive = false;
-    this._lastTabNavDirection = null;
-  }
-
-  // Getters
-  static get Default() {
-    return Default;
-  }
-  static get DefaultType() {
-    return DefaultType;
-  }
-  static get NAME() {
-    return NAME;
-  }
-
-  // Public
-  activate() {
-    if (this._isActive) {
-      return;
-    }
-    if (this._config.autofocus) {
-      this._config.trapElement.focus();
-    }
-    EventHandler.off(document, EVENT_KEY); // guard against infinite focus loop
-    EventHandler.on(document, EVENT_FOCUSIN, event => this._handleFocusin(event));
-    EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event));
-    this._isActive = true;
-  }
-  deactivate() {
-    if (!this._isActive) {
-      return;
-    }
-    this._isActive = false;
-    EventHandler.off(document, EVENT_KEY);
-  }
-
-  // Private
-  _handleFocusin(event) {
-    const {
-      trapElement
-    } = this._config;
-    if (event.target === document || event.target === trapElement || trapElement.contains(event.target)) {
-      return;
-    }
-    const elements = SelectorEngine.focusableChildren(trapElement);
-    if (elements.length === 0) {
-      trapElement.focus();
-    } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {
-      elements.at(-1).focus();
-    } else {
-      elements[0].focus();
-    }
-  }
-  _handleKeydown(event) {
-    if (event.key !== TAB_KEY) {
-      return;
-    }
-    this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD;
-  }
-}
-
-export { FocusTrap as default };
-//# sourceMappingURL=focustrap.js.map
diff --git a/js/dist/util/focustrap.js.map b/js/dist/util/focustrap.js.map
deleted file mode 100644 (file)
index 0b4db47..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"focustrap.js","sources":["../../src/util/focustrap.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap util/focustrap.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport EventHandler from '../dom/event-handler.js'\nimport SelectorEngine from '../dom/selector-engine.js'\nimport Config from './config.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'focustrap'\nconst DATA_KEY = 'bs.focustrap'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst EVENT_FOCUSIN = `focusin${EVENT_KEY}`\nconst EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY}`\n\nconst TAB_KEY = 'Tab'\nconst TAB_NAV_FORWARD = 'forward'\nconst TAB_NAV_BACKWARD = 'backward'\n\nconst Default = {\n  autofocus: true,\n  trapElement: null // The element to trap focus inside of\n}\n\nconst DefaultType = {\n  autofocus: 'boolean',\n  trapElement: 'element'\n}\n\n/**\n * Class definition\n */\n\nclass FocusTrap extends Config {\n  constructor(config) {\n    super()\n    this._config = this._getConfig(config)\n    this._isActive = false\n    this._lastTabNavDirection = null\n  }\n\n  // Getters\n  static get Default() {\n    return Default\n  }\n\n  static get DefaultType() {\n    return DefaultType\n  }\n\n  static get NAME() {\n    return NAME\n  }\n\n  // Public\n  activate() {\n    if (this._isActive) {\n      return\n    }\n\n    if (this._config.autofocus) {\n      this._config.trapElement.focus()\n    }\n\n    EventHandler.off(document, EVENT_KEY) // guard against infinite focus loop\n    EventHandler.on(document, EVENT_FOCUSIN, event => this._handleFocusin(event))\n    EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event))\n\n    this._isActive = true\n  }\n\n  deactivate() {\n    if (!this._isActive) {\n      return\n    }\n\n    this._isActive = false\n    EventHandler.off(document, EVENT_KEY)\n  }\n\n  // Private\n  _handleFocusin(event) {\n    const { trapElement } = this._config\n\n    if (event.target === document || event.target === trapElement || trapElement.contains(event.target)) {\n      return\n    }\n\n    const elements = SelectorEngine.focusableChildren(trapElement)\n\n    if (elements.length === 0) {\n      trapElement.focus()\n    } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {\n      elements.at(-1).focus()\n    } else {\n      elements[0].focus()\n    }\n  }\n\n  _handleKeydown(event) {\n    if (event.key !== TAB_KEY) {\n      return\n    }\n\n    this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD\n  }\n}\n\nexport default FocusTrap\n"],"names":["NAME","DATA_KEY","EVENT_KEY","EVENT_FOCUSIN","EVENT_KEYDOWN_TAB","TAB_KEY","TAB_NAV_FORWARD","TAB_NAV_BACKWARD","Default","autofocus","trapElement","DefaultType","FocusTrap","Config","constructor","config","_config","_getConfig","_isActive","_lastTabNavDirection","activate","focus","EventHandler","off","document","on","event","_handleFocusin","_handleKeydown","deactivate","target","contains","elements","SelectorEngine","focusableChildren","length","at","key","shiftKey"],"mappings":"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"}
\ No newline at end of file
diff --git a/js/dist/util/scrollbar.js b/js/dist/util/scrollbar.js
deleted file mode 100644 (file)
index d40ff86..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*!
-  * Bootstrap scrollbar.js v6.0.0-alpha1 (https://getbootstrap.com/)
-  * Copyright 2011-2026 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
-  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
-  */
-import Manipulator from '../dom/manipulator.js';
-import SelectorEngine from '../dom/selector-engine.js';
-import { isElement } from './index.js';
-
-/**
- * --------------------------------------------------------------------------
- * Bootstrap util/scrollBar.js
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
- * --------------------------------------------------------------------------
- */
-
-
-/**
- * Constants
- */
-
-const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';
-const SELECTOR_STICKY_CONTENT = '.sticky-top';
-const PROPERTY_PADDING = 'padding-right';
-const PROPERTY_MARGIN = 'margin-right';
-
-/**
- * Class definition
- */
-
-class ScrollBarHelper {
-  constructor() {
-    this._element = document.body;
-  }
-
-  // Public
-  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);
-  }
-  hide() {
-    const width = this.getWidth();
-    this._disableOverFlow();
-    // give padding to element to balance the hidden scrollbar width
-    this._setElementAttributes(this._element, PROPERTY_PADDING, calculatedValue => calculatedValue + width);
-    // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth
-    this._setElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING, calculatedValue => calculatedValue + width);
-    this._setElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN, calculatedValue => calculatedValue - width);
-  }
-  reset() {
-    this._resetElementAttributes(this._element, 'overflow');
-    this._resetElementAttributes(this._element, PROPERTY_PADDING);
-    this._resetElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING);
-    this._resetElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN);
-  }
-  isOverflowing() {
-    return this.getWidth() > 0;
-  }
-
-  // Private
-  _disableOverFlow() {
-    this._saveInitialAttribute(this._element, 'overflow');
-    this._element.style.overflow = 'hidden';
-  }
-  _setElementAttributes(selector, styleProperty, callback) {
-    const scrollbarWidth = this.getWidth();
-    const manipulationCallBack = element => {
-      if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {
-        return;
-      }
-      this._saveInitialAttribute(element, styleProperty);
-      const calculatedValue = window.getComputedStyle(element).getPropertyValue(styleProperty);
-      element.style.setProperty(styleProperty, `${callback(Number.parseFloat(calculatedValue))}px`);
-    };
-    this._applyManipulationCallback(selector, manipulationCallBack);
-  }
-  _saveInitialAttribute(element, styleProperty) {
-    const actualValue = element.style.getPropertyValue(styleProperty);
-    if (actualValue) {
-      Manipulator.setDataAttribute(element, styleProperty, actualValue);
-    }
-  }
-  _resetElementAttributes(selector, styleProperty) {
-    const manipulationCallBack = element => {
-      const value = Manipulator.getDataAttribute(element, styleProperty);
-      // We only want to remove the property if the value is `null`; the value can also be zero
-      if (value === null) {
-        element.style.removeProperty(styleProperty);
-        return;
-      }
-      Manipulator.removeDataAttribute(element, styleProperty);
-      element.style.setProperty(styleProperty, value);
-    };
-    this._applyManipulationCallback(selector, manipulationCallBack);
-  }
-  _applyManipulationCallback(selector, callBack) {
-    if (isElement(selector)) {
-      callBack(selector);
-      return;
-    }
-    for (const sel of SelectorEngine.find(selector, this._element)) {
-      callBack(sel);
-    }
-  }
-}
-
-export { ScrollBarHelper as default };
-//# sourceMappingURL=scrollbar.js.map
diff --git a/js/dist/util/scrollbar.js.map b/js/dist/util/scrollbar.js.map
deleted file mode 100644 (file)
index dfee4dd..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"scrollbar.js","sources":["../../src/util/scrollbar.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap util/scrollBar.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport Manipulator from '../dom/manipulator.js'\nimport SelectorEngine from '../dom/selector-engine.js'\nimport { isElement } from './index.js'\n\n/**\n * Constants\n */\n\nconst SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'\nconst SELECTOR_STICKY_CONTENT = '.sticky-top'\nconst PROPERTY_PADDING = 'padding-right'\nconst PROPERTY_MARGIN = 'margin-right'\n\n/**\n * Class definition\n */\n\nclass ScrollBarHelper {\n  constructor() {\n    this._element = document.body\n  }\n\n  // Public\n  getWidth() {\n    // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes\n    const documentWidth = document.documentElement.clientWidth\n    return Math.abs(window.innerWidth - documentWidth)\n  }\n\n  hide() {\n    const width = this.getWidth()\n    this._disableOverFlow()\n    // give padding to element to balance the hidden scrollbar width\n    this._setElementAttributes(this._element, PROPERTY_PADDING, calculatedValue => calculatedValue + width)\n    // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth\n    this._setElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING, calculatedValue => calculatedValue + width)\n    this._setElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN, calculatedValue => calculatedValue - width)\n  }\n\n  reset() {\n    this._resetElementAttributes(this._element, 'overflow')\n    this._resetElementAttributes(this._element, PROPERTY_PADDING)\n    this._resetElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING)\n    this._resetElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN)\n  }\n\n  isOverflowing() {\n    return this.getWidth() > 0\n  }\n\n  // Private\n  _disableOverFlow() {\n    this._saveInitialAttribute(this._element, 'overflow')\n    this._element.style.overflow = 'hidden'\n  }\n\n  _setElementAttributes(selector, styleProperty, callback) {\n    const scrollbarWidth = this.getWidth()\n    const manipulationCallBack = element => {\n      if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {\n        return\n      }\n\n      this._saveInitialAttribute(element, styleProperty)\n      const calculatedValue = window.getComputedStyle(element).getPropertyValue(styleProperty)\n      element.style.setProperty(styleProperty, `${callback(Number.parseFloat(calculatedValue))}px`)\n    }\n\n    this._applyManipulationCallback(selector, manipulationCallBack)\n  }\n\n  _saveInitialAttribute(element, styleProperty) {\n    const actualValue = element.style.getPropertyValue(styleProperty)\n    if (actualValue) {\n      Manipulator.setDataAttribute(element, styleProperty, actualValue)\n    }\n  }\n\n  _resetElementAttributes(selector, styleProperty) {\n    const manipulationCallBack = element => {\n      const value = Manipulator.getDataAttribute(element, styleProperty)\n      // We only want to remove the property if the value is `null`; the value can also be zero\n      if (value === null) {\n        element.style.removeProperty(styleProperty)\n        return\n      }\n\n      Manipulator.removeDataAttribute(element, styleProperty)\n      element.style.setProperty(styleProperty, value)\n    }\n\n    this._applyManipulationCallback(selector, manipulationCallBack)\n  }\n\n  _applyManipulationCallback(selector, callBack) {\n    if (isElement(selector)) {\n      callBack(selector)\n      return\n    }\n\n    for (const sel of SelectorEngine.find(selector, this._element)) {\n      callBack(sel)\n    }\n  }\n}\n\nexport default ScrollBarHelper\n"],"names":["SELECTOR_FIXED_CONTENT","SELECTOR_STICKY_CONTENT","PROPERTY_PADDING","PROPERTY_MARGIN","ScrollBarHelper","constructor","_element","document","body","getWidth","documentWidth","documentElement","clientWidth","Math","abs","window","innerWidth","hide","width","_disableOverFlow","_setElementAttributes","calculatedValue","reset","_resetElementAttributes","isOverflowing","_saveInitialAttribute","style","overflow","selector","styleProperty","callback","scrollbarWidth","manipulationCallBack","element","getComputedStyle","getPropertyValue","setProperty","Number","parseFloat","_applyManipulationCallback","actualValue","Manipulator","setDataAttribute","value","getDataAttribute","removeProperty","removeDataAttribute","callBack","isElement","sel","SelectorEngine","find"],"mappings":"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"}
\ No newline at end of file
diff --git a/js/src/util/focustrap.js b/js/src/util/focustrap.js
deleted file mode 100644 (file)
index 7900ab8..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/**
- * --------------------------------------------------------------------------
- * Bootstrap util/focustrap.js
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
- * --------------------------------------------------------------------------
- */
-
-import EventHandler from '../dom/event-handler.js'
-import SelectorEngine from '../dom/selector-engine.js'
-import Config from './config.js'
-
-/**
- * Constants
- */
-
-const NAME = 'focustrap'
-const DATA_KEY = 'bs.focustrap'
-const EVENT_KEY = `.${DATA_KEY}`
-const EVENT_FOCUSIN = `focusin${EVENT_KEY}`
-const EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY}`
-
-const TAB_KEY = 'Tab'
-const TAB_NAV_FORWARD = 'forward'
-const TAB_NAV_BACKWARD = 'backward'
-
-const Default = {
-  autofocus: true,
-  trapElement: null // The element to trap focus inside of
-}
-
-const DefaultType = {
-  autofocus: 'boolean',
-  trapElement: 'element'
-}
-
-/**
- * Class definition
- */
-
-class FocusTrap extends Config {
-  constructor(config) {
-    super()
-    this._config = this._getConfig(config)
-    this._isActive = false
-    this._lastTabNavDirection = null
-  }
-
-  // Getters
-  static get Default() {
-    return Default
-  }
-
-  static get DefaultType() {
-    return DefaultType
-  }
-
-  static get NAME() {
-    return NAME
-  }
-
-  // Public
-  activate() {
-    if (this._isActive) {
-      return
-    }
-
-    if (this._config.autofocus) {
-      this._config.trapElement.focus()
-    }
-
-    EventHandler.off(document, EVENT_KEY) // guard against infinite focus loop
-    EventHandler.on(document, EVENT_FOCUSIN, event => this._handleFocusin(event))
-    EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event))
-
-    this._isActive = true
-  }
-
-  deactivate() {
-    if (!this._isActive) {
-      return
-    }
-
-    this._isActive = false
-    EventHandler.off(document, EVENT_KEY)
-  }
-
-  // Private
-  _handleFocusin(event) {
-    const { trapElement } = this._config
-
-    if (event.target === document || event.target === trapElement || trapElement.contains(event.target)) {
-      return
-    }
-
-    const elements = SelectorEngine.focusableChildren(trapElement)
-
-    if (elements.length === 0) {
-      trapElement.focus()
-    } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {
-      elements.at(-1).focus()
-    } else {
-      elements[0].focus()
-    }
-  }
-
-  _handleKeydown(event) {
-    if (event.key !== TAB_KEY) {
-      return
-    }
-
-    this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD
-  }
-}
-
-export default FocusTrap
diff --git a/js/src/util/scrollbar.js b/js/src/util/scrollbar.js
deleted file mode 100644 (file)
index 413f178..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/**
- * --------------------------------------------------------------------------
- * Bootstrap util/scrollBar.js
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
- * --------------------------------------------------------------------------
- */
-
-import Manipulator from '../dom/manipulator.js'
-import SelectorEngine from '../dom/selector-engine.js'
-import { isElement } from './index.js'
-
-/**
- * Constants
- */
-
-const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'
-const SELECTOR_STICKY_CONTENT = '.sticky-top'
-const PROPERTY_PADDING = 'padding-right'
-const PROPERTY_MARGIN = 'margin-right'
-
-/**
- * Class definition
- */
-
-class ScrollBarHelper {
-  constructor() {
-    this._element = document.body
-  }
-
-  // Public
-  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)
-  }
-
-  hide() {
-    const width = this.getWidth()
-    this._disableOverFlow()
-    // give padding to element to balance the hidden scrollbar width
-    this._setElementAttributes(this._element, PROPERTY_PADDING, calculatedValue => calculatedValue + width)
-    // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth
-    this._setElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING, calculatedValue => calculatedValue + width)
-    this._setElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN, calculatedValue => calculatedValue - width)
-  }
-
-  reset() {
-    this._resetElementAttributes(this._element, 'overflow')
-    this._resetElementAttributes(this._element, PROPERTY_PADDING)
-    this._resetElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING)
-    this._resetElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN)
-  }
-
-  isOverflowing() {
-    return this.getWidth() > 0
-  }
-
-  // Private
-  _disableOverFlow() {
-    this._saveInitialAttribute(this._element, 'overflow')
-    this._element.style.overflow = 'hidden'
-  }
-
-  _setElementAttributes(selector, styleProperty, callback) {
-    const scrollbarWidth = this.getWidth()
-    const manipulationCallBack = element => {
-      if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {
-        return
-      }
-
-      this._saveInitialAttribute(element, styleProperty)
-      const calculatedValue = window.getComputedStyle(element).getPropertyValue(styleProperty)
-      element.style.setProperty(styleProperty, `${callback(Number.parseFloat(calculatedValue))}px`)
-    }
-
-    this._applyManipulationCallback(selector, manipulationCallBack)
-  }
-
-  _saveInitialAttribute(element, styleProperty) {
-    const actualValue = element.style.getPropertyValue(styleProperty)
-    if (actualValue) {
-      Manipulator.setDataAttribute(element, styleProperty, actualValue)
-    }
-  }
-
-  _resetElementAttributes(selector, styleProperty) {
-    const manipulationCallBack = element => {
-      const value = Manipulator.getDataAttribute(element, styleProperty)
-      // We only want to remove the property if the value is `null`; the value can also be zero
-      if (value === null) {
-        element.style.removeProperty(styleProperty)
-        return
-      }
-
-      Manipulator.removeDataAttribute(element, styleProperty)
-      element.style.setProperty(styleProperty, value)
-    }
-
-    this._applyManipulationCallback(selector, manipulationCallBack)
-  }
-
-  _applyManipulationCallback(selector, callBack) {
-    if (isElement(selector)) {
-      callBack(selector)
-      return
-    }
-
-    for (const sel of SelectorEngine.find(selector, this._element)) {
-      callBack(sel)
-    }
-  }
-}
-
-export default ScrollBarHelper
diff --git a/js/tests/unit/util/focustrap.spec.js b/js/tests/unit/util/focustrap.spec.js
deleted file mode 100644 (file)
index 0a20017..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-import EventHandler from '../../../src/dom/event-handler.js'
-import SelectorEngine from '../../../src/dom/selector-engine.js'
-import FocusTrap from '../../../src/util/focustrap.js'
-import { clearFixture, createEvent, getFixture } from '../../helpers/fixture.js'
-
-describe('FocusTrap', () => {
-  let fixtureEl
-
-  beforeAll(() => {
-    fixtureEl = getFixture()
-  })
-
-  afterEach(() => {
-    clearFixture()
-  })
-
-  describe('activate', () => {
-    it('should autofocus itself by default', () => {
-      fixtureEl.innerHTML = '<div id="focustrap" tabindex="-1"></div>'
-
-      const trapElement = fixtureEl.querySelector('div')
-
-      const spy = spyOn(trapElement, 'focus')
-
-      const focustrap = new FocusTrap({ trapElement })
-      focustrap.activate()
-
-      expect(spy).toHaveBeenCalled()
-    })
-
-    it('if configured not to autofocus, should not autofocus itself', () => {
-      fixtureEl.innerHTML = '<div id="focustrap" tabindex="-1"></div>'
-
-      const trapElement = fixtureEl.querySelector('div')
-
-      const spy = spyOn(trapElement, 'focus')
-
-      const focustrap = new FocusTrap({ trapElement, autofocus: false })
-      focustrap.activate()
-
-      expect(spy).not.toHaveBeenCalled()
-    })
-
-    it('should force focus inside focus trap if it can', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = [
-          '<a href="#" id="outside">outside</a>',
-          '<div id="focustrap" tabindex="-1">',
-          '  <a href="#" id="inside">inside</a>',
-          '</div>'
-        ].join('')
-
-        const trapElement = fixtureEl.querySelector('div')
-        const focustrap = new FocusTrap({ trapElement })
-        focustrap.activate()
-
-        const inside = document.getElementById('inside')
-
-        const focusInListener = () => {
-          expect(spy).toHaveBeenCalled()
-          document.removeEventListener('focusin', focusInListener)
-          resolve()
-        }
-
-        const spy = spyOn(inside, 'focus')
-        spyOn(SelectorEngine, 'focusableChildren').and.callFake(() => [inside])
-
-        document.addEventListener('focusin', focusInListener)
-
-        const focusInEvent = createEvent('focusin', { bubbles: true })
-        Object.defineProperty(focusInEvent, 'target', {
-          value: document.getElementById('outside')
-        })
-
-        document.dispatchEvent(focusInEvent)
-      })
-    })
-
-    it('should wrap focus around forward on tab', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = [
-          '<a href="#" id="outside">outside</a>',
-          '<div id="focustrap" tabindex="-1">',
-          '  <a href="#" id="first">first</a>',
-          '  <a href="#" id="inside">inside</a>',
-          '  <a href="#" id="last">last</a>',
-          '</div>'
-        ].join('')
-
-        const trapElement = fixtureEl.querySelector('div')
-        const focustrap = new FocusTrap({ trapElement })
-        focustrap.activate()
-
-        const first = document.getElementById('first')
-        const inside = document.getElementById('inside')
-        const last = document.getElementById('last')
-        const outside = document.getElementById('outside')
-
-        spyOn(SelectorEngine, 'focusableChildren').and.callFake(() => [first, inside, last])
-        const spy = spyOn(first, 'focus').and.callThrough()
-
-        const focusInListener = () => {
-          expect(spy).toHaveBeenCalled()
-          first.removeEventListener('focusin', focusInListener)
-          resolve()
-        }
-
-        first.addEventListener('focusin', focusInListener)
-
-        const keydown = createEvent('keydown')
-        keydown.key = 'Tab'
-
-        document.dispatchEvent(keydown)
-        outside.focus()
-      })
-    })
-
-    it('should wrap focus around backwards on shift-tab', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = [
-          '<a href="#" id="outside">outside</a>',
-          '<div id="focustrap" tabindex="-1">',
-          '  <a href="#" id="first">first</a>',
-          '  <a href="#" id="inside">inside</a>',
-          '  <a href="#" id="last">last</a>',
-          '</div>'
-        ].join('')
-
-        const trapElement = fixtureEl.querySelector('div')
-        const focustrap = new FocusTrap({ trapElement })
-        focustrap.activate()
-
-        const first = document.getElementById('first')
-        const inside = document.getElementById('inside')
-        const last = document.getElementById('last')
-        const outside = document.getElementById('outside')
-
-        spyOn(SelectorEngine, 'focusableChildren').and.callFake(() => [first, inside, last])
-        const spy = spyOn(last, 'focus').and.callThrough()
-
-        const focusInListener = () => {
-          expect(spy).toHaveBeenCalled()
-          last.removeEventListener('focusin', focusInListener)
-          resolve()
-        }
-
-        last.addEventListener('focusin', focusInListener)
-
-        const keydown = createEvent('keydown')
-        keydown.key = 'Tab'
-        keydown.shiftKey = true
-
-        document.dispatchEvent(keydown)
-        outside.focus()
-      })
-    })
-
-    it('should force focus on itself if there is no focusable content', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = [
-          '<a href="#" id="outside">outside</a>',
-          '<div id="focustrap" tabindex="-1"></div>'
-        ].join('')
-
-        const trapElement = fixtureEl.querySelector('div')
-        const focustrap = new FocusTrap({ trapElement })
-        focustrap.activate()
-
-        const focusInListener = () => {
-          expect(spy).toHaveBeenCalled()
-          document.removeEventListener('focusin', focusInListener)
-          resolve()
-        }
-
-        const spy = spyOn(focustrap._config.trapElement, 'focus')
-
-        document.addEventListener('focusin', focusInListener)
-
-        const focusInEvent = createEvent('focusin', { bubbles: true })
-        Object.defineProperty(focusInEvent, 'target', {
-          value: document.getElementById('outside')
-        })
-
-        document.dispatchEvent(focusInEvent)
-      })
-    })
-  })
-
-  describe('deactivate', () => {
-    it('should flag itself as no longer active', () => {
-      const focustrap = new FocusTrap({ trapElement: fixtureEl })
-      focustrap.activate()
-      expect(focustrap._isActive).toBeTrue()
-
-      focustrap.deactivate()
-      expect(focustrap._isActive).toBeFalse()
-    })
-
-    it('should remove all event listeners', () => {
-      const focustrap = new FocusTrap({ trapElement: fixtureEl })
-      focustrap.activate()
-
-      const spy = spyOn(EventHandler, 'off')
-      focustrap.deactivate()
-
-      expect(spy).toHaveBeenCalled()
-    })
-
-    it('doesn\'t try removing event listeners unless it needs to (in case it hasn\'t been activated)', () => {
-      const focustrap = new FocusTrap({ trapElement: fixtureEl })
-
-      const spy = spyOn(EventHandler, 'off')
-      focustrap.deactivate()
-
-      expect(spy).not.toHaveBeenCalled()
-    })
-  })
-})
diff --git a/js/tests/unit/util/scrollbar.spec.js b/js/tests/unit/util/scrollbar.spec.js
deleted file mode 100644 (file)
index 6dadfcd..0000000
+++ /dev/null
@@ -1,363 +0,0 @@
-import Manipulator from '../../../src/dom/manipulator.js'
-import ScrollBarHelper from '../../../src/util/scrollbar.js'
-import { clearBodyAndDocument, clearFixture, getFixture } from '../../helpers/fixture.js'
-
-describe('ScrollBar', () => {
-  let fixtureEl
-  const doc = document.documentElement
-  const parseIntDecimal = arg => Number.parseInt(arg, 10)
-  const getPaddingX = el => parseIntDecimal(window.getComputedStyle(el).paddingRight)
-  const getMarginX = el => parseIntDecimal(window.getComputedStyle(el).marginRight)
-  const getOverFlow = el => el.style.overflow
-  const getPaddingAttr = el => Manipulator.getDataAttribute(el, 'padding-right')
-  const getMarginAttr = el => Manipulator.getDataAttribute(el, 'margin-right')
-  const getOverFlowAttr = el => Manipulator.getDataAttribute(el, 'overflow')
-  const windowCalculations = () => {
-    return {
-      htmlClient: document.documentElement.clientWidth,
-      htmlOffset: document.documentElement.offsetWidth,
-      docClient: document.body.clientWidth,
-      htmlBound: document.documentElement.getBoundingClientRect().width,
-      bodyBound: document.body.getBoundingClientRect().width,
-      window: window.innerWidth,
-      width: Math.abs(window.innerWidth - document.documentElement.clientWidth)
-    }
-  }
-
-  // iOS, Android devices and macOS browsers hide scrollbar by default and show it only while scrolling.
-  // So the tests for scrollbar would fail
-  const isScrollBarHidden = () => {
-    const calc = windowCalculations()
-    return calc.htmlClient === calc.htmlOffset && calc.htmlClient === calc.window
-  }
-
-  beforeAll(() => {
-    fixtureEl = getFixture()
-    // custom fixture to avoid extreme style values
-    fixtureEl.removeAttribute('style')
-  })
-
-  afterAll(() => {
-    fixtureEl.remove()
-  })
-
-  afterEach(() => {
-    clearFixture()
-    clearBodyAndDocument()
-  })
-
-  beforeEach(() => {
-    clearBodyAndDocument()
-  })
-
-  describe('isBodyOverflowing', () => {
-    it('should return true if body is overflowing', () => {
-      document.documentElement.style.overflowY = 'scroll'
-      document.body.style.overflowY = 'scroll'
-      fixtureEl.innerHTML = '<div style="height: 110vh; width: 100%"></div>'
-      const result = new ScrollBarHelper().isOverflowing()
-
-      if (isScrollBarHidden()) {
-        expect(result).toBeFalse()
-      } else {
-        expect(result).toBeTrue()
-      }
-    })
-
-    it('should return false if body is not overflowing', () => {
-      doc.style.overflowY = 'hidden'
-      document.body.style.overflowY = 'hidden'
-      fixtureEl.innerHTML = '<div style="height: 110vh; width: 100%"></div>'
-      const scrollBar = new ScrollBarHelper()
-      const result = scrollBar.isOverflowing()
-
-      expect(result).toBeFalse()
-    })
-  })
-
-  describe('getWidth', () => {
-    it('should return an integer greater than zero, if body is overflowing', () => {
-      doc.style.overflowY = 'scroll'
-      document.body.style.overflowY = 'scroll'
-      fixtureEl.innerHTML = '<div style="height: 110vh; width: 100%"></div>'
-      const result = new ScrollBarHelper().getWidth()
-
-      if (isScrollBarHidden()) {
-        expect(result).toEqual(0)
-      } else {
-        expect(result).toBeGreaterThan(1)
-      }
-    })
-
-    it('should return 0 if body is not overflowing', () => {
-      document.documentElement.style.overflowY = 'hidden'
-      document.body.style.overflowY = 'hidden'
-      fixtureEl.innerHTML = '<div style="height: 110vh; width: 100%"></div>'
-
-      const result = new ScrollBarHelper().getWidth()
-
-      expect(result).toEqual(0)
-    })
-  })
-
-  describe('hide - reset', () => {
-    it('should adjust the inline padding of fixed elements which are full-width', () => {
-      fixtureEl.innerHTML = [
-        '<div style="height: 110vh; width: 100%">',
-        '  <div class="fixed-top" id="fixed1" style="padding-right: 0px; width: 100vw"></div>',
-        '  <div class="fixed-top" id="fixed2" style="padding-right: 5px; width: 100vw"></div>',
-        '</div>'
-      ].join('')
-      doc.style.overflowY = 'scroll'
-
-      const fixedEl = fixtureEl.querySelector('#fixed1')
-      const fixedEl2 = fixtureEl.querySelector('#fixed2')
-      const originalPadding = getPaddingX(fixedEl)
-      const originalPadding2 = getPaddingX(fixedEl2)
-      const scrollBar = new ScrollBarHelper()
-      const expectedPadding = originalPadding + scrollBar.getWidth()
-      const expectedPadding2 = originalPadding2 + scrollBar.getWidth()
-
-      scrollBar.hide()
-
-      let currentPadding = getPaddingX(fixedEl)
-      let currentPadding2 = getPaddingX(fixedEl2)
-      expect(getPaddingAttr(fixedEl)).toEqual(`${originalPadding}px`)
-      expect(getPaddingAttr(fixedEl2)).toEqual(`${originalPadding2}px`)
-      expect(currentPadding).toEqual(expectedPadding)
-      expect(currentPadding2).toEqual(expectedPadding2)
-
-      scrollBar.reset()
-      currentPadding = getPaddingX(fixedEl)
-      currentPadding2 = getPaddingX(fixedEl2)
-      expect(getPaddingAttr(fixedEl)).toBeNull()
-      expect(getPaddingAttr(fixedEl2)).toBeNull()
-      expect(currentPadding).toEqual(originalPadding)
-      expect(currentPadding2).toEqual(originalPadding2)
-    })
-
-    it('should remove padding & margin if not existed before adjustment', () => {
-      fixtureEl.innerHTML = [
-        '<div style="height: 110vh; width: 100%">',
-        '  <div class="fixed" id="fixed" style="width: 100vw;"></div>',
-        '  <div class="sticky-top" id="sticky" style=" width: 100vw;"></div>',
-        '</div>'
-      ].join('')
-      doc.style.overflowY = 'scroll'
-
-      const fixedEl = fixtureEl.querySelector('#fixed')
-      const stickyEl = fixtureEl.querySelector('#sticky')
-      const scrollBar = new ScrollBarHelper()
-
-      scrollBar.hide()
-      scrollBar.reset()
-
-      expect(fixedEl.getAttribute('style').includes('padding-right')).toBeFalse()
-      expect(stickyEl.getAttribute('style').includes('margin-right')).toBeFalse()
-    })
-
-    it('should adjust the inline margin and padding of sticky elements', () => {
-      fixtureEl.innerHTML = [
-        '<div style="height: 110vh">',
-        '  <div class="sticky-top" style="margin-right: 10px; padding-right: 20px; width: 100vw; height: 10px"></div>',
-        '</div>'
-      ].join('')
-      doc.style.overflowY = 'scroll'
-
-      const stickyTopEl = fixtureEl.querySelector('.sticky-top')
-      const originalMargin = getMarginX(stickyTopEl)
-      const originalPadding = getPaddingX(stickyTopEl)
-      const scrollBar = new ScrollBarHelper()
-      const expectedMargin = originalMargin - scrollBar.getWidth()
-      const expectedPadding = originalPadding + scrollBar.getWidth()
-      scrollBar.hide()
-
-      expect(getMarginAttr(stickyTopEl)).toEqual(`${originalMargin}px`)
-      expect(getMarginX(stickyTopEl)).toEqual(expectedMargin)
-      expect(getPaddingAttr(stickyTopEl)).toEqual(`${originalPadding}px`)
-      expect(getPaddingX(stickyTopEl)).toEqual(expectedPadding)
-
-      scrollBar.reset()
-      expect(getMarginAttr(stickyTopEl)).toBeNull()
-      expect(getMarginX(stickyTopEl)).toEqual(originalMargin)
-      expect(getPaddingAttr(stickyTopEl)).toBeNull()
-      expect(getPaddingX(stickyTopEl)).toEqual(originalPadding)
-    })
-
-    it('should not adjust the inline margin and padding of sticky and fixed elements when element do not have full width', () => {
-      fixtureEl.innerHTML = '<div class="sticky-top" style="margin-right: 0px; padding-right: 0px; width: 50vw"></div>'
-
-      const stickyTopEl = fixtureEl.querySelector('.sticky-top')
-      const originalMargin = getMarginX(stickyTopEl)
-      const originalPadding = getPaddingX(stickyTopEl)
-
-      const scrollBar = new ScrollBarHelper()
-      scrollBar.hide()
-
-      const currentMargin = getMarginX(stickyTopEl)
-      const currentPadding = getPaddingX(stickyTopEl)
-
-      expect(currentMargin).toEqual(originalMargin)
-      expect(currentPadding).toEqual(originalPadding)
-
-      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', () => {
-      fixtureEl.innerHTML = [
-        '<div style="height: 110vh; width: 100%">',
-        '  <div class="sticky-top" id="sticky" style="width: 100vw"></div>',
-        '</div>'
-      ].join('')
-
-      document.body.style.overflowY = 'scroll'
-      const scrollBar = new ScrollBarHelper()
-
-      const hasPaddingAttr = el => el.hasAttribute('data-bs-padding-right')
-      const hasMarginAttr = el => el.hasAttribute('data-bs-margin-right')
-      const stickyEl = fixtureEl.querySelector('#sticky')
-      const originalPadding = getPaddingX(stickyEl)
-      const originalMargin = getMarginX(stickyEl)
-      const scrollBarWidth = scrollBar.getWidth()
-
-      scrollBar.hide()
-
-      expect(getPaddingX(stickyEl)).toEqual(scrollBarWidth + originalPadding)
-      const expectedMargin = scrollBarWidth + originalMargin
-      expect(getMarginX(stickyEl)).toEqual(expectedMargin === 0 ? expectedMargin : -expectedMargin)
-      expect(hasMarginAttr(stickyEl)).toBeFalse() // We do not have to keep css margin
-      expect(hasPaddingAttr(stickyEl)).toBeFalse() // We do not have to keep css padding
-
-      scrollBar.reset()
-
-      expect(getPaddingX(stickyEl)).toEqual(originalPadding)
-      expect(getPaddingX(stickyEl)).toEqual(originalPadding)
-    })
-
-    describe('Body Handling', () => {
-      it('should ignore other inline styles when trying to restore body defaults ', () => {
-        document.body.style.color = 'red'
-
-        const scrollBar = new ScrollBarHelper()
-        const scrollBarWidth = scrollBar.getWidth()
-        scrollBar.hide()
-
-        expect(getPaddingX(document.body)).toEqual(scrollBarWidth)
-        expect(document.body.style.color).toEqual('red')
-
-        scrollBar.reset()
-      })
-
-      it('should hide scrollbar and reset it to its initial value', () => {
-        const styleSheetPadding = '7px'
-        fixtureEl.innerHTML = [
-          '<style>',
-          '  body {',
-          `    padding-right: ${styleSheetPadding}`,
-          '  }',
-          '</style>'
-        ].join('')
-
-        const el = document.body
-        const inlineStylePadding = '10px'
-        el.style.paddingRight = inlineStylePadding
-
-        const originalPadding = getPaddingX(el)
-        expect(originalPadding).toEqual(parseIntDecimal(inlineStylePadding)) // Respect only the inline style as it has prevails this of css
-        const originalOverFlow = 'auto'
-        el.style.overflow = originalOverFlow
-        const scrollBar = new ScrollBarHelper()
-        const scrollBarWidth = scrollBar.getWidth()
-
-        scrollBar.hide()
-
-        const currentPadding = getPaddingX(el)
-
-        expect(currentPadding).toEqual(scrollBarWidth + originalPadding)
-        expect(currentPadding).toEqual(scrollBarWidth + parseIntDecimal(inlineStylePadding))
-        expect(getPaddingAttr(el)).toEqual(inlineStylePadding)
-        expect(getOverFlow(el)).toEqual('hidden')
-        expect(getOverFlowAttr(el)).toEqual(originalOverFlow)
-
-        scrollBar.reset()
-
-        const currentPadding1 = getPaddingX(el)
-        expect(currentPadding1).toEqual(originalPadding)
-        expect(getPaddingAttr(el)).toBeNull()
-        expect(getOverFlow(el)).toEqual(originalOverFlow)
-        expect(getOverFlowAttr(el)).toBeNull()
-      })
-
-      it('should hide scrollbar and reset it to its initial value - respecting css rules', () => {
-        const styleSheetPadding = '7px'
-        fixtureEl.innerHTML = [
-          '<style>',
-          '  body {',
-          `    padding-right: ${styleSheetPadding}`,
-          '  }',
-          '</style>'
-        ].join('')
-        const el = document.body
-        const originalPadding = getPaddingX(el)
-        const originalOverFlow = 'scroll'
-        el.style.overflow = originalOverFlow
-        const scrollBar = new ScrollBarHelper()
-        const scrollBarWidth = scrollBar.getWidth()
-
-        scrollBar.hide()
-
-        const currentPadding = getPaddingX(el)
-
-        expect(currentPadding).toEqual(scrollBarWidth + originalPadding)
-        expect(currentPadding).toEqual(scrollBarWidth + parseIntDecimal(styleSheetPadding))
-        expect(getPaddingAttr(el)).toBeNull() // We do not have to keep css padding
-        expect(getOverFlow(el)).toEqual('hidden')
-        expect(getOverFlowAttr(el)).toEqual(originalOverFlow)
-
-        scrollBar.reset()
-
-        const currentPadding1 = getPaddingX(el)
-        expect(currentPadding1).toEqual(originalPadding)
-        expect(getPaddingAttr(el)).toBeNull()
-        expect(getOverFlow(el)).toEqual(originalOverFlow)
-        expect(getOverFlowAttr(el)).toBeNull()
-      })
-
-      it('should not adjust the inline body padding when it does not overflow', () => {
-        const originalPadding = getPaddingX(document.body)
-        const scrollBar = new ScrollBarHelper()
-
-        // Hide scrollbars to prevent the body overflowing
-        doc.style.overflowY = 'hidden'
-        doc.style.paddingRight = '0px'
-
-        scrollBar.hide()
-        const currentPadding = getPaddingX(document.body)
-
-        expect(currentPadding).toEqual(originalPadding)
-        scrollBar.reset()
-      })
-
-      it('should not adjust the inline body padding when it does not overflow, even on a scaled display', () => {
-        const originalPadding = getPaddingX(document.body)
-        const scrollBar = new ScrollBarHelper()
-        // Remove body margins as would be done by Bootstrap css
-        document.body.style.margin = '0'
-
-        // Hide scrollbars to prevent the body overflowing
-        doc.style.overflowY = 'hidden'
-
-        // 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%
-        doc.style.paddingRight = '.48px'
-        scrollBar.hide()
-
-        const currentPadding = getPaddingX(document.body)
-
-        expect(currentPadding).toEqual(originalPadding)
-
-        scrollBar.reset()
-      })
-    })
-  })
-})