1
1
/**
2
- * @import {AstAttribute, AstRule} from 'css-selector-parser'
2
+ * @import {AstRule} from 'css-selector-parser'
3
3
* @import {Element, Properties} from 'hast'
4
4
*/
5
5
@@ -79,38 +79,59 @@ export function fromSelector(selector, options) {
79
79
* One or more elements.
80
80
*/
81
81
function rule ( query , state ) {
82
- const space =
83
- state . space === 'html' &&
84
- query . tag &&
85
- query . tag . type === 'TagName' &&
86
- query . tag . name === 'svg'
87
- ? 'svg'
88
- : state . space
89
-
90
- const pseudoClass = query . pseudoClasses ? query . pseudoClasses [ 0 ] : undefined
91
-
92
- if ( pseudoClass ) {
93
- if ( pseudoClass . name ) {
94
- throw new Error ( 'Cannot handle pseudo class `' + pseudoClass . name + '`' )
95
- /* c8 ignore next 4 -- types say this can occur, but I don’t understand how */
96
- }
82
+ let space = state . space
83
+ /** @type { Properties } */
84
+ const properties = { }
85
+ /** @ type { Array<string> | undefined } */
86
+ let className
87
+ /** @type { Array<string> } */
88
+ const ids = [ ]
89
+ /** @type { Array<string> } */
90
+ const names = [ ]
91
+
92
+ for ( const item of query . items ) {
93
+ if ( item . type === 'Attribute' ) {
94
+ if ( 'operator' in item ) {
95
+ if ( item . operator === '=' ) {
96
+ const value = item . value
97
97
98
- throw new Error ( 'Cannot handle empty pseudo class' )
98
+ // eslint-disable-next-line max-depth
99
+ if ( value ) {
100
+ assert ( value . type === 'String' , 'substitution are not enabled' )
101
+ properties [ item . name ] = value . value
102
+ }
103
+ } else {
104
+ throw new Error (
105
+ 'Cannot handle attribute equality modifier `' + item . operator + '`'
106
+ )
107
+ }
108
+ } else {
109
+ properties [ item . name ] = true
110
+ }
111
+ } else if ( item . type === 'ClassName' ) {
112
+ if ( ! className ) className = [ ]
113
+ className . push ( item . name )
114
+ } else if ( item . type === 'Id' ) {
115
+ ids . push ( item . name )
116
+ } else if ( item . type === 'PseudoClass' ) {
117
+ throw new Error ( 'Cannot handle pseudo class `' + item . name + '`' )
118
+ } else if ( item . type === 'PseudoElement' ) {
119
+ throw new Error ( 'Cannot handle pseudo element `' + item . name + '`' )
120
+ } else if ( item . type === 'TagName' ) {
121
+ names . push ( item . name )
122
+ } else {
123
+ assert ( item . type === 'WildcardTag' )
124
+ // Ignore.
125
+ }
99
126
}
100
127
101
- if ( query . pseudoElement ) {
102
- throw new Error (
103
- 'Cannot handle pseudo element `' + query . pseudoElement + '`'
104
- )
128
+ const id = ids [ ids . length - 1 ]
129
+ const name = names [ names . length - 1 ] || ''
130
+ if ( state . space === 'html' && name === 'svg' ) {
131
+ space = 'svg'
105
132
}
106
133
107
- const name = query . tag && query . tag . type === 'TagName' ? query . tag . name : ''
108
-
109
- const node = build ( space ) ( name , {
110
- id : query . ids ? query . ids [ query . ids . length - 1 ] : undefined ,
111
- className : query . classNames ,
112
- ...attributesToHast ( query . attributes )
113
- } )
134
+ const node = build ( space ) ( name , { id, className, ...properties } , [ ] )
114
135
const results = [ node ]
115
136
116
137
if ( query . nestedRule ) {
@@ -130,48 +151,6 @@ function rule(query, state) {
130
151
return results
131
152
}
132
153
133
- /**
134
- * Turn attribute selectors into properties.
135
- *
136
- * @param {Array<AstAttribute> | undefined } attributes
137
- * Attribute selectors.
138
- * @returns {Properties }
139
- * Properties.
140
- */
141
- function attributesToHast ( attributes ) {
142
- /** @type {Properties } */
143
- const properties = { }
144
- let index = - 1
145
-
146
- if ( attributes ) {
147
- while ( ++ index < attributes . length ) {
148
- const attribute = attributes [ index ]
149
-
150
- if ( 'operator' in attribute ) {
151
- if ( attribute . operator === '=' ) {
152
- const value = attribute . value
153
-
154
- // eslint-disable-next-line max-depth
155
- if ( value ) {
156
- assert ( value . type === 'String' , 'substitution are not enabled' )
157
- properties [ attribute . name ] = value . value
158
- }
159
- } else {
160
- throw new Error (
161
- 'Cannot handle attribute equality modifier `' +
162
- attribute . operator +
163
- '`'
164
- )
165
- }
166
- } else {
167
- properties [ attribute . name ] = true
168
- }
169
- }
170
- }
171
-
172
- return properties
173
- }
174
-
175
154
/**
176
155
* @param {Space } space
177
156
* Space.
0 commit comments