0
0
mirror of https://github.com/twbs/bootstrap.git synced 2024-11-29 11:24:18 +01:00

Fix TypeError when Bootstrap is included in head (#32024)

* extend jquery after domContentLoaded event is fired

* add unittest for util onDOMContentLoaded

* wait for trigger jquery event after domContentLoaded

* remove domcontentready from eventHandler

* move istanbul ignore statements to correct line

Co-authored-by: XhmikosR <xhmikosr@gmail.com>
This commit is contained in:
Sascha 2020-11-01 14:32:36 +01:00 committed by GitHub
parent 3a5f9f5cf0
commit c21506d499
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 184 additions and 126 deletions

View File

@ -7,6 +7,7 @@
import {
getjQuery,
onDOMContentLoaded,
TRANSITION_END,
emulateTransitionEnd,
getElementFromSelector,
@ -146,8 +147,6 @@ class Alert {
*/
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DISMISS, Alert.handleDismiss(new Alert()))
const $ = getjQuery()
/**
* ------------------------------------------------------------------------
* jQuery
@ -155,6 +154,8 @@ const $ = getjQuery()
* add .alert to jQuery only if jQuery is present
*/
onDOMContentLoaded(() => {
const $ = getjQuery()
/* istanbul ignore if */
if ($) {
const JQUERY_NO_CONFLICT = $.fn[NAME]
@ -165,5 +166,6 @@ if ($) {
return Alert.jQueryInterface
}
}
})
export default Alert

View File

@ -5,7 +5,7 @@
* --------------------------------------------------------------------------
*/
import { getjQuery } from './util/index'
import { getjQuery, onDOMContentLoaded } from './util/index'
import Data from './dom/data'
import EventHandler from './dom/event-handler'
@ -97,14 +97,15 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, event => {
data.toggle()
})
const $ = getjQuery()
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
* add .button to jQuery only if jQuery is present
*/
onDOMContentLoaded(() => {
const $ = getjQuery()
/* istanbul ignore if */
if ($) {
const JQUERY_NO_CONFLICT = $.fn[NAME]
@ -116,5 +117,6 @@ if ($) {
return Button.jQueryInterface
}
}
})
export default Button

View File

@ -7,6 +7,7 @@
import {
getjQuery,
onDOMContentLoaded,
TRANSITION_END,
emulateTransitionEnd,
getElementFromSelector,
@ -611,14 +612,15 @@ EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
}
})
const $ = getjQuery()
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
* add .carousel to jQuery only if jQuery is present
*/
onDOMContentLoaded(() => {
const $ = getjQuery()
/* istanbul ignore if */
if ($) {
const JQUERY_NO_CONFLICT = $.fn[NAME]
@ -629,5 +631,6 @@ if ($) {
return Carousel.jQueryInterface
}
}
})
export default Carousel

View File

@ -7,6 +7,7 @@
import {
getjQuery,
onDOMContentLoaded,
TRANSITION_END,
emulateTransitionEnd,
getSelectorFromElement,
@ -408,14 +409,15 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (
})
})
const $ = getjQuery()
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
* add .collapse to jQuery only if jQuery is present
*/
onDOMContentLoaded(() => {
const $ = getjQuery()
/* istanbul ignore if */
if ($) {
const JQUERY_NO_CONFLICT = $.fn[NAME]
@ -426,5 +428,6 @@ if ($) {
return Collapse.jQueryInterface
}
}
})
export default Collapse

View File

@ -14,7 +14,6 @@ import { defaultPreventedPreservedOnDispatch } from './polyfill'
* ------------------------------------------------------------------------
*/
const $ = getjQuery()
const namespaceRegex = /[^.]*(?=\..*)\.|.*/
const stripNameRegex = /\..*/
const stripUidRegex = /::\d+$/
@ -272,6 +271,7 @@ const EventHandler = {
return null
}
const $ = getjQuery()
const typeEvent = event.replace(stripNameRegex, '')
const inNamespace = event !== typeEvent
const isNative = nativeEvents.indexOf(typeEvent) > -1

View File

@ -7,6 +7,7 @@
import {
getjQuery,
onDOMContentLoaded,
getElementFromSelector,
isElement,
isVisible,
@ -512,14 +513,15 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (
})
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_FORM_CHILD, e => e.stopPropagation())
const $ = getjQuery()
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
* add .dropdown to jQuery only if jQuery is present
*/
onDOMContentLoaded(() => {
const $ = getjQuery()
/* istanbul ignore if */
if ($) {
const JQUERY_NO_CONFLICT = $.fn[NAME]
@ -530,5 +532,6 @@ if ($) {
return Dropdown.jQueryInterface
}
}
})
export default Dropdown

View File

