UNPKG

2.44 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3var procedure_1 = require("./procedure");
4var attributes = {
5 exists: 10,
6 equals: 8,
7 not: 7,
8 start: 6,
9 end: 6,
10 any: 5,
11 hyphen: 4,
12 element: 4,
13};
14/**
15 * Sort the parts of the passed selector,
16 * as there is potential for optimization
17 * (some types of selectors are faster than others)
18 *
19 * @param arr Selector to sort
20 */
21function sortByProcedure(arr) {
22 var procs = arr.map(getProcedure);
23 for (var i = 1; i < arr.length; i++) {
24 var procNew = procs[i];
25 if (procNew < 0)
26 continue;
27 for (var j = i - 1; j >= 0 && procNew < procs[j]; j--) {
28 var token = arr[j + 1];
29 arr[j + 1] = arr[j];
30 arr[j] = token;
31 procs[j + 1] = procs[j];
32 procs[j] = procNew;
33 }
34 }
35}
36exports.default = sortByProcedure;
37function getProcedure(token) {
38 var proc = procedure_1.procedure[token.type];
39 if (token.type === "attribute") {
40 proc = attributes[token.action];
41 if (proc === attributes.equals && token.name === "id") {
42 // Prefer ID selectors (eg. #ID)
43 proc = 9;
44 }
45 if (token.ignoreCase) {
46 /*
47 * IgnoreCase adds some overhead, prefer "normal" token
48 * this is a binary operation, to ensure it's still an int
49 */
50 proc >>= 1;
51 }
52 }
53 else if (token.type === "pseudo") {
54 if (!token.data) {
55 proc = 3;
56 }
57 else if (token.name === "has" || token.name === "contains") {
58 proc = 0; // Expensive in any case
59 }
60 else if (Array.isArray(token.data)) {
61 // "matches" and "not"
62 proc = 0;
63 for (var i = 0; i < token.data.length; i++) {
64 // TODO better handling of complex selectors
65 if (token.data[i].length !== 1)
66 continue;
67 var cur = getProcedure(token.data[i][0]);
68 // Avoid executing :has or :contains
69 if (cur === 0) {
70 proc = 0;
71 break;
72 }
73 if (cur > proc)
74 proc = cur;
75 }
76 if (token.data.length > 1 && proc > 0)
77 proc -= 1;
78 }
79 else {
80 proc = 1;
81 }
82 }
83 return proc;
84}