mirror of
https://github.com/twbs/bootstrap.git
synced 2025-02-20 17:54:23 +01:00
chore(update): bump to 4.1.3
This commit is contained in:
parent
cf821e1d4d
commit
c44db783bf
@ -26,6 +26,11 @@ const plugins = [
|
||||
})
|
||||
]
|
||||
const bsPlugins = {
|
||||
Data: path.resolve(__dirname, '../js/src/dom/data.js'),
|
||||
EventHandler: path.resolve(__dirname, '../js/src/dom/eventHandler.js'),
|
||||
Manipulator: path.resolve(__dirname, '../js/src/dom/manipulator.js'),
|
||||
Polyfill: path.resolve(__dirname, '../js/src/dom/polyfill.js'),
|
||||
SelectorEngine: path.resolve(__dirname, '../js/src/dom/selectorEngine.js'),
|
||||
Alert: path.resolve(__dirname, '../js/src/alert.js'),
|
||||
Button: path.resolve(__dirname, '../js/src/button.js'),
|
||||
Carousel: path.resolve(__dirname, '../js/src/carousel.js'),
|
||||
@ -41,26 +46,112 @@ const bsPlugins = {
|
||||
}
|
||||
const rootPath = TEST ? '../js/coverage/dist/' : '../js/dist/'
|
||||
|
||||
const defaultPluginConfig = {
|
||||
external: [
|
||||
bsPlugins.Data,
|
||||
bsPlugins.EventHandler,
|
||||
bsPlugins.SelectorEngine,
|
||||
bsPlugins.Util
|
||||
],
|
||||
globals: {
|
||||
[bsPlugins.Data]: 'Data',
|
||||
[bsPlugins.EventHandler]: 'EventHandler',
|
||||
[bsPlugins.SelectorEngine]: 'SelectorEngine',
|
||||
[bsPlugins.Util]: 'Util'
|
||||
}
|
||||
}
|
||||
|
||||
function getConfigByPluginKey(pluginKey) {
|
||||
if (
|
||||
pluginKey === 'Data' ||
|
||||
pluginKey === 'Manipulator' ||
|
||||
pluginKey === 'Util'
|
||||
) {
|
||||
return {
|
||||
external: [],
|
||||
globals: {}
|
||||
}
|
||||
}
|
||||
|
||||
if (pluginKey === 'EventHandler' || pluginKey === 'SelectorEngine') {
|
||||
return {
|
||||
external: [
|
||||
bsPlugins.Polyfill,
|
||||
bsPlugins.Util
|
||||
],
|
||||
globals: {
|
||||
[bsPlugins.Polyfill]: 'Polyfill',
|
||||
[bsPlugins.Util]: 'Util'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pluginKey === 'Polyfill') {
|
||||
return {
|
||||
external: [bsPlugins.Util],
|
||||
globals: {
|
||||
[bsPlugins.Util]: 'Util'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pluginKey === 'Alert' || pluginKey === 'Tab') {
|
||||
return defaultPluginConfig
|
||||
}
|
||||
|
||||
if (
|
||||
pluginKey === 'Button' ||
|
||||
pluginKey === 'Carousel' ||
|
||||
pluginKey === 'Collapse' ||
|
||||
pluginKey === 'Modal' ||
|
||||
pluginKey === 'ScrollSpy'
|
||||
) {
|
||||
const config = Object.assign(defaultPluginConfig)
|
||||
config.external.push(bsPlugins.Manipulator)
|
||||
config.globals[bsPlugins.Manipulator] = 'Manipulator'
|
||||
return config
|
||||
}
|
||||
|
||||
if (pluginKey === 'Dropdown' || pluginKey === 'Tooltip') {
|
||||
const config = Object.assign(defaultPluginConfig)
|
||||
config.external.push(bsPlugins.Manipulator, 'popper.js')
|
||||
config.globals[bsPlugins.Manipulator] = 'Manipulator'
|
||||
config.globals['popper.js'] = 'Popper'
|
||||
return config
|
||||
}
|
||||
|
||||
if (pluginKey === 'Popover') {
|
||||
return {
|
||||
external: [
|
||||
bsPlugins.Data,
|
||||
bsPlugins.SelectorEngine,
|
||||
bsPlugins.Tooltip,
|
||||
bsPlugins.Util
|
||||
],
|
||||
globals: {
|
||||
[bsPlugins.Data]: 'Data',
|
||||
[bsPlugins.SelectorEngine]: 'SelectorEngine',
|
||||
[bsPlugins.Tooltip]: 'Tooltip',
|
||||
[bsPlugins.Util]: 'Util'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function build(plugin) {
|
||||
console.log(`Building ${plugin} plugin...`)
|
||||
|
||||
const external = ['jquery', 'popper.js']
|
||||
const globals = {
|
||||
jquery: 'jQuery', // Ensure we use jQuery which is always available even in noConflict mode
|
||||
'popper.js': 'Popper'
|
||||
}
|
||||
const config = getConfigByPluginKey(plugin)
|
||||
const external = config.external
|
||||
const globals = config.globals
|
||||
|
||||
// Do not bundle Util in plugins
|
||||
if (plugin !== 'Util') {
|
||||
external.push(bsPlugins.Util)
|
||||
globals[bsPlugins.Util] = 'Util'
|
||||
}
|
||||
|
||||
// Do not bundle Tooltip in Popover
|
||||
if (plugin === 'Popover') {
|
||||
external.push(bsPlugins.Tooltip)
|
||||
globals[bsPlugins.Tooltip] = 'Tooltip'
|
||||
}
|
||||
const pluginPath = [
|
||||
'Data',
|
||||
'EventHandler',
|
||||
'Manipulator',
|
||||
'Polyfill',
|
||||
'SelectorEngine'
|
||||
].includes(plugin) ? `${rootPath}/dom/` : rootPath
|
||||
|
||||
const pluginFilename = `${plugin.toLowerCase()}.js`
|
||||
|
||||
@ -75,7 +166,7 @@ function build(plugin) {
|
||||
name: plugin,
|
||||
sourcemap: true,
|
||||
globals,
|
||||
file: path.resolve(__dirname, `${rootPath}${pluginFilename}`)
|
||||
file: path.resolve(__dirname, `${pluginPath}${pluginFilename}`)
|
||||
})
|
||||
.then(() => console.log(`Building ${plugin} plugin... Done!`))
|
||||
.catch((err) => console.error(`${plugin}: ${err}`))
|
||||
|
@ -140,6 +140,16 @@ class Alert {
|
||||
})
|
||||
}
|
||||
|
||||
static _handleDismiss(alertInstance) {
|
||||
return function (event) {
|
||||
if (event) {
|
||||
event.preventDefault()
|
||||
}
|
||||
|
||||
alertInstance.close(this)
|
||||
}
|
||||
}
|
||||
|
||||
static _getInstance(element) {
|
||||
return Data.getData(element, DATA_KEY)
|
||||
}
|
||||
|
@ -178,7 +178,7 @@ class Carousel {
|
||||
this._interval = null
|
||||
}
|
||||
|
||||
if (this._config.interval && !this._isPaused) {
|
||||
if (this._config && this._config.interval && !this._isPaused) {
|
||||
this._interval = setInterval(
|
||||
(document.visibilityState ? this.nextWhenVisible : this.next).bind(this),
|
||||
this._config.interval
|
||||
@ -298,7 +298,7 @@ class Carousel {
|
||||
}
|
||||
|
||||
const end = (event) => {
|
||||
if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {
|
||||
if (this._pointerEvent && PointerType[event.pointerType.toUpperCase()]) {
|
||||
this.touchDeltaX = event.clientX - this.touchStartX
|
||||
}
|
||||
|
||||
@ -464,6 +464,14 @@ class Carousel {
|
||||
activeElement.classList.add(directionalClassName)
|
||||
nextElement.classList.add(directionalClassName)
|
||||
|
||||
const nextElementInterval = parseInt(nextElement.getAttribute('data-interval'), 10)
|
||||
if (nextElementInterval) {
|
||||
this._config.defaultInterval = this._config.defaultInterval || this._config.interval
|
||||
this._config.interval = nextElementInterval
|
||||
} else {
|
||||
this._config.interval = this._config.defaultInterval || this._config.interval
|
||||
}
|
||||
|
||||
const transitionDuration = Util.getTransitionDurationFromElement(activeElement)
|
||||
|
||||
EventHandler
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v4.1.1): dom/data.js
|
||||
* Bootstrap (v4.1.3): dom/data.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -3,7 +3,7 @@ import Util from '../util'
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v4.1.1): dom/eventHandler.js
|
||||
* Bootstrap (v4.1.3): dom/eventHandler.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
@ -32,6 +32,7 @@ const EventHandler = (() => {
|
||||
'keydown', 'keypress', 'keyup',
|
||||
'orientationchange',
|
||||
'touchstart', 'touchmove', 'touchend', 'touchcancel',
|
||||
'pointerdown', 'pointermove', 'pointerup', 'pointerleave', 'pointercancel',
|
||||
'gesturestart', 'gesturechange', 'gestureend',
|
||||
'focus', 'blur', 'change', 'reset', 'select', 'submit', 'focusin', 'focusout',
|
||||
'load', 'unload', 'beforeunload', 'resize', 'move', 'DOMContentLoaded', 'readystatechange',
|
||||
@ -314,4 +315,19 @@ const EventHandler = (() => {
|
||||
}
|
||||
})()
|
||||
|
||||
/* istanbul ignore next */
|
||||
// focusin and focusout polyfill
|
||||
if (Polyfill.focusIn) {
|
||||
(() => {
|
||||
function listenerFocus(event) {
|
||||
EventHandler.trigger(event.target, 'focusin')
|
||||
}
|
||||
function listenerBlur(event) {
|
||||
EventHandler.trigger(event.target, 'focusout')
|
||||
}
|
||||
EventHandler.on(document, 'focus', 'input', listenerFocus)
|
||||
EventHandler.on(document, 'blur', 'input', listenerBlur)
|
||||
})()
|
||||
}
|
||||
|
||||
export default EventHandler
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v4.1.1): dom/manipulator.js
|
||||
* Bootstrap (v4.1.3): dom/manipulator.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -2,7 +2,7 @@ import Util from '../util'
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v4.1.1): dom/polyfill.js
|
||||
* Bootstrap (v4.1.3): dom/polyfill.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -3,7 +3,7 @@ import Util from '../util'
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v4.1.1): dom/selectorEngine.js
|
||||
* Bootstrap (v4.1.3): dom/selectorEngine.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -234,7 +234,7 @@ class Dropdown {
|
||||
|
||||
Manipulator.toggleClass(this._menu, ClassName.SHOW)
|
||||
Manipulator.toggleClass(parent, ClassName.SHOW)
|
||||
EventHandler.trigger(parent, Event.SHOWN, relatedTarget)
|
||||
EventHandler.trigger(parent, Event.HIDDEN, relatedTarget)
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
@ -3,9 +3,7 @@ import Button from './button'
|
||||
import Carousel from './carousel'
|
||||
import Collapse from './collapse'
|
||||
import Dropdown from './dropdown'
|
||||
import EventHandler from './dom/eventHandler'
|
||||
import Modal from './modal'
|
||||
import Polyfill from './dom/polyfill'
|
||||
import Popover from './popover'
|
||||
import ScrollSpy from './scrollspy'
|
||||
import Tab from './tab'
|
||||
@ -20,21 +18,6 @@ import Util from './util'
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* istanbul ignore next */
|
||||
// focusin and focusout polyfill
|
||||
if (Polyfill.focusIn) {
|
||||
(() => {
|
||||
function listenerFocus(event) {
|
||||
EventHandler.trigger(event.target, 'focusin')
|
||||
}
|
||||
function listenerBlur(event) {
|
||||
EventHandler.trigger(event.target, 'focusout')
|
||||
}
|
||||
EventHandler.on(document, 'focus', 'input', listenerFocus)
|
||||
EventHandler.on(document, 'blur', 'input', listenerBlur)
|
||||
})()
|
||||
}
|
||||
|
||||
export {
|
||||
Util,
|
||||
Alert,
|
||||
|
@ -119,7 +119,7 @@ class Modal {
|
||||
relatedTarget
|
||||
})
|
||||
|
||||
if (this._isShown || showEvent.isDefaultPrevented()) {
|
||||
if (this._isShown || showEvent.defaultPrevented) {
|
||||
return
|
||||
}
|
||||
|
||||
@ -161,7 +161,7 @@ class Modal {
|
||||
|
||||
const hideEvent = EventHandler.trigger(this._element, Event.HIDE)
|
||||
|
||||
if (!this._isShown || hideEvent.isDefaultPrevented()) {
|
||||
if (!this._isShown || hideEvent.defaultPrevented) {
|
||||
return
|
||||
}
|
||||
|
||||
@ -282,16 +282,14 @@ class Modal {
|
||||
}
|
||||
|
||||
_enforceFocus() {
|
||||
if (this._isShown && this._config.keyboard) {
|
||||
EventHandler.on(this._element, Event.KEYDOWN_DISMISS, (event) => {
|
||||
if (event.which === ESCAPE_KEYCODE) {
|
||||
event.preventDefault()
|
||||
this.hide()
|
||||
}
|
||||
})
|
||||
} else if (!this._isShown) {
|
||||
EventHandler.off(this._element, Event.KEYDOWN_DISMISS)
|
||||
}
|
||||
EventHandler.off(document, Event.FOCUSIN) // guard against infinite focus loop
|
||||
EventHandler.on(document, Event.FOCUSIN, (event) => {
|
||||
if (document !== event.target &&
|
||||
this._element !== event.target &&
|
||||
!this._element.contains(event.target)) {
|
||||
this._element.focus()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
_setEscapeEvent() {
|
||||
@ -383,7 +381,7 @@ class Modal {
|
||||
const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)
|
||||
|
||||
EventHandler.one(this._backdrop, Util.TRANSITION_END, callback)
|
||||
Util.emulateTransitionEnd(backdropTransitionDuration)
|
||||
Util.emulateTransitionEnd(this._backdrop, backdropTransitionDuration)
|
||||
} else if (!this._isShown && this._backdrop) {
|
||||
this._backdrop.classList.remove(ClassName.SHOW)
|
||||
|
||||
|
@ -682,8 +682,7 @@ class Tooltip {
|
||||
}
|
||||
})
|
||||
|
||||
if (typeof config !== 'undefined' &&
|
||||
typeof config.container === 'object' && config.container.jquery) {
|
||||
if (config && typeof config.container === 'object' && config.container.jquery) {
|
||||
config.container = config.container[0]
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,6 @@
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
import EventHandler from './dom/eventHandler'
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Private TransitionEnd Helpers
|
||||
|
@ -97,12 +97,12 @@
|
||||
</script>
|
||||
|
||||
<!-- Transpiled Plugins -->
|
||||
<script src="../dist/util.js"></script>
|
||||
<script src="../dist/dom/polyfill.js"></script>
|
||||
<script src="../dist/dom/manipulator.js"></script>
|
||||
<script src="../dist/dom/eventHandler.js"></script>
|
||||
<script src="../dist/dom/selectorEngine.js"></script>
|
||||
<script src="../dist/dom/data.js"></script>
|
||||
<script src="../dist/util.js"></script>
|
||||
<script src="../dist/alert.js"></script>
|
||||
<script src="../dist/button.js"></script>
|
||||
<script src="../dist/carousel.js"></script>
|
||||
|
@ -93,12 +93,12 @@ if (bundle) {
|
||||
reporters.push('BrowserStack')
|
||||
files = files.concat([
|
||||
'node_modules/jquery/dist/jquery.slim.min.js',
|
||||
'js/coverage/dist/util.js',
|
||||
'js/coverage/dist/dom/polyfill.js',
|
||||
'js/coverage/dist/dom/eventHandler.js',
|
||||
'js/coverage/dist/dom/selectorEngine.js',
|
||||
'js/coverage/dist/dom/data.js',
|
||||
'js/coverage/dist/dom/manipulator.js',
|
||||
'js/coverage/dist/util.js',
|
||||
'js/coverage/dist/dom/polyfill.js',
|
||||
'js/coverage/dist/dom/!(polyfill).js',
|
||||
'js/coverage/dist/tooltip.js',
|
||||
'js/coverage/dist/!(util|index|tooltip).js', // include all of our js/dist files except util.js, index.js and tooltip.js
|
||||
@ -115,12 +115,12 @@ if (bundle) {
|
||||
)
|
||||
files = files.concat([
|
||||
jqueryFile,
|
||||
'js/coverage/dist/util.js',
|
||||
'js/coverage/dist/dom/polyfill.js',
|
||||
'js/coverage/dist/dom/eventHandler.js',
|
||||
'js/coverage/dist/dom/selectorEngine.js',
|
||||
'js/coverage/dist/dom/data.js',
|
||||
'js/coverage/dist/dom/manipulator.js',
|
||||
'js/coverage/dist/util.js',
|
||||
'js/coverage/dist/dom/polyfill.js',
|
||||
'js/coverage/dist/dom/!(polyfill).js',
|
||||
'js/coverage/dist/tooltip.js',
|
||||
'js/coverage/dist/!(util|index|tooltip).js', // include all of our js/dist files except util.js, index.js and tooltip.js
|
||||
|
@ -541,16 +541,19 @@ $(function () {
|
||||
'<a class="left carousel-control" href="#myCarousel" data-slide="prev">‹</a>' +
|
||||
'<a class="right carousel-control" href="#myCarousel" data-slide="next">›</a>' +
|
||||
'</div>'
|
||||
var $carousel = $(templateHTML)
|
||||
|
||||
$carousel.appendTo('body')
|
||||
var $carousel = $(templateHTML).appendTo('#qunit-fixture')
|
||||
$carousel.bootstrapCarousel(1)
|
||||
assert.strictEqual($carousel.data('bs.carousel')._config.interval, 3814)
|
||||
var carousel = Carousel._getInstance($carousel[0])
|
||||
assert.strictEqual(carousel._config.interval, 3814)
|
||||
carousel.dispose()
|
||||
$carousel.remove()
|
||||
|
||||
$carousel.appendTo('body')
|
||||
$carousel = $carousel.appendTo('#qunit-fixture')
|
||||
$carousel.bootstrapCarousel(2)
|
||||
assert.strictEqual($carousel.data('bs.carousel')._config.interval, 1814, 'reverts to default interval if no data-interval is set')
|
||||
carousel = Carousel._getInstance($carousel[0])
|
||||
|
||||
assert.strictEqual(carousel._config.interval, 1814, 'reverts to default interval if no data-interval is set')
|
||||
$carousel.remove()
|
||||
})
|
||||
|
||||
@ -1080,7 +1083,7 @@ $(function () {
|
||||
var $carousel = $(carouselHTML).appendTo('#qunit-fixture')
|
||||
var $item = $('#item')
|
||||
$carousel.bootstrapCarousel()
|
||||
var carousel = $carousel.data('bs.carousel')
|
||||
var carousel = Carousel._getInstance($carousel[0])
|
||||
var spy = sinon.spy(carousel, 'prev')
|
||||
|
||||
$carousel.one('slid.bs.carousel', function () {
|
||||
@ -1122,7 +1125,7 @@ $(function () {
|
||||
$carousel.appendTo('#qunit-fixture')
|
||||
var $item = $('#item')
|
||||
$carousel.bootstrapCarousel()
|
||||
var carousel = $carousel.data('bs.carousel')
|
||||
var carousel = Carousel._getInstance($carousel[0])
|
||||
var spy = sinon.spy(carousel, 'prev')
|
||||
|
||||
$carousel.one('slid.bs.carousel', function () {
|
||||
@ -1169,7 +1172,7 @@ $(function () {
|
||||
$carousel.appendTo('#qunit-fixture')
|
||||
var $item = $('#item')
|
||||
$carousel.bootstrapCarousel()
|
||||
var carousel = $carousel.data('bs.carousel')
|
||||
var carousel = Carousel._getInstance($carousel[0])
|
||||
var spy = sinon.spy(carousel, 'next')
|
||||
|
||||
$carousel.one('slid.bs.carousel', function () {
|
||||
@ -1212,7 +1215,7 @@ $(function () {
|
||||
$carousel.appendTo('#qunit-fixture')
|
||||
var $item = $('#item')
|
||||
$carousel.bootstrapCarousel()
|
||||
var carousel = $carousel.data('bs.carousel')
|
||||
var carousel = Carousel._getInstance($carousel[0])
|
||||
var spy = sinon.spy(carousel, 'next')
|
||||
|
||||
$carousel.one('slid.bs.carousel', function () {
|
||||
@ -1264,7 +1267,7 @@ $(function () {
|
||||
$carousel.appendTo('#qunit-fixture')
|
||||
$carousel.bootstrapCarousel()
|
||||
|
||||
var carousel = $carousel.data('bs.carousel')
|
||||
var carousel = Carousel._getInstance($carousel[0])
|
||||
|
||||
var spy = sinon.spy(carousel, '_slide')
|
||||
|
||||
@ -1283,7 +1286,7 @@ $(function () {
|
||||
$carousel.appendTo('#qunit-fixture')
|
||||
$carousel.bootstrapCarousel()
|
||||
|
||||
var carousel = $carousel.data('bs.carousel')
|
||||
var carousel = Carousel._getInstance($carousel[0])
|
||||
|
||||
var spy = sinon.spy(carousel, 'next')
|
||||
var sandbox = sinon.createSandbox()
|
||||
|
@ -517,7 +517,7 @@ $(function () {
|
||||
$(document.body).trigger('click')
|
||||
})
|
||||
|
||||
$dropdown.trigger('click')
|
||||
$dropdown[0].click()
|
||||
})
|
||||
|
||||
QUnit.test('should fire hide and hidden event without a clickEvent if event type is not click', function (assert) {
|
||||
@ -547,12 +547,13 @@ $(function () {
|
||||
})
|
||||
.on('shown.bs.dropdown', function () {
|
||||
assert.ok(true, 'shown was fired')
|
||||
$dropdown.trigger($.Event('keydown', {
|
||||
which: 27
|
||||
}))
|
||||
|
||||
var keyDown = new Event('keydown')
|
||||
keyDown.which = 27
|
||||
$dropdown[0].dispatchEvent(keyDown)
|
||||
})
|
||||
|
||||
$dropdown.trigger('click')
|
||||
$dropdown[0].click()
|
||||
})
|
||||
|
||||
QUnit.test('should ignore keyboard events within <input>s and <textarea>s', function (assert) {
|
||||
@ -1132,38 +1133,6 @@ $(function () {
|
||||
assert.ok(dropdown._element === null)
|
||||
})
|
||||
|
||||
QUnit.test('should show dropdown', function (assert) {
|
||||
assert.expect(2)
|
||||
|
||||
var dropdownHTML =
|
||||
'<div class="dropdown">' +
|
||||
' <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>' +
|
||||
' <div class="dropdown-menu">' +
|
||||
' <a class="dropdown-item" href="#">Another link</a>' +
|
||||
' </div>' +
|
||||
'</div>'
|
||||
|
||||
var $dropdown = $(dropdownHTML)
|
||||
.appendTo('#qunit-fixture')
|
||||
.find('[data-toggle="dropdown"]')
|
||||
.bootstrapDropdown()
|
||||
|
||||
var dropdown = $dropdown.data('bs.dropdown')
|
||||
var done = assert.async()
|
||||
|
||||
$dropdown
|
||||
.parent('.dropdown')
|
||||
.on('show.bs.dropdown', function () {
|
||||
assert.ok(true, 'show was fired')
|
||||
})
|
||||
.on('shown.bs.dropdown', function () {
|
||||
assert.ok($dropdown.parent('.dropdown').hasClass('show'), 'dropdown menu is shown')
|
||||
done()
|
||||
})
|
||||
|
||||
dropdown.show()
|
||||
})
|
||||
|
||||
QUnit.test('should hide dropdown', function (assert) {
|
||||
assert.expect(2)
|
||||
|
||||
@ -1180,12 +1149,14 @@ $(function () {
|
||||
.find('[data-toggle="dropdown"]')
|
||||
.bootstrapDropdown()
|
||||
|
||||
var dropdown = $dropdown.data('bs.dropdown')
|
||||
var dropdown = Dropdown._getInstance($dropdown[0])
|
||||
var done = assert.async()
|
||||
$dropdown.trigger('click')
|
||||
|
||||
$dropdown
|
||||
.parent('.dropdown')
|
||||
.on('shown.bs.dropdown', function () {
|
||||
dropdown.hide()
|
||||
})
|
||||
.on('hide.bs.dropdown', function () {
|
||||
assert.ok(true, 'hide was fired')
|
||||
})
|
||||
@ -1194,7 +1165,7 @@ $(function () {
|
||||
done()
|
||||
})
|
||||
|
||||
dropdown.hide()
|
||||
dropdown.show()
|
||||
})
|
||||
|
||||
QUnit.test('should not hide dropdown', function (assert) {
|
||||
@ -1213,7 +1184,7 @@ $(function () {
|
||||
.find('[data-toggle="dropdown"]')
|
||||
.bootstrapDropdown()
|
||||
|
||||
var dropdown = $dropdown.data('bs.dropdown')
|
||||
var dropdown = Dropdown._getInstance($dropdown[0])
|
||||
$dropdown.trigger('click')
|
||||
dropdown.show()
|
||||
|
||||
@ -1236,7 +1207,7 @@ $(function () {
|
||||
.find('[data-toggle="dropdown"]')
|
||||
.bootstrapDropdown()
|
||||
|
||||
var dropdown = $dropdown.data('bs.dropdown')
|
||||
var dropdown = Dropdown._getInstance($dropdown[0])
|
||||
dropdown.hide()
|
||||
assert.ok(!$dropdown.parent('.dropdown').hasClass('show'), 'dropdown menu is still hidden')
|
||||
})
|
||||
@ -1257,7 +1228,7 @@ $(function () {
|
||||
.find('[data-toggle="dropdown"]')
|
||||
.bootstrapDropdown()
|
||||
|
||||
var dropdown = $dropdown.data('bs.dropdown')
|
||||
var dropdown = Dropdown._getInstance($dropdown[0])
|
||||
var done = assert.async()
|
||||
|
||||
$dropdown
|
||||
@ -1289,7 +1260,7 @@ $(function () {
|
||||
.find('[data-toggle="dropdown"]')
|
||||
.bootstrapDropdown()
|
||||
|
||||
var dropdown = $dropdown.data('bs.dropdown')
|
||||
var dropdown = Dropdown._getInstance($dropdown[0])
|
||||
var done = assert.async()
|
||||
|
||||
$dropdown
|
||||
@ -1319,19 +1290,21 @@ $(function () {
|
||||
.find('[data-toggle="dropdown"]')
|
||||
.bootstrapDropdown()
|
||||
|
||||
var dropdown = $dropdown.data('bs.dropdown')
|
||||
var dropdown = Dropdown._getInstance($dropdown[0])
|
||||
var done = assert.async()
|
||||
$dropdown.trigger('click')
|
||||
|
||||
$dropdown
|
||||
.parent('.dropdown')
|
||||
.on('shown.bs.dropdown', function () {
|
||||
dropdown.hide()
|
||||
})
|
||||
.on('hide.bs.dropdown', function (event) {
|
||||
event.preventDefault()
|
||||
assert.ok($dropdown.parent('.dropdown').hasClass('show'), 'dropdown menu is shown')
|
||||
done()
|
||||
})
|
||||
|
||||
dropdown.hide()
|
||||
assert.ok($dropdown.parent('.dropdown').hasClass('show'), 'dropdown menu is shown')
|
||||
dropdown.show()
|
||||
})
|
||||
|
||||
QUnit.test('should not open dropdown via show method if target is disabled via attribute', function (assert) {
|
||||
|
@ -2,6 +2,7 @@ $(function () {
|
||||
'use strict'
|
||||
|
||||
window.Util = typeof bootstrap !== 'undefined' ? bootstrap.Util : Util
|
||||
var Modal = typeof window.bootstrap !== 'undefined' ? window.bootstrap.Modal : window.Modal
|
||||
|
||||
QUnit.module('modal plugin')
|
||||
|
||||
@ -624,43 +625,6 @@ $(function () {
|
||||
assert.ok(evt.defaultPrevented, 'model shown instead of navigating to href')
|
||||
})
|
||||
|
||||
QUnit.test('should not parse target as html', function (assert) {
|
||||
assert.expect(1)
|
||||
var done = assert.async()
|
||||
|
||||
var $toggleBtn = $('<button data-toggle="modal" data-target="<div id="modal-test"><div class="contents"<div<div id="close" data-dismiss="modal"/></div></div>"/>')
|
||||
.appendTo('#qunit-fixture')
|
||||
|
||||
$toggleBtn.trigger('click')
|
||||
setTimeout(function () {
|
||||
assert.strictEqual($('#modal-test').length, 0, 'target has not been parsed and added to the document')
|
||||
done()
|
||||
}, 0)
|
||||
})
|
||||
|
||||
QUnit.test('should not execute js from target', function (assert) {
|
||||
assert.expect(0)
|
||||
var done = assert.async()
|
||||
|
||||
// This toggle button contains XSS payload in its data-target
|
||||
// Note: it uses the onerror handler of an img element to execute the js, because a simple script element does not work here
|
||||
// a script element works in manual tests though, so here it is likely blocked by the qunit framework
|
||||
var $toggleBtn = $('<button data-toggle="modal" data-target="<div><image src="missing.png" onerror="$('#qunit-fixture button.control').trigger('click')"></div>"/>')
|
||||
.appendTo('#qunit-fixture')
|
||||
// The XSS payload above does not have a closure over this function and cannot access the assert object directly
|
||||
// However, it can send a click event to the following control button, which will then fail the assert
|
||||
$('<button>')
|
||||
.addClass('control')
|
||||
.on('click', function () {
|
||||
assert.notOk(true, 'XSS payload is not executed as js')
|
||||
})
|
||||
.appendTo('#qunit-fixture')
|
||||
|
||||
$toggleBtn.trigger('click')
|
||||
|
||||
setTimeout(done, 500)
|
||||
})
|
||||
|
||||
QUnit.test('should not try to open a modal which is already visible', function (assert) {
|
||||
assert.expect(1)
|
||||
var done = assert.async()
|
||||
@ -717,7 +681,7 @@ $(function () {
|
||||
})
|
||||
|
||||
QUnit.test('should dispose modal', function (assert) {
|
||||
assert.expect(3)
|
||||
assert.expect(2)
|
||||
var done = assert.async()
|
||||
|
||||
var $modal = $([
|
||||
@ -731,31 +695,19 @@ $(function () {
|
||||
].join('')).appendTo('#qunit-fixture')
|
||||
|
||||
$modal.on('shown.bs.modal', function () {
|
||||
var spy = sinon.spy($.fn, 'off')
|
||||
var modal = Modal._getInstance($modal[0])
|
||||
var spy = sinon.spy($modal[0], 'removeEventListener')
|
||||
|
||||
$(this).bootstrapModal('dispose')
|
||||
modal.dispose()
|
||||
|
||||
var modalDataApiEvent = []
|
||||
$._data(document, 'events').click
|
||||
.forEach(function (e) {
|
||||
if (e.namespace === 'bs.data-api.modal') {
|
||||
modalDataApiEvent.push(e)
|
||||
}
|
||||
})
|
||||
|
||||
assert.ok(typeof $(this).data('bs.modal') === 'undefined', 'modal data object was disposed')
|
||||
|
||||
assert.ok(spy.callCount === 4, '`jQuery.off` was called')
|
||||
|
||||
assert.ok(modalDataApiEvent.length === 1, '`Event.CLICK_DATA_API` on `document` was not removed')
|
||||
|
||||
$.fn.off.restore()
|
||||
assert.ok(!Modal._getInstance($modal[0]), 'modal data object was disposed')
|
||||
assert.ok(spy.called)
|
||||
done()
|
||||
}).bootstrapModal('show')
|
||||
})
|
||||
|
||||
QUnit.test('should enforce focus', function (assert) {
|
||||
assert.expect(4)
|
||||
assert.expect(2)
|
||||
var done = assert.async()
|
||||
|
||||
var $modal = $([
|
||||
@ -770,27 +722,26 @@ $(function () {
|
||||
.bootstrapModal()
|
||||
.appendTo('#qunit-fixture')
|
||||
|
||||
var modal = $modal.data('bs.modal')
|
||||
var modal = Modal._getInstance($modal[0])
|
||||
var spy = sinon.spy(modal, '_enforceFocus')
|
||||
var spyDocOff = sinon.spy($(document), 'off')
|
||||
var spyDocOn = sinon.spy($(document), 'on')
|
||||
|
||||
$modal.one('shown.bs.modal', function () {
|
||||
assert.ok(spy.called, '_enforceFocus called')
|
||||
assert.ok(spyDocOff.withArgs('focusin.bs.modal'))
|
||||
assert.ok(spyDocOn.withArgs('focusin.bs.modal'))
|
||||
|
||||
var spyFocus = sinon.spy(modal._element, 'focus')
|
||||
var event = $.Event('focusin', {
|
||||
target: $('#qunit-fixture')[0]
|
||||
})
|
||||
|
||||
$(document).one('focusin', function () {
|
||||
function focusInListener() {
|
||||
assert.ok(spyFocus.called)
|
||||
document.removeEventListener('focusin', focusInListener)
|
||||
done()
|
||||
}
|
||||
document.addEventListener('focusin', focusInListener)
|
||||
|
||||
var focusInEvent = new Event('focusin')
|
||||
Object.defineProperty(focusInEvent, 'target', {
|
||||
value: $('#qunit-fixture')[0]
|
||||
})
|
||||
|
||||
$(document).trigger(event)
|
||||
document.dispatchEvent(focusInEvent)
|
||||
})
|
||||
.bootstrapModal('show')
|
||||
})
|
||||
|
@ -1034,7 +1034,7 @@ $(function () {
|
||||
var $tipTest = $('<div class="bs-tooltip" />')
|
||||
.appendTo('#qunit-fixture')
|
||||
|
||||
var tooltip = $tooltip.data('bs.tooltip')
|
||||
var tooltip = Tooltip._getInstance($tooltip[0])
|
||||
tooltip.tip = null
|
||||
|
||||
tooltip._handlePopperPlacementChange({
|
||||
@ -1054,7 +1054,7 @@ $(function () {
|
||||
.appendTo('#qunit-fixture')
|
||||
.bootstrapTooltip()
|
||||
|
||||
var tooltip = $tooltip.data('bs.tooltip')
|
||||
var tooltip = Tooltip._getInstance($tooltip[0])
|
||||
|
||||
assert.strictEqual(tooltip._isEnabled, true)
|
||||
|
||||
|
@ -51,11 +51,11 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="../../dist/util.js"></script>
|
||||
<script src="../../dist/dom/polyfill.js"></script>
|
||||
<script src="../../dist/dom/eventHandler.js"></script>
|
||||
<script src="../../dist/dom/selectorEngine.js"></script>
|
||||
<script src="../../dist/dom/data.js"></script>
|
||||
<script src="../../dist/util.js"></script>
|
||||
<script src="../../dist/alert.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -45,6 +45,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="../../dist/util.js"></script>
|
||||
<script src="../../dist/dom/polyfill.js"></script>
|
||||
<script src="../../dist/dom/manipulator.js"></script>
|
||||
<script src="../../dist/dom/eventHandler.js"></script>
|
||||
|
@ -71,12 +71,12 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="../../dist/util.js"></script>
|
||||
<script src="../../dist/dom/polyfill.js"></script>
|
||||
<script src="../../dist/dom/manipulator.js"></script>
|
||||
<script src="../../dist/dom/eventHandler.js"></script>
|
||||
<script src="../../dist/dom/selectorEngine.js"></script>
|
||||
<script src="../../dist/dom/data.js"></script>
|
||||
<script src="../../dist/util.js"></script>
|
||||
<script src="../../dist/collapse.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -210,12 +210,12 @@
|
||||
</div>
|
||||
|
||||
<script src="../../../node_modules/popper.js/dist/umd/popper.min.js"></script>
|
||||
<script src="../../dist/util.js"></script>
|
||||
<script src="../../dist/dom/polyfill.js"></script>
|
||||
<script src="../../dist/dom/eventHandler.js"></script>
|
||||
<script src="../../dist/dom/data.js"></script>
|
||||
<script src="../../dist/dom/selectorEngine.js"></script>
|
||||
<script src="../../dist/dom/manipulator.js"></script>
|
||||
<script src="../../dist/util.js"></script>
|
||||
<script src="../../dist/dropdown.js"></script>
|
||||
<script src="../../dist/collapse.js"></script>
|
||||
</body>
|
||||
|
@ -206,12 +206,12 @@
|
||||
</div>
|
||||
|
||||
<script src="../../../node_modules/popper.js/dist/umd/popper.min.js"></script>
|
||||
<script src="../../dist/util.js"></script>
|
||||
<script src="../../dist/dom/polyfill.js"></script>
|
||||
<script src="../../dist/dom/data.js"></script>
|
||||
<script src="../../dist/dom/eventHandler.js"></script>
|
||||
<script src="../../dist/dom/manipulator.js"></script>
|
||||
<script src="../../dist/dom/selectorEngine.js"></script>
|
||||
<script src="../../dist/util.js"></script>
|
||||
<script src="../../dist/modal.js"></script>
|
||||
<script src="../../dist/collapse.js"></script>
|
||||
<script src="../../dist/tooltip.js"></script>
|
||||
|
@ -32,12 +32,12 @@
|
||||
</div>
|
||||
|
||||
<script src="../../../node_modules/popper.js/dist/umd/popper.min.js"></script>
|
||||
<script src="../../dist/util.js"></script>
|
||||
<script src="../../dist/dom/polyfill.js"></script>
|
||||
<script src="../../dist/dom/manipulator.js"></script>
|
||||
<script src="../../dist/dom/data.js"></script>
|
||||
<script src="../../dist/dom/eventHandler.js"></script>
|
||||
<script src="../../dist/dom/selectorEngine.js"></script>
|
||||
<script src="../../dist/util.js"></script>
|
||||
<script src="../../dist/tooltip.js"></script>
|
||||
<script src="../../dist/popover.js"></script>
|
||||
<script>
|
||||
|
@ -86,13 +86,12 @@
|
||||
<p>Ad leggings keytar, brunch id art party dolor labore.</p>
|
||||
</div>
|
||||
|
||||
<script src="../../../site/docs/4.2/assets/js/vendor/popper.min.js"></script>
|
||||
<script src="../../dist/util.js"></script>
|
||||
<script src="../../dist/dom/polyfill.js"></script>
|
||||
<script src="../../dist/dom/data.js"></script>
|
||||
<script src="../../dist/dom/eventHandler.js"></script>
|
||||
<script src="../../dist/dom/manipulator.js"></script>
|
||||
<script src="../../dist/dom/selectorEngine.js"></script>
|
||||
<script src="../../dist/util.js"></script>
|
||||
<script src="../../dist/scrollspy.js"></script>
|
||||
<script src="../../dist/dropdown.js"></script>
|
||||
<script src="../../dist/collapse.js"></script>
|
||||
|
@ -226,12 +226,12 @@
|
||||
</div>
|
||||
|
||||
<script src="../../../node_modules/popper.js/dist/umd/popper.min.js"></script>
|
||||
<script src="../../dist/util.js"></script>
|
||||
<script src="../../dist/dom/polyfill.js"></script>
|
||||
<script src="../../dist/dom/data.js"></script>
|
||||
<script src="../../dist/dom/eventHandler.js"></script>
|
||||
<script src="../../dist/dom/manipulator.js"></script>
|
||||
<script src="../../dist/dom/selectorEngine.js"></script>
|
||||
<script src="../../dist/util.js"></script>
|
||||
<script src="../../dist/tab.js"></script>
|
||||
<script src="../../dist/dropdown.js"></script>
|
||||
</body>
|
||||
|
@ -72,12 +72,12 @@
|
||||
</div>
|
||||
|
||||
<script src="../../../node_modules/popper.js/dist/umd/popper.min.js"></script>
|
||||
<script src="../../dist/util.js"></script>
|
||||
<script src="../../dist/dom/polyfill.js"></script>
|
||||
<script src="../../dist/dom/manipulator.js"></script>
|
||||
<script src="../../dist/dom/data.js"></script>
|
||||
<script src="../../dist/dom/eventHandler.js"></script>
|
||||
<script src="../../dist/dom/selectorEngine.js"></script>
|
||||
<script src="../../dist/util.js"></script>
|
||||
<script src="../../dist/tooltip.js"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
|
Loading…
x
Reference in New Issue
Block a user