4.0.2 (2026-04-13)
4.0.1 (2026-03-30)
4.0.0 (2026-03-23)
- Require Node.js ^20.19.0 || ^22.13.0 || >=24 (#121)
3.6.9 (2026-02-07)
- add support for
alpha()color function (#107) (b96f42b) - allow declarations inside nested
[@layer](https://github.com/layer)rules (#108) (a9a18dc) - correctly parse nested element selectors (#104) (82729c1)
3.6.8 (2025-11-21)
3.6.7 (2025-11-18)
- browser hack property parsing and invalid selector validation (#98) (2f5781c)
- nested element selector parsing in DeclarationList context (#85) (f6222c9)
3.6.6 (2025-10-02)
- add support for relative color values (#87) (486c559)
- allow relative color syntax for rgb() & rgba() (#80) (a08c7ab)
3.6.5 (2025-08-25)
3.6.4 (2025-08-17)
- Correct @font-feature-values nested at-rules structure (#69) (fb1c8e0)
- Increase iteration limit (#74) (8c4813d)
3.6.3 (2025-07-29)
3.6.2 (2025-07-21)
3.6.1 (2025-06-09)
- ParserContext to have all methods (e069f6f)
- ParserContext type to have all methods (#57) (e069f6f)
- Types for node generate() function (#56) (846120b)
3.6.0 (2025-06-05)
3.5.4 (2025-05-28)
3.5.3 (2025-05-23)
3.5.2 (2025-05-15)
3.5.1 (2025-05-08)
3.5.0 (2025-04-22)
3.4.0 (2025-04-16)
3.3.4 (2025-04-09)
- Remove outdated
anchor()&anchor-size()descriptor patch (afd673a) - Remove outdated
anchor()&anchor-size()function patch (#29) (afd673a) - Update mdn-data and patch (#32) (20b412f)
3.3.3 (2025-04-04)
- Add patch for <cubic-bezier-easing-function> (#28) (c4d6c44), closes #27
- Remove
srcdescriptor patch (#23) (e3d17f0) - Remove
unicode-rangedescriptor patch (#25) (2048240) - Remove outdated
@font-face/unicode-rangedescriptor patch (#26) (1ea54f7) - Remove wrong
scroll-timelineproperty patch (#22) (b142b20) - Remove wrong scroll-timeline property patch (b142b20)
3.3.2 (2025-03-29)
3.3.1 (2025-03-20)
3.3.0 (2025-03-18)
- add support for typed custom properties (0e9d141)
- Add support for typed custom properties (#11) (0e9d141)
- passthrough env in lexer syntax matching (c0e22c0)
- passthrough env() in lexer syntax matching (#12) (c0e22c0)
- Add parse.SyntaxError and parse.config types (#14) (d201786)
- Add types for onToken callback (#9) (b403ffb)
3.2.0 (2025-03-12)
- Added
onTokenoption to theparse()method, which can be either an array or a function:- When the value is an array, it is populated with objects
{ type, start, end }(token type, and its start and end offsets). - When the value is a function, it accepts
type,start,end, andindexparameters, and is invoked with a token API asthis, enabling advanced token handling (see onToken). For example, the following demonstrates checking if all block tokens have matching pairs:parse(css, { onToken(type, start, end, index) { if (this.isBlockOpenerTokenType(type)) { if (this.getBlockPairTokenIndex(index) === -1) { console.warn('No closing pair for', this.getTokenValue(index), this.getRangeLocation(start, end)); } } else if (this.isBlockCloserTokenType(type)) { if (this.getBlockPairTokenIndex(index) === -1) { console.warn('No opening pair for', this.getTokenValue(index), this.getRangeLocation(start, end)); } } } });
- When the value is an array, it is populated with objects
- Extended
TokenStreamwith the following methods:getTokenEnd(tokenIndex)– returns the token's end offset by index, complementinggetTokenStart(tokenIndex)getTokenType(tokenIndex)– returns the token's type by indexisBlockOpenerTokenType(tokenType)– returnstruefor<function-token>,<(-token>,<[-token>, and<{-token>isBlockCloserTokenType(tokenType)– returnstruefor<)-token>,<]-token>, and<}-token>getBlockTokenPairIndex(tokenIndex)– returns the index of the pair token for a block, or-1if no pair exists
- Fixed
fork()to extendnodedefinitions instead of overriding them. For example,fork({ node: { Dimension: { generate() { /* ... */ } } } })will now update only thegenerate()method on theDimensionnode, while inheriting all other properties from the previous syntax definition.
- Added support for boolean expression multiplier in syntax definition, i.e.
<boolean-expr[ test ]>(#304) - Added
source,startOffset,startLine, andstartColumnparameters toOffsetToLocationconstructor, eliminating the need to callsetSource()after creating a newOffsetToLocationinstance - Exposed
OffsetToLocationclass in the main entry point, which was previously accessible only viacss-tree/tokenizer - Fixed
Rawnode value consumption by ignoring stop tokens inside blocks, resolving an issue whereRawvalue consumption stopped prematurely. This fix also enables parsing of functions whose content includes stop characters (e.g., semicolons and curly braces) within declaration values, aligning with the latest draft of CSS Values and Units Module Level 5. - Fixed
TokenStream#balancecomputation to handle unmatched brackets correctly. Previously, when encountering a closing bracket, theTokenStreamwould prioritize it over unmatched opening brackets, leading to improper parsing. For example, the parser would incorrectly consume the declaration value of.a { prop: ([{); }as([{)instead of consuming it until all opened brackets were closed (([{); }). Now, unmatched closing brackets are discarded unless they match the most recent opening bracket on the stack. This change aligns CSSTree with CSS specifications and browser behavior. - Fixed syntax definition parser to allow a token to be followed by a multiplier (#303)
- Fixed location for
Layernode (#310) - Bumped
mdn/datato 2.12.2
- Bumped
mdn/datato 2.12.1 - Added
errorsarray to theLexer#validate()method result, providing details on problematic syntax. - Added CSS wide keyword customization and introspection:
- Added a
Lexer#cssWideKeywordsdictionary to list CSS-wide keywords - Updated the Lexer's constructor to consider
config.cssWideKeywordsfor overriding the default list - Expanded the lexer's dump output to include the
cssWideKeywordsdictionary - Modified the
fork()method to accept acssWideKeywordsoption, allowing the addition of new keywords to the existing list
- Added a
- Reverted changes to
Blockto include{and}, andAtruleandRuleto exclude{and}for ablock(#296) - Removed second parameter (
assign) for the callback in thefork()method (e.g.,syntax.fork((config, assign) => { ... })), as it simply refers toObject.assign() - Fixes in syntaxes:
<basic-shapes>,<absolute-color-function>and<'stroke-opacity'>
- Added support for the
@containerat-rule - Added support for the
@starting-styleat-rule - Added support for the
@scopeat-rule - Added support for the
@position-tryat-rule - Added support for the
@layerat-rule - Added support for
layer,layer()andsupports()in the@mediaat-rule (according to the @import rule in Cascading and Inheritance 5) - Added
LayerandLayerListnode types - Added
TokenStream#lookupTypeNonSC()method - Added
<dashed-ident>to generic types - Bumped
mdn/datato2.10.0 - Aligned
<'font'>to CSS Fonts 4 - Aligned
<color>to CSS Color 5 - Fixed initialization when
Object.prototypeis extended or polluted (#262) - Fixed
fork()method to consider thegenericoption when creating a Lexer instance (#266) - Fixed crash on parse error when custom
lineoroffsetis specified via options (#251) - Fixed
speaksyntax patch (#241) - Fixed
:lang()to accept a list of<ident>or<string>per spec (#265) - Fixed lexer matching for syntaxes referred to as
<'property'>, when the syntax has a top-level#-multiplier (#102) - Relaxed parsing of syntax definition to allow whitespaces in range multiplier (#270)
- Changed
parseWithFallback()to rollbacktokenIndexbefore calling a fallback - Changed
Blockto not include{and} - Changed
AtruleandRuleto include{and}for a block - Changed
Ratioparsing:- Left and right parts contain nodes instead of strings
- Both left and right parts of a ratio can now be any number; validation of number range is no longer within the parser's scope.
- Both parts can now be functions. Although not explicitly mentioned in the specification, mathematical functions can replace numbers, addressing potential use cases (#162).
- As per the CSS Values and Units Level 4 specification, the right part of
Ratiocan be omitted. While this can't be a parser output (which would produce aNumbernode), it's feasible duringRationode construction or transformation.
- Changes to query-related at-rules:
-
Added new node types:
Feature: represents features like(feature)and(feature: value), fundamental for both@mediaand@containerat-rulesFeatureRange: represents features in a range contextFeatureFunction: represents functional features such as@supports'sselector()or@container'sstyle()Condition: used across all query-like at-rules, encapsulating queries with features and thenot,and, andoroperatorsGeneralEnclosure: represents the<general-enclosed>production, which caters to unparsed parentheses or functional expressions
Note: All new nodes include a
kindproperty to define the at-rule type. Supported kinds aremedia,supports, andcontainer. -
Added support for functions for features and features in a range context, e.g.
(width: calc(100cm / 6)) -
Added a
conditionvalue for the parser's context option to parse queries. Use thekindoption to specify the condition type, e.g.,parse('...', { context: 'condition', kind: 'media' }). -
Introduced a
featuressection in the syntax configuration for defining functional features of at-rules. Expand definitions using thefork()method. The current definition is as follows:features: { supports: { selector() { /* ... */ } }, container: { style() { /* ... */ } } }
-
Changes for
@mediaat-rule:- Enhanced prelude parsing for complex queries. Parentheses with errors will be parsed as
GeneralEnclosed. - Added support for features in a range context, e.g.
(width > 100px)or(100px < height < 400px) - Transitioned from
MediaFeaturenode type to theFeaturenode type withkind: "media". - Changed
MediaQuerynode structure into the following form:type MediaQuery = { type: "MediaQuery"; modifier: string | null; // e.g. "not", "only", etc. mediaType: string | null; // e.g. "all", "screen", etc. condition: Condition | null; }
- Enhanced prelude parsing for complex queries. Parentheses with errors will be parsed as
-
Changes for
@supportsat-rule:- Enhanced prelude parsing for complex queries. Parentheses with errors will be parsed as
GeneralEnclosed. - Added support for features in a range context, e.g.
(width > 100px)or(100px < height < 400px) - Added
SupportsDeclarationnode type to encapsulate a declaration in a query, replacingParentheses. - Parsing now employs
ConditionorSupportsDeclarationnodes of kindsupportsinstead ofParentheses. - Added support for the
selector()feature via theFeatureFunctionnode (configured infeatures.supports.selector).
- Enhanced prelude parsing for complex queries. Parentheses with errors will be parsed as
-
- Added
:host,:host()and:host-context()pseudo class support (#216) - Fixed
generator,parseandparse-selectorentry points by adding missedNestedSelectornode type - Removed npm > 7 version requirement (#218)
- Added CSS Nesting support:
- Added
NestingSelectornode type for&(a nesting selector) in selectors - Added
@nestat-rule - Changed behaviour for
@mediainside aRuleto parse its block content as aDeclarationfirst - Changed
DeclarationListbehaviour to follow the rules forRule's block
- Added
- Added the dimension units introspection & customisation:
- Added
Lexer#unitsdictionary to provide unit groups (length,angle, etc.) used for matching - Changed Lexer's constructor to take into consideration
config.unitsto override default units - Extended lexer's dump to contain a units dictionary
- Added
- Bumped
mdn-datato2.0.30
- Fixed a regression added in
2.2.0for at-rule syntax matching when at-rule has no prelude
- Bumped
mdn-datato2.0.28 - Added support for CSS wide keywords
revertandrevert-layer - Dropped support for
expression()the same way as CSS wide keywords - Patched
background-clipproperty definition to match Backgrounds and Borders 4 (#190) - Patched
contentproperty definition to allowattr()(#201) - Fixed definition syntax matching when a comma is expected before a
<delim-token> - Fixed at-rule validation fail when no prelude is specified and its syntax allows an empty prelude, that's the case for
@pageat-rule (#191) - Added new units according to current state of CSS Values and Units 4:
rex,cap,rcap,rch,ic,ric,lh,rlh,vi,vb,sv*,lv*,dv* - Added container relative length units from CSS Containment 3:
cqw,cqh,cqi,cqb,cqmin,cqmax - Removed
vmunit (supposed to be an old IE versions supported this unit instead ofvmax) - Value definition syntax:
- Added support for stacked multipliers
+#and#?according to spec (#199) - Added parsing of a dimension in range definition notations, however, a validation for such ranges is not supported yet (#192)
- Changed parsing of range definition notation to not omitting
[-∞,∞]ranges
- Added support for stacked multipliers
- Bumped
mdn-datato2.0.27 - Added
modulefield topackage.json - Fixed minor issues in CommonJS version
- Fixed
css-tree/utilsexport (#181) - Added
css-tree/convertorexport - Added
css-tree/selector-parserexport (~27kb when bundled, #183) - Reduced bundle size:
css-tree/parser50kb -> 41kbcss-tree/generator46kb -> 23kb
- Renamed
syntaxesintotypesincss-tree/definition-syntax-data-patch - Added parsing support for
:is(),:-moz-any(),:-webkit-any()and:where()(#182, #184)
- Extended Node.js support to include
^10 - Fixed
generate()in safe mode to add a whitespace between<dimension-token>and<hash-token>, otherwise some values are broken in IE11, e.g.borderproperties (#173) - Removed allowance for
:for an attribute name onAttributeSelectorparsing as it does not meet the CSS specs (details)
- Fixed unintended whitespace on
generate()insafemode betweentype-selectorandid-selector(e.g.a#id). A regression was introduces in2.0.2since IE11 fails on values when<hash-token>goes after<ident-token>without a whitespace in the middle, e.g.1px solid#000. Thus, in one case, a space between the<ident-token>and the<hash-token>is required, and in the other, vice versa. Until a better solution found, a workaround is used onid-selectorgeneration by producing a<delim-token>instead of<hash-token>.
- Updated
width,min-widthandmax-widthsyntax definitions - Patched counter related syntaxes to match specs until updated in
mdn-data - Replaced
source-mapwithsource-map-jswhich reduce install size by ~700KB - Fixed
calc()function consumption on definition syntax matching - Fixed
generate()auto emitting a whitespace edge cases when next token starts with a dash (minus) - Fixed
generate()safe mode to cover more cases for IE11 - Fixed CommonJS bundling by adding browser files
dist/data.cjsanddist/version.cjs - Added exports:
css-tree/definition-syntax-datacss-tree/definition-syntax-data-patch
- Extended Node.js support to include
^12.20.0and^14.13.0versions
- Package
- Dropped support for Node.js prior 14.16 (following patch versions changed it to
^10 || ^12.20.0 || ^14.13.0 || >=15.0.0) - Converted to ES modules. However, CommonJS is supported as well (dual module)
- Added exports for standalone parts instead of internal paths usage (use as
import * as parser from "css-tree/parser"orrequire("css-tree/parser")):css-tree/tokenizercss-tree/parsercss-tree/walkercss-tree/generatorcss-tree/lexercss-tree/definition-syntaxcss-tree/utils
- Changed bundle set to provide
dist/csstree.js(an IIFE version withcsstreeas a global name) anddist/csstree.esm.js(as ES module). Both are minified - Bumped
mdn-datato2.0.23
- Dropped support for Node.js prior 14.16 (following patch versions changed it to
- Tokenizer
- Changed
tokenize()to take a function as second argument, which will be called for every token. No stream instance is creating when second argument is ommited. - Changed
TokenStream#getRawLength()to take second parameter as a function (rule) that check a char code to stop a scanning - Added
TokenStream#forEachToken(fn)method - Removed
TokenStream#skipWS()method - Removed
TokenStream#getTokenLength()method
- Changed
- Parser
- Moved
SyntaxError(custom parser's error class) from root of public API to parser viaparse.SyntaxError - Removed
parseErrorfield in parser'sSyntaxError - Changed selector parsing to produce
{ type: 'Combinator', name: ' ' }node instead ofWhiteSpacenode - Removed producing of
WhiteSpacenodes with the single exception for a custom property declaration with a single white space token as a value - Parser adds a whitespace to
+and-operators, when a whitespace is before and/or after an operator - Exposed parser's inner configuration as
parse.config - Added
consumeUntilBalanceEnd(),consumeUntilLeftCurlyBracket(),consumeUntilLeftCurlyBracketOrSemicolon(),consumeUntilExclamationMarkOrSemicolon()andconsumeUntilSemicolonIncluded()methods to parser's inner API to use withRawinstead ofRaw.mode - Changed
Nthto always consumeofclause when presented, so it became more general and moves validation to lexer - Changed
Stringnode type to store decoded string value, i.e. with no quotes and escape sequences - Changed
Urlnode type to store decoded url value as a string instead ofStringorRawnode, i.e. with no quotes, escape sequences andurl()wrapper
- Moved
- Generator
- Generator is now determines itself when a white space required between emitting tokens
- Changed
chunk()handler totoken()(output a single token) andtokenize()(split a string into tokens and output each of them) - Added
modeoption forgenerate()to specify a mode of token separation:specorsafe(by default) - Added
emit(token, type, auto)handler as implementation specific token processor - Changed
Nthto serialize+nasn - Added auto-encoding for a
stringandurltokens on serialization
- Lexer
- Removed
Lexer#matchDeclaration()method
- Removed
- Utils
- Added
ident,stringandurlhelpers to decode/encode corresponding values, e.g.url.decode('url("image.jpg")')==='image.jpg' - List
- Changed
Listto be iterable (iterates data) - Changed
List#first,List#lastandList#isEmptyto getters - Changed
List#getSize()method toList#sizegetter - Removed
List#each()andList#eachRight()methods,List#forEach()andList#forEachRight()should be used instead
- Changed
- Added
- Fixed matching on CSS wide keywords for at-rule's prelude and descriptors
- Added
fit-contenttowidthproperty patch as browsers are supported it as a keyword (nonstandard), but spec defines it as a function - Fixed parsing a value contains parentheses or brackets and
parseValueoption is set tofalse, in that case!importantwas included into a value but must not (#155)
- Rolled back to use spread syntax in object literals since it not supported by nodejs < 8.3 (#145)
- Fixed edge cases in mismatch location computation for
SyntaxMatchError
- Bumped
mdn-datato 2.0.14 - Extended
fork()method to allow append syntax instead of overriding fortypes,propertiesandatrules, e.g.csstree.fork({ types: { color: '| foo | bar' } }) - Extended lexer API for validation
- Added
Lexer#checkAtruleName(atruleName),Lexer#checkAtrulePrelude(atruleName, prelude),Lexer#checkAtruleDescriptorName(atruleName, descriptorName)andLexer#checkPropertyName(propertyName) - Added
Lexer#getAtrule(atruleName, fallbackBasename)method - Extended
Lexer#getAtrulePrelude()andLexer#getProperty()methods to takefallbackBasenameparameter - Improved
SyntaxMatchErrorlocation details - Changed error messages
- Added
- Fixed edge cases for parsing of custom property value with a single whitespace when
parseCustomProperty:true
- Added
onCommentoption to parser config - Added support for
breakandskipvalues inwalk()to control traversal - Added
List#reduce()andList#reduceRight()methods - Bumped
mdn-datato 2.0.12 - Exposed version of the lib (i.e.
import { version } from 'css-tree') - Fixed
Lexer#dump()to dump atrules syntaxes as well - Fixed matching comma separated
<urange>list (#135) - Renamed
HexColornode type intoHash - Removed
element()specific parsing rules - Removed
dist/default-syntax.jsonfrom package
- Fixed walker with
visit: "Declaration"to iterateDeclarationList(#114)
- Bumped
mdn-datato2.0.6 - Added initial implmentation for at-rule matching via
Lexer#matchAtrulePrelude()andLexer#matchAtruleDescriptor()methods - Added
-moz-control-character-visibility,-ms-grid-columns,-ms-grid-rowsand-ms-hyphenate-limit-lastproperties to patch (#111) - Added
flow,flow-rootandtable-captionvalues to patcheddisplay(#112)
- Bumped
source-mapversion to^0.6.1to fix source map generation inconsistency across node.js versions due to mappings sorting bug and v8 moving to a stable Array#sort (fix commit insource-map)
- Dropped support for Node < 8
- Updated dev deps (fixed
npm auditissues) - Reworked build pipeline
- Package provides
dist/csstree.jsanddist/csstree.min.jsnow (instead of singledist/csstree.jsthat was a min version) - Bundle size (min version) reduced from 191Kb to 158Kb due to some optimisations
- Package provides
- Definition syntax
- Renamed
grammarintodefinitionSyntax(named per spec) - Added
compactoption togenerate()method to avoid formatting (spaces) when possible
- Renamed
- Lexer
- Changed
dump()method to produce syntaxes in compact form by default
- Changed
- Walker
- Changed implementation to avoid runtime compilation due to CSP issues (see #91, #109)
- Added
find(),findLast()andfindAll()methods (e.g.csstree.find(ast, node => node.type === 'ClassSelector'))
- Tokenizer
- Added
isBOM()function - Added
charCodeCategory()function - Removed
firstCharOffset()function (useisBOM()instead) - Removed
CHARCODEdictionary - Removed
INPUT_STREAM_CODE*dictionaries
- Added
- Lexer
- Allowed comments in matching value (just ignore them like whitespaces)
- Increased iteration count in value matching from 10k up to 15k
- Fixed missed
debugger(#104)
- Lexer
- Fixed low priority productions matching by changing an approach for robust one (#103)
- Lexer
- Fixed low priority productions matching in long
||-and&&-groups (#103)
- Fixed low priority productions matching in long
- Bumped
mdn/datato2.0.4(#99) - Lexer
- Added bracketed range notation support and related refactoring
- Removed
<number-zero-one>,<number-one-or-greater>and<positive-integer>from generic types. In fact, types moved to patch, because those types can be expressed in a regular grammar due to bracketed range notation implemented - Added support for multiple token string matching
- Improved
<custom-ident>production matching to claim the keyword only if no other unfulfilled production can claim it (#101) - Improved
<length>production matching to claim "unitless zero" only if no other unfulfilled production can claim it - Changed lexer's constructor to prevent generic types override when used
- Fixed large
||- and&&-group matching, matching continues from the beginning on term match (#85) - Fixed checking that value has
var()occurrences when value is a string (such values can't be matched on syntax currently and fail with specific error that can be used for ignorance in validation tools) - Fixed
<declaration-value>and<any-value>matching when a value contains a function, parentheses or braces
- Bumped
mdn/datato~2.0.3- Removed type removals from
mdn/datadue to lack of some generic types and specific lexer restictions (since lexer was reworked, see below) - Reduced and updated patches
- Removed type removals from
- Tokenizer
- Reworked tokenizer itself to compliment CSS Syntax Module Level 3
Tokenizerclass splitted into several abstractions:- Added
TokenStreamclass - Added
OffsetToLocationclass - Added
tokenize()function that createsTokenStreaminstance for given string or updates aTokenStreaminstance passed as second parameter - Removed
Tokenizerclass
- Added
- Removed
Rawtoken type - Renamed
Identifiertoken type toIdent - Added token types:
Hash,BadString,BadUrl,Delim,Percentage,Dimension,Colon,Semicolon,Comma,LeftSquareBracket,RightSquareBracket,LeftParenthesis,RightParenthesis,LeftCurlyBracket,RightCurlyBracket - Replaced
PunctuatorwithDelimtoken type, that excludes specific characters with its own token type likeColon,Semicolonetc - Removed
findCommentEnd,findStringEnd,findDecimalNumberEnd,findNumberEnd,findEscapeEnd,findIdentifierEndandfindUrlRawEndhelper function - Removed
SYMBOL_TYPE,PUNCTUATIONandSTOP_URL_RAWdictionaries - Added
isDigit,isHexDigit,isUppercaseLetter,isLowercaseLetter,isLetter,isNonAscii,isNameStart,isName,isNonPrintable,isNewline,isWhiteSpace,isValidEscape,isIdentifierStart,isNumberStart,consumeEscaped,consumeName,consumeNumberandconsumeBadUrlRemnantshelper functions
- Parser
- Changed parsing algorithms to work with new token type set
- Changed
HexColorconsumption in way to relax checking a value, i.e. nowvalueis a sequence of one or more name chars - Added
&as a property hack - Relaxed
var()parsing to only check that a first arguments is an identifier (not a custom property name as before)
- Lexer
- Reworked syntax matching to relay on token set only (having AST is optional now)
- Extended
Lexer#match(),Lexer#matchType()andLexer#matchProperty()methods to take a string as value, beside AST as a value - Extended
Lexer#match()method to take a string as a syntax, beside of syntax descriptor - Reworked generic types:
- Removed
<attr()>,<url>(moved to patch) and<progid>types - Added types:
- Related to token types:
<ident-token>,<function-token>,<at-keyword-token>,<hash-token>,<string-token>,<bad-string-token>,<url-token>,<bad-url-token>,<delim-token>,<number-token>,<percentage-token>,<dimension-token>,<whitespace-token>,<CDO-token>,<CDC-token>,<colon-token>,<semicolon-token>,<comma-token>,<[-token>,<]-token>,<(-token>,<)-token>,<{-token>and<}-token> - Complex types:
<an-plus-b>,<urange>,<custom-property-name>,<declaration-value>,<any-value>and<zero>
- Related to token types:
- Renamed
<unicode-range>to<urange>as per spec - Renamed
<expression>(IE legacy extension) to<-ms-legacy-expression>and may to be removed in next releases
- Removed
- Lexer
- Syntax matching was completely reworked. Now it's token-based and uses state machine. Public API has not changed. However, some internal data structures have changed. Most significal change in syntax match result tree structure, it's became token-based instead of node-based.
- Grammar
- Changed grammar tree format:
- Added
Tokennode type to represent a single code point (<delim-token>) - Added
Multiplierthat wraps a single node (termproperty) - Added
AtKeywordto represent<at-keyword-token> - Removed
SlashandPercentnode types, they are replaced for a node withTokentype - Changed
Functionto represent<function-token>with no children - Removed
multiplierproperty fromGroup
- Added
- Changed
generate()method:- Method takes an
optionsas second argument now (generate(node, forceBraces, decorator)->generate(node, options)). Two options are supported:forceBracesanddecorator - When a second parameter is a function it treats as
decorateoption value, i.e.generate(node, fn)->generate(node, { decorate: fn }) - Decorate function invokes with additional parameter – a reference to a node
- Method takes an
- Changed grammar tree format:
- Tokenizer
- Renamed
Atruleconst toAtKeyword
- Renamed
- Renamed
lexer.grammar.translate()method intogenerate() - Fixed
<'-webkit-font-smoothing'>and<'-moz-osx-font-smoothing'>syntaxes (#75) - Added vendor keywords for
<'overflow'>property syntax (#76) - Pinned
mdn-datato~1.1.0and fixed issues with some updated property syntaxes
- Generator
- Changed node's
generate()methods invocation, methods now take a node as a single argument and context (i.e.this) that have methods:chunk(),node()andchildren() - Renamed
translate()togenerate()and changed to takeoptionsargument - Removed
translateMarkup(ast, enter, leave)method, usegenerate(ast, { decorator: (handlers) => { ... }})instead - Removed
translateWithSourceMap(ast), usegenerate(ast, { sourceMap: true })instead - Changed to support for children as an array
- Changed node's
- Walker
- Changed
walk()to take anoptionsargument instead of handler, withenter,leave,visitandreverseoptions (walk(ast, fn)is still works and equivalent towalk(ast, { enter: fn })) - Removed
walkUp(ast, fn), usewalk(ast, { leave: fn }) - Removed
walkRules(ast, fn), usewalk(ast, { visit: 'Rule', enter: fn })instead - Removed
walkRulesRight(ast, fn), usewalk(ast, { visit: 'Rule', reverse: true, enter: fn })instead - Removed
walkDeclarations(ast, fn), usewalk(ast, { visit: 'Declaration', enter: fn })instead - Changed to support for children as array in most cases (
reverse: truewill fail on arrays since they have noforEachRight()method)
- Changed
- Misc
- List
- Added
List#forEach()method - Added
List#forEachRight()method - Added
List#filter()method - Changed
List#map()method to return aListinstance instead ofArray - Added
List#push()method, similar toList#appendData()but returns nothing - Added
List#pop()method - Added
List#unshift()method, similar toList#prependData()but returns nothing - Added
List#shift()method - Added
List#prependList()method - Changed
List#insert(),List#insertData(),List#appendList()andList#insertList()methods to return a list that performed an operation
- Added
- Changed
keyword()method- Changed
namefield to include a vendor prefix - Added
basenamefield to contain a name without a vendor prefix - Added
customfield that contain atruewhen keyword is a custom property reference
- Changed
- Changed
property()method- Changed
namefield to include a vendor prefix - Added
basenamefield to contain a name without any prefixes, i.e. a hack and a vendor prefix
- Changed
- Added
vendorPrefix()method - Added
isCustomProperty()method
- List
- Tokenizer
- Added
Tokenizer#isBalanceEdge()method - Removed
Tokenizer.endsWith()method
- Added
- Parser
- Made the parser tolerant to errors by default
- Removed
tolerantparser option (no parsing modes anymore) - Removed
propertyparser option (a value parsing does not depend on property name anymore) - Canceled error for a handing semicolon in a block
- Canceled error for unclosed
Brackets,FunctionandParentheseswhen EOF is reached - Fixed error when prelude ends with a comment for at-rules with custom prelude consumer
- Relaxed at-rule parsing:
- Canceled error when EOF is reached after a prelude
- Canceled error for an at-rule with custom block consumer when at-rule has no block (just don't apply consumer in that case)
- Canceled error on at-rule parsing when it occurs outside prelude or block (at-rule is converting to
Rawnode) - Allowed for any at-rule to have a prelude and a block, even if it's invalid per at-rule syntax (the responsibility for this check is moved to lexer, since it's possible to construct a AST with such errors)
- Made a declaration value a safe parsing point (i.e. error on value parsing lead to a value is turning into
Rawnode, not a declaration as before) - Excluded surrounding white spaces and comments from a
Rawnode that represents a declaration value - Changed
Valueparse handler to return a node only with typeValue(previously it returned aRawnode in some cases) - Fixed issue with
onParseError()is not invoked for errors occured on selector or declaration value parsing in some cases - Changed using of
onParseError()to stop parsing if handler throws an exception
- Lexer
- Changed
grammar.walk()to invoke passed handler on entering to node rather than on leaving the node - Improved
grammar.walk()to take a walk handler pair as an object, i.e.walk(node, { enter: fn, leave: fn }) - Changed
Lexer#match*()methods to take a node of any type, but with achildrenfield - Added
Lexer#match(syntax, node)method - Fixed
Lexer#matchType()method to stop return a positive result for the CSS wide keywords
- Changed
- Parser
- Added fallback node as argument to
onParseError()handler - Fixed raw consuming in tolerant mode when selector is invalid (greedy consuming and redundant warnings)
- Fixed exception in tolerant mode caused by unknown at-rule with unclosed block
- Changed handling of semicolons:
- Hanging semicolon inside declaration blocks raise an error or turns into a
Rawnode in tolerant mode instead of being ignored - Semicolon outside of declaration blocks opens a
Rulenode as part of selector instead of being ignored
- Hanging semicolon inside declaration blocks raise an error or turns into a
- Aligned
parseAtrulePreludebehaviour toparseRulePrelude- Removed
Rawnode wraping intoAtrulePreludewhenparseAtrulePreludeis disabled - Removed error emitting when at-rule has a custom prelude customer but no prelude is found (it should be validated by a lexer later)
- Removed
- Added fallback node as argument to
- Generator
- Fixed performance issue with
translateWithSourceMap(), flattening the string (because of mixing building string and indexing into it) turned it into a quadratic algorithm (approximate numbers can be found in the quiz created by this case)
- Fixed performance issue with
- Added support for a single solidus hack for
property() - Minor fixes for custom errors
- Improved CSSTree to be stable for standart build-in objects extension (#58)
- Parser
- Renamed rule's
selectortoprelude. The reasons: spec names this part so, and this branch can contain not only a selector (SelectorList) but also a raw payload (Raw). What's changed:- Renamed
Rule.selectortoRule.prelude - Renamed
parseSelectorparser option toparseRulePrelude - Removed option for selector parse in
SelectorList
- Renamed
- Renamed rule's
- Lexer
- Fixed undefined positions in a error when match a syntax to empty or white space only value
- Improved
Lexer#checkStructure()- Return a warning as an object with node reference and message
- No exception on unknown node type, return a warning instead
- Fixed
Tokenizer#getRawLength()'s false positive balance match to the end of input in some cases (#56) - Rename walker's entry point methods to be the same as CSSTree exposed methods (i.e.
walk(),walkUp()etc) - Rename at-rule's
expressiontoprelude(since spec names it so)AtruleExpressionnode type →AtrulePreludeAtrule.expressionfield →Atrule.preludeparseAtruleExpressionparser's option →parseAtrulePreludeatruleExpressionparse context →atrulePreludeatruleExpressionwalk context reference →atrulePrelude
- Parser
- Fixed exception on parsing of unclosed
{}-blockin tolerant mode - Added tolerant mode support for
DeclarationList - Added standalone entry point, i.e. default parser can be used via
require('css-tree/lib/parser')(#47)
- Fixed exception on parsing of unclosed
- Generator
- Changed generator to produce
+nwhenAnPlusB.ais+1to be "round-trip" with parser - Added standalone entry point, i.e. default generators can be used via
require('css-tree/lib/generator')
- Changed generator to produce
- Walker
- Added standalone entry point, i.e. default walkers can be used via
require('css-tree/lib/walker')(#47)
- Added standalone entry point, i.e. default walkers can be used via
- Lexer
- Added
defaultkeyword to the list of invalid values for<custom-ident>(since it reversed per spec)
- Added
- Convertors (
toPlainObject()andfromPlainObject()) moved tolib/convertor(entry point isrequire('css-tree/lib/convertor'))
- Tokenizer
- Added
Rawtoken type - Improved tokenization of
url()with raw as url to be more spec complient - Added
Tokenizer#balancearray computation on token layout - Added
Tokenizer#getRawLength()to compute a raw length with respect of block balance - Added
Tokenizer#getTokenStart(offset)method to get token start offset by token index - Added
idxandbalancefields to each token ofTokenizer#dump()method result
- Added
- Parser
- Added
onParseErroroption - Reworked node parsers that consume a
Rawnode to use a new approach. Since now aRawnode builds inparser#Raw()function only - Changed semantic of
parser#Raw(), it takes 5 parameters now (it might to be changed in future) - Changed
parser#tolerantParse()to pass a start token index to fallback function instead of source offset - Fixed
AtruleExpressionconsuming in tolerant mode - Atrule handler to convert an empty
AtruleExpressionnode intonull - Changed
AtruleExpressionhandler to always return a node (before it could return anullin some cases)
- Added
- Lexer
- Fixed comma match node for
#multiplier - Added reference name to
SyntaxReferenceError
- Fixed comma match node for
- Additional fixes on custom errors
- Reduced possible corruption of base config by
syntax.fork()
- Tokenizer
- Added
Atruletoken type (<at-rule-token>per spec) - Added
Functiontoken type (<function-token>per spec) - Added
Urltoken type - Replaced
Tokenizer#getTypes()method withTokenizer#dump()to get all tokens as an array - Renamed
Tokenizer.TYPE.WhitespacetoTokenizer.TYPE.WhiteSpace - Renamed
Tokenizer.findWhitespaceEnd()toTokenizer.findWhiteSpaceEnd()
- Added
- Parser
- Added initial implementation of tollerant mode (turn on by passing
tolerant: trueoption). In this mode parse errors are never occour and any invalid part of CSS turns into aRawnode. Current safe points:Atrule,AtruleExpression,Rule,SelectorandDeclaration. Feature is experimental and further improvements are planned. - Changed
Atrule.expressionto contain aAtruleExpressionnode ornullonly (other node types is wrapping into aAtruleExpressionnode) - Renamed
AttributeSelector.operatortoAttributeSelector.matcher
- Added initial implementation of tollerant mode (turn on by passing
- Generator
translate()method is now can take a function as second argument, that recieves every generated chunk. When no function is passed, default handler is used, it concats all the chunks and method returns a string.
- Lexer
- Used mdn/data package as source of lexer's grammar instead of local dictionaries
- Added
xunit to<resolution>generic type - Improved match tree:
- Omited Group (sequences) match nodes
- Omited empty match nodes (for terms with
zero or moremultipliers) - Added
ASTNodenode type to contain a reference to AST node - Fixed node duplication (uncompleted match were added to tree)
- Added AST node reference in match nodes
- Added comma match node by
#multiplier
- Grammar
- Changed
translate()function to get a handler as third argument (optional). That handler recieves result of node traslation and can be used for decoration purposes. See example - Added
SyntaxParseErrorto grammar export - Reworked group and multipliers representation in syntax tree:
- Replaced
SequenceforGroupnode type (Sequencenode type removed) - Added
explicitboolean property forGroup - Only groups can have a multiplier now (other node types is wrapping into a single term implicit group when multiplier is applied)
- Renamed
nonEmptyGroup's property todisallowEmpty - Added optimisation for syntax tree by dropping redundant root
Groupwhen it contains a singleGroupterm (return thisGroupas a result)
- Replaced
- Changed
- Changed lexer's match functionality
- Changed
Lexer#matchProperty()andLexer#matchType()to return an object instead of match tree. A match tree stores inmatchedfield when AST is matched to grammar successfully, otherwise an error inerrorfield. The result object also has some methods to test AST node against a match tree:getTrace(),isType(),isProperty()andisKeyword() - Added
Lexer#matchDeclaration()method - Removed
Lexer#lastMatchError(error stores in match result object inerrorfield)
- Changed
- Added initial implementation of search for AST segments (new lexer methods:
Lexer#findValueSegments(),Lexer#findDeclarationValueSegments()andLexer#findAllSegments) - Implemented
SyntaxReferenceErrorfor unknown property and type references
- Renamed field in resulting object of
property()function:variable→custom - Fixed issue with readonly properties (e.g.
lineandcolumn) ofErrorand exception on attempt to write in iOS Safari
- Extended
Listclass with new methods:List#prepend(item)List#prependData(data)List#insertData(data)List#insertList(list)List#replace(item, itemOrList)
- Added
atrulewalk context (#39) - Changed a result of generate method for
AnPlusB,AttributeSelector,Function,MediaFeatureandRatio(1e95877) - Fixed typo in
Listexception messages (@strarsis, #42) - Improved tokenizer to convert an input to a string
- Implemented new concept of
syntax- Changed main
exportsto expose a default syntax - Defined initial CSS syntax
- Implemented
createSyntax()method to create a new syntax from scratch - Implemented
fork()method to create a new syntax based on given via extension
- Changed main
- Parser
- Implemented
mediaQueryListandmediaQueryparsing contexts - Implemented
CDOandCDCnode types - Implemented additional declaration property prefix hacks (
#and+) - Added support for UTF-16LE BOM
- Added support for
@font-faceat-rule - Added
chroma()to legacy IE filter functions - Improved
HexColorto consume hex only - Improved support for
\0and\9hacks (#2) - Relaxed number check for
Ratioterms- Allowed fractal values as a
Ratioterm - Disallowed zero number as a
Ratioterm
- Allowed fractal values as a
- Changed important clause parsing
- Allowed any identifier for important (to support hacks like
!ie) - Store
trueforimportantfield in case identifier equals toimportantand string otherwise
- Allowed any identifier for important (to support hacks like
- Fixed parse error formatted message rendering to take into account tabs
- Removed exposing of
Parserclass - Removed
readSelectorSequence(),readSequenceFallback()andreadSelectorSequenceFallbackmethods - Used single universal sequence consumer for
AtruleExpression,SelectorandValue
- Implemented
- Generator
- Reworked generator to use auto-generated functions based on syntax definition (additional work to be done in next releases)
- Implemented
translateMarkup(ast, before, after)method for complex cases - Reworked
translateWithSourceMapto be more flexible (based ontranslateMarkup, additional work to be done in next releases)
- Walker
- Reworked walker to use auto-generated function based on syntax definition (additional work to be done in next releases)
- Lexer
- Prepared for better extensibility (additional work to be done in next releases)
- Implemented
checkStructure(ast)method to check AST structure based on syntax definition - Update syntax dictionaries to latest
mdn/data- Add missing
<'offset-position'>syntax - Extended
<position>property with-webkit-sticky(@sergejmueller, #37)
- Add missing
- Improved mismatch error position
- Implemented script (
gen:syntax) to generate AST format reference page (docs/ast.md) using syntax definition
- Exposed
Parserclass - Added
startOffsetoption toTokenizer(constructor andsetSource()method) - Added fallback functions for default (
readSequenceFallback) and selector (readSelectorSequenceFallback) sequence readers - Fixed edge cases for
AnPlusB - Fixed wrong whitespace ignoring in
Selectorconsumer
- Fixed broken
atruleExpressioncontext - Fixed vendor prefix detection in
keyword()andproperty() - Fixed
property()to not lowercase custom property names - Added
variableboolean flag inproperty()result - Renamed
scannerintotokenizer - Ranamed
syntaxintolexer - Moved
docs/*.htmlfiles to csstree/docs repo - Added
element()function forValuecontext (-moz-element()supported as well) - Merged
Universalnode type intoType - Renamed node types:
Id->IdSelectorClass->ClassSelectorType->TypeSelectorAttribute->AttributeSelectorPseudoClass->PseudoClassSelectorPseudoElement->PseudoElementSelectorHash->HexColorSpace->WhiteSpaceAn+B->AnPlusB
- Removed
Progidnode type - Relaxed
MediaQueryconsumer to not validate syntax on parse and to include whitespaces in children sequence as is - Added
WhiteSpace.valueproperty to store whitespace sequence - Implemented parser options to specify what should be parsed in details (when option is
falsesome part of CSS represents as balancedRaw):parseAtruleExpression– to parse at-rule expressions (trueby default)parseSelector– to parse rule's selector (trueby default)parseValue- to parse declaration's value (trueby default)parseCustomProperty– to parse value and fallback of custom property (falseby default)
- Changed tokenization to stick leading hyphen minus to identifier token
- Changed selector parsing:
- Don't convert spaces into descendant combinator
- Don't validate selector structure on parsing (selectors may be checked by lexer later)
- Initial refactoring of docs
- Various improvements and fixes
- Implemented
DeclarationList,MediaQueryList,MediaQuery,MediaFeatureandRationode types - Implemented
declarationListcontext (useful to parse HTMLstyleattribute content) - Implemented custom consumers for
@import,@media,@pageand@supportsat-rules - Implemented
atruleoption forparse()config, is used foratruleExpessioncontext to specify custom consumer for at-rule if any - Added
Scanner#skipWS(),Scanner#eatNonWS(),Scanner#consume()andScanner#consumeNonWS()helper methods - Added custom consumers for known functional-pseudos, consume unknown functional-pseudo content as balanced
Raw - Allowed any
PseudoElementto be a functional-pseudo (#33) - Improved walker implementations to reduce GC thrashing by reusing cursors
- Changed
Atrule.blockto contain aBlocknode type only if any - Changed
Block.locpositions to include curly brackets - Changed
Atrule.expressionto store anullif no expression - Changed parser to use
StyleSheetnode type only for top level node (when context isstylesheet, that's by default) - Changed
Parentheses,BracketsandFunctionconsumers to use passed sequence reader instead of its own - Changed
ValueandAtruleExpressionconsumers to use common sequence reader (that reader was used byValueconsumer before) - Changed default sequence reader to exclude storage of spaces around
Comma - Changed processing of custom properties:
- Consume declaration value as balanced
Raw - Consume
var()fallback value as balancedRaw - Validate first argument of
var()starts with double dash - Custom property's value and fallback includes spaces around
- Consume declaration value as balanced
- Fixed
Nthto have alocproperty - Fixed
SelectorList.locandSelector.locpositions to exclude spaces - Fixed issue Browserify build fail with
default-syntax.jsonis not found error (#32, @philschatz) - Disallowed
Typeselector starting with dash (parser throws an error in this case now) - Disallowed empty selectors for
Rule(not sure if it's correct but looks reasonable) - Removed
>>combinator support until any browser support (no signals about that yet) - Removed
PseudoElement.legacyproperty - Removed special case for
:before,:after,:first-letterand:first-lineto represent them asPseudoElement, now those pseudos are represented asPseudoClassnodes - Removed deprecated
Syntax#match()method - Parser was splitted into modules and related changes, one step closer to an extensible parser
- Various fixes and improvements, all changes have negligible impact on performance
- Changed location storing in
SyntaxMatchError- Changed property to store mismatch offset to
mismatchOffset - Changed
offsetproperty to store bad node offset in source CSS if any - Added
locproperty that stores bad nodelocif any
- Changed property to store mismatch offset to
- Fixed
Syntax#matchProperty()method to always return a positive result for custom properties since syntax is never defined for them (#31) - Implemented
fromPlainObject()andtoPlainObject()to convert plain object to AST or AST to plain object (currently convertsList<->Array)
- Added support for
:matches(<selector-list>)(#28) - Added support for
:has(<relative-selector-list>) - Added support for
::slotted(<compound-selector>) - Implemented
Bracketsnode type - Implemented basic support for at-rule inside rule block (#24)
- Renamed
Selectornode type toSelectorList - Renamed
SimpleSelectornode type toSelector - Renamed
UnicodeRange.nameproperty toUnicodeRange.value - Replaced
Negationnode type for regularPseudoClass - Unified name of node property to store nested nodes, it always
childrennow:StyleSheet.rules->StyleSheet.childrenSelectorList.selectors->SelectorList.childrenBlock.declarations->Block.children*.sequence->*.children
- Fixed edge cases in parsing
HexandUnicodeRangewhen number not an integer - Changed
nth-pseudos parsing- Implemented
An+Bnode type to represent expressions like2n + 1or-3n - Fixed edge cases when
aorbis not an integer - Changed
oddandevenkeywords processing, keywords are storing asIdentifiernode type now - Changed
Nthnode type format to store anth-query and an optionalselector - Implemented
ofclause fornth-pseudos (a.e.:nth-child(2n + 1 of li, img)) - Limited
Nthparsing rules to:nth-child(),:nth-last-child(),:nth-of-type()and:nth-last-of-type()pseudos
- Implemented
- Changed the way to store locations
- Renamed
infonode property toloc - Changed format of
locto storestartandendpositions
- Renamed
- Reworked
Scannerto be a single point to its functionality - Exposed
Scannerclass to be useful for external projects - Changed
walk()function behaviour to traverse AST nodes in natural order - Implemented
walkUp()function to traverse AST nodes from deepest to parent (behaves aswalk()before)
- Fixed
<angle>generic according to specs that allow a<number>equals to zero to be used as valid value (#30)
- Fixed
Scanner#skip()issue method when cursor is moving to the end of source - Simplified
Progidnode - Changed behaviour for bad selector processing, now parsing fails instead of selector ignoring
- Fixed
<id-selector>generic syntax - Added
qunit for<length>generic syntax - Refactored syntax parser (performance)
- Reduced startup time by implementing lazy syntax parsing (default syntax doesn't parse on module load)
- Updated syntax dictionaries and used
mdn/datainstead ofTemplate:CSSData - Renamed
syntax.stringify()method tosyntax.translate() - Simplified generic syntax functions, those functions receive a single AST node for checking and should return
trueorfalse - Added exception for values that contains
var(), those values are always valid for now - Added more tests and increase code coverage to
98.5%
- Added support for explicit descendant combinator (
>>) - Implemented
TypeandUniversaltype nodes - Improved
Numberparsing by including sign and exponent (#26) - Parse
before,after,first-letterandfirst-linepseudos with single colon asPseudoElement - Changed
FunctionalPseudonode type toPseudoClass - Fixed attribute selector name parsing (namespace edge cases)
- Fixed location calculation for specified offset when
eofis reached - Added more non-standard colors (#25)
- Removed obsolete
Syntax#getAll()method - Fixed various edge cases, code clean up and performance improvements
- More accurate positions for syntax mismatch errors
- Added
applespecific font keywords (#20) - Changed
Propertynode stucture from object to string - Renamed
Rulesetnode type toRule - Removed
Argumentnode type - Fixed
DimensionandPercentageposition computation - Fixed bad selector parsing (temporary solution)
- Fixed location computation for CSS with very long lines that may lead to really long parsing with
positions:true(even freeze) - Fixed
lineandcolumncomputation forSyntaxMatcherror - Improved performance of parsing and translation. Now CSSTree is under 10ms in PostCSS benchmark.