source-map version to ^0.6.1 to fix source map generation inconsistency across node.js versions due to mappings sorting bug and v8 moving to a stable Array#sort (fix commit in source-map)npm audit issues)dist/csstree.js and dist/csstree.min.js now (instead of single dist/csstree.js that was a min version)grammar into definitionSyntax (named per spec)compact option to generate() method to avoid formatting (spaces) when possibledump() method to produce syntaxes in compact form by defaultisBOM() functioncharCodeCategory() functionfirstCharOffset() function (use isBOM() instead)CHARCODE dictionaryINPUT_STREAM_CODE* dictionariesdebugger (#104)||- and &&- groups (#103)mdn/data to 2.0.4 (#99)<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<custom-ident> production matching to claim the keyword only if no other unfulfilled production can claim it (#101)<length> production matching to claim "unitless zero" only if no other unfulfilled production can claim it||- and &&-group matching, matching continues from the beginning on term match (#85)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)<declaration-value> and <any-value> matching when a value contains a function, parentheses or bracesmdn/data to ~2.0.3
mdn/data due to lack of some generic types and specific lexer restictions (since lexer was reworked, see below)Tokenizer class splitted into several abstractions:
TokenStream classOffsetToLocation classtokenize() function that creates TokenStream instance for given string or updates a TokenStream instance passed as second parameterTokenizer classRaw token typeIdentifier token type to IdentHash, BadString, BadUrl, Delim, Percentage, Dimension, Colon, Semicolon, Comma, LeftSquareBracket, RightSquareBracket, LeftParenthesis, RightParenthesis, LeftCurlyBracket, RightCurlyBracketPunctuator with Delim token type, that excludes specific characters with its own token type like Colon, Semicolon etcfindCommentEnd, findStringEnd, findDecimalNumberEnd, findNumberEnd, findEscapeEnd, findIdentifierEnd and findUrlRawEnd helper functionSYMBOL_TYPE, PUNCTUATION and STOP_URL_RAW dictionariesisDigit, isHexDigit, isUppercaseLetter, isLowercaseLetter, isLetter, isNonAscii, isNameStart, isName, isNonPrintable, isNewline, isWhiteSpace, isValidEscape, isIdentifierStart, isNumberStart, consumeEscaped, consumeName, consumeNumber and consumeBadUrlRemnants helper functionsHexColor consumption in way to relax checking a value, i.e. now value is a sequence of one or more name chars& as a property hackvar() parsing to only check that a first arguments is an identifier (not a custom property name as before)Lexer#match(), Lexer#matchType() and Lexer#matchProperty() methods to take a string as value, beside AST as a valueLexer#match() method to take a string as a syntax, beside of syntax descriptor<attr()>, <url> (moved to patch) and <progid> 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><an-plus-b>, <urange>, <custom-property-name>, <declaration-value>, <any-value> and <zero><unicode-range> to <urange> as per spec<expression> (IE legacy extension) to <-ms-legacy-expression> and may to be removed in next releasesToken node type to represent a single code point (<delim-token>)Multiplier that wraps a single node (term property)AtKeyword to represent <at-keyword-token>Slash and Percent node types, they are replaced for a node with Token typeFunction to represent <function-token> with no childrenmultiplier property from Groupgenerate() method:
options as second argument now (generate(node, forceBraces, decorator) -> generate(node, options)). Two options are supported: forceBraces and decoratordecorate option value, i.e. generate(node, fn) -> generate(node, { decorate: fn })Atrule const to AtKeywordlexer.grammar.translate() method into generate()<'-webkit-font-smoothing'> and <'-moz-osx-font-smoothing'> syntaxes (#75)<'overflow'> property syntax (#76)mdn-data to ~1.1.0 and fixed issues with some updated property syntaxesgenerate() methods invocation, methods now take a node as a single argument and context (i.e. this) that have methods: chunk(), node() and children()translate() to generate() and changed to take options argumenttranslateMarkup(ast, enter, leave) method, use generate(ast, { decorator: (handlers) => { ... }}) insteadtranslateWithSourceMap(ast), use generate(ast, { sourceMap: true }) insteadwalk() to take an options argument instead of handler, with enter, leave, visit and reverse options (walk(ast, fn) is still works and equivalent to walk(ast, { enter: fn }))walkUp(ast, fn), use walk(ast, { leave: fn })walkRules(ast, fn), use walk(ast, { visit: 'Rule', enter: fn }) insteadwalkRulesRight(ast, fn), use walk(ast, { visit: 'Rule', reverse: true, enter: fn }) insteadwalkDeclarations(ast, fn), use walk(ast, { visit: 'Declaration', enter: fn }) insteadreverse: true will fail on arrays since they have no forEachRight() method)List#forEach() methodList#forEachRight() methodList#filter() methodList#map() method to return a List instance instead of ArrayList#push() method, similar to List#appendData() but returns nothingList#pop() methodList#unshift() method, similar to List#prependData() but returns nothingList#shift() methodList#prependList() methodList#insert(), List#insertData(), List#appendList() and List#insertList() methods to return a list that performed an operationkeyword() method
name field to include a vendor prefixbasename field to contain a name without a vendor prefixcustom field that contain a true when keyword is a custom property referenceproperty() method
name field to include a vendor prefixbasename field to contain a name without any prefixes, i.e. a hack and a vendor prefixvendorPrefix() methodisCustomProperty() methodTokenizer#isBalanceEdge() methodTokenizer.endsWith() methodtolerant parser option (no parsing modes anymore)property parser option (a value parsing does not depend on property name anymore)Brackets, Function and Parentheses when EOF is reachedRaw node)Raw node, not a declaration as before)Raw node that represents a declaration valueValue parse handler to return a node only with type Value (previously it returned a Raw node in some cases)onParseError() is not invoked for errors occured on selector or declaration value parsing in some casesonParseError() to stop parsing if handler throws an exceptiongrammar.walk() to invoke passed handler on entering to node rather than on leaving the nodegrammar.walk() to take a walk handler pair as an object, i.e. walk(node, { enter: fn, leave: fn })Lexer#match*() methods to take a node of any type, but with a children fieldLexer#match(syntax, node) methodLexer#matchType() method to stop return a positive result for the CSS wide keywordsonParseError() handlerRaw node in tolerant mode instead of being ignoredRule node as part of selector instead of being ignoredparseAtrulePrelude behaviour to parseRulePrelude
Raw node wraping into AtrulePrelude when parseAtrulePrelude is disabledtranslateWithSourceMap(), 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)property()selector to prelude. 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:
Rule.selector to Rule.preludeparseSelector parser option to parseRulePreludeSelectorListLexer#checkStructure()
Tokenizer#getRawLength()'s false positive balance match to the end of input in some cases (#56)walk(), walkUp() etc)expression to prelude (since spec names it so)
AtruleExpression node type → AtrulePreludeAtrule.expression field → Atrule.preludeparseAtruleExpression parser's option → parseAtrulePreludeatruleExpression parse context → atrulePreludeatruleExpression walk context reference → atrulePrelude{}-block in tolerant modeDeclarationListrequire('css-tree/lib/parser') (#47)+n when AnPlusB.a is +1 to be "round-trip" with parserrequire('css-tree/lib/generator')require('css-tree/lib/walker') (#47)default keyword to the list of invalid values for <custom-ident> (since it reversed per spec)toPlainObject() and fromPlainObject()) moved to lib/convertor (entry point is require('css-tree/lib/convertor'))Raw token typeurl() with raw as url to be more spec complientTokenizer#balance array computation on token layoutTokenizer#getRawLength() to compute a raw length with respect of block balanceTokenizer#getTokenStart(offset) method to get token start offset by token indexidx and balance fields to each token of Tokenizer#dump() method resultonParseError optionRaw node to use a new approach. Since now a Raw node builds in parser#Raw() function onlyparser#Raw(), it takes 5 parameters now (it might to be changed in future)parser#tolerantParse() to pass a start token index to fallback function instead of source offsetAtruleExpression consuming in tolerant modeAtruleExpression node into nullAtruleExpression handler to always return a node (before it could return a null in some cases)# multiplierSyntaxReferenceErrorsyntax.fork()Atrule token type (<at-rule-token> per spec)Function token type (<function-token> per spec)Url token typeTokenizer#getTypes() method with Tokenizer#dump() to get all tokens as an arrayTokenizer.TYPE.Whitespace to Tokenizer.TYPE.WhiteSpaceTokenizer.findWhitespaceEnd() to Tokenizer.findWhiteSpaceEnd()tolerant: true option). In this mode parse errors are never occour and any invalid part of CSS turns into a Raw node. Current safe points: Atrule, AtruleExpression, Rule, Selector and Declaration. Feature is experimental and further improvements are planned.Atrule.expression to contain a AtruleExpression node or null only (other node types is wrapping into a AtruleExpression node)AttributeSelector.operator to AttributeSelector.matchertranslate() 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.x unit to <resolution> generic typezero or more multipliers)ASTNode node type to contain a reference to AST node# multipliertranslate() function to get a handler as third argument (optional). That handler recieves result of node traslation and can be used for decoration purposes. See exampleSyntaxParseError to grammar exportSequence for Group node type (Sequence node type removed)explicit boolean property for GroupnonEmpty Group's property to disallowEmptyGroup when it contains a single Group term (return this Group as a result)Lexer#matchProperty() and Lexer#matchType() to return an object instead of match tree. A match tree stores in matched field when AST is matched to grammar successfully, otherwise an error in error field. The result object also has some methods to test AST node against a match tree: getTrace(), isType(), isProperty() and isKeyword()Lexer#matchDeclaration() methodLexer#lastMatchError (error stores in match result object in error field)Lexer#findValueSegments(), Lexer#findDeclarationValueSegments() and Lexer#findAllSegments)SyntaxReferenceError for unknown property and type referencesproperty() function: variable → customline and column) of Error and exception on attempt to write in iOS SafariList class with new methods:
List#prepend(item)List#prependData(data)List#insertData(data)List#insertList(list)List#replace(item, itemOrList)atrule walk context (#39)AnPlusB, AttributeSelector, Function, MediaFeature and Ratio (1e95877)List exception messages (@strarsis, #42)syntax
exports to expose a default syntaxcreateSyntax() method to create a new syntax from scratchfork() method to create a new syntax based on given via extensionmediaQueryList and mediaQuery parsing contextsCDO and CDC node types# and +)@font-face at-rulechroma() to legacy IE filter functionsHexColor to consume hex only\0 and \9 hacks (#2)Ratio terms
Ratio termRatio term!ie)true for important field in case identifier equals to important and string otherwiseParser classreadSelectorSequence(), readSequenceFallback() and readSelectorSequenceFallback methodsAtruleExpression, Selector and ValuetranslateMarkup(ast, before, after) method for complex casestranslateWithSourceMap to be more flexible (based on translateMarkup, additional work to be done in next releases)checkStructure(ast) method to check AST structure based on syntax definitionmdn/data
<'offset-position'> syntax<position> property with -webkit-sticky (@sergejmueller, #37)gen:syntax) to generate AST format reference page (docs/ast.md) using syntax definitionParser classstartOffset option to Tokenizer (constructor and setSource() method)readSequenceFallback) and selector (readSelectorSequenceFallback) sequence readersAnPlusBSelector consumeratruleExpression contextkeyword() and property()property() to not lowercase custom property namesvariable boolean flag in property() resultscanner into tokenizersyntax into lexerdocs/*.html files to csstree/docs repoelement() function for Value context (-moz-element() supported as well)Universal node type into TypeId -> IdSelectorClass -> ClassSelectorType -> TypeSelectorAttribute -> AttributeSelectorPseudoClass -> PseudoClassSelectorPseudoElement -> PseudoElementSelectorHash -> HexColorSpace -> WhiteSpaceAn+B -> AnPlusBProgid 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)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 methodsRawPseudoElement 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)CommaRawvar() fallback value as balanced Rawvar() 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() methodSyntaxMatchError
mismatchOffsetoffset property to store bad node offset in source CSS if anyloc property that stores bad node loc if anySyntax#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):matches(<selector-list>) (#28):has(<relative-selector-list>)::slotted(<compound-selector>)Brackets node typeSelector node type to SelectorListSimpleSelector node type to SelectorUnicodeRange.name property to UnicodeRange.valueNegation node type for regular PseudoClasschildren now:
StyleSheet.rules -> StyleSheet.childrenSelectorList.selectors -> SelectorList.childrenBlock.declarations -> Block.children*.sequence -> *.childrenHex and UnicodeRange when number not an integernth- pseudos parsing
An+B node type to represent expressions like 2n + 1 or -3na 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 selectorof 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() pseudosinfo node property to locloc to store start and end positionsScanner 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)<angle> generic according to specs that allow a <number> equals to zero to be used as valid value (#30)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:CSSDatasyntax.stringify() method to syntax.translate()true or falsevar(), those values are always valid for now98.5%>>)Type and Universal type nodesNumber parsing by including sign and exponent (#26)before, after, first-letter and first-line pseudos with single colon as PseudoElementFunctionalPseudo node type to PseudoClasseof is reachedSyntax#getAll() methodapple specific font keywords (#20)Property node stucture from object to stringRuleset node type to RuleArgument node typeDimension and Percentage position computationpositions:true (even freeze)line and column computation for SyntaxMatch error