From 6f16614ec945f132aecce1e7d9c4332a9f7ea36f Mon Sep 17 00:00:00 2001 From: Titus Wormer Date: Mon, 6 Nov 2023 16:55:07 +0100 Subject: [PATCH] Update `css-selector-parser` --- lib/attribute.js | 24 +----------------------- lib/pseudo.js | 42 +----------------------------------------- lib/test.js | 32 +++++++++++++++++++------------- package.json | 2 +- 4 files changed, 22 insertions(+), 78 deletions(-) diff --git a/lib/attribute.js b/lib/attribute.js index 8979cf2..c8fbe9c 100644 --- a/lib/attribute.js +++ b/lib/attribute.js @@ -7,28 +7,6 @@ import {ok as assert} from 'devlop' import {indexable} from './util.js' -/** - * @param {AstRule} query - * Query. - * @param {Node} node - * Node. - * @returns {boolean} - * Whether `node` matches `query`. - */ -export function attributes(query, node) { - let index = -1 - - if (query.attributes) { - while (++index < query.attributes.length) { - if (!attribute(query.attributes[index], node)) { - return false - } - } - } - - return true -} - /** * @param {AstAttribute} query * Query. @@ -38,7 +16,7 @@ export function attributes(query, node) { * Whether `node` matches `query`. */ -function attribute(query, node) { +export function attribute(query, node) { indexable(node) const value = node[query.name] diff --git a/lib/pseudo.js b/lib/pseudo.js index f365185..8b930bb 100644 --- a/lib/pseudo.js +++ b/lib/pseudo.js @@ -1,5 +1,4 @@ /** - * @typedef {import('css-selector-parser').AstRule} AstRule * @typedef {import('css-selector-parser').AstPseudoClass} AstPseudoClass * @typedef {import('unist').Node} Node * @typedef {import('unist').Parent} Parent @@ -17,7 +16,7 @@ import {walk} from './walk.js' const nthCheck = fauxEsmNthCheck.default || fauxEsmNthCheck /** @type {(rule: AstPseudoClass, node: Node, index: number | undefined, parent: Parent | undefined, state: SelectState) => boolean} */ -const handle = zwitch('name', { +export const pseudo = zwitch('name', { // @ts-expect-error: always known. unknown: unknownPseudo, invalid: invalidPseudo, @@ -42,45 +41,6 @@ const handle = zwitch('name', { } }) -pseudo.needsIndex = [ - 'any', - 'first-child', - 'first-of-type', - 'last-child', - 'last-of-type', - 'is', - 'not', - 'nth-child', - 'nth-last-child', - 'nth-of-type', - 'nth-last-of-type', - 'only-child', - 'only-of-type' -] - -/** - * Check whether an node matches pseudo selectors. - * - * @param {AstRule} query - * @param {Node} node - * @param {number | undefined} index - * @param {Parent | undefined} parent - * @param {SelectState} state - * @returns {boolean} - */ -export function pseudo(query, node, index, parent, state) { - let offset = -1 - - if (query.pseudoClasses) { - while (++offset < query.pseudoClasses.length) { - if (!handle(query.pseudoClasses[offset], node, index, parent, state)) - return false - } - } - - return true -} - /** * Check whether a node matches an `:empty` pseudo. * diff --git a/lib/test.js b/lib/test.js index 53c6774..7e4ebc6 100644 --- a/lib/test.js +++ b/lib/test.js @@ -5,7 +5,7 @@ * @typedef {import('./types.js').SelectState} SelectState */ -import {attributes} from './attribute.js' +import {attribute} from './attribute.js' import {pseudo} from './pseudo.js' /** @@ -17,18 +17,24 @@ import {pseudo} from './pseudo.js' * @returns {boolean} */ export function test(query, node, index, parent, state) { - if (query.ids) throw new Error('Invalid selector: id') - if (query.classNames) throw new Error('Invalid selector: class') - if (query.pseudoElement) { - throw new Error('Invalid selector: `::' + query.pseudoElement + '`') + for (const item of query.items) { + // eslint-disable-next-line unicorn/prefer-switch + if (item.type === 'Attribute') { + if (!attribute(item, node)) return false + } else if (item.type === 'Id') { + throw new Error('Invalid selector: id') + } else if (item.type === 'ClassName') { + throw new Error('Invalid selector: class') + } else if (item.type === 'PseudoClass') { + if (!pseudo(item, node, index, parent, state)) return false + } else if (item.type === 'PseudoElement') { + throw new Error('Invalid selector: `::' + item.name + '`') + } else if (item.type === 'TagName') { + if (item.name !== node.type) return false + } else { + // Otherwise `item.type` is `WildcardTag`, which matches. + } } - return Boolean( - node && - (!query.tag || - query.tag.type === 'WildcardTag' || - query.tag.name === node.type) && - (!query.attributes || attributes(query, node)) && - (!query.pseudoClasses || pseudo(query, node, index, parent, state)) - ) + return true } diff --git a/package.json b/package.json index 14de040..ba3a874 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ ], "dependencies": { "@types/unist": "^3.0.0", - "css-selector-parser": "^2.0.0", + "css-selector-parser": "^3.0.0", "devlop": "^1.1.0", "nth-check": "^2.0.0", "zwitch": "^2.0.0"