11/**
22 * @typedef {import('./types.js').Rule } Rule
33 * @typedef {import('./types.js').RulePseudo } RulePseudo
4- * @typedef {import('./types.js').RulePseudoNth } RulePseudoNth
54 * @typedef {import('./types.js').RulePseudoSelector } RulePseudoSelector
65 * @typedef {import('./types.js').Parent } Parent
76 * @typedef {import('./types.js').Selector } Selector
@@ -16,9 +15,14 @@ import {parse as commas} from 'comma-separated-tokens'
1615import { hasProperty } from 'hast-util-has-property'
1716import { isElement } from 'hast-util-is-element'
1817import { whitespace } from 'hast-util-whitespace'
18+ import fauxEsmNthCheck from 'nth-check'
1919import { zwitch } from 'zwitch'
2020import { any } from './any.js'
2121
22+ /** @type {import('nth-check').default } */
23+ // @ts -expect-error
24+ const nthCheck = fauxEsmNthCheck . default || fauxEsmNthCheck
25+
2226/** @type {(rule: Rule | RulePseudo, element: Element, index: number | undefined, parent: Parent | undefined, state: SelectState) => boolean } */
2327const handle = zwitch ( 'name' , {
2428 unknown : unknownPseudo ,
@@ -375,64 +379,66 @@ function onlyChild(query, _1, _2, _3, state) {
375379}
376380
377381/**
378- * @param {RulePseudoNth } query
382+ * @param {RulePseudo } query
379383 * @param {Element } _1
380384 * @param {number | undefined } _2
381385 * @param {Parent | undefined } _3
382386 * @param {SelectState } state
383387 * @returns {boolean }
384388 */
385389function nthChild ( query , _1 , _2 , _3 , state ) {
390+ const fn = getCachedNthCheck ( query )
386391 assertDeep ( state , query )
387- return (
388- typeof state . elementIndex === 'number' && query . value ( state . elementIndex )
389- )
392+ return typeof state . elementIndex === 'number' && fn ( state . elementIndex )
390393}
391394
392395/**
393- * @param {RulePseudoNth } query
396+ * @param {RulePseudo } query
394397 * @param {Element } _1
395398 * @param {number | undefined } _2
396399 * @param {Parent | undefined } _3
397400 * @param {SelectState } state
398401 * @returns {boolean }
399402 */
400403function nthLastChild ( query , _1 , _2 , _3 , state ) {
404+ const fn = getCachedNthCheck ( query )
401405 assertDeep ( state , query )
402406 return Boolean (
403407 typeof state . elementCount === 'number' &&
404408 typeof state . elementIndex === 'number' &&
405- query . value ( state . elementCount - state . elementIndex - 1 )
409+ fn ( state . elementCount - state . elementIndex - 1 )
406410 )
407411}
408412
409413/**
410- * @param {RulePseudoNth } query
414+ * @param {RulePseudo } query
411415 * @param {Element } _1
412416 * @param {number | undefined } _2
413417 * @param {Parent | undefined } _3
414418 * @param {SelectState } state
415419 * @returns {boolean }
416420 */
417421function nthOfType ( query , _1 , _2 , _3 , state ) {
422+ const fn = getCachedNthCheck ( query )
418423 assertDeep ( state , query )
419- return typeof state . typeIndex === 'number' && query . value ( state . typeIndex )
424+ return typeof state . typeIndex === 'number' && fn ( state . typeIndex )
420425}
421426
422427/**
423- * @param {RulePseudoNth } query
428+ * @param {RulePseudo } query
424429 * @param {Element } _1
425430 * @param {number | undefined } _2
426431 * @param {Parent | undefined } _3
427432 * @param {SelectState } state
428433 * @returns {boolean }
429434 */
430435function nthLastOfType ( query , _1 , _2 , _3 , state ) {
436+ const fn = getCachedNthCheck ( query )
431437 assertDeep ( state , query )
432438 return (
433439 typeof state . typeCount === 'number' &&
434440 typeof state . typeIndex === 'number' &&
435- query . value ( state . typeCount - 1 - state . typeIndex )
441+ fn ( state . typeCount - 1 - state . typeIndex )
436442 )
437443}
438444
@@ -517,7 +523,7 @@ function unknownPseudo(query) {
517523
518524/**
519525 * @param {SelectState } state
520- * @param {RulePseudo | RulePseudoNth } query
526+ * @param {RulePseudo } query
521527 */
522528function assertDeep ( state , query ) {
523529 if ( state . shallow ) {
@@ -581,3 +587,22 @@ function appendScope(value) {
581587
582588 return selector
583589}
590+
591+ /**
592+ * @param {RulePseudo } query
593+ * @returns {(value: number) => boolean }
594+ */
595+ function getCachedNthCheck ( query ) {
596+ /** @type {(value: number) => boolean } */
597+ // @ts -expect-error: cache.
598+ let fn = query . _cachedFn
599+
600+ if ( ! fn ) {
601+ // @ts -expect-error: always string.
602+ fn = nthCheck ( query . value )
603+ // @ts -expect-error: cache.
604+ query . _cachedFn = fn
605+ }
606+
607+ return fn
608+ }
0 commit comments