| 1802 | } |
| 1803 | |
| 1804 | function matcherFromGroupMatchers( elementMatchers, setMatchers ) { |
| 1805 | var bySet = setMatchers.length > 0, |
| 1806 | byElement = elementMatchers.length > 0, |
| 1807 | |
| 1808 | superMatcher = function( seed, context, xml, results, outermost ) { |
| 1809 | var elem, j, matcher, |
| 1810 | matchedCount = 0, |
| 1811 | i = "0", |
| 1812 | unmatched = seed && [], |
| 1813 | setMatched = [], |
| 1814 | contextBackup = outermostContext, |
| 1815 | // We must always have either seed elements or outermost context |
| 1816 | elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), |
| 1817 | // Use integer dirruns iff this is the outermost matcher |
| 1818 | dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), |
| 1819 | len = elems.length; |
| 1820 | |
| 1821 | if ( outermost ) { |
| 1822 | outermostContext = context !== document && context; |
| 1823 | } |
| 1824 | |
| 1825 | // Add elements passing elementMatchers directly to results |
| 1826 | // Keep `i` a string if there are no elements so `matchedCount` will be "00" below |
| 1827 | // Support: IE<9, Safari |
| 1828 | // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id |
| 1829 | for ( ; i !== len && (elem = elems[i]) != null; i++ ) { |
| 1830 | if ( byElement && elem ) { |
| 1831 | j = 0; |
| 1832 | while ( (matcher = elementMatchers[j++]) ) { |
| 1833 | if ( matcher( elem, context, xml ) ) { |
| 1834 | results.push( elem ); |
| 1835 | break; |
| 1836 | } |
| 1837 | } |
| 1838 | if ( outermost ) { |
| 1839 | dirruns = dirrunsUnique; |
| 1840 | } |
| 1841 | } |
| 1842 | |
| 1843 | // Track unmatched elements for set filters |
| 1844 | if ( bySet ) { |
| 1845 | // They will have gone through all possible matchers |
| 1846 | if ( (elem = !matcher && elem) ) { |
| 1847 | matchedCount--; |
| 1848 | } |
| 1849 | |
| 1850 | // Lengthen the array for every element, matched or not |
| 1851 | if ( seed ) { |
| 1852 | unmatched.push( elem ); |
| 1853 | } |
| 1854 | } |
| 1855 | } |
| 1856 | |
| 1857 | // Apply set filters to unmatched elements |
| 1858 | matchedCount += i; |
| 1859 | if ( bySet && i !== matchedCount ) { |
| 1860 | j = 0; |
| 1861 | while ( (matcher = setMatchers[j++]) ) { |