+import Polyfill from './polyfill'
import Util from '../util'
/**
* --------------------------------------------------------------------------
- * Bootstrap (v4.0.0-beta): dom/eventHandler.js
+ * Bootstrap (v4.1.1): dom/eventHandler.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* --------------------------------------------------------------------------
*/
const EventHandler = (() => {
- /**
- * ------------------------------------------------------------------------
- * Polyfills
- * ------------------------------------------------------------------------
- */
-
- // defaultPrevented is broken in IE.
- // https://connect.microsoft.com/IE/feedback/details/790389/event-defaultprevented-returns-false-after-preventdefault-was-called
- const workingDefaultPrevented = (() => {
- const e = document.createEvent('CustomEvent')
- e.initEvent('Bootstrap', true, true)
- e.preventDefault()
- return e.defaultPrevented
- })()
-
- let defaultPreventedPreservedOnDispatch = true
-
- // CustomEvent polyfill for IE (see: https://mzl.la/2v76Zvn)
- if (typeof window.CustomEvent !== 'function') {
- window.CustomEvent = (event, params) => {
- params = params || {
- bubbles: false,
- cancelable: false,
- detail: null
- }
- const evt = document.createEvent('CustomEvent')
- evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail)
- if (!workingDefaultPrevented) {
- const origPreventDefault = Event.prototype.preventDefault
- evt.preventDefault = () => {
- if (!evt.cancelable) {
- return
- }
-
- origPreventDefault.call(evt)
- Object.defineProperty(evt, 'defaultPrevented', {
- get() {
- return true
- },
- configurable: true
- })
- }
- }
- return evt
- }
-
- window.CustomEvent.prototype = window.Event.prototype
- } else {
- // MSEdge resets defaultPrevented flag upon dispatchEvent call if at least one listener is attached
- defaultPreventedPreservedOnDispatch = (() => {
- const e = new CustomEvent('Bootstrap', {
- cancelable: true
- })
-
- const element = document.createElement('div')
- element.addEventListener('Bootstrap', () => null)
-
- e.preventDefault()
- element.dispatchEvent(e)
- return e.defaultPrevented
- })()
- }
-
- // Event constructor shim
- if (!window.Event || typeof window.Event !== 'function') {
- const origEvent = window.Event
- window.Event = (inType, params) => {
- params = params || {}
- const e = document.createEvent('Event')
- e.initEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable))
- return e
- }
- window.Event.prototype = origEvent.prototype
- }
-
/**
* ------------------------------------------------------------------------
* Constants
if (defaultPrevented) {
evt.preventDefault()
- if (!defaultPreventedPreservedOnDispatch) {
+ if (!Polyfill.defaultPreventedPreservedOnDispatch) {
Object.defineProperty(evt, 'defaultPrevented', {
get: () => true
})
})()
// focusin and focusout polyfill
-if (typeof window.onfocusin === 'undefined') {
+if (Polyfill.focusIn) {
(() => {
function listenerFocus(event) {
EventHandler.trigger(event.target, 'focusin')
-import EventHandler from './eventHandler'
+import Util from '../util'
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.1.1): dom/polyfill.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
const Polyfill = (() => {
- // defaultPrevented is broken in IE.
- // https://connect.microsoft.com/IE/feedback/details/790389/event-defaultprevented-returns-false-after-preventdefault-was-called
+ // defaultPrevented is broken in IE
const workingDefaultPrevented = (() => {
const e = document.createEvent('CustomEvent')
e.initEvent('Bootstrap', true, true)
return e.defaultPrevented
})()
- let defaultPreventedPreservedOnDispatch = true
+ if (!workingDefaultPrevented) {
+ const origPreventDefault = Event.prototype.preventDefault
+ Event.prototype.preventDefault = function () {
+ if (!this.cancelable) {
+ return
+ }
+
+ origPreventDefault.call(this)
+ Object.defineProperty(this, 'defaultPrevented', {
+ get() {
+ return true
+ },
+ configurable: true
+ })
+ }
+ }
// CustomEvent polyfill for IE (see: https://mzl.la/2v76Zvn)
if (typeof window.CustomEvent !== 'function') {
}
const evt = document.createEvent('CustomEvent')
evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail)
- if (!workingDefaultPrevented) {
- const origPreventDefault = Event.prototype.preventDefault
- evt.preventDefault = () => {
- if (!evt.cancelable) {
- return
- }
-
- origPreventDefault.call(evt)
- Object.defineProperty(evt, 'defaultPrevented', {
- get() {
- return true
- },
- configurable: true
- })
- }
- }
return evt
}
window.CustomEvent.prototype = window.Event.prototype
- } else {
- // MSEdge resets defaultPrevented flag upon dispatchEvent call if at least one listener is attached
- defaultPreventedPreservedOnDispatch = (() => {
- const e = new CustomEvent('Bootstrap', {
- cancelable: true
- })
+ }
- const element = document.createElement('div')
- element.addEventListener('Bootstrap', () => null)
+ // MSEdge resets defaultPrevented flag upon dispatchEvent call if at least one listener is attached
+ const defaultPreventedPreservedOnDispatch = (() => {
+ const e = new CustomEvent('Bootstrap', {
+ cancelable: true
+ })
- e.preventDefault()
- element.dispatchEvent(e)
- return e.defaultPrevented
- })()
- }
+ const element = document.createElement('div')
+ element.addEventListener('Bootstrap', () => null)
+
+ e.preventDefault()
+ element.dispatchEvent(e)
+ return e.defaultPrevented
+ })()
// Event constructor shim
if (!window.Event || typeof window.Event !== 'function') {
window.Event.prototype = origEvent.prototype
}
- // focusin and focusout polyfill
- if (typeof window.onfocusin === 'undefined') {
- (() => {
- function listenerFocus(event) {
- EventHandler.trigger(event.target, 'focusin')
+ // matches polyfill (see: https://mzl.la/2ikXneG)
+ if (!Element.prototype.matches) {
+ Element.prototype.matches =
+ Element.prototype.msMatchesSelector ||
+ Element.prototype.webkitMatchesSelector
+ }
+
+ // closest polyfill (see: https://mzl.la/2vXggaI)
+ let closest
+ if (!Element.prototype.closest) {
+ closest = (element, selector) => {
+ let ancestor = element
+ do {
+ if (ancestor.matches(selector)) {
+ return ancestor
+ }
+
+ ancestor = ancestor.parentElement
+ } while (ancestor !== null && ancestor.nodeType === Node.ELEMENT_NODE)
+
+ return null
+ }
+ } else {
+ closest = (element, selector) => element.closest(selector)
+ }
+
+ const supportScopeQuery = (() => {
+ const element = document.createElement('div')
+ try {
+ element.querySelectorAll(':scope *')
+ } catch (e) {
+ return false
+ }
+
+ return true
+ })()
+
+ const scopeSelectorRegex = /:scope\b/
+ let find = Element.prototype.querySelectorAll
+ let findOne = Element.prototype.querySelector
+
+ if (!supportScopeQuery) {
+ find = function (selector) {
+ if (!scopeSelectorRegex.test(selector)) {
+ return this.querySelectorAll(selector)
}
- function listenerBlur(event) {
- EventHandler.trigger(event.target, 'focusout')
+
+ const hasId = Boolean(this.id)
+ if (!hasId) {
+ this.id = Util.getUID('scope')
}
- EventHandler.on(document, 'focus', 'input', listenerFocus)
- EventHandler.on(document, 'blur', 'input', listenerBlur)
- })()
+
+ let nodeList = null
+ try {
+ selector = selector.replace(scopeSelectorRegex, `#${this.id}`)
+ nodeList = this.querySelectorAll(selector)
+ } finally {
+ if (!hasId) {
+ this.removeAttribute('id')
+ }
+ }
+
+ return nodeList
+ }
+
+ findOne = function (selector) {
+ if (!scopeSelectorRegex.test(selector)) {
+ return this.querySelector(selector)
+ }
+
+ const matches = find.call(this, selector)
+ if (typeof matches[0] !== 'undefined') {
+ return matches[0]
+ }
+
+ return null
+ }
}
return {
- get defaultPreventedPreservedOnDispatch() {
- return defaultPreventedPreservedOnDispatch
- }
+ defaultPreventedPreservedOnDispatch,
+ focusIn: typeof window.onfocusin === 'undefined',
+ closest,
+ find,
+ findOne
}
})()
+import Polyfill from './polyfill'
import Util from '../util'
/**
const SelectorEngine = (() => {
/**
* ------------------------------------------------------------------------
- * Polyfills
+ * Constants
* ------------------------------------------------------------------------
*/
- // matches polyfill (see: https://mzl.la/2ikXneG)
- let fnMatches = null
- if (!Element.prototype.matches) {
- fnMatches =
- Element.prototype.msMatchesSelector ||
- Element.prototype.webkitMatchesSelector
- } else {
- fnMatches = Element.prototype.matches
- }
-
- // closest polyfill (see: https://mzl.la/2vXggaI)
- let fnClosest = null
- if (!Element.prototype.closest) {
- fnClosest = (element, selector) => {
- let ancestor = element
- do {
- if (fnMatches.call(ancestor, selector)) {
- return ancestor
- }
-
- ancestor = ancestor.parentElement
- } while (ancestor !== null && ancestor.nodeType === Node.ELEMENT_NODE)
-
- return null
- }
- } else {
- // eslint-disable-next-line arrow-body-style
- fnClosest = (element, selector) => {
- return element.closest(selector)
- }
- }
-
- const scopeSelectorRegex = /:scope\b/
- const supportScopeQuery = (() => {
- const element = document.createElement('div')
- try {
- element.querySelectorAll(':scope *')
- } catch (e) {
- return false
- }
-
- return true
- })()
-
- let findFn = null
- let findOneFn = null
- if (supportScopeQuery) {
- findFn = Element.prototype.querySelectorAll
- findOneFn = Element.prototype.querySelector
- } else {
- findFn = function (selector) {
- if (!scopeSelectorRegex.test(selector)) {
- return this.querySelectorAll(selector)
- }
-
- const hasId = Boolean(this.id)
- if (!hasId) {
- this.id = Util.getUID('scope')
- }
-
- let nodeList = null
- try {
- selector = selector.replace(scopeSelectorRegex, `#${this.id}`)
- nodeList = this.querySelectorAll(selector)
- } finally {
- if (!hasId) {
- this.removeAttribute('id')
- }
- }
-
- return nodeList
- }
-
- findOneFn = function (selector) {
- if (!scopeSelectorRegex.test(selector)) {
- return this.querySelector(selector)
- }
-
- const matches = findFn.call(this, selector)
- if (typeof matches[0] !== 'undefined') {
- return matches[0]
- }
-
- return null
- }
- }
+ const closest = Polyfill.closest
+ const find = Polyfill.find
+ const findOne = Polyfill.findOne
return {
matches(element, selector) {
- return fnMatches.call(element, selector)
+ return element.matches(selector)
},
find(selector, element = document.documentElement) {
return null
}
- return findFn.call(element, selector)
+ return find.call(element, selector)
},
findOne(selector, element = document.documentElement) {
return null
}
- return findOneFn.call(element, selector)
+ return findOne.call(element, selector)
},
children(element, selector) {
let ancestor = element.parentNode
while (ancestor && ancestor.nodeType === Node.ELEMENT_NODE) {
- if (fnMatches.call(ancestor, selector)) {
+ if (ancestor.matches(selector)) {
parents.push(ancestor)
}
},
closest(element, selector) {
- return fnClosest(element, selector)
+ return closest(element, selector)
},
prev(element, selector) {
let previous = element.previousSibling
while (previous) {
- if (fnMatches.call(previous, selector)) {
+ if (previous.matches(selector)) {
siblings.push(previous)
}
'js/coverage/dist/dom/data.js',
'js/coverage/dist/dom/manipulator.js',
'js/coverage/dist/util.js',
- 'js/coverage/dist/dom/*.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
'js/tests/unit/*.js',
'js/coverage/dist/dom/data.js',
'js/coverage/dist/dom/manipulator.js',
'js/coverage/dist/util.js',
- 'js/coverage/dist/dom/*.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
'js/tests/unit/*.js',