1 | # API Documentation
|
---|
2 |
|
---|
3 | *Please use only this documented API when working with the parser. Methods
|
---|
4 | not documented here are subject to change at any point.*
|
---|
5 |
|
---|
6 | <!-- toc -->
|
---|
7 |
|
---|
8 | - [`parser` function](#parser-function)
|
---|
9 | * [`parser.atword([props])`](#parseratwordprops)
|
---|
10 | * [`parser.colon([props])`](#parsercolonprops)
|
---|
11 | * [`parser.comma([props])`](#parsercommaprops)
|
---|
12 | * [`parser.comment([props])`](#parsercommentprops)
|
---|
13 | * [`parser.func([props])`](#parserfuncprops)
|
---|
14 | * [`parser.number([props])`](#parsernumberprops)
|
---|
15 | * [`parser.operator([props])`](#parseroperatorprops)
|
---|
16 | * [`parser.paren([props])`](#parserparenprops)
|
---|
17 | * [`parser.string([props])`](#parserstringprops)
|
---|
18 | * [`parser.value([props])`](#parservalueprops)
|
---|
19 | * [`parser.word([props])`](#parserwordprops)
|
---|
20 | * [`parser.unicodeRange([props])`](#parserunicoderangeprops)
|
---|
21 | - [Node types](#node-types)
|
---|
22 | * [`node.type`](#nodetype)
|
---|
23 | * [`node.parent`](#nodeparent)
|
---|
24 | * [`node.toString()`, `String(node)`, or `'' + node`](#nodetostring-stringnode-or---node)
|
---|
25 | * [`node.next()` & `node.prev()`](#nodenext--nodeprev)
|
---|
26 | * [`node.replaceWith(node)`](#nodereplacewithnode)
|
---|
27 | * [`node.remove()`](#noderemove)
|
---|
28 | * [`node.clone()`](#nodeclone)
|
---|
29 | * [`node.raws`](#noderaws)
|
---|
30 | * [`node.source`](#nodesource)
|
---|
31 | * [`node.sourceIndex`](#nodesourceindex)
|
---|
32 | - [Container types](#container-types)
|
---|
33 | * [`container.nodes`](#containernodes)
|
---|
34 | * [`container.first` & `container.last`](#containerfirst--containerlast)
|
---|
35 | * [`container.at(index)`](#containeratindex)
|
---|
36 | * [`container.index(node)`](#containerindexnode)
|
---|
37 | * [`container.length`](#containerlength)
|
---|
38 | * [`container.each(callback)`](#containereachcallback)
|
---|
39 | * [`container.walk(callback)`](#containerwalkcallback)
|
---|
40 | * [`container.walk` proxies](#containerwalk-proxies)
|
---|
41 | * [`container.prepend(node)` & `container.append(node)`](#containerprependnode--containerappendnode)
|
---|
42 | * [`container.insertBefore(old, new)` & `container.insertAfter(old, new)`](#containerinsertbeforeold-new--containerinsertafterold-new)
|
---|
43 | * [`container.removeChild(node)`](#containerremovechildnode)
|
---|
44 | * [`container.removeAll()` or `container.empty()`](#containerremoveall-or-containerempty)
|
---|
45 | - [Root nodes`](#root-nodes)
|
---|
46 | - [Value nodes](#value-nodes)
|
---|
47 |
|
---|
48 | <!-- tocstop -->
|
---|
49 |
|
---|
50 | ## `parser` function
|
---|
51 |
|
---|
52 | This is the module's main entry point, and returns a `new Parser`.
|
---|
53 |
|
---|
54 | ```js
|
---|
55 | let parser = require('postcss-values-parser');
|
---|
56 |
|
---|
57 | let ast = parser(source) // tokenizes the source string
|
---|
58 | .parse(); // parses the tokens and returns an AST
|
---|
59 | ```
|
---|
60 |
|
---|
61 | ### `parser.atword([props])`
|
---|
62 |
|
---|
63 | Creates a new AtWord value.
|
---|
64 |
|
---|
65 | ```js
|
---|
66 | parser.atword({ value: '@foo' });
|
---|
67 | // → @foo
|
---|
68 | ```
|
---|
69 |
|
---|
70 | Arguments:
|
---|
71 |
|
---|
72 | * `props (object)`: The new node's properties.
|
---|
73 |
|
---|
74 | ### `parser.colon([props])`
|
---|
75 |
|
---|
76 | Creates a new colon Node.
|
---|
77 |
|
---|
78 | ```js
|
---|
79 | parser.colon({ value: ':' });
|
---|
80 | // → :
|
---|
81 | ```
|
---|
82 |
|
---|
83 | Arguments:
|
---|
84 |
|
---|
85 | * `props (object)`: The new node's properties. If no properties are specified,
|
---|
86 | the default value of `:` will be used. It's not recommended to deviate from this.
|
---|
87 |
|
---|
88 | ### `parser.comma([props])`
|
---|
89 |
|
---|
90 | Creates a new comma Node.
|
---|
91 |
|
---|
92 | ```js
|
---|
93 | parser.comma({ value: ',' });
|
---|
94 | // → ,
|
---|
95 | ```
|
---|
96 |
|
---|
97 | Arguments:
|
---|
98 |
|
---|
99 | * `props (object)`: The new node's properties. If no properties are specified,
|
---|
100 | the default value of `,` will be used. It's not recommended to deviate from this.
|
---|
101 |
|
---|
102 | ### `parser.comment([props])`
|
---|
103 |
|
---|
104 | Creates a new comment.
|
---|
105 |
|
---|
106 | ```js
|
---|
107 | parser.comment({ value: 'Affirmative, Dave. I read you.' });
|
---|
108 | // → /* Affirmative, Dave. I read you. */
|
---|
109 | ```
|
---|
110 |
|
---|
111 | ```js
|
---|
112 | parser.comment({ value: 'Affirmative, Dave. I read you.', inline: true });
|
---|
113 | // → // Affirmative, Dave. I read you.
|
---|
114 | ```
|
---|
115 |
|
---|
116 | Arguments:
|
---|
117 |
|
---|
118 | * `props (object)`: The new node's properties.
|
---|
119 |
|
---|
120 | ### `parser.func([props])`
|
---|
121 |
|
---|
122 | Creates a new function value Container node.
|
---|
123 |
|
---|
124 | ```js
|
---|
125 | let func = parser.func({ value: 'calc' });
|
---|
126 |
|
---|
127 | func.append(parser.paren());
|
---|
128 | func.append(parser.paren({ value: ')' }));
|
---|
129 |
|
---|
130 | func.toString();
|
---|
131 | // → calc()
|
---|
132 | ```
|
---|
133 |
|
---|
134 | Arguments:
|
---|
135 |
|
---|
136 | * `props (object)`: The new node's properties.
|
---|
137 |
|
---|
138 | ### `parser.number([props])`
|
---|
139 |
|
---|
140 | Creates a new number Node.
|
---|
141 |
|
---|
142 | ```js
|
---|
143 | parser.number({ value: 10, unit: 'px' });
|
---|
144 | // → 10px
|
---|
145 | ```
|
---|
146 |
|
---|
147 | Arguments:
|
---|
148 |
|
---|
149 | * `props (object)`: The new node's properties.
|
---|
150 |
|
---|
151 | ### `parser.operator([props])`
|
---|
152 |
|
---|
153 | Creates a new operator Node.
|
---|
154 |
|
---|
155 | ```js
|
---|
156 | parser.operator({ value: '+' });
|
---|
157 | // → +
|
---|
158 | ```
|
---|
159 |
|
---|
160 | Arguments:
|
---|
161 |
|
---|
162 | * `props (object)`: The new node's properties.
|
---|
163 |
|
---|
164 | ### `parser.paren([props])`
|
---|
165 |
|
---|
166 | Creates a new parenthesis Node.
|
---|
167 |
|
---|
168 | ```js
|
---|
169 | parser.paren();
|
---|
170 | // → (
|
---|
171 |
|
---|
172 | parser.paren({ value: ')' });
|
---|
173 | // → )
|
---|
174 | ```
|
---|
175 |
|
---|
176 | Arguments:
|
---|
177 |
|
---|
178 | * `props (object)`: The new node's properties. If no value is specified, the
|
---|
179 | default value of `(` will be used.
|
---|
180 |
|
---|
181 | ### `parser.string([props])`
|
---|
182 |
|
---|
183 | Creates a new string node.
|
---|
184 |
|
---|
185 | ```js
|
---|
186 | parser.string();
|
---|
187 | // → (empty)
|
---|
188 |
|
---|
189 | parser.string({ value: 'hello', quote: '"' });
|
---|
190 | // → "hello"
|
---|
191 | ```
|
---|
192 |
|
---|
193 | Arguments:
|
---|
194 |
|
---|
195 | * `props (object)`: The new node's properties. Note: If no `quote` property is
|
---|
196 | specified, the default value of `'` will be used.
|
---|
197 |
|
---|
198 | ### `parser.value([props])`
|
---|
199 |
|
---|
200 | Creates a new value Node. This node acts as the container for all values within
|
---|
201 | the Root node, but can be created for convenience.
|
---|
202 |
|
---|
203 | ### `parser.word([props])`
|
---|
204 |
|
---|
205 | Creates a new word Node. A `Word` is anything that doesn't fall into one of the
|
---|
206 | other node types.
|
---|
207 |
|
---|
208 | ```js
|
---|
209 | let word = parser.word({ value: '#fff' });
|
---|
210 | // → #fff
|
---|
211 |
|
---|
212 | word.isHex;
|
---|
213 | // → true
|
---|
214 |
|
---|
215 | word.isColor;
|
---|
216 | // → true
|
---|
217 | ```
|
---|
218 |
|
---|
219 | Arguments:
|
---|
220 |
|
---|
221 | * `props (object)`: The new node's properties.
|
---|
222 |
|
---|
223 | ### `parser.unicodeRange([props])`
|
---|
224 |
|
---|
225 | Creates a new unicode range Node.
|
---|
226 |
|
---|
227 | ```js
|
---|
228 | parser.unicodeRange({ value: 'U+26' });
|
---|
229 | // → U+26
|
---|
230 | ```
|
---|
231 |
|
---|
232 | Arguments:
|
---|
233 |
|
---|
234 | * `props (object)`: The new node's properties.
|
---|
235 |
|
---|
236 | ## Node types
|
---|
237 |
|
---|
238 | ### `node.type`
|
---|
239 |
|
---|
240 | A string representation of the node type. It can be one of the following;
|
---|
241 | `atword`, `colon`, `comma`, `comment`, `func`, `number`, `operator`,
|
---|
242 | `paren`, `string`, `unicoderange`, `value`, `word`.
|
---|
243 |
|
---|
244 | ```js
|
---|
245 | parser.word({ value: '#fff' }).type;
|
---|
246 | // → 'word'
|
---|
247 | ```
|
---|
248 |
|
---|
249 | ### `node.parent`
|
---|
250 |
|
---|
251 | Returns the parent node.
|
---|
252 |
|
---|
253 | ```js
|
---|
254 | root.nodes[0].parent === root;
|
---|
255 | ```
|
---|
256 |
|
---|
257 | ### `node.toString()`, `String(node)`, or `'' + node`
|
---|
258 |
|
---|
259 | Returns a string representation of the node.
|
---|
260 |
|
---|
261 | ```js
|
---|
262 | let color = parser.word({ value: '#fff' });
|
---|
263 | console.log(String(color));
|
---|
264 | // → #fff
|
---|
265 | ```
|
---|
266 |
|
---|
267 | ### `node.next()` & `node.prev()`
|
---|
268 |
|
---|
269 | Returns the next/previous child of the parent node.
|
---|
270 |
|
---|
271 | ```js
|
---|
272 | let next = func.next();
|
---|
273 | if (next && next.type !== 'paren') {
|
---|
274 | throw new Error('Unclosed function parenthesis!');
|
---|
275 | }
|
---|
276 | ```
|
---|
277 |
|
---|
278 | ### `node.replaceWith(node)`
|
---|
279 |
|
---|
280 | Replace a node with another.
|
---|
281 |
|
---|
282 | ```js
|
---|
283 | let ast = parser('#fff').parse();
|
---|
284 | let word = ast.first.first;
|
---|
285 | let atword = parser.atword({ value: '@purple' });
|
---|
286 |
|
---|
287 | word.replaceWith(atword);
|
---|
288 | ```
|
---|
289 |
|
---|
290 | Arguments:
|
---|
291 |
|
---|
292 | * `node`: The node to substitute the original with.
|
---|
293 |
|
---|
294 | ### `node.remove()`
|
---|
295 |
|
---|
296 | Removes the node from its parent node.
|
---|
297 |
|
---|
298 | ```js
|
---|
299 | if (node.type === 'word') {
|
---|
300 | node.remove();
|
---|
301 | }
|
---|
302 | ```
|
---|
303 |
|
---|
304 | ### `node.clone()`
|
---|
305 |
|
---|
306 | Returns a copy of a node, detached from any parent containers that the
|
---|
307 | original might have had.
|
---|
308 |
|
---|
309 | ```js
|
---|
310 | let word = parser.word({ value: '#fff' });
|
---|
311 | let cloned = word.clone();
|
---|
312 |
|
---|
313 | cloned.value = '#fff';
|
---|
314 | String(cloned);
|
---|
315 | // → #000
|
---|
316 |
|
---|
317 | String(word);
|
---|
318 | // → #fff
|
---|
319 | ```
|
---|
320 |
|
---|
321 | ### `node.raws`
|
---|
322 |
|
---|
323 | Extra whitespaces around the node will be assigned to `node.raws.before` and
|
---|
324 | `node.raws.after`. Spaces in this context have no semantic meaning, but may
|
---|
325 | be useful for inspection:
|
---|
326 |
|
---|
327 | ```css
|
---|
328 | 1px solid black
|
---|
329 | ```
|
---|
330 |
|
---|
331 | Any space following a node/segement is assigned to the next node's
|
---|
332 | `raws.before` property, unless the node with the trailing space is the only
|
---|
333 | node in the set.
|
---|
334 |
|
---|
335 | ```js
|
---|
336 | let source = 'calc(something about mary)';
|
---|
337 | let ast = parser(source).parse();
|
---|
338 | let func = ast.first.first;
|
---|
339 |
|
---|
340 | let something = func.first.next();
|
---|
341 | let about = something.next();
|
---|
342 |
|
---|
343 | something.raws.after;
|
---|
344 | // → (empty)
|
---|
345 |
|
---|
346 | about.raws.before;
|
---|
347 | // → ' '
|
---|
348 | ```
|
---|
349 |
|
---|
350 | Additionally, any space remaining after the last node in a
|
---|
351 | set will be assigned to the last non-symbol child's `raws.after` property.
|
---|
352 | For example:
|
---|
353 |
|
---|
354 | ```js
|
---|
355 | let source = 'calc(something )';
|
---|
356 | let ast = parser(source).parse();
|
---|
357 | let func = ast.first.first;
|
---|
358 |
|
---|
359 | let something = func.first.next();
|
---|
360 | something.raws.after;
|
---|
361 | // → ' '
|
---|
362 | ```
|
---|
363 |
|
---|
364 | ### `node.source`
|
---|
365 |
|
---|
366 | An object describing the node's start/end, line/column source position.
|
---|
367 |
|
---|
368 | Within the following CSS, the `.bar` class node ...
|
---|
369 |
|
---|
370 | ```css
|
---|
371 | .foo,
|
---|
372 | .bar {}
|
---|
373 | ```
|
---|
374 |
|
---|
375 | ... will contain the following `source` object.
|
---|
376 |
|
---|
377 | ```js
|
---|
378 | source: {
|
---|
379 | start: {
|
---|
380 | line: 2,
|
---|
381 | column: 3
|
---|
382 | },
|
---|
383 | end: {
|
---|
384 | line: 2,
|
---|
385 | column: 6
|
---|
386 | }
|
---|
387 | }
|
---|
388 | ```
|
---|
389 |
|
---|
390 | ### `node.sourceIndex`
|
---|
391 |
|
---|
392 | The zero-based index of the node within the original source string.
|
---|
393 |
|
---|
394 | Within the following CSS, the `.baz` class node will have a `sourceIndex` of `12`.
|
---|
395 |
|
---|
396 | ```css
|
---|
397 | .foo, .bar, .baz {}
|
---|
398 | ```
|
---|
399 |
|
---|
400 | ## Container types
|
---|
401 |
|
---|
402 | The `root`, `node`, and `pseudo` nodes have some helper methods for working
|
---|
403 | with their children.
|
---|
404 |
|
---|
405 | ### `container.nodes`
|
---|
406 |
|
---|
407 | An array of the container's children.
|
---|
408 |
|
---|
409 | ```js
|
---|
410 | // Input: h1 h2
|
---|
411 | nodes.at(0).nodes.length // → 3
|
---|
412 | nodes.at(0).nodes[0].value // → 'h1'
|
---|
413 | nodes.at(0).nodes[1].value // → ' '
|
---|
414 | ```
|
---|
415 |
|
---|
416 | ### `container.first` & `container.last`
|
---|
417 |
|
---|
418 | The first/last child of the container.
|
---|
419 |
|
---|
420 | ```js
|
---|
421 | node.first === node.nodes[0];
|
---|
422 | node.last === node.nodes[node.nodes.length - 1];
|
---|
423 | ```
|
---|
424 |
|
---|
425 | ### `container.at(index)`
|
---|
426 |
|
---|
427 | Returns the node at position `index`.
|
---|
428 |
|
---|
429 | ```js
|
---|
430 | node.at(0) === node.first;
|
---|
431 | node.at(0) === node.nodes[0];
|
---|
432 | ```
|
---|
433 |
|
---|
434 | Arguments:
|
---|
435 |
|
---|
436 | * `index`: The index of the node to return.
|
---|
437 |
|
---|
438 | ### `container.index(node)`
|
---|
439 |
|
---|
440 | Return the index of the node within its container.
|
---|
441 |
|
---|
442 | ```js
|
---|
443 | node.index(node.nodes[2]) // → 2
|
---|
444 | ```
|
---|
445 |
|
---|
446 | Arguments:
|
---|
447 |
|
---|
448 | * `node`: A node within the current container.
|
---|
449 |
|
---|
450 | ### `container.length`
|
---|
451 |
|
---|
452 | Proxy to the length of the container's nodes.
|
---|
453 |
|
---|
454 | ```js
|
---|
455 | container.length === container.nodes.length
|
---|
456 | ```
|
---|
457 |
|
---|
458 | ### `container.each(callback)`
|
---|
459 |
|
---|
460 | Iterate the container's immediate children, calling `callback` for each child.
|
---|
461 | You may return `false` within the callback to break the iteration.
|
---|
462 |
|
---|
463 | ```js
|
---|
464 | let className;
|
---|
465 | nodes.each(function (node, index) {
|
---|
466 | if (node.type === 'class') {
|
---|
467 | className = node.value;
|
---|
468 | return false;
|
---|
469 | }
|
---|
470 | });
|
---|
471 | ```
|
---|
472 |
|
---|
473 | Note that unlike `Array#forEach()`, this iterator is safe to use whilst adding
|
---|
474 | or removing nodes from the container.
|
---|
475 |
|
---|
476 | Arguments:
|
---|
477 |
|
---|
478 | * `callback (function)`: A function to call for each node, which receives `node`
|
---|
479 | and `index` arguments.
|
---|
480 |
|
---|
481 | ### `container.walk(callback)`
|
---|
482 |
|
---|
483 | Like `container#each`, but will also iterate child nodes as long as they are
|
---|
484 | `container` types.
|
---|
485 |
|
---|
486 | ```js
|
---|
487 | nodes.walk(function (node, index) {
|
---|
488 | // all nodes
|
---|
489 | });
|
---|
490 | ```
|
---|
491 |
|
---|
492 | Arguments:
|
---|
493 |
|
---|
494 | * `callback (function)`: A function to call for each node, which receives `node`
|
---|
495 | and `index` arguments.
|
---|
496 |
|
---|
497 | This iterator is safe to use whilst mutating `container.nodes`,
|
---|
498 | like `container#each`.
|
---|
499 |
|
---|
500 | ### `container.walk` proxies
|
---|
501 |
|
---|
502 | The container class provides proxy methods for iterating over types of nodes,
|
---|
503 | so that it is easier to write modules that target specific nodes. Those
|
---|
504 | methods are:
|
---|
505 |
|
---|
506 | * `container.walkAtWords`
|
---|
507 | * `container.walkColons`
|
---|
508 | * `container.walkCommas`
|
---|
509 | * `container.walkComments`
|
---|
510 | * `container.walkFunctionNodes`
|
---|
511 | * `container.walkNumberNodes`
|
---|
512 | * `container.walkOperators`
|
---|
513 | * `container.walkParenthesis`
|
---|
514 | * `container.walkStringNodes`
|
---|
515 | * `container.walkUnicodeRanges`
|
---|
516 | * `container.walkWords`
|
---|
517 |
|
---|
518 | ### `container.prepend(node)` & `container.append(node)`
|
---|
519 |
|
---|
520 | Add a node to the start/end of the container. Note that doing so will set
|
---|
521 | the parent property of the node to this container.
|
---|
522 |
|
---|
523 | ```js
|
---|
524 | let color = parser.word({ value: '#fff' });
|
---|
525 | node.append(color);
|
---|
526 | ```
|
---|
527 |
|
---|
528 | Arguments:
|
---|
529 |
|
---|
530 | * `node`: The node to add.
|
---|
531 |
|
---|
532 | ### `container.insertBefore(old, new)` & `container.insertAfter(old, new)`
|
---|
533 |
|
---|
534 | Add a node before or after an existing node in a container:
|
---|
535 |
|
---|
536 | ```js
|
---|
537 | nodes.walk(function (node) {
|
---|
538 | if (node.type !== 'word') {
|
---|
539 | let colon = parser.colon();
|
---|
540 | node.parent.insertAfter(node, colon);
|
---|
541 | }
|
---|
542 | });
|
---|
543 | ```
|
---|
544 |
|
---|
545 | Arguments:
|
---|
546 |
|
---|
547 | * `old`: The existing node in the container.
|
---|
548 | * `new`: The new node to add before/after the existing node.
|
---|
549 |
|
---|
550 | ### `container.removeChild(node)`
|
---|
551 |
|
---|
552 | Remove the node from the container. Note that you can also use
|
---|
553 | `node.remove()` if you would like to remove just a single node.
|
---|
554 |
|
---|
555 | ```js
|
---|
556 | node.length // → 2
|
---|
557 | node.remove(word)
|
---|
558 | node.length // → 1;
|
---|
559 | word.parent // undefined
|
---|
560 | ```
|
---|
561 |
|
---|
562 | Arguments:
|
---|
563 |
|
---|
564 | * `node`: The node to remove.
|
---|
565 |
|
---|
566 | ### `container.removeAll()` or `container.empty()`
|
---|
567 |
|
---|
568 | Remove all children from the container.
|
---|
569 |
|
---|
570 | ```js
|
---|
571 | node.removeAll();
|
---|
572 | node.length // → 0
|
---|
573 | ```
|
---|
574 |
|
---|
575 | ## Root nodes`
|
---|
576 |
|
---|
577 | A root node represents the top-level Container for Value nodes. Indeed, all
|
---|
578 | a root's `toString()` method does is join its node children with a ','.
|
---|
579 | Other than this, it has no special functionality and acts like a container.
|
---|
580 |
|
---|
581 | ## Value nodes
|
---|
582 |
|
---|
583 | A Value node represents a single compound node. For example, this
|
---|
584 | node string `1px solid black`, is represented as three distinct nodes.
|
---|
585 | It has no special functionality of its own.
|
---|