Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

css-tree

Package Overview
Dependencies
Maintainers
1
Versions
58
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

css-tree - npm Package Compare versions

Comparing version 1.0.0-alpha10 to 1.0.0-alpha11

28

HISTORY.md

@@ -0,1 +1,29 @@

## 1.0.0-alpha11 (January 18, 2017)
- Added support for `:matches(<selector-list>)` (#28)
- Added support for `:has(<relative-selector-list>)`
- Added support for `::slotted(<compound-selector>)`
- Implemented `Brackets` node type
- Implemented basic support for at-rule inside rule block (#24)
- Renamed `Selector` node type to `SelectorList`
- Renamed `SimpleSelector` node type to `Selector`
- Renamed `UnicodeRange.name` property to `UnicodeRange.value`
- Replaced `Negation` node type for regular `PseudoClass`
- Unified name of node property to store nested nodes, it always `children` now:
- `StyleSheet.rules` -> `StyleSheet.children`
- `SelectorList.selectors` -> `SelectorList.children`
- `Block.declarations` -> `Block.children`
- `*.sequence` -> `*.children`
- Fixed edge cases in parsing `Hex` and `UnicodeRange` when number not an integer
- Changed `nth-` pseudos parsing
- Implemented `An+B` node type to represent expressions like `2n + 1` or `-3n`
- Fixed edge cases when `a` or `b` is not an integer
- Changed `odd` and `even` keywords processing, keywords are storing as `Identifier` node type now
- Changed `Nth` node type format to store a `nth`-query and an optional `selector`
- Implemented `of` clause for `nth-` pseudos (a.e. `:nth-child(2n + 1 of li, img)`)
- Limited `Nth` parsing rules to `:nth-child()`, `:nth-last-child()`, `:nth-of-type()` and `:nth-last-of-type()` pseudos
- Changed the way to store locations
- Renamed `info` node property to `loc`
- Changed format of `loc` to store `start` and `end` positions
## 1.0.0-alpha10 (January 11, 2017)

@@ -2,0 +30,0 @@

2

lib/index.js

@@ -0,1 +1,3 @@

'use strict';
var walkers = require('./utils/walk');

@@ -2,0 +4,0 @@ var names = require('./utils/names');

819

lib/parser/index.js

@@ -8,4 +8,4 @@ 'use strict';

var cmpChar = Scanner.cmpChar;
var cmpStr = Scanner.cmpStr;
var endsWith = Scanner.endsWith;
var isNumber = Scanner.isNumber;
var isHex = Scanner.isHex;

@@ -17,2 +17,5 @@ var needPositions;

var SPACE_NODE = { type: 'Space' };
var NESTED = true;
var ABSOLUTE = false;
var RELATIVE = true;

@@ -56,3 +59,5 @@ var WHITESPACE = Scanner.TYPE.Whitespace;

url: getUri,
not: getNotFunction
not: getSelectorListFunction,
matches: getSelectorListFunction,
has: getRelativeSelectorListFunction
};

@@ -70,4 +75,4 @@ var SCOPE_VALUE = {

rule: getRule,
selectorList: getSelectorList,
selector: getSelector,
simpleSelector: getSimpleSelector,
block: getBlock,

@@ -78,10 +83,7 @@ declaration: getDeclaration,

function isNumber(code) {
return code >= 48 && code <= 57;
}
function getInfo(start) {
function getLocation(start, end) {
if (needPositions) {
return scanner.getLocation(
start !== undefined ? start : scanner.tokenStart,
return scanner.getLocationRange(
start,
end,
filename

@@ -96,3 +98,3 @@ );

var start = scanner.tokenStart;
var rules = new List();
var children = new List();
var child;

@@ -132,3 +134,3 @@

rules.appendData(child);
children.appendData(child);
}

@@ -138,4 +140,4 @@

type: 'StyleSheet',
info: getInfo(start),
rules: rules
loc: getLocation(start, scanner.tokenStart),
children: children
};

@@ -160,8 +162,10 @@ }

function getAtruleExpression() {
var start = scanner.tokenStart;
var sequence = new List();
var start;
var children = new List();
var wasSpace = false;
var lastNonSpace = null;
var child;
readSC();
start = scanner.tokenStart;

@@ -206,6 +210,7 @@ scan:

wasSpace = false;
sequence.appendData(SPACE_NODE);
children.appendData(SPACE_NODE);
}
sequence.appendData(child);
lastNonSpace = scanner.tokenStart;
children.appendData(child);
}

@@ -215,4 +220,4 @@

type: 'AtruleExpression',
info: getInfo(start),
sequence: sequence
loc: getLocation(start, lastNonSpace !== null ? lastNonSpace : scanner.tokenStart),
children: children
};

@@ -222,11 +227,11 @@ }