@ -7,6 +7,7 @@
import {
getjQuery,
onDOMContentLoaded,
TRANSITION_END,
emulateTransitionEnd,
getElementFromSelector,
@ -607,14 +608,15 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (
data.show(this)
})
const $ = getjQuery()
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
* add .modal to jQuery only if jQuery is present
*/
onDOMContentLoaded(() => {
const $ = getjQuery()
/* istanbul ignore if */
if ($) {
const JQUERY_NO_CONFLICT = $.fn[NAME]
@ -625,5 +627,6 @@ if ($) {
return Modal.jQueryInterface
}
}
})
export default Modal

View File

@ -5,7 +5,7 @@
* --------------------------------------------------------------------------
*/
import { getjQuery } from './util/index'
import { getjQuery, onDOMContentLoaded } from './util/index'
import Data from './dom/data'
import SelectorEngine from './dom/selector-engine'
import Tooltip from './tooltip'
@ -167,13 +167,14 @@ class Popover extends Tooltip {
}
}
const $ = getjQuery()
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
*/
onDOMContentLoaded(() => {
const $ = getjQuery()
/* istanbul ignore if */
if ($) {
const JQUERY_NO_CONFLICT = $.fn[NAME]
@ -184,5 +185,6 @@ if ($) {
return Popover.jQueryInterface
}
}
})
export default Popover

View File

@ -7,6 +7,7 @@
import {
getjQuery,
onDOMContentLoaded,
getSelectorFromElement,
getUID,
isElement,
@ -317,13 +318,14 @@ EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
.forEach(spy => new ScrollSpy(spy, Manipulator.getDataAttributes(spy)))
})
const $ = getjQuery()
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
*/
onDOMContentLoaded(() => {
const $ = getjQuery()
/* istanbul ignore if */
if ($) {
const JQUERY_NO_CONFLICT = $.fn[NAME]
@ -334,5 +336,6 @@ if ($) {
return ScrollSpy.jQueryInterface
}
}
})
export default ScrollSpy

View File

@ -7,6 +7,7 @@
import {
getjQuery,
onDOMContentLoaded,
TRANSITION_END,
emulateTransitionEnd,
getElementFromSelector,
@ -235,14 +236,15 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (
data.show()
})
const $ = getjQuery()
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
* add .tab to jQuery only if jQuery is present
*/
onDOMContentLoaded(() => {
const $ = getjQuery()
/* istanbul ignore if */
if ($) {
const JQUERY_NO_CONFLICT = $.fn[NAME]
@ -253,5 +255,6 @@ if ($) {
return Tab.jQueryInterface
}
}
})
export default Tab

View File

@ -7,6 +7,7 @@
import {
getjQuery,
onDOMContentLoaded,
TRANSITION_END,
emulateTransitionEnd,
getTransitionDurationFromElement,
@ -213,14 +214,15 @@ class Toast {
}
}
const $ = getjQuery()
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
* add .toast to jQuery only if jQuery is present
*/
onDOMContentLoaded(() => {
const $ = getjQuery()
/* istanbul ignore if */
if ($) {
const JQUERY_NO_CONFLICT = $.fn[NAME]
@ -231,5 +233,6 @@ if ($) {
return Toast.jQueryInterface
}
}
})
export default Toast

View File

@ -7,6 +7,7 @@
import {
getjQuery,
onDOMContentLoaded,
TRANSITION_END,
emulateTransitionEnd,
findShadowRoot,
@ -793,14 +794,15 @@ class Tooltip {
}
}
const $ = getjQuery()
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
* add .tooltip to jQuery only if jQuery is present
*/
onDOMContentLoaded(() => {
const $ = getjQuery()
/* istanbul ignore if */
if ($) {
const JQUERY_NO_CONFLICT = $.fn[NAME]
@ -811,5 +813,6 @@ if ($) {
return Tooltip.jQueryInterface
}
}
})
export default Tooltip

View File

@ -180,8 +180,15 @@ const getjQuery = () => {
return null
}
const onDOMContentLoaded = callback => {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', callback)
} else {
callback()
}
}
export {
getjQuery,
TRANSITION_END,
getUID,
getSelectorFromElement,
@ -194,5 +201,7 @@ export {
isVisible,
findShadowRoot,
noop,
reflow
reflow,
getjQuery,
onDOMContentLoaded
}

View File

@ -394,4 +394,23 @@ describe('Util', () => {
expect(Util.getjQuery()).toEqual(null)
})
})
describe('onDOMContentLoaded', () => {
it('should execute callback when DOMContentLoaded is fired', () => {
const spy = jasmine.createSpy()
spyOnProperty(document, 'readyState').and.returnValue('loading')
Util.onDOMContentLoaded(spy)
window.document.dispatchEvent(new Event('DOMContentLoaded', {
bubbles: true,
cancelable: true
}))
expect(spy).toHaveBeenCalled()
})
it('should execute callback if readyState is not "loading"', () => {
const spy = jasmine.createSpy()
Util.onDOMContentLoaded(spy)
expect(spy).toHaveBeenCalled()
})
})
})