[6a3a178] | 1 | "use strict";
|
---|
| 2 | Object.defineProperty(exports, "__esModule", { value: true });
|
---|
| 3 | var procedure_1 = require("./procedure");
|
---|
| 4 | var 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 | */
|
---|
| 21 | function 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 | }
|
---|
| 36 | exports.default = sortByProcedure;
|
---|
| 37 | function 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 | }
|
---|