|
12 | 12 | getText, |
13 | 13 | isXML, |
14 | 14 | compile, |
15 | | - hasDuplicate, |
16 | 15 | outermostContext, |
17 | 16 |
|
18 | 17 | // Local document vars |
|
25 | 24 | matches, |
26 | 25 | contains, |
27 | 26 | sortOrder, |
| 27 | + hasDuplicate, |
| 28 | + sortInput, |
28 | 29 |
|
29 | 30 | // Instance-specific data |
30 | 31 | expando = "sizzle" + -(new Date()), |
@@ -392,6 +393,16 @@ setDocument = Sizzle.setDocument = function( node ) { |
392 | 393 | return pass; |
393 | 394 | }); |
394 | 395 |
|
| 396 | + // Support: Webkit |
| 397 | + // Detached nodes confoundingly follow *each other* |
| 398 | + support.sortDetached = assert(function( div1 ) { |
| 399 | + return assert(function( div2 ) { |
| 400 | + return div1.compareDocumentPosition && |
| 401 | + // Should return 1, but Webkit returns 4 (following) |
| 402 | + !!(div1.compareDocumentPosition( div2 ) & 1); |
| 403 | + }); |
| 404 | + }); |
| 405 | + |
395 | 406 | // IE6/7 return modified attributes |
396 | 407 | Expr.attrHandle = assert(function( div ) { |
397 | 408 | div.innerHTML = "<a href='#'></a>"; |
@@ -588,26 +599,42 @@ setDocument = Sizzle.setDocument = function( node ) { |
588 | 599 | // Document order sorting |
589 | 600 | sortOrder = docElem.compareDocumentPosition ? |
590 | 601 | function( a, b ) { |
591 | | - var compare; |
592 | 602 |
|
| 603 | + // Flag for duplicate removal |
593 | 604 | if ( a === b ) { |
594 | 605 | hasDuplicate = true; |
595 | 606 | return 0; |
596 | 607 | } |
597 | 608 |
|
598 | | - if ( (compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b )) ) { |
599 | | - if ( compare & 1 || a.parentNode && a.parentNode.nodeType === 11 ) { |
600 | | - if ( a === doc || contains( preferredDoc, a ) ) { |
| 609 | + var compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b ); |
| 610 | + |
| 611 | + if ( compare ) { |
| 612 | + // Disconnected nodes |
| 613 | + if ( compare & 1 || |
| 614 | + // Support: Opera, Firefox |
| 615 | + // Results can't be trusted for document fragment children |
| 616 | + a.parentNode && a.parentNode.nodeType === 11 || |
| 617 | + // Support: Webkit |
| 618 | + (sortInput && b.compareDocumentPosition( a ) === compare) ) { |
| 619 | + |
| 620 | + // Choose the first element that is related to our preferred document |
| 621 | + if ( a === doc || contains(preferredDoc, a) ) { |
601 | 622 | return -1; |
602 | 623 | } |
603 | | - if ( b === doc || contains( preferredDoc, b ) ) { |
| 624 | + if ( b === doc || contains(preferredDoc, b) ) { |
604 | 625 | return 1; |
605 | 626 | } |
606 | | - return 0; |
| 627 | + |
| 628 | + // Maintain original order |
| 629 | + return sortInput ? |
| 630 | + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : |
| 631 | + 0; |
607 | 632 | } |
| 633 | + |
608 | 634 | return compare & 4 ? -1 : 1; |
609 | 635 | } |
610 | 636 |
|
| 637 | + // Not directly comparable, sort on existence of method |
611 | 638 | return a.compareDocumentPosition ? -1 : 1; |
612 | 639 | } : |
613 | 640 | function( a, b ) { |
@@ -744,6 +771,8 @@ Sizzle.uniqueSort = function( results ) { |
744 | 771 |
|
745 | 772 | // Unless we *know* we can detect duplicates, assume their presence |
746 | 773 | hasDuplicate = !support.detectDuplicates; |
| 774 | + // Save the original sort order if necessary |
| 775 | + sortInput = !support.sortDetached && results.slice( 0 ); |
747 | 776 | results.sort( sortOrder ); |
748 | 777 |
|
749 | 778 | if ( hasDuplicate ) { |
|
0 commit comments