JQuery selector source code (4): Expr. preFilter and jquerytokenize of the tokenize Method
Expr. preFilter is a preprocessing method for ATTR, CHILD, and PSEUDO selectors in the tokenize method. The details are as follows:
Expr. preFilter: {"ATTR": function (match) {/** to complete the following tasks: * 1. attribute name decoding * 2. Attribute Value decoding * 3. If the judgment character is ~ =, A space is added on both sides of the property value * 4. The final mtach object ** match [1] is returned to indicate the property name, * match [1]. replace (runescape, funescape): decodes the hexadecimal number in the attribute name into * single-byte unicode character or double-byte unicode character (Chinese or other text that requires two bytes) * For a detailed description of the regular expression, refer to my "jQuery selector regular expression" article */match [1] = match [1]. replace (runescape, funescape);/** decodes attribute values * match [4]: attribute values placed in single or double quotation marks * match [5]: indicates the attribute value without quotation marks */match [3] = (match [4] | match [5] | ""). replace (runescape, funescape );/**~ = Indicates word matching. In W3C, the definition of a word is a blank separator for different words. * therefore, after spaces are added on both sides of match [3], indexOf can be used, correctly identifies whether the word exists */if (match [2] = "~ = ") {Match [3] =" "+ match [3] +" ";}/** returns the first four useful element results */return match. slice (0, 4) ;}, "CHILD": function (match) {/** to complete the following tasks: * 1. Convert the characters before child and of-type in the command to lowercase characters * 2. Check the Data Validity in brackets for the selector starting with nth * 3. match [4] and match [5] respectively Store x and B in xn + B, x and B can be negative * 4. Return the final match object ** match [1] :( only | first | last | nth-last) */match [1] = match [1]. toLowerCase ();/** four types of brackets, nth-child, nth-of-type, nth-last-child, and nth-last-of-type, must be set. Set valid data * while other parameters cannot contain any data */if (match [1]. slice (0, 3) = "nth") {/** if no valid parameter exists in the selector brackets, an exception is thrown * example: if the selector is nth or nth (abc) it is an invalid selector */if (! Match [3]) {Sizzle. error (match [0]);}/** the following uses nth-child () as an example to describe the syntax, to better understand the role of the following code * nth-child allows the following usage methods: *: nth-child (even) *: nth-child (odd )*: nth-child (3n) *: nth-child (+ 2n + 1) *: nth-child (2n-1) * In the following code, match [4] and match [5] on the left of the assigned number are used to record the values before and after n in the brackets, including the plus and minus signs. *: for nth-child (even) and: nth-child (odd), match [4] is null, * therefore, 2 * is returned (match [3] === "even" | match [3] === "odd ") * Because true = 1, false = 0 in js, (match [3] =" Even "| match [3] ===" odd ") equal to 1 * therefore, 2 * (match [3] === "even" | match [3] === "odd ") the calculation result is 2 ** + on the right side of the equal sign to force type conversion, convert the subsequent string to the numeric type */match [4] = + (match [4]? Match [5] + (match [6] | 1 ): 2 * (match [3] === "even" | match [3] === "odd ")); match [5] = + (match [7] + match [8]) | match [3] = "odd ");} else if (match [3]) {/** if other CHILD type selectors without nth headers have brackets, an exception is thrown. * jQuery is not determined strictly according to W3C rules, because it allows this form of: first-child () to exist * That is, for jQuery: first-child () is equivalent to: first-child, which is a valid selector */Sizzle. error (match [0]);} return match;}, "PSEUDO": function (match) {/** to complete the following tasks: * 1. Obtain the value enclosed by quotation marks in a pseudo class. * 2. For values enclosed by non-quotation marks, if pseudo-class nesting exists, the actual end position of the current pseudo-class will be further resolved and determined, * obtain the complete string and value of the current pseudo-class * 3. Return the first three copies of the match. ** Unquoted indicates the value enclosed by non-quotation marks in the brackets. * For example, in eq (2), unquoted = 2 */var excess, unquoted =! Match [5] & match [2];/** because the matching Regular Expression of pseudo and child has an intersection, ignore the child part */if (matchExpr ["CHILD"]. test (match [0]) {return null;}/** if the values in the brackets are enclosed by quotation marks (match [3, * The value except the quotation marks (match [4]) is assigned to match [2]. * Match [3] indicates quotation marks. */If (match [3] & match [4]! = Undefined) {match [2] = match [4];} else if (unquoted/** rpseudo. test (unquoted): used to test whether unquoted contains a pseudo class. * if it contains a pseudo class, it indicates that there may be a possibility of pseudo-class nesting. Further unquoted Parsing is required. * For example :: not (: eq (3) */& rpseudo. test (unquoted) &/** obtains the position of the last character continuously valid in unquoted */(excess = tokenize (unquoted, true) &/** unquoted. indexOf (")", unquoted. length-excess) * Find the ")" position after the last character position of the continuously valid selector obtained previously, * usually after the current position. * Subtract unquoted. length is used to obtain the final position of the valid and Complete Pseudo-class string in match [0]. * Note that excess is a negative value. **/(excess = unquoted. indexOf (")", unquoted. length-excess)-unquoted. length) {// obtain valid full pseudo-class match [0] and data in pseudo-class brackets match [2] match [0] = match [0]. slice (0, excess); match [2] = unquoted. slice (0, excess);} // return the copy of the first three elements of match return match. slice (0, 3 );}}