From: David Mark on
Having recently added an experimental QSA add-on for My Library, I have
been warned that QSA is a bear cross-browser. I don't doubt that, but
the other assertion was that the "major" libraries have it beat (likely
in the same way they "beat" DOM traversal).

I suppose to determine if it is buggy, you have to have a baseline that
is not buggy. So I suspected that some of the "buggy" behavior and
accompanying workarounds would be mystical incantations.

The querying in jQuery 1.41 (for example), uses an oddly named variable
called "Zizzle" to abstract the two layers (QSA and some really
off-the-wall and error-filled DOM traversal).

The original Sizzle is "declared" as follows:-

window.Sizzle = Sizzle;

Well, of course it is. Some things never change. :(

if ( document.querySelectorAll ) {

Bad feature detection (of course). I can easily see that blowing up in
some future IE incarnation (or who knows what other browser as host
objects can do what they want on type conversion).

(function(){
var oldSizzle = Sizzle, div = document.createElement("div");
div.innerHTML = "<p class='TEST'></p>";

Same old story. Needlessly tangling up feature testing with the
notoriously flaky innerHTML property.

// Safari can't handle uppercase or unicode characters when
// in quirks mode.

Interesting observation. Just Safari? Seems more like a Webkit issue
(assuming there is an issue). And what unicode characters?

if ( div.querySelectorAll && div.querySelectorAll(".TEST").length
=== 0) {
return;
}

How about !div.querySelectorAll(".TEST").length? The strict comparison
is silly.

Sizzle = function(query, context, extra, seed){
context = context || document;

That lets out frames.

// Only use querySelectorAll on non-XML documents

No worries, it is well established that jQuery is unsuitable for
traversing (or mutating) XML documents (Resig called a punt on that
issue a few months back). So this should really read: don't use jQuery
to read or write XML documents of any kind.

// (ID selectors don't work in non-HTML documents)
if ( !seed && context.nodeType === 9 && !isXML(context) ) {

isXML? Lets see:-

var isXML = function(elem){
// documentElement is verified for cases where it doesn't yet exist

Always a good idea.

// (such as loading iframes in IE - #4833)

Interesting observation, but the understanding must be that the
documentElement may not exist, period. In other words, this is not an
IE/IFrame issue, but a gap in logic that could have been avoided long
before the observed failure.

And, of course, jQuery can't support frames anyway (see above). I
assume bits of it do, but certainly not the query engine.

var documentElement = (elem ? elem.ownerDocument || elem :
0).documentElement;

What a perfectly ludicrous (and unreadable) line of code (didn't look to
see what it was replacing). But at least it doesn't throw exceptions if
the documentElement property is missing. The telling thing is that this
is one of those "overloaded" functions that jQuery is famous for,
requiring it to discriminate between different types of host objects
(elements and documents in this case).

return documentElement ? documentElement.nodeName !== "HTML" : false;

Whatever. It certainly doesn't add up to a cross-browser XML
discriminator (and is used all over the place in a library that doesn't
really support XML). And according to the above comment about IE and
IFrames, the documentElement may be missing in some cases, but otherwise
supported, so this is tangled up as it always returns false whenever it
can't find that property.

};

Back to the query portion:-

try {
return makeArray( context.querySelectorAll(query), extra );
} catch(e){}
}

That's it, is it? One (possible) quirk worked around. I see I haven't
been missing out on much (if anything). Who would have thought that
"jdalton" would exaggerate a claim? It must be the end of the world. :)

return oldSizzle(query, context, extra, seed);
};

for ( var prop in oldSizzle ) {

No filter (of course). Keep this thing away from other scripts.

Sizzle[ prop ] = oldSizzle[ prop ];
}

div = null; // release memory in IE

Cargo cult. There's no circular reference to break here. I used to do
the same thing, which is likely not a coincidence. ;)

})();
}

Okay, so how about the latest "stable" version of Prototype:-

SelectorsAPI: !!document.querySelector,

[...]

