Skip to content

Commit

Permalink
Merge pull request #125 from camchenry/master
Browse files Browse the repository at this point in the history
Implement correct `:disabled` support for fieldsets and nested form controls
  • Loading branch information
dperini authored Sep 27, 2024
2 parents 088475f + b3cfd88 commit f93dae4
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 4 deletions.
29 changes: 25 additions & 4 deletions src/nwsapi.js
Original file line number Diff line number Diff line change
Expand Up @@ -1123,10 +1123,31 @@
')){' + source + '}';
break;
case 'disabled':
// https://www.w3.org/TR/html5/forms.html#enabling-and-disabling-form-controls:-the-disabled-attribute
source = 'if((("form" in e||/^optgroup$/i.test(e.localName))&&"disabled" in e&&' +
'(e.disabled===true||(n=s.ancestor("fieldset",e))&&(n=s.first("legend",n))&&!n.contains(e))' +
')){' + source + '}';
// https://html.spec.whatwg.org/#enabling-and-disabling-form-controls:-the-disabled-attribute
source = 'if((("form" in e||/^optgroup$/i.test(e.localName))&&"disabled" in e)){' +
// F is true if any of the fieldset elements in the ancestry chain has the disabled attribute specified
// L is true if the first legend element of the fieldset contains the element
'var x=0,N=[],F=false,L=false;' +
'if(!(/^(optgroup|option)$/i.test(e.localName))){' +
'n=e.parentElement;' +
'while(n){' +
'if(n.localName=="fieldset"){' +
'N[x++]=n;' +
'if(n.disabled===true){' +
'F=true;' +
'break;' +
'}' +
'}' +
'n=n.parentElement;' +
'}' +
'for(var x=0;x<N.length;x++){' +
'if((n=s.first("legend",N[x]))&&n.contains(e)){' +
'L=true;' +
'break;' +
'}' +
'}' +
'}' +
'if(e.disabled===true||(F&&!L)){' + source + '}}';
break;
case 'read-only':
source =
Expand Down
20 changes: 20 additions & 0 deletions test/w3c/html/semantics/selectors/pseudo-classes/disabled.html
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,24 @@
var input = document.createElement("input");
input.setAttribute("disabled", "disabled");
testSelectorIdsMatch(":disabled", ["button1", "input2", "select2", "optgroup2", "option2", "textarea2", "fieldset2", "clubname", "clubnum"], "':disabled' should not match elements not in the document");

var fieldset = document.createElement("fieldset");
fieldset.id = "fieldset_nested";
fieldset.innerHTML = `
<input id=input_nested>
<button id=button_nested>button nested</button>
<select id=select_nested>
<optgroup label="options" id=optgroup_nested>
<option value="options" id=option_nested>option nested</option>
</optgroup>
</select>
<textarea id=textarea_nested>textarea nested</textarea>
<object id=object_nested></object>
<output id=output_nested></output>
<fieldset id=fieldset_nested2>
<input id=input_nested2>
</fieldset>
`;
document.getElementById("fieldset2").appendChild(fieldset);
testSelectorIdsMatch("#fieldset2 :disabled", ["clubname", "clubnum", "fieldset_nested", "input_nested", "button_nested", "select_nested", "textarea_nested", "fieldset_nested2", "input_nested2"], "':disabled' should match elements that are appended to a disabled fieldset dynamically");
</script>

0 comments on commit f93dae4

Please sign in to comment.