function getAtrule() {
var start = scanner.tokenStart;
var name;
var expression;
var block = null;
scanner.eat(COMMERCIALAT);
var node = {
type: 'Atrule',
info: getInfo(),
name: readIdent(false),
expression: getAtruleExpression(),
block: null
};
name = readIdent(false);
expression = getAtruleExpression();

@@ -241,5 +246,5 @@ switch (scanner.tokenType) {

node.block = isBlockAtrule()
block = isBlockAtrule()
? getBlock()
: getStylesheet(true);
: getStylesheet(NESTED);

@@ -252,24 +257,32 @@ scanner.eat(RIGHTCURLYBRACKET);

return node;
return {
type: 'Atrule',
loc: getLocation(start, scanner.tokenStart),
name: name,
expression: expression,
block: block
};
}
function getRule() {
var node = {
type: 'Rule',
info: getInfo(),
selector: getSelector(),
block: null
};
var start = scanner.tokenStart;
var selector = getSelectorList();
var block;
scanner.eat(LEFTCURLYBRACKET);
node.block = getBlock();
block = getBlock();
scanner.eat(RIGHTCURLYBRACKET);
return node;
return {
type: 'Rule',
loc: getLocation(start, scanner.tokenStart),
selector: selector,
block: block
};
}
function getSelector() {
function getSelectorList(nested, relative) {
var start = scanner.tokenStart;
var selectors = new List();
var simpleSelector;
var children = new List();
var selector;
var lastComma = -2;

@@ -281,4 +294,14 @@

case LEFTCURLYBRACKET:
if (nested) {
scanner.error();
}
break scan;
case RIGHTPARENTHESIS:
if (!nested) {
scanner.error();
}
break scan;
case COMMA:

@@ -295,6 +318,6 @@ if (lastComma !== -1) {

lastComma = -1;
simpleSelector = getSimpleSelector();
selectors.appendData(simpleSelector);
selector = getSelector(nested, relative);
children.appendData(selector);
if (simpleSelector.sequence.isEmpty()) {
if (selector.children.isEmpty()) {
scanner.error('Simple selector expected');

@@ -310,11 +333,11 @@ }

return {
type: 'Selector',
info: getInfo(start),
selectors: selectors
type: 'SelectorList',
loc: getLocation(start, scanner.tokenStart),
children: children
};
}
function getSimpleSelector(nested) {
function getSelector(nested, relative) {
var start = scanner.tokenStart;
var sequence = new List();
var children = new List();
var combinator = null;

@@ -349,3 +372,3 @@ var combinatorOffset = -1;

case WHITESPACE:
if (combinator === null && sequence.head !== null) {
if (combinator === null && children.head !== null) {
combinatorOffset = scanner.tokenStart;

@@ -362,3 +385,3 @@ combinator = DESCENDANT_COMBINATOR;

case SOLIDUS:
if ((sequence.head === null) || // combinator in the beginning
if ((children.head === null && !relative) || // combinator in the beginning
(combinator !== null && combinator !== DESCENDANT_COMBINATOR)) {

@@ -408,3 +431,3 @@ scanner.error('Unexpected combinator');

type: 'Combinator',
info: getInfo(combinatorOffset),
loc: getLocation(combinatorOffset, combinatorOffset + 1),
name: ' '

@@ -414,7 +437,7 @@ };

sequence.appendData(combinator);
children.appendData(combinator);
combinator = null;
}
sequence.appendData(child);
children.appendData(child);
}

@@ -427,11 +450,87 @@

return {
type: 'SimpleSelector',
info: getInfo(start),
sequence: sequence
type: 'Selector',
loc: getLocation(start, scanner.tokenStart),
children: children
};
}
function getCompoundSelector(nested) {
var start = scanner.tokenStart;
var children = new List();
var child;
readSC();
scan:
while (!scanner.eof) {
switch (scanner.tokenType) {
case COMMA:
break scan;
case LEFTCURLYBRACKET:
if (nested) {
scanner.error();
}
break scan;
case RIGHTPARENTHESIS:
if (!nested) {
scanner.error();
}
break scan;
case COMMENT:
scanner.next();
continue;
case WHITESPACE:
readSC();
break scan;
case FULLSTOP:
child = getClass();
break;
case LEFTSQUAREBRACKET:
child = getAttribute();
break;
case NUMBERSIGN:
child = getId();
break;
case COLON:
child = getPseudo();
break;
case HYPHENMINUS:
case IDENTIFIER:
case ASTERISK:
case VERTICALLINE:
child = getTypeOrUniversal();
break;
default:
scanner.error();
}
children.appendData(child);
}
if (children.isEmpty()) {
scanner.error('Simple selector expected');
}
return {
type: 'Selector',
loc: getLocation(start, scanner.tokenStart),
children: children
};
}
function getBlock() {
var start = scanner.tokenStart;
var declarations = new List();
var children = new List();

@@ -450,4 +549,8 @@ scan:

case COMMERCIALAT:
children.appendData(getAtrule());
break;
default:
declarations.appendData(getDeclaration());
children.appendData(getDeclaration());
}

@@ -458,4 +561,4 @@ }

type: 'Block',
info: getInfo(start),
declarations: declarations
loc: getLocation(start, scanner.tokenStart),
children: children
};

@@ -478,5 +581,10 @@ }

// TODO: include or not to include semicolon to range?
// if (scanner.tokenType === SEMICOLON) {
// scanner.next();
// }
return {
type: 'Declaration',
info: getInfo(start),
loc: getLocation(start, scanner.tokenStart),
important: important,

@@ -512,3 +620,3 @@ property: property,

var start = scanner.tokenStart;
var sequence = new List();
var children = new List();
var wasSpace = false;

@@ -556,2 +664,6 @@ var child;

case LEFTSQUAREBRACKET:
child = getBrackets();
break;
case STRING:

@@ -580,6 +692,6 @@ child = getString();

wasSpace = false;
sequence.appendData(SPACE_NODE);
children.appendData(SPACE_NODE);
}
sequence.appendData(child);
children.appendData(child);
}

@@ -589,4 +701,4 @@

type: 'Value',
info: getInfo(start),
sequence: sequence
loc: getLocation(start, scanner.tokenStart),
children: children
};

@@ -597,3 +709,3 @@ }

var start = scanner.tokenStart;
var sequence = new List();
var children = new List();
var progid;

@@ -603,3 +715,3 @@

readSC();
sequence.appendData(getProgid(progid));
children.appendData(getProgid(progid));
}

@@ -611,4 +723,4 @@

type: 'Value',
info: getInfo(start),
sequence: sequence
loc: getLocation(start, scanner.tokenStart),
children: children
};

@@ -644,3 +756,3 @@ }

type: 'Number',
info: getInfo(),
loc: getLocation(scanner.tokenStart, scanner.tokenEnd),
value: readNumber()

@@ -659,3 +771,3 @@ };

if (scanner.tokenType === LEFTPARENTHESIS) {
return getFunction(scope, getInfo(start), scanner.substrToCursor(start));
return getFunction(scope, start, scanner.substrToCursor(start));
}

@@ -665,3 +777,3 @@

type: 'Identifier',
info: getInfo(start),
loc: getLocation(start, scanner.tokenStart),
name: scanner.substrToCursor(start)

@@ -698,10 +810,7 @@ };

function getAttribute() {
var node = {
type: 'Attribute',
info: getInfo(),
name: null,
operator: null,
value: null,
flags: null
};
var start = scanner.tokenStart;
var name;
var operator = null;
var value = null;
var flags = null;

@@ -711,3 +820,3 @@ scanner.eat(LEFTSQUAREBRACKET);

node.name = getAttributeName();
name = getAttributeName();
readSC();

@@ -718,7 +827,7 @@

if (scanner.tokenType !== IDENTIFIER) {
node.operator = readAttrselector();
operator = readAttrselector();
readSC();
node.value = scanner.tokenType === STRING
value = scanner.tokenType === STRING
? getString()

@@ -732,3 +841,3 @@ : getIdentifier(false);

if (scanner.tokenType === IDENTIFIER) {
node.flags = scanner.getTokenValue();
flags = scanner.getTokenValue();
scanner.next();

@@ -742,3 +851,10 @@

return node;
return {
type: 'Attribute',
loc: getLocation(start, scanner.tokenStart),
name: name,
operator: operator,
value: value,
flags: flags
};
}

@@ -748,7 +864,7 @@

var start = scanner.tokenStart;
var sequence = new List();
var children = new List();
var wasSpace = false;
var child;
// left brace
// left parenthesis
scanner.eat(LEFTPARENTHESIS);

@@ -797,9 +913,9 @@ readSC();

wasSpace = false;
sequence.appendData(SPACE_NODE);
children.appendData(SPACE_NODE);
}
sequence.appendData(child);
children.appendData(child);
}
// right brace
// right parenthesis
scanner.eat(RIGHTPARENTHESIS);

@@ -809,17 +925,69 @@

