-
Notifications
You must be signed in to change notification settings - Fork 252
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: check for inherited
:disabled
(#872)
- Loading branch information
1 parent
75fdd44
commit 1a00fdf
Showing
2 changed files
with
108 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,37 @@ | ||
// This should probably be extended with checking the element type | ||
// https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/disabled | ||
import {isElementType} from './isElementType' | ||
|
||
// This should probably just rely on the :disabled pseudo-class, but JSDOM doesn't implement it properly. | ||
export function isDisabled(element: Element | null): boolean { | ||
return Boolean(element && (element as {disabled?: boolean}).disabled) | ||
for (let el = element; el; el = el.parentElement) { | ||
if ( | ||
isElementType(el, [ | ||
'button', | ||
'input', | ||
'select', | ||
'textarea', | ||
'optgroup', | ||
'option', | ||
]) | ||
) { | ||
if (el.hasAttribute('disabled')) { | ||
return true | ||
} | ||
} else if (isElementType(el, 'fieldset')) { | ||
if ( | ||
el.hasAttribute('disabled') && | ||
!el.querySelector(':scope > legend')?.contains(element) | ||
) { | ||
return true | ||
} | ||
} else if (el.tagName.includes('-')) { | ||
if ( | ||
(el.constructor as {formAssociated?: boolean}).formAssociated && | ||
el.hasAttribute('disabled') | ||
) { | ||
return true | ||
} | ||
} | ||
} | ||
|
||
return false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import cases from 'jest-in-case' | ||
import {isDisabled} from '#src/utils' | ||
import {render} from '#testHelpers' | ||
|
||
customElements.define( | ||
'form-associated', | ||
class FormAssociated extends HTMLElement { | ||
static formAssociated = true | ||
get disabled() { | ||
return this.hasAttribute('disabled') | ||
} | ||
}, | ||
) | ||
|
||
customElements.define( | ||
'custom-el', | ||
class CustomEl extends HTMLElement { | ||
get disabled() { | ||
return this.hasAttribute('disabled') | ||
} | ||
}, | ||
) | ||
|
||
// https://html.spec.whatwg.org/multipage/semantics-other.html#disabled-elements | ||
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#enabling-and-disabling-form-controls:-the-disabled-attribute | ||
cases( | ||
'check if element is disabled', | ||
({html, node = '//input', expected = true}) => { | ||
const {xpathNode} = render(html) | ||
expect(isDisabled(xpathNode<Element>(node))).toBe(expected) | ||
}, | ||
{ | ||
control: { | ||
html: `<input/>`, | ||
expected: false, | ||
}, | ||
'disabled control': { | ||
html: `<input disabled/>`, | ||
}, | ||
'control in disabled fieldset': { | ||
html: `<fieldset disabled><input/></fieldset>`, | ||
}, | ||
'control in first legend of disabled fieldset': { | ||
html: `<fieldset disabled><legend><input/></legend></fieldset>`, | ||
expected: false, | ||
}, | ||
'control in other legend of disabled fieldset': { | ||
html: `<fieldset disabled><legend></legend><legend><input/></legend></fieldset>`, | ||
}, | ||
'control in nested legend of disabled fieldset': { | ||
html: `<fieldset disabled><div>><legend><input/></legend></div></fieldset>`, | ||
}, | ||
'element without support for disabled': { | ||
html: `<div disabled></div>`, | ||
node: '*', | ||
expected: false, | ||
}, | ||
'form-associated disabled custom element': { | ||
html: `<form-associated disabled></form-associated>`, | ||
node: '*', | ||
}, | ||
'form-associated enabled custom element': { | ||
html: `<form-associated></form-associated>`, | ||
node: '*', | ||
expected: false, | ||
}, | ||
'other custom element': { | ||
html: `<custom-el disabled></custom-el>`, | ||
node: '*', | ||
expected: false, | ||
}, | ||
}, | ||
) |