mirror of
https://github.com/twbs/bootstrap.git
synced 2025-01-18 10:52:19 +01:00
This commit is contained in:
parent
e81e7cda90
commit
ef4e2daa48
@ -38,7 +38,7 @@
|
||||
},
|
||||
{
|
||||
"path": "./dist/js/bootstrap.bundle.min.js",
|
||||
"maxSize": "22.75 kB"
|
||||
"maxSize": "23.0 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/js/bootstrap.esm.js",
|
||||
|
@ -5,7 +5,7 @@
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
import { isDisabled, isVisible } from '../util/index.js'
|
||||
import { isDisabled, isVisible, parseSelector } from '../util/index.js'
|
||||
|
||||
/**
|
||||
* Constants
|
||||
@ -99,6 +99,7 @@ const SelectorEngine = {
|
||||
}
|
||||
|
||||
selector = hrefAttribute && hrefAttribute !== '#' ? hrefAttribute.trim() : null
|
||||
selector = parseSelector(selector)
|
||||
}
|
||||
|
||||
return selector
|
||||
|
@ -9,6 +9,20 @@ const MAX_UID = 1_000_000
|
||||
const MILLISECONDS_MULTIPLIER = 1000
|
||||
const TRANSITION_END = 'transitionend'
|
||||
|
||||
/**
|
||||
* Properly escape IDs selectors to handle weird IDs
|
||||
* @param {string} selector
|
||||
* @returns {string}
|
||||
*/
|
||||
const parseSelector = selector => {
|
||||
if (selector && window.CSS && window.CSS.escape) {
|
||||
// document.querySelector needs escaping to handle IDs (html5+) containing for instance /
|
||||
selector = selector.replaceAll(/#([^\s"#']+)/g, (match, id) => '#' + CSS.escape(id))
|
||||
}
|
||||
|
||||
return selector
|
||||
}
|
||||
|
||||
// Shout-out Angus Croll (https://goo.gl/pxwQGp)
|
||||
const toType = object => {
|
||||
if (object === null || object === undefined) {
|
||||
@ -76,7 +90,7 @@ const getElement = object => {
|
||||
}
|
||||
|
||||
if (typeof object === 'string' && object.length > 0) {
|
||||
return document.querySelector(object)
|
||||
return document.querySelector(parseSelector(object))
|
||||
}
|
||||
|
||||
return null
|
||||
@ -285,6 +299,7 @@ export {
|
||||
isVisible,
|
||||
noop,
|
||||
onDOMContentLoaded,
|
||||
parseSelector,
|
||||
reflow,
|
||||
triggerTransitionEnd,
|
||||
toType
|
||||
|
@ -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')
|
||||
|
@ -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>'
|
||||
|
Loading…
x
Reference in New Issue
Block a user