Skip to content

Commit 3142384

Browse files
committed
Refactor to simplify has handling
1 parent b600536 commit 3142384

File tree

3 files changed

+11
-55
lines changed

3 files changed

+11
-55
lines changed

lib/parse.js

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/**
22
* @typedef {import('./types.js').Selectors} Selectors
3+
* @typedef {import('./types.js').RuleSet} RuleSet
34
*/
45

56
import {CssSelectorParser} from 'css-selector-parser'
@@ -12,23 +13,12 @@ parser.registerNestingOperators('>', '+', '~')
1213

1314
/**
1415
* @param {string} selector
15-
* @returns {Selectors}
16+
* @returns {Selectors|RuleSet|undefined}
1617
*/
1718
export function parse(selector) {
1819
if (typeof selector !== 'string') {
1920
throw new TypeError('Expected `string` as selector, not `' + selector + '`')
2021
}
2122

22-
const query = parser.parse(selector)
23-
24-
// Empty selectors object doesn’t match anything.
25-
if (!query) {
26-
return {type: 'selectors', selectors: []}
27-
}
28-
29-
if (query.type === 'selectors') {
30-
return query
31-
}
32-
33-
return {type: 'selectors', selectors: [query]}
23+
return parser.parse(selector)
3424
}

lib/pseudo.js

Lines changed: 7 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
/**
22
* @typedef {import('./types.js').Rule} Rule
3+
* @typedef {import('./types.js').RuleSet} RuleSet
34
* @typedef {import('./types.js').RulePseudo} RulePseudo
45
* @typedef {import('./types.js').RulePseudoSelector} RulePseudoSelector
56
* @typedef {import('./types.js').Parent} Parent
6-
* @typedef {import('./types.js').Selector} Selector
77
* @typedef {import('./types.js').Selectors} Selectors
88
* @typedef {import('./types.js').SelectState} SelectState
9+
* @typedef {import('./types.js').Root} Root
910
* @typedef {import('./types.js').Element} Element
1011
* @typedef {import('./types.js').ElementChild} ElementChild
1112
*/
@@ -103,8 +104,7 @@ export function pseudo(query, element, index, parent, state) {
103104
* @returns {boolean}
104105
*/
105106
function matches(query, element, _, parent, state) {
106-
const shallow = state.shallow
107-
const one = state.one
107+
const {shallow, one} = state
108108

109109
state.shallow = false
110110
state.one = true
@@ -344,7 +344,6 @@ function lang(query, _1, _2, _3, state) {
344344
return (
345345
state.language !== '' &&
346346
state.language !== undefined &&
347-
state.language !== undefined &&
348347
// @ts-expect-error never `selectors`.
349348
extendedFilter(state.language, commas(query.value)).length > 0
350349
)
@@ -540,16 +539,15 @@ function assertDeep(state, query) {
540539
* @returns {boolean}
541540
*/
542541
function has(query, element, _1, _2, state) {
543-
const shallow = state.shallow
544-
const one = state.one
545-
const scopeElements = state.scopeElements
546-
const value = appendScope(query.value)
542+
/** @type {Root} */
543+
const fragment = {type: 'root', children: element.children}
544+
const {shallow, one, scopeElements} = state
547545

548546
state.shallow = false
549547
state.one = true
550548
state.scopeElements = [element]
551549

552-
const result = any(value, element, state).length > 0
550+
const result = any(query.value, fragment, state).length > 0
553551

554552
state.shallow = shallow
555553
state.one = one
@@ -558,36 +556,6 @@ function has(query, element, _1, _2, state) {
558556
return result
559557
}
560558

561-
/**
562-
* @param {Selector} value
563-
* @returns {Selectors}
564-
*/
565-
function appendScope(value) {
566-
/** @type {Selectors} */
567-
const selector =
568-
value.type === 'ruleSet' ? {type: 'selectors', selectors: [value]} : value
569-
let index = -1
570-
571-
while (++index < selector.selectors.length) {
572-
const rule = selector.selectors[index].rule
573-
rule.nestingOperator = null
574-
575-
if (
576-
!rule.pseudos ||
577-
rule.pseudos.length !== 1 ||
578-
rule.pseudos[0].name !== 'scope'
579-
) {
580-
selector.selectors[index] = {
581-
type: 'ruleSet',
582-
// @ts-expect-error pseudos are fine w/ just a name!
583-
rule: {type: 'rule', rule, pseudos: [{name: 'scope'}]}
584-
}
585-
}
586-
}
587-
588-
return selector
589-
}
590-
591559
/**
592560
* @param {RulePseudo} query
593561
* @returns {(value: number) => boolean}

lib/types.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
* @typedef {Properties[keyof Properties]} PropertyValue
1818
* Any property value.
1919
*
20-
* @typedef {import('css-selector-parser').Selector} Selector
21-
* One selector.
2220
* @typedef {import('css-selector-parser').Selectors} Selectors
2321
* Multiple selectors.
2422
* @typedef {import('css-selector-parser').Rule} Rule
@@ -47,7 +45,7 @@
4745
* Name of pseudo, such as `'matches'`.
4846
* @property {'selector'} valueType
4947
* Set to `'selector'`, because `value` is a compiled selector.
50-
* @property {Selector} value
48+
* @property {Selectors|RuleSet} value
5149
* Selector.
5250
*
5351
* @typedef {'html' | 'svg'} Space

0 commit comments

Comments
 (0)