Also note that :enabled and :disabled can only match elements from exactly the same set, which includes three that aren't listed form-associated elements and don't have form IDL attributes: <optgroup>, <option>, and <menuitem>. All three have label IDL attributes (as do the non-disableable <menu> and <track>), but none of them need to consider ancestor fieldsets (although <option> does need to consider parent <optgroup>).
The bottom line is that boolean disabled is a good indicator, excepting two special cases where an element can match :disabled instead of :enabled despite having .disabled === false:
<option> (the only element having both label and form IDL attributes) with a disabled parent <optgroup> (which also has label)
an element with both form IDL attribute and a disabled fieldset ancestor whose legend is not also an ancestor
It is interesting to observe that special processing is required if and only if disabled is false and form exists. I think the resulting logic will look like
// Only certain elements can match :enabled or :disabled// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled// Check for inherited disabledness on relevant non-disabled elements:// * listed form-associated elements// https://html.spec.whatwg.org/multipage/forms.html#category-listed// * option elements// https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabledreturn"form"in elem &&elem.disabled===false?// Support: IE 6 - 11// Use the shortcut property, which already covers inheritanceelem.isDisabled=== disabled ||elem.isDisabled!==!disabled && ("label"in elem ?// Option elements defer to a parent optgroup if present
(elem.parentNode&&"label"inelem.parentNode?elem.parentNode.disabled=== disabled :elem.disabled=== disabled) :// All others defer to ancestor fieldsets if presentdisabledAncestor( elem ) === disabled
) :// Check other disableable elements for direct disabledness// Some victims get caught in our net (label, legend, menu, track),// but they shouldn't have the property anyway."form"in elem &&elem.disabled=== disabled ||"label"in elem &&elem.disabled=== disabled;
gibson042
added a commit
to gibson042/sizzle
that referenced
this issue
Jul 30, 2016
Ref jquery/jquery#3224
Ref 7999a01
Include citations to:
<label>and<option>and<legend>also haveformIDL attributes).Also note that
:enabledand:disabledcan only match elements from exactly the same set, which includes three that aren't listed form-associated elements and don't haveformIDL attributes:<optgroup>,<option>, and<menuitem>. All three havelabelIDL attributes (as do the non-disableable<menu>and<track>), but none of them need to consider ancestor fieldsets (although<option>does need to consider parent<optgroup>).The bottom line is that boolean
disabledis a good indicator, excepting two special cases where an element can match:disabledinstead of:enableddespite having.disabled === false:<option>(the only element having bothlabelandformIDL attributes) with a disabled parent<optgroup>(which also haslabel)formIDL attribute and a disabled fieldset ancestor whose legend is not also an ancestorIt is interesting to observe that special processing is required if and only if
disabledisfalseandformexists. I think the resulting logic will look like