1+ /**
2+ * @typedef {import('css-selector-parser').RuleAttr } CssRuleAttr
3+ * @typedef {import('css-selector-parser').RulePseudo } CssRulePseudo
4+ * @typedef {import('css-selector-parser').Selectors } CssSelectors
5+ * @typedef {import('css-selector-parser').RuleSet } CssRuleSet
6+ * @typedef {import('css-selector-parser').Rule } CssRule
7+ *
8+ * @typedef {import('hast').Element } HastElement
9+ * @typedef {import('hast').Properties } HastProperties
10+ *
11+ * @typedef {'html'|'svg' } Space
12+ *
13+ * @typedef Options
14+ * @property {Space } [space]
15+ *
16+ * @typedef Context
17+ * @property {Space } space
18+ * @property {boolean } root
19+ */
20+
121import { h , s } from 'hastscript'
222import { zwitch } from 'zwitch'
323import { CssSelectorParser } from 'css-selector-parser'
424
5- var compile = zwitch ( 'type' , {
6- handlers : {
7- selectors,
8- ruleSet,
9- rule
10- }
11- } )
25+ var compile = zwitch ( 'type' , { handlers : { selectors, ruleSet, rule} } )
1226
1327var parser = new CssSelectorParser ( )
1428
1529parser . registerNestingOperators ( '>' , '+' , '~' )
1630// Register these so we can throw nicer errors.
1731parser . registerAttrEqualityMods ( '~' , '|' , '^' , '$' , '*' )
1832
33+ /**
34+ * @param {string } [selector='']
35+ * @param {Space|Options } [space='html']
36+ * @returns {HastElement }
37+ */
1938export function fromSelector ( selector , space ) {
20- var config = { space : ( space && space . space ) || space || 'html' , root : true }
39+ /** @type {Context } */
40+ var config = {
41+ space :
42+ ( space && typeof space === 'object' && space . space ) ||
43+ ( typeof space === 'string' && space ) ||
44+ 'html' ,
45+ root : true
46+ }
2147
2248 return (
49+ // @ts -ignore Assume one element is returned.
2350 compile ( parser . parse ( selector || '' ) , config ) || build ( config . space ) ( '' )
2451 )
2552}
2653
27- function selectors ( ) {
54+ /**
55+ * @param {CssSelectors } _
56+ */
57+ function selectors ( _ ) {
2858 throw new Error ( 'Cannot handle selector list' )
2959}
3060
61+ /**
62+ * @param {CssRuleSet } query
63+ * @param {Context } config
64+ * @returns {HastElement|Array.<HastElement> }
65+ */
3166function ruleSet ( query , config ) {
67+ // @ts -ignore Assume one or more elements is returned.
3268 return compile ( query . rule , config )
3369}
3470
71+ /**
72+ * @param {CssRule } query
73+ * @param {Context } config
74+ * @returns {HastElement|Array.<HastElement> }
75+ */
3576function rule ( query , config ) {
3677 var parentSpace = config . space
3778 var name = query . tagName === '*' ? '' : query . tagName || ''
3879 var space = parentSpace === 'html' && name === 'svg' ? 'svg' : parentSpace
80+ /** @type {boolean } */
3981 var sibling
40- var operator
82+ /** @type { HastElement } */
4183 var node
4284
4385 if ( query . rule ) {
44- operator = query . rule . nestingOperator
45- sibling = operator === '+' || operator === '~'
86+ sibling =
87+ query . rule . nestingOperator === '+' || query . rule . nestingOperator === '~'
4688
4789 if ( sibling && config . root ) {
4890 throw new Error (
49- 'Cannot handle sibling combinator `' + operator + '` at root'
91+ 'Cannot handle sibling combinator `' +
92+ query . rule . nestingOperator +
93+ '` at root'
5094 )
5195 }
5296 }
5397
98+ // @ts -ignore Assume one or more elements is returned.
5499 node = build ( space ) (
55100 name ,
56101 Object . assign (
@@ -61,9 +106,14 @@ function rule(query, config) {
61106 ! query . rule || sibling ? [ ] : compile ( query . rule , { space} )
62107 )
63108
109+ // @ts -ignore Assume one or more elements is returned.
64110 return sibling ? [ node , compile ( query . rule , { space : parentSpace } ) ] : node
65111}
66112
113+ /**
114+ * @param {Array.<CssRulePseudo> } pseudos
115+ * @returns {HastProperties }
116+ */
67117function pseudosToHast ( pseudos ) {
68118 var pseudo = pseudos [ 0 ]
69119
@@ -78,15 +128,21 @@ function pseudosToHast(pseudos) {
78128 return { }
79129}
80130
131+ /**
132+ * @param {Array.<CssRuleAttr> } attrs
133+ * @returns {HastProperties }
134+ */
81135function attrsToHast ( attrs ) {
82- var props = { }
83136 var index = - 1
137+ /** @type {HastProperties } */
138+ var props = { }
139+ /** @type {CssRuleAttr } */
84140 var attr
85141
86142 while ( ++ index < attrs . length ) {
87143 attr = attrs [ index ]
88144
89- if ( attr . operator ) {
145+ if ( ' operator' in attr ) {
90146 if ( attr . operator === '=' ) {
91147 props [ attr . name ] = attr . value
92148 } else {
@@ -102,6 +158,10 @@ function attrsToHast(attrs) {
102158 return props
103159}
104160
161+ /**
162+ * @param {Space } space
163+ * @returns {typeof h }
164+ */
105165function build ( space ) {
106166 return space === 'html' ? h : s
107167}
0 commit comments