From 633141b8728351973ec8945145f8de09894b877e Mon Sep 17 00:00:00 2001 From: Roman Dvornov Date: Tue, 7 Feb 2017 01:27:21 +0300 Subject: [PATCH] simplify identifier consuming --- lib/parser/Parser.js | 16 +- lib/parser/atrule/supports.js | 3 +- lib/parser/function/var.js | 19 +- lib/parser/sequence.js | 7 +- lib/parser/type/Atrule.js | 3 +- lib/parser/type/Attribute.js | 21 +- lib/parser/type/Class.js | 2 +- lib/parser/type/Declaration.js | 29 +- lib/parser/type/Function.js | 3 +- lib/parser/type/Hash.js | 2 + lib/parser/type/Id.js | 2 +- lib/parser/type/Identifier.js | 5 +- lib/parser/type/MediaFeature.js | 5 +- lib/parser/type/MediaQuery.js | 3 +- lib/parser/type/Nth.js | 4 +- lib/parser/type/PseudoClass.js | 3 +- lib/parser/type/PseudoElement.js | 3 +- .../parse/declaration/Declaration.json | 67 ++++- .../parse/declaration/custom-property.json | 5 + test/fixture/parse/selector/Attribute.json | 26 ++ test/fixture/parse/selector/Class.json | 7 + test/fixture/parse/value/function/var.json | 4 +- test/fixture/stringify.ast | 269 +++++++++++++++++- test/fixture/stringify.css | 4 + 24 files changed, 444 insertions(+), 68 deletions(-) diff --git a/lib/parser/Parser.js b/lib/parser/Parser.js index bab949bf..2426a06a 100644 --- a/lib/parser/Parser.js +++ b/lib/parser/Parser.js @@ -50,24 +50,15 @@ var getUniversal = require('./type/Universal'); var getUrl = require('./type/Url'); var getValue = require('./type/Value'); -function scanIdent(varAllowed) { +function readIdent() { + var start = this.scanner.tokenStart; + // optional first - if (this.scanner.tokenType === HYPHENMINUS) { this.scanner.next(); - - // variable -- - if (varAllowed && this.scanner.tokenType === HYPHENMINUS) { - this.scanner.next(); - } } this.scanner.eat(IDENTIFIER); -} - -function readIdent(varAllowed) { - var start = this.scanner.tokenStart; - - this.scanIdent(varAllowed); return this.scanner.substrToCursor(start); } @@ -173,7 +164,6 @@ Parser.prototype = { Url: getUrl, Value: getValue, - scanIdent: scanIdent, readIdent: readIdent, readSC: readSC, readSequence: sequence.default, diff --git a/lib/parser/atrule/supports.js b/lib/parser/atrule/supports.js index 0db506e9..4c72df36 100644 --- a/lib/parser/atrule/supports.js +++ b/lib/parser/atrule/supports.js @@ -7,7 +7,6 @@ var IDENTIFIER = TYPE.Identifier; var LEFTPARENTHESIS = TYPE.LeftParenthesis; var HYPHENMINUS = TYPE.HyphenMinus; var COLON = TYPE.Colon; -var DISALLOW_VAR = false; var BALANCED = true; function readRaw() { @@ -64,7 +63,7 @@ function readSequence() { if (this.scanner.lookupType(1) === LEFTPARENTHESIS) { child = this.Function(this.scopeAtruleExpression, readRaw); } else { - child = this.Identifier(DISALLOW_VAR); + child = this.Identifier(); } break; diff --git a/lib/parser/function/var.js b/lib/parser/function/var.js index 8c1a7e7f..28b2d44b 100644 --- a/lib/parser/function/var.js +++ b/lib/parser/function/var.js @@ -1,10 +1,10 @@ var List = require('../../utils/list'); var TYPE = require('../../tokenizer').TYPE; +var IDENTIFIER = TYPE.Identifier; var COMMA = TYPE.Comma; var HYPHENMINUS = TYPE.HyphenMinus; var EXCLAMATIONMARK = TYPE.ExclamationMark; -var ALLOWED_VAR = true; var BALANCED = true; // var '(' ident (',' ? )? ')' @@ -13,14 +13,17 @@ module.exports = function getVarFunction() { this.readSC(); - if (this.scanner.tokenType !== HYPHENMINUS) { - this.scanner.error('Hyphen minus is expected'); - } - if (this.scanner.lookupType(1) !== HYPHENMINUS) { - this.scanner.error('Hyphen minus is expected', this.scanner.tokenStart + 1); - } + var identStart = this.scanner.tokenStart; + + this.scanner.eat(HYPHENMINUS); + this.scanner.eat(HYPHENMINUS); + this.scanner.eat(IDENTIFIER); - children.appendData(this.Identifier(ALLOWED_VAR)); + children.appendData({ + type: 'Identifier', + loc: this.getLocation(identStart, this.scanner.tokenStart), + name: this.scanner.substrToCursor(identStart) + }); this.readSC(); diff --git a/lib/parser/sequence.js b/lib/parser/sequence.js index 77fb89eb..f45e74be 100644 --- a/lib/parser/sequence.js +++ b/lib/parser/sequence.js @@ -20,11 +20,10 @@ var U = 117; // 'u'.charCodeAt(0) var ALLOW_OF_CLAUSE = true; var DISALLOW_OF_CLAUSE = false; -var DISALLOW_VAR = false; function singleIdentifier() { return new List().appendData( - this.Identifier(DISALLOW_VAR) + this.Identifier() ); } @@ -99,7 +98,7 @@ function defaultSequence(scope) { if (this.scanner.lookupType(2) === LEFTPARENTHESIS) { child = this.Function(scope, defaultSequence); } else { - child = this.Identifier(DISALLOW_VAR); + child = this.Identifier(); } } else { child = this.Operator(); @@ -147,7 +146,7 @@ function defaultSequence(scope) { child = this.Function(scope, defaultSequence); } } else { - child = this.Identifier(DISALLOW_VAR); + child = this.Identifier(); } break; diff --git a/lib/parser/type/Atrule.js b/lib/parser/type/Atrule.js index 670f5429..0ecec1d1 100644 --- a/lib/parser/type/Atrule.js +++ b/lib/parser/type/Atrule.js @@ -4,7 +4,6 @@ var SEMICOLON = TYPE.Semicolon; var COMMERCIALAT = TYPE.CommercialAt; var LEFTCURLYBRACKET = TYPE.LeftCurlyBracket; var RIGHTCURLYBRACKET = TYPE.RightCurlyBracket; -var DISALLOW_VAR = false; var BALANCED = true; function isBlockAtrule() { @@ -32,7 +31,7 @@ module.exports = function Atrule() { this.scanner.eat(COMMERCIALAT); - name = this.readIdent(DISALLOW_VAR); + name = this.readIdent(); nameLowerCase = name.toLowerCase(); this.readSC(); diff --git a/lib/parser/type/Attribute.js b/lib/parser/type/Attribute.js index 2932e705..58cd3077 100644 --- a/lib/parser/type/Attribute.js +++ b/lib/parser/type/Attribute.js @@ -12,7 +12,6 @@ var RIGHTSQUAREBRACKET = TYPE.RightSquareBracket; var CIRCUMFLEXACCENT = TYPE.CircumflexAccent; var VERTICALLINE = TYPE.VerticalLine; var TILDE = TYPE.Tilde; -var DISALLOW_VAR = false; function getAttributeName() { if (this.scanner.eof) { @@ -28,18 +27,19 @@ function getAttributeName() { checkColon = false; this.scanner.next(); } else if (this.scanner.tokenType !== VERTICALLINE) { - this.scanIdent(false); + if (this.scanner.tokenType === HYPHENMINUS) { + this.scanner.next(); + } + this.scanner.eat(IDENTIFIER); } if (this.scanner.tokenType === VERTICALLINE) { if (this.scanner.lookupType(1) !== EQUALSSIGN) { this.scanner.next(); - - if (this.scanner.tokenType === HYPHENMINUS || this.scanner.tokenType === IDENTIFIER) { - this.scanIdent(false); - } else { - this.scanner.error('Identifier is expected'); + if (this.scanner.tokenType === HYPHENMINUS) { + this.scanner.next(); } + this.scanner.eat(IDENTIFIER); } else if (expectIdentifier) { this.scanner.error('Identifier is expected', this.scanner.tokenEnd); } @@ -49,7 +49,10 @@ function getAttributeName() { if (checkColon && this.scanner.tokenType === COLON) { this.scanner.next(); - this.scanIdent(false); + if (this.scanner.tokenType === HYPHENMINUS) { + this.scanner.next(); + } + this.scanner.eat(IDENTIFIER); } return { @@ -107,7 +110,7 @@ module.exports = function Attribute() { value = this.scanner.tokenType === STRING ? this.String() - : this.Identifier(DISALLOW_VAR); + : this.Identifier(); this.readSC(); } diff --git a/lib/parser/type/Class.js b/lib/parser/type/Class.js index 9f8504fe..0680322c 100644 --- a/lib/parser/type/Class.js +++ b/lib/parser/type/Class.js @@ -6,7 +6,7 @@ module.exports = function Class() { var name; this.scanner.eat(FULLSTOP); - name = this.readIdent(false); + name = this.readIdent(); return { type: 'Class', diff --git a/lib/parser/type/Declaration.js b/lib/parser/type/Declaration.js index f4050b13..2e499cb6 100644 --- a/lib/parser/type/Declaration.js +++ b/lib/parser/type/Declaration.js @@ -1,5 +1,6 @@ var TYPE = require('../../tokenizer').TYPE; +var IDENTIFIER = TYPE.Identifier; var COLON = TYPE.Colon; var EXCLAMATIONMARK = TYPE.ExclamationMark; var SOLIDUS = TYPE.Solidus; @@ -13,17 +14,33 @@ var BALANCED = true; function readProperty() { var start = this.scanner.tokenStart; - var type; + var prefix = 0; - for (; type = this.scanner.tokenType; this.scanner.next()) { - if (type !== SOLIDUS && - type !== ASTERISK && - type !== DOLLARSIGN) { + // hacks + switch (this.scanner.tokenType) { + case ASTERISK: + case DOLLARSIGN: + prefix = 1; break; + + // TODO: not sure we should support this hack + case SOLIDUS: + prefix = this.scanner.lookupType(1) === SOLIDUS ? 2 : 1; + break; + } + + if (this.scanner.lookupType(prefix) === HYPHENMINUS) { + prefix++; + if (this.scanner.lookupType(prefix) === HYPHENMINUS) { + prefix++; } } - this.scanIdent(true); + if (prefix) { + this.scanner.skip(prefix); + } + + this.scanner.eat(IDENTIFIER); return this.scanner.substrToCursor(start); } diff --git a/lib/parser/type/Function.js b/lib/parser/type/Function.js index b816bd32..2f141cce 100644 --- a/lib/parser/type/Function.js +++ b/lib/parser/type/Function.js @@ -2,12 +2,11 @@ var TYPE = require('../../tokenizer').TYPE; var LEFTPARENTHESIS = TYPE.LeftParenthesis; var RIGHTPARENTHESIS = TYPE.RightParenthesis; -var DISALLOW_VAR = false; // ident '(' ')' module.exports = function Function(scope, readSequence) { var start = this.scanner.tokenStart; - var name = this.readIdent(DISALLOW_VAR); + var name = this.readIdent(); var nameLowerCase = name.toLowerCase(); var children; diff --git a/lib/parser/type/Hash.js b/lib/parser/type/Hash.js index 93fdda9f..5b3f9859 100644 --- a/lib/parser/type/Hash.js +++ b/lib/parser/type/Hash.js @@ -36,6 +36,7 @@ module.exports = function Hash() { this.scanner.next(); // if next token is identifier add it to result + // TODO: consume hex only if (this.scanner.tokenType === IDENTIFIER) { this.scanner.next(); } @@ -43,6 +44,7 @@ module.exports = function Hash() { break; case IDENTIFIER: + // TODO: consume hex only this.scanner.next(); // add token to result break; diff --git a/lib/parser/type/Id.js b/lib/parser/type/Id.js index 33b5aa3c..22f655da 100644 --- a/lib/parser/type/Id.js +++ b/lib/parser/type/Id.js @@ -6,7 +6,7 @@ module.exports = function Id() { var name; this.scanner.eat(NUMBERSIGN); - name = this.readIdent(false); + name = this.readIdent(); return { type: 'Id', diff --git a/lib/parser/type/Identifier.js b/lib/parser/type/Identifier.js index bde04223..5764b835 100644 --- a/lib/parser/type/Identifier.js +++ b/lib/parser/type/Identifier.js @@ -1,6 +1,7 @@ -module.exports = function Identifier(varAllowed) { + +module.exports = function Identifier() { var start = this.scanner.tokenStart; - var name = this.readIdent(varAllowed); + var name = this.readIdent(); return { type: 'Identifier', diff --git a/lib/parser/type/MediaFeature.js b/lib/parser/type/MediaFeature.js index 1e3658da..5eb92d97 100644 --- a/lib/parser/type/MediaFeature.js +++ b/lib/parser/type/MediaFeature.js @@ -6,7 +6,6 @@ var LEFTPARENTHESIS = TYPE.LeftParenthesis; var RIGHTPARENTHESIS = TYPE.RightParenthesis; var COLON = TYPE.Colon; var SOLIDUS = TYPE.Solidus; -var DISALLOW_VAR = false; module.exports = function MediaFeature() { var start = this.scanner.tokenStart; @@ -16,7 +15,7 @@ module.exports = function MediaFeature() { this.scanner.eat(LEFTPARENTHESIS); this.readSC(); - name = this.readIdent(DISALLOW_VAR); + name = this.readIdent(); this.readSC(); if (this.scanner.tokenType !== RIGHTPARENTHESIS) { @@ -36,7 +35,7 @@ module.exports = function MediaFeature() { break; case IDENTIFIER: - value = this.Identifier(DISALLOW_VAR); + value = this.Identifier(); break; diff --git a/lib/parser/type/MediaQuery.js b/lib/parser/type/MediaQuery.js index 2f235800..e0f0218e 100644 --- a/lib/parser/type/MediaQuery.js +++ b/lib/parser/type/MediaQuery.js @@ -5,7 +5,6 @@ var WHITESPACE = TYPE.Whitespace; var COMMENT = TYPE.Comment; var IDENTIFIER = TYPE.Identifier; var LEFTPARENTHESIS = TYPE.LeftParenthesis; -var DISALLOW_VAR = false; module.exports = function MediaQuery() { this.readSC(); @@ -31,7 +30,7 @@ module.exports = function MediaQuery() { this.scanner.error('Space is expected'); } - child = this.Identifier(DISALLOW_VAR); + child = this.Identifier(); break; case LEFTPARENTHESIS: diff --git a/lib/parser/type/Nth.js b/lib/parser/type/Nth.js index 563b4ccd..e65d5875 100644 --- a/lib/parser/type/Nth.js +++ b/lib/parser/type/Nth.js @@ -1,5 +1,3 @@ -var DISALLOW_VAR = false; - // https://drafts.csswg.org/css-syntax-3/#the-anb-type module.exports = function Nth(allowOfClause) { this.readSC(); @@ -10,7 +8,7 @@ module.exports = function Nth(allowOfClause) { var query; if (this.scanner.lookupValue(0, 'odd') || this.scanner.lookupValue(0, 'even')) { - query = this.Identifier(DISALLOW_VAR); + query = this.Identifier(); } else { query = this.AnPlusB(); } diff --git a/lib/parser/type/PseudoClass.js b/lib/parser/type/PseudoClass.js index 8ef4b06a..3b579b21 100644 --- a/lib/parser/type/PseudoClass.js +++ b/lib/parser/type/PseudoClass.js @@ -4,7 +4,6 @@ var TYPE = require('../../tokenizer').TYPE; var COLON = TYPE.Colon; var LEFTPARENTHESIS = TYPE.LeftParenthesis; var RIGHTPARENTHESIS = TYPE.RightParenthesis; -var DISALLOW_VAR = false; var BALANCED = true; // : ident [ '(' .. ')' ]? @@ -15,7 +14,7 @@ module.exports = function PseudoClass() { this.scanner.eat(COLON); - name = this.readIdent(DISALLOW_VAR); + name = this.readIdent(); if (this.scanner.tokenType === LEFTPARENTHESIS) { var nameLowerCase = name.toLowerCase(); diff --git a/lib/parser/type/PseudoElement.js b/lib/parser/type/PseudoElement.js index e26d0cb0..268379c8 100644 --- a/lib/parser/type/PseudoElement.js +++ b/lib/parser/type/PseudoElement.js @@ -4,7 +4,6 @@ var TYPE = require('../../tokenizer').TYPE; var COLON = TYPE.Colon; var LEFTPARENTHESIS = TYPE.LeftParenthesis; var RIGHTPARENTHESIS = TYPE.RightParenthesis; -var DISALLOW_VAR = false; var BALANCED = true; // :: ident [ '(' .. ')' ]? @@ -16,7 +15,7 @@ module.exports = function PseudoElement() { this.scanner.eat(COLON); this.scanner.eat(COLON); - name = this.readIdent(DISALLOW_VAR); + name = this.readIdent(); if (this.scanner.tokenType === LEFTPARENTHESIS) { var nameLowerCase = name.toLowerCase(); diff --git a/test/fixture/parse/declaration/Declaration.json b/test/fixture/parse/declaration/Declaration.json index a252ac84..d9a1f923 100644 --- a/test/fixture/parse/declaration/Declaration.json +++ b/test/fixture/parse/declaration/Declaration.json @@ -33,7 +33,7 @@ } } }, - "declaration property with hack": { + "declaration property with // hack": { "source": "//property:value", "ast": { "type": "Declaration", @@ -50,6 +50,57 @@ } } }, + "declaration property with $ hack": { + "source": "$property:value", + "ast": { + "type": "Declaration", + "important": false, + "property": "$property", + "value": { + "type": "Value", + "children": [ + { + "type": "Identifier", + "name": "value" + } + ] + } + } + }, + "declaration property with _ hack": { + "source": "_property:value", + "ast": { + "type": "Declaration", + "important": false, + "property": "_property", + "value": { + "type": "Value", + "children": [ + { + "type": "Identifier", + "name": "value" + } + ] + } + } + }, + "declaration property with * hack": { + "source": "*property:value", + "ast": { + "type": "Declaration", + "important": false, + "property": "*property", + "value": { + "type": "Value", + "children": [ + { + "type": "Identifier", + "name": "value" + } + ] + } + } + }, "declaration.c.0": { "source": "property/*test*/:value", "translate": "property:value", @@ -208,5 +259,17 @@ "value": " value" } } - } + }, + "error": [ + { + "source": "//: 1", + "offset": " ^", + "error": "Identifier is expected" + }, + { + "source": "$: 1", + "offset": " ^", + "error": "Identifier is expected" + } + ] } diff --git a/test/fixture/parse/declaration/custom-property.json b/test/fixture/parse/declaration/custom-property.json index 147aa95c..bcdcc631 100644 --- a/test/fixture/parse/declaration/custom-property.json +++ b/test/fixture/parse/declaration/custom-property.json @@ -161,6 +161,11 @@ "source": "--var: !important ()", "offset": " ^", "error": "Unexpected input" + }, + { + "source": "--: 1", + "offset": " ^", + "error": "Identifier is expected" } ] } diff --git a/test/fixture/parse/selector/Attribute.json b/test/fixture/parse/selector/Attribute.json index 65ce9a1d..e46f2c97 100644 --- a/test/fixture/parse/selector/Attribute.json +++ b/test/fixture/parse/selector/Attribute.json @@ -60,6 +60,32 @@ "flags": null } }, + "starting with dash": { + "source": "[-b]", + "ast": { + "type": "Attribute", + "name": { + "type": "Identifier", + "name": "-b" + }, + "operator": null, + "value": null, + "flags": null + } + }, + "namespaced starting with dash": { + "source": "[*|-b]", + "ast": { + "type": "Attribute", + "name": { + "type": "Identifier", + "name": "*|-b" + }, + "operator": null, + "value": null, + "flags": null + } + }, "attrib.2 with flags": { "source": "[b i]", "ast": { diff --git a/test/fixture/parse/selector/Class.json b/test/fixture/parse/selector/Class.json index d0afd270..1a746b05 100644 --- a/test/fixture/parse/selector/Class.json +++ b/test/fixture/parse/selector/Class.json @@ -6,6 +6,13 @@ "name": "abc" } }, + "start with dash": { + "source": ".-abc", + "ast": { + "type": "Class", + "name": "-abc" + } + }, "excaped class selector #1": { "source": ".\\31 0\\+", "ast": { diff --git a/test/fixture/parse/value/function/var.json b/test/fixture/parse/value/function/var.json index 9fba7642..a8319e92 100644 --- a/test/fixture/parse/value/function/var.json +++ b/test/fixture/parse/value/function/var.json @@ -200,12 +200,12 @@ "error #1": { "source": "var(name)", "offset": " ^", - "error": "Hyphen minus is expected" + "error": "HyphenMinus is expected" }, "error #2": { "source": "var(-name)", "offset": " ^", - "error": "Hyphen minus is expected" + "error": "HyphenMinus is expected" }, "error #3": { "source": "var(--name,([)])", diff --git a/test/fixture/stringify.ast b/test/fixture/stringify.ast index c5c70862..02d23b69 100644 --- a/test/fixture/stringify.ast +++ b/test/fixture/stringify.ast @@ -8,8 +8,8 @@ "column": 1 }, "end": { - "offset": 1057, - "line": 38, + "offset": 1101, + "line": 42, "column": 1 } }, @@ -3223,6 +3223,271 @@ } ] } + }, + { + "type": "Rule", + "loc": { + "source": "stringify.css", + "start": { + "offset": 1058, + "line": 39, + "column": 1 + }, + "end": { + "offset": 1100, + "line": 41, + "column": 2 + } + }, + "selector": { + "type": "SelectorList", + "loc": { + "source": "stringify.css", + "start": { + "offset": 1058, + "line": 39, + "column": 1 + }, + "end": { + "offset": 1081, + "line": 39, + "column": 24 + } + }, + "children": [ + { + "type": "Selector", + "loc": { + "source": "stringify.css", + "start": { + "offset": 1058, + "line": 39, + "column": 1 + }, + "end": { + "offset": 1081, + "line": 39, + "column": 24 + } + }, + "children": [ + { + "type": "Class", + "loc": { + "source": "stringify.css", + "start": { + "offset": 1058, + "line": 39, + "column": 1 + }, + "end": { + "offset": 1061, + "line": 39, + "column": 4 + } + }, + "name": "-a" + }, + { + "type": "Id", + "loc": { + "source": "stringify.css", + "start": { + "offset": 1061, + "line": 39, + "column": 4 + }, + "end": { + "offset": 1064, + "line": 39, + "column": 7 + } + }, + "name": "-b" + }, + { + "type": "PseudoClass", + "loc": { + "source": "stringify.css", + "start": { + "offset": 1064, + "line": 39, + "column": 7 + }, + "end": { + "offset": 1067, + "line": 39, + "column": 10 + } + }, + "name": "-c", + "children": null + }, + { + "type": "PseudoElement", + "loc": { + "source": "stringify.css", + "start": { + "offset": 1067, + "line": 39, + "column": 10 + }, + "end": { + "offset": 1071, + "line": 39, + "column": 14 + } + }, + "name": "-d", + "children": null + }, + { + "type": "Attribute", + "loc": { + "source": "stringify.css", + "start": { + "offset": 1071, + "line": 39, + "column": 14 + }, + "end": { + "offset": 1075, + "line": 39, + "column": 18 + } + }, + "name": { + "type": "Identifier", + "loc": { + "source": "stringify.css", + "start": { + "offset": 1072, + "line": 39, + "column": 15 + }, + "end": { + "offset": 1074, + "line": 39, + "column": 17 + } + }, + "name": "-e" + }, + "operator": null, + "value": null, + "flags": null + }, + { + "type": "Attribute", + "loc": { + "source": "stringify.css", + "start": { + "offset": 1075, + "line": 39, + "column": 18 + }, + "end": { + "offset": 1081, + "line": 39, + "column": 24 + } + }, + "name": { + "type": "Identifier", + "loc": { + "source": "stringify.css", + "start": { + "offset": 1076, + "line": 39, + "column": 19 + }, + "end": { + "offset": 1080, + "line": 39, + "column": 23 + } + }, + "name": "*|-f" + }, + "operator": null, + "value": null, + "flags": null + } + ] + } + ] + }, + "block": { + "type": "Block", + "loc": { + "source": "stringify.css", + "start": { + "offset": 1082, + "line": 39, + "column": 25 + }, + "end": { + "offset": 1100, + "line": 41, + "column": 2 + } + }, + "children": [ + { + "type": "Declaration", + "loc": { + "source": "stringify.css", + "start": { + "offset": 1088, + "line": 40, + "column": 5 + }, + "end": { + "offset": 1097, + "line": 40, + "column": 14 + } + }, + "important": false, + "property": "-foo", + "value": { + "type": "Value", + "loc": { + "source": "stringify.css", + "start": { + "offset": 1093, + "line": 40, + "column": 10 + }, + "end": { + "offset": 1097, + "line": 40, + "column": 14 + } + }, + "children": [ + { + "type": "Number", + "loc": { + "source": "stringify.css", + "start": { + "offset": 1094, + "line": 40, + "column": 11 + }, + "end": { + "offset": 1097, + "line": 40, + "column": 14 + } + }, + "value": "123" + } + ] + } + } + ] + } } ] } diff --git a/test/fixture/stringify.css b/test/fixture/stringify.css index cd18f82d..8f47b4f8 100644 --- a/test/fixture/stringify.css +++ b/test/fixture/stringify.css @@ -35,3 +35,7 @@ svg|*:matches(a)::slotted(c) > :nth-child(odd of a, :b):nth-child(2n + 1 of [a]) box-shadow: var(--something, fallback); } } + +.-a#-b:-c::-d[-e][*|-f] { + -foo: 123; +}