1
0
Fork 0

Merging upstream version 5.3.0+dfsg.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-17 07:08:19 +01:00
parent a87fc4fcc7
commit e92720b6a7
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
605 changed files with 15320 additions and 9495 deletions

View file

@ -1,13 +0,0 @@
{
"extends": [
"../../../.eslintrc.json"
],
"env": {
"jasmine": true
},
"rules": {
"unicorn/consistent-function-scoping": "off",
"unicorn/no-useless-undefined": "off",
"unicorn/prefer-add-event-listener": "off"
}
}

View file

@ -1,6 +1,6 @@
import Alert from '../../src/alert'
import { getTransitionDurationFromElement } from '../../src/util/index'
import { clearFixture, getFixture, jQueryMock } from '../helpers/fixture'
import Alert from '../../src/alert.js'
import { getTransitionDurationFromElement } from '../../src/util/index.js'
import { clearFixture, getFixture, jQueryMock } from '../helpers/fixture.js'
describe('Alert', () => {
let fixtureEl

View file

@ -1,7 +1,7 @@
import BaseComponent from '../../src/base-component'
import { clearFixture, getFixture } from '../helpers/fixture'
import EventHandler from '../../src/dom/event-handler'
import { noop } from '../../src/util'
import BaseComponent from '../../src/base-component.js'
import EventHandler from '../../src/dom/event-handler.js'
import { noop } from '../../src/util/index.js'
import { clearFixture, getFixture } from '../helpers/fixture.js'
class DummyClass extends BaseComponent {
constructor(element) {

View file

@ -1,5 +1,5 @@
import Button from '../../src/button'
import { getFixture, clearFixture, jQueryMock } from '../helpers/fixture'
import Button from '../../src/button.js'
import { clearFixture, getFixture, jQueryMock } from '../helpers/fixture.js'
describe('Button', () => {
let fixtureEl

View file

@ -1,8 +1,8 @@
import Carousel from '../../src/carousel'
import EventHandler from '../../src/dom/event-handler'
import { clearFixture, createEvent, getFixture, jQueryMock } from '../helpers/fixture'
import { isRTL, noop } from '../../src/util/index'
import Swipe from '../../src/util/swipe'
import Carousel from '../../src/carousel.js'
import EventHandler from '../../src/dom/event-handler.js'
import { isRTL, noop } from '../../src/util/index.js'
import Swipe from '../../src/util/swipe.js'
import { clearFixture, createEvent, getFixture, jQueryMock } from '../helpers/fixture.js'
describe('Carousel', () => {
const { Simulator, PointerEvent } = window

View file

@ -1,6 +1,6 @@
import Collapse from '../../src/collapse'
import EventHandler from '../../src/dom/event-handler'
import { clearFixture, getFixture, jQueryMock } from '../helpers/fixture'
import Collapse from '../../src/collapse.js'
import EventHandler from '../../src/dom/event-handler.js'
import { clearFixture, getFixture, jQueryMock } from '../helpers/fixture.js'
describe('Collapse', () => {
let fixtureEl
@ -277,25 +277,25 @@ describe('Collapse', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = [
'<div id="parentGroup" class="accordion">',
' <div id="parentHeader" class="accordion-header">',
' <button data-bs-target="#parentContent" data-bs-toggle="collapse" role="button" class="accordion-toggle">Parent</button>',
' <div class="accordion-header">',
' <button data-bs-target="#parentContent" data-bs-toggle="collapse" class="accordion-toggle">Parent</button>',
' </div>',
' <div id="parentContent" class="accordion-collapse collapse" aria-labelledby="parentHeader" data-bs-parent="#parentGroup">',
' <div id="parentContent" class="accordion-collapse collapse" data-bs-parent="#parentGroup">',
' <div class="accordion-body">',
' <div id="childGroup" class="accordion">',
' <div class="accordion-item">',
' <div id="childHeader1" class="accordion-header">',
' <button data-bs-target="#childContent1" data-bs-toggle="collapse" role="button" class="accordion-toggle">Child 1</button>',
' <div class="accordion-header">',
' <button data-bs-target="#childContent1" data-bs-toggle="collapse" class="accordion-toggle">Child 1</button>',
' </div>',
' <div id="childContent1" class="accordion-collapse collapse" aria-labelledby="childHeader1" data-bs-parent="#childGroup">',
' <div id="childContent1" class="accordion-collapse collapse" data-bs-parent="#childGroup">',
' <div>content</div>',
' </div>',
' </div>',
' <div class="accordion-item">',
' <div id="childHeader2" class="accordion-header">',
' <button data-bs-target="#childContent2" data-bs-toggle="collapse" role="button" class="accordion-toggle">Child 2</button>',
' <div class="accordion-header">',
' <button data-bs-target="#childContent2" data-bs-toggle="collapse" class="accordion-toggle">Child 2</button>',
' </div>',
' <div id="childContent2" class="accordion-collapse collapse" aria-labelledby="childHeader2" data-bs-parent="#childGroup">',
' <div id="childContent2" class="accordion-collapse collapse" data-bs-parent="#childGroup">',
' <div>content</div>',
' </div>',
' </div>',
@ -338,12 +338,12 @@ describe('Collapse', () => {
fixtureEl.innerHTML = [
'<div class="accordion" id="accordionExample">',
' <div class="accordion-item">',
' <h2 class="accordion-header" id="headingOne">',
' <h2 class="accordion-header">',
' <button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">',
' Accordion Item #1',
' </button>',
' </h2>',
' <div id="collapseOne" class="accordion-collapse collapse show" aria-labelledby="headingOne" data-bs-parent="#accordionExample">',
' <div id="collapseOne" class="accordion-collapse collapse show" data-bs-parent="#accordionExample">',
' <div class="accordion-body">',
' <nav>',
' <div class="nav nav-tabs" id="nav-tab" role="tablist">',
@ -640,11 +640,11 @@ describe('Collapse', () => {
'<div id="accordion">',
' <div class="item">',
' <a id="linkTrigger" data-bs-toggle="collapse" href="#collapseOne" aria-expanded="false" aria-controls="collapseOne"></a>',
' <div id="collapseOne" class="collapse" role="tabpanel" aria-labelledby="headingThree" data-bs-parent="#accordion"></div>',
' <div id="collapseOne" class="collapse" role="tabpanel" data-bs-parent="#accordion"></div>',
' </div>',
' <div class="item">',
' <a id="linkTriggerTwo" data-bs-toggle="collapse" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo"></a>',
' <div id="collapseTwo" class="collapse show" role="tabpanel" aria-labelledby="headingTwo" data-bs-parent="#accordion"></div>',
' <div id="collapseTwo" class="collapse show" role="tabpanel" data-bs-parent="#accordion"></div>',
' </div>',
'</div>'
].join('')
@ -699,13 +699,13 @@ describe('Collapse', () => {
' <div class="col-lg-6">',
' <div class="item">',
' <a id="linkTrigger" data-bs-toggle="collapse" href="#collapseOne" aria-expanded="false" aria-controls="collapseOne"></a>',
' <div id="collapseOne" class="collapse" role="tabpanel" aria-labelledby="headingThree" data-bs-parent="#accordion"></div>',
' <div id="collapseOne" class="collapse" role="tabpanel" data-bs-parent="#accordion"></div>',
' </div>',
' </div>',
' <div class="col-lg-6">',
' <div class="item">',
' <a id="linkTriggerTwo" data-bs-toggle="collapse" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo"></a>',
' <div id="collapseTwo" class="collapse show" role="tabpanel" aria-labelledby="headingTwo" data-bs-parent="#accordion"></div>',
' <div id="collapseTwo" class="collapse show" role="tabpanel" data-bs-parent="#accordion"></div>',
' </div>',
' </div>',
' </div>',
@ -829,18 +829,18 @@ describe('Collapse', () => {
'<div id="accordion">',
' <div class="item">',
' <a id="linkTrigger" data-bs-toggle="collapse" href="#collapseOne" aria-expanded="false" aria-controls="collapseOne"></a>',
' <div id="collapseOne" data-bs-parent="#accordion" class="collapse" role="tabpanel" aria-labelledby="headingThree">',
' <div id="collapseOne" data-bs-parent="#accordion" class="collapse" role="tabpanel">',
' <div id="nestedAccordion">',
' <div class="item">',
' <a id="nestedLinkTrigger" data-bs-toggle="collapse" href="#nestedCollapseOne" aria-expanded="false" aria-controls="nestedCollapseOne"></a>',
' <div id="nestedCollapseOne" data-bs-parent="#nestedAccordion" class="collapse" role="tabpanel" aria-labelledby="headingThree"></div>',
' <div id="nestedCollapseOne" data-bs-parent="#nestedAccordion" class="collapse" role="tabpanel"></div>',
' </div>',
' </div>',
' </div>',
' </div>',
' <div class="item">',
' <a id="linkTriggerTwo" data-bs-toggle="collapse" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo"></a>',
' <div id="collapseTwo" data-bs-parent="#accordion" class="collapse show" role="tabpanel" aria-labelledby="headingTwo"></div>',
' <div id="collapseTwo" data-bs-parent="#accordion" class="collapse show" role="tabpanel"></div>',
' </div>',
'</div>'
].join('')
@ -887,17 +887,17 @@ describe('Collapse', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = [
'<a id="trigger1" role="button" data-bs-toggle="collapse" href="#test1"></a>',
'<a id="trigger2" role="button" data-bs-toggle="collapse" href="#test2"></a>',
'<a id="trigger2" role="button" data-bs-toggle="collapse" href="#0/my/id"></a>',
'<a id="trigger3" role="button" data-bs-toggle="collapse" href=".multi"></a>',
'<div id="test1" class="multi"></div>',
'<div id="test2" class="multi"></div>'
'<div id="0/my/id" class="multi"></div>'
].join('')
const trigger1 = fixtureEl.querySelector('#trigger1')
const trigger2 = fixtureEl.querySelector('#trigger2')
const trigger3 = fixtureEl.querySelector('#trigger3')
const target1 = fixtureEl.querySelector('#test1')
const target2 = fixtureEl.querySelector('#test2')
const target2 = fixtureEl.querySelector(`#${CSS.escape('0/my/id')}`)
const target2Shown = () => {
expect(trigger1).not.toHaveClass('collapsed')

View file

@ -1,5 +1,5 @@
import Data from '../../../src/dom/data'
import { getFixture, clearFixture } from '../../helpers/fixture'
import Data from '../../../src/dom/data.js'
import { clearFixture, getFixture } from '../../helpers/fixture.js'
describe('Data', () => {
const TEST_KEY = 'bs.test'
@ -89,7 +89,6 @@ describe('Data', () => {
expect(Data.get(div, TEST_KEY)).toBeNull()
})
/* eslint-disable no-console */
it('should console.error a message if called with multiple keys', () => {
console.error = jasmine.createSpy('console.error')
@ -102,5 +101,4 @@ describe('Data', () => {
expect(console.error).toHaveBeenCalled()
expect(Data.get(div, UNKNOWN_KEY)).toBeNull()
})
/* eslint-enable no-console */
})

View file

@ -1,6 +1,6 @@
import EventHandler from '../../../src/dom/event-handler'
import { clearFixture, getFixture } from '../../helpers/fixture'
import { noop } from '../../../src/util'
import EventHandler from '../../../src/dom/event-handler.js'
import { noop } from '../../../src/util/index.js'
import { clearFixture, getFixture } from '../../helpers/fixture.js'
describe('EventHandler', () => {
let fixtureEl

View file

@ -1,5 +1,5 @@
import Manipulator from '../../../src/dom/manipulator'
import { clearFixture, getFixture } from '../../helpers/fixture'
import Manipulator from '../../../src/dom/manipulator.js'
import { clearFixture, getFixture } from '../../helpers/fixture.js'
describe('Manipulator', () => {
let fixtureEl

View file

@ -1,5 +1,5 @@
import SelectorEngine from '../../../src/dom/selector-engine'
import { getFixture, clearFixture } from '../../helpers/fixture'
import SelectorEngine from '../../../src/dom/selector-engine.js'
import { clearFixture, getFixture } from '../../helpers/fixture.js'
describe('SelectorEngine', () => {
let fixtureEl
@ -232,5 +232,159 @@ describe('SelectorEngine', () => {
expect(SelectorEngine.focusableChildren(fixtureEl)).toEqual(expectedElements)
})
})
})
describe('getSelectorFromElement', () => {
it('should get selector from data-bs-target', () => {
fixtureEl.innerHTML = [
'<div id="test" data-bs-target=".target"></div>',
'<div class="target"></div>'
].join('')
const testEl = fixtureEl.querySelector('#test')
expect(SelectorEngine.getSelectorFromElement(testEl)).toEqual('.target')
})
it('should get selector from href if no data-bs-target set', () => {
fixtureEl.innerHTML = [
'<a id="test" href=".target"></a>',
'<div class="target"></div>'
].join('')
const testEl = fixtureEl.querySelector('#test')
expect(SelectorEngine.getSelectorFromElement(testEl)).toEqual('.target')
})
it('should get selector from href if data-bs-target equal to #', () => {
fixtureEl.innerHTML = [
'<a id="test" data-bs-target="#" href=".target"></a>',
'<div class="target"></div>'
].join('')
const testEl = fixtureEl.querySelector('#test')
expect(SelectorEngine.getSelectorFromElement(testEl)).toEqual('.target')
})
it('should return null if a selector from a href is a url without an anchor', () => {
fixtureEl.innerHTML = [
'<a id="test" data-bs-target="#" href="foo/bar.html"></a>',
'<div class="target"></div>'
].join('')
const testEl = fixtureEl.querySelector('#test')
expect(SelectorEngine.getSelectorFromElement(testEl)).toBeNull()
})
it('should return the anchor if a selector from a href is a url', () => {
fixtureEl.innerHTML = [
'<a id="test" data-bs-target="#" href="foo/bar.html#target"></a>',
'<div id="target"></div>'
].join('')
const testEl = fixtureEl.querySelector('#test')
expect(SelectorEngine.getSelectorFromElement(testEl)).toEqual('#target')
})
it('should return null if selector not found', () => {
fixtureEl.innerHTML = '<a id="test" href=".target"></a>'
const testEl = fixtureEl.querySelector('#test')
expect(SelectorEngine.getSelectorFromElement(testEl)).toBeNull()
})
it('should return null if no selector', () => {
fixtureEl.innerHTML = '<div></div>'
const testEl = fixtureEl.querySelector('div')
expect(SelectorEngine.getSelectorFromElement(testEl)).toBeNull()
})
})
describe('getElementFromSelector', () => {
it('should get element from data-bs-target', () => {
fixtureEl.innerHTML = [
'<div id="test" data-bs-target=".target"></div>',
'<div class="target"></div>'
].join('')
const testEl = fixtureEl.querySelector('#test')
expect(SelectorEngine.getElementFromSelector(testEl)).toEqual(fixtureEl.querySelector('.target'))
})
it('should get element from href if no data-bs-target set', () => {
fixtureEl.innerHTML = [
'<a id="test" href=".target"></a>',
'<div class="target"></div>'
].join('')
const testEl = fixtureEl.querySelector('#test')
expect(SelectorEngine.getElementFromSelector(testEl)).toEqual(fixtureEl.querySelector('.target'))
})
it('should return null if element not found', () => {
fixtureEl.innerHTML = '<a id="test" href=".target"></a>'
const testEl = fixtureEl.querySelector('#test')
expect(SelectorEngine.getElementFromSelector(testEl)).toBeNull()
})
it('should return null if no selector', () => {
fixtureEl.innerHTML = '<div></div>'
const testEl = fixtureEl.querySelector('div')
expect(SelectorEngine.getElementFromSelector(testEl)).toBeNull()
})
})
describe('getMultipleElementsFromSelector', () => {
it('should get elements from data-bs-target', () => {
fixtureEl.innerHTML = [
'<div id="test" data-bs-target=".target"></div>',
'<div class="target"></div>',
'<div class="target"></div>'
].join('')
const testEl = fixtureEl.querySelector('#test')
expect(SelectorEngine.getMultipleElementsFromSelector(testEl)).toEqual(Array.from(fixtureEl.querySelectorAll('.target')))
})
it('should get elements in array, from href if no data-bs-target set', () => {
fixtureEl.innerHTML = [
'<a id="test" href=".target"></a>',
'<div class="target"></div>',
'<div class="target"></div>'
].join('')
const testEl = fixtureEl.querySelector('#test')
expect(SelectorEngine.getMultipleElementsFromSelector(testEl)).toEqual(Array.from(fixtureEl.querySelectorAll('.target')))
})
it('should return empty array if elements not found', () => {
fixtureEl.innerHTML = '<a id="test" href=".target"></a>'
const testEl = fixtureEl.querySelector('#test')
expect(SelectorEngine.getMultipleElementsFromSelector(testEl)).toHaveSize(0)
})
it('should return empty array if no selector', () => {
fixtureEl.innerHTML = '<div></div>'
const testEl = fixtureEl.querySelector('div')
expect(SelectorEngine.getMultipleElementsFromSelector(testEl)).toHaveSize(0)
})
})
})

View file

@ -1,7 +1,7 @@
import Dropdown from '../../src/dropdown'
import EventHandler from '../../src/dom/event-handler'
import { noop } from '../../src/util/index'
import { clearFixture, createEvent, getFixture, jQueryMock } from '../helpers/fixture'
import EventHandler from '../../src/dom/event-handler.js'
import Dropdown from '../../src/dropdown.js'
import { noop } from '../../src/util/index.js'
import { clearFixture, createEvent, getFixture, jQueryMock } from '../helpers/fixture.js'
describe('Dropdown', () => {
let fixtureEl
@ -75,6 +75,7 @@ describe('Dropdown', () => {
resolve()
})
expect().nothing()
dropdown.show()
})
})

View file

@ -1,18 +1,18 @@
/* eslint-env jquery */
import Alert from '../../src/alert'
import Button from '../../src/button'
import Carousel from '../../src/carousel'
import Collapse from '../../src/collapse'
import Dropdown from '../../src/dropdown'
import Modal from '../../src/modal'
import Offcanvas from '../../src/offcanvas'
import Popover from '../../src/popover'
import ScrollSpy from '../../src/scrollspy'
import Tab from '../../src/tab'
import Toast from '../../src/toast'
import Tooltip from '../../src/tooltip'
import { clearFixture, getFixture } from '../helpers/fixture'
import Alert from '../../src/alert.js'
import Button from '../../src/button.js'
import Carousel from '../../src/carousel.js'
import Collapse from '../../src/collapse.js'
import Dropdown from '../../src/dropdown.js'
import Modal from '../../src/modal.js'
import Offcanvas from '../../src/offcanvas.js'
import Popover from '../../src/popover.js'
import ScrollSpy from '../../src/scrollspy.js'
import Tab from '../../src/tab.js'
import Toast from '../../src/toast.js'
import Tooltip from '../../src/tooltip.js'
import { clearFixture, getFixture } from '../helpers/fixture.js'
describe('jQuery', () => {
let fixtureEl

View file

@ -1,7 +1,7 @@
import Modal from '../../src/modal'
import EventHandler from '../../src/dom/event-handler'
import ScrollBarHelper from '../../src/util/scrollbar'
import { clearBodyAndDocument, clearFixture, createEvent, getFixture, jQueryMock } from '../helpers/fixture'
import EventHandler from '../../src/dom/event-handler.js'
import Modal from '../../src/modal.js'
import ScrollBarHelper from '../../src/util/scrollbar.js'
import { clearBodyAndDocument, clearFixture, createEvent, getFixture, jQueryMock } from '../helpers/fixture.js'
describe('Modal', () => {
let fixtureEl

View file

@ -1,8 +1,8 @@
import Offcanvas from '../../src/offcanvas'
import EventHandler from '../../src/dom/event-handler'
import { clearBodyAndDocument, clearFixture, createEvent, getFixture, jQueryMock } from '../helpers/fixture'
import { isVisible } from '../../src/util/index'
import ScrollBarHelper from '../../src/util/scrollbar'
import EventHandler from '../../src/dom/event-handler.js'
import Offcanvas from '../../src/offcanvas.js'
import { isVisible } from '../../src/util/index.js'
import ScrollBarHelper from '../../src/util/scrollbar.js'
import { clearBodyAndDocument, clearFixture, createEvent, getFixture, jQueryMock } from '../helpers/fixture.js'
describe('Offcanvas', () => {
let fixtureEl

View file

@ -1,6 +1,6 @@
import Popover from '../../src/popover'
import EventHandler from '../../src/dom/event-handler'
import { clearFixture, getFixture, jQueryMock } from '../helpers/fixture'
import EventHandler from '../../src/dom/event-handler.js'
import Popover from '../../src/popover.js'
import { clearFixture, getFixture, jQueryMock } from '../helpers/fixture.js'
describe('Popover', () => {
let fixtureEl

View file

@ -1,8 +1,6 @@
import ScrollSpy from '../../src/scrollspy'
/** Test helpers */
import { clearFixture, createEvent, getFixture, jQueryMock } from '../helpers/fixture'
import EventHandler from '../../src/dom/event-handler'
import EventHandler from '../../src/dom/event-handler.js'
import ScrollSpy from '../../src/scrollspy.js'
import { clearFixture, createEvent, getFixture, jQueryMock } from '../helpers/fixture.js'
describe('ScrollSpy', () => {
let fixtureEl
@ -942,5 +940,39 @@ describe('ScrollSpy', () => {
}, 100)
link.click()
})
it('should smoothscroll to observable with anchor link that contains a french word as id', done => {
fixtureEl.innerHTML = [
'<nav id="navBar" class="navbar">',
' <ul class="nav">',
' <li class="nav-item"><a id="li-jsm-1" class="nav-link" href="#présentation">div 1</a></li>',
' </ul>',
'</nav>',
'<div class="content" data-bs-target="#navBar" style="overflow-y: auto">',
' <div id="présentation">div 1</div>',
'</div>'
].join('')
const div = fixtureEl.querySelector('.content')
const link = fixtureEl.querySelector('[href="#présentation"]')
const observable = fixtureEl.querySelector('#présentation')
const clickSpy = getElementScrollSpy(div)
// eslint-disable-next-line no-new
new ScrollSpy(div, {
offset: 1,
smoothScroll: true
})
setTimeout(() => {
if (div.scrollTo) {
expect(clickSpy).toHaveBeenCalledWith({ top: observable.offsetTop - div.offsetTop, behavior: 'smooth' })
} else {
expect(clickSpy).toHaveBeenCalledWith(observable.offsetTop - div.offsetTop)
}
done()
}, 100)
link.click()
})
})
})

View file

@ -1,5 +1,5 @@
import Tab from '../../src/tab'
import { clearFixture, createEvent, getFixture, jQueryMock } from '../helpers/fixture'
import Tab from '../../src/tab.js'
import { clearFixture, createEvent, getFixture, jQueryMock } from '../helpers/fixture.js'
describe('Tab', () => {
let fixtureEl
@ -177,6 +177,43 @@ describe('Tab', () => {
})
})
it('should work with tab id being an int', done => {
fixtureEl.innerHTML = [
'<div class="card-header d-block d-inline-block">',
' <ul class="nav nav-tabs card-header-tabs" id="page_tabs">',
' <li class="nav-item">',
' <a class="nav-link" draggable="false" data-toggle="tab" href="#tab1">',
' Working Tab 1 (#tab1)',
' </a>',
' </li>',
' <li class="nav-item">',
' <a id="trigger2" class="nav-link" draggable="false" data-toggle="tab" href="#2">',
' Tab with numeric ID should work (#2)',
' </a>',
' </li>',
' </ul>',
'</div>',
'<div class="card-body">',
' <div class="tab-content" id="page_content">',
' <div class="tab-pane fade" id="tab1">',
' Working Tab 1 (#tab1) Content Here',
' </div>',
' <div class="tab-pane fade" id="2">',
' Working Tab 2 (#2) with numeric ID',
' </div>',
'</div>'
].join('')
const profileTriggerEl = fixtureEl.querySelector('#trigger2')
const tab = new Tab(profileTriggerEl)
profileTriggerEl.addEventListener('shown.bs.tab', () => {
expect(fixtureEl.querySelector(`#${CSS.escape('2')}`)).toHaveClass('active')
done()
})
tab.show()
})
it('should not fire shown when show is prevented', () => {
return new Promise((resolve, reject) => {
fixtureEl.innerHTML = '<div class="nav"><div class="nav-link"></div></div>'
@ -477,7 +514,7 @@ describe('Tab', () => {
expect(tabPanel.hasAttribute('tabindex')).toBeFalse()
expect(tabPanel.hasAttribute('tabindex2')).toBeFalse()
expect(tabPanel.getAttribute('aria-labelledby')).toEqual('#foo')
expect(tabPanel.getAttribute('aria-labelledby')).toEqual('foo')
expect(tabPanel2.hasAttribute('aria-labelledby')).toBeFalse()
})
})
@ -603,19 +640,19 @@ describe('Tab', () => {
'</div>'
].join('')
const tabEl = fixtureEl.querySelector('#tab1')
const tabEl1 = fixtureEl.querySelector('#tab1')
const tabEl2 = fixtureEl.querySelector('#tab2')
const tabEl3 = fixtureEl.querySelector('#tab3')
const tabEl4 = fixtureEl.querySelector('#tab4')
const tab = new Tab(tabEl)
const tab1 = new Tab(tabEl1)
const tab2 = new Tab(tabEl2)
const tab3 = new Tab(tabEl3)
const tab4 = new Tab(tabEl4)
const spy1 = spyOn(tab, 'show').and.callThrough()
const spy1 = spyOn(tab1, 'show').and.callThrough()
const spy2 = spyOn(tab2, 'show').and.callThrough()
const spy3 = spyOn(tab3, 'show').and.callThrough()
const spy4 = spyOn(tab4, 'show').and.callThrough()
const spyFocus1 = spyOn(tabEl, 'focus').and.callThrough()
const spyFocus1 = spyOn(tabEl1, 'focus').and.callThrough()
const spyFocus2 = spyOn(tabEl2, 'focus').and.callThrough()
const spyFocus3 = spyOn(tabEl3, 'focus').and.callThrough()
const spyFocus4 = spyOn(tabEl4, 'focus').and.callThrough()
@ -623,7 +660,7 @@ describe('Tab', () => {
const keydown = createEvent('keydown')
keydown.key = 'ArrowRight'
tabEl.dispatchEvent(keydown)
tabEl1.dispatchEvent(keydown)
expect(spy1).not.toHaveBeenCalled()
expect(spy2).not.toHaveBeenCalled()
expect(spy3).not.toHaveBeenCalled()
@ -644,19 +681,19 @@ describe('Tab', () => {
'</div>'
].join('')
const tabEl = fixtureEl.querySelector('#tab1')
const tabEl1 = fixtureEl.querySelector('#tab1')
const tabEl2 = fixtureEl.querySelector('#tab2')
const tabEl3 = fixtureEl.querySelector('#tab3')
const tabEl4 = fixtureEl.querySelector('#tab4')
const tab = new Tab(tabEl)
const tab1 = new Tab(tabEl1)
const tab2 = new Tab(tabEl2)
const tab3 = new Tab(tabEl3)
const tab4 = new Tab(tabEl4)
const spy1 = spyOn(tab, 'show').and.callThrough()
const spy1 = spyOn(tab1, 'show').and.callThrough()
const spy2 = spyOn(tab2, 'show').and.callThrough()
const spy3 = spyOn(tab3, 'show').and.callThrough()
const spy4 = spyOn(tab4, 'show').and.callThrough()
const spyFocus1 = spyOn(tabEl, 'focus').and.callThrough()
const spyFocus1 = spyOn(tabEl1, 'focus').and.callThrough()
const spyFocus2 = spyOn(tabEl2, 'focus').and.callThrough()
const spyFocus3 = spyOn(tabEl3, 'focus').and.callThrough()
const spyFocus4 = spyOn(tabEl4, 'focus').and.callThrough()

View file

@ -1,5 +1,5 @@
import Toast from '../../src/toast'
import { clearFixture, createEvent, getFixture, jQueryMock } from '../helpers/fixture'
import Toast from '../../src/toast.js'
import { clearFixture, createEvent, getFixture, jQueryMock } from '../helpers/fixture.js'
describe('Toast', () => {
let fixtureEl

View file

@ -1,7 +1,7 @@
import Tooltip from '../../src/tooltip'
import EventHandler from '../../src/dom/event-handler'
import { noop } from '../../src/util/index'
import { clearFixture, createEvent, getFixture, jQueryMock } from '../helpers/fixture'
import EventHandler from '../../src/dom/event-handler.js'
import Tooltip from '../../src/tooltip.js'
import { noop } from '../../src/util/index.js'
import { clearFixture, createEvent, getFixture, jQueryMock } from '../helpers/fixture.js'
describe('Tooltip', () => {
let fixtureEl
@ -56,7 +56,7 @@ describe('Tooltip', () => {
describe('constructor', () => {
it('should take care of element either passed as a CSS selector or DOM element', () => {
fixtureEl.innerHTML = '<a href="#" id="tooltipEl" rel="tooltip" title="Nice and short title">'
fixtureEl.innerHTML = '<a href="#" id="tooltipEl" rel="tooltip" title="Nice and short title"></a>'
const tooltipEl = fixtureEl.querySelector('#tooltipEl')
const tooltipBySelector = new Tooltip('#tooltipEl')
@ -67,7 +67,7 @@ describe('Tooltip', () => {
})
it('should not take care of disallowed data attributes', () => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" data-bs-sanitize="false" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" data-bs-sanitize="false" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)
@ -76,7 +76,7 @@ describe('Tooltip', () => {
})
it('should convert title and content to string if numbers', () => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl, {
@ -98,7 +98,7 @@ describe('Tooltip', () => {
trigger: 'click'
})
containerEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
containerEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipInContainerEl = containerEl.querySelector('a')
@ -114,7 +114,7 @@ describe('Tooltip', () => {
it('should create offset modifier when offset is passed as a function', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Offset from function">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Offset from function"></a>'
const getOffset = jasmine.createSpy('getOffset').and.returnValue([10, 20])
const tooltipEl = fixtureEl.querySelector('a')
@ -141,7 +141,7 @@ describe('Tooltip', () => {
})
it('should create offset modifier when offset option is passed in data attribute', () => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" data-bs-offset="10,20" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" data-bs-offset="10,20" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)
@ -150,7 +150,7 @@ describe('Tooltip', () => {
})
it('should allow to pass config to Popper with `popperConfig`', () => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl, {
@ -165,7 +165,7 @@ describe('Tooltip', () => {
})
it('should allow to pass config to Popper with `popperConfig` as a function', () => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const getPopperConfig = jasmine.createSpy('getPopperConfig').and.returnValue({ placement: 'left' })
@ -192,7 +192,7 @@ describe('Tooltip', () => {
describe('enable', () => {
it('should enable a tooltip', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)
@ -212,7 +212,7 @@ describe('Tooltip', () => {
describe('disable', () => {
it('should disable tooltip', () => {
return new Promise((resolve, reject) => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)
@ -235,7 +235,7 @@ describe('Tooltip', () => {
describe('toggleEnabled', () => {
it('should toggle enabled', () => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)
@ -251,7 +251,7 @@ describe('Tooltip', () => {
describe('toggle', () => {
it('should do nothing if disabled', () => {
return new Promise((resolve, reject) => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)
@ -273,7 +273,7 @@ describe('Tooltip', () => {
it('should show a tooltip', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)
@ -289,7 +289,7 @@ describe('Tooltip', () => {
it('should call toggle and show the tooltip when trigger is "click"', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl, {
@ -309,7 +309,7 @@ describe('Tooltip', () => {
it('should hide a tooltip', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)
@ -329,7 +329,7 @@ describe('Tooltip', () => {
it('should call toggle and hide the tooltip when trigger is "click"', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl, {
@ -354,7 +354,7 @@ describe('Tooltip', () => {
describe('dispose', () => {
it('should destroy a tooltip', () => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const addEventSpy = spyOn(tooltipEl, 'addEventListener').and.callThrough()
@ -381,7 +381,7 @@ describe('Tooltip', () => {
it('should destroy a tooltip after it is shown and hidden', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)
@ -402,7 +402,7 @@ describe('Tooltip', () => {
it('should destroy a tooltip and remove it from the dom', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)
@ -443,7 +443,7 @@ describe('Tooltip', () => {
describe('show', () => {
it('should show a tooltip', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)
@ -488,7 +488,7 @@ describe('Tooltip', () => {
it('should show a tooltip on mobile', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)
@ -509,7 +509,7 @@ describe('Tooltip', () => {
it('should show a tooltip relative to placement option', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl, {
@ -532,7 +532,7 @@ describe('Tooltip', () => {
it('should not error when trying to show a tooltip that has been removed from the dom', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)
@ -561,7 +561,7 @@ describe('Tooltip', () => {
it('should show a tooltip with a dom element container', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl, {
@ -579,7 +579,7 @@ describe('Tooltip', () => {
it('should show a tooltip with a jquery element container', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl, {
@ -600,7 +600,7 @@ describe('Tooltip', () => {
it('should show a tooltip with a selector in container', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl, {
@ -618,7 +618,7 @@ describe('Tooltip', () => {
it('should show a tooltip with placement as a function', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const spy = jasmine.createSpy('placement').and.returnValue('top')
const tooltipEl = fixtureEl.querySelector('a')
@ -638,7 +638,7 @@ describe('Tooltip', () => {
it('should show a tooltip without the animation', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl, {
@ -658,7 +658,7 @@ describe('Tooltip', () => {
})
it('should throw an error the element is not visible', () => {
fixtureEl.innerHTML = '<a href="#" style="display: none" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" style="display: none" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)
@ -672,7 +672,7 @@ describe('Tooltip', () => {
it('should not show a tooltip if show.bs.tooltip is prevented', () => {
return new Promise((resolve, reject) => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)
@ -699,7 +699,7 @@ describe('Tooltip', () => {
it('should show tooltip if leave event hasn\'t occurred before delay expires', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl, {
@ -723,7 +723,7 @@ describe('Tooltip', () => {
it('should not show tooltip if leave event occurs before delay expires', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl, {
@ -845,7 +845,7 @@ describe('Tooltip', () => {
it('should only trigger inserted event if a new tooltip element was created', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)
@ -878,7 +878,7 @@ describe('Tooltip', () => {
it('should show a tooltip with custom class provided in data attributes', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip" data-bs-custom-class="custom-class">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip" data-bs-custom-class="custom-class"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)
@ -896,7 +896,7 @@ describe('Tooltip', () => {
it('should show a tooltip with custom class provided as a string in config', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl, {
@ -917,7 +917,7 @@ describe('Tooltip', () => {
it('should show a tooltip with custom class provided as a function in config', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const spy = jasmine.createSpy('customClass').and.returnValue('custom-class')
const tooltipEl = fixtureEl.querySelector('a')
@ -956,7 +956,7 @@ describe('Tooltip', () => {
describe('hide', () => {
it('should hide a tooltip', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)
@ -974,7 +974,7 @@ describe('Tooltip', () => {
it('should hide a tooltip on mobile', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)
@ -998,7 +998,7 @@ describe('Tooltip', () => {
it('should hide a tooltip without animation', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl, {
@ -1018,7 +1018,7 @@ describe('Tooltip', () => {
it('should not hide a tooltip if hide event is prevented', () => {
return new Promise((resolve, reject) => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const assertDone = () => {
setTimeout(() => {
@ -1063,7 +1063,7 @@ describe('Tooltip', () => {
describe('update', () => {
it('should call popper update', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)
@ -1082,7 +1082,7 @@ describe('Tooltip', () => {
})
it('should do nothing if the tooltip is not shown', () => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)
@ -1094,7 +1094,7 @@ describe('Tooltip', () => {
describe('_isWithContent', () => {
it('should return true if there is content', () => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)
@ -1103,7 +1103,7 @@ describe('Tooltip', () => {
})
it('should return false if there is no content', () => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title=""></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)
@ -1114,7 +1114,7 @@ describe('Tooltip', () => {
describe('_getTipElement', () => {
it('should create the tip element and return it', () => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)
@ -1126,7 +1126,7 @@ describe('Tooltip', () => {
})
it('should return the created tip element', () => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)
@ -1145,7 +1145,7 @@ describe('Tooltip', () => {
describe('setContent', () => {
it('should set tip content', () => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl, { animation: false })
@ -1160,7 +1160,7 @@ describe('Tooltip', () => {
})
it('should re-show tip if it was already shown', () => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" data-bs-title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" data-bs-title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)
@ -1175,7 +1175,7 @@ describe('Tooltip', () => {
})
it('should keep tip hidden, if it was already hidden before', () => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" data-bs-title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" data-bs-title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)
@ -1190,7 +1190,7 @@ describe('Tooltip', () => {
})
it('"setContent" should keep the initial template', () => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)
@ -1207,7 +1207,7 @@ describe('Tooltip', () => {
describe('setContent', () => {
it('should do nothing if the element is null', () => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)

View file

@ -1,6 +1,6 @@
import Backdrop from '../../../src/util/backdrop'
import { getTransitionDurationFromElement } from '../../../src/util/index'
import { clearFixture, getFixture } from '../../helpers/fixture'
import Backdrop from '../../../src/util/backdrop.js'
import { getTransitionDurationFromElement } from '../../../src/util/index.js'
import { clearFixture, getFixture } from '../../helpers/fixture.js'
const CLASS_BACKDROP = '.modal-backdrop'
const CLASS_NAME_FADE = 'fade'

View file

@ -1,8 +1,6 @@
/* Test helpers */
import { clearFixture, createEvent, getFixture } from '../../helpers/fixture'
import { enableDismissTrigger } from '../../../src/util/component-functions'
import BaseComponent from '../../../src/base-component'
import BaseComponent from '../../../src/base-component.js'
import { enableDismissTrigger } from '../../../src/util/component-functions.js'
import { clearFixture, createEvent, getFixture } from '../../helpers/fixture.js'
class DummyClass2 extends BaseComponent {
static get NAME() {

View file

@ -1,5 +1,5 @@
import Config from '../../../src/util/config'
import { clearFixture, getFixture } from '../../helpers/fixture'
import Config from '../../../src/util/config.js'
import { clearFixture, getFixture } from '../../helpers/fixture.js'
class DummyConfigClass extends Config {
static get NAME() {
@ -128,7 +128,7 @@ describe('Config', () => {
const obj = new DummyConfigClass()
expect(() => {
obj._typeCheckConfig(config)
}).toThrowError(TypeError, obj.constructor.NAME.toUpperCase() + ': Option "parent" provided type "number" but expected type "(string|element)".')
}).toThrowError(TypeError, `${obj.constructor.NAME.toUpperCase()}: Option "parent" provided type "number" but expected type "(string|element)".`)
})
it('should return null stringified when null is passed', () => {

View file

@ -1,7 +1,7 @@
import FocusTrap from '../../../src/util/focustrap'
import EventHandler from '../../../src/dom/event-handler'
import SelectorEngine from '../../../src/dom/selector-engine'
import { clearFixture, createEvent, getFixture } from '../../helpers/fixture'
import EventHandler from '../../../src/dom/event-handler.js'
import SelectorEngine from '../../../src/dom/selector-engine.js'
import FocusTrap from '../../../src/util/focustrap.js'
import { clearFixture, createEvent, getFixture } from '../../helpers/fixture.js'
describe('FocusTrap', () => {
let fixtureEl

View file

@ -1,6 +1,6 @@
import * as Util from '../../../src/util/index'
import { clearFixture, getFixture } from '../../helpers/fixture'
import { noop } from '../../../src/util/index'
import * as Util from '../../../src/util/index.js'
import { noop } from '../../../src/util/index.js'
import { clearFixture, getFixture } from '../../helpers/fixture.js'
describe('Util', () => {
let fixtureEl
@ -22,119 +22,6 @@ describe('Util', () => {
})
})
describe('getSelectorFromElement', () => {
it('should get selector from data-bs-target', () => {
fixtureEl.innerHTML = [
'<div id="test" data-bs-target=".target"></div>',
'<div class="target"></div>'
].join('')
const testEl = fixtureEl.querySelector('#test')
expect(Util.getSelectorFromElement(testEl)).toEqual('.target')
})
it('should get selector from href if no data-bs-target set', () => {
fixtureEl.innerHTML = [
'<a id="test" href=".target"></a>',
'<div class="target"></div>'
].join('')
const testEl = fixtureEl.querySelector('#test')
expect(Util.getSelectorFromElement(testEl)).toEqual('.target')
})
it('should get selector from href if data-bs-target equal to #', () => {
fixtureEl.innerHTML = [
'<a id="test" data-bs-target="#" href=".target"></a>',
'<div class="target"></div>'
].join('')
const testEl = fixtureEl.querySelector('#test')
expect(Util.getSelectorFromElement(testEl)).toEqual('.target')
})
it('should return null if a selector from a href is a url without an anchor', () => {
fixtureEl.innerHTML = [
'<a id="test" data-bs-target="#" href="foo/bar.html"></a>',
'<div class="target"></div>'
].join('')
const testEl = fixtureEl.querySelector('#test')
expect(Util.getSelectorFromElement(testEl)).toBeNull()
})
it('should return the anchor if a selector from a href is a url', () => {
fixtureEl.innerHTML = [
'<a id="test" data-bs-target="#" href="foo/bar.html#target"></a>',
'<div id="target"></div>'
].join('')
const testEl = fixtureEl.querySelector('#test')
expect(Util.getSelectorFromElement(testEl)).toEqual('#target')
})
it('should return null if selector not found', () => {
fixtureEl.innerHTML = '<a id="test" href=".target"></a>'
const testEl = fixtureEl.querySelector('#test')
expect(Util.getSelectorFromElement(testEl)).toBeNull()
})
it('should return null if no selector', () => {
fixtureEl.innerHTML = '<div></div>'
const testEl = fixtureEl.querySelector('div')
expect(Util.getSelectorFromElement(testEl)).toBeNull()
})
})
describe('getElementFromSelector', () => {
it('should get element from data-bs-target', () => {
fixtureEl.innerHTML = [
'<div id="test" data-bs-target=".target"></div>',
'<div class="target"></div>'
].join('')
const testEl = fixtureEl.querySelector('#test')
expect(Util.getElementFromSelector(testEl)).toEqual(fixtureEl.querySelector('.target'))
})
it('should get element from href if no data-bs-target set', () => {
fixtureEl.innerHTML = [
'<a id="test" href=".target"></a>',
'<div class="target"></div>'
].join('')
const testEl = fixtureEl.querySelector('#test')
expect(Util.getElementFromSelector(testEl)).toEqual(fixtureEl.querySelector('.target'))
})
it('should return null if element not found', () => {
fixtureEl.innerHTML = '<a id="test" href=".target"></a>'
const testEl = fixtureEl.querySelector('#test')
expect(Util.getElementFromSelector(testEl)).toBeNull()
})
it('should return null if no selector', () => {
fixtureEl.innerHTML = '<div></div>'
const testEl = fixtureEl.querySelector('div')
expect(Util.getElementFromSelector(testEl)).toBeNull()
})
})
describe('getTransitionDurationFromElement', () => {
it('should get transition from element', () => {
fixtureEl.innerHTML = '<div style="transition: all 300ms ease-out;"></div>'
@ -631,6 +518,25 @@ describe('Util', () => {
Util.execute(spy)
expect(spy).toHaveBeenCalled()
})
it('should execute if arg is function & return the result', () => {
const functionFoo = (num1, num2 = 10) => num1 + num2
const resultFoo = Util.execute(functionFoo, [4, 5])
expect(resultFoo).toBe(9)
const resultFoo1 = Util.execute(functionFoo, [4])
expect(resultFoo1).toBe(14)
const functionBar = () => 'foo'
const resultBar = Util.execute(functionBar)
expect(resultBar).toBe('foo')
})
it('should not execute if arg is not function & return default argument', () => {
const foo = 'bar'
expect(Util.execute(foo)).toBe('bar')
expect(Util.execute(foo, [], 4)).toBe(4)
})
})
describe('executeAfterTransition', () => {

View file

@ -1,4 +1,4 @@
import { DefaultAllowlist, sanitizeHtml } from '../../../src/util/sanitizer'
import { DefaultAllowlist, sanitizeHtml } from '../../../src/util/sanitizer.js'
describe('Sanitizer', () => {
describe('sanitizeHtml', () => {
@ -10,17 +10,75 @@ describe('Sanitizer', () => {
expect(result).toEqual(empty)
})
it('should retain tags with valid URLs', () => {
const validUrls = [
'',
'http://abc',
'HTTP://abc',
'https://abc',
'HTTPS://abc',
'ftp://abc',
'FTP://abc',
'mailto:me@example.com',
'MAILTO:me@example.com',
'tel:123-123-1234',
'TEL:123-123-1234',
'sip:me@example.com',
'SIP:me@example.com',
'#anchor',
'/page1.md',
'http://JavaScript/my.js',
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/', // Truncated.
'data:video/webm;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/',
'data:audio/opus;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/',
'unknown-scheme:abc'
]
for (const url of validUrls) {
const template = [
'<div>',
` <a href="${url}">Click me</a>`,
' <span>Some content</span>',
'</div>'
].join('')
const result = sanitizeHtml(template, DefaultAllowlist, null)
expect(result).toContain(`href="${url}"`)
}
})
it('should sanitize template by removing tags with XSS', () => {
const template = [
'<div>',
' <a href="javascript:alert(7)">Click me</a>',
' <span>Some content</span>',
'</div>'
].join('')
const invalidUrls = [
// eslint-disable-next-line no-script-url
'javascript:alert(7)',
// eslint-disable-next-line no-script-url
'javascript:evil()',
// eslint-disable-next-line no-script-url
'JavaScript:abc',
' javascript:abc',
' \n Java\n Script:abc',
'&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;',
'&#106&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;',
'&#106 &#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;',
'&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058',
'&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A;',
'jav&#x09;ascript:alert();',
'jav\u0000ascript:alert();'
]
const result = sanitizeHtml(template, DefaultAllowlist, null)
for (const url of invalidUrls) {
const template = [
'<div>',
` <a href="${url}">Click me</a>`,
' <span>Some content</span>',
'</div>'
].join('')
expect(result).not.toContain('href="javascript:alert(7)')
const result = sanitizeHtml(template, DefaultAllowlist, null)
expect(result).not.toContain(`href="${url}"`)
}
})
it('should sanitize template and work with multiple regex', () => {

View file

@ -1,6 +1,6 @@
import { clearBodyAndDocument, clearFixture, getFixture } from '../../helpers/fixture'
import Manipulator from '../../../src/dom/manipulator'
import ScrollBarHelper from '../../../src/util/scrollbar'
import Manipulator from '../../../src/dom/manipulator.js'
import ScrollBarHelper from '../../../src/util/scrollbar.js'
import { clearBodyAndDocument, clearFixture, getFixture } from '../../helpers/fixture.js'
describe('ScrollBar', () => {
let fixtureEl

View file

@ -1,7 +1,7 @@
import { clearFixture, getFixture } from '../../helpers/fixture'
import EventHandler from '../../../src/dom/event-handler'
import Swipe from '../../../src/util/swipe'
import { noop } from '../../../src/util'
import EventHandler from '../../../src/dom/event-handler.js'
import { noop } from '../../../src/util/index.js'
import Swipe from '../../../src/util/swipe.js'
import { clearFixture, getFixture } from '../../helpers/fixture.js'
describe('Swipe', () => {
const { Simulator, PointerEvent } = window

View file

@ -1,5 +1,5 @@
import { clearFixture, getFixture } from '../../helpers/fixture'
import TemplateFactory from '../../../src/util/template-factory'
import TemplateFactory from '../../../src/util/template-factory.js'
import { clearFixture, getFixture } from '../../helpers/fixture.js'
describe('TemplateFactory', () => {
let fixtureEl