Commit c44db783 authored by Johann-S's avatar Johann-S Committed by XhmikosR
Browse files

chore(update): bump to 4.1.3

parent cf821e1d
main cleanup-floating-forms cssvar-function dependabot/npm_and_yarn/stylelint-and-stylelint-config-twbs-bootstrap-15.3.0 extend-snippets feat/data-target floating-always-visible floating-labels-icons fod-main-banner form-controls-with-icons github/fork/719media/patch-13 github/fork/719media/patch-14 github/fork/719media/patch-9 github/fork/ChellyAhmed/fix-typo-reboot.md github/fork/ChellyAhmed/offcanvas-scroll-back github/fork/CtrlAltLilith/main github/fork/Elysiome/offcanvas-optional-window-resizing github/fork/JanSargsyan/main github/fork/LunicLynx/support-different-line-height-for-buttons github/fork/Psixodelik/main github/fork/Ronid1/ronid1/offcanvas_static_backdrop github/fork/RyanBerliner/tooltip-accessibility github/fork/SantiagoPVazquez/Feature-default-border-bottom-to-dropdown-item github/fork/Sir-Genius/utils github/fork/Sumit-Singh-8/main github/fork/Viktor-VERA2020/offcanvas-slide github/fork/Zivangu9/input-group-for-form-control-plaintext github/fork/alpadev/alpadev/call-dispose-on-component-reinstantiation github/fork/astagi/fix/tree-shake-modules github/fork/compnerd/dark-accordion-icon github/fork/derSascha/dropdown-dont-close-on-input-click github/fork/dev-ph1l/main github/fork/donquixote/issue-33861-utl-mixin github/fork/florianlacreuse/mixin-make-row-gutter-y github/fork/gregorw/main github/fork/iteggmbh/transitionend-dispose-race github/fork/jdelStrother/patch-1 github/fork/jonnysp/form-floating github/fork/jonnysp/independent-offcanvas github/fork/jonnysp/theme-dark-on-card-and-modal-fix github/fork/josefdlange/floating-label-placeholder-opacity github/fork/julien-deramond/enhance-change-version.js github/fork/julien-deramond/main-jd-fix-offset-content github/fork/julien-deramond/main-jd-issue-with-utitlies github/fork/julien-deramond/main-xmr-pa11y-ci-jd-add-hideElements github/fork/kyletsang/fix-tooltip-padding github/fork/lacutah/CheckboxCenteringDocumentation github/fork/lekoala/patch-3 github/fork/louismaximepiton/main-kld-lmp-collapse-proposal github/fork/louismaximepiton/main-lmp-card-inner-border-radius-fix github/fork/louismaximepiton/main-lmp-carousel-multiple-images github/fork/louismaximepiton/main-lmp-css-var-init github/fork/louismaximepiton/main-lmp-disabled-floating-label-fix github/fork/louismaximepiton/main-lmp-input-range-fix github/fork/louismaximepiton/main-lmp-shift-color github/fork/louismaximepiton/main-lmp-table-active-tr-fix github/fork/maciek-szn/switch github/fork/michael-roth/feature/19964-multiple-tab-targets github/fork/mistic100/dom-utils github/fork/nkdas91/accordion github/fork/nstungcom/fix-missing-modal-open-class github/fork/oraliahdz/animation-utilities github/fork/pine3ree/patch-7 github/fork/pouwerkerk/unindent-scss-docs-shortcode github/fork/smares/smares-no-scolling-on-modal-close github/fork/tgm-git/patch-1 gs-forms gs-toasts-with-animated-progress-bar gs/add-history-helper gs/change-version-dir-on-docs gs/data-must-set-onlu-one-instance gs/docs/fix-drop-down-error gs/event-handler-2 gs/make-docs-js-build gs/make-simple-attribute-toggler gs/popover-fix-doc gs/provide-steConfig-method gs/scrollspy-smoothscroll-option-use-browser-history gs/streamline-jqueryInterface gs/support-drop-down-in-navbar gs/test-js-generic-trigger gs/try-web-components gs/tweak-collapse-js-selector gs/use-event-handler-in-cocmponent gs/use-rollup-replace-for-version jo-docs-thanks-page jo-ssr-friendly logical-props-spacing-utils main-fod-disabled-form-check-label main-fod-nested-accordion main-fod-simpler-table-structure main-fod-table-separator main-fod-utilities-contrast main-jd-abbr-title main-jd-add-chips main-jd-add-doc-for-sass-custom-colors main-jd-add-enable-host-to-handle-web-components main-jd-browserstack-fine-tune main-jd-browserstack-updates main-jd-docs-consistent-usage-of-css-sections-step-2 main-jd-fix-docs-headers-in-white main-jd-fix-highlight-docs-border-radius main-jd-fix-placeholder-color-background-params-for-img-markup main-jd-glossary-experiment main-jd-postcss-drop-empty-css-vars main-jd-proto-doc-astro main-jd-skip-navigation-component main-jd-stackblitz-for-examples main-jd-upgrade-browserlistrc main-jd-use-host main-lmp-dark-theme-customization main-lmp-handle-scroll-target main-lmp-tab-fix main-mc-opensearch main-xmr-bundlewatch-action main-xmr-eslint-plugin-compat main-xmr-hugo-docs-vendor main-xmr-hugo-rm-ver main-xmr-linkinator-prod main-xmr-min-mangle main-xmr-pa11y-ci more-darkmode-examples nested-dropdowns patrickhlauke-issue37428 patrickhlauke-use-of-color-tweaks pr/34102 pr/37590 previous-next-docs-links sticky-thead utilities-functions-mixin v530-dev v6-postcss-custom-media v6-spinner-dots v6/gs/use-floating-ui-in-place-of-popper xmr/dev xmr/docs-png xmr/docs-svgs xmr/hugo-reorg-files xmr/js-2 xmr/markdownlint xmr/prepare-530-alpha2 xmr/xo v5.3.0-alpha1 v5.2.3 v5.2.2 v5.2.1 v5.2.0 v5.2.0-beta1 v5.1.3 v5.1.2 v5.1.1 v5.1.0 v5.0.2 v5.0.1 v5.0.0 v5.0.0-beta3 v5.0.0-beta2 v5.0.0-beta1 v5.0.0-alpha3 v5.0.0-alpha2 v5.0.0-alpha1
5 merge requests!31948Examples/Floating-labels: fix bad behavior with autofill,!30064test,!29779Responsive sizing,!28882fix custom-select-indicator in IE10,!28721Hot test
Showing with 220 additions and 190 deletions
+220 -190
......@@ -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/'
function build(plugin) {
console.log(`Building ${plugin} plugin...`)
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
}
const external = ['jquery', 'popper.js']
const globals = {
jquery: 'jQuery', // Ensure we use jQuery which is always available even in noConflict mode
'popper.js': 'Popper'
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
}
// Do not bundle Util in plugins
if (plugin !== 'Util') {
external.push(bsPlugins.Util)
globals[bsPlugins.Util] = 'Util'
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
}
// Do not bundle Tooltip in Popover
if (plugin === 'Popover') {
external.push(bsPlugins.Tooltip)
globals[bsPlugins.Tooltip] = 'Tooltip'
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 config = getConfigByPluginKey(plugin)
const external = config.external
const globals = config.globals
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
......
/**
* --------------------------------------------------------------------------
* 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
/**
* --------------------------------------------------------------------------
* 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">&lsaquo;</a>' +
'<a class="right carousel-control" href="#myCarousel" data-slide="next">&rsaquo;</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,7 +1133,7 @@ $(function () {
assert.ok(dropdown._element === null)
})
QUnit.test('should show dropdown', function (assert) {
QUnit.test('should hide dropdown', function (assert) {
assert.expect(2)
var dropdownHTML =
......@@ -1148,44 +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
.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.hide()
})
dropdown.show()
})
QUnit.test('should hide 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.trigger('click')
$dropdown
.parent('.dropdown')
.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="&lt;div id=&quot;modal-test&quot;&gt;&lt;div class=&quot;contents&quot;&lt;div&lt;div id=&quot;close&quot; data-dismiss=&quot;modal&quot;/&gt;&lt;/div&gt;&lt;/div&gt;"/>')
.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="&lt;div&gt;&lt;image src=&quot;missing.png&quot; onerror=&quot;$(&apos;#qunit-fixture button.control&apos;).trigger(&apos;click&apos;)&quot;&gt;&lt;/div&gt;"/>')
.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')
$(this).bootstrapModal('dispose')
var modal = Modal._getInstance($modal[0])
var spy = sinon.spy($modal[0], 'removeEventListener')
var modalDataApiEvent = []
$._data(document, 'events').click
.forEach(function (e) {
if (e.namespace === 'bs.data-api.modal') {
modalDataApiEvent.push(e)
}
})
modal.dispose()
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>
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment