1
0
Fork 0
mirror of https://github.com/twbs/bootstrap.git synced 2022-11-09 12:25:43 -05:00

add a way to disable jQuery detection

This commit is contained in:
Johann-S 2019-08-02 15:51:05 +02:00
parent 1ebb8e7d9b
commit 8b2b490f9b
15 changed files with 92 additions and 27 deletions

View file

@ -6,7 +6,7 @@
*/ */
import { import {
jQuery as $, getjQuery,
TRANSITION_END, TRANSITION_END,
emulateTransitionEnd, emulateTransitionEnd,
getElementFromSelector, getElementFromSelector,
@ -165,6 +165,8 @@ class Alert {
EventHandler EventHandler
.on(document, Event.CLICK_DATA_API, Selector.DISMISS, Alert.handleDismiss(new Alert())) .on(document, Event.CLICK_DATA_API, Selector.DISMISS, Alert.handleDismiss(new Alert()))
const $ = getjQuery()
/** /**
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
* jQuery * jQuery
@ -173,7 +175,7 @@ EventHandler
*/ */
/* istanbul ignore if */ /* istanbul ignore if */
if (typeof $ !== 'undefined') { if ($) {
const JQUERY_NO_CONFLICT = $.fn[NAME] const JQUERY_NO_CONFLICT = $.fn[NAME]
$.fn[NAME] = Alert.jQueryInterface $.fn[NAME] = Alert.jQueryInterface
$.fn[NAME].Constructor = Alert $.fn[NAME].Constructor = Alert

View file

@ -5,7 +5,7 @@
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
import { jQuery as $ } from '../util/index' import { getjQuery } from '../util/index'
import Data from '../dom/data' import Data from '../dom/data'
import EventHandler from '../dom/event-handler' import EventHandler from '../dom/event-handler'
import SelectorEngine from '../dom/selector-engine' import SelectorEngine from '../dom/selector-engine'
@ -179,6 +179,8 @@ EventHandler.on(document, Event.BLUR_DATA_API, Selector.DATA_TOGGLE_CARROT, even
} }
}) })
const $ = getjQuery()
/** /**
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
* jQuery * jQuery
@ -186,7 +188,7 @@ EventHandler.on(document, Event.BLUR_DATA_API, Selector.DATA_TOGGLE_CARROT, even
* add .button to jQuery only if jQuery is present * add .button to jQuery only if jQuery is present
*/ */
/* istanbul ignore if */ /* istanbul ignore if */
if (typeof $ !== 'undefined') { if ($) {
const JQUERY_NO_CONFLICT = $.fn[NAME] const JQUERY_NO_CONFLICT = $.fn[NAME]
$.fn[NAME] = Button.jQueryInterface $.fn[NAME] = Button.jQueryInterface
$.fn[NAME].Constructor = Button $.fn[NAME].Constructor = Button

View file

@ -6,7 +6,7 @@
*/ */
import { import {
jQuery as $, getjQuery,
TRANSITION_END, TRANSITION_END,
emulateTransitionEnd, emulateTransitionEnd,
getElementFromSelector, getElementFromSelector,
@ -615,6 +615,8 @@ EventHandler.on(window, Event.LOAD_DATA_API, () => {
} }
}) })
const $ = getjQuery()
/** /**
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
* jQuery * jQuery
@ -622,7 +624,7 @@ EventHandler.on(window, Event.LOAD_DATA_API, () => {
* add .carousel to jQuery only if jQuery is present * add .carousel to jQuery only if jQuery is present
*/ */
/* istanbul ignore if */ /* istanbul ignore if */
if (typeof $ !== 'undefined') { if ($) {
const JQUERY_NO_CONFLICT = $.fn[NAME] const JQUERY_NO_CONFLICT = $.fn[NAME]
$.fn[NAME] = Carousel.jQueryInterface $.fn[NAME] = Carousel.jQueryInterface
$.fn[NAME].Constructor = Carousel $.fn[NAME].Constructor = Carousel

View file

@ -6,7 +6,7 @@
*/ */
import { import {
jQuery as $, getjQuery,
TRANSITION_END, TRANSITION_END,
emulateTransitionEnd, emulateTransitionEnd,
getSelectorFromElement, getSelectorFromElement,
@ -419,6 +419,8 @@ EventHandler.on(document, Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (
}) })
}) })
const $ = getjQuery()
/** /**
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
* jQuery * jQuery
@ -426,7 +428,7 @@ EventHandler.on(document, Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (
* add .collapse to jQuery only if jQuery is present * add .collapse to jQuery only if jQuery is present
*/ */
/* istanbul ignore if */ /* istanbul ignore if */
if (typeof $ !== 'undefined') { if ($) {
const JQUERY_NO_CONFLICT = $.fn[NAME] const JQUERY_NO_CONFLICT = $.fn[NAME]
$.fn[NAME] = Collapse.jQueryInterface $.fn[NAME] = Collapse.jQueryInterface
$.fn[NAME].Constructor = Collapse $.fn[NAME].Constructor = Collapse

View file

@ -5,7 +5,7 @@
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
import { jQuery as $ } from '../util/index' import { getjQuery } from '../util/index'
import { createCustomEvent, defaultPreventedPreservedOnDispatch } from './polyfill' import { createCustomEvent, defaultPreventedPreservedOnDispatch } from './polyfill'
/** /**
@ -14,6 +14,7 @@ import { createCustomEvent, defaultPreventedPreservedOnDispatch } from './polyfi
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
*/ */
const $ = getjQuery()
const namespaceRegex = /[^.]*(?=\..*)\.|.*/ const namespaceRegex = /[^.]*(?=\..*)\.|.*/
const stripNameRegex = /\..*/ const stripNameRegex = /\..*/
const keyEventRegex = /^key/ const keyEventRegex = /^key/
@ -293,7 +294,7 @@ const EventHandler = {
let defaultPrevented = false let defaultPrevented = false
let evt = null let evt = null
if (inNamespace && typeof $ !== 'undefined') { if (inNamespace && $) {
jQueryEvent = $.Event(event, args) jQueryEvent = $.Event(event, args)
$(element).trigger(jQueryEvent) $(element).trigger(jQueryEvent)

View file

@ -6,7 +6,7 @@
*/ */
import { import {
jQuery as $, getjQuery,
getElementFromSelector, getElementFromSelector,
isElement, isElement,
makeArray, makeArray,
@ -526,6 +526,8 @@ EventHandler.on(document, Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (
EventHandler EventHandler
.on(document, Event.CLICK_DATA_API, Selector.FORM_CHILD, e => e.stopPropagation()) .on(document, Event.CLICK_DATA_API, Selector.FORM_CHILD, e => e.stopPropagation())
const $ = getjQuery()
/** /**
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
* jQuery * jQuery
@ -533,7 +535,7 @@ EventHandler
* add .dropdown to jQuery only if jQuery is present * add .dropdown to jQuery only if jQuery is present
*/ */
/* istanbul ignore if */ /* istanbul ignore if */
if (typeof $ !== 'undefined') { if ($) {
const JQUERY_NO_CONFLICT = $.fn[NAME] const JQUERY_NO_CONFLICT = $.fn[NAME]
$.fn[NAME] = Dropdown.jQueryInterface $.fn[NAME] = Dropdown.jQueryInterface
$.fn[NAME].Constructor = Dropdown $.fn[NAME].Constructor = Dropdown

View file

@ -6,7 +6,7 @@
*/ */
import { import {
jQuery as $, getjQuery,
TRANSITION_END, TRANSITION_END,
emulateTransitionEnd, emulateTransitionEnd,
getElementFromSelector, getElementFromSelector,
@ -582,6 +582,8 @@ EventHandler.on(document, Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (
data.show(this) data.show(this)
}) })
const $ = getjQuery()
/** /**
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
* jQuery * jQuery
@ -589,7 +591,7 @@ EventHandler.on(document, Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (
* add .modal to jQuery only if jQuery is present * add .modal to jQuery only if jQuery is present
*/ */
/* istanbul ignore if */ /* istanbul ignore if */
if (typeof $ !== 'undefined') { if ($) {
const JQUERY_NO_CONFLICT = $.fn[NAME] const JQUERY_NO_CONFLICT = $.fn[NAME]
$.fn[NAME] = Modal.jQueryInterface $.fn[NAME] = Modal.jQueryInterface
$.fn[NAME].Constructor = Modal $.fn[NAME].Constructor = Modal

View file

@ -5,7 +5,7 @@
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
import { jQuery as $ } from '../util/index' import { getjQuery } from '../util/index'
import Data from '../dom/data' import Data from '../dom/data'
import SelectorEngine from '../dom/selector-engine' import SelectorEngine from '../dom/selector-engine'
import Tooltip from '../tooltip/tooltip' import Tooltip from '../tooltip/tooltip'
@ -173,13 +173,15 @@ class Popover extends Tooltip {
} }
} }
const $ = getjQuery()
/** /**
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
* jQuery * jQuery
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
*/ */
/* istanbul ignore if */ /* istanbul ignore if */
if (typeof $ !== 'undefined') { if ($) {
const JQUERY_NO_CONFLICT = $.fn[NAME] const JQUERY_NO_CONFLICT = $.fn[NAME]
$.fn[NAME] = Popover.jQueryInterface $.fn[NAME] = Popover.jQueryInterface
$.fn[NAME].Constructor = Popover $.fn[NAME].Constructor = Popover

View file

@ -6,7 +6,7 @@
*/ */
import { import {
jQuery as $, getjQuery,
getSelectorFromElement, getSelectorFromElement,
getUID, getUID,
makeArray, makeArray,
@ -336,13 +336,15 @@ EventHandler.on(window, Event.LOAD_DATA_API, () => {
.forEach(spy => new ScrollSpy(spy, Manipulator.getDataAttributes(spy))) .forEach(spy => new ScrollSpy(spy, Manipulator.getDataAttributes(spy)))
}) })
const $ = getjQuery()
/** /**
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
* jQuery * jQuery
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
*/ */
/* istanbul ignore if */ /* istanbul ignore if */
if (typeof $ !== 'undefined') { if ($) {
const JQUERY_NO_CONFLICT = $.fn[NAME] const JQUERY_NO_CONFLICT = $.fn[NAME]
$.fn[NAME] = ScrollSpy.jQueryInterface $.fn[NAME] = ScrollSpy.jQueryInterface
$.fn[NAME].Constructor = ScrollSpy $.fn[NAME].Constructor = ScrollSpy

View file

@ -6,7 +6,7 @@
*/ */
import { import {
jQuery as $, getjQuery,
TRANSITION_END, TRANSITION_END,
emulateTransitionEnd, emulateTransitionEnd,
getElementFromSelector, getElementFromSelector,
@ -242,6 +242,8 @@ EventHandler.on(document, Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (
data.show() data.show()
}) })
const $ = getjQuery()
/** /**
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
* jQuery * jQuery
@ -249,7 +251,7 @@ EventHandler.on(document, Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (
* add .tab to jQuery only if jQuery is present * add .tab to jQuery only if jQuery is present
*/ */
/* istanbul ignore if */ /* istanbul ignore if */
if (typeof $ !== 'undefined') { if ($) {
const JQUERY_NO_CONFLICT = $.fn[NAME] const JQUERY_NO_CONFLICT = $.fn[NAME]
$.fn[NAME] = Tab.jQueryInterface $.fn[NAME] = Tab.jQueryInterface
$.fn[NAME].Constructor = Tab $.fn[NAME].Constructor = Tab

View file

@ -6,7 +6,7 @@
*/ */
import { import {
jQuery as $, getjQuery,
TRANSITION_END, TRANSITION_END,
emulateTransitionEnd, emulateTransitionEnd,
getTransitionDurationFromElement, getTransitionDurationFromElement,
@ -222,6 +222,8 @@ class Toast {
} }
} }
const $ = getjQuery()
/** /**
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
* jQuery * jQuery
@ -229,7 +231,7 @@ class Toast {
* add .toast to jQuery only if jQuery is present * add .toast to jQuery only if jQuery is present
*/ */
/* istanbul ignore if */ /* istanbul ignore if */
if (typeof $ !== 'undefined') { if ($) {
const JQUERY_NO_CONFLICT = $.fn[NAME] const JQUERY_NO_CONFLICT = $.fn[NAME]
$.fn[NAME] = Toast.jQueryInterface $.fn[NAME] = Toast.jQueryInterface
$.fn[NAME].Constructor = Toast $.fn[NAME].Constructor = Toast

View file

@ -6,7 +6,7 @@
*/ */
import { import {
jQuery as $, getjQuery,
TRANSITION_END, TRANSITION_END,
emulateTransitionEnd, emulateTransitionEnd,
findShadowRoot, findShadowRoot,
@ -798,6 +798,8 @@ class Tooltip {
} }
} }
const $ = getjQuery()
/** /**
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
* jQuery * jQuery
@ -805,7 +807,7 @@ class Tooltip {
* add .tooltip to jQuery only if jQuery is present * add .tooltip to jQuery only if jQuery is present
*/ */
/* istanbul ignore if */ /* istanbul ignore if */
if (typeof $ !== 'undefined') { if ($) {
const JQUERY_NO_CONFLICT = $.fn[NAME] const JQUERY_NO_CONFLICT = $.fn[NAME]
$.fn[NAME] = Tooltip.jQueryInterface $.fn[NAME] = Tooltip.jQueryInterface
$.fn[NAME].Constructor = Tooltip $.fn[NAME].Constructor = Tooltip

View file

@ -8,7 +8,6 @@
const MAX_UID = 1000000 const MAX_UID = 1000000
const MILLISECONDS_MULTIPLIER = 1000 const MILLISECONDS_MULTIPLIER = 1000
const TRANSITION_END = 'transitionend' const TRANSITION_END = 'transitionend'
const { jQuery } = window
// Shoutout AngusCroll (https://goo.gl/pxwQGp) // Shoutout AngusCroll (https://goo.gl/pxwQGp)
const toType = obj => ({}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase()) const toType = obj => ({}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase())
@ -176,8 +175,18 @@ const noop = () => function () {}
const reflow = element => element.offsetHeight const reflow = element => element.offsetHeight
const getjQuery = () => {
const { jQuery } = window
if (jQuery && !document.body.hasAttribute('data-no-jquery')) {
return jQuery
}
return null
}
export { export {
jQuery, getjQuery,
TRANSITION_END, TRANSITION_END,
getUID, getUID,
getSelectorFromElement, getSelectorFromElement,

View file

@ -346,4 +346,37 @@ describe('Util', () => {
expect(Util.reflow(div)).toEqual(0) expect(Util.reflow(div)).toEqual(0)
}) })
}) })
describe('getjQuery', () => {
const fakejQuery = { trigger() {} }
beforeEach(() => {
Object.defineProperty(window, 'jQuery', {
value: fakejQuery,
writable: true
})
})
afterEach(() => {
window.jQuery = undefined
})
it('should return jQuery object when present', () => {
expect(Util.getjQuery()).toEqual(fakejQuery)
})
it('should not return jQuery object when present if data-no-jquery', () => {
document.body.setAttribute('data-no-jquery', '')
expect(window.jQuery).toEqual(fakejQuery)
expect(Util.getjQuery()).toEqual(null)
document.body.removeAttribute('data-no-jquery')
})
it('should not return jQuery if not present', () => {
window.jQuery = undefined
expect(Util.getjQuery()).toEqual(null)
})
})
}) })

View file

@ -67,7 +67,7 @@ myModal.addEventListener('show.bs.modal', function (e) {
{{< callout warning >}} {{< callout warning >}}
## jQuery events ## jQuery events
Bootstrap will detect jQuery only if `jQuery` is present in the `window` object. 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`). Bootstrap will detect jQuery if `jQuery` is present in the `window` object and no `data-no-jquery` attribute on `<body>`. 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`.
{{< highlight js >}} {{< highlight js >}}
$('#myTab a').on('shown.bs.tab', function () { $('#myTab a').on('shown.bs.tab', function () {