mirror of
https://github.com/twbs/bootstrap.git
synced 2025-10-03 00:03:44 -04:00
Compare commits
4 Commits
32ab9f68a7
...
eb8bc74c40
Author | SHA1 | Date | |
---|---|---|---|
|
eb8bc74c40 | ||
|
e0d1dad9ca | ||
|
588cf7e5fc | ||
|
f84bf47e1a |
@ -9,7 +9,7 @@ import BaseComponent from './base-component.js'
|
|||||||
import EventHandler from './dom/event-handler.js'
|
import EventHandler from './dom/event-handler.js'
|
||||||
import SelectorEngine from './dom/selector-engine.js'
|
import SelectorEngine from './dom/selector-engine.js'
|
||||||
import {
|
import {
|
||||||
defineJQueryPlugin, getElement, isDisabled, isVisible
|
defineJQueryPlugin, getElement, isDisabled, isVisible, parseSelector
|
||||||
} from './util/index.js'
|
} from './util/index.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -210,11 +210,13 @@ class ScrollSpy extends BaseComponent {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
const observableSection = SelectorEngine.findOne(decodeURI(anchor.hash), this._element)
|
const withDecodeUri = decodeURI(anchor.hash)
|
||||||
|
const withEscape = parseSelector(withDecodeUri)
|
||||||
|
const observableSection = SelectorEngine.findOne(withEscape, this._element)
|
||||||
|
|
||||||
// ensure that the observableSection exists & is visible
|
// ensure that the observableSection exists & is visible
|
||||||
if (isVisible(observableSection)) {
|
if (isVisible(observableSection)) {
|
||||||
this._targetLinks.set(decodeURI(anchor.hash), anchor)
|
this._targetLinks.set(withDecodeUri, anchor)
|
||||||
this._observableSections.set(anchor.hash, observableSection)
|
this._observableSections.set(anchor.hash, observableSection)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ const TRANSITION_END = 'transitionend'
|
|||||||
const parseSelector = selector => {
|
const parseSelector = selector => {
|
||||||
if (selector && window.CSS && window.CSS.escape) {
|
if (selector && window.CSS && window.CSS.escape) {
|
||||||
// document.querySelector needs escaping to handle IDs (html5+) containing for instance /
|
// document.querySelector needs escaping to handle IDs (html5+) containing for instance /
|
||||||
selector = selector.replace(/#([^\s"#']+)/g, (match, id) => `#${CSS.escape(id)}`)
|
selector = selector.replace(/#([^\s"']+)/g, (match, id) => `#${CSS.escape(id)}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
return selector
|
return selector
|
||||||
|
@ -194,6 +194,34 @@ describe('ScrollSpy', () => {
|
|||||||
expect(scrollSpy._targetLinks.size).toBe(1)
|
expect(scrollSpy._targetLinks.size).toBe(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should take account of escaped IDs', () => {
|
||||||
|
fixtureEl.innerHTML = [
|
||||||
|
'<nav id="navigation" class="navbar">',
|
||||||
|
' <ul class="navbar-nav">',
|
||||||
|
' <li class="nav-item"><a class="nav-link active" id="one-link" href="#div-2.1">One</a></li>',
|
||||||
|
' <li class="nav-item"><a class="nav-link" id="two-link" href="#!@#$_^&*()">Two</a></li>',
|
||||||
|
' <li class="nav-item"><a class="nav-link" id="three-link" href="#id.div.Element@data-custom=true">Three</a></li>',
|
||||||
|
' <li class="nav-item"><a class="nav-link" id="four-link" href="#https://domain.to/#%2F%40user%3Aname.test">Four</a></li>',
|
||||||
|
' <li class="nav-item"><a class="nav-link" id="five-link" href="#https://domain.to/#/@user:name.test">Five</a></li>',
|
||||||
|
' </ul>',
|
||||||
|
'</nav>',
|
||||||
|
'<div id="content" style="height: 200px; overflow-y: auto;">',
|
||||||
|
' <div id="div-2.1" style="height: 300px;">test</div>',
|
||||||
|
' <div id="!@#$_^&*()" style="height: 300px;">test</div>',
|
||||||
|
' <div id="id.div.Element@data-custom=true" style="height: 300px;">test</div>',
|
||||||
|
' <div id="https://domain.to/#%2F%40user%3Aname.test" style="height: 300px;">test</div>',
|
||||||
|
' <div id="https://domain.to/#/@user:name.test">test</div>',
|
||||||
|
'</div>'
|
||||||
|
].join('')
|
||||||
|
|
||||||
|
const scrollSpy = new ScrollSpy(fixtureEl.querySelector('#content'), {
|
||||||
|
target: '#navigation'
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(scrollSpy._observableSections.size).toBe(5)
|
||||||
|
expect(scrollSpy._targetLinks.size).toBe(5)
|
||||||
|
})
|
||||||
|
|
||||||
it('should not process element without target', () => {
|
it('should not process element without target', () => {
|
||||||
fixtureEl.innerHTML = [
|
fixtureEl.innerHTML = [
|
||||||
'<nav id="navigation" class="navbar">',
|
'<nav id="navigation" class="navbar">',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user