ded/qwery — Issue #63: TODO: always return results in document-order
Author: rvagg
Created: 2011-12-12 05:55:04+00:00
State: open

I'm just going to put this out there as something for someone to do at some point in the future if they feel so inclined. I don't think it'd be a particularly easy job, especially while maintaining current performance.

Native `querySelectorAll()` works, conceptually at least, by scanning all nodes from top to bottom and checking them against the selector, each match gets added to the return list and then we end up with a list of elements in proper document order. Qwery does this except in the case of grouped selectors because we split the selector up into component parts with `selector.split(',')` and process them separately with `_qwery()`. This split is also done for all browsers in the case of element-rooted queries with a relationship selector first (e.g. `Q('>.yee, .haa', element)`).

Take a fragment: `

` and query it for `'b,a'`. qSA will give you `[,]` because this is document-order while Qwery will give you `[,]` because we first process the `'b'` and then the '`a`' and append the results together. Sizzle and NW manage to do this properly. There are some cases where it matters but it mainly matters because that's the de-facto standard that's emerged and been written into the actual standard.

Here's a snippet that you can run in the console of a modern browser to demonstrate the issue and could form the basis of a simple unit test:

```js
var e = document.createElement('p');
e.innerHTML = '';
e.querySelectorAll = null; // comment this out to run with the native qSA
var r = qwery('b,a', e); // insert other selector engine here if you want to see if it works properly
if (r.length !== 2 || !/[aA]/.test(r[0].tagName)) console.log("Bzzt! Wrong answer", r);
else console.log('correct:',r);
```

This mainly matters for IE <= 7, it matters in IE8 when you're using CSS3+ selectors (otherwise it uses the in-built CSS2-compliant qSA) and I think it'll matter for all browsers with element-rooted queries with relationship selectors first (see above). IE6&7 will hopefully not matter soon so fixing it just for the CSS3 qSA case might be a bit simpler.