.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / postcss-selector-parser / API.md
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 ## `parser` function
7
8 This is the module's main entry point.
9
10 ```js
11 const parser = require('postcss-selector-parser');
12 ```
13
14 ### `parser([transform], [options])`
15
16 Creates a new `processor` instance
17
18 ```js
19 const processor = parser();
20
21 // or, with optional transform function
22 const transform = selectors => {
23     selectors.walkUniversals(selector => {
24         selector.remove();
25     });
26 };
27
28 const processor = parser(transform)
29
30 // Example
31 const result = processor.processSync('*.class');
32 // => .class
33 ```
34
35 [See processor documentation](#processor)
36
37 Arguments:
38
39 * `transform (function)`: Provide a function to work with the parsed AST.
40 * `options (object)`: Provide default options for all calls on the returned `Processor`.
41
42 ### `parser.attribute([props])`
43
44 Creates a new attribute selector.
45
46 ```js
47 parser.attribute({attribute: 'href'});
48 // => [href]
49 ```
50
51 Arguments:
52
53 * `props (object)`: The new node's properties.
54
55 ### `parser.className([props])`
56
57 Creates a new class selector.
58
59 ```js
60 parser.className({value: 'button'});
61 // => .button
62 ```
63
64 Arguments:
65
66 * `props (object)`: The new node's properties.
67
68 ### `parser.combinator([props])`
69
70 Creates a new selector combinator.
71
72 ```js
73 parser.combinator({value: '+'});
74 // => +
75 ```
76
77 Arguments:
78
79 * `props (object)`: The new node's properties.
80
81 ### `parser.comment([props])`
82
83 Creates a new comment.
84
85 ```js
86 parser.comment({value: '/* Affirmative, Dave. I read you. */'});
87 // => /* Affirmative, Dave. I read you. */
88 ```
89
90 Arguments:
91
92 * `props (object)`: The new node's properties.
93
94 ### `parser.id([props])`
95
96 Creates a new id selector.
97
98 ```js
99 parser.id({value: 'search'});
100 // => #search
101 ```
102
103 Arguments:
104
105 * `props (object)`: The new node's properties.
106
107 ### `parser.nesting([props])`
108
109 Creates a new nesting selector.
110
111 ```js
112 parser.nesting();
113 // => &
114 ```
115
116 Arguments:
117
118 * `props (object)`: The new node's properties.
119
120 ### `parser.pseudo([props])`
121
122 Creates a new pseudo selector.
123
124 ```js
125 parser.pseudo({value: '::before'});
126 // => ::before
127 ```
128
129 Arguments:
130
131 * `props (object)`: The new node's properties.
132
133 ### `parser.root([props])`
134
135 Creates a new root node.
136
137 ```js
138 parser.root();
139 // => (empty)
140 ```
141
142 Arguments:
143
144 * `props (object)`: The new node's properties.
145
146 ### `parser.selector([props])`
147
148 Creates a new selector node.
149
150 ```js
151 parser.selector();
152 // => (empty)
153 ```
154
155 Arguments:
156
157 * `props (object)`: The new node's properties.
158
159 ### `parser.string([props])`
160
161 Creates a new string node.
162
163 ```js
164 parser.string();
165 // => (empty)
166 ```
167
168 Arguments:
169
170 * `props (object)`: The new node's properties.
171
172 ### `parser.tag([props])`
173
174 Creates a new tag selector.
175
176 ```js
177 parser.tag({value: 'button'});
178 // => button
179 ```
180
181 Arguments:
182
183 * `props (object)`: The new node's properties.
184
185 ### `parser.universal([props])`
186
187 Creates a new universal selector.
188
189 ```js
190 parser.universal();
191 // => *
192 ```
193
194 Arguments:
195
196 * `props (object)`: The new node's properties.
197
198 ## Node types
199
200 ### `node.type`
201
202 A string representation of the selector type. It can be one of the following;
203 `attribute`, `class`, `combinator`, `comment`, `id`, `nesting`, `pseudo`,
204 `root`, `selector`, `string`, `tag`, or `universal`. Note that for convenience,
205 these constants are exposed on the main `parser` as uppercased keys. So for
206 example you can get `id` by querying `parser.ID`.
207
208 ```js
209 parser.attribute({attribute: 'href'}).type;
210 // => 'attribute'
211 ```
212
213 ### `node.parent`
214
215 Returns the parent node.
216
217 ```js
218 root.nodes[0].parent === root;
219 ```
220
221 ### `node.toString()`, `String(node)`, or `'' + node`
222
223 Returns a string representation of the node.
224
225 ```js
226 const id = parser.id({value: 'search'});
227 console.log(String(id));
228 // => #search
229 ```
230
231 ### `node.next()` & `node.prev()`
232
233 Returns the next/previous child of the parent node.
234
235 ```js
236 const next = id.next();
237 if (next && next.type !== 'combinator') {
238     throw new Error('Qualified IDs are not allowed!');
239 }
240 ```
241
242 ### `node.replaceWith(node)`
243
244 Replace a node with another.
245
246 ```js
247 const attr = selectors.first.first;
248 const className = parser.className({value: 'test'});
249 attr.replaceWith(className);
250 ```
251
252 Arguments:
253
254 * `node`: The node to substitute the original with.
255
256 ### `node.remove()`
257
258 Removes the node from its parent node.
259
260 ```js
261 if (node.type === 'id') {
262     node.remove();
263 }
264 ```
265
266 ### `node.clone()`
267
268 Returns a copy of a node, detached from any parent containers that the
269 original might have had.
270
271 ```js
272 const cloned = parser.id({value: 'search'});
273 String(cloned);
274
275 // => #search
276 ```
277
278 ### `node.spaces`
279
280 Extra whitespaces around the node will be moved into `node.spaces.before` and
281 `node.spaces.after`. So for example, these spaces will be moved as they have
282 no semantic meaning:
283
284 ```css
285       h1     ,     h2   {}
286 ```
287
288 However, *combinating* spaces will form a `combinator` node:
289
290 ```css
291 h1        h2 {}
292 ```
293
294 A `combinator` node may only have the `spaces` property set if the combinator
295 value is a non-whitespace character, such as `+`, `~` or `>`. Otherwise, the
296 combinator value will contain all of the spaces between selectors.
297
298 ### `node.source`
299
300 An object describing the node's start/end, line/column source position.
301
302 Within the following CSS, the `.bar` class node ...
303
304 ```css
305 .foo,
306   .bar {}
307 ```
308
309 ... will contain the following `source` object.
310
311 ```js
312 source: {
313     start: {
314         line: 2,
315         column: 3
316     },
317     end: {
318         line: 2,
319         column: 6
320     }
321 }
322 ```
323
324 ### `node.sourceIndex`
325
326 The zero-based index of the node within the original source string.
327
328 Within the following CSS, the `.baz` class node will have a `sourceIndex` of `12`.
329
330 ```css
331 .foo, .bar, .baz {}
332 ```
333
334 ## Container types
335
336 The `root`, `selector`, and `pseudo` nodes have some helper methods for working
337 with their children.
338
339 ### `container.nodes`
340
341 An array of the container's children.
342
343 ```js
344 // Input: h1 h2
345 selectors.at(0).nodes.length   // => 3
346 selectors.at(0).nodes[0].value // => 'h1'
347 selectors.at(0).nodes[1].value // => ' '
348 ```
349
350 ### `container.first` & `container.last`
351
352 The first/last child of the container.
353
354 ```js
355 selector.first === selector.nodes[0];
356 selector.last === selector.nodes[selector.nodes.length - 1];
357 ```
358
359 ### `container.at(index)`
360
361 Returns the node at position `index`.
362
363 ```js
364 selector.at(0) === selector.first;
365 selector.at(0) === selector.nodes[0];
366 ```
367
368 Arguments:
369
370 * `index`: The index of the node to return.
371
372 ### `container.index(node)`
373
374 Return the index of the node within its container.
375
376 ```js
377 selector.index(selector.nodes[2]) // => 2
378 ```
379
380 Arguments:
381
382 * `node`: A node within the current container.
383
384 ### `container.length`
385
386 Proxy to the length of the container's nodes.
387
388 ```js
389 container.length === container.nodes.length
390 ```
391
392 ### `container` Array iterators
393
394 The container class provides proxies to certain Array methods; these are:
395
396 * `container.map === container.nodes.map`
397 * `container.reduce === container.nodes.reduce`
398 * `container.every === container.nodes.every`
399 * `container.some === container.nodes.some`
400 * `container.filter === container.nodes.filter`
401 * `container.sort === container.nodes.sort`
402
403 Note that these methods only work on a container's immediate children; recursive
404 iteration is provided by `container.walk`.
405
406 ### `container.each(callback)`
407
408 Iterate the container's immediate children, calling `callback` for each child.
409 You may return `false` within the callback to break the iteration.
410
411 ```js
412 let className;
413 selectors.each((selector, index) => {
414     if (selector.type === 'class') {
415         className = selector.value;
416         return false;
417     }
418 });
419 ```
420
421 Note that unlike `Array#forEach()`, this iterator is safe to use whilst adding
422 or removing nodes from the container.
423
424 Arguments:
425
426 * `callback (function)`: A function to call for each node, which receives `node`
427   and `index` arguments.
428
429 ### `container.walk(callback)`
430
431 Like `container#each`, but will also iterate child nodes as long as they are
432 `container` types.
433
434 ```js
435 selectors.walk((selector, index) => {
436     // all nodes
437 });
438 ```
439
440 Arguments:
441
442 * `callback (function)`: A function to call for each node, which receives `node`
443   and `index` arguments.
444
445 This iterator is safe to use whilst mutating `container.nodes`,
446 like `container#each`.
447
448 ### `container.walk` proxies
449
450 The container class provides proxy methods for iterating over types of nodes,
451 so that it is easier to write modules that target specific selectors. Those
452 methods are:
453
454 * `container.walkAttributes`
455 * `container.walkClasses`
456 * `container.walkCombinators`
457 * `container.walkComments`
458 * `container.walkIds`
459 * `container.walkNesting`
460 * `container.walkPseudos`
461 * `container.walkTags`
462 * `container.walkUniversals`
463
464 ### `container.split(callback)`
465
466 This method allows you to split a group of nodes by returning `true` from
467 a callback. It returns an array of arrays, where each inner array corresponds
468 to the groups that you created via the callback.
469
470 ```js
471 // (input) => h1 h2>>h3
472 const list = selectors.first.split(selector => {
473     return selector.type === 'combinator';
474 });
475
476 // (node values) => [['h1', ' '], ['h2', '>>'], ['h3']]
477 ```
478
479 Arguments:
480
481 * `callback (function)`: A function to call for each node, which receives `node`
482   as an argument.
483
484 ### `container.prepend(node)` & `container.append(node)`
485
486 Add a node to the start/end of the container. Note that doing so will set
487 the parent property of the node to this container.
488
489 ```js
490 const id = parser.id({value: 'search'});
491 selector.append(id);
492 ```
493
494 Arguments:
495
496 * `node`: The node to add.
497
498 ### `container.insertBefore(old, new)` & `container.insertAfter(old, new)`
499
500 Add a node before or after an existing node in a container:
501
502 ```js
503 selectors.walk(selector => {
504     if (selector.type !== 'class') {
505         const className = parser.className({value: 'theme-name'});
506         selector.parent.insertAfter(selector, className);
507     }
508 });
509 ```
510
511 Arguments:
512
513 * `old`: The existing node in the container.
514 * `new`: The new node to add before/after the existing node.
515
516 ### `container.removeChild(node)`
517
518 Remove the node from the container. Note that you can also use
519 `node.remove()` if you would like to remove just a single node.
520
521 ```js
522 selector.length // => 2
523 selector.remove(id)
524 selector.length // => 1;
525 id.parent       // undefined
526 ```
527
528 Arguments:
529
530 * `node`: The node to remove.
531
532 ### `container.removeAll()` or `container.empty()`
533
534 Remove all children from the container.
535
536 ```js
537 selector.removeAll();
538 selector.length // => 0
539 ```
540
541 ## Root nodes
542
543 A root node represents a comma separated list of selectors. Indeed, all
544 a root's `toString()` method does is join its selector children with a ','.
545 Other than this, it has no special functionality and acts like a container.
546
547 ### `root.trailingComma`
548
549 This will be set to `true` if the input has a trailing comma, in order to
550 support parsing of legacy CSS hacks.
551
552 ## Selector nodes
553
554 A selector node represents a single compound selector. For example, this
555 selector string `h1 h2 h3, [href] > p`, is represented as two selector nodes.
556 It has no special functionality of its own.
557
558 ## Pseudo nodes
559
560 A pseudo selector extends a container node; if it has any parameters of its
561 own (such as `h1:not(h2, h3)`), they will be its children. Note that the pseudo
562 `value` will always contain the colons preceding the pseudo identifier. This
563 is so that both `:before` and `::before` are properly represented in the AST.
564
565 ## Attribute nodes
566
567 ### `attribute.quoted`
568
569 Returns `true` if the attribute's value is wrapped in quotation marks, false if it is not.
570 Remains `undefined` if there is no attribute value.
571
572 ```css
573 [href=foo] /* false */
574 [href='foo'] /* true */
575 [href="foo"] /* true */
576 [href] /* undefined */
577 ```
578
579 ### `attribute.qualifiedAttribute`
580
581 Returns the attribute name qualified with the namespace if one is given.
582
583 ### `attribute.offsetOf(part)`
584
585  Returns the offset of the attribute part specified relative to the
586  start of the node of the output string. This is useful in raising
587  error messages about a specific part of the attribute, especially
588  in combination with `attribute.sourceIndex`.
589
590  Returns `-1` if the name is invalid or the value doesn't exist in this
591  attribute.
592
593  The legal values for `part` are:
594
595  * `"ns"` - alias for "namespace"
596  * `"namespace"` - the namespace if it exists.
597  * `"attribute"` - the attribute name
598  * `"attributeNS"` - the start of the attribute or its namespace
599  * `"operator"` - the match operator of the attribute
600  * `"value"` - The value (string or identifier)
601  * `"insensitive"` - the case insensitivity flag
602
603 ### `attribute.raws.unquoted`
604
605 Returns the unquoted content of the attribute's value.
606 Remains `undefined` if there is no attribute value.
607
608 ```css
609 [href=foo] /* foo */
610 [href='foo'] /* foo */
611 [href="foo"] /* foo */
612 [href] /* undefined */
613 ```
614
615 ### `attribute.spaces`
616
617 Like `node.spaces` with the `before` and `after` values containing the spaces
618 around the element, the parts of the attribute can also have spaces before
619 and after them. The for each of `attribute`, `operator`, `value` and
620 `insensitive` there is corresponding property of the same nam in
621 `node.spaces` that has an optional `before` or `after` string containing only
622 whitespace.
623
624 Note that corresponding values in `attributes.raws.spaces` contain values
625 including any comments. If set, these values will override the
626 `attribute.spaces` value. Take care to remove them if changing
627 `attribute.spaces`.
628
629 ### `attribute.raws`
630
631 The raws object stores comments and other information necessary to re-render
632 the node exactly as it was in the source.
633
634 If a comment is embedded within the identifiers for the `namespace`, `attribute`
635 or `value` then a property is placed in the raws for that value containing the full source of the propery including comments.
636
637 If a comment is embedded within the space between parts of the attribute
638 then the raw for that space is set accordingly.
639
640 Setting an attribute's property `raws` value to be deleted.
641
642 For now, changing the spaces required also updating or removing any of the 
643 raws values that override them.
644
645 Example: `[ /*before*/ href /* after-attr */ = /* after-operator */ te/*inside-value*/st/* wow */ /*omg*/i/*bbq*/ /*whodoesthis*/]` would parse as:
646
647 ```js
648 {
649   attribute: "href",
650   operatator: "=",
651   value: "test",
652   spaces: {
653     before: '',
654     after: '',
655     attribute: { before: '  ', after: '  ' },
656     operator: { after: '  ' },
657     value: { after: ' ' },
658     insensitive: { after: ' ' }
659   },
660   raws: {
661     spaces: {
662       attribute: { before: ' /*before*/ ', after: ' /* after-attr */ ' },
663       operator: { after: ' /* after-operator */ ' },
664       value: { after: '/* wow */ /*omg*/' },
665       insensitive: { after: '/*bbq*/ /*whodoesthis*/' }
666     },
667     unquoted: 'test',
668     value: 'te/*inside-value*/st'
669   }
670 }
671 ```
672
673 ## `Processor`
674
675 ### `ProcessorOptions`
676
677 * `lossless` - When `true`, whitespace is preserved. Defaults to `true`.
678 * `updateSelector` - When `true`, if any processor methods are passed a postcss
679   `Rule` node instead of a string, then that Rule's selector is updated
680   with the results of the processing. Defaults to `true`.
681
682 ### `process|processSync(selectors, [options])`
683
684 Processes the `selectors`, returning a string from the result of processing.
685
686 Note: when the `updateSelector` option is set, the rule's selector
687 will be updated with the resulting string.
688
689 **Example:**
690
691 ```js
692 const parser = require("postcss-selector-parser");
693 const processor = parser();
694
695 let result = processor.processSync(' .class');
696 console.log(result);
697 // =>  .class
698
699 // Asynchronous operation
700 let promise = processor.process(' .class').then(result => {
701     console.log(result)
702     // => .class
703 });
704
705 // To have the parser normalize whitespace values, utilize the options
706 result = processor.processSync('  .class  ', {lossless: false});
707 console.log(result);
708 // => .class
709
710 // For better syntax errors, pass a PostCSS Rule node.
711 const postcss = require('postcss');
712 rule = postcss.rule({selector: ' #foo    > a,  .class  '});
713 processor.process(rule, {lossless: false, updateSelector: true}).then(result => {
714     console.log(result);
715     // => #foo>a,.class
716     console.log("rule:", rule.selector);
717     // => rule: #foo>a,.class
718 })
719 ```
720
721 Arguments:
722
723 * `selectors (string|postcss.Rule)`: Either a selector string or a PostCSS Rule
724   node.
725 * `[options] (object)`: Process options
726
727
728 ### `ast|astSync(selectors, [options])`
729
730 Like `process()` and `processSync()` but after
731 processing the `selectors` these methods return the `Root` node of the result
732 instead of a string.
733
734 Note: when the `updateSelector` option is set, the rule's selector
735 will be updated with the resulting string.
736
737 ### `transform|transformSync(selectors, [options])`
738
739 Like `process()` and `processSync()` but after
740 processing the `selectors` these methods return the value returned by the
741 processor callback.
742
743 Note: when the `updateSelector` option is set, the rule's selector
744 will be updated with the resulting string.
745
746 ### Error Handling Within Selector Processors
747
748 The root node passed to the selector processor callback
749 has a method `error(message, options)` that returns an
750 error object. This method should always be used to raise
751 errors relating to the syntax of selectors. The options
752 to this method are passed to postcss's error constructor
753 ([documentation](http://api.postcss.org/Container.html#error)).
754
755 #### Async Error Example
756
757 ```js
758 let processor = (root) => {
759     return new Promise((resolve, reject) => {
760         root.walkClasses((classNode) => {
761             if (/^(.*)[-_]/.test(classNode.value)) {
762                 let msg = "classes may not have underscores or dashes in them";
763                 reject(root.error(msg, {
764                     index: classNode.sourceIndex + RegExp.$1.length + 1,
765                     word: classNode.value
766                 }));
767             }
768         });
769         resolve();
770     });
771 };
772
773 const postcss = require("postcss");
774 const parser = require("postcss-selector-parser");
775 const selectorProcessor = parser(processor);
776 const plugin = postcss.plugin('classValidator', (options) => {
777     return (root) => {
778         let promises = [];
779         root.walkRules(rule => {
780             promises.push(selectorProcessor.process(rule));
781         });
782         return Promise.all(promises);
783     };
784 });
785 postcss(plugin()).process(`
786 .foo-bar {
787   color: red;
788 }
789 `.trim(), {from: 'test.css'}).catch((e) => console.error(e.toString()));
790
791 // CssSyntaxError: classValidator: ./test.css:1:5: classes may not have underscores or dashes in them
792 // 
793 // > 1 | .foo-bar {
794 //     |     ^
795 //   2 |   color: red;
796 //   3 | }
797 ```
798
799 #### Synchronous Error Example
800
801 ```js
802 let processor = (root) => {
803     root.walkClasses((classNode) => {
804         if (/.*[-_]/.test(classNode.value)) {
805             let msg = "classes may not have underscores or dashes in them";
806             throw root.error(msg, {
807                 index: classNode.sourceIndex,
808                 word: classNode.value
809             });
810         }
811     });
812 };
813
814 const postcss = require("postcss");
815 const parser = require("postcss-selector-parser");
816 const selectorProcessor = parser(processor);
817 const plugin = postcss.plugin('classValidator', (options) => {
818     return (root) => {
819         root.walkRules(rule => {
820             selectorProcessor.processSync(rule);
821         });
822     };
823 });
824 postcss(plugin()).process(`
825 .foo-bar {
826   color: red;
827 }
828 `.trim(), {from: 'test.css'}).catch((e) => console.error(e.toString()));
829
830 // CssSyntaxError: classValidator: ./test.css:1:5: classes may not have underscores or dashes in them
831 // 
832 // > 1 | .foo-bar {
833 //     |     ^
834 //   2 |   color: red;
835 //   3 | }
836 ```