From 89b9c9a79ca43dbc1ab06e0a947a2c71c2d785dc Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Tue, 31 Mar 2020 16:59:34 +0300 Subject: [PATCH] Switch to string 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 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 %) --- bundlesize.config.json | 4 +- js/src/alert.js | 34 ++++---- js/src/button.js | 84 ++++++++++---------- js/src/carousel.js | 173 +++++++++++++++++++---------------------- js/src/collapse.js | 90 ++++++++++----------- js/src/dropdown.js | 155 +++++++++++++++++------------------- js/src/modal.js | 156 ++++++++++++++++++------------------- js/src/popover.js | 18 ++--- js/src/scrollspy.js | 74 ++++++++---------- js/src/tab.js | 90 ++++++++++----------- js/src/toast.js | 60 +++++++------- js/src/tooltip.js | 82 +++++++++---------- 12 files changed, 469 insertions(+), 551 deletions(-) diff --git a/bundlesize.config.json b/bundlesize.config.json index e772acbfde39..71fbc812d6b3 100644 --- a/bundlesize.config.json +++ b/bundlesize.config.json @@ -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" } ] } diff --git a/js/src/alert.js b/js/src/alert.js index 57ab676f9d27..6d961670ff15 100644 --- a/js/src/alert.js +++ b/js/src/alert.js @@ -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()) ) diff --git a/js/src/button.js b/js/src/button.js index 76ea9e337720..322cb1066c37 100644 --- a/js/src/button.js +++ b/js/src/button.js @@ -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 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 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 CLASS_NAME_ACTIVE = 'active' +const CLASS_NAME_BUTTON = 'btn' +const CLASS_NAME_FOCUS = 'focus' + +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}` +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) } } }) diff --git a/js/src/carousel.js b/js/src/carousel.js index 74c41016831d..6d21a7f22d71 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -43,51 +43,42 @@ const DefaultType = { touch : 'boolean' } -const Direction = { - NEXT : 'next', - PREV : 'prev', - LEFT : 'left', - RIGHT : 'right' -} - -const Event = { - SLIDE : `slide${EVENT_KEY}`, - SLID : `slid${EVENT_KEY}`, - KEYDOWN : `keydown${EVENT_KEY}`, - MOUSEENTER : `mouseenter${EVENT_KEY}`, - MOUSELEAVE : `mouseleave${EVENT_KEY}`, - TOUCHSTART : `touchstart${EVENT_KEY}`, - TOUCHMOVE : `touchmove${EVENT_KEY}`, - TOUCHEND : `touchend${EVENT_KEY}`, - POINTERDOWN : `pointerdown${EVENT_KEY}`, - POINTERUP : `pointerup${EVENT_KEY}`, - DRAG_START : `dragstart${EVENT_KEY}`, - LOAD_DATA_API : `load${EVENT_KEY}${DATA_API_KEY}`, - CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}` -} - -const ClassName = { - CAROUSEL : 'carousel', - ACTIVE : 'active', - SLIDE : 'slide', - RIGHT : 'carousel-item-right', - LEFT : 'carousel-item-left', - NEXT : 'carousel-item-next', - PREV : 'carousel-item-prev', - ITEM : 'carousel-item', - POINTER_EVENT : 'pointer-event' -} - -const Selector = { - ACTIVE : '.active', - ACTIVE_ITEM : '.active.carousel-item', - ITEM : '.carousel-item', - ITEM_IMG : '.carousel-item img', - NEXT_PREV : '.carousel-item-next, .carousel-item-prev', - INDICATORS : '.carousel-indicators', - DATA_SLIDE : '[data-slide], [data-slide-to]', - DATA_RIDE : '[data-ride="carousel"]' -} +const DIRECTION_NEXT = 'next' +const DIRECTION_PREV = 'prev' +const DIRECTION_LEFT = 'left' +const DIRECTION_RIGHT = 'right' + +const EVENT_SLIDE = `slide${EVENT_KEY}` +const EVENT_SLID = `slid${EVENT_KEY}` +const EVENT_KEYDOWN = `keydown${EVENT_KEY}` +const EVENT_MOUSEENTER = `mouseenter${EVENT_KEY}` +const EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY}` +const EVENT_TOUCHSTART = `touchstart${EVENT_KEY}` +const EVENT_TOUCHMOVE = `touchmove${EVENT_KEY}` +const EVENT_TOUCHEND = `touchend${EVENT_KEY}` +const EVENT_POINTERDOWN = `pointerdown${EVENT_KEY}` +const EVENT_POINTERUP = `pointerup${EVENT_KEY}` +const EVENT_DRAG_START = `dragstart${EVENT_KEY}` +const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}` +const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` + +const CLASS_NAME_CAROUSEL = 'carousel' +const CLASS_NAME_ACTIVE = 'active' +const CLASS_NAME_SLIDE = 'slide' +const CLASS_NAME_RIGHT = 'carousel-item-right' +const CLASS_NAME_LEFT = 'carousel-item-left' +const CLASS_NAME_NEXT = 'carousel-item-next' +const CLASS_NAME_PREV = 'carousel-item-prev' +const CLASS_NAME_POINTER_EVENT = 'pointer-event' + +const SELECTOR_ACTIVE = '.active' +const SELECTOR_ACTIVE_ITEM = '.active.carousel-item' +const SELECTOR_ITEM = '.carousel-item' +const SELECTOR_ITEM_IMG = '.carousel-item img' +const SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev' +const SELECTOR_INDICATORS = '.carousel-indicators' +const SELECTOR_DATA_SLIDE = '[data-slide], [data-slide-to]' +const SELECTOR_DATA_RIDE = '[data-ride="carousel"]' const PointerType = { TOUCH : 'touch', @@ -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()) diff --git a/js/src/collapse.js b/js/src/collapse.js index 8abab3f1dbb8..4243019a8e88 100644 --- a/js/src/collapse.js +++ b/js/src/collapse.js @@ -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 elements (which change the URL) not inside the collapsible element if (event.currentTarget.tagName === 'A') { event.preventDefault() diff --git a/js/src/dropdown.js b/js/src/dropdown.js index f907c0849583..12ca85756e12 100644 --- a/js/src/dropdown.js +++ b/js/src/dropdown.js @@ -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 ClassName = { - DISABLED : 'disabled', - SHOW : 'show', - DROPUP : 'dropup', - DROPRIGHT : 'dropright', - DROPLEFT : 'dropleft', - MENURIGHT : 'dropdown-menu-right', - MENULEFT : 'dropdown-menu-left', - 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 AttachmentMap = { - TOP : 'top-start', - TOPEND : 'top-end', - BOTTOM : 'bottom-start', - BOTTOMEND : 'bottom-end', - RIGHT : 'right-start', - RIGHTEND : 'right-end', - LEFT : 'left-start', - LEFTEND : 'left-end' -} +const EVENT_HIDE = `hide${EVENT_KEY}` +const EVENT_HIDDEN = `hidden${EVENT_KEY}` +const EVENT_SHOW = `show${EVENT_KEY}` +const EVENT_SHOWN = `shown${EVENT_KEY}` +const EVENT_CLICK = `click${EVENT_KEY}` +const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` +const EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY}${DATA_API_KEY}` +const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}` + +const CLASS_NAME_DISABLED = 'disabled' +const CLASS_NAME_SHOW = 'show' +const CLASS_NAME_DROPUP = 'dropup' +const CLASS_NAME_DROPRIGHT = 'dropright' +const CLASS_NAME_DROPLEFT = 'dropleft' +const CLASS_NAME_MENURIGHT = 'dropdown-menu-right' +const CLASS_NAME_POSITION_STATIC = 'position-static' + +const SELECTOR_DATA_TOGGLE = '[data-toggle="dropdown"]' +const SELECTOR_FORM_CHILD = '.dropdown form' +const SELECTOR_MENU = '.dropdown-menu' +const SELECTOR_NAVBAR_NAV = '.navbar-nav' +const SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)' + +const PLACEMENT_TOP = 'top-start' +const PLACEMENT_TOPEND = 'top-end' +const PLACEMENT_BOTTOM = 'bottom-start' +const PLACEMENT_BOTTOMEND = 'bottom-end' +const PLACEMENT_RIGHT = 'right-start' +const PLACEMENT_LEFT = 'left-start' const Default = { offset : 0, @@ -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() }) diff --git a/js/src/modal.js b/js/src/modal.js index faaa8f108386..6b80bb2f0dfd 100644 --- a/js/src/modal.js +++ b/js/src/modal.js @@ -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 ClassName = { - SCROLLABLE : 'modal-dialog-scrollable', - SCROLLBAR_MEASURER : 'modal-scrollbar-measure', - BACKDROP : 'modal-backdrop', - OPEN : 'modal-open', - FADE : 'fade', - SHOW : 'show', - STATIC : 'modal-static' -} - -const Selector = { - DIALOG : '.modal-dialog', - MODAL_BODY : '.modal-body', - DATA_TOGGLE : '[data-toggle="modal"]', - DATA_DISMISS : '[data-dismiss="modal"]', - FIXED_CONTENT : '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top', - STICKY_CONTENT : '.sticky-top' -} +const EVENT_HIDE = `hide${EVENT_KEY}` +const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}` +const EVENT_HIDDEN = `hidden${EVENT_KEY}` +const EVENT_SHOW = `show${EVENT_KEY}` +const EVENT_SHOWN = `shown${EVENT_KEY}` +const EVENT_FOCUSIN = `focusin${EVENT_KEY}` +const EVENT_RESIZE = `resize${EVENT_KEY}` +const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}` +const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}` +const EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY}` +const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}` +const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` + +const CLASS_NAME_SCROLLABLE = 'modal-dialog-scrollable' +const CLASS_NAME_SCROLLBAR_MEASURER = 'modal-scrollbar-measure' +const CLASS_NAME_BACKDROP = 'modal-backdrop' +const CLASS_NAME_OPEN = 'modal-open' +const CLASS_NAME_FADE = 'fade' +const CLASS_NAME_SHOW = 'show' +const CLASS_NAME_STATIC = 'modal-static' + +const SELECTOR_DIALOG = '.modal-dialog' +const SELECTOR_MODAL_BODY = '.modal-body' +const SELECTOR_DATA_TOGGLE = '[data-toggle="modal"]' +const SELECTOR_DATA_DISMISS = '[data-dismiss="modal"]' +const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top' +const SELECTOR_STICKY_CONTENT = '.sticky-top' /** * ------------------------------------------------------------------------ @@ -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() } diff --git a/js/src/popover.js b/js/src/popover.js index 570dba99183f..8e6ed62067c2 100644 --- a/js/src/popover.js +++ b/js/src/popover.js @@ -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 diff --git a/js/src/scrollspy.js b/js/src/scrollspy.js index e9b6c8cd29e3..9c856c4edf15 100644 --- a/js/src/scrollspy.js +++ b/js/src/scrollspy.js @@ -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