node_modules

This commit is contained in:
saeid
2019-07-15 13:07:31 +04:30
parent d3735c6d30
commit ce1a3ebf9c
35713 changed files with 3639219 additions and 1 deletions
BIN
View File
Binary file not shown.
+3
View File
@@ -0,0 +1,3 @@
# Lexer
> To be done
+132
View File
@@ -0,0 +1,132 @@
# List
<!-- MarkdownTOC -->
- [Static methods](#static-methods)
- [List.createItem](#listcreateitem)
- [Properties](#properties)
- [List#head](#listhead)
- [List#tail](#listtail)
- [List#cursor](#listcursor)
- [Methods](#methods)
- [List#createItem\(\)](#listcreateitem-1)
- [List#updateCursors\(\)](#listupdatecursors)
- [List#getSize\(\)](#listgetsize)
- [List#fromArray\(\)](#listfromarray)
- [List#toArray\(\)](#listtoarray)
- [List#toJSON\(\)](#listtojson)
- [List#isEmpty\(\)](#listisempty)
- [List#first\(\)](#listfirst)
- [List#last\(\)](#listlast)
- [List#each\(\)](#listeach)
- [List#forEach\(\)](#listforeach)
- [List#eachRight\(\)](#listeachright)
- [List#forEachRight\(\)](#listforeachright)
- [List#nextUntil\(\)](#listnextuntil)
- [List#prevUntil\(\)](#listprevuntil)
- [List#some\(\)](#listsome)
- [List#map\(\)](#listmap)
- [List#filter\(\)](#listfilter)
- [List#clear\(\)](#listclear)
- [List#copy\(\)](#listcopy)
- [List#prepend\(\)](#listprepend)
- [List#prependData\(\)](#listprependdata)
- [List#append\(\)](#listappend)
- [List#appendData\(\)](#listappenddata)
- [List#insert\(\)](#listinsert)
- [List#insertData\(\)](#listinsertdata)
- [List#remove\(\)](#listremove)
- [List#push\(\)](#listpush)
- [List#pop\(\)](#listpop)
- [List#unshift\(\)](#listunshift)
- [List#shift\(\)](#listshift)
- [List#prependList\(\)](#listprependlist)
- [List#appendList\(\)](#listappendlist)
- [List#insertList\(\)](#listinsertlist)
- [List#replace\(\)](#listreplace)
<!-- /MarkdownTOC -->
## Static methods
### List.createItem
## Properties
### List#head
### List#tail
### List#cursor
## Methods
### List#createItem()
### List#updateCursors()
### List#getSize()
### List#fromArray()
### List#toArray()
### List#toJSON()
### List#isEmpty()
### List#first()
### List#last()
### List#each()
### List#forEach()
### List#eachRight()
### List#forEachRight()
### List#nextUntil()
### List#prevUntil()
### List#some()
### List#map()
### List#filter()
### List#clear()
### List#copy()
### List#prepend()
### List#prependData()
### List#append()
### List#appendData()
### List#insert()
### List#insertData()
### List#remove()
### List#push()
### List#pop()
### List#unshift()
### List#shift()
### List#prependList()
### List#appendList()
### List#insertList()
### List#replace()
+131
View File
@@ -0,0 +1,131 @@
# Tokenizer
<!-- MarkdownTOC -->
- [Static properties](#static-properties)
- [CssSyntaxError](#csssyntaxerror)
- [TYPE](#type)
- [NAME](#name)
- [SYMBOL_TYPE](#symboltype)
- [PUNCTUATION](#punctuation)
- [Static methods](#static-methods)
- [firstCharOffset\(source\)](#firstcharoffsetsource)
- [isHex\(code\)](#ishexcode)
- [isNumber\(code\)](#isnumbercode)
- [isNewline\(source, offset, code\)](#isnewlinesource-offset-code)
- [cmpChar\(testStr, offset, referenceCode\)](#cmpcharteststr-offset-referencecode)
- [cmpStr\(testStr, start, end, referenceStr\)](#cmpstrteststr-start-end-referencestr)
- [endsWith\(testStr, referenceStr\)](#endswithteststr-referencestr)
- [findLastNonSpaceLocation\(scanner\)](#findlastnonspacelocationscanner)
- [findWhitespaceEnd\(source, offset\)](#findwhitespaceendsource-offset)
- [findCommentEnd\(source, offset\)](#findcommentendsource-offset)
- [findStringEnd\(source, offset, quote\)](#findstringendsource-offset-quote)
- [findDecimalNumberEnd\(source, offset\)](#finddecimalnumberendsource-offset)
- [findNumberEnd\(source, offset, allowFraction\)](#findnumberendsource-offset-allowfraction)
- [findEscaseEnd\(source, offset\)](#findescaseendsource-offset)
- [findIdentifierEnd\(source, offset\)](#findidentifierendsource-offset)
- [Methods](#methods)
- [setSource\(source, startOffset, startLine, startColumn\)](#setsourcesource-startoffset-startline-startcolumn)
- [lookupType\(offset\)](#lookuptypeoffset)
- [lookupNonWSType\(offset\)](#lookupnonwstypeoffset)
- [lookupValue\(offset, referenceStr\)](#lookupvalueoffset-referencestr)
- [getTokenValue\(\)](#gettokenvalue)
- [substrToCursor\(start\)](#substrtocursorstart)
- [skipWS\(\)](#skipws)
- [skip\(tokenCount\)](#skiptokencount)
- [next\(\)](#next)
- [eat\(tokenType\)](#eattokentype)
- [eatNonWS\(tokenType\)](#eatnonwstokentype)
- [consume\(tokenType\)](#consumetokentype)
- [consumeNonWS\(tokenType\)](#consumenonwstokentype)
- [expectIdentifier\(name\)](#expectidentifiername)
- [getLocation\(offset, filename\)](#getlocationoffset-filename)
- [getLocationRange\(start, end, filename\)](#getlocationrangestart-end-filename)
- [error\(message, offset\)](#errormessage-offset)
- [getTypes\(\)](#gettypes)
<!-- /MarkdownTOC -->
## Static properties
### CssSyntaxError
### TYPE
### NAME
### SYMBOL_TYPE
### PUNCTUATION
## Static methods
### firstCharOffset(source)
### isHex(code)
### isNumber(code)
### isNewline(source, offset, code)
### cmpChar(testStr, offset, referenceCode)
### cmpStr(testStr, start, end, referenceStr)
### endsWith(testStr, referenceStr)
### findLastNonSpaceLocation(scanner)
### findWhitespaceEnd(source, offset)
### findCommentEnd(source, offset)
### findStringEnd(source, offset, quote)
### findDecimalNumberEnd(source, offset)
### findNumberEnd(source, offset, allowFraction)
### findEscaseEnd(source, offset)
### findIdentifierEnd(source, offset)
## Methods
### setSource(source, startOffset, startLine, startColumn)
### lookupType(offset)
### lookupNonWSType(offset)
### lookupValue(offset, referenceStr)
### getTokenValue()
### substrToCursor(start)
### skipWS()
### skip(tokenCount)
### next()
### eat(tokenType)
### eatNonWS(tokenType)
### consume(tokenType)
### consumeNonWS(tokenType)
### expectIdentifier(name)
### getLocation(offset, filename)
### getLocationRange(start, end, filename)
### error(message, offset)
### getTypes()
+3
View File
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 42 KiB

+567
View File
@@ -0,0 +1,567 @@
# AST format
CSSTree's AST consists of nodes (leafs). Each node is an object with a set of properties that depends on node's type. Nodes can refers to other nodes and contain a list of nested nodes.
Interactively explore the AST with [AST Explorer](https://astexplorer.net/#/gist/244e2fb4da940df52bf0f4b94277db44/e79aff44611020b22cfd9708f3a99ce09b7d67a8).
<!-- MarkdownTOC -->
- [Example](#example)
- [Common node's properties](#common-nodes-properties)
- [type](#type)
- [loc](#loc)
- [children](#children)
- [Node types](#node-types)
- [AnPlusB](#anplusb)
- [Atrule](#atrule)
- [AtrulePrelude](#atruleprelude)
- [AttributeSelector](#attributeselector)
- [Block](#block)
- [Brackets](#brackets)
- [CDC](#cdc)
- [CDO](#cdo)
- [ClassSelector](#classselector)
- [Combinator](#combinator)
- [Comment](#comment)
- [Declaration](#declaration)
- [DeclarationList](#declarationlist)
- [Dimension](#dimension)
- [Function](#function)
- [HexColor](#hexcolor)
- [IdSelector](#idselector)
- [Identifier](#identifier)
- [MediaFeature](#mediafeature)
- [MediaQuery](#mediaquery)
- [MediaQueryList](#mediaquerylist)
- [Nth](#nth)
- [Number](#number)
- [Operator](#operator)
- [Parentheses](#parentheses)
- [Percentage](#percentage)
- [PseudoClassSelector](#pseudoclassselector)
- [PseudoElementSelector](#pseudoelementselector)
- [Ratio](#ratio)
- [Raw](#raw)
- [Rule](#rule)
- [Selector](#selector)
- [SelectorList](#selectorlist)
- [String](#string)
- [StyleSheet](#stylesheet)
- [TypeSelector](#typeselector)
- [UnicodeRange](#unicoderange)
- [Url](#url)
- [Value](#value)
- [WhiteSpace](#whitespace)
<!-- /MarkdownTOC -->
## Example
Assume we have a CSS:
```css
body {
color: red;
}
```
An AST for this CSS might look like:
```js
{
type: 'StyleSheet',
loc: null,
children: [
{
type: 'Rule',
loc: null,
prelude: {
type: 'SelectorList',
loc: null,
children: [
{
type: 'Selector',
loc: null,
children: [
{
type: 'TypeSelector',
loc: null,
name: 'body'
}
]
}
]
},
block: {
type: 'Block',
loc: null,
children: [
{
type: 'Declaration',
loc: null,
important: false,
property: 'color',
value: {
type: 'Value',
loc: null,
children: [
{
type: 'Identifier',
loc: null,
name: 'red'
}
]
}
}
]
}
}
]
}
```
> NOTE: The example uses arrays for the values of the property `children`. In fact, the values of this property are instances of the [`List`](List.md) class.
An AST structure (i.e. details level, include positions or not) is depend on options passed to parser. See [Parsing CSS into AST](parsing.md) for details.
## Common node's properties
All nodes have the following properties.
### type
Type: `String`
Indicates the type of a node. The possible values are the ones listed in the [Node types](#node-types) below.
### loc
Type: `Object` or `null`
Information about the position in the source string that corresponds to the node. It has the following structure:
```js
{
source: String,
start: {
offset: Number,
line: Number,
column: Number
},
end: {
offset: Number,
line: Number,
column: Number
}
}
```
The `source` property contains value of `options.filename` if passed to `csstree.parse()`, otherwise `"<unknown>"`.
The `offset` number is zero-based, indicates the index in a source string passed to the parser.
The `line` and `column` numbers are 1-based: the first line is `1` and the first column of a line is `1`.
The `loc` property lets you know from which source file the node comes from (if available) and what part of that file was parsed into the node. By default parser doesn't include `loc` data into the AST (sets `null` for this property), you should pass `options.positions` equal to `true` to make `loc` filled.
### children
Type: `List` or `null`
Only certain types of nodes can contain this property, such as [`StyleSheet`](#stylesheet) or [`Block`](#block). However, this is the only property that can store a list of nested nodes.
Most node types always store an instance of the `List` in this property, even if there is no nested nodes (the list is empty). Only some node types, such as `PseudoClassSelector` and `PseudoElementSelector`, can store a `null` instead of a list. This is due to the fact that in the absence of a list such node types is represent a pseudo-selector, and in the presence of a list, a functional pseudo-selector. See definition of each node type for details.
## Node types
> NOTE: Despite every node has a `loc` property, this property is excluded from definitions to reduce a noise.
<!-- node types -->
### AnPlusB
Used for [the An+B microsyntax](https://drafts.csswg.org/css-syntax/#anb-microsyntax).
```js
{
type: "AnPlusB",
a: String | null,
b: String | null
}
```
`a` or `b` fields may have no value (equals to `null`) but not both at the same time. Parser normalizes `a` value to store a valid integer, i.e. parser will store `-1` for `-n` and `1` for `n`.
### Atrule
```js
{
type: "Atrule",
name: String,
prelude: <AtrulePrelude> | <Raw> | null,
block: <Block> | null
}
```
### AtrulePrelude
```js
{
type: "AtrulePrelude",
children: List
}
```
### AttributeSelector
```js
{
type: "AttributeSelector",
name: <Identifier>,
matcher: String | null,
value: <String> | <Identifier> | null,
flags: String | null
}
```
### Block
```js
{
type: "Block",
children: List
}
```
### Brackets
```js
{
type: "Brackets",
children: List
}
```
### CDC
```js
{
type: "CDC"
}
```
### CDO
```js
{
type: "CDO"
}
```
### ClassSelector
```js
{
type: "ClassSelector",
name: String
}
```
### Combinator
```js
{
type: "Combinator",
name: String
}
```
### Comment
```js
{
type: "Comment",
value: String
}
```
### Declaration
```js
{
type: "Declaration",
important: Boolean | String,
property: String,
value: <Value> | <Raw>
}
```
### DeclarationList
```js
{
type: "DeclarationList",
children: List
}
```
### Dimension
```js
{
type: "Dimension",
value: String,
unit: String
}
```
### Function
```js
{
type: "Function",
name: String,
children: List
}
```
### HexColor
```js
{
type: "HexColor",
value: String
}
```
### IdSelector
```js
{
type: "IdSelector",
name: String
}
```
### Identifier
```js
{
type: "Identifier",
name: String
}
```
### MediaFeature
```js
{
type: "MediaFeature",
name: String,
value: <Identifier> | <Number> | <Dimension> | <Ratio> | null
}
```
### MediaQuery
```js
{
type: "MediaQuery",
children: List
}
```
### MediaQueryList
```js
{
type: "MediaQueryList",
children: List
}
```
### Nth
```js
{
type: "Nth",
nth: <AnPlusB> | <Identifier>,
selector: <SelectorList> | null
}
```
### Number
```js
{
type: "Number",
value: String
}
```
### Operator
```js
{
type: "Operator",
value: String
}
```
### Parentheses
```js
{
type: "Parentheses",
children: List
}
```
### Percentage
```js
{
type: "Percentage",
value: String
}
```
### PseudoClassSelector
```js
{
type: "PseudoClassSelector",
name: String,
children: List | null
}
```
### PseudoElementSelector
```js
{
type: "PseudoElementSelector",
name: String,
children: List | null
}
```
### Ratio
```js
{
type: "Ratio",
left: String,
right: String
}
```
### Raw
A sequence of any characters. This node type is used for unparsed fragments of CSS, e.g. due to parse error or parser settings, and for quirk parts like content of some functions, such as `url()` or `expression()`.
```js
{
type: "Raw",
value: String
}
```
### Rule
```js
{
type: "Rule",
prelude: <SelectorList> | <Raw>,
block: <Block>
}
```
### Selector
```js
{
type: "Selector",
children: List
}
```
### SelectorList
```js
{
type: "SelectorList",
children: List
}
```
### String
A sequence of characters enclosed in double quotes or single quotes.
```js
{
type: "String",
value: String
}
```
### StyleSheet
```js
{
type: "StyleSheet",
children: List
}
```
### TypeSelector
```js
{
type: "TypeSelector",
name: String
}
```
### UnicodeRange
Used for [the Unicode-Range microsyntax](https://drafts.csswg.org/css-syntax/#urange).
```js
{
type: "UnicodeRange",
value: String
}
```
### Url
```js
{
type: "Url",
value: <String> | <Raw>
}
```
### Value
```js
{
type: "Value",
children: List
}
```
### WhiteSpace
A sequence of one or more white spaces, i.e. ` ` (space), `\t`, `\r`, `\n` and `\f`.
```js
{
type: "WhiteSpace",
value: String
}
```
<!-- /node types -->
+48
View File
@@ -0,0 +1,48 @@
# Translate AST to string
## generate(ast[, options])
Generates a CSS string for given AST.
```js
// generate with default settings
csstree.generate(ast);
// generate with options
csstree.generate(ast, {
sourceMap: true
});
```
Options (optional):
<!-- MarkdownTOC -->
- [sourceMap](#sourcemap)
- [decorator](#decorator)
<!-- /MarkdownTOC -->
### sourceMap
Type: `boolean`
Default: `false`
Generates a source map (nodes should contain positions in `loc` property). Note, that an object instead of string is returned in that case.
```js
var ast = csstree.parse('.test { color: red }', {
filename: 'my.css',
positions: true
});
var result = csstree.generate(ast, { sourceMap: true });
// { css: '.test{color:red}', map: SourceMapGenerator {} }
```
### decorator
Type: `function`
Default: none
A function that a handlers used by a generator. TBD
+285
View File
@@ -0,0 +1,285 @@
# Parsing CSS into AST
> NOTE: Currenly parser omits redundant separators, spaces and comments (except exclamation comments, i.e. `/*! comment */`) on AST build.
## parse(source[, options])
Parses CSS into AST.
```js
// simple parsing with no options
var ast = csstree.parse('.example { color: red }');
// parse with options
var ast = csstree.parse('.foo.bar', {
context: 'selector',
positions: true
});
```
Options (optional):
<!-- MarkdownTOC -->
- [context](#context)
- [atrule](#atrule)
- [positions](#positions)
- [onParseError](#onparseerror)
- [filename](#filename)
- [offset](#offset)
- [line](#line)
- [column](#column)
- [parseAtrulePrelude](#parseatruleprelude)
- [parseRulePrelude](#parseruleprelude)
- [parseValue](#parsevalue)
- [parseCustomProperty](#parsecustomproperty)
<!-- /MarkdownTOC -->
### context
Type: `string`
Default: `'stylesheet'`
Defines what part of CSS is parsing.
Contexts:
- `stylesheet` (default) – regular stylesheet, should be suitable in most cases
- `atrule` – at-rule (e.g. `@media screen, print { ... }`)
- `atrulePrelude` – at-rule prelude (`screen, print` for example above)
- `mediaQueryList` – used to parse comma separated media query list
- `mediaQuery` – used to parse media query
- `rule` – rule (e.g. `.foo, .bar:hover { color: red; border: 1px solid black; }`)
- `selectorList` – selector group (`.foo, .bar:hover` for rule example)
- `selector` – selector (`.foo` or `.bar:hover` for rule example)
- `block` – block with curly braces (`{ color: red; border: 1px solid black; }` for rule example)
- `declarationList` – block content w/o curly braces (`color: red; border: 1px solid black;` for rule example), useful for parsing HTML `style` attribute value
- `declaration` – declaration (`color: red` or `border: 1px solid black` for rule example)
- `value` – declaration value (`red` or `1px solid black` for rule example)
### atrule
Type: `string` or `null`
Default: `null`
Using for `atrulePrelude` context to apply atrule specific parse rules.
### positions
Type: `boolean`
Default: `false`
Specify to store locations of node content in original source. Location is storing as `loc` field of nodes. `loc` property is always `null` when option is `false`. The structure of `loc`:
```
loc: {
source: 'value of `filename` option or `<unknown>`',
start: {
offset: <number>,
line: <number>,
column: <number>
},
end: {
offset: <number>,
line: <number>,
column: <number>
}
}
```
### onParseError
Type: `function(error, fallbackNode)` or `null`
Default: `null`
Parsing is tolerant by default, i.e. any text may to be parsed with no an raised exception. However, mistakes in CSS may make it imposible to parse some part, e.g. a selector or declaration. In that case bad content is wrapping into a `Raw` node and `onParseError` is invoking.
```js
csstree.parse('example { foo; bar: 1! }', {
onParseError: function(error) {
console.log(error.formattedMessage);
}
});
// Parse error: Colon is expected
// 1 |example { foo; bar: 1! }
// --------------------^
// Parse error: Identifier is expected
// 1 |example { foo; bar: 1! }
// ------------------------------^
```
### filename
Type: `string`
Default: `'<unknown>'`
Filename of source. This value adds to `loc` as `source` property when `positions` option is `true`. Using for source map generation.
### offset
Type: `number`
Default: `0`
Start offset. Useful when parsing a fragment of CSS to store a correct positions for node's `loc` property.
### line
Type: `number`
Default: `1`
Start line number. Useful when parsing fragment of CSS to store correct positions in node's `loc` property.
### column
Type: `number`
Default: `1`
Start column number. Useful when parsing fragment of CSS to store correct positions in node's `loc` property.
### parseAtrulePrelude
Type: `boolean`
Default: `true`
Defines to parse a at-rule prelude in details (represents as `AtruleExpresion`, `MediaQueryList` or `SelectorList` if any). Otherwise represents prelude as `Raw` node.
```js
csstree.parse('@example 1 2;');
// {
// "type": "Atrule",
// "prelude": {
// "type": "AtrulePrelude",
// "children": [
// { "type": "Number", "value": "1" },
// { "type": "WhiteSpace", "value": " " },
// { "type": "Number", "value": "2" }
// ]
// },
// "block": null
// }
csstree.parse('@example 1 2;', { parseAtrulePrelude: false });
// {
// "type": "Atrule",
// "prelude": {
// "type": "Raw",
// "value": "1 2"
// },
// "block": null
// }
```
### parseRulePrelude
Type: `boolean`
Default: `true`
Defines to parse a rule prelude in details or left unparsed (represents as `Raw` node).
```js
csstree.parse('.foo {}');
// {
// "type": "Rule",
// "prelude": {
// "type": "SelectorList",
// "children": [
// {
// "type": "Selector",
// "children": [
// { "type": "ClassSelector", "name": "foo" }
// ]
// }
// ]
// },
// "block": {
// "type": "Block",
// "children": []
// }
// }
csstree.parse('.foo {}', { parseRulePrelude: false });
// {
// "type": "Rule",
// "prelude": {
// "type": "Raw",
// "value": ".foo"
// },
// "block": {
// "type": "Block",
// "children": []
// }
// }
```
### parseValue
Type: `boolean`
Default: `true`
Defines to parse a declaration value in details (represents as `Value`). Otherwise represents value as `Raw` node.
```js
csstree.parse('color: #aabbcc', { context: 'declaration' });
// {
// "type": "Declaration",
// "important": false,
// "property": "color",
// "value": {
// "type": "Value",
// "children": [
// {
// "type": "HexColor",
// "value": "aabbcc"
// }
// ]
// }
// }
csstree.parse('color: #aabbcc', { context: 'declaration', parseValue: false });
// {
// "type": "Declaration",
// "important": false,
// "property": "color",
// "value": {
// "type": "Raw",
// "value": " #aabbcc"
// }
// }
```
### parseCustomProperty
Type: `boolean`
Default: `false`
Defines to parse a custom property value and a `var()` fallback in details (represents as `Value`). Otherwise represents value as `Raw` node.
```js
csstree.parse('--custom: #aabbcc', { context: 'declaration' });
// {
// "type": "Declaration",
// "important": false,
// "property": "--custom",
// "value": {
// "type": "Raw",
// "value": " #aabbcc"
// }
// }
csstree.parse('--custom: #aabbcc', { context: 'declaration', parseCustomProperty: true });
// {
// "type": "Declaration",
// "important": false,
// "property": "--custom",
// "value": {
// "type": "Value",
// "children": [
// {
// "type": "HexColor",
// "value": "aabbcc"
// }
// ]
// }
// }
```
+15
View File
@@ -0,0 +1,15 @@
# API
## General
- [Parsing CSS into AST](parsing.md)
- [AST format](ast.md)
- [Generate CSS from AST](generate.md)
- [AST traversal](traversal.md)
- [Utils to work with AST](utils.md)
## Classes
- [Tokenizer](Tokenizer.md)
- [Lexer](Lexer.md)
- [List](List.md)
+512
View File
@@ -0,0 +1,512 @@
# Supported syntaxes
> ⚠️ This is a basic implementation of support reference. Further improvements are pending. See comments on each section for details.
> ⚠️ This page is auto-generated. Please, don't update any content between special comments.
<!-- MarkdownTOC -->
- [Atrules](#atrules)
- [Functional pseudos](#functional-pseudos)
- [Properties](#properties)
<!-- /MarkdownTOC -->
## Atrules
At-rules with a custom parsing rules. In fact, any at-rule is supported but prelude and block are parsing with default rules. Validation support isn't supported for at-rules at the moment.
<!-- gen:atrule -->
- `@font-face`
- `@import`
- `@media`
- `@page`
- `@supports`
<!-- /gen:atrule -->
## Functional pseudos
Functional pseudos with a custom parsing rule. Non-listed functional pseudos don't parse a content inside parentheses and represent it as a `Raw` node if any. There is no difference between pseudo class and pseudo element on parsing, like no validation for functional pseudos is supported at the moment.
<!-- gen:pseudo -->
- `:dir()`
- `:has()`
- `:lang()`
- `:matches()`
- `:not()`
- `:nth-child()`
- `:nth-last-child()`
- `:nth-last-of-type()`
- `:nth-of-type()`
- `:slotted()`
<!-- /gen:pseudo -->
## Properties
Support for a property means CSSTree has a grammar for such property, so its value can be checked (validated) for complience to spec or browser inplementations (for non-standart properties). The validation doesn't perform on parsing stage and should be done as a separate step using Lexer API. In other words any property value can be parsed with default parsing rules, but validation is possible for listed properties only.
<!-- gen:properties -->
- `-moz-appearance`
- `-moz-background-clip`
- `-moz-binding`
- `-moz-border-bottom-colors`
- `-moz-border-left-colors`
- `-moz-border-radius-bottomleft`
- `-moz-border-radius-bottomright`
- `-moz-border-radius-topleft`
- `-moz-border-radius-topright`
- `-moz-border-right-colors`
- `-moz-border-top-colors`
- `-moz-context-properties`
- `-moz-float-edge`
- `-moz-force-broken-image-icon`
- `-moz-image-region`
- `-moz-orient`
- `-moz-osx-font-smoothing`
- `-moz-outline-radius`
- `-moz-outline-radius-bottomleft`
- `-moz-outline-radius-bottomright`
- `-moz-outline-radius-topleft`
- `-moz-outline-radius-topright`
- `-moz-stack-sizing`
- `-moz-text-blink`
- `-moz-user-focus`
- `-moz-user-input`
- `-moz-user-modify`
- `-moz-user-select`
- `-moz-window-dragging`
- `-moz-window-shadow`
- `-ms-filter`
- `-ms-flex-align`
- `-ms-flex-item-align`
- `-ms-flex-line-pack`
- `-ms-flex-negative`
- `-ms-flex-order`
- `-ms-flex-pack`
- `-ms-flex-positive`
- `-ms-flex-preferred-size`
- `-ms-grid-column-align`
- `-ms-grid-row-align`
- `-ms-high-contrast-adjust`
- `-ms-interpolation-mode`
- `-ms-overflow-style`
- `-ms-user-select`
- `-webkit-appearance`
- `-webkit-background-clip`
- `-webkit-border-before`
- `-webkit-border-before-color`
- `-webkit-border-before-style`
- `-webkit-border-before-width`
- `-webkit-box-reflect`
- `-webkit-column-break-after`
- `-webkit-column-break-before`
- `-webkit-column-break-inside`
- `-webkit-font-smoothing`
- `-webkit-line-clamp`
- `-webkit-mask`
- `-webkit-mask-attachment`
- `-webkit-mask-box-image`
- `-webkit-mask-clip`
- `-webkit-mask-composite`
- `-webkit-mask-image`
- `-webkit-mask-origin`
- `-webkit-mask-position`
- `-webkit-mask-position-x`
- `-webkit-mask-position-y`
- `-webkit-mask-repeat`
- `-webkit-mask-repeat-x`
- `-webkit-mask-repeat-y`
- `-webkit-overflow-scrolling`
- `-webkit-print-color-adjust`
- `-webkit-tap-highlight-color`
- `-webkit-text-fill-color`
- `-webkit-text-security`
- `-webkit-text-stroke`
- `-webkit-text-stroke-color`
- `-webkit-text-stroke-width`
- `-webkit-touch-callout`
- `-webkit-user-drag`
- `-webkit-user-select`
- `align-content`
- `align-items`
- `align-self`
- `alignment-baseline`
- `all`
- `animation`
- `animation-delay`
- `animation-direction`
- `animation-duration`
- `animation-fill-mode`
- `animation-iteration-count`
- `animation-name`
- `animation-play-state`
- `animation-timing-function`
- `appearance`
- `azimuth`
- `backdrop-filter`
- `backface-visibility`
- `background`
- `background-attachment`
- `background-blend-mode`
- `background-clip`
- `background-color`
- `background-image`
- `background-origin`
- `background-position`
- `background-position-x`
- `background-position-y`
- `background-repeat`
- `background-size`
- `baseline-shift`
- `behavior`
- `block-size`
- `border`
- `border-block-end`
- `border-block-end-color`
- `border-block-end-style`
- `border-block-end-width`
- `border-block-start`
- `border-block-start-color`
- `border-block-start-style`
- `border-block-start-width`
- `border-bottom`
- `border-bottom-color`
- `border-bottom-left-radius`
- `border-bottom-right-radius`
- `border-bottom-style`
- `border-bottom-width`
- `border-collapse`
- `border-color`
- `border-image`
- `border-image-outset`
- `border-image-repeat`
- `border-image-slice`
- `border-image-source`
- `border-image-width`
- `border-inline-end`
- `border-inline-end-color`
- `border-inline-end-style`
- `border-inline-end-width`
- `border-inline-start`
- `border-inline-start-color`
- `border-inline-start-style`
- `border-inline-start-width`
- `border-left`
- `border-left-color`
- `border-left-style`
- `border-left-width`
- `border-radius`
- `border-right`
- `border-right-color`
- `border-right-style`
- `border-right-width`
- `border-spacing`
- `border-style`
- `border-top`
- `border-top-color`
- `border-top-left-radius`
- `border-top-right-radius`
- `border-top-style`
- `border-top-width`
- `border-width`
- `bottom`
- `box-align`
- `box-decoration-break`
- `box-direction`
- `box-flex`
- `box-flex-group`
- `box-lines`
- `box-ordinal-group`
- `box-orient`
- `box-pack`
- `box-shadow`
- `box-sizing`
- `break-after`
- `break-before`
- `break-inside`
- `caption-side`
- `caret-color`
- `clear`
- `clip`
- `clip-path`
- `clip-rule`
- `color`
- `column-count`
- `column-fill`
- `column-gap`
- `column-rule`
- `column-rule-color`
- `column-rule-style`
- `column-rule-width`
- `column-span`
- `column-width`
- `columns`
- `contain`
- `content`
- `counter-increment`
- `counter-reset`
- `cue`
- `cue-after`
- `cue-before`
- `cursor`
- `direction`
- `display`
- `display-inside`
- `display-list`
- `display-outside`
- `dominant-baseline`
- `empty-cells`
- `fill`
- `fill-opacity`
- `fill-rule`
- `filter`
- `flex`
- `flex-basis`
- `flex-direction`
- `flex-flow`
- `flex-grow`
- `flex-shrink`
- `flex-wrap`
- `float`
- `font`
- `font-family`
- `font-feature-settings`
- `font-kerning`
- `font-language-override`
- `font-size`
- `font-size-adjust`
- `font-stretch`
- `font-style`
- `font-synthesis`
- `font-variant`
- `font-variant-alternates`
- `font-variant-caps`
- `font-variant-east-asian`
- `font-variant-ligatures`
- `font-variant-numeric`
- `font-variant-position`
- `font-variation-settings`
- `font-weight`
- `glyph-orientation-horizontal`
- `glyph-orientation-vertical`
- `grid`
- `grid-area`
- `grid-auto-columns`
- `grid-auto-flow`
- `grid-auto-rows`
- `grid-column`
- `grid-column-end`
- `grid-column-gap`
- `grid-column-start`
- `grid-gap`
- `grid-row`
- `grid-row-end`
- `grid-row-gap`
- `grid-row-start`
- `grid-template`
- `grid-template-areas`
- `grid-template-columns`
- `grid-template-rows`
- `hanging-punctuation`
- `height`
- `hyphens`
- `image-orientation`
- `image-rendering`
- `image-resolution`
- `ime-mode`
- `initial-letter`
- `initial-letter-align`
- `inline-size`
- `isolation`
- `justify-content`
- `kerning`
- `left`
- `letter-spacing`
- `line-break`
- `line-height`
- `line-height-step`
- `list-style`
- `list-style-image`
- `list-style-position`
- `list-style-type`
- `margin`
- `margin-block-end`
- `margin-block-start`
- `margin-bottom`
- `margin-inline-end`
- `margin-inline-start`
- `margin-left`
- `margin-right`
- `margin-top`
- `marker`
- `marker-end`
- `marker-mid`
- `marker-start`
- `mask`
- `mask-border`
- `mask-border-mode`
- `mask-border-outset`
- `mask-border-repeat`
- `mask-border-slice`
- `mask-border-source`
- `mask-border-width`
- `mask-clip`
- `mask-composite`
- `mask-image`
- `mask-mode`
- `mask-origin`
- `mask-position`
- `mask-repeat`
- `mask-size`
- `mask-type`
- `max-block-size`
- `max-height`
- `max-inline-size`
- `max-width`
- `min-block-size`
- `min-height`
- `min-inline-size`
- `min-width`
- `mix-blend-mode`
- `object-fit`
- `object-position`
- `offset`
- `offset-anchor`
- `offset-block-end`
- `offset-block-start`
- `offset-distance`
- `offset-inline-end`
- `offset-inline-start`
- `offset-path`
- `offset-position`
- `offset-rotate`
- `opacity`
- `order`
- `orphans`
- `outline`
- `outline-color`
- `outline-offset`
- `outline-style`
- `outline-width`
- `overflow`
- `overflow-clip-box`
- `overflow-wrap`
- `overflow-x`
- `overflow-y`
- `padding`
- `padding-block-end`
- `padding-block-start`
- `padding-bottom`
- `padding-inline-end`
- `padding-inline-start`
- `padding-left`
- `padding-right`
- `padding-top`
- `page-break-after`
- `page-break-before`
- `page-break-inside`
- `pause`
- `pause-after`
- `pause-before`
- `perspective`
- `perspective-origin`
- `pointer-events`
- `position`
- `quotes`
- `resize`
- `rest`
- `rest-after`
- `rest-before`
- `right`
- `ruby-align`
- `ruby-merge`
- `ruby-position`
- `scroll-behavior`
- `scroll-snap-coordinate`
- `scroll-snap-destination`
- `scroll-snap-points-x`
- `scroll-snap-points-y`
- `scroll-snap-type`
- `scroll-snap-type-x`
- `scroll-snap-type-y`
- `shape-image-threshold`
- `shape-margin`
- `shape-outside`
- `shape-rendering`
- `speak`
- `speak-as`
- `src`
- `stroke`
- `stroke-dasharray`
- `stroke-dashoffset`
- `stroke-linecap`
- `stroke-linejoin`
- `stroke-miterlimit`
- `stroke-opacity`
- `stroke-width`
- `tab-size`
- `table-layout`
- `text-align`
- `text-align-last`
- `text-anchor`
- `text-combine-upright`
- `text-decoration`
- `text-decoration-color`
- `text-decoration-line`
- `text-decoration-skip`
- `text-decoration-skip-ink`
- `text-decoration-style`
- `text-emphasis`
- `text-emphasis-color`
- `text-emphasis-position`
- `text-emphasis-style`
- `text-indent`
- `text-justify`
- `text-orientation`
- `text-overflow`
- `text-rendering`
- `text-shadow`
- `text-size-adjust`
- `text-transform`
- `text-underline-position`
- `top`
- `touch-action`
- `transform`
- `transform-box`
- `transform-origin`
- `transform-style`
- `transition`
- `transition-delay`
- `transition-duration`
- `transition-property`
- `transition-timing-function`
- `unicode-bidi`
- `unicode-range`
- `user-select`
- `vertical-align`
- `visibility`
- `voice-balance`
- `voice-duration`
- `voice-family`
- `voice-pitch`
- `voice-range`
- `voice-rate`
- `voice-stress`
- `voice-volume`
- `white-space`
- `widows`
- `width`
- `will-change`
- `word-break`
- `word-spacing`
- `word-wrap`
- `writing-mode`
- `z-index`
- `zoom`
<!-- /gen:properties -->
+3
View File
@@ -0,0 +1,3 @@
# Working with syntax
> To be done...
+249
View File
@@ -0,0 +1,249 @@
# AST traversal
AST traversal API is provided by `walk()` method.
```js
var csstree = require('css-tree');
var ast = csstree.parse('.a { color: red; }');
csstree.walk(ast, function(node) {
console.log(node.type);
});
// StyleSheet
// Rule
// SelectorList
// Selector
// ClassSelector
// Block
// Declaration
// Value
// Identifier
```
The facts you should know about `walk()` internals:
- Method uses `structure` field value of every node type to define the way how to iterate the nodes:
- A function-iterator is generating for every node type.
- Node's properties iterates in the order it defined in `structure` ([reverse](#reverse) option can invert an order).
- Properties that are not defined in `structure` are ignoring (doesn't interate).
- An exception is possible when a tree is not following to expected structure (it may happen if AST was built outside the CSSTree parser or transformed in a wrong way). In case you are not sure about correctness of a tree structure, you can use `try/catch` or check the tree with `csstree.lexer.validateStructure(ast)` before iterate it.
- Only `children` fields can contain a list of nodes. A list of nodes should be represented as a `List` instances. But for certain cases, `children` can be an array. Since `List` provides a similar to `Array` API, traversal can work in most cases, but without any guarantee. Therefore usings arrays in AST is not recomended, use them on your own risk.
## walk(ast, options)
Method visits each node of passed tree in a natural way and calls a handler for each one. It takes two arguments: a root node (`ast`) and an object (`options`). In simple case, it can take a function (handler) instead of `options` (`walk(ast, fn)` is equivalent to `walk(ast, { enter: fn })`).
Options:
<!-- MarkdownTOC -->
- [enter](#enter)
- [leave](#leave)
- [visit](#visit)
- [reverse](#reverse)
<!-- /MarkdownTOC -->
### enter
Type: `function` or `undefined`
Default: `undefined`
Handler on node entrance, i.e. before any nested node is processed.
```js
var csstree = require('css-tree');
var ast = csstree.parse('.a { color: red; }');
csstree.walk(ast, {
enter: function(node) {
console.log(node.type);
}
});
// StyleSheet
// Rule
// SelectorList
// Selector
// ClassSelector
// Block
// Declaration
// Value
// Identifier
```
In case `options` has a single `enter` field, it can replaced for the handler passed as a value for `enter`, i.e. `walk(ast, { enter: fn })` → `walk(ast, fn)`.
Handler receives a three arguments:
- `node` – the AST node a walker entering to
- `item` – node wrapper, that contains references to `prev` and `next` nodes in a list, and `data` reference for the node
- `list` – is a reference for the list; it's useful for list operations like `remove()` or `insert()`
> NOTE: If `children` is an array, the last two arguments are `index` and `array`, like for `Array#forEach()` or `Array#map()` methods.
```js
const csstree = require('css-tree');
const ast = csstree.parse(`
.a { foo: 1; bar: 2; }
.b { bar: 3; baz: 4; }
`);
// remove declarations with `bar` property from the tree
csstree.walk(ast, function(node, item, list) {
if (node.type === 'Declaration' && node.property === 'bar' && list) {
// remove a declaration from a list it
list.remove(item);
}
});
console.log(csstree.generate(ast));
// .a{foo:1}.b{baz:4}
```
> NOTE:
> - `item` and `list` are not defined for nodes that are not in a list. Even `Declaration` can be outside of any list in case it is a root of tree or a part of `@supports` prelude, e.g. `@supports (bar: 123) { ... }`. Therefore, it's recomended to check `item` or `list` are defined before using of it (those values both are defined or both are undefined, so it's enough to test one of them)
> - Only `List` instances are safe for tree transformations such as node removal. In case you perform such operations, you can ensure that all `children` in a tree is a `List` instances by calling `csstree.fromPlainObject(ast)` before traversal.
> - It's better to use `visit` option when possible to reach better performance
Context (`this`) for a handler is an object with a references to the closest ancestor nodes:
- `root` – refers to AST root node (actually it's a node passed to `walk()` method)
- `stylesheet` – refers to `StyleSheet` node, usually it's a root node
- `atrule` – refers to closest `Atrule` node if any
- `atrulePrelude` – refers to `AtrulePrelude` node if any
- `rule` – refers to closest `Rule` node if any
- `selector` – refers to `SelectorList` node if any
- `block` - refers to closest `Block` node if any
- `declaration` – refers to `Declaration` node if any
- `function` – refers to closest `Function`, `PseudoClassSelector` or `PseudoElementSelector` node if current node inside one of them
```js
const csstree = require('css-tree');
const ast = csstree.parse(`
@import url(import.css);
.foo { background: url('foo.jpg'); }
.bar { background-image: url(bar.png); }
`);
// collect all urls in declarations
const urls = [];
csstree.walk(ast, function(node) {
if (this.declaration !== null && node.type === 'Url') {
const value = node.value;
if (value.type === 'Raw') {
urls.push(value.value);
} else {
urls.push(value.value.substr(1, value.value.length - 2));
}
}
});
console.log(urls);
// [ 'foo.jpg', 'bar.png' ]
```
### leave
Type: `function` or `undefined`
Default: `undefined`
The same as `enter` handler but invokes on node exit, i.e. after all nested nodes are processed.
```js
var csstree = require('css-tree');
var ast = csstree.parse('.a { color: red; }');
csstree.walk(ast, {
leave: function(node) {
console.log(node.type);
}
});
// ClassSelector
// Selector
// SelectorList
// Identifier
// Value
// Declaration
// Block
// Rule
// StyleSheet
```
### visit
Type: `string` or `null`
Default: `null`
Invokes a handler for a specified node type only.
```js
var csstree = require('css-tree');
var ast = csstree.parse('.a { color: red; } .b { color: green; }');
csstree.walk(ast, {
visit: 'ClassSelector',
enter: function(node) {
console.log(node.name);
}
});
// example above is equal to
csstree.walk(ast, {
enter: function(node) {
if (node.type === 'ClassSelector') {
console.log(node.name);
}
}
});
```
The traveral for some node types can performs faster (10-15 times depending on the CSS structure), because some subtrees may to be skipped since they can't contain a node of specified type (e.g. `Rule` can't be used inside of `Declaration`, so declaration's subtree can be exclude from traversal path). Fast traversal is supported for node types:
- `Atrule`
- `Rule`
- `Declaration`
> NOTE: When fast traversal is applied, some nodes may not be reached in case of an incorrect location in the tree. That's may happen if AST was built outside the CSSTree parser or transformed in a wrong way. If you need to be 100% sure that every node of type will be visited (even in wrong position), don't use `visit` option and test node type by your own.
### reverse
Type: `boolean`
Default: `false`
Inverts a natural order of traversal of nodes. To achieve this, the following actions are performed:
- children nodes are iterated in reverse order (from last to first)
- properties are iterated in reverse order (according to `structure` definition of node)
- `enter` and `leave` handlers are swapped
```js
var assert = require('assert');
var csstree = require('css-tree');
var ast = csstree.parse('.a { color: red; }');
var natural = [];
csstree.walk(ast, {
enter: function(node) {
natural.push('enter ' + node.type);
},
leave: function(node) {
natural.push('leave ' + node.type);
}
});
var reverse = [];
csstree.walk(ast, {
reverse: true,
enter: function(node) {
reverse.push('enter ' + node.type);
},
leave: function(node) {
reverse.push('leave ' + node.type);
}
});
// will be truthy
assert.deepEqual(
reverse,
natural.reverse()
);
```
+151
View File
@@ -0,0 +1,151 @@
# Utils to work with AST
<!-- MarkdownTOC -->
- [property\(name\)](#propertyname)
- [keyword\(name\)](#keywordname)
- [clone\(ast\)](#cloneast)
- [fromPlainObject\(object\)](#fromplainobjectobject)
- [toPlainObject\(ast\)](#toplainobjectast)
<!-- /MarkdownTOC -->
## property(name)
Returns details for a property name, such as vendor prefix, used hack etc. Using for safe test of declaration property names, i.e. `Declaration.property`.
```js
var csstree = require('css-tree');
csstree.property('*-vendor-property');
// {
// basename: 'property',
// name: '-vendor-property',
// hack: '*',
// vendor: '-vendor-',
// prefix: '*-vendor-',
// custom: false
// }
csstree.property('--test-var');
// {
// basename: '--test-var',
// name: '--test-var',
// hack: '',
// vendor: '',
// prefix: '',
// custom: true
// };
```
`property()` function normalizes a name to lower case, except custom property names since they are case sensitive. It returns the same immutable (freezed) object for the same input (input after normalization).
```js
csstree.property('name') === csstree.property('NAME') // true
csstree.property('NAME').name === 'name' // true
csstree.property('--custom') === csstree.property('--Custom') // false
var info = csstree.property('NAME');
info.name === 'name'; //
info.name = 'foo'; // have no effect
info.name === 'name'; // true
```
Supported hacks:
- `_` in the beginning
- `+` in the beginning
- `#` in the beginning
- `*` in the beginning
- `$` in the beginning
- `/` in the beginning
- `//` in the beginning
## keyword(name)
Mostly the same as `property()` function, but without hack detection. Using for any identifier except declaration property name.
```js
var csstree = require('css-tree');
csstree.keyword('-vendor-keyword');
// {
// basename: 'keyword',
// name: '-vendor-keyword',
// vendor: '-vendor-',
// prefix: '-vendor-',
// custom: false
// };
```
## clone(ast)
Make AST deep copy.
```js
var orig = csstree.parse('.test { color: red }');
var copy = csstree.clone(orig);
csstree.walk(copy, function(node) {
if (node.type === 'Class') {
node.name = 'replaced';
}
});
console.log(csstree.generate(orig));
// .test{color:red}
console.log(csstree.generate(copy));
// .replaced{color:red}
```
## fromPlainObject(object)
`fromPlainObject()` walks through AST and coverts each `children` value into a `List` instance when value is an array.
```js
var csstree = require('css-tree');
var ast = {
type: 'SelectorList',
children: []
};
console.log(Array.isArray(ast.children)); // true
console.log(ast.children instanceof csstree.List); // false
ast = csstree.fromPlainObject(ast);
console.log(Array.isArray(ast.children)); // false
console.log(ast.children instanceof csstree.List); // true
```
Function mutates the passed AST. Use `clone()` function before passing AST to `fromPlainObject()` in case you want to avoid original tree mutation.
```js
astClone = csstree.fromPlainObject(csstree.clone(ast));
```
## toPlainObject(ast)
`fromPlainObject()` walks through AST and coverts each `children` value to regular array when value is a `List` instance.
```js
var csstree = require('css-tree');
var ast = {
type: 'SelectorList',
children: new List()
};
console.log(Array.isArray(ast.children)); // false
console.log(ast.children instanceof csstree.List); // true
ast = csstree.toPlainObject(ast);
console.log(Array.isArray(ast.children)); // true
console.log(ast.children instanceof csstree.List); // false
```
Function mutates the passed AST. Use `clone()` function before passing AST to `toPlainObject()` in case you want to avoid original tree mutation.
```js
ast = csstree.toPlainObject(csstree.clone(ast));
```