586 lines
13 KiB
Markdown
586 lines
13 KiB
Markdown
|
# API Documentation
|
||
|
|
||
|
*Please use only this documented API when working with the parser. Methods
|
||
|
not documented here are subject to change at any point.*
|
||
|
|
||
|
<!-- toc -->
|
||
|
|
||
|
- [`parser` function](#parser-function)
|
||
|
* [`parser.atword([props])`](#parseratwordprops)
|
||
|
* [`parser.colon([props])`](#parsercolonprops)
|
||
|
* [`parser.comma([props])`](#parsercommaprops)
|
||
|
* [`parser.comment([props])`](#parsercommentprops)
|
||
|
* [`parser.func([props])`](#parserfuncprops)
|
||
|
* [`parser.number([props])`](#parsernumberprops)
|
||
|
* [`parser.operator([props])`](#parseroperatorprops)
|
||
|
* [`parser.paren([props])`](#parserparenprops)
|
||
|
* [`parser.string([props])`](#parserstringprops)
|
||
|
* [`parser.value([props])`](#parservalueprops)
|
||
|
* [`parser.word([props])`](#parserwordprops)
|
||
|
* [`parser.unicodeRange([props])`](#parserunicoderangeprops)
|
||
|
- [Node types](#node-types)
|
||
|
* [`node.type`](#nodetype)
|
||
|
* [`node.parent`](#nodeparent)
|
||
|
* [`node.toString()`, `String(node)`, or `'' + node`](#nodetostring-stringnode-or---node)
|
||
|
* [`node.next()` & `node.prev()`](#nodenext--nodeprev)
|
||
|
* [`node.replaceWith(node)`](#nodereplacewithnode)
|
||
|
* [`node.remove()`](#noderemove)
|
||
|
* [`node.clone()`](#nodeclone)
|
||
|
* [`node.raws`](#noderaws)
|
||
|
* [`node.source`](#nodesource)
|
||
|
* [`node.sourceIndex`](#nodesourceindex)
|
||
|
- [Container types](#container-types)
|
||
|
* [`container.nodes`](#containernodes)
|
||
|
* [`container.first` & `container.last`](#containerfirst--containerlast)
|
||
|
* [`container.at(index)`](#containeratindex)
|
||
|
* [`container.index(node)`](#containerindexnode)
|
||
|
* [`container.length`](#containerlength)
|
||
|
* [`container.each(callback)`](#containereachcallback)
|
||
|
* [`container.walk(callback)`](#containerwalkcallback)
|
||
|
* [`container.walk` proxies](#containerwalk-proxies)
|
||
|
* [`container.prepend(node)` & `container.append(node)`](#containerprependnode--containerappendnode)
|
||
|
* [`container.insertBefore(old, new)` & `container.insertAfter(old, new)`](#containerinsertbeforeold-new--containerinsertafterold-new)
|
||
|
* [`container.removeChild(node)`](#containerremovechildnode)
|
||
|
* [`container.removeAll()` or `container.empty()`](#containerremoveall-or-containerempty)
|
||
|
- [Root nodes`](#root-nodes)
|
||
|
- [Value nodes](#value-nodes)
|
||
|
|
||
|
<!-- tocstop -->
|
||
|
|
||
|
## `parser` function
|
||
|
|
||
|
This is the module's main entry point, and returns a `new Parser`.
|
||
|
|
||
|
```js
|
||
|
let parser = require('postcss-values-parser');
|
||
|
|
||
|
let ast = parser(source) // tokenizes the source string
|
||
|
.parse(); // parses the tokens and returns an AST
|
||
|
```
|
||
|
|
||
|
### `parser.atword([props])`
|
||
|
|
||
|
Creates a new AtWord value.
|
||
|
|
||
|
```js
|
||
|
parser.atword({ value: '@foo' });
|
||
|
// → @foo
|
||
|
```
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
* `props (object)`: The new node's properties.
|
||
|
|
||
|
### `parser.colon([props])`
|
||
|
|
||
|
Creates a new colon Node.
|
||
|
|
||
|
```js
|
||
|
parser.colon({ value: ':' });
|
||
|
// → :
|
||
|
```
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
* `props (object)`: The new node's properties. If no properties are specified,
|
||
|
the default value of `:` will be used. It's not recommended to deviate from this.
|
||
|
|
||
|
### `parser.comma([props])`
|
||
|
|
||
|
Creates a new comma Node.
|
||
|
|
||
|
```js
|
||
|
parser.comma({ value: ',' });
|
||
|
// → ,
|
||
|
```
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
* `props (object)`: The new node's properties. If no properties are specified,
|
||
|
the default value of `,` will be used. It's not recommended to deviate from this.
|
||
|
|
||
|
### `parser.comment([props])`
|
||
|
|
||
|
Creates a new comment.
|
||
|
|
||
|
```js
|
||
|
parser.comment({ value: 'Affirmative, Dave. I read you.' });
|
||
|
// → /* Affirmative, Dave. I read you. */
|
||
|
```
|
||
|
|
||
|
```js
|
||
|
parser.comment({ value: 'Affirmative, Dave. I read you.', inline: true });
|
||
|
// → // Affirmative, Dave. I read you.
|
||
|
```
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
* `props (object)`: The new node's properties.
|
||
|
|
||
|
### `parser.func([props])`
|
||
|
|
||
|
Creates a new function value Container node.
|
||
|
|
||
|
```js
|
||
|
let func = parser.func({ value: 'calc' });
|
||
|
|
||
|
func.append(parser.paren());
|
||
|
func.append(parser.paren({ value: ')' }));
|
||
|
|
||
|
func.toString();
|
||
|
// → calc()
|
||
|
```
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
* `props (object)`: The new node's properties.
|
||
|
|
||
|
### `parser.number([props])`
|
||
|
|
||
|
Creates a new number Node.
|
||
|
|
||
|
```js
|
||
|
parser.number({ value: 10, unit: 'px' });
|
||
|
// → 10px
|
||
|
```
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
* `props (object)`: The new node's properties.
|
||
|
|
||
|
### `parser.operator([props])`
|
||
|
|
||
|
Creates a new operator Node.
|
||
|
|
||
|
```js
|
||
|
parser.operator({ value: '+' });
|
||
|
// → +
|
||
|
```
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
* `props (object)`: The new node's properties.
|
||
|
|
||
|
### `parser.paren([props])`
|
||
|
|
||
|
Creates a new parenthesis Node.
|
||
|
|
||
|
```js
|
||
|
parser.paren();
|
||
|
// → (
|
||
|
|
||
|
parser.paren({ value: ')' });
|
||
|
// → )
|
||
|
```
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
* `props (object)`: The new node's properties. If no value is specified, the
|
||
|
default value of `(` will be used.
|
||
|
|
||
|
### `parser.string([props])`
|
||
|
|
||
|
Creates a new string node.
|
||
|
|
||
|
```js
|
||
|
parser.string();
|
||
|
// → (empty)
|
||
|
|
||
|
parser.string({ value: 'hello', quote: '"' });
|
||
|
// → "hello"
|
||
|
```
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
* `props (object)`: The new node's properties. Note: If no `quote` property is
|
||
|
specified, the default value of `'` will be used.
|
||
|
|
||
|
### `parser.value([props])`
|
||
|
|
||
|
Creates a new value Node. This node acts as the container for all values within
|
||
|
the Root node, but can be created for convenience.
|
||
|
|
||
|
### `parser.word([props])`
|
||
|
|
||
|
Creates a new word Node. A `Word` is anything that doesn't fall into one of the
|
||
|
other node types.
|
||
|
|
||
|
```js
|
||
|
let word = parser.word({ value: '#fff' });
|
||
|
// → #fff
|
||
|
|
||
|
word.isHex;
|
||
|
// → true
|
||
|
|
||
|
word.isColor;
|
||
|
// → true
|
||
|
```
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
* `props (object)`: The new node's properties.
|
||
|
|
||
|
### `parser.unicodeRange([props])`
|
||
|
|
||
|
Creates a new unicode range Node.
|
||
|
|
||
|
```js
|
||
|
parser.unicodeRange({ value: 'U+26' });
|
||
|
// → U+26
|
||
|
```
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
* `props (object)`: The new node's properties.
|
||
|
|
||
|
## Node types
|
||
|
|
||
|
### `node.type`
|
||
|
|
||
|
A string representation of the node type. It can be one of the following;
|
||
|
`atword`, `colon`, `comma`, `comment`, `func`, `number`, `operator`,
|
||
|
`paren`, `string`, `unicoderange`, `value`, `word`.
|
||
|
|
||
|
```js
|
||
|
parser.word({ value: '#fff' }).type;
|
||
|
// → 'word'
|
||
|
```
|
||
|
|
||
|
### `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
|
||
|
let color = parser.word({ value: '#fff' });
|
||
|
console.log(String(color));
|
||
|
// → #fff
|
||
|
```
|
||
|
|
||
|
### `node.next()` & `node.prev()`
|
||
|
|
||
|
Returns the next/previous child of the parent node.
|
||
|
|
||
|
```js
|
||
|
let next = func.next();
|
||
|
if (next && next.type !== 'paren') {
|
||
|
throw new Error('Unclosed function parenthesis!');
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### `node.replaceWith(node)`
|
||
|
|
||
|
Replace a node with another.
|
||
|
|
||
|
```js
|
||
|
let ast = parser('#fff').parse();
|
||
|
let word = ast.first.first;
|
||
|
let atword = parser.atword({ value: '@purple' });
|
||
|
|
||
|
word.replaceWith(atword);
|
||
|
```
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
* `node`: The node to substitute the original with.
|
||
|
|
||
|
### `node.remove()`
|
||
|
|
||
|
Removes the node from its parent node.
|
||
|
|
||
|
```js
|
||
|
if (node.type === 'word') {
|
||
|
node.remove();
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### `node.clone()`
|
||
|
|
||
|
Returns a copy of a node, detached from any parent containers that the
|
||
|
original might have had.
|
||
|
|
||
|
```js
|
||
|
let word = parser.word({ value: '#fff' });
|
||
|
let cloned = word.clone();
|
||
|
|
||
|
cloned.value = '#fff';
|
||
|
String(cloned);
|
||
|
// → #000
|
||
|
|
||
|
String(word);
|
||
|
// → #fff
|
||
|
```
|
||
|
|
||
|
### `node.raws`
|
||
|
|
||
|
Extra whitespaces around the node will be assigned to `node.raws.before` and
|
||
|
`node.raws.after`. Spaces in this context have no semantic meaning, but may
|
||
|
be useful for inspection:
|
||
|
|
||
|
```css
|
||
|
1px solid black
|
||
|
```
|
||
|
|
||
|
Any space following a node/segement is assigned to the next node's
|
||
|
`raws.before` property, unless the node with the trailing space is the only
|
||
|
node in the set.
|
||
|
|
||
|
```js
|
||
|
let source = 'calc(something about mary)';
|
||
|
let ast = parser(source).parse();
|
||
|
let func = ast.first.first;
|
||
|
|
||
|
let something = func.first.next();
|
||
|
let about = something.next();
|
||
|
|
||
|
something.raws.after;
|
||
|
// → (empty)
|
||
|
|
||
|
about.raws.before;
|
||
|
// → ' '
|
||
|
```
|
||
|
|
||
|
Additionally, any space remaining after the last node in a
|
||
|
set will be assigned to the last non-symbol child's `raws.after` property.
|
||
|
For example:
|
||
|
|
||
|
```js
|
||
|
let source = 'calc(something )';
|
||
|
let ast = parser(source).parse();
|
||
|
let func = ast.first.first;
|
||
|
|
||
|
let something = func.first.next();
|
||
|
something.raws.after;
|
||
|
// → ' '
|
||
|
```
|
||
|
|
||
|
### `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`, `node`, 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
|
||
|
nodes.at(0).nodes.length // → 3
|
||
|
nodes.at(0).nodes[0].value // → 'h1'
|
||
|
nodes.at(0).nodes[1].value // → ' '
|
||
|
```
|
||
|
|
||
|
### `container.first` & `container.last`
|
||
|
|
||
|
The first/last child of the container.
|
||
|
|
||
|
```js
|
||
|
node.first === node.nodes[0];
|
||
|
node.last === node.nodes[node.nodes.length - 1];
|
||
|
```
|
||
|
|
||
|
### `container.at(index)`
|
||
|
|
||
|
Returns the node at position `index`.
|
||
|
|
||
|
```js
|
||
|
node.at(0) === node.first;
|
||
|
node.at(0) === node.nodes[0];
|
||
|
```
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
* `index`: The index of the node to return.
|
||
|
|
||
|
### `container.index(node)`
|
||
|
|
||
|
Return the index of the node within its container.
|
||
|
|
||
|
```js
|
||
|
node.index(node.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.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;
|
||
|
nodes.each(function (node, index) {
|
||
|
if (node.type === 'class') {
|
||
|
className = node.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
|
||
|
nodes.walk(function (node, 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 nodes. Those
|
||
|
methods are:
|
||
|
|
||
|
* `container.walkAtWords`
|
||
|
* `container.walkColons`
|
||
|
* `container.walkCommas`
|
||
|
* `container.walkComments`
|
||
|
* `container.walkFunctionNodes`
|
||
|
* `container.walkNumberNodes`
|
||
|
* `container.walkOperators`
|
||
|
* `container.walkParenthesis`
|
||
|
* `container.walkStringNodes`
|
||
|
* `container.walkUnicodeRanges`
|
||
|
* `container.walkWords`
|
||
|
|
||
|
### `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
|
||
|
let color = parser.word({ value: '#fff' });
|
||
|
node.append(color);
|
||
|
```
|
||
|
|
||
|
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
|
||
|
nodes.walk(function (node) {
|
||
|
if (node.type !== 'word') {
|
||
|
let colon = parser.colon();
|
||
|
node.parent.insertAfter(node, colon);
|
||
|
}
|
||
|
});
|
||
|
```
|
||
|
|
||
|
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
|
||
|
node.length // → 2
|
||
|
node.remove(word)
|
||
|
node.length // → 1;
|
||
|
word.parent // undefined
|
||
|
```
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
* `node`: The node to remove.
|
||
|
|
||
|
### `container.removeAll()` or `container.empty()`
|
||
|
|
||
|
Remove all children from the container.
|
||
|
|
||
|
```js
|
||
|
node.removeAll();
|
||
|
node.length // → 0
|
||
|
```
|
||
|
|
||
|
## Root nodes`
|
||
|
|
||
|
A root node represents the top-level Container for Value nodes. Indeed, all
|
||
|
a root's `toString()` method does is join its node children with a ','.
|
||
|
Other than this, it has no special functionality and acts like a container.
|
||
|
|
||
|
## Value nodes
|
||
|
|
||
|
A Value node represents a single compound node. For example, this
|
||
|
node string `1px solid black`, is represented as three distinct nodes.
|
||
|
It has no special functionality of its own.
|