( tokens )
| 1737 | } |
| 1738 | |
| 1739 | function matcherFromTokens( tokens ) { |
| 1740 | var checkContext, matcher, j, |
| 1741 | len = tokens.length, |
| 1742 | leadingRelative = Expr.relative[ tokens[0].type ], |
| 1743 | implicitRelative = leadingRelative || Expr.relative[" "], |
| 1744 | i = leadingRelative ? 1 : 0, |
| 1745 | |
| 1746 | // The foundational matcher ensures that elements are reachable from top-level context(s) |
| 1747 | matchContext = addCombinator( function( elem ) { |
| 1748 | return elem === checkContext; |
| 1749 | }, implicitRelative, true ), |
| 1750 | |
| 1751 | matchAnyContext = addCombinator( function( elem ) { |
| 1752 | return indexOf.call( checkContext, elem ) > -1; |
| 1753 | }, implicitRelative, true ), |
| 1754 | |
| 1755 | matchers = [ function( elem, context, xml /*last*/) { |
| 1756 | return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( |
| 1757 | (checkContext = context).nodeType ? |
| 1758 | matchContext( elem, context, xml ) : |
| 1759 | matchAnyContext( elem, context, xml ) ); |
| 1760 | } ]; |
| 1761 | |
| 1762 | |
| 1763 | //拿出挑出种子集的数据的tokens,在继续分解,从左往右 |
| 1764 | for ( ; i < len; i++ ) { |
| 1765 | //遇到关系选择器处理 |
| 1766 | //把之前的分解关系先用elementMatcher生成遍历分解matchers闭包 |
| 1767 | //然后用addCombinator制作一个调用闭包 |
| 1768 | if ( (matcher = Expr.relative[ tokens[i].type ]) ) { |
| 1769 | matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; |
| 1770 | } else { |
| 1771 | |
| 1772 | //过滤 ATTR CHILD CLASS ID PSEUDO TAG |
| 1773 | matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); |
| 1774 | |
| 1775 | // Return special upon seeing a positional matcher |
| 1776 | if ( matcher[ expando ] ) { |
| 1777 | // Find the next relative operator (if any) for proper handling |
| 1778 | j = ++i; |
| 1779 | for ( ; j < len; j++ ) { |
| 1780 | if ( Expr.relative[ tokens[j].type ] ) { |
| 1781 | break; |
| 1782 | } |
| 1783 | } |
| 1784 | return setMatcher( |
| 1785 | i > 1 && elementMatcher( matchers ), |
| 1786 | i > 1 && toSelector( |
| 1787 | // If the preceding token was a descendant combinator, insert an implicit any-element `*` |
| 1788 | tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) |
| 1789 | ).replace( rtrim, "$1" ), |
| 1790 | matcher, |
| 1791 | i < j && matcherFromTokens( tokens.slice( i, j ) ), |
| 1792 | j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), |
| 1793 | j < len && toSelector( tokens ) |
| 1794 | ); |
| 1795 | } |
| 1796 | matchers.push( matcher ); |
no test coverage detected