Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 75f24c8

Browse files
committed
Selector: pass jQuery unit tests with selector-native
- Ignore certain tests that obviously are not supported - Beefed up the sortOrder, uniqueSort, isXMLDoc, and attr functions Fixes gh-1742 Fixes gh-2048
1 parent ab06be5 commit 75f24c8

File tree

9 files changed

+311
-215
lines changed

9 files changed

+311
-215
lines changed

src/selector-native.js

Lines changed: 76 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
define( [
22
"./core",
33
"./var/document",
4-
"./var/documentElement"
5-
], function( jQuery, document, documentElement ) {
4+
"./var/documentElement",
5+
"./var/hasOwn",
6+
"./var/indexOf"
7+
], function( jQuery, document, documentElement, hasOwn, indexOf ) {
68

79
/*
810
* Optional (non-Sizzle) selector module for custom builds.
@@ -29,69 +31,84 @@ define( [
2931
* customize this stub for the project's specific needs.
3032
*/
3133

32-
var hasDuplicate,
34+
var hasDuplicate, sortInput,
35+
sortStable = jQuery.expando.split( "" ).sort( sortOrder ).join( "" ) === jQuery.expando,
3336
matches = documentElement.matches ||
3437
documentElement.webkitMatchesSelector ||
3538
documentElement.mozMatchesSelector ||
3639
documentElement.oMatchesSelector ||
37-
documentElement.msMatchesSelector,
38-
sortOrder = function( a, b ) {
40+
documentElement.msMatchesSelector;
3941

40-
// Flag for duplicate removal
41-
if ( a === b ) {
42-
hasDuplicate = true;
43-
return 0;
44-
}
42+
function sortOrder( a, b ) {
4543

46-
var compare = b.compareDocumentPosition &&
47-
a.compareDocumentPosition &&
48-
a.compareDocumentPosition( b );
44+
// Flag for duplicate removal
45+
if ( a === b ) {
46+
hasDuplicate = true;
47+
return 0;
48+
}
4949

50-
if ( compare ) {
50+
// Sort on method existence if only one input has compareDocumentPosition
51+
var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
52+
if ( compare ) {
53+
return compare;
54+
}
5155

52-
// Disconnected nodes
53-
if ( compare & 1 ) {
56+
// Calculate position if both inputs belong to the same document
57+
compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
58+
a.compareDocumentPosition( b ) :
5459

55-
// Choose the first element that is related to our document
56-
if ( a === document || jQuery.contains( document, a ) ) {
57-
return -1;
58-
}
59-
if ( b === document || jQuery.contains( document, b ) ) {
60-
return 1;
61-
}
60+
// Otherwise we know they are disconnected
61+
1;
6262

63-
// Maintain original order
64-
return 0;
65-
}
63+
// Disconnected nodes
64+
if ( compare & 1 ) {
6665

67-
return compare & 4 ? -1 : 1;
66+
// Choose the first element that is related to our preferred document
67+
if ( a === document || a.ownerDocument === document &&
68+
jQuery.contains( document, a ) ) {
69+
return -1;
70+
}
71+
if ( b === document || b.ownerDocument === document &&
72+
jQuery.contains( document, b ) ) {
73+
return 1;
6874
}
6975

70-
// Not directly comparable, sort on existence of method
71-
return a.compareDocumentPosition ? -1 : 1;
72-
},
73-
uniqueSort = function( results ) {
74-
var elem,
75-
duplicates = [],
76-
i = 0,
77-
j = 0;
76+
// Maintain original order
77+
return sortInput ?
78+
( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
79+
0;
80+
}
7881

79-
hasDuplicate = false;
80-
results.sort( sortOrder );
82+
return compare & 4 ? -1 : 1;
83+
}
8184

82-
if ( hasDuplicate ) {
83-
while ( ( elem = results[ i++ ] ) ) {
84-
if ( elem === results[ i ] ) {
85-
j = duplicates.push( i );
86-
}
87-
}
88-
while ( j-- ) {
89-
results.splice( duplicates[ j ], 1 );
85+
function uniqueSort( results ) {
86+
var elem,
87+
duplicates = [],
88+
j = 0,
89+
i = 0;
90+
91+
hasDuplicate = false;
92+
sortInput = !sortStable && results.slice( 0 );
93+
results.sort( sortOrder );
94+
95+
if ( hasDuplicate ) {
96+
while ( ( elem = results[ i++ ] ) ) {
97+
if ( elem === results[ i ] ) {
98+
j = duplicates.push( i );
9099
}
91100
}
101+
while ( j-- ) {
102+
results.splice( duplicates[ j ], 1 );
103+
}
104+
}
92105

93-
return results;
94-
};
106+
// Clear input after sorting to release objects
107+
// See https://github.com/jquery/sizzle/pull/225
108+
sortInput = null;
109+
110+
return results;
111+
}
95112

96113
jQuery.extend( {
97114
find: function( selector, context, results, seed ) {
@@ -157,7 +174,11 @@ jQuery.extend( {
157174
return a === bup || !!( bup && bup.nodeType === 1 && adown.contains( bup ) );
158175
},
159176
isXMLDoc: function( elem ) {
160-
return ( elem.ownerDocument || elem ).documentElement.nodeName !== "HTML";
177+
178+
// documentElement is verified for cases where it doesn't yet exist
179+
// (such as loading iframes in IE - #4833)
180+
var documentElement = elem && ( elem.ownerDocument || elem ).documentElement;
181+
return documentElement ? documentElement.nodeName !== "HTML" : false;
161182
},
162183
expr: {
163184
attrHandle: {},
@@ -177,7 +198,13 @@ jQuery.extend( jQuery.find, {
177198
return matches.call( elem, expr );
178199
},
179200
attr: function( elem, name ) {
180-
return elem.getAttribute( name );
201+
var fn = jQuery.expr.attrHandle[ name.toLowerCase() ],
202+
203+
// Don't get fooled by Object.prototype properties (jQuery #13807)
204+
value = fn && hasOwn.call( jQuery.expr.attrHandle, name.toLowerCase() ) ?
205+
fn( elem, name, jQuery.isXMLDoc( elem ) ) :
206+
undefined;
207+
return value !== undefined ? value : elem.getAttribute( name );
181208
}
182209
} );
183210

test/unit/core.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ QUnit.test( "jQuery()", function( assert ) {
145145
"Empty attributes object is not interpreted as a document (trac-8950)" );
146146
} );
147147

148-
QUnit.test( "jQuery(selector, context)", function( assert ) {
148+
QUnit[ jQuery.find.compile ? "test" : "skip" ]( "jQuery(selector, context)", function( assert ) {
149149
assert.expect( 3 );
150150
assert.deepEqual( jQuery( "div p", "#qunit-fixture" ).get(), q( "sndp", "en", "sap" ), "Basic selector with string as context" );
151151
assert.deepEqual( jQuery( "div p", q( "qunit-fixture" )[ 0 ] ).get(), q( "sndp", "en", "sap" ), "Basic selector with element as context" );
@@ -618,8 +618,12 @@ QUnit.test( "jQuery('html')", function( assert ) {
618618

619619
//equal( jQuery( "element[attribute=<div></div>]" ).length, 0,
620620
// "When html is within brackets, do not recognize as html." );
621-
assert.equal( jQuery( "element:not(<div></div>)" ).length, 0,
622-
"When html is within parens, do not recognize as html." );
621+
if ( jQuery.find.compile ) {
622+
assert.equal( jQuery( "element:not(<div></div>)" ).length, 0,
623+
"When html is within parens, do not recognize as html." );
624+
} else {
625+
assert.ok( true, "Complex :not not supported in selector-native" );
626+
}
623627
assert.equal( jQuery( "\\<div\\>" ).length, 0, "Ignore escaped html characters" );
624628
} );
625629

test/unit/css.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -666,9 +666,7 @@ QUnit.test( "show() after hide() should always set display to initial value (#14
666666

667667
}
668668

669-
if ( jQuery.fn.toggle ) {
670-
671-
QUnit.test( "toggle()", function( assert ) {
669+
QUnit[ jQuery.find.compile && jQuery.fn.toggle ? "test" : "skip" ]( "toggle()", function( assert ) {
672670
assert.expect( 9 );
673671
var div, oldHide,
674672
x = jQuery( "#foo" );
@@ -701,8 +699,6 @@ QUnit.test( "toggle()", function( assert ) {
701699
jQuery.fn.hide = oldHide;
702700
} );
703701

704-
}
705-
706702
QUnit.test( "jQuery.css(elem, 'height') doesn't clear radio buttons (bug #1095)", function( assert ) {
707703
assert.expect( 4 );
708704

@@ -1012,7 +1008,7 @@ QUnit.test( "css opacity consistency across browsers (#12685)", function( assert
10121008
assert.equal( Math.round( el.css( "opacity" ) * 100 ), 20, "remove opacity override" );
10131009
} );
10141010

1015-
QUnit.test( ":visible/:hidden selectors", function( assert ) {
1011+
QUnit[ jQuery.find.compile ? "test" : "skip" ]( ":visible/:hidden selectors", function( assert ) {
10161012
assert.expect( 17 );
10171013

10181014
var $div, $table, $a;

test/unit/effects.js

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ QUnit.module( "effects", {
2727
}
2828
} );
2929

30-
QUnit.test( "sanity check", function( assert ) {
30+
QUnit[ jQuery.find.compile ? "test" : "skip" ]( "sanity check", function( assert ) {
3131
assert.expect( 1 );
3232
assert.equal( jQuery( "#dl:visible, #qunit-fixture:visible, #foo:visible" ).length, 3, "QUnit state is correct for testing effects" );
3333
} );
@@ -769,7 +769,7 @@ QUnit.test( "stop( queue, ..., ... ) - Stop single queues", function( assert ) {
769769
this.clock.tick( 500 );
770770
} );
771771

772-
QUnit.test( "toggle()", function( assert ) {
772+
QUnit[ jQuery.find.compile ? "test" : "skip" ]( "toggle()", function( assert ) {
773773
assert.expect( 6 );
774774
var x = jQuery( "#foo" );
775775
assert.ok( x.is( ":visible" ), "is visible" );
@@ -1527,7 +1527,7 @@ QUnit.test( "Animate callbacks have correct context", function( assert ) {
15271527
this.clock.tick( 10 );
15281528
} );
15291529

1530-
QUnit.test( "User supplied callback called after show when fx off (#8892)", function( assert ) {
1530+
QUnit[ jQuery.find.compile ? "test" : "skip" ]( "User supplied callback called after show when fx off (#8892)", function( assert ) {
15311531
assert.expect( 2 );
15321532

15331533
var foo = jQuery( "#foo" );
@@ -1592,7 +1592,7 @@ QUnit.test( "animate should set display for disconnected nodes", function( asser
15921592
clock.tick( 400 );
15931593
} );
15941594

1595-
QUnit.test( "Animation callback should not show animated element as :animated (#7157)", function( assert ) {
1595+
QUnit[ jQuery.find.compile ? "test" : "skip" ]( "Animation callback should not show animated element as :animated (#7157)", function( assert ) {
15961596
assert.expect( 1 );
15971597

15981598
var foo = jQuery( "#foo" );
@@ -1605,7 +1605,7 @@ QUnit.test( "Animation callback should not show animated element as :animated (#
16051605
this.clock.tick( 100 );
16061606
} );
16071607

1608-
QUnit.test( "Initial step callback should show element as :animated (#14623)", function( assert ) {
1608+
QUnit[ jQuery.find.compile ? "test" : "skip" ]( "Initial step callback should show element as :animated (#14623)", function( assert ) {
16091609
assert.expect( 1 );
16101610

16111611
var foo = jQuery( "#foo" );
@@ -2125,7 +2125,12 @@ QUnit.test( ".finish() completes all queued animations", function( assert ) {
21252125
assert.equal( parseFloat( div.css( prop ) ), value, prop + " finished at correct value" );
21262126
} );
21272127
assert.equal( div.queue().length, 0, "empty queue when done" );
2128-
assert.equal( div.is( ":animated" ), false, ":animated doesn't match" );
2128+
2129+
if ( jQuery.find.compile ) {
2130+
assert.equal( div.is( ":animated" ), false, ":animated doesn't match" );
2131+
} else {
2132+
assert.ok( true, ":animated selector not supported with selector-native" );
2133+
}
21292134

21302135
// cleanup
21312136
div.remove();
@@ -2160,7 +2165,12 @@ QUnit.test( ".finish( false ) - unqueued animations", function( assert ) {
21602165
jQuery.each( animations, function( prop, value ) {
21612166
assert.equal( parseFloat( div.css( prop ) ), value, prop + " finished at correct value" );
21622167
} );
2163-
assert.equal( div.is( ":animated" ), false, ":animated doesn't match" );
2168+
2169+
if ( jQuery.find.compile ) {
2170+
assert.equal( div.is( ":animated" ), false, ":animated doesn't match" );
2171+
} else {
2172+
assert.ok( true, ":animated selector not supported with selector-native" );
2173+
}
21642174

21652175
// cleanup
21662176
div.remove();
@@ -2194,12 +2204,23 @@ QUnit.test( ".finish( \"custom\" ) - custom queue animations", function( assert
21942204

21952205
// start the first animation
21962206
div.dequeue( "custom" );
2197-
assert.equal( div.is( ":animated" ), true, ":animated matches" );
2207+
2208+
if ( jQuery.find.compile ) {
2209+
assert.equal( div.is( ":animated" ), true, ":animated matches" );
2210+
} else {
2211+
assert.ok( true, ":animated selector not supported with selector-native" );
2212+
}
2213+
21982214
div.finish( "custom" );
21992215
jQuery.each( animations, function( prop, value ) {
22002216
assert.equal( parseFloat( div.css( prop ) ), value, prop + " finished at correct value" );
22012217
} );
2202-
assert.equal( div.is( ":animated" ), false, ":animated doesn't match" );
2218+
2219+
if ( jQuery.find.compile ) {
2220+
assert.equal( div.is( ":animated" ), false, ":animated doesn't match" );
2221+
} else {
2222+
assert.ok( true, ":animated selector not supported with selector-native" );
2223+
}
22032224

22042225
// cleanup
22052226
div.remove();

test/unit/event.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1750,7 +1750,8 @@ QUnit.test( "jQuery.off using dispatched jQuery.Event", function( assert ) {
17501750
.remove();
17511751
} );
17521752

1753-
QUnit.test( "delegated event with delegateTarget-relative selector", function( assert ) {
1753+
// selector-native does not support scope-fixing in delegation
1754+
QUnit[ jQuery.find.compile ? "test" : "skip" ]( "delegated event with delegateTarget-relative selector", function( assert ) {
17541755
assert.expect( 3 );
17551756
var markup = jQuery( "<div><ul><li><a id=\"a0\"></a><ul id=\"ul0\"><li class=test><a id=\"a0_0\"></a></li><li><a id=\"a0_1\"></a></li></ul></li></ul></div>" ).appendTo( "#qunit-fixture" );
17561757

0 commit comments

Comments
 (0)