import type { InternalSelector } from "./types" ; import { AttributeAction , SelectorType } from "css-what" ; import { procedure } from "./procedure" ; const attributes = { exists : 10 , equals : 8 , not : 7 , start : 6 , end : 6 , any : 5 , hyphen : 4 , element : 4 , } ; param arr 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 ) { let proc = procedure [ token . type ] ; if ( token . type === SelectorType . Attribute ) { proc = attributes [ token . action ] ; if ( proc === attributes . equals && token . name === "id" ) { proc = 9 ; } if ( token . ignoreCase ) { proc >>= 1 ; } } else if ( token . type === SelectorType . Pseudo ) { if ( ! token . data ) { proc = 3 ; } else if ( token . name === "has" || token . name === "contains" ) { proc = 0 ; } else if ( Array . isArray ( token . data ) ) { proc = 0 ; for ( let i = 0 ; i < token . data . length ; i ++ ) { if ( token . data [ i ] . length !== 1 ) continue ; const cur = getProcedure ( token . data [ i ] [ 0 ] ) ; if ( cur === 0 ) { proc = 0 ; break ; } if ( cur > proc ) proc = cur ; } if ( token . data . length > 1 && proc > 0 ) proc -= 1 ; } else { proc = 1 ; } } return proc ; }