type: 'Parentheses',
info: getInfo(start),
sequence: sequence
loc: getLocation(start, scanner.tokenStart),
children: children
};
}
// currently only Grid Layout uses square brackets
// https://drafts.csswg.org/css-grid/#track-sizing
// [ ident* ]
function getBrackets() {
var start = scanner.tokenStart;
var children = new List();
var wasSpace = false;
var child;
// left bracket
scanner.eat(LEFTSQUAREBRACKET);
readSC();
scan:
while (!scanner.eof) {
switch (scanner.tokenType) {
case RIGHTSQUAREBRACKET:
break scan;
case WHITESPACE:
wasSpace = true;
scanner.next();
continue;
case COMMENT: // ignore comments
scanner.next();
continue;
default:
child = getIdentifier(false);
}
if (wasSpace) {
wasSpace = false;
children.appendData(SPACE_NODE);
}
children.appendData(child);
}
// right bracket
scanner.eat(RIGHTSQUAREBRACKET);
return {
type: 'Brackets',
loc: getLocation(start, scanner.tokenStart),
children: children
};
}
// '.' ident
function getClass() {
var start = scanner.tokenStart;
var name;
scanner.eat(FULLSTOP);
name = readIdent(false);
return {
type: 'Class',
info: getInfo(start),
name: readIdent(false)
loc: getLocation(start, scanner.tokenStart),
name: name
};

@@ -831,9 +999,11 @@ }

var start = scanner.tokenStart;
var name;
scanner.eat(NUMBERSIGN);
name = readIdent(false);
return {
type: 'Id',
info: getInfo(start),
name: readIdent(false)
loc: getLocation(start, scanner.tokenStart),
name: name
};

@@ -876,3 +1046,3 @@ }

type: 'Combinator',
info: getInfo(start),
loc: getLocation(start, scanner.tokenStart),
name: combinator

@@ -884,6 +1054,6 @@ };

function getComment() {
var start = scanner.tokenStart + 2;
var start = scanner.tokenStart;
var end = scanner.tokenEnd;
if ((end - start) >= 2 &&
if ((end - start + 2) >= 2 &&
scanner.source.charCodeAt(end - 2) === ASTERISK &&

@@ -898,4 +1068,4 @@ scanner.source.charCodeAt(end - 1) === SOLIDUS) {

type: 'Comment',
info: getInfo(start),
value: scanner.source.substring(start, end)
loc: getLocation(start, scanner.tokenStart),
value: scanner.source.substring(start + 2, end)
};

@@ -926,7 +1096,11 @@ }

function getDimension() {
var start = scanner.tokenStart;
var value = readNumber();
var unit = readUnit();
return {
type: 'Dimension',
info: getInfo(),
value: readNumber(),
unit: readUnit()
loc: getLocation(start, scanner.tokenStart),
value: value,
unit: unit
};

@@ -943,3 +1117,3 @@ }

type: 'Percentage',
info: getInfo(start),
loc: getLocation(start, scanner.tokenStart),
value: number

@@ -949,5 +1123,4 @@ };

