Switch to string constants. (#30490)

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     22.09 kB    21.13 kB    -0.96 kB (-4.35 %)
bootstrap.min.js            15.4 kB     14.46 kB    -0.94 kB (-3.86 %)
This commit is contained in:
XhmikosR 2020-03-31 21:27:35 +03:00 committed by GitHub
parent 0225c1173b
commit f7ed579d91
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 457 additions and 539 deletions

View File

@ -30,7 +30,7 @@
},
{
"path": "./dist/js/bootstrap.bundle.min.js",
"maxSize": "22.25 kB"
"maxSize": "21.5 kB"
},
{
"path": "./dist/js/bootstrap.js",
@ -38,7 +38,7 @@
},
{
"path": "./dist/js/bootstrap.min.js",
"maxSize": "15.75 kB"
"maxSize": "14.75 kB"
}
]
}

View File

@ -21,21 +21,15 @@ const EVENT_KEY = `.${DATA_KEY}`
const DATA_API_KEY = '.data-api'
const JQUERY_NO_CONFLICT = $.fn[NAME]
const Selector = {
DISMISS : '[data-dismiss="alert"]'
}
const SELECTOR_DISMISS = '[data-dismiss="alert"]'
const Event = {
CLOSE : `close${EVENT_KEY}`,
CLOSED : `closed${EVENT_KEY}`,
CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`
}
const EVENT_CLOSE = `close${EVENT_KEY}`
const EVENT_CLOSED = `closed${EVENT_KEY}`
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
const ClassName = {
ALERT : 'alert',
FADE : 'fade',
SHOW : 'show'
}
const CLASS_NAME_ALERT = 'alert'
const CLASS_NAME_FADE = 'fade'
const CLASS_NAME_SHOW = 'show'
/**
* ------------------------------------------------------------------------
@ -87,23 +81,23 @@ class Alert {
}
if (!parent) {
parent = $(element).closest(`.${ClassName.ALERT}`)[0]
parent = $(element).closest(`.${CLASS_NAME_ALERT}`)[0]
}
return parent
}
_triggerCloseEvent(element) {
const closeEvent = $.Event(Event.CLOSE)
const closeEvent = $.Event(EVENT_CLOSE)
$(element).trigger(closeEvent)
return closeEvent
}
_removeElement(element) {
$(element).removeClass(ClassName.SHOW)
$(element).removeClass(CLASS_NAME_SHOW)
if (!$(element).hasClass(ClassName.FADE)) {
if (!$(element).hasClass(CLASS_NAME_FADE)) {
this._destroyElement(element)
return
}
@ -118,7 +112,7 @@ class Alert {
_destroyElement(element) {
$(element)
.detach()
.trigger(Event.CLOSED)
.trigger(EVENT_CLOSED)
.remove()
}
@ -158,8 +152,8 @@ class Alert {
*/
$(document).on(
Event.CLICK_DATA_API,
Selector.DISMISS,
EVENT_CLICK_DATA_API,
SELECTOR_DISMISS,
Alert._handleDismiss(new Alert())
)

View File

@ -20,28 +20,22 @@ const EVENT_KEY = `.${DATA_KEY}`
const DATA_API_KEY = '.data-api'
const JQUERY_NO_CONFLICT = $.fn[NAME]
const ClassName = {
ACTIVE : 'active',
BUTTON : 'btn',
FOCUS : 'focus'
}
const CLASS_NAME_ACTIVE = 'active'
const CLASS_NAME_BUTTON = 'btn'
const CLASS_NAME_FOCUS = 'focus'
const Selector = {
DATA_TOGGLE_CARROT : '[data-toggle^="button"]',
DATA_TOGGLES : '[data-toggle="buttons"]',
DATA_TOGGLE : '[data-toggle="button"]',
DATA_TOGGLES_BUTTONS : '[data-toggle="buttons"] .btn',
INPUT : 'input:not([type="hidden"])',
ACTIVE : '.active',
BUTTON : '.btn'
}
const SELECTOR_DATA_TOGGLE_CARROT = '[data-toggle^="button"]'
const SELECTOR_DATA_TOGGLES = '[data-toggle="buttons"]'
const SELECTOR_DATA_TOGGLE = '[data-toggle="button"]'
const SELECTOR_DATA_TOGGLES_BUTTONS = '[data-toggle="buttons"] .btn'
const SELECTOR_INPUT = 'input:not([type="hidden"])'
const SELECTOR_ACTIVE = '.active'
const SELECTOR_BUTTON = '.btn'
const Event = {
CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`,
FOCUS_BLUR_DATA_API : `focus${EVENT_KEY}${DATA_API_KEY} ` +
`blur${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}`
const EVENT_FOCUS_BLUR_DATA_API = `focus${EVENT_KEY}${DATA_API_KEY} ` +
`blur${EVENT_KEY}${DATA_API_KEY}`
const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`
/**
* ------------------------------------------------------------------------
@ -66,22 +60,22 @@ class Button {
let triggerChangeEvent = true
let addAriaPressed = true
const rootElement = $(this._element).closest(
Selector.DATA_TOGGLES
SELECTOR_DATA_TOGGLES
)[0]
if (rootElement) {
const input = this._element.querySelector(Selector.INPUT)
const input = this._element.querySelector(SELECTOR_INPUT)
if (input) {
if (input.type === 'radio') {
if (input.checked &&
this._element.classList.contains(ClassName.ACTIVE)) {
this._element.classList.contains(CLASS_NAME_ACTIVE)) {
triggerChangeEvent = false
} else {
const activeElement = rootElement.querySelector(Selector.ACTIVE)
const activeElement = rootElement.querySelector(SELECTOR_ACTIVE)
if (activeElement) {
$(activeElement).removeClass(ClassName.ACTIVE)
$(activeElement).removeClass(CLASS_NAME_ACTIVE)
}
}
}
@ -89,7 +83,7 @@ class Button {
if (triggerChangeEvent) {
// if it's not a radio button or checkbox don't add a pointless/invalid checked property to the input
if (input.type === 'checkbox' || input.type === 'radio') {
input.checked = !this._element.classList.contains(ClassName.ACTIVE)
input.checked = !this._element.classList.contains(CLASS_NAME_ACTIVE)
}
$(input).trigger('change')
}
@ -102,11 +96,11 @@ class Button {
if (!(this._element.hasAttribute('disabled') || this._element.classList.contains('disabled'))) {
if (addAriaPressed) {
this._element.setAttribute('aria-pressed',
!this._element.classList.contains(ClassName.ACTIVE))
!this._element.classList.contains(CLASS_NAME_ACTIVE))
}
if (triggerChangeEvent) {
$(this._element).toggleClass(ClassName.ACTIVE)
$(this._element).toggleClass(CLASS_NAME_ACTIVE)
}
}
}
@ -141,18 +135,18 @@ class Button {
*/
$(document)
.on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE_CARROT, (event) => {
.on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, (event) => {
let button = event.target
const initialButton = button
if (!$(button).hasClass(ClassName.BUTTON)) {
button = $(button).closest(Selector.BUTTON)[0]
if (!$(button).hasClass(CLASS_NAME_BUTTON)) {
button = $(button).closest(SELECTOR_BUTTON)[0]
}
if (!button || button.hasAttribute('disabled') || button.classList.contains('disabled')) {
event.preventDefault() // work around Firefox bug #1540995
} else {
const inputBtn = button.querySelector(Selector.INPUT)
const inputBtn = button.querySelector(SELECTOR_INPUT)
if (inputBtn && (inputBtn.hasAttribute('disabled') || inputBtn.classList.contains('disabled'))) {
event.preventDefault() // work around Firefox bug #1540995
@ -165,34 +159,34 @@ $(document)
Button._jQueryInterface.call($(button), 'toggle')
}
})
.on(Event.FOCUS_BLUR_DATA_API, Selector.DATA_TOGGLE_CARROT, (event) => {
const button = $(event.target).closest(Selector.BUTTON)[0]
$(button).toggleClass(ClassName.FOCUS, /^focus(in)?$/.test(event.type))
.on(EVENT_FOCUS_BLUR_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, (event) => {
const button = $(event.target).closest(SELECTOR_BUTTON)[0]
$(button).toggleClass(CLASS_NAME_FOCUS, /^focus(in)?$/.test(event.type))
})
$(window).on(Event.LOAD_DATA_API, () => {
$(window).on(EVENT_LOAD_DATA_API, () => {
// ensure correct active class is set to match the controls' actual values/states
// find all checkboxes/readio buttons inside data-toggle groups
let buttons = [].slice.call(document.querySelectorAll(Selector.DATA_TOGGLES_BUTTONS))
let buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLES_BUTTONS))
for (let i = 0, len = buttons.length; i < len; i++) {
const button = buttons[i]
const input = button.querySelector(Selector.INPUT)
const input = button.querySelector(SELECTOR_INPUT)
if (input.checked || input.hasAttribute('checked')) {
button.classList.add(ClassName.ACTIVE)
button.classList.add(CLASS_NAME_ACTIVE)
} else {
button.classList.remove(ClassName.ACTIVE)
button.classList.remove(CLASS_NAME_ACTIVE)
}
}
// find all button toggles
buttons = [].slice.call(document.querySelectorAll(Selector.DATA_TOGGLE))
buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))
for (let i = 0, len = buttons.length; i < len; i++) {
const button = buttons[i]
if (button.getAttribute('aria-pressed') === 'true') {
button.classList.add(ClassName.ACTIVE)
button.classList.add(CLASS_NAME_ACTIVE)
} else {
button.classList.remove(ClassName.ACTIVE)
button.classList.remove(CLASS_NAME_ACTIVE)
}
}
})

View File

@ -43,51 +43,42 @@ const DefaultType = {
touch : 'boolean'
}
const Direction = {
NEXT : 'next',
PREV : 'prev',
LEFT : 'left',
RIGHT : 'right'
}
const DIRECTION_NEXT = 'next'
const DIRECTION_PREV = 'prev'
const DIRECTION_LEFT = 'left'
const DIRECTION_RIGHT = 'right'
const Event = {
SLIDE : `slide${EVENT_KEY}`,
SLID : `slid${EVENT_KEY}`,
KEYDOWN : `keydown${EVENT_KEY}`,
MOUSEENTER : `mouseenter${EVENT_KEY}`,
MOUSELEAVE : `mouseleave${EVENT_KEY}`,
TOUCHSTART : `touchstart${EVENT_KEY}`,
TOUCHMOVE : `touchmove${EVENT_KEY}`,
TOUCHEND : `touchend${EVENT_KEY}`,
POINTERDOWN : `pointerdown${EVENT_KEY}`,
POINTERUP : `pointerup${EVENT_KEY}`,
DRAG_START : `dragstart${EVENT_KEY}`,
LOAD_DATA_API : `load${EVENT_KEY}${DATA_API_KEY}`,
CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`
}
const EVENT_SLIDE = `slide${EVENT_KEY}`
const EVENT_SLID = `slid${EVENT_KEY}`
const EVENT_KEYDOWN = `keydown${EVENT_KEY}`
const EVENT_MOUSEENTER = `mouseenter${EVENT_KEY}`
const EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY}`
const EVENT_TOUCHSTART = `touchstart${EVENT_KEY}`
const EVENT_TOUCHMOVE = `touchmove${EVENT_KEY}`
const EVENT_TOUCHEND = `touchend${EVENT_KEY}`
const EVENT_POINTERDOWN = `pointerdown${EVENT_KEY}`
const EVENT_POINTERUP = `pointerup${EVENT_KEY}`
const EVENT_DRAG_START = `dragstart${EVENT_KEY}`
const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
const ClassName = {
CAROUSEL : 'carousel',
ACTIVE : 'active',
SLIDE : 'slide',
RIGHT : 'carousel-item-right',
LEFT : 'carousel-item-left',
NEXT : 'carousel-item-next',
PREV : 'carousel-item-prev',
ITEM : 'carousel-item',
POINTER_EVENT : 'pointer-event'
}
const CLASS_NAME_CAROUSEL = 'carousel'
const CLASS_NAME_ACTIVE = 'active'
const CLASS_NAME_SLIDE = 'slide'
const CLASS_NAME_RIGHT = 'carousel-item-right'
const CLASS_NAME_LEFT = 'carousel-item-left'
const CLASS_NAME_NEXT = 'carousel-item-next'
const CLASS_NAME_PREV = 'carousel-item-prev'
const CLASS_NAME_POINTER_EVENT = 'pointer-event'
const Selector = {
ACTIVE : '.active',
ACTIVE_ITEM : '.active.carousel-item',
ITEM : '.carousel-item',
ITEM_IMG : '.carousel-item img',
NEXT_PREV : '.carousel-item-next, .carousel-item-prev',
INDICATORS : '.carousel-indicators',
DATA_SLIDE : '[data-slide], [data-slide-to]',
DATA_RIDE : '[data-ride="carousel"]'
}
const SELECTOR_ACTIVE = '.active'
const SELECTOR_ACTIVE_ITEM = '.active.carousel-item'
const SELECTOR_ITEM = '.carousel-item'
const SELECTOR_ITEM_IMG = '.carousel-item img'
const SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev'
const SELECTOR_INDICATORS = '.carousel-indicators'
const SELECTOR_DATA_SLIDE = '[data-slide], [data-slide-to]'
const SELECTOR_DATA_RIDE = '[data-ride="carousel"]'
const PointerType = {
TOUCH : 'touch',
@ -112,7 +103,7 @@ class Carousel {
this._config = this._getConfig(config)
this._element = element
this._indicatorsElement = this._element.querySelector(Selector.INDICATORS)
this._indicatorsElement = this._element.querySelector(SELECTOR_INDICATORS)
this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0
this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent)
@ -133,7 +124,7 @@ class Carousel {
next() {
if (!this._isSliding) {
this._slide(Direction.NEXT)
this._slide(DIRECTION_NEXT)
}
}
@ -148,7 +139,7 @@ class Carousel {
prev() {
if (!this._isSliding) {
this._slide(Direction.PREV)
this._slide(DIRECTION_PREV)
}
}
@ -157,7 +148,7 @@ class Carousel {
this._isPaused = true
}
if (this._element.querySelector(Selector.NEXT_PREV)) {
if (this._element.querySelector(SELECTOR_NEXT_PREV)) {
Util.triggerTransitionEnd(this._element)
this.cycle(true)
}
@ -185,7 +176,7 @@ class Carousel {
}
to(index) {
this._activeElement = this._element.querySelector(Selector.ACTIVE_ITEM)
this._activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM)
const activeIndex = this._getItemIndex(this._activeElement)
@ -194,7 +185,7 @@ class Carousel {
}
if (this._isSliding) {
$(this._element).one(Event.SLID, () => this.to(index))
$(this._element).one(EVENT_SLID, () => this.to(index))
return
}
@ -205,8 +196,8 @@ class Carousel {
}
const direction = index > activeIndex
? Direction.NEXT
: Direction.PREV
? DIRECTION_NEXT
: DIRECTION_PREV
this._slide(direction, this._items[index])
}
@ -261,13 +252,13 @@ class Carousel {
_addEventListeners() {
if (this._config.keyboard) {
$(this._element)
.on(Event.KEYDOWN, (event) => this._keydown(event))
.on(EVENT_KEYDOWN, (event) => this._keydown(event))
}
if (this._config.pause === 'hover') {
$(this._element)
.on(Event.MOUSEENTER, (event) => this.pause(event))
.on(Event.MOUSELEAVE, (event) => this.cycle(event))
.on(EVENT_MOUSEENTER, (event) => this.pause(event))
.on(EVENT_MOUSELEAVE, (event) => this.cycle(event))
}
if (this._config.touch) {
@ -320,16 +311,16 @@ class Carousel {
}
}
$(this._element.querySelectorAll(Selector.ITEM_IMG)).on(Event.DRAG_START, (e) => e.preventDefault())
$(this._element.querySelectorAll(SELECTOR_ITEM_IMG)).on(EVENT_DRAG_START, (e) => e.preventDefault())
if (this._pointerEvent) {
$(this._element).on(Event.POINTERDOWN, (event) => start(event))
$(this._element).on(Event.POINTERUP, (event) => end(event))
$(this._element).on(EVENT_POINTERDOWN, (event) => start(event))
$(this._element).on(EVENT_POINTERUP, (event) => end(event))
this._element.classList.add(ClassName.POINTER_EVENT)
this._element.classList.add(CLASS_NAME_POINTER_EVENT)
} else {
$(this._element).on(Event.TOUCHSTART, (event) => start(event))
$(this._element).on(Event.TOUCHMOVE, (event) => move(event))
$(this._element).on(Event.TOUCHEND, (event) => end(event))
$(this._element).on(EVENT_TOUCHSTART, (event) => start(event))
$(this._element).on(EVENT_TOUCHMOVE, (event) => move(event))
$(this._element).on(EVENT_TOUCHEND, (event) => end(event))
}
}
@ -353,14 +344,14 @@ class Carousel {
_getItemIndex(element) {
this._items = element && element.parentNode
? [].slice.call(element.parentNode.querySelectorAll(Selector.ITEM))
? [].slice.call(element.parentNode.querySelectorAll(SELECTOR_ITEM))
: []
return this._items.indexOf(element)
}
_getItemByDirection(direction, activeElement) {
const isNextDirection = direction === Direction.NEXT
const isPrevDirection = direction === Direction.PREV
const isNextDirection = direction === DIRECTION_NEXT
const isPrevDirection = direction === DIRECTION_PREV
const activeIndex = this._getItemIndex(activeElement)
const lastItemIndex = this._items.length - 1
const isGoingToWrap = isPrevDirection && activeIndex === 0 ||
@ -370,7 +361,7 @@ class Carousel {
return activeElement
}
const delta = direction === Direction.PREV ? -1 : 1
const delta = direction === DIRECTION_PREV ? -1 : 1
const itemIndex = (activeIndex + delta) % this._items.length
return itemIndex === -1
@ -379,8 +370,8 @@ class Carousel {
_triggerSlideEvent(relatedTarget, eventDirectionName) {
const targetIndex = this._getItemIndex(relatedTarget)
const fromIndex = this._getItemIndex(this._element.querySelector(Selector.ACTIVE_ITEM))
const slideEvent = $.Event(Event.SLIDE, {
const fromIndex = this._getItemIndex(this._element.querySelector(SELECTOR_ACTIVE_ITEM))
const slideEvent = $.Event(EVENT_SLIDE, {
relatedTarget,
direction: eventDirectionName,
from: fromIndex,
@ -394,22 +385,22 @@ class Carousel {
_setActiveIndicatorElement(element) {
if (this._indicatorsElement) {
const indicators = [].slice.call(this._indicatorsElement.querySelectorAll(Selector.ACTIVE))
const indicators = [].slice.call(this._indicatorsElement.querySelectorAll(SELECTOR_ACTIVE))
$(indicators)
.removeClass(ClassName.ACTIVE)
.removeClass(CLASS_NAME_ACTIVE)
const nextIndicator = this._indicatorsElement.children[
this._getItemIndex(element)
]
if (nextIndicator) {
$(nextIndicator).addClass(ClassName.ACTIVE)
$(nextIndicator).addClass(CLASS_NAME_ACTIVE)
}
}
}
_slide(direction, element) {
const activeElement = this._element.querySelector(Selector.ACTIVE_ITEM)
const activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM)
const activeElementIndex = this._getItemIndex(activeElement)
const nextElement = element || activeElement &&
this._getItemByDirection(direction, activeElement)
@ -420,17 +411,17 @@ class Carousel {
let orderClassName
let eventDirectionName
if (direction === Direction.NEXT) {
directionalClassName = ClassName.LEFT
orderClassName = ClassName.NEXT
eventDirectionName = Direction.LEFT
if (direction === DIRECTION_NEXT) {
directionalClassName = CLASS_NAME_LEFT
orderClassName = CLASS_NAME_NEXT
eventDirectionName = DIRECTION_LEFT
} else {
directionalClassName = ClassName.RIGHT
orderClassName = ClassName.PREV
eventDirectionName = Direction.RIGHT
directionalClassName = CLASS_NAME_RIGHT
orderClassName = CLASS_NAME_PREV
eventDirectionName = DIRECTION_RIGHT
}
if (nextElement && $(nextElement).hasClass(ClassName.ACTIVE)) {
if (nextElement && $(nextElement).hasClass(CLASS_NAME_ACTIVE)) {
this._isSliding = false
return
}
@ -453,14 +444,14 @@ class Carousel {
this._setActiveIndicatorElement(nextElement)
const slidEvent = $.Event(Event.SLID, {
const slidEvent = $.Event(EVENT_SLID, {
relatedTarget: nextElement,
direction: eventDirectionName,
from: activeElementIndex,
to: nextElementIndex
})
if ($(this._element).hasClass(ClassName.SLIDE)) {
if ($(this._element).hasClass(CLASS_NAME_SLIDE)) {
$(nextElement).addClass(orderClassName)
Util.reflow(nextElement)
@ -482,9 +473,9 @@ class Carousel {
.one(Util.TRANSITION_END, () => {
$(nextElement)
.removeClass(`${directionalClassName} ${orderClassName}`)
.addClass(ClassName.ACTIVE)
.addClass(CLASS_NAME_ACTIVE)
$(activeElement).removeClass(`${ClassName.ACTIVE} ${orderClassName} ${directionalClassName}`)
$(activeElement).removeClass(`${CLASS_NAME_ACTIVE} ${orderClassName} ${directionalClassName}`)
this._isSliding = false
@ -492,8 +483,8 @@ class Carousel {
})
.emulateTransitionEnd(transitionDuration)
} else {
$(activeElement).removeClass(ClassName.ACTIVE)
$(nextElement).addClass(ClassName.ACTIVE)
$(activeElement).removeClass(CLASS_NAME_ACTIVE)
$(nextElement).addClass(CLASS_NAME_ACTIVE)
this._isSliding = false
$(this._element).trigger(slidEvent)
@ -551,7 +542,7 @@ class Carousel {
const target = $(selector)[0]
if (!target || !$(target).hasClass(ClassName.CAROUSEL)) {
if (!target || !$(target).hasClass(CLASS_NAME_CAROUSEL)) {
return
}
@ -582,10 +573,10 @@ class Carousel {
*/
$(document)
.on(Event.CLICK_DATA_API, Selector.DATA_SLIDE, Carousel._dataApiClickHandler)
.on(EVENT_CLICK_DATA_API, SELECTOR_DATA_SLIDE, Carousel._dataApiClickHandler)
$(window).on(Event.LOAD_DATA_API, () => {
const carousels = [].slice.call(document.querySelectorAll(Selector.DATA_RIDE))
$(window).on(EVENT_LOAD_DATA_API, () => {
const carousels = [].slice.call(document.querySelectorAll(SELECTOR_DATA_RIDE))
for (let i = 0, len = carousels.length; i < len; i++) {
const $carousel = $(carousels[i])
Carousel._jQueryInterface.call($carousel, $carousel.data())

View File

@ -31,30 +31,22 @@ const DefaultType = {
parent : '(string|element)'
}
const Event = {
SHOW : `show${EVENT_KEY}`,
SHOWN : `shown${EVENT_KEY}`,
HIDE : `hide${EVENT_KEY}`,
HIDDEN : `hidden${EVENT_KEY}`,
CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`
}
const EVENT_SHOW = `show${EVENT_KEY}`
const EVENT_SHOWN = `shown${EVENT_KEY}`
const EVENT_HIDE = `hide${EVENT_KEY}`
const EVENT_HIDDEN = `hidden${EVENT_KEY}`
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
const ClassName = {
SHOW : 'show',
COLLAPSE : 'collapse',
COLLAPSING : 'collapsing',
COLLAPSED : 'collapsed'
}
const CLASS_NAME_SHOW = 'show'
const CLASS_NAME_COLLAPSE = 'collapse'
const CLASS_NAME_COLLAPSING = 'collapsing'
const CLASS_NAME_COLLAPSED = 'collapsed'
const Dimension = {
WIDTH : 'width',
HEIGHT : 'height'
}
const DIMENSION_WIDTH = 'width'
const DIMENSION_HEIGHT = 'height'
const Selector = {
ACTIVES : '.show, .collapsing',
DATA_TOGGLE : '[data-toggle="collapse"]'
}
const SELECTOR_ACTIVES = '.show, .collapsing'
const SELECTOR_DATA_TOGGLE = '[data-toggle="collapse"]'
/**
* ------------------------------------------------------------------------
@ -72,7 +64,7 @@ class Collapse {
`[data-toggle="collapse"][data-target="#${element.id}"]`
))
const toggleList = [].slice.call(document.querySelectorAll(Selector.DATA_TOGGLE))
const toggleList = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))
for (let i = 0, len = toggleList.length; i < len; i++) {
const elem = toggleList[i]
const selector = Util.getSelectorFromElement(elem)
@ -109,7 +101,7 @@ class Collapse {
// Public
toggle() {
if ($(this._element).hasClass(ClassName.SHOW)) {
if ($(this._element).hasClass(CLASS_NAME_SHOW)) {
this.hide()
} else {
this.show()
@ -118,7 +110,7 @@ class Collapse {
show() {
if (this._isTransitioning ||
$(this._element).hasClass(ClassName.SHOW)) {
$(this._element).hasClass(CLASS_NAME_SHOW)) {
return
}
@ -126,13 +118,13 @@ class Collapse {
let activesData
if (this._parent) {
actives = [].slice.call(this._parent.querySelectorAll(Selector.ACTIVES))
actives = [].slice.call(this._parent.querySelectorAll(SELECTOR_ACTIVES))
.filter((elem) => {
if (typeof this._config.parent === 'string') {
return elem.getAttribute('data-parent') === this._config.parent
}
return elem.classList.contains(ClassName.COLLAPSE)
return elem.classList.contains(CLASS_NAME_COLLAPSE)
})
if (actives.length === 0) {
@ -147,7 +139,7 @@ class Collapse {
}
}
const startEvent = $.Event(Event.SHOW)
const startEvent = $.Event(EVENT_SHOW)
$(this._element).trigger(startEvent)
if (startEvent.isDefaultPrevented()) {
return
@ -163,14 +155,14 @@ class Collapse {
const dimension = this._getDimension()
$(this._element)
.removeClass(ClassName.COLLAPSE)
.addClass(ClassName.COLLAPSING)
.removeClass(CLASS_NAME_COLLAPSE)
.addClass(CLASS_NAME_COLLAPSING)
this._element.style[dimension] = 0
if (this._triggerArray.length) {
$(this._triggerArray)
.removeClass(ClassName.COLLAPSED)
.removeClass(CLASS_NAME_COLLAPSED)
.attr('aria-expanded', true)
}
@ -178,15 +170,15 @@ class Collapse {
const complete = () => {
$(this._element)
.removeClass(ClassName.COLLAPSING)
.addClass(ClassName.COLLAPSE)
.addClass(ClassName.SHOW)
.removeClass(CLASS_NAME_COLLAPSING)
.addClass(CLASS_NAME_COLLAPSE)
.addClass(CLASS_NAME_SHOW)
this._element.style[dimension] = ''
this.setTransitioning(false)
$(this._element).trigger(Event.SHOWN)
$(this._element).trigger(EVENT_SHOWN)
}
const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)
@ -202,11 +194,11 @@ class Collapse {
hide() {
if (this._isTransitioning ||
!$(this._element).hasClass(ClassName.SHOW)) {
!$(this._element).hasClass(CLASS_NAME_SHOW)) {
return
}
const startEvent = $.Event(Event.HIDE)
const startEvent = $.Event(EVENT_HIDE)
$(this._element).trigger(startEvent)
if (startEvent.isDefaultPrevented()) {
return
@ -219,9 +211,9 @@ class Collapse {
Util.reflow(this._element)
$(this._element)
.addClass(ClassName.COLLAPSING)
.removeClass(ClassName.COLLAPSE)
.removeClass(ClassName.SHOW)
.addClass(CLASS_NAME_COLLAPSING)
.removeClass(CLASS_NAME_COLLAPSE)
.removeClass(CLASS_NAME_SHOW)
const triggerArrayLength = this._triggerArray.length
if (triggerArrayLength > 0) {
@ -231,8 +223,8 @@ class Collapse {
if (selector !== null) {
const $elem = $([].slice.call(document.querySelectorAll(selector)))
if (!$elem.hasClass(ClassName.SHOW)) {
$(trigger).addClass(ClassName.COLLAPSED)
if (!$elem.hasClass(CLASS_NAME_SHOW)) {
$(trigger).addClass(CLASS_NAME_COLLAPSED)
.attr('aria-expanded', false)
}
}
@ -244,9 +236,9 @@ class Collapse {
const complete = () => {
this.setTransitioning(false)
$(this._element)
.removeClass(ClassName.COLLAPSING)
.addClass(ClassName.COLLAPSE)
.trigger(Event.HIDDEN)
.removeClass(CLASS_NAME_COLLAPSING)
.addClass(CLASS_NAME_COLLAPSE)
.trigger(EVENT_HIDDEN)
}
this._element.style[dimension] = ''
@ -284,8 +276,8 @@ class Collapse {
}
_getDimension() {
const hasWidth = $(this._element).hasClass(Dimension.WIDTH)
return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT
const hasWidth = $(this._element).hasClass(DIMENSION_WIDTH)
return hasWidth ? DIMENSION_WIDTH : DIMENSION_HEIGHT
}
_getParent() {
@ -317,11 +309,11 @@ class Collapse {
}
_addAriaAndCollapsedClass(element, triggerArray) {
const isOpen = $(element).hasClass(ClassName.SHOW)
const isOpen = $(element).hasClass(CLASS_NAME_SHOW)
if (triggerArray.length) {
$(triggerArray)
.toggleClass(ClassName.COLLAPSED, !isOpen)
.toggleClass(CLASS_NAME_COLLAPSED, !isOpen)
.attr('aria-expanded', isOpen)
}
}
@ -368,7 +360,7 @@ class Collapse {
* ------------------------------------------------------------------------
*/
$(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
// preventDefault only for <a> elements (which change the URL) not inside the collapsible element
if (event.currentTarget.tagName === 'A') {
event.preventDefault()

View File

@ -29,46 +29,35 @@ const ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow
const RIGHT_MOUSE_BUTTON_WHICH = 3 // MouseEvent.which value for the right button (assuming a right-handed mouse)
const REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`)
const Event = {
HIDE : `hide${EVENT_KEY}`,
HIDDEN : `hidden${EVENT_KEY}`,
SHOW : `show${EVENT_KEY}`,
SHOWN : `shown${EVENT_KEY}`,
CLICK : `click${EVENT_KEY}`,
CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`,
KEYDOWN_DATA_API : `keydown${EVENT_KEY}${DATA_API_KEY}`,
KEYUP_DATA_API : `keyup${EVENT_KEY}${DATA_API_KEY}`
}
const EVENT_HIDE = `hide${EVENT_KEY}`
const EVENT_HIDDEN = `hidden${EVENT_KEY}`
const EVENT_SHOW = `show${EVENT_KEY}`
const EVENT_SHOWN = `shown${EVENT_KEY}`
const EVENT_CLICK = `click${EVENT_KEY}`
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
const EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY}${DATA_API_KEY}`
const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}`
const ClassName = {
DISABLED : 'disabled',
SHOW : 'show',
DROPUP : 'dropup',
DROPRIGHT : 'dropright',
DROPLEFT : 'dropleft',
MENURIGHT : 'dropdown-menu-right',
MENULEFT : 'dropdown-menu-left',
POSITION_STATIC : 'position-static'
}
const CLASS_NAME_DISABLED = 'disabled'
const CLASS_NAME_SHOW = 'show'
const CLASS_NAME_DROPUP = 'dropup'
const CLASS_NAME_DROPRIGHT = 'dropright'
const CLASS_NAME_DROPLEFT = 'dropleft'
const CLASS_NAME_MENURIGHT = 'dropdown-menu-right'
const CLASS_NAME_POSITION_STATIC = 'position-static'
const Selector = {
DATA_TOGGLE : '[data-toggle="dropdown"]',
FORM_CHILD : '.dropdown form',
MENU : '.dropdown-menu',
NAVBAR_NAV : '.navbar-nav',
VISIBLE_ITEMS : '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'
}
const SELECTOR_DATA_TOGGLE = '[data-toggle="dropdown"]'
const SELECTOR_FORM_CHILD = '.dropdown form'
const SELECTOR_MENU = '.dropdown-menu'
const SELECTOR_NAVBAR_NAV = '.navbar-nav'
const SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'
const AttachmentMap = {
TOP : 'top-start',
TOPEND : 'top-end',
BOTTOM : 'bottom-start',
BOTTOMEND : 'bottom-end',
RIGHT : 'right-start',
RIGHTEND : 'right-end',
LEFT : 'left-start',
LEFTEND : 'left-end'
}
const PLACEMENT_TOP = 'top-start'
const PLACEMENT_TOPEND = 'top-end'
const PLACEMENT_BOTTOM = 'bottom-start'
const PLACEMENT_BOTTOMEND = 'bottom-end'
const PLACEMENT_RIGHT = 'right-start'
const PLACEMENT_LEFT = 'left-start'
const Default = {
offset : 0,
@ -122,11 +111,11 @@ class Dropdown {
// Public
toggle() {
if (this._element.disabled || $(this._element).hasClass(ClassName.DISABLED)) {
if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED)) {
return
}
const isActive = $(this._menu).hasClass(ClassName.SHOW)
const isActive = $(this._menu).hasClass(CLASS_NAME_SHOW)
Dropdown._clearMenus()
@ -138,14 +127,14 @@ class Dropdown {
}
show(usePopper = false) {
if (this._element.disabled || $(this._element).hasClass(ClassName.DISABLED) || $(this._menu).hasClass(ClassName.SHOW)) {
if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || $(this._menu).hasClass(CLASS_NAME_SHOW)) {
return
}
const relatedTarget = {
relatedTarget: this._element
}
const showEvent = $.Event(Event.SHOW, relatedTarget)
const showEvent = $.Event(EVENT_SHOW, relatedTarget)
const parent = Dropdown._getParentFromElement(this._element)
$(parent).trigger(showEvent)
@ -181,7 +170,7 @@ class Dropdown {
// to allow the menu to "escape" the scroll parent's boundaries
// https://github.com/twbs/bootstrap/issues/24251
if (this._config.boundary !== 'scrollParent') {
$(parent).addClass(ClassName.POSITION_STATIC)
$(parent).addClass(CLASS_NAME_POSITION_STATIC)
}
this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig())
}
@ -191,28 +180,28 @@ class Dropdown {
// only needed because of broken event delegation on iOS
// https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
if ('ontouchstart' in document.documentElement &&
$(parent).closest(Selector.NAVBAR_NAV).length === 0) {
$(parent).closest(SELECTOR_NAVBAR_NAV).length === 0) {
$(document.body).children().on('mouseover', null, $.noop)
}
this._element.focus()
this._element.setAttribute('aria-expanded', true)
$(this._menu).toggleClass(ClassName.SHOW)
$(this._menu).toggleClass(CLASS_NAME_SHOW)
$(parent)
.toggleClass(ClassName.SHOW)
.trigger($.Event(Event.SHOWN, relatedTarget))
.toggleClass(CLASS_NAME_SHOW)
.trigger($.Event(EVENT_SHOWN, relatedTarget))
}
hide() {
if (this._element.disabled || $(this._element).hasClass(ClassName.DISABLED) || !$(this._menu).hasClass(ClassName.SHOW)) {
if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || !$(this._menu).hasClass(CLASS_NAME_SHOW)) {
return
}
const relatedTarget = {
relatedTarget: this._element
}
const hideEvent = $.Event(Event.HIDE, relatedTarget)
const hideEvent = $.Event(EVENT_HIDE, relatedTarget)
const parent = Dropdown._getParentFromElement(this._element)
$(parent).trigger(hideEvent)
@ -225,10 +214,10 @@ class Dropdown {
this._popper.destroy()
}
$(this._menu).toggleClass(ClassName.SHOW)
$(this._menu).toggleClass(CLASS_NAME_SHOW)
$(parent)
.toggleClass(ClassName.SHOW)
.trigger($.Event(Event.HIDDEN, relatedTarget))
.toggleClass(CLASS_NAME_SHOW)
.trigger($.Event(EVENT_HIDDEN, relatedTarget))
}
dispose() {
@ -252,7 +241,7 @@ class Dropdown {
// Private
_addEventListeners() {
$(this._element).on(Event.CLICK, (event) => {
$(this._element).on(EVENT_CLICK, (event) => {
event.preventDefault()
event.stopPropagation()
this.toggle()
@ -280,7 +269,7 @@ class Dropdown {
const parent = Dropdown._getParentFromElement(this._element)
if (parent) {
this._menu = parent.querySelector(Selector.MENU)
this._menu = parent.querySelector(SELECTOR_MENU)
}
}
return this._menu
@ -288,20 +277,20 @@ class Dropdown {
_getPlacement() {
const $parentDropdown = $(this._element.parentNode)
let placement = AttachmentMap.BOTTOM
let placement = PLACEMENT_BOTTOM
// Handle dropup
if ($parentDropdown.hasClass(ClassName.DROPUP)) {
placement = AttachmentMap.TOP
if ($(this._menu).hasClass(ClassName.MENURIGHT)) {
placement = AttachmentMap.TOPEND
if ($parentDropdown.hasClass(CLASS_NAME_DROPUP)) {
placement = PLACEMENT_TOP
if ($(this._menu).hasClass(CLASS_NAME_MENURIGHT)) {
placement = PLACEMENT_TOPEND
}
} else if ($parentDropdown.hasClass(ClassName.DROPRIGHT)) {
placement = AttachmentMap.RIGHT
} else if ($parentDropdown.hasClass(ClassName.DROPLEFT)) {
placement = AttachmentMap.LEFT
} else if ($(this._menu).hasClass(ClassName.MENURIGHT)) {
placement = AttachmentMap.BOTTOMEND
} else if ($parentDropdown.hasClass(CLASS_NAME_DROPRIGHT)) {
placement = PLACEMENT_RIGHT
} else if ($parentDropdown.hasClass(CLASS_NAME_DROPLEFT)) {
placement = PLACEMENT_LEFT
} else if ($(this._menu).hasClass(CLASS_NAME_MENURIGHT)) {
placement = PLACEMENT_BOTTOMEND
}
return placement
}
@ -383,7 +372,7 @@ class Dropdown {
return
}
const toggles = [].slice.call(document.querySelectorAll(Selector.DATA_TOGGLE))
const toggles = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))
for (let i = 0, len = toggles.length; i < len; i++) {
const parent = Dropdown._getParentFromElement(toggles[i])
@ -401,7 +390,7 @@ class Dropdown {
}
const dropdownMenu = context._menu
if (!$(parent).hasClass(ClassName.SHOW)) {
if (!$(parent).hasClass(CLASS_NAME_SHOW)) {
continue
}
@ -411,7 +400,7 @@ class Dropdown {
continue
}
const hideEvent = $.Event(Event.HIDE, relatedTarget)
const hideEvent = $.Event(EVENT_HIDE, relatedTarget)
$(parent).trigger(hideEvent)
if (hideEvent.isDefaultPrevented()) {
continue
@ -429,10 +418,10 @@ class Dropdown {
context._popper.destroy()
}
$(dropdownMenu).removeClass(ClassName.SHOW)
$(dropdownMenu).removeClass(CLASS_NAME_SHOW)
$(parent)
.removeClass(ClassName.SHOW)
.trigger($.Event(Event.HIDDEN, relatedTarget))
.removeClass(CLASS_NAME_SHOW)
.trigger($.Event(EVENT_HIDDEN, relatedTarget))
}
}
@ -459,19 +448,19 @@ class Dropdown {
if (/input|textarea/i.test(event.target.tagName)
? event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE &&
(event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE ||
$(event.target).closest(Selector.MENU).length) : !REGEXP_KEYDOWN.test(event.which)) {
$(event.target).closest(SELECTOR_MENU).length) : !REGEXP_KEYDOWN.test(event.which)) {
return
}
event.preventDefault()
event.stopPropagation()
if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {
if (this.disabled || $(this).hasClass(CLASS_NAME_DISABLED)) {
return
}
const parent = Dropdown._getParentFromElement(this)
const isActive = $(parent).hasClass(ClassName.SHOW)
const isActive = $(parent).hasClass(CLASS_NAME_SHOW)
if (!isActive && event.which === ESCAPE_KEYCODE) {
return
@ -479,7 +468,7 @@ class Dropdown {
if (!isActive || isActive && (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) {
if (event.which === ESCAPE_KEYCODE) {
const toggle = parent.querySelector(Selector.DATA_TOGGLE)
const toggle = parent.querySelector(SELECTOR_DATA_TOGGLE)
$(toggle).trigger('focus')
}
@ -487,7 +476,7 @@ class Dropdown {
return
}
const items = [].slice.call(parent.querySelectorAll(Selector.VISIBLE_ITEMS))
const items = [].slice.call(parent.querySelectorAll(SELECTOR_VISIBLE_ITEMS))
.filter((item) => $(item).is(':visible'))
if (items.length === 0) {
@ -519,15 +508,15 @@ class Dropdown {
*/
$(document)
.on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler)
.on(Event.KEYDOWN_DATA_API, Selector.MENU, Dropdown._dataApiKeydownHandler)
.on(`${Event.CLICK_DATA_API} ${Event.KEYUP_DATA_API}`, Dropdown._clearMenus)
.on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
.on(EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE, Dropdown._dataApiKeydownHandler)
.on(EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown._dataApiKeydownHandler)
.on(`${EVENT_CLICK_DATA_API} ${EVENT_KEYUP_DATA_API}`, Dropdown._clearMenus)
.on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
event.preventDefault()
event.stopPropagation()
Dropdown._jQueryInterface.call($(this), 'toggle')
})
.on(Event.CLICK_DATA_API, Selector.FORM_CHILD, (e) => {
.on(EVENT_CLICK_DATA_API, SELECTOR_FORM_CHILD, (e) => {
e.stopPropagation()
})

View File

@ -36,39 +36,33 @@ const DefaultType = {
show : 'boolean'
}
const Event = {
HIDE : `hide${EVENT_KEY}`,
HIDE_PREVENTED : `hidePrevented${EVENT_KEY}`,
HIDDEN : `hidden${EVENT_KEY}`,
SHOW : `show${EVENT_KEY}`,
SHOWN : `shown${EVENT_KEY}`,
FOCUSIN : `focusin${EVENT_KEY}`,
RESIZE : `resize${EVENT_KEY}`,
CLICK_DISMISS : `click.dismiss${EVENT_KEY}`,
KEYDOWN_DISMISS : `keydown.dismiss${EVENT_KEY}`,
MOUSEUP_DISMISS : `mouseup.dismiss${EVENT_KEY}`,
MOUSEDOWN_DISMISS : `mousedown.dismiss${EVENT_KEY}`,
CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`
}
const EVENT_HIDE = `hide${EVENT_KEY}`
const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`
const EVENT_HIDDEN = `hidden${EVENT_KEY}`
const EVENT_SHOW = `show${EVENT_KEY}`
const EVENT_SHOWN = `shown${EVENT_KEY}`
const EVENT_FOCUSIN = `focusin${EVENT_KEY}`
const EVENT_RESIZE = `resize${EVENT_KEY}`
const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`
const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`
const EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY}`
const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
const ClassName = {
SCROLLABLE : 'modal-dialog-scrollable',
SCROLLBAR_MEASURER : 'modal-scrollbar-measure',
BACKDROP : 'modal-backdrop',
OPEN : 'modal-open',
FADE : 'fade',
SHOW : 'show',
STATIC : 'modal-static'
}
const CLASS_NAME_SCROLLABLE = 'modal-dialog-scrollable'
const CLASS_NAME_SCROLLBAR_MEASURER = 'modal-scrollbar-measure'
const CLASS_NAME_BACKDROP = 'modal-backdrop'
const CLASS_NAME_OPEN = 'modal-open'
const CLASS_NAME_FADE = 'fade'
const CLASS_NAME_SHOW = 'show'
const CLASS_NAME_STATIC = 'modal-static'
const Selector = {
DIALOG : '.modal-dialog',
MODAL_BODY : '.modal-body',
DATA_TOGGLE : '[data-toggle="modal"]',
DATA_DISMISS : '[data-dismiss="modal"]',
FIXED_CONTENT : '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top',
STICKY_CONTENT : '.sticky-top'
}
const SELECTOR_DIALOG = '.modal-dialog'
const SELECTOR_MODAL_BODY = '.modal-body'
const SELECTOR_DATA_TOGGLE = '[data-toggle="modal"]'
const SELECTOR_DATA_DISMISS = '[data-dismiss="modal"]'
const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'
const SELECTOR_STICKY_CONTENT = '.sticky-top'
/**
* ------------------------------------------------------------------------
@ -80,7 +74,7 @@ class Modal {
constructor(element, config) {
this._config = this._getConfig(config)
this._element = element
this._dialog = element.querySelector(Selector.DIALOG)
this._dialog = element.querySelector(SELECTOR_DIALOG)
this._backdrop = null
this._isShown = false
this._isBodyOverflowing = false
@ -110,11 +104,11 @@ class Modal {
return
}
if ($(this._element).hasClass(ClassName.FADE)) {
if ($(this._element).hasClass(CLASS_NAME_FADE)) {
this._isTransitioning = true
}
const showEvent = $.Event(Event.SHOW, {
const showEvent = $.Event(EVENT_SHOW, {
relatedTarget
})
@ -135,13 +129,13 @@ class Modal {
this._setResizeEvent()
$(this._element).on(
Event.CLICK_DISMISS,
Selector.DATA_DISMISS,
EVENT_CLICK_DISMISS,
SELECTOR_DATA_DISMISS,
(event) => this.hide(event)
)
$(this._dialog).on(Event.MOUSEDOWN_DISMISS, () => {
$(this._element).one(Event.MOUSEUP_DISMISS, (event) => {
$(this._dialog).on(EVENT_MOUSEDOWN_DISMISS, () => {
$(this._element).one(EVENT_MOUSEUP_DISMISS, (event) => {
if ($(event.target).is(this._element)) {
this._ignoreBackdropClick = true
}
@ -160,7 +154,7 @@ class Modal {
return
}
const hideEvent = $.Event(Event.HIDE)
const hideEvent = $.Event(EVENT_HIDE)
$(this._element).trigger(hideEvent)
@ -169,7 +163,7 @@ class Modal {
}
this._isShown = false
const transition = $(this._element).hasClass(ClassName.FADE)
const transition = $(this._element).hasClass(CLASS_NAME_FADE)
if (transition) {
this._isTransitioning = true
@ -178,12 +172,12 @@ class Modal {
this._setEscapeEvent()
this._setResizeEvent()
$(document).off(Event.FOCUSIN)
$(document).off(EVENT_FOCUSIN)
$(this._element).removeClass(ClassName.SHOW)
$(this._element).removeClass(CLASS_NAME_SHOW)
$(this._element).off(Event.CLICK_DISMISS)
$(this._dialog).off(Event.MOUSEDOWN_DISMISS)
$(this._element).off(EVENT_CLICK_DISMISS)
$(this._dialog).off(EVENT_MOUSEDOWN_DISMISS)
if (transition) {
@ -202,11 +196,11 @@ class Modal {
.forEach((htmlElement) => $(htmlElement).off(EVENT_KEY))
/**
* `document` has 2 events `Event.FOCUSIN` and `Event.CLICK_DATA_API`
* `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API`
* Do not move `document` in `htmlElements` array
* It will remove `Event.CLICK_DATA_API` event that should remain
* It will remove `EVENT_CLICK_DATA_API` event that should remain
*/
$(document).off(Event.FOCUSIN)
$(document).off(EVENT_FOCUSIN)
$.removeData(this._element, DATA_KEY)
@ -238,19 +232,19 @@ class Modal {
_triggerBackdropTransition() {
if (this._config.backdrop === 'static') {
const hideEventPrevented = $.Event(Event.HIDE_PREVENTED)
const hideEventPrevented = $.Event(EVENT_HIDE_PREVENTED)
$(this._element).trigger(hideEventPrevented)
if (hideEventPrevented.defaultPrevented) {
return
}
this._element.classList.add(ClassName.STATIC)
this._element.classList.add(CLASS_NAME_STATIC)
const modalTransitionDuration = Util.getTransitionDurationFromElement(this._element)
$(this._element).one(Util.TRANSITION_END, () => {
this._element.classList.remove(ClassName.STATIC)
this._element.classList.remove(CLASS_NAME_STATIC)
})
.emulateTransitionEnd(modalTransitionDuration)
this._element.focus()
@ -260,8 +254,8 @@ class Modal {
}
_showElement(relatedTarget) {
const transition = $(this._element).hasClass(ClassName.FADE)
const modalBody = this._dialog ? this._dialog.querySelector(Selector.MODAL_BODY) : null
const transition = $(this._element).hasClass(CLASS_NAME_FADE)
const modalBody = this._dialog ? this._dialog.querySelector(SELECTOR_MODAL_BODY) : null
if (!this._element.parentNode ||
this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
@ -273,7 +267,7 @@ class Modal {
this._element.removeAttribute('aria-hidden')
this._element.setAttribute('aria-modal', true)
if ($(this._dialog).hasClass(ClassName.SCROLLABLE) && modalBody) {
if ($(this._dialog).hasClass(CLASS_NAME_SCROLLABLE) && modalBody) {
modalBody.scrollTop = 0
} else {
this._element.scrollTop = 0
@ -283,13 +277,13 @@ class Modal {
Util.reflow(this._element)
}
$(this._element).addClass(ClassName.SHOW)
$(this._element).addClass(CLASS_NAME_SHOW)
if (this._config.focus) {
this._enforceFocus()
}
const shownEvent = $.Event(Event.SHOWN, {
const shownEvent = $.Event(EVENT_SHOWN, {
relatedTarget
})
@ -314,8 +308,8 @@ class Modal {
_enforceFocus() {
$(document)
.off(Event.FOCUSIN) // Guard against infinite focus loop
.on(Event.FOCUSIN, (event) => {
.off(EVENT_FOCUSIN) // Guard against infinite focus loop
.on(EVENT_FOCUSIN, (event) => {
if (document !== event.target &&
this._element !== event.target &&
$(this._element).has(event.target).length === 0) {
@ -326,7 +320,7 @@ class Modal {
_setEscapeEvent() {
if (this._isShown) {
$(this._element).on(Event.KEYDOWN_DISMISS, (event) => {
$(this._element).on(EVENT_KEYDOWN_DISMISS, (event) => {
if (this._config.keyboard && event.which === ESCAPE_KEYCODE) {
event.preventDefault()
this.hide()
@ -335,15 +329,15 @@ class Modal {
}
})
} else if (!this._isShown) {
$(this._element).off(Event.KEYDOWN_DISMISS)
$(this._element).off(EVENT_KEYDOWN_DISMISS)
}
}
_setResizeEvent() {
if (this._isShown) {
$(window).on(Event.RESIZE, (event) => this.handleUpdate(event))
$(window).on(EVENT_RESIZE, (event) => this.handleUpdate(event))
} else {
$(window).off(Event.RESIZE)
$(window).off(EVENT_RESIZE)
}
}
@ -353,10 +347,10 @@ class Modal {
this._element.removeAttribute('aria-modal')
this._isTransitioning = false
this._showBackdrop(() => {
$(document.body).removeClass(ClassName.OPEN)
$(document.body).removeClass(CLASS_NAME_OPEN)
this._resetAdjustments()
this._resetScrollbar()
$(this._element).trigger(Event.HIDDEN)
$(this._element).trigger(EVENT_HIDDEN)
})
}
@ -368,12 +362,12 @@ class Modal {
}
_showBackdrop(callback) {
const animate = $(this._element).hasClass(ClassName.FADE)
? ClassName.FADE : ''
const animate = $(this._element).hasClass(CLASS_NAME_FADE)
? CLASS_NAME_FADE : ''
if (this._isShown && this._config.backdrop) {
this._backdrop = document.createElement('div')
this._backdrop.className = ClassName.BACKDROP
this._backdrop.className = CLASS_NAME_BACKDROP
if (animate) {
this._backdrop.classList.add(animate)
@ -381,7 +375,7 @@ class Modal {
$(this._backdrop).appendTo(document.body)
$(this._element).on(Event.CLICK_DISMISS, (event) => {
$(this._element).on(EVENT_CLICK_DISMISS, (event) => {
if (this._ignoreBackdropClick) {
this._ignoreBackdropClick = false
return
@ -397,7 +391,7 @@ class Modal {
Util.reflow(this._backdrop)
}
$(this._backdrop).addClass(ClassName.SHOW)
$(this._backdrop).addClass(CLASS_NAME_SHOW)
if (!callback) {
return
@ -414,7 +408,7 @@ class Modal {
.one(Util.TRANSITION_END, callback)
.emulateTransitionEnd(backdropTransitionDuration)
} else if (!this._isShown && this._backdrop) {
$(this._backdrop).removeClass(ClassName.SHOW)
$(this._backdrop).removeClass(CLASS_NAME_SHOW)
const callbackRemove = () => {
this._removeBackdrop()
@ -423,7 +417,7 @@ class Modal {
}
}
if ($(this._element).hasClass(ClassName.FADE)) {
if ($(this._element).hasClass(CLASS_NAME_FADE)) {
const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)
$(this._backdrop)
@ -470,8 +464,8 @@ class Modal {
if (this._isBodyOverflowing) {
// Note: DOMNode.style.paddingRight returns the actual value or '' if not set
// while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set
const fixedContent = [].slice.call(document.querySelectorAll(Selector.FIXED_CONTENT))
const stickyContent = [].slice.call(document.querySelectorAll(Selector.STICKY_CONTENT))
const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT))
const stickyContent = [].slice.call(document.querySelectorAll(SELECTOR_STICKY_CONTENT))
// Adjust fixed content padding
$(fixedContent).each((index, element) => {
@ -499,12 +493,12 @@ class Modal {
.css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)
}
$(document.body).addClass(ClassName.OPEN)
$(document.body).addClass(CLASS_NAME_OPEN)
}
_resetScrollbar() {
// Restore fixed content padding
const fixedContent = [].slice.call(document.querySelectorAll(Selector.FIXED_CONTENT))
const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT))
$(fixedContent).each((index, element) => {
const padding = $(element).data('padding-right')
$(element).removeData('padding-right')
@ -512,7 +506,7 @@ class Modal {
})
// Restore sticky content
const elements = [].slice.call(document.querySelectorAll(`${Selector.STICKY_CONTENT}`))
const elements = [].slice.call(document.querySelectorAll(`${SELECTOR_STICKY_CONTENT}`))
$(elements).each((index, element) => {
const margin = $(element).data('margin-right')
if (typeof margin !== 'undefined') {
@ -528,7 +522,7 @@ class Modal {
_getScrollbarWidth() { // thx d.walsh
const scrollDiv = document.createElement('div')
scrollDiv.className = ClassName.SCROLLBAR_MEASURER
scrollDiv.className = CLASS_NAME_SCROLLBAR_MEASURER
document.body.appendChild(scrollDiv)
const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth
document.body.removeChild(scrollDiv)
@ -569,7 +563,7 @@ class Modal {
* ------------------------------------------------------------------------
*/
$(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
let target
const selector = Util.getSelectorFromElement(this)
@ -587,13 +581,13 @@ $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
event.preventDefault()
}
const $target = $(target).one(Event.SHOW, (showEvent) => {
const $target = $(target).one(EVENT_SHOW, (showEvent) => {
if (showEvent.isDefaultPrevented()) {
// Only register focus restorer if modal will actually get shown
return
}
$target.one(Event.HIDDEN, () => {
$target.one(EVENT_HIDDEN, () => {
if ($(this).is(':visible')) {
this.focus()
}

View File

@ -38,15 +38,11 @@ const DefaultType = {
content : '(string|element|function)'
}
const ClassName = {
FADE : 'fade',
SHOW : 'show'
}
const CLASS_NAME_FADE = 'fade'
const CLASS_NAME_SHOW = 'show'
const Selector = {
TITLE : '.popover-header',
CONTENT : '.popover-body'
}
const SELECTOR_TITLE = '.popover-header'
const SELECTOR_CONTENT = '.popover-body'
const Event = {
HIDE : `hide${EVENT_KEY}`,
@ -117,14 +113,14 @@ class Popover extends Tooltip {
const $tip = $(this.getTipElement())
// We use append for html objects to maintain js events
this.setElementContent($tip.find(Selector.TITLE), this.getTitle())
this.setElementContent($tip.find(SELECTOR_TITLE), this.getTitle())
let content = this._getContent()
if (typeof content === 'function') {
content = content.call(this.element)
}
this.setElementContent($tip.find(Selector.CONTENT), content)
this.setElementContent($tip.find(SELECTOR_CONTENT), content)
$tip.removeClass(`${ClassName.FADE} ${ClassName.SHOW}`)
$tip.removeClass(`${CLASS_NAME_FADE} ${CLASS_NAME_SHOW}`)
}
// Private

View File

@ -33,34 +33,24 @@ const DefaultType = {
target : '(string|element)'
}
const Event = {
ACTIVATE : `activate${EVENT_KEY}`,
SCROLL : `scroll${EVENT_KEY}`,
LOAD_DATA_API : `load${EVENT_KEY}${DATA_API_KEY}`
}
const EVENT_ACTIVATE = `activate${EVENT_KEY}`
const EVENT_SCROLL = `scroll${EVENT_KEY}`
const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`
const ClassName = {
DROPDOWN_ITEM : 'dropdown-item',
DROPDOWN_MENU : 'dropdown-menu',
ACTIVE : 'active'
}
const CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item'
const CLASS_NAME_ACTIVE = 'active'
const Selector = {
DATA_SPY : '[data-spy="scroll"]',
ACTIVE : '.active',
NAV_LIST_GROUP : '.nav, .list-group',
NAV_LINKS : '.nav-link',
NAV_ITEMS : '.nav-item',
LIST_ITEMS : '.list-group-item',
DROPDOWN : '.dropdown',
DROPDOWN_ITEMS : '.dropdown-item',
DROPDOWN_TOGGLE : '.dropdown-toggle'
}
const SELECTOR_DATA_SPY = '[data-spy="scroll"]'
const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'
const SELECTOR_NAV_LINKS = '.nav-link'
const SELECTOR_NAV_ITEMS = '.nav-item'
const SELECTOR_LIST_ITEMS = '.list-group-item'
const SELECTOR_DROPDOWN = '.dropdown'
const SELECTOR_DROPDOWN_ITEMS = '.dropdown-item'
const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'
const OffsetMethod = {
OFFSET : 'offset',
POSITION : 'position'
}
const METHOD_OFFSET = 'offset'
const METHOD_POSITION = 'position'
/**
* ------------------------------------------------------------------------
@ -73,15 +63,15 @@ class ScrollSpy {
this._element = element
this._scrollElement = element.tagName === 'BODY' ? window : element
this._config = this._getConfig(config)
this._selector = `${this._config.target} ${Selector.NAV_LINKS},` +
`${this._config.target} ${Selector.LIST_ITEMS},` +
`${this._config.target} ${Selector.DROPDOWN_ITEMS}`
this._selector = `${this._config.target} ${SELECTOR_NAV_LINKS},` +
`${this._config.target} ${SELECTOR_LIST_ITEMS},` +
`${this._config.target} ${SELECTOR_DROPDOWN_ITEMS}`
this._offsets = []
this._targets = []
this._activeTarget = null
this._scrollHeight = 0
$(this._scrollElement).on(Event.SCROLL, (event) => this._process(event))
$(this._scrollElement).on(EVENT_SCROLL, (event) => this._process(event))
this.refresh()
this._process()
@ -101,12 +91,12 @@ class ScrollSpy {
refresh() {
const autoMethod = this._scrollElement === this._scrollElement.window
? OffsetMethod.OFFSET : OffsetMethod.POSITION
? METHOD_OFFSET : METHOD_POSITION
const offsetMethod = this._config.method === 'auto'
? autoMethod : this._config.method
const offsetBase = offsetMethod === OffsetMethod.POSITION
const offsetBase = offsetMethod === METHOD_POSITION
? this._getScrollTop() : 0
this._offsets = []
@ -248,28 +238,28 @@ class ScrollSpy {
const $link = $([].slice.call(document.querySelectorAll(queries.join(','))))
if ($link.hasClass(ClassName.DROPDOWN_ITEM)) {
$link.closest(Selector.DROPDOWN).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE)
$link.addClass(ClassName.ACTIVE)
if ($link.hasClass(CLASS_NAME_DROPDOWN_ITEM)) {
$link.closest(SELECTOR_DROPDOWN).find(SELECTOR_DROPDOWN_TOGGLE).addClass(CLASS_NAME_ACTIVE)
$link.addClass(CLASS_NAME_ACTIVE)
} else {
// Set triggered link as active
$link.addClass(ClassName.ACTIVE)
$link.addClass(CLASS_NAME_ACTIVE)
// Set triggered links parents as active
// With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
$link.parents(Selector.NAV_LIST_GROUP).prev(`${Selector.NAV_LINKS}, ${Selector.LIST_ITEMS}`).addClass(ClassName.ACTIVE)
$link.parents(SELECTOR_NAV_LIST_GROUP).prev(`${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`).addClass(CLASS_NAME_ACTIVE)
// Handle special case when .nav-link is inside .nav-item
$link.parents(Selector.NAV_LIST_GROUP).prev(Selector.NAV_ITEMS).children(Selector.NAV_LINKS).addClass(ClassName.ACTIVE)
$link.parents(SELECTOR_NAV_LIST_GROUP).prev(SELECTOR_NAV_ITEMS).children(SELECTOR_NAV_LINKS).addClass(CLASS_NAME_ACTIVE)
}
$(this._scrollElement).trigger(Event.ACTIVATE, {
$(this._scrollElement).trigger(EVENT_ACTIVATE, {
relatedTarget: target
})
}
_clear() {
[].slice.call(document.querySelectorAll(this._selector))
.filter((node) => node.classList.contains(ClassName.ACTIVE))
.forEach((node) => node.classList.remove(ClassName.ACTIVE))
.filter((node) => node.classList.contains(CLASS_NAME_ACTIVE))
.forEach((node) => node.classList.remove(CLASS_NAME_ACTIVE))
}
// Static
@ -300,8 +290,8 @@ class ScrollSpy {
* ------------------------------------------------------------------------
*/
$(window).on(Event.LOAD_DATA_API, () => {
const scrollSpys = [].slice.call(document.querySelectorAll(Selector.DATA_SPY))
$(window).on(EVENT_LOAD_DATA_API, () => {
const scrollSpys = [].slice.call(document.querySelectorAll(SELECTOR_DATA_SPY))
const scrollSpysLength = scrollSpys.length
for (let i = scrollSpysLength; i--;) {

View File

@ -21,31 +21,25 @@ const EVENT_KEY = `.${DATA_KEY}`
const DATA_API_KEY = '.data-api'
const JQUERY_NO_CONFLICT = $.fn[NAME]
const Event = {
HIDE : `hide${EVENT_KEY}`,
HIDDEN : `hidden${EVENT_KEY}`,
SHOW : `show${EVENT_KEY}`,
SHOWN : `shown${EVENT_KEY}`,
CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`
}
const EVENT_HIDE = `hide${EVENT_KEY}`
const EVENT_HIDDEN = `hidden${EVENT_KEY}`
const EVENT_SHOW = `show${EVENT_KEY}`
const EVENT_SHOWN = `shown${EVENT_KEY}`
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
const ClassName = {
DROPDOWN_MENU : 'dropdown-menu',
ACTIVE : 'active',
DISABLED : 'disabled',
FADE : 'fade',
SHOW : 'show'
}
const CLASS_NAME_DROPDOWN_MENU = 'dropdown-menu'
const CLASS_NAME_ACTIVE = 'active'
const CLASS_NAME_DISABLED = 'disabled'
const CLASS_NAME_FADE = 'fade'
const CLASS_NAME_SHOW = 'show'
const Selector = {
DROPDOWN : '.dropdown',
NAV_LIST_GROUP : '.nav, .list-group',
ACTIVE : '.active',
ACTIVE_UL : '> li > .active',
DATA_TOGGLE : '[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',
DROPDOWN_TOGGLE : '.dropdown-toggle',
DROPDOWN_ACTIVE_CHILD : '> .dropdown-menu .active'
}
const SELECTOR_DROPDOWN = '.dropdown'
const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'
const SELECTOR_ACTIVE = '.active'
const SELECTOR_ACTIVE_UL = '> li > .active'
const SELECTOR_DATA_TOGGLE = '[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]'
const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'
const SELECTOR_DROPDOWN_ACTIVE_CHILD = '> .dropdown-menu .active'
/**
* ------------------------------------------------------------------------
@ -69,27 +63,27 @@ class Tab {
show() {
if (this._element.parentNode &&
this._element.parentNode.nodeType === Node.ELEMENT_NODE &&
$(this._element).hasClass(ClassName.ACTIVE) ||
$(this._element).hasClass(ClassName.DISABLED)) {
$(this._element).hasClass(CLASS_NAME_ACTIVE) ||
$(this._element).hasClass(CLASS_NAME_DISABLED)) {
return
}
let target
let previous
const listElement = $(this._element).closest(Selector.NAV_LIST_GROUP)[0]
const listElement = $(this._element).closest(SELECTOR_NAV_LIST_GROUP)[0]
const selector = Util.getSelectorFromElement(this._element)
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($(listElement).find(itemSelector))
previous = previous[previous.length - 1]
}
const hideEvent = $.Event(Event.HIDE, {
const hideEvent = $.Event(EVENT_HIDE, {
relatedTarget: this._element
})
const showEvent = $.Event(Event.SHOW, {
const showEvent = $.Event(EVENT_SHOW, {
relatedTarget: previous
})
@ -114,11 +108,11 @@ class Tab {
)
const complete = () => {
const hiddenEvent = $.Event(Event.HIDDEN, {
const hiddenEvent = $.Event(EVENT_HIDDEN, {
relatedTarget: this._element
})
const shownEvent = $.Event(Event.SHOWN, {
const shownEvent = $.Event(EVENT_SHOWN, {
relatedTarget: previous
})
@ -142,11 +136,11 @@ class Tab {
_activate(element, container, callback) {
const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL')
? $(container).find(Selector.ACTIVE_UL)
: $(container).children(Selector.ACTIVE)
? $(container).find(SELECTOR_ACTIVE_UL)
: $(container).children(SELECTOR_ACTIVE)
const active = activeElements[0]
const isTransitioning = callback && (active && $(active).hasClass(ClassName.FADE))
const isTransitioning = callback && (active && $(active).hasClass(CLASS_NAME_FADE))
const complete = () => this._transitionComplete(
element,
active,
@ -157,7 +151,7 @@ class Tab {
const transitionDuration = Util.getTransitionDurationFromElement(active)
$(active)
.removeClass(ClassName.SHOW)
.removeClass(CLASS_NAME_SHOW)
.one(Util.TRANSITION_END, complete)
.emulateTransitionEnd(transitionDuration)
} else {
@ -167,14 +161,14 @@ class Tab {
_transitionComplete(element, active, callback) {
if (active) {
$(active).removeClass(ClassName.ACTIVE)
$(active).removeClass(CLASS_NAME_ACTIVE)
const dropdownChild = $(active.parentNode).find(
Selector.DROPDOWN_ACTIVE_CHILD
SELECTOR_DROPDOWN_ACTIVE_CHILD
)[0]
if (dropdownChild) {
$(dropdownChild).removeClass(ClassName.ACTIVE)
$(dropdownChild).removeClass(CLASS_NAME_ACTIVE)
}
if (active.getAttribute('role') === 'tab') {
@ -182,24 +176,24 @@ class Tab {
}
}
$(element).addClass(ClassName.ACTIVE)
$(element).addClass(CLASS_NAME_ACTIVE)
if (element.getAttribute('role') === 'tab') {
element.setAttribute('aria-selected', true)
}
Util.reflow(element)
if (element.classList.contains(ClassName.FADE)) {
element.classList.add(ClassName.SHOW)
if (element.classList.contains(CLASS_NAME_FADE)) {
element.classList.add(CLASS_NAME_SHOW)
}
if (element.parentNode && $(element.parentNode).hasClass(ClassName.DROPDOWN_MENU)) {
const dropdownElement = $(element).closest(Selector.DROPDOWN)[0]
if (element.parentNode && $(element.parentNode).hasClass(CLASS_NAME_DROPDOWN_MENU)) {
const dropdownElement = $(element).closest(SELECTOR_DROPDOWN)[0]
if (dropdownElement) {
const dropdownToggleList = [].slice.call(dropdownElement.querySelectorAll(Selector.DROPDOWN_TOGGLE))
const dropdownToggleList = [].slice.call(dropdownElement.querySelectorAll(SELECTOR_DROPDOWN_TOGGLE))
$(dropdownToggleList).addClass(ClassName.ACTIVE)
$(dropdownToggleList).addClass(CLASS_NAME_ACTIVE)
}
element.setAttribute('aria-expanded', true)
@ -239,7 +233,7 @@ class Tab {
*/
$(document)
.on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
.on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
event.preventDefault()
Tab._jQueryInterface.call($(this), 'show')
})

View File

@ -20,20 +20,16 @@ const DATA_KEY = 'bs.toast'
const EVENT_KEY = `.${DATA_KEY}`
const JQUERY_NO_CONFLICT = $.fn[NAME]
const Event = {
CLICK_DISMISS : `click.dismiss${EVENT_KEY}`,
HIDE : `hide${EVENT_KEY}`,
HIDDEN : `hidden${EVENT_KEY}`,
SHOW : `show${EVENT_KEY}`,
SHOWN : `shown${EVENT_KEY}`
}
const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`
const EVENT_HIDE = `hide${EVENT_KEY}`
const EVENT_HIDDEN = `hidden${EVENT_KEY}`
const EVENT_SHOW = `show${EVENT_KEY}`
const EVENT_SHOWN = `shown${EVENT_KEY}`
const ClassName = {
FADE : 'fade',
HIDE : 'hide',
SHOW : 'show',
SHOWING : 'showing'
}
const CLASS_NAME_FADE = 'fade'
const CLASS_NAME_HIDE = 'hide'
const CLASS_NAME_SHOW = 'show'
const CLASS_NAME_SHOWING = 'showing'
const DefaultType = {
animation : 'boolean',
@ -47,9 +43,7 @@ const Default = {
delay : 500
}
const Selector = {
DATA_DISMISS : '[data-dismiss="toast"]'
}
const SELECTOR_DATA_DISMISS = '[data-dismiss="toast"]'
/**
* ------------------------------------------------------------------------
@ -82,7 +76,7 @@ class Toast {
// Public
show() {
const showEvent = $.Event(Event.SHOW)
const showEvent = $.Event(EVENT_SHOW)
$(this._element).trigger(showEvent)
if (showEvent.isDefaultPrevented()) {
@ -90,14 +84,14 @@ class Toast {
}
if (this._config.animation) {
this._element.classList.add(ClassName.FADE)
this._element.classList.add(CLASS_NAME_FADE)
}
const complete = () => {
this._element.classList.remove(ClassName.SHOWING)
this._element.classList.add(ClassName.SHOW)
this._element.classList.remove(CLASS_NAME_SHOWING)
this._element.classList.add(CLASS_NAME_SHOW)
$(this._element).trigger(Event.SHOWN)
$(this._element).trigger(EVENT_SHOWN)
if (this._config.autohide) {
this._timeout = setTimeout(() => {
@ -106,9 +100,9 @@ class Toast {
}
}
this._element.classList.remove(ClassName.HIDE)
this._element.classList.remove(CLASS_NAME_HIDE)
Util.reflow(this._element)
this._element.classList.add(ClassName.SHOWING)
this._element.classList.add(CLASS_NAME_SHOWING)
if (this._config.animation) {
const transitionDuration = Util.getTransitionDurationFromElement(this._element)
@ -121,11 +115,11 @@ class Toast {
}
hide() {
if (!this._element.classList.contains(ClassName.SHOW)) {
if (!this._element.classList.contains(CLASS_NAME_SHOW)) {
return
}
const hideEvent = $.Event(Event.HIDE)
const hideEvent = $.Event(EVENT_HIDE)
$(this._element).trigger(hideEvent)
if (hideEvent.isDefaultPrevented()) {
@ -139,11 +133,11 @@ class Toast {
clearTimeout(this._timeout)
this._timeout = null
if (this._element.classList.contains(ClassName.SHOW)) {
this._element.classList.remove(ClassName.SHOW)
if (this._element.classList.contains(CLASS_NAME_SHOW)) {
this._element.classList.remove(CLASS_NAME_SHOW)
}
$(this._element).off(Event.CLICK_DISMISS)
$(this._element).off(EVENT_CLICK_DISMISS)
$.removeData(this._element, DATA_KEY)
this._element = null
@ -170,19 +164,19 @@ class Toast {
_setListeners() {
$(this._element).on(
Event.CLICK_DISMISS,
Selector.DATA_DISMISS,
EVENT_CLICK_DISMISS,
SELECTOR_DATA_DISMISS,
() => this.hide()
)
}
_close() {
const complete = () => {
this._element.classList.add(ClassName.HIDE)
$(this._element).trigger(Event.HIDDEN)
this._element.classList.add(CLASS_NAME_HIDE)
$(this._element).trigger(EVENT_HIDDEN)
}
this._element.classList.remove(ClassName.SHOW)
this._element.classList.remove(CLASS_NAME_SHOW)
if (this._config.animation) {
const transitionDuration = Util.getTransitionDurationFromElement(this._element)

View File

@ -76,10 +76,8 @@ const Default = {
popperConfig : null
}
const HoverState = {
SHOW : 'show',
OUT : 'out'
}
const HOVER_STATE_SHOW = 'show'
const HOVER_STATE_OUT = 'out'
const Event = {
HIDE : `hide${EVENT_KEY}`,
@ -94,24 +92,16 @@ const Event = {
MOUSELEAVE : `mouseleave${EVENT_KEY}`
}
const ClassName = {
FADE : 'fade',
SHOW : 'show'
}
const CLASS_NAME_FADE = 'fade'
const CLASS_NAME_SHOW = 'show'
const Selector = {
TOOLTIP : '.tooltip',
TOOLTIP_INNER : '.tooltip-inner',
ARROW : '.arrow'
}
const Trigger = {
HOVER : 'hover',
FOCUS : 'focus',
CLICK : 'click',
MANUAL : 'manual'
}
const SELECTOR_TOOLTIP_INNER = '.tooltip-inner'
const SELECTOR_ARROW = '.arrow'
const TRIGGER_HOVER = 'hover'
const TRIGGER_FOCUS = 'focus'
const TRIGGER_CLICK = 'click'
const TRIGGER_MANUAL = 'manual'
/**
* ------------------------------------------------------------------------
@ -209,7 +199,7 @@ class Tooltip {
context._leave(null, context)
}
} else {
if ($(this.getTipElement()).hasClass(ClassName.SHOW)) {
if ($(this.getTipElement()).hasClass(CLASS_NAME_SHOW)) {
this._leave(null, this)
return
}
@ -272,7 +262,7 @@ class Tooltip {
this.setContent()
if (this.config.animation) {
$(tip).addClass(ClassName.FADE)
$(tip).addClass(CLASS_NAME_FADE)
}
const placement = typeof this.config.placement === 'function'
@ -293,7 +283,7 @@ class Tooltip {
this._popper = new Popper(this.element, tip, this._getPopperConfig(attachment))
$(tip).addClass(ClassName.SHOW)
$(tip).addClass(CLASS_NAME_SHOW)
// If this is a touch-enabled device we add extra
// empty mouseover listeners to the body's immediate children;
@ -312,12 +302,12 @@ class Tooltip {
$(this.element).trigger(this.constructor.Event.SHOWN)
if (prevHoverState === HoverState.OUT) {
if (prevHoverState === HOVER_STATE_OUT) {
this._leave(null, this)
}
}
if ($(this.tip).hasClass(ClassName.FADE)) {
if ($(this.tip).hasClass(CLASS_NAME_FADE)) {
const transitionDuration = Util.getTransitionDurationFromElement(this.tip)
$(this.tip)
@ -333,7 +323,7 @@ class Tooltip {
const tip = this.getTipElement()
const hideEvent = $.Event(this.constructor.Event.HIDE)
const complete = () => {
if (this._hoverState !== HoverState.SHOW && tip.parentNode) {
if (this._hoverState !== HOVER_STATE_SHOW && tip.parentNode) {
tip.parentNode.removeChild(tip)
}
@ -355,7 +345,7 @@ class Tooltip {
return
}
$(tip).removeClass(ClassName.SHOW)
$(tip).removeClass(CLASS_NAME_SHOW)
// If this is a touch-enabled device we remove the extra
// empty mouseover listeners we added for iOS support
@ -363,11 +353,11 @@ class Tooltip {
$(document.body).children().off('mouseover', null, $.noop)
}
this._activeTrigger[Trigger.CLICK] = false
this._activeTrigger[Trigger.FOCUS] = false
this._activeTrigger[Trigger.HOVER] = false
this._activeTrigger[TRIGGER_CLICK] = false
this._activeTrigger[TRIGGER_FOCUS] = false
this._activeTrigger[TRIGGER_HOVER] = false
if ($(this.tip).hasClass(ClassName.FADE)) {
if ($(this.tip).hasClass(CLASS_NAME_FADE)) {
const transitionDuration = Util.getTransitionDurationFromElement(tip)
$(tip)
@ -403,8 +393,8 @@ class Tooltip {
setContent() {
const tip = this.getTipElement()
this.setElementContent($(tip.querySelectorAll(Selector.TOOLTIP_INNER)), this.getTitle())
$(tip).removeClass(`${ClassName.FADE} ${ClassName.SHOW}`)
this.setElementContent($(tip.querySelectorAll(SELECTOR_TOOLTIP_INNER)), this.getTitle())
$(tip).removeClass(`${CLASS_NAME_FADE} ${CLASS_NAME_SHOW}`)
}
setElementContent($element, content) {
@ -455,7 +445,7 @@ class Tooltip {
behavior: this.config.fallbackPlacement
},
arrow: {
element: Selector.ARROW
element: SELECTOR_ARROW
},
preventOverflow: {
boundariesElement: this.config.boundary
@ -520,11 +510,11 @@ class Tooltip {
this.config.selector,
(event) => this.toggle(event)
)
} else if (trigger !== Trigger.MANUAL) {
const eventIn = trigger === Trigger.HOVER
} else if (trigger !== TRIGGER_MANUAL) {
const eventIn = trigger === TRIGGER_HOVER
? this.constructor.Event.MOUSEENTER
: this.constructor.Event.FOCUSIN
const eventOut = trigger === Trigger.HOVER
const eventOut = trigger === TRIGGER_HOVER
? this.constructor.Event.MOUSELEAVE
: this.constructor.Event.FOCUSOUT
@ -591,18 +581,18 @@ class Tooltip {
if (event) {
context._activeTrigger[
event.type === 'focusin' ? Trigger.FOCUS : Trigger.HOVER
event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER
] = true
}
if ($(context.getTipElement()).hasClass(ClassName.SHOW) || context._hoverState === HoverState.SHOW) {
context._hoverState = HoverState.SHOW
if ($(context.getTipElement()).hasClass(CLASS_NAME_SHOW) || context._hoverState === HOVER_STATE_SHOW) {
context._hoverState = HOVER_STATE_SHOW
return
}
clearTimeout(context._timeout)
context._hoverState = HoverState.SHOW
context._hoverState = HOVER_STATE_SHOW
if (!context.config.delay || !context.config.delay.show) {
context.show()
@ -610,7 +600,7 @@ class Tooltip {
}
context._timeout = setTimeout(() => {
if (context._hoverState === HoverState.SHOW) {
if (context._hoverState === HOVER_STATE_SHOW) {
context.show()
}
}, context.config.delay.show)
@ -630,7 +620,7 @@ class Tooltip {
if (event) {
context._activeTrigger[
event.type === 'focusout' ? Trigger.FOCUS : Trigger.HOVER
event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER
] = false
}
@ -640,7 +630,7 @@ class Tooltip {
clearTimeout(context._timeout)
context._hoverState = HoverState.OUT
context._hoverState = HOVER_STATE_OUT
if (!context.config.delay || !context.config.delay.hide) {
context.hide()
@ -648,7 +638,7 @@ class Tooltip {
}
context._timeout = setTimeout(() => {
if (context._hoverState === HoverState.OUT) {
if (context._hoverState === HOVER_STATE_OUT) {
context.hide()
}
}, context.config.delay.hide)
@ -745,7 +735,7 @@ class Tooltip {
return
}
$(tip).removeClass(ClassName.FADE)
$(tip).removeClass(CLASS_NAME_FADE)
this.config.animation = false
this.hide()
this.show()