1
0
Fork 0

Merging upstream version 5.3.1+dfsg.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-17 07:08:40 +01:00
parent 02bb7909a6
commit cbd3962c37
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
92 changed files with 3961 additions and 3355 deletions

View file

@ -14,7 +14,7 @@ import { executeAfterTransition, getElement } from './util/index.js'
* Constants
*/
const VERSION = '5.3.0'
const VERSION = '5.3.1'
/**
* Class definition

View file

@ -30,6 +30,8 @@ const ARROW_LEFT_KEY = 'ArrowLeft'
const ARROW_RIGHT_KEY = 'ArrowRight'
const ARROW_UP_KEY = 'ArrowUp'
const ARROW_DOWN_KEY = 'ArrowDown'
const HOME_KEY = 'Home'
const END_KEY = 'End'
const CLASS_NAME_ACTIVE = 'active'
const CLASS_NAME_FADE = 'fade'
@ -151,14 +153,22 @@ class Tab extends BaseComponent {
}
_keydown(event) {
if (!([ARROW_LEFT_KEY, ARROW_RIGHT_KEY, ARROW_UP_KEY, ARROW_DOWN_KEY].includes(event.key))) {
if (!([ARROW_LEFT_KEY, ARROW_RIGHT_KEY, ARROW_UP_KEY, ARROW_DOWN_KEY, HOME_KEY, END_KEY].includes(event.key))) {
return
}
event.stopPropagation()// stopPropagation/preventDefault both added to support up/down keys without scrolling the page
event.preventDefault()
const isNext = [ARROW_RIGHT_KEY, ARROW_DOWN_KEY].includes(event.key)
const nextActiveElement = getNextActiveElement(this._getChildren().filter(element => !isDisabled(element)), event.target, isNext, true)
const children = this._getChildren().filter(element => !isDisabled(element))
let nextActiveElement
if ([HOME_KEY, END_KEY].includes(event.key)) {
nextActiveElement = children[event.key === HOME_KEY ? 0 : children.length - 1]
} else {
const isNext = [ARROW_RIGHT_KEY, ARROW_DOWN_KEY].includes(event.key)
nextActiveElement = getNextActiveElement(children, event.target, isNext, true)
}
if (nextActiveElement) {
nextActiveElement.focus({ preventScroll: true })

View file

@ -630,6 +630,58 @@ describe('Tab', () => {
expect(spyPrevent).toHaveBeenCalledTimes(2)
})
it('if keydown event is Home, handle it', () => {
fixtureEl.innerHTML = [
'<div class="nav">',
' <span id="tab1" class="nav-link" data-bs-toggle="tab"></span>',
' <span id="tab2" class="nav-link" data-bs-toggle="tab"></span>',
' <span id="tab3" class="nav-link" data-bs-toggle="tab"></span>',
'</div>'
].join('')
const tabEl1 = fixtureEl.querySelector('#tab1')
const tabEl3 = fixtureEl.querySelector('#tab3')
const tab3 = new Tab(tabEl3)
tab3.show()
const spyShown = jasmine.createSpy()
tabEl1.addEventListener('shown.bs.tab', spyShown)
const keydown = createEvent('keydown')
keydown.key = 'Home'
tabEl3.dispatchEvent(keydown)
expect(spyShown).toHaveBeenCalled()
})
it('if keydown event is End, handle it', () => {
fixtureEl.innerHTML = [
'<div class="nav">',
' <span id="tab1" class="nav-link" data-bs-toggle="tab"></span>',
' <span id="tab2" class="nav-link" data-bs-toggle="tab"></span>',
' <span id="tab3" class="nav-link" data-bs-toggle="tab"></span>',
'</div>'
].join('')
const tabEl1 = fixtureEl.querySelector('#tab1')
const tabEl3 = fixtureEl.querySelector('#tab3')
const tab1 = new Tab(tabEl1)
tab1.show()
const spyShown = jasmine.createSpy()
tabEl3.addEventListener('shown.bs.tab', spyShown)
const keydown = createEvent('keydown')
keydown.key = 'End'
tabEl1.dispatchEvent(keydown)
expect(spyShown).toHaveBeenCalled()
})
it('if keydown event is right arrow and next element is disabled', () => {
fixtureEl.innerHTML = [
'<div class="nav">',
@ -711,6 +763,66 @@ describe('Tab', () => {
expect(spyFocus2).not.toHaveBeenCalled()
expect(spyFocus1).toHaveBeenCalledTimes(1)
})
it('if keydown event is Home and first element is disabled', () => {
fixtureEl.innerHTML = [
'<div class="nav">',
' <span id="tab1" class="nav-link disabled" data-bs-toggle="tab" disabled></span>',
' <span id="tab2" class="nav-link" data-bs-toggle="tab"></span>',
' <span id="tab3" class="nav-link" data-bs-toggle="tab"></span>',
'</div>'
].join('')
const tabEl1 = fixtureEl.querySelector('#tab1')
const tabEl2 = fixtureEl.querySelector('#tab2')
const tabEl3 = fixtureEl.querySelector('#tab3')
const tab3 = new Tab(tabEl3)
tab3.show()
const spyShown1 = jasmine.createSpy()
const spyShown2 = jasmine.createSpy()
tabEl1.addEventListener('shown.bs.tab', spyShown1)
tabEl2.addEventListener('shown.bs.tab', spyShown2)
const keydown = createEvent('keydown')
keydown.key = 'Home'
tabEl3.dispatchEvent(keydown)
expect(spyShown1).not.toHaveBeenCalled()
expect(spyShown2).toHaveBeenCalled()
})
it('if keydown event is End and last element is disabled', () => {
fixtureEl.innerHTML = [
'<div class="nav">',
' <span id="tab1" class="nav-link" data-bs-toggle="tab"></span>',
' <span id="tab2" class="nav-link" data-bs-toggle="tab"></span>',
' <span id="tab3" class="nav-link" data-bs-toggle="tab" disabled></span>',
'</div>'
].join('')
const tabEl1 = fixtureEl.querySelector('#tab1')
const tabEl2 = fixtureEl.querySelector('#tab2')
const tabEl3 = fixtureEl.querySelector('#tab3')
const tab1 = new Tab(tabEl1)
tab1.show()
const spyShown2 = jasmine.createSpy()
const spyShown3 = jasmine.createSpy()
tabEl2.addEventListener('shown.bs.tab', spyShown2)
tabEl3.addEventListener('shown.bs.tab', spyShown3)
const keydown = createEvent('keydown')
keydown.key = 'End'
tabEl1.dispatchEvent(keydown)
expect(spyShown3).not.toHaveBeenCalled()
expect(spyShown2).toHaveBeenCalled()
})
})
describe('jQueryInterface', () => {

View file

@ -161,12 +161,12 @@
<h4>Tabs with nav and using links (with fade)</h4>
<nav>
<div class="nav nav-pills" id="nav-tab" role="tablist">
<div class="nav nav-pills" id="nav-tab" role="tablist">
<a class="nav-link nav-item active" role="tab" data-bs-toggle="tab" href="#home5">Home</a>
<a class="nav-link nav-item" role="tab" data-bs-toggle="tab" href="#profile5">Profile</a>
<a class="nav-link nav-item" role="tab" data-bs-toggle="tab" href="#fat5">@fat</a>
<a class="nav-link nav-item" role="tab" data-bs-toggle="tab" href="#mdo5">@mdo</a>
<a class="nav-link nav-item disabled" role="tab" href="#">Disabled</a>
<a class="nav-link nav-item disabled" role="tab" href="#" aria-disabled="true">Disabled</a>
</div>
</nav>