| 2133 | } |
| 2134 | |
| 2135 | function addCombinator( matcher, combinator, base ) { |
| 2136 | var dir = combinator.dir, |
| 2137 | checkNonElements = base && dir === "parentNode", |
| 2138 | doneName = done++; |
| 2139 | |
| 2140 | return combinator.first ? |
| 2141 | // Check against closest ancestor/preceding element |
| 2142 | function( elem, context, xml ) { |
| 2143 | while ( (elem = elem[ dir ]) ) { |
| 2144 | if ( elem.nodeType === 1 || checkNonElements ) { |
| 2145 | return matcher( elem, context, xml ); |
| 2146 | } |
| 2147 | } |
| 2148 | } : |
| 2149 | |
| 2150 | // Check against all ancestor/preceding elements |
| 2151 | function( elem, context, xml ) { |
| 2152 | var oldCache, uniqueCache, outerCache, |
| 2153 | newCache = [ dirruns, doneName ]; |
| 2154 | |
| 2155 | // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching |
| 2156 | if ( xml ) { |
| 2157 | while ( (elem = elem[ dir ]) ) { |
| 2158 | if ( elem.nodeType === 1 || checkNonElements ) { |
| 2159 | if ( matcher( elem, context, xml ) ) { |
| 2160 | return true; |
| 2161 | } |
| 2162 | } |
| 2163 | } |
| 2164 | } else { |
| 2165 | while ( (elem = elem[ dir ]) ) { |
| 2166 | if ( elem.nodeType === 1 || checkNonElements ) { |
| 2167 | outerCache = elem[ expando ] || (elem[ expando ] = {}); |
| 2168 | |
| 2169 | // Support: IE <9 only |
| 2170 | // Defend against cloned attroperties (jQuery gh-1709) |
| 2171 | uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); |
| 2172 | |
| 2173 | if ( (oldCache = uniqueCache[ dir ]) && |
| 2174 | oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { |
| 2175 | |
| 2176 | // Assign to newCache so results back-propagate to previous elements |
| 2177 | return (newCache[ 2 ] = oldCache[ 2 ]); |
| 2178 | } else { |
| 2179 | // Reuse newcache so results back-propagate to previous elements |
| 2180 | uniqueCache[ dir ] = newCache; |
| 2181 | |
| 2182 | // A match means we're done; a fail means we have to keep checking |
| 2183 | if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { |
| 2184 | return true; |
| 2185 | } |
| 2186 | } |
| 2187 | } |
| 2188 | } |
| 2189 | } |
| 2190 | }; |
| 2191 | } |
| 2192 | |