A fix for the broken "selected" code in attr()

A fix for the broken "selected" code in attr()

The attr() method contains this spooky code:
// Safari mis-reports the default selected property of a hidden
option
// Accessing the parent's selectedIndex property fixes it
if ( name == "selected" && elem.parentNode ) {
elem.parentNode.selectedIndex;
}
I previously made two points:
1) This code will not work of the <option> is in an <optgroup>
(common)
2) The comment incorrectly identifies the quirk being corrected
After some discussion with colleagues, a better approach has been
identified. However, I would suggest that this simply be removed from
the code. The specs do not demand the behavior being sought after, and
the correct solution to the "problem" would be to simply add a
"selected" attribute to the first <option>.
If you still want this "fix" in there, then I suggest adding this
method:
// Get the true "selected" property of an option.
// Safari mis-reports the selected property of the first (default)
selected
// option in a single-select list, when checked before the window's
onload
// event has fired.
function getOptionSelected(el) {
// Do a feature test to see if the "broken" functionality exists
var s = document.createElement("select");
s.add(new Option("a"));
if (s.options[0].selected) {
// Not broken, so unroll this method to be efficient next time
return (getOptionSelected = function(o) {return o.selected;})(el);
}
s=null;
// If we're getting a false value, it may be that the option
// will be selected when fully rendered, but has not happened yet.
return (getOptionSelected=function(o) {
if (o.selected === false) {
var s=(o.parentNode.tagName=="SELECT")?
o.parentNode:o.parentNode.parentNode;
// Verify selectedIndex because this doesn't apply to multiple-
selects
if (s.selectedIndex>=0) {
s.options[s.selectedIndex].selected=true;
}
}
return o.selected;
})(el);
}
Or you could put it in as jQuery.getOptionSelected, obviously.
Then in attr() replace these lines:
// Safari mis-reports the default selected property of a hidden
option
// Accessing the parent's selectedIndex property fixes it
if ( name == "selected" && elem.parentNode ) {
elem.parentNode.selectedIndex;
}
with these:
if (name=="selected") {
return getOptionSelected(elem);
}
Then you'll have a more robust, feature-tested, efficient, correctly-
documented fix to this "problem".
Again, though, my suggestion is to just remove it. I don't think
generalized library code should try to normalize behavior that is not
demanded by the specs and that can be easily corrected through proper
HTML.
Hope that helps,
Matt Kruse
--