Switch to strings constants.
This allows the minifier to mangle the constants. It also allows the linter to find unused strings properly. While at it, remove a few unused properties. File Before After Diff -------------------------------------------------------- bootstrap.bundle.min.js 23.61 kB 22.61 kB -1.00 kB (-4.23 %) bootstrap.min.js 17.04 kB 16.08 kB -0.96 kB (-5.63 %)
This commit is contained in:
parent
cece839fc9
commit
38333feda5
|
@ -28,21 +28,15 @@ const DATA_KEY = 'bs.alert'
|
||||||
const EVENT_KEY = `.${DATA_KEY}`
|
const EVENT_KEY = `.${DATA_KEY}`
|
||||||
const DATA_API_KEY = '.data-api'
|
const DATA_API_KEY = '.data-api'
|
||||||
|
|
||||||
const Selector = {
|
const SELECTOR_DISMISS = '[data-dismiss="alert"]'
|
||||||
DISMISS: '[data-dismiss="alert"]'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Event = {
|
const EVENT_CLOSE = `close${EVENT_KEY}`
|
||||||
CLOSE: `close${EVENT_KEY}`,
|
const EVENT_CLOSED = `closed${EVENT_KEY}`
|
||||||
CLOSED: `closed${EVENT_KEY}`,
|
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
|
||||||
CLICK_DATA_API: `click${EVENT_KEY}${DATA_API_KEY}`
|
|
||||||
}
|
|
||||||
|
|
||||||
const ClassName = {
|
const CLASSNAME_ALERT = 'alert'
|
||||||
ALERT: 'alert',
|
const CLASSNAME_FADE = 'fade'
|
||||||
FADE: 'fade',
|
const CLASSNAME_SHOW = 'show'
|
||||||
SHOW: 'show'
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ------------------------------------------------------------------------
|
* ------------------------------------------------------------------------
|
||||||
|
@ -93,20 +87,20 @@ class Alert {
|
||||||
let parent = getElementFromSelector(element)
|
let parent = getElementFromSelector(element)
|
||||||
|
|
||||||
if (!parent) {
|
if (!parent) {
|
||||||
parent = SelectorEngine.closest(element, `.${ClassName.ALERT}`)
|
parent = SelectorEngine.closest(element, `.${CLASSNAME_ALERT}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent
|
return parent
|
||||||
}
|
}
|
||||||
|
|
||||||
_triggerCloseEvent(element) {
|
_triggerCloseEvent(element) {
|
||||||
return EventHandler.trigger(element, Event.CLOSE)
|
return EventHandler.trigger(element, EVENT_CLOSE)
|
||||||
}
|
}
|
||||||
|
|
||||||
_removeElement(element) {
|
_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)
|
this._destroyElement(element)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -123,7 +117,7 @@ class Alert {
|
||||||
element.parentNode.removeChild(element)
|
element.parentNode.removeChild(element)
|
||||||
}
|
}
|
||||||
|
|
||||||
EventHandler.trigger(element, Event.CLOSED)
|
EventHandler.trigger(element, EVENT_CLOSED)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Static
|
// Static
|
||||||
|
@ -163,7 +157,7 @@ class Alert {
|
||||||
* ------------------------------------------------------------------------
|
* ------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
EventHandler
|
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()
|
const $ = getjQuery()
|
||||||
|
|
||||||
|
|
|
@ -22,26 +22,20 @@ const DATA_KEY = 'bs.button'
|
||||||
const EVENT_KEY = `.${DATA_KEY}`
|
const EVENT_KEY = `.${DATA_KEY}`
|
||||||
const DATA_API_KEY = '.data-api'
|
const DATA_API_KEY = '.data-api'
|
||||||
|
|
||||||
const ClassName = {
|
const CLASS_NAME_ACTIVE = 'active'
|
||||||
ACTIVE: 'active',
|
const CLASS_NAME_BUTTON = 'btn'
|
||||||
BUTTON: 'btn',
|
const CLASS_NAME_DISABLED = 'disabled'
|
||||||
DISABLED: 'disabled',
|
const CLASS_NAME_FOCUS = 'focus'
|
||||||
FOCUS: 'focus'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Selector = {
|
const SELECTOR_DATA_TOGGLE_CARROT = '[data-toggle^="button"]'
|
||||||
DATA_TOGGLE_CARROT: '[data-toggle^="button"]',
|
const SELECTOR_DATA_TOGGLE = '[data-toggle="buttons"]'
|
||||||
DATA_TOGGLE: '[data-toggle="buttons"]',
|
const SELECTOR_INPUT = 'input:not([type="hidden"])'
|
||||||
INPUT: 'input:not([type="hidden"])',
|
const SELECTOR_ACTIVE = '.active'
|
||||||
ACTIVE: '.active',
|
const SELECTOR_BUTTON = '.btn'
|
||||||
BUTTON: '.btn'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Event = {
|
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
|
||||||
CLICK_DATA_API: `click${EVENT_KEY}${DATA_API_KEY}`,
|
const EVENT_FOCUS_DATA_API = `focus${EVENT_KEY}${DATA_API_KEY}`
|
||||||
FOCUS_DATA_API: `focus${EVENT_KEY}${DATA_API_KEY}`,
|
const EVENT_BLUR_DATA_API = `blur${EVENT_KEY}${DATA_API_KEY}`
|
||||||
BLUR_DATA_API: `blur${EVENT_KEY}${DATA_API_KEY}`
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ------------------------------------------------------------------------
|
* ------------------------------------------------------------------------
|
||||||
|
@ -69,33 +63,33 @@ class Button {
|
||||||
|
|
||||||
const rootElement = SelectorEngine.closest(
|
const rootElement = SelectorEngine.closest(
|
||||||
this._element,
|
this._element,
|
||||||
Selector.DATA_TOGGLE
|
SELECTOR_DATA_TOGGLE
|
||||||
)
|
)
|
||||||
|
|
||||||
if (rootElement) {
|
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 && input.type === 'radio') {
|
||||||
if (input.checked &&
|
if (input.checked &&
|
||||||
this._element.classList.contains(ClassName.ACTIVE)) {
|
this._element.classList.contains(CLASS_NAME_ACTIVE)) {
|
||||||
triggerChangeEvent = false
|
triggerChangeEvent = false
|
||||||
} else {
|
} else {
|
||||||
const activeElement = SelectorEngine.findOne(Selector.ACTIVE, rootElement)
|
const activeElement = SelectorEngine.findOne(SELECTOR_ACTIVE, rootElement)
|
||||||
|
|
||||||
if (activeElement) {
|
if (activeElement) {
|
||||||
activeElement.classList.remove(ClassName.ACTIVE)
|
activeElement.classList.remove(CLASS_NAME_ACTIVE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (triggerChangeEvent) {
|
if (triggerChangeEvent) {
|
||||||
if (input.hasAttribute('disabled') ||
|
if (input.hasAttribute('disabled') ||
|
||||||
rootElement.hasAttribute('disabled') ||
|
rootElement.hasAttribute('disabled') ||
|
||||||
input.classList.contains(ClassName.DISABLED) ||
|
input.classList.contains(CLASS_NAME_DISABLED) ||
|
||||||
rootElement.classList.contains(ClassName.DISABLED)) {
|
rootElement.classList.contains(CLASS_NAME_DISABLED)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
input.checked = !this._element.classList.contains(ClassName.ACTIVE)
|
input.checked = !this._element.classList.contains(CLASS_NAME_ACTIVE)
|
||||||
EventHandler.trigger(input, 'change')
|
EventHandler.trigger(input, 'change')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,11 +100,11 @@ class Button {
|
||||||
|
|
||||||
if (addAriaPressed) {
|
if (addAriaPressed) {
|
||||||
this._element.setAttribute('aria-pressed',
|
this._element.setAttribute('aria-pressed',
|
||||||
!this._element.classList.contains(ClassName.ACTIVE))
|
!this._element.classList.contains(CLASS_NAME_ACTIVE))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (triggerChangeEvent) {
|
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()
|
event.preventDefault()
|
||||||
|
|
||||||
let button = event.target
|
let button = event.target
|
||||||
if (!button.classList.contains(ClassName.BUTTON)) {
|
if (!button.classList.contains(CLASS_NAME_BUTTON)) {
|
||||||
button = SelectorEngine.closest(button, Selector.BUTTON)
|
button = SelectorEngine.closest(button, SELECTOR_BUTTON)
|
||||||
}
|
}
|
||||||
|
|
||||||
let data = Data.getData(button, DATA_KEY)
|
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()
|
data.toggle()
|
||||||
})
|
})
|
||||||
|
|
||||||
EventHandler.on(document, Event.FOCUS_DATA_API, Selector.DATA_TOGGLE_CARROT, event => {
|
EventHandler.on(document, EVENT_FOCUS_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, event => {
|
||||||
const button = SelectorEngine.closest(event.target, Selector.BUTTON)
|
const button = SelectorEngine.closest(event.target, SELECTOR_BUTTON)
|
||||||
|
|
||||||
if (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 => {
|
EventHandler.on(document, EVENT_BLUR_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, event => {
|
||||||
const button = SelectorEngine.closest(event.target, Selector.BUTTON)
|
const button = SelectorEngine.closest(event.target, SELECTOR_BUTTON)
|
||||||
|
|
||||||
if (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 DATA_KEY = 'bs.carousel'
|
||||||
const EVENT_KEY = `.${DATA_KEY}`
|
const EVENT_KEY = `.${DATA_KEY}`
|
||||||
const DATA_API_KEY = '.data-api'
|
const DATA_API_KEY = '.data-api'
|
||||||
|
|
||||||
const ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key
|
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 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
|
const TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch
|
||||||
|
@ -56,51 +57,42 @@ const DefaultType = {
|
||||||
touch: 'boolean'
|
touch: 'boolean'
|
||||||
}
|
}
|
||||||
|
|
||||||
const Direction = {
|
const DIRECTION_NEXT = 'next'
|
||||||
NEXT: 'next',
|
const DIRECTION_PREV = 'prev'
|
||||||
PREV: 'prev',
|
const DIRECTION_LEFT = 'left'
|
||||||
LEFT: 'left',
|
const DIRECTION_RIGHT = 'right'
|
||||||
RIGHT: 'right'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Event = {
|
const EVENT_SLIDE = `slide${EVENT_KEY}`
|
||||||
SLIDE: `slide${EVENT_KEY}`,
|
const EVENT_SLID = `slid${EVENT_KEY}`
|
||||||
SLID: `slid${EVENT_KEY}`,
|
const EVENT_KEYDOWN = `keydown${EVENT_KEY}`
|
||||||
KEYDOWN: `keydown${EVENT_KEY}`,
|
const EVENT_MOUSEENTER = `mouseenter${EVENT_KEY}`
|
||||||
MOUSEENTER: `mouseenter${EVENT_KEY}`,
|
const EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY}`
|
||||||
MOUSELEAVE: `mouseleave${EVENT_KEY}`,
|
const EVENT_TOUCHSTART = `touchstart${EVENT_KEY}`
|
||||||
TOUCHSTART: `touchstart${EVENT_KEY}`,
|
const EVENT_TOUCHMOVE = `touchmove${EVENT_KEY}`
|
||||||
TOUCHMOVE: `touchmove${EVENT_KEY}`,
|
const EVENT_TOUCHEND = `touchend${EVENT_KEY}`
|
||||||
TOUCHEND: `touchend${EVENT_KEY}`,
|
const EVENT_POINTERDOWN = `pointerdown${EVENT_KEY}`
|
||||||
POINTERDOWN: `pointerdown${EVENT_KEY}`,
|
const EVENT_POINTERUP = `pointerup${EVENT_KEY}`
|
||||||
POINTERUP: `pointerup${EVENT_KEY}`,
|
const EVENT_DRAG_START = `dragstart${EVENT_KEY}`
|
||||||
DRAG_START: `dragstart${EVENT_KEY}`,
|
const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`
|
||||||
LOAD_DATA_API: `load${EVENT_KEY}${DATA_API_KEY}`,
|
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
|
||||||
CLICK_DATA_API: `click${EVENT_KEY}${DATA_API_KEY}`
|
|
||||||
}
|
|
||||||
|
|
||||||
const ClassName = {
|
const CLASS_NAME_CAROUSEL = 'carousel'
|
||||||
CAROUSEL: 'carousel',
|
const CLASS_NAME_ACTIVE = 'active'
|
||||||
ACTIVE: 'active',
|
const CLASS_NAME_SLIDE = 'slide'
|
||||||
SLIDE: 'slide',
|
const CLASS_NAME_RIGHT = 'carousel-item-right'
|
||||||
RIGHT: 'carousel-item-right',
|
const CLASS_NAME_LEFT = 'carousel-item-left'
|
||||||
LEFT: 'carousel-item-left',
|
const CLASS_NAME_NEXT = 'carousel-item-next'
|
||||||
NEXT: 'carousel-item-next',
|
const CLASS_NAME_PREV = 'carousel-item-prev'
|
||||||
PREV: 'carousel-item-prev',
|
const CLASS_NAME_POINTER_EVENT = 'pointer-event'
|
||||||
ITEM: 'carousel-item',
|
|
||||||
POINTER_EVENT: 'pointer-event'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Selector = {
|
const SELECTOR_ACTIVE = '.active'
|
||||||
ACTIVE: '.active',
|
const SELECTOR_ACTIVE_ITEM = '.active.carousel-item'
|
||||||
ACTIVE_ITEM: '.active.carousel-item',
|
const SELECTOR_ITEM = '.carousel-item'
|
||||||
ITEM: '.carousel-item',
|
const SELECTOR_ITEM_IMG = '.carousel-item img'
|
||||||
ITEM_IMG: '.carousel-item img',
|
const SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev'
|
||||||
NEXT_PREV: '.carousel-item-next, .carousel-item-prev',
|
const SELECTOR_INDICATORS = '.carousel-indicators'
|
||||||
INDICATORS: '.carousel-indicators',
|
const SELECTOR_DATA_SLIDE = '[data-slide], [data-slide-to]'
|
||||||
DATA_SLIDE: '[data-slide], [data-slide-to]',
|
const SELECTOR_DATA_RIDE = '[data-ride="carousel"]'
|
||||||
DATA_RIDE: '[data-ride="carousel"]'
|
|
||||||
}
|
|
||||||
|
|
||||||
const PointerType = {
|
const PointerType = {
|
||||||
TOUCH: 'touch',
|
TOUCH: 'touch',
|
||||||
|
@ -125,7 +117,7 @@ class Carousel {
|
||||||
|
|
||||||
this._config = this._getConfig(config)
|
this._config = this._getConfig(config)
|
||||||
this._element = element
|
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._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0
|
||||||
this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent)
|
this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent)
|
||||||
|
|
||||||
|
@ -147,7 +139,7 @@ class Carousel {
|
||||||
|
|
||||||
next() {
|
next() {
|
||||||
if (!this._isSliding) {
|
if (!this._isSliding) {
|
||||||
this._slide(Direction.NEXT)
|
this._slide(DIRECTION_NEXT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +153,7 @@ class Carousel {
|
||||||
|
|
||||||
prev() {
|
prev() {
|
||||||
if (!this._isSliding) {
|
if (!this._isSliding) {
|
||||||
this._slide(Direction.PREV)
|
this._slide(DIRECTION_PREV)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,7 +162,7 @@ class Carousel {
|
||||||
this._isPaused = true
|
this._isPaused = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SelectorEngine.findOne(Selector.NEXT_PREV, this._element)) {
|
if (SelectorEngine.findOne(SELECTOR_NEXT_PREV, this._element)) {
|
||||||
triggerTransitionEnd(this._element)
|
triggerTransitionEnd(this._element)
|
||||||
this.cycle(true)
|
this.cycle(true)
|
||||||
}
|
}
|
||||||
|
@ -198,7 +190,7 @@ class Carousel {
|
||||||
}
|
}
|
||||||
|
|
||||||
to(index) {
|
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)
|
const activeIndex = this._getItemIndex(this._activeElement)
|
||||||
|
|
||||||
if (index > this._items.length - 1 || index < 0) {
|
if (index > this._items.length - 1 || index < 0) {
|
||||||
|
@ -206,7 +198,7 @@ class Carousel {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._isSliding) {
|
if (this._isSliding) {
|
||||||
EventHandler.one(this._element, Event.SLID, () => this.to(index))
|
EventHandler.one(this._element, EVENT_SLID, () => this.to(index))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,8 +209,8 @@ class Carousel {
|
||||||
}
|
}
|
||||||
|
|
||||||
const direction = index > activeIndex ?
|
const direction = index > activeIndex ?
|
||||||
Direction.NEXT :
|
DIRECTION_NEXT :
|
||||||
Direction.PREV
|
DIRECTION_PREV
|
||||||
|
|
||||||
this._slide(direction, this._items[index])
|
this._slide(direction, this._items[index])
|
||||||
}
|
}
|
||||||
|
@ -273,14 +265,14 @@ class Carousel {
|
||||||
_addEventListeners() {
|
_addEventListeners() {
|
||||||
if (this._config.keyboard) {
|
if (this._config.keyboard) {
|
||||||
EventHandler
|
EventHandler
|
||||||
.on(this._element, Event.KEYDOWN, event => this._keydown(event))
|
.on(this._element, EVENT_KEYDOWN, event => this._keydown(event))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._config.pause === 'hover') {
|
if (this._config.pause === 'hover') {
|
||||||
EventHandler
|
EventHandler
|
||||||
.on(this._element, Event.MOUSEENTER, event => this.pause(event))
|
.on(this._element, EVENT_MOUSEENTER, event => this.pause(event))
|
||||||
EventHandler
|
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) {
|
if (this._config.touch && this._touchSupported) {
|
||||||
|
@ -330,19 +322,19 @@ class Carousel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
makeArray(SelectorEngine.find(Selector.ITEM_IMG, this._element)).forEach(itemImg => {
|
makeArray(SelectorEngine.find(SELECTOR_ITEM_IMG, this._element)).forEach(itemImg => {
|
||||||
EventHandler.on(itemImg, Event.DRAG_START, e => e.preventDefault())
|
EventHandler.on(itemImg, EVENT_DRAG_START, e => e.preventDefault())
|
||||||
})
|
})
|
||||||
|
|
||||||
if (this._pointerEvent) {
|
if (this._pointerEvent) {
|
||||||
EventHandler.on(this._element, Event.POINTERDOWN, event => start(event))
|
EventHandler.on(this._element, EVENT_POINTERDOWN, event => start(event))
|
||||||
EventHandler.on(this._element, Event.POINTERUP, event => end(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 {
|
} else {
|
||||||
EventHandler.on(this._element, Event.TOUCHSTART, event => start(event))
|
EventHandler.on(this._element, EVENT_TOUCHSTART, event => start(event))
|
||||||
EventHandler.on(this._element, Event.TOUCHMOVE, event => move(event))
|
EventHandler.on(this._element, EVENT_TOUCHMOVE, event => move(event))
|
||||||
EventHandler.on(this._element, Event.TOUCHEND, event => end(event))
|
EventHandler.on(this._element, EVENT_TOUCHEND, event => end(event))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,15 +358,15 @@ class Carousel {
|
||||||
|
|
||||||
_getItemIndex(element) {
|
_getItemIndex(element) {
|
||||||
this._items = element && element.parentNode ?
|
this._items = element && element.parentNode ?
|
||||||
makeArray(SelectorEngine.find(Selector.ITEM, element.parentNode)) :
|
makeArray(SelectorEngine.find(SELECTOR_ITEM, element.parentNode)) :
|
||||||
[]
|
[]
|
||||||
|
|
||||||
return this._items.indexOf(element)
|
return this._items.indexOf(element)
|
||||||
}
|
}
|
||||||
|
|
||||||
_getItemByDirection(direction, activeElement) {
|
_getItemByDirection(direction, activeElement) {
|
||||||
const isNextDirection = direction === Direction.NEXT
|
const isNextDirection = direction === DIRECTION_NEXT
|
||||||
const isPrevDirection = direction === Direction.PREV
|
const isPrevDirection = direction === DIRECTION_PREV
|
||||||
const activeIndex = this._getItemIndex(activeElement)
|
const activeIndex = this._getItemIndex(activeElement)
|
||||||
const lastItemIndex = this._items.length - 1
|
const lastItemIndex = this._items.length - 1
|
||||||
const isGoingToWrap = (isPrevDirection && activeIndex === 0) ||
|
const isGoingToWrap = (isPrevDirection && activeIndex === 0) ||
|
||||||
|
@ -384,7 +376,7 @@ class Carousel {
|
||||||
return activeElement
|
return activeElement
|
||||||
}
|
}
|
||||||
|
|
||||||
const delta = direction === Direction.PREV ? -1 : 1
|
const delta = direction === DIRECTION_PREV ? -1 : 1
|
||||||
const itemIndex = (activeIndex + delta) % this._items.length
|
const itemIndex = (activeIndex + delta) % this._items.length
|
||||||
|
|
||||||
return itemIndex === -1 ?
|
return itemIndex === -1 ?
|
||||||
|
@ -394,9 +386,9 @@ class Carousel {
|
||||||
|
|
||||||
_triggerSlideEvent(relatedTarget, eventDirectionName) {
|
_triggerSlideEvent(relatedTarget, eventDirectionName) {
|
||||||
const targetIndex = this._getItemIndex(relatedTarget)
|
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,
|
relatedTarget,
|
||||||
direction: eventDirectionName,
|
direction: eventDirectionName,
|
||||||
from: fromIndex,
|
from: fromIndex,
|
||||||
|
@ -406,9 +398,9 @@ class Carousel {
|
||||||
|
|
||||||
_setActiveIndicatorElement(element) {
|
_setActiveIndicatorElement(element) {
|
||||||
if (this._indicatorsElement) {
|
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++) {
|
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[
|
const nextIndicator = this._indicatorsElement.children[
|
||||||
|
@ -416,13 +408,13 @@ class Carousel {
|
||||||
]
|
]
|
||||||
|
|
||||||
if (nextIndicator) {
|
if (nextIndicator) {
|
||||||
nextIndicator.classList.add(ClassName.ACTIVE)
|
nextIndicator.classList.add(CLASS_NAME_ACTIVE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_slide(direction, element) {
|
_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 activeElementIndex = this._getItemIndex(activeElement)
|
||||||
const nextElement = element || (activeElement &&
|
const nextElement = element || (activeElement &&
|
||||||
this._getItemByDirection(direction, activeElement))
|
this._getItemByDirection(direction, activeElement))
|
||||||
|
@ -434,17 +426,17 @@ class Carousel {
|
||||||
let orderClassName
|
let orderClassName
|
||||||
let eventDirectionName
|
let eventDirectionName
|
||||||
|
|
||||||
if (direction === Direction.NEXT) {
|
if (direction === DIRECTION_NEXT) {
|
||||||
directionalClassName = ClassName.LEFT
|
directionalClassName = CLASS_NAME_LEFT
|
||||||
orderClassName = ClassName.NEXT
|
orderClassName = CLASS_NAME_NEXT
|
||||||
eventDirectionName = Direction.LEFT
|
eventDirectionName = DIRECTION_LEFT
|
||||||
} else {
|
} else {
|
||||||
directionalClassName = ClassName.RIGHT
|
directionalClassName = CLASS_NAME_RIGHT
|
||||||
orderClassName = ClassName.PREV
|
orderClassName = CLASS_NAME_PREV
|
||||||
eventDirectionName = Direction.RIGHT
|
eventDirectionName = DIRECTION_RIGHT
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextElement && nextElement.classList.contains(ClassName.ACTIVE)) {
|
if (nextElement && nextElement.classList.contains(CLASS_NAME_ACTIVE)) {
|
||||||
this._isSliding = false
|
this._isSliding = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -467,7 +459,7 @@ class Carousel {
|
||||||
|
|
||||||
this._setActiveIndicatorElement(nextElement)
|
this._setActiveIndicatorElement(nextElement)
|
||||||
|
|
||||||
if (this._element.classList.contains(ClassName.SLIDE)) {
|
if (this._element.classList.contains(CLASS_NAME_SLIDE)) {
|
||||||
nextElement.classList.add(orderClassName)
|
nextElement.classList.add(orderClassName)
|
||||||
|
|
||||||
reflow(nextElement)
|
reflow(nextElement)
|
||||||
|
@ -489,16 +481,16 @@ class Carousel {
|
||||||
.one(activeElement, TRANSITION_END, () => {
|
.one(activeElement, TRANSITION_END, () => {
|
||||||
nextElement.classList.remove(directionalClassName)
|
nextElement.classList.remove(directionalClassName)
|
||||||
nextElement.classList.remove(orderClassName)
|
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(orderClassName)
|
||||||
activeElement.classList.remove(directionalClassName)
|
activeElement.classList.remove(directionalClassName)
|
||||||
|
|
||||||
this._isSliding = false
|
this._isSliding = false
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
EventHandler.trigger(this._element, Event.SLID, {
|
EventHandler.trigger(this._element, EVENT_SLID, {
|
||||||
relatedTarget: nextElement,
|
relatedTarget: nextElement,
|
||||||
direction: eventDirectionName,
|
direction: eventDirectionName,
|
||||||
from: activeElementIndex,
|
from: activeElementIndex,
|
||||||
|
@ -509,11 +501,11 @@ class Carousel {
|
||||||
|
|
||||||
emulateTransitionEnd(activeElement, transitionDuration)
|
emulateTransitionEnd(activeElement, transitionDuration)
|
||||||
} else {
|
} else {
|
||||||
activeElement.classList.remove(ClassName.ACTIVE)
|
activeElement.classList.remove(CLASS_NAME_ACTIVE)
|
||||||
nextElement.classList.add(ClassName.ACTIVE)
|
nextElement.classList.add(CLASS_NAME_ACTIVE)
|
||||||
|
|
||||||
this._isSliding = false
|
this._isSliding = false
|
||||||
EventHandler.trigger(this._element, Event.SLID, {
|
EventHandler.trigger(this._element, EVENT_SLID, {
|
||||||
relatedTarget: nextElement,
|
relatedTarget: nextElement,
|
||||||
direction: eventDirectionName,
|
direction: eventDirectionName,
|
||||||
from: activeElementIndex,
|
from: activeElementIndex,
|
||||||
|
@ -571,7 +563,7 @@ class Carousel {
|
||||||
static dataApiClickHandler(event) {
|
static dataApiClickHandler(event) {
|
||||||
const target = getElementFromSelector(this)
|
const target = getElementFromSelector(this)
|
||||||
|
|
||||||
if (!target || !target.classList.contains(ClassName.CAROUSEL)) {
|
if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -606,10 +598,10 @@ class Carousel {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
EventHandler
|
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, () => {
|
EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
|
||||||
const carousels = makeArray(SelectorEngine.find(Selector.DATA_RIDE))
|
const carousels = makeArray(SelectorEngine.find(SELECTOR_DATA_RIDE))
|
||||||
for (let i = 0, len = carousels.length; i < len; i++) {
|
for (let i = 0, len = carousels.length; i < len; i++) {
|
||||||
Carousel.carouselInterface(carousels[i], Data.getData(carousels[i], DATA_KEY))
|
Carousel.carouselInterface(carousels[i], Data.getData(carousels[i], DATA_KEY))
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,30 +44,22 @@ const DefaultType = {
|
||||||
parent: '(string|element)'
|
parent: '(string|element)'
|
||||||
}
|
}
|
||||||
|
|
||||||
const Event = {
|
const EVENT_SHOW = `show${EVENT_KEY}`
|
||||||
SHOW: `show${EVENT_KEY}`,
|
const EVENT_SHOWN = `shown${EVENT_KEY}`
|
||||||
SHOWN: `shown${EVENT_KEY}`,
|
const EVENT_HIDE = `hide${EVENT_KEY}`
|
||||||
HIDE: `hide${EVENT_KEY}`,
|
const EVENT_HIDDEN = `hidden${EVENT_KEY}`
|
||||||
HIDDEN: `hidden${EVENT_KEY}`,
|
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
|
||||||
CLICK_DATA_API: `click${EVENT_KEY}${DATA_API_KEY}`
|
|
||||||
}
|
|
||||||
|
|
||||||
const ClassName = {
|
const CLASS_NAME_SHOW = 'show'
|
||||||
SHOW: 'show',
|
const CLASS_NAME_COLLAPSE = 'collapse'
|
||||||
COLLAPSE: 'collapse',
|
const CLASS_NAME_COLLAPSING = 'collapsing'
|
||||||
COLLAPSING: 'collapsing',
|
const CLASS_NAME_COLLAPSED = 'collapsed'
|
||||||
COLLAPSED: 'collapsed'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Dimension = {
|
const WIDTH = 'width'
|
||||||
WIDTH: 'width',
|
const HEIGHT = 'height'
|
||||||
HEIGHT: 'height'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Selector = {
|
const SELECTOR_ACTIVES = '.show, .collapsing'
|
||||||
ACTIVES: '.show, .collapsing',
|
const SELECTOR_DATA_TOGGLE = '[data-toggle="collapse"]'
|
||||||
DATA_TOGGLE: '[data-toggle="collapse"]'
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ------------------------------------------------------------------------
|
* ------------------------------------------------------------------------
|
||||||
|
@ -81,11 +73,11 @@ class Collapse {
|
||||||
this._element = element
|
this._element = element
|
||||||
this._config = this._getConfig(config)
|
this._config = this._getConfig(config)
|
||||||
this._triggerArray = makeArray(SelectorEngine.find(
|
this._triggerArray = makeArray(SelectorEngine.find(
|
||||||
`${Selector.DATA_TOGGLE}[href="#${element.id}"],` +
|
`${SELECTOR_DATA_TOGGLE}[href="#${element.id}"],` +
|
||||||
`${Selector.DATA_TOGGLE}[data-target="#${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++) {
|
for (let i = 0, len = toggleList.length; i < len; i++) {
|
||||||
const elem = toggleList[i]
|
const elem = toggleList[i]
|
||||||
const selector = getSelectorFromElement(elem)
|
const selector = getSelectorFromElement(elem)
|
||||||
|
@ -124,7 +116,7 @@ class Collapse {
|
||||||
// Public
|
// Public
|
||||||
|
|
||||||
toggle() {
|
toggle() {
|
||||||
if (this._element.classList.contains(ClassName.SHOW)) {
|
if (this._element.classList.contains(CLASS_NAME_SHOW)) {
|
||||||
this.hide()
|
this.hide()
|
||||||
} else {
|
} else {
|
||||||
this.show()
|
this.show()
|
||||||
|
@ -133,7 +125,7 @@ class Collapse {
|
||||||
|
|
||||||
show() {
|
show() {
|
||||||
if (this._isTransitioning ||
|
if (this._isTransitioning ||
|
||||||
this._element.classList.contains(ClassName.SHOW)) {
|
this._element.classList.contains(CLASS_NAME_SHOW)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,13 +133,13 @@ class Collapse {
|
||||||
let activesData
|
let activesData
|
||||||
|
|
||||||
if (this._parent) {
|
if (this._parent) {
|
||||||
actives = makeArray(SelectorEngine.find(Selector.ACTIVES, this._parent))
|
actives = makeArray(SelectorEngine.find(SELECTOR_ACTIVES, this._parent))
|
||||||
.filter(elem => {
|
.filter(elem => {
|
||||||
if (typeof this._config.parent === 'string') {
|
if (typeof this._config.parent === 'string') {
|
||||||
return elem.getAttribute('data-parent') === this._config.parent
|
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) {
|
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) {
|
if (startEvent.defaultPrevented) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -184,14 +176,14 @@ class Collapse {
|
||||||
|
|
||||||
const dimension = this._getDimension()
|
const dimension = this._getDimension()
|
||||||
|
|
||||||
this._element.classList.remove(ClassName.COLLAPSE)
|
this._element.classList.remove(CLASS_NAME_COLLAPSE)
|
||||||
this._element.classList.add(ClassName.COLLAPSING)
|
this._element.classList.add(CLASS_NAME_COLLAPSING)
|
||||||
|
|
||||||
this._element.style[dimension] = 0
|
this._element.style[dimension] = 0
|
||||||
|
|
||||||
if (this._triggerArray.length) {
|
if (this._triggerArray.length) {
|
||||||
this._triggerArray.forEach(element => {
|
this._triggerArray.forEach(element => {
|
||||||
element.classList.remove(ClassName.COLLAPSED)
|
element.classList.remove(CLASS_NAME_COLLAPSED)
|
||||||
element.setAttribute('aria-expanded', true)
|
element.setAttribute('aria-expanded', true)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -199,15 +191,15 @@ class Collapse {
|
||||||
this.setTransitioning(true)
|
this.setTransitioning(true)
|
||||||
|
|
||||||
const complete = () => {
|
const complete = () => {
|
||||||
this._element.classList.remove(ClassName.COLLAPSING)
|
this._element.classList.remove(CLASS_NAME_COLLAPSING)
|
||||||
this._element.classList.add(ClassName.COLLAPSE)
|
this._element.classList.add(CLASS_NAME_COLLAPSE)
|
||||||
this._element.classList.add(ClassName.SHOW)
|
this._element.classList.add(CLASS_NAME_SHOW)
|
||||||
|
|
||||||
this._element.style[dimension] = ''
|
this._element.style[dimension] = ''
|
||||||
|
|
||||||
this.setTransitioning(false)
|
this.setTransitioning(false)
|
||||||
|
|
||||||
EventHandler.trigger(this._element, Event.SHOWN)
|
EventHandler.trigger(this._element, EVENT_SHOWN)
|
||||||
}
|
}
|
||||||
|
|
||||||
const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)
|
const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)
|
||||||
|
@ -222,11 +214,11 @@ class Collapse {
|
||||||
|
|
||||||
hide() {
|
hide() {
|
||||||
if (this._isTransitioning ||
|
if (this._isTransitioning ||
|
||||||
!this._element.classList.contains(ClassName.SHOW)) {
|
!this._element.classList.contains(CLASS_NAME_SHOW)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const startEvent = EventHandler.trigger(this._element, Event.HIDE)
|
const startEvent = EventHandler.trigger(this._element, EVENT_HIDE)
|
||||||
if (startEvent.defaultPrevented) {
|
if (startEvent.defaultPrevented) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -237,9 +229,9 @@ class Collapse {
|
||||||
|
|
||||||
reflow(this._element)
|
reflow(this._element)
|
||||||
|
|
||||||
this._element.classList.add(ClassName.COLLAPSING)
|
this._element.classList.add(CLASS_NAME_COLLAPSING)
|
||||||
this._element.classList.remove(ClassName.COLLAPSE)
|
this._element.classList.remove(CLASS_NAME_COLLAPSE)
|
||||||
this._element.classList.remove(ClassName.SHOW)
|
this._element.classList.remove(CLASS_NAME_SHOW)
|
||||||
|
|
||||||
const triggerArrayLength = this._triggerArray.length
|
const triggerArrayLength = this._triggerArray.length
|
||||||
if (triggerArrayLength > 0) {
|
if (triggerArrayLength > 0) {
|
||||||
|
@ -247,8 +239,8 @@ class Collapse {
|
||||||
const trigger = this._triggerArray[i]
|
const trigger = this._triggerArray[i]
|
||||||
const elem = getElementFromSelector(trigger)
|
const elem = getElementFromSelector(trigger)
|
||||||
|
|
||||||
if (elem && !elem.classList.contains(ClassName.SHOW)) {
|
if (elem && !elem.classList.contains(CLASS_NAME_SHOW)) {
|
||||||
trigger.classList.add(ClassName.COLLAPSED)
|
trigger.classList.add(CLASS_NAME_COLLAPSED)
|
||||||
trigger.setAttribute('aria-expanded', false)
|
trigger.setAttribute('aria-expanded', false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -258,9 +250,9 @@ class Collapse {
|
||||||
|
|
||||||
const complete = () => {
|
const complete = () => {
|
||||||
this.setTransitioning(false)
|
this.setTransitioning(false)
|
||||||
this._element.classList.remove(ClassName.COLLAPSING)
|
this._element.classList.remove(CLASS_NAME_COLLAPSING)
|
||||||
this._element.classList.add(ClassName.COLLAPSE)
|
this._element.classList.add(CLASS_NAME_COLLAPSE)
|
||||||
EventHandler.trigger(this._element, Event.HIDDEN)
|
EventHandler.trigger(this._element, EVENT_HIDDEN)
|
||||||
}
|
}
|
||||||
|
|
||||||
this._element.style[dimension] = ''
|
this._element.style[dimension] = ''
|
||||||
|
@ -297,8 +289,8 @@ class Collapse {
|
||||||
}
|
}
|
||||||
|
|
||||||
_getDimension() {
|
_getDimension() {
|
||||||
const hasWidth = this._element.classList.contains(Dimension.WIDTH)
|
const hasWidth = this._element.classList.contains(WIDTH)
|
||||||
return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT
|
return hasWidth ? WIDTH : HEIGHT
|
||||||
}
|
}
|
||||||
|
|
||||||
_getParent() {
|
_getParent() {
|
||||||
|
@ -313,7 +305,7 @@ class Collapse {
|
||||||
parent = SelectorEngine.findOne(parent)
|
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))
|
makeArray(SelectorEngine.find(selector, parent))
|
||||||
.forEach(element => {
|
.forEach(element => {
|
||||||
|
@ -330,14 +322,14 @@ class Collapse {
|
||||||
|
|
||||||
_addAriaAndCollapsedClass(element, triggerArray) {
|
_addAriaAndCollapsedClass(element, triggerArray) {
|
||||||
if (element) {
|
if (element) {
|
||||||
const isOpen = element.classList.contains(ClassName.SHOW)
|
const isOpen = element.classList.contains(CLASS_NAME_SHOW)
|
||||||
|
|
||||||
if (triggerArray.length) {
|
if (triggerArray.length) {
|
||||||
triggerArray.forEach(elem => {
|
triggerArray.forEach(elem => {
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
elem.classList.remove(ClassName.COLLAPSED)
|
elem.classList.remove(CLASS_NAME_COLLAPSED)
|
||||||
} else {
|
} else {
|
||||||
elem.classList.add(ClassName.COLLAPSED)
|
elem.classList.add(CLASS_NAME_COLLAPSED)
|
||||||
}
|
}
|
||||||
|
|
||||||
elem.setAttribute('aria-expanded', isOpen)
|
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
|
// preventDefault only for <a> elements (which change the URL) not inside the collapsible element
|
||||||
if (event.target.tagName === 'A') {
|
if (event.target.tagName === 'A') {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
|
|
@ -31,54 +31,46 @@ const VERSION = '4.3.1'
|
||||||
const DATA_KEY = 'bs.dropdown'
|
const DATA_KEY = 'bs.dropdown'
|
||||||
const EVENT_KEY = `.${DATA_KEY}`
|
const EVENT_KEY = `.${DATA_KEY}`
|
||||||
const DATA_API_KEY = '.data-api'
|
const DATA_API_KEY = '.data-api'
|
||||||
|
|
||||||
const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key
|
const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key
|
||||||
const SPACE_KEYCODE = 32 // KeyboardEvent.which value for space key
|
const SPACE_KEYCODE = 32 // KeyboardEvent.which value for space key
|
||||||
const TAB_KEYCODE = 9 // KeyboardEvent.which value for tab 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_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key
|
||||||
const ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down 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 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 REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`)
|
||||||
|
|
||||||
const Event = {
|
const EVENT_HIDE = `hide${EVENT_KEY}`
|
||||||
HIDE: `hide${EVENT_KEY}`,
|
const EVENT_HIDDEN = `hidden${EVENT_KEY}`
|
||||||
HIDDEN: `hidden${EVENT_KEY}`,
|
const EVENT_SHOW = `show${EVENT_KEY}`
|
||||||
SHOW: `show${EVENT_KEY}`,
|
const EVENT_SHOWN = `shown${EVENT_KEY}`
|
||||||
SHOWN: `shown${EVENT_KEY}`,
|
const EVENT_CLICK = `click${EVENT_KEY}`
|
||||||
CLICK: `click${EVENT_KEY}`,
|
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
|
||||||
CLICK_DATA_API: `click${EVENT_KEY}${DATA_API_KEY}`,
|
const EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY}${DATA_API_KEY}`
|
||||||
KEYDOWN_DATA_API: `keydown${EVENT_KEY}${DATA_API_KEY}`,
|
const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}`
|
||||||
KEYUP_DATA_API: `keyup${EVENT_KEY}${DATA_API_KEY}`
|
|
||||||
}
|
|
||||||
|
|
||||||
const ClassName = {
|
const CLASS_NAME_DISABLED = 'disabled'
|
||||||
DISABLED: 'disabled',
|
const CLASS_NAME_SHOW = 'show'
|
||||||
SHOW: 'show',
|
const CLASS_NAME_DROPUP = 'dropup'
|
||||||
DROPUP: 'dropup',
|
const CLASS_NAME_DROPRIGHT = 'dropright'
|
||||||
DROPRIGHT: 'dropright',
|
const CLASS_NAME_DROPLEFT = 'dropleft'
|
||||||
DROPLEFT: 'dropleft',
|
const CLASS_NAME_MENURIGHT = 'dropdown-menu-right'
|
||||||
MENURIGHT: 'dropdown-menu-right',
|
const CLASS_NAME_NAVBAR = 'navbar'
|
||||||
NAVBAR: 'navbar',
|
const CLASS_NAME_POSITION_STATIC = 'position-static'
|
||||||
POSITION_STATIC: 'position-static'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Selector = {
|
const SELECTOR_DATA_TOGGLE = '[data-toggle="dropdown"]'
|
||||||
DATA_TOGGLE: '[data-toggle="dropdown"]',
|
const SELECTOR_FORM_CHILD = '.dropdown form'
|
||||||
FORM_CHILD: '.dropdown form',
|
const SELECTOR_MENU = '.dropdown-menu'
|
||||||
MENU: '.dropdown-menu',
|
const SELECTOR_NAVBAR_NAV = '.navbar-nav'
|
||||||
NAVBAR_NAV: '.navbar-nav',
|
const SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'
|
||||||
VISIBLE_ITEMS: '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'
|
|
||||||
}
|
|
||||||
|
|
||||||
const AttachmentMap = {
|
const PLACEMENT_TOP = 'top-start'
|
||||||
TOP: 'top-start',
|
const PLACEMENT_TOPEND = 'top-end'
|
||||||
TOPEND: 'top-end',
|
const PLACEMENT_BOTTOM = 'bottom-start'
|
||||||
BOTTOM: 'bottom-start',
|
const PLACEMENT_BOTTOMEND = 'bottom-end'
|
||||||
BOTTOMEND: 'bottom-end',
|
const PLACEMENT_RIGHT = 'right-start'
|
||||||
RIGHT: 'right-start',
|
const PLACEMENT_LEFT = 'left-start'
|
||||||
RIGHTEND: 'right-end',
|
|
||||||
LEFT: 'left-start',
|
|
||||||
LEFTEND: 'left-end'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Default = {
|
const Default = {
|
||||||
offset: 0,
|
offset: 0,
|
||||||
|
@ -133,11 +125,11 @@ class Dropdown {
|
||||||
// Public
|
// Public
|
||||||
|
|
||||||
toggle() {
|
toggle() {
|
||||||
if (this._element.disabled || this._element.classList.contains(ClassName.DISABLED)) {
|
if (this._element.disabled || this._element.classList.contains(CLASS_NAME_DISABLED)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const isActive = this._menu.classList.contains(ClassName.SHOW)
|
const isActive = this._menu.classList.contains(CLASS_NAME_SHOW)
|
||||||
|
|
||||||
Dropdown.clearMenus()
|
Dropdown.clearMenus()
|
||||||
|
|
||||||
|
@ -149,7 +141,7 @@ class Dropdown {
|
||||||
}
|
}
|
||||||
|
|
||||||
show() {
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +150,7 @@ class Dropdown {
|
||||||
relatedTarget: this._element
|
relatedTarget: this._element
|
||||||
}
|
}
|
||||||
|
|
||||||
const showEvent = EventHandler.trigger(parent, Event.SHOW, relatedTarget)
|
const showEvent = EventHandler.trigger(parent, EVENT_SHOW, relatedTarget)
|
||||||
|
|
||||||
if (showEvent.defaultPrevented) {
|
if (showEvent.defaultPrevented) {
|
||||||
return
|
return
|
||||||
|
@ -187,7 +179,7 @@ class Dropdown {
|
||||||
// to allow the menu to "escape" the scroll parent's boundaries
|
// to allow the menu to "escape" the scroll parent's boundaries
|
||||||
// https://github.com/twbs/bootstrap/issues/24251
|
// https://github.com/twbs/bootstrap/issues/24251
|
||||||
if (this._config.boundary !== 'scrollParent') {
|
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())
|
this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig())
|
||||||
|
@ -198,7 +190,7 @@ class Dropdown {
|
||||||
// only needed because of broken event delegation on iOS
|
// only needed because of broken event delegation on iOS
|
||||||
// https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
|
// https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
|
||||||
if ('ontouchstart' in document.documentElement &&
|
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)
|
makeArray(document.body.children)
|
||||||
.forEach(elem => EventHandler.on(elem, 'mouseover', null, noop()))
|
.forEach(elem => EventHandler.on(elem, 'mouseover', null, noop()))
|
||||||
}
|
}
|
||||||
|
@ -206,13 +198,13 @@ class Dropdown {
|
||||||
this._element.focus()
|
this._element.focus()
|
||||||
this._element.setAttribute('aria-expanded', true)
|
this._element.setAttribute('aria-expanded', true)
|
||||||
|
|
||||||
Manipulator.toggleClass(this._menu, ClassName.SHOW)
|
Manipulator.toggleClass(this._menu, CLASS_NAME_SHOW)
|
||||||
Manipulator.toggleClass(parent, ClassName.SHOW)
|
Manipulator.toggleClass(parent, CLASS_NAME_SHOW)
|
||||||
EventHandler.trigger(parent, Event.SHOWN, relatedTarget)
|
EventHandler.trigger(parent, EVENT_SHOWN, relatedTarget)
|
||||||
}
|
}
|
||||||
|
|
||||||
hide() {
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,7 +213,7 @@ class Dropdown {
|
||||||
relatedTarget: this._element
|
relatedTarget: this._element
|
||||||
}
|
}
|
||||||
|
|
||||||
const hideEvent = EventHandler.trigger(parent, Event.HIDE, relatedTarget)
|
const hideEvent = EventHandler.trigger(parent, EVENT_HIDE, relatedTarget)
|
||||||
|
|
||||||
if (hideEvent.defaultPrevented) {
|
if (hideEvent.defaultPrevented) {
|
||||||
return
|
return
|
||||||
|
@ -231,9 +223,9 @@ class Dropdown {
|
||||||
this._popper.destroy()
|
this._popper.destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
Manipulator.toggleClass(this._menu, ClassName.SHOW)
|
Manipulator.toggleClass(this._menu, CLASS_NAME_SHOW)
|
||||||
Manipulator.toggleClass(parent, ClassName.SHOW)
|
Manipulator.toggleClass(parent, CLASS_NAME_SHOW)
|
||||||
EventHandler.trigger(parent, Event.HIDDEN, relatedTarget)
|
EventHandler.trigger(parent, EVENT_HIDDEN, relatedTarget)
|
||||||
}
|
}
|
||||||
|
|
||||||
dispose() {
|
dispose() {
|
||||||
|
@ -257,7 +249,7 @@ class Dropdown {
|
||||||
// Private
|
// Private
|
||||||
|
|
||||||
_addEventListeners() {
|
_addEventListeners() {
|
||||||
EventHandler.on(this._element, Event.CLICK, event => {
|
EventHandler.on(this._element, EVENT_CLICK, event => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
this.toggle()
|
this.toggle()
|
||||||
|
@ -283,32 +275,32 @@ class Dropdown {
|
||||||
_getMenuElement() {
|
_getMenuElement() {
|
||||||
const parent = Dropdown.getParentFromElement(this._element)
|
const parent = Dropdown.getParentFromElement(this._element)
|
||||||
|
|
||||||
return SelectorEngine.findOne(Selector.MENU, parent)
|
return SelectorEngine.findOne(SELECTOR_MENU, parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
_getPlacement() {
|
_getPlacement() {
|
||||||
const parentDropdown = this._element.parentNode
|
const parentDropdown = this._element.parentNode
|
||||||
let placement = AttachmentMap.BOTTOM
|
let placement = PLACEMENT_BOTTOM
|
||||||
|
|
||||||
// Handle dropup
|
// Handle dropup
|
||||||
if (parentDropdown.classList.contains(ClassName.DROPUP)) {
|
if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) {
|
||||||
placement = AttachmentMap.TOP
|
placement = PLACEMENT_TOP
|
||||||
if (this._menu.classList.contains(ClassName.MENURIGHT)) {
|
if (this._menu.classList.contains(CLASS_NAME_MENURIGHT)) {
|
||||||
placement = AttachmentMap.TOPEND
|
placement = PLACEMENT_TOPEND
|
||||||
}
|
}
|
||||||
} else if (parentDropdown.classList.contains(ClassName.DROPRIGHT)) {
|
} else if (parentDropdown.classList.contains(CLASS_NAME_DROPRIGHT)) {
|
||||||
placement = AttachmentMap.RIGHT
|
placement = PLACEMENT_RIGHT
|
||||||
} else if (parentDropdown.classList.contains(ClassName.DROPLEFT)) {
|
} else if (parentDropdown.classList.contains(CLASS_NAME_DROPLEFT)) {
|
||||||
placement = AttachmentMap.LEFT
|
placement = PLACEMENT_LEFT
|
||||||
} else if (this._menu.classList.contains(ClassName.MENURIGHT)) {
|
} else if (this._menu.classList.contains(CLASS_NAME_MENURIGHT)) {
|
||||||
placement = AttachmentMap.BOTTOMEND
|
placement = PLACEMENT_BOTTOMEND
|
||||||
}
|
}
|
||||||
|
|
||||||
return placement
|
return placement
|
||||||
}
|
}
|
||||||
|
|
||||||
_detectNavbar() {
|
_detectNavbar() {
|
||||||
return Boolean(SelectorEngine.closest(this._element, `.${ClassName.NAVBAR}`))
|
return Boolean(SelectorEngine.closest(this._element, `.${CLASS_NAME_NAVBAR}`))
|
||||||
}
|
}
|
||||||
|
|
||||||
_getOffset() {
|
_getOffset() {
|
||||||
|
@ -388,7 +380,7 @@ class Dropdown {
|
||||||
return
|
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++) {
|
for (let i = 0, len = toggles.length; i < len; i++) {
|
||||||
const parent = Dropdown.getParentFromElement(toggles[i])
|
const parent = Dropdown.getParentFromElement(toggles[i])
|
||||||
const context = Data.getData(toggles[i], DATA_KEY)
|
const context = Data.getData(toggles[i], DATA_KEY)
|
||||||
|
@ -405,7 +397,7 @@ class Dropdown {
|
||||||
}
|
}
|
||||||
|
|
||||||
const dropdownMenu = context._menu
|
const dropdownMenu = context._menu
|
||||||
if (!parent.classList.contains(ClassName.SHOW)) {
|
if (!parent.classList.contains(CLASS_NAME_SHOW)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,7 +408,7 @@ class Dropdown {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
const hideEvent = EventHandler.trigger(parent, Event.HIDE, relatedTarget)
|
const hideEvent = EventHandler.trigger(parent, EVENT_HIDE, relatedTarget)
|
||||||
if (hideEvent.defaultPrevented) {
|
if (hideEvent.defaultPrevented) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -434,9 +426,9 @@ class Dropdown {
|
||||||
context._popper.destroy()
|
context._popper.destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
dropdownMenu.classList.remove(ClassName.SHOW)
|
dropdownMenu.classList.remove(CLASS_NAME_SHOW)
|
||||||
parent.classList.remove(ClassName.SHOW)
|
parent.classList.remove(CLASS_NAME_SHOW)
|
||||||
EventHandler.trigger(parent, Event.HIDDEN, relatedTarget)
|
EventHandler.trigger(parent, EVENT_HIDDEN, relatedTarget)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -455,7 +447,7 @@ class Dropdown {
|
||||||
if (/input|textarea/i.test(event.target.tagName) ?
|
if (/input|textarea/i.test(event.target.tagName) ?
|
||||||
event.which === SPACE_KEYCODE || (event.which !== ESCAPE_KEYCODE &&
|
event.which === SPACE_KEYCODE || (event.which !== ESCAPE_KEYCODE &&
|
||||||
((event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_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)) {
|
!REGEXP_KEYDOWN.test(event.which)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -463,23 +455,23 @@ class Dropdown {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
|
|
||||||
if (this.disabled || this.classList.contains(ClassName.DISABLED)) {
|
if (this.disabled || this.classList.contains(CLASS_NAME_DISABLED)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const parent = Dropdown.getParentFromElement(this)
|
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 (!isActive || (isActive && (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE))) {
|
||||||
if (event.which === ESCAPE_KEYCODE) {
|
if (event.which === ESCAPE_KEYCODE) {
|
||||||
SelectorEngine.findOne(Selector.DATA_TOGGLE, parent).focus()
|
SelectorEngine.findOne(SELECTOR_DATA_TOGGLE, parent).focus()
|
||||||
}
|
}
|
||||||
|
|
||||||
Dropdown.clearMenus()
|
Dropdown.clearMenus()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const items = makeArray(SelectorEngine.find(Selector.VISIBLE_ITEMS, parent))
|
const items = makeArray(SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, parent))
|
||||||
.filter(isVisible)
|
.filter(isVisible)
|
||||||
|
|
||||||
if (!items.length) {
|
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_DATA_TOGGLE, Dropdown.dataApiKeydownHandler)
|
||||||
EventHandler.on(document, Event.KEYDOWN_DATA_API, Selector.MENU, 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_CLICK_DATA_API, Dropdown.clearMenus)
|
||||||
EventHandler.on(document, Event.KEYUP_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_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
Dropdown.dropdownInterface(this, 'toggle')
|
Dropdown.dropdownInterface(this, 'toggle')
|
||||||
})
|
})
|
||||||
EventHandler
|
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()
|
const $ = getjQuery()
|
||||||
|
|
||||||
|
|
152
js/src/modal.js
152
js/src/modal.js
|
@ -48,39 +48,33 @@ const DefaultType = {
|
||||||
show: 'boolean'
|
show: 'boolean'
|
||||||
}
|
}
|
||||||
|
|
||||||
const Event = {
|
const EVENT_HIDE = `hide${EVENT_KEY}`
|
||||||
HIDE: `hide${EVENT_KEY}`,
|
const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`
|
||||||
HIDE_PREVENTED: `hidePrevented${EVENT_KEY}`,
|
const EVENT_HIDDEN = `hidden${EVENT_KEY}`
|
||||||
HIDDEN: `hidden${EVENT_KEY}`,
|
const EVENT_SHOW = `show${EVENT_KEY}`
|
||||||
SHOW: `show${EVENT_KEY}`,
|
const EVENT_SHOWN = `shown${EVENT_KEY}`
|
||||||
SHOWN: `shown${EVENT_KEY}`,
|
const EVENT_FOCUSIN = `focusin${EVENT_KEY}`
|
||||||
FOCUSIN: `focusin${EVENT_KEY}`,
|
const EVENT_RESIZE = `resize${EVENT_KEY}`
|
||||||
RESIZE: `resize${EVENT_KEY}`,
|
const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`
|
||||||
CLICK_DISMISS: `click.dismiss${EVENT_KEY}`,
|
const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`
|
||||||
KEYDOWN_DISMISS: `keydown.dismiss${EVENT_KEY}`,
|
const EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY}`
|
||||||
MOUSEUP_DISMISS: `mouseup.dismiss${EVENT_KEY}`,
|
const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`
|
||||||
MOUSEDOWN_DISMISS: `mousedown.dismiss${EVENT_KEY}`,
|
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
|
||||||
CLICK_DATA_API: `click${EVENT_KEY}${DATA_API_KEY}`
|
|
||||||
}
|
|
||||||
|
|
||||||
const ClassName = {
|
const CLASS_NAME_SCROLLABLE = 'modal-dialog-scrollable'
|
||||||
SCROLLABLE: 'modal-dialog-scrollable',
|
const CLASS_NAME_SCROLLBAR_MEASURER = 'modal-scrollbar-measure'
|
||||||
SCROLLBAR_MEASURER: 'modal-scrollbar-measure',
|
const CLASS_NAME_BACKDROP = 'modal-backdrop'
|
||||||
BACKDROP: 'modal-backdrop',
|
const CLASS_NAME_OPEN = 'modal-open'
|
||||||
OPEN: 'modal-open',
|
const CLASS_NAME_FADE = 'fade'
|
||||||
FADE: 'fade',
|
const CLASS_NAME_SHOW = 'show'
|
||||||
SHOW: 'show',
|
const CLASS_NAME_STATIC = 'modal-static'
|
||||||
STATIC: 'modal-static'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Selector = {
|
const SELECTOR_DIALOG = '.modal-dialog'
|
||||||
DIALOG: '.modal-dialog',
|
const SELECTOR_MODAL_BODY = '.modal-body'
|
||||||
MODAL_BODY: '.modal-body',
|
const SELECTOR_DATA_TOGGLE = '[data-toggle="modal"]'
|
||||||
DATA_TOGGLE: '[data-toggle="modal"]',
|
const SELECTOR_DATA_DISMISS = '[data-dismiss="modal"]'
|
||||||
DATA_DISMISS: '[data-dismiss="modal"]',
|
const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'
|
||||||
FIXED_CONTENT: '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top',
|
const SELECTOR_STICKY_CONTENT = '.sticky-top'
|
||||||
STICKY_CONTENT: '.sticky-top'
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ------------------------------------------------------------------------
|
* ------------------------------------------------------------------------
|
||||||
|
@ -92,7 +86,7 @@ class Modal {
|
||||||
constructor(element, config) {
|
constructor(element, config) {
|
||||||
this._config = this._getConfig(config)
|
this._config = this._getConfig(config)
|
||||||
this._element = element
|
this._element = element
|
||||||
this._dialog = SelectorEngine.findOne(Selector.DIALOG, element)
|
this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, element)
|
||||||
this._backdrop = null
|
this._backdrop = null
|
||||||
this._isShown = false
|
this._isShown = false
|
||||||
this._isBodyOverflowing = false
|
this._isBodyOverflowing = false
|
||||||
|
@ -123,11 +117,11 @@ class Modal {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._element.classList.contains(ClassName.FADE)) {
|
if (this._element.classList.contains(CLASS_NAME_FADE)) {
|
||||||
this._isTransitioning = true
|
this._isTransitioning = true
|
||||||
}
|
}
|
||||||
|
|
||||||
const showEvent = EventHandler.trigger(this._element, Event.SHOW, {
|
const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, {
|
||||||
relatedTarget
|
relatedTarget
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -146,13 +140,13 @@ class Modal {
|
||||||
this._setResizeEvent()
|
this._setResizeEvent()
|
||||||
|
|
||||||
EventHandler.on(this._element,
|
EventHandler.on(this._element,
|
||||||
Event.CLICK_DISMISS,
|
EVENT_CLICK_DISMISS,
|
||||||
Selector.DATA_DISMISS,
|
SELECTOR_DATA_DISMISS,
|
||||||
event => this.hide(event)
|
event => this.hide(event)
|
||||||
)
|
)
|
||||||
|
|
||||||
EventHandler.on(this._dialog, Event.MOUSEDOWN_DISMISS, () => {
|
EventHandler.on(this._dialog, EVENT_MOUSEDOWN_DISMISS, () => {
|
||||||
EventHandler.one(this._element, Event.MOUSEUP_DISMISS, event => {
|
EventHandler.one(this._element, EVENT_MOUSEUP_DISMISS, event => {
|
||||||
if (event.target === this._element) {
|
if (event.target === this._element) {
|
||||||
this._ignoreBackdropClick = true
|
this._ignoreBackdropClick = true
|
||||||
}
|
}
|
||||||
|
@ -171,14 +165,14 @@ class Modal {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const hideEvent = EventHandler.trigger(this._element, Event.HIDE)
|
const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE)
|
||||||
|
|
||||||
if (hideEvent.defaultPrevented) {
|
if (hideEvent.defaultPrevented) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
this._isShown = false
|
this._isShown = false
|
||||||
const transition = this._element.classList.contains(ClassName.FADE)
|
const transition = this._element.classList.contains(CLASS_NAME_FADE)
|
||||||
|
|
||||||
if (transition) {
|
if (transition) {
|
||||||
this._isTransitioning = true
|
this._isTransitioning = true
|
||||||
|
@ -187,12 +181,12 @@ class Modal {
|
||||||
this._setEscapeEvent()
|
this._setEscapeEvent()
|
||||||
this._setResizeEvent()
|
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._element, EVENT_CLICK_DISMISS)
|
||||||
EventHandler.off(this._dialog, Event.MOUSEDOWN_DISMISS)
|
EventHandler.off(this._dialog, EVENT_MOUSEDOWN_DISMISS)
|
||||||
|
|
||||||
if (transition) {
|
if (transition) {
|
||||||
const transitionDuration = getTransitionDurationFromElement(this._element)
|
const transitionDuration = getTransitionDurationFromElement(this._element)
|
||||||
|
@ -209,11 +203,11 @@ class Modal {
|
||||||
.forEach(htmlElement => EventHandler.off(htmlElement, EVENT_KEY))
|
.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
|
* 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)
|
Data.removeData(this._element, DATA_KEY)
|
||||||
|
|
||||||
|
@ -244,8 +238,8 @@ class Modal {
|
||||||
}
|
}
|
||||||
|
|
||||||
_showElement(relatedTarget) {
|
_showElement(relatedTarget) {
|
||||||
const transition = this._element.classList.contains(ClassName.FADE)
|
const transition = this._element.classList.contains(CLASS_NAME_FADE)
|
||||||
const modalBody = SelectorEngine.findOne(Selector.MODAL_BODY, this._dialog)
|
const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog)
|
||||||
|
|
||||||
if (!this._element.parentNode ||
|
if (!this._element.parentNode ||
|
||||||
this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
|
this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
|
||||||
|
@ -257,7 +251,7 @@ class Modal {
|
||||||
this._element.removeAttribute('aria-hidden')
|
this._element.removeAttribute('aria-hidden')
|
||||||
this._element.setAttribute('aria-modal', true)
|
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
|
modalBody.scrollTop = 0
|
||||||
} else {
|
} else {
|
||||||
this._element.scrollTop = 0
|
this._element.scrollTop = 0
|
||||||
|
@ -267,7 +261,7 @@ class Modal {
|
||||||
reflow(this._element)
|
reflow(this._element)
|
||||||
}
|
}
|
||||||
|
|
||||||
this._element.classList.add(ClassName.SHOW)
|
this._element.classList.add(CLASS_NAME_SHOW)
|
||||||
|
|
||||||
if (this._config.focus) {
|
if (this._config.focus) {
|
||||||
this._enforceFocus()
|
this._enforceFocus()
|
||||||
|
@ -279,7 +273,7 @@ class Modal {
|
||||||
}
|
}
|
||||||
|
|
||||||
this._isTransitioning = false
|
this._isTransitioning = false
|
||||||
EventHandler.trigger(this._element, Event.SHOWN, {
|
EventHandler.trigger(this._element, EVENT_SHOWN, {
|
||||||
relatedTarget
|
relatedTarget
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -295,8 +289,8 @@ class Modal {
|
||||||
}
|
}
|
||||||
|
|
||||||
_enforceFocus() {
|
_enforceFocus() {
|
||||||
EventHandler.off(document, Event.FOCUSIN) // guard against infinite focus loop
|
EventHandler.off(document, EVENT_FOCUSIN) // guard against infinite focus loop
|
||||||
EventHandler.on(document, Event.FOCUSIN, event => {
|
EventHandler.on(document, EVENT_FOCUSIN, event => {
|
||||||
if (document !== event.target &&
|
if (document !== event.target &&
|
||||||
this._element !== event.target &&
|
this._element !== event.target &&
|
||||||
!this._element.contains(event.target)) {
|
!this._element.contains(event.target)) {
|
||||||
|
@ -307,7 +301,7 @@ class Modal {
|
||||||
|
|
||||||
_setEscapeEvent() {
|
_setEscapeEvent() {
|
||||||
if (this._isShown) {
|
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) {
|
if (this._config.keyboard && event.which === ESCAPE_KEYCODE) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
this.hide()
|
this.hide()
|
||||||
|
@ -316,15 +310,15 @@ class Modal {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
EventHandler.off(this._element, Event.KEYDOWN_DISMISS)
|
EventHandler.off(this._element, EVENT_KEYDOWN_DISMISS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_setResizeEvent() {
|
_setResizeEvent() {
|
||||||
if (this._isShown) {
|
if (this._isShown) {
|
||||||
EventHandler.on(window, Event.RESIZE, () => this._adjustDialog())
|
EventHandler.on(window, EVENT_RESIZE, () => this._adjustDialog())
|
||||||
} else {
|
} else {
|
||||||
EventHandler.off(window, Event.RESIZE)
|
EventHandler.off(window, EVENT_RESIZE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,10 +328,10 @@ class Modal {
|
||||||
this._element.removeAttribute('aria-modal')
|
this._element.removeAttribute('aria-modal')
|
||||||
this._isTransitioning = false
|
this._isTransitioning = false
|
||||||
this._showBackdrop(() => {
|
this._showBackdrop(() => {
|
||||||
document.body.classList.remove(ClassName.OPEN)
|
document.body.classList.remove(CLASS_NAME_OPEN)
|
||||||
this._resetAdjustments()
|
this._resetAdjustments()
|
||||||
this._resetScrollbar()
|
this._resetScrollbar()
|
||||||
EventHandler.trigger(this._element, Event.HIDDEN)
|
EventHandler.trigger(this._element, EVENT_HIDDEN)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,13 +341,13 @@ class Modal {
|
||||||
}
|
}
|
||||||
|
|
||||||
_showBackdrop(callback) {
|
_showBackdrop(callback) {
|
||||||
const animate = this._element.classList.contains(ClassName.FADE) ?
|
const animate = this._element.classList.contains(CLASS_NAME_FADE) ?
|
||||||
ClassName.FADE :
|
CLASS_NAME_FADE :
|
||||||
''
|
''
|
||||||
|
|
||||||
if (this._isShown && this._config.backdrop) {
|
if (this._isShown && this._config.backdrop) {
|
||||||
this._backdrop = document.createElement('div')
|
this._backdrop = document.createElement('div')
|
||||||
this._backdrop.className = ClassName.BACKDROP
|
this._backdrop.className = CLASS_NAME_BACKDROP
|
||||||
|
|
||||||
if (animate) {
|
if (animate) {
|
||||||
this._backdrop.classList.add(animate)
|
this._backdrop.classList.add(animate)
|
||||||
|
@ -361,7 +355,7 @@ class Modal {
|
||||||
|
|
||||||
document.body.appendChild(this._backdrop)
|
document.body.appendChild(this._backdrop)
|
||||||
|
|
||||||
EventHandler.on(this._element, Event.CLICK_DISMISS, event => {
|
EventHandler.on(this._element, EVENT_CLICK_DISMISS, event => {
|
||||||
if (this._ignoreBackdropClick) {
|
if (this._ignoreBackdropClick) {
|
||||||
this._ignoreBackdropClick = false
|
this._ignoreBackdropClick = false
|
||||||
return
|
return
|
||||||
|
@ -378,7 +372,7 @@ class Modal {
|
||||||
reflow(this._backdrop)
|
reflow(this._backdrop)
|
||||||
}
|
}
|
||||||
|
|
||||||
this._backdrop.classList.add(ClassName.SHOW)
|
this._backdrop.classList.add(CLASS_NAME_SHOW)
|
||||||
|
|
||||||
if (!animate) {
|
if (!animate) {
|
||||||
callback()
|
callback()
|
||||||
|
@ -390,14 +384,14 @@ class Modal {
|
||||||
EventHandler.one(this._backdrop, TRANSITION_END, callback)
|
EventHandler.one(this._backdrop, TRANSITION_END, callback)
|
||||||
emulateTransitionEnd(this._backdrop, backdropTransitionDuration)
|
emulateTransitionEnd(this._backdrop, backdropTransitionDuration)
|
||||||
} else if (!this._isShown && this._backdrop) {
|
} else if (!this._isShown && this._backdrop) {
|
||||||
this._backdrop.classList.remove(ClassName.SHOW)
|
this._backdrop.classList.remove(CLASS_NAME_SHOW)
|
||||||
|
|
||||||
const callbackRemove = () => {
|
const callbackRemove = () => {
|
||||||
this._removeBackdrop()
|
this._removeBackdrop()
|
||||||
callback()
|
callback()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._element.classList.contains(ClassName.FADE)) {
|
if (this._element.classList.contains(CLASS_NAME_FADE)) {
|
||||||
const backdropTransitionDuration = getTransitionDurationFromElement(this._backdrop)
|
const backdropTransitionDuration = getTransitionDurationFromElement(this._backdrop)
|
||||||
EventHandler.one(this._backdrop, TRANSITION_END, callbackRemove)
|
EventHandler.one(this._backdrop, TRANSITION_END, callbackRemove)
|
||||||
emulateTransitionEnd(this._backdrop, backdropTransitionDuration)
|
emulateTransitionEnd(this._backdrop, backdropTransitionDuration)
|
||||||
|
@ -411,15 +405,15 @@ class Modal {
|
||||||
|
|
||||||
_triggerBackdropTransition() {
|
_triggerBackdropTransition() {
|
||||||
if (this._config.backdrop === 'static') {
|
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) {
|
if (hideEvent.defaultPrevented) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
this._element.classList.add(ClassName.STATIC)
|
this._element.classList.add(CLASS_NAME_STATIC)
|
||||||
const modalTransitionDuration = getTransitionDurationFromElement(this._element)
|
const modalTransitionDuration = getTransitionDurationFromElement(this._element)
|
||||||
EventHandler.one(this._element, TRANSITION_END, () => {
|
EventHandler.one(this._element, TRANSITION_END, () => {
|
||||||
this._element.classList.remove(ClassName.STATIC)
|
this._element.classList.remove(CLASS_NAME_STATIC)
|
||||||
})
|
})
|
||||||
emulateTransitionEnd(this._element, modalTransitionDuration)
|
emulateTransitionEnd(this._element, modalTransitionDuration)
|
||||||
this._element.focus()
|
this._element.focus()
|
||||||
|
@ -462,7 +456,7 @@ class Modal {
|
||||||
// while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set
|
// while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set
|
||||||
|
|
||||||
// Adjust fixed content padding
|
// Adjust fixed content padding
|
||||||
makeArray(SelectorEngine.find(Selector.FIXED_CONTENT))
|
makeArray(SelectorEngine.find(SELECTOR_FIXED_CONTENT))
|
||||||
.forEach(element => {
|
.forEach(element => {
|
||||||
const actualPadding = element.style.paddingRight
|
const actualPadding = element.style.paddingRight
|
||||||
const calculatedPadding = window.getComputedStyle(element)['padding-right']
|
const calculatedPadding = window.getComputedStyle(element)['padding-right']
|
||||||
|
@ -471,7 +465,7 @@ class Modal {
|
||||||
})
|
})
|
||||||
|
|
||||||
// Adjust sticky content margin
|
// Adjust sticky content margin
|
||||||
makeArray(SelectorEngine.find(Selector.STICKY_CONTENT))
|
makeArray(SelectorEngine.find(SELECTOR_STICKY_CONTENT))
|
||||||
.forEach(element => {
|
.forEach(element => {
|
||||||
const actualMargin = element.style.marginRight
|
const actualMargin = element.style.marginRight
|
||||||
const calculatedMargin = window.getComputedStyle(element)['margin-right']
|
const calculatedMargin = window.getComputedStyle(element)['margin-right']
|
||||||
|
@ -487,12 +481,12 @@ class Modal {
|
||||||
document.body.style.paddingRight = `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`
|
document.body.style.paddingRight = `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`
|
||||||
}
|
}
|
||||||
|
|
||||||
document.body.classList.add(ClassName.OPEN)
|
document.body.classList.add(CLASS_NAME_OPEN)
|
||||||
}
|
}
|
||||||
|
|
||||||
_resetScrollbar() {
|
_resetScrollbar() {
|
||||||
// Restore fixed content padding
|
// Restore fixed content padding
|
||||||
makeArray(SelectorEngine.find(Selector.FIXED_CONTENT))
|
makeArray(SelectorEngine.find(SELECTOR_FIXED_CONTENT))
|
||||||
.forEach(element => {
|
.forEach(element => {
|
||||||
const padding = Manipulator.getDataAttribute(element, 'padding-right')
|
const padding = Manipulator.getDataAttribute(element, 'padding-right')
|
||||||
if (typeof padding !== 'undefined') {
|
if (typeof padding !== 'undefined') {
|
||||||
|
@ -502,7 +496,7 @@ class Modal {
|
||||||
})
|
})
|
||||||
|
|
||||||
// Restore sticky content and navbar-toggler margin
|
// Restore sticky content and navbar-toggler margin
|
||||||
makeArray(SelectorEngine.find(`${Selector.STICKY_CONTENT}`))
|
makeArray(SelectorEngine.find(`${SELECTOR_STICKY_CONTENT}`))
|
||||||
.forEach(element => {
|
.forEach(element => {
|
||||||
const margin = Manipulator.getDataAttribute(element, 'margin-right')
|
const margin = Manipulator.getDataAttribute(element, 'margin-right')
|
||||||
if (typeof margin !== 'undefined') {
|
if (typeof margin !== 'undefined') {
|
||||||
|
@ -523,7 +517,7 @@ class Modal {
|
||||||
|
|
||||||
_getScrollbarWidth() { // thx d.walsh
|
_getScrollbarWidth() { // thx d.walsh
|
||||||
const scrollDiv = document.createElement('div')
|
const scrollDiv = document.createElement('div')
|
||||||
scrollDiv.className = ClassName.SCROLLBAR_MEASURER
|
scrollDiv.className = CLASS_NAME_SCROLLBAR_MEASURER
|
||||||
document.body.appendChild(scrollDiv)
|
document.body.appendChild(scrollDiv)
|
||||||
const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth
|
const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth
|
||||||
document.body.removeChild(scrollDiv)
|
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)
|
const target = getElementFromSelector(this)
|
||||||
|
|
||||||
if (this.tagName === 'A' || this.tagName === 'AREA') {
|
if (this.tagName === 'A' || this.tagName === 'AREA') {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
}
|
}
|
||||||
|
|
||||||
EventHandler.one(target, Event.SHOW, showEvent => {
|
EventHandler.one(target, EVENT_SHOW, showEvent => {
|
||||||
if (showEvent.defaultPrevented) {
|
if (showEvent.defaultPrevented) {
|
||||||
// only register focus restorer if modal will actually get shown
|
// only register focus restorer if modal will actually get shown
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
EventHandler.one(target, Event.HIDDEN, () => {
|
EventHandler.one(target, EVENT_HIDDEN, () => {
|
||||||
if (isVisible(this)) {
|
if (isVisible(this)) {
|
||||||
this.focus()
|
this.focus()
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,16 +39,6 @@ const DefaultType = {
|
||||||
content: '(string|element|function)'
|
content: '(string|element|function)'
|
||||||
}
|
}
|
||||||
|
|
||||||
const ClassName = {
|
|
||||||
FADE: 'fade',
|
|
||||||
SHOW: 'show'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Selector = {
|
|
||||||
TITLE: '.popover-header',
|
|
||||||
CONTENT: '.popover-body'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Event = {
|
const Event = {
|
||||||
HIDE: `hide${EVENT_KEY}`,
|
HIDE: `hide${EVENT_KEY}`,
|
||||||
HIDDEN: `hidden${EVENT_KEY}`,
|
HIDDEN: `hidden${EVENT_KEY}`,
|
||||||
|
@ -62,6 +52,12 @@ const Event = {
|
||||||
MOUSELEAVE: `mouseleave${EVENT_KEY}`
|
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
|
* Class Definition
|
||||||
|
@ -109,16 +105,16 @@ class Popover extends Tooltip {
|
||||||
const tip = this.getTipElement()
|
const tip = this.getTipElement()
|
||||||
|
|
||||||
// we use append for html objects to maintain js events
|
// 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()
|
let content = this._getContent()
|
||||||
if (typeof content === 'function') {
|
if (typeof content === 'function') {
|
||||||
content = content.call(this.element)
|
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(CLASS_NAME_FADE)
|
||||||
tip.classList.remove(ClassName.SHOW)
|
tip.classList.remove(CLASS_NAME_SHOW)
|
||||||
}
|
}
|
||||||
|
|
||||||
_addAttachmentClass(attachment) {
|
_addAttachmentClass(attachment) {
|
||||||
|
|
|
@ -41,31 +41,23 @@ const DefaultType = {
|
||||||
target: '(string|element)'
|
target: '(string|element)'
|
||||||
}
|
}
|
||||||
|
|
||||||
const Event = {
|
const EVENT_ACTIVATE = `activate${EVENT_KEY}`
|
||||||
ACTIVATE: `activate${EVENT_KEY}`,
|
const EVENT_SCROLL = `scroll${EVENT_KEY}`
|
||||||
SCROLL: `scroll${EVENT_KEY}`,
|
const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`
|
||||||
LOAD_DATA_API: `load${EVENT_KEY}${DATA_API_KEY}`
|
|
||||||
}
|
|
||||||
|
|
||||||
const ClassName = {
|
const CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item'
|
||||||
DROPDOWN_ITEM: 'dropdown-item',
|
const CLASS_NAME_ACTIVE = 'active'
|
||||||
ACTIVE: 'active'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Selector = {
|
const SELECTOR_DATA_SPY = '[data-spy="scroll"]'
|
||||||
DATA_SPY: '[data-spy="scroll"]',
|
const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'
|
||||||
NAV_LIST_GROUP: '.nav, .list-group',
|
const SELECTOR_NAV_LINKS = '.nav-link'
|
||||||
NAV_LINKS: '.nav-link',
|
const SELECTOR_NAV_ITEMS = '.nav-item'
|
||||||
NAV_ITEMS: '.nav-item',
|
const SELECTOR_LIST_ITEMS = '.list-group-item'
|
||||||
LIST_ITEMS: '.list-group-item',
|
const SELECTOR_DROPDOWN = '.dropdown'
|
||||||
DROPDOWN: '.dropdown',
|
const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'
|
||||||
DROPDOWN_TOGGLE: '.dropdown-toggle'
|
|
||||||
}
|
|
||||||
|
|
||||||
const OffsetMethod = {
|
const METHOD_OFFSET = 'offset'
|
||||||
OFFSET: 'offset',
|
const METHOD_POSITION = 'position'
|
||||||
POSITION: 'position'
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ------------------------------------------------------------------------
|
* ------------------------------------------------------------------------
|
||||||
|
@ -78,15 +70,15 @@ class ScrollSpy {
|
||||||
this._element = element
|
this._element = element
|
||||||
this._scrollElement = element.tagName === 'BODY' ? window : element
|
this._scrollElement = element.tagName === 'BODY' ? window : element
|
||||||
this._config = this._getConfig(config)
|
this._config = this._getConfig(config)
|
||||||
this._selector = `${this._config.target} ${Selector.NAV_LINKS},` +
|
this._selector = `${this._config.target} ${SELECTOR_NAV_LINKS},` +
|
||||||
`${this._config.target} ${Selector.LIST_ITEMS},` +
|
`${this._config.target} ${SELECTOR_LIST_ITEMS},` +
|
||||||
`${this._config.target} .${ClassName.DROPDOWN_ITEM}`
|
`${this._config.target} .${CLASS_NAME_DROPDOWN_ITEM}`
|
||||||
this._offsets = []
|
this._offsets = []
|
||||||
this._targets = []
|
this._targets = []
|
||||||
this._activeTarget = null
|
this._activeTarget = null
|
||||||
this._scrollHeight = 0
|
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.refresh()
|
||||||
this._process()
|
this._process()
|
||||||
|
@ -108,14 +100,14 @@ class ScrollSpy {
|
||||||
|
|
||||||
refresh() {
|
refresh() {
|
||||||
const autoMethod = this._scrollElement === this._scrollElement.window ?
|
const autoMethod = this._scrollElement === this._scrollElement.window ?
|
||||||
OffsetMethod.OFFSET :
|
METHOD_OFFSET :
|
||||||
OffsetMethod.POSITION
|
METHOD_POSITION
|
||||||
|
|
||||||
const offsetMethod = this._config.method === 'auto' ?
|
const offsetMethod = this._config.method === 'auto' ?
|
||||||
autoMethod :
|
autoMethod :
|
||||||
this._config.method
|
this._config.method
|
||||||
|
|
||||||
const offsetBase = offsetMethod === OffsetMethod.POSITION ?
|
const offsetBase = offsetMethod === METHOD_POSITION ?
|
||||||
this._getScrollTop() :
|
this._getScrollTop() :
|
||||||
0
|
0
|
||||||
|
|
||||||
|
@ -261,42 +253,42 @@ class ScrollSpy {
|
||||||
|
|
||||||
const link = SelectorEngine.findOne(queries.join(','))
|
const link = SelectorEngine.findOne(queries.join(','))
|
||||||
|
|
||||||
if (link.classList.contains(ClassName.DROPDOWN_ITEM)) {
|
if (link.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {
|
||||||
SelectorEngine
|
SelectorEngine
|
||||||
.findOne(Selector.DROPDOWN_TOGGLE, SelectorEngine.closest(link, Selector.DROPDOWN))
|
.findOne(SELECTOR_DROPDOWN_TOGGLE, SelectorEngine.closest(link, SELECTOR_DROPDOWN))
|
||||||
.classList.add(ClassName.ACTIVE)
|
.classList.add(CLASS_NAME_ACTIVE)
|
||||||
|
|
||||||
link.classList.add(ClassName.ACTIVE)
|
link.classList.add(CLASS_NAME_ACTIVE)
|
||||||
} else {
|
} else {
|
||||||
// Set triggered link as active
|
// Set triggered link as active
|
||||||
link.classList.add(ClassName.ACTIVE)
|
link.classList.add(CLASS_NAME_ACTIVE)
|
||||||
|
|
||||||
SelectorEngine
|
SelectorEngine
|
||||||
.parents(link, Selector.NAV_LIST_GROUP)
|
.parents(link, SELECTOR_NAV_LIST_GROUP)
|
||||||
.forEach(listGroup => {
|
.forEach(listGroup => {
|
||||||
// Set triggered links parents as active
|
// Set triggered links parents as active
|
||||||
// With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
|
// 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}`)
|
SelectorEngine.prev(listGroup, `${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`)
|
||||||
.forEach(item => item.classList.add(ClassName.ACTIVE))
|
.forEach(item => item.classList.add(CLASS_NAME_ACTIVE))
|
||||||
|
|
||||||
// Handle special case when .nav-link is inside .nav-item
|
// Handle special case when .nav-link is inside .nav-item
|
||||||
SelectorEngine.prev(listGroup, Selector.NAV_ITEMS)
|
SelectorEngine.prev(listGroup, SELECTOR_NAV_ITEMS)
|
||||||
.forEach(navItem => {
|
.forEach(navItem => {
|
||||||
SelectorEngine.children(navItem, Selector.NAV_LINKS)
|
SelectorEngine.children(navItem, SELECTOR_NAV_LINKS)
|
||||||
.forEach(item => item.classList.add(ClassName.ACTIVE))
|
.forEach(item => item.classList.add(CLASS_NAME_ACTIVE))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
EventHandler.trigger(this._scrollElement, Event.ACTIVATE, {
|
EventHandler.trigger(this._scrollElement, EVENT_ACTIVATE, {
|
||||||
relatedTarget: target
|
relatedTarget: target
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
_clear() {
|
_clear() {
|
||||||
makeArray(SelectorEngine.find(this._selector))
|
makeArray(SelectorEngine.find(this._selector))
|
||||||
.filter(node => node.classList.contains(ClassName.ACTIVE))
|
.filter(node => node.classList.contains(CLASS_NAME_ACTIVE))
|
||||||
.forEach(node => node.classList.remove(ClassName.ACTIVE))
|
.forEach(node => node.classList.remove(CLASS_NAME_ACTIVE))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Static
|
// Static
|
||||||
|
@ -331,8 +323,8 @@ class ScrollSpy {
|
||||||
* ------------------------------------------------------------------------
|
* ------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
EventHandler.on(window, Event.LOAD_DATA_API, () => {
|
EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
|
||||||
makeArray(SelectorEngine.find(Selector.DATA_SPY))
|
makeArray(SelectorEngine.find(SELECTOR_DATA_SPY))
|
||||||
.forEach(spy => new ScrollSpy(spy, Manipulator.getDataAttributes(spy)))
|
.forEach(spy => new ScrollSpy(spy, Manipulator.getDataAttributes(spy)))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -30,31 +30,25 @@ const DATA_KEY = 'bs.tab'
|
||||||
const EVENT_KEY = `.${DATA_KEY}`
|
const EVENT_KEY = `.${DATA_KEY}`
|
||||||
const DATA_API_KEY = '.data-api'
|
const DATA_API_KEY = '.data-api'
|
||||||
|
|
||||||
const Event = {
|
const EVENT_HIDE = `hide${EVENT_KEY}`
|
||||||
HIDE: `hide${EVENT_KEY}`,
|
const EVENT_HIDDEN = `hidden${EVENT_KEY}`
|
||||||
HIDDEN: `hidden${EVENT_KEY}`,
|
const EVENT_SHOW = `show${EVENT_KEY}`
|
||||||
SHOW: `show${EVENT_KEY}`,
|
const EVENT_SHOWN = `shown${EVENT_KEY}`
|
||||||
SHOWN: `shown${EVENT_KEY}`,
|
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
|
||||||
CLICK_DATA_API: `click${EVENT_KEY}${DATA_API_KEY}`
|
|
||||||
}
|
|
||||||
|
|
||||||
const ClassName = {
|
const CLASS_NAME_DROPDOWN_MENU = 'dropdown-menu'
|
||||||
DROPDOWN_MENU: 'dropdown-menu',
|
const CLASS_NAME_ACTIVE = 'active'
|
||||||
ACTIVE: 'active',
|
const CLASS_NAME_DISABLED = 'disabled'
|
||||||
DISABLED: 'disabled',
|
const CLASS_NAME_FADE = 'fade'
|
||||||
FADE: 'fade',
|
const CLASS_NAME_SHOW = 'show'
|
||||||
SHOW: 'show'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Selector = {
|
const SELECTOR_DROPDOWN = '.dropdown'
|
||||||
DROPDOWN: '.dropdown',
|
const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'
|
||||||
NAV_LIST_GROUP: '.nav, .list-group',
|
const SELECTOR_ACTIVE = '.active'
|
||||||
ACTIVE: '.active',
|
const SELECTOR_ACTIVE_UL = ':scope > li > .active'
|
||||||
ACTIVE_UL: ':scope > li > .active',
|
const SELECTOR_DATA_TOGGLE = '[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]'
|
||||||
DATA_TOGGLE: '[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',
|
const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'
|
||||||
DROPDOWN_TOGGLE: '.dropdown-toggle',
|
const SELECTOR_DROPDOWN_ACTIVE_CHILD = ':scope > .dropdown-menu .active'
|
||||||
DROPDOWN_ACTIVE_CHILD: ':scope > .dropdown-menu .active'
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ------------------------------------------------------------------------
|
* ------------------------------------------------------------------------
|
||||||
|
@ -80,17 +74,17 @@ class Tab {
|
||||||
show() {
|
show() {
|
||||||
if ((this._element.parentNode &&
|
if ((this._element.parentNode &&
|
||||||
this._element.parentNode.nodeType === Node.ELEMENT_NODE &&
|
this._element.parentNode.nodeType === Node.ELEMENT_NODE &&
|
||||||
this._element.classList.contains(ClassName.ACTIVE)) ||
|
this._element.classList.contains(CLASS_NAME_ACTIVE)) ||
|
||||||
this._element.classList.contains(ClassName.DISABLED)) {
|
this._element.classList.contains(CLASS_NAME_DISABLED)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let previous
|
let previous
|
||||||
const target = getElementFromSelector(this._element)
|
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) {
|
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 = makeArray(SelectorEngine.find(itemSelector, listElement))
|
||||||
previous = previous[previous.length - 1]
|
previous = previous[previous.length - 1]
|
||||||
}
|
}
|
||||||
|
@ -98,12 +92,12 @@ class Tab {
|
||||||
let hideEvent = null
|
let hideEvent = null
|
||||||
|
|
||||||
if (previous) {
|
if (previous) {
|
||||||
hideEvent = EventHandler.trigger(previous, Event.HIDE, {
|
hideEvent = EventHandler.trigger(previous, EVENT_HIDE, {
|
||||||
relatedTarget: this._element
|
relatedTarget: this._element
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const showEvent = EventHandler.trigger(this._element, Event.SHOW, {
|
const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, {
|
||||||
relatedTarget: previous
|
relatedTarget: previous
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -118,10 +112,10 @@ class Tab {
|
||||||
)
|
)
|
||||||
|
|
||||||
const complete = () => {
|
const complete = () => {
|
||||||
EventHandler.trigger(previous, Event.HIDDEN, {
|
EventHandler.trigger(previous, EVENT_HIDDEN, {
|
||||||
relatedTarget: this._element
|
relatedTarget: this._element
|
||||||
})
|
})
|
||||||
EventHandler.trigger(this._element, Event.SHOWN, {
|
EventHandler.trigger(this._element, EVENT_SHOWN, {
|
||||||
relatedTarget: previous
|
relatedTarget: previous
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -142,12 +136,12 @@ class Tab {
|
||||||
|
|
||||||
_activate(element, container, callback) {
|
_activate(element, container, callback) {
|
||||||
const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ?
|
const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ?
|
||||||
SelectorEngine.find(Selector.ACTIVE_UL, container) :
|
SelectorEngine.find(SELECTOR_ACTIVE_UL, container) :
|
||||||
SelectorEngine.children(container, Selector.ACTIVE)
|
SelectorEngine.children(container, SELECTOR_ACTIVE)
|
||||||
|
|
||||||
const active = activeElements[0]
|
const active = activeElements[0]
|
||||||
const isTransitioning = callback &&
|
const isTransitioning = callback &&
|
||||||
(active && active.classList.contains(ClassName.FADE))
|
(active && active.classList.contains(CLASS_NAME_FADE))
|
||||||
|
|
||||||
const complete = () => this._transitionComplete(
|
const complete = () => this._transitionComplete(
|
||||||
element,
|
element,
|
||||||
|
@ -157,7 +151,7 @@ class Tab {
|
||||||
|
|
||||||
if (active && isTransitioning) {
|
if (active && isTransitioning) {
|
||||||
const transitionDuration = getTransitionDurationFromElement(active)
|
const transitionDuration = getTransitionDurationFromElement(active)
|
||||||
active.classList.remove(ClassName.SHOW)
|
active.classList.remove(CLASS_NAME_SHOW)
|
||||||
|
|
||||||
EventHandler.one(active, TRANSITION_END, complete)
|
EventHandler.one(active, TRANSITION_END, complete)
|
||||||
emulateTransitionEnd(active, transitionDuration)
|
emulateTransitionEnd(active, transitionDuration)
|
||||||
|
@ -168,12 +162,12 @@ class Tab {
|
||||||
|
|
||||||
_transitionComplete(element, active, callback) {
|
_transitionComplete(element, active, callback) {
|
||||||
if (active) {
|
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) {
|
if (dropdownChild) {
|
||||||
dropdownChild.classList.remove(ClassName.ACTIVE)
|
dropdownChild.classList.remove(CLASS_NAME_ACTIVE)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (active.getAttribute('role') === 'tab') {
|
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') {
|
if (element.getAttribute('role') === 'tab') {
|
||||||
element.setAttribute('aria-selected', true)
|
element.setAttribute('aria-selected', true)
|
||||||
}
|
}
|
||||||
|
|
||||||
reflow(element)
|
reflow(element)
|
||||||
|
|
||||||
if (element.classList.contains(ClassName.FADE)) {
|
if (element.classList.contains(CLASS_NAME_FADE)) {
|
||||||
element.classList.add(ClassName.SHOW)
|
element.classList.add(CLASS_NAME_SHOW)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (element.parentNode && element.parentNode.classList.contains(ClassName.DROPDOWN_MENU)) {
|
if (element.parentNode && element.parentNode.classList.contains(CLASS_NAME_DROPDOWN_MENU)) {
|
||||||
const dropdownElement = SelectorEngine.closest(element, Selector.DROPDOWN)
|
const dropdownElement = SelectorEngine.closest(element, SELECTOR_DROPDOWN)
|
||||||
|
|
||||||
if (dropdownElement) {
|
if (dropdownElement) {
|
||||||
makeArray(SelectorEngine.find(Selector.DROPDOWN_TOGGLE))
|
makeArray(SelectorEngine.find(SELECTOR_DROPDOWN_TOGGLE))
|
||||||
.forEach(dropdown => dropdown.classList.add(ClassName.ACTIVE))
|
.forEach(dropdown => dropdown.classList.add(CLASS_NAME_ACTIVE))
|
||||||
}
|
}
|
||||||
|
|
||||||
element.setAttribute('aria-expanded', true)
|
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()
|
event.preventDefault()
|
||||||
|
|
||||||
const data = Data.getData(this, DATA_KEY) || new Tab(this)
|
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 DATA_KEY = 'bs.toast'
|
||||||
const EVENT_KEY = `.${DATA_KEY}`
|
const EVENT_KEY = `.${DATA_KEY}`
|
||||||
|
|
||||||
const Event = {
|
const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`
|
||||||
CLICK_DISMISS: `click.dismiss${EVENT_KEY}`,
|
const EVENT_HIDE = `hide${EVENT_KEY}`
|
||||||
HIDE: `hide${EVENT_KEY}`,
|
const EVENT_HIDDEN = `hidden${EVENT_KEY}`
|
||||||
HIDDEN: `hidden${EVENT_KEY}`,
|
const EVENT_SHOW = `show${EVENT_KEY}`
|
||||||
SHOW: `show${EVENT_KEY}`,
|
const EVENT_SHOWN = `shown${EVENT_KEY}`
|
||||||
SHOWN: `shown${EVENT_KEY}`
|
|
||||||
}
|
|
||||||
|
|
||||||
const ClassName = {
|
const CLASS_NAME_FADE = 'fade'
|
||||||
FADE: 'fade',
|
const CLASS_NAME_HIDE = 'hide'
|
||||||
HIDE: 'hide',
|
const CLASS_NAME_SHOW = 'show'
|
||||||
SHOW: 'show',
|
const CLASS_NAME_SHOWING = 'showing'
|
||||||
SHOWING: 'showing'
|
|
||||||
}
|
|
||||||
|
|
||||||
const DefaultType = {
|
const DefaultType = {
|
||||||
animation: 'boolean',
|
animation: 'boolean',
|
||||||
|
@ -55,9 +51,7 @@ const Default = {
|
||||||
delay: 500
|
delay: 500
|
||||||
}
|
}
|
||||||
|
|
||||||
const Selector = {
|
const SELECTOR_DATA_DISMISS = '[data-dismiss="toast"]'
|
||||||
DATA_DISMISS: '[data-dismiss="toast"]'
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ------------------------------------------------------------------------
|
* ------------------------------------------------------------------------
|
||||||
|
@ -91,21 +85,21 @@ class Toast {
|
||||||
// Public
|
// Public
|
||||||
|
|
||||||
show() {
|
show() {
|
||||||
const showEvent = EventHandler.trigger(this._element, Event.SHOW)
|
const showEvent = EventHandler.trigger(this._element, EVENT_SHOW)
|
||||||
|
|
||||||
if (showEvent.defaultPrevented) {
|
if (showEvent.defaultPrevented) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._config.animation) {
|
if (this._config.animation) {
|
||||||
this._element.classList.add(ClassName.FADE)
|
this._element.classList.add(CLASS_NAME_FADE)
|
||||||
}
|
}
|
||||||
|
|
||||||
const complete = () => {
|
const complete = () => {
|
||||||
this._element.classList.remove(ClassName.SHOWING)
|
this._element.classList.remove(CLASS_NAME_SHOWING)
|
||||||
this._element.classList.add(ClassName.SHOW)
|
this._element.classList.add(CLASS_NAME_SHOW)
|
||||||
|
|
||||||
EventHandler.trigger(this._element, Event.SHOWN)
|
EventHandler.trigger(this._element, EVENT_SHOWN)
|
||||||
|
|
||||||
if (this._config.autohide) {
|
if (this._config.autohide) {
|
||||||
this._timeout = setTimeout(() => {
|
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)
|
reflow(this._element)
|
||||||
this._element.classList.add(ClassName.SHOWING)
|
this._element.classList.add(CLASS_NAME_SHOWING)
|
||||||
if (this._config.animation) {
|
if (this._config.animation) {
|
||||||
const transitionDuration = getTransitionDurationFromElement(this._element)
|
const transitionDuration = getTransitionDurationFromElement(this._element)
|
||||||
|
|
||||||
|
@ -128,22 +122,22 @@ class Toast {
|
||||||
}
|
}
|
||||||
|
|
||||||
hide() {
|
hide() {
|
||||||
if (!this._element.classList.contains(ClassName.SHOW)) {
|
if (!this._element.classList.contains(CLASS_NAME_SHOW)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const hideEvent = EventHandler.trigger(this._element, Event.HIDE)
|
const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE)
|
||||||
|
|
||||||
if (hideEvent.defaultPrevented) {
|
if (hideEvent.defaultPrevented) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const complete = () => {
|
const complete = () => {
|
||||||
this._element.classList.add(ClassName.HIDE)
|
this._element.classList.add(CLASS_NAME_HIDE)
|
||||||
EventHandler.trigger(this._element, Event.HIDDEN)
|
EventHandler.trigger(this._element, EVENT_HIDDEN)
|
||||||
}
|
}
|
||||||
|
|
||||||
this._element.classList.remove(ClassName.SHOW)
|
this._element.classList.remove(CLASS_NAME_SHOW)
|
||||||
if (this._config.animation) {
|
if (this._config.animation) {
|
||||||
const transitionDuration = getTransitionDurationFromElement(this._element)
|
const transitionDuration = getTransitionDurationFromElement(this._element)
|
||||||
|
|
||||||
|
@ -158,11 +152,11 @@ class Toast {
|
||||||
clearTimeout(this._timeout)
|
clearTimeout(this._timeout)
|
||||||
this._timeout = null
|
this._timeout = null
|
||||||
|
|
||||||
if (this._element.classList.contains(ClassName.SHOW)) {
|
if (this._element.classList.contains(CLASS_NAME_SHOW)) {
|
||||||
this._element.classList.remove(ClassName.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)
|
Data.removeData(this._element, DATA_KEY)
|
||||||
|
|
||||||
this._element = null
|
this._element = null
|
||||||
|
@ -190,8 +184,8 @@ class Toast {
|
||||||
_setListeners() {
|
_setListeners() {
|
||||||
EventHandler.on(
|
EventHandler.on(
|
||||||
this._element,
|
this._element,
|
||||||
Event.CLICK_DISMISS,
|
EVENT_CLICK_DISMISS,
|
||||||
Selector.DATA_DISMISS,
|
SELECTOR_DATA_DISMISS,
|
||||||
() => this.hide()
|
() => this.hide()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,11 +89,6 @@ const Default = {
|
||||||
popperConfig: null
|
popperConfig: null
|
||||||
}
|
}
|
||||||
|
|
||||||
const HoverState = {
|
|
||||||
SHOW: 'show',
|
|
||||||
OUT: 'out'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Event = {
|
const Event = {
|
||||||
HIDE: `hide${EVENT_KEY}`,
|
HIDE: `hide${EVENT_KEY}`,
|
||||||
HIDDEN: `hidden${EVENT_KEY}`,
|
HIDDEN: `hidden${EVENT_KEY}`,
|
||||||
|
@ -107,22 +102,19 @@ const Event = {
|
||||||
MOUSELEAVE: `mouseleave${EVENT_KEY}`
|
MOUSELEAVE: `mouseleave${EVENT_KEY}`
|
||||||
}
|
}
|
||||||
|
|
||||||
const ClassName = {
|
const CLASS_NAME_FADE = 'fade'
|
||||||
FADE: 'fade',
|
const CLASS_NAME_MODAL = 'modal'
|
||||||
MODAL: 'modal',
|
const CLASS_NAME_SHOW = 'show'
|
||||||
SHOW: 'show'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Selector = {
|
const HOVER_STATE_SHOW = 'show'
|
||||||
TOOLTIP_INNER: '.tooltip-inner'
|
const HOVER_STATE_OUT = 'out'
|
||||||
}
|
|
||||||
|
|
||||||
const Trigger = {
|
const SELECTOR_TOOLTIP_INNER = '.tooltip-inner'
|
||||||
HOVER: 'hover',
|
|
||||||
FOCUS: 'focus',
|
const TRIGGER_HOVER = 'hover'
|
||||||
CLICK: 'click',
|
const TRIGGER_FOCUS = 'focus'
|
||||||
MANUAL: 'manual'
|
const TRIGGER_CLICK = 'click'
|
||||||
}
|
const TRIGGER_MANUAL = 'manual'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ------------------------------------------------------------------------
|
* ------------------------------------------------------------------------
|
||||||
|
@ -221,7 +213,7 @@ class Tooltip {
|
||||||
context._leave(null, context)
|
context._leave(null, context)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (this.getTipElement().classList.contains(ClassName.SHOW)) {
|
if (this.getTipElement().classList.contains(CLASS_NAME_SHOW)) {
|
||||||
this._leave(null, this)
|
this._leave(null, this)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -236,7 +228,7 @@ class Tooltip {
|
||||||
Data.removeData(this.element, this.constructor.DATA_KEY)
|
Data.removeData(this.element, this.constructor.DATA_KEY)
|
||||||
|
|
||||||
EventHandler.off(this.element, this.constructor.EVENT_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) {
|
if (this.tip) {
|
||||||
this.tip.parentNode.removeChild(this.tip)
|
this.tip.parentNode.removeChild(this.tip)
|
||||||
|
@ -281,7 +273,7 @@ class Tooltip {
|
||||||
this.setContent()
|
this.setContent()
|
||||||
|
|
||||||
if (this.config.animation) {
|
if (this.config.animation) {
|
||||||
tip.classList.add(ClassName.FADE)
|
tip.classList.add(CLASS_NAME_FADE)
|
||||||
}
|
}
|
||||||
|
|
||||||
const placement = typeof this.config.placement === 'function' ?
|
const placement = typeof this.config.placement === 'function' ?
|
||||||
|
@ -302,7 +294,7 @@ class Tooltip {
|
||||||
|
|
||||||
this._popper = new Popper(this.element, tip, this._getPopperConfig(attachment))
|
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
|
// If this is a touch-enabled device we add extra
|
||||||
// empty mouseover listeners to the body's immediate children;
|
// empty mouseover listeners to the body's immediate children;
|
||||||
|
@ -324,12 +316,12 @@ class Tooltip {
|
||||||
|
|
||||||
EventHandler.trigger(this.element, this.constructor.Event.SHOWN)
|
EventHandler.trigger(this.element, this.constructor.Event.SHOWN)
|
||||||
|
|
||||||
if (prevHoverState === HoverState.OUT) {
|
if (prevHoverState === HOVER_STATE_OUT) {
|
||||||
this._leave(null, this)
|
this._leave(null, this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.tip.classList.contains(ClassName.FADE)) {
|
if (this.tip.classList.contains(CLASS_NAME_FADE)) {
|
||||||
const transitionDuration = getTransitionDurationFromElement(this.tip)
|
const transitionDuration = getTransitionDurationFromElement(this.tip)
|
||||||
EventHandler.one(this.tip, TRANSITION_END, complete)
|
EventHandler.one(this.tip, TRANSITION_END, complete)
|
||||||
emulateTransitionEnd(this.tip, transitionDuration)
|
emulateTransitionEnd(this.tip, transitionDuration)
|
||||||
|
@ -342,7 +334,7 @@ class Tooltip {
|
||||||
hide() {
|
hide() {
|
||||||
const tip = this.getTipElement()
|
const tip = this.getTipElement()
|
||||||
const complete = () => {
|
const complete = () => {
|
||||||
if (this._hoverState !== HoverState.SHOW && tip.parentNode) {
|
if (this._hoverState !== HOVER_STATE_SHOW && tip.parentNode) {
|
||||||
tip.parentNode.removeChild(tip)
|
tip.parentNode.removeChild(tip)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,7 +349,7 @@ class Tooltip {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tip.classList.remove(ClassName.SHOW)
|
tip.classList.remove(CLASS_NAME_SHOW)
|
||||||
|
|
||||||
// If this is a touch-enabled device we remove the extra
|
// If this is a touch-enabled device we remove the extra
|
||||||
// empty mouseover listeners we added for iOS support
|
// empty mouseover listeners we added for iOS support
|
||||||
|
@ -366,11 +358,11 @@ class Tooltip {
|
||||||
.forEach(element => EventHandler.off(element, 'mouseover', noop))
|
.forEach(element => EventHandler.off(element, 'mouseover', noop))
|
||||||
}
|
}
|
||||||
|
|
||||||
this._activeTrigger[Trigger.CLICK] = false
|
this._activeTrigger[TRIGGER_CLICK] = false
|
||||||
this._activeTrigger[Trigger.FOCUS] = false
|
this._activeTrigger[TRIGGER_FOCUS] = false
|
||||||
this._activeTrigger[Trigger.HOVER] = 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)
|
const transitionDuration = getTransitionDurationFromElement(tip)
|
||||||
|
|
||||||
EventHandler.one(tip, TRANSITION_END, complete)
|
EventHandler.one(tip, TRANSITION_END, complete)
|
||||||
|
@ -408,9 +400,9 @@ class Tooltip {
|
||||||
|
|
||||||
setContent() {
|
setContent() {
|
||||||
const tip = this.getTipElement()
|
const tip = this.getTipElement()
|
||||||
this.setElementContent(SelectorEngine.findOne(Selector.TOOLTIP_INNER, tip), this.getTitle())
|
this.setElementContent(SelectorEngine.findOne(SELECTOR_TOOLTIP_INNER, tip), this.getTitle())
|
||||||
tip.classList.remove(ClassName.FADE)
|
tip.classList.remove(CLASS_NAME_FADE)
|
||||||
tip.classList.remove(ClassName.SHOW)
|
tip.classList.remove(CLASS_NAME_SHOW)
|
||||||
}
|
}
|
||||||
|
|
||||||
setElementContent(element, content) {
|
setElementContent(element, content) {
|
||||||
|
@ -539,11 +531,11 @@ class Tooltip {
|
||||||
this.config.selector,
|
this.config.selector,
|
||||||
event => this.toggle(event)
|
event => this.toggle(event)
|
||||||
)
|
)
|
||||||
} else if (trigger !== Trigger.MANUAL) {
|
} else if (trigger !== TRIGGER_MANUAL) {
|
||||||
const eventIn = trigger === Trigger.HOVER ?
|
const eventIn = trigger === TRIGGER_HOVER ?
|
||||||
this.constructor.Event.MOUSEENTER :
|
this.constructor.Event.MOUSEENTER :
|
||||||
this.constructor.Event.FOCUSIN
|
this.constructor.Event.FOCUSIN
|
||||||
const eventOut = trigger === Trigger.HOVER ?
|
const eventOut = trigger === TRIGGER_HOVER ?
|
||||||
this.constructor.Event.MOUSELEAVE :
|
this.constructor.Event.MOUSELEAVE :
|
||||||
this.constructor.Event.FOCUSOUT
|
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',
|
'hide.bs.modal',
|
||||||
this._hideModalHandler
|
this._hideModalHandler
|
||||||
)
|
)
|
||||||
|
@ -609,19 +601,19 @@ class Tooltip {
|
||||||
|
|
||||||
if (event) {
|
if (event) {
|
||||||
context._activeTrigger[
|
context._activeTrigger[
|
||||||
event.type === 'focusin' ? Trigger.FOCUS : Trigger.HOVER
|
event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER
|
||||||
] = true
|
] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.getTipElement().classList.contains(ClassName.SHOW) ||
|
if (context.getTipElement().classList.contains(CLASS_NAME_SHOW) ||
|
||||||
context._hoverState === HoverState.SHOW) {
|
context._hoverState === HOVER_STATE_SHOW) {
|
||||||
context._hoverState = HoverState.SHOW
|
context._hoverState = HOVER_STATE_SHOW
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
clearTimeout(context._timeout)
|
clearTimeout(context._timeout)
|
||||||
|
|
||||||
context._hoverState = HoverState.SHOW
|
context._hoverState = HOVER_STATE_SHOW
|
||||||
|
|
||||||
if (!context.config.delay || !context.config.delay.show) {
|
if (!context.config.delay || !context.config.delay.show) {
|
||||||
context.show()
|
context.show()
|
||||||
|
@ -629,7 +621,7 @@ class Tooltip {
|
||||||
}
|
}
|
||||||
|
|
||||||
context._timeout = setTimeout(() => {
|
context._timeout = setTimeout(() => {
|
||||||
if (context._hoverState === HoverState.SHOW) {
|
if (context._hoverState === HOVER_STATE_SHOW) {
|
||||||
context.show()
|
context.show()
|
||||||
}
|
}
|
||||||
}, context.config.delay.show)
|
}, context.config.delay.show)
|
||||||
|
@ -649,7 +641,7 @@ class Tooltip {
|
||||||
|
|
||||||
if (event) {
|
if (event) {
|
||||||
context._activeTrigger[
|
context._activeTrigger[
|
||||||
event.type === 'focusout' ? Trigger.FOCUS : Trigger.HOVER
|
event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER
|
||||||
] = false
|
] = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -659,7 +651,7 @@ class Tooltip {
|
||||||
|
|
||||||
clearTimeout(context._timeout)
|
clearTimeout(context._timeout)
|
||||||
|
|
||||||
context._hoverState = HoverState.OUT
|
context._hoverState = HOVER_STATE_OUT
|
||||||
|
|
||||||
if (!context.config.delay || !context.config.delay.hide) {
|
if (!context.config.delay || !context.config.delay.hide) {
|
||||||
context.hide()
|
context.hide()
|
||||||
|
@ -667,7 +659,7 @@ class Tooltip {
|
||||||
}
|
}
|
||||||
|
|
||||||
context._timeout = setTimeout(() => {
|
context._timeout = setTimeout(() => {
|
||||||
if (context._hoverState === HoverState.OUT) {
|
if (context._hoverState === HOVER_STATE_OUT) {
|
||||||
context.hide()
|
context.hide()
|
||||||
}
|
}
|
||||||
}, context.config.delay.hide)
|
}, context.config.delay.hide)
|
||||||
|
@ -768,7 +760,7 @@ class Tooltip {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tip.classList.remove(ClassName.FADE)
|
tip.classList.remove(CLASS_NAME_FADE)
|
||||||
this.config.animation = false
|
this.config.animation = false
|
||||||
this.hide()
|
this.hide()
|
||||||
this.show()
|
this.show()
|
||||||
|
|
Loading…
Reference in New Issue