Yawwwwnnnnn.... this is, quite possibly, the most inane set of
ramblings set up by someone who has obviously never created a
JavaScript library of any kind, nor has used JavaScript code in any
sort of production environment.
Wrong on all counts.
I'll reply to your alleged critiques to the code below.
To start with, jQuery only supports the following browsers:
- IE 6+
- Firefox 2+
- Opera 9
- Safari 2+
Which is why it is amazing that it has to resort to browser sniffing.
Of course, it likely won't wory very well in say IE8, Opera 10,
Firefox 3, etc.
Anything outside that jurisdiction is not guaranteed to work. But
considering that that selection is something like 99% of all browsers
(and considering that the selection of supported browsers is "good
enough" for Google, Amazon, NBC, IBM, Oracle, etc. etc.) I think it's
Google as an example?! The worst JavaScript developers in history?
Same goes for Amazon. Whatever you support, you shouldn't have to
parse the userAgent string to support it. That was clear 10 years
ago. Where have you been?
safe to say that we've made a good choice.
The ones we care about?
So your library is inappropriate for a site on the public Internet?
Pray tell! I must've missed the boolean property that tells me that
it's broken as all get out.
You simply not thinking.
The .attr() function can be a little futzy (it's long due for a
rewrite). For now, it's written this way to keep all attribute/css
special-case logic contained to a single location.
It is a crock any way you slice it.
Huh? That gets the interpreted value of an attribute, only in IE, and
only if it isn't within an XML document (and only for the href and src
attributes - which are the ones that have the specific URL-
interpretation problems).
Just like I said. Every time through it is interpreted. You don't
"know" it is IE until you test that useless msie property. And the
question remains: what sort of XML document runs script in IE?
// Certain attributes only work when accessed via the old DOM 0 way
if ( fix[name] ) {
if ( value != undefined ) elem[fix[name]] = value;
return elem[fix[name]];
This demonstrates a stunning lack of understanding of attributes (and
IE's problems with them.) Where's the sniff (or feature detect) for
IE? This IE-specific workaround runs on everything.
This has nothing to do with being IE-specific, or not. Look at the fix
object - it contains a number of properties (both CSS and regular
attribute) that need to be re-written or defer to another attribute.
(For example, this is also used to fix cases where a user
types .attr("readonly") instead of .attr("readOnly")).
And that has everything to do with IE. The fact that you don't
realize that speaks volumes. Do you even understand what the problem
is with get/setAttribute in IE?
The action and method attributes can be overwritten in IE, like so:
<form>
<input type="text" id="action"/>
</form>
Thus, this code handles that case and gets the correct value, special.
Your magic spell is botched. Did it occur to you detect when
attributes are mistakenly treated as properties (hint #2 on that
subject) and then to test getAttributeNode before blindly inferring
its existence from a useless flag?
It only runs on the ones that we care about - but apparently this
mythical, ultra-popular, StrawMan v1.0 is all the rage these days.
What does that mean? There are hundreds of agents in use today that
identify as IE and any Website that uses your script will break them.
This was done completely intentionally - we don't support dynamically
changing the type attribute on input elements, since it causes an
exception to be thrown in IE (we would rather have a consistent code
Read your code again. It causes an exception under some circumstances
and other problems under other circumstances. Your parentNode test is
incorrect. Try using that code to create a new radio button and you
will see what I mean.
base, across all browsers that we support, than have problems arise
later for users).
Oddly enough, I don't have any trouble setting the type attribute for
input elements, dynamically created or not. Of course, to do this you
have to go back and re-think your strategy concerning finding a
boolean flag that will alert you to IE's botched attribute handling.
See what above? A tangled mess?
Error-prone? Doubtful. Where's your test suite-backed attribute/css
manipulation code, I'd love to see it!
I bet you would. My test suite covers quite a few more agents than
yours. And of course, I don't have to worry too much about ones I
don't use or future revisions as I don't employ browser sniffing. See
how that works?
Inefficient, possibly. We've already made a number of optimizations
wherever possible - but many of the checks can't be circumvented.
The whole structure is rotten. It's only 80K. Why not tear it down
and rewrite it?
Convoluted - sure. As I mentioned before, it's due for a re-write.
The whole thing, right?
Sigh. Where's your ultra-documented, totally-awesome, perfect-in-every-
way JavaScript library? That's what I thought - you don't have one,
nor does one exist.
That is the Matt Kruse school of baiting. I am not going to help you
rewrite your library any more than I already have. Sorry.
See above - it works for everything that we support. We make no
illusions as to otherwise.
But many delusions as to why you need to support only five browsers
and why you need to sniff the userAgent string to do it.
Wow. WowWowWow. Spoken like a true babe! It's damn simple to detect it
You come off as an idiot.
in all browsers but Safari. In Safari 2, in an element that is
display: none, getComputedStyle() returns null. In Safari 3, it
That problem is not limited to Safari.
returns a style object, but within with all values return "" (which
Not in Windows Safari 3. Regardless, I was referring to something
else entirely. It looks like you do have a feature detect for
getComputedStyle, but the section of code is so convoluted that I
missed it. Adjusted score is about negative a million plus one.
Also, the handling of this issue is typically inept. You should never
try to query the computed style of an element that isn't part of the
layout. Barring (!important) user style sheet overrides, calling
programs should be aware when an element is part of the layout and
when it is not. All of those hoops you are going through to display
parentNodes (with an arbitrary rule no less) is a waste of time.
You've got much bigger and more important problems.
may, or may not, be a valid return value - it's impossible to tell!).
Thus, you have to check for the existence of the computed color value
(which will always exist) and if it's empty, then we're inside a
corrupted element.
Yes? Your point? IE can, sometimes, not auto-generate a <tbody>
You missed the point completely. The general theme is feature
detection (and the lack thereof.) I didn't spell everything out for
you as this was not a support request ticket. Look a couple of lines
down from that and find:
for ( var n = tb.length-1; n >= 0 ; --n )
This assumes that tb was actually set to something. What if the agent
had no firstChild property? Certainly many agents that identify as IE
fall into that category. Isn't this script supposed to make it easier
to build a Website? Seems odd that it is completely unsuitable for
the Internet.
wrapper (when there's no contents to the table). This verifies when a
<table></table> is passed in makes sure that a tbody is constructed.
Again, everything here is backed by a test suite.
But even if it aces your limited tests, it is still unsuitable for
building Web applications. So what is it good for?
// IE can't serialize <link> and <script> tags normally
jQuery.browser.msie && [1, "div<div>", "</div>"]
You have to keep in mind while reading this stuff that
jQuery.browser.msie is meaningless on the Web. It isn't of much use
on an Intranet either, unless you use the same version and
configuration of IE forever.
Huh? Show me a drastically improved version of IE and I'll show you an
updated copy of jQuery.
What does that mean? If you had written it right to begin with, you
wouldn't have to go back and rewrite it every time a new version is
released. And the other browsers you support are updated constantly.
Any way you slice it, people that rely on your code are actually
relying on you. That is a scary thought as you clearly don't know the
first thing about JavaScript, let alone browser scripting.
// Also, we need to make sure that the correct elements are being
returned
// (IE returns comment nodes in a '*' query)
if ( jQuery.browser.msie ) {
for ( var i = 0; second; i++ )
if ( second.nodeType != 8 )
first.push(second);
} else
Same problem different function. What if some agent that doesn't
identify as IE has the same problem?
These browsers that you keep talking about must be amazing! They're,
quite literally, everywhere! At every turn there's a browser that we
support that also claims to be IE, but it isn't IE! What have we been
doing wrong all this time? How could we have been so naive?
You read it backwards apparently. The point is that the problem may
exist in browsers that are NOT IE. Why make stupid assumptions? Here
is that portion of the code:
if ( jQuery.browser.msie ) {
for ( var i = 0; second; i++ )
if ( second.nodeType != 8 )
first.push(second);
} else
for ( var i = 0; second; i++ )
first.push(second);
What's wrong with that picture? I don't mean the missing brackets
that make it nearly impossible to follow and easy to foul up during
the inevitable maintenance.
That captures the essence of your code and comments perfectly.
The same argument, over and over, is getting incredibly old. Where's
your ultra-popular library that is 100% future proof?
The difference between you and me is that I don't give away code for
beer money donations. Get it? And I gave you the answer to that
one. So why not get rid of at least that one browser sniff. Do you
really need to peek at my style functions to do this?
Considering that IE is going to be backwards compatible for, most
likely, many many years to come, I'm not worried. When the year 2031
arrives, jQuery can, and will adapt.
It is absurd to think the jQuery will be around even a few more years,
let alone decades.
// Check to see if the W3C box model is being used
boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat",
That could have far-reaching implications. A quick search found it in
an attempt to measure the viewport:
return this[0] == window ?
jQuery.browser.safari && self["inner" + name] || jQuery.boxModel &&
Math.max(document.documentElement["client" + name],
document.body["client" + name]) ||
document.body["client" + name] :
this[0] == document ?
Math.max( document.body["scroll" + name], document.body["offset" +
name] ) :
h == undefined ?( this.length ? jQuery.css( this[0], n ) : null ) :
this.css( n, h.constructor == String ? h : h + "px" );
I characterized this as a "million monkey" project earlier and I want
to take a moment to apologize to monkeys everywhere. I think even a
single monkey could write a better solution to this very common
problem. Certainly there are many better solutions floating around on
the Internet.
Certainly! They are, literally, everywhere! I mean, I can't go
anywhere without tripping over a test-suite-backed, cross browser,
quirksmode-handling, browser width and height detection script.
Idiot. I posted one here not three weeks ago. It was tested on
virtually everything, all the way back to IE5/NS6 and you can be sure
that the word "userAgent" does not appear in it. It is a good idea to
read the newsgroup and its FAQ (to quote another regular's sig.)
Your "arguments" consist of nothing but assumptions dressed up as
criticism.
I don't have to assume. I have dealt with all of the same problems
that you are stumbling over.
Yes, we are well aware of the clientLeft/Top properties -
unfortunately there are edge cases where they are not sufficient
(especially when moving between standards and quirksmode).
Gibberish. If you had any idea what you were doing, you wouldn't make
patently false comments like:
"IE 7 standards mode, the border is always 2px"
Do you understand that in quirks mode there is no HTML element present
in the layout. That 2px (which is not always 2px) represents part of
the chrome. It has nothing to do with the border style of the HTML
element. You can give the HTML element a border of 200px and it will
have no affect on the layout and certainly no affect on positioning.
In quirks mode it is the BODY border that gets subtracted from the
coordinates returned by getBoundingClientRect. No magic spells are
needed when you understand what is going on. Edge cases indeed.
It is pretty clear that you don't know what you are doing, which is
why you shouldn't be doing it. Not in public anyway. The fact that
you are also snotty towards criticism comes as no surprise. Most
incompetents have the same attitude.
You're definitely proving that it's much easier to make off-the-cuff
criticisms than to actually provide working, tested, cross-browser
solutions. All of which we've done, and supported, for almost 2 years
now.
Working? Cross-browser? Hardly. If you tested, then why are you
still clueless about simple things like the effect of borders on
positioning? Try turning on HTML borders in any other of your
supported browsers and see what happens to your positioning tests.
Same goes for margins. BODY borders are more prevalent and will also
cause problems in some cases. From the above comment about "edge
cases" for "HTML borders" in quirks mode, it appears you never tested
those at all.
// Mozilla and Safari > 2 does not include the border on offset
parents
// However Mozilla adds the border for table cells
if ( mozilla && /^t[d|h]$/i.test(parent.tagName) || !safari2 )
border( offsetParent );
Apparently, in the jQuery universe there is only Opera, Mozilla,
Safari and IE. IE never gets here. Opera (and Safari <= 2 if you
believe the comments) adds borders when it shouldn't. So this logic
excludes everything the author has ever heard of that isn't Opera.
Right. See above.
But you still don't see why the logic and comments are senseless?
Opera (and Safari 2) are the exceptions, not the rule. The "borders-
included-in-offsets" anomaly is easy enough to feature test.
Coincidentally, I have posted examples of it in the past. They
weren't posts about jQuery, so I guess you didn't read them. Every
time a new version of Opera or Mozilla (or whatever) comes out, you've
got a lot of re-testing and (possibly re-working) to do, which can
easily introduce new bugs, which leads to more re-testing, etc. Then
the dialog pops up telling you that Firefox has a new version and do
you still think this is a good strategy? Since all of your testing is
based on browser names, what exactly will you do when Opera fixes
their border problem? Add another flag based on the version number?
You mentioned something about 2035 (or some ridiculously far off year)
earlier. How long will jQuery's browser sniffing branches be by
then? It is a rhetorical question. Obviously it will have long since
gone the way of the dodo.
Because it's not? It captures everything that we care about.
Does it indicate Mozilla? IE has spoofed Mozilla in its userAgent
string since the beginning. So is IE Mozilla? Or perhaps in the
various branches it never checks Mozilla unless it has branched away
from IE? Does any of this sound like good coding practice to you?
Variable that have meaningless names, strange twisting branches based
on a string of characters that has no relation to the terrain, adding
more branches every time a new browser version comes out, etc.? Why
would anybody do that? A better question is why would anybody rely on
somebody who does it (especially when the person refuses to listen to
the advice of those who know better.)
LOL. I think you need to see above. More "edge cases?" You have got
to be kidding. To find the border of an element, you start with
clientLeft/Top. Computing styles is the last resort for browsers that
do not support clientLeft/Top. Considering how outrageously
inefficient your style wrappers are, you would be well advised to use
the clientLeft/Top properties when they are available.
It should have been fixed before it was released.
Man, why am I not using this StrawMan browser? It is, apparently, used
everywhere. Once again, if it's not in the 99% of all browsers that we
support, we don't care.
You are deluded. You don't support anywhere near 99% of all
browsers. And whether you care is not the point. Who was talking to
you?
We remove the event to be tidy - if we don't need to keep it bound,
then there's no reason to waste any perfectly-good memory on it. I
don't understand why this is an issue for you. Do you prefer that
libraries keep everything bound indefinitely? Do you want them to have
high overhead and run slow?
GC is automatic. Do you understand that a memory leak is an exception
to GC? Your comment indicated that you thought the event might leak.
What do you base that suspicion on? Do you automatically remove every
listener every time the page unloads, just in case it might cause a
memory leak?
Except for half the browsers - Safari and IE. Which is not "virtually
everything".
Not IE? Are you sure? Last I checked, IE spoofed Mozilla. I think
it was about ten years ago. I doubt it has changed.
You've got to love the comments. "Use the handy event callback" may
be the least informative one yet. Here's another interesting one from
makeArray:
// Need to use typeof to fight Safari childNodes crashes
if ( typeof a != "array" )
for ( var i = 0, al = a.length; i < al; i++ )
r.push( a );
else
r = a.slice( 0 );
And why would you pass an array to a "makeArray" function anyway?
.makeArray() is designed to take any array-like object and return a
clone of itself. Thus this will work for both NodeLists and regular
arrays (for example). Note the key word there: clone - it doesn't
return the original (hence it's only used for when an array needs to
be cloned).
You should try coming up with logical names for your functions. You
notice you how had to explain what that function did?
Regardless, you can't see what is wrong with this line?
if ( typeof a != "array" )
What (in any JavaScript implementation) will evaulate that to false?
What is an array in JavaScript?
I assume that you're referring to jQuery.isFunction(). If you have a
comparable method that's able to pass all of these tests in all modern
browsers, let me know! I'll be happy to take a look.
We just went over this a few weeks ago. Search the group before
posting. It might help you avoid shooting yourself in the foot next
time.
Test your own code.
Apparently, a thoroughly tested and comprehensively written JavaScript
library - who knew?
Nobody knew that, though some thought they did.
Probably the same one that Google, Amazon, IBM, AOL, etc. are from.
Again with the Google and Amazon (and AOL?!) nonsense. Is that
supposed to be funny?
Run through Dean Edwards' Packer script. jQuery is ~14K minified +
gzipped.
Which would imply that packer does a worse job than GZIP, so it should
not be used. And of course, GZIP doesn't factor into page weight
comparisons. The server might GZIP it, it might not. All things
equal, it is a 50K script minified.
[snip non-discussion]
So besides .attr() needing a rewrite (I fully admit that) - I see
absolutely no valid criticism of the library - and if anything, a
You are blind. Others certainly did. Even the jQuery fanboy Matt
Kruse agreed with enough of it to open up tickets on your site. I
wondered where he got the idea that you knew better about some of this
stuff as I didn't realize you were nuts enough to actually post a
retort here. When I saw that Matt "re-printed" one of his earlier
responses to you, I couldn't believe my eyes. I knew it would be a
bunch of clueless nonsense, but this exceeded my expectations by far.
gross misunderstanding of common cross browser issues and of how test
driven development works.
Let me know when you release your library, as I'd love to take a look
and see what I've been missing.
I bet you would like to crib from me. And who said I was releasing a
public general-purpose JavaScript library? Seems to me I said just
recently that I would never do that (much to the chagrin of several
people in this thread.) Apparently you don't read before you post.