jquery Selector Source code interpretation (iii): Tokenize method _jquery

Source: Internet
Author: User
Tags rtrim
The * * Tokenize method is the core function of the selector resolution, which converts the selector to a two-level array groups * For example: * If the selector is "Div.class,span", then the result of parsing is: * Group[0][0] = {type: ' TAG ', V Alue: ' div ', matches:match} * group[0][1] = {type: ' class ', Value: '. Class ', Matches:match} * group[1][0] = {type: ' TAG ', Valu E: ' span ', matches:match} * by the above results, we can see that each of the groups is a comma-separated selector block of the analytic result, * In addition, the results of the matches equals pattern matching results, because this is not convenient to write clearly, *
 So just write the code matches:match here. * * Tokenize method completes the following two main tasks: * 1, parse selector * 2, save the parsing result in the cache for later use * * * @param selector The selector string to be resolved @param parseonly is Tru E, the description of this call is a matching child selector * For example: If the initial selector is "Div:not (. Class:not (: eq (4))): EQ (3)" * Code first matches the tag Selector Div, * The matching pseudo selector string is: not (. cl Ass:not (: eq (4)): EQ (3), * The code will be ". Class:not (: eq (4))): EQ (3" As the value in the parentheses of not further parsing, * at this time the code in the call to Tokenize parsing,
 The parseonly parameter will pass in true. */function Tokenize (selector, parseonly) {var matched, match, tokens, type, sofar, groups, prefilters,//Get results in cache C

	ached = Tokencache[selector + ""]; * * If there is a selector corresponding resolution in the cache * then execute the statement body */if (cached) {//If the initial selector parsing (parseonly!=true),Returns the cached result,//If not, returns 0 return parseonly?
	0:cached.slice (0);  * * * because strings are not treated as objects in JavaScript, * so by assigning values, the code automatically copies a new string to Sofar, * so that any processing of SOFAR will not affect the original data of selector * * Sofar
	= selector;
	groups = [];

	This assignment is only used to reduce the number of words followed by the code, shortening the execution path prefilters = Expr.prefilter; while (SOFAR) {//Comma and A/* Rcomma = new RegExp ("^" + whitespace + "*," + whitespace + "*") * r
		 The comma is used to determine whether there are multiple selector blocks, that is, multiple parallel selectors separated by commas * * The following conditions are determined to be: *!matched: True if the first execution of the loop body, or false.
		 * Here matched is the identity of the loop body for the first time, * Also as a flag in this loop sofar whether to start with an illegal string (that is, a non-legitimate single selector). * (match = rcomma.exec (Sofar): Get a match with Rcomma/if (!matched | | (match = Rcomma.exec (Sofar)) {if (match) {//Don ' t consume trailing commas as valid * * Remove the first comma and all previous characters * For example: * If the initial selector is 
				 : "Div.news,span.closed", * in the parsing process, first parsed by the subsequent code div.news, leaving ", span.closed" * In the loop body to execute here, the comma and the previous continuous blank (match[0]) deleted, * Make Sofar into "span.closed", continue parsing process * Here, if the last non-white-space character of the initial selector is funny#, * then sofar the following code, that is, Sofar.slice (match[0].length) returns an empty string, * So the final return is | | Back Sofar * * Sofar = Sofar.slice (match[0].length) | |
			Sofar;
		* * * The first time the loop body is executed or the comma delimiter is encountered, the tokens assignment to an empty array, * simultaneously pressing into the groups array/groups.push (tokens = []);

		} matched = false;  combinators * * rcombinators = new RegExp (* "^" + whitespace + "* ([>+~]|" + whitespace + ")" + whitespace + "*"), * rcombinators is used to match four relationship characters, that is, >+~ and blank * * If the sofar begins with a relationship, execute the statement body in the IF (match = Rcombinators.exe C (SOFAR))) {* * match[0] removes the match array and assigns it to matched * If the original relationship character has spaces on either side, then match[0 is not equal to matched * For example: * if s
			 Ofar = "+. Div";
			 * Execute match = rcombinators.exec (Sofar), * match[0] = "+", and match[1]= "+";
			 * After the completion of matched = Match.shift (), * matched= "+", and match[0]= "+";
			* * matched = Match.shift (); Presses the matching result into the tokens array Tokens.push ({value:matched,//Cast descendant combinators to spaces/* RTrim = new RegExp ("^"+ whitespace + "+| ((?:^| [^\\\\]) (?:\ \\\.)
				 *) "* + whitespace +" +$ "," G "), * whitespace =" [\\x20\\t\\r\\n\\f] ";
				 * * Below Match[0].replace (RTrim, "") is to replace the left and right sides of the match[0] blank space * But because of its match.shift role, Match[0] is a string with no white space on both sides,
			
			* Therefore, the replacement is no use code */Type:match[0].replace (RTrim, "")});
		Assigns the string after the relationship character to Sofar, continues to parse Sofar = Sofar.slice (matched.length); ///Filters/* Following the Sofar matching ID, TAG, CLASS, child, ATTR, pseudo type by using the For statement, the filter function corresponding to the type selector is called first, and then the
		 The results are pressed into the tokens array to continue this cycle. * * (type in expr.filter) {/* match = Matchexpr[type].exec (Sofar): matches the sofar with a regular expression that calls type type Sofar, * and Match results are given.
			 If the data is not matched, match is undefined. *!prefilters[type]: true * match = Prefilters[type] (match) If no filter function of type types exists: Performs a filter and returns the result to match * */if ( (match = Matchexpr[type].exec (Sofar)) && (!prefilters[type] | | (match = Prefilters[type] (match)) {//match[0] removes the match array and assigns it to the matched Matched = Match.shift ();
				The matching result is pressed into the tokens array Tokens.push ({value:matched, Type:type, matches:match});
			Assigns the string after the match result to Sofar, continues to parse Sofar = Sofar.slice (matched.length); }/* If Matched==false, * indicates that there is no valid selector for this cycle (including the relationship character and ID, class, etc.) * Therefore, parsing to the current position left Sofar is illegal selector string * jump out of WH
		Ile Circulation Body */if (!matched) {break; 
	}//Return the length of the invalid excess//If we ' re just parsing//otherwise, throw a error or return tokens * * If the initial selector string is not parsed (!parseonly==true), the * returns SOFAR.LENGTH, at which point the sofar.length represents a continuous and valid selector final position, * the following article will be illustrated with an example * if the The initial selector string is parsed to see if Sofar has a character, * if so, the execution Sizzle.error (selector) throws an exception; * If not, execute Tokencache (selector, groups). Slice (0) Press the result into
	 Cache, and returns a copy of the result. * * return parseonly? SoFar.length:soFar?
Sizzle.error (selector)://Cache the Tokens Tokencache (selector, groups). Slice (0); }

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.