tags:

views:

265

answers:

2

The code here does not return what one expects:

jQuery('<div>Look here: [ jQuery0="null" ]</div>').html()

Rather, you get:

Look here: [ ]

The jQuery source code in question:

html: function( value ) {
        return value === undefined ?
                (this[0] ?
                        this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") :
                        null) :
                this.empty().append( value );
},

What would be the motivation behind the .replace? I do not have time to go over the rest of jQuery, but code like this makes me wonder if I should use jQuery in production at all.

+3  A: 

This code is new in 1.3.2, it wasn't in 1.3.1. It looks to me like jQuery uses attributes whose names start with "jQuery" to store data on elements, and this is its way of not exposing that to you when you ask for the html back.

It clearly isn't a bug. The author intended to remove that HTML before returning you the string.

Does this affect your code? As with any library, you should test your production code thoroughly before deploying it.

Ned Batchelder
Granted, it does not yet affect my code but it breaks the `x.html(y).html() == y` invariant, which rings an alarm bell. Thanks for the info on when this was introduced. You are right, it is not a bug, but a questionable design decision.
toyvo
+6  A: 

What would be the motivation behind the .replace?

To hide attributes that jQuery is using for internal purposes.

code like this makes me wonder if I should use jQuery in production at all.

Yes, I had the exact same reaction. It's just incredibly sloppy. Trying to process HTML with regexp is the kind of naïve hack you expect from first-time question posters, not the sort of behaviour you'd hope to see in the framework so many SO users appear to worship.

It's not the only place where jQuery trips up by trying to parse markup with regex; some of the selector stuff is broken too. These may be obscure corner cases, but to me it's a huge red flag indicative of the wrong approach.

bobince
Incidentally, there's an easy fix for this. IE only includes expando properties in its `innerHTML` serialisation when their values are simple types like `String` and `Number`. Other Objects such as Array do not show up. So all jQuery needs to do is set `node[expando]= [uuid];` instead of `node[expando]= uuid;` and all this nonsense regex processing can go away.
bobince