0
0
mirror of https://github.com/twbs/bootstrap.git synced 2024-12-01 13:24:25 +01:00

Refactor isVisible helper, fixing false positives from deep nesting or alternate means (#33960)

This commit is contained in:
Ryan Berliner 2021-05-20 09:50:53 -04:00 committed by GitHub
parent 79c3bf47bc
commit 4ac711b5b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 13 deletions

View File

@ -159,20 +159,11 @@ const typeCheckConfig = (componentName, config, configTypes) => {
}
const isVisible = element => {
if (!element) {
if (!isElement(element) || element.getClientRects().length === 0) {
return false
}
if (element.style && element.parentNode && element.parentNode.style) {
const elementStyle = getComputedStyle(element)
const parentNodeStyle = getComputedStyle(element.parentNode)
return elementStyle.display !== 'none' &&
parentNodeStyle.display !== 'none' &&
elementStyle.visibility !== 'hidden'
}
return false
return getComputedStyle(element).getPropertyValue('visibility') === 'visible'
}
const isDisabled = element => {

View File

@ -326,10 +326,14 @@ describe('Util', () => {
expect(Util.isVisible(div)).toEqual(false)
})
it('should return false if the parent element is not visible', () => {
it('should return false if an ancestor element is display none', () => {
fixtureEl.innerHTML = [
'<div style="display: none;">',
' <div class="content"></div>',
' <div>',
' <div>',
' <div class="content"></div>',
' </div>',
' </div>',
'</div>'
].join('')
@ -338,6 +342,38 @@ describe('Util', () => {
expect(Util.isVisible(div)).toEqual(false)
})
it('should return false if an ancestor element is visibility hidden', () => {
fixtureEl.innerHTML = [
'<div style="visibility: hidden;">',
' <div>',
' <div>',
' <div class="content"></div>',
' </div>',
' </div>',
'</div>'
].join('')
const div = fixtureEl.querySelector('.content')
expect(Util.isVisible(div)).toEqual(false)
})
it('should return true if an ancestor element is visibility hidden, but reverted', () => {
fixtureEl.innerHTML = [
'<div style="visibility: hidden;">',
' <div style="visibility: visible;">',
' <div>',
' <div class="content"></div>',
' </div>',
' </div>',
'</div>'
].join('')
const div = fixtureEl.querySelector('.content')
expect(Util.isVisible(div)).toEqual(true)
})
it('should return true if the element is visible', () => {
fixtureEl.innerHTML = [
'<div>',
@ -349,6 +385,18 @@ describe('Util', () => {
expect(Util.isVisible(div)).toEqual(true)
})
it('should return false if the element is hidden, but not via display or visibility', () => {
fixtureEl.innerHTML = [
'<details>',
' <div id="element"></div>',
'</details>'
].join('')
const div = fixtureEl.querySelector('#element')
expect(Util.isVisible(div)).toEqual(false)
})
})
describe('isDisabled', () => {