diff options
35 files changed, 614 insertions, 582 deletions
diff --git a/build/build-plugins.js b/build/build-plugins.js index 3829bb294c..521450f856 100644 --- a/build/build-plugins.js +++ b/build/build-plugins.js @@ -39,7 +39,7 @@ const bsPlugins = { } const rootPath = TEST ? '../js/coverage/dist/' : '../js/dist/' -const build = async (plugin) => { +const build = async plugin => { console.log(`Building ${plugin} plugin...`) const external = ['jquery', 'popper.js'] @@ -81,7 +81,7 @@ const build = async (plugin) => { const main = async () => { try { - await Promise.all(Object.keys(bsPlugins).map((plugin) => build(plugin))) + await Promise.all(Object.keys(bsPlugins).map(plugin => build(plugin))) } catch (error) { console.error(error) diff --git a/build/change-version.js b/build/change-version.js index d1131237c1..e2de874d7f 100755 --- a/build/change-version.js +++ b/build/change-version.js @@ -30,18 +30,21 @@ function walkAsync(directory, excludedDirectories, fileCallback, errback) { if (excludedDirectories.has(path.parse(directory).base)) { return } + fs.readdir(directory, (err, names) => { if (err) { errback(err) return } - names.forEach((name) => { + + names.forEach(name => { const filepath = path.join(directory, name) fs.lstat(filepath, (err, stats) => { if (err) { process.nextTick(errback, err) return } + if (stats.isDirectory()) { process.nextTick(walkAsync, filepath, excludedDirectories, fileCallback, errback) } else if (stats.isFile()) { @@ -55,18 +58,19 @@ function walkAsync(directory, excludedDirectories, fileCallback, errback) { function replaceRecursively(directory, excludedDirectories, allowedExtensions, original, replacement) { original = new RegExp(regExpQuote(original), 'g') replacement = regExpQuoteReplacement(replacement) - const updateFile = DRY_RUN ? (filepath) => { + const updateFile = DRY_RUN ? filepath => { if (allowedExtensions.has(path.parse(filepath).ext)) { console.log(`FILE: ${filepath}`) } else { console.log(`EXCLUDED:${filepath}`) } - } : (filepath) => { + } : filepath => { if (allowedExtensions.has(path.parse(filepath).ext)) { sh.sed('-i', original, replacement, filepath) } } - walkAsync(directory, excludedDirectories, updateFile, (err) => { + + walkAsync(directory, excludedDirectories, updateFile, err => { console.error('ERROR while traversing directory!:') console.error(err) process.exit(1) @@ -79,6 +83,7 @@ function main(args) { console.error('Got arguments:', args) process.exit(1) } + const oldVersion = args[0] const newVersion = args[1] const EXCLUDED_DIRS = new Set([ diff --git a/build/generate-sri.js b/build/generate-sri.js index d340b5378f..972f8622ef 100644 --- a/build/generate-sri.js +++ b/build/generate-sri.js @@ -49,7 +49,7 @@ const files = [ } ] -files.forEach((file) => { +files.forEach(file => { fs.readFile(file.file, 'utf8', (err, data) => { if (err) { throw err diff --git a/build/postcss.config.js b/build/postcss.config.js index 157291ffd2..bd307fa35d 100644 --- a/build/postcss.config.js +++ b/build/postcss.config.js @@ -1,6 +1,6 @@ 'use strict' -module.exports = (ctx) => ({ +module.exports = ctx => ({ map: ctx.file.dirname.includes('examples') ? false : { inline: false, annotation: true, diff --git a/build/zip-examples.js b/build/zip-examples.js index 5d6d31454c..778d75f05b 100644 --- a/build/zip-examples.js +++ b/build/zip-examples.js @@ -43,7 +43,7 @@ sh.cp('-f', [ sh.rm(`${folderName}/index.html`) // get all examples' HTML files -sh.find(`${folderName}/**/*.html`).forEach((file) => { +sh.find(`${folderName}/**/*.html`).forEach(file => { const fileContents = sh.cat(file) .toString() .replace(new RegExp(`"/docs/${versionShort}/`, 'g'), '"../') diff --git a/js/src/alert.js b/js/src/alert.js index 2cdb0f0238..29743aa9bc 100644 --- a/js/src/alert.js +++ b/js/src/alert.js @@ -14,22 +14,22 @@ import Util from './util' * ------------------------------------------------------------------------ */ -const NAME = 'alert' -const VERSION = '4.5.2' -const DATA_KEY = 'bs.alert' -const EVENT_KEY = `.${DATA_KEY}` -const DATA_API_KEY = '.data-api' -const JQUERY_NO_CONFLICT = $.fn[NAME] +const NAME = 'alert' +const VERSION = '4.5.2' +const DATA_KEY = 'bs.alert' +const EVENT_KEY = `.${DATA_KEY}` +const DATA_API_KEY = '.data-api' +const JQUERY_NO_CONFLICT = $.fn[NAME] const SELECTOR_DISMISS = '[data-dismiss="alert"]' -const EVENT_CLOSE = `close${EVENT_KEY}` -const EVENT_CLOSED = `closed${EVENT_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 CLASS_NAME_ALERT = 'alert' -const CLASS_NAME_FADE = 'fade' -const CLASS_NAME_SHOW = 'show' +const CLASS_NAME_FADE = 'fade' +const CLASS_NAME_SHOW = 'show' /** * ------------------------------------------------------------------------ @@ -74,7 +74,7 @@ class Alert { _getRootElement(element) { const selector = Util.getSelectorFromElement(element) - let parent = false + let parent = false if (selector) { parent = document.querySelector(selector) @@ -105,7 +105,7 @@ class Alert { const transitionDuration = Util.getTransitionDurationFromElement(element) $(element) - .one(Util.TRANSITION_END, (event) => this._destroyElement(element, event)) + .one(Util.TRANSITION_END, event => this._destroyElement(element, event)) .emulateTransitionEnd(transitionDuration) } @@ -121,7 +121,7 @@ class Alert { static _jQueryInterface(config) { return this.each(function () { const $element = $(this) - let data = $element.data(DATA_KEY) + let data = $element.data(DATA_KEY) if (!data) { data = new Alert(this) @@ -163,9 +163,9 @@ $(document).on( * ------------------------------------------------------------------------ */ -$.fn[NAME] = Alert._jQueryInterface +$.fn[NAME] = Alert._jQueryInterface $.fn[NAME].Constructor = Alert -$.fn[NAME].noConflict = () => { +$.fn[NAME].noConflict = () => { $.fn[NAME] = JQUERY_NO_CONFLICT return Alert._jQueryInterface } diff --git a/js/src/button.js b/js/src/button.js index 98fd8afce6..2aed6b09c7 100644 --- a/js/src/button.js +++ b/js/src/button.js @@ -13,29 +13,29 @@ import $ from 'jquery' * ------------------------------------------------------------------------ */ -const NAME = 'button' -const VERSION = '4.5.2' -const DATA_KEY = 'bs.button' -const EVENT_KEY = `.${DATA_KEY}` -const DATA_API_KEY = '.data-api' -const JQUERY_NO_CONFLICT = $.fn[NAME] +const NAME = 'button' +const VERSION = '4.5.2' +const DATA_KEY = 'bs.button' +const EVENT_KEY = `.${DATA_KEY}` +const DATA_API_KEY = '.data-api' +const JQUERY_NO_CONFLICT = $.fn[NAME] const CLASS_NAME_ACTIVE = 'active' const CLASS_NAME_BUTTON = 'btn' -const CLASS_NAME_FOCUS = 'focus' +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_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 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_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}` +const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}` /** * ------------------------------------------------------------------------ @@ -85,6 +85,7 @@ class Button { if (input.type === 'checkbox' || input.type === 'radio') { input.checked = !this._element.classList.contains(CLASS_NAME_ACTIVE) } + $(input).trigger('change') } @@ -135,7 +136,7 @@ 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 @@ -158,7 +159,7 @@ $(document) } } }) - .on(EVENT_FOCUS_BLUR_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, (event) => { + .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)) }) diff --git a/js/src/carousel.js b/js/src/carousel.js index d18cc8a1a0..8c03818ab0 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -14,75 +14,75 @@ import Util from './util' * ------------------------------------------------------------------------ */ -const NAME = 'carousel' -const VERSION = '4.5.2' -const DATA_KEY = 'bs.carousel' -const EVENT_KEY = `.${DATA_KEY}` -const DATA_API_KEY = '.data-api' -const JQUERY_NO_CONFLICT = $.fn[NAME] -const ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key -const ARROW_RIGHT_KEYCODE = 39 // KeyboardEvent.which value for right arrow key +const NAME = 'carousel' +const VERSION = '4.5.2' +const DATA_KEY = 'bs.carousel' +const EVENT_KEY = `.${DATA_KEY}` +const DATA_API_KEY = '.data-api' +const JQUERY_NO_CONFLICT = $.fn[NAME] +const ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key +const ARROW_RIGHT_KEYCODE = 39 // KeyboardEvent.which value for right arrow key const TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch -const SWIPE_THRESHOLD = 40 +const SWIPE_THRESHOLD = 40 const Default = { - interval : 5000, - keyboard : true, - slide : false, - pause : 'hover', - wrap : true, - touch : true + interval: 5000, + keyboard: true, + slide: false, + pause: 'hover', + wrap: true, + touch: true } const DefaultType = { - interval : '(number|boolean)', - keyboard : 'boolean', - slide : '(boolean|string)', - pause : '(string|boolean)', - wrap : 'boolean', - touch : 'boolean' + interval: '(number|boolean)', + keyboard: 'boolean', + slide: '(boolean|string)', + pause: '(string|boolean)', + wrap: 'boolean', + touch: 'boolean' } -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 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_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 = '.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 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', - PEN : 'pen' + TOUCH: 'touch', + PEN: 'pen' } /** @@ -92,20 +92,20 @@ const PointerType = { */ class Carousel { constructor(element, config) { - this._items = null - this._interval = null + this._items = null + this._interval = null this._activeElement = null - this._isPaused = false - this._isSliding = false - this.touchTimeout = null - this.touchStartX = 0 - this.touchDeltaX = 0 - - this._config = this._getConfig(config) - this._element = element + this._isPaused = false + this._isSliding = false + this.touchTimeout = null + this.touchStartX = 0 + this.touchDeltaX = 0 + + this._config = this._getConfig(config) + this._element = element this._indicatorsElement = this._element.querySelector(SELECTOR_INDICATORS) - this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0 - this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent) + this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0 + this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent) this._addEventListeners() } @@ -195,9 +195,9 @@ class Carousel { return } - const direction = index > activeIndex - ? DIRECTION_NEXT - : DIRECTION_PREV + const direction = index > activeIndex ? + DIRECTION_NEXT : + DIRECTION_PREV this._slide(direction, this._items[index]) } @@ -206,13 +206,13 @@ class Carousel { $(this._element).off(EVENT_KEY) $.removeData(this._element, DATA_KEY) - this._items = null - this._config = null - this._element = null - this._interval = null - this._isPaused = null - this._isSliding = null - this._activeElement = null + this._items = null + this._config = null + this._element = null + this._interval = null + this._isPaused = null + this._isSliding = null + this._activeElement = null this._indicatorsElement = null } @@ -251,13 +251,13 @@ class Carousel { _addEventListeners() { if (this._config.keyboard) { - $(this._element).on(EVENT_KEYDOWN, (event) => this._keydown(event)) + $(this._element).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) { @@ -270,7 +270,7 @@ class Carousel { return } - const start = (event) => { + const start = event => { if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) { this.touchStartX = event.originalEvent.clientX } else if (!this._pointerEvent) { @@ -278,7 +278,7 @@ class Carousel { } } - const move = (event) => { + const move = event => { // ensure swiping with one touch and not pinching if (event.originalEvent.touches && event.originalEvent.touches.length > 1) { this.touchDeltaX = 0 @@ -287,7 +287,7 @@ class Carousel { } } - const end = (event) => { + const end = event => { if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) { this.touchDeltaX = event.originalEvent.clientX - this.touchStartX } @@ -306,22 +306,23 @@ class Carousel { if (this.touchTimeout) { clearTimeout(this.touchTimeout) } - this.touchTimeout = setTimeout((event) => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval) + + this.touchTimeout = setTimeout(event => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval) } } $(this._element.querySelectorAll(SELECTOR_ITEM_IMG)) - .on(EVENT_DRAG_START, (e) => e.preventDefault()) + .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(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)) } } @@ -344,29 +345,29 @@ class Carousel { } _getItemIndex(element) { - this._items = element && element.parentNode - ? [].slice.call(element.parentNode.querySelectorAll(SELECTOR_ITEM)) - : [] + this._items = element && element.parentNode ? + [].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 activeIndex = this._getItemIndex(activeElement) - const lastItemIndex = this._items.length - 1 - const isGoingToWrap = isPrevDirection && activeIndex === 0 || + const activeIndex = this._getItemIndex(activeElement) + const lastItemIndex = this._items.length - 1 + const isGoingToWrap = isPrevDirection && activeIndex === 0 || isNextDirection && activeIndex === lastItemIndex if (isGoingToWrap && !this._config.wrap) { 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 - ? this._items[this._items.length - 1] : this._items[itemIndex] + return itemIndex === -1 ? + this._items[this._items.length - 1] : this._items[itemIndex] } _triggerSlideEvent(relatedTarget, eventDirectionName) { @@ -402,7 +403,7 @@ class Carousel { _slide(direction, element) { const activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM) const activeElementIndex = this._getItemIndex(activeElement) - const nextElement = element || activeElement && + const nextElement = element || activeElement && this._getItemByDirection(direction, activeElement) const nextElementIndex = this._getItemIndex(nextElement) const isCycling = Boolean(this._interval) @@ -525,6 +526,7 @@ class Carousel { if (typeof data[action] === 'undefined') { throw new TypeError(`No method named "${action}"`) } + data[action]() } else if (_config.interval && _config.ride) { data.pause() diff --git a/js/src/collapse.js b/js/src/collapse.js index 9e501e085a..04653b835e 100644 --- a/js/src/collapse.js +++ b/js/src/collapse.js @@ -14,38 +14,38 @@ import Util from './util' * ------------------------------------------------------------------------ */ -const NAME = 'collapse' -const VERSION = '4.5.2' -const DATA_KEY = 'bs.collapse' -const EVENT_KEY = `.${DATA_KEY}` -const DATA_API_KEY = '.data-api' -const JQUERY_NO_CONFLICT = $.fn[NAME] +const NAME = 'collapse' +const VERSION = '4.5.2' +const DATA_KEY = 'bs.collapse' +const EVENT_KEY = `.${DATA_KEY}` +const DATA_API_KEY = '.data-api' +const JQUERY_NO_CONFLICT = $.fn[NAME] const Default = { - toggle : true, - parent : '' + toggle: true, + parent: '' } const DefaultType = { - toggle : 'boolean', - parent : '(string|element)' + toggle: 'boolean', + parent: '(string|element)' } -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_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 CLASS_NAME_SHOW = 'show' -const CLASS_NAME_COLLAPSE = 'collapse' +const CLASS_NAME_SHOW = 'show' +const CLASS_NAME_COLLAPSE = 'collapse' const CLASS_NAME_COLLAPSING = 'collapsing' -const CLASS_NAME_COLLAPSED = 'collapsed' +const CLASS_NAME_COLLAPSED = 'collapsed' -const DIMENSION_WIDTH = 'width' +const DIMENSION_WIDTH = 'width' const DIMENSION_HEIGHT = 'height' -const SELECTOR_ACTIVES = '.show, .collapsing' +const SELECTOR_ACTIVES = '.show, .collapsing' const SELECTOR_DATA_TOGGLE = '[data-toggle="collapse"]' /** @@ -57,9 +57,9 @@ const SELECTOR_DATA_TOGGLE = '[data-toggle="collapse"]' class Collapse { constructor(element, config) { this._isTransitioning = false - this._element = element - this._config = this._getConfig(config) - this._triggerArray = [].slice.call(document.querySelectorAll( + this._element = element + this._config = this._getConfig(config) + this._triggerArray = [].slice.call(document.querySelectorAll( `[data-toggle="collapse"][href="#${element.id}"],` + `[data-toggle="collapse"][data-target="#${element.id}"]` )) @@ -69,7 +69,7 @@ class Collapse { const elem = toggleList[i] const selector = Util.getSelectorFromElement(elem) const filterElement = [].slice.call(document.querySelectorAll(selector)) - .filter((foundElem) => foundElem === element) + .filter(foundElem => foundElem === element) if (selector !== null && filterElement.length > 0) { this._selector = selector @@ -119,7 +119,7 @@ class Collapse { if (this._parent) { actives = [].slice.call(this._parent.querySelectorAll(SELECTOR_ACTIVES)) - .filter((elem) => { + .filter(elem => { if (typeof this._config.parent === 'string') { return elem.getAttribute('data-parent') === this._config.parent } @@ -254,10 +254,10 @@ class Collapse { dispose() { $.removeData(this._element, DATA_KEY) - this._config = null - this._parent = null - this._element = null - this._triggerArray = null + this._config = null + this._parent = null + this._element = null + this._triggerArray = null this._isTransitioning = null } @@ -324,8 +324,8 @@ class Collapse { static _jQueryInterface(config) { return this.each(function () { - const $this = $(this) - let data = $this.data(DATA_KEY) + const $this = $(this) + let data = $this.data(DATA_KEY) const _config = { ...Default, ...$this.data(), @@ -345,6 +345,7 @@ class Collapse { if (typeof data[config] === 'undefined') { throw new TypeError(`No method named "${config}"`) } + data[config]() } }) @@ -369,8 +370,8 @@ $(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { $(selectors).each(function () { const $target = $(this) - const data = $target.data(DATA_KEY) - const config = data ? 'toggle' : $trigger.data() + const data = $target.data(DATA_KEY) + const config = data ? 'toggle' : $trigger.data() Collapse._jQueryInterface.call($target, config) }) }) diff --git a/js/src/dropdown.js b/js/src/dropdown.js index bfb1f668cc..8cfa5564ab 100644 --- a/js/src/dropdown.js +++ b/js/src/dropdown.js @@ -15,66 +15,66 @@ import Util from './util' * ------------------------------------------------------------------------ */ -const NAME = 'dropdown' -const VERSION = '4.5.2' -const DATA_KEY = 'bs.dropdown' -const EVENT_KEY = `.${DATA_KEY}` -const DATA_API_KEY = '.data-api' -const JQUERY_NO_CONFLICT = $.fn[NAME] -const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key -const SPACE_KEYCODE = 32 // KeyboardEvent.which value for space key -const TAB_KEYCODE = 9 // KeyboardEvent.which value for tab key -const ARROW_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key -const ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow key +const NAME = 'dropdown' +const VERSION = '4.5.2' +const DATA_KEY = 'bs.dropdown' +const EVENT_KEY = `.${DATA_KEY}` +const DATA_API_KEY = '.data-api' +const JQUERY_NO_CONFLICT = $.fn[NAME] +const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key +const SPACE_KEYCODE = 32 // KeyboardEvent.which value for space key +const TAB_KEYCODE = 9 // KeyboardEvent.which value for tab key +const ARROW_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key +const ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow key const RIGHT_MOUSE_BUTTON_WHICH = 3 // MouseEvent.which value for the right button (assuming a right-handed mouse) -const REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`) - -const EVENT_HIDE = `hide${EVENT_KEY}` -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 REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`) + +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 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_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_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 PLACEMENT_RIGHT = 'right-start' +const PLACEMENT_LEFT = 'left-start' const Default = { - offset : 0, - flip : true, - boundary : 'scrollParent', - reference : 'toggle', - display : 'dynamic', - popperConfig : null + offset: 0, + flip: true, + boundary: 'scrollParent', + reference: 'toggle', + display: 'dynamic', + popperConfig: null } const DefaultType = { - offset : '(number|string|function)', - flip : 'boolean', - boundary : '(string|element)', - reference : '(string|element)', - display : 'string', - popperConfig : '(null|object)' + offset: '(number|string|function)', + flip: 'boolean', + boundary: '(string|element)', + reference: '(string|element)', + display: 'string', + popperConfig: '(null|object)' } /** @@ -85,10 +85,10 @@ const DefaultType = { class Dropdown { constructor(element, config) { - this._element = element - this._popper = null - this._config = this._getConfig(config) - this._menu = this._getMenuElement() + this._element = element + this._popper = null + this._config = this._getConfig(config) + this._menu = this._getMenuElement() this._inNavbar = this._detectNavbar() this._addEventListeners() @@ -172,6 +172,7 @@ class Dropdown { if (this._config.boundary !== 'scrollParent') { $(parent).addClass(CLASS_NAME_POSITION_STATIC) } + this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig()) } @@ -241,7 +242,7 @@ class Dropdown { // Private _addEventListeners() { - $(this._element).on(EVENT_CLICK, (event) => { + $(this._element).on(EVENT_CLICK, event => { event.preventDefault() event.stopPropagation() this.toggle() @@ -272,6 +273,7 @@ class Dropdown { this._menu = parent.querySelector(SELECTOR_MENU) } } + return this._menu } @@ -281,9 +283,9 @@ class Dropdown { // Handle dropup if ($parentDropdown.hasClass(CLASS_NAME_DROPUP)) { - placement = $(this._menu).hasClass(CLASS_NAME_MENURIGHT) - ? PLACEMENT_TOPEND - : PLACEMENT_TOP + placement = $(this._menu).hasClass(CLASS_NAME_MENURIGHT) ? + PLACEMENT_TOPEND : + PLACEMENT_TOP } else if ($parentDropdown.hasClass(CLASS_NAME_DROPRIGHT)) { placement = PLACEMENT_RIGHT } else if ($parentDropdown.hasClass(CLASS_NAME_DROPLEFT)) { @@ -291,6 +293,7 @@ class Dropdown { } else if ($(this._menu).hasClass(CLASS_NAME_MENURIGHT)) { placement = PLACEMENT_BOTTOMEND } + return placement } @@ -302,7 +305,7 @@ class Dropdown { const offset = {} if (typeof this._config.offset === 'function') { - offset.fn = (data) => { + offset.fn = data => { data.offsets = { ...data.offsets, ...this._config.offset(data.offsets, this._element) || {} @@ -360,6 +363,7 @@ class Dropdown { if (typeof data[config] === 'undefined') { throw new TypeError(`No method named "${config}"`) } + data[config]() } }) @@ -444,8 +448,8 @@ class Dropdown { // - If key is other than escape // - If key is not up or down => not a dropdown command // - If trigger inside the menu => not a dropdown command - if (/input|textarea/i.test(event.target.tagName) - ? event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE && + 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)) { return @@ -455,7 +459,7 @@ class Dropdown { return } - const parent = Dropdown._getParentFromElement(this) + const parent = Dropdown._getParentFromElement(this) const isActive = $(parent).hasClass(CLASS_NAME_SHOW) if (!isActive && event.which === ESCAPE_KEYCODE) { @@ -475,7 +479,7 @@ class Dropdown { } const items = [].slice.call(parent.querySelectorAll(SELECTOR_VISIBLE_ITEMS)) - .filter((item) => $(item).is(':visible')) + .filter(item => $(item).is(':visible')) if (items.length === 0) { return @@ -514,7 +518,7 @@ $(document) 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 b67507b1ee..311c369ebb 100644 --- a/js/src/modal.js +++ b/js/src/modal.js @@ -14,54 +14,54 @@ import Util from './util' * ------------------------------------------------------------------------ */ -const NAME = 'modal' -const VERSION = '4.5.2' -const DATA_KEY = 'bs.modal' -const EVENT_KEY = `.${DATA_KEY}` -const DATA_API_KEY = '.data-api' +const NAME = 'modal' +const VERSION = '4.5.2' +const DATA_KEY = 'bs.modal' +const EVENT_KEY = `.${DATA_KEY}` +const DATA_API_KEY = '.data-api' const JQUERY_NO_CONFLICT = $.fn[NAME] -const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key +const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key const Default = { - backdrop : true, - keyboard : true, - focus : true, - show : true + backdrop: true, + keyboard: true, + focus: true, + show: true } const DefaultType = { - backdrop : '(boolean|string)', - keyboard : 'boolean', - focus : 'boolean', - show : 'boolean' + backdrop: '(boolean|string)', + keyboard: 'boolean', + focus: 'boolean', + show: 'boolean' } -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_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 EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` -const CLASS_NAME_SCROLLABLE = 'modal-dialog-scrollable' +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 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' /** @@ -72,15 +72,15 @@ const SELECTOR_STICKY_CONTENT = '.sticky-top' class Modal { constructor(element, config) { - this._config = this._getConfig(config) - this._element = element - this._dialog = element.querySelector(SELECTOR_DIALOG) - this._backdrop = null - this._isShown = false - this._isBodyOverflowing = false + this._config = this._getConfig(config) + this._element = element + this._dialog = element.querySelector(SELECTOR_DIALOG) + this._backdrop = null + this._isShown = false + this._isBodyOverflowing = false this._ignoreBackdropClick = false - this._isTransitioning = false - this._scrollbarWidth = 0 + this._isTransitioning = false + this._scrollbarWidth = 0 } // Getters @@ -131,11 +131,11 @@ class Modal { $(this._element).on( EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, - (event) => this.hide(event) + event => this.hide(event) ) $(this._dialog).on(EVENT_MOUSEDOWN_DISMISS, () => { - $(this._element).one(EVENT_MOUSEUP_DISMISS, (event) => { + $(this._element).one(EVENT_MOUSEUP_DISMISS, event => { if ($(event.target).is(this._element)) { this._ignoreBackdropClick = true } @@ -180,10 +180,10 @@ class Modal { $(this._dialog).off(EVENT_MOUSEDOWN_DISMISS) if (transition) { - const transitionDuration = Util.getTransitionDurationFromElement(this._element) + const transitionDuration = Util.getTransitionDurationFromElement(this._element) $(this._element) - .one(Util.TRANSITION_END, (event) => this._hideModal(event)) + .one(Util.TRANSITION_END, event => this._hideModal(event)) .emulateTransitionEnd(transitionDuration) } else { this._hideModal() @@ -192,7 +192,7 @@ class Modal { dispose() { [window, this._element, this._dialog] - .forEach((htmlElement) => $(htmlElement).off(EVENT_KEY)) + .forEach(htmlElement => $(htmlElement).off(EVENT_KEY)) /** * `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API` @@ -203,15 +203,15 @@ class Modal { $.removeData(this._element, DATA_KEY) - this._config = null - this._element = null - this._dialog = null - this._backdrop = null - this._isShown = null - this._isBodyOverflowing = null + this._config = null + this._element = null + this._dialog = null + this._backdrop = null + this._isShown = null + this._isBodyOverflowing = null this._ignoreBackdropClick = null - this._isTransitioning = null - this._scrollbarWidth = null + this._isTransitioning = null + this._scrollbarWidth = null } handleUpdate() { @@ -304,12 +304,13 @@ class Modal { if (this._config.focus) { this._element.focus() } + this._isTransitioning = false $(this._element).trigger(shownEvent) } if (transition) { - const transitionDuration = Util.getTransitionDurationFromElement(this._dialog) + const transitionDuration = Util.getTransitionDurationFromElement(this._dialog) $(this._dialog) .one(Util.TRANSITION_END, transitionComplete) @@ -322,7 +323,7 @@ class Modal { _enforceFocus() { $(document) .off(EVENT_FOCUSIN) // Guard against infinite focus loop - .on(EVENT_FOCUSIN, (event) => { + .on(EVENT_FOCUSIN, event => { if (document !== event.target && this._element !== event.target && $(this._element).has(event.target).length === 0) { @@ -333,7 +334,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() @@ -348,7 +349,7 @@ class Modal { _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) } @@ -376,8 +377,8 @@ class Modal { } _showBackdrop(callback) { - const animate = $(this._element).hasClass(CLASS_NAME_FADE) - ? CLASS_NAME_FADE : '' + const animate = $(this._element).hasClass(CLASS_NAME_FADE) ? + CLASS_NAME_FADE : '' if (this._isShown && this._config.backdrop) { this._backdrop = document.createElement('div') @@ -389,11 +390,12 @@ 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 } + if (event.target !== event.currentTarget) { return } @@ -563,6 +565,7 @@ class Modal { if (typeof data[config] === 'undefined') { throw new TypeError(`No method named "${config}"`) } + data[config](relatedTarget) } else if (_config.show) { data.show(relatedTarget) @@ -585,8 +588,8 @@ $(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { target = document.querySelector(selector) } - const config = $(target).data(DATA_KEY) - ? 'toggle' : { + const config = $(target).data(DATA_KEY) ? + 'toggle' : { ...$(target).data(), ...$(this).data() } @@ -595,7 +598,7 @@ $(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 diff --git a/js/src/popover.js b/js/src/popover.js index 885d162349..c81a18bad8 100644 --- a/js/src/popover.js +++ b/js/src/popover.js @@ -14,20 +14,20 @@ import Tooltip from './tooltip' * ------------------------------------------------------------------------ */ -const NAME = 'popover' -const VERSION = '4.5.2' -const DATA_KEY = 'bs.popover' -const EVENT_KEY = `.${DATA_KEY}` -const JQUERY_NO_CONFLICT = $.fn[NAME] -const CLASS_PREFIX = 'bs-popover' -const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\s)${CLASS_PREFIX}\\S+`, 'g') +const NAME = 'popover' +const VERSION = '4.5.2' +const DATA_KEY = 'bs.popover' +const EVENT_KEY = `.${DATA_KEY}` +const JQUERY_NO_CONFLICT = $.fn[NAME] +const CLASS_PREFIX = 'bs-popover' +const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\s)${CLASS_PREFIX}\\S+`, 'g') const Default = { ...Tooltip.Default, - placement : 'right', - trigger : 'click', - content : '', - template : '<div class="popover" role="tooltip">' + + placement: 'right', + trigger: 'click', + content: '', + template: '<div class="popover" role="tooltip">' + '<div class="arrow"></div>' + '<h3 class="popover-header"></h3>' + '<div class="popover-body"></div></div>' @@ -35,26 +35,26 @@ const Default = { const DefaultType = { ...Tooltip.DefaultType, - content : '(string|element|function)' + content: '(string|element|function)' } const CLASS_NAME_FADE = 'fade' const CLASS_NAME_SHOW = 'show' -const SELECTOR_TITLE = '.popover-header' +const SELECTOR_TITLE = '.popover-header' const SELECTOR_CONTENT = '.popover-body' const Event = { - HIDE : `hide${EVENT_KEY}`, - HIDDEN : `hidden${EVENT_KEY}`, - SHOW : `show${EVENT_KEY}`, - SHOWN : `shown${EVENT_KEY}`, - INSERTED : `inserted${EVENT_KEY}`, - CLICK : `click${EVENT_KEY}`, - FOCUSIN : `focusin${EVENT_KEY}`, - FOCUSOUT : `focusout${EVENT_KEY}`, - MOUSEENTER : `mouseenter${EVENT_KEY}`, - MOUSELEAVE : `mouseleave${EVENT_KEY}` + HIDE: `hide${EVENT_KEY}`, + HIDDEN: `hidden${EVENT_KEY}`, + SHOW: `show${EVENT_KEY}`, + SHOWN: `shown${EVENT_KEY}`, + INSERTED: `inserted${EVENT_KEY}`, + CLICK: `click${EVENT_KEY}`, + FOCUSIN: `focusin${EVENT_KEY}`, + FOCUSOUT: `focusout${EVENT_KEY}`, + MOUSEENTER: `mouseenter${EVENT_KEY}`, + MOUSELEAVE: `mouseleave${EVENT_KEY}` } /** @@ -118,6 +118,7 @@ class Popover extends Tooltip { if (typeof content === 'function') { content = content.call(this.element) } + this.setElementContent($tip.find(SELECTOR_CONTENT), content) $tip.removeClass(`${CLASS_NAME_FADE} ${CLASS_NAME_SHOW}`) @@ -158,6 +159,7 @@ class Popover extends Tooltip { if (typeof data[config] === 'undefined') { throw new TypeError(`No method named "${config}"`) } + data[config]() } }) diff --git a/js/src/scrollspy.js b/js/src/scrollspy.js index 78b5e71911..fbfc50043f 100644 --- a/js/src/scrollspy.js +++ b/js/src/scrollspy.js @@ -14,42 +14,42 @@ import Util from './util' * ------------------------------------------------------------------------ */ -const NAME = 'scrollspy' -const VERSION = '4.5.2' -const DATA_KEY = 'bs.scrollspy' -const EVENT_KEY = `.${DATA_KEY}` -const DATA_API_KEY = '.data-api' +const NAME = 'scrollspy' +const VERSION = '4.5.2' +const DATA_KEY = 'bs.scrollspy' +const EVENT_KEY = `.${DATA_KEY}` +const DATA_API_KEY = '.data-api' const JQUERY_NO_CONFLICT = $.fn[NAME] const Default = { - offset : 10, - method : 'auto', - target : '' + offset: 10, + method: 'auto', + target: '' } const DefaultType = { - offset : 'number', - method : 'string', - target : '(string|element)' + offset: 'number', + method: 'string', + target: '(string|element)' } -const EVENT_ACTIVATE = `activate${EVENT_KEY}` -const EVENT_SCROLL = `scroll${EVENT_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 CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item' -const CLASS_NAME_ACTIVE = 'active' - -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 CLASS_NAME_ACTIVE = 'active' + +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 METHOD_OFFSET = 'offset' +const METHOD_OFFSET = 'offset' const METHOD_POSITION = 'position' /** @@ -60,18 +60,18 @@ const METHOD_POSITION = 'position' class ScrollSpy { constructor(element, config) { - this._element = element + 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 = this._getConfig(config) + 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._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() @@ -90,14 +90,14 @@ class ScrollSpy { // Public refresh() { - const autoMethod = this._scrollElement === this._scrollElement.window - ? METHOD_OFFSET : METHOD_POSITION + const autoMethod = this._scrollElement === this._scrollElement.window ? + METHOD_OFFSET : METHOD_POSITION - const offsetMethod = this._config.method === 'auto' - ? autoMethod : this._config.method + const offsetMethod = this._config.method === 'auto' ? + autoMethod : this._config.method - const offsetBase = offsetMethod === METHOD_POSITION - ? this._getScrollTop() : 0 + const offsetBase = offsetMethod === METHOD_POSITION ? + this._getScrollTop() : 0 this._offsets = [] this._targets = [] @@ -107,7 +107,7 @@ class ScrollSpy { const targets = [].slice.call(document.querySelectorAll(this._selector)) targets - .map((element) => { + .map(element => { let target const targetSelector = Util.getSelectorFromElement(element) @@ -125,11 +125,12 @@ class ScrollSpy { ] } } + return null }) - .filter((item) => item) + .filter(item => item) .sort((a, b) => a[0] - b[0]) - .forEach((item) => { + .forEach(item => { this._offsets.push(item[0]) this._targets.push(item[1]) }) @@ -139,14 +140,14 @@ class ScrollSpy { $.removeData(this._element, DATA_KEY) $(this._scrollElement).off(EVENT_KEY) - this._element = null + this._element = null this._scrollElement = null - this._config = null - this._selector = null - this._offsets = null - this._targets = null - this._activeTarget = null - this._scrollHeight = null + this._config = null + this._selector = null + this._offsets = null + this._targets = null + this._activeTarget = null + this._scrollHeight = null } // Private @@ -163,6 +164,7 @@ class ScrollSpy { id = Util.getUID(NAME) $(config.target).attr('id', id) } + config.target = `#${id}` } @@ -172,8 +174,8 @@ class ScrollSpy { } _getScrollTop() { - return this._scrollElement === window - ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop + return this._scrollElement === window ? + this._scrollElement.pageYOffset : this._scrollElement.scrollTop } _getScrollHeight() { @@ -184,14 +186,14 @@ class ScrollSpy { } _getOffsetHeight() { - return this._scrollElement === window - ? window.innerHeight : this._scrollElement.getBoundingClientRect().height + return this._scrollElement === window ? + window.innerHeight : this._scrollElement.getBoundingClientRect().height } _process() { - const scrollTop = this._getScrollTop() + this._config.offset + const scrollTop = this._getScrollTop() + this._config.offset const scrollHeight = this._getScrollHeight() - const maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight() + const maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight() if (this._scrollHeight !== scrollHeight) { this.refresh() @@ -203,6 +205,7 @@ class ScrollSpy { if (this._activeTarget !== target) { this._activate(target) } + return } @@ -231,7 +234,7 @@ class ScrollSpy { const queries = this._selector .split(',') - .map((selector) => `${selector}[data-target="${target}"],${selector}[href="${target}"]`) + .map(selector => `${selector}[data-target="${target}"],${selector}[href="${target}"]`) const $link = $([].slice.call(document.querySelectorAll(queries.join(',')))) @@ -262,8 +265,8 @@ class ScrollSpy { _clear() { [].slice.call(document.querySelectorAll(this._selector)) - .filter((node) => node.classList.contains(CLASS_NAME_ACTIVE)) - .forEach((node) => node.classList.remove(CLASS_NAME_ACTIVE)) + .filter(node => node.classList.contains(CLASS_NAME_ACTIVE)) + .forEach(node => node.classList.remove(CLASS_NAME_ACTIVE)) } // Static @@ -282,6 +285,7 @@ class ScrollSpy { if (typeof data[config] === 'undefined') { throw new TypeError(`No method named "${config}"`) } + data[config]() } }) diff --git a/js/src/tab.js b/js/src/tab.js index 4e8981351b..7fcf07bc59 100644 --- a/js/src/tab.js +++ b/js/src/tab.js @@ -14,31 +14,31 @@ import Util from './util' * ------------------------------------------------------------------------ */ -const NAME = 'tab' -const VERSION = '4.5.2' -const DATA_KEY = 'bs.tab' -const EVENT_KEY = `.${DATA_KEY}` -const DATA_API_KEY = '.data-api' +const NAME = 'tab' +const VERSION = '4.5.2' +const DATA_KEY = 'bs.tab' +const EVENT_KEY = `.${DATA_KEY}` +const DATA_API_KEY = '.data-api' const JQUERY_NO_CONFLICT = $.fn[NAME] -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_HIDE = `hide${EVENT_KEY}` +const EVENT_HIDDEN = `hidden${EVENT_KEY}` +const EVENT_SHOW = `show${EVENT_KEY}` +const EVENT_SHOWN = `shown${EVENT_KEY}` const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` const CLASS_NAME_DROPDOWN_MENU = 'dropdown-menu' -const CLASS_NAME_ACTIVE = 'active' -const CLASS_NAME_DISABLED = 'disabled' -const CLASS_NAME_FADE = 'fade' -const CLASS_NAME_SHOW = 'show' - -const SELECTOR_DROPDOWN = '.dropdown' -const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group' -const SELECTOR_ACTIVE = '.active' -const SELECTOR_ACTIVE_UL = '> li > .active' -const SELECTOR_DATA_TOGGLE = '[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]' -const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle' +const CLASS_NAME_ACTIVE = 'active' +const CLASS_NAME_DISABLED = 'disabled' +const CLASS_NAME_FADE = 'fade' +const CLASS_NAME_SHOW = 'show' + +const SELECTOR_DROPDOWN = '.dropdown' +const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group' +const SELECTOR_ACTIVE = '.active' +const SELECTOR_ACTIVE_UL = '> 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' /** @@ -135,9 +135,9 @@ class Tab { // Private _activate(element, container, callback) { - const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') - ? $(container).find(SELECTOR_ACTIVE_UL) - : $(container).children(SELECTOR_ACTIVE) + const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ? + $(container).find(SELECTOR_ACTIVE_UL) : + $(container).children(SELECTOR_ACTIVE) const active = activeElements[0] const isTransitioning = callback && (active && $(active).hasClass(CLASS_NAME_FADE)) @@ -220,6 +220,7 @@ class Tab { if (typeof data[config] === 'undefined') { throw new TypeError(`No method named "${config}"`) } + data[config]() } }) diff --git a/js/src/toast.js b/js/src/toast.js index 8709d84e19..1959e72a61 100644 --- a/js/src/toast.js +++ b/js/src/toast.js @@ -14,33 +14,33 @@ import Util from './util' * ------------------------------------------------------------------------ */ -const NAME = 'toast' -const VERSION = '4.5.2' -const DATA_KEY = 'bs.toast' -const EVENT_KEY = `.${DATA_KEY}` +const NAME = 'toast' +const VERSION = '4.5.2' +const DATA_KEY = 'bs.toast' +const EVENT_KEY = `.${DATA_KEY}` const JQUERY_NO_CONFLICT = $.fn[NAME] 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 CLASS_NAME_FADE = 'fade' -const CLASS_NAME_HIDE = 'hide' -const CLASS_NAME_SHOW = 'show' +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 CLASS_NAME_FADE = 'fade' +const CLASS_NAME_HIDE = 'hide' +const CLASS_NAME_SHOW = 'show' const CLASS_NAME_SHOWING = 'showing' const DefaultType = { - animation : 'boolean', - autohide : 'boolean', - delay : 'number' + animation: 'boolean', + autohide: 'boolean', + delay: 'number' } const Default = { - animation : true, - autohide : true, - delay : 500 + animation: true, + autohide: true, + delay: 500 } const SELECTOR_DATA_DISMISS = '[data-dismiss="toast"]' @@ -54,7 +54,7 @@ const SELECTOR_DATA_DISMISS = '[data-dismiss="toast"]' class Toast { constructor(element, config) { this._element = element - this._config = this._getConfig(config) + this._config = this._getConfig(config) this._timeout = null this._setListeners() } @@ -142,7 +142,7 @@ class Toast { $.removeData(this._element, DATA_KEY) this._element = null - this._config = null + this._config = null } // Private @@ -195,8 +195,8 @@ class Toast { static _jQueryInterface(config) { return this.each(function () { const $element = $(this) - let data = $element.data(DATA_KEY) - const _config = typeof config === 'object' && config + let data = $element.data(DATA_KEY) + const _config = typeof config === 'object' && config if (!data) { data = new Toast(this, _config) @@ -220,9 +220,9 @@ class Toast { * ------------------------------------------------------------------------ */ -$.fn[NAME] = Toast._jQueryInterface +$.fn[NAME] = Toast._jQueryInterface $.fn[NAME].Constructor = Toast -$.fn[NAME].noConflict = () => { +$.fn[NAME].noConflict = () => { $.fn[NAME] = JQUERY_NO_CONFLICT return Toast._jQueryInterface } diff --git a/js/src/tools/sanitizer.js b/js/src/tools/sanitizer.js index 5ad77f330d..ef5c1c8144 100644 --- a/js/src/tools/sanitizer.js +++ b/js/src/tools/sanitizer.js @@ -77,7 +77,7 @@ function allowedAttribute(attr, allowedAttributeList) { return true } - const regExp = allowedAttributeList.filter((attrRegex) => attrRegex instanceof RegExp) + const regExp = allowedAttributeList.filter(attrRegex => attrRegex instanceof RegExp) // Check if a regular expression validates the attribute. for (let i = 0, len = regExp.length; i < len; i++) { @@ -116,7 +116,7 @@ export function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) { const attributeList = [].slice.call(el.attributes) const whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || []) - attributeList.forEach((attr) => { + attributeList.forEach(attr => { if (!allowedAttribute(attr, whitelistedAttributes)) { el.removeAttribute(attr.nodeName) } diff --git a/js/src/tooltip.js b/js/src/tooltip.js index c431459e1e..a1ce7ca87e 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -19,88 +19,88 @@ import Util from './util' * ------------------------------------------------------------------------ */ -const NAME = 'tooltip' -const VERSION = '4.5.2' -const DATA_KEY = 'bs.tooltip' -const EVENT_KEY = `.${DATA_KEY}` -const JQUERY_NO_CONFLICT = $.fn[NAME] -const CLASS_PREFIX = 'bs-tooltip' -const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\s)${CLASS_PREFIX}\\S+`, 'g') +const NAME = 'tooltip' +const VERSION = '4.5.2' +const DATA_KEY = 'bs.tooltip' +const EVENT_KEY = `.${DATA_KEY}` +const JQUERY_NO_CONFLICT = $.fn[NAME] +const CLASS_PREFIX = 'bs-tooltip' +const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\s)${CLASS_PREFIX}\\S+`, 'g') const DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn'] const DefaultType = { - animation : 'boolean', - template : 'string', - title : '(string|element|function)', - trigger : 'string', - delay : '(number|object)', - html : 'boolean', - selector : '(string|boolean)', - placement : '(string|function)', - offset : '(number|string|function)', - container : '(string|element|boolean)', - fallbackPlacement : '(string|array)', - boundary : '(string|element)', - sanitize : 'boolean', - sanitizeFn : '(null|function)', - whiteList : 'object', - popperConfig : '(null|object)' + animation: 'boolean', + template: 'string', + title: '(string|element|function)', + trigger: 'string', + delay: '(number|object)', + html: 'boolean', + selector: '(string|boolean)', + placement: '(string|function)', + offset: '(number|string|function)', + container: '(string|element|boolean)', + fallbackPlacement: '(string|array)', + boundary: '(string|element)', + sanitize: 'boolean', + sanitizeFn: '(null|function)', + whiteList: 'object', + popperConfig: '(null|object)' } const AttachmentMap = { - AUTO : 'auto', - TOP : 'top', - RIGHT : 'right', - BOTTOM : 'bottom', - LEFT : 'left' + AUTO: 'auto', + TOP: 'top', + RIGHT: 'right', + BOTTOM: 'bottom', + LEFT: 'left' } const Default = { - animation : true, - template : '<div class="tooltip" role="tooltip">' + + animation: true, + template: '<div class="tooltip" role="tooltip">' + '<div class="arrow"></div>' + '<div class="tooltip-inner"></div></div>', - trigger : 'hover focus', - title : '', - delay : 0, - html : false, - selector : false, - placement : 'top', - offset : 0, - container : false, - fallbackPlacement : 'flip', - boundary : 'scrollParent', - sanitize : true, - sanitizeFn : null, - whiteList : DefaultWhitelist, - popperConfig : null + trigger: 'hover focus', + title: '', + delay: 0, + html: false, + selector: false, + placement: 'top', + offset: 0, + container: false, + fallbackPlacement: 'flip', + boundary: 'scrollParent', + sanitize: true, + sanitizeFn: null, + whiteList: DefaultWhitelist, + popperConfig: null } const HOVER_STATE_SHOW = 'show' -const HOVER_STATE_OUT = 'out' +const HOVER_STATE_OUT = 'out' const Event = { - HIDE : `hide${EVENT_KEY}`, - HIDDEN : `hidden${EVENT_KEY}`, - SHOW : `show${EVENT_KEY}`, - SHOWN : `shown${EVENT_KEY}`, - INSERTED : `inserted${EVENT_KEY}`, - CLICK : `click${EVENT_KEY}`, - FOCUSIN : `focusin${EVENT_KEY}`, - FOCUSOUT : `focusout${EVENT_KEY}`, - MOUSEENTER : `mouseenter${EVENT_KEY}`, - MOUSELEAVE : `mouseleave${EVENT_KEY}` + HIDE: `hide${EVENT_KEY}`, + HIDDEN: `hidden${EVENT_KEY}`, + SHOW: `show${EVENT_KEY}`, + SHOWN: `shown${EVENT_KEY}`, + INSERTED: `inserted${EVENT_KEY}`, + CLICK: `click${EVENT_KEY}`, + FOCUSIN: `focusin${EVENT_KEY}`, + FOCUSOUT: `focusout${EVENT_KEY}`, + MOUSEENTER: `mouseenter${EVENT_KEY}`, + MOUSELEAVE: `mouseleave${EVENT_KEY}` } const CLASS_NAME_FADE = 'fade' const CLASS_NAME_SHOW = 'show' const SELECTOR_TOOLTIP_INNER = '.tooltip-inner' -const SELECTOR_ARROW = '.arrow' +const SELECTOR_ARROW = '.arrow' -const TRIGGER_HOVER = 'hover' -const TRIGGER_FOCUS = 'focus' -const TRIGGER_CLICK = 'click' +const TRIGGER_HOVER = 'hover' +const TRIGGER_FOCUS = 'focus' +const TRIGGER_CLICK = 'click' const TRIGGER_MANUAL = 'manual' /** @@ -116,16 +116,16 @@ class Tooltip { } // private - this._isEnabled = true - this._timeout = 0 - this._hoverState = '' + this._isEnabled = true + this._timeout = 0 + this._hoverState = '' this._activeTrigger = {} - this._popper = null + this._popper = null // Protected this.element = element - this.config = this._getConfig(config) - this.tip = null + this.config = this._getConfig(config) + this.tip = null this._setListeners() } @@ -220,9 +220,9 @@ class Tooltip { $(this.tip).remove() } - this._isEnabled = null - this._timeout = null - this._hoverState = null + this._isEnabled = null + this._timeout = null + this._hoverState = null this._activeTrigger = null if (this._popper) { this._popper.destroy() @@ -230,8 +230,8 @@ class Tooltip { this._popper = null this.element = null - this.config = null - this.tip = null + this.config = null + this.tip = null } show() { @@ -253,7 +253,7 @@ class Tooltip { return } - const tip = this.getTipElement() + const tip = this.getTipElement() const tipId = Util.getUID(this.constructor.NAME) tip.setAttribute('id', tipId) @@ -265,9 +265,9 @@ class Tooltip { $(tip).addClass(CLASS_NAME_FADE) } - const placement = typeof this.config.placement === 'function' - ? this.config.placement.call(this, tip, this.element) - : this.config.placement + const placement = typeof this.config.placement === 'function' ? + this.config.placement.call(this, tip, this.element) : + this.config.placement const attachment = this._getAttachment(placement) this.addAttachmentClass(attachment) @@ -297,8 +297,9 @@ class Tooltip { if (this.config.animation) { this._fixTransition() } + const prevHoverState = this._hoverState - this._hoverState = null + this._hoverState = null $(this.element).trigger(this.constructor.Event.SHOWN) @@ -320,7 +321,7 @@ class Tooltip { } hide(callback) { - const tip = this.getTipElement() + const tip = this.getTipElement() const hideEvent = $.Event(this.constructor.Event.HIDE) const complete = () => { if (this._hoverState !== HOVER_STATE_SHOW && tip.parentNode) { @@ -426,9 +427,9 @@ class Tooltip { let title = this.element.getAttribute('data-original-title') if (!title) { - title = typeof this.config.title === 'function' - ? this.config.title.call(this.element) - : this.config.title + title = typeof this.config.title === 'function' ? + this.config.title.call(this.element) : + this.config.title } return title @@ -451,12 +452,12 @@ class Tooltip { boundariesElement: this.config.boundary } }, - onCreate: (data) => { + onCreate: data => { if (data.originalPlacement !== data.placement) { this._handlePopperPlacementChange(data) } }, - onUpdate: (data) => this._handlePopperPlacementChange(data) + onUpdate: data => this._handlePopperPlacementChange(data) } return { @@ -469,7 +470,7 @@ class Tooltip { const offset = {} if (typeof this.config.offset === 'function') { - offset.fn = (data) => { + offset.fn = data => { data.offsets = { ...data.offsets, ...this.config.offset(data.offsets, this.element) || {} @@ -503,24 +504,24 @@ class Tooltip { _setListeners() { const triggers = this.config.trigger.split(' ') - triggers.forEach((trigger) => { + triggers.forEach(trigger => { if (trigger === 'click') { $(this.element).on( this.constructor.Event.CLICK, this.config.selector, - (event) => this.toggle(event) + event => this.toggle(event) ) } else if (trigger !== TRIGGER_MANUAL) { - const eventIn = trigger === TRIGGER_HOVER - ? this.constructor.Event.MOUSEENTER - : this.constructor.Event.FOCUSIN - const eventOut = trigger === TRIGGER_HOVER - ? this.constructor.Event.MOUSELEAVE - : this.constructor.Event.FOCUSOUT + const eventIn = trigger === TRIGGER_HOVER ? + this.constructor.Event.MOUSEENTER : + this.constructor.Event.FOCUSIN + const eventOut = trigger === TRIGGER_HOVER ? + this.constructor.Event.MOUSELEAVE : + this.constructor.Event.FOCUSOUT $(this.element) - .on(eventIn, this.config.selector, (event) => this._enter(event)) - .on(eventOut, this.config.selector, (event) => this._leave(event)) + .on(eventIn, this.config.selector, event => this._enter(event)) + .on(eventOut, this.config.selector, event => this._leave(event)) } }) @@ -647,7 +648,7 @@ class Tooltip { const dataAttributes = $(this.element).data() Object.keys(dataAttributes) - .forEach((dataAttr) => { + .forEach(dataAttr => { if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) { delete dataAttributes[dataAttr] } @@ -750,6 +751,7 @@ class Tooltip { if (typeof data[config] === 'undefined') { throw new TypeError(`No method named "${config}"`) } + data[config]() } }) diff --git a/js/src/util.js b/js/src/util.js index 9beafc4b56..c27ab33ed6 100644 --- a/js/src/util.js +++ b/js/src/util.js @@ -34,6 +34,7 @@ function getSpecialTransitionEndEvent() { if ($(event.target).is(this)) { return event.handleObj.handler.apply(this, arguments) // eslint-disable-line prefer-rest-params } + return undefined } } @@ -71,9 +72,9 @@ const Util = { getUID(prefix) { do { - // eslint-disable-next-line no-bitwise prefix += ~~(Math.random() * MAX_UID) // "~~" acts like a faster Math.floor() here } while (document.getElementById(prefix)) + return prefix }, @@ -87,7 +88,7 @@ const Util = { try { return document.querySelector(selector) ? selector : null - } catch (err) { + } catch (_) { return null } }, @@ -137,9 +138,9 @@ const Util = { for (const property in configTypes) { if (Object.prototype.hasOwnProperty.call(configTypes, property)) { const expectedTypes = configTypes[property] - const value = config[property] - const valueType = value && Util.isElement(value) - ? 'element' : toType(value) + const value = config[property] + const valueType = value && Util.isElement(value) ? + 'element' : toType(value) if (!new RegExp(expectedTypes).test(valueType)) { throw new Error( diff --git a/js/tests/browsers.js b/js/tests/browsers.js index 183084fefc..c61490fa15 100644 --- a/js/tests/browsers.js +++ b/js/tests/browsers.js @@ -13,8 +13,8 @@ const browsers = { base: 'BrowserStack', os: 'OS X', os_version: 'High Sierra', - browser : 'Chrome', - browser_version : 'latest' + browser: 'Chrome', + browser_version: 'latest' }, firefoxMac: { base: 'BrowserStack', diff --git a/js/tests/karma.conf.js b/js/tests/karma.conf.js index fc3c7703b4..65b292b5b3 100644 --- a/js/tests/karma.conf.js +++ b/js/tests/karma.conf.js @@ -135,7 +135,7 @@ conf.plugins = plugins conf.reporters = reporters conf.files = files -module.exports = (karmaConfig) => { +module.exports = karmaConfig => { // possible values: karmaConfig.LOG_DISABLE || karmaConfig.LOG_ERROR || karmaConfig.LOG_WARN || karmaConfig.LOG_INFO || karmaConfig.LOG_DEBUG conf.logLevel = karmaConfig.LOG_ERROR || karmaConfig.LOG_WARN karmaConfig.set(conf) diff --git a/js/tests/unit/carousel.js b/js/tests/unit/carousel.js index 3de00a2bdb..757461575b 100644 --- a/js/tests/unit/carousel.js +++ b/js/tests/unit/carousel.js @@ -65,8 +65,8 @@ $(function () { $el.bootstrapCarousel() try { $el.bootstrapCarousel('noMethod') - } catch (err) { - assert.strictEqual(err.message, 'No method named "noMethod"') + } catch (error) { + assert.strictEqual(error.message, 'No method named "noMethod"') } }) @@ -89,8 +89,8 @@ $(function () { try { $('<div/>').bootstrapCarousel(config) - } catch (err) { - message = err.message + } catch (error) { + message = error.message } assert.ok(message === expectedMessage, 'correct error message') @@ -102,8 +102,8 @@ $(function () { try { $('<div/>').bootstrapCarousel(config) - } catch (err) { - message = err.message + } catch (error) { + message = error.message } assert.ok(message === expectedMessage, 'correct error message') @@ -652,7 +652,7 @@ $(function () { var eventArrowDown = $.Event('keydown', { which: 40 }) - var eventArrowUp = $.Event('keydown', { + var eventArrowUp = $.Event('keydown', { which: 38 }) diff --git a/js/tests/unit/collapse.js b/js/tests/unit/collapse.js index 73bf6b35f7..293c7cada4 100644 --- a/js/tests/unit/collapse.js +++ b/js/tests/unit/collapse.js @@ -31,8 +31,8 @@ $(function () { $el.bootstrapCollapse() try { $el.bootstrapCollapse('noMethod') - } catch (err) { - assert.strictEqual(err.message, 'No method named "noMethod"') + } catch (error) { + assert.strictEqual(error.message, 'No method named "noMethod"') } }) @@ -457,7 +457,7 @@ $(function () { '<div class="card"/>' + '</div>' var showFired = false - var $groups = $(accordionHTML).appendTo('#qunit-fixture').find('.card') + var $groups = $(accordionHTML).appendTo('#qunit-fixture').find('.card') var $target1 = $('<a role="button" data-toggle="collapse" href="#body1"/>').appendTo($groups.eq(0)) @@ -468,7 +468,7 @@ $(function () { }) var $target2 = $('<a role="button" data-toggle="collapse" href="#body2"/>').appendTo($groups.eq(1)) - var $body2 = $('<div id="body2" class="collapse" data-parent="#accordion"/>').appendTo($groups.eq(1)) + var $body2 = $('<div id="body2" class="collapse" data-parent="#accordion"/>').appendTo($groups.eq(1)) $target2.trigger('click') @@ -604,8 +604,8 @@ $(function () { var $collapseTwoOne = $('#collapseTwoOne') var $collapseTwoTwo = $('#collapseTwoTwo') var collapsedElements = { - one : false, - two : false + one: false, + two: false } function firstTest() { @@ -830,7 +830,7 @@ $(function () { parent: $('.my-collapse') }) assert.ok(true, 'collapse correctly created') - } catch (err) { + } catch (_) { assert.ok(false, 'collapse not created') } }) @@ -851,7 +851,7 @@ $(function () { parent: $('.my-collapse')[0] }) assert.ok(true, 'collapse correctly created') - } catch (err) { + } catch (_) { assert.ok(false, 'collapse not created') } }) diff --git a/js/tests/unit/dropdown.js b/js/tests/unit/dropdown.js index 247bc66552..62b7993339 100644 --- a/js/tests/unit/dropdown.js +++ b/js/tests/unit/dropdown.js @@ -31,8 +31,8 @@ $(function () { $el.bootstrapDropdown() try { $el.bootstrapDropdown('noMethod') - } catch (err) { - assert.strictEqual(err.message, 'No method named "noMethod"') + } catch (error) { + assert.strictEqual(error.message, 'No method named "noMethod"') } }) diff --git a/js/tests/unit/modal.js b/js/tests/unit/modal.js index 3920fe387f..c4e5a30565 100644 --- a/js/tests/unit/modal.js +++ b/js/tests/unit/modal.js @@ -44,8 +44,8 @@ $(function () { $el.bootstrapModal() try { $el.bootstrapModal('noMethod') - } catch (err) { - assert.strictEqual(err.message, 'No method named "noMethod"') + } catch (error) { + assert.strictEqual(error.message, 'No method named "noMethod"') } }) @@ -450,8 +450,8 @@ $(function () { var originalPadding = $body.css('padding-right') // Hide scrollbars to prevent the body overflowing - $body.css('overflow', 'hidden') // Real scrollbar (for in-browser testing) - $('html').css('padding-right', '0px') // Simulated scrollbar (for PhantomJS) + $body.css('overflow', 'hidden') // Real scrollbar (for in-browser testing) + $('html').css('padding-right', '0px') // Simulated scrollbar (for PhantomJS) $('<div id="modal-test"/>') .on('shown.bs.modal', function () { diff --git a/js/tests/unit/popover.js b/js/tests/unit/popover.js index f4b29cc9e0..a5981e45ff 100644 --- a/js/tests/unit/popover.js +++ b/js/tests/unit/popover.js @@ -32,8 +32,8 @@ $(function () { $el.bootstrapPopover() try { $el.bootstrapPopover('noMethod') - } catch (err) { - assert.strictEqual(err.message, 'No method named "noMethod"') + } catch (error) { + assert.strictEqual(error.message, 'No method named "noMethod"') } }) @@ -369,8 +369,8 @@ $(function () { try { $('<div data-toggle="popover" data-title="some title" data-content="@Johann-S" style="display: none"/>').bootstrapPopover('show') - } catch (err) { - assert.strictEqual(err.message, 'Please use show on visible elements') + } catch (error) { + assert.strictEqual(error.message, 'Please use show on visible elements') done() } }) diff --git a/js/tests/unit/scrollspy.js b/js/tests/unit/scrollspy.js index 2e079bc8cd..4628c79b2a 100644 --- a/js/tests/unit/scrollspy.js +++ b/js/tests/unit/scrollspy.js @@ -31,8 +31,8 @@ $(function () { $el.bootstrapScrollspy() try { $el.bootstrapScrollspy('noMethod') - } catch (err) { - assert.strictEqual(err.message, 'No method named "noMethod"') + } catch (error) { + assert.strictEqual(error.message, 'No method named "noMethod"') } }) diff --git a/js/tests/unit/tab.js b/js/tests/unit/tab.js index 6e25f09dda..a0c4ddf155 100644 --- a/js/tests/unit/tab.js +++ b/js/tests/unit/tab.js @@ -31,8 +31,8 @@ $(function () { $el.bootstrapTab() try { $el.bootstrapTab('noMethod') - } catch (err) { - assert.strictEqual(err.message, 'No method named "noMethod"') + } catch (error) { + assert.strictEqual(error.message, 'No method named "noMethod"') } }) @@ -94,7 +94,7 @@ $(function () { QUnit.test('should activate element by tab id in nav list', function (assert) { assert.expect(2) - var tabsHTML = '<nav class="nav">' + + var tabsHTML = '<nav class="nav">' + '<a href="#home">Home</a>' + '<a href="#profile">Profile</a>' + '</nav>' @@ -110,7 +110,7 @@ $(function () { QUnit.test('should activate element by tab id in list group', function (assert) { assert.expect(2) - var tabsHTML = '<div class="list-group">' + + var tabsHTML = '<div class="list-group">' + '<a href="#home">Home</a>' + '<a href="#profile">Profile</a>' + '</div>' diff --git a/js/tests/unit/toast.js b/js/tests/unit/toast.js index a4c6560b88..f2f8a756bd 100644 --- a/js/tests/unit/toast.js +++ b/js/tests/unit/toast.js @@ -41,8 +41,8 @@ $(function () { try { $el.bootstrapToast('noMethod') - } catch (err) { - assert.strictEqual(err.message, 'No method named "noMethod"') + } catch (error) { + assert.strictEqual(error.message, 'No method named "noMethod"') } }) diff --git a/js/tests/unit/tooltip.js b/js/tests/unit/tooltip.js index 45c66a7f63..fb308cf388 100644 --- a/js/tests/unit/tooltip.js +++ b/js/tests/unit/tooltip.js @@ -32,8 +32,8 @@ $(function () { $el.bootstrapTooltip() try { $el.bootstrapTooltip('noMethod') - } catch (err) { - assert.strictEqual(err.message, 'No method named "noMethod"') + } catch (error) { + assert.strictEqual(error.message, 'No method named "noMethod"') } }) @@ -231,8 +231,8 @@ $(function () { try { $('<div title="tooltip title" style="display: none"/>').bootstrapTooltip('show') - } catch (err) { - assert.strictEqual(err.message, 'Please use show on visible elements') + } catch (error) { + assert.strictEqual(error.message, 'Please use show on visible elements') done() } }) @@ -336,7 +336,7 @@ $(function () { assert.expect(7) var $tooltip = $('<div/>') .bootstrapTooltip() - .on('click.foo', function () {}) // eslint-disable-line no-empty-function + .on('click.foo', function () {}) assert.ok($tooltip.data('bs.tooltip'), 'tooltip has data') assert.ok($._data($tooltip[0], 'events').mouseover && $._data($tooltip[0], 'events').mouseout, 'tooltip has hover events') @@ -561,7 +561,7 @@ $(function () { try { $tooltip.bootstrapTooltip('show') - } catch (err) { + } catch (_) { passed = false } diff --git a/js/tests/unit/util.js b/js/tests/unit/util.js index 887bad3f85..63c79e7ca7 100644 --- a/js/tests/unit/util.js +++ b/js/tests/unit/util.js @@ -46,8 +46,8 @@ $(function () { try { Util.typeCheckConfig(namePlugin, config, defaultType) - } catch (err) { - assert.strictEqual(err.message, 'COLLAPSE: Option "parent" provided type "number" but expected type "(string|element)".') + } catch (error) { + assert.strictEqual(error.message, 'COLLAPSE: Option "parent" provided type "number" but expected type "(string|element)".') } }) diff --git a/site/docs/4.5/assets/js/src/application.js b/site/docs/4.5/assets/js/src/application.js index 0a870261a2..a3032173bf 100644 --- a/site/docs/4.5/assets/js/src/application.js +++ b/site/docs/4.5/assets/js/src/application.js @@ -44,8 +44,8 @@ // Modal relatedTarget demo $('#exampleModal').on('show.bs.modal', function (event) { - var $button = $(event.relatedTarget) // Button that triggered the modal - var recipient = $button.data('whatever') // Extract info from data-* attributes + var $button = $(event.relatedTarget) // Button that triggered the modal + var recipient = $button.data('whatever') // Extract info from data-* attributes // If necessary, you could initiate an AJAX request here (and then do the updating in a callback). // Update the modal's content. We'll use jQuery here, but you could use a data binding library or other methods instead. var $modal = $(this) @@ -109,4 +109,4 @@ bsCustomFileInput.init() }) -}(jQuery)) +})(jQuery) diff --git a/site/docs/4.5/assets/js/src/ie-emulation-modes-warning.js b/site/docs/4.5/assets/js/src/ie-emulation-modes-warning.js index 6e6ed9c273..d11ec1c5a8 100644 --- a/site/docs/4.5/assets/js/src/ie-emulation-modes-warning.js +++ b/site/docs/4.5/assets/js/src/ie-emulation-modes-warning.js @@ -11,6 +11,7 @@ if (groups === null) { return null } + var ieVersionNum = parseInt(groups[1], 10) var ieMajorVersion = Math.floor(ieVersionNum) return ieMajorVersion @@ -24,9 +25,11 @@ if (typeof jscriptVersion === 'undefined') { return 11 // IE11+ not in emulation mode } + if (jscriptVersion < 9) { return 8 // IE8 (or lower; haven't tested on IE<8) } + return jscriptVersion // IE9 or IE10 in any mode, or IE11 in non-IE11 mode } @@ -34,14 +37,16 @@ if (ua.indexOf('Opera') > -1 || ua.indexOf('Presto') > -1) { return // Opera, which might pretend to be IE } + var emulated = emulatedIEMajorVersion() if (emulated === null) { return // Not IE } + var nonEmulated = actualNonEmulatedIEMajorVersion() if (emulated !== nonEmulated) { // eslint-disable-next-line no-alert window.alert('WARNING: You appear to be using IE' + nonEmulated + ' in IE' + emulated + ' emulation mode.\nIE emulation modes can behave significantly differently from ACTUAL older versions of IE.\nPLEASE DON\'T FILE BOOTSTRAP BUGS based on testing in IE emulation modes!') } -}()) +})() diff --git a/site/docs/4.5/assets/js/src/search.js b/site/docs/4.5/assets/js/src/search.js index e372d15537..bb97c5cf80 100644 --- a/site/docs/4.5/assets/js/src/search.js +++ b/site/docs/4.5/assets/js/src/search.js @@ -37,12 +37,12 @@ var currentUrl = getOrigin() var liveUrl = 'https://getbootstrap.com/' - hit.url = currentUrl.lastIndexOf(liveUrl, 0) === 0 + hit.url = currentUrl.lastIndexOf(liveUrl, 0) === 0 ? // On production, return the result as is - ? hit.url + hit.url : // On development or Netlify, replace `hit.url` with a trailing slash, // so that the result link is relative to the server root - : hit.url.replace(liveUrl, '/') + hit.url.replace(liveUrl, '/') // Prevent jumping to first header if (hit.anchor === 'content') { @@ -56,4 +56,4 @@ // Set debug to `true` if you want to inspect the dropdown debug: false }) -}()) +})() diff --git a/site/docs/4.5/examples/checkout/form-validation.js b/site/docs/4.5/examples/checkout/form-validation.js index 280849408b..59291c8b39 100644 --- a/site/docs/4.5/examples/checkout/form-validation.js +++ b/site/docs/4.5/examples/checkout/form-validation.js @@ -13,8 +13,9 @@ event.preventDefault() event.stopPropagation() } + form.classList.add('was-validated') }, false) }) }, false) -}()) +})() diff --git a/site/docs/4.5/examples/dashboard/dashboard.js b/site/docs/4.5/examples/dashboard/dashboard.js index de4a6347a3..d3f5499285 100644 --- a/site/docs/4.5/examples/dashboard/dashboard.js +++ b/site/docs/4.5/examples/dashboard/dashboard.js @@ -50,4 +50,4 @@ } } }) -}()) +})() |