Skip to content

Commit 2214b35

Browse files
committed
Refactor collecting of results
1 parent bbe3479 commit 2214b35

File tree

4 files changed

+31
-90
lines changed

4 files changed

+31
-90
lines changed

index.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ export function matches(selector, node) {
2828
const state = createState(node)
2929
state.one = true
3030
state.shallow = true
31-
const result = any(parse(selector), node || undefined, state)
32-
return result.length > 0
31+
any(parse(selector), node || undefined, state)
32+
return state.results.length > 0
3333
}
3434

3535
/**
@@ -50,9 +50,9 @@ export function matches(selector, node) {
5050
export function select(selector, tree) {
5151
const state = createState(tree)
5252
state.one = true
53-
const result = any(parse(selector), tree || undefined, state)
53+
any(parse(selector), tree || undefined, state)
5454
// To do next major: return `undefined`.
55-
return result[0] || null
55+
return state.results[0] || null
5656
}
5757

5858
/**
@@ -71,7 +71,8 @@ export function select(selector, tree) {
7171
*/
7272
export function selectAll(selector, tree) {
7373
const state = createState(tree)
74-
return any(parse(selector), tree || undefined, state)
74+
any(parse(selector), tree || undefined, state)
75+
return state.results
7576
}
7677

7778
/**
@@ -80,6 +81,7 @@ export function selectAll(selector, tree) {
8081
*/
8182
function createState(tree) {
8283
return {
84+
results: [],
8385
any,
8486
iterator: undefined,
8587
scopeNodes: tree ? (root(tree) ? tree.children : [tree]) : [],

lib/any.js

Lines changed: 9 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,12 @@ const type = zwitch('type', {
2828
* Tree.
2929
* @param {SelectState} state
3030
* State.
31-
* @returns {Array<Node>}
32-
* Results.
31+
* @returns {void}
3332
*/
3433
export function any(query, node, state) {
35-
return query && node ? type(query, node, state) : []
34+
if (query && node) {
35+
type(query, node, state)
36+
}
3637
}
3738

3839
/**
@@ -44,19 +45,15 @@ export function any(query, node, state) {
4445
* Tree.
4546
* @param {SelectState} state
4647
* State.
47-
* @returns {Array<Node>}
48-
* Results.
48+
* @returns {void}
4949
*/
5050
function selectors(query, node, state) {
51-
const collector = new Collector(state.one)
5251
let index = -1
5352

5453
while (++index < query.selectors.length) {
5554
const set = query.selectors[index]
56-
collector.collectAll(rule(set.rule, node, state))
55+
rule(set.rule, node, state)
5756
}
58-
59-
return collector.result
6057
}
6158

6259
/**
@@ -68,8 +65,7 @@ function selectors(query, node, state) {
6865
* Tree.
6966
* @param {SelectState} state
7067
* State.
71-
* @returns {Array<Node>}
72-
* Results.
68+
* @returns {void}
7369
*/
7470
function ruleSet(query, node, state) {
7571
return rule(query.rule, node, state)
@@ -84,12 +80,9 @@ function ruleSet(query, node, state) {
8480
* Tree.
8581
* @param {SelectState} state
8682
* State.
87-
* @returns {Array<Node>}
88-
* Results.
83+
* @returns {void}
8984
*/
9085
function rule(query, tree, state) {
91-
const collector = new Collector(state.one)
92-
9386
if (state.shallow && query.rule) {
9487
throw new Error('Expected selector without nesting')
9588
}
@@ -106,8 +99,6 @@ function rule(query, tree, state) {
10699
})
107100
)
108101

109-
return collector.result
110-
111102
/** @type {SelectIterator} */
112103
function iterator(query, node, index, parent, state) {
113104
if (test(query, node, index, parent, state)) {
@@ -118,7 +109,7 @@ function rule(query, tree, state) {
118109
index: needsIndex(query.rule)
119110
})
120111
} else {
121-
collector.collect(node)
112+
if (!state.results.includes(node)) state.results.push(node)
122113
state.found = true
123114
}
124115
}
@@ -183,63 +174,3 @@ function unknownType(query) {
183174
function invalidType() {
184175
throw new Error('Invalid type')
185176
}
186-
187-
/**
188-
* Collect nodes.
189-
*/
190-
class Collector {
191-
/**
192-
* @param {boolean | undefined} one
193-
*/
194-
constructor(one) {
195-
/**
196-
* Found nodes.
197-
*
198-
* @type {Array<Node>}
199-
*/
200-
this.result = []
201-
202-
/**
203-
* Whether we’re looking for one result.
204-
*
205-
* @type {boolean}
206-
*/
207-
this.one = one || false
208-
209-
/**
210-
* Whether we’ve found something.
211-
*
212-
* @type {boolean}
213-
*/
214-
this.found = false
215-
}
216-
217-
/**
218-
* Add multiple nodes.
219-
*
220-
* @param {Array<Node>} nodes
221-
*/
222-
collectAll(nodes) {
223-
let index = -1
224-
225-
while (++index < nodes.length) {
226-
this.collect(nodes[index])
227-
}
228-
}
229-
230-
/**
231-
* Add one node.
232-
*
233-
* @param {Node} node
234-
*/
235-
collect(node) {
236-
if (this.one) {
237-
// Shouldn’t happen, safeguards performance problems.
238-
/* c8 ignore next */
239-
if (this.found) return
240-
this.found = true
241-
}
242-
243-
if (!this.result.includes(node)) this.result.push(node)
244-
}
245-
}

lib/pseudo.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,17 +91,20 @@ export function pseudo(query, node, index, parent, state) {
9191
* @returns {boolean}
9292
*/
9393
function matches(query, node, _1, _2, state) {
94-
const {shallow, one} = state
94+
const {shallow, one, results, any} = state
9595

9696
state.shallow = false
9797
state.one = true
98+
state.results = []
9899

99-
const result = state.any(query.value, node, state)[0] === node
100+
any(query.value, node, state)
101+
const matches = state.results[0] === node
100102

101103
state.shallow = shallow
102104
state.one = one
105+
state.results = results
103106

104-
return result
107+
return matches
105108
}
106109

107110
/**
@@ -340,19 +343,22 @@ function assertDeep(state, query) {
340343
*/
341344
function hasSelector(query, node, _1, _2, state) {
342345
const fragment = {type: 'root', children: parent(node) ? node.children : []}
343-
const {shallow, one, scopeNodes, any} = state
346+
const {shallow, one, scopeNodes, results, any} = state
344347

345348
state.shallow = false
346349
state.one = true
347350
state.scopeNodes = [node]
351+
state.results = []
348352

349-
const result = any(query.value, fragment, state).length > 0
353+
any(query.value, fragment, state)
354+
const has = state.results.length > 0
350355

351356
state.shallow = shallow
352357
state.one = one
353358
state.scopeNodes = scopeNodes
359+
state.results = results
354360

355-
return result
361+
return has
356362
}
357363

358364
/**

lib/types.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@
3939
*
4040
* @typedef SelectState
4141
* Current state.
42-
* @property {(query: Selectors | RuleSet | Rule, node: Node | undefined, state: SelectState) => Array<Node>} any
42+
* @property {Array<Node>} results
43+
* Matches.
44+
* @property {(query: Selectors | RuleSet | Rule, node: Node | undefined, state: SelectState) => void} any
4345
* To do: Remove.
4446
* @property {SelectIterator | undefined} iterator
4547
* Current iterator.

0 commit comments

Comments
 (0)