A tool set for CSS including fast detailed parser, walker, generator and lexer based on W3C specs and browser implementations
MIT License
Bot releases are visible (Hide)
Published by lahmatiy over 7 years ago
Parser
classstartOffset
option to Tokenizer
(constructor and setSource()
method)readSequenceFallback
) and selector (readSelectorSequenceFallback
) sequence readersAnPlusB
Selector
consumerPublished by lahmatiy over 7 years ago
atruleExpression
contextkeyword()
and property()
property()
to not lowercase custom property namesvariable
boolean flag in property()
resultscanner
into tokenizer
syntax
into lexer
docs/*.html
files to csstree/docs repoelement()
function for Value
context (-moz-element()
supported as well)Universal
node type into Type
Id
-> IdSelector
Class
-> ClassSelector
Type
-> TypeSelector
Attribute
-> AttributeSelector
PseudoClass
-> PseudoClassSelector
PseudoElement
-> PseudoElementSelector
Hash
-> HexColor
Space
-> WhiteSpace
An+B
-> AnPlusB
Progid
node typeMediaQuery
consumer to not validate syntax on parse and to include whitespaces in children sequence as isWhiteSpace.value
property to store whitespace sequencefalse
some part of CSS represents as balanced Raw
):
parseAtruleExpression
– to parse at-rule expressions (true
by default)parseSelector
– to parse rule's selector (true
by default)parseValue
– to parse declaration's value (true
by default)parseCustomProperty
– to parse value and fallback of custom property (false
by default)Published by lahmatiy over 7 years ago
DeclarationList
, MediaQueryList
, MediaQuery
, MediaFeature
and Ratio
node typesdeclarationList
context (useful to parse HTML style
attribute content)@import
, @media
, @page
and @supports
at-rulesatrule
option for parse()
config, is used for atruleExpession
context to specify custom consumer for at-rule if anyScanner#skipWS()
, Scanner#eatNonWS()
, Scanner#consume()
and Scanner#consumeNonWS()
helper methodsRaw
PseudoElement
to be a functional-pseudo (#33)Atrule.block
to contain a Block
node type only if anyBlock.loc
positions to include curly bracketsAtrule.expression
to store a null
if no expressionStyleSheet
node type only for top level node (when context is stylesheet
, that's by default)Parentheses
, Brackets
and Function
consumers to use passed sequence reader instead of its ownValue
and AtruleExpression
consumers to use common sequence reader (that reader was used by Value
consumer before)Comma
Raw
var()
fallback value as balanced Raw
var()
starts with double dashNth
to have a loc
propertySelectorList.loc
and Selector.loc
positions to exclude spacesdefault-syntax.json
is not found error (#32, @philschatz)Type
selector starting with dash (parser throws an error in this case now)Rule
(not sure if it's correct but looks reasonable)>>
combinator support until any browser support (no signals about that yet)PseudoElement.legacy
property:before
, :after
, :first-letter
and :first-line
to represent them as PseudoElement
, now those pseudos are represented as PseudoClass
nodesSyntax#match()
methodThe major change in this release is about splitting the parser. The earlier parser version was presented as a single module. Now it's a bunch of modules. It helped to simplify maintenance and readability. Moreover it leads to the parser extensibility, because splitting into modules requires another code structure.
The Parser
class was implemented as context for the parsing. It hosts all node type consumers as its own methods and this makes an access from one consumer to another one quite simple. Furthermore it allows redefinition and extension of the consumer set. In addition some known at-rules, functional-pseudos and functions may have their own consumers for their content. Currently CSSTree has several such consumers for complex cases like @supports
at-rule or :nth-child()
pseudo.
That's the first step towards for parser's extensibility. But we are surely going in this direction. Some things left to be done before exposing Parser
class in public API. However, this will happen in the future releases.
The good news is that changes almost didn't affect performance. Yep, some thing got more complicated and lower performance a little bit. But those changes are negligible. So parser became better and still as fast as before last changes.
CSSTree was added to AST Explorer. You can explore AST with zero setup now. 🎉
Published by lahmatiy over 7 years ago
SyntaxMatchError
mismatchOffset
offset
property to store bad node offset in source CSS if anyloc
property that stores bad node loc
if anyPublished by lahmatiy over 7 years ago
Syntax#matchProperty()
method to always return a positive result for custom properties since syntax is never defined for them (#31)fromPlainObject()
and toPlainObject()
to convert plain object to AST or AST to plain object (currently converts List
<-> Array
)Published by lahmatiy almost 8 years ago
Big refactoring, new syntax support, changes in nth
-pseudos format and the new way to store locations.
:matches(<selector-list>)
(#28):has(<relative-selector-list>)
::slotted(<compound-selector>)
Brackets
node typeSelector
node type to SelectorList
SimpleSelector
node type to Selector
UnicodeRange.name
property to UnicodeRange.value
Negation
node type for regular PseudoClass
children
now:
StyleSheet.rules
-> StyleSheet.children
SelectorList.selectors
-> SelectorList.children
Block.declarations
-> Block.children
*.sequence
-> *.children
Hex
and UnicodeRange
when number not an integernth-
pseudosAn+B
node type to represent expressions like 2n + 1
or -3n
a
or b
is not an integerodd
and even
keywords processing, keywords are storing as Identifier
node type nowNth
node type format to store a nth
-query and an optional selector
of
clause for nth-
pseudos (a.e. :nth-child(2n + 1 of li, img)
)Nth
parsing rules to :nth-child()
, :nth-last-child()
, :nth-of-type()
and :nth-last-of-type()
pseudosvar ast = csstree.parse(':nth-child(2n + 1 of li):nth-child(odd) {}');
console.log(JSON.stringify(ast.children[0].selector.children[0].children[0], null, 4));
// NOTE: loc properties are omitted to reduce output
// {
// "type": "PseudoClass",
// "name": "nth-child",
// "children": [
// {
// "type": "Nth",
// "nth": {
// "type": "An+B",
// "a": "2",
// "b": "1"
// },
// "selector": {
// "type": "SelectorList",
// "children": [
// {
// "type": "Selector",
// "children": [
// {
// "type": "Type",
// "name": "li"
// }
// ]
// }
// ]
// }
// }
// ]
// }
console.log(JSON.stringify(ast.children[0].selector.children[0].children[1], null, 4));
// NOTE: loc properties are omitted to reduce output
// {
// "type": "PseudoClass",
// "name": "nth-child",
// "children": [
// {
// "type": "Nth",
// "nth": {
// "type": "Identifier",
// "name": "odd"
// },
// "selector": null
// }
// ]
// }
info
node property to loc
loc
to store start
and end
positionsvar ast = csstree.parse('.foo {}', { positions: true });
console.log(JSON.stringify(ast, null, 4));
// {
// "type": "StyleSheet",
// "loc": {
// "source": "<unknown>",
// "start": {
// "offset": 0,
// "line": 1,
// "column": 1
// },
// "end": {
// "offset": 7,
// "line": 1,
// "column": 8
// }
// }
// "children": [ ... ]
// }
Published by lahmatiy almost 8 years ago
Scanner
to be a single point to its functionalityScanner
class to be useful for external projectswalk()
function behaviour to traverse AST nodes in natural orderwalkUp()
function to traverse AST nodes from deepest to parent (behaves as walk()
before)Published by lahmatiy almost 8 years ago
<angle>
generic according to specs that allow a <number>
equals to zero to be used as valid value (#30)Published by lahmatiy almost 8 years ago
Scanner#skip()
issue method when cursor is moving to the end of sourceProgid
node<id-selector>
generic syntaxq
unit for <length>
generic syntaxmdn/data
instead of Template:CSSData
syntax.stringify()
method to syntax.translate()
true
or false
var()
, those values are always valid for now98.5%
Published by lahmatiy about 8 years ago
>>
)Type
and Universal
type nodes to replace Identifier
in selectorsNumber
parsing by including sign and exponent (#26)before
, after
, first-letter
and first-line
pseudos with single colon as PseudoElement
FunctionalPseudo
node type to PseudoClass
eof
is reachedSyntax#getAll()
methodPublished by lahmatiy about 8 years ago
apple
specific font keywords (#20)Property
node structure from object to stringRuleset
node type to Rule
Argument
node typeDimension
and Percentage
position computationpositions:true
(even freeze)line
and column
computation for SyntaxMatch
error