77 * @typedef {import('./index.js').State } State
88 */
99
10- import { attributes } from './attribute.js'
10+ import { attribute } from './attribute.js'
1111import { className } from './class-name.js'
1212import { id } from './id.js'
1313import { name } from './name.js'
@@ -30,15 +30,24 @@ import {pseudo} from './pseudo.js'
3030 * Whether `element` matches `query`.
3131 */
3232export function test ( query , element , index , parent , state ) {
33- if ( query . pseudoElement ) {
34- throw new Error ( 'Invalid selector: `::' + query . pseudoElement + '`' )
33+ for ( const item of query . items ) {
34+ // eslint-disable-next-line unicorn/prefer-switch
35+ if ( item . type === 'Attribute' ) {
36+ if ( ! attribute ( item , element , state . schema ) ) return false
37+ } else if ( item . type === 'Id' ) {
38+ if ( ! id ( item , element ) ) return false
39+ } else if ( item . type === 'ClassName' ) {
40+ if ( ! className ( item , element ) ) return false
41+ } else if ( item . type === 'PseudoClass' ) {
42+ if ( ! pseudo ( item , element , index , parent , state ) ) return false
43+ } else if ( item . type === 'PseudoElement' ) {
44+ throw new Error ( 'Invalid selector: `::' + item . name + '`' )
45+ } else if ( item . type === 'TagName' ) {
46+ if ( ! name ( item , element ) ) return false
47+ } else {
48+ // Otherwise `item.type` is `WildcardTag`, which matches.
49+ }
3550 }
3651
37- return Boolean (
38- ( ! query . tag || name ( query , element ) ) &&
39- ( ! query . classNames || className ( query , element ) ) &&
40- ( ! query . ids || id ( query , element ) ) &&
41- ( ! query . attributes || attributes ( query , element , state . schema ) ) &&
42- ( ! query . pseudoClasses || pseudo ( query , element , index , parent , state ) )
43- )
52+ return true
4453}
0 commit comments