diff options
-rw-r--r-- | js/src/alert.js | 16 | ||||
-rw-r--r-- | js/src/base-component.js | 12 | ||||
-rw-r--r-- | js/src/button.js | 18 | ||||
-rw-r--r-- | js/src/carousel.js | 64 | ||||
-rw-r--r-- | js/src/collapse.js | 37 | ||||
-rw-r--r-- | js/src/dom/data.js | 2 | ||||
-rw-r--r-- | js/src/dom/event-handler.js | 12 | ||||
-rw-r--r-- | js/src/dom/selector-engine.js | 10 | ||||
-rw-r--r-- | js/src/dropdown.js | 18 | ||||
-rw-r--r-- | js/src/modal.js | 47 | ||||
-rw-r--r-- | js/src/offcanvas.js | 47 | ||||
-rw-r--r-- | js/src/popover.js | 19 | ||||
-rw-r--r-- | js/src/scrollspy.js | 41 | ||||
-rw-r--r-- | js/src/tab.js | 29 | ||||
-rw-r--r-- | js/src/toast.js | 17 | ||||
-rw-r--r-- | js/src/tooltip.js | 88 | ||||
-rw-r--r-- | js/src/util/backdrop.js | 40 | ||||
-rw-r--r-- | js/src/util/focustrap.js | 28 | ||||
-rw-r--r-- | js/src/util/index.js | 36 | ||||
-rw-r--r-- | js/src/util/scrollbar.js | 32 | ||||
-rw-r--r-- | js/src/util/swipe.js | 18 |
21 files changed, 254 insertions, 377 deletions
diff --git a/js/src/alert.js b/js/src/alert.js index 192bea89fe..7d4b555ea0 100644 --- a/js/src/alert.js +++ b/js/src/alert.js @@ -11,9 +11,7 @@ import BaseComponent from './base-component' import { enableDismissTrigger } from './util/component-functions' /** - * ------------------------------------------------------------------------ * Constants - * ------------------------------------------------------------------------ */ const NAME = 'alert' @@ -26,20 +24,16 @@ const CLASS_NAME_FADE = 'fade' const CLASS_NAME_SHOW = 'show' /** - * ------------------------------------------------------------------------ - * Class Definition - * ------------------------------------------------------------------------ + * Class definition */ class Alert extends BaseComponent { // Getters - static get NAME() { return NAME } // Public - close() { const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE) @@ -61,7 +55,6 @@ class Alert extends BaseComponent { } // Static - static jQueryInterface(config) { return this.each(function () { const data = Alert.getOrCreateInstance(this) @@ -80,18 +73,13 @@ class Alert extends BaseComponent { } /** - * ------------------------------------------------------------------------ - * Data Api implementation - * ------------------------------------------------------------------------ + * Data API implementation */ enableDismissTrigger(Alert, 'close') /** - * ------------------------------------------------------------------------ * jQuery - * ------------------------------------------------------------------------ - * add .Alert to jQuery only if jQuery is present */ defineJQueryPlugin(Alert) diff --git a/js/src/base-component.js b/js/src/base-component.js index fb33d7b0cd..3c5eb460ab 100644 --- a/js/src/base-component.js +++ b/js/src/base-component.js @@ -13,13 +13,15 @@ import { import EventHandler from './dom/event-handler' /** - * ------------------------------------------------------------------------ * Constants - * ------------------------------------------------------------------------ */ const VERSION = '5.1.3' +/** + * Class definition + */ + class BaseComponent { constructor(element) { element = getElement(element) @@ -32,6 +34,7 @@ class BaseComponent { Data.set(this._element, this.constructor.DATA_KEY, this) } + // Public dispose() { Data.remove(this._element, this.constructor.DATA_KEY) EventHandler.off(this._element, this.constructor.EVENT_KEY) @@ -45,8 +48,7 @@ class BaseComponent { executeAfterTransition(callback, element, isAnimated) } - /** Static */ - + // Static static getInstance(element) { return Data.get(getElement(element), this.DATA_KEY) } @@ -60,7 +62,7 @@ class BaseComponent { } static get NAME() { - throw new Error('You have to implement the static method "NAME", for each component!') + throw new Error('You have to implement the static method "NAME" for each component!') } static get DATA_KEY() { diff --git a/js/src/button.js b/js/src/button.js index 82d1b87db1..e2a52e7eba 100644 --- a/js/src/button.js +++ b/js/src/button.js @@ -10,9 +10,7 @@ import EventHandler from './dom/event-handler' import BaseComponent from './base-component' /** - * ------------------------------------------------------------------------ * Constants - * ------------------------------------------------------------------------ */ const NAME = 'button' @@ -21,33 +19,26 @@ const EVENT_KEY = `.${DATA_KEY}` const DATA_API_KEY = '.data-api' const CLASS_NAME_ACTIVE = 'active' - const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="button"]' - const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` /** - * ------------------------------------------------------------------------ - * Class Definition - * ------------------------------------------------------------------------ + * Class definition */ class Button extends BaseComponent { // Getters - static get NAME() { return NAME } // Public - toggle() { // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE)) } // Static - static jQueryInterface(config) { return this.each(function () { const data = Button.getOrCreateInstance(this) @@ -60,9 +51,7 @@ class Button extends BaseComponent { } /** - * ------------------------------------------------------------------------ - * Data Api implementation - * ------------------------------------------------------------------------ + * Data API implementation */ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, event => { @@ -75,10 +64,7 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, event => { }) /** - * ------------------------------------------------------------------------ * jQuery - * ------------------------------------------------------------------------ - * add .Button to jQuery only if jQuery is present */ defineJQueryPlugin(Button) diff --git a/js/src/carousel.js b/js/src/carousel.js index f28ee259b3..3589f22067 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -22,9 +22,7 @@ import Swipe from './util/swipe' import BaseComponent from './base-component' /** - * ------------------------------------------------------------------------ * Constants - * ------------------------------------------------------------------------ */ const NAME = 'carousel' @@ -36,34 +34,11 @@ const ARROW_LEFT_KEY = 'ArrowLeft' const ARROW_RIGHT_KEY = 'ArrowRight' const TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch -const Default = { - interval: 5000, - keyboard: true, - slide: false, - pause: 'hover', - wrap: true, - touch: true -} - -const DefaultType = { - interval: '(number|boolean)', - keyboard: 'boolean', - slide: '(boolean|string)', - pause: '(string|boolean)', - wrap: 'boolean', - touch: 'boolean' -} - const ORDER_NEXT = 'next' const ORDER_PREV = 'prev' const DIRECTION_LEFT = 'left' const DIRECTION_RIGHT = 'right' -const KEY_TO_DIRECTION = { - [ARROW_LEFT_KEY]: DIRECTION_RIGHT, - [ARROW_RIGHT_KEY]: DIRECTION_LEFT -} - const EVENT_SLIDE = `slide${EVENT_KEY}` const EVENT_SLID = `slid${EVENT_KEY}` const EVENT_KEYDOWN = `keydown${EVENT_KEY}` @@ -91,11 +66,33 @@ const SELECTOR_INDICATOR = '[data-bs-target]' const SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]' const SELECTOR_DATA_RIDE = '[data-bs-ride="carousel"]' +const KEY_TO_DIRECTION = { + [ARROW_LEFT_KEY]: DIRECTION_RIGHT, + [ARROW_RIGHT_KEY]: DIRECTION_LEFT +} + +const Default = { + interval: 5000, + keyboard: true, + slide: false, + pause: 'hover', + wrap: true, + touch: true +} + +const DefaultType = { + interval: '(number|boolean)', + keyboard: 'boolean', + slide: '(boolean|string)', + pause: '(string|boolean)', + wrap: 'boolean', + touch: 'boolean' +} + /** - * ------------------------------------------------------------------------ - * Class Definition - * ------------------------------------------------------------------------ + * Class definition */ + class Carousel extends BaseComponent { constructor(element, config) { super(element) @@ -114,7 +111,6 @@ class Carousel extends BaseComponent { } // Getters - static get Default() { return Default } @@ -124,7 +120,6 @@ class Carousel extends BaseComponent { } // Public - next() { this._slide(ORDER_NEXT) } @@ -210,7 +205,6 @@ class Carousel extends BaseComponent { } // Private - _getConfig(config) { config = { ...Default, @@ -451,7 +445,6 @@ class Carousel extends BaseComponent { } // Static - static carouselInterface(element, config) { const data = Carousel.getOrCreateInstance(element, config) @@ -513,9 +506,7 @@ class Carousel extends BaseComponent { } /** - * ------------------------------------------------------------------------ - * Data Api implementation - * ------------------------------------------------------------------------ + * Data API implementation */ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_SLIDE, Carousel.dataApiClickHandler) @@ -529,10 +520,7 @@ EventHandler.on(window, EVENT_LOAD_DATA_API, () => { }) /** - * ------------------------------------------------------------------------ * jQuery - * ------------------------------------------------------------------------ - * add .Carousel to jQuery only if jQuery is present */ defineJQueryPlugin(Carousel) diff --git a/js/src/collapse.js b/js/src/collapse.js index b32ce01862..39093c7a2a 100644 --- a/js/src/collapse.js +++ b/js/src/collapse.js @@ -20,9 +20,7 @@ import SelectorEngine from './dom/selector-engine' import BaseComponent from './base-component' /** - * ------------------------------------------------------------------------ * Constants - * ------------------------------------------------------------------------ */ const NAME = 'collapse' @@ -30,16 +28,6 @@ const DATA_KEY = 'bs.collapse' const EVENT_KEY = `.${DATA_KEY}` const DATA_API_KEY = '.data-api' -const Default = { - toggle: true, - parent: null -} - -const DefaultType = { - toggle: 'boolean', - parent: '(null|element)' -} - const EVENT_SHOW = `show${EVENT_KEY}` const EVENT_SHOWN = `shown${EVENT_KEY}` const EVENT_HIDE = `hide${EVENT_KEY}` @@ -59,10 +47,18 @@ const HEIGHT = 'height' const SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing' const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="collapse"]' +const Default = { + toggle: true, + parent: null +} + +const DefaultType = { + toggle: 'boolean', + parent: '(null|element)' +} + /** - * ------------------------------------------------------------------------ - * Class Definition - * ------------------------------------------------------------------------ + * Class definition */ class Collapse extends BaseComponent { @@ -98,7 +94,6 @@ class Collapse extends BaseComponent { } // Getters - static get Default() { return Default } @@ -108,7 +103,6 @@ class Collapse extends BaseComponent { } // Public - toggle() { if (this._isShown()) { this.hide() @@ -230,7 +224,6 @@ class Collapse extends BaseComponent { } // Private - _getConfig(config) { config = { ...Default, @@ -281,7 +274,6 @@ class Collapse extends BaseComponent { } // Static - static jQueryInterface(config) { return this.each(function () { const _config = {} @@ -303,9 +295,7 @@ class Collapse extends BaseComponent { } /** - * ------------------------------------------------------------------------ - * Data Api implementation - * ------------------------------------------------------------------------ + * Data API implementation */ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { @@ -323,10 +313,7 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function ( }) /** - * ------------------------------------------------------------------------ * jQuery - * ------------------------------------------------------------------------ - * add .Collapse to jQuery only if jQuery is present */ defineJQueryPlugin(Collapse) diff --git a/js/src/dom/data.js b/js/src/dom/data.js index c702fc82cb..4209f3188e 100644 --- a/js/src/dom/data.js +++ b/js/src/dom/data.js @@ -6,9 +6,7 @@ */ /** - * ------------------------------------------------------------------------ * Constants - * ------------------------------------------------------------------------ */ const elementMap = new Map() diff --git a/js/src/dom/event-handler.js b/js/src/dom/event-handler.js index bf01694f4a..b9ebce3244 100644 --- a/js/src/dom/event-handler.js +++ b/js/src/dom/event-handler.js @@ -8,9 +8,7 @@ import { getjQuery } from '../util/index' /** - * ------------------------------------------------------------------------ * Constants - * ------------------------------------------------------------------------ */ const namespaceRegex = /[^.]*(?=\..*)\.|.*/ @@ -73,9 +71,7 @@ const nativeEvents = new Set([ ]) /** - * ------------------------------------------------------------------------ * Private methods - * ------------------------------------------------------------------------ */ function getUidEvent(element, uid) { @@ -143,7 +139,6 @@ function findHandler(events, handler, delegationSelector = null) { function normalizeParams(originalTypeEvent, handler, delegationFn) { const delegation = typeof handler === 'string' const originalHandler = delegation ? delegationFn : handler - let typeEvent = getTypeEvent(originalTypeEvent) const isNative = nativeEvents.has(typeEvent) @@ -224,7 +219,6 @@ function removeNamespacedHandlers(element, events, typeEvent, namespace) { for (const handlerKey of Object.keys(storeElementEvent)) { if (handlerKey.includes(namespace)) { const event = storeElementEvent[handlerKey] - removeHandler(element, events, typeEvent, event.originalHandler, event.delegationSelector) } } @@ -277,7 +271,6 @@ const EventHandler = { if (!inNamespace || originalTypeEvent.includes(handlerKey)) { const event = storeElementEvent[keyHandlers] - removeHandler(element, events, typeEvent, event.originalHandler, event.delegationSelector) } } @@ -312,10 +305,7 @@ const EventHandler = { evt = document.createEvent('HTMLEvents') evt.initEvent(typeEvent, bubbles, true) } else { - evt = new CustomEvent(event, { - bubbles, - cancelable: true - }) + evt = new CustomEvent(event, { bubbles, cancelable: true }) } // merge custom information in our event diff --git a/js/src/dom/selector-engine.js b/js/src/dom/selector-engine.js index 54f270f4c6..af27dc3795 100644 --- a/js/src/dom/selector-engine.js +++ b/js/src/dom/selector-engine.js @@ -5,14 +5,12 @@ * -------------------------------------------------------------------------- */ +import { isDisabled, isVisible } from '../util/index' + /** - * ------------------------------------------------------------------------ * Constants - * ------------------------------------------------------------------------ */ -import { isDisabled, isVisible } from '../util/index' - const NODE_TEXT = 3 const SelectorEngine = { @@ -25,13 +23,11 @@ const SelectorEngine = { }, children(element, selector) { - return [].concat(...element.children) - .filter(child => child.matches(selector)) + return [].concat(...element.children).filter(child => child.matches(selector)) }, parents(element, selector) { const parents = [] - let ancestor = element.parentNode while (ancestor && ancestor.nodeType === Node.ELEMENT_NODE && ancestor.nodeType !== NODE_TEXT) { diff --git a/js/src/dropdown.js b/js/src/dropdown.js index 360808eca0..6129707e26 100644 --- a/js/src/dropdown.js +++ b/js/src/dropdown.js @@ -6,7 +6,6 @@ */ import * as Popper from '@popperjs/core' - import { defineJQueryPlugin, getElement, @@ -25,9 +24,7 @@ import SelectorEngine from './dom/selector-engine' import BaseComponent from './base-component' /** - * ------------------------------------------------------------------------ * Constants - * ------------------------------------------------------------------------ */ const NAME = 'dropdown' @@ -89,9 +86,7 @@ const DefaultType = { } /** - * ------------------------------------------------------------------------ - * Class Definition - * ------------------------------------------------------------------------ + * Class definition */ class Dropdown extends BaseComponent { @@ -105,7 +100,6 @@ class Dropdown extends BaseComponent { } // Getters - static get Default() { return Default } @@ -119,7 +113,6 @@ class Dropdown extends BaseComponent { } // Public - toggle() { return this._isShown() ? this.hide() : this.show() } @@ -193,7 +186,6 @@ class Dropdown extends BaseComponent { } // Private - _completeHide(relatedTarget) { const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE, relatedTarget) if (hideEvent.defaultPrevented) { @@ -354,7 +346,6 @@ class Dropdown extends BaseComponent { } // Static - static jQueryInterface(config) { return this.each(function () { const data = Dropdown.getOrCreateInstance(this, config) @@ -474,9 +465,7 @@ class Dropdown extends BaseComponent { } /** - * ------------------------------------------------------------------------ - * Data Api implementation - * ------------------------------------------------------------------------ + * Data API implementation */ EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE, Dropdown.dataApiKeydownHandler) @@ -489,10 +478,7 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function ( }) /** - * ------------------------------------------------------------------------ * jQuery - * ------------------------------------------------------------------------ - * add .Dropdown to jQuery only if jQuery is present */ defineJQueryPlugin(Dropdown) diff --git a/js/src/modal.js b/js/src/modal.js index 2efbaa4b35..bfb980236c 100644 --- a/js/src/modal.js +++ b/js/src/modal.js @@ -23,9 +23,7 @@ import FocusTrap from './util/focustrap' import { enableDismissTrigger } from './util/component-functions' /** - * ------------------------------------------------------------------------ * Constants - * ------------------------------------------------------------------------ */ const NAME = 'modal' @@ -34,18 +32,6 @@ const EVENT_KEY = `.${DATA_KEY}` const DATA_API_KEY = '.data-api' const ESCAPE_KEY = 'Escape' -const Default = { - backdrop: true, - keyboard: true, - focus: true -} - -const DefaultType = { - backdrop: '(boolean|string)', - keyboard: 'boolean', - focus: 'boolean' -} - const EVENT_HIDE = `hide${EVENT_KEY}` const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}` const EVENT_HIDDEN = `hidden${EVENT_KEY}` @@ -68,10 +54,20 @@ const SELECTOR_DIALOG = '.modal-dialog' const SELECTOR_MODAL_BODY = '.modal-body' const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="modal"]' +const Default = { + backdrop: true, + keyboard: true, + focus: true +} + +const DefaultType = { + backdrop: '(boolean|string)', + keyboard: 'boolean', + focus: 'boolean' +} + /** - * ------------------------------------------------------------------------ - * Class Definition - * ------------------------------------------------------------------------ + * Class definition */ class Modal extends BaseComponent { @@ -89,7 +85,6 @@ class Modal extends BaseComponent { } // Getters - static get Default() { return Default } @@ -99,7 +94,6 @@ class Modal extends BaseComponent { } // Public - toggle(relatedTarget) { return this._isShown ? this.hide() : this.show(relatedTarget) } @@ -189,7 +183,6 @@ class Modal extends BaseComponent { } // Private - _initializeBackDrop() { return new Backdrop({ isVisible: Boolean(this._config.backdrop), // 'static' option will be translated to true, and booleans will keep their value @@ -345,9 +338,9 @@ class Modal extends BaseComponent { this._element.focus() } - // ---------------------------------------------------------------------- - // the following methods are used to handle overflowing modals - // ---------------------------------------------------------------------- + /** + * The following methods are used to handle overflowing modals + */ _adjustDialog() { const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight @@ -369,7 +362,6 @@ class Modal extends BaseComponent { } // Static - static jQueryInterface(config, relatedTarget) { return this.each(function () { const data = Modal.getOrCreateInstance(this, config) @@ -388,9 +380,7 @@ class Modal extends BaseComponent { } /** - * ------------------------------------------------------------------------ - * Data Api implementation - * ------------------------------------------------------------------------ + * Data API implementation */ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { @@ -427,10 +417,7 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function ( enableDismissTrigger(Modal) /** - * ------------------------------------------------------------------------ * jQuery - * ------------------------------------------------------------------------ - * add .Modal to jQuery only if jQuery is present */ defineJQueryPlugin(Modal) diff --git a/js/src/offcanvas.js b/js/src/offcanvas.js index c501ca14df..6878b1f628 100644 --- a/js/src/offcanvas.js +++ b/js/src/offcanvas.js @@ -22,9 +22,7 @@ import FocusTrap from './util/focustrap' import { enableDismissTrigger } from './util/component-functions' /** - * ------------------------------------------------------------------------ * Constants - * ------------------------------------------------------------------------ */ const NAME = 'offcanvas' @@ -34,18 +32,6 @@ const DATA_API_KEY = '.data-api' const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}` const ESCAPE_KEY = 'Escape' -const Default = { - backdrop: true, - keyboard: true, - scroll: false -} - -const DefaultType = { - backdrop: 'boolean', - keyboard: 'boolean', - scroll: 'boolean' -} - const CLASS_NAME_SHOW = 'show' const CLASS_NAME_BACKDROP = 'offcanvas-backdrop' const OPEN_SELECTOR = '.offcanvas.show' @@ -59,10 +45,20 @@ const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}` const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="offcanvas"]' +const Default = { + backdrop: true, + keyboard: true, + scroll: false +} + +const DefaultType = { + backdrop: 'boolean', + keyboard: 'boolean', + scroll: 'boolean' +} + /** - * ------------------------------------------------------------------------ - * Class Definition - * ------------------------------------------------------------------------ + * Class definition */ class Offcanvas extends BaseComponent { @@ -77,7 +73,6 @@ class Offcanvas extends BaseComponent { } // Getters - static get NAME() { return NAME } @@ -87,7 +82,6 @@ class Offcanvas extends BaseComponent { } // Public - toggle(relatedTarget) { return this._isShown ? this.hide() : this.show(relatedTarget) } @@ -168,7 +162,6 @@ class Offcanvas extends BaseComponent { } // Private - _getConfig(config) { config = { ...Default, @@ -204,7 +197,6 @@ class Offcanvas extends BaseComponent { } // Static - static jQueryInterface(config) { return this.each(function () { const data = Offcanvas.getOrCreateInstance(this, config) @@ -223,9 +215,7 @@ class Offcanvas extends BaseComponent { } /** - * ------------------------------------------------------------------------ - * Data Api implementation - * ------------------------------------------------------------------------ + * Data API implementation */ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { @@ -247,9 +237,9 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function ( }) // avoid conflict when clicking a toggler of an offcanvas, while another is open - const allReadyOpen = SelectorEngine.findOne(OPEN_SELECTOR) - if (allReadyOpen && allReadyOpen !== target) { - Offcanvas.getInstance(allReadyOpen).hide() + const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR) + if (alreadyOpen && alreadyOpen !== target) { + Offcanvas.getInstance(alreadyOpen).hide() } const data = Offcanvas.getOrCreateInstance(target) @@ -263,10 +253,9 @@ EventHandler.on(window, EVENT_LOAD_DATA_API, () => { }) enableDismissTrigger(Offcanvas) + /** - * ------------------------------------------------------------------------ * jQuery - * ------------------------------------------------------------------------ */ defineJQueryPlugin(Offcanvas) diff --git a/js/src/popover.js b/js/src/popover.js index aa9b0bc9ea..144ec1cad5 100644 --- a/js/src/popover.js +++ b/js/src/popover.js @@ -9,9 +9,7 @@ import { defineJQueryPlugin } from './util/index' import Tooltip from './tooltip' /** - * ------------------------------------------------------------------------ * Constants - * ------------------------------------------------------------------------ */ const NAME = 'popover' @@ -19,6 +17,9 @@ const DATA_KEY = 'bs.popover' const EVENT_KEY = `.${DATA_KEY}` const CLASS_PREFIX = 'bs-popover' +const SELECTOR_TITLE = '.popover-header' +const SELECTOR_CONTENT = '.popover-body' + const Default = { ...Tooltip.Default, placement: 'right', @@ -50,18 +51,12 @@ const Event = { MOUSELEAVE: `mouseleave${EVENT_KEY}` } -const SELECTOR_TITLE = '.popover-header' -const SELECTOR_CONTENT = '.popover-body' - /** - * ------------------------------------------------------------------------ - * Class Definition - * ------------------------------------------------------------------------ + * Class definition */ class Popover extends Tooltip { // Getters - static get Default() { return Default } @@ -79,7 +74,6 @@ class Popover extends Tooltip { } // Overrides - isWithContent() { return this.getTitle() || this._getContent() } @@ -90,7 +84,6 @@ class Popover extends Tooltip { } // Private - _getContent() { return this._resolvePossibleFunction(this._config.content) } @@ -100,7 +93,6 @@ class Popover extends Tooltip { } // Static - static jQueryInterface(config) { return this.each(function () { const data = Popover.getOrCreateInstance(this, config) @@ -117,10 +109,7 @@ class Popover extends Tooltip { } /** - * ------------------------------------------------------------------------ * jQuery - * ------------------------------------------------------------------------ - * add .Popover to jQuery only if jQuery is present */ defineJQueryPlugin(Popover) diff --git a/js/src/scrollspy.js b/js/src/scrollspy.js index bdc22653b6..27bc0cd877 100644 --- a/js/src/scrollspy.js +++ b/js/src/scrollspy.js @@ -17,9 +17,7 @@ import SelectorEngine from './dom/selector-engine' import BaseComponent from './base-component' /** - * ------------------------------------------------------------------------ * Constants - * ------------------------------------------------------------------------ */ const NAME = 'scrollspy' @@ -27,18 +25,6 @@ const DATA_KEY = 'bs.scrollspy' const EVENT_KEY = `.${DATA_KEY}` const DATA_API_KEY = '.data-api' -const Default = { - offset: 10, - method: 'auto', - target: '' -} - -const DefaultType = { - offset: 'number', - method: 'string', - target: '(string|element)' -} - const EVENT_ACTIVATE = `activate${EVENT_KEY}` const EVENT_SCROLL = `scroll${EVENT_KEY}` const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}` @@ -58,10 +44,20 @@ const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle' const METHOD_OFFSET = 'offset' const METHOD_POSITION = 'position' +const Default = { + offset: 10, + method: 'auto', + target: '' +} + +const DefaultType = { + offset: 'number', + method: 'string', + target: '(string|element)' +} + /** - * ------------------------------------------------------------------------ - * Class Definition - * ------------------------------------------------------------------------ + * Class definition */ class ScrollSpy extends BaseComponent { @@ -81,7 +77,6 @@ class ScrollSpy extends BaseComponent { } // Getters - static get Default() { return Default } @@ -91,7 +86,6 @@ class ScrollSpy extends BaseComponent { } // Public - refresh() { const autoMethod = this._scrollElement === this._scrollElement.window ? METHOD_OFFSET : @@ -141,7 +135,6 @@ class ScrollSpy extends BaseComponent { } // Private - _getConfig(config) { config = { ...Default, @@ -257,7 +250,6 @@ class ScrollSpy extends BaseComponent { } // Static - static jQueryInterface(config) { return this.each(function () { const data = ScrollSpy.getOrCreateInstance(this, config) @@ -276,9 +268,7 @@ class ScrollSpy extends BaseComponent { } /** - * ------------------------------------------------------------------------ - * Data Api implementation - * ------------------------------------------------------------------------ + * Data API implementation */ EventHandler.on(window, EVENT_LOAD_DATA_API, () => { @@ -288,10 +278,7 @@ EventHandler.on(window, EVENT_LOAD_DATA_API, () => { }) /** - * ------------------------------------------------------------------------ * jQuery - * ------------------------------------------------------------------------ - * add .ScrollSpy to jQuery only if jQuery is present */ defineJQueryPlugin(ScrollSpy) diff --git a/js/src/tab.js b/js/src/tab.js index 1fc00f7976..4a018ca77d 100644 --- a/js/src/tab.js +++ b/js/src/tab.js @@ -16,9 +16,7 @@ import SelectorEngine from './dom/selector-engine' import BaseComponent from './base-component' /** - * ------------------------------------------------------------------------ * Constants - * ------------------------------------------------------------------------ */ const NAME = 'tab' @@ -46,20 +44,16 @@ const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle' const SELECTOR_DROPDOWN_ACTIVE_CHILD = ':scope > .dropdown-menu .active' /** - * ------------------------------------------------------------------------ - * Class Definition - * ------------------------------------------------------------------------ + * Class definition */ class Tab extends BaseComponent { // Getters - static get NAME() { return NAME } // Public - show() { if ((this._element.parentNode && this._element.parentNode.nodeType === Node.ELEMENT_NODE && @@ -78,9 +72,7 @@ class Tab extends BaseComponent { } const hideEvent = previous ? - EventHandler.trigger(previous, EVENT_HIDE, { - relatedTarget: this._element - }) : + EventHandler.trigger(previous, EVENT_HIDE, { relatedTarget: this._element }) : null const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, { @@ -94,12 +86,8 @@ class Tab extends BaseComponent { this._activate(this._element, listElement) const complete = () => { - EventHandler.trigger(previous, EVENT_HIDDEN, { - relatedTarget: this._element - }) - EventHandler.trigger(this._element, EVENT_SHOWN, { - relatedTarget: previous - }) + EventHandler.trigger(previous, EVENT_HIDDEN, { relatedTarget: this._element }) + EventHandler.trigger(this._element, EVENT_SHOWN, { relatedTarget: previous }) } if (target) { @@ -110,7 +98,6 @@ class Tab extends BaseComponent { } // Private - _activate(element, container, callback) { const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ? SelectorEngine.find(SELECTOR_ACTIVE_UL, container) : @@ -178,7 +165,6 @@ class Tab extends BaseComponent { } // Static - static jQueryInterface(config) { return this.each(function () { const data = Tab.getOrCreateInstance(this) @@ -195,9 +181,7 @@ class Tab extends BaseComponent { } /** - * ------------------------------------------------------------------------ - * Data Api implementation - * ------------------------------------------------------------------------ + * Data API implementation */ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { @@ -214,10 +198,7 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function ( }) /** - * ------------------------------------------------------------------------ * jQuery - * ------------------------------------------------------------------------ - * add .Tab to jQuery only if jQuery is present */ defineJQueryPlugin(Tab) diff --git a/js/src/toast.js b/js/src/toast.js index 780279be97..c45721c8f8 100644 --- a/js/src/toast.js +++ b/js/src/toast.js @@ -16,9 +16,7 @@ import BaseComponent from './base-component' import { enableDismissTrigger } from './util/component-functions' /** - * ------------------------------------------------------------------------ * Constants - * ------------------------------------------------------------------------ */ const NAME = 'toast' @@ -52,9 +50,7 @@ const Default = { } /** - * ------------------------------------------------------------------------ - * Class Definition - * ------------------------------------------------------------------------ + * Class definition */ class Toast extends BaseComponent { @@ -69,7 +65,6 @@ class Toast extends BaseComponent { } // Getters - static get DefaultType() { return DefaultType } @@ -83,7 +78,6 @@ class Toast extends BaseComponent { } // Public - show() { const showEvent = EventHandler.trigger(this._element, EVENT_SHOW) @@ -145,7 +139,6 @@ class Toast extends BaseComponent { } // Private - _getConfig(config) { config = { ...Default, @@ -212,7 +205,6 @@ class Toast extends BaseComponent { } // Static - static jQueryInterface(config) { return this.each(function () { const data = Toast.getOrCreateInstance(this, config) @@ -228,13 +220,14 @@ class Toast extends BaseComponent { } } +/** + * Data API implementation + */ + enableDismissTrigger(Toast) /** - * ------------------------------------------------------------------------ * jQuery - * ------------------------------------------------------------------------ - * add .Toast to jQuery only if jQuery is present */ defineJQueryPlugin(Toast) diff --git a/js/src/tooltip.js b/js/src/tooltip.js index 7a8986548f..f069dc7515 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -6,7 +6,6 @@ */ import * as Popper from '@popperjs/core' - import { defineJQueryPlugin, findShadowRoot, @@ -25,9 +24,7 @@ import SelectorEngine from './dom/selector-engine' import BaseComponent from './base-component' /** - * ------------------------------------------------------------------------ * Constants - * ------------------------------------------------------------------------ */ const NAME = 'tooltip' @@ -36,25 +33,22 @@ const EVENT_KEY = `.${DATA_KEY}` const CLASS_PREFIX = 'bs-tooltip' const DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn']) -const DefaultType = { - animation: 'boolean', - template: 'string', - title: '(string|element|function)', - trigger: 'string', - delay: '(number|object)', - html: 'boolean', - selector: '(string|boolean)', - placement: '(string|function)', - offset: '(array|string|function)', - container: '(string|element|boolean)', - fallbackPlacements: 'array', - boundary: '(string|element)', - customClass: '(string|function)', - sanitize: 'boolean', - sanitizeFn: '(null|function)', - allowList: 'object', - popperConfig: '(null|object|function)' -} +const CLASS_NAME_FADE = 'fade' +const CLASS_NAME_MODAL = 'modal' +const CLASS_NAME_SHOW = 'show' + +const HOVER_STATE_SHOW = 'show' +const HOVER_STATE_OUT = 'out' + +const SELECTOR_TOOLTIP_INNER = '.tooltip-inner' +const SELECTOR_MODAL = `.${CLASS_NAME_MODAL}` + +const EVENT_MODAL_HIDE = 'hide.bs.modal' + +const TRIGGER_HOVER = 'hover' +const TRIGGER_FOCUS = 'focus' +const TRIGGER_CLICK = 'click' +const TRIGGER_MANUAL = 'manual' const AttachmentMap = { AUTO: 'auto', @@ -87,6 +81,26 @@ const Default = { popperConfig: null } +const DefaultType = { + animation: 'boolean', + template: 'string', + title: '(string|element|function)', + trigger: 'string', + delay: '(number|object)', + html: 'boolean', + selector: '(string|boolean)', + placement: '(string|function)', + offset: '(array|string|function)', + container: '(string|element|boolean)', + fallbackPlacements: 'array', + boundary: '(string|element)', + customClass: '(string|function)', + sanitize: 'boolean', + sanitizeFn: '(null|function)', + allowList: 'object', + popperConfig: '(null|object|function)' +} + const Event = { HIDE: `hide${EVENT_KEY}`, HIDDEN: `hidden${EVENT_KEY}`, @@ -100,27 +114,8 @@ const Event = { MOUSELEAVE: `mouseleave${EVENT_KEY}` } -const CLASS_NAME_FADE = 'fade' -const CLASS_NAME_MODAL = 'modal' -const CLASS_NAME_SHOW = 'show' - -const HOVER_STATE_SHOW = 'show' -const HOVER_STATE_OUT = 'out' - -const SELECTOR_TOOLTIP_INNER = '.tooltip-inner' -const SELECTOR_MODAL = `.${CLASS_NAME_MODAL}` - -const EVENT_MODAL_HIDE = 'hide.bs.modal' - -const TRIGGER_HOVER = 'hover' -const TRIGGER_FOCUS = 'focus' -const TRIGGER_CLICK = 'click' -const TRIGGER_MANUAL = 'manual' - /** - * ------------------------------------------------------------------------ - * Class Definition - * ------------------------------------------------------------------------ + * Class definition */ class Tooltip extends BaseComponent { @@ -131,7 +126,7 @@ class Tooltip extends BaseComponent { super(element) - // private + // Private this._isEnabled = true this._timeout = 0 this._hoverState = '' @@ -146,7 +141,6 @@ class Tooltip extends BaseComponent { } // Getters - static get Default() { return Default } @@ -164,7 +158,6 @@ class Tooltip extends BaseComponent { } // Public - enable() { this._isEnabled = true } @@ -358,7 +351,6 @@ class Tooltip extends BaseComponent { } // Protected - isWithContent() { return Boolean(this.getTitle()) } @@ -446,7 +438,6 @@ class Tooltip extends BaseComponent { } // Private - _initializeOnDelegatedTarget(event, context) { return context || this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig()) } @@ -754,10 +745,7 @@ class Tooltip extends BaseComponent { } /** - * ------------------------------------------------------------------------ * jQuery - * ------------------------------------------------------------------------ - * add .Tooltip to jQuery only if jQuery is present */ defineJQueryPlugin(Tooltip) diff --git a/js/src/util/backdrop.js b/js/src/util/backdrop.js index 04c763518b..fb1b2776bc 100644 --- a/js/src/util/backdrop.js +++ b/js/src/util/backdrop.js @@ -8,6 +8,15 @@ import EventHandler from '../dom/event-handler' import { execute, executeAfterTransition, getElement, reflow, typeCheckConfig } from './index' +/** + * Constants + */ + +const NAME = 'backdrop' +const CLASS_NAME_FADE = 'fade' +const CLASS_NAME_SHOW = 'show' +const EVENT_MOUSEDOWN = `mousedown.bs.${NAME}` + const Default = { className: 'modal-backdrop', isVisible: true, // if false, we use the backdrop helper without adding any element to the dom @@ -23,11 +32,10 @@ const DefaultType = { rootElement: '(element|string)', clickCallback: '(function|null)' } -const NAME = 'backdrop' -const CLASS_NAME_FADE = 'fade' -const CLASS_NAME_SHOW = 'show' -const EVENT_MOUSEDOWN = `mousedown.bs.${NAME}` +/** + * Class definition + */ class Backdrop { constructor(config) { @@ -36,6 +44,7 @@ class Backdrop { this._element = null } + // Public show(callback) { if (!this._config.isVisible) { execute(callback) @@ -69,8 +78,18 @@ class Backdrop { }) } - // Private + dispose() { + if (!this._isAppended) { + return + } + EventHandler.off(this._element, EVENT_MOUSEDOWN) + + this._element.remove() + this._isAppended = false + } + + // Private _getElement() { if (!this._element) { const backdrop = document.createElement('div') @@ -111,17 +130,6 @@ class Backdrop { this._isAppended = true } - dispose() { - if (!this._isAppended) { - return - } - - EventHandler.off(this._element, EVENT_MOUSEDOWN) - - this._element.remove() - this._isAppended = false - } - _emulateAnimation(callback) { executeAfterTransition(callback, this._getElement(), this._config.isAnimated) } diff --git a/js/src/util/focustrap.js b/js/src/util/focustrap.js index 44d5f47ebf..a1975f4899 100644 --- a/js/src/util/focustrap.js +++ b/js/src/util/focustrap.js @@ -9,15 +9,9 @@ import EventHandler from '../dom/event-handler' import SelectorEngine from '../dom/selector-engine' import { typeCheckConfig } from './index' -const Default = { - trapElement: null, // The element to trap focus inside of - autofocus: true -} - -const DefaultType = { - trapElement: 'element', - autofocus: 'boolean' -} +/** + * Constants + */ const NAME = 'focustrap' const DATA_KEY = 'bs.focustrap' @@ -29,6 +23,20 @@ const TAB_KEY = 'Tab' const TAB_NAV_FORWARD = 'forward' const TAB_NAV_BACKWARD = 'backward' +const Default = { + trapElement: null, // The element to trap focus inside of + autofocus: true +} + +const DefaultType = { + trapElement: 'element', + autofocus: 'boolean' +} + +/** + * Class definition + */ + class FocusTrap { constructor(config) { this._config = this._getConfig(config) @@ -36,6 +44,7 @@ class FocusTrap { this._lastTabNavDirection = null } + // Public activate() { const { trapElement, autofocus } = this._config @@ -64,7 +73,6 @@ class FocusTrap { } // Private - _handleFocusin(event) { const { target } = event const { trapElement } = this._config diff --git a/js/src/util/index.js b/js/src/util/index.js index 93f7223b12..0ba6ce6f8c 100644 --- a/js/src/util/index.js +++ b/js/src/util/index.js @@ -19,9 +19,7 @@ const toType = obj => { } /** - * -------------------------------------------------------------------------- - * Public Util Api - * -------------------------------------------------------------------------- + * Public Util API */ const getUID = prefix => { @@ -113,7 +111,8 @@ const isElement = obj => { } const getElement = obj => { - if (isElement(obj)) { // it's a jQuery object or a node element + // it's a jQuery object or a node element + if (isElement(obj)) { return obj.jquery ? obj[0] : obj } @@ -196,8 +195,7 @@ const noop = () => {} * @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation */ const reflow = element => { - // eslint-disable-next-line no-unused-expressions - element.offsetHeight + element.offsetHeight // eslint-disable-line no-unused-expressions } const getjQuery = () => { @@ -312,24 +310,24 @@ const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed } export { + defineJQueryPlugin, + execute, + executeAfterTransition, + findShadowRoot, getElement, - getUID, - getSelectorFromElement, getElementFromSelector, + getjQuery, + getNextActiveElement, + getSelectorFromElement, getTransitionDurationFromElement, - triggerTransitionEnd, + getUID, + isDisabled, isElement, - typeCheckConfig, + isRTL, isVisible, - isDisabled, - findShadowRoot, noop, - getNextActiveElement, - reflow, - getjQuery, onDOMContentLoaded, - isRTL, - defineJQueryPlugin, - execute, - executeAfterTransition + reflow, + triggerTransitionEnd, + typeCheckConfig } diff --git a/js/src/util/scrollbar.js b/js/src/util/scrollbar.js index 16e14d1f3c..55b7244ab3 100644 --- a/js/src/util/scrollbar.js +++ b/js/src/util/scrollbar.js @@ -9,14 +9,23 @@ import SelectorEngine from '../dom/selector-engine' import Manipulator from '../dom/manipulator' import { isElement } from './index' +/** + * Constants + */ + const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top' const SELECTOR_STICKY_CONTENT = '.sticky-top' +/** + * 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 @@ -33,6 +42,18 @@ class ScrollBarHelper { this._setElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight', calculatedValue => calculatedValue - width) } + reset() { + this._resetElementAttributes(this._element, 'overflow') + this._resetElementAttributes(this._element, 'paddingRight') + this._resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight') + this._resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight') + } + + isOverflowing() { + return this.getWidth() > 0 + } + + // Private _disableOverFlow() { this._saveInitialAttribute(this._element, 'overflow') this._element.style.overflow = 'hidden' @@ -53,13 +74,6 @@ class ScrollBarHelper { 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) { @@ -90,10 +104,6 @@ class ScrollBarHelper { } } } - - isOverflowing() { - return this.getWidth() > 0 - } } export default ScrollBarHelper diff --git a/js/src/util/swipe.js b/js/src/util/swipe.js index a78f598d9d..87a5f7f5ae 100644 --- a/js/src/util/swipe.js +++ b/js/src/util/swipe.js @@ -1,6 +1,17 @@ +/** + * -------------------------------------------------------------------------- + * Bootstrap (v5.1.3): util/swipe.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + * -------------------------------------------------------------------------- + */ + import EventHandler from '../dom/event-handler' import { execute, typeCheckConfig } from './index' +/** + * Constants + */ + const NAME = 'swipe' const EVENT_KEY = '.bs.swipe' const EVENT_TOUCHSTART = `touchstart${EVENT_KEY}` @@ -25,6 +36,10 @@ const DefaultType = { endCallback: '(function|null)' } +/** + * Class definition + */ + class Swipe { constructor(element, config) { this._element = element @@ -39,10 +54,12 @@ class Swipe { this._initEvents() } + // Public dispose() { EventHandler.off(this._element, EVENT_KEY) } + // Private _start(event) { if (!this._supportPointerEvents) { this._deltaX = event.touches[0].clientX @@ -114,6 +131,7 @@ class Swipe { return this._supportPointerEvents && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH) } + // Static static isSupported() { return 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0 } |