@@ -2211,3 +2211,232 @@ QUnit[ QUnit.jQuerySelectors ? "test" : "skip" ]( "custom pseudos", function( as
22112211 delete jQuery . expr . filters . slice ;
22122212 }
22132213} ) ;
2214+
2215+ QUnit . test ( "jQuery.find.matchesSelector" , function ( assert ) {
2216+ assert . expect ( 15 ) ;
2217+
2218+ var link = document . getElementById ( "simon1" ) ,
2219+ input = document . getElementById ( "text1" ) ,
2220+ option = document . getElementById ( "option1a" ) ,
2221+ disconnected = document . createElement ( "div" ) ;
2222+
2223+ link . title = "Don't click me" ;
2224+ assert . ok ( jQuery . find . matchesSelector ( link , "[rel='bookmark']" ) , "attribute-equals string" ) ;
2225+ assert . ok ( jQuery . find . matchesSelector ( link , "[rel=bookmark]" ) , "attribute-equals identifier" ) ;
2226+ assert . ok ( jQuery . find . matchesSelector ( link , "[\nrel = bookmark\t]" ) ,
2227+ "attribute-equals identifier (whitespace ignored)" ) ;
2228+ assert . ok ( jQuery . find . matchesSelector ( link , "a[title=\"Don't click me\"]" ) ,
2229+ "attribute-equals string containing single quote" ) ;
2230+
2231+ // trac-12303
2232+ input . setAttribute ( "data-pos" , ":first" ) ;
2233+ assert . ok ( jQuery . find . matchesSelector ( input , "input[data-pos=\\:first]" ) ,
2234+ "attribute-equals POS in identifier" ) ;
2235+ assert . ok ( jQuery . find . matchesSelector ( input , "input[data-pos=':first']" ) ,
2236+ "attribute-equals POS in string" ) ;
2237+ if ( QUnit . jQuerySelectors ) {
2238+ assert . ok ( jQuery . find . matchesSelector ( input , ":input[data-pos=':first']" ) ,
2239+ "attribute-equals POS in string after pseudo" ) ;
2240+ } else {
2241+ assert . ok ( "skip" , ":input not supported in selector-native" ) ;
2242+ }
2243+
2244+ option . setAttribute ( "test" , "" ) ;
2245+ assert . ok ( jQuery . find . matchesSelector ( option , "[id=option1a]" ) ,
2246+ "id attribute-equals identifier" ) ;
2247+ if ( QUnit . jQuerySelectors ) {
2248+ assert . ok ( jQuery . find . matchesSelector ( option , "[id*=option1][type!=checkbox]" ) ,
2249+ "attribute-not-equals identifier" ) ;
2250+ } else {
2251+ assert . ok ( "skip" , "[key!=value] not supported in selector-native" ) ;
2252+ }
2253+ assert . ok ( jQuery . find . matchesSelector ( option , "[id*=option1]" ) , "attribute-contains identifier" ) ;
2254+ assert . ok ( ! jQuery . find . matchesSelector ( option , "[test^='']" ) ,
2255+ "attribute-starts-with empty string (negative)" ) ;
2256+
2257+ option . className = "=]" ;
2258+ assert . ok ( jQuery . find . matchesSelector ( option , ".\\=\\]" ) ,
2259+ "class selector with attribute-equals confusable" ) ;
2260+
2261+ assert . ok ( jQuery . find . matchesSelector ( disconnected , "div" ) , "disconnected element" ) ;
2262+ assert . ok ( jQuery . find . matchesSelector ( link , "* > *" ) , "child combinator matches in document" ) ;
2263+ assert . ok ( ! jQuery . find . matchesSelector ( disconnected , "* > *" ) , "child combinator fails in fragment" ) ;
2264+ } ) ;
2265+
2266+ QUnit . test ( "jQuery.find.matches" , function ( assert ) {
2267+ assert . expect ( 4 ) ;
2268+
2269+ var iframeChild ,
2270+ input = document . getElementById ( "text1" ) ,
2271+ div = document . createElement ( "div" ) ,
2272+ iframe = document . getElementById ( "iframe" ) ,
2273+ iframeDoc = iframe . contentDocument || iframe . contentWindow . document ;
2274+
2275+ assert . deepEqual ( jQuery . find . matches ( "input" , [ input ] ) , [ input ] ,
2276+ "jQuery.find.matches with seed of input element" ) ;
2277+ assert . deepEqual ( jQuery . find . matches ( "div" , [ div ] ) , [ div ] ,
2278+ "jQuery.find.matches with disconnected element" ) ;
2279+
2280+ iframeDoc . open ( ) ;
2281+ iframeDoc . write ( "<body><div id='foo'><div id='bar'></div></div></body>" ) ;
2282+ iframeDoc . close ( ) ;
2283+
2284+ iframeChild = iframeDoc . getElementById ( "bar" ) ;
2285+
2286+ assert . deepEqual (
2287+ jQuery . find . matches ( ":root > body > #foo > #bar" , [ iframeChild ] ) ,
2288+ [ iframeChild ] ,
2289+ "jQuery.find.matches infers context from element"
2290+ ) ;
2291+
2292+ assert . deepEqual (
2293+ jQuery . find . matches ( ":root *" , [ div , iframeChild , input ] ) ,
2294+ [ iframeChild , input ] ,
2295+ "jQuery.find.matches infers context from each seed element"
2296+ ) ;
2297+ } ) ;
2298+
2299+ QUnit [ QUnit . jQuerySelectors ? "test" : "skip" ] ( "jQuery.find.select with pre-compiled function" , function ( assert ) {
2300+ assert . expect ( 6 ) ;
2301+
2302+ supportjQuery . each ( [
2303+ "#qunit-fixture #first" ,
2304+ "ol#listWithTabIndex > li[tabindex]" ,
2305+ "#liveSpan1"
2306+ ] , function ( i , selector ) {
2307+ var compiled = jQuery . find . compile ( selector ) ;
2308+ assert . equal ( jQuery . find . select ( compiled , document ) . length ,
2309+ 1 , "Should match using a compiled selector function" ) ;
2310+ assert . equal (
2311+ jQuery . find . select ( compiled , jQuery ( "#first" ) [ 0 ] ) . length ,
2312+ 0 , "Should not match with different context" ) ;
2313+ } ) ;
2314+ } ) ;
2315+
2316+ // Internal, but we test it for backwards compatibility for edge cases
2317+ QUnit [ QUnit . jQuerySelectors ? "test" : "skip" ] ( "jQuery.find.tokenize" , function ( assert ) {
2318+ assert . expect ( 1 ) ;
2319+
2320+ var selector = "#id .class > div[prop=\"value\"] + input:nth-child(1):button, span:contains(\"Text\") ~ div:has(div:has(span)):not(.not-this.not-that > div)" ,
2321+ tokens = [
2322+ [
2323+ {
2324+ "value" : "#id" ,
2325+ "type" : "ID" ,
2326+ "matches" : [
2327+ "id"
2328+ ]
2329+ } ,
2330+ {
2331+ "value" : " " ,
2332+ "type" : " "
2333+ } ,
2334+ {
2335+ "value" : ".class" ,
2336+ "type" : "CLASS" ,
2337+ "matches" : [
2338+ "class"
2339+ ]
2340+ } ,
2341+ {
2342+ "value" : " > " ,
2343+ "type" : ">"
2344+ } ,
2345+ {
2346+ "value" : "div" ,
2347+ "type" : "TAG" ,
2348+ "matches" : [
2349+ "div"
2350+ ]
2351+ } ,
2352+ {
2353+ "value" : "[prop=\"value\"]" ,
2354+ "type" : "ATTR" ,
2355+ "matches" : [
2356+ "prop" ,
2357+ "=" ,
2358+ "value"
2359+ ]
2360+ } ,
2361+ {
2362+ "value" : " + " ,
2363+ "type" : "+"
2364+ } ,
2365+ {
2366+ "value" : "input" ,
2367+ "type" : "TAG" ,
2368+ "matches" : [
2369+ "input"
2370+ ]
2371+ } ,
2372+ {
2373+ "value" : ":nth-child(1)" ,
2374+ "type" : "CHILD" ,
2375+ "matches" : [
2376+ "nth" ,
2377+ "child" ,
2378+ "1" ,
2379+ 0 ,
2380+ 1 ,
2381+ undefined ,
2382+ "" ,
2383+ "1"
2384+ ]
2385+ } ,
2386+ {
2387+ "value" : ":button" ,
2388+ "type" : "PSEUDO" ,
2389+ "matches" : [
2390+ "button" ,
2391+ undefined
2392+ ]
2393+ }
2394+ ] ,
2395+ [
2396+ {
2397+ "value" : "span" ,
2398+ "type" : "TAG" ,
2399+ "matches" : [
2400+ "span"
2401+ ]
2402+ } ,
2403+ {
2404+ "value" : ":contains(\"Text\")" ,
2405+ "type" : "PSEUDO" ,
2406+ "matches" : [
2407+ "contains" ,
2408+ "Text"
2409+ ]
2410+ } ,
2411+ {
2412+ "value" : " ~ " ,
2413+ "type" : "~"
2414+ } ,
2415+ {
2416+ "value" : "div" ,
2417+ "type" : "TAG" ,
2418+ "matches" : [
2419+ "div"
2420+ ]
2421+ } ,
2422+ {
2423+ "value" : ":has(div:has(span))" ,
2424+ "type" : "PSEUDO" ,
2425+ "matches" : [
2426+ "has" ,
2427+ "div:has(span)"
2428+ ]
2429+ } ,
2430+ {
2431+ "value" : ":not(.not-this.not-that > div)" ,
2432+ "type" : "PSEUDO" ,
2433+ "matches" : [
2434+ "not" ,
2435+ ".not-this.not-that > div"
2436+ ]
2437+ }
2438+ ]
2439+ ] ;
2440+
2441+ assert . deepEqual ( jQuery . find . tokenize ( selector ) , tokens , "Tokenization successful" ) ;
2442+ } ) ;
0 commit comments