1
0
mirror of https://github.com/twbs/bootstrap.git synced 2025-08-09 23:26:40 +02:00

prev() function fails when non-element nodes are present (#30117)

The `prev()` function doesn't take nodes other than elements into account. Also we could simplify things a lot using the `previousElementSibling` property. This property isn't fully supported in IE, it only works for elements, but since the `element` variable is an element, we can safely use it here.

I've also added an additional test.

I don't think we had this issue in v4, since we relied on jQuery back then.

Ref. https://developer.mozilla.org/en-US/docs/Web/API/NonDocumentTypeChildNode/nextElementSibling
This commit is contained in:
Martijn Cuppens
2020-03-09 16:21:04 +01:00
committed by GitHub
parent 14c4a601fe
commit 7d8c7c4ba8
2 changed files with 20 additions and 7 deletions

View File

@@ -56,19 +56,17 @@ const SelectorEngine = {
}, },
prev(element, selector) { prev(element, selector) {
const siblings = [] let previous = element.previousElementSibling
let previous = element.previousSibling while (previous) {
while (previous && previous.nodeType === Node.ELEMENT_NODE && previous.nodeType !== NODE_TEXT) {
if (this.matches(previous, selector)) { if (this.matches(previous, selector)) {
siblings.push(previous) return [previous]
} }
previous = previous.previousSibling previous = previous.previousElementSibling
} }
return siblings return []
} }
} }

View File

@@ -110,6 +110,21 @@ describe('SelectorEngine', () => {
expect(SelectorEngine.prev(btn, '.test')).toEqual([divTest]) expect(SelectorEngine.prev(btn, '.test')).toEqual([divTest])
}) })
it('should return previous element with comments or text nodes between', () => {
fixtureEl.innerHTML = [
'<div class="test"></div>',
'<div class="test"></div>',
'<!-- Comment-->',
'Text',
'<button class="btn"></button>'
].join('')
const btn = fixtureEl.querySelector('.btn')
const divTest = fixtureEl.querySelectorAll('.test')[1]
expect(SelectorEngine.prev(btn, '.test')).toEqual([divTest])
})
}) })
}) })