( matcher, combinator, base )
| 2395 | } |
| 2396 | |
| 2397 | function addCombinator( matcher, combinator, base ) { |
| 2398 | var dir = combinator.dir, |
| 2399 | skip = combinator.next, |
| 2400 | key = skip || dir, |
| 2401 | checkNonElements = base && key === "parentNode", |
| 2402 | doneName = done++; |
| 2403 | |
| 2404 | return combinator.first ? |
| 2405 | |
| 2406 | // Check against closest ancestor/preceding element |
| 2407 | function( elem, context, xml ) { |
| 2408 | while ( ( elem = elem[ dir ] ) ) { |
| 2409 | if ( elem.nodeType === 1 || checkNonElements ) { |
| 2410 | return matcher( elem, context, xml ); |
| 2411 | } |
| 2412 | } |
| 2413 | return false; |
| 2414 | } : |
| 2415 | |
| 2416 | // Check against all ancestor/preceding elements |
| 2417 | function( elem, context, xml ) { |
| 2418 | var oldCache, uniqueCache, outerCache, |
| 2419 | newCache = [ dirruns, doneName ]; |
| 2420 | |
| 2421 | // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching |
| 2422 | if ( xml ) { |
| 2423 | while ( ( elem = elem[ dir ] ) ) { |
| 2424 | if ( elem.nodeType === 1 || checkNonElements ) { |
| 2425 | if ( matcher( elem, context, xml ) ) { |
| 2426 | return true; |
| 2427 | } |
| 2428 | } |
| 2429 | } |
| 2430 | } else { |
| 2431 | while ( ( elem = elem[ dir ] ) ) { |
| 2432 | if ( elem.nodeType === 1 || checkNonElements ) { |
| 2433 | outerCache = elem[ expando ] || ( elem[ expando ] = {} ); |
| 2434 | |
| 2435 | // Support: IE <9 only |
| 2436 | // Defend against cloned attroperties (jQuery gh-1709) |
| 2437 | uniqueCache = outerCache[ elem.uniqueID ] || |
| 2438 | ( outerCache[ elem.uniqueID ] = {} ); |
| 2439 | |
| 2440 | if ( skip && skip === elem.nodeName.toLowerCase() ) { |
| 2441 | elem = elem[ dir ] || elem; |
| 2442 | } else if ( ( oldCache = uniqueCache[ key ] ) && |
| 2443 | oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { |
| 2444 | |
| 2445 | // Assign to newCache so results back-propagate to previous elements |
| 2446 | return ( newCache[ 2 ] = oldCache[ 2 ] ); |
| 2447 | } else { |
| 2448 | |
| 2449 | // Reuse newcache so results back-propagate to previous elements |
| 2450 | uniqueCache[ key ] = newCache; |
| 2451 | |
| 2452 | // A match means we're done; a fail means we have to keep checking |
| 2453 | if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { |
| 2454 | return true; |
no test coverage detected