### Quick Start: Parse and Transform Selectors Source: https://github.com/postcss/postcss-selector-parser/blob/master/README.md This example demonstrates how to use the parser to walk through selectors and perform actions on each one. It logs the string representation of each selector. ```javascript const parser = require('postcss-selector-parser'); const transform = selectors => { selectors.walk(selector => { // do something with the selector console.log(String(selector)) }); }; const transformed = parser(transform).processSync('h1, h2, h3'); ``` -------------------------------- ### Install postcss-selector-parser with npm Source: https://github.com/postcss/postcss-selector-parser/blob/master/README.md Use this command to install the library via npm. ```bash npm install postcss-selector-parser ``` -------------------------------- ### Create a Processor with Transform Function Source: https://context7.com/postcss/postcss-selector-parser/llms.txt Creates a processor with a transform function to modify the selector AST. This example removes all universal selectors. ```javascript const parser = require('postcss-selector-parser'); // Processor with a transform: remove all universal selectors const stripUniversal = parser(selectors => { selectors.walkUniversals(node => node.remove()); }); console.log(stripUniversal.processSync('*.active, *')); // => '.active, ' ``` -------------------------------- ### Attribute Parsing Example Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Demonstrates the parsed structure of a complex attribute selector, including spaces and raw values with comments. Useful for understanding how the parser breaks down and stores attribute information. ```js { attribute: "href", operator: "=", value: "test", spaces: { before: '', after: '', attribute: { before: ' ', after: ' ' }, operator: { after: ' ' }, value: { after: ' ' }, insensitive: { after: ' ' } }, raws: { spaces: { attribute: { before: ' /*before*/ ', after: ' /* after-attr */ ' }, operator: { after: ' /* after-operator */ ' }, value: { after: '/* wow */ /*omg*/' }, insensitive: { after: '/*bbq*/ /*whodoesthis*/' } }, unquoted: 'test', value: 'te/*inside-value*/st' } } ``` -------------------------------- ### Split selectors by combinator Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Use the `split` method to divide a group of nodes based on a callback function. This example splits selectors whenever a combinator is encountered. ```javascript // (input) => h1 h2>>h3 const list = selectors.first.split(selector => { return selector.type === 'combinator'; }); // (node values) => [['h1', ' '], ['h2', '>>'], ['h3']] ``` -------------------------------- ### Normalize Selector Whitespace Source: https://github.com/postcss/postcss-selector-parser/blob/master/README.md This example shows how to normalize whitespace within selector strings using the `lossless: false` option. ```javascript const parser = require('postcss-selector-parser'); const normalized = parser().processSync('h1, h2, h3', {lossless: false}); // -> h1,h2,h3 ``` -------------------------------- ### Get Next or Previous Node Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Use `next()` and `prev()` methods to navigate to the next or previous sibling node within the parent. ```javascript const next = id.next(); if (next && next.type !== 'combinator') { throw new Error('Qualified IDs are not allowed!'); } ``` -------------------------------- ### Async Error Handling with PostCSS Selector Parser Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md This example demonstrates how to handle errors asynchronously when processing selectors. It uses a Promise-based processor that rejects on validation failure. ```javascript let processor = (root) => { return new Promise((resolve, reject) => { root.walkClasses((classNode) => { if (/^(.*)[-_]/.test(classNode.value)) { let msg = "classes may not have underscores or dashes in them"; reject(root.error(msg, { index: classNode.sourceIndex + RegExp.$1.length + 1, word: classNode.value })); } }); resolve(); }); }; const postcss = require("postcss"); const parser = require("postcss-selector-parser"); const selectorProcessor = parser(processor); const plugin = postcss.plugin('classValidator', (options) => { return (root) => { let promises = []; root.walkRules(rule => { promises.push(selectorProcessor.process(rule)); }); return Promise.all(promises); }; }); postcss(plugin()).process( `.foo-bar { color: red; }`.trim(), {from: 'test.css'}).catch((e) => console.error(e.toString())); // CssSyntaxError: classValidator: ./test.css:1:5: classes may not have underscores or dashes in them // // > 1 | .foo-bar { // | ^ // 2 | color: red; // 3 | } ``` -------------------------------- ### processor.astSync(selector, [options]) — Get AST Synchronously Source: https://context7.com/postcss/postcss-selector-parser/llms.txt Parses a selector string synchronously and returns the Abstract Syntax Tree (AST) `Root` node directly. This is useful for detailed inspection or complex, multi-step transformations. ```APIDOC ## processor.astSync(selector, [options]) ### Description Parses a selector and returns the `Root` AST node directly instead of a string. Useful for deep inspection or multi-step transformations. ### Parameters #### selector - **selector** (string) - The CSS selector string to parse. #### options - **options** (object) - Optional. Configuration options. See `processSync` for details. ### Usage Examples ```javascript const parser = require('postcss-selector-parser'); const root = parser().astSync('h1 > .title, a[href]:hover'); console.log(root.nodes.length); // => 2 root.nodes[0].each((node, i) => { console.log(i, node.type, node.value); }); // 0 tag h1 // 1 combinator > // 2 class title ``` ``` -------------------------------- ### node.source Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md An object containing source position information, including start and end line/column numbers. ```APIDOC ## node.source ### Description An object describing the node's start/end, line/column source position. Within the following CSS, the `.bar` class node ... ```css .foo, .bar {} ``` ... will contain the following `source` object. ```js source: { start: { line: 2, column: 3 }, end: { line: 2, column: 6 } } ``` ``` -------------------------------- ### Synchronous Error Handling with PostCSS Selector Parser Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md This example shows synchronous error handling using PostCSS Selector Parser. The processor throws an error immediately when a validation rule is violated. ```javascript let processor = (root) => { root.walkClasses((classNode) => { if (/.*[-_]/.test(classNode.value)) { let msg = "classes may not have underscores or dashes in them"; throw root.error(msg, { index: classNode.sourceIndex, word: classNode.value }); } }); }; const postcss = require("postcss"); const parser = require("postcss-selector-parser"); const selectorProcessor = parser(processor); const plugin = postcss.plugin('classValidator', (options) => { return (root) => { root.walkRules(rule => { selectorProcessor.processSync(rule); }); }; }); postcss(plugin()).process( `.foo-bar { color: red; }`.trim(), {from: 'test.css'}).catch((e) => console.error(e.toString())); // CssSyntaxError: classValidator: ./test.css:1:5: classes may not have underscores or dashes in them // // > 1 | .foo-bar { // | ^ // 2 | color: red; // 3 | } ``` -------------------------------- ### node.source / node.sourceIndex Source: https://context7.com/postcss/postcss-selector-parser/llms.txt Provides access to source metadata for each parsed node. `node.source` contains `start` and `end` properties with line and column numbers (1-based), while `sourceIndex` gives the zero-based character offset within the original input string. ```APIDOC ## `node.source` / `node.sourceIndex` — Source Metadata Every parsed node carries `source.start` / `source.end` (line/column, 1-based) and `sourceIndex` (zero-based character offset in the input string). ```js const parser = require('postcss-selector-parser'); const root = parser().astSync('.foo, .bar, .baz'); root.walkClasses(cls => { console.log( cls.value, 'starts at index', cls.sourceIndex, 'line', cls.source.start.line, 'col', cls.source.start.column ); }); // foo starts at index 0 line 1 col 1 // bar starts at index 6 line 1 col 7 // baz starts at index 12 line 1 col 13 ``` ``` -------------------------------- ### Get AST Asynchronously Source: https://context7.com/postcss/postcss-selector-parser/llms.txt Parses a selector string and returns the AST `Root` node as a Promise. This allows for asynchronous operations within the parsing or transformation process. ```javascript const parser = require('postcss-selector-parser'); parser().ast('input[type="text"]::placeholder').then(root => { root.walkAttributes(attr => { console.log(attr.attribute, attr.operator, attr.value, attr.quoteMark); // => type = text " }); root.walkPseudos(pseudo => { console.log(pseudo.value); // => ::placeholder }); }); ``` -------------------------------- ### Get AST Synchronously Source: https://context7.com/postcss/postcss-selector-parser/llms.txt Parses a selector string and returns the Abstract Syntax Tree (AST) `Root` node directly. Useful for detailed inspection or multi-step transformations. ```javascript const parser = require('postcss-selector-parser'); const root = parser().astSync('h1 > .title, a[href]:hover'); // Root contains Selector nodes separated by commas console.log(root.nodes.length); // => 2 // Inspect first selector's nodes root.nodes[0].each((node, i) => { console.log(i, node.type, node.value); }); // 0 tag h1 // 1 combinator > // 2 class title ``` -------------------------------- ### processor.ast(selector, [options]) — Get AST Asynchronously Source: https://context7.com/postcss/postcss-selector-parser/llms.txt Parses a selector string asynchronously and returns a Promise that resolves with the Abstract Syntax Tree (AST) `Root` node. This method is suitable for scenarios involving asynchronous operations within the parsing or transformation process. ```APIDOC ## processor.ast(selector, [options]) ### Description Like `astSync` but returns `Promise`. ### Parameters #### selector - **selector** (string) - The CSS selector string to parse. #### options - **options** (object) - Optional. Configuration options. See `processSync` for details. ### Usage Examples ```javascript const parser = require('postcss-selector-parser'); parser().ast('input[type="text"]::placeholder').then(root => { root.walkAttributes(attr => { console.log(attr.attribute, attr.operator, attr.value, attr.quoteMark); // => type = text " }); root.walkPseudos(pseudo => { console.log(pseudo.value); // => ::placeholder }); }); ``` ``` -------------------------------- ### Create a Processor with Async Transform Source: https://context7.com/postcss/postcss-selector-parser/llms.txt Demonstrates creating a processor with an asynchronous transform function. The transform function can use `await` for asynchronous operations. ```javascript const parser = require('postcss-selector-parser'); // Async transform const asyncProc = parser(async selectors => { await someAsyncCheck(); selectors.walkTags(tag => { tag.value = tag.value.toUpperCase(); }); }); asyncProc.process('div > p').then(result => { console.log(result); // => 'DIV > P' }); ``` -------------------------------- ### Processor Basic Usage Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Shows how to use the `processSync` method to parse a simple selector string. Demonstrates the default behavior of normalizing whitespace. ```js const parser = require("postcss-selector-parser"); const processor = parser(); let result = processor.processSync(' .class'); console.log(result); // => .class // To have the parser normalize whitespace values, utilize the options result = processor.processSync(' .class ', {lossless: false}); console.log(result); // => .class ``` -------------------------------- ### Get Node Type Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Access the 'type' property of a node to determine its selector type (e.g., 'attribute', 'class', 'id'). ```javascript parser.attribute({attribute: 'href'}).type; // => 'attribute' ``` -------------------------------- ### parser([transform], [options]) Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md The main entry point for the library. It creates a new processor instance, optionally accepting a transform function and default options. ```APIDOC ## `parser` function This is the module's main entry point. ```js const parser = require('postcss-selector-parser'); ``` ### `parser([transform], [options])` Creates a new `processor` instance ```js const processor = parser(); ``` Or, with optional transform function ```js const transform = selectors => { selectors.walkUniversals(selector => { selector.remove(); }); }; const processor = parser(transform) // Example const result = processor.processSync('*.class'); // => .class ``` [See processor documentation](#processor) Arguments: * `transform (function)`: Provide a function to work with the parsed AST. * `options (object)`: Provide default options for all calls on the returned `Processor`. ``` -------------------------------- ### parser.root([props]) Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Creates a new root node. ```APIDOC ### `parser.root([props])` Creates a new root node. ```js parser.root(); // => (empty) ``` Arguments: * `props (object)`: The new node's properties. ``` -------------------------------- ### parser.string([props]) Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Creates a new string node. ```APIDOC ### `parser.string([props])` Creates a new string node. ```js parser.string(); // => (empty) ``` Arguments: * `props (object)`: The new node's properties. ``` -------------------------------- ### attribute.offsetOf(part) Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Calculates the offset of a specific part of the attribute relative to the start of the node's string representation. Returns -1 if the part is invalid or not found. ```APIDOC ## attribute.offsetOf(part) ### Description Returns the offset of the attribute part specified relative to the start of the node of the output string. This is useful in raising error messages about a specific part of the attribute, especially in combination with `attribute.sourceIndex`. Returns `-1` if the name is invalid or the value doesn't exist in this attribute. The legal values for `part` are: * `"ns"` - alias for "namespace" * `"namespace"` - the namespace if it exists. * `"attribute"` - the attribute name * `"attributeNS"` - the start of the attribute or its namespace * `"operator"` - the match operator of the attribute * `"value"` - The value (string or identifier) * `"insensitive"` - the case insensitivity flag ``` -------------------------------- ### parser.universal([props]) Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Creates a new universal selector node. ```APIDOC ### `parser.universal([props])` Creates a new universal selector. ```js parser.universal(); // => * ``` Arguments: * `props (object)`: The new node's properties. ``` -------------------------------- ### Processor with PostCSS Rule Node Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Demonstrates passing a PostCSS Rule node to the `process` method for better syntax error reporting and direct selector updating. Requires the `postcss` package. ```js // For better syntax errors, pass a PostCSS Rule node. const postcss = require('postcss'); rule = postcss.rule({selector: ' #foo > a, .class '}); processor.process(rule, {lossless: false, updateSelector: true}).then(result => { console.log(result); // => #foo>a,.class console.log("rule:", rule.selector); // => rule: #foo>a,.class }) ``` -------------------------------- ### Node Source Position Information Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md The `node.source` object contains `start` and `end` properties, each with `line` and `column` numbers, detailing the node's location in the source CSS. ```javascript source: { start: { line: 2, column: 3 }, end: { line: 2, column: 6 } } ``` -------------------------------- ### Create a Parser Instance Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Create a new processor instance using the parser function. This instance can then be used to process selectors. ```javascript const processor = parser(); ``` -------------------------------- ### Create a Parser Instance with a Transform Function Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Create a processor instance with an optional transform function. This function will be applied to the parsed AST. ```javascript const transform = selectors => { selectors.walkUniversals(selector => { selector.remove(); }); }; const processor = parser(transform) ``` -------------------------------- ### parser.selector([props]) Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Creates a new selector node. ```APIDOC ### `parser.selector([props])` Creates a new selector node. ```js parser.selector(); // => (empty) ``` Arguments: * `props (object)`: The new node's properties. ``` -------------------------------- ### Get Node Index within Container Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md The `container.index(node)` method returns the zero-based index of a given node within its parent container. This is useful for relative positioning or manipulation. ```javascript selector.index(selector.nodes[2]) // => 2 ``` -------------------------------- ### Import the PostCSS Selector Parser Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Import the main parser function from the 'postcss-selector-parser' module. ```javascript const parser = require('postcss-selector-parser'); ``` -------------------------------- ### Node Constructors Source: https://context7.com/postcss/postcss-selector-parser/llms.txt Allows building CSS selectors programmatically by providing factory functions for each node type (e.g., `root`, `selector`, `className`, `combinator`). Each constructor accepts an optional props object. ```APIDOC ## Node Constructors — Building Selectors Programmatically All node types are available as factory functions on the `parser` object. Each accepts an optional props object. ```js const parser = require('postcss-selector-parser'); // Build a new selector from scratch: .active > #submit[type="button"]::after const root = parser.root(); const sel = parser.selector(); const cls = parser.className({ value: 'active' }); const comb = parser.combinator({ value: '>' }); const id = parser.id({ value: 'submit' }); const attr = parser.attribute({ attribute: 'type', operator: '=', value: 'button', quoteMark: '"' }); const pseudo = parser.pseudo({ value: '::after' }); const nesting = parser.nesting(); // & tag = parser.tag({ value: 'div' }); const univ = parser.universal(); // * const comment = parser.comment({ value: '/* my comment */' }); sel.append(cls); sel.append(comb); sel.append(id); sel.append(attr); sel.append(pseudo); root.append(sel); console.log(root.toString()); // => .active>#submit[type="button"]::after // Type constants are exposed as uppercase strings console.log(parser.TAG); // => 'tag' console.log(parser.CLASS); // => 'class' console.log(parser.ATTRIBUTE); // => 'attribute' console.log(parser.PSEUDO); // => 'pseudo' ``` ``` -------------------------------- ### parser.tag([props]) Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Creates a new tag selector node. ```APIDOC ### `parser.tag([props])` Creates a new tag selector. ```js parser.tag({value: 'button'}); // => button ``` Arguments: * `props (object)`: The new node's properties. ``` -------------------------------- ### parser.pseudo([props]) Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Creates a new pseudo selector node. ```APIDOC ### `parser.pseudo([props])` Creates a new pseudo selector. ```js parser.pseudo({value: '::before'}); // => ::before ``` Arguments: * `props (object)`: The new node's properties. ``` -------------------------------- ### container.walk(callback) Source: https://context7.com/postcss/postcss-selector-parser/llms.txt Recursively visits every node within a container. The iteration can be stopped early by returning `false` from the callback. This method is safe to use even when mutating the nodes during iteration. ```APIDOC ## `container.walk(callback)` — Recursive Traversal Recursively visits every node in a container. Return `false` to stop iteration early. Iteration is safe during mutation (nodes can be added/removed inside the callback). ```js const parser = require('postcss-selector-parser'); const root = parser().astSync('h1.title, a:not(.external)'); root.walk((node, index) => { console.log(node.type, ':', String(node).trim()); }); // selector : h1.title // tag : h1 // class : .title // selector : a:not(.external) // tag : a // pseudo : :not(.external) // selector : .external // class : .external ``` ``` -------------------------------- ### node.isAtPosition(line, column) / container.atPosition(line, column) Source: https://context7.com/postcss/postcss-selector-parser/llms.txt Provides functionality for source location lookups. `container.atPosition` returns the most specific node at a given line and column, while `node.isAtPosition` checks if a specific node exists at those coordinates. ```APIDOC ## `node.isAtPosition(line, column)` / `container.atPosition(line, column)` — Source Location Lookup Returns `true` / the most specific node at a 1-based line and column derived from the original source. ```js const parser = require('postcss-selector-parser'); const root = parser().astSync(':not(.foo), #bar > :matches(ol, ul)'); // Find node covering line 2, column 1 const node = root.atPosition(2, 1); console.log(node.type, node.value); // => id #bar // Check if a known node is at a position const idNode = root.nodes[1].first; // #bar console.log(idNode.isAtPosition(2, 1)); // => true console.log(idNode.isAtPosition(1, 1)); // => false ``` ``` -------------------------------- ### container.insertBefore(old, new[, ...newNodes]) & container.insertAfter(old, new[, ...newNodes]) Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Inserts a new node before or after an existing node within a container. ```APIDOC ## container.insertBefore(old, new[, ...newNodes]) & container.insertAfter(old, new[, ...newNodes]) ### Description Add a node before or after an existing node in a container. ### Arguments * `old`: The existing node in the container. * `new`: The new node to add before/after the existing node. ### Example ```js selectors.walk(selector => { if (selector.type !== 'class') { const className = parser.className({value: 'theme-name'}); selector.parent.insertAfter(selector, className); } }); ``` ``` -------------------------------- ### Create a Class Selector Node Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Create a new class selector node. Provide an object with a 'value' property for the class name. ```javascript parser.className({value: 'button'}); // => .button ``` -------------------------------- ### Create a Universal Selector Node Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Create a new universal selector node, represented by '*'. ```javascript parser.universal(); // => * ``` -------------------------------- ### parser.className([props]) Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Creates a new class selector node. ```APIDOC ### `parser.className([props])` Creates a new class selector. ```js parser.className({value: 'button'}); // => .button ``` Arguments: * `props (object)`: The new node's properties. ``` -------------------------------- ### ast|astSync(selectors, [options]) Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Similar to process and processSync, but returns the Root node of the result instead of a string. The rule's selector will be updated if the `updateSelector` option is set. ```APIDOC ## `ast|astSync(selectors, [options])` Like `process()` and `processSync()` but after processing the `selectors` these methods return the `Root` node of the result instead of a string. Note: when the `updateSelector` option is set, the rule's selector will be updated with the resulting string. ``` -------------------------------- ### container.insertBefore(oldNode, newNode) / container.insertAfter(oldNode, newNode) Source: https://context7.com/postcss/postcss-selector-parser/llms.txt Inserts one or more new nodes either before or after an existing child node within a container. This allows for precise placement of nodes in relation to others. ```APIDOC ## `container.insertBefore(oldNode, newNode)` / `container.insertAfter(oldNode, newNode)` — Insert at Position Inserts one or more nodes before or after an existing child node. ```js const parser = require('postcss-selector-parser'); parser(selectors => { selectors.walkTags(tag => { // Wrap every tag with a class: div → div.themed const cls = parser.className({ value: 'themed' }); tag.parent.insertAfter(tag, cls); }); }).processSync('div, section > p'); // => div.themed, section.themed > p.themed ``` ``` -------------------------------- ### Find Node at Specific Source Location Source: https://context7.com/postcss/postcss-selector-parser/llms.txt Use `atPosition(line, column)` on a container or `isAtPosition(line, column)` on a node to find or verify the node covering a specific line and column in the original source. ```javascript const parser = require('postcss-selector-parser'); const root = parser().astSync(':not(.foo), #bar > :matches(ol, ul)'); // Find node covering line 2, column 1 const node = root.atPosition(2, 1); console.log(node.type, node.value); // => id #bar // Check if a known node is at a position const idNode = root.nodes[1].first; // #bar console.log(idNode.isAtPosition(2, 1)); // => true console.log(idNode.isAtPosition(1, 1)); // => false ``` -------------------------------- ### Programmatic Selector Node Construction Source: https://context7.com/postcss/postcss-selector-parser/llms.txt Build selectors by instantiating node types directly from the `parser` object. Each constructor accepts an optional properties object. Use `toString()` on the root node to serialize the constructed selector. ```javascript const parser = require('postcss-selector-parser'); // Build a new selector from scratch: .active > #submit[type="button"]::after const root = parser.root(); const sel = parser.selector(); const cls = parser.className({ value: 'active' }); const comb = parser.combinator({ value: '>' }); const id = parser.id({ value: 'submit' }); const attr = parser.attribute({ attribute: 'type', operator: '=', value: 'button', quoteMark: '"' }); const pseudo = parser.pseudo({ value: '::after' }); const nesting = parser.nesting(); // & const tag = parser.tag({ value: 'div' }); const univ = parser.universal(); // * const comment = parser.comment({ value: '/* my comment */' }); sel.append(cls); sel.append(comb); sel.append(id); sel.append(attr); sel.append(pseudo); root.append(sel); console.log(root.toString()); // => .active>#submit[type="button"]::after // Type constants are exposed as uppercase strings console.log(parser.TAG); // => 'tag' console.log(parser.CLASS); // => 'class' console.log(parser.ATTRIBUTE); // => 'attribute' console.log(parser.PSEUDO); // => 'pseudo' ``` -------------------------------- ### Create a Root Node Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Create a new root node, which serves as the top-level container for parsed selectors. ```javascript parser.root(); // => (empty) ``` -------------------------------- ### parser.nesting([props]) Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Creates a new nesting selector node. ```APIDOC ### `parser.nesting([props])` Creates a new nesting selector. ```js parser.nesting(); // => & ``` Arguments: * `props (object)`: The new node's properties. ``` -------------------------------- ### process|processSync(selectors, [options]) Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Processes the selectors, returning a string from the result of processing. The rule's selector will be updated if the `updateSelector` option is set. ```APIDOC ## `process|processSync(selectors, [options])` Processes the `selectors`, returning a string from the result of processing. Note: when the `updateSelector` option is set, the rule's selector will be updated with the resulting string. **Example:** ```js const parser = require("postcss-selector-parser"); const processor = parser(); let result = processor.processSync(' .class'); console.log(result); // => .class // Asynchronous operation let promise = processor.process(' .class').then(result => { console.log(result) // => .class }); // To have the parser normalize whitespace values, utilize the options result = processor.processSync(' .class ', {lossless: false}); console.log(result); // => .class // For better syntax errors, pass a PostCSS Rule node. const postcss = require('postcss'); rule = postcss.rule({selector: ' #foo > a, .class '}); processor.process(rule, {lossless: false, updateSelector: true}).then(result => { console.log(result); // => #foo>a,.class console.log("rule:", rule.selector); // => rule: #foo>a,.class }) ``` Arguments: * `selectors (string|postcss.Rule)`: Either a selector string or a PostCSS Rule node. * `[options] (object)`: Process options ``` -------------------------------- ### container.prepend(node) & container.append(node) Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Adds a node to the beginning or end of a container, setting the node's parent property to the container. ```APIDOC ## container.prepend(node) & container.append(node) ### Description Add a node to the start/end of the container. Note that doing so will set the parent property of the node to this container. ### Arguments * `node`: The node to add. ### Example ```js const id = parser.id({value: 'search'}); selector.append(id); ``` ``` -------------------------------- ### Synchronous Processing with Class Prefixing Source: https://context7.com/postcss/postcss-selector-parser/llms.txt Processes a selector string synchronously, applying a transformation to prefix all class names. Requires `postcss` if processing PostCSS Rule nodes. ```javascript const parser = require('postcss-selector-parser'); const proc = parser(selectors => { // prefix every class with 'scoped-' selectors.walkClasses(cls => { cls.value = 'scoped-' + cls.value; }); }); // String input console.log(proc.processSync('.btn.primary')); // => '.scoped-btn.scoped-primary' ``` -------------------------------- ### Recursive Node Traversal with `walk` Source: https://context7.com/postcss/postcss-selector-parser/llms.txt Use `root.walk(callback)` to recursively visit every node in a container. Returning `false` from the callback stops iteration. This method is safe for mutations during traversal. ```javascript const parser = require('postcss-selector-parser'); const root = parser().astSync('h1.title, a:not(.external)'); root.walk((node, index) => { console.log(node.type, ':', String(node).trim()); }); // selector : h1.title // tag : h1 // class : .title // selector : a:not(.external) // tag : a // pseudo : :not(.external) // selector : .external // class : .external ``` -------------------------------- ### container.each(callback) Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Iterates over the immediate children of a container, executing a callback for each. The iteration can be stopped by returning false from the callback. ```APIDOC ## container.each(callback) ### Description Iterate the container's immediate children, calling `callback` for each child. You may return `false` within the callback to break the iteration. ### Usage ```js let className; selectors.each((selector, index) => { if (selector.type === 'class') { className = selector.value; return false; } }); ``` Note that unlike `Array#forEach()`, this iterator is safe to use whilst adding or removing nodes from the container. ### Arguments * `callback (function)`: A function to call for each node, which receives `node` and `index` arguments. ``` -------------------------------- ### container.walkAttributes / walkClasses / walkIds / walkTags / walkPseudos / walkCombinators / walkComments / walkNesting / walkUniversals Source: https://context7.com/postcss/postcss-selector-parser/llms.txt These are convenience walker methods that filter nodes by their specific type, allowing for targeted traversal and manipulation of selectors. ```APIDOC ## `container.walkAttributes` / `walkClasses` / `walkIds` / `walkTags` / `walkPseudos` / `walkCombinators` / `walkComments` / `walkNesting` / `walkUniversals` — Typed Walkers Convenience walkers that filter by node type. ```js const parser = require('postcss-selector-parser'); const root = parser().astSync('[href^="https"] .link > *:focus-visible'); // All attribute nodes root.walkAttributes(attr => { console.log(`[${attr.attribute}${attr.operator}${attr.getQuotedValue()}]`); // => [href^="https"] }); // All class nodes root.walkClasses(cls => { console.log(cls.value); // => link }); // All combinators root.walkCombinators(comb => { console.log(comb.value); // => > }); // All pseudo selectors root.walkPseudos(pseudo => { console.log(pseudo.value); // => :focus-visible }); // All universal selectors root.walkUniversals(u => { u.remove(); // strip * from selector }); console.log(root.toString()); // => [href^="https"] .link > :focus-visible ``` ``` -------------------------------- ### parser.comment([props]) Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Creates a new comment node. ```APIDOC ### `parser.comment([props])` Creates a new comment. ```js parser.comment({value: '/* Affirmative, Dave. I read you. */'}); // => /* Affirmative, Dave. I read you. */ ``` Arguments: * `props (object)`: The new node's properties. ``` -------------------------------- ### Error Handling Source: https://context7.com/postcss/postcss-selector-parser/llms.txt Demonstrates how to use the `root.error()` method to generate `CssSyntaxError` objects with precise source locations, integrating with PostCSS's error reporting system. ```APIDOC ## Error Handling ### Description Demonstrates how to use the `root.error()` method to generate `CssSyntaxError` objects with precise source locations, integrating with PostCSS's error reporting system. ### Method - `root.error(message, options)`: Creates a `CssSyntaxError`. `options` can include `index` (character position) and `word` (the problematic word). ### Example Usage (Synchronous) ```js const postcss = require('postcss'); const parser = require('postcss-selector-parser'); // Synchronous PostCSS plugin that rejects underscore/dash class names const plugin = postcss.plugin('no-dashes', () => root => { const proc = parser(selectors => { selectors.walkClasses(cls => { if (/[-_]/.test(cls.value)) { throw selectors.error( `Class ".${cls.value}" must not contain dashes or underscores`, { index: cls.sourceIndex, word: cls.value } ); } }); }); root.walkRules(rule => proc.processSync(rule)); }); postcss([plugin()]) .process('.foo-bar { color: red; }', { from: 'style.css' }) .catch(e => console.error(e.toString())); // CssSyntaxError: no-dashes: style.css:1:1: Class ".foo-bar" must not // contain dashes or underscores // // > 1 | // | ^ ``` ### Example Usage (Asynchronous) ```js // Async version using root.error with Promise rejection const asyncProc = parser(root => new Promise((resolve, reject) => { root.walkIds(id => { if (id.value.startsWith('js-')) { reject(root.error('IDs starting with "js-" are reserved', { index: id.sourceIndex, word: id.value, })); } }); resolve(); })); asyncProc.process('#js-modal').catch(e => console.error(e.message)); // => IDs starting with "js-" are reserved ``` ``` -------------------------------- ### Create a Selector Node Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Create a new selector node, which represents a single CSS selector. ```javascript parser.selector(); // => (empty) ``` -------------------------------- ### Create a String Node Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Create a new string node. This is typically used for string literals within selectors. ```javascript parser.string(); // => (empty) ``` -------------------------------- ### parser.combinator([props]) Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Creates a new selector combinator node. ```APIDOC ### `parser.combinator([props])` Creates a new selector combinator. ```js parser.combinator({value: '+'}); // => + ``` Arguments: * `props (object)`: The new node's properties. Notes: * **Descendant Combinators** The value of descendant combinators created by the parser always just a single space (`" "`). For descendant selectors with no comments, additional space is now stored in `node.spaces.before`. Depending on the location of comments, additional spaces may be stored in `node.raws.spaces.before`, `node.raws.spaces.after`, or `node.raws.value`. * **Named Combinators** Although, nonstandard and unlikely to ever become a standard, named combinators like `/deep/` and `/for/` are parsed as combinators. The `node.value` is name after being unescaped and normalized as lowercase. The original value for the combinator name is stored in `node.raws.value`. ``` -------------------------------- ### container.walk(callback) Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Similar to `container.each`, but recursively iterates through all child nodes, including those within nested containers. ```APIDOC ## container.walk(callback) ### Description Like `container#each`, but will also iterate child nodes as long as they are `container` types. ### Usage ```js selectors.walk((selector, index) => { // all nodes }); ``` ### Arguments * `callback (function)`: A function to call for each node, which receives `node` and `index` arguments. This iterator is safe to use whilst mutating `container.nodes`, like `container#each`. ``` -------------------------------- ### Typed Node Traversal with `walkClasses`, `walkIds`, etc. Source: https://context7.com/postcss/postcss-selector-parser/llms.txt Utilize specific `walk` methods like `walkAttributes`, `walkClasses`, `walkIds`, `walkTags`, `walkPseudos`, `walkCombinators`, `walkComments`, `walkNesting`, and `walkUniversals` to filter traversal by node type. These provide a convenient way to process only relevant nodes. ```javascript const parser = require('postcss-selector-parser'); const root = parser().astSync('[href^="https"] .link > *:focus-visible'); // All attribute nodes root.walkAttributes(attr => { console.log(`[${attr.attribute}${attr.operator}${attr.getQuotedValue()}]`); // => [href^="https"] }); // All class nodes root.walkClasses(cls => { console.log(cls.value); // => link }); // All combinators root.walkCombinators(comb => { console.log(comb.value); // => > }); // All pseudo selectors root.walkPseudos(pseudo => { console.log(pseudo.value); // => :focus-visible }); // All universal selectors root.walkUniversals(u => { u.remove(); // strip * from selector }); console.log(root.toString()); // => [href^="https"] .link > :focus-visible ``` -------------------------------- ### Processor Options Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Options available for the Processor, controlling whitespace preservation and selector updates. ```APIDOC ### `ProcessorOptions` * `lossless` - When `true`, whitespace is preserved. Defaults to `true`. * `updateSelector` - When `true`, if any processor methods are passed a postcss `Rule` node instead of a string, then that Rule's selector is updated with the results of the processing. Defaults to `true`. ``` -------------------------------- ### Add Children to Container Node Source: https://context7.com/postcss/postcss-selector-parser/llms.txt Use `append` or `prepend` to add nodes to the beginning or end of a container. The `parent` property of the added node is automatically set. ```javascript const parser = require('postcss-selector-parser'); const root = parser().astSync('button'); const firstSel = root.first; // Add a class to the existing tag node firstSel.append(parser.className({ value: 'primary' })); // Add a pseudo-class at the end firstSel.append(parser.pseudo({ value: ':disabled' })); // Prepend a universal selector firstSel.prepend(parser.universal()); console.log(root.toString()); // => *button.primary:disabled ``` -------------------------------- ### Create a Pseudo Selector Node Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Create a new pseudo selector node. The 'value' property specifies the pseudo-selector, e.g., '::before'. ```javascript parser.pseudo({value: '::before'}); // => ::before ``` -------------------------------- ### Traverse Siblings Source: https://context7.com/postcss/postcss-selector-parser/llms.txt Use `next()` and `prev()` to navigate to the subsequent or preceding sibling node within the same parent. This is essential for understanding node relationships. ```javascript const parser = require('postcss-selector-parser'); const root = parser().astSync('a > b'); const combinator = root.first.nodes[1]; // '>' node console.log(combinator.prev().value); // => 'a' console.log(combinator.next().value); // => 'b' // Validate: IDs must not have sibling simple selectors immediately after root.walkIds(id => { const next = id.next(); if (next && next.type !== 'combinator') { throw new Error(`Qualified ID "#${id.value}" is not allowed`); } }); ``` -------------------------------- ### parser([transformFn]) — Create a Processor Source: https://context7.com/postcss/postcss-selector-parser/llms.txt Creates a Processor instance that can be used to parse and transform CSS selector strings. An optional transform function can be provided to mutate the parsed AST. ```APIDOC ## parser([transformFn]) ### Description Creates a `Processor` instance. The optional `transformFn` receives the parsed `Root` node and may mutate it or return a value. All subsequent calls on the processor inherit the options passed here. ### Parameters #### transformFn - `transformFn` (function) - Optional. A function that receives the parsed `Root` AST node and can be used for transformations. ### Usage Examples ```javascript const parser = require('postcss-selector-parser'); // No-op processor const proc = parser(); console.log(proc.processSync('h1, h2, h3')); // Processor with a transform function const stripUniversal = parser(selectors => { selectors.walkUniversals(node => node.remove()); }); console.log(stripUniversal.processSync('*.active, *')); // Async transform function const asyncProc = parser(async selectors => { await someAsyncCheck(); selectors.walkTags(tag => { tag.value = tag.value.toUpperCase(); }); }); asyncProc.process('div > p').then(result => { console.log(result); }); ``` ``` -------------------------------- ### Create a No-op Processor Source: https://context7.com/postcss/postcss-selector-parser/llms.txt Creates a processor that only parses and stringifies selectors without applying transformations. ```javascript const parser = require('postcss-selector-parser'); // No-op processor — just parse and stringify const proc = parser(); console.log(proc.processSync('h1, h2, h3')); // => 'h1, h2, h3' ``` -------------------------------- ### parser.attribute([props]) Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Creates a new attribute selector node. ```APIDOC ### `parser.attribute([props])` Creates a new attribute selector. ```js parser.attribute({attribute: 'href'}); // => [href] ``` Arguments: * `props (object)`: The new node's properties. ``` -------------------------------- ### Create a Tag Selector Node Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Create a new tag selector node. Provide an object with a 'value' property for the tag name. ```javascript parser.tag({value: 'button'}); // => button ``` -------------------------------- ### Processor Asynchronous Usage Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Illustrates the asynchronous `process` method using Promises to handle selector parsing. This is useful for non-blocking operations in Node.js environments. ```js // Asynchronous operation let promise = processor.process(' .class').then(result => { console.log(result) // => .class }); ``` -------------------------------- ### container.at(index) Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Retrieves a node from the container at a specific index. ```APIDOC ## container.at(index) ### Description Returns the node at position `index`. ### Usage ```js selector.at(0) === selector.first; selector.at(0) === selector.nodes[0]; ``` ### Arguments * `index`: The index of the node to return. ``` -------------------------------- ### Access Source Metadata Source: https://context7.com/postcss/postcss-selector-parser/llms.txt Nodes contain `source.start`, `source.end` (line/column, 1-based), and `sourceIndex` (zero-based character offset) properties, providing details about their origin in the input string. ```javascript const parser = require('postcss-selector-parser'); const root = parser().astSync('.foo, .bar, .baz'); root.walkClasses(cls => { console.log( cls.value, 'starts at index', cls.sourceIndex, 'line', cls.source.start.line, 'col', cls.source.start.column ); }); // foo starts at index 0 line 1 col 1 // bar starts at index 6 line 1 col 7 // baz starts at index 12 line 1 col 13 ``` -------------------------------- ### Create a Comment Node Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Create a new comment node. The 'value' property holds the comment content. ```javascript parser.comment({value: '/* Affirmative, Dave. I read you. */'}); // => /* Affirmative, Dave. I read you. */ ``` -------------------------------- ### container.append(node) / container.prepend(node) Source: https://context7.com/postcss/postcss-selector-parser/llms.txt Adds a node to the end or beginning of a container, automatically setting its parent reference. This is useful for dynamically building or modifying selector structures. ```APIDOC ## `container.append(node)` / `container.prepend(node)` — Add Children Adds a node to the end or beginning of a container, setting its `parent` automatically. ```js const parser = require('postcss-selector-parser'); const root = parser().astSync('button'); const firstSel = root.first; // Add a class to the existing tag node firstSel.append(parser.className({ value: 'primary' })); // Add a pseudo-class at the end firstSel.append(parser.pseudo({ value: ':disabled' })); // Prepend a universal selector firstSel.prepend(parser.universal()); console.log(root.toString()); // => *button.primary:disabled ``` ``` -------------------------------- ### transform|transformSync(selectors, [options]) Source: https://github.com/postcss/postcss-selector-parser/blob/master/API.md Similar to process and processSync, but returns the value returned by the processor callback. The rule's selector will be updated if the `updateSelector` option is set. ```APIDOC ## `transform|transformSync(selectors, [options])` Like `process()` and `processSync()` but after processing the `selectors` these methods return the value returned by the processor callback. Note: when the `updateSelector` option is set, the rule's selector will be updated with the resulting string. ```