Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/twbs/bootstrap.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/js
diff options
context:
space:
mode:
authorGeoSot <geo.sotis@gmail.com>2021-04-20 08:26:58 +0300
committerGitHub <noreply@github.com>2021-04-20 08:26:58 +0300
commit0bbe45cd977ae69f11b4cdd55e5d5be08e4a137a (patch)
tree3a66a5e3d2e88baa8cc0298a00b569df972c9b69 /js
parentb59b75bc55ad9d5d2d0259f6b3364a7bcb82b033 (diff)
Tab.js: Fixes on click handling (#33586)
* use prevent default only if triggered by anchor * disable auto-initialization if trigger is disabled
Diffstat (limited to 'js')
-rw-r--r--js/src/tab.js11
-rw-r--r--js/tests/unit/tab.spec.js121
2 files changed, 77 insertions, 55 deletions
diff --git a/js/src/tab.js b/js/src/tab.js
index ffca5f299e..4d823cc61c 100644
--- a/js/src/tab.js
+++ b/js/src/tab.js
@@ -66,8 +66,7 @@ class Tab extends BaseComponent {
show() {
if ((this._element.parentNode &&
this._element.parentNode.nodeType === Node.ELEMENT_NODE &&
- this._element.classList.contains(CLASS_NAME_ACTIVE)) ||
- isDisabled(this._element)) {
+ this._element.classList.contains(CLASS_NAME_ACTIVE))) {
return
}
@@ -202,7 +201,13 @@ class Tab extends BaseComponent {
*/
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
- event.preventDefault()
+ if (['A', 'AREA'].includes(this.tagName)) {
+ event.preventDefault()
+ }
+
+ if (isDisabled(this)) {
+ return
+ }
const data = Data.get(this, DATA_KEY) || new Tab(this)
data.show()
diff --git a/js/tests/unit/tab.spec.js b/js/tests/unit/tab.spec.js
index 5b98bad9d5..4741b495de 100644
--- a/js/tests/unit/tab.spec.js
+++ b/js/tests/unit/tab.spec.js
@@ -198,58 +198,6 @@ describe('Tab', () => {
}, 30)
})
- it('should not fire shown when tab has disabled attribute', done => {
- fixtureEl.innerHTML = [
- '<ul class="nav nav-tabs" role="tablist">',
- ' <li class="nav-item" role="presentation"><button type="button" data-bs-target="#home" class="nav-link active" role="tab" aria-selected="true">Home</button></li>',
- ' <li class="nav-item" role="presentation"><button type="button" data-bs-target="#profile" class="nav-link" disabled role="tab">Profile</button></li>',
- '</ul>',
- '<div class="tab-content">',
- ' <div class="tab-pane active" id="home" role="tabpanel"></div>',
- ' <div class="tab-pane" id="profile" role="tabpanel"></div>',
- '</div>'
- ].join('')
-
- const triggerDisabled = fixtureEl.querySelector('button[disabled]')
- const tab = new Tab(triggerDisabled)
-
- triggerDisabled.addEventListener('shown.bs.tab', () => {
- throw new Error('should not trigger shown event')
- })
-
- tab.show()
- setTimeout(() => {
- expect().nothing()
- done()
- }, 30)
- })
-
- it('should not fire shown when tab has disabled class', done => {
- fixtureEl.innerHTML = [
- '<ul class="nav nav-tabs" role="tablist">',
- ' <li class="nav-item" role="presentation"><a href="#home" class="nav-link active" role="tab" aria-selected="true">Home</a></li>',
- ' <li class="nav-item" role="presentation"><a href="#profile" class="nav-link disabled" role="tab">Profile</a></li>',
- '</ul>',
- '<div class="tab-content">',
- ' <div class="tab-pane active" id="home" role="tabpanel"></div>',
- ' <div class="tab-pane" id="profile" role="tabpanel"></div>',
- '</div>'
- ].join('')
-
- const triggerDisabled = fixtureEl.querySelector('a.disabled')
- const tab = new Tab(triggerDisabled)
-
- triggerDisabled.addEventListener('shown.bs.tab', () => {
- throw new Error('should not trigger shown event')
- })
-
- tab.show()
- setTimeout(() => {
- expect().nothing()
- done()
- }, 30)
- })
-
it('show and shown events should reference correct relatedTarget', done => {
fixtureEl.innerHTML = [
'<ul class="nav nav-tabs" role="tablist">',
@@ -695,5 +643,74 @@ describe('Tab', () => {
secondNavEl.click()
})
+
+ it('should prevent default when the trigger is <a> or <area>', done => {
+ fixtureEl.innerHTML = [
+ '<ul class="nav" role="tablist">',
+ ' <li><a type="button" href="#test" class="active" role="tab" data-bs-toggle="tab">Home</a></li>',
+ ' <li><a type="button" href="#test2" role="tab" data-bs-toggle="tab">Home</a></li>',
+ '</ul>'
+ ].join('')
+
+ const tabEl = fixtureEl.querySelector('[href="#test2"]')
+ spyOn(Event.prototype, 'preventDefault').and.callThrough()
+
+ tabEl.addEventListener('shown.bs.tab', () => {
+ expect(tabEl.classList.contains('active')).toEqual(true)
+ expect(Event.prototype.preventDefault).toHaveBeenCalled()
+ done()
+ })
+
+ tabEl.click()
+ })
+
+ it('should not fire shown when tab has disabled attribute', done => {
+ fixtureEl.innerHTML = [
+ '<ul class="nav nav-tabs" role="tablist">',
+ ' <li class="nav-item" role="presentation"><button type="button" data-bs-target="#home" class="nav-link active" role="tab" aria-selected="true">Home</button></li>',
+ ' <li class="nav-item" role="presentation"><button type="button" data-bs-target="#profile" class="nav-link" disabled role="tab">Profile</button></li>',
+ '</ul>',
+ '<div class="tab-content">',
+ ' <div class="tab-pane active" id="home" role="tabpanel"></div>',
+ ' <div class="tab-pane" id="profile" role="tabpanel"></div>',
+ '</div>'
+ ].join('')
+
+ const triggerDisabled = fixtureEl.querySelector('button[disabled]')
+ triggerDisabled.addEventListener('shown.bs.tab', () => {
+ throw new Error('should not trigger shown event')
+ })
+
+ triggerDisabled.click()
+ setTimeout(() => {
+ expect().nothing()
+ done()
+ }, 30)
+ })
+
+ it('should not fire shown when tab has disabled class', done => {
+ fixtureEl.innerHTML = [
+ '<ul class="nav nav-tabs" role="tablist">',
+ ' <li class="nav-item" role="presentation"><a href="#home" class="nav-link active" role="tab" aria-selected="true">Home</a></li>',
+ ' <li class="nav-item" role="presentation"><a href="#profile" class="nav-link disabled" role="tab">Profile</a></li>',
+ '</ul>',
+ '<div class="tab-content">',
+ ' <div class="tab-pane active" id="home" role="tabpanel"></div>',
+ ' <div class="tab-pane" id="profile" role="tabpanel"></div>',
+ '</div>'
+ ].join('')
+
+ const triggerDisabled = fixtureEl.querySelector('a.disabled')
+
+ triggerDisabled.addEventListener('shown.bs.tab', () => {
+ throw new Error('should not trigger shown event')
+ })
+
+ triggerDisabled.click()
+ setTimeout(() => {
+ expect().nothing()
+ done()
+ }, 30)
+ })
})
})