11# unist-util-select [ ![ Build] [ build-badge ]] [ build ] [ ![ Coverage] [ coverage-badge ]] [ coverage ] [ ![ Downloads] [ downloads-badge ]] [ downloads ] [ ![ Chat] [ chat-badge ]] [ chat ]
22
3- Select [ unist] [ ] nodes with CSS-like selectors.
3+ Selector support for [ unist] [ ] .
4+ ` querySelector ` , ` querySelectorAll ` , and ` matches ` .
5+
6+ Note that the DOM has references to their parent nodes, meaning that
7+ ` document.body.matches(':last-child') ` can be evaluated.
8+ This information is not stored in unist, so selectors like that don’t work.
49
510[ View the list of supported selectors »] [ support ]
611
@@ -14,98 +19,139 @@ npm install unist-util-select
1419
1520## API
1621
17- ### ` select.one(tree, selector ) `
22+ ### ` select.matches(selector, node ) `
1823
19- ### ` select.one(tree)(selector) `
24+ Check that the given [ node] [ ] matches ` selector ` .
25+ Returns ` boolean ` , whether the node matches or not.
2026
21- Select the first node matching ` selector ` in the given ` tree ` (could be the
22- tree itself).
23- Returns the found [ node ] [ ] , if any .
24- Throws an error if node is not found or not unique .
27+ This only checks the element itself, not the surrounding tree.
28+ Thus, nesting in selectors is not supported ( ` paragraph strong ` ,
29+ ` paragraph > strong ` ), not are selectors like ` :first-child ` , etc .
30+ This simply checks that the given element matches the selector .
2531
26- ##### Usage
27-
28- Say we have the following file, ` example.md ` :
29-
30- ``` markdown
31- 1. Step 1.
32- 2. TODO Step 2.
33- 3. Step 3.
32+ ``` javascript
33+ var u = require (' unist-builder' )
34+ var matches = require (' unist-util-select' ).matches
3435
35- 1. TODO Step 3.1.
36- 2. Step 3.2.
37- 3. TODO Step 3.3.
36+ matches (' strong, em' , u (' strong' , [u (' text' , ' bold' )])) // => true
37+ matches (' [lang]' , u (' code' , {lang: ' js' }, ' console.log(1)' )) // => true
3838```
3939
40- And our script, ` example.js ` , looks as follows:
40+ ### ` select.select(selector, tree) `
4141
42- ``` javascript
43- var fs = require (' fs' )
44- var remark = require (' remark' )
45- var select = require (' unist-util-select' )
46-
47- var tree = remark ().parse (fs .readFileSync (' example.md' ))
48-
49- var step = select .one (tree, ' list text[value*=3.2]' )
42+ Select the first node matching ` selector ` in the given ` tree ` (could be the
43+ tree itself).
44+ Returns the found [ node] [ ] , if any.
5045
51- console .log (step)
46+ ``` javascript
47+ var u = require (' unist-builder' )
48+ var select = require (' unist-util-select' ).select
49+
50+ console .log (
51+ select (
52+ ' code ~ :nth-child(even)' ,
53+ u (' blockquote' , [
54+ u (' paragraph' , [u (' text' , ' Alpha' )]),
55+ u (' paragraph' , [u (' text' , ' Bravo' )]),
56+ u (' code' , ' Charlie' ),
57+ u (' paragraph' , [u (' text' , ' Delta' )]),
58+ u (' paragraph' , [u (' text' , ' Echo' )])
59+ ])
60+ )
61+ )
5262```
5363
54- Now, running ` node example ` yields :
64+ Yields :
5565
5666``` javascript
57- { type: ' text' , value: ' Step 3.2.' }
67+ { type: ' paragraph' ,
68+ children: [ { type: ' text' , value: ' Delta' } ] }
5869```
5970
60- ### ` select(tree, selector) `
61-
62- ### ` select(tree)(selector) `
71+ ### ` select.selectAll(selector, tree) `
6372
6473Select all nodes matching ` selector ` in the given ` tree ` (could include the
6574tree itself).
66- Returns the found [ node] [ ] s, if any.
67-
68- ##### Usage
69-
70- Say we have the following file, ` example.md ` :
71-
72- ``` markdown
73- 1. Step 1.
74- 2. TODO Step 2.
75- 3. Step 3.
76-
77- 1. TODO Step 3.1.
78- 2. Step 3.2.
79- 3. TODO Step 3.3.
80- ```
81-
82- And our script, ` example.js ` , looks as follows:
75+ Returns all found [ node] [ ] s, if any.
8376
8477``` javascript
85- var fs = require (' fs' )
86- var remark = require (' remark' )
87- var select = require (' unist-util-select' )
88-
89- var tree = remark ().parse (fs .readFileSync (' example.md' ))
90-
91- var todos = select (tree, ' list text[value*=TODO]' )
92-
93- console .log (todos)
78+ var u = require (' unist-builder' )
79+ var selectAll = require (' unist-util-select' ).selectAll
80+
81+ console .log (
82+ selectAll (
83+ ' code ~ :nth-child(even)' ,
84+ u (' blockquote' , [
85+ u (' paragraph' , [u (' text' , ' Alpha' )]),
86+ u (' paragraph' , [u (' text' , ' Bravo' )]),
87+ u (' code' , ' Charlie' ),
88+ u (' paragraph' , [u (' text' , ' Delta' )]),
89+ u (' paragraph' , [u (' text' , ' Echo' )]),
90+ u (' paragraph' , [u (' text' , ' Foxtrot' )]),
91+ u (' paragraph' , [u (' text' , ' Golf' )])
92+ ])
93+ )
94+ )
9495```
9596
96- Now, running ` node example ` yields :
97+ Yields :
9798
9899``` javascript
99- [ { type: ' text' ,
100- value: ' TODO Step 2.' },
101- { type: ' text' ,
102- value: ' TODO Step 3.1.' },
103- { type: ' text' ,
104- value: ' TODO Step 3.3.' } ]
100+ [ { type: ' paragraph' ,
101+ children: [ { type: ' text' , value: ' Delta' } ] },
102+ { type: ' paragraph' ,
103+ children: [ { type: ' text' , value: ' Foxtrot' } ] } ]
105104```
106105
107106## Support
108107
108+ <!-- lint ignore no-html-->
109+
110+ * [x] ` * ` (universal selector)
111+ * [x] ` , ` (multiple selector)
112+ * [x] ` paragraph ` (type selector)
113+ * [x] ` blockquote paragraph ` (combinator: descendant selector)
114+ * [x] ` blockquote > paragraph ` (combinator: child selector)
115+ * [x] ` code + paragraph ` (combinator: adjacent sibling selector)
116+ * [x] ` code ~ paragraph ` (combinator: general sibling selector)
117+ * [x] ` [attr] ` (attribute existence, checks that the value on the tree is not
118+ nully)
119+ * [x] ` [attr=value] ` (attribute equality, this stringifies values on the tree)
120+ * [x] ` [attr^=value] ` (attribute begins with, only works on strings)
121+ * [x] ` [attr$=value] ` (attribute ends with, only works on strings)
122+ * [x] ` [attr*=value] ` (attribute contains, only works on strings)
123+ * [x] ` [attr~=value] ` (checks if ` value ` is in the array, if there’s an array
124+ on the tree, otherwise same as attribute equality)
125+ * [x] ` :any() ` (functional pseudo-class, use ` :matches ` instead)
126+ * [x] ` :has() ` (functional pseudo-class).
127+ <small >Relative selectors (` :has(> img) ` ) are not supported, but ` :scope ` is
128+ * [x] ` :matches() ` (functional pseudo-class)
129+ * [x] ` :not() ` (functional pseudo-class)
130+ * [x] ` :blank ` (pseudo-class)
131+ <small >blank and empty are the same: a parent without children, or a node
132+ without value</small >
133+ * [x] ` :empty ` (pseudo-class)
134+ <small >blank and empty are the same: a parent without children, or a node
135+ without value</small >
136+ * [x] ` :root ` (pseudo-class)
137+ <small >Matches the given node</small >
138+ * [x] ` :scope ` (pseudo-class):
139+ <small >Matches the given node</small >
140+ * [x] \* ` :first-child ` (pseudo-class)
141+ * [x] \* ` :first-of-type ` (pseudo-class)
142+ * [x] \* ` :last-child ` (pseudo-class)
143+ * [x] \* ` :last-of-type ` (pseudo-class)
144+ * [x] \* ` :only-child ` (pseudo-class)
145+ * [x] \* ` :only-of-type ` (pseudo-class)
146+ * [x] \* ` :nth-child() ` (functional pseudo-class)
147+ * [x] \* ` :nth-last-child() ` (functional pseudo-class)
148+ * [x] \* ` :nth-last-of-type() ` (functional pseudo-class)
149+ * [x] \* ` :nth-of-type() ` (functional pseudo-class)
150+
151+ ###### Notes
152+
153+ * \* — Not supported in ` matches `
154+
109155## Contribute
110156
111157See [ ` contributing.md ` in ` syntax-tree/unist ` ] [ contributing ] for ways to get
0 commit comments