// ident '(' functionBody ')' |
// not '(' <simpleSelector>* ')'
function getFunction(scope, info, name) {
// ident '(' functionBody ')'
function getFunction(scope, start, name) {
// parse special functions

@@ -959,3 +1132,3 @@ var nameLowerCase = name.toLowerCase();

if (SCOPE_SELECTOR.hasOwnProperty(nameLowerCase)) {
return SCOPE_SELECTOR[nameLowerCase](scope, info, name);
return SCOPE_SELECTOR[nameLowerCase](scope, start, name);
}

@@ -965,3 +1138,3 @@ break;

if (SCOPE_VALUE.hasOwnProperty(nameLowerCase)) {
return SCOPE_VALUE[nameLowerCase](scope, info, name);
return SCOPE_VALUE[nameLowerCase](scope, start, name);
}

@@ -971,3 +1144,3 @@ break;

if (SCOPE_ATRULE_EXPRESSION.hasOwnProperty(nameLowerCase)) {
return SCOPE_ATRULE_EXPRESSION[nameLowerCase](scope, info, name);
return SCOPE_ATRULE_EXPRESSION[nameLowerCase](scope, start, name);
}

@@ -977,10 +1150,10 @@ break;

return getFunctionInternal(getFunctionArguments, scope, info, name);
return getFunctionInternal(getFunctionArguments, scope, start, name);
}
function getFunctionInternal(readSequence, scope, info, name) {
var sequence;
function getFunctionInternal(readSequence, scope, start, name) {
var children;
scanner.eat(LEFTPARENTHESIS);
sequence = readSequence(scope);
children = readSequence(scope);
scanner.eat(RIGHTPARENTHESIS);

@@ -990,5 +1163,5 @@

type: scope === SCOPE_SELECTOR ? 'PseudoClass' : 'Function',
info: info,
loc: getLocation(start, scanner.tokenStart),
name: name,
sequence: sequence
children: children
};

@@ -998,3 +1171,3 @@ }

function getFunctionArguments(scope) {
var sequence = new List();
var children = new List();
var wasSpace = false;

@@ -1051,7 +1224,7 @@ var prevNonSpaceOperator = false;

if (!nonSpaceOperator && !prevNonSpaceOperator) {
sequence.appendData(SPACE_NODE);
children.appendData(SPACE_NODE);
}
}
sequence.appendData(child);
children.appendData(child);
prevNonSpaceOperator = nonSpaceOperator;

@@ -1061,55 +1234,19 @@ nonSpaceOperator = false;

return sequence;
return children;
}
function getVarFunction(scope, info, name) {
return getFunctionInternal(getVarFunctionArguments, scope, info, name);
function getSelectorListFunction(scope, start, name) {
return getFunctionInternal(function() {
return new List().appendData(getSelectorList(NESTED, ABSOLUTE));
}, scope, start, name);
}
// TODO: -> getSimpleSelectorList
function getNotFunctionArguments() {
var args = new List();
var wasSelector = false;
scan:
while (!scanner.eof) {
switch (scanner.tokenType) {
case RIGHTPARENTHESIS:
if (!wasSelector) {
scanner.error('Simple selector is expected');
}
break scan;
case COMMA:
if (!wasSelector) {
scanner.error('Simple selector is expected');
}
wasSelector = false;
scanner.next();
break;
default:
wasSelector = true;
args.appendData(getSimpleSelector(true));
}
}
return args;
function getRelativeSelectorListFunction(scope, start, name) {
return getFunctionInternal(function() {
return new List().appendData(getSelectorList(NESTED, RELATIVE));
}, scope, start, name);
}
function getNotFunction(scope, info) {
var selectors;
scanner.eat(LEFTPARENTHESIS);
selectors = getNotFunctionArguments(scope);
scanner.eat(RIGHTPARENTHESIS);
return {
type: 'Negation',
info: info,
// name: name, // TODO: add name?
sequence: selectors // TODO: sequence -> selectors
};
function getVarFunction(scope, start, name) {
return getFunctionInternal(getVarFunctionArguments, scope, start, name);
}

@@ -1119,21 +1256,21 @@

function getVarFunctionArguments() { // TODO: special type Variable?
var sequence = new List();
var children = new List();
readSC();
sequence.appendData(getIdentifier(true));
children.appendData(getIdentifier(true));
readSC();
if (scanner.tokenType === COMMA) {
sequence.appendData(getOperator());
children.appendData(getOperator());
readSC();
sequence.appendData(getValue(true, null));
children.appendData(getValue(true, null));
readSC();
}
return sequence;
return children;
}
// url '(' ws* (string | raw) ws* ')'
function getUri(scope, info) {
function getUri(scope, start) {
var value;

@@ -1147,3 +1284,3 @@

} else {
var start = scanner.tokenStart;
var rawStart = scanner.tokenStart;

@@ -1163,4 +1300,4 @@ // TODO: fix me, looks like incorrect raw scan

type: 'Raw',
info: getInfo(start),
value: scanner.substrToCursor(start)
loc: getLocation(rawStart, scanner.tokenStart),
value: scanner.substrToCursor(rawStart)
};

@@ -1174,3 +1311,3 @@ }

type: 'Url',
info: info,
loc: getLocation(start, scanner.tokenStart),
value: value

@@ -1181,5 +1318,5 @@ };

// expression '(' raw ')'
function getOldIEExpression(scope, info, name) {
var start = scanner.tokenStart + 1; // skip open parenthesis
var raw;
function getOldIEExpression(scope, start, name) {
var rawStart = scanner.tokenStart + 1; // skip open parenthesis
var rawNode;

@@ -1201,3 +1338,7 @@ scanner.eat(LEFTPARENTHESIS);

raw = scanner.substrToCursor(start);
rawNode = {
type: 'Raw',
loc: getLocation(rawStart, scanner.tokenStart),
value: scanner.substrToCursor(rawStart)
};

@@ -1208,11 +1349,23 @@ scanner.eat(RIGHTPARENTHESIS);

type: 'Function',
info: info,
loc: getLocation(start, scanner.tokenStart),
name: name,
sequence: new List().appendData({
type: 'Raw',
value: raw
})
children: new List().appendData(rawNode)
};
}
function scanUnicodeNumber() {
for (var pos = scanner.tokenStart + 1; pos < scanner.tokenEnd; pos++) {
var code = scanner.source.charCodeAt(pos);
// break on fullstop or hyperminus/plussign after exponent
if (code === FULLSTOP || code === PLUSSIGN) {
// break token, exclude symbol
scanner.tokenStart = pos;
return false;
}
}
return true;
}
// https://drafts.csswg.org/css-syntax-3/#urange

@@ -1223,21 +1376,32 @@ function scanUnicodeRange() {

scanner.next(); // always PLUSSIGN or NUMBER
scan: {
if (scanner.tokenType === NUMBER) {
if (scanner.source.charCodeAt(scanner.tokenStart) !== FULLSTOP && scanUnicodeNumber()) {
scanner.next();
} else if (scanner.source.charCodeAt(scanner.tokenStart) !== HYPHENMINUS) {
break scan;
}
} else {
scanner.next(); // PLUSSIGN
}
if (scanner.tokenType === HYPHENMINUS) {
scanner.next();
}
if (scanner.tokenType === HYPHENMINUS) {
scanner.next();
}
if (scanner.tokenType === NUMBER) {
scanner.next();
}
if (scanner.tokenType === NUMBER) {
scanner.next();
}
if (scanner.tokenType === IDENTIFIER) {
scanner.next();
}
if (scanner.tokenType === IDENTIFIER) {
scanner.next();
}
if (scanner.tokenStart === hexStart) {
scanner.error('Unexpected input', hexStart);
if (scanner.tokenStart === hexStart) {
scanner.error('Unexpected input', hexStart);
}
}
// validate hex for U+xxxxxx or U+xxxxxx-xxxxxx
// validate for U+x{1,6} or U+x{1,6}-x{1,6}
// where x is [0-9a-fA-F]
// TODO: check hex sequence length

@@ -1270,2 +1434,7 @@ for (var i = hexStart, wasHyphenMinus = false; i < scanner.tokenStart; i++) {

// check we have a non-zero sequence
if (hexLength === 0) {
scanner.error('Unexpected input', i - 1);
}
// U+abc???

@@ -1292,4 +1461,4 @@ if (!wasHyphenMinus) {

type: 'UnicodeRange',
info: getInfo(start),
name: scanner.substrToCursor(start)
loc: getLocation(start, scanner.tokenStart),
value: scanner.substrToCursor(start)
};

@@ -1360,3 +1529,3 @@ }

type: 'Identifier',
info: getInfo(start),
loc: getLocation(start, scanner.tokenStart),
name: scanner.substrToCursor(start)

@@ -1393,3 +1562,3 @@ };

type: universal ? 'Universal' : 'Type',
info: getInfo(start),
loc: getLocation(start, scanner.tokenStart),
name: scanner.substrToCursor(start)

@@ -1400,6 +1569,9 @@ };

function getIdentifier(varAllowed) {
var start = scanner.tokenStart;
var name = readIdent(varAllowed);
return {
type: 'Identifier',
info: getInfo(),
name: readIdent(varAllowed)
loc: getLocation(start, scanner.tokenStart),
name: name
};

@@ -1420,6 +1592,22 @@ }

function checkTokenIsInteger() {
var pos = scanner.tokenStart;
if (scanner.source.charCodeAt(pos) === PLUSSIGN ||
scanner.source.charCodeAt(pos) === HYPHENMINUS) {
pos++;
}
for (; pos < scanner.tokenEnd; pos++) {
if (!isNumber(scanner.source.charCodeAt(pos))) {
scanner.error('Unexpected input', pos);
}
}
}
// https://drafts.csswg.org/css-syntax-3/#the-anb-type
function getNthSelector() {
function getNthSelector(allowOfClause) {
var start = scanner.tokenStart;
var sequence = new List();
var selector = null;
var query;
var name;

@@ -1432,16 +1620,16 @@

var nthStart = scanner.tokenStart;
if (scanner.lookupValue(0, 'odd') || scanner.lookupValue(0, 'even')) {
var start = scanner.tokenStart;
var info = getInfo();
scanner.next();
sequence.appendData({
type: 'Nth',
info: info,
value: scanner.substrToCursor(start)
});
query = {
type: 'Identifier',
loc: getLocation(nthStart, scanner.tokenStart),
name: scanner.substrToCursor(nthStart)
};
} else {
// scan An+B microsyntax https://www.w3.org/TR/css-syntax-3/#anb
var prefix = '';
var start = scanner.tokenStart;
var info = getInfo();
var a = null;
var b = null;

@@ -1451,2 +1639,3 @@ if (scanner.tokenType === HYPHENMINUS ||

scanner.tokenType === NUMBER) {
checkTokenIsInteger();
prefix = scanner.getTokenValue();

@@ -1461,26 +1650,19 @@ scanner.next();

sequence.appendData({
type: 'Nth',
info: info,
value: prefix + scanner.source.charAt(scanner.tokenStart)
});
a = prefix === '' || prefix === '+' ? '1' :
prefix === '-' ? '-1' :
prefix;
var len = scanner.tokenEnd - scanner.tokenStart;
if (len > 1) {
var start = scanner.tokenStart;
var bStart = scanner.tokenStart;
// ..n-..
if (scanner.source.charCodeAt(start + 1) !== HYPHENMINUS) {
scanner.error('Unexpected input', start + 1);
if (scanner.source.charCodeAt(bStart + 1) !== HYPHENMINUS) {
scanner.error('Unexpected input', bStart + 1);
}
scanner.tokenStart = start + 1;
sequence.appendData({
type: 'Operator',
info: getInfo(),
value: scanner.source.charAt(start + 1)
});
scanner.tokenStart = bStart + 1;
// ..n-{number}..
if (len > 2) {
for (var i = start + 2; i < scanner.tokenEnd; i++) {
for (var i = bStart + 2; i < scanner.tokenEnd; i++) {
if (!isNumber(scanner.source.charCodeAt(i))) {

@@ -1491,12 +1673,4 @@ scanner.error('Unexpected input', i);

scanner.tokenStart = start + 2;
var info = getInfo();
scanner.next();
sequence.appendData({
type: 'Nth',
info: info,
value: scanner.substrToCursor(start + 2)
});
b = '-' + scanner.substrToCursor(bStart + 2);
} else {

@@ -1512,8 +1686,3 @@ scanner.next();

sequence.appendData({
type: 'Nth',
info: getInfo(),
value: scanner.getTokenValue()
});
b = '-' + scanner.getTokenValue();
scanner.next();

@@ -1528,3 +1697,2 @@ }

scanner.tokenType === PLUSSIGN) {
info = getInfo();
prefix = scanner.getTokenValue();

@@ -1536,31 +1704,25 @@ scanner.next();

if (scanner.tokenType === NUMBER) {
var sign = '';
checkTokenIsInteger();
if (cmpChar(scanner.source, scanner.tokenStart, PLUSSIGN) ||
cmpChar(scanner.source, scanner.tokenStart, HYPHENMINUS)) {
info = getInfo();
sign = scanner.source.charAt(scanner.tokenStart);
// prefix or sign should be specified but not both
if (prefix !== '') {
scanner.error();
}
prefix = scanner.source.charAt(scanner.tokenStart);
scanner.tokenStart++;
}
// prefix or sign should be specified but not both
if (!(prefix === '' ^ sign === '')) {
if (prefix === '') {
// should be an operator before number
scanner.error();
} else if (prefix === '+') {
// plus is using by default
prefix = '';
}
if (sign) {
scanner.tokenStart++;
}
b = prefix + scanner.getTokenValue();
sequence.appendData({
type: 'Operator',
info: info,
value: prefix || sign
});
sequence.appendData({
type: 'Nth',
info: getInfo(),
value: scanner.getTokenValue()
});
scanner.next();

@@ -1574,11 +1736,20 @@ }

sequence.appendData({
type: 'Nth',
info: info,
value: prefix
});
b = prefix;
}
query = {
type: 'An+B',
loc: getLocation(nthStart, scanner.tokenStart),
a: a,
b: b
};
}
readSC();
if (allowOfClause && scanner.lookupValue(0, 'of')) {
scanner.next();
selector = getSelectorList(NESTED);
}
scanner.eat(RIGHTPARENTHESIS);

@@ -1588,5 +1759,9 @@

type: 'PseudoClass',
info: getInfo(start),
loc: getLocation(start, scanner.tokenStart),
name: name,
sequence: sequence
children: new List().appendData({ // TODO: add loc
type: 'Nth',
nth: query,
selector: selector
})
};

@@ -1611,3 +1786,3 @@ }

type: 'Operator',
info: getInfo(start),
loc: getLocation(start, scanner.tokenStart),
value: scanner.substrToCursor(start)

@@ -1666,3 +1841,3 @@ };

type: 'Progid',
info: getInfo(start),
loc: getLocation(start, scanner.tokenStart),
value: scanner.substrToCursor(start)

@@ -1690,5 +1865,11 @@ };

if (cmpStr(scanner.source, scanner.tokenEnd, scanner.tokenEnd + 4, 'nth-')) {
return getNthSelector();
if (scanner.lookupValue(1, 'nth-child') ||
scanner.lookupValue(1, 'nth-last-child')) {
return getNthSelector(true);
}
if (scanner.lookupValue(1, 'nth-of-type') ||
scanner.lookupValue(1, 'nth-last-of-type')) {
return getNthSelector(false);
}
}

@@ -1702,2 +1883,4 @@

var start = scanner.tokenStart;
var name;
var children = null;

@@ -1707,6 +1890,17 @@ scanner.eat(COLON);

// https://drafts.csswg.org/css-scoping/#slotted-pseudo
if (scanner.lookupValue(0, 'slotted')) {
name = readIdent(false);
scanner.eat(LEFTPARENTHESIS);
children = new List().appendData(getCompoundSelector(true));
scanner.eat(RIGHTPARENTHESIS);
} else {
name = readIdent(false);
}
return {
type: 'PseudoElement',
info: getInfo(start),
name: readIdent(false),
loc: getLocation(start, scanner.tokenStart),
name: name,
children: children,
legacy: false

@@ -1723,9 +1917,12 @@ };

var start = scanner.tokenStart;
var name;
scanner.eat(COLON);
name = readIdent(false);
return {
type: 'PseudoElement',
info: getInfo(start),
name: readIdent(false),
loc: getLocation(start, scanner.tokenStart),
name: name,
children: null,
legacy: true

@@ -1743,3 +1940,3 @@ };

if (scanner.tokenType === LEFTPARENTHESIS) {
return getFunction(SCOPE_SELECTOR, getInfo(start), scanner.substrToCursor(start + 1));
return getFunction(SCOPE_SELECTOR, start, scanner.substrToCursor(start + 1));
}

@@ -1749,5 +1946,5 @@

type: 'PseudoClass',
info: getInfo(start),
loc: getLocation(start, scanner.tokenStart),
name: scanner.substrToCursor(start + 1),
sequence: null
children: null
};

@@ -1780,3 +1977,3 @@ }

type: 'String',
info: getInfo(start),
loc: getLocation(start, scanner.tokenStart),
value: scanner.substrToCursor(start)

@@ -1792,12 +1989,36 @@ };

if (scanner.tokenType !== NUMBER &&
scanner.tokenType !== IDENTIFIER) {
scanner.error('Number or identifier is expected');
}
scan:
switch (scanner.tokenType) {
case NUMBER:
if (!isNumber(scanner.source.charCodeAt(scanner.tokenStart))) {
scanner.error('Unexpected input', scanner.tokenStart);
}
scanner.next(); // number or identifier
for (var pos = scanner.tokenStart + 1; pos < scanner.tokenEnd; pos++) {
var code = scanner.source.charCodeAt(pos);
// there was a number before identifier
if (scanner.tokenType === IDENTIFIER) {
scanner.next();
// break on fullstop or hyperminus/plussign after exponent
if (code === FULLSTOP || code === HYPHENMINUS || code === PLUSSIGN) {
// break token, exclude symbol
scanner.tokenStart = pos;
break scan;
}
}
// number contains digits only, go to next token
scanner.next();
// if next token is identifier add it to result
if (scanner.tokenType === IDENTIFIER) {
scanner.next();
}
break;
case IDENTIFIER:
scanner.next(); // add token to result
break;
default:
scanner.error('Number or identifier is expected');
}

@@ -1807,3 +2028,3 @@

type: 'Hash',
info: getInfo(start),
loc: getLocation(start, scanner.tokenStart),
value: scanner.substrToCursor(start + 1) // skip #

@@ -1842,4 +2063,4 @@ };

// fix soft deoptimizations (insufficient type feedback)
parse('a.b#c:e:NOT(a)::g,* b >c+d~e/deep/f,100%{v:1 2em t a(2%, var(--a)) url(..) -foo-bar !important}');
parse('a.b#c:e:Not(a):Nth-child(2n+1)::g,* b >c+d~e/deep/f,100%{v:1 2em t a(2%, var(--a)) url(..) -foo-bar !important}');
module.exports = parse;

@@ -0,1 +1,3 @@

'use strict';
// token types (note: value shouldn't intersect with used char codes)

@@ -2,0 +4,0 @@ var WHITESPACE = 1;

@@ -0,1 +1,3 @@

'use strict';
var MAX_LINE_LENGTH = 100;

@@ -2,0 +4,0 @@ var OFFSET_CORRECTION = 60;

@@ -43,5 +43,4 @@ 'use strict';

var SafeUint32Array = typeof Uint32Array !== 'undefined' ? Uint32Array : Array; // fallback on Array when TypedArray is not supported
var lastIndexOf = Array.prototype.lastIndexOf; // some browser implementations have no TypedArray#lastIndexOf
function computeLines(scanner, source) {
function computeLinesAndColumns(scanner, source) {
var sourceLength = source.length;

@@ -51,5 +50,8 @@ var start = firstCharOffset(source);

var line = scanner.initLine;
var columns = scanner.columns;
var column = scanner.initColumn;
if (lines === null || lines.length < sourceLength + 1) {
lines = new SafeUint32Array(Math.max(sourceLength + 1024, MIN_BUFFER_SIZE));
columns = new SafeUint32Array(lines.length);
}

@@ -61,2 +63,3 @@

lines[i] = line;
columns[i] = column++;

@@ -67,4 +70,7 @@ if (code === N || code === R || code === F) {

lines[i] = line;
columns[i] = column;
}
line++;
column = 1;
}

@@ -74,5 +80,7 @@ }

lines[i] = line;
columns[i] = column;
scanner.lineComputed = true;
scanner.linesAnsColumnsComputed = true;
scanner.lines = lines;
scanner.columns = columns;
}

@@ -156,2 +164,3 @@

this.lines = null;
this.columns = null;

@@ -167,6 +176,4 @@ this.setSource(source || '', initLine, initColumn);

this.initLine = typeof initLine === 'undefined' ? 1 : initLine;
this.initColumn = (typeof initColumn === 'undefined' ? 1 : initColumn) - start;
this.lastLocationLine = this.initLine;
this.lastLocationLineOffset = 1 - this.initColumn;
this.lineComputed = false;
this.initColumn = typeof initColumn === 'undefined' ? 1 : initColumn;
this.linesAnsColumnsComputed = false;

@@ -260,32 +267,32 @@ this.eof = false;

getLocation: function(offset, source) {
if (!this.lineComputed) {
computeLines(this, this.source);
getLocation: function(offset, filename) {
if (!this.linesAnsColumnsComputed) {
computeLinesAndColumns(this, this.source);
}
var line = this.lines[offset];
var column = offset;
var lineOffset;
return {
source: filename,
offset: offset,
line: this.lines[offset],
column: this.columns[offset]
};
},
if (line === this.initLine) {
column += this.initColumn;
} else {
// try get precomputed line offset
if (line === this.lastLocationLine) {
lineOffset = this.lastLocationLineOffset;
} else {
// try avoid to compute line offset since it's expensive for long lines
lineOffset = lastIndexOf.call(this.lines, line - 1, offset);
this.lastLocationLine = line;
this.lastLocationLineOffset = lineOffset;
}
column -= lineOffset;
getLocationRange: function(start, end, filename) {
if (!this.linesAnsColumnsComputed) {
computeLinesAndColumns(this, this.source);
}
return {
source: source,
offset: offset,
line: line,
column: column
source: filename,
start: {
offset: start,
line: this.lines[start],
column: this.columns[start]
},
end: {
offset: end,
line: this.lines[end],
column: this.columns[end]
}
};

@@ -292,0 +299,0 @@ },

@@ -0,1 +1,3 @@

'use strict';
var constants = require('./const');

@@ -2,0 +4,0 @@ var PUNCTUATION = constants.PUNCTUATION;

@@ -0,1 +1,3 @@

'use strict';
var data = require('../../data');

@@ -2,0 +4,0 @@

@@ -0,1 +1,3 @@

'use strict';
var translateSyntax = require('./translate');

@@ -34,3 +36,3 @@ var translateCss = require('../utils/translate');

value.sequence.each(function(node) {
value.children.each(function(node) {
if (badNode === node || (badNode && contains(node, badNode))) {

@@ -52,4 +54,4 @@ errorOffset = css.length;

error.css = css;
error.line = badNode && badNode.info ? badNode.info.line : undefined;
error.column = badNode && badNode.info ? badNode.info.column : undefined;
error.line = badNode && badNode.loc && badNode.loc.start ? badNode.loc.start.line : undefined;
error.column = badNode && badNode.loc && badNode.loc.start ? badNode.loc.start.column : undefined;
error.offset = errorOffset;

@@ -56,0 +58,0 @@ error.message = message + '\n' +

@@ -0,1 +1,3 @@

'use strict';
var names = require('../utils/names.js');

@@ -2,0 +4,0 @@

@@ -0,1 +1,3 @@

'use strict';
module.exports = {

@@ -2,0 +4,0 @@ defaultSyntax: require('./default'),

@@ -0,1 +1,3 @@

'use strict';
var names = require('../utils/names');

@@ -244,3 +246,3 @@ var MULTIPLIER_DEFAULT = {

var res = match(syntax, syntaxNode.sequence, node.data.sequence.head);
var res = match(syntax, syntaxNode.sequence, node.data.children.head);
if (!res.match || res.next) {

@@ -263,3 +265,3 @@ badNode = res.badNode || res.lastNode || (res.next ? res.next.data : null) || node.data;

var res = match(syntax, syntaxNode.sequence, node.data.sequence.head);
var res = match(syntax, syntaxNode.sequence, node.data.children.head);
if (!res.match || res.next) {

@@ -266,0 +268,0 @@ badNode = res.badNode || res.lastNode || (res.next ? res.next.data : null) || node.data; // TODO: case when res.next === null

@@ -0,1 +1,3 @@

'use strict';
var SyntaxParseError = require('./error').SyntaxParseError;

@@ -2,0 +4,0 @@

@@ -0,1 +1,3 @@

'use strict';
var MatchError = require('./error').MatchError;

@@ -50,6 +52,6 @@ var walkAst = require('../utils/walk').all;

result = match(dictionary, dictionary.valueCommonSyntax, value.sequence.head);
result = match(dictionary, dictionary.valueCommonSyntax, value.children.head);
if (!result.match) {
result = syntax.match(value.sequence.head);
result = syntax.match(value.children.head);
if (!result || !result.match) {

@@ -56,0 +58,0 @@ dictionary.lastMatchError = new MatchError('Mismatch', syntax.syntax, value, result.badNode || unwrapNode(result.next));

@@ -0,1 +1,3 @@

'use strict';
function isTokenType(token/*, type, type*/) {

@@ -2,0 +4,0 @@ if (token) {

@@ -0,1 +1,3 @@

'use strict';
module.exports = function walk(node, fn, context) {

@@ -2,0 +4,0 @@ switch (node.type) {

@@ -0,1 +1,3 @@

'use strict';
var List = require('./list');

@@ -2,0 +4,0 @@

@@ -0,1 +1,3 @@

'use strict';
//

@@ -2,0 +4,0 @@ // item item item item

@@ -0,1 +1,3 @@

'use strict';
var hasOwnProperty = Object.prototype.hasOwnProperty;

@@ -2,0 +4,0 @@ var knownKeywords = Object.create(null);

@@ -0,1 +1,3 @@

'use strict';
function each(list) {

@@ -48,3 +50,3 @@ var cursor = list.head;

if (node.expression && !node.expression.sequence.isEmpty()) {
if (node.expression && !node.expression.children.isEmpty()) {
result += ' ' + translate(node.expression);

@@ -62,3 +64,3 @@ }

function translateSimpleSelector(list) {
function translateSelector(list) {
var cursor = list.head;

@@ -91,3 +93,3 @@ var result = '';

case 'StyleSheet':
return each(node.rules);
return each(node.children);

@@ -100,10 +102,10 @@ case 'Atrule':

case 'SelectorList':
return eachDelim(node.children, ',');
case 'Selector':
return eachDelim(node.selectors, ',');
return translateSelector(node.children);
case 'SimpleSelector':
return translateSimpleSelector(node.sequence);
case 'Block':
return eachDelim(node.declarations, ';');
return eachDelim(node.children, ';');

@@ -116,4 +118,11 @@ case 'Declaration':

case 'Value':
return each(node.sequence);
return each(node.children);
case 'Nth':
var result = translate(node.nth);
if (node.selector !== null) {
result += ' of ' + translate(node.selector);
}
return result;
case 'Attribute':

@@ -143,12 +152,12 @@ var result = translate(node.name);

case 'Function':
return node.name + '(' + each(node.sequence) + ')';
return node.name + '(' + each(node.children) + ')';
case 'Negation':
return ':not(' + eachDelim(node.sequence, ',') + ')';
case 'Parentheses':
return '(' + each(node.sequence) + ')';
return '(' + each(node.children) + ')';
case 'Brackets':
return '[' + each(node.children) + ']';
case 'AtruleExpression':
return each(node.sequence);
return each(node.children);

@@ -173,8 +182,5 @@ case 'Url':

case 'UnicodeRange':
return node.name;
case 'PseudoClass':
return node.sequence !== null
? ':' + node.name + '(' + each(node.sequence) + ')'
return node.children !== null
? ':' + node.name + '(' + each(node.children) + ')'
: ':' + node.name;

@@ -185,3 +191,5 @@

? ':' + node.name // :before, :after, :first-letter and :first-line
: '::' + node.name;
: node.children !== null
? '::' + node.name + '(' + each(node.children) + ')'
: '::' + node.name;

@@ -194,2 +202,5 @@ case 'Class':

case 'UnicodeRange':
return node.value;
case 'Hash':

@@ -201,5 +212,26 @@ return '#' + node.value;

case 'Nth':
return node.value;
case 'An+B':
var result = '';
var a = node.a !== null && node.a !== undefined;
var b = node.b !== null && node.b !== undefined;
if (a) {
result += node.a === '+1' || node.a === '1' ? 'n' :
node.a === '-1' ? '-n' :
node.a + 'n';
}
if (a && b) {
if (String(node.b).charAt(0) !== '-' &&
String(node.b).charAt(0) !== '+') {
result += '+';
}
}
if (b) {
result += node.b;
}
return result;
case 'Number':

@@ -206,0 +238,0 @@ return node.value;

@@ -0,1 +1,3 @@

'use strict';
var SourceMapGenerator = require('source-map').SourceMapGenerator;

@@ -86,17 +88,17 @@ var SourceNode = require('source-map').SourceNode;

function createSourceNode(info, children) {
if (info.primary) {
function createSourceNode(loc, children) {
if (loc.primary) {
// special marker node to add several references to original
// var merged = createSourceNode(info.merged, []);
// var merged = createSourceNode(loc.merged, []);
// merged.merged = true;
// children.unshift(merged);
// use recursion, because primary can also has a primary/merged info
return createSourceNode(info.primary, children);
// use recursion, because primary can also has a primary/merged loc
return createSourceNode(loc.primary, children);
}
return new SourceNode(
info.line,
info.column - 1,
info.source,
loc.start ? loc.start.line : null,
loc.start ? loc.start.column - 1 : null,
loc.source,
children

@@ -118,18 +120,6 @@ );

function eachDelim(list, delimeter) {
if (list.head === null) {
return '';
}
if (list.head === list.tail) {
return translate(list.head.data);
}
return list.map(translate).join(delimeter);
}
function translate(node) {
switch (node.type) {
case 'StyleSheet':
return createAnonymousSourceNode(node.rules.map(translate));
return createAnonymousSourceNode(node.children.map(translate));

@@ -139,3 +129,3 @@ case 'Atrule':

if (node.expression && !node.expression.sequence.isEmpty()) {
if (node.expression && !node.expression.children.isEmpty()) {
nodes.push(' ', translate(node.expression));

@@ -150,3 +140,3 @@ }

return createSourceNode(node.info, nodes);
return createSourceNode(node.loc, nodes);

@@ -158,7 +148,7 @@ case 'Rule':

case 'SelectorList':
return createAnonymousSourceNode(node.children.map(translate)).join(',');
case 'Selector':
return createAnonymousSourceNode(node.selectors.map(translate)).join(',');
case 'SimpleSelector':
var nodes = node.sequence.map(function(node) {
var nodes = node.children.map(function(node) {
// add extra spaces around /deep/ combinator since comment beginning/ending may to be produced

@@ -172,6 +162,6 @@ if (node.type === 'Combinator' && node.name === '/deep/') {

return createSourceNode(node.info, nodes);
return createSourceNode(node.loc, nodes);
case 'Block':
return createAnonymousSourceNode(node.declarations.map(translate)).join(';');
return createAnonymousSourceNode(node.children.map(translate)).join(';');

@@ -181,3 +171,3 @@ case 'Declaration':

return createSourceNode(
node.info,
node.loc,
[node.property, ':', translate(node.value), '!important']

@@ -187,3 +177,3 @@ );

return createSourceNode(
node.info,
node.loc,
[node.property, ':', translate(node.value)]

@@ -194,4 +184,11 @@ );

case 'Value':
return each(node.sequence);
return each(node.children);
case 'Nth':
var nodes = [translate(node.nth)];
if (node.selector !== null) {
nodes.push(' of ', translate(node.selector));
}
return createAnonymousSourceNode(nodes);
case 'Attribute':

@@ -221,12 +218,12 @@ var result = translate(node.name);

case 'Function':
return node.name + '(' + each(node.sequence) + ')';
return node.name + '(' + each(node.children) + ')';
case 'Negation':
return ':not(' + eachDelim(node.sequence, ',') + ')';
case 'Parentheses':
return '(' + each(node.sequence) + ')';
return '(' + each(node.children) + ')';
case 'Brackets':
return '[' + each(node.children) + ']';
case 'AtruleExpression':
return each(node.sequence);
return each(node.children);

@@ -251,8 +248,5 @@ case 'Url':

case 'UnicodeRange':
return node.name;
case 'PseudoClass':
return node.sequence !== null
? ':' + node.name + '(' + each(node.sequence) + ')'
return node.children !== null
? ':' + node.name + '(' + each(node.children) + ')'
: ':' + node.name;

@@ -263,3 +257,5 @@

? ':' + node.name // :before, :after, :first-letter and :first-line
: '::' + node.name;
: node.children !== null
? '::' + node.name + '(' + each(node.children) + ')'
: '::' + node.name;

@@ -272,2 +268,5 @@ case 'Class':

case 'UnicodeRange':
return node.value;
case 'Hash':

@@ -279,5 +278,26 @@ return '#' + node.value;

case 'Nth':
return node.value;
case 'An+B':
var result = '';
var a = node.a !== null && node.a !== undefined;
var b = node.b !== null && node.b !== undefined;
if (a) {
result += node.a === '+1' || node.a === '1' ? 'n' :
node.a === '-1' ? '-n' :
node.a + 'n';
}
if (a && b) {
if (String(node.b).charAt(0) !== '-' &&
String(node.b).charAt(0) !== '+') {
result += '+';
}
}
if (b) {
result += node.b;
}
return result;
case 'Number':

@@ -284,0 +304,0 @@ return node.value;

@@ -0,1 +1,3 @@

'use strict';
function walkRules(node, item, list) {

@@ -7,3 +9,3 @@ switch (node.type) {

node.rules.each(walkRules, this);
node.children.each(walkRules, this);

@@ -23,2 +25,9 @@ this.stylesheet = oldStylesheet;

this.fn(node, item, list);
var oldRule = this.rule;
this.rule = node;
node.block.children.each(walkRules, this);
this.rule = oldRule;
break;

@@ -35,3 +44,3 @@ }

node.rules.eachRight(walkRulesRight, this);
node.children.eachRight(walkRulesRight, this);

@@ -50,2 +59,9 @@ this.stylesheet = oldStylesheet;

case 'Rule':
var oldRule = this.rule;
this.rule = node;
node.block.children.eachRight(walkRulesRight, this);
this.rule = oldRule;
this.fn(node, item, list);

@@ -62,3 +78,3 @@ break;

node.rules.each(walkDeclarations, this);
node.children.each(walkDeclarations, this);

@@ -69,3 +85,3 @@ this.stylesheet = oldStylesheet;

case 'Atrule':
if (node.block !== null && node.block.type === 'StyleSheet') {
if (node.block !== null) {
walkDeclarations.call(this, node.block);

@@ -76,10 +92,21 @@ }

case 'Rule':
var oldRule = this.rule;
this.rule = node;
if (node.block !== null) {
node.block.declarations.each(this.fn);
walkDeclarations.call(this, node.block);
}
this.rule = null;
this.rule = oldRule;
break;
case 'Block':
node.children.each(function(node, item, list) {
if (node.type === 'Declaration') {
this.fn(node, item, list);
} else {
walkDeclarations.call(this, node);
}
}, this);
break;
}

@@ -104,3 +131,3 @@ }

node.rules.each(walk, this);
node.children.each(walk, this);

@@ -130,7 +157,7 @@ this.stylesheet = oldStylesheet;

case 'Selector':
case 'SelectorList':
var oldSelector = this.selector;
this.selector = node;
node.selectors.each(walk, this);
node.children.each(walk, this);

@@ -140,4 +167,11 @@ this.selector = oldSelector;

case 'Nth':
walk.call(this, node.nth);
if (node.selector !== null) {
walk.call(this, node.selector);
}
break;
case 'Block':
node.declarations.each(walk, this);
node.children.each(walk, this);
break;

@@ -161,6 +195,6 @@

case 'PseudoClass':
if (node.sequence !== null) {
if (node.children !== null) {
this['function'] = node;
node.sequence.each(walk, this);
node.children.each(walk, this);

@@ -171,6 +205,16 @@ this['function'] = null;

case 'PseudoElement':
if (node.children !== null) {
this['function'] = node;
node.children.each(walk, this);
this['function'] = null;
}
break;
case 'Function':
this['function'] = node;
node.sequence.each(walk, this);
node.children.each(walk, this);

@@ -183,3 +227,3 @@ this['function'] = null;

node.sequence.each(walk, this);
node.children.each(walk, this);

@@ -189,8 +233,7 @@ this.atruleExpression = null;

case 'Selector':
case 'Value':
case 'Argument':
case 'SimpleSelector':
case 'Parentheses':
case 'Negation':
node.sequence.each(walk, this);
case 'Brackets':
node.children.each(walk, this);
break;

@@ -212,8 +255,6 @@

// case 'UnicodeRange':
// case 'Nth':
// case 'An+B':
// case 'Class':
// case 'Id':
// case 'Percentage':
// case 'PseudoClass':
// case 'PseudoElement':
// case 'Space':

@@ -220,0 +261,0 @@ // case 'Number':

{
"name": "css-tree",
"version": "1.0.0-alpha10",
"description": "Detailed CSS parser",
"version": "1.0.0-alpha11",
"description": "Fast detailed CSS parser",
"keywords": [

@@ -6,0 +6,0 @@ "css",

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc