| 1751 | } |
| 1752 | |
| 1753 | function matcherFromGroupMatchers(elementMatchers, setMatchers) { |
| 1754 | // A counter to specify which element is currently being matched |
| 1755 | var matcherCachedRuns = 0, |
| 1756 | bySet = setMatchers.length > 0, |
| 1757 | byElement = elementMatchers.length > 0, |
| 1758 | superMatcher = function(seed, context, xml, results, expandContext) { |
| 1759 | var elem, j, matcher, |
| 1760 | setMatched = [], |
| 1761 | matchedCount = 0, |
| 1762 | i = "0", |
| 1763 | unmatched = seed && [], |
| 1764 | outermost = expandContext != null, |
| 1765 | contextBackup = outermostContext, |
| 1766 | // We must always have either seed elements or context |
| 1767 | elems = seed || byElement && Expr.find["TAG"]("*", expandContext && context.parentNode || context), |
| 1768 | // Use integer dirruns iff this is the outermost matcher |
| 1769 | dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1); |
| 1770 | |
| 1771 | if (outermost) { |
| 1772 | outermostContext = context !== document && context; |
| 1773 | cachedruns = matcherCachedRuns; |
| 1774 | } |
| 1775 | |
| 1776 | // Add elements passing elementMatchers directly to results |
| 1777 | // Keep `i` a string if there are no elements so `matchedCount` will be "00" below |
| 1778 | for (; |
| 1779 | (elem = elems[i]) != null; i++) { |
| 1780 | if (byElement && elem) { |
| 1781 | j = 0; |
| 1782 | while ((matcher = elementMatchers[j++])) { |
| 1783 | if (matcher(elem, context, xml)) { |
| 1784 | results.push(elem); |
| 1785 | break; |
| 1786 | } |
| 1787 | } |
| 1788 | if (outermost) { |
| 1789 | dirruns = dirrunsUnique; |
| 1790 | cachedruns = ++matcherCachedRuns; |
| 1791 | } |
| 1792 | } |
| 1793 | |
| 1794 | // Track unmatched elements for set filters |
| 1795 | if (bySet) { |
| 1796 | // They will have gone through all possible matchers |
| 1797 | if ((elem = !matcher && elem)) { |
| 1798 | matchedCount--; |
| 1799 | } |
| 1800 | |
| 1801 | // Lengthen the array for every element, matched or not |
| 1802 | if (seed) { |
| 1803 | unmatched.push(elem); |
| 1804 | } |
| 1805 | } |
| 1806 | } |
| 1807 | |
| 1808 | // Apply set filters to unmatched elements |
| 1809 | matchedCount += i; |
| 1810 | if (bySet && i !== matchedCount) { |