@@ -37,7 +37,7 @@ const empty = []
37
37
*/
38
38
export function walk ( state , tree ) {
39
39
if ( tree ) {
40
- one ( state , [ ] , tree , undefined , undefined )
40
+ one ( state , [ ] , tree , undefined , undefined , tree )
41
41
}
42
42
}
43
43
@@ -49,9 +49,10 @@ export function walk(state, tree) {
49
49
* @param {Node } node
50
50
* @param {number | undefined } index
51
51
* @param {Parent | undefined } parentNode
52
+ * @param {Node } tree
52
53
* @returns {Nest }
53
54
*/
54
- function one ( state , currentRules , node , index , parentNode ) {
55
+ function one ( state , currentRules , node , index , parentNode , tree ) {
55
56
/** @type {Nest } */
56
57
let nestResult = {
57
58
directChild : undefined ,
@@ -60,10 +61,23 @@ function one(state, currentRules, node, index, parentNode) {
60
61
generalSibling : undefined
61
62
}
62
63
64
+ let rootRules = state . rootQuery . rules
65
+
66
+ // Remove direct child rules if this is the root.
67
+ // This only happens for a `:has()` rule, which can be like
68
+ // `a:has(> b)`.
69
+ if ( parentNode && parentNode !== tree ) {
70
+ rootRules = state . rootQuery . rules . filter (
71
+ ( d ) =>
72
+ d . combinator === undefined ||
73
+ ( d . combinator === '>' && parentNode === tree )
74
+ )
75
+ }
76
+
63
77
nestResult = applySelectors (
64
78
state ,
65
79
// Try the root rules for this node too.
66
- combine ( currentRules , state . rootQuery . rules ) ,
80
+ combine ( currentRules , rootRules ) ,
67
81
node ,
68
82
index ,
69
83
parentNode
@@ -72,7 +86,7 @@ function one(state, currentRules, node, index, parentNode) {
72
86
// If this is a parent, and we want to delve into them, and we haven’t found
73
87
// our single result yet.
74
88
if ( parent ( node ) && ! state . shallow && ! ( state . one && state . found ) ) {
75
- all ( state , nestResult , node )
89
+ all ( state , nestResult , node , tree )
76
90
}
77
91
78
92
return nestResult
@@ -84,9 +98,10 @@ function one(state, currentRules, node, index, parentNode) {
84
98
* @param {SelectState } state
85
99
* @param {Nest } nest
86
100
* @param {Parent } node
101
+ * @param {Node } tree
87
102
* @returns {undefined }
88
103
*/
89
- function all ( state , nest , node ) {
104
+ function all ( state , nest , node , tree ) {
90
105
const fromParent = combine ( nest . descendant , nest . directChild )
91
106
/** @type {Array<AstRule> | undefined } */
92
107
let fromSibling
@@ -121,7 +136,7 @@ function all(state, nest, node) {
121
136
122
137
// Only apply if this is a parent.
123
138
const forSibling = combine ( fromParent , fromSibling )
124
- const nest = one ( state , forSibling , node . children [ index ] , index , node )
139
+ const nest = one ( state , forSibling , node . children [ index ] , index , node , tree )
125
140
fromSibling = combine ( nest . generalSibling , nest . adjacentSibling )
126
141
127
142
// We found one thing, and one is enough.
@@ -208,7 +223,7 @@ function applySelectors(state, rules, node, index, parent) {
208
223
else if ( rule . combinator === '~' ) {
209
224
add ( nestResult , 'generalSibling' , rule )
210
225
}
211
- // Drop top-level nesting (`undefined`), direct child (`>`), adjacent sibling (`+`).
226
+ // Drop direct child (`>`), adjacent sibling (`+`).
212
227
}
213
228
214
229
return nestResult
0 commit comments