Make sure that elements are returned in document order - and that the results are...
authorJohn Resig <jeresig@gmail.com>
Sat, 14 Feb 2009 16:59:10 +0000 (16:59 +0000)
committerJohn Resig <jeresig@gmail.com>
Sat, 14 Feb 2009 16:59:10 +0000 (16:59 +0000)
src/selector.js
test/unit/selector.js

index 331ad3c..bc898e1 100644 (file)
@@ -111,6 +111,19 @@ var Sizzle = function(selector, context, results, seed) {
 
        if ( extra ) {
                Sizzle( extra, context, results, seed );
+
+               if ( sortOrder ) {
+                       hasDuplicate = false;
+                       results.sort(sortOrder);
+
+                       if ( hasDuplicate ) {
+                               for ( var i = 1; i < results.length; i++ ) {
+                                       if ( results[i] === results[i-1] ) {
+                                               results.splice(i--, 1);
+                                       }
+                               }
+                       }
+               }
        }
 
        return results;
@@ -648,6 +661,26 @@ try {
        };
 }
 
+var sortOrder;
+
+if ( document.documentElement.compareDocumentPosition ) {
+       sortOrder = function( a, b ) {
+               var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
+               if ( ret === 0 ) {
+                       hasDuplicate = true;
+               }
+               return ret;
+       };
+} else if ( document.documentElement.sourceIndex === 0 ) {
+       sortOrder = function( a, b ) {
+               var ret = a.sourceIndex - b.sourceIndex;
+               if ( ret === 0 ) {
+                       hasDuplicate = true;
+               }
+               return ret;
+       };
+}
+
 // Check to see if the browser returns elements by name when
 // querying by getElementById (and provide a workaround)
 (function(){
index f7c3912..7f74d75 100644 (file)
@@ -1,7 +1,7 @@
 module("selector");
 
 test("element", function() {
-       expect(9);
+       expect(13);
        reset();
 
        ok( jQuery("*").size() >= 30, "Select all" );
@@ -18,6 +18,13 @@ test("element", function() {
        
        ok( jQuery("#length").length, '&lt;input name="length"&gt; cannot be found under IE, see #945' );
        ok( jQuery("#lengthtest input").length, '&lt;input name="length"&gt; cannot be found under IE, see #945' );
+
+       // Check for unique-ness and sort order
+       isSet( jQuery("*"), jQuery("*, *"), "Check for duplicates: *, *" );
+       isSet( jQuery("p"), jQuery("p, div p"), "Check for duplicates: p, div p" );
+
+       t( "Checking sort order", "h2, h1", ["header", "banner", "userAgent"] );
+       t( "Checking sort order", "p, p a", ["firstp", "simon1", "ap", "google", "groups", "anchor1", "mark", "sndp", "en", "yahoo", "sap", "anchor2", "simon", "first"] );
 });
 
 if ( location.protocol != "file:" ) {
@@ -333,7 +340,7 @@ test("pseudo (:) selectors", function() {
        t( "Form element :text", "#form :text", ["text1", "text2", "hidden2", "name"] );
        t( "Form element :radio:checked", "#form :radio:checked", ["radio2"] );
        t( "Form element :checkbox:checked", "#form :checkbox:checked", ["check1"] );
-       t( "Form element :checkbox:checked, :radio:checked", "#form :checkbox:checked, #form :radio:checked", ["check1", "radio2"] );
+       t( "Form element :radio:checked, :checkbox:checked", "#form :radio:checked, #form :checkbox:checked", ["radio2", "check1"] );
 
        t( "Headers", ":header", ["header", "banner", "userAgent"] );
        t( "Has Children - :has()", "p:has(a)", ["firstp","ap","en","sap"] );