aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.browserslistrc2
-rw-r--r--.github/ISSUE_TEMPLATE/bug.md4
-rw-r--r--.github/ISSUE_TEMPLATE/bug_report.md4
-rw-r--r--build/vnu-jar.js5
-rw-r--r--bundlesize.config.json4
-rw-r--r--config.yml2
-rw-r--r--js/src/alert.js32
-rw-r--r--js/src/button.js68
-rw-r--r--js/src/carousel.js178
-rw-r--r--js/src/collapse.js98
-rw-r--r--js/src/dom/event-handler.js4
-rw-r--r--js/src/dom/polyfill.js68
-rw-r--r--js/src/dom/selector-engine.js6
-rw-r--r--js/src/dropdown.js162
-rw-r--r--js/src/modal.js156
-rw-r--r--js/src/popover.js24
-rw-r--r--js/src/scrollspy.js82
-rw-r--r--js/src/tab.js90
-rw-r--r--js/src/toast.js60
-rw-r--r--js/src/tooltip.js88
-rw-r--r--js/src/util/index.js13
-rw-r--r--js/tests/browsers.js7
-rw-r--r--js/tests/unit/modal.spec.js6
-rw-r--r--js/tests/unit/util/index.spec.js31
-rw-r--r--package-lock.json242
-rw-r--r--package.json10
-rw-r--r--scss/_breadcrumb.scss16
-rw-r--r--scss/_card.scss4
-rw-r--r--scss/_modal.scss34
-rw-r--r--scss/_navbar.scss5
-rw-r--r--scss/_reboot.scss43
-rw-r--r--scss/_variables.scss2
-rw-r--r--scss/forms/_form-control.scss6
-rw-r--r--scss/forms/_form-file.scss7
-rw-r--r--scss/forms/_form-select.scss7
-rw-r--r--site/content/docs/4.3/components/card.md2
-rw-r--r--site/content/docs/4.3/content/tables.md18
-rw-r--r--site/content/docs/4.3/examples/album/index.html2
-rw-r--r--site/content/docs/4.3/examples/blog/index.html2
-rw-r--r--site/content/docs/4.3/examples/carousel/index.html2
-rw-r--r--site/content/docs/4.3/examples/cover/index.html2
-rw-r--r--site/content/docs/4.3/examples/dashboard/dashboard.css7
-rw-r--r--site/content/docs/4.3/examples/dashboard/index.html4
-rw-r--r--site/content/docs/4.3/examples/floating-labels/floating-labels.css11
-rw-r--r--site/content/docs/4.3/examples/navbar-fixed/index.html2
-rw-r--r--site/content/docs/4.3/examples/navbar-static/index.html2
-rw-r--r--site/content/docs/4.3/examples/navbars/index.html2
-rw-r--r--site/content/docs/4.3/examples/offcanvas/index.html2
-rw-r--r--site/content/docs/4.3/examples/starter-template/index.html2
-rw-r--r--site/content/docs/4.3/examples/sticky-footer-navbar/index.html2
-rw-r--r--site/content/docs/4.3/examples/sticky-footer/index.html2
-rw-r--r--site/content/docs/4.3/forms/form-control.md2
-rw-r--r--site/content/docs/4.3/getting-started/browsers-devices.md9
-rw-r--r--site/content/docs/4.3/getting-started/theming.md2
-rw-r--r--site/content/docs/4.3/helpers/position.md2
-rw-r--r--site/content/docs/4.3/layout/grid.md2
-rw-r--r--site/content/docs/4.3/migration.md2
-rw-r--r--site/content/docs/4.3/utilities/flex.md2
-rw-r--r--site/layouts/_default/404.html2
-rw-r--r--site/layouts/_default/docs.html2
-rw-r--r--site/layouts/_default/single.html2
-rw-r--r--site/layouts/partials/callout-warning-input-support.md2
-rw-r--r--site/layouts/partials/docs-navbar.html2
-rw-r--r--site/layouts/partials/home/masthead.html2
64 files changed, 710 insertions, 957 deletions
diff --git a/.browserslistrc b/.browserslistrc
index f316fb3fd..ab6f9ffa2 100644
--- a/.browserslistrc
+++ b/.browserslistrc
@@ -6,8 +6,8 @@ not dead
Chrome >= 60
Firefox >= 60
Edge >= 16.16299
-Explorer 11
iOS >= 10
Safari >= 10
Android >= 6
+not Explorer <= 11
not ExplorerMobile <= 11
diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md
index 8971d44ad..1f2a890b1 100644
--- a/.github/ISSUE_TEMPLATE/bug.md
+++ b/.github/ISSUE_TEMPLATE/bug.md
@@ -6,6 +6,6 @@ Before opening:
Bug reports must include:
-- Operating system and version (Windows, macOS, Android, iOS, Win10 Mobile)
-- Browser and version (Chrome, Firefox, Safari, IE, MS Edge, Opera 15+, Android Browser)
+- Operating system and version (Windows, macOS, Android, iOS)
+- Browser and version (Chrome, Firefox, Safari, Microsoft Edge, Opera, Android Browser)
- [Reduced test case](https://css-tricks.com/reduced-test-cases/) and suggested fix using [CodePen](https://codepen.io/) or [JS Bin](https://jsbin.com/)
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index 2d77bb50e..083fa137e 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -12,6 +12,6 @@ Before opening:
Bug reports must include:
-- Operating system and version (Windows, macOS, Android, iOS, Win10 Mobile)
-- Browser and version (Chrome, Firefox, Safari, IE, MS Edge, Opera 15+, Android Browser)
+- Operating system and version (Windows, macOS, Android, iOS)
+- Browser and version (Chrome, Firefox, Safari, Microsoft Edge, Opera, Android Browser)
- [Reduced test case](https://css-tricks.com/reduced-test-cases/) and suggested fix using [CodePen](https://codepen.io/) or [JS Bin](https://jsbin.com/)
diff --git a/build/vnu-jar.js b/build/vnu-jar.js
index 4018873f8..674cdb443 100644
--- a/build/vnu-jar.js
+++ b/build/vnu-jar.js
@@ -37,10 +37,7 @@ childProcess.exec('java -version', (error, stdout, stderr) => {
'The “month” input type is not supported in all browsers.*',
'The “color” input type is not supported in all browsers.*',
'The “datetime-local” input type is not supported in all browsers.*',
- 'The “time” input type is not supported in all browsers.*',
- // IE11 doesn't recognize <main> / give the element an implicit "main" landmark.
- // Explicit role="main" is redundant for other modern browsers, but still valid.
- 'The “main” role is unnecessary for element “main”.'
+ 'The “time” input type is not supported in all browsers.*'
].join('|')
const args = [
diff --git a/bundlesize.config.json b/bundlesize.config.json
index a8778cd47..da23ad29f 100644
--- a/bundlesize.config.json
+++ b/bundlesize.config.json
@@ -38,7 +38,7 @@
},
{
"path": "./dist/js/bootstrap.bundle.min.js",
- "maxSize": "24 kB"
+ "maxSize": "23 kB"
},
{
"path": "./dist/js/bootstrap.esm.js",
@@ -54,7 +54,7 @@
},
{
"path": "./dist/js/bootstrap.min.js",
- "maxSize": "17.5 kB"
+ "maxSize": "16.5 kB"
}
]
}
diff --git a/config.yml b/config.yml
index af406a33f..ff9b7046a 100644
--- a/config.yml
+++ b/config.yml
@@ -51,7 +51,7 @@ params:
current_ruby_version: "4.3.1"
rfs_version: "9.0.2"
docs_version: "4.3"
- repo: "https://github.com/twbs/bootstrap"
+ repo: "https://github.com/twbs"
twitter: "getbootstrap"
slack: "https://bootstrap-slack.herokuapp.com/"
opencollective: "https://opencollective.com/bootstrap"
diff --git a/js/src/alert.js b/js/src/alert.js
index dbd931b52..6de3fa7f8 100644
--- a/js/src/alert.js
+++ b/js/src/alert.js
@@ -28,21 +28,15 @@ const DATA_KEY = 'bs.alert'
const EVENT_KEY = `.${DATA_KEY}`
const DATA_API_KEY = '.data-api'
-const Selector = {
- DISMISS: '[data-dismiss="alert"]'
-}
+const SELECTOR_DISMISS = '[data-dismiss="alert"]'
-const Event = {
- CLOSE: `close${EVENT_KEY}`,
- CLOSED: `closed${EVENT_KEY}`,
- CLICK_DATA_API: `click${EVENT_KEY}${DATA_API_KEY}`
-}
+const EVENT_CLOSE = `close${EVENT_KEY}`
+const EVENT_CLOSED = `closed${EVENT_KEY}`
+const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
-const ClassName = {
- ALERT: 'alert',
- FADE: 'fade',
- SHOW: 'show'
-}
+const CLASSNAME_ALERT = 'alert'
+const CLASSNAME_FADE = 'fade'
+const CLASSNAME_SHOW = 'show'
/**
* ------------------------------------------------------------------------
@@ -93,20 +87,20 @@ class Alert {
let parent = getElementFromSelector(element)
if (!parent) {
- parent = SelectorEngine.closest(element, `.${ClassName.ALERT}`)
+ parent = SelectorEngine.closest(element, `.${CLASSNAME_ALERT}`)
}
return parent
}
_triggerCloseEvent(element) {
- return EventHandler.trigger(element, Event.CLOSE)
+ return EventHandler.trigger(element, EVENT_CLOSE)
}
_removeElement(element) {
- element.classList.remove(ClassName.SHOW)
+ element.classList.remove(CLASSNAME_SHOW)
- if (!element.classList.contains(ClassName.FADE)) {
+ if (!element.classList.contains(CLASSNAME_FADE)) {
this._destroyElement(element)
return
}
@@ -123,7 +117,7 @@ class Alert {
element.parentNode.removeChild(element)
}
- EventHandler.trigger(element, Event.CLOSED)
+ EventHandler.trigger(element, EVENT_CLOSED)
}
// Static
@@ -163,7 +157,7 @@ class Alert {
* ------------------------------------------------------------------------
*/
EventHandler
- .on(document, Event.CLICK_DATA_API, Selector.DISMISS, Alert.handleDismiss(new Alert()))
+ .on(document, EVENT_CLICK_DATA_API, SELECTOR_DISMISS, Alert.handleDismiss(new Alert()))
const $ = getjQuery()
diff --git a/js/src/button.js b/js/src/button.js
index 314d2a22a..9c68862b2 100644
--- a/js/src/button.js
+++ b/js/src/button.js
@@ -22,26 +22,20 @@ const DATA_KEY = 'bs.button'
const EVENT_KEY = `.${DATA_KEY}`
const DATA_API_KEY = '.data-api'
-const ClassName = {
- ACTIVE: 'active',
- BUTTON: 'btn',
- DISABLED: 'disabled',
- FOCUS: 'focus'
-}
+const CLASS_NAME_ACTIVE = 'active'
+const CLASS_NAME_BUTTON = 'btn'
+const CLASS_NAME_DISABLED = 'disabled'
+const CLASS_NAME_FOCUS = 'focus'
-const Selector = {
- DATA_TOGGLE_CARROT: '[data-toggle^="button"]',
- DATA_TOGGLE: '[data-toggle="buttons"]',
- INPUT: 'input:not([type="hidden"])',
- ACTIVE: '.active',
- BUTTON: '.btn'
-}
+const SELECTOR_DATA_TOGGLE_CARROT = '[data-toggle^="button"]'
+const SELECTOR_DATA_TOGGLE = '[data-toggle="buttons"]'
+const SELECTOR_INPUT = 'input:not([type="hidden"])'
+const SELECTOR_ACTIVE = '.active'
+const SELECTOR_BUTTON = '.btn'
-const Event = {
- CLICK_DATA_API: `click${EVENT_KEY}${DATA_API_KEY}`,
- FOCUS_DATA_API: `focus${EVENT_KEY}${DATA_API_KEY}`,
- BLUR_DATA_API: `blur${EVENT_KEY}${DATA_API_KEY}`
-}
+const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
+const EVENT_FOCUS_DATA_API = `focus${EVENT_KEY}${DATA_API_KEY}`
+const EVENT_BLUR_DATA_API = `blur${EVENT_KEY}${DATA_API_KEY}`
/**
* ------------------------------------------------------------------------
@@ -69,33 +63,33 @@ class Button {
const rootElement = SelectorEngine.closest(
this._element,
- Selector.DATA_TOGGLE
+ SELECTOR_DATA_TOGGLE
)
if (rootElement) {
- const input = SelectorEngine.findOne(Selector.INPUT, this._element)
+ const input = SelectorEngine.findOne(SELECTOR_INPUT, this._element)
if (input && input.type === 'radio') {
if (input.checked &&
- this._element.classList.contains(ClassName.ACTIVE)) {
+ this._element.classList.contains(CLASS_NAME_ACTIVE)) {
triggerChangeEvent = false
} else {
- const activeElement = SelectorEngine.findOne(Selector.ACTIVE, rootElement)
+ const activeElement = SelectorEngine.findOne(SELECTOR_ACTIVE, rootElement)
if (activeElement) {
- activeElement.classList.remove(ClassName.ACTIVE)
+ activeElement.classList.remove(CLASS_NAME_ACTIVE)
}
}
if (triggerChangeEvent) {
if (input.hasAttribute('disabled') ||
rootElement.hasAttribute('disabled') ||
- input.classList.contains(ClassName.DISABLED) ||
- rootElement.classList.contains(ClassName.DISABLED)) {
+ input.classList.contains(CLASS_NAME_DISABLED) ||
+ rootElement.classList.contains(CLASS_NAME_DISABLED)) {
return
}
- input.checked = !this._element.classList.contains(ClassName.ACTIVE)
+ input.checked = !this._element.classList.contains(CLASS_NAME_ACTIVE)
EventHandler.trigger(input, 'change')
}
@@ -106,11 +100,11 @@ class Button {
if (addAriaPressed) {
this._element.setAttribute('aria-pressed',
- !this._element.classList.contains(ClassName.ACTIVE))
+ !this._element.classList.contains(CLASS_NAME_ACTIVE))
}
if (triggerChangeEvent) {
- this._element.classList.toggle(ClassName.ACTIVE)
+ this._element.classList.toggle(CLASS_NAME_ACTIVE)
}
}
@@ -146,12 +140,12 @@ class Button {
* ------------------------------------------------------------------------
*/
-EventHandler.on(document, Event.CLICK_DATA_API, Selector.DATA_TOGGLE_CARROT, event => {
+EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, event => {
event.preventDefault()
let button = event.target
- if (!button.classList.contains(ClassName.BUTTON)) {
- button = SelectorEngine.closest(button, Selector.BUTTON)
+ if (!button.classList.contains(CLASS_NAME_BUTTON)) {
+ button = SelectorEngine.closest(button, SELECTOR_BUTTON)
}
let data = Data.getData(button, DATA_KEY)
@@ -162,19 +156,19 @@ EventHandler.on(document, Event.CLICK_DATA_API, Selector.DATA_TOGGLE_CARROT, eve
data.toggle()
})
-EventHandler.on(document, Event.FOCUS_DATA_API, Selector.DATA_TOGGLE_CARROT, event => {
- const button = SelectorEngine.closest(event.target, Selector.BUTTON)
+EventHandler.on(document, EVENT_FOCUS_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, event => {
+ const button = SelectorEngine.closest(event.target, SELECTOR_BUTTON)
if (button) {
- button.classList.add(ClassName.FOCUS)
+ button.classList.add(CLASS_NAME_FOCUS)
}
})
-EventHandler.on(document, Event.BLUR_DATA_API, Selector.DATA_TOGGLE_CARROT, event => {
- const button = SelectorEngine.closest(event.target, Selector.BUTTON)
+EventHandler.on(document, EVENT_BLUR_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, event => {
+ const button = SelectorEngine.closest(event.target, SELECTOR_BUTTON)
if (button) {
- button.classList.remove(ClassName.FOCUS)
+ button.classList.remove(CLASS_NAME_FOCUS)
}
})
diff --git a/js/src/carousel.js b/js/src/carousel.js
index 5034f1798..7230d5aaf 100644
--- a/js/src/carousel.js
+++ b/js/src/carousel.js
@@ -33,6 +33,7 @@ const VERSION = '4.3.1'
const DATA_KEY = 'bs.carousel'
const EVENT_KEY = `.${DATA_KEY}`
const DATA_API_KEY = '.data-api'
+
const ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key
const ARROW_RIGHT_KEYCODE = 39 // KeyboardEvent.which value for right arrow key
const TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch
@@ -56,51 +57,42 @@ const DefaultType = {
touch: 'boolean'
}
-const Direction = {
- NEXT: 'next',
- PREV: 'prev',
- LEFT: 'left',
- RIGHT: 'right'
-}
-
-const Event = {
- SLIDE: `slide${EVENT_KEY}`,
- SLID: `slid${EVENT_KEY}`,
- KEYDOWN: `keydown${EVENT_KEY}`,
- MOUSEENTER: `mouseenter${EVENT_KEY}`,
- MOUSELEAVE: `mouseleave${EVENT_KEY}`,
- TOUCHSTART: `touchstart${EVENT_KEY}`,
- TOUCHMOVE: `touchmove${EVENT_KEY}`,
- TOUCHEND: `touchend${EVENT_KEY}`,
- POINTERDOWN: `pointerdown${EVENT_KEY}`,
- POINTERUP: `pointerup${EVENT_KEY}`,
- DRAG_START: `dragstart${EVENT_KEY}`,
- LOAD_DATA_API: `load${EVENT_KEY}${DATA_API_KEY}`,
- CLICK_DATA_API: `click${EVENT_KEY}${DATA_API_KEY}`
-}
-
-const ClassName = {
- CAROUSEL: 'carousel',
- ACTIVE: 'active',
- SLIDE: 'slide',
- RIGHT: 'carousel-item-right',
- LEFT: 'carousel-item-left',
- NEXT: 'carousel-item-next',
- PREV: 'carousel-item-prev',
- ITEM: 'carousel-item',
- POINTER_EVENT: 'pointer-event'
-}
-
-const Selector = {
- ACTIVE: '.active',
- ACTIVE_ITEM: '.active.carousel-item',
- ITEM: '.carousel-item',
- ITEM_IMG: '.carousel-item img',
- NEXT_PREV: '.carousel-item-next, .carousel-item-prev',
- INDICATORS: '.carousel-indicators',
- DATA_SLIDE: '[data-slide], [data-slide-to]',
- DATA_RIDE: '[data-ride="carousel"]'
-}
+const DIRECTION_NEXT = 'next'
+const DIRECTION_PREV = 'prev'
+const DIRECTION_LEFT = 'left'
+const DIRECTION_RIGHT = 'right'
+
+const EVENT_SLIDE = `slide${EVENT_KEY}`
+const EVENT_SLID = `slid${EVENT_KEY}`
+const EVENT_KEYDOWN = `keydown${EVENT_KEY}`
+const EVENT_MOUSEENTER = `mouseenter${EVENT_KEY}`
+const EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY}`
+const EVENT_TOUCHSTART = `touchstart${EVENT_KEY}`
+const EVENT_TOUCHMOVE = `touchmove${EVENT_KEY}`
+const EVENT_TOUCHEND = `touchend${EVENT_KEY}`
+const EVENT_POINTERDOWN = `pointerdown${EVENT_KEY}`
+const EVENT_POINTERUP = `pointerup${EVENT_KEY}`
+const EVENT_DRAG_START = `dragstart${EVENT_KEY}`
+const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`
+const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
+
+const CLASS_NAME_CAROUSEL = 'carousel'
+const CLASS_NAME_ACTIVE = 'active'
+const CLASS_NAME_SLIDE = 'slide'
+const CLASS_NAME_RIGHT = 'carousel-item-right'
+const CLASS_NAME_LEFT = 'carousel-item-left'
+const CLASS_NAME_NEXT = 'carousel-item-next'
+const CLASS_NAME_PREV = 'carousel-item-prev'
+const CLASS_NAME_POINTER_EVENT = 'pointer-event'
+
+const SELECTOR_ACTIVE = '.active'
+const SELECTOR_ACTIVE_ITEM = '.active.carousel-item'
+const SELECTOR_ITEM = '.carousel-item'
+const SELECTOR_ITEM_IMG = '.carousel-item img'
+const SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev'
+const SELECTOR_INDICATORS = '.carousel-indicators'
+const SELECTOR_DATA_SLIDE = '[data-slide], [data-slide-to]'
+const SELECTOR_DATA_RIDE = '[data-ride="carousel"]'
const PointerType = {
TOUCH: 'touch',
@@ -125,7 +117,7 @@ class Carousel {
this._config = this._getConfig(config)
this._element = element
- this._indicatorsElement = SelectorEngine.findOne(Selector.INDICATORS, this._element)
+ this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element)
this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0
this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent)
@@ -147,7 +139,7 @@ class Carousel {
next() {
if (!this._isSliding) {
- this._slide(Direction.NEXT)
+ this._slide(DIRECTION_NEXT)
}
}
@@ -161,7 +153,7 @@ class Carousel {
prev() {
if (!this._isSliding) {
- this._slide(Direction.PREV)
+ this._slide(DIRECTION_PREV)
}
}
@@ -170,7 +162,7 @@ class Carousel {
this._isPaused = true
}
- if (SelectorEngine.findOne(Selector.NEXT_PREV, this._element)) {
+ if (SelectorEngine.findOne(SELECTOR_NEXT_PREV, this._element)) {
triggerTransitionEnd(this._element)
this.cycle(true)
}
@@ -198,7 +190,7 @@ class Carousel {
}
to(index) {
- this._activeElement = SelectorEngine.findOne(Selector.ACTIVE_ITEM, this._element)
+ this._activeElement = SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element)
const activeIndex = this._getItemIndex(this._activeElement)
if (index > this._items.length - 1 || index < 0) {
@@ -206,7 +198,7 @@ class Carousel {
}
if (this._isSliding) {
- EventHandler.one(this._element, Event.SLID, () => this.to(index))
+ EventHandler.one(this._element, EVENT_SLID, () => this.to(index))
return
}
@@ -217,8 +209,8 @@ class Carousel {
}
const direction = index > activeIndex ?
- Direction.NEXT :
- Direction.PREV
+ DIRECTION_NEXT :
+ DIRECTION_PREV
this._slide(direction, this._items[index])
}
@@ -273,14 +265,14 @@ class Carousel {
_addEventListeners() {
if (this._config.keyboard) {
EventHandler
- .on(this._element, Event.KEYDOWN, event => this._keydown(event))
+ .on(this._element, EVENT_KEYDOWN, event => this._keydown(event))
}
if (this._config.pause === 'hover') {
EventHandler
- .on(this._element, Event.MOUSEENTER, event => this.pause(event))
+ .on(this._element, EVENT_MOUSEENTER, event => this.pause(event))
EventHandler
- .on(this._element, Event.MOUSELEAVE, event => this.cycle(event))
+ .on(this._element, EVENT_MOUSELEAVE, event => this.cycle(event))
}
if (this._config.touch && this._touchSupported) {
@@ -330,19 +322,19 @@ class Carousel {
}
}
- makeArray(SelectorEngine.find(Selector.ITEM_IMG, this._element)).forEach(itemImg => {
- EventHandler.on(itemImg, Event.DRAG_START, e => e.preventDefault())
+ makeArray(SelectorEngine.find(SELECTOR_ITEM_IMG, this._element)).forEach(itemImg => {
+ EventHandler.on(itemImg, EVENT_DRAG_START, e => e.preventDefault())
})
if (this._pointerEvent) {
- EventHandler.on(this._element, Event.POINTERDOWN, event => start(event))
- EventHandler.on(this._element, Event.POINTERUP, event => end(event))
+ EventHandler.on(this._element, EVENT_POINTERDOWN, event => start(event))
+ EventHandler.on(this._element, EVENT_POINTERUP, event => end(event))
- this._element.classList.add(ClassName.POINTER_EVENT)
+ this._element.classList.add(CLASS_NAME_POINTER_EVENT)
} else {
- EventHandler.on(this._element, Event.TOUCHSTART, event => start(event))
- EventHandler.on(this._element, Event.TOUCHMOVE, event => move(event))
- EventHandler.on(this._element, Event.TOUCHEND, event => end(event))
+ EventHandler.on(this._element, EVENT_TOUCHSTART, event => start(event))
+ EventHandler.on(this._element, EVENT_TOUCHMOVE, event => move(event))
+ EventHandler.on(this._element, EVENT_TOUCHEND, event => end(event))
}
}
@@ -366,15 +358,15 @@ class Carousel {
_getItemIndex(element) {
this._items = element && element.parentNode ?
- makeArray(SelectorEngine.find(Selector.ITEM, element.parentNode)) :
+ makeArray(SelectorEngine.find(SELECTOR_ITEM, element.parentNode)) :
[]
return this._items.indexOf(element)
}
_getItemByDirection(direction, activeElement) {
- const isNextDirection = direction === Direction.NEXT
- const isPrevDirection = direction === Direction.PREV
+ const isNextDirection = direction === DIRECTION_NEXT
+ const isPrevDirection = direction === DIRECTION_PREV
const activeIndex = this._getItemIndex(activeElement)
const lastItemIndex = this._items.length - 1
const isGoingToWrap = (isPrevDirection && activeIndex === 0) ||
@@ -384,7 +376,7 @@ class Carousel {
return activeElement
}
- const delta = direction === Direction.PREV ? -1 : 1
+ const delta = direction === DIRECTION_PREV ? -1 : 1
const itemIndex = (activeIndex + delta) % this._items.length
return itemIndex === -1 ?
@@ -394,9 +386,9 @@ class Carousel {
_triggerSlideEvent(relatedTarget, eventDirectionName) {
const targetIndex = this._getItemIndex(relatedTarget)
- const fromIndex = this._getItemIndex(SelectorEngine.findOne(Selector.ACTIVE_ITEM, this._element))
+ const fromIndex = this._getItemIndex(SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element))
- return EventHandler.trigger(this._element, Event.SLIDE, {
+ return EventHandler.trigger(this._element, EVENT_SLIDE, {
relatedTarget,
direction: eventDirectionName,
from: fromIndex,
@@ -406,9 +398,9 @@ class Carousel {
_setActiveIndicatorElement(element) {
if (this._indicatorsElement) {
- const indicators = SelectorEngine.find(Selector.ACTIVE, this._indicatorsElement)
+ const indicators = SelectorEngine.find(SELECTOR_ACTIVE, this._indicatorsElement)
for (let i = 0; i < indicators.length; i++) {
- indicators[i].classList.remove(ClassName.ACTIVE)
+ indicators[i].classList.remove(CLASS_NAME_ACTIVE)
}
const nextIndicator = this._indicatorsElement.children[
@@ -416,13 +408,13 @@ class Carousel {
]
if (nextIndicator) {
- nextIndicator.classList.add(ClassName.ACTIVE)
+ nextIndicator.classList.add(CLASS_NAME_ACTIVE)
}
}
}
_slide(direction, element) {
- const activeElement = SelectorEngine.findOne(Selector.ACTIVE_ITEM, this._element)
+ const activeElement = SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element)
const activeElementIndex = this._getItemIndex(activeElement)
const nextElement = element || (activeElement &&
this._getItemByDirection(direction, activeElement))
@@ -434,17 +426,17 @@ class Carousel {
let orderClassName
let eventDirectionName
- if (direction === Direction.NEXT) {
- directionalClassName = ClassName.LEFT
- orderClassName = ClassName.NEXT
- eventDirectionName = Direction.LEFT
+ if (direction === DIRECTION_NEXT) {
+ directionalClassName = CLASS_NAME_LEFT
+ orderClassName = CLASS_NAME_NEXT
+ eventDirectionName = DIRECTION_LEFT
} else {
- directionalClassName = ClassName.RIGHT
- orderClassName = ClassName.PREV
- eventDirectionName = Direction.RIGHT
+ directionalClassName = CLASS_NAME_RIGHT
+ orderClassName = CLASS_NAME_PREV
+ eventDirectionName = DIRECTION_RIGHT
}
- if (nextElement && nextElement.classList.contains(ClassName.ACTIVE)) {
+ if (nextElement && nextElement.classList.contains(CLASS_NAME_ACTIVE)) {
this._isSliding = false
return
}
@@ -467,7 +459,7 @@ class Carousel {
this._setActiveIndicatorElement(nextElement)
- if (this._element.classList.contains(ClassName.SLIDE)) {
+ if (this._element.classList.contains(CLASS_NAME_SLIDE)) {
nextElement.classList.add(orderClassName)
reflow(nextElement)
@@ -489,16 +481,16 @@ class Carousel {
.one(activeElement, TRANSITION_END, () => {
nextElement.classList.remove(directionalClassName)
nextElement.classList.remove(orderClassName)
- nextElement.classList.add(ClassName.ACTIVE)
+ nextElement.classList.add(CLASS_NAME_ACTIVE)
- activeElement.classList.remove(ClassName.ACTIVE)
+ activeElement.classList.remove(CLASS_NAME_ACTIVE)
activeElement.classList.remove(orderClassName)
activeElement.classList.remove(directionalClassName)
this._isSliding = false
setTimeout(() => {
- EventHandler.trigger(this._element, Event.SLID, {
+ EventHandler.trigger(this._element, EVENT_SLID, {
relatedTarget: nextElement,
direction: eventDirectionName,
from: activeElementIndex,
@@ -509,11 +501,11 @@ class Carousel {
emulateTransitionEnd(activeElement, transitionDuration)
} else {
- activeElement.classList.remove(ClassName.ACTIVE)
- nextElement.classList.add(ClassName.ACTIVE)
+ activeElement.classList.remove(CLASS_NAME_ACTIVE)
+ nextElement.classList.add(CLASS_NAME_ACTIVE)
this._isSliding = false
- EventHandler.trigger(this._element, Event.SLID, {
+ EventHandler.trigger(this._element, EVENT_SLID, {
relatedTarget: nextElement,
direction: eventDirectionName,
from: activeElementIndex,
@@ -571,7 +563,7 @@ class Carousel {
static dataApiClickHandler(event) {
const target = getElementFromSelector(this)
- if (!target || !target.classList.contains(ClassName.CAROUSEL)) {
+ if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) {
return
}
@@ -606,10 +598,10 @@ class Carousel {
*/
EventHandler
- .on(document, Event.CLICK_DATA_API, Selector.DATA_SLIDE, Carousel.dataApiClickHandler)
+ .on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_SLIDE, Carousel.dataApiClickHandler)
-EventHandler.on(window, Event.LOAD_DATA_API, () => {
- const carousels = makeArray(SelectorEngine.find(Selector.DATA_RIDE))
+EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
+ const carousels = makeArray(SelectorEngine.find(SELECTOR_DATA_RIDE))
for (let i = 0, len = carousels.length; i < len; i++) {
Carousel.carouselInterface(carousels[i], Data.getData(carousels[i], DATA_KEY))
}
diff --git a/js/src/collapse.js b/js/src/collapse.js
index 27eef4ef7..3b78c5cdb 100644
--- a/js/src/collapse.js
+++ b/js/src/collapse.js
@@ -44,30 +44,22 @@ const DefaultType = {
parent: '(string|element)'
}
-const Event = {
- SHOW: `show${EVENT_KEY}`,
- SHOWN: `shown${EVENT_KEY}`,
- HIDE: `hide${EVENT_KEY}`,
- HIDDEN: `hidden${EVENT_KEY}`,
- CLICK_DATA_API: `click${EVENT_KEY}${DATA_API_KEY}`
-}
+const EVENT_SHOW = `show${EVENT_KEY}`
+const EVENT_SHOWN = `shown${EVENT_KEY}`
+const EVENT_HIDE = `hide${EVENT_KEY}`
+const EVENT_HIDDEN = `hidden${EVENT_KEY}`
+const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
-const ClassName = {
- SHOW: 'show',
- COLLAPSE: 'collapse',
- COLLAPSING: 'collapsing',
- COLLAPSED: 'collapsed'
-}
+const CLASS_NAME_SHOW = 'show'
+const CLASS_NAME_COLLAPSE = 'collapse'
+const CLASS_NAME_COLLAPSING = 'collapsing'
+const CLASS_NAME_COLLAPSED = 'collapsed'
-const Dimension = {
- WIDTH: 'width',
- HEIGHT: 'height'
-}
+const WIDTH = 'width'
+const HEIGHT = 'height'
-const Selector = {
- ACTIVES: '.show, .collapsing',
- DATA_TOGGLE: '[data-toggle="collapse"]'
-}
+const SELECTOR_ACTIVES = '.show, .collapsing'
+const SELECTOR_DATA_TOGGLE = '[data-toggle="collapse"]'
/**
* ------------------------------------------------------------------------
@@ -81,11 +73,11 @@ class Collapse {
this._element = element
this._config = this._getConfig(config)
this._triggerArray = makeArray(SelectorEngine.find(
- `${Selector.DATA_TOGGLE}[href="#${element.id}"],` +
- `${Selector.DATA_TOGGLE}[data-target="#${element.id}"]`
+ `${SELECTOR_DATA_TOGGLE}[href="#${element.id}"],` +
+ `${SELECTOR_DATA_TOGGLE}[data-target="#${element.id}"]`
))
- const toggleList = makeArray(SelectorEngine.find(Selector.DATA_TOGGLE))
+ const toggleList = makeArray(SelectorEngine.find(SELECTOR_DATA_TOGGLE))
for (let i = 0, len = toggleList.length; i < len; i++) {
const elem = toggleList[i]
const selector = getSelectorFromElement(elem)
@@ -124,7 +116,7 @@ class Collapse {
// Public
toggle() {
- if (this._element.classList.contains(ClassName.SHOW)) {
+ if (this._element.classList.contains(CLASS_NAME_SHOW)) {
this.hide()
} else {
this.show()
@@ -133,7 +125,7 @@ class Collapse {
show() {
if (this._isTransitioning ||
- this._element.classList.contains(ClassName.SHOW)) {
+ this._element.classList.contains(CLASS_NAME_SHOW)) {
return
}
@@ -141,13 +133,13 @@ class Collapse {
let activesData
if (this._parent) {
- actives = makeArray(SelectorEngine.find(Selector.ACTIVES, this._parent))
+ actives = makeArray(SelectorEngine.find(SELECTOR_ACTIVES, this._parent))
.filter(elem => {
if (typeof this._config.parent === 'string') {
return elem.getAttribute('data-parent') === this._config.parent
}
- return elem.classList.contains(ClassName.COLLAPSE)
+ return elem.classList.contains(CLASS_NAME_COLLAPSE)
})
if (actives.length === 0) {
@@ -165,7 +157,7 @@ class Collapse {
}
}
- const startEvent = EventHandler.trigger(this._element, Event.SHOW)
+ const startEvent = EventHandler.trigger(this._element, EVENT_SHOW)
if (startEvent.defaultPrevented) {
return
}
@@ -184,14 +176,14 @@ class Collapse {
const dimension = this._getDimension()
- this._element.classList.remove(ClassName.COLLAPSE)
- this._element.classList.add(ClassName.COLLAPSING)
+ this._element.classList.remove(CLASS_NAME_COLLAPSE)
+ this._element.classList.add(CLASS_NAME_COLLAPSING)
this._element.style[dimension] = 0
if (this._triggerArray.length) {
this._triggerArray.forEach(element => {
- element.classList.remove(ClassName.COLLAPSED)
+ element.classList.remove(CLASS_NAME_COLLAPSED)
element.setAttribute('aria-expanded', true)
})
}
@@ -199,15 +191,15 @@ class Collapse {
this.setTransitioning(true)
const complete = () => {
- this._element.classList.remove(ClassName.COLLAPSING)
- this._element.classList.add(ClassName.COLLAPSE)
- this._element.classList.add(ClassName.SHOW)
+ this._element.classList.remove(CLASS_NAME_COLLAPSING)
+ this._element.classList.add(CLASS_NAME_COLLAPSE)
+ this._element.classList.add(CLASS_NAME_SHOW)
this._element.style[dimension] = ''
this.setTransitioning(false)
- EventHandler.trigger(this._element, Event.SHOWN)
+ EventHandler.trigger(this._element, EVENT_SHOWN)
}
const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)
@@ -222,11 +214,11 @@ class Collapse {
hide() {
if (this._isTransitioning ||
- !this._element.classList.contains(ClassName.SHOW)) {
+ !this._element.classList.contains(CLASS_NAME_SHOW)) {
return
}
- const startEvent = EventHandler.trigger(this._element, Event.HIDE)
+ const startEvent = EventHandler.trigger(this._element, EVENT_HIDE)
if (startEvent.defaultPrevented) {
return
}
@@ -237,9 +229,9 @@ class Collapse {
reflow(this._element)
- this._element.classList.add(ClassName.COLLAPSING)
- this._element.classList.remove(ClassName.COLLAPSE)
- this._element.classList.remove(ClassName.SHOW)
+ this._element.classList.add(CLASS_NAME_COLLAPSING)
+ this._element.classList.remove(CLASS_NAME_COLLAPSE)
+ this._element.classList.remove(CLASS_NAME_SHOW)
const triggerArrayLength = this._triggerArray.length
if (triggerArrayLength > 0) {
@@ -247,8 +239,8 @@ class Collapse {
const trigger = this._triggerArray[i]
const elem = getElementFromSelector(trigger)
- if (elem && !elem.classList.contains(ClassName.SHOW)) {
- trigger.classList.add(ClassName.COLLAPSED)
+ if (elem && !elem.classList.contains(CLASS_NAME_SHOW)) {
+ trigger.classList.add(CLASS_NAME_COLLAPSED)
trigger.setAttribute('aria-expanded', false)
}
}
@@ -258,9 +250,9 @@ class Collapse {
const complete = () => {
this.setTransitioning(false)
- this._element.classList.remove(ClassName.COLLAPSING)
- this._element.classList.add(ClassName.COLLAPSE)
- EventHandler.trigger(this._element, Event.HIDDEN)
+ this._element.classList.remove(CLASS_NAME_COLLAPSING)
+ this._element.classList.add(CLASS_NAME_COLLAPSE)
+ EventHandler.trigger(this._element, EVENT_HIDDEN)
}
this._element.style[dimension] = ''
@@ -297,8 +289,8 @@ class Collapse {
}
_getDimension() {
- const hasWidth = this._element.classList.contains(Dimension.WIDTH)
- return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT
+ const hasWidth = this._element.classList.contains(WIDTH)
+ return hasWidth ? WIDTH : HEIGHT
}
_getParent() {
@@ -313,7 +305,7 @@ class Collapse {
parent = SelectorEngine.findOne(parent)
}
- const selector = `${Selector.DATA_TOGGLE}[data-parent="${parent}"]`
+ const selector = `${SELECTOR_DATA_TOGGLE}[data-parent="${parent}"]`
makeArray(SelectorEngine.find(selector, parent))
.forEach(element => {
@@ -330,14 +322,14 @@ class Collapse {
_addAriaAndCollapsedClass(element, triggerArray) {
if (element) {
- const isOpen = element.classList.contains(ClassName.SHOW)
+ const isOpen = element.classList.contains(CLASS_NAME_SHOW)
if (triggerArray.length) {
triggerArray.forEach(elem => {
if (isOpen) {
- elem.classList.remove(ClassName.COLLAPSED)
+ elem.classList.remove(CLASS_NAME_COLLAPSED)
} else {
- elem.classList.add(ClassName.COLLAPSED)
+ elem.classList.add(CLASS_NAME_COLLAPSED)
}
elem.setAttribute('aria-expanded', isOpen)
@@ -390,7 +382,7 @@ class Collapse {
* ------------------------------------------------------------------------
*/
-EventHandler.on(document, Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
+EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
// preventDefault only for <a> elements (which change the URL) not inside the collapsible element
if (event.target.tagName === 'A') {
event.preventDefault()
diff --git a/js/src/dom/event-handler.js b/js/src/dom/event-handler.js
index b1484e517..7fdeaa4f8 100644
--- a/js/src/dom/event-handler.js
+++ b/js/src/dom/event-handler.js
@@ -6,7 +6,7 @@
*/
import { getjQuery } from '../util/index'
-import { createCustomEvent, defaultPreventedPreservedOnDispatch } from './polyfill'
+import { defaultPreventedPreservedOnDispatch } from './polyfill'
/**
* ------------------------------------------------------------------------
@@ -307,7 +307,7 @@ const EventHandler = {
evt = document.createEvent('HTMLEvents')
evt.initEvent(typeEvent, bubbles, true)
} else {
- evt = createCustomEvent(event, {
+ evt = new CustomEvent(event, {
bubbles,
cancelable: true
})
diff --git a/js/src/dom/polyfill.js b/js/src/dom/polyfill.js
index 9e74c7cd2..2a1c381e6 100644
--- a/js/src/dom/polyfill.js
+++ b/js/src/dom/polyfill.js
@@ -9,55 +9,12 @@
import { getUID } from '../util/index'
-let { matches, closest } = Element.prototype
let find = Element.prototype.querySelectorAll
let findOne = Element.prototype.querySelector
-let createCustomEvent = (eventName, params) => {
- const cEvent = new CustomEvent(eventName, params)
-
- return cEvent
-}
-
-if (typeof window.CustomEvent !== 'function') {
- createCustomEvent = (eventName, params) => {
- params = params || { bubbles: false, cancelable: false, detail: null }
-
- const evt = document.createEvent('CustomEvent')
-
- evt.initCustomEvent(eventName, params.bubbles, params.cancelable, params.detail)
- return evt
- }
-}
-
-const workingDefaultPrevented = (() => {
- const e = document.createEvent('CustomEvent')
-
- e.initEvent('Bootstrap', true, true)
- e.preventDefault()
- return e.defaultPrevented
-})()
-
-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
- })
- }
-}
// MSEdge resets defaultPrevented flag upon dispatchEvent call if at least one listener is attached
const defaultPreventedPreservedOnDispatch = (() => {
- const e = createCustomEvent('Bootstrap', {
+ const e = new CustomEvent('Bootstrap', {
cancelable: true
})
@@ -69,26 +26,6 @@ const defaultPreventedPreservedOnDispatch = (() => {
return e.defaultPrevented
})()
-if (!matches) {
- matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector
-}
-
-if (!closest) {
- closest = function (selector) {
- let element = this
-
- do {
- if (matches.call(element, selector)) {
- return element
- }
-
- element = element.parentElement || element.parentNode
- } while (element !== null && element.nodeType === 1)
-
- return null
- }
-}
-
const scopeSelectorRegex = /:scope\b/
const supportScopeQuery = (() => {
const element = document.createElement('div')
@@ -143,10 +80,7 @@ if (!supportScopeQuery) {
}
export {
- createCustomEvent,
find,
findOne,
- matches,
- closest,
defaultPreventedPreservedOnDispatch
}
diff --git a/js/src/dom/selector-engine.js b/js/src/dom/selector-engine.js
index c9d25f68c..a8c14ae4c 100644
--- a/js/src/dom/selector-engine.js
+++ b/js/src/dom/selector-engine.js
@@ -5,7 +5,7 @@
* --------------------------------------------------------------------------
*/
-import { find as findFn, findOne, matches, closest } from './polyfill'
+import { find as findFn, findOne } from './polyfill'
import { makeArray } from '../util/index'
/**
@@ -18,7 +18,7 @@ const NODE_TEXT = 3
const SelectorEngine = {
matches(element, selector) {
- return matches.call(element, selector)
+ return element.matches(selector)
},
find(selector, element = document.documentElement) {
@@ -52,7 +52,7 @@ const SelectorEngine = {
},
closest(element, selector) {
- return closest.call(element, selector)
+ return element.closest(selector)
},
prev(element, selector) {
diff --git a/js/src/dropdown.js b/js/src/dropdown.js
index 82a24405a..9d6f8a329 100644
--- a/js/src/dropdown.js
+++ b/js/src/dropdown.js
@@ -31,54 +31,46 @@ const VERSION = '4.3.1'
const DATA_KEY = 'bs.dropdown'
const EVENT_KEY = `.${DATA_KEY}`
const DATA_API_KEY = '.data-api'
+
const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key
const SPACE_KEYCODE = 32 // KeyboardEvent.which value for space key
const TAB_KEYCODE = 9 // KeyboardEvent.which value for tab key
const ARROW_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key
const ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow key
const RIGHT_MOUSE_BUTTON_WHICH = 3 // MouseEvent.which value for the right button (assuming a right-handed mouse)
-const REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`)
-const Event = {
- HIDE: `hide${EVENT_KEY}`,
- HIDDEN: `hidden${EVENT_KEY}`,
- SHOW: `show${EVENT_KEY}`,
- SHOWN: `shown${EVENT_KEY}`,
- CLICK: `click${EVENT_KEY}`,
- CLICK_DATA_API: `click${EVENT_KEY}${DATA_API_KEY}`,
- KEYDOWN_DATA_API: `keydown${EVENT_KEY}${DATA_API_KEY}`,
- KEYUP_DATA_API: `keyup${EVENT_KEY}${DATA_API_KEY}`
-}
-
-const ClassName = {
- DISABLED: 'disabled',
- SHOW: 'show',
- DROPUP: 'dropup',
- DROPRIGHT: 'dropright',
- DROPLEFT: 'dropleft',
- MENURIGHT: 'dropdown-menu-right',
- NAVBAR: 'navbar',
- POSITION_STATIC: 'position-static'
-}
-
-const Selector = {
- DATA_TOGGLE: '[data-toggle="dropdown"]',
- FORM_CHILD: '.dropdown form',
- MENU: '.dropdown-menu',
- NAVBAR_NAV: '.navbar-nav',
- VISIBLE_ITEMS: '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'
-}
+const REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`)
-const AttachmentMap = {
- TOP: 'top-start',
- TOPEND: 'top-end',
- BOTTOM: 'bottom-start',
- BOTTOMEND: 'bottom-end',
- RIGHT: 'right-start',
- RIGHTEND: 'right-end',
- LEFT: 'left-start',
- LEFTEND: 'left-end'
-}
+const EVENT_HIDE = `hide${EVENT_KEY}`
+const EVENT_HIDDEN = `hidden${EVENT_KEY}`
+const EVENT_SHOW = `show${EVENT_KEY}`
+const EVENT_SHOWN = `shown${EVENT_KEY}`
+const EVENT_CLICK = `click${EVENT_KEY}`
+const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
+const EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY}${DATA_API_KEY}`
+const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}`
+
+const CLASS_NAME_DISABLED = 'disabled'
+const CLASS_NAME_SHOW = 'show'
+const CLASS_NAME_DROPUP = 'dropup'
+const CLASS_NAME_DROPRIGHT = 'dropright'
+const CLASS_NAME_DROPLEFT = 'dropleft'
+const CLASS_NAME_MENURIGHT = 'dropdown-menu-right'
+const CLASS_NAME_NAVBAR = 'navbar'
+const CLASS_NAME_POSITION_STATIC = 'position-static'
+
+const SELECTOR_DATA_TOGGLE = '[data-toggle="dropdown"]'
+const SELECTOR_FORM_CHILD = '.dropdown form'
+const SELECTOR_MENU = '.dropdown-menu'
+const SELECTOR_NAVBAR_NAV = '.navbar-nav'
+const SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'
+
+const PLACEMENT_TOP = 'top-start'
+const PLACEMENT_TOPEND = 'top-end'
+const PLACEMENT_BOTTOM = 'bottom-start'
+const PLACEMENT_BOTTOMEND = 'bottom-end'
+const PLACEMENT_RIGHT = 'right-start'
+const PLACEMENT_LEFT = 'left-start'
const Default = {
offset: 0,
@@ -133,11 +125,11 @@ class Dropdown {
// Public
toggle() {
- if (this._element.disabled || this._element.classList.contains(ClassName.DISABLED)) {
+ if (this._element.disabled || this._element.classList.contains(CLASS_NAME_DISABLED)) {
return
}
- const isActive = this._menu.classList.contains(ClassName.SHOW)
+ const isActive = this._menu.classList.contains(CLASS_NAME_SHOW)
Dropdown.clearMenus()
@@ -149,7 +141,7 @@ class Dropdown {
}
show() {
- if (this._element.disabled || this._element.classList.contains(ClassName.DISABLED) || this._menu.classList.contains(ClassName.SHOW)) {
+ if (this._element.disabled || this._element.classList.contains(CLASS_NAME_DISABLED) || this._menu.classList.contains(CLASS_NAME_SHOW)) {
return
}
@@ -158,7 +150,7 @@ class Dropdown {
relatedTarget: this._element
}
- const showEvent = EventHandler.trigger(parent, Event.SHOW, relatedTarget)
+ const showEvent = EventHandler.trigger(parent, EVENT_SHOW, relatedTarget)
if (showEvent.defaultPrevented) {
return
@@ -187,7 +179,7 @@ class Dropdown {
// to allow the menu to "escape" the scroll parent's boundaries
// https://github.com/twbs/bootstrap/issues/24251
if (this._config.boundary !== 'scrollParent') {
- parent.classList.add(ClassName.POSITION_STATIC)
+ parent.classList.add(CLASS_NAME_POSITION_STATIC)
}
this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig())
@@ -198,7 +190,7 @@ class Dropdown {
// only needed because of broken event delegation on iOS
// https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
if ('ontouchstart' in document.documentElement &&
- !makeArray(SelectorEngine.closest(parent, Selector.NAVBAR_NAV)).length) {
+ !makeArray(SelectorEngine.closest(parent, SELECTOR_NAVBAR_NAV)).length) {
makeArray(document.body.children)
.forEach(elem => EventHandler.on(elem, 'mouseover', null, noop()))
}
@@ -206,13 +198,13 @@ class Dropdown {
this._element.focus()
this._element.setAttribute('aria-expanded', true)
- Manipulator.toggleClass(this._menu, ClassName.SHOW)
- Manipulator.toggleClass(parent, ClassName.SHOW)
- EventHandler.trigger(parent, Event.SHOWN, relatedTarget)
+ Manipulator.toggleClass(this._menu, CLASS_NAME_SHOW)
+ Manipulator.toggleClass(parent, CLASS_NAME_SHOW)
+ EventHandler.trigger(parent, EVENT_SHOWN, relatedTarget)
}
hide() {
- if (this._element.disabled || this._element.classList.contains(ClassName.DISABLED) || !this._menu.classList.contains(ClassName.SHOW)) {
+ if (this._element.disabled || this._element.classList.contains(CLASS_NAME_DISABLED) || !this._menu.classList.contains(CLASS_NAME_SHOW)) {
return
}
@@ -221,7 +213,7 @@ class Dropdown {
relatedTarget: this._element
}
- const hideEvent = EventHandler.trigger(parent, Event.HIDE, relatedTarget)
+ const hideEvent = EventHandler.trigger(parent, EVENT_HIDE, relatedTarget)
if (hideEvent.defaultPrevented) {
return
@@ -231,9 +223,9 @@ class Dropdown {
this._popper.destroy()
}
- Manipulator.toggleClass(this._menu, ClassName.SHOW)
- Manipulator.toggleClass(parent, ClassName.SHOW)
- EventHandler.trigger(parent, Event.HIDDEN, relatedTarget)
+ Manipulator.toggleClass(this._menu, CLASS_NAME_SHOW)
+ Manipulator.toggleClass(parent, CLASS_NAME_SHOW)
+ EventHandler.trigger(parent, EVENT_HIDDEN, relatedTarget)
}
dispose() {
@@ -257,7 +249,7 @@ class Dropdown {
// Private
_addEventListeners() {
- EventHandler.on(this._element, Event.CLICK, event => {
+ EventHandler.on(this._element, EVENT_CLICK, event => {
event.preventDefault()
event.stopPropagation()
this.toggle()
@@ -283,32 +275,32 @@ class Dropdown {
_getMenuElement() {
const parent = Dropdown.getParentFromElement(this._element)
- return SelectorEngine.findOne(Selector.MENU, parent)
+ return SelectorEngine.findOne(SELECTOR_MENU, parent)
}
_getPlacement() {
const parentDropdown = this._element.parentNode
- let placement = AttachmentMap.BOTTOM
+ let placement = PLACEMENT_BOTTOM
// Handle dropup
- if (parentDropdown.classList.contains(ClassName.DROPUP)) {
- placement = AttachmentMap.TOP
- if (this._menu.classList.contains(ClassName.MENURIGHT)) {
- placement = AttachmentMap.TOPEND
+ if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) {
+ placement = PLACEMENT_TOP
+ if (this._menu.classList.contains(CLASS_NAME_MENURIGHT)) {
+ placement = PLACEMENT_TOPEND
}
- } else if (parentDropdown.classList.contains(ClassName.DROPRIGHT)) {
- placement = AttachmentMap.RIGHT
- } else if (parentDropdown.classList.contains(ClassName.DROPLEFT)) {
- placement = AttachmentMap.LEFT
- } else if (this._menu.classList.contains(ClassName.MENURIGHT)) {
- placement = AttachmentMap.BOTTOMEND
+ } else if (parentDropdown.classList.contains(CLASS_NAME_DROPRIGHT)) {
+ placement = PLACEMENT_RIGHT
+ } else if (parentDropdown.classList.contains(CLASS_NAME_DROPLEFT)) {
+ placement = PLACEMENT_LEFT
+ } else if (this._menu.classList.contains(CLASS_NAME_MENURIGHT)) {
+ placement = PLACEMENT_BOTTOMEND
}
return placement
}
_detectNavbar() {
- return Boolean(SelectorEngine.closest(this._element, `.${ClassName.NAVBAR}`))
+ return Boolean(SelectorEngine.closest(this._element, `.${CLASS_NAME_NAVBAR}`))
}
_getOffset() {
@@ -388,7 +380,7 @@ class Dropdown {
return
}
- const toggles = makeArray(SelectorEngine.find(Selector.DATA_TOGGLE))
+ const toggles = makeArray(SelectorEngine.find(SELECTOR_DATA_TOGGLE))
for (let i = 0, len = toggles.length; i < len; i++) {
const parent = Dropdown.getParentFromElement(toggles[i])
const context = Data.getData(toggles[i], DATA_KEY)
@@ -405,7 +397,7 @@ class Dropdown {
}
const dropdownMenu = context._menu
- if (!parent.classList.contains(ClassName.SHOW)) {
+ if (!parent.classList.contains(CLASS_NAME_SHOW)) {
continue
}
@@ -416,7 +408,7 @@ class Dropdown {
continue
}
- const hideEvent = EventHandler.trigger(parent, Event.HIDE, relatedTarget)
+ const hideEvent = EventHandler.trigger(parent, EVENT_HIDE, relatedTarget)
if (hideEvent.defaultPrevented) {
continue
}
@@ -434,9 +426,9 @@ class Dropdown {
context._popper.destroy()
}
- dropdownMenu.classList.remove(ClassName.SHOW)
- parent.classList.remove(ClassName.SHOW)
- EventHandler.trigger(parent, Event.HIDDEN, relatedTarget)
+ dropdownMenu.classList.remove(CLASS_NAME_SHOW)
+ parent.classList.remove(CLASS_NAME_SHOW)
+ EventHandler.trigger(parent, EVENT_HIDDEN, relatedTarget)
}
}
@@ -455,7 +447,7 @@ class Dropdown {
if (/input|textarea/i.test(event.target.tagName) ?
event.which === SPACE_KEYCODE || (event.which !== ESCAPE_KEYCODE &&
((event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE) ||
- SelectorEngine.closest(event.target, Selector.MENU))) :
+ SelectorEngine.closest(event.target, SELECTOR_MENU))) :
!REGEXP_KEYDOWN.test(event.which)) {
return
}
@@ -463,23 +455,23 @@ class Dropdown {
event.preventDefault()
event.stopPropagation()
- if (this.disabled || this.classList.contains(ClassName.DISABLED)) {
+ if (this.disabled || this.classList.contains(CLASS_NAME_DISABLED)) {
return
}
const parent = Dropdown.getParentFromElement(this)
- const isActive = parent.classList.contains(ClassName.SHOW)
+ const isActive = parent.classList.contains(CLASS_NAME_SHOW)
if (!isActive || (isActive && (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE))) {
if (event.which === ESCAPE_KEYCODE) {
- SelectorEngine.findOne(Selector.DATA_TOGGLE, parent).focus()
+ SelectorEngine.findOne(SELECTOR_DATA_TOGGLE, parent).focus()
}
Dropdown.clearMenus()
return
}
- const items = makeArray(SelectorEngine.find(Selector.VISIBLE_ITEMS, parent))
+ const items = makeArray(SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, parent))
.filter(isVisible)
if (!items.length) {
@@ -514,17 +506,17 @@ class Dropdown {
* ------------------------------------------------------------------------
*/
-EventHandler.on(document, Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Dropdown.dataApiKeydownHandler)
-EventHandler.on(document, Event.KEYDOWN_DATA_API, Selector.MENU, Dropdown.dataApiKeydownHandler)
-EventHandler.on(document, Event.CLICK_DATA_API, Dropdown.clearMenus)
-EventHandler.on(document, Event.KEYUP_DATA_API, Dropdown.clearMenus)
-EventHandler.on(document, Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
+EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE, Dropdown.dataApiKeydownHandler)
+EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler)
+EventHandler.on(document, EVENT_CLICK_DATA_API, Dropdown.clearMenus)
+EventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus)
+EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
event.preventDefault()
event.stopPropagation()
Dropdown.dropdownInterface(this, 'toggle')
})
EventHandler
- .on(document, Event.CLICK_DATA_API, Selector.FORM_CHILD, e => e.stopPropagation())
+ .on(document, EVENT_CLICK_DATA_API, SELECTOR_FORM_CHILD, e => e.stopPropagation())
const $ = getjQuery()
diff --git a/js/src/modal.js b/js/src/modal.js
index 48ff5b854..bcf13454f 100644
--- a/js/src/modal.js
+++ b/js/src/modal.js
@@ -48,39 +48,33 @@ const DefaultType = {
show: 'boolean'
}
-const Event = {
- HIDE: `hide${EVENT_KEY}`,
- HIDE_PREVENTED: `hidePrevented${EVENT_KEY}`,
- HIDDEN: `hidden${EVENT_KEY}`,
- SHOW: `show${EVENT_KEY}`,
- SHOWN: `shown${EVENT_KEY}`,
- FOCUSIN: `focusin${EVENT_KEY}`,
- RESIZE: `resize${EVENT_KEY}`,
- CLICK_DISMISS: `click.dismiss${EVENT_KEY}`,
- KEYDOWN_DISMISS: `keydown.dismiss${EVENT_KEY}`,
- MOUSEUP_DISMISS: `mouseup.dismiss${EVENT_KEY}`,
- MOUSEDOWN_DISMISS: `mousedown.dismiss${EVENT_KEY}`,
- CLICK_DATA_API: `click${EVENT_KEY}${DATA_API_KEY}`
-}
-
-const ClassName = {
- SCROLLABLE: 'modal-dialog-scrollable',
- SCROLLBAR_MEASURER: 'modal-scrollbar-measure',
- BACKDROP: 'modal-backdrop',
- OPEN: 'modal-open',
- FADE: 'fade',
- SHOW: 'show',
- STATIC: 'modal-static'
-}
-
-const Selector = {
- DIALOG: '.modal-dialog',
- MODAL_BODY: '.modal-body',
- DATA_TOGGLE: '[data-toggle="modal"]',
- DATA_DISMISS: '[data-dismiss="modal"]',
- FIXED_CONTENT: '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top',
- STICKY_CONTENT: '.sticky-top'
-}
+const EVENT_HIDE = `hide${EVENT_KEY}`
+const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`
+const EVENT_HIDDEN = `hidden${EVENT_KEY}`
+const EVENT_SHOW = `show${EVENT_KEY}`
+const EVENT_SHOWN = `shown${EVENT_KEY}`
+const EVENT_FOCUSIN = `focusin${EVENT_KEY}`
+const EVENT_RESIZE = `resize${EVENT_KEY}`
+const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`
+const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`
+const EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY}`
+const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`
+const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
+
+const CLASS_NAME_SCROLLABLE = 'modal-dialog-scrollable'
+const CLASS_NAME_SCROLLBAR_MEASURER = 'modal-scrollbar-measure'
+const CLASS_NAME_BACKDROP = 'modal-backdrop'
+const CLASS_NAME_OPEN = 'modal-open'
+const CLASS_NAME_FADE = 'fade'
+const CLASS_NAME_SHOW = 'show'
+const CLASS_NAME_STATIC = 'modal-static'
+
+const SELECTOR_DIALOG = '.modal-dialog'
+const SELECTOR_MODAL_BODY = '.modal-body'
+const SELECTOR_DATA_TOGGLE = '[data-toggle="modal"]'
+const SELECTOR_DATA_DISMISS = '[data-dismiss="modal"]'
+const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'
+const SELECTOR_STICKY_CONTENT = '.sticky-top'
/**
* ------------------------------------------------------------------------
@@ -92,7 +86,7 @@ class Modal {
constructor(element, config) {
this._config = this._getConfig(config)
this._element = element
- this._dialog = SelectorEngine.findOne(Selector.DIALOG, element)
+ this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, element)
this._backdrop = null
this._isShown = false
this._isBodyOverflowing = false
@@ -123,11 +117,11 @@ class Modal {
return
}
- if (this._element.classList.contains(ClassName.FADE)) {
+ if (this._element.classList.contains(CLASS_NAME_FADE)) {
this._isTransitioning = true
}
- const showEvent = EventHandler.trigger(this._element, Event.SHOW, {
+ const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, {
relatedTarget
})
@@ -146,13 +140,13 @@ class Modal {
this._setResizeEvent()
EventHandler.on(this._element,
- Event.CLICK_DISMISS,
- Selector.DATA_DISMISS,
+ EVENT_CLICK_DISMISS,
+ SELECTOR_DATA_DISMISS,
event => this.hide(event)
)
- EventHandler.on(this._dialog, Event.MOUSEDOWN_DISMISS, () => {
- EventHandler.one(this._element, Event.MOUSEUP_DISMISS, event => {
+ EventHandler.on(this._dialog, EVENT_MOUSEDOWN_DISMISS, () => {
+ EventHandler.one(this._element, EVENT_MOUSEUP_DISMISS, event => {
if (event.target === this._element) {
this._ignoreBackdropClick = true
}
@@ -171,14 +165,14 @@ class Modal {
return
}
- const hideEvent = EventHandler.trigger(this._element, Event.HIDE)
+ const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE)
if (hideEvent.defaultPrevented) {
return
}
this._isShown = false
- const transition = this._element.classList.contains(ClassName.FADE)
+ const transition = this._element.classList.contains(CLASS_NAME_FADE)
if (transition) {
this._isTransitioning = true
@@ -187,12 +181,12 @@ class Modal {
this._setEscapeEvent()
this._setResizeEvent()
- EventHandler.off(document, Event.FOCUSIN)
+ EventHandler.off(document, EVENT_FOCUSIN)
- this._element.classList.remove(ClassName.SHOW)
+ this._element.classList.remove(CLASS_NAME_SHOW)
- EventHandler.off(this._element, Event.CLICK_DISMISS)
- EventHandler.off(this._dialog, Event.MOUSEDOWN_DISMISS)
+ EventHandler.off(this._element, EVENT_CLICK_DISMISS)
+ EventHandler.off(this._dialog, EVENT_MOUSEDOWN_DISMISS)
if (transition) {
const transitionDuration = getTransitionDurationFromElement(this._element)
@@ -209,11 +203,11 @@ class Modal {
.forEach(htmlElement => EventHandler.off(htmlElement, EVENT_KEY))
/**
- * `document` has 2 events `Event.FOCUSIN` and `Event.CLICK_DATA_API`
+ * `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API`
* Do not move `document` in `htmlElements` array
- * It will remove `Event.CLICK_DATA_API` event that should remain
+ * It will remove `EVENT_CLICK_DATA_API` event that should remain
*/
- EventHandler.off(document, Event.FOCUSIN)
+ EventHandler.off(document, EVENT_FOCUSIN)
Data.removeData(this._element, DATA_KEY)
@@ -244,8 +238,8 @@ class Modal {
}
_showElement(relatedTarget) {
- const transition = this._element.classList.contains(ClassName.FADE)
- const modalBody = SelectorEngine.findOne(Selector.MODAL_BODY, this._dialog)
+ const transition = this._element.classList.contains(CLASS_NAME_FADE)
+ const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog)
if (!this._element.parentNode ||
this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
@@ -257,7 +251,7 @@ class Modal {
this._element.removeAttribute('aria-hidden')
this._element.setAttribute('aria-modal', true)
- if (this._dialog.classList.contains(ClassName.SCROLLABLE) && modalBody) {
+ if (this._dialog.classList.contains(CLASS_NAME_SCROLLABLE) && modalBody) {
modalBody.scrollTop = 0
} else {
this._element.scrollTop = 0
@@ -267,7 +261,7 @@ class Modal {
reflow(this._element)
}
- this._element.classList.add(ClassName.SHOW)
+ this._element.classList.add(CLASS_NAME_SHOW)
if (this._config.focus) {
this._enforceFocus()
@@ -279,7 +273,7 @@ class Modal {
}
this._isTransitioning = false
- EventHandler.trigger(this._element, Event.SHOWN, {
+ EventHandler.trigger(this._element, EVENT_SHOWN, {
relatedTarget
})
}
@@ -295,8 +289,8 @@ class Modal {
}
_enforceFocus() {
- EventHandler.off(document, Event.FOCUSIN) // guard against infinite focus loop
- EventHandler.on(document, Event.FOCUSIN, event => {
+ 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)) {
@@ -307,7 +301,7 @@ class Modal {
_setEscapeEvent() {
if (this._isShown) {
- EventHandler.on(this._element, Event.KEYDOWN_DISMISS, event => {
+ EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {
if (this._config.keyboard && event.which === ESCAPE_KEYCODE) {
event.preventDefault()
this.hide()
@@ -316,15 +310,15 @@ class Modal {
}
})
} else {
- EventHandler.off(this._element, Event.KEYDOWN_DISMISS)
+ EventHandler.off(this._element, EVENT_KEYDOWN_DISMISS)
}
}
_setResizeEvent() {
if (this._isShown) {
- EventHandler.on(window, Event.RESIZE, () => this._adjustDialog())
+ EventHandler.on(window, EVENT_RESIZE, () => this._adjustDialog())
} else {
- EventHandler.off(window, Event.RESIZE)
+ EventHandler.off(window, EVENT_RESIZE)
}
}
@@ -334,10 +328,10 @@ class Modal {
this._element.removeAttribute('aria-modal')
this._isTransitioning = false
this._showBackdrop(() => {
- document.body.classList.remove(ClassName.OPEN)
+ document.body.classList.remove(CLASS_NAME_OPEN)
this._resetAdjustments()
this._resetScrollbar()
- EventHandler.trigger(this._element, Event.HIDDEN)
+ EventHandler.trigger(this._element, EVENT_HIDDEN)
})
}
@@ -347,13 +341,13 @@ class Modal {
}
_showBackdrop(callback) {
- const animate = this._element.classList.contains(ClassName.FADE) ?
- ClassName.FADE :
+ const animate = this._element.classList.contains(CLASS_NAME_FADE) ?
+ CLASS_NAME_FADE :
''
if (this._isShown && this._config.backdrop) {
this._backdrop = document.createElement('div')
- this._backdrop.className = ClassName.BACKDROP
+ this._backdrop.className = CLASS_NAME_BACKDROP
if (animate) {
this._backdrop.classList.add(animate)
@@ -361,7 +355,7 @@ class Modal {
document.body.appendChild(this._backdrop)
- EventHandler.on(this._element, Event.CLICK_DISMISS, event => {
+ EventHandler.on(this._element, EVENT_CLICK_DISMISS, event => {
if (this._ignoreBackdropClick) {
this._ignoreBackdropClick = false
return
@@ -378,7 +372,7 @@ class Modal {
reflow(this._backdrop)
}
- this._backdrop.classList.add(ClassName.SHOW)
+ this._backdrop.classList.add(CLASS_NAME_SHOW)
if (!animate) {
callback()
@@ -390,14 +384,14 @@ class Modal {
EventHandler.one(this._backdrop, TRANSITION_END, callback)
emulateTransitionEnd(this._backdrop, backdropTransitionDuration)
} else if (!this._isShown && this._backdrop) {
- this._backdrop.classList.remove(ClassName.SHOW)
+ this._backdrop.classList.remove(CLASS_NAME_SHOW)
const callbackRemove = () => {
this._removeBackdrop()
callback()
}
- if (this._element.classList.contains(ClassName.FADE)) {
+ if (this._element.classList.contains(CLASS_NAME_FADE)) {
const backdropTransitionDuration = getTransitionDurationFromElement(this._backdrop)
EventHandler.one(this._backdrop, TRANSITION_END, callbackRemove)
emulateTransitionEnd(this._backdrop, backdropTransitionDuration)
@@ -411,15 +405,15 @@ class Modal {
_triggerBackdropTransition() {
if (this._config.backdrop === 'static') {
- const hideEvent = EventHandler.trigger(this._element, Event.HIDE_PREVENTED)
+ const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED)
if (hideEvent.defaultPrevented) {
return
}
- this._element.classList.add(ClassName.STATIC)
+ this._element.classList.add(CLASS_NAME_STATIC)
const modalTransitionDuration = getTransitionDurationFromElement(this._element)
EventHandler.one(this._element, TRANSITION_END, () => {
- this._element.classList.remove(ClassName.STATIC)
+ this._element.classList.remove(CLASS_NAME_STATIC)
})
emulateTransitionEnd(this._element, modalTransitionDuration)
this._element.focus()
@@ -462,7 +456,7 @@ class Modal {
// while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set
// Adjust fixed content padding
- makeArray(SelectorEngine.find(Selector.FIXED_CONTENT))
+ makeArray(SelectorEngine.find(SELECTOR_FIXED_CONTENT))
.forEach(element => {
const actualPadding = element.style.paddingRight
const calculatedPadding = window.getComputedStyle(element)['padding-right']
@@ -471,7 +465,7 @@ class Modal {
})
// Adjust sticky content margin
- makeArray(SelectorEngine.find(Selector.STICKY_CONTENT))
+ makeArray(SelectorEngine.find(SELECTOR_STICKY_CONTENT))
.forEach(element => {
const actualMargin = element.style.marginRight
const calculatedMargin = window.getComputedStyle(element)['margin-right']
@@ -487,12 +481,12 @@ class Modal {
document.body.style.paddingRight = `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`
}
- document.body.classList.add(ClassName.OPEN)
+ document.body.classList.add(CLASS_NAME_OPEN)
}
_resetScrollbar() {
// Restore fixed content padding
- makeArray(SelectorEngine.find(Selector.FIXED_CONTENT))
+ makeArray(SelectorEngine.find(SELECTOR_FIXED_CONTENT))
.forEach(element => {
const padding = Manipulator.getDataAttribute(element, 'padding-right')
if (typeof padding !== 'undefined') {
@@ -502,7 +496,7 @@ class Modal {
})
// Restore sticky content and navbar-toggler margin
- makeArray(SelectorEngine.find(`${Selector.STICKY_CONTENT}`))
+ makeArray(SelectorEngine.find(`${SELECTOR_STICKY_CONTENT}`))
.forEach(element => {
const margin = Manipulator.getDataAttribute(element, 'margin-right')
if (typeof margin !== 'undefined') {
@@ -523,7 +517,7 @@ class Modal {
_getScrollbarWidth() { // thx d.walsh
const scrollDiv = document.createElement('div')
- scrollDiv.className = ClassName.SCROLLBAR_MEASURER
+ scrollDiv.className = CLASS_NAME_SCROLLBAR_MEASURER
document.body.appendChild(scrollDiv)
const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth
document.body.removeChild(scrollDiv)
@@ -568,20 +562,20 @@ class Modal {
* ------------------------------------------------------------------------
*/
-EventHandler.on(document, Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
+EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
const target = getElementFromSelector(this)
if (this.tagName === 'A' || this.tagName === 'AREA') {
event.preventDefault()
}
- EventHandler.one(target, Event.SHOW, showEvent => {
+ EventHandler.one(target, EVENT_SHOW, showEvent => {
if (showEvent.defaultPrevented) {
// only register focus restorer if modal will actually get shown
return
}
- EventHandler.one(target, Event.HIDDEN, () => {
+ EventHandler.one(target, EVENT_HIDDEN, () => {
if (isVisible(this)) {
this.focus()
}
diff --git a/js/src/popover.js b/js/src/popover.js
index d71a78236..2d423f0dd 100644
--- a/js/src/popover.js
+++ b/js/src/popover.js
@@ -39,16 +39,6 @@ const DefaultType = {
content: '(string|element|function)'
}
-const ClassName = {
- FADE: 'fade',
- SHOW: 'show'
-}
-
-const Selector = {
- TITLE: '.popover-header',
- CONTENT: '.popover-body'
-}
-
const Event = {
HIDE: `hide${EVENT_KEY}`,
HIDDEN: `hidden${EVENT_KEY}`,
@@ -62,6 +52,12 @@ const Event = {
MOUSELEAVE: `mouseleave${EVENT_KEY}`
}
+const CLASS_NAME_FADE = 'fade'
+const CLASS_NAME_SHOW = 'show'
+
+const SELECTOR_TITLE = '.popover-header'
+const SELECTOR_CONTENT = '.popover-body'
+
/**
* ------------------------------------------------------------------------
* Class Definition
@@ -109,16 +105,16 @@ class Popover extends Tooltip {
const tip = this.getTipElement()
// we use append for html objects to maintain js events
- this.setElementContent(SelectorEngine.findOne(Selector.TITLE, tip), this.getTitle())
+ this.setElementContent(SelectorEngine.findOne(SELECTOR_TITLE, tip), this.getTitle())
let content = this._getContent()
if (typeof content === 'function') {
content = content.call(this.element)
}
- this.setElementContent(SelectorEngine.findOne(Selector.CONTENT, tip), content)
+ this.setElementContent(SelectorEngine.findOne(SELECTOR_CONTENT, tip), content)
- tip.classList.remove(ClassName.FADE)
- tip.classList.remove(ClassName.SHOW)
+ tip.classList.remove(CLASS_NAME_FADE)
+ tip.classList.remove(CLASS_NAME_SHOW)
}
_addAttachmentClass(attachment) {
diff --git a/js/src/scrollspy.js b/js/src/scrollspy.js
index c379c6223..dd68ed386 100644
--- a/js/src/scrollspy.js
+++ b/js/src/scrollspy.js
@@ -41,31 +41,23 @@ const DefaultType = {
target: '(string|element)'
}
-const Event = {
- ACTIVATE: `activate${EVENT_KEY}`,
- SCROLL: `scroll${EVENT_KEY}`,
- LOAD_DATA_API: `load${EVENT_KEY}${DATA_API_KEY}`
-}
+const EVENT_ACTIVATE = `activate${EVENT_KEY}`
+const EVENT_SCROLL = `scroll${EVENT_KEY}`
+const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`
-const ClassName = {
- DROPDOWN_ITEM: 'dropdown-item',
- ACTIVE: 'active'
-}
+const CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item'
+const CLASS_NAME_ACTIVE = 'active'
-const Selector = {
- DATA_SPY: '[data-spy="scroll"]',
- NAV_LIST_GROUP: '.nav, .list-group',
- NAV_LINKS: '.nav-link',
- NAV_ITEMS: '.nav-item',
- LIST_ITEMS: '.list-group-item',
- DROPDOWN: '.dropdown',
- DROPDOWN_TOGGLE: '.dropdown-toggle'
-}
+const SELECTOR_DATA_SPY = '[data-spy="scroll"]'
+const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'
+const SELECTOR_NAV_LINKS = '.nav-link'
+const SELECTOR_NAV_ITEMS = '.nav-item'
+const SELECTOR_LIST_ITEMS = '.list-group-item'
+const SELECTOR_DROPDOWN = '.dropdown'
+const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'
-const OffsetMethod = {
- OFFSET: 'offset',
- POSITION: 'position'
-}
+const METHOD_OFFSET = 'offset'
+const METHOD_POSITION = 'position'
/**
* ------------------------------------------------------------------------
@@ -78,15 +70,15 @@ class ScrollSpy {
this._element = element
this._scrollElement = element.tagName === 'BODY' ? window : element
this._config = this._getConfig(config)
- this._selector = `${this._config.target} ${Selector.NAV_LINKS},` +
- `${this._config.target} ${Selector.LIST_ITEMS},` +
- `${this._config.target} .${ClassName.DROPDOWN_ITEM}`
+ this._selector = `${this._config.target} ${SELECTOR_NAV_LINKS},` +
+ `${this._config.target} ${SELECTOR_LIST_ITEMS},` +
+ `${this._config.target} .${CLASS_NAME_DROPDOWN_ITEM}`
this._offsets = []
this._targets = []
this._activeTarget = null
this._scrollHeight = 0
- EventHandler.on(this._scrollElement, Event.SCROLL, event => this._process(event))
+ EventHandler.on(this._scrollElement, EVENT_SCROLL, event => this._process(event))
this.refresh()
this._process()
@@ -108,14 +100,14 @@ class ScrollSpy {
refresh() {
const autoMethod = this._scrollElement === this._scrollElement.window ?
- OffsetMethod.OFFSET :
- OffsetMethod.POSITION
+ METHOD_OFFSET :
+ METHOD_POSITION
const offsetMethod = this._config.method === 'auto' ?
autoMethod :
this._config.method
- const offsetBase = offsetMethod === OffsetMethod.POSITION ?
+ const offsetBase = offsetMethod === METHOD_POSITION ?
this._getScrollTop() :
0
@@ -261,42 +253,42 @@ class ScrollSpy {
const link = SelectorEngine.findOne(queries.join(','))
- if (link.classList.contains(ClassName.DROPDOWN_ITEM)) {
+ if (link.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {
SelectorEngine
- .findOne(Selector.DROPDOWN_TOGGLE, SelectorEngine.closest(link, Selector.DROPDOWN))
- .classList.add(ClassName.ACTIVE)
+ .findOne(SELECTOR_DROPDOWN_TOGGLE, SelectorEngine.closest(link, SELECTOR_DROPDOWN))
+ .classList.add(CLASS_NAME_ACTIVE)
- link.classList.add(ClassName.ACTIVE)
+ link.classList.add(CLASS_NAME_ACTIVE)
} else {
// Set triggered link as active
- link.classList.add(ClassName.ACTIVE)
+ link.classList.add(CLASS_NAME_ACTIVE)
SelectorEngine
- .parents(link, Selector.NAV_LIST_GROUP)
+ .parents(link, SELECTOR_NAV_LIST_GROUP)
.forEach(listGroup => {
// Set triggered links parents as active
// With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
- SelectorEngine.prev(listGroup, `${Selector.NAV_LINKS}, ${Selector.LIST_ITEMS}`)
- .forEach(item => item.classList.add(ClassName.ACTIVE))
+ SelectorEngine.prev(listGroup, `${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`)
+ .forEach(item => item.classList.add(CLASS_NAME_ACTIVE))
// Handle special case when .nav-link is inside .nav-item
- SelectorEngine.prev(listGroup, Selector.NAV_ITEMS)
+ SelectorEngine.prev(listGroup, SELECTOR_NAV_ITEMS)
.forEach(navItem => {
- SelectorEngine.children(navItem, Selector.NAV_LINKS)
- .forEach(item => item.classList.add(ClassName.ACTIVE))
+ SelectorEngine.children(navItem, SELECTOR_NAV_LINKS)
+ .forEach(item => item.classList.add(CLASS_NAME_ACTIVE))
})
})
}
- EventHandler.trigger(this._scrollElement, Event.ACTIVATE, {
+ EventHandler.trigger(this._scrollElement, EVENT_ACTIVATE, {
relatedTarget: target
})
}
_clear() {
makeArray(SelectorEngine.find(this._selector))
- .filter(node => node.classList.contains(ClassName.ACTIVE))
- .forEach(node => node.classList.remove(ClassName.ACTIVE))
+ .filter(node => node.classList.contains(CLASS_NAME_ACTIVE))
+ .forEach(node => node.classList.remove(CLASS_NAME_ACTIVE))
}
// Static
@@ -331,8 +323,8 @@ class ScrollSpy {
* ------------------------------------------------------------------------
*/
-EventHandler.on(window, Event.LOAD_DATA_API, () => {
- makeArray(SelectorEngine.find(Selector.DATA_SPY))
+EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
+ makeArray(SelectorEngine.find(SELECTOR_DATA_SPY))
.forEach(spy => new ScrollSpy(spy, Manipulator.getDataAttributes(spy)))
})
diff --git a/js/src/tab.js b/js/src/tab.js
index d9bd1fc05..f7ec29946 100644
--- a/js/src/tab.js
+++ b/js/src/tab.js
@@ -30,31 +30,25 @@ const DATA_KEY = 'bs.tab'
const EVENT_KEY = `.${DATA_KEY}`
const DATA_API_KEY = '.data-api'
-const Event = {
- HIDE: `hide${EVENT_KEY}`,
- HIDDEN: `hidden${EVENT_KEY}`,
- SHOW: `show${EVENT_KEY}`,
- SHOWN: `shown${EVENT_KEY}`,
- CLICK_DATA_API: `click${EVENT_KEY}${DATA_API_KEY}`
-}
-
-const ClassName = {
- DROPDOWN_MENU: 'dropdown-menu',
- ACTIVE: 'active',
- DISABLED: 'disabled',
- FADE: 'fade',
- SHOW: 'show'
-}
-
-const Selector = {
- DROPDOWN: '.dropdown',
- NAV_LIST_GROUP: '.nav, .list-group',
- ACTIVE: '.active',
- ACTIVE_UL: ':scope > li > .active',
- DATA_TOGGLE: '[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',
- DROPDOWN_TOGGLE: '.dropdown-toggle',
- DROPDOWN_ACTIVE_CHILD: ':scope > .dropdown-menu .active'
-}
+const EVENT_HIDE = `hide${EVENT_KEY}`
+const EVENT_HIDDEN = `hidden${EVENT_KEY}`
+const EVENT_SHOW = `show${EVENT_KEY}`
+const EVENT_SHOWN = `shown${EVENT_KEY}`
+const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
+
+const CLASS_NAME_DROPDOWN_MENU = 'dropdown-menu'
+const CLASS_NAME_ACTIVE = 'active'
+const CLASS_NAME_DISABLED = 'disabled'
+const CLASS_NAME_FADE = 'fade'
+const CLASS_NAME_SHOW = 'show'
+
+const SELECTOR_DROPDOWN = '.dropdown'
+const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'
+const SELECTOR_ACTIVE = '.active'
+const SELECTOR_ACTIVE_UL = ':scope > li > .active'
+const SELECTOR_DATA_TOGGLE = '[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]'
+const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'
+const SELECTOR_DROPDOWN_ACTIVE_CHILD = ':scope > .dropdown-menu .active'
/**
* ------------------------------------------------------------------------
@@ -80,17 +74,17 @@ class Tab {
show() {
if ((this._element.parentNode &&
this._element.parentNode.nodeType === Node.ELEMENT_NODE &&
- this._element.classList.contains(ClassName.ACTIVE)) ||
- this._element.classList.contains(ClassName.DISABLED)) {
+ this._element.classList.contains(CLASS_NAME_ACTIVE)) ||
+ this._element.classList.contains(CLASS_NAME_DISABLED)) {
return
}
let previous
const target = getElementFromSelector(this._element)
- const listElement = SelectorEngine.closest(this._element, Selector.NAV_LIST_GROUP)
+ const listElement = SelectorEngine.closest(this._element, SELECTOR_NAV_LIST_GROUP)
if (listElement) {
- const itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? Selector.ACTIVE_UL : Selector.ACTIVE
+ const itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? SELECTOR_ACTIVE_UL : SELECTOR_ACTIVE
previous = makeArray(SelectorEngine.find(itemSelector, listElement))
previous = previous[previous.length - 1]
}
@@ -98,12 +92,12 @@ class Tab {
let hideEvent = null
if (previous) {
- hideEvent = EventHandler.trigger(previous, Event.HIDE, {
+ hideEvent = EventHandler.trigger(previous, EVENT_HIDE, {
relatedTarget: this._element
})
}
- const showEvent = EventHandler.trigger(this._element, Event.SHOW, {
+ const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, {
relatedTarget: previous
})
@@ -118,10 +112,10 @@ class Tab {
)
const complete = () => {
- EventHandler.trigger(previous, Event.HIDDEN, {
+ EventHandler.trigger(previous, EVENT_HIDDEN, {
relatedTarget: this._element
})
- EventHandler.trigger(this._element, Event.SHOWN, {
+ EventHandler.trigger(this._element, EVENT_SHOWN, {
relatedTarget: previous
})
}
@@ -142,12 +136,12 @@ class Tab {
_activate(element, container, callback) {
const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ?
- SelectorEngine.find(Selector.ACTIVE_UL, container) :
- SelectorEngine.children(container, Selector.ACTIVE)
+ SelectorEngine.find(SELECTOR_ACTIVE_UL, container) :
+ SelectorEngine.children(container, SELECTOR_ACTIVE)
const active = activeElements[0]
const isTransitioning = callback &&
- (active && active.classList.contains(ClassName.FADE))
+ (active && active.classList.contains(CLASS_NAME_FADE))
const complete = () => this._transitionComplete(
element,
@@ -157,7 +151,7 @@ class Tab {
if (active && isTransitioning) {
const transitionDuration = getTransitionDurationFromElement(active)
- active.classList.remove(ClassName.SHOW)
+ active.classList.remove(CLASS_NAME_SHOW)
EventHandler.one(active, TRANSITION_END, complete)
emulateTransitionEnd(active, transitionDuration)
@@ -168,12 +162,12 @@ class Tab {
_transitionComplete(element, active, callback) {
if (active) {
- active.classList.remove(ClassName.ACTIVE)
+ active.classList.remove(CLASS_NAME_ACTIVE)
- const dropdownChild = SelectorEngine.findOne(Selector.DROPDOWN_ACTIVE_CHILD, active.parentNode)
+ const dropdownChild = SelectorEngine.findOne(SELECTOR_DROPDOWN_ACTIVE_CHILD, active.parentNode)
if (dropdownChild) {
- dropdownChild.classList.remove(ClassName.ACTIVE)
+ dropdownChild.classList.remove(CLASS_NAME_ACTIVE)
}
if (active.getAttribute('role') === 'tab') {
@@ -181,23 +175,23 @@ class Tab {
}
}
- element.classList.add(ClassName.ACTIVE)
+ element.classList.add(CLASS_NAME_ACTIVE)
if (element.getAttribute('role') === 'tab') {
element.setAttribute('aria-selected', true)
}
reflow(element)
- if (element.classList.contains(ClassName.FADE)) {
- element.classList.add(ClassName.SHOW)
+ if (element.classList.contains(CLASS_NAME_FADE)) {
+ element.classList.add(CLASS_NAME_SHOW)
}
- if (element.parentNode && element.parentNode.classList.contains(ClassName.DROPDOWN_MENU)) {
- const dropdownElement = SelectorEngine.closest(element, Selector.DROPDOWN)
+ if (element.parentNode && element.parentNode.classList.contains(CLASS_NAME_DROPDOWN_MENU)) {
+ const dropdownElement = SelectorEngine.closest(element, SELECTOR_DROPDOWN)
if (dropdownElement) {
- makeArray(SelectorEngine.find(Selector.DROPDOWN_TOGGLE))
- .forEach(dropdown => dropdown.classList.add(ClassName.ACTIVE))
+ makeArray(SelectorEngine.find(SELECTOR_DROPDOWN_TOGGLE))
+ .forEach(dropdown => dropdown.classList.add(CLASS_NAME_ACTIVE))
}
element.setAttribute('aria-expanded', true)
@@ -235,7 +229,7 @@ class Tab {
* ------------------------------------------------------------------------
*/
-EventHandler.on(document, Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
+EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
event.preventDefault()
const data = Data.getData(this, DATA_KEY) || new Tab(this)
diff --git a/js/src/toast.js b/js/src/toast.js
index e0d2a8b3f..abb0ffd34 100644
--- a/js/src/toast.js
+++ b/js/src/toast.js
@@ -28,20 +28,16 @@ const VERSION = '4.3.1'
const DATA_KEY = 'bs.toast'
const EVENT_KEY = `.${DATA_KEY}`
-const Event = {
- CLICK_DISMISS: `click.dismiss${EVENT_KEY}`,
- HIDE: `hide${EVENT_KEY}`,
- HIDDEN: `hidden${EVENT_KEY}`,
- SHOW: `show${EVENT_KEY}`,
- SHOWN: `shown${EVENT_KEY}`
-}
+const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`
+const EVENT_HIDE = `hide${EVENT_KEY}`
+const EVENT_HIDDEN = `hidden${EVENT_KEY}`
+const EVENT_SHOW = `show${EVENT_KEY}`
+const EVENT_SHOWN = `shown${EVENT_KEY}`
-const ClassName = {
- FADE: 'fade',
- HIDE: 'hide',
- SHOW: 'show',
- SHOWING: 'showing'
-}
+const CLASS_NAME_FADE = 'fade'
+const CLASS_NAME_HIDE = 'hide'
+const CLASS_NAME_SHOW = 'show'
+const CLASS_NAME_SHOWING = 'showing'
const DefaultType = {
animation: 'boolean',
@@ -55,9 +51,7 @@ const Default = {
delay: 500
}
-const Selector = {
- DATA_DISMISS: '[data-dismiss="toast"]'
-}
+const SELECTOR_DATA_DISMISS = '[data-dismiss="toast"]'
/**
* ------------------------------------------------------------------------
@@ -91,21 +85,21 @@ class Toast {
// Public
show() {
- const showEvent = EventHandler.trigger(this._element, Event.SHOW)
+ const showEvent = EventHandler.trigger(this._element, EVENT_SHOW)
if (showEvent.defaultPrevented) {
return
}
if (this._config.animation) {
- this._element.classList.add(ClassName.FADE)
+ this._element.classList.add(CLASS_NAME_FADE)
}
const complete = () => {
- this._element.classList.remove(ClassName.SHOWING)
- this._element.classList.add(ClassName.SHOW)
+ this._element.classList.remove(CLASS_NAME_SHOWING)
+ this._element.classList.add(CLASS_NAME_SHOW)
- EventHandler.trigger(this._element, Event.SHOWN)
+ EventHandler.trigger(this._element, EVENT_SHOWN)
if (this._config.autohide) {
this._timeout = setTimeout(() => {
@@ -114,9 +108,9 @@ class Toast {
}
}
- this._element.classList.remove(ClassName.HIDE)
+ this._element.classList.remove(CLASS_NAME_HIDE)
reflow(this._element)
- this._element.classList.add(ClassName.SHOWING)
+ this._element.classList.add(CLASS_NAME_SHOWING)
if (this._config.animation) {
const transitionDuration = getTransitionDurationFromElement(this._element)
@@ -128,22 +122,22 @@ class Toast {
}
hide() {
- if (!this._element.classList.contains(ClassName.SHOW)) {
+ if (!this._element.classList.contains(CLASS_NAME_SHOW)) {
return
}
- const hideEvent = EventHandler.trigger(this._element, Event.HIDE)
+ const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE)
if (hideEvent.defaultPrevented) {
return
}
const complete = () => {
- this._element.classList.add(ClassName.HIDE)
- EventHandler.trigger(this._element, Event.HIDDEN)
+ this._element.classList.add(CLASS_NAME_HIDE)
+ EventHandler.trigger(this._element, EVENT_HIDDEN)
}
- this._element.classList.remove(ClassName.SHOW)
+ this._element.classList.remove(CLASS_NAME_SHOW)
if (this._config.animation) {
const transitionDuration = getTransitionDurationFromElement(this._element)
@@ -158,11 +152,11 @@ class Toast {
clearTimeout(this._timeout)
this._timeout = null
- if (this._element.classList.contains(ClassName.SHOW)) {
- this._element.classList.remove(ClassName.SHOW)
+ if (this._element.classList.contains(CLASS_NAME_SHOW)) {
+ this._element.classList.remove(CLASS_NAME_SHOW)
}
- EventHandler.off(this._element, Event.CLICK_DISMISS)
+ EventHandler.off(this._element, EVENT_CLICK_DISMISS)
Data.removeData(this._element, DATA_KEY)
this._element = null
@@ -190,8 +184,8 @@ class Toast {
_setListeners() {
EventHandler.on(
this._element,
- Event.CLICK_DISMISS,
- Selector.DATA_DISMISS,
+ EVENT_CLICK_DISMISS,
+ SELECTOR_DATA_DISMISS,
() => this.hide()
)
}
diff --git a/js/src/tooltip.js b/js/src/tooltip.js
index 9b2ae6f61..b723b1ba8 100644
--- a/js/src/tooltip.js
+++ b/js/src/tooltip.js
@@ -89,11 +89,6 @@ const Default = {
popperConfig: null
}
-const HoverState = {
- SHOW: 'show',
- OUT: 'out'
-}
-
const Event = {
HIDE: `hide${EVENT_KEY}`,
HIDDEN: `hidden${EVENT_KEY}`,
@@ -107,22 +102,19 @@ const Event = {
MOUSELEAVE: `mouseleave${EVENT_KEY}`
}
-const ClassName = {
- FADE: 'fade',
- MODAL: 'modal',
- SHOW: 'show'
-}
+const CLASS_NAME_FADE = 'fade'
+const CLASS_NAME_MODAL = 'modal'
+const CLASS_NAME_SHOW = 'show'
-const Selector = {
- TOOLTIP_INNER: '.tooltip-inner'
-}
+const HOVER_STATE_SHOW = 'show'
+const HOVER_STATE_OUT = 'out'
-const Trigger = {
- HOVER: 'hover',
- FOCUS: 'focus',
- CLICK: 'click',
- MANUAL: 'manual'
-}
+const SELECTOR_TOOLTIP_INNER = '.tooltip-inner'
+
+const TRIGGER_HOVER = 'hover'
+const TRIGGER_FOCUS = 'focus'
+const TRIGGER_CLICK = 'click'
+const TRIGGER_MANUAL = 'manual'
/**
* ------------------------------------------------------------------------
@@ -221,7 +213,7 @@ class Tooltip {
context._leave(null, context)
}
} else {
- if (this.getTipElement().classList.contains(ClassName.SHOW)) {
+ if (this.getTipElement().classList.contains(CLASS_NAME_SHOW)) {
this._leave(null, this)
return
}
@@ -236,7 +228,7 @@ class Tooltip {
Data.removeData(this.element, this.constructor.DATA_KEY)
EventHandler.off(this.element, this.constructor.EVENT_KEY)
- EventHandler.off(SelectorEngine.closest(this.element, `.${ClassName.MODAL}`), 'hide.bs.modal', this._hideModalHandler)
+ EventHandler.off(SelectorEngine.closest(this.element, `.${CLASS_NAME_MODAL}`), 'hide.bs.modal', this._hideModalHandler)
if (this.tip) {
this.tip.parentNode.removeChild(this.tip)
@@ -281,7 +273,7 @@ class Tooltip {
this.setContent()
if (this.config.animation) {
- tip.classList.add(ClassName.FADE)
+ tip.classList.add(CLASS_NAME_FADE)
}
const placement = typeof this.config.placement === 'function' ?
@@ -302,7 +294,7 @@ class Tooltip {
this._popper = new Popper(this.element, tip, this._getPopperConfig(attachment))
- tip.classList.add(ClassName.SHOW)
+ tip.classList.add(CLASS_NAME_SHOW)
// If this is a touch-enabled device we add extra
// empty mouseover listeners to the body's immediate children;
@@ -324,12 +316,12 @@ class Tooltip {
EventHandler.trigger(this.element, this.constructor.Event.SHOWN)
- if (prevHoverState === HoverState.OUT) {
+ if (prevHoverState === HOVER_STATE_OUT) {
this._leave(null, this)
}
}
- if (this.tip.classList.contains(ClassName.FADE)) {
+ if (this.tip.classList.contains(CLASS_NAME_FADE)) {
const transitionDuration = getTransitionDurationFromElement(this.tip)
EventHandler.one(this.tip, TRANSITION_END, complete)
emulateTransitionEnd(this.tip, transitionDuration)
@@ -342,7 +334,7 @@ class Tooltip {
hide() {
const tip = this.getTipElement()
const complete = () => {
- if (this._hoverState !== HoverState.SHOW && tip.parentNode) {
+ if (this._hoverState !== HOVER_STATE_SHOW && tip.parentNode) {
tip.parentNode.removeChild(tip)
}
@@ -357,7 +349,7 @@ class Tooltip {
return
}
- tip.classList.remove(ClassName.SHOW)
+ tip.classList.remove(CLASS_NAME_SHOW)
// If this is a touch-enabled device we remove the extra
// empty mouseover listeners we added for iOS support
@@ -366,11 +358,11 @@ class Tooltip {
.forEach(element => EventHandler.off(element, 'mouseover', noop))
}
- this._activeTrigger[Trigger.CLICK] = false
- this._activeTrigger[Trigger.FOCUS] = false
- this._activeTrigger[Trigger.HOVER] = false
+ this._activeTrigger[TRIGGER_CLICK] = false
+ this._activeTrigger[TRIGGER_FOCUS] = false
+ this._activeTrigger[TRIGGER_HOVER] = false
- if (this.tip.classList.contains(ClassName.FADE)) {
+ if (this.tip.classList.contains(CLASS_NAME_FADE)) {
const transitionDuration = getTransitionDurationFromElement(tip)
EventHandler.one(tip, TRANSITION_END, complete)
@@ -408,9 +400,9 @@ class Tooltip {
setContent() {
const tip = this.getTipElement()
- this.setElementContent(SelectorEngine.findOne(Selector.TOOLTIP_INNER, tip), this.getTitle())
- tip.classList.remove(ClassName.FADE)
- tip.classList.remove(ClassName.SHOW)
+ this.setElementContent(SelectorEngine.findOne(SELECTOR_TOOLTIP_INNER, tip), this.getTitle())
+ tip.classList.remove(CLASS_NAME_FADE)
+ tip.classList.remove(CLASS_NAME_SHOW)
}
setElementContent(element, content) {
@@ -539,11 +531,11 @@ class Tooltip {
this.config.selector,
event => this.toggle(event)
)
- } else if (trigger !== Trigger.MANUAL) {
- const eventIn = trigger === Trigger.HOVER ?
+ } else if (trigger !== TRIGGER_MANUAL) {
+ const eventIn = trigger === TRIGGER_HOVER ?
this.constructor.Event.MOUSEENTER :
this.constructor.Event.FOCUSIN
- const eventOut = trigger === Trigger.HOVER ?
+ const eventOut = trigger === TRIGGER_HOVER ?
this.constructor.Event.MOUSELEAVE :
this.constructor.Event.FOCUSOUT
@@ -566,7 +558,7 @@ class Tooltip {
}
}
- EventHandler.on(SelectorEngine.closest(this.element, `.${ClassName.MODAL}`),
+ EventHandler.on(SelectorEngine.closest(this.element, `.${CLASS_NAME_MODAL}`),
'hide.bs.modal',
this._hideModalHandler
)
@@ -609,19 +601,19 @@ class Tooltip {
if (event) {
context._activeTrigger[
- event.type === 'focusin' ? Trigger.FOCUS : Trigger.HOVER
+ event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER
] = true
}
- if (context.getTipElement().classList.contains(ClassName.SHOW) ||
- context._hoverState === HoverState.SHOW) {
- context._hoverState = HoverState.SHOW
+ if (context.getTipElement().classList.contains(CLASS_NAME_SHOW) ||
+ context._hoverState === HOVER_STATE_SHOW) {
+ context._hoverState = HOVER_STATE_SHOW
return
}
clearTimeout(context._timeout)
- context._hoverState = HoverState.SHOW
+ context._hoverState = HOVER_STATE_SHOW
if (!context.config.delay || !context.config.delay.show) {
context.show()
@@ -629,7 +621,7 @@ class Tooltip {
}
context._timeout = setTimeout(() => {
- if (context._hoverState === HoverState.SHOW) {
+ if (context._hoverState === HOVER_STATE_SHOW) {
context.show()
}
}, context.config.delay.show)
@@ -649,7 +641,7 @@ class Tooltip {
if (event) {
context._activeTrigger[
- event.type === 'focusout' ? Trigger.FOCUS : Trigger.HOVER
+ event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER
] = false
}
@@ -659,7 +651,7 @@ class Tooltip {
clearTimeout(context._timeout)
- context._hoverState = HoverState.OUT
+ context._hoverState = HOVER_STATE_OUT
if (!context.config.delay || !context.config.delay.hide) {
context.hide()
@@ -667,7 +659,7 @@ class Tooltip {
}
context._timeout = setTimeout(() => {
- if (context._hoverState === HoverState.OUT) {
+ if (context._hoverState === HOVER_STATE_OUT) {
context.hide()
}
}, context.config.delay.hide)
@@ -768,7 +760,7 @@ class Tooltip {
return
}
- tip.classList.remove(ClassName.FADE)
+ tip.classList.remove(CLASS_NAME_FADE)
this.config.animation = false
this.hide()
this.show()
diff --git a/js/src/util/index.js b/js/src/util/index.js
index 8a5ae2156..001201b4b 100644
--- a/js/src/util/index.js
+++ b/js/src/util/index.js
@@ -10,7 +10,13 @@ const MILLISECONDS_MULTIPLIER = 1000
const TRANSITION_END = 'transitionend'
// Shoutout AngusCroll (https://goo.gl/pxwQGp)
-const toType = obj => ({}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase())
+const toType = obj => {
+ if (obj === null || obj === undefined) {
+ return `${obj}`
+ }
+
+ return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase()
+}
/**
* --------------------------------------------------------------------------
@@ -81,10 +87,7 @@ const getTransitionDurationFromElement = element => {
}
const triggerTransitionEnd = element => {
- const evt = document.createEvent('HTMLEvents')
-
- evt.initEvent(TRANSITION_END, true, true)
- element.dispatchEvent(evt)
+ element.dispatchEvent(new Event(TRANSITION_END))
}
const isElement = obj => (obj[0] || obj).nodeType
diff --git a/js/tests/browsers.js b/js/tests/browsers.js
index a0d43da86..859f9505c 100644
--- a/js/tests/browsers.js
+++ b/js/tests/browsers.js
@@ -30,13 +30,6 @@ const browsers = {
browser: 'Edge',
browser_version: 'latest'
},
- ie11Win10: {
- base: 'BrowserStack',
- os: 'Windows',
- os_version: '10',
- browser: 'IE',
- browser_version: '11.0'
- },
chromeWin10: {
base: 'BrowserStack',
os: 'Windows',
diff --git a/js/tests/unit/modal.spec.js b/js/tests/unit/modal.spec.js
index b4923ab3f..62d0835ee 100644
--- a/js/tests/unit/modal.spec.js
+++ b/js/tests/unit/modal.spec.js
@@ -653,7 +653,6 @@ describe('Modal', () => {
it('should enforce focus', done => {
fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog" /></div>'
- const isIE11 = Boolean(window.MSInputMethodContext) && Boolean(document.documentMode)
const modalEl = fixtureEl.querySelector('.modal')
const modal = new Modal(modalEl)
@@ -668,11 +667,6 @@ describe('Modal', () => {
modalEl.addEventListener('shown.bs.modal', () => {
expect(modal._enforceFocus).toHaveBeenCalled()
- if (isIE11) {
- done()
- return
- }
-
spyOn(modal._element, 'focus')
document.addEventListener('focusin', focusInListener)
diff --git a/js/tests/unit/util/index.spec.js b/js/tests/unit/util/index.spec.js
index 42c273f06..57ca1a9c7 100644
--- a/js/tests/unit/util/index.spec.js
+++ b/js/tests/unit/util/index.spec.js
@@ -198,8 +198,9 @@ describe('Util', () => {
})
describe('typeCheckConfig', () => {
+ const namePlugin = 'collapse'
+
it('should check type of the config object', () => {
- const namePlugin = 'collapse'
const defaultType = {
toggle: 'boolean',
parent: '(string|element)'
@@ -213,6 +214,34 @@ describe('Util', () => {
Util.typeCheckConfig(namePlugin, config, defaultType)
}).toThrow(new Error('COLLAPSE: Option "parent" provided type "number" but expected type "(string|element)".'))
})
+
+ it('should return null stringified when null is passed', () => {
+ const defaultType = {
+ toggle: 'boolean',
+ parent: '(null|element)'
+ }
+ const config = {
+ toggle: true,
+ parent: null
+ }
+
+ Util.typeCheckConfig(namePlugin, config, defaultType)
+ expect().nothing()
+ })
+
+ it('should return undefined stringified when undefined is passed', () => {
+ const defaultType = {
+ toggle: 'boolean',
+ parent: '(undefined|element)'
+ }
+ const config = {
+ toggle: true,
+ parent: undefined
+ }
+
+ Util.typeCheckConfig(namePlugin, config, defaultType)
+ expect().nothing()
+ })
})
describe('makeArray', () => {
diff --git a/package-lock.json b/package-lock.json
index 41fe28ce2..aeb1f06a3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -82,9 +82,9 @@
}
},
"@babel/generator": {
- "version": "7.8.7",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.7.tgz",
- "integrity": "sha512-DQwjiKJqH4C3qGiyQCAExJHoZssn49JTMJgZ8SANGgVFdkupcUhLOdkAeoC6kmHZCPfoDG5M0b6cFlSN5wW7Ew==",
+ "version": "7.8.8",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.8.tgz",
+ "integrity": "sha512-HKyUVu69cZoclptr8t8U5b6sx6zoWjh8jiUhnuj3MpZuKT2dJ8zPTuiy31luq32swhI0SpwItCIlU8XW7BZeJg==",
"dev": true,
"requires": {
"@babel/types": "^7.8.7",
@@ -137,14 +137,14 @@
}
},
"@babel/helper-create-regexp-features-plugin": {
- "version": "7.8.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.6.tgz",
- "integrity": "sha512-bPyujWfsHhV/ztUkwGHz/RPV1T1TDEsSZDsN42JPehndA+p1KKTh3npvTadux0ZhCrytx9tvjpWNowKby3tM6A==",
+ "version": "7.8.8",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.8.tgz",
+ "integrity": "sha512-LYVPdwkrQEiX9+1R29Ld/wTrmQu1SSKYnuOk3g0CkcZMA1p0gsNxJFj/3gBdaJ7Cg0Fnek5z0DsMULePP7Lrqg==",
"dev": true,
"requires": {
"@babel/helper-annotate-as-pure": "^7.8.3",
"@babel/helper-regex": "^7.8.3",
- "regexpu-core": "^4.6.0"
+ "regexpu-core": "^4.7.0"
}
},
"@babel/helper-define-map": {
@@ -333,9 +333,9 @@
}
},
"@babel/parser": {
- "version": "7.8.7",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.7.tgz",
- "integrity": "sha512-9JWls8WilDXFGxs0phaXAZgpxTZhSk/yOYH2hTHC0X1yC7Z78IJfvR1vJ+rmJKq3I35td2XzXzN6ZLYlna+r/A==",
+ "version": "7.8.8",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.8.tgz",
+ "integrity": "sha512-mO5GWzBPsPf6865iIbzNE0AvkKF3NE+2S3eRUpE+FE07BOAkXh6G+GW/Pj01hhXjve1WScbaIO4UlY1JKeqCcA==",
"dev": true
},
"@babel/plugin-proposal-async-generator-functions": {
@@ -410,12 +410,12 @@
}
},
"@babel/plugin-proposal-unicode-property-regex": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.3.tgz",
- "integrity": "sha512-1/1/rEZv2XGweRwwSkLpY+s60za9OZ1hJs4YDqFHCw0kYWYwL5IFljVY1MYBL+weT1l9pokDO2uhSTLVxzoHkQ==",
+ "version": "7.8.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.8.tgz",
+ "integrity": "sha512-EVhjVsMpbhLw9ZfHWSx2iy13Q8Z/eg8e8ccVWt23sWQK5l1UdkoLJPN5w69UA4uITGBnEZD2JOe4QOHycYKv8A==",
"dev": true,
"requires": {
- "@babel/helper-create-regexp-features-plugin": "^7.8.3",
+ "@babel/helper-create-regexp-features-plugin": "^7.8.8",
"@babel/helper-plugin-utils": "^7.8.3"
}
},
@@ -556,9 +556,9 @@
}
},
"@babel/plugin-transform-destructuring": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.8.3.tgz",
- "integrity": "sha512-H4X646nCkiEcHZUZaRkhE2XVsoz0J/1x3VVujnn96pSoGCtKPA99ZZA+va+gK+92Zycd6OBKCD8tDb/731bhgQ==",
+ "version": "7.8.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.8.8.tgz",
+ "integrity": "sha512-eRJu4Vs2rmttFCdhPUM3bV0Yo/xPSdPw6ML9KHs/bjB4bLA5HXlbvYXPOD5yASodGod+krjYx21xm1QmL8dCJQ==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3"
@@ -704,9 +704,9 @@
}
},
"@babel/plugin-transform-parameters": {
- "version": "7.8.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.8.7.tgz",
- "integrity": "sha512-brYWaEPTRimOctz2NDA3jnBbDi7SVN2T4wYuu0aqSzxC3nozFZngGaw29CJ9ZPweB7k+iFmZuoG3IVPIcXmD2g==",
+ "version": "7.8.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.8.8.tgz",
+ "integrity": "sha512-hC4Ld/Ulpf1psQciWWwdnUspQoQco2bMzSrwU6TmzRlvoYQe4rQFy9vnCZDTlVeCQj0JPfL+1RX0V8hCJvkgBA==",
"dev": true,
"requires": {
"@babel/helper-call-delegate": "^7.8.7",
@@ -1046,9 +1046,9 @@
"dev": true
},
"@types/node": {
- "version": "13.7.7",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-13.7.7.tgz",
- "integrity": "sha512-Uo4chgKbnPNlxQwoFmYIwctkQVkMMmsAoGGU4JKwLuvBefF0pCq4FybNSnfkfRCpC7ZW7kttcC/TrRtAJsvGtg==",
+ "version": "13.9.1",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.1.tgz",
+ "integrity": "sha512-E6M6N0blf/jiZx8Q3nb0vNaswQeEyn0XlupO+xN6DtJ6r6IT4nXrTry7zhIfYvFCl3/8Cu6WIysmUBKiqV0bqQ==",
"dev": true
},
"@types/normalize-package-data": {
@@ -1955,11 +1955,13 @@
}
},
"bl": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.1.tgz",
- "integrity": "sha512-FL/TdvchukRCuWVxT0YMO/7+L5TNeNrVFvRU2IY63aUyv9mpt8splf2NEr6qXtPo5fya5a66YohQKvGNmLrWNA==",
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.2.tgz",
+ "integrity": "sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ==",
"dev": true,
"requires": {
+ "buffer": "^5.5.0",
+ "inherits": "^2.0.4",
"readable-stream": "^3.4.0"
},
"dependencies": {
@@ -2385,9 +2387,9 @@
}
},
"caniuse-lite": {
- "version": "1.0.30001032",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001032.tgz",
- "integrity": "sha512-8joOm7BwcpEN4BfVHtfh0hBXSAPVYk+eUIcNntGtMkUWy/6AKRCDZINCLe3kB1vHhT2vBxBF85Hh9VlPXi/qjA==",
+ "version": "1.0.30001035",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001035.tgz",
+ "integrity": "sha512-C1ZxgkuA4/bUEdMbU5WrGY4+UhMFFiXrgNAfxiMIqWgFTWfv/xsZCS2xEHT2LMq7xAZfuAnu6mcqyDl0ZR6wLQ==",
"dev": true
},
"capture-stack-trace": {
@@ -3633,9 +3635,9 @@
"dev": true
},
"electron-to-chromium": {
- "version": "1.3.370",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.370.tgz",
- "integrity": "sha512-399cXDE9C7qoVF2CUgCA/MLflfvxbo1F0kB/pkB94426freL/JgZ0HNaloomsOfnE+VC/qgTFZqzmivSdaNfPQ==",
+ "version": "1.3.378",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.378.tgz",
+ "integrity": "sha512-nBp/AfhaVIOnfwgL1CZxt80IcqWcyYXiX6v5gflAksxy+SzBVz7A7UWR1Nos92c9ofXW74V9PoapzRb0jJfYXw==",
"dev": true
},
"emoji-regex": {
@@ -3908,9 +3910,9 @@
}
},
"globals": {
- "version": "12.3.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-12.3.0.tgz",
- "integrity": "sha512-wAfjdLgFsPZsklLJvOBUBmzYE8/CwhEqSBEMRXA3qxIiNtyqvjYurAtIfDh6chlEPUfmTY3MnZh5Hfh4q0UlIw==",
+ "version": "12.4.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
+ "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==",
"dev": true,
"requires": {
"type-fest": "^0.8.1"
@@ -4227,12 +4229,12 @@
"dev": true
},
"espree": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.0.tgz",
- "integrity": "sha512-Xs8airJ7RQolnDIbLtRutmfvSsAe0xqMMAantCN/GMoqf81TFbeI1T7Jpd56qYu1uuh32dOG5W/X9uO+ghPXzA==",
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz",
+ "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==",
"dev": true,
"requires": {
- "acorn": "^7.1.0",
+ "acorn": "^7.1.1",
"acorn-jsx": "^5.2.0",
"eslint-visitor-keys": "^1.1.0"
}
@@ -5580,9 +5582,9 @@
}
},
"gaxios": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-2.3.2.tgz",
- "integrity": "sha512-K/+py7UvKRDaEwEKlLiRKrFr+wjGjsMz5qH7Vs549QJS7cpSCOT/BbWL7pzqECflc46FcNPipjSfB+V1m8PAhw==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-3.0.0.tgz",
+ "integrity": "sha512-9UwpmysNKCwSCSvFqTSTPFZX89RgMpJBFzKknrjpEm6oQGn7QDlFO57mPqJHP9X4llPR8uSt3LAHBZDXoetGnA==",
"dev": true,
"requires": {
"abort-controller": "^3.0.0",
@@ -6324,9 +6326,9 @@
"dev": true
},
"in-publish": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz",
- "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.1.tgz",
+ "integrity": "sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ==",
"dev": true
},
"indent-string": {
@@ -6370,9 +6372,9 @@
"dev": true
},
"inquirer": {
- "version": "7.0.6",
- "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.6.tgz",
- "integrity": "sha512-7SVO4h+QIdMq6XcqIqrNte3gS5MzCCKZdsq9DO4PJziBFNYzP3PGFbDjgadDb//MCahzgjCxvQ/O2wa7kx9o4w==",
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz",
+ "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==",
"dev": true,
"requires": {
"ansi-escapes": "^4.2.1",
@@ -7140,12 +7142,12 @@
"dev": true
},
"json5": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz",
- "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.2.tgz",
+ "integrity": "sha512-MoUOQ4WdiN3yxhm7NEVJSJrieAo5hNSLQ5sj05OTRHPL9HOBy8u4Bu88jsC1jvqAdN+E1bJmsUcZH+1HQxliqQ==",
"dev": true,
"requires": {
- "minimist": "^1.2.0"
+ "minimist": "^1.2.5"
}
},
"jsonexport": {
@@ -7583,15 +7585,15 @@
"dev": true
},
"linkinator": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/linkinator/-/linkinator-2.0.3.tgz",
- "integrity": "sha512-K1AhPAydXL9l4YX0o/FEYQUcBmjQQon3P6xzEZeZvQD1HSpa6FrAVrqZMxaEaDXUc8N1Y7vCmAKKNC6TX+2a5g==",
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/linkinator/-/linkinator-2.0.4.tgz",
+ "integrity": "sha512-5CJbZ2CWa2uK/YWvqtglzGuiy8ccYmoCCh+QEmwLa70KDSaphu5/DDbOlPHOSsy5ExN7fnaWtpatmnJi929pBA==",
"dev": true,
"requires": {
"chalk": "^3.0.0",
"cheerio": "^1.0.0-rc.2",
"finalhandler": "^1.1.2",
- "gaxios": "^2.0.1",
+ "gaxios": "^3.0.0",
"jsonexport": "^2.4.1",
"meow": "^6.0.0",
"p-queue": "^6.2.1",
@@ -8170,9 +8172,9 @@
}
},
"minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
"dev": true
},
"minimist-options": {
@@ -8209,20 +8211,12 @@
}
},
"mkdirp": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
- "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.3.tgz",
+ "integrity": "sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg==",
"dev": true,
"requires": {
- "minimist": "0.0.8"
- },
- "dependencies": {
- "minimist": {
- "version": "0.0.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
- "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
- "dev": true
- }
+ "minimist": "^1.2.5"
}
},
"ms": {
@@ -8346,9 +8340,9 @@
}
},
"node-releases": {
- "version": "1.1.50",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.50.tgz",
- "integrity": "sha512-lgAmPv9eYZ0bGwUYAKlr8MG6K4CvWliWqnkcT2P8mMAgVrH3lqfBPorFlxiG1pHQnqmavJZ9vbMXUTNyMLbrgQ==",
+ "version": "1.1.52",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.52.tgz",
+ "integrity": "sha512-snSiT1UypkgGt2wxPqS6ImEUICbNCMb31yaxWrOLXjhlt2z2/IBpaOxzONExqSm4y5oLnAqjjRWu+wsDzK5yNQ==",
"dev": true,
"requires": {
"semver": "^6.3.0"
@@ -10725,24 +10719,24 @@
"dev": true
},
"regenerate-unicode-properties": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz",
- "integrity": "sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA==",
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz",
+ "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==",
"dev": true,
"requires": {
"regenerate": "^1.4.0"
}
},
"regenerator-runtime": {
- "version": "0.13.4",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.4.tgz",
- "integrity": "sha512-plpwicqEzfEyTQohIKktWigcLzmNStMGwbOUbykx51/29Z3JOGYldaaNGK7ngNXV+UcoqvIMmloZ48Sr74sd+g==",
+ "version": "0.13.5",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz",
+ "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==",
"dev": true
},
"regenerator-transform": {
- "version": "0.14.2",
- "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.2.tgz",
- "integrity": "sha512-V4+lGplCM/ikqi5/mkkpJ06e9Bujq1NFmNLvsCs56zg3ZbzrnUzAtizZ24TXxtRX/W2jcdScwQCnbL0CICTFkQ==",
+ "version": "0.14.3",
+ "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.3.tgz",
+ "integrity": "sha512-zXHNKJspmONxBViAb3ZUmFoFPnTBs3zFhCEZJiwp/gkNzxVbTqNJVjYKx6Qk1tQ1P4XLf4TbH9+KBB7wGoAaUw==",
"dev": true,
"requires": {
"@babel/runtime": "^7.8.4",
@@ -10773,17 +10767,17 @@
"dev": true
},
"regexpu-core": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.6.0.tgz",
- "integrity": "sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg==",
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.0.tgz",
+ "integrity": "sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ==",
"dev": true,
"requires": {
"regenerate": "^1.4.0",
- "regenerate-unicode-properties": "^8.1.0",
- "regjsgen": "^0.5.0",
- "regjsparser": "^0.6.0",
+ "regenerate-unicode-properties": "^8.2.0",
+ "regjsgen": "^0.5.1",
+ "regjsparser": "^0.6.4",
"unicode-match-property-ecmascript": "^1.0.4",
- "unicode-match-property-value-ecmascript": "^1.1.0"
+ "unicode-match-property-value-ecmascript": "^1.2.0"
}
},
"registry-auth-token": {
@@ -10811,9 +10805,9 @@
"dev": true
},
"regjsparser": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.3.tgz",
- "integrity": "sha512-8uZvYbnfAtEm9Ab8NTb3hdLwL4g/LQzEYP7Xs27T96abJCCE2d6r3cPZPQEsLKy0vRSGVNG+/zVGtLr86HQduA==",
+ "version": "0.6.4",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.4.tgz",
+ "integrity": "sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw==",
"dev": true,
"requires": {
"jsesc": "~0.5.0"
@@ -11048,9 +11042,9 @@
}
},
"rollup": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.0.6.tgz",
- "integrity": "sha512-P42IlI6a/bxh52ed8hEXXe44LcHfep2f26OZybMJPN1TTQftibvQEl3CWeOmJrzqGbFxOA000QXDWO9WJaOQpA==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.1.0.tgz",
+ "integrity": "sha512-gfE1455AEazVVTJoeQtcOq/U6GSxwoj4XPSWVsuWmgIxj7sBQNLDOSA82PbdMe+cP8ql8fR1jogPFe8Wg8g4SQ==",
"dev": true,
"requires": {
"fsevents": "~2.1.2"
@@ -12745,9 +12739,9 @@
}
},
"stylelint-scss": {
- "version": "3.14.2",
- "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-3.14.2.tgz",
- "integrity": "sha512-59/BkIEWyFoORiejDIQB2P2kmg0KcqMn7wtj1y5sRvS4N+Qh+Ng3hbKelOzgS+OM2Ezbai0uEev8xckXxkh9TQ==",
+ "version": "3.15.0",
+ "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-3.15.0.tgz",
+ "integrity": "sha512-c6poL7nsU5XVXxl94jl+RY2Rf3CFfMuL8kWp9PfvDi4A7Op30KGAiIfB5Co1RFKnpIOkzz44EO8ur1T9DEl5mA==",
"dev": true,
"requires": {
"lodash": "^4.17.15",
@@ -12857,9 +12851,9 @@
}
},
"tar-stream": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.1.tgz",
- "integrity": "sha512-GZjLk64XcE/58qwIc1ZfXGqTSE4OutPMEkfBE/oh9eJ4x1eMRjYkgrLrav7PzddpvIpSJSGi8FgNNYXdB9Vumg==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz",
+ "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==",
"dev": true,
"requires": {
"bl": "^4.0.1",
@@ -12889,9 +12883,9 @@
"dev": true
},
"terser": {
- "version": "4.6.6",
- "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.6.tgz",
- "integrity": "sha512-4lYPyeNmstjIIESr/ysHg2vUPRGf2tzF9z2yYwnowXVuVzLEamPN1Gfrz7f8I9uEPuHcbFlW4PLIAsJoxXyJ1g==",
+ "version": "4.6.7",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.7.tgz",
+ "integrity": "sha512-fmr7M1f7DBly5cX2+rFDvmGBAaaZyPrHYK4mMdHEDAdNTqXSZgSOfqsfGq2HqPGT/1V0foZZuCZFx8CHKgAk3g==",
"dev": true,
"requires": {
"commander": "^2.20.0",
@@ -13207,15 +13201,15 @@
}
},
"unicode-match-property-value-ecmascript": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz",
- "integrity": "sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz",
+ "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==",
"dev": true
},
"unicode-property-aliases-ecmascript": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz",
- "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz",
+ "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==",
"dev": true
},
"unified": {
@@ -13918,18 +13912,18 @@
"dev": true
},
"yaml": {
- "version": "1.7.2",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.7.2.tgz",
- "integrity": "sha512-qXROVp90sb83XtAoqE8bP9RwAkTTZbugRUTm5YeFCBfNRPEp2YzTeqWiz7m5OORHzEvrA/qcGS8hp/E+MMROYw==",
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.8.2.tgz",
+ "integrity": "sha512-omakb0d7FjMo3R1D2EbTKVIk6dAVLRxFXdLZMEUToeAvuqgG/YuHMuQOZ5fgk+vQ8cx+cnGKwyg+8g8PNT0xQg==",
"dev": true,
"requires": {
- "@babel/runtime": "^7.6.3"
+ "@babel/runtime": "^7.8.7"
}
},
"yargs": {
- "version": "15.1.0",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.1.0.tgz",
- "integrity": "sha512-T39FNN1b6hCW4SOIk1XyTOWxtXdcen0t+XYrysQmChzSipvhBO8Bj0nK1ozAasdk24dNWuMZvr4k24nz+8HHLg==",
+ "version": "15.3.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz",
+ "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==",
"dev": true,
"requires": {
"cliui": "^6.0.0",
@@ -13942,7 +13936,7 @@
"string-width": "^4.2.0",
"which-module": "^2.0.0",
"y18n": "^4.0.0",
- "yargs-parser": "^16.1.0"
+ "yargs-parser": "^18.1.1"
},
"dependencies": {
"ansi-regex": {
@@ -14025,6 +14019,16 @@
"requires": {
"ansi-regex": "^5.0.0"
}
+ },
+ "yargs-parser": {
+ "version": "18.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.1.tgz",
+ "integrity": "sha512-KRHEsOM16IX7XuLnMOqImcPNbLVXMNHYAoFc3BKR8Ortl5gzDbtXvvEoGx9imk5E+X1VeNKNlcHr8B8vi+7ipA==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ }
}
}
},
diff --git a/package.json b/package.json
index 89b6e1463..0cd88af0c 100644
--- a/package.json
+++ b/package.json
@@ -37,9 +37,9 @@
"js-compile-plugins": "node build/build-plugins.js",
"js-lint": "eslint --cache --cache-location .cache/.eslintcache --report-unused-disable-directives .",
"js-minify": "npm-run-all --parallel js-minify-*",
- "js-minify-standalone": "terser --compress typeofs=false --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.js.map,includeSources,url=bootstrap.min.js.map\" --output dist/js/bootstrap.min.js dist/js/bootstrap.js",
+ "js-minify-standalone": "terser --compress --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.js.map,includeSources,url=bootstrap.min.js.map\" --output dist/js/bootstrap.min.js dist/js/bootstrap.js",
"js-minify-standalone-esm": "terser --compress --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.esm.js.map,includeSources,url=bootstrap.esm.min.js.map\" --output dist/js/bootstrap.esm.min.js dist/js/bootstrap.esm.js",
- "js-minify-bundle": "terser --compress typeofs=false --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.bundle.js.map,includeSources,url=bootstrap.bundle.min.js.map\" --output dist/js/bootstrap.bundle.min.js dist/js/bootstrap.bundle.js",
+ "js-minify-bundle": "terser --compress --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.bundle.js.map,includeSources,url=bootstrap.bundle.min.js.map\" --output dist/js/bootstrap.bundle.min.js dist/js/bootstrap.bundle.js",
"js-test": "npm-run-all --parallel js-test-karma js-test-integration",
"js-debug": "cross-env DEBUG=true karma start js/tests/karma.conf.js",
"js-test-karma": "karma start js/tests/karma.conf.js",
@@ -118,21 +118,21 @@
"karma-jasmine": "^3.1.1",
"karma-jasmine-html-reporter": "^1.5.2",
"karma-rollup-preprocessor": "^7.0.3",
- "linkinator": "^2.0.3",
+ "linkinator": "^2.0.4",
"lockfile-lint": "^4.1.0",
"node-sass": "^4.13.1",
"nodemon": "^2.0.2",
"npm-run-all": "^4.1.5",
"popper.js": "^1.16.0",
"postcss-cli": "^7.1.0",
- "rollup": "^2.0.6",
+ "rollup": "^2.1.0",
"rollup-plugin-babel": "^4.4.0",
"rollup-plugin-istanbul": "^2.0.1",
"serve": "^11.3.0",
"shelljs": "^0.8.3",
"stylelint": "^13.2.1",
"stylelint-config-twbs-bootstrap": "^2.0.1",
- "terser": "^4.6.6",
+ "terser": "^4.6.7",
"vnu-jar": "20.3.16"
},
"files": [
diff --git a/scss/_breadcrumb.scss b/scss/_breadcrumb.scss
index d5c5a9a99..db8e74193 100644
--- a/scss/_breadcrumb.scss
+++ b/scss/_breadcrumb.scss
@@ -17,27 +17,13 @@
padding-left: $breadcrumb-item-padding-x;
&::before {
- display: inline-block; // Suppress underlining of the separator in modern browsers
+ display: inline-block; // Suppress underlining of the separator
padding-right: $breadcrumb-item-padding-x;
color: $breadcrumb-divider-color;
content: escape-svg($breadcrumb-divider);
}
}
- // IE9-11 hack to properly handle hyperlink underlines for breadcrumbs built
- // without `<ul>`s. The `::before` pseudo-element generates an element
- // *within* the .breadcrumb-item and thereby inherits the `text-decoration`.
- //
- // To trick IE into suppressing the underline, we give the pseudo-element an
- // underline and then immediately remove it.
- + .breadcrumb-item:hover::before {
- text-decoration: underline;
- }
- // stylelint-disable-next-line no-duplicate-selectors
- + .breadcrumb-item:hover::before {
- text-decoration: none;
- }
-
&.active {
color: $breadcrumb-active-color;
}
diff --git a/scss/_card.scss b/scss/_card.scss
index 132f79e1e..3099109b1 100644
--- a/scss/_card.scss
+++ b/scss/_card.scss
@@ -36,9 +36,6 @@
// Enable `flex-grow: 1` for decks and groups so that card blocks take up
// as much space as possible, ensuring footers are aligned to the bottom.
flex: 1 1 auto;
- // Workaround for the image size bug in IE
- // See: https://github.com/twbs/bootstrap/pull/28855
- min-height: 1px;
padding: $card-spacer-y $card-spacer-x;
color: $card-color;
}
@@ -135,7 +132,6 @@
.card-img,
.card-img-top,
.card-img-bottom {
- flex-shrink: 0; // For IE: https://github.com/twbs/bootstrap/issues/29396
width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch
}
diff --git a/scss/_modal.scss b/scss/_modal.scss
index e43c70fbb..ed6ab4eb1 100644
--- a/scss/_modal.scss
+++ b/scss/_modal.scss
@@ -56,11 +56,9 @@
}
.modal-dialog-scrollable {
- display: flex; // IE10/11
max-height: subtract(100%, $modal-dialog-margin * 2);
.modal-content {
- max-height: subtract(100vh, $modal-dialog-margin * 2); // IE10/11
overflow: hidden;
}
@@ -78,29 +76,6 @@
display: flex;
align-items: center;
min-height: subtract(100%, $modal-dialog-margin * 2);
-
- // Ensure `modal-dialog-centered` extends the full height of the view (IE10/11)
- &::before {
- display: block; // IE10
- height: subtract(100vh, $modal-dialog-margin * 2);
- height: min-content; // Reset height to 0 except on IE
- content: "";
- }
-
- // Ensure `.modal-body` shows scrollbar (IE10/11)
- &.modal-dialog-scrollable {
- flex-direction: column;
- justify-content: center;
- height: 100%;
-
- .modal-content {
- max-height: none;
- }
-
- &::before {
- content: none;
- }
- }
}
// Actual modal
@@ -206,19 +181,10 @@
.modal-dialog-scrollable {
max-height: subtract(100%, $modal-dialog-margin-y-sm-up * 2);
-
- .modal-content {
- max-height: subtract(100vh, $modal-dialog-margin-y-sm-up * 2);
- }
}
.modal-dialog-centered {
min-height: subtract(100%, $modal-dialog-margin-y-sm-up * 2);
-
- &::before {
- height: subtract(100vh, $modal-dialog-margin-y-sm-up * 2);
- height: min-content;
- }
}
.modal-content {
diff --git a/scss/_navbar.scss b/scss/_navbar.scss
index d46a815d6..c21d9fd73 100644
--- a/scss/_navbar.scss
+++ b/scss/_navbar.scss
@@ -107,10 +107,10 @@
// the default flexbox row orientation. Requires the use of `flex-wrap: wrap`
// on the `.navbar` parent.
.navbar-collapse {
- flex: 1 0 100%;
// For always expanded or extra full navbars, ensure content aligns itself
// properly vertically. Can be easily overridden with flex utilities.
align-items: center;
+ width: 100%;
}
// Button for toggling the navbar when in its collapsed state
@@ -173,9 +173,6 @@
.navbar-collapse {
display: flex !important; // stylelint-disable-line declaration-no-important
-
- // Changes flex-bases to auto because of an IE10 bug
- flex-basis: auto;
}
.navbar-toggler {
diff --git a/scss/_reboot.scss b/scss/_reboot.scss
index 9f63ab68a..b5fc6f101 100644
--- a/scss/_reboot.scss
+++ b/scss/_reboot.scss
@@ -34,7 +34,7 @@
//
// 1. Remove the margin in all browsers.
// 2. As a best practice, apply a default `background-color`.
-// 3. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS.
+// 3. Prevent adjustments of font size after orientation changes in iOS.
// 4. Change the default tap highlight to be completely transparent in iOS.
body {
@@ -145,7 +145,7 @@ p {
// Abbreviations
//
// 1. Duplicate behavior to the data-* attribute for our tooltip plugin
-// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
+// 2. Add the correct text decoration in Chrome, Edge, Opera, and Safari.
// 3. Add explicit cursor to indicate changed behavior.
// 4. Prevent the text-decoration to be skipped.
@@ -344,15 +344,8 @@ figure {
// Images and content
-img {
- vertical-align: middle;
-}
-
-// 1. Workaround for the SVG overflow bug in IE 11 is still required.
-// See https://github.com/twbs/bootstrap/issues/26878
-
+img,
svg {
- overflow: hidden; // 1
vertical-align: middle;
}
@@ -399,7 +392,7 @@ button {
border-radius: 0;
}
-// Work around a Firefox/IE bug where the transparent `button` background
+// Work around a Firefox bug where the transparent `button` background
// results in a loss of the default `button` focus styles.
// Credit https://github.com/suitcss/base/
@@ -487,12 +480,10 @@ input[type="month"] {
-webkit-appearance: textfield;
}
-// 1. Remove the default vertical scrollbar in IE.
-// 2. Textareas should really only resize vertically so they don't break their (horizontal) containers.
+// 1. Textareas should really only resize vertically so they don't break their (horizontal) containers.
textarea {
- overflow: auto; // 1
- resize: vertical; // 2
+ resize: vertical; // 1
}
// 1. Browsers set a default `min-width: min-content;` on fieldsets,
@@ -510,8 +501,7 @@ fieldset {
}
// 1. By using `float: left`, the legend will behave like a block element
-// 2. Correct the color inheritance from `fieldset` elements in IE.
-// 3. Correct the text wrapping in Edge and IE.
+// 2. Correct the text wrapping in Edge.
legend {
float: left; // 1
@@ -521,8 +511,7 @@ legend {
@include font-size($legend-font-size);
font-weight: $legend-font-weight;
line-height: inherit;
- color: inherit; // 2
- white-space: normal; // 3
+ white-space: normal; // 2
}
// Fix height of inputs with a type of datetime-local, date, month, week, or time
@@ -590,22 +579,6 @@ summary {
}
-// Template
-//
-// Add the correct display for template & main in IE 11
-
-template {
- display: none;
-}
-
-
-// Main
-
-main {
- display: block;
-}
-
-
// Progress
//
// Add the correct vertical alignment in Chrome, Firefox, and Opera.
diff --git a/scss/_variables.scss b/scss/_variables.scss
index 39b9f5d22..7818a09d8 100644
--- a/scss/_variables.scss
+++ b/scss/_variables.scss
@@ -720,7 +720,7 @@ $form-range-thumb-border: 0 !default;
$form-range-thumb-border-radius: 1rem !default;
$form-range-thumb-box-shadow: 0 .1rem .25rem rgba($black, .1) !default;
$form-range-thumb-focus-box-shadow: 0 0 0 1px $body-bg, $input-focus-box-shadow !default;
-$form-range-thumb-focus-box-shadow-width: $input-focus-width !default; // For focus box shadow issue in IE/Edge
+$form-range-thumb-focus-box-shadow-width: $input-focus-width !default; // For focus box shadow issue in Edge
$form-range-thumb-active-bg: lighten($component-active-bg, 35%) !default;
$form-range-thumb-disabled-bg: $gray-500 !default;
$form-range-thumb-transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;
diff --git a/scss/forms/_form-control.scss b/scss/forms/_form-control.scss
index 5d1c1b692..fb3142333 100644
--- a/scss/forms/_form-control.scss
+++ b/scss/forms/_form-control.scss
@@ -22,12 +22,6 @@
@include box-shadow($input-box-shadow);
@include transition($input-transition);
- // Unstyle the caret on `<select>`s in IE10+.
- &::-ms-expand {
- background-color: transparent;
- border: 0;
- }
-
// Customize the `:focus` state to imitate native WebKit styles.
&:focus {
color: $input-focus-color;
diff --git a/scss/forms/_form-file.scss b/scss/forms/_form-file.scss
index 500591cab..8e9c6c443 100644
--- a/scss/forms/_form-file.scss
+++ b/scss/forms/_form-file.scss
@@ -11,13 +11,6 @@
margin: 0;
opacity: 0;
- // Separate rules for :focus and :focus-within as IE doesn't support the latter, and
- // thus ignores the entire ruleset. See https://github.com/twbs/bootstrap/pull/29036.
- &:focus ~ .form-file-label {
- border-color: $form-file-focus-border-color;
- box-shadow: $form-file-focus-box-shadow;
- }
-
&:focus-within ~ .form-file-label {
border-color: $form-file-focus-border-color;
box-shadow: $form-file-focus-box-shadow;
diff --git a/scss/forms/_form-select.scss b/scss/forms/_form-select.scss
index fa3206881..8c410c97b 100644
--- a/scss/forms/_form-select.scss
+++ b/scss/forms/_form-select.scss
@@ -37,7 +37,7 @@
// For visual consistency with other platforms/browsers,
// suppress the default white text on blue background highlight given to
// the selected option text when the (still closed) <select> receives focus
- // in IE and (under certain conditions) Edge.
+ // in Edge.
// See https://github.com/twbs/bootstrap/issues/19398.
color: $input-color;
background-color: $input-bg;
@@ -57,11 +57,6 @@
border-color: $form-select-disabled-border-color;
}
- // Hides the default caret in IE11
- &::-ms-expand {
- display: none;
- }
-
// Remove outline from select box in FF
&:-moz-focusring {
color: transparent;
diff --git a/site/content/docs/4.3/components/card.md b/site/content/docs/4.3/components/card.md
index 5fd1fce45..4bb116f0f 100644
--- a/site/content/docs/4.3/components/card.md
+++ b/site/content/docs/4.3/components/card.md
@@ -463,7 +463,7 @@ In addition to styling the content within cards, Bootstrap includes a few option
### Card groups
-Use card groups to render cards as a single, attached element with equal width and height columns. Card groups use `display: flex;` to achieve their uniform sizing.
+Use card groups to render cards as a single, attached element with equal width and height columns. Card groups start off stacked and use `display: flex;` to become attached with uniform dimensions starting at the `sm` breakpoint.
{{< example >}}
<div class="card-group">
diff --git a/site/content/docs/4.3/content/tables.md b/site/content/docs/4.3/content/tables.md
index 12aac11c9..d5dc98347 100644
--- a/site/content/docs/4.3/content/tables.md
+++ b/site/content/docs/4.3/content/tables.md
@@ -459,15 +459,15 @@ Use contextual classes to color table rows or individual cells.
<td>Cell</td>
<td>Cell</td>
</tr>
-{{< table.inline >}}
- {{- range (index $.Site.Data "theme-colors") }}
- <tr class="table-{{ .name }}">
- <th scope="row">{{ .name | title }}</th>
- <td>Cell</td>
- <td>Cell</td>
- </tr>
- {{- end -}}
-{{< /table.inline >}}
+ {{< table.inline >}}
+ {{- range (index $.Site.Data "theme-colors") }}
+ <tr class="table-{{ .name }}">
+ <th scope="row">{{ .name | title }}</th>
+ <td>Cell</td>
+ <td>Cell</td>
+ </tr>
+ {{- end -}}
+ {{< /table.inline >}}
</tbody>
</table>
</div>
diff --git a/site/content/docs/4.3/examples/album/index.html b/site/content/docs/4.3/examples/album/index.html
index 05e80a032..5219acbba 100644
--- a/site/content/docs/4.3/examples/album/index.html
+++ b/site/content/docs/4.3/examples/album/index.html
@@ -35,7 +35,7 @@ title: Album example
</div>
</header>
-<main role="main">
+<main>
<section class="py-5 text-center container">
<div class="row py-lg-5">
diff --git a/site/content/docs/4.3/examples/blog/index.html b/site/content/docs/4.3/examples/blog/index.html
index 4baee1942..be7801350 100644
--- a/site/content/docs/4.3/examples/blog/index.html
+++ b/site/content/docs/4.3/examples/blog/index.html
@@ -82,7 +82,7 @@ include_js: false
</div>
</div>
-<main role="main" class="container">
+<main class="container">
<div class="row">
<div class="col-md-8 blog-main">
<h3 class="pb-4 mb-4 font-italic border-bottom">
diff --git a/site/content/docs/4.3/examples/carousel/index.html b/site/content/docs/4.3/examples/carousel/index.html
index 2e824c4e0..e5b9f4649 100644
--- a/site/content/docs/4.3/examples/carousel/index.html
+++ b/site/content/docs/4.3/examples/carousel/index.html
@@ -33,7 +33,7 @@ extra_css:
</nav>
</header>
-<main role="main">
+<main>
<div id="myCarousel" class="carousel slide" data-ride="carousel">
<ol class="carousel-indicators">
diff --git a/site/content/docs/4.3/examples/cover/index.html b/site/content/docs/4.3/examples/cover/index.html
index cce84690b..ea5b0b13a 100644
--- a/site/content/docs/4.3/examples/cover/index.html
+++ b/site/content/docs/4.3/examples/cover/index.html
@@ -20,7 +20,7 @@ include_js: false
</div>
</header>
- <main role="main" class="px-3">
+ <main class="px-3">
<h1>Cover your page.</h1>
<p class="lead">Cover is a one-page template for building simple and beautiful home pages. Download, edit the text, and add your own fullscreen background photo to make it your own.</p>
<p class="lead">
diff --git a/site/content/docs/4.3/examples/dashboard/dashboard.css b/site/content/docs/4.3/examples/dashboard/dashboard.css
index ef196319a..7e3ac226d 100644
--- a/site/content/docs/4.3/examples/dashboard/dashboard.css
+++ b/site/content/docs/4.3/examples/dashboard/dashboard.css
@@ -37,13 +37,6 @@ body {
overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */
}
-@supports ((position: -webkit-sticky) or (position: sticky)) {
- .sidebar-sticky {
- position: -webkit-sticky;
- position: sticky;
- }
-}
-
.sidebar .nav-link {
font-weight: 500;
color: #333;
diff --git a/site/content/docs/4.3/examples/dashboard/index.html b/site/content/docs/4.3/examples/dashboard/index.html
index a21af0186..adfb5a9a9 100644
--- a/site/content/docs/4.3/examples/dashboard/index.html
+++ b/site/content/docs/4.3/examples/dashboard/index.html
@@ -27,7 +27,7 @@ extra_js:
<div class="container-fluid">
<div class="row">
<nav id="sidebarMenu" class="col-md-2 d-md-block bg-light sidebar collapse">
- <div class="sidebar-sticky">
+ <div class="position-sticky">
<ul class="nav flex-column">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">
@@ -102,7 +102,7 @@ extra_js:
</div>
</nav>
- <main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-md-4">
+ <main class="col-md-9 ml-sm-auto col-lg-10 px-md-4">
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2">Dashboard</h1>
<div class="btn-toolbar mb-2 mb-md-0">
diff --git a/site/content/docs/4.3/examples/floating-labels/floating-labels.css b/site/content/docs/4.3/examples/floating-labels/floating-labels.css
index d6398b257..b9c5d7cdc 100644
--- a/site/content/docs/4.3/examples/floating-labels/floating-labels.css
+++ b/site/content/docs/4.3/examples/floating-labels/floating-labels.css
@@ -86,14 +86,3 @@ body {
color: #777;
}
}
-
-/* Fallback for IE
--------------------------------------------------- */
-@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
- .form-label-group > label {
- display: none;
- }
- .form-label-group input:-ms-input-placeholder {
- color: #777;
- }
-}
diff --git a/site/content/docs/4.3/examples/navbar-fixed/index.html b/site/content/docs/4.3/examples/navbar-fixed/index.html
index 382235645..d6404f293 100644
--- a/site/content/docs/4.3/examples/navbar-fixed/index.html
+++ b/site/content/docs/4.3/examples/navbar-fixed/index.html
@@ -31,7 +31,7 @@ extra_css:
</div>
</nav>
-<main role="main" class="container">
+<main class="container">
<div class="bg-light p-5 rounded">
<h1>Navbar example</h1>
<p class="lead">This example is a quick exercise to illustrate how fixed to top navbar works. As you scroll, it will remain fixed to the top of your browser’s viewport.</p>
diff --git a/site/content/docs/4.3/examples/navbar-static/index.html b/site/content/docs/4.3/examples/navbar-static/index.html
index 4043587f7..0b6c4d273 100644
--- a/site/content/docs/4.3/examples/navbar-static/index.html
+++ b/site/content/docs/4.3/examples/navbar-static/index.html
@@ -31,7 +31,7 @@ extra_css:
</div>
</nav>
-<main role="main" class="container">
+<main class="container">
<div class="bg-light p-5 rounded">
<h1>Navbar example</h1>
<p class="lead">This example is a quick exercise to illustrate how the top-aligned navbar works. As you scroll, this navbar remains in its original position and moves with the rest of the page.</p>
diff --git a/site/content/docs/4.3/examples/navbars/index.html b/site/content/docs/4.3/examples/navbars/index.html
index ad2649cc3..47c23aa79 100644
--- a/site/content/docs/4.3/examples/navbars/index.html
+++ b/site/content/docs/4.3/examples/navbars/index.html
@@ -365,7 +365,7 @@ extra_css:
</div>
</nav>
- <main role="main">
+ <main>
<div class="bg-light p-5 rounded">
<div class="col-sm-8 mx-auto">
<h1>Navbar examples</h1>
diff --git a/site/content/docs/4.3/examples/offcanvas/index.html b/site/content/docs/4.3/examples/offcanvas/index.html
index bb26ffc58..4a8501e3a 100644
--- a/site/content/docs/4.3/examples/offcanvas/index.html
+++ b/site/content/docs/4.3/examples/offcanvas/index.html
@@ -63,7 +63,7 @@ body_class: "bg-light"
</nav>
</div>
-<main role="main" class="container">
+<main class="container">
<div class="d-flex align-items-center p-3 my-3 text-white-50 bg-purple rounded shadow-sm">
<img class="mr-3" src="/docs/{{< param docs_version >}}/assets/brand/bootstrap-outline.svg" alt="" width="48" height="48">
<div class="lh-1">
diff --git a/site/content/docs/4.3/examples/starter-template/index.html b/site/content/docs/4.3/examples/starter-template/index.html
index 91701691f..0a6ea6291 100644
--- a/site/content/docs/4.3/examples/starter-template/index.html
+++ b/site/content/docs/4.3/examples/starter-template/index.html
@@ -40,7 +40,7 @@ extra_css:
</div>
</nav>
-<main role="main" class="container">
+<main class="container">
<div class="starter-template text-center py-5 px-3">
<h1>Bootstrap starter template</h1>
diff --git a/site/content/docs/4.3/examples/sticky-footer-navbar/index.html b/site/content/docs/4.3/examples/sticky-footer-navbar/index.html
index 6620c6941..4203772d7 100644
--- a/site/content/docs/4.3/examples/sticky-footer-navbar/index.html
+++ b/site/content/docs/4.3/examples/sticky-footer-navbar/index.html
@@ -37,7 +37,7 @@ body_class: "d-flex flex-column h-100"
</header>
<!-- Begin page content -->
-<main role="main" class="flex-shrink-0">
+<main class="flex-shrink-0">
<div class="container">
<h1 class="mt-5">Sticky footer with fixed navbar</h1>
<p class="lead">Pin a footer to the bottom of the viewport in desktop browsers with this custom HTML and CSS. A fixed navbar has been added with <code class="small">padding-top: 60px;</code> on the <code class="small">main &gt; .container</code>.</p>
diff --git a/site/content/docs/4.3/examples/sticky-footer/index.html b/site/content/docs/4.3/examples/sticky-footer/index.html
index 3e52a62e3..7a6e127cd 100644
--- a/site/content/docs/4.3/examples/sticky-footer/index.html
+++ b/site/content/docs/4.3/examples/sticky-footer/index.html
@@ -9,7 +9,7 @@ include_js: false
---
<!-- Begin page content -->
-<main role="main" class="flex-shrink-0">
+<main class="flex-shrink-0">
<div class="container">
<h1 class="mt-5">Sticky footer</h1>
<p class="lead">Pin a footer to the bottom of the viewport in desktop browsers with this custom HTML and CSS.</p>
diff --git a/site/content/docs/4.3/forms/form-control.md b/site/content/docs/4.3/forms/form-control.md
index 30b569edf..060af37ff 100644
--- a/site/content/docs/4.3/forms/form-control.md
+++ b/site/content/docs/4.3/forms/form-control.md
@@ -78,8 +78,6 @@ If you want to have `<input readonly>` elements in your form styled as plain tex
## Color
-Keep in mind color inputs are [not supported in IE](https://caniuse.com/#feat=input-color).
-
{{< example >}}
<form>
<label for="exampleColorInput">Color picker</label>
diff --git a/site/content/docs/4.3/getting-started/browsers-devices.md b/site/content/docs/4.3/getting-started/browsers-devices.md
index 0b84930cb..97011fdd4 100644
--- a/site/content/docs/4.3/getting-started/browsers-devices.md
+++ b/site/content/docs/4.3/getting-started/browsers-devices.md
@@ -8,7 +8,7 @@ toc: true
## Supported browsers
-Bootstrap supports the **latest, stable releases** of all major browsers and platforms. On Windows, **we support Internet Explorer 11 / Microsoft Edge**.
+Bootstrap supports the **latest, stable releases** of all major browsers and platforms. This also includes the latest version of Legacy Edge (EdgeHTML layout engine).
Alternative browsers which use the latest version of WebKit, Blink, or Gecko, whether directly or via the platform's web view API, are not explicitly supported. However, Bootstrap should (in most cases) display and function correctly in these browsers as well. More specific support information is provided below.
@@ -64,7 +64,6 @@ Similarly, the latest versions of most desktop browsers are supported.
<th></th>
<th>Chrome</th>
<th>Firefox</th>
- <th>Internet Explorer</th>
<th>Microsoft Edge</th>
<th>Opera</th>
<th>Safari</th>
@@ -75,7 +74,6 @@ Similarly, the latest versions of most desktop browsers are supported.
<th scope="row">Mac</th>
<td>Supported</td>
<td>Supported</td>
- <td class="text-muted">&mdash;</td>
<td>Supported</td>
<td>Supported</td>
<td>Supported</td>
@@ -84,7 +82,6 @@ Similarly, the latest versions of most desktop browsers are supported.
<th scope="row">Windows</th>
<td>Supported</td>
<td>Supported</td>
- <td>IE11 only</td>
<td>Supported</td>
<td>Supported</td>
<td class="text-muted">&mdash;</td>
@@ -94,11 +91,11 @@ Similarly, the latest versions of most desktop browsers are supported.
For Firefox, in addition to the latest normal stable release, we also support the latest [Extended Support Release (ESR)](https://www.mozilla.org/en-US/firefox/organizations/#faq) version of Firefox.
-Unofficially, Bootstrap should look and behave well enough in Chromium and Chrome for Linux, Firefox for Linux, and Internet Explorer 9, though they are not officially supported.
+Unofficially, Bootstrap should look and behave well enough in Chromium and Chrome for Linux, and Firefox for Linux, though they are not officially supported.
## Internet Explorer
-Internet Explorer 11 is supported; IE10 and down is not. Please be aware that some CSS3 properties and HTML5 elements are not fully supported in Internet Explorer, or require prefixed properties for full functionality. Visit [Can I use...](https://caniuse.com/) for details on browser support of CSS3 and HTML5 features. **If you require IE10 support, use Bootstrap 4.**
+Internet Explorer is not supported. **If you require Internet Explorer support, please use Bootstrap v4.**
## Modals and dropdowns on mobile
diff --git a/site/content/docs/4.3/getting-started/theming.md b/site/content/docs/4.3/getting-started/theming.md
index ad028b792..dcaa593f1 100644
--- a/site/content/docs/4.3/getting-started/theming.md
+++ b/site/content/docs/4.3/getting-started/theming.md
@@ -221,7 +221,7 @@ You can also specify a base color with our color map functions:
#### Escape SVG
-We use the `escape-svg` function to escape the `<`, `>` and `#` characters for SVG background images. These characters need to be escaped to properly render the background images in IE.
+We use the `escape-svg` function to escape the `<`, `>` and `#` characters for SVG background images.
#### Add and Subtract functions
diff --git a/site/content/docs/4.3/helpers/position.md b/site/content/docs/4.3/helpers/position.md
index c44002ae9..ef7ab0dfc 100644
--- a/site/content/docs/4.3/helpers/position.md
+++ b/site/content/docs/4.3/helpers/position.md
@@ -26,8 +26,6 @@ Position an element at the bottom of the viewport, from edge to edge. Be sure yo
Position an element at the top of the viewport, from edge to edge, but only after you scroll past it. The `.sticky-top` utility uses CSS's `position: sticky`, which isn't fully supported in all browsers.
-**IE11 and IE10 will render `position: sticky` as `position: relative`.** As such, we wrap the styles in a `@supports` query, limiting the stickiness to only browsers that can render it properly.
-
{{< highlight html >}}
<div class="sticky-top">...</div>
{{< /highlight >}}
diff --git a/site/content/docs/4.3/layout/grid.md b/site/content/docs/4.3/layout/grid.md
index 82ee25f1f..cba764b3e 100644
--- a/site/content/docs/4.3/layout/grid.md
+++ b/site/content/docs/4.3/layout/grid.md
@@ -520,7 +520,7 @@ In practice, here's how it looks. Note you can continue to use this with all oth
## Alignment
-Use flexbox alignment utilities to vertically and horizontally align columns. **Internet Explorer 10-11 do not support vertical alignment of flex items when the flex container has a `min-height` as shown below.** [See Flexbugs #3 for more details.](https://github.com/philipwalton/flexbugs#flexbug-3)
+Use flexbox alignment utilities to vertically and horizontally align columns.
### Vertical alignment
diff --git a/site/content/docs/4.3/migration.md b/site/content/docs/4.3/migration.md
index 91d4bf20c..7c0541c00 100644
--- a/site/content/docs/4.3/migration.md
+++ b/site/content/docs/4.3/migration.md
@@ -11,7 +11,7 @@ toc: true
See the browser and devices page for details on what is currently supported in Bootstrap 5. Since v4, here's what's changed to our browser support:
-- Dropped support for Internet Explorer NN
+- Dropped support for Internet Explorer 10 and 11
- Dropped support for Firefox NN - MM
- Dropped support for Safari NN
- Dropped support for iOS Safari NN
diff --git a/site/content/docs/4.3/utilities/flex.md b/site/content/docs/4.3/utilities/flex.md
index 9ce4f27c5..58043a47a 100644
--- a/site/content/docs/4.3/utilities/flex.md
+++ b/site/content/docs/4.3/utilities/flex.md
@@ -296,8 +296,6 @@ Responsive variations also exist for `flex-grow` and `flex-shrink`.
Flexbox can do some pretty awesome things when you mix flex alignments with auto margins. Shown below are three examples of controlling flex items via auto margins: default (no auto margin), pushing two items to the right (`.mr-auto`), and pushing two items to the left (`.ml-auto`).
-**Unfortunately, IE10 and IE11 do not properly support auto margins on flex items whose parent has a non-default `justify-content` value.** [See this StackOverflow answer](https://stackoverflow.com/a/37535548) for more details.
-
{{< example >}}
<div class="d-flex bd-highlight mb-3">
<div class="p-2 bd-highlight">Flex item</div>
diff --git a/site/layouts/_default/404.html b/site/layouts/_default/404.html
index fc0890087..744865cd4 100644
--- a/site/layouts/_default/404.html
+++ b/site/layouts/_default/404.html
@@ -8,7 +8,7 @@
{{ partial "docs-navbar" . }}
- <main class="my-auto p-5" id="content" role="main">
+ <main class="my-auto p-5" id="content">
{{ .Content }}
</main>
diff --git a/site/layouts/_default/docs.html b/site/layouts/_default/docs.html
index c47c0af7f..b1efb6b13 100644
--- a/site/layouts/_default/docs.html
+++ b/site/layouts/_default/docs.html
@@ -15,7 +15,7 @@
{{ partial "docs-sidebar" . }}
</div>
- <main class="col-md-9 py-md-3 pl-md-5 bd-content" role="main">
+ <main class="col-md-9 py-md-3 pl-md-5 bd-content">
<h1 class="bd-title" id="content">{{ .Title | markdownify }}</h1>
<p class="bd-lead">{{ .Page.Params.Description | markdownify }}</p>
{{ partial "ads" . }}
diff --git a/site/layouts/_default/single.html b/site/layouts/_default/single.html
index 09631ac19..02972c3dd 100644
--- a/site/layouts/_default/single.html
+++ b/site/layouts/_default/single.html
@@ -19,7 +19,7 @@
</div>
</header>
- <main class="bd-content py-5" id="content" role="main">
+ <main class="bd-content py-5" id="content">
<div class="container">
{{ .Content }}
</div>
diff --git a/site/layouts/partials/callout-warning-input-support.md b/site/layouts/partials/callout-warning-input-support.md
index 7c76995ed..b6e140e9c 100644
--- a/site/layouts/partials/callout-warning-input-support.md
+++ b/site/layouts/partials/callout-warning-input-support.md
@@ -1,3 +1,3 @@
##### Date & color input support
-Keep in mind date inputs are [not fully supported](https://caniuse.com/#feat=input-datetime) by IE and Safari. Color inputs also [lack support](https://caniuse.com/#feat=input-color) on IE.
+Keep in mind date inputs are [not fully supported](https://caniuse.com/#feat=input-datetime) by all browsers, namely Safari.
diff --git a/site/layouts/partials/docs-navbar.html b/site/layouts/partials/docs-navbar.html
index 3b07cba9d..20b86ab12 100644
--- a/site/layouts/partials/docs-navbar.html
+++ b/site/layouts/partials/docs-navbar.html
@@ -16,7 +16,7 @@
<a class="nav-link{{ if eq .Page.Title "Examples" }} active" aria-current="true{{ end }}" href="/docs/{{ .Site.Params.docs_version }}/examples/" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Examples');">Examples</a>
</li>
<li class="nav-item">
- <a class="nav-link" href="{{ .Site.Params.icons }}" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Icons');">Icons</a>
+ <a class="nav-link" href="{{ .Site.Params.icons }}" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Icons');" target="_blank" rel="noopener">Icons</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ .Site.Params.themes }}" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Themes');" target="_blank" rel="noopener">Themes</a>
diff --git a/site/layouts/partials/home/masthead.html b/site/layouts/partials/home/masthead.html
index 0cc05723f..42897a720 100644
--- a/site/layouts/partials/home/masthead.html
+++ b/site/layouts/partials/home/masthead.html
@@ -1,4 +1,4 @@
-<main class="bd-masthead mb-3 mb-md-5 border-bottom" id="content" role="main">
+<main class="bd-masthead mb-3 mb-md-5 border-bottom" id="content">
<div class="container">
<div class="row">
<div class="col-6 mx-auto col-md-4 order-md-2 col-lg-5">