diff --git a/js/src/alert.js b/js/src/alert.js index 88232bceba..a0e6cab970 100644 --- a/js/src/alert.js +++ b/js/src/alert.js @@ -8,7 +8,6 @@ import BaseComponent from './base-component.js' import EventHandler from './dom/event-handler.js' import { enableDismissTrigger } from './util/component-functions.js' -import { defineJQueryPlugin } from './util/index.js' /** * Constants @@ -53,23 +52,6 @@ class Alert extends BaseComponent { EventHandler.trigger(this._element, EVENT_CLOSED) this.dispose() } - - // Static - static jQueryInterface(config) { - return this.each(function () { - const data = Alert.getOrCreateInstance(this) - - if (typeof config !== 'string') { - return - } - - if (data[config] === undefined || config.startsWith('_') || config === 'constructor') { - throw new TypeError(`No method named "${config}"`) - } - - data[config](this) - }) - } } /** @@ -78,10 +60,4 @@ class Alert extends BaseComponent { enableDismissTrigger(Alert, 'close') -/** - * jQuery - */ - -defineJQueryPlugin(Alert) - export default Alert diff --git a/js/src/button.js b/js/src/button.js index a797f5050d..7697edecf2 100644 --- a/js/src/button.js +++ b/js/src/button.js @@ -7,7 +7,6 @@ import BaseComponent from './base-component.js' import EventHandler from './dom/event-handler.js' -import { defineJQueryPlugin } from './util/index.js' /** * Constants @@ -37,17 +36,6 @@ class Button extends BaseComponent { // 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) - - if (config === 'toggle') { - data[config]() - } - }) - } } /** @@ -63,10 +51,4 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, event => { data.toggle() }) -/** - * jQuery - */ - -defineJQueryPlugin(Button) - export default Button diff --git a/js/src/carousel.js b/js/src/carousel.js index 68d11a32f2..a8df5f7b53 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -10,7 +10,6 @@ import EventHandler from './dom/event-handler.js' import Manipulator from './dom/manipulator.js' import SelectorEngine from './dom/selector-engine.js' import { - defineJQueryPlugin, getNextActiveElement, isRTL, isVisible, @@ -404,25 +403,6 @@ class Carousel extends BaseComponent { return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT } - // Static - static jQueryInterface(config) { - return this.each(function () { - const data = Carousel.getOrCreateInstance(this, config) - - if (typeof config === 'number') { - data.to(config) - return - } - - if (typeof config === 'string') { - if (data[config] === undefined || config.startsWith('_') || config === 'constructor') { - throw new TypeError(`No method named "${config}"`) - } - - data[config]() - } - }) - } } /** @@ -465,10 +445,4 @@ EventHandler.on(window, EVENT_LOAD_DATA_API, () => { } }) -/** - * jQuery - */ - -defineJQueryPlugin(Carousel) - export default Carousel diff --git a/js/src/collapse.js b/js/src/collapse.js index 9f0c60cc53..2010d16f38 100644 --- a/js/src/collapse.js +++ b/js/src/collapse.js @@ -9,7 +9,6 @@ import BaseComponent from './base-component.js' import EventHandler from './dom/event-handler.js' import SelectorEngine from './dom/selector-engine.js' import { - defineJQueryPlugin, getElement, reflow } from './util/index.js' @@ -251,26 +250,6 @@ class Collapse extends BaseComponent { element.setAttribute('aria-expanded', isOpen) } } - - // Static - static jQueryInterface(config) { - const _config = {} - if (typeof config === 'string' && /show|hide/.test(config)) { - _config.toggle = false - } - - return this.each(function () { - const data = Collapse.getOrCreateInstance(this, _config) - - if (typeof config === 'string') { - if (typeof data[config] === 'undefined') { - throw new TypeError(`No method named "${config}"`) - } - - data[config]() - } - }) - } } /** @@ -288,10 +267,4 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function ( } }) -/** - * jQuery - */ - -defineJQueryPlugin(Collapse) - export default Collapse diff --git a/js/src/dom/event-handler.js b/js/src/dom/event-handler.js index 561d8751d7..5b2d4c1dd8 100644 --- a/js/src/dom/event-handler.js +++ b/js/src/dom/event-handler.js @@ -5,8 +5,6 @@ * -------------------------------------------------------------------------- */ -import { getjQuery } from '../util/index.js' - /** * Constants */ @@ -261,38 +259,8 @@ const EventHandler = { return null } - const $ = getjQuery() - const typeEvent = getTypeEvent(event) - const inNamespace = event !== typeEvent - - let jQueryEvent = null - let bubbles = true - let nativeDispatch = true - let defaultPrevented = false - - if (inNamespace && $) { - jQueryEvent = $.Event(event, args) - - $(element).trigger(jQueryEvent) - bubbles = !jQueryEvent.isPropagationStopped() - nativeDispatch = !jQueryEvent.isImmediatePropagationStopped() - defaultPrevented = jQueryEvent.isDefaultPrevented() - } - - const evt = hydrateObj(new Event(event, { bubbles, cancelable: true }), args) - - if (defaultPrevented) { - evt.preventDefault() - } - - if (nativeDispatch) { - element.dispatchEvent(evt) - } - - if (evt.defaultPrevented && jQueryEvent) { - jQueryEvent.preventDefault() - } - + const evt = hydrateObj(new Event(event, { bubbles: true, cancelable: true }), args) + element.dispatchEvent(evt) return evt } } diff --git a/js/src/dropdown.js b/js/src/dropdown.js index 96094a3e65..a31f801d5b 100644 --- a/js/src/dropdown.js +++ b/js/src/dropdown.js @@ -11,7 +11,6 @@ import EventHandler from './dom/event-handler.js' import Manipulator from './dom/manipulator.js' import SelectorEngine from './dom/selector-engine.js' import { - defineJQueryPlugin, execute, getElement, getNextActiveElement, @@ -336,23 +335,6 @@ class Dropdown extends BaseComponent { getNextActiveElement(items, target, key === ARROW_DOWN_KEY, !items.includes(target)).focus() } - // Static - static jQueryInterface(config) { - return this.each(function () { - const data = Dropdown.getOrCreateInstance(this, config) - - if (typeof config !== 'string') { - return - } - - if (typeof data[config] === 'undefined') { - throw new TypeError(`No method named "${config}"`) - } - - data[config]() - }) - } - static clearMenus(event) { if (event.button === RIGHT_MOUSE_BUTTON || (event.type === 'keyup' && event.key !== TAB_KEY)) { return @@ -446,10 +428,4 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function ( Dropdown.getOrCreateInstance(this).toggle() }) -/** - * jQuery - */ - -defineJQueryPlugin(Dropdown) - export default Dropdown diff --git a/js/src/modal.js b/js/src/modal.js index dd61649ecc..538d218653 100644 --- a/js/src/modal.js +++ b/js/src/modal.js @@ -12,7 +12,7 @@ import Backdrop from './util/backdrop.js' import { enableDismissTrigger } from './util/component-functions.js' import FocusTrap from './util/focustrap.js' import { - defineJQueryPlugin, isRTL, isVisible, reflow + isRTL, isVisible, reflow } from './util/index.js' import ScrollBarHelper from './util/scrollbar.js' @@ -313,23 +313,6 @@ class Modal extends BaseComponent { this._element.style.paddingLeft = '' this._element.style.paddingRight = '' } - - // Static - static jQueryInterface(config, relatedTarget) { - return this.each(function () { - const data = Modal.getOrCreateInstance(this, config) - - if (typeof config !== 'string') { - return - } - - if (typeof data[config] === 'undefined') { - throw new TypeError(`No method named "${config}"`) - } - - data[config](relatedTarget) - }) - } } /** @@ -369,10 +352,4 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function ( enableDismissTrigger(Modal) -/** - * jQuery - */ - -defineJQueryPlugin(Modal) - export default Modal diff --git a/js/src/offcanvas.js b/js/src/offcanvas.js index 8d1feb13bb..decc156439 100644 --- a/js/src/offcanvas.js +++ b/js/src/offcanvas.js @@ -12,7 +12,6 @@ import Backdrop from './util/backdrop.js' import { enableDismissTrigger } from './util/component-functions.js' import FocusTrap from './util/focustrap.js' import { - defineJQueryPlugin, isDisabled, isVisible } from './util/index.js' @@ -207,22 +206,6 @@ class Offcanvas extends BaseComponent { }) } - // Static - static jQueryInterface(config) { - return this.each(function () { - const data = Offcanvas.getOrCreateInstance(this, config) - - if (typeof config !== 'string') { - return - } - - if (data[config] === undefined || config.startsWith('_') || config === 'constructor') { - throw new TypeError(`No method named "${config}"`) - } - - data[config](this) - }) - } } /** @@ -273,10 +256,4 @@ EventHandler.on(window, EVENT_RESIZE, () => { enableDismissTrigger(Offcanvas) -/** - * jQuery - */ - -defineJQueryPlugin(Offcanvas) - export default Offcanvas diff --git a/js/src/popover.js b/js/src/popover.js index 612c5218fc..b8383dc0d5 100644 --- a/js/src/popover.js +++ b/js/src/popover.js @@ -6,7 +6,6 @@ */ import Tooltip from './tooltip.js' -import { defineJQueryPlugin } from './util/index.js' /** * Constants @@ -69,29 +68,6 @@ class Popover extends Tooltip { _getContent() { return this._resolvePossibleFunction(this._config.content) } - - // Static - static jQueryInterface(config) { - return this.each(function () { - const data = Popover.getOrCreateInstance(this, config) - - if (typeof config !== 'string') { - return - } - - if (typeof data[config] === 'undefined') { - throw new TypeError(`No method named "${config}"`) - } - - data[config]() - }) - } } -/** - * jQuery - */ - -defineJQueryPlugin(Popover) - export default Popover diff --git a/js/src/scrollspy.js b/js/src/scrollspy.js index 368092de45..f3473ab2bd 100644 --- a/js/src/scrollspy.js +++ b/js/src/scrollspy.js @@ -9,7 +9,7 @@ import BaseComponent from './base-component.js' import EventHandler from './dom/event-handler.js' import SelectorEngine from './dom/selector-engine.js' import { - defineJQueryPlugin, getElement, isDisabled, isVisible + getElement, isDisabled, isVisible } from './util/index.js' /** @@ -259,22 +259,6 @@ class ScrollSpy extends BaseComponent { } } - // Static - static jQueryInterface(config) { - return this.each(function () { - const data = ScrollSpy.getOrCreateInstance(this, config) - - if (typeof config !== 'string') { - return - } - - if (data[config] === undefined || config.startsWith('_') || config === 'constructor') { - throw new TypeError(`No method named "${config}"`) - } - - data[config]() - }) - } } /** @@ -287,10 +271,4 @@ EventHandler.on(window, EVENT_LOAD_DATA_API, () => { } }) -/** - * jQuery - */ - -defineJQueryPlugin(ScrollSpy) - export default ScrollSpy diff --git a/js/src/tab.js b/js/src/tab.js index dfaef0ffa2..989a37a657 100644 --- a/js/src/tab.js +++ b/js/src/tab.js @@ -8,7 +8,7 @@ import BaseComponent from './base-component.js' import EventHandler from './dom/event-handler.js' import SelectorEngine from './dom/selector-engine.js' -import { defineJQueryPlugin, getNextActiveElement, isDisabled } from './util/index.js' +import { getNextActiveElement, isDisabled } from './util/index.js' /** * Constants @@ -263,23 +263,6 @@ class Tab extends BaseComponent { _getOuterElement(elem) { return elem.closest(SELECTOR_OUTER) || elem } - - // Static - static jQueryInterface(config) { - return this.each(function () { - const data = Tab.getOrCreateInstance(this) - - if (typeof config !== 'string') { - return - } - - if (data[config] === undefined || config.startsWith('_') || config === 'constructor') { - throw new TypeError(`No method named "${config}"`) - } - - data[config]() - }) - } } /** @@ -306,10 +289,5 @@ EventHandler.on(window, EVENT_LOAD_DATA_API, () => { Tab.getOrCreateInstance(element) } }) -/** - * jQuery - */ - -defineJQueryPlugin(Tab) export default Tab diff --git a/js/src/toast.js b/js/src/toast.js index d5d9c0ee0c..d5db423fe9 100644 --- a/js/src/toast.js +++ b/js/src/toast.js @@ -8,7 +8,7 @@ import BaseComponent from './base-component.js' import EventHandler from './dom/event-handler.js' import { enableDismissTrigger } from './util/component-functions.js' -import { defineJQueryPlugin, reflow } from './util/index.js' +import { reflow } from './util/index.js' /** * Constants @@ -193,21 +193,6 @@ class Toast extends BaseComponent { clearTimeout(this._timeout) this._timeout = null } - - // Static - static jQueryInterface(config) { - return this.each(function () { - const data = Toast.getOrCreateInstance(this, config) - - if (typeof config === 'string') { - if (typeof data[config] === 'undefined') { - throw new TypeError(`No method named "${config}"`) - } - - data[config](this) - } - }) - } } /** @@ -216,10 +201,4 @@ class Toast extends BaseComponent { enableDismissTrigger(Toast) -/** - * jQuery - */ - -defineJQueryPlugin(Toast) - export default Toast diff --git a/js/src/tooltip.js b/js/src/tooltip.js index 097477f7a1..9b7584e639 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -10,7 +10,7 @@ import BaseComponent from './base-component.js' import EventHandler from './dom/event-handler.js' import Manipulator from './dom/manipulator.js' import { - defineJQueryPlugin, execute, findShadowRoot, getElement, getUID, isRTL, noop + execute, findShadowRoot, getElement, getUID, isRTL, noop } from './util/index.js' import { DefaultAllowlist } from './util/sanitizer.js' import TemplateFactory from './util/template-factory.js' @@ -604,29 +604,5 @@ class Tooltip extends BaseComponent { this.tip = null } } - - // Static - static jQueryInterface(config) { - return this.each(function () { - const data = Tooltip.getOrCreateInstance(this, config) - - if (typeof config !== 'string') { - return - } - - if (typeof data[config] === 'undefined') { - throw new TypeError(`No method named "${config}"`) - } - - data[config]() - }) - } } - -/** - * jQuery - */ - -defineJQueryPlugin(Tooltip) - export default Tooltip diff --git a/js/src/util/index.js b/js/src/util/index.js index c271cc5368..4f35f31a5d 100644 --- a/js/src/util/index.js +++ b/js/src/util/index.js @@ -176,14 +176,6 @@ const reflow = element => { element.offsetHeight // eslint-disable-line no-unused-expressions } -const getjQuery = () => { - if (window.jQuery && !document.body.hasAttribute('data-bs-no-jquery')) { - return window.jQuery - } - - return null -} - const DOMContentLoadedCallbacks = [] const onDOMContentLoaded = callback => { @@ -205,23 +197,6 @@ const onDOMContentLoaded = callback => { const isRTL = () => document.documentElement.dir === 'rtl' -const defineJQueryPlugin = plugin => { - onDOMContentLoaded(() => { - const $ = getjQuery() - /* istanbul ignore if */ - if ($) { - const name = plugin.NAME - const JQUERY_NO_CONFLICT = $.fn[name] - $.fn[name] = plugin.jQueryInterface - $.fn[name].Constructor = plugin - $.fn[name].noConflict = () => { - $.fn[name] = JQUERY_NO_CONFLICT - return plugin.jQueryInterface - } - } - }) -} - const execute = (possibleCallback, args = [], defaultValue = possibleCallback) => { return typeof possibleCallback === 'function' ? possibleCallback.call(...args) : defaultValue } @@ -284,12 +259,10 @@ const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed } export { - defineJQueryPlugin, execute, executeAfterTransition, findShadowRoot, getElement, - getjQuery, getNextActiveElement, getTransitionDurationFromElement, getUID, diff --git a/site/src/content/docs/getting-started/javascript.mdx b/site/src/content/docs/getting-started/javascript.mdx index 51a002effe..8abf5ea001 100644 --- a/site/src/content/docs/getting-started/javascript.mdx +++ b/site/src/content/docs/getting-started/javascript.mdx @@ -261,47 +261,6 @@ const tooltip = new bootstrap.Tooltip(yourTooltipEl, { }) ``` -## Optionally using jQuery - -**You don't need jQuery in Bootstrap 5**, but it's still possible to use our components with jQuery. If Bootstrap detects `jQuery` in the `window` object, it'll add all of our components in jQuery's plugin system. This allows you to do the following: - -```js -// to enable tooltips with the default configuration -$('[data-bs-toggle="tooltip"]').tooltip() - -// to initialize tooltips with given configuration -$('[data-bs-toggle="tooltip"]').tooltip({ - boundary: 'clippingParents', - customClass: 'myClass' -}) - -// to trigger the `show` method -$('#myTooltip').tooltip('show') -``` - -The same goes for our other components. - -### No conflict - -Sometimes it is necessary to use Bootstrap plugins with other UI frameworks. In these circumstances, namespace collisions can occasionally occur. If this happens, you may call `.noConflict` on the plugin you wish to revert the value of. - -```js -const bootstrapButton = $.fn.button.noConflict() // return $.fn.button to previously assigned value -$.fn.bootstrapBtn = bootstrapButton // give $().bootstrapBtn the Bootstrap functionality -``` - -Bootstrap does not officially support third-party JavaScript libraries like Prototype or jQuery UI. Despite `.noConflict` and namespaced events, there may be compatibility problems that you need to fix on your own. - -### jQuery events - -Bootstrap will detect jQuery if `jQuery` is present in the `window` object and there is no `data-bs-no-jquery` attribute set on `
`. If jQuery is found, Bootstrap will emit events thanks to jQuery's event system. So if you want to listen to Bootstrap's events, you'll have to use the jQuery methods (`.on`, `.one`) instead of `addEventListener`. - -```js -$('#myTab a').on('shown.bs.tab', () => { - // do something... -}) -``` - ## Disabled JavaScript Bootstrap's plugins have no special fallback when JavaScript is disabled. If you care about the user experience in this case, use [`