diff --git a/config.yml b/config.yml
index f1d7a2a23f15..f1a25cb57a0c 100644
--- a/config.yml
+++ b/config.yml
@@ -75,5 +75,5 @@ params:
js_hash: "sha384-j0CNLUeiqtyaRmlzUHCPZ+Gy5fQu0dQ6eZ/xAww941Ai1SxSY+0EQqNXNE6DZiVc"
js_bundle: "https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/js/bootstrap.bundle.min.js"
js_bundle_hash: "sha384-JEW9xMcG8R+pH31jmWH6WWP0WintQrMb4s7ZOdauHnUtxwoG2vI5DkLtS3qm9Ekf"
- popper: "https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.1/dist/umd/popper.min.js"
- popper_hash: "sha384-SR1sx49pcuLnqZUnnPwx6FCym0wLsk5JZuNx2bPPENzswTNFaQU1RDvt3wT4gWFG"
+ popper: "https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js"
+ popper_hash: "sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p"
diff --git a/js/src/carousel.js b/js/src/carousel.js
index 76581ca5d42c..e336abb1eda2 100644
--- a/js/src/carousel.js
+++ b/js/src/carousel.js
@@ -336,10 +336,10 @@ class Carousel extends BaseComponent {
if (event.key === ARROW_LEFT_KEY) {
event.preventDefault()
- this._slide(DIRECTION_LEFT)
+ this._slide(DIRECTION_RIGHT)
} else if (event.key === ARROW_RIGHT_KEY) {
event.preventDefault()
- this._slide(DIRECTION_RIGHT)
+ this._slide(DIRECTION_LEFT)
}
}
@@ -509,10 +509,10 @@ class Carousel extends BaseComponent {
}
if (isRTL()) {
- return direction === DIRECTION_RIGHT ? ORDER_PREV : ORDER_NEXT
+ return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT
}
- return direction === DIRECTION_RIGHT ? ORDER_NEXT : ORDER_PREV
+ return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV
}
_orderToDirection(order) {
@@ -521,10 +521,10 @@ class Carousel extends BaseComponent {
}
if (isRTL()) {
- return order === ORDER_NEXT ? DIRECTION_LEFT : DIRECTION_RIGHT
+ return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT
}
- return order === ORDER_NEXT ? DIRECTION_RIGHT : DIRECTION_LEFT
+ return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT
}
// Static
diff --git a/js/src/dropdown.js b/js/src/dropdown.js
index fd16e912676b..e3cbb3321a27 100644
--- a/js/src/dropdown.js
+++ b/js/src/dropdown.js
@@ -10,6 +10,7 @@ import * as Popper from '@popperjs/core'
import {
defineJQueryPlugin,
getElementFromSelector,
+ isDisabled,
isElement,
isVisible,
isRTL,
@@ -51,7 +52,6 @@ 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_DROPEND = 'dropend'
@@ -121,7 +121,7 @@ class Dropdown extends BaseComponent {
// Public
toggle() {
- if (this._element.disabled || this._element.classList.contains(CLASS_NAME_DISABLED)) {
+ if (isDisabled(this._element)) {
return
}
@@ -137,7 +137,7 @@ class Dropdown extends BaseComponent {
}
show() {
- if (this._element.disabled || this._element.classList.contains(CLASS_NAME_DISABLED) || this._menu.classList.contains(CLASS_NAME_SHOW)) {
+ if (isDisabled(this._element) || this._menu.classList.contains(CLASS_NAME_SHOW)) {
return
}
@@ -204,7 +204,7 @@ class Dropdown extends BaseComponent {
}
hide() {
- if (this._element.disabled || this._element.classList.contains(CLASS_NAME_DISABLED) || !this._menu.classList.contains(CLASS_NAME_SHOW)) {
+ if (isDisabled(this._element) || !this._menu.classList.contains(CLASS_NAME_SHOW)) {
return
}
@@ -218,12 +218,20 @@ class Dropdown extends BaseComponent {
return
}
+ // If this is a touch-enabled device we remove the extra
+ // empty mouseover listeners we added for iOS support
+ if ('ontouchstart' in document.documentElement) {
+ [].concat(...document.body.children)
+ .forEach(elem => EventHandler.off(elem, 'mouseover', null, noop()))
+ }
+
if (this._popper) {
this._popper.destroy()
}
this._menu.classList.toggle(CLASS_NAME_SHOW)
this._element.classList.toggle(CLASS_NAME_SHOW)
+ this._element.setAttribute('aria-expanded', 'false')
Manipulator.removeDataAttribute(this._menu, 'popper')
EventHandler.trigger(this._element, EVENT_HIDDEN, relatedTarget)
}
@@ -430,19 +438,43 @@ class Dropdown extends BaseComponent {
.forEach(elem => EventHandler.off(elem, 'mouseover', noop))
}
- toggles[i].setAttribute('aria-expanded', 'false')
-
if (context._popper) {
context._popper.destroy()
}
dropdownMenu.classList.remove(CLASS_NAME_SHOW)
toggles[i].classList.remove(CLASS_NAME_SHOW)
+ toggles[i].setAttribute('aria-expanded', 'false')
Manipulator.removeDataAttribute(dropdownMenu, 'popper')
EventHandler.trigger(toggles[i], EVENT_HIDDEN, relatedTarget)
}
}
+ static selectMenuItem(parent, event) {
+ const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, parent).filter(isVisible)
+
+ if (!items.length) {
+ return
+ }
+
+ let index = items.indexOf(event.target)
+
+ // Up
+ if (event.key === ARROW_UP_KEY && index > 0) {
+ index--
+ }
+
+ // Down
+ if (event.key === ARROW_DOWN_KEY && index < items.length - 1) {
+ index++
+ }
+
+ // index is -1 if the first keydown is an ArrowUp
+ index = index === -1 ? 0 : index
+
+ items[index].focus()
+ }
+
static getParentFromElement(element) {
return getElementFromSelector(element) || element.parentNode
}
@@ -463,26 +495,29 @@ class Dropdown extends BaseComponent {
return
}
+ const isActive = this.classList.contains(CLASS_NAME_SHOW)
+
+ if (!isActive && event.key === ESCAPE_KEY) {
+ return
+ }
+
event.preventDefault()
event.stopPropagation()
- if (this.disabled || this.classList.contains(CLASS_NAME_DISABLED)) {
+ if (isDisabled(this)) {
return
}
- const parent = Dropdown.getParentFromElement(this)
- const isActive = this.classList.contains(CLASS_NAME_SHOW)
+ const getToggleButton = () => this.matches(SELECTOR_DATA_TOGGLE) ? this : SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE)[0]
if (event.key === ESCAPE_KEY) {
- const button = this.matches(SELECTOR_DATA_TOGGLE) ? this : SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE)[0]
- button.focus()
+ getToggleButton().focus()
Dropdown.clearMenus()
return
}
if (!isActive && (event.key === ARROW_UP_KEY || event.key === ARROW_DOWN_KEY)) {
- const button = this.matches(SELECTOR_DATA_TOGGLE) ? this : SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE)[0]
- button.click()
+ getToggleButton().click()
return
}
@@ -491,28 +526,7 @@ class Dropdown extends BaseComponent {
return
}
- const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, parent).filter(isVisible)
-
- if (!items.length) {
- return
- }
-
- let index = items.indexOf(event.target)
-
- // Up
- if (event.key === ARROW_UP_KEY && index > 0) {
- index--
- }
-
- // Down
- if (event.key === ARROW_DOWN_KEY && index < items.length - 1) {
- index++
- }
-
- // index is -1 if the first keydown is an ArrowUp
- index = index === -1 ? 0 : index
-
- items[index].focus()
+ Dropdown.selectMenuItem(Dropdown.getParentFromElement(this), event)
}
}
diff --git a/js/src/modal.js b/js/src/modal.js
index 2966f03fb5d1..b2a2e80ebc04 100644
--- a/js/src/modal.js
+++ b/js/src/modal.js
@@ -10,12 +10,11 @@ import {
emulateTransitionEnd,
getElementFromSelector,
getTransitionDurationFromElement,
- isVisible,
isRTL,
+ isVisible,
reflow,
typeCheckConfig
} from './util/index'
-import Data from './dom/data'
import EventHandler from './dom/event-handler'
import Manipulator from './dom/manipulator'
import SelectorEngine from './dom/selector-engine'
@@ -222,6 +221,7 @@ class Modal extends BaseComponent {
_getConfig(config) {
config = {
...Default,
+ ...Manipulator.getDataAttributes(this._element),
...config
}
typeCheckConfig(NAME, config, DefaultType)
@@ -474,7 +474,7 @@ class Modal extends BaseComponent {
const actualValue = element.style[styleProp]
const calculatedValue = window.getComputedStyle(element)[styleProp]
Manipulator.setDataAttribute(element, styleProp, actualValue)
- element.style[styleProp] = callback(Number.parseFloat(calculatedValue)) + 'px'
+ element.style[styleProp] = `${callback(Number.parseFloat(calculatedValue))}px`
})
}
@@ -509,24 +509,17 @@ class Modal extends BaseComponent {
static jQueryInterface(config, relatedTarget) {
return this.each(function () {
- let data = Data.get(this, DATA_KEY)
- const _config = {
- ...Default,
- ...Manipulator.getDataAttributes(this),
- ...(typeof config === 'object' && config ? config : {})
- }
+ const data = Modal.getInstance(this) || new Modal(this, typeof config === 'object' ? config : {})
- if (!data) {
- data = new Modal(this, _config)
+ if (typeof config !== 'string') {
+ return
}
- if (typeof config === 'string') {
- if (typeof data[config] === 'undefined') {
- throw new TypeError(`No method named "${config}"`)
- }
-
- data[config](relatedTarget)
+ if (typeof data[config] === 'undefined') {
+ throw new TypeError(`No method named "${config}"`)
}
+
+ data[config](relatedTarget)
})
}
}
@@ -540,7 +533,7 @@ class Modal extends BaseComponent {
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
const target = getElementFromSelector(this)
- if (this.tagName === 'A' || this.tagName === 'AREA') {
+ if (['A', 'AREA'].includes(this.tagName)) {
event.preventDefault()
}
@@ -557,15 +550,7 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (
})
})
- let data = Data.get(target, DATA_KEY)
- if (!data) {
- const config = {
- ...Manipulator.getDataAttributes(target),
- ...Manipulator.getDataAttributes(this)
- }
-
- data = new Modal(target, config)
- }
+ const data = Modal.getInstance(target) || new Modal(target)
data.toggle(this)
})
diff --git a/js/src/scrollspy.js b/js/src/scrollspy.js
index 3667b9a12dd0..4e830b530b14 100644
--- a/js/src/scrollspy.js
+++ b/js/src/scrollspy.js
@@ -12,7 +12,6 @@ import {
isElement,
typeCheckConfig
} from './util/index'
-import Data from './dom/data'
import EventHandler from './dom/event-handler'
import Manipulator from './dom/manipulator'
import SelectorEngine from './dom/selector-engine'
@@ -155,6 +154,7 @@ class ScrollSpy extends BaseComponent {
_getConfig(config) {
config = {
...Default,
+ ...Manipulator.getDataAttributes(this._element),
...(typeof config === 'object' && config ? config : {})
}
@@ -278,20 +278,17 @@ class ScrollSpy extends BaseComponent {
static jQueryInterface(config) {
return this.each(function () {
- let data = Data.get(this, DATA_KEY)
- const _config = typeof config === 'object' && config
+ const data = ScrollSpy.getInstance(this) || new ScrollSpy(this, typeof config === 'object' ? config : {})
- if (!data) {
- data = new ScrollSpy(this, _config)
+ if (typeof config !== 'string') {
+ return
}
- if (typeof config === 'string') {
- if (typeof data[config] === 'undefined') {
- throw new TypeError(`No method named "${config}"`)
- }
-
- data[config]()
+ if (typeof data[config] === 'undefined') {
+ throw new TypeError(`No method named "${config}"`)
}
+
+ data[config]()
})
}
}
@@ -304,7 +301,7 @@ class ScrollSpy extends BaseComponent {
EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
SelectorEngine.find(SELECTOR_DATA_SPY)
- .forEach(spy => new ScrollSpy(spy, Manipulator.getDataAttributes(spy)))
+ .forEach(spy => new ScrollSpy(spy))
})
/**
diff --git a/js/src/util/index.js b/js/src/util/index.js
index 77583aee3b9a..f19d76e036e9 100644
--- a/js/src/util/index.js
+++ b/js/src/util/index.js
@@ -48,7 +48,7 @@ const getSelector = element => {
// Just in case some CMS puts out a full URL with the anchor appended
if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
- hrefAttr = '#' + hrefAttr.split('#')[1]
+ hrefAttr = `#${hrefAttr.split('#')[1]}`
}
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null
@@ -128,9 +128,7 @@ const typeCheckConfig = (componentName, config, configTypes) => {
if (!new RegExp(expectedTypes).test(valueType)) {
throw new TypeError(
- `${componentName.toUpperCase()}: ` +
- `Option "${property}" provided type "${valueType}" ` +
- `but expected type "${expectedTypes}".`
+ `${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`
)
}
})
diff --git a/js/src/util/scrollbar.js b/js/src/util/scrollbar.js
index 3e619ef51e43..e63a66bf218b 100644
--- a/js/src/util/scrollbar.js
+++ b/js/src/util/scrollbar.js
@@ -35,7 +35,7 @@ const _setElementAttributes = (selector, styleProp, callback) => {
const actualValue = element.style[styleProp]
const calculatedValue = window.getComputedStyle(element)[styleProp]
Manipulator.setDataAttribute(element, styleProp, actualValue)
- element.style[styleProp] = callback(Number.parseFloat(calculatedValue)) + 'px'
+ element.style[styleProp] = `${callback(Number.parseFloat(calculatedValue))}px`
})
}
diff --git a/js/tests/unit/carousel.spec.js b/js/tests/unit/carousel.spec.js
index dc3006fffd2b..75c3bbd6d8dc 100644
--- a/js/tests/unit/carousel.spec.js
+++ b/js/tests/unit/carousel.spec.js
@@ -317,7 +317,7 @@ describe('Carousel', () => {
expect(carousel._addTouchEventListeners).toHaveBeenCalled()
})
- it('should allow swiperight and call _slide with pointer events', done => {
+ it('should allow swiperight and call _slide (prev) with pointer events', done => {
if (!supportPointerEvent) {
expect().nothing()
done()
@@ -362,7 +362,7 @@ describe('Carousel', () => {
})
})
- it('should allow swipeleft and call previous with pointer events', done => {
+ it('should allow swipeleft and call next with pointer events', done => {
if (!supportPointerEvent) {
expect().nothing()
done()
@@ -408,7 +408,7 @@ describe('Carousel', () => {
})
})
- it('should allow swiperight and call _slide with touch events', done => {
+ it('should allow swiperight and call _slide (prev) with touch events', done => {
Simulator.setType('touch')
clearPointerEvents()
document.documentElement.ontouchstart = () => {}
@@ -447,7 +447,7 @@ describe('Carousel', () => {
})
})
- it('should allow swipeleft and call _slide with touch events', done => {
+ it('should allow swipeleft and call _slide (next) with touch events', done => {
Simulator.setType('touch')
clearPointerEvents()
document.documentElement.ontouchstart = () => {}
@@ -601,7 +601,7 @@ describe('Carousel', () => {
const carousel = new Carousel(carouselEl, {})
const onSlide = e => {
- expect(e.direction).toEqual('right')
+ expect(e.direction).toEqual('left')
expect(e.relatedTarget.classList.contains('carousel-item')).toEqual(true)
expect(e.from).toEqual(0)
expect(e.to).toEqual(1)
@@ -613,7 +613,7 @@ describe('Carousel', () => {
}
const onSlide2 = e => {
- expect(e.direction).toEqual('left')
+ expect(e.direction).toEqual('right')
done()
}
@@ -636,7 +636,7 @@ describe('Carousel', () => {
const carousel = new Carousel(carouselEl, {})
const onSlid = e => {
- expect(e.direction).toEqual('right')
+ expect(e.direction).toEqual('left')
expect(e.relatedTarget.classList.contains('carousel-item')).toEqual(true)
expect(e.from).toEqual(0)
expect(e.to).toEqual(1)
@@ -648,7 +648,7 @@ describe('Carousel', () => {
}
const onSlid2 = e => {
- expect(e.direction).toEqual('left')
+ expect(e.direction).toEqual('right')
done()
}
@@ -1069,13 +1069,13 @@ describe('Carousel', () => {
const carouselEl = fixtureEl.querySelector('div')
const carousel = new Carousel(carouselEl, {})
- expect(carousel._directionToOrder('left')).toEqual('prev')
+ expect(carousel._directionToOrder('left')).toEqual('next')
expect(carousel._directionToOrder('prev')).toEqual('prev')
- expect(carousel._directionToOrder('right')).toEqual('next')
+ expect(carousel._directionToOrder('right')).toEqual('prev')
expect(carousel._directionToOrder('next')).toEqual('next')
- expect(carousel._orderToDirection('next')).toEqual('right')
- expect(carousel._orderToDirection('prev')).toEqual('left')
+ expect(carousel._orderToDirection('next')).toEqual('left')
+ expect(carousel._orderToDirection('prev')).toEqual('right')
})
it('"_directionToOrder" and "_orderToDirection" must return the right results when rtl=true', () => {
@@ -1086,13 +1086,13 @@ describe('Carousel', () => {
const carousel = new Carousel(carouselEl, {})
expect(util.isRTL()).toEqual(true, 'rtl has to be true')
- expect(carousel._directionToOrder('left')).toEqual('next')
+ expect(carousel._directionToOrder('left')).toEqual('prev')
expect(carousel._directionToOrder('prev')).toEqual('prev')
- expect(carousel._directionToOrder('right')).toEqual('prev')
+ expect(carousel._directionToOrder('right')).toEqual('next')
expect(carousel._directionToOrder('next')).toEqual('next')
- expect(carousel._orderToDirection('next')).toEqual('left')
- expect(carousel._orderToDirection('prev')).toEqual('right')
+ expect(carousel._orderToDirection('next')).toEqual('right')
+ expect(carousel._orderToDirection('prev')).toEqual('left')
document.documentElement.dir = 'ltl'
})
@@ -1106,11 +1106,11 @@ describe('Carousel', () => {
carousel._slide('left')
expect(spy).toHaveBeenCalledWith('left')
- expect(spy2).toHaveBeenCalledWith('prev')
+ expect(spy2).toHaveBeenCalledWith('next')
carousel._slide('right')
expect(spy).toHaveBeenCalledWith('right')
- expect(spy2).toHaveBeenCalledWith('next')
+ expect(spy2).toHaveBeenCalledWith('prev')
})
it('"_slide" has to call "_directionToOrder" and "_orderToDirection" when rtl=true', () => {
@@ -1124,11 +1124,11 @@ describe('Carousel', () => {
carousel._slide('left')
expect(spy).toHaveBeenCalledWith('left')
- expect(spy2).toHaveBeenCalledWith('next')
+ expect(spy2).toHaveBeenCalledWith('prev')
carousel._slide('right')
expect(spy).toHaveBeenCalledWith('right')
- expect(spy2).toHaveBeenCalledWith('prev')
+ expect(spy2).toHaveBeenCalledWith('next')
document.documentElement.dir = 'ltl'
})
diff --git a/js/tests/unit/dropdown.spec.js b/js/tests/unit/dropdown.spec.js
index ad51d487bf12..b8969be7c7d7 100644
--- a/js/tests/unit/dropdown.spec.js
+++ b/js/tests/unit/dropdown.spec.js
@@ -743,7 +743,7 @@ describe('Dropdown', () => {
it('should hide a dropdown', done => {
fixtureEl.innerHTML = [
'
',
- '
Dropdown ',
+ '
Dropdown ',
' ',
@@ -756,6 +756,7 @@ describe('Dropdown', () => {
btnDropdown.addEventListener('hidden.bs.dropdown', () => {
expect(dropdownMenu.classList.contains('show')).toEqual(false)
+ expect(btnDropdown.getAttribute('aria-expanded')).toEqual('false')
done()
})
@@ -894,6 +895,39 @@ describe('Dropdown', () => {
done()
})
})
+
+ it('should remove event listener on touch-enabled device that was added in show method', done => {
+ fixtureEl.innerHTML = [
+ '
',
+ ' Dropdown ',
+ ' ',
+ '
'
+ ].join('')
+
+ const defaultValueOnTouchStart = document.documentElement.ontouchstart
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdown = new Dropdown(btnDropdown)
+
+ document.documentElement.ontouchstart = () => {}
+ spyOn(EventHandler, 'off')
+
+ btnDropdown.addEventListener('shown.bs.dropdown', () => {
+ dropdown.hide()
+ })
+
+ btnDropdown.addEventListener('hidden.bs.dropdown', () => {
+ expect(btnDropdown.classList.contains('show')).toEqual(false)
+ expect(btnDropdown.getAttribute('aria-expanded')).toEqual('false')
+ expect(EventHandler.off).toHaveBeenCalled()
+
+ document.documentElement.ontouchstart = defaultValueOnTouchStart
+ done()
+ })
+
+ dropdown.show()
+ })
})
describe('dispose', () => {
@@ -1671,6 +1705,39 @@ describe('Dropdown', () => {
done()
}, 20)
})
+
+ it('should propagate escape key events if dropdown is closed', done => {
+ fixtureEl.innerHTML = [
+ '
',
+ '
',
+ ' Dropdown ',
+ ' ',
+ '
',
+ '
'
+ ]
+
+ const parent = fixtureEl.querySelector('.parent')
+ const toggle = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+
+ const parentKeyHandler = jasmine.createSpy('parentKeyHandler')
+
+ parent.addEventListener('keydown', parentKeyHandler)
+ parent.addEventListener('keyup', () => {
+ expect(parentKeyHandler).toHaveBeenCalled()
+ done()
+ })
+
+ const keydownEscape = createEvent('keydown', { bubbles: true })
+ keydownEscape.key = 'Escape'
+ const keyupEscape = createEvent('keyup', { bubbles: true })
+ keyupEscape.key = 'Escape'
+
+ toggle.focus()
+ toggle.dispatchEvent(keydownEscape)
+ toggle.dispatchEvent(keyupEscape)
+ })
})
describe('jQueryInterface', () => {
diff --git a/js/tests/unit/modal.spec.js b/js/tests/unit/modal.spec.js
index 2e46b9cb3627..7e26c5a00c4f 100644
--- a/js/tests/unit/modal.spec.js
+++ b/js/tests/unit/modal.spec.js
@@ -2,7 +2,7 @@ import Modal from '../../src/modal'
import EventHandler from '../../src/dom/event-handler'
/** Test helpers */
-import { getFixture, clearFixture, createEvent, jQueryMock } from '../helpers/fixture'
+import { clearFixture, createEvent, getFixture, jQueryMock } from '../helpers/fixture'
describe('Modal', () => {
let fixtureEl
@@ -1090,6 +1090,23 @@ describe('Modal', () => {
expect(Modal.getInstance(div)).toBeDefined()
})
+ it('should create a modal with given config', () => {
+ fixtureEl.innerHTML = '
'
+
+ const div = fixtureEl.querySelector('div')
+
+ jQueryMock.fn.modal = Modal.jQueryInterface
+ jQueryMock.elements = [div]
+
+ jQueryMock.fn.modal.call(jQueryMock, { keyboard: false })
+ spyOn(Modal.prototype, 'constructor')
+ expect(Modal.prototype.constructor).not.toHaveBeenCalledWith(div, { keyboard: false })
+
+ const modal = Modal.getInstance(div)
+ expect(modal).toBeDefined()
+ expect(modal._config.keyboard).toBe(false)
+ })
+
it('should not re create a modal', () => {
fixtureEl.innerHTML = '
'
diff --git a/js/tests/unit/scrollspy.spec.js b/js/tests/unit/scrollspy.spec.js
index f7258ba355b8..c4130a1aa707 100644
--- a/js/tests/unit/scrollspy.spec.js
+++ b/js/tests/unit/scrollspy.spec.js
@@ -605,6 +605,23 @@ describe('ScrollSpy', () => {
expect(ScrollSpy.getInstance(div)).toBeDefined()
})
+ it('should create a scrollspy with given config', () => {
+ fixtureEl.innerHTML = '
'
+
+ const div = fixtureEl.querySelector('div')
+
+ jQueryMock.fn.scrollspy = ScrollSpy.jQueryInterface
+ jQueryMock.elements = [div]
+
+ jQueryMock.fn.scrollspy.call(jQueryMock, { offset: 15 })
+ spyOn(ScrollSpy.prototype, 'constructor')
+ expect(ScrollSpy.prototype.constructor).not.toHaveBeenCalledWith(div, { offset: 15 })
+
+ const scrollspy = ScrollSpy.getInstance(div)
+ expect(scrollspy).toBeDefined()
+ expect(scrollspy._config.offset).toBe(15)
+ })
+
it('should not re create a scrollspy', () => {
fixtureEl.innerHTML = '
'
diff --git a/package-lock.json b/package-lock.json
index acf42523cb64..57637ae3891f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5,9 +5,9 @@
"requires": true,
"dependencies": {
"@babel/cli": {
- "version": "7.13.10",
- "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.13.10.tgz",
- "integrity": "sha512-lYSBC7B4B9hJ7sv0Ojx1BrGhuzCoOIYfLjd+Xpd4rOzdS+a47yi8voV8vFkfjlZR1N5qZO7ixOCbobUdT304PQ==",
+ "version": "7.13.14",
+ "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.13.14.tgz",
+ "integrity": "sha512-zmEFV8WBRsW+mPQumO1/4b34QNALBVReaiHJOkxhUsdo/AvYM62c+SKSuLi2aZ42t3ocK6OI0uwUXRvrIbREZw==",
"dev": true,
"requires": {
"@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents",
@@ -32,53 +32,34 @@
}
},
"@babel/compat-data": {
- "version": "7.13.8",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.8.tgz",
- "integrity": "sha512-EaI33z19T4qN3xLXsGf48M2cDqa6ei9tPZlfLdb2HC+e/cFtREiRd8hdSqDbwdLB0/+gLwqJmCYASH0z2bUdog==",
+ "version": "7.13.12",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.12.tgz",
+ "integrity": "sha512-3eJJ841uKxeV8dcN/2yGEUy+RfgQspPEgQat85umsE1rotuquQ2AbIub4S6j7c50a2d+4myc+zSlnXeIHrOnhQ==",
"dev": true
},
"@babel/core": {
- "version": "7.13.10",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.10.tgz",
- "integrity": "sha512-bfIYcT0BdKeAZrovpMqX2Mx5NrgAckGbwT982AkdS5GNfn3KMGiprlBAtmBcFZRUmpaufS6WZFP8trvx8ptFDw==",
+ "version": "7.13.14",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.14.tgz",
+ "integrity": "sha512-wZso/vyF4ki0l0znlgM4inxbdrUvCb+cVz8grxDq+6C9k6qbqoIJteQOKicaKjCipU3ISV+XedCqpL2RJJVehA==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.12.13",
"@babel/generator": "^7.13.9",
- "@babel/helper-compilation-targets": "^7.13.10",
- "@babel/helper-module-transforms": "^7.13.0",
+ "@babel/helper-compilation-targets": "^7.13.13",
+ "@babel/helper-module-transforms": "^7.13.14",
"@babel/helpers": "^7.13.10",
- "@babel/parser": "^7.13.10",
+ "@babel/parser": "^7.13.13",
"@babel/template": "^7.12.13",
- "@babel/traverse": "^7.13.0",
- "@babel/types": "^7.13.0",
+ "@babel/traverse": "^7.13.13",
+ "@babel/types": "^7.13.14",
"convert-source-map": "^1.7.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
"json5": "^2.1.2",
- "lodash": "^4.17.19",
"semver": "^6.3.0",
"source-map": "^0.5.0"
},
"dependencies": {
- "@babel/helper-compilation-targets": {
- "version": "7.13.10",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.10.tgz",
- "integrity": "sha512-/Xju7Qg1GQO4mHZ/Kcs6Au7gfafgZnwm+a7sy/ow/tV1sHeraRUHbjdat8/UvDor4Tez+siGKDk6zIKtCPKVJA==",
- "dev": true,
- "requires": {
- "@babel/compat-data": "^7.13.8",
- "@babel/helper-validator-option": "^7.12.17",
- "browserslist": "^4.14.5",
- "semver": "^6.3.0"
- }
- },
- "@babel/parser": {
- "version": "7.13.10",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.10.tgz",
- "integrity": "sha512-0s7Mlrw9uTWkYua7xWr99Wpk2bnGa0ANleKfksYAES8LpWH4gW1OUr42vqKNf0us5UQNfru2wPqMqRITzq/SIQ==",
- "dev": true
- },
"debug": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
@@ -103,26 +84,16 @@
}
},
"@babel/eslint-parser": {
- "version": "7.13.10",
- "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.13.10.tgz",
- "integrity": "sha512-/I1HQ3jGPhIpeBFeI3wO9WwWOnBYpuR0pX0KlkdGcRQAVX9prB/FCS2HBpL7BiFbzhny1YCiBH8MTZD2jJa7Hg==",
+ "version": "7.13.14",
+ "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.13.14.tgz",
+ "integrity": "sha512-I0HweR36D73Ibn/FfrRDMKlMqJHFwidIUgYdMpH+aXYuQC+waq59YaJ6t9e9N36axJ82v1jR041wwqDrDXEwRA==",
"dev": true,
"requires": {
- "eslint-scope": "5.1.0",
+ "eslint-scope": "^5.1.0",
"eslint-visitor-keys": "^1.3.0",
"semver": "^6.3.0"
},
"dependencies": {
- "eslint-scope": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz",
- "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==",
- "dev": true,
- "requires": {
- "esrecurse": "^4.1.0",
- "estraverse": "^4.1.1"
- }
- },
"eslint-visitor-keys": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
@@ -168,12 +139,12 @@
}
},
"@babel/helper-compilation-targets": {
- "version": "7.13.10",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.10.tgz",
- "integrity": "sha512-/Xju7Qg1GQO4mHZ/Kcs6Au7gfafgZnwm+a7sy/ow/tV1sHeraRUHbjdat8/UvDor4Tez+siGKDk6zIKtCPKVJA==",
+ "version": "7.13.13",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.13.tgz",
+ "integrity": "sha512-q1kcdHNZehBwD9jYPh3WyXcsFERi39X4I59I3NadciWtNDyZ6x+GboOxncFK0kXlKIv6BJm5acncehXWUjWQMQ==",
"dev": true,
"requires": {
- "@babel/compat-data": "^7.13.8",
+ "@babel/compat-data": "^7.13.12",
"@babel/helper-validator-option": "^7.12.17",
"browserslist": "^4.14.5",
"semver": "^6.3.0"
@@ -289,38 +260,37 @@
}
},
"@babel/helper-member-expression-to-functions": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.0.tgz",
- "integrity": "sha512-yvRf8Ivk62JwisqV1rFRMxiSMDGnN6KH1/mDMmIrij4jztpQNRoHqqMG3U6apYbGRPJpgPalhva9Yd06HlUxJQ==",
+ "version": "7.13.12",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz",
+ "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==",
"dev": true,
"requires": {
- "@babel/types": "^7.13.0"
+ "@babel/types": "^7.13.12"
}
},
"@babel/helper-module-imports": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.13.tgz",
- "integrity": "sha512-NGmfvRp9Rqxy0uHSSVP+SRIW1q31a7Ji10cLBcqSDUngGentY4FRiHOFZFE1CLU5eiL0oE8reH7Tg1y99TDM/g==",
+ "version": "7.13.12",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz",
+ "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==",
"dev": true,
"requires": {
- "@babel/types": "^7.12.13"
+ "@babel/types": "^7.13.12"
}
},
"@babel/helper-module-transforms": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.0.tgz",
- "integrity": "sha512-Ls8/VBwH577+pw7Ku1QkUWIyRRNHpYlts7+qSqBBFCW3I8QteB9DxfcZ5YJpOwH6Ihe/wn8ch7fMGOP1OhEIvw==",
+ "version": "7.13.14",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz",
+ "integrity": "sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g==",
"dev": true,
"requires": {
- "@babel/helper-module-imports": "^7.12.13",
- "@babel/helper-replace-supers": "^7.13.0",
- "@babel/helper-simple-access": "^7.12.13",
+ "@babel/helper-module-imports": "^7.13.12",
+ "@babel/helper-replace-supers": "^7.13.12",
+ "@babel/helper-simple-access": "^7.13.12",
"@babel/helper-split-export-declaration": "^7.12.13",
"@babel/helper-validator-identifier": "^7.12.11",
"@babel/template": "^7.12.13",
- "@babel/traverse": "^7.13.0",
- "@babel/types": "^7.13.0",
- "lodash": "^4.17.19"
+ "@babel/traverse": "^7.13.13",
+ "@babel/types": "^7.13.14"
}
},
"@babel/helper-optimise-call-expression": {
@@ -350,24 +320,24 @@
}
},
"@babel/helper-replace-supers": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.0.tgz",
- "integrity": "sha512-Segd5me1+Pz+rmN/NFBOplMbZG3SqRJOBlY+mA0SxAv6rjj7zJqr1AVr3SfzUVTLCv7ZLU5FycOM/SBGuLPbZw==",
+ "version": "7.13.12",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz",
+ "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==",
"dev": true,
"requires": {
- "@babel/helper-member-expression-to-functions": "^7.13.0",
+ "@babel/helper-member-expression-to-functions": "^7.13.12",
"@babel/helper-optimise-call-expression": "^7.12.13",
"@babel/traverse": "^7.13.0",
- "@babel/types": "^7.13.0"
+ "@babel/types": "^7.13.12"
}
},
"@babel/helper-simple-access": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.13.tgz",
- "integrity": "sha512-0ski5dyYIHEfwpWGx5GPWhH35j342JaflmCeQmsPWcrOQDtCN6C1zKAVRFVbK53lPW2c9TsuLLSUDf0tIGJ5hA==",
+ "version": "7.13.12",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz",
+ "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==",
"dev": true,
"requires": {
- "@babel/types": "^7.12.13"
+ "@babel/types": "^7.13.12"
}
},
"@babel/helper-skip-transparent-expression-wrappers": {
@@ -424,9 +394,9 @@
}
},
"@babel/highlight": {
- "version": "7.13.8",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.8.tgz",
- "integrity": "sha512-4vrIhfJyfNf+lCtXC2ck1rKSzDwciqF7IWFhXXrSOUC2O5DrVp+w4c6ed4AllTxhTkUP5x2tYj41VaxdVMMRDw==",
+ "version": "7.13.10",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz",
+ "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==",
"dev": true,
"requires": {
"@babel/helper-validator-identifier": "^7.12.11",
@@ -435,9 +405,9 @@
}
},
"@babel/parser": {
- "version": "7.13.9",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.9.tgz",
- "integrity": "sha512-nEUfRiARCcaVo3ny3ZQjURjHQZUo/JkEw7rLlSZy/psWGnvwXFtPcr6jb7Yb41DVW5LTe6KRq9LGleRNsg1Frw==",
+ "version": "7.13.13",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.13.tgz",
+ "integrity": "sha512-OhsyMrqygfk5v8HmWwOzlYjJrtLaFhF34MrfG/Z73DgYCI6ojNUTUp2TYbtnjo8PegeJp12eamsNettCQjKjVw==",
"dev": true
},
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
@@ -1083,23 +1053,6 @@
"semver": "^6.3.0"
},
"dependencies": {
- "@babel/compat-data": {
- "version": "7.13.12",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.12.tgz",
- "integrity": "sha512-3eJJ841uKxeV8dcN/2yGEUy+RfgQspPEgQat85umsE1rotuquQ2AbIub4S6j7c50a2d+4myc+zSlnXeIHrOnhQ==",
- "dev": true
- },
- "@babel/types": {
- "version": "7.13.12",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.12.tgz",
- "integrity": "sha512-K4nY2xFN4QMvQwkQ+zmBDp6ANMbVNw6BbxWmYA4qNjhR9W+Lj/8ky5MEY2Me5r+B2c6/v6F53oMndG+f9s3IiA==",
- "dev": true,
- "requires": {
- "@babel/helper-validator-identifier": "^7.12.11",
- "lodash": "^4.17.19",
- "to-fast-properties": "^2.0.0"
- }
- },
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
@@ -1142,20 +1095,19 @@
}
},
"@babel/traverse": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.0.tgz",
- "integrity": "sha512-xys5xi5JEhzC3RzEmSGrs/b3pJW/o87SypZ+G/PhaE7uqVQNv/jlmVIBXuoh5atqQ434LfXV+sf23Oxj0bchJQ==",
+ "version": "7.13.13",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.13.tgz",
+ "integrity": "sha512-CblEcwmXKR6eP43oQGG++0QMTtCjAsa3frUuzHoiIJWpaIIi8dwMyEFUJoXRLxagGqCK+jALRwIO+o3R9p/uUg==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.12.13",
- "@babel/generator": "^7.13.0",
+ "@babel/generator": "^7.13.9",
"@babel/helper-function-name": "^7.12.13",
"@babel/helper-split-export-declaration": "^7.12.13",
- "@babel/parser": "^7.13.0",
- "@babel/types": "^7.13.0",
+ "@babel/parser": "^7.13.13",
+ "@babel/types": "^7.13.13",
"debug": "^4.1.0",
- "globals": "^11.1.0",
- "lodash": "^4.17.19"
+ "globals": "^11.1.0"
},
"dependencies": {
"debug": {
@@ -1176,9 +1128,9 @@
}
},
"@babel/types": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.0.tgz",
- "integrity": "sha512-hE+HE8rnG1Z6Wzo+MhaKE5lM5eMx71T4EHJgku2E3xIfaULhDcxiiRxUYgwX8qwP1BBSlag+TdGOt6JAidIZTA==",
+ "version": "7.13.14",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.14.tgz",
+ "integrity": "sha512-A2aa3QTkWoyqsZZFl56MLUsfmh7O0gN41IPvXAE/++8ojpbz12SszD7JEGYVdn4f9Kt4amIei07swF1h4AqmmQ==",
"dev": true,
"requires": {
"@babel/helper-validator-identifier": "^7.12.11",
@@ -1282,9 +1234,9 @@
}
},
"@popperjs/core": {
- "version": "2.9.1",
- "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.9.1.tgz",
- "integrity": "sha512-DvJbbn3dUgMxDnJLH+RZQPnXak1h4ZVYQ7CWiFWjQwBFkVajT4rfw2PdpHLTSTwxrYfnoEXkuBiwkDm6tPMQeA==",
+ "version": "2.9.2",
+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.9.2.tgz",
+ "integrity": "sha512-VZMYa7+fXHdwIq1TDhSXoVmSPEGM/aa+6Aiq3nVVJ9bXr24zScr+NlKFKC3iPljA7ho/GAZr+d2jOf5GIRC30Q==",
"dev": true
},
"@rollup/plugin-babel": {
@@ -1298,9 +1250,9 @@
}
},
"@rollup/plugin-commonjs": {
- "version": "17.1.0",
- "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-17.1.0.tgz",
- "integrity": "sha512-PoMdXCw0ZyvjpCMT5aV4nkL0QywxP29sODQsSGeDpr/oI49Qq9tRtAsb/LbYbDzFlOydVEqHmmZWFtXJEAX9ew==",
+ "version": "18.0.0",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-18.0.0.tgz",
+ "integrity": "sha512-fj92shhg8luw7XbA0HowAqz90oo7qtLGwqTKbyZ8pmOyH8ui5e+u0wPEgeHLH3djcVma6gUCUrjY6w5R2o1u6g==",
"dev": true,
"requires": {
"@rollup/pluginutils": "^3.1.0",
@@ -1321,9 +1273,9 @@
}
},
"@rollup/plugin-node-resolve": {
- "version": "11.2.0",
- "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.0.tgz",
- "integrity": "sha512-qHjNIKYt5pCcn+5RUBQxK8krhRvf1HnyVgUCcFFcweDS7fhkOLZeYh0mhHK6Ery8/bb9tvN/ubPzmfF0qjDCTA==",
+ "version": "11.2.1",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz",
+ "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==",
"dev": true,
"requires": {
"@rollup/pluginutils": "^3.1.0",
@@ -1335,9 +1287,9 @@
}
},
"@rollup/plugin-replace": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.1.tgz",
- "integrity": "sha512-XwC1oK5rrtRJ0tn1ioLHS6OV5JTluJF7QE1J/q1hN3bquwjnVxjtMyY9iCnoyH9DQbf92CxajB3o98wZbP3oAQ==",
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz",
+ "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==",
"dev": true,
"requires": {
"@rollup/pluginutils": "^3.1.0",
@@ -1435,9 +1387,9 @@
"dev": true
},
"@types/node": {
- "version": "14.14.32",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.32.tgz",
- "integrity": "sha512-/Ctrftx/zp4m8JOujM5ZhwzlWLx22nbQJiVqz8/zE15gOeEW+uly3FSX4fGFpcfEvFzXcMCJwq9lGVWgyARXhg==",
+ "version": "14.14.37",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.37.tgz",
+ "integrity": "sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw==",
"dev": true
},
"@types/normalize-package-data": {
@@ -2460,9 +2412,9 @@
}
},
"caniuse-lite": {
- "version": "1.0.30001197",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001197.tgz",
- "integrity": "sha512-8aE+sqBqtXz4G8g35Eg/XEaFr2N7rd/VQ6eABGBmNtcB8cN6qNJhMi6oSFy4UWWZgqgL3filHT8Nha4meu3tsw==",
+ "version": "1.0.30001204",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001204.tgz",
+ "integrity": "sha512-JUdjWpcxfJ9IPamy2f5JaRDCaqJOxDzOSKtbdx4rH9VivMd1vIzoPumsJa9LoMIi4Fx2BV2KZOxWhNkBjaYivQ==",
"dev": true
},
"caw": {
@@ -2644,9 +2596,9 @@
"dev": true
},
"ci-info": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
- "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.1.1.tgz",
+ "integrity": "sha512-kdRWLBIJwdsYJWYJFtAFFYxybguqeF91qpZaggjG5Nf8QKdizFG2hjqvaTXbxFIcYbSaD74KpAXv6BSm17DHEQ==",
"dev": true
},
"class-utils": {
@@ -3387,9 +3339,9 @@
}
},
"domutils": {
- "version": "2.4.4",
- "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.4.4.tgz",
- "integrity": "sha512-jBC0vOsECI4OMdD0GC9mGn7NXPLb+Qt6KW1YDQzeQYRUFKmNG8lh7mO5HiELfr+lLQE7loDVI4QcAxV80HS+RA==",
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.5.0.tgz",
+ "integrity": "sha512-Ho16rzNMOFk2fPwChGh3D2D9OEHAfG19HgmRR2l+WLSsIstNsAYBzePH412bL0y5T44ejABIVfTHQ8nqi/tBCg==",
"dev": true,
"requires": {
"dom-serializer": "^1.0.1",
@@ -3471,9 +3423,9 @@
"dev": true
},
"electron-to-chromium": {
- "version": "1.3.682",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.682.tgz",
- "integrity": "sha512-zok2y37qR00U14uM6qBz/3iIjWHom2eRfC2S1StA0RslP7x34jX+j4mxv80t8OEOHLJPVG54ZPeaFxEI7gPrwg==",
+ "version": "1.3.702",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.702.tgz",
+ "integrity": "sha512-qJVUKFWQnF6wP7MmTngDkmm8/KPzaiTXNFOAg5j7DSa6J7kPou7mTBqC8jpUOxauQWwHR3pn4dMRdV8IE1xdtA==",
"dev": true
},
"emoji-regex": {
@@ -3643,9 +3595,9 @@
"dev": true
},
"eslint": {
- "version": "7.22.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.22.0.tgz",
- "integrity": "sha512-3VawOtjSJUQiiqac8MQc+w457iGLfuNGLFn8JmF051tTKbh5/x/0vlcEj8OgDCaw7Ysa2Jn8paGshV7x2abKXg==",
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.23.0.tgz",
+ "integrity": "sha512-kqvNVbdkjzpFy0XOszNwjkKzZ+6TcwCQ/h+ozlcIWwaimBBuhlQ4nN6kbiM2L+OjDcznkTJxzYfRFH92sx4a0Q==",
"dev": true,
"requires": {
"@babel/code-frame": "7.12.11",
@@ -3749,9 +3701,9 @@
}
},
"globals": {
- "version": "13.6.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.6.0.tgz",
- "integrity": "sha512-YFKCX0SiPg7l5oKYCJ2zZGxcXprVXHcSnVuvzrT3oSENQonVLqM5pf9fN5dLGZGyCjhw8TN8Btwe/jKnZ0pjvQ==",
+ "version": "13.7.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.7.0.tgz",
+ "integrity": "sha512-Aipsz6ZKRxa/xQkZhNg0qIWXT6x6rD46f6x/PCnBomlttdIyAPak4YD9jTmKpZ72uROSMU87qJtcgpgHaVchiA==",
"dev": true,
"requires": {
"type-fest": "^0.20.2"
@@ -3770,9 +3722,9 @@
"dev": true
},
"semver": {
- "version": "7.3.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
- "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
@@ -3948,12 +3900,6 @@
"semver": "^7.3.4"
},
"dependencies": {
- "ci-info": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.1.1.tgz",
- "integrity": "sha512-kdRWLBIJwdsYJWYJFtAFFYxybguqeF91qpZaggjG5Nf8QKdizFG2hjqvaTXbxFIcYbSaD74KpAXv6BSm17DHEQ==",
- "dev": true
- },
"safe-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz",
@@ -5490,6 +5436,14 @@
"dev": true,
"requires": {
"ci-info": "^2.0.0"
+ },
+ "dependencies": {
+ "ci-info": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+ "dev": true
+ }
}
},
"is-core-module": {
@@ -5750,6 +5704,12 @@
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
"dev": true
},
+ "is-unicode-supported": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
+ "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
+ "dev": true
+ },
"is-windows": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
@@ -5938,9 +5898,9 @@
}
},
"jasmine-core": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.6.0.tgz",
- "integrity": "sha512-8uQYa7zJN8hq9z+g8z1bqCfdC8eoDAeVnM5sfqs7KHv9/ifoJ500m018fpFc7RDaO6SWCLCXwo/wPSNcdYTgcw==",
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.7.1.tgz",
+ "integrity": "sha512-DH3oYDS/AUvvr22+xUBW62m1Xoy7tUlY1tsxKEJvl5JeJ7q8zd1K5bUwiOxdH+erj6l2vAMM3hV25Xs9/WrmuQ==",
"dev": true
},
"jquery": {
@@ -6032,9 +5992,9 @@
"dev": true
},
"karma": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/karma/-/karma-6.2.0.tgz",
- "integrity": "sha512-pCB8eNxGgdIdZeC885rbhZ/VyuOPNHUIDNL9EaaMf1NVzpvTjMO8a7zRTn51ZJhOOOxCSpalUdT1A8x76LyVqg==",
+ "version": "6.3.2",
+ "resolved": "https://registry.npmjs.org/karma/-/karma-6.3.2.tgz",
+ "integrity": "sha512-fo4Wt0S99/8vylZMxNj4cBFyOBBnC1bewZ0QOlePij/2SZVWxqbyLeIddY13q6URa2EpLRW8ixvFRUMjkmo1bw==",
"dev": true,
"requires": {
"body-parser": "^1.19.0",
@@ -6425,6 +6385,12 @@
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
},
+ "lodash.clonedeep": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+ "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=",
+ "dev": true
+ },
"lodash.debounce": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
@@ -6437,6 +6403,12 @@
"integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=",
"dev": true
},
+ "lodash.flatten": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz",
+ "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=",
+ "dev": true
+ },
"lodash.forown": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/lodash.forown/-/lodash.forown-4.4.0.tgz",
@@ -6467,13 +6439,20 @@
"integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
"dev": true
},
+ "lodash.truncate": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
+ "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=",
+ "dev": true
+ },
"log-symbols": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz",
- "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==",
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
+ "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
"dev": true,
"requires": {
- "chalk": "^4.0.0"
+ "chalk": "^4.1.0",
+ "is-unicode-supported": "^0.1.0"
},
"dependencies": {
"ansi-styles": {
@@ -6611,9 +6590,9 @@
"optional": true
},
"map-obj": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.1.0.tgz",
- "integrity": "sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g==",
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.2.0.tgz",
+ "integrity": "sha512-NAq0fCmZYGz9UFEQyndp7sisrow4GroyGeKluyKC/chuITZsPyOyC1UJZPJlVFImhXdROIP5xqouRLThT3BbpQ==",
"dev": true
},
"map-visit": {
@@ -6704,30 +6683,30 @@
},
"dependencies": {
"hosted-git-info": {
- "version": "3.0.8",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.8.tgz",
- "integrity": "sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw==",
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz",
+ "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
},
"normalize-package-data": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.0.tgz",
- "integrity": "sha512-6lUjEI0d3v6kFrtgA/lOx4zHCWULXsFNIjHolnZCKCTLA6m/G625cdn3O7eNmT0iD3jfo6HZ9cdImGZwf21prw==",
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.2.tgz",
+ "integrity": "sha512-6CdZocmfGaKnIHPVFhJJZ3GuR8SsLKvDANFp47Jmy51aKIr8akjAWTSxtpI+MBgBFdSMRyo4hMpDlT6dTffgZg==",
"dev": true,
"requires": {
- "hosted-git-info": "^3.0.6",
- "resolve": "^1.17.0",
- "semver": "^7.3.2",
+ "hosted-git-info": "^4.0.1",
+ "resolve": "^1.20.0",
+ "semver": "^7.3.4",
"validate-npm-package-license": "^3.0.1"
}
},
"semver": {
- "version": "7.3.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
- "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
@@ -7942,13 +7921,13 @@
"optional": true
},
"postcss": {
- "version": "8.2.8",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.8.tgz",
- "integrity": "sha512-1F0Xb2T21xET7oQV9eKuctbM9S7BC0fetoHCc4H13z0PT6haiRLP4T0ZY4XWh7iLP0usgqykT6p9B2RtOf4FPw==",
+ "version": "8.2.9",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.9.tgz",
+ "integrity": "sha512-b+TmuIL4jGtCHtoLi+G/PisuIl9avxs8IZMSmlABRwNz5RLUUACrC+ws81dcomz1nRezm5YPdXiMEzBEKgYn+Q==",
"dev": true,
"requires": {
"colorette": "^1.2.2",
- "nanoid": "^3.1.20",
+ "nanoid": "^3.1.22",
"source-map": "^0.6.1"
},
"dependencies": {
@@ -8499,9 +8478,9 @@
}
},
"queue-microtask": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.2.tgz",
- "integrity": "sha512-dB15eXv3p2jDlbOiNLyMabYg1/sXvppd8DP2J3EOCQ0AkuSXCW2tP7mnVouVLJKgUMY6yP0kcQDVpLCN13h4Xg==",
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
"dev": true
},
"quick-lru": {
@@ -8734,9 +8713,9 @@
"dev": true
},
"regjsparser": {
- "version": "0.6.8",
- "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.8.tgz",
- "integrity": "sha512-3weFrFQREJhJ2PW+iCGaG6TenyzNSZgsBKZ/oEf6Trme31COSeIWhHw9O6FPkuXktfx+b6Hf/5e6dKPHaROq2g==",
+ "version": "0.6.9",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.9.tgz",
+ "integrity": "sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ==",
"dev": true,
"requires": {
"jsesc": "~0.5.0"
@@ -8884,9 +8863,9 @@
}
},
"rollup": {
- "version": "2.42.3",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.42.3.tgz",
- "integrity": "sha512-JjaT9WaUS5vmjy6xUrnPOskjkQg2cN4WSACNCwbOvBz8VDmbiKVdmTFUoMPRqTud0tsex8Xy9/boLbDW9HKD1w==",
+ "version": "2.44.0",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.44.0.tgz",
+ "integrity": "sha512-rGSF4pLwvuaH/x4nAS+zP6UNn5YUDWf/TeEU5IoXSZKBbKRNTCI3qMnYXKZgrC0D2KzS2baiOZt1OlqhMu5rnQ==",
"dev": true,
"requires": {
"fsevents": "~2.3.1"
@@ -10259,21 +10238,26 @@
"dev": true
},
"table": {
- "version": "6.0.7",
- "resolved": "https://registry.npmjs.org/table/-/table-6.0.7.tgz",
- "integrity": "sha512-rxZevLGTUzWna/qBLObOe16kB2RTnnbhciwgPbMMlazz1yZGVEgnZK762xyVdVznhqxrfCeBMmMkgOOaPwjH7g==",
+ "version": "6.0.9",
+ "resolved": "https://registry.npmjs.org/table/-/table-6.0.9.tgz",
+ "integrity": "sha512-F3cLs9a3hL1Z7N4+EkSscsel3z55XT950AvB05bwayrNg5T1/gykXtigioTAjbltvbMSJvvhFCbnf6mX+ntnJQ==",
"dev": true,
"requires": {
- "ajv": "^7.0.2",
- "lodash": "^4.17.20",
+ "ajv": "^8.0.1",
+ "is-boolean-object": "^1.1.0",
+ "is-number-object": "^1.0.4",
+ "is-string": "^1.0.5",
+ "lodash.clonedeep": "^4.5.0",
+ "lodash.flatten": "^4.4.0",
+ "lodash.truncate": "^4.4.2",
"slice-ansi": "^4.0.0",
"string-width": "^4.2.0"
},
"dependencies": {
"ajv": {
- "version": "7.2.1",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.2.1.tgz",
- "integrity": "sha512-+nu0HDv7kNSOua9apAVc979qd932rrZeb3WOvoiD31A/p1mIE5/9bN2027pE2rOPYEdS3UHzsvof4hY+lM9/WQ==",
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.0.1.tgz",
+ "integrity": "sha512-46ZA4TalFcLLqX1dEU3dhdY38wAtDydJ4e7QQTVekLUTzXkb1LfqU6VOBXC/a9wiv4T094WURqJH6ZitF92Kqw==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
@@ -10536,21 +10520,21 @@
}
},
"ua-parser-js": {
- "version": "0.7.24",
- "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.24.tgz",
- "integrity": "sha512-yo+miGzQx5gakzVK3QFfN0/L9uVhosXBBO7qmnk7c2iw1IhL212wfA3zbnI54B0obGwC/5NWub/iT9sReMx+Fw==",
+ "version": "0.7.26",
+ "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.26.tgz",
+ "integrity": "sha512-VwIvGlFNmpKbjzRt51jpbbFTrKIEgGHxIwA8Y69K1Bqc6bTIV7TaGGABOkghSFQWsLmcRB4drGvpfv9z2szqoQ==",
"dev": true
},
"unbox-primitive": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.0.tgz",
- "integrity": "sha512-P/51NX+JXyxK/aigg1/ZgyccdAxm5K1+n8+tvqSntjOivPt19gvm1VC49RWYetsiub8WViUchdxl/KWHHB0kzA==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz",
+ "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==",
"dev": true,
"requires": {
"function-bind": "^1.1.1",
- "has-bigints": "^1.0.0",
- "has-symbols": "^1.0.0",
- "which-boxed-primitive": "^1.0.1"
+ "has-bigints": "^1.0.1",
+ "has-symbols": "^1.0.2",
+ "which-boxed-primitive": "^1.0.2"
}
},
"unbzip2-stream": {
@@ -10829,9 +10813,9 @@
"dev": true
},
"semver": {
- "version": "7.3.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
- "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
@@ -11085,9 +11069,9 @@
"dev": true
},
"yaml": {
- "version": "1.10.0",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz",
- "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==",
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
+ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
"dev": true
},
"yargs": {
@@ -11106,9 +11090,9 @@
}
},
"yargs-parser": {
- "version": "20.2.6",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.6.tgz",
- "integrity": "sha512-AP1+fQIWSM/sMiET8fyayjx/J+JmTPt2Mr0FkrgqB4todtfa53sOsrSAcIrJRD5XS20bKUwaDIuMkWKCEiQLKA==",
+ "version": "20.2.7",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz",
+ "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==",
"dev": true
},
"yauzl": {
diff --git a/package.json b/package.json
index 2efcada97ebe..15d352936e9f 100644
--- a/package.json
+++ b/package.json
@@ -97,22 +97,22 @@
},
"dependencies": {},
"peerDependencies": {
- "@popperjs/core": "^2.9.1"
+ "@popperjs/core": "^2.9.2"
},
"devDependencies": {
- "@babel/cli": "^7.13.10",
- "@babel/core": "^7.13.10",
+ "@babel/cli": "^7.13.14",
+ "@babel/core": "^7.13.14",
"@babel/preset-env": "^7.13.12",
- "@popperjs/core": "^2.9.1",
+ "@popperjs/core": "^2.9.2",
"@rollup/plugin-babel": "^5.3.0",
- "@rollup/plugin-commonjs": "^17.1.0",
- "@rollup/plugin-node-resolve": "^11.2.0",
- "@rollup/plugin-replace": "^2.4.1",
+ "@rollup/plugin-commonjs": "^18.0.0",
+ "@rollup/plugin-node-resolve": "^11.2.1",
+ "@rollup/plugin-replace": "^2.4.2",
"autoprefixer": "^10.2.5",
"bundlewatch": "^0.3.2",
"clean-css-cli": "^5.2.2",
"cross-env": "^7.0.3",
- "eslint": "^7.22.0",
+ "eslint": "^7.23.0",
"eslint-config-xo": "^0.35.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-unicorn": "^29.0.0",
@@ -123,7 +123,7 @@
"hugo-bin": "^0.70.0",
"ip": "^1.1.5",
"jquery": "^3.6.0",
- "karma": "^6.2.0",
+ "karma": "^6.3.2",
"karma-browserstack-launcher": "1.4.0",
"karma-chrome-launcher": "^3.1.0",
"karma-coverage-istanbul-reporter": "^3.0.3",
@@ -136,9 +136,9 @@
"lockfile-lint": "^4.6.2",
"nodemon": "^2.0.7",
"npm-run-all": "^4.1.5",
- "postcss": "^8.2.8",
+ "postcss": "^8.2.9",
"postcss-cli": "^8.3.1",
- "rollup": "^2.42.3",
+ "rollup": "^2.44.0",
"rollup-plugin-istanbul": "^3.0.0",
"rtlcss": "^3.1.2",
"sass": "^1.32.8",
@@ -171,7 +171,7 @@
},
"dependencies": {},
"peerDependencies": {
- "@popperjs/core": "^2.9.1"
+ "@popperjs/core": "^2.9.2"
}
}
}
diff --git a/scss/_offcanvas.scss b/scss/_offcanvas.scss
index 1eeb989666d1..5c11101f6556 100644
--- a/scss/_offcanvas.scss
+++ b/scss/_offcanvas.scss
@@ -16,6 +16,7 @@
.offcanvas-header {
display: flex;
+ align-items: center;
justify-content: space-between;
padding: $offcanvas-padding-y $offcanvas-padding-x;
@@ -52,6 +53,16 @@
transform: translateX(100%);
}
+.offcanvas-top {
+ top: 0;
+ right: 0;
+ left: 0;
+ height: $offcanvas-vertical-height;
+ max-height: 100%;
+ border-bottom: $offcanvas-border-width solid $offcanvas-border-color;
+ transform: translateY(-100%);
+}
+
.offcanvas-bottom {
right: 0;
left: 0;
diff --git a/scss/_spinners.scss b/scss/_spinners.scss
index 8e19bae514b8..a4a2c77cf678 100644
--- a/scss/_spinners.scss
+++ b/scss/_spinners.scss
@@ -12,7 +12,7 @@
display: inline-block;
width: $spinner-width;
height: $spinner-height;
- vertical-align: text-bottom;
+ vertical-align: $spinner-vertical-align;
border: $spinner-border-width solid currentColor;
border-right-color: transparent;
// stylelint-disable-next-line property-disallowed-list
@@ -46,7 +46,7 @@
display: inline-block;
width: $spinner-width;
height: $spinner-height;
- vertical-align: text-bottom;
+ vertical-align: $spinner-vertical-align;
background-color: currentColor;
// stylelint-disable-next-line property-disallowed-list
border-radius: 50%;
diff --git a/scss/_variables.scss b/scss/_variables.scss
index 7558224f9dce..4c7ce3b0bc3c 100644
--- a/scss/_variables.scss
+++ b/scss/_variables.scss
@@ -917,8 +917,8 @@ $nav-link-padding-y: .5rem !default;
$nav-link-padding-x: 1rem !default;
$nav-link-font-size: null !default;
$nav-link-font-weight: null !default;
-$nav-link-color: null !default;
-$nav-link-hover-color: null !default;
+$nav-link-color: $link-color !default;
+$nav-link-hover-color: $link-hover-color !default;
$nav-link-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out !default;
$nav-link-disabled-color: $gray-600 !default;
@@ -1406,6 +1406,7 @@ $carousel-dark-control-icon-filter: invert(1) grayscale(100) !default;
// scss-docs-start spinner-variables
$spinner-width: 2rem !default;
$spinner-height: $spinner-width !default;
+$spinner-vertical-align: -.125em !default;
$spinner-border-width: .25em !default;
$spinner-animation-speed: .75s !default;
diff --git a/scss/mixins/_forms.scss b/scss/mixins/_forms.scss
index a1e0849df01a..612f94d17cb5 100644
--- a/scss/mixins/_forms.scss
+++ b/scss/mixins/_forms.scss
@@ -92,6 +92,14 @@
background-image: escape-svg($form-select-indicator), escape-svg($icon);
background-position: $form-select-bg-position, $form-select-feedback-icon-position;
background-size: $form-select-bg-size, $form-select-feedback-icon-size;
+
+ &[multiple],
+ &[size]:not([size="1"]) {
+ padding-right: $input-height-inner;
+ background-image: escape-svg($icon);
+ background-position: top $input-height-inner-quarter right $input-height-inner-quarter;
+ background-size: $form-select-feedback-icon-size;
+ }
}
&:focus {
diff --git a/scss/mixins/_grid.scss b/scss/mixins/_grid.scss
index 92bb88ad4944..d757eac7404a 100644
--- a/scss/mixins/_grid.scss
+++ b/scss/mixins/_grid.scss
@@ -26,9 +26,14 @@
margin-top: var(--#{$variable-prefix}gutter-y);
}
-@mixin make-col($size, $columns: $grid-columns) {
- flex: 0 0 auto;
- width: percentage($size / $columns);
+@mixin make-col($size: false, $columns: $grid-columns) {
+ @if $size {
+ flex: 0 0 auto;
+ width: percentage($size / $columns);
+ } @else {
+ flex: 1 1 0;
+ max-width: 100%;
+ }
}
@mixin make-col-auto() {
diff --git a/site/assets/scss/_footer.scss b/site/assets/scss/_footer.scss
index 48ad349de0dd..87cee6d2bd0d 100644
--- a/site/assets/scss/_footer.scss
+++ b/site/assets/scss/_footer.scss
@@ -3,16 +3,14 @@
//
.bd-footer {
- @include font-size(.875rem);
- color: #63707c;
-
a {
- font-weight: 600;
color: $gray-700;
+ text-decoration: none;
&:hover,
&:focus {
color: $link-color;
+ text-decoration: underline;
}
}
}
diff --git a/site/content/docs/5.0/components/accordion.md b/site/content/docs/5.0/components/accordion.md
index 923d5a98bd24..864ff90c5464 100644
--- a/site/content/docs/5.0/components/accordion.md
+++ b/site/content/docs/5.0/components/accordion.md
@@ -31,7 +31,7 @@ Click the accordions below to expand/collapse the accordion content.
- This is the first item's accordion body. It is hidden by default, until the collapse plugin adds the appropriate classes that we use to style each element. These classes control the overall appearance, as well as the showing and hiding via CSS transitions. You can modify any of this with custom CSS or overriding our default variables. It's also worth noting that just about any HTML can go within the .accordion-body
, though the transition does limit overflow.
+ This is the first item's accordion body. It is shown by default, until the collapse plugin adds the appropriate classes that we use to style each element. These classes control the overall appearance, as well as the showing and hiding via CSS transitions. You can modify any of this with custom CSS or overriding our default variables. It's also worth noting that just about any HTML can go within the .accordion-body
, though the transition does limit overflow.
diff --git a/site/content/docs/5.0/components/offcanvas.md b/site/content/docs/5.0/components/offcanvas.md
index a2b5ed3fa577..b9dbd7ce8da2 100644
--- a/site/content/docs/5.0/components/offcanvas.md
+++ b/site/content/docs/5.0/components/offcanvas.md
@@ -85,9 +85,24 @@ There's no default placement for offcanvas components, so you must add one of th
- `.offcanvas-start` places offcanvas on the left of the viewport (shown above)
- `.offcanvas-end` places offcanvas on the right of the viewport
+- `.offcanvas-top` places offcanvas on the top of the viewport
- `.offcanvas-bottom` places offcanvas on the bottom of the viewport
-Try the right and bottom examples out below.
+Try the top, right, and bottom examples out below.
+
+{{< example >}}
+