jquery
Version:
JavaScript library for DOM operations
82 lines (66 loc) • 1.92 kB
JavaScript
import { jQuery } from "../core.js";
import { rcomma } from "./var/rcomma.js";
import { rleadingCombinator } from "./var/rleadingCombinator.js";
import { rtrimCSS } from "../var/rtrimCSS.js";
import { createCache } from "./createCache.js";
import { selectorError } from "./selectorError.js";
import { filterMatchExpr } from "./filterMatchExpr.js";
var tokenCache = createCache();
export function tokenize( selector, parseOnly ) {
var matched, match, tokens, type,
soFar, groups, preFilters,
cached = tokenCache[ selector + " " ];
if ( cached ) {
return parseOnly ? 0 : cached.slice( 0 );
}
soFar = selector;
groups = [];
preFilters = jQuery.expr.preFilter;
while ( soFar ) {
// Comma and first run
if ( !matched || ( match = rcomma.exec( soFar ) ) ) {
if ( match ) {
// Don't consume trailing commas as valid
soFar = soFar.slice( match[ 0 ].length ) || soFar;
}
groups.push( ( tokens = [] ) );
}
matched = false;
// Combinators
if ( ( match = rleadingCombinator.exec( soFar ) ) ) {
matched = match.shift();
tokens.push( {
value: matched,
// Cast descendant combinators to space
type: match[ 0 ].replace( rtrimCSS, " " )
} );
soFar = soFar.slice( matched.length );
}
// Filters
for ( type in filterMatchExpr ) {
if ( ( match = jQuery.expr.match[ type ].exec( soFar ) ) && ( !preFilters[ type ] ||
( match = preFilters[ type ]( match ) ) ) ) {
matched = match.shift();
tokens.push( {
value: matched,
type: type,
matches: match
} );
soFar = soFar.slice( matched.length );
}
}
if ( !matched ) {
break;
}
}
// Return the length of the invalid excess
// if we're just parsing
// Otherwise, throw an error or return tokens
if ( parseOnly ) {
return soFar.length;
}
return soFar ?
selectorError( selector ) :
// Cache the tokens
tokenCache( selector, groups ).slice( 0 );
}