File Explorer

/proc/1/cwd/proc/self/root/node24/lib/node_modules/npm/node_modules/postcss-selector-parser

This explorer reads the filesystem of the server it runs on, so /workspace/user isn't present here. Browsing and the terminal still work against this server's own disk from /.

API.md20.6 KB · 875 lines
# API Documentation *Please use only this documented API when working with the parser. Methodsnot documented here are subject to change at any point.* ## `parser` function This is the module's main entry point. ```jsconst parser = require('postcss-selector-parser');``` ### `parser([transform], [options])` Creates a new `processor` instance ```jsconst processor = parser();``` Or, with optional transform function ```jsconst transform = selectors => {    selectors.walkUniversals(selector => {        selector.remove();    });}; const processor = parser(transform) // Exampleconst 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.attribute([props])` Creates a new attribute selector. ```jsparser.attribute({attribute: 'href'});// => [href]``` Arguments: * `props (object)`: The new node's properties. ### `parser.className([props])` Creates a new class selector. ```jsparser.className({value: 'button'});// => .button``` Arguments: * `props (object)`: The new node's properties. ### `parser.combinator([props])` Creates a new selector combinator. ```jsparser.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`.  ### `parser.comment([props])` Creates a new comment. ```jsparser.comment({value: '/* Affirmative, Dave. I read you. */'});// => /* Affirmative, Dave. I read you. */``` Arguments: * `props (object)`: The new node's properties. ### `parser.id([props])` Creates a new id selector. ```jsparser.id({value: 'search'});// => #search``` Arguments: * `props (object)`: The new node's properties. ### `parser.nesting([props])` Creates a new nesting selector. ```jsparser.nesting();// => &``` Arguments: * `props (object)`: The new node's properties. ### `parser.pseudo([props])` Creates a new pseudo selector. ```jsparser.pseudo({value: '::before'});// => ::before``` Arguments: * `props (object)`: The new node's properties. ### `parser.root([props])` Creates a new root node. ```jsparser.root();// => (empty)``` Arguments: * `props (object)`: The new node's properties. ### `parser.selector([props])` Creates a new selector node. ```jsparser.selector();// => (empty)``` Arguments: * `props (object)`: The new node's properties. ### `parser.string([props])` Creates a new string node. ```jsparser.string();// => (empty)``` Arguments: * `props (object)`: The new node's properties. ### `parser.tag([props])` Creates a new tag selector. ```jsparser.tag({value: 'button'});// => button``` Arguments: * `props (object)`: The new node's properties. ### `parser.universal([props])` Creates a new universal selector. ```jsparser.universal();// => *``` Arguments: * `props (object)`: The new node's properties. ## Node types ### `node.type` A string representation of the selector type. It can be one of the following;`attribute`, `class`, `combinator`, `comment`, `id`, `nesting`, `pseudo`,`root`, `selector`, `string`, `tag`, or `universal`. Note that for convenience,these constants are exposed on the main `parser` as uppercased keys. So forexample you can get `id` by querying `parser.ID`. ```jsparser.attribute({attribute: 'href'}).type;// => 'attribute'``` ### `node.parent` Returns the parent node. ```jsroot.nodes[0].parent === root;``` ### `node.toString()`, `String(node)`, or `'' + node` Returns a string representation of the node. ```jsconst id = parser.id({value: 'search'});console.log(String(id));// => #search``` ### `node.next()` & `node.prev()` Returns the next/previous child of the parent node. ```jsconst next = id.next();if (next && next.type !== 'combinator') {    throw new Error('Qualified IDs are not allowed!');}``` ### `node.replaceWith(node[,...nodeN])` Replace a node with another. ```jsconst attr = selectors.first.first;const className = parser.className({value: 'test'});attr.replaceWith(className);``` Arguments: * `node`: The node to substitute the original with....* `nodeN`: The node to substitute the original with. ### `node.remove()` Removes the node from its parent node. ```jsif (node.type === 'id') {    node.remove();}``` ### `node.clone([opts])` Returns a copy of a node, detached from any parent containers that theoriginal might have had. ```jsconst cloned = node.clone();``` ### `node.isAtPosition(line, column)` Return a `boolean` indicating whether this node includes the character at theposition of the given line and column. Returns `undefined` if the nodes lacksufficient source metadata to determine the position. Arguments: * `line`: 1-index based line number relative to the start of the selector.* `column`: 1-index based column number relative to the start of the selector. ### `node.spaces` Extra whitespaces around the node will be moved into `node.spaces.before` and`node.spaces.after`. So for example, these spaces will be moved as they haveno semantic meaning: ```css      h1     ,     h2   {}``` For descendent selectors, the value is always a single space. ```cssh1        h2 {}``` Additional whitespace is found in either the `node.spaces.before` and `node.spaces.after` depending on the presence of comments or other whitespace characters. If the actual whitespace does not start or end with a single space, the node's raw value is set to the actual space(s) found in the source. ### `node.source` 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. ```jssource: {    start: {        line: 2,        column: 3    },    end: {        line: 2,        column: 6    }}``` ### `node.sourceIndex` The zero-based index of the node within the original source string. Within the following CSS, the `.baz` class node will have a `sourceIndex` of `12`. ```css.foo, .bar, .baz {}``` ## Container types The `root`, `selector`, and `pseudo` nodes have some helper methods for workingwith their children. ### `container.nodes` An array of the container's children. ```js// Input: h1 h2selectors.at(0).nodes.length   // => 3selectors.at(0).nodes[0].value // => 'h1'selectors.at(0).nodes[1].value // => ' '``` ### `container.first` & `container.last` The first/last child of the container. ```jsselector.first === selector.nodes[0];selector.last === selector.nodes[selector.nodes.length - 1];``` ### `container.at(index)` Returns the node at position `index`. ```jsselector.at(0) === selector.first;selector.at(0) === selector.nodes[0];``` Arguments: * `index`: The index of the node to return. ### `container.atPosition(line, column)` Returns the node at the source position `line` and `column`. ```js// Input: :not(.foo),\n#foo > :matches(ol, ul)selector.atPosition(1, 1); // => :not(.foo)selector.atPosition(2, 1); // => \n#foo``` Arguments: * `line`: The line number of the node to return.* `column`: The column number of the node to return. ### `container.index(node)` Return the index of the node within its container. ```jsselector.index(selector.nodes[2]) // => 2``` Arguments: * `node`: A node within the current container. ### `container.length` Proxy to the length of the container's nodes. ```jscontainer.length === container.nodes.length``` ### `container` Array iterators The container class provides proxies to certain Array methods; these are: * `container.map === container.nodes.map`* `container.reduce === container.nodes.reduce`* `container.every === container.nodes.every`* `container.some === container.nodes.some`* `container.filter === container.nodes.filter`* `container.sort === container.nodes.sort` Note that these methods only work on a container's immediate children; recursiveiteration is provided by `container.walk`. ### `container.each(callback)` Iterate the container's immediate children, calling `callback` for each child.You may return `false` within the callback to break the iteration. ```jslet 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 addingor removing nodes from the container. Arguments: * `callback (function)`: A function to call for each node, which receives `node`  and `index` arguments. ### `container.walk(callback)` Like `container#each`, but will also iterate child nodes as long as they are`container` types. ```jsselectors.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`. ### `container.walk` proxies The container class provides proxy methods for iterating over types of nodes,so that it is easier to write modules that target specific selectors. Thosemethods are: * `container.walkAttributes`* `container.walkClasses`* `container.walkCombinators`* `container.walkComments`* `container.walkIds`* `container.walkNesting`* `container.walkPseudos`* `container.walkTags`* `container.walkUniversals` ### `container.split(callback)` This method allows you to split a group of nodes by returning `true` froma callback. It returns an array of arrays, where each inner array correspondsto the groups that you created via the callback. ```js// (input) => h1 h2>>h3const list = selectors.first.split(selector => {    return selector.type === 'combinator';}); // (node values) => [['h1', ' '], ['h2', '>>'], ['h3']]``` Arguments: * `callback (function)`: A function to call for each node, which receives `node`  as an argument. ### `container.prepend(node)` & `container.append(node)` Add a node to the start/end of the container. Note that doing so will setthe parent property of the node to this container. ```jsconst id = parser.id({value: 'search'});selector.append(id);``` Arguments: * `node`: The node to add. ### `container.insertBefore(old, new[, ...newNodes])` & `container.insertAfter(old, new[, ...newNodes])` Add a node before or after an existing node in a container: ```jsselectors.walk(selector => {    if (selector.type !== 'class') {        const className = parser.className({value: 'theme-name'});        selector.parent.insertAfter(selector, className);    }});``` Arguments: * `old`: The existing node in the container.* `new`: The new node to add before/after the existing node. ### `container.removeChild(node)` Remove the node from the container. Note that you can also use`node.remove()` if you would like to remove just a single node. ```jsselector.length // => 2selector.remove(id)selector.length // => 1;id.parent       // undefined``` Arguments: * `node`: The node to remove. ### `container.removeAll()` or `container.empty()` Remove all children from the container. ```jsselector.removeAll();selector.length // => 0``` ## Root nodes A root node represents a comma separated list of selectors. Indeed, alla root's `toString()` method does is join its selector children with a ','.Other than this, it has no special functionality and acts like a container. ### `root.trailingComma` This will be set to `true` if the input has a trailing comma, in order tosupport parsing of legacy CSS hacks. ## Selector nodes A selector node represents a single complex selector. For example, thisselector string `h1 h2 h3, [href] > p`, is represented as two selector nodes.It has no special functionality of its own. ## Pseudo nodes A pseudo selector extends a container node; if it has any parameters of itsown (such as `h1:not(h2, h3)`), they will be its children. Note that the pseudo`value` will always contain the colons preceding the pseudo identifier. Thisis so that both `:before` and `::before` are properly represented in the AST. ## Attribute nodes ### `attribute.quoted` Returns `true` if the attribute's value is wrapped in quotation marks, false if it is not.Remains `undefined` if there is no attribute value. ```css[href=foo] /* false */[href='foo'] /* true */[href="foo"] /* true */[href] /* undefined */``` ### `attribute.qualifiedAttribute` Returns the attribute name qualified with the namespace if one is given. ### `attribute.offsetOf(part)`  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 ### `attribute.raws.unquoted` Returns the unquoted content of the attribute's value.Remains `undefined` if there is no attribute value. ```css[href=foo] /* foo */[href='foo'] /* foo */[href="foo"] /* foo */[href] /* undefined */``` ### `attribute.spaces` Like `node.spaces` with the `before` and `after` values containing the spacesaround the element, the parts of the attribute can also have spaces beforeand after them. The for each of `attribute`, `operator`, `value` and`insensitive` there is corresponding property of the same nam in`node.spaces` that has an optional `before` or `after` string containing onlywhitespace. Note that corresponding values in `attributes.raws.spaces` contain valuesincluding any comments. If set, these values will override the`attribute.spaces` value. Take care to remove them if changing`attribute.spaces`. ### `attribute.raws` The raws object stores comments and other information necessary to re-renderthe node exactly as it was in the source. If a comment is embedded within the identifiers for the `namespace`, `attribute`or `value` then a property is placed in the raws for that value containing the full source of the propery including comments. If a comment is embedded within the space between parts of the attributethen the raw for that space is set accordingly. Setting an attribute's property `raws` value to be deleted. For now, changing the spaces required also updating or removing any of theraws values that override them. Example: `[ /*before*/ href /* after-attr */ = /* after-operator */ te/*inside-value*/st/* wow */ /*omg*/i/*bbq*/ /*whodoesthis*/]` would parse as: ```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'  }}``` ## `Processor` ### `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`. ### `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 selectorwill be updated with the resulting string. **Example:** ```jsconst parser = require("postcss-selector-parser");const processor = parser(); let result = processor.processSync(' .class');console.log(result);// =>  .class // Asynchronous operationlet promise = processor.process(' .class').then(result => {    console.log(result)    // => .class}); // To have the parser normalize whitespace values, utilize the optionsresult = 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  ### `ast|astSync(selectors, [options])` Like `process()` and `processSync()` but afterprocessing the `selectors` these methods return the `Root` node of the resultinstead of a string. Note: when the `updateSelector` option is set, the rule's selectorwill be updated with the resulting string. ### `transform|transformSync(selectors, [options])` Like `process()` and `processSync()` but afterprocessing the `selectors` these methods return the value returned by theprocessor callback. Note: when the `updateSelector` option is set, the rule's selectorwill be updated with the resulting string. ### Error Handling Within Selector Processors The root node passed to the selector processor callbackhas a method `error(message, options)` that returns anerror object. This method should always be used to raiseerrors relating to the syntax of selectors. The optionsto this method are passed to postcss's error constructor([documentation](http://postcss.org/api/#container-error)). #### Async Error Example ```jslet 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 | }``` #### Synchronous Error Example ```jslet 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 | }```