A CSS selector parser.
It parses any valid CSS3 selector into tokens. Try it!
Found a selector that cannot be parsed? Raise an issue.
This parser is implemented using Earley parser algorithm. Read about Writing a CSS selector parser in under 120 LoC.
Note:
This parser could be extended to support the entire CSS grammar. I don't have such a use case. However, should you want to add new grammar, raise an issue.
import {
createGenerator,
createParser
} from 'scalpel';
const generator = createGenerator();
const parser = createParser();
const tokens: Array<SelectorTokenType | CombinatorTokenType> = parser.parse('.foo.bar');
// [
// {
// type: 'selector',
// body: [
// {
// type: 'classSelector',
// name: 'foo'
// },
// {
// type: 'classSelector',
// name: 'bar'
// }
// ]
// }
// ]
const selector: string = generator.generate(token);
// .foo.bar
Note:
For programmatic type definitions, refer to
./src/types.js
.
Type | Description | Example |
---|---|---|
adjacentSiblingCombinator |
An adjacent sibling combinator. | .baz0 + .baz1 |
attributePresenceSelector |
An attribute presence selector. | [qux] |
attributeValueSelector |
An attribute value selector. | [qux=val] , [qux~=val] |
childCombinator |
A child combinator. | .baz0 > .baz1 |
classSelector |
A class selector. | .baz |
descendantCombinator |
A descendant combinator. | .baz0 .baz1 |
generalSiblingCombinator |
A general sibling combinator. | .baz0 ~ .baz1 |
idSelector |
An ID selector | #bar |
pseudoClassSelector |
A pseudo-class selector. | :corge , :corge() , :corge(val0, 'val1', "val2") |
pseudoElementSelector |
A pseudo-element selector. | ::grault |
typeSelector |
A type selector. | foo |
universalSelector |
A universal selector. | * |
Tokens have fields that describe additional information about the token. Fields are token type specific.
Name | Description | Example |
---|---|---|
type |
Name of the token type. | "adjacentSiblingCombinator" |
Name | Description | Example |
---|---|---|
name |
Name of the element attribute. | "qux" in [qux] |
type |
Name of the token type. | "attributePresenceSelector" |
Name | Description | Example |
---|---|---|
name |
Name of the element attribute. | "qux" in [qux] |
operator |
Operator of the expression. | "*=" in [qux*=val] |
type |
Name of the token type. | "attributeValueSelector" |
value |
Value of the expression. | "val" in [qux=val] |
Name | Description | Example |
---|---|---|
type |
Name of the token type. | "childCombinator" |
Name | Description | Example |
---|---|---|
name |
Class name. | "baz" in .baz[qux] |
type |
Name of the token type. | "classSelector" |
Name | Description | Example |
---|---|---|
type |
Name of the token type. | "descendantCombinator" |
Name | Description | Example |
---|---|---|
type |
Name of the token type. | "generalSiblingCombinator" |
Name | Description | Example |
---|---|---|
name |
Name of the ID. | "bar" in #bar:corge() |
type |
Name of the token type. | "idSelector" |
Name | Description | Example |
---|---|---|
name |
Name of the pseudo-class. | "corge" in #bar:corge() |
parameters |
Array of parameter values. | "var0", "var1" and "var2" in :corge(var0, 'var1', "var2") |
type |
Name of the token type. | "pseudoClassSelector" |
Name | Description | Example |
---|---|---|
name |
Name of the pseudo-element. | "grault" in #bar::grault |
type |
Name of the token type. | "pseudoElementSelector" |
Name | Description | Example |
---|---|---|
name |
Name of the node. | "foo" in foo#bar.baz |
type |
Name of the token type. | "typeSelector" |
Name | Description | Example |
---|---|---|
type |
Name of the token type. | "universalSelector" |
git pull git@github.com:gajus/scalpel.git
cd ./scalpel
npm install
npm run test
The parser grammar is in the ./src/grammar.ne
file. After making changes to the parser grammar, you need to compile the parser using npm run compile-grammar
command.