You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			79 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			JavaScript
		
	
			
		
		
	
	
			79 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			JavaScript
		
	
| import { AttributeAction, SelectorType } from "css-what";
 | |
| const procedure = new Map([
 | |
|     [SelectorType.Universal, 50],
 | |
|     [SelectorType.Tag, 30],
 | |
|     [SelectorType.Attribute, 1],
 | |
|     [SelectorType.Pseudo, 0],
 | |
| ]);
 | |
| export function isTraversal(token) {
 | |
|     return !procedure.has(token.type);
 | |
| }
 | |
| const attributes = new Map([
 | |
|     [AttributeAction.Exists, 10],
 | |
|     [AttributeAction.Equals, 8],
 | |
|     [AttributeAction.Not, 7],
 | |
|     [AttributeAction.Start, 6],
 | |
|     [AttributeAction.End, 6],
 | |
|     [AttributeAction.Any, 5],
 | |
| ]);
 | |
| /**
 | |
|  * Sort the parts of the passed selector,
 | |
|  * as there is potential for optimization
 | |
|  * (some types of selectors are faster than others)
 | |
|  *
 | |
|  * @param arr Selector to sort
 | |
|  */
 | |
| export default function sortByProcedure(arr) {
 | |
|     const procs = arr.map(getProcedure);
 | |
|     for (let i = 1; i < arr.length; i++) {
 | |
|         const procNew = procs[i];
 | |
|         if (procNew < 0)
 | |
|             continue;
 | |
|         for (let j = i - 1; j >= 0 && procNew < procs[j]; j--) {
 | |
|             const token = arr[j + 1];
 | |
|             arr[j + 1] = arr[j];
 | |
|             arr[j] = token;
 | |
|             procs[j + 1] = procs[j];
 | |
|             procs[j] = procNew;
 | |
|         }
 | |
|     }
 | |
| }
 | |
| function getProcedure(token) {
 | |
|     var _a, _b;
 | |
|     let proc = (_a = procedure.get(token.type)) !== null && _a !== void 0 ? _a : -1;
 | |
|     if (token.type === SelectorType.Attribute) {
 | |
|         proc = (_b = attributes.get(token.action)) !== null && _b !== void 0 ? _b : 4;
 | |
|         if (token.action === AttributeAction.Equals && token.name === "id") {
 | |
|             // Prefer ID selectors (eg. #ID)
 | |
|             proc = 9;
 | |
|         }
 | |
|         if (token.ignoreCase) {
 | |
|             /*
 | |
|              * IgnoreCase adds some overhead, prefer "normal" token
 | |
|              * this is a binary operation, to ensure it's still an int
 | |
|              */
 | |
|             proc >>= 1;
 | |
|         }
 | |
|     }
 | |
|     else if (token.type === SelectorType.Pseudo) {
 | |
|         if (!token.data) {
 | |
|             proc = 3;
 | |
|         }
 | |
|         else if (token.name === "has" || token.name === "contains") {
 | |
|             proc = 0; // Expensive in any case
 | |
|         }
 | |
|         else if (Array.isArray(token.data)) {
 | |
|             // Eg. :matches, :not
 | |
|             proc = Math.min(...token.data.map((d) => Math.min(...d.map(getProcedure))));
 | |
|             // If we have traversals, try to avoid executing this selector
 | |
|             if (proc < 0) {
 | |
|                 proc = 0;
 | |
|             }
 | |
|         }
 | |
|         else {
 | |
|             proc = 2;
 | |
|         }
 | |
|     }
 | |
|     return proc;
 | |
| }
 | |
| //# sourceMappingURL=sort.js.map
 |