if (Prototype.BrowserFeatures.SelectorsAPI &&
document.compatMode === 'BackCompat') {

So any quirks mode.

Selector.CASE_INSENSITIVE_CLASS_NAMES = (function(){

That sounds sort of like the quirk that surfaced in jQuery.

var div = document.createElement('div'),
span = document.createElement('span');

div.id = "prototype_test_id";
span.className = 'Test';
div.appendChild(span);
var isIgnored = (div.querySelector('#prototype_test_id .test') !==
null);
div = span = null;

Another coincidence perhaps? Looks almost exactly like what I was
putting out in 2007, which showed up in jQuery in 2008 and is now being
copied by Prototype. Odd that these bums are my biggest "critics" (or
perhaps they are just jealous). :)

return isIgnored;
})();

I do like that pattern. :) And the logic is better than jQuery's.
Still, it is testing querySelector, but using querySelectorAll for its
queries (bad object inference).

}

[...]

shouldUseSelectorsAPI: function() {
if (!Prototype.BrowserFeatures.SelectorsAPI) return false;

Poor form.

if (Selector.CASE_INSENSITIVE_CLASS_NAMES) return false;

Same.


if (!Selector._div) Selector._div = new Element('div');

The RHS is mind-bogglingly inept. How about using createElement?

They are setting up for the big finale:-

try {
Selector._div.querySelector(this.expression);
} catch(e) {
return false;
}

return true;
},

Making the try-catch a one-off is admirable. The object inference is
inexcusable. And unless I've missed something, that's it for Prototype.

So, it appears there is nearly one quirk worked around between these two
"majors". I won't confirm it as one for sure, but I do remember such an
issue with Webkit in quirks mode (unrelated to QSA), so perhaps. I'll
look into it further. I don't know why jQuery bothered as they can't
support quirks mode in IE, which makes it a waste to attempt to support
others. Not surprising given its history though.

Yes, It appears I've seriously underestimated the time and care it takes
to create a QSA adapter. I should probably just pack it in. :)
From: David Mark on
David Mark wrote:
> Having recently added an experimental QSA add-on for My Library, I have
> been warned that QSA is a bear cross-browser. I don't doubt that, but
> the other assertion was that the "major" libraries have it beat (likely
> in the same way they "beat" DOM traversal).
>
> I suppose to determine if it is buggy, you have to have a baseline that
> is not buggy. So I suspected that some of the "buggy" behavior and
> accompanying workarounds would be mystical incantations.
>
> The querying in jQuery 1.41 (for example), uses an oddly named variable
> called "Zizzle" to abstract the two layers (QSA and some really
> off-the-wall and error-filled DOM traversal).

Typo. "Sizzle" of course.

[...]
>
> Cargo cult. There's no circular reference to break here. I used to do
> the same thing, which is likely not a coincidence. ;)

And, of course, it exits early if it spots that one quirk. I'm sure
Resig would say that the memory issue is only in IE and the quirk is
only in Safari, so it's all good. ;)
From: Roja Gilwreathe on
It is completely disingenuous for you to assert that you never flame
or act immaturely on this newsgroup. This thread was a completely un-
instigated set of potshots against jQuery just to make your own ideas
and library sound great and wonderful. Of course, this is standard
operating procedure on this alleged 'newsgroup,' which devolved long
ago into your personal dumping ground for whichever axe you feel like
grinding at the moment.

You should have figured out a long time ago that relevance goes hand
in hand with manners. You may be a damn clever JS developer, but no
one, I assure you, no one, thinks of you as anything more than a forum
troll with severe anger and jealousy issues.

