| 2432 | } |
| 2433 | |
| 2434 | function addCombinator( matcher, combinator, base ) { |
| 2435 | var dir = combinator.dir, |
| 2436 | checkNonElements = base && dir === "parentNode", |
| 2437 | doneName = done++; |
| 2438 | |
| 2439 | return combinator.first ? |
| 2440 | // Check against closest ancestor/preceding element |
| 2441 | function( elem, context, xml ) { |
| 2442 | while ( (elem = elem[ dir ]) ) { |
| 2443 | if ( elem.nodeType === 1 || checkNonElements ) { |
| 2444 | return matcher( elem, context, xml ); |
| 2445 | } |
| 2446 | } |
| 2447 | } : |
| 2448 | |
| 2449 | // Check against all ancestor/preceding elements |
| 2450 | function( elem, context, xml ) { |
| 2451 | var oldCache, uniqueCache, outerCache, |
| 2452 | newCache = [ dirruns, doneName ]; |
| 2453 | |
| 2454 | // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching |
| 2455 | if ( xml ) { |
| 2456 | while ( (elem = elem[ dir ]) ) { |
| 2457 | if ( elem.nodeType === 1 || checkNonElements ) { |
| 2458 | if ( matcher( elem, context, xml ) ) { |
| 2459 | return true; |
| 2460 | } |
| 2461 | } |
| 2462 | } |
| 2463 | } else { |
| 2464 | while ( (elem = elem[ dir ]) ) { |
| 2465 | if ( elem.nodeType === 1 || checkNonElements ) { |
| 2466 | outerCache = elem[ expando ] || (elem[ expando ] = {}); |
| 2467 | |
| 2468 | // Support: IE <9 only |
| 2469 | // Defend against cloned attroperties (jQuery gh-1709) |
| 2470 | uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); |
| 2471 | |
| 2472 | if ( (oldCache = uniqueCache[ dir ]) && |
| 2473 | oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { |
| 2474 | |
| 2475 | // Assign to newCache so results back-propagate to previous elements |
| 2476 | return (newCache[ 2 ] = oldCache[ 2 ]); |
| 2477 | } else { |
| 2478 | // Reuse newcache so results back-propagate to previous elements |
| 2479 | uniqueCache[ dir ] = newCache; |
| 2480 | |
| 2481 | // A match means we're done; a fail means we have to keep checking |
| 2482 | if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { |
| 2483 | return true; |
| 2484 | } |
| 2485 | } |
| 2486 | } |
| 2487 | } |
| 2488 | } |
| 2489 | }; |
| 2490 | } |
| 2491 | |