Skip to main content

Bug Tracker

Side navigation

#5832 closed bug (duplicate)

Opened January 15, 2010 10:09PM UTC

Closed October 19, 2010 01:11AM UTC

Last modified October 19, 2010 01:11AM UTC

Webkit radio input Node.cloneNode-related regression in jQuery 1.4 (patch and test included)

Reported by: mmonteleone Owned by:
Priority: major Milestone: 1.4.1
Component: core Version: 1.4
Keywords: cache cloneNode webkit radio input Cc:
Blocked by: Blocking:
Description

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 -->

<script type="text/javascript" src="jquery-1.3.2.js"></script>

<script type="text/javascript">jq13 = jQuery.noConflict()</script>

<!-- load jquery 1.4 -->

<script type="text/javascript" src="jquery-1.4.js"></script>

<script type="text/javascript">jq14 = jQuery.noConflict()</script>

<script type="text/javascript">

jq14(function(){

// 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'));

});

</script>

<body>

<form></form>

</body>

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/Node.cloneNode.

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.

http://github.com/mmonteleone/jquery/commit/60c28596fb1dbce44bf464435d31cc2faa2c1e09

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.

Michael Monteleone

(michael@michaelmonteleone.net)

Attachments (0)
Change History (3)

Changed January 26, 2010 02:00AM UTC by mmonteleone comment:1

Re-mentioned and resolved in #5929

Changed October 19, 2010 01:11AM UTC by snover comment:2

resolution: → duplicate
status: newclosed

Changed October 19, 2010 01:11AM UTC by snover comment:3

Duplicate of #5929.