On Feb 10, 1:12 am, David Mark <dmark.cins...(a)gmail.com> wrote:
> David Mark wrote:
> > Having recently added an experimental QSA add-on for My Library, I have
> > been warned that QSA is a bear cross-browser.  I don't doubt that, but
> > the other assertion was that the "major" libraries have it beat (likely
> > in the same way they "beat" DOM traversal).
>
> > I suppose to determine if it is buggy, you have to have a baseline that
> > is not buggy.  So I suspected that some of the "buggy" behavior and
> > accompanying workarounds would be mystical incantations.
>
> > The querying in jQuery 1.41 (for example), uses an oddly named variable
> > called "Zizzle" to abstract the two layers (QSA and some really
> > off-the-wall and error-filled DOM traversal).
>
> Typo.  "Sizzle" of course.
>
> [...]
>
>
>
> > Cargo cult.  There's no circular reference to break here.  I used to do
> > the same thing, which is likely not a coincidence.  ;)
>
> And, of course, it exits early if it spots that one quirk.  I'm sure
> Resig would say that the memory issue is only in IE and the quirk is
> only in Safari, so it's all good.  ;)

From: john on
On 09 Feb 11:46 PM, David Mark wrote:
> Having recently added an experimental QSA add-on for My Library, I have
> been warned that QSA is a bear cross-browser.

i've been testing both querySelector and querySelectorAll recently and
the results are pretty much what you'd expect. the following from
IE8/JScript 5.8 which all complain about "Invalid argument." where as
Safari 4, Firefox 3.6 and Opera 10.10 all agree (mostly) about the results:

var a = document.querySelector('ul li:last-child');
var b = document.querySelectorAll('table tbody tr:nth-child(2n+0)');
var c = document.querySelectorAll('table tbody tr:nth-child(2n+1)');
var d = document.querySelectorAll('table tbody tr:nth-child(even)');
var e = document.querySelectorAll('table tbody tr:nth-child(odd)');
var f = document.querySelectorAll('input:not([disabled])');
var g = document.querySelectorAll('html:root');
var h = document.querySelector('table tbody tr:first-of-type'); *
var i = document.querySelector('table tbody tr:last-of-type'); *
var j = document.querySelectorAll('div:empty');
var k = document.querySelector('div span:only-child');
var l = document.querySelectorAll('table:first-of-type');
var m = document.querySelector('body div:last-of-type'); *+
var n = document.querySelector('span:only-of-type');
var o = document.querySelector('input:checked');
var p = document.querySelectorAll('input:enabled');
var q = document.querySelectorAll('input:disabled');

while the following match in IE8, Safari 4, Firefox 3.6 and Opera 10.10:

var r = document.querySelector('ul li:first-child');
var s = document.querySelector('input[type=submit]');
var t = document.querySelector('input[value~=Submit]');
var u = document.querySelector('input[name|=submit]');
var v = document.querySelectorAll('input[type^=s]');
var w = document.querySelectorAll('input[type$=t]');
var x = document.querySelectorAll('input[type*=ubmi]');
var y = document.querySelectorAll('table + ul');
var z = document.querySelector('table ~ p');

--- test document ---------------------------------------------------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>qs(a)</title>
</head>
<body>
<p><input type=submit name=submit_button value=Submit></p>
<p><input type=submit name=submit-button value=Submit></p>
<table>
<caption>caption</caption>
<thead>
<tr><th>header</th></tr>
</thead>
<tbody>
<tr><td>data1</td></tr>
<tr><td>data2</td></tr>
<tr><td>data3</td></tr>
</tbody>
</table>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<p>abc</p>
<div></div>
<div><span>span</span></div>
<p><input type="checkbox" name="box" value="box" checked></p>
</body>
</html>
----------------------------------------------------------------------

* failed in Opera 10.10
+ failed in Safari 4.0.4
From: john on
On 10 Feb 2:46 AM, john wrote:
> On 09 Feb 11:46 PM, David Mark wrote:
>> Having recently added an experimental QSA add-on for My Library, I have
>> been warned that QSA is a bear cross-browser.
>
> i've been testing both querySelector and querySelectorAll recently and
> the results are pretty much what you'd expect. the following from
> IE8/JScript 5.8 which all complain about "Invalid argument." where as
> Safari 4, Firefox 3.6 and Opera 10.10 all agree (mostly) about the results:
>
>[ results ]

and Google Chrome 5.0.307.5 matches Safari 4