]> git.ipfire.org Git - thirdparty/bootstrap.git/commitdiff
chore(update): bump to 4.1.3
authorJohann-S <johann.servoire@gmail.com>
Wed, 25 Jul 2018 09:29:16 +0000 (11:29 +0200)
committerXhmikosR <xhmikosr@gmail.com>
Wed, 20 Feb 2019 20:05:45 +0000 (22:05 +0200)
28 files changed:
build/build-plugins.js
js/src/alert.js
js/src/carousel.js
js/src/dom/data.js
js/src/dom/eventHandler.js
js/src/dom/manipulator.js
js/src/dom/polyfill.js
js/src/dom/selectorEngine.js
js/src/dropdown.js
js/src/index.js
js/src/modal.js
js/src/tooltip.js
js/src/util.js
js/tests/index.html
js/tests/karma.conf.js
js/tests/unit/carousel.js
js/tests/unit/dropdown.js
js/tests/unit/modal.js
js/tests/unit/tooltip.js
js/tests/visual/alert.html
js/tests/visual/carousel.html
js/tests/visual/collapse.html
js/tests/visual/dropdown.html
js/tests/visual/modal.html
js/tests/visual/popover.html
js/tests/visual/scrollspy.html
js/tests/visual/tab.html
js/tests/visual/tooltip.html

index abcbc5e2f577edc75d874d6284a284b2f693669d..a5f95a9d15886efd7c037d54c82c25b4dbeb5451 100644 (file)
@@ -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}`))
index bc368ae6224f37ff9222ca179599a03c5a4311a3..a8d0cc5da99b9acedf4788b1a62af6d708920d30 100644 (file)
@@ -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)
   }
index 32a039c49dcb09659dba60e7d99f827362a36fdb..9ff7c09e729d2e43f4bfeca25d6cc3cf1785d3de 100644 (file)
@@ -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
index 2c11151257bd3cb2fed3a12aa83b3e5edbb15c0b..2dfaad91a416dc023540298a7151a401d6e16e5f 100644 (file)
@@ -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)
  * --------------------------------------------------------------------------
  */
index 17f6d077a6d3e18e82e1b3ce19217bbac009e376..259f575ed933661e8de1dc3e4319d3e040ceb3d4 100644 (file)
@@ -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
index db3113f88d6e6706da4fc02726f40f1b379a174d..ad14e2914860af8fd1e2177eadaebfba30233318 100644 (file)
@@ -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)
  * --------------------------------------------------------------------------
  */
index c0c1139f03604a842ff8a7ff9914decfb7a9a401..45defb76e74b1e2015557b79ff9cee3e04da6bef 100644 (file)
@@ -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)
  * --------------------------------------------------------------------------
  */
index 55d2ce4bbc017272d93cc1614b76082b79017b19..c2eec95a7eb73a64fa47031b867b536b466dcfc2 100644 (file)
@@ -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)
  * --------------------------------------------------------------------------
  */
index 6a4fb9e0137c1649f163845a2796c1fdf3a035d5..9a22a69916e319a670b25995ee4324c433f5093e 100644 (file)
@@ -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() {
index 0c662873df3cdcd3d90837064471549b65016bbb..aa35ed07b30b35894b2c11b15566960936ddbf1a 100644 (file)
@@ -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,
index 34aa56606c2489f83f270353368d222b5c3924fe..8e56fc5b29dc63dc76a0eb087f0703c409ca0b31 100644 (file)
@@ -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)
 
index 29394b9484e23478c5f8dee5929982f01d63c12c..93880bb8e402e9dcc0fdd316bf2690582da96150 100644 (file)
@@ -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]
     }
 
index 7a97411bbf24ef3aaf6120e26c5d31cdd5dec6f6..caa2e63485afd32baee2b308160c3591457f64fb 100644 (file)
@@ -5,8 +5,6 @@
  * --------------------------------------------------------------------------
  */
 
-import EventHandler from './dom/eventHandler'
-
 /**
  * ------------------------------------------------------------------------
  * Private TransitionEnd Helpers
index d0ff5b82b62ea2b3762dab1fe86adffa9aa53003..77c29f8f85fdd21da72b121a1572a928f7a0c838 100644 (file)
     </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>
index 469a95561f516305420a172987d9cdbb01b38861..641ac88949cd083ebcbfb85dff6ce657848d030b 100644 (file)
@@ -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
index 9016f61abb44f1f5c5133130c792f62477c45a2d..3db83eaa38cfedafdb67aa65f5b83c11303f4496 100644 (file)
@@ -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()
index a9a5773e61cc62ee44a9d565cbddf718f099df45..3c1c9d03dfa44e3774f0416a77eea13f09346aa0 100644 (file)
@@ -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) {
index 0739f03782846857cb7aee435217ddbd9e70b6fa..dacb1fb8d71071ef55cf6378468881f42cd0a69e 100644 (file)
@@ -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')
   })
index 23cd0cafd5fa2b3b6556361b5cdc9bb87f1a593c..47425dd57f2afd0821b344d0825b5f518d630722 100644 (file)
@@ -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)
 
index 8b073a9fc106b470a806e2a0740fabdd9fb74b81..2e0733c4250ec0265f1bc799d6278f2ec90bc845 100644 (file)
       </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>
index 42e81df6c0869aef6f41dd539e9333b2d4924904..fba62866d153a6b8c2094394e941ef008cbb3da0 100644 (file)
@@ -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>
index e905e451a1c8dee527e6af6a8da1f5009b2ac951..1d6533a3ca19f8b73f2c71de9c6905416c6e9a80 100644 (file)
       </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>
index 951aefa96e4e51e30c444936c28f5b9306cd0dcb..c6f8387a64895719283ae78d161d5635ecfec38f 100644 (file)
     </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>
index 1f0eb0d637faa1bae34597da36e41fe61eafc2d7..b37beeef38423e6b22cf229202d391a5244dd7be 100644 (file)
     </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>
index 676ca9448ea08538d086a50d30939dfb64cee357..d408dbb9035b4c9c8bf123938ea0a672344f64a8 100644 (file)
     </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>
index 00def6a7c6a634ee7a1ac54ff05e77bce5b74562..692d84cf4affbde121cf4a731b6c6f519af41b7a 100644 (file)
       <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>
index 7c6d95ee49e02d4b055e26ed9d71586919482ffa..0b0582adda4adbe0d6f7a476f61ffa5868beaa7a 100644 (file)
     </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>
index d97f8d57a34cf61aad6af1a5e7c61772dcc49730..1cc5507a79ac30e71a747bf88114a7a16313c1e6 100644 (file)
     </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 () {