# API Documentation

*Please use only this documented API when working with the parser. Methods
not documented here are subject to change at any point.*

## `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.attribute([props])`

Creates a new attribute selector.

```js
parser.attribute({attribute: 'href'});
// => [href]
```

Arguments:

* `props (object)`: The new node's properties.

### `parser.className([props])`

Creates a new class selector.

```js
parser.className({value: 'button'});
// => .button
```

Arguments:

* `props (object)`: The new node's properties.

### `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`.


### `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.

### `parser.id([props])`

Creates a new id selector.

```js
parser.id({value: 'search'});
// => #search
```

Arguments:

* `props (object)`: The new node's properties.

### `parser.nesting([props])`

Creates a new nesting selector.

```js
parser.nesting();
// => &
```

Arguments:

* `props (object)`: The new node's properties.

### `parser.pseudo([props])`

Creates a new pseudo selector.

```js
parser.pseudo({value: '::before'});
// => ::before
```

Arguments:

* `props (object)`: The new node's properties.

### `parser.root([props])`

Creates a new root node.

```js
parser.root();
// => (empty)
```

Arguments:

* `props (object)`: The new node's properties.

### `parser.selector([props])`

Creates a new selector node.

```js
parser.selector();
// => (empty)
```

Arguments:

* `props (object)`: The new node's properties.

### `parser.string([props])`

Creates a new string node.

```js
parser.string();
// => (empty)
```

Arguments:

* `props (object)`: The new node's properties.

### `parser.tag([props])`

Creates a new tag selector.

```js
parser.tag({value: 'button'});
// => button
```

Arguments:

* `props (object)`: The new node's properties.

### `parser.universal([props])`

Creates a new universal selector.

```js
parser.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 for
example you can get `id` by querying `parser.ID`.

```js
parser.attribute({attribute: 'href'}).type;
// => 'attribute'
```

### `node.parent`

Returns the parent node.

```js
root.nodes[0].parent === root;
```

### `node.toString()`, `String(node)`, or `'' + node`

Returns a string representation of the node.

```js
const id = parser.id({value: 'search'});
console.log(String(id));
// => #search
```

### `node.next()` & `node.prev()`

Returns the next/previous child of the parent node.

```js
const next = id.next();
if (next && next.type !== 'combinator') {
    throw new Error('Qualified IDs are not allowed!');
}
```

### `node.replaceWith(node)`

Replace a node with another.

```js
const attr = selectors.first.first;
const className = parser.className({value: 'test'});
attr.replaceWith(className);
```

Arguments:

* `node`: The node to substitute the original with.

### `node.remove()`

Removes the node from its parent node.

```js
if (node.type === 'id') {
    node.remove();
}
```

### `node.clone()`

Returns a copy of a node, detached from any parent containers that the
original might have had.

```js
const cloned = parser.id({value: 'search'});
String(cloned);

// => #search
```

### `node.isAtPosition(line, column)`

Return a `boolean` indicating whether this node includes the character at the
position of the given line and column. Returns `undefined` if the nodes lack
sufficient 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 have
no semantic meaning:

```css
      h1     ,     h2   {}
```

For descendent selectors, the value is always a single space.

```css
h1        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.

```js
source: {
    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 working
with their children.

### `container.nodes`

An array of the container's children.

```js
// Input: h1 h2
selectors.at(0).nodes.length   // => 3
selectors.at(0).nodes[0].value // => 'h1'
selectors.at(0).nodes[1].value // => ' '
```

### `container.first` & `container.last`

The first/last child of the container.

```js
selector.first === selector.nodes[0];
selector.last === selector.nodes[selector.nodes.length - 1];
```

### `container.at(index)`

Returns the node at position `index`.

```js
selector.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 `index`.

```js
selector.at(0) === selector.first;
selector.at(0) === selector.nodes[0];
```

Arguments:

* `index`: The index of the node to return.

### `container.index(node)`

Return the index of the node within its container.

```js
selector.index(selector.nodes[2]) // => 2
```

Arguments:

* `node`: A node within the current container.

### `container.length`

Proxy to the length of the container's nodes.

```js
container.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; recursive
iteration 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.

```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.walk(callback)`

Like `container#each`, but will also iterate child nodes as long as they are
`container` types.

```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`.

### `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. Those
methods 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` from
a callback. It returns an array of arrays, where each inner array corresponds
to the groups that you created via the callback.

```js
// (input) => h1 h2>>h3
const 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 set
the parent property of the node to this container.

```js
const id = parser.id({value: 'search'});
selector.append(id);
```

Arguments:

* `node`: The node to add.

### `container.insertBefore(old, new)` & `container.insertAfter(old, new)`

Add a node before or after an existing node in a container:

```js
selectors.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.

```js
selector.length // => 2
selector.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.

```js
selector.removeAll();
selector.length // => 0
```

## Root nodes

A root node represents a comma separated list of selectors. Indeed, all
a 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 to
support parsing of legacy CSS hacks.

## Selector nodes

A selector node represents a single complex selector. For example, this
selector 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 its
own (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. This
is 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 spaces
around the element, the parts of the attribute can also have spaces before
and 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 only
whitespace.

Note that corresponding values in `attributes.raws.spaces` contain values
including 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-render
the 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 attribute
then 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 the
raws 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",
  operatator: "=",
  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 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


### `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.

### `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.

### Error Handling Within Selector Processors

The root node passed to the selector processor callback
has a method `error(message, options)` that returns an
error object. This method should always be used to raise
errors relating to the syntax of selectors. The options
to this method are passed to postcss's error constructor
([documentation](http://api.postcss.org/Container.html#error)).

#### Async Error Example

```js
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 | }
```

#### Synchronous Error Example

```js
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 | }
```
