MCPcopy Create free account
hub / github.com/JsAaron/jQuery / matcherFromTokens

Function matcherFromTokens

2.0.3/Sizzle-annotation.js:1870–1939  ·  view source on GitHub ↗
(tokens)

Source from the content-addressed store, hash-verified

1868 //Sizzle巧妙的就是它没有直接将拿到的“分词”结果与Expr中的方法逐个匹配逐个执行,
1869 //而是先根据规则组合出一个大的匹配方法,最后一步执行。但是组合之后怎么执行的
1870 function matcherFromTokens(tokens) {
1871 var checkContext, matcher, j,
1872 len = tokens.length,
1873 leadingRelative = Expr.relative[tokens[0].type],
1874 implicitRelative = leadingRelative || Expr.relative[" "], //亲密度关系
1875 i = leadingRelative ? 1 : 0,
1876
1877 // The foundational matcher ensures that elements are reachable from top-level context(s)
1878 // 确保这些元素可以在context中找到
1879 matchContext = addCombinator(function(elem) {
1880 return elem === checkContext;
1881 }, implicitRelative, true),
1882
1883 matchAnyContext = addCombinator(function(elem) {
1884 return indexOf.call(checkContext, elem) > -1;
1885 }, implicitRelative, true),
1886
1887 //这里用来确定元素在哪个context
1888 matchers = [
1889 function(elem, context, xml) {
1890 return (!leadingRelative && (xml || context !== outermostContext)) || (
1891 (checkContext = context).nodeType ?
1892 matchContext(elem, context, xml) :
1893 matchAnyContext(elem, context, xml));
1894 }
1895 ];
1896
1897 for (; i < len; i++) {
1898 // Expr.relative 匹配关系选择器类型
1899 // "空 > ~ +"
1900 if ((matcher = Expr.relative[tokens[i].type])) {
1901 //当遇到关系选择器时elementMatcher函数将matchers数组中的函数生成一个函数
1902 //(elementMatcher利用了闭包所以matchers一直存在内存中)
1903 matchers = [addCombinator(elementMatcher(matchers), matcher)];
1904 } else {
1905 //过滤 ATTR CHILD CLASS ID PSEUDO TAG
1906 matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches);
1907
1908 // Return special upon seeing a positional matcher
1909 //返回一个特殊的位置匹配函数
1910 //伪类会把selector分两部分
1911 if (matcher[expando]) {
1912 // Find the next relative operator (if any) for proper handling
1913 // 发现下一个关系操作符(如果有话)并做适当处理
1914 j = ++i;
1915 for (; j < len; j++) {
1916 if (Expr.relative[tokens[j].type]) { //如果位置伪类后面还有关系选择器还需要筛选
1917 break;
1918 }
1919 }
1920 return setMatcher(
1921 i > 1 && elementMatcher(matchers),
1922 i > 1 && toSelector(
1923 // If the preceding token was a descendant combinator, insert an implicit any-element `*`
1924 tokens.slice(0, i - 1).concat({
1925 value: tokens[i - 2].type === " " ? "*" : ""
1926 })
1927 ).replace(rtrim, "$1"),

Callers 1

Calls 4

addCombinatorFunction · 0.70
elementMatcherFunction · 0.70
setMatcherFunction · 0.70
toSelectorFunction · 0.70

Tested by

no test coverage detected