I am truly impressed with the quality of significant optimizations in the recent jQuery 1.4 release. The use of fragment caching in conjunction with browser-native
Node.cloneNode for small strings passed to $('...') is quite clever.
I apologize for not noticing this earlier a, but it seems perhaps the use of
Node.cloneNode has exposed at least one browser-specific implementation bug causing a regression.
Unlike other engines, Webkit's
Node.cloneNode seems to not clone the 'checked' attribute of radio inputs. It does clone the
checked attribute of checkbox inputs. This means that code that used to work fine, like...
$('form').append('<input type="radio" checked="checked" />');
...no longer checks the input in Webkit for jQuery 1.4, since this fragment is otherwise small enough to hit the fragment cache and be subsequently cloned, and Webkit does not clone the
checked attribute on radio inputs.
Here is code to reproduce in Webkit:
<!-- load jquery 1.3 -->
<!-- load jquery 1.4 -->
// in jQuery 1.3, this works fine
jq13('form').append('<input type="radio" id="r1" name="r1" value="r1val" checked="checked" />');
alert('1.3 - should be true: ' + jq13('#r1').is(':checked'));
in jQuery 1.4, the fragment cache means that the new node gets cached, and then cloned
via Node.cloneNode. Webkit will not honor the 'checked' attribute during cloning
// Oddly enough, it would have honored a checkbox's
jq14('form').append('<input type="radio" id="r2" name="r2" value="r1val" checked="checked" />');
alert('1.4 - this is now false: ' + jq14('#r2').is(':checked'));
And here is a live running sample: http://michaelmonteleone.net/files/jq14webkit/
So, this isn't technically a jQuery issue as much it is a Webkit one, except for the fact that these kinds of operations always worked before in jQuery before the advent of the fragment cache/
I have prepared a small patch to address this within the
buildFragment function by adding another clause to the end of the if branch where it determines whether the fragment should be cacheable (and thus cloned). It's inspecting the fragment via a regex for the presence of various forms of checked="checked", and considering if matches exist. Unit tests are included.
To be fully correct, the if statement should probably also check for jQuery.browser.webkit and a more precise regular expression that specifically matches only radio inputs, but I was concerned this would add too much overhead for such a commonly used function.
I recognize there is probably a much more elegant and efficient way of solving this problem!
Thank you for another fantastic release of a fantastic framework.