{"issue":{"state":"open","created_at":"2011-12-12T05:55:04Z","updated_at":"2011-12-13T23:53:55Z","comments":3,"user":{"gravatar_id":"026f5af604a336a38301639027757f29","id":495647,"url":"https://api.github.com/users/rvagg","avatar_url":"https://secure.gravatar.com/avatar/026f5af604a336a38301639027757f29?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png","login":"rvagg"},"body":"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.\r\n\r\nNative `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)`).\r\n\r\nTake a fragment: `<p><a/><b/><i/><em/></p>` and query it for `'b,a'`. qSA will give you `[<a/>,<b/>]` because this is document-order while Qwery will give you  `[<b/>,<a/>]` 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.\r\n\r\nHere'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:\r\n\r\n```js\r\nvar e = document.createElement('p');\r\ne.innerHTML = '<a/><i/><b/>';\r\ne.querySelectorAll = null; // comment this out to run with the native qSA\r\nvar r = qwery('b,a', e); // insert other selector engine here if you want to see if it works properly\r\nif (r.length !== 2 || !/[aA]/.test(r[0].tagName)) console.log(\"Bzzt! Wrong answer\", r);\r\nelse console.log('correct:',r);\r\n```\r\n\r\nThis 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.","assignee":null,"id":2519728,"labels":[],"pull_request":{"patch_url":null,"html_url":null,"diff_url":null},"number":63,"title":"TODO: always return results in document-order","html_url":"https://github.com/ded/qwery/issues/63","closed_at":null,"url":"https://api.github.com/repos/ded/qwery/issues/63","milestone":null},"action":"created","comment":{"created_at":"2011-12-13T23:53:55Z","updated_at":"2011-12-13T23:53:55Z","user":{"gravatar_id":"026f5af604a336a38301639027757f29","id":495647,"url":"https://api.github.com/users/rvagg","avatar_url":"https://secure.gravatar.com/avatar/026f5af604a336a38301639027757f29?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png","login":"rvagg"},"body":"So here's where it matters. In [Traversty](https://github.com/rvagg/traversty) I use the selector engine to find child elements matching the given selector and then return the element at the index requested.\r\n\r\nSo, `$('ul').down('span,li', 2)` (both args are optional but the problem only occurs where you provide both) is intended to return the 3rd child element in document order matching the selector `'span,li'`. But since Qwery will do the `'span'` first followed by the `'li'` we'd likely get them in the wrong order and return the wrong element.\r\n\r\nThis is an uncommon use-case though, you're more likely to give very simple selectors, it's also only a problem on IE6&7 (and 8 if you use a CSS3 selector) but it's a use-case none the less! And the workaround is fairly simple, if the selector has a comma then I get all child elements (byTag(*)) and run an `is()` on each of them: https://github.com/rvagg/traversty/blob/3eb6f257e641abeead2f31eb258a05e53639a45d/src/traversty.js#L60-74","id":3132953,"url":"https://api.github.com/repos/ded/qwery/issues/comments/3132953"}}