| 2172 | } |
| 2173 | |
| 2174 | function addCombinator( matcher, combinator, base ) { |
| 2175 | var dir = combinator.dir, |
| 2176 | checkNonElements = base && dir === "parentNode", |
| 2177 | doneName = done++; |
| 2178 | |
| 2179 | return combinator.first ? |
| 2180 | // Check against closest ancestor/preceding element |
| 2181 | function( elem, context, xml ) { |
| 2182 | while ( (elem = elem[ dir ]) ) { |
| 2183 | if ( elem.nodeType === 1 || checkNonElements ) { |
| 2184 | return matcher( elem, context, xml ); |
| 2185 | } |
| 2186 | } |
| 2187 | } : |
| 2188 | |
| 2189 | // Check against all ancestor/preceding elements |
| 2190 | function( elem, context, xml ) { |
| 2191 | var oldCache, uniqueCache, outerCache, |
| 2192 | newCache = [ dirruns, doneName ]; |
| 2193 | |
| 2194 | // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching |
| 2195 | if ( xml ) { |
| 2196 | while ( (elem = elem[ dir ]) ) { |
| 2197 | if ( elem.nodeType === 1 || checkNonElements ) { |
| 2198 | if ( matcher( elem, context, xml ) ) { |
| 2199 | return true; |
| 2200 | } |
| 2201 | } |
| 2202 | } |
| 2203 | } else { |
| 2204 | while ( (elem = elem[ dir ]) ) { |
| 2205 | if ( elem.nodeType === 1 || checkNonElements ) { |
| 2206 | outerCache = elem[ expando ] || (elem[ expando ] = {}); |
| 2207 | |
| 2208 | // Support: IE <9 only |
| 2209 | // Defend against cloned attroperties (jQuery gh-1709) |
| 2210 | uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); |
| 2211 | |
| 2212 | if ( (oldCache = uniqueCache[ dir ]) && |
| 2213 | oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { |
| 2214 | |
| 2215 | // Assign to newCache so results back-propagate to previous elements |
| 2216 | return (newCache[ 2 ] = oldCache[ 2 ]); |
| 2217 | } else { |
| 2218 | // Reuse newcache so results back-propagate to previous elements |
| 2219 | uniqueCache[ dir ] = newCache; |
| 2220 | |
| 2221 | // A match means we're done; a fail means we have to keep checking |
| 2222 | if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { |
| 2223 | return true; |
| 2224 | } |
| 2225 | } |
| 2226 | } |
| 2227 | } |
| 2228 | } |
| 2229 | }; |
| 2230 | } |
| 2231 | |