1 | css-selector-parser
|
2 | ===================
|
3 |
|
4 | * Fast and low memory CSS selector parser.
|
5 | * Parses CSS selector into object-model (AST).
|
6 | * Compliant with all historical and modern CSS specs.
|
7 | * Covered with tests.
|
8 | * Documented.
|
9 | * Supported CSS selector standards:
|
10 | * `css1`: https://www.w3.org/TR/CSS1/
|
11 | * `css2`: https://www.w3.org/TR/CSS2/
|
12 | * `css3`/`selectors-3`: https://www.w3.org/TR/selectors-3/
|
13 | * `selectors-4`: https://www.w3.org/TR/selectors-4/
|
14 | * `latest`: refers to `selectors-4`
|
15 | * `progressive`: `latest` + accepts unknown psudo-classes, psudo-elements and attribute case sensitivity modifiers
|
16 |
|
17 | **Important:**
|
18 | * [Migrating from 1.x to 3.x](CHANGELOG.md#migrating-from-1x-to-3x).
|
19 | * [Migrating from 2.x to 3.x](CHANGELOG.md#migrating-from-2x-to-3x).
|
20 | * [Migrating from 1.x to 2.x](CHANGELOG.md#220).
|
21 |
|
22 | Latest releases: [Changelog](CHANGELOG.md).
|
23 |
|
24 | Installation
|
25 | ------------
|
26 |
|
27 | ```
|
28 | npm install css-selector-parser
|
29 | ```
|
30 |
|
31 | Usage
|
32 | -----
|
33 |
|
34 | ### Parsing
|
35 |
|
36 | ```javascript
|
37 | import {createParser} from 'css-selector-parser';
|
38 |
|
39 | const parse = createParser();
|
40 | const selector = parse('a[href^="/"], .container:has(nav) > a[href]:nth-child(2)::before');
|
41 |
|
42 | console.log(selector);
|
43 | ```
|
44 |
|
45 | Produces:
|
46 |
|
47 | ```javascript
|
48 | ({
|
49 | type: 'Selector',
|
50 | rules: [
|
51 | {
|
52 | type: 'Rule',
|
53 | items: [
|
54 | { type: 'TagName', name: 'a' },
|
55 | {
|
56 | type: 'Attribute',
|
57 | name: 'href',
|
58 | operator: '^=',
|
59 | value: { type: 'String', value: '/' }
|
60 | }
|
61 | ]
|
62 | },
|
63 | {
|
64 | type: 'Rule',
|
65 | items: [
|
66 | { type: 'ClassName', name: 'container' },
|
67 | {
|
68 | type: 'PseudoClass',
|
69 | name: 'has',
|
70 | argument: {
|
71 | type: 'Selector',
|
72 | rules: [
|
73 | {
|
74 | type: 'Rule',
|
75 | items: [ { type: 'TagName', name: 'nav' } ]
|
76 | }
|
77 | ]
|
78 | }
|
79 | }
|
80 | ],
|
81 | nestedRule: {
|
82 | type: 'Rule',
|
83 | items: [
|
84 | { type: 'TagName', name: 'a' },
|
85 | { type: 'Attribute', name: 'href' },
|
86 | {
|
87 | type: 'PseudoClass',
|
88 | name: 'nth-child',
|
89 | argument: { type: 'Formula', a: 0, b: 2 }
|
90 | },
|
91 | {
|
92 | type: 'PseudoElement',
|
93 | name: 'before'
|
94 | }
|
95 | ],
|
96 | combinator: '>'
|
97 | }
|
98 | }
|
99 | ]
|
100 | })
|
101 | ```
|
102 |
|
103 | ### Constructing AST and rendering
|
104 |
|
105 | ```javascript
|
106 | import {ast, render} from 'css-selector-parser';
|
107 |
|
108 | const selector = ast.selector({
|
109 | rules: [
|
110 | ast.rule({
|
111 | items: [
|
112 | ast.tagName({name: 'a'}),
|
113 | ast.attribute({name: 'href', operator: '^=', value: ast.string({value: '/'})})
|
114 | ]
|
115 | }),
|
116 | ast.rule({
|
117 | items: [
|
118 | ast.className({name: 'container'}),
|
119 | ast.pseudoClass({
|
120 | name: 'has',
|
121 | argument: ast.selector({
|
122 | rules: [ast.rule({items: [ast.tagName({name: 'nav'})]})]
|
123 | })
|
124 | })
|
125 | ],
|
126 | nestedRule: ast.rule({
|
127 | combinator: '>',
|
128 | items: [
|
129 | ast.tagName({name: 'a'}),
|
130 | ast.attribute({name: 'href'}),
|
131 | ast.pseudoClass({
|
132 | name: 'nth-child',
|
133 | argument: ast.formula({a: 0, b: 2})
|
134 | }),
|
135 | ast.pseudoElement({name: 'before'})
|
136 | ]
|
137 | })
|
138 | })
|
139 | ]
|
140 | });
|
141 |
|
142 | console.log(render(selector)); // a[href^="/"], .container:has(nav) > a[href]:nth-child(2)::before
|
143 | ```
|
144 |
|
145 | API
|
146 | ---
|
147 |
|
148 | * [Full API Documentation](docs/modules.md)
|
149 | * [Parsing CSS selectors](docs/modules.md#createParser)
|
150 | * [Constructing CSS AST](docs/modules.md#ast)
|
151 | * [Rendering CSS AST](docs/modules.md#render)
|
152 |
|
153 | LICENSE
|
154 | -------
|
155 |
|
156 | MIT
|
157 |
|
158 | ## Security contact information
|
159 |
|
160 | To report a security vulnerability, please use the
|
161 | [Tidelift security contact](https://tidelift.com/security).
|
162 | Tidelift will coordinate the fix and disclosure.
|