mirror of
https://github.com/twbs/bootstrap.git
synced 2024-12-01 13:24:25 +01:00
Merge branch 'master' into underline-links
This commit is contained in:
commit
4a37677dda
@ -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
|
||||
|
4
.github/ISSUE_TEMPLATE/bug.md
vendored
4
.github/ISSUE_TEMPLATE/bug.md
vendored
@ -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/)
|
||||
|
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -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/)
|
||||
|
@ -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 = [
|
||||
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -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 DIRECTION_NEXT = 'next'
|
||||
const DIRECTION_PREV = 'prev'
|
||||
const DIRECTION_LEFT = 'left'
|
||||
const DIRECTION_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 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 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 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',
|
||||
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 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))
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
})
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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 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 ClassName = {
|
||||
DISABLED: 'disabled',
|
||||
SHOW: 'show',
|
||||
DROPUP: 'dropup',
|
||||
DROPRIGHT: 'dropright',
|
||||
DROPLEFT: 'dropleft',
|
||||
MENURIGHT: 'dropdown-menu-right',
|
||||
NAVBAR: 'navbar',
|
||||
POSITION_STATIC: 'position-static'
|
||||
}
|
||||
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"]',
|
||||
FORM_CHILD: '.dropdown form',
|
||||
MENU: '.dropdown-menu',
|
||||
NAVBAR_NAV: '.navbar-nav',
|
||||
VISIBLE_ITEMS: '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'
|
||||
}
|
||||
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 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 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()
|
||||
|
||||
|
152
js/src/modal.js
152
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 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 ClassName = {
|
||||
SCROLLABLE: 'modal-dialog-scrollable',
|
||||
SCROLLBAR_MEASURER: 'modal-scrollbar-measure',
|
||||
BACKDROP: 'modal-backdrop',
|
||||
OPEN: 'modal-open',
|
||||
FADE: 'fade',
|
||||
SHOW: 'show',
|
||||
STATIC: 'modal-static'
|
||||
}
|
||||
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',
|
||||
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 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()
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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)))
|
||||
})
|
||||
|
||||
|
@ -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 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 ClassName = {
|
||||
DROPDOWN_MENU: 'dropdown-menu',
|
||||
ACTIVE: 'active',
|
||||
DISABLED: 'disabled',
|
||||
FADE: 'fade',
|
||||
SHOW: 'show'
|
||||
}
|
||||
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',
|
||||
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 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)
|
||||
|
@ -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()
|
||||
)
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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',
|
||||
|
@ -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)
|
||||
|
@ -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', () => {
|
||||
|
242
package-lock.json
generated
242
package-lock.json
generated
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
10
package.json
10
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": [
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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">
|
||||
|
@ -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>
|
||||
|
@ -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">
|
||||
|
@ -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">
|
||||
|
@ -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">
|
||||
|
@ -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">
|
||||
|
@ -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;
|
||||
|
@ -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">
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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">
|
||||
|
@ -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>
|
||||
|
@ -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 > .container</code>.</p>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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">—</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">—</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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 >}}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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" . }}
|
||||
|
@ -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>
|
||||
|
@ -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.
|
||||
|
@ -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>
|
||||
|
@ -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">
|
||||
|
Loading…
Reference in New Issue
Block a user