File: /var/www/quadcode/frontend/node_modules/csso/src/gonzales.cssp.web.js
function srcToCSSP(s, rule, _needInfo) {
var TokenType = {
StringSQ: 'StringSQ',
StringDQ: 'StringDQ',
CommentML: 'CommentML',
CommentSL: 'CommentSL',
Newline: 'Newline',
Space: 'Space',
Tab: 'Tab',
ExclamationMark: 'ExclamationMark', // !
QuotationMark: 'QuotationMark', // "
NumberSign: 'NumberSign', // #
DollarSign: 'DollarSign', // $
PercentSign: 'PercentSign', // %
Ampersand: 'Ampersand', // &
Apostrophe: 'Apostrophe', // '
LeftParenthesis: 'LeftParenthesis', // (
RightParenthesis: 'RightParenthesis', // )
Asterisk: 'Asterisk', // *
PlusSign: 'PlusSign', // +
Comma: 'Comma', // ,
HyphenMinus: 'HyphenMinus', // -
FullStop: 'FullStop', // .
Solidus: 'Solidus', // /
Colon: 'Colon', // :
Semicolon: 'Semicolon', // ;
LessThanSign: 'LessThanSign', // <
EqualsSign: 'EqualsSign', // =
GreaterThanSign: 'GreaterThanSign', // >
QuestionMark: 'QuestionMark', // ?
CommercialAt: 'CommercialAt', // @
LeftSquareBracket: 'LeftSquareBracket', // [
ReverseSolidus: 'ReverseSolidus', // \
RightSquareBracket: 'RightSquareBracket', // ]
CircumflexAccent: 'CircumflexAccent', // ^
LowLine: 'LowLine', // _
LeftCurlyBracket: 'LeftCurlyBracket', // {
VerticalLine: 'VerticalLine', // |
RightCurlyBracket: 'RightCurlyBracket', // }
Tilde: 'Tilde', // ~
Identifier: 'Identifier',
DecimalNumber: 'DecimalNumber'
};
function getTokens(s) {
var Punctuation,
urlMode = false,
blockMode = 0;
Punctuation = {
' ': TokenType.Space,
'\n': TokenType.Newline,
'\r': TokenType.Newline,
'\t': TokenType.Tab,
'!': TokenType.ExclamationMark,
'"': TokenType.QuotationMark,
'#': TokenType.NumberSign,
'$': TokenType.DollarSign,
'%': TokenType.PercentSign,
'&': TokenType.Ampersand,
'\'': TokenType.Apostrophe,
'(': TokenType.LeftParenthesis,
')': TokenType.RightParenthesis,
'*': TokenType.Asterisk,
'+': TokenType.PlusSign,
',': TokenType.Comma,
'-': TokenType.HyphenMinus,
'.': TokenType.FullStop,
'/': TokenType.Solidus,
':': TokenType.Colon,
';': TokenType.Semicolon,
'<': TokenType.LessThanSign,
'=': TokenType.EqualsSign,
'>': TokenType.GreaterThanSign,
'?': TokenType.QuestionMark,
'@': TokenType.CommercialAt,
'[': TokenType.LeftSquareBracket,
// '\\': TokenType.ReverseSolidus,
']': TokenType.RightSquareBracket,
'^': TokenType.CircumflexAccent,
'_': TokenType.LowLine,
'{': TokenType.LeftCurlyBracket,
'|': TokenType.VerticalLine,
'}': TokenType.RightCurlyBracket,
'~': TokenType.Tilde
};
function isDecimalDigit(c) {
return '0123456789'.indexOf(c) >= 0;
}
function throwError(message) {
throw message;
}
var buffer = '',
tokens = [],
pos,
tn = 0,
ln = 1;
function _getTokens(s) {
if (!s) return [];
tokens = [];
var c, cn;
for (pos = 0; pos < s.length; pos++) {
c = s.charAt(pos);
cn = s.charAt(pos + 1);
if (c === '/' && cn === '*') {
parseMLComment(s);
} else if (!urlMode && c === '/' && cn === '/') {
if (blockMode > 0) parseIdentifier(s);
else parseSLComment(s);
} else if (c === '"' || c === "'") {
parseString(s, c);
} else if (c === ' ') {
parseSpaces(s)
} else if (c in Punctuation) {
pushToken(Punctuation[c], c);
if (c === '\n' || c === '\r') ln++;
if (c === ')') urlMode = false;
if (c === '{') blockMode++;
if (c === '}') blockMode--;
} else if (isDecimalDigit(c)) {
parseDecimalNumber(s);
} else {
parseIdentifier(s);
}
}
mark();
return tokens;
}
function pushToken(type, value) {
tokens.push({ tn: tn++, ln: ln, type: type, value: value });
}
function parseSpaces(s) {
var start = pos;
for (; pos < s.length; pos++) {
if (s.charAt(pos) !== ' ') break;
}
pushToken(TokenType.Space, s.substring(start, pos));
pos--;
}
function parseMLComment(s) {
var start = pos;
for (pos = pos + 2; pos < s.length; pos++) {
if (s.charAt(pos) === '*') {
if (s.charAt(pos + 1) === '/') {
pos++;
break;
}
}
}
pushToken(TokenType.CommentML, s.substring(start, pos + 1));
}
function parseSLComment(s) {
var start = pos;
for (pos = pos + 2; pos < s.length; pos++) {
if (s.charAt(pos) === '\n' || s.charAt(pos) === '\r') {
pos++;
break;
}
}
pushToken(TokenType.CommentSL, s.substring(start, pos));
pos--;
}
function parseString(s, q) {
var start = pos;
for (pos = pos + 1; pos < s.length; pos++) {
if (s.charAt(pos) === '\\') pos++;
else if (s.charAt(pos) === q) break;
}
pushToken(q === '"' ? TokenType.StringDQ : TokenType.StringSQ, s.substring(start, pos + 1));
}
function parseDecimalNumber(s) {
var start = pos;
for (; pos < s.length; pos++) {
if (!isDecimalDigit(s.charAt(pos))) break;
}
pushToken(TokenType.DecimalNumber, s.substring(start, pos));
pos--;
}
function parseIdentifier(s) {
var start = pos;
while (s.charAt(pos) === '/') pos++;
for (; pos < s.length; pos++) {
if (s.charAt(pos) === '\\') pos++;
else if (s.charAt(pos) in Punctuation) break;
}
var ident = s.substring(start, pos);
urlMode = urlMode || ident === 'url';
pushToken(TokenType.Identifier, ident);
pos--;
}
// ====================================
// second run
// ====================================
function mark() {
var ps = [], // Parenthesis
sbs = [], // SquareBracket
cbs = [], // CurlyBracket
t;
for (var i = 0; i < tokens.length; i++) {
t = tokens[i];
switch(t.type) {
case TokenType.LeftParenthesis:
ps.push(i);
break;
case TokenType.RightParenthesis:
if (ps.length) {
t.left = ps.pop();
tokens[t.left].right = i;
}
break;
case TokenType.LeftSquareBracket:
sbs.push(i);
break;
case TokenType.RightSquareBracket:
if (sbs.length) {
t.left = sbs.pop();
tokens[t.left].right = i;
}
break;
case TokenType.LeftCurlyBracket:
cbs.push(i);
break;
case TokenType.RightCurlyBracket:
if (cbs.length) {
t.left = cbs.pop();
tokens[t.left].right = i;
}
break;
}
}
}
return _getTokens(s);
}
// version: 1.0.0
function getCSSPAST(_tokens, rule, _needInfo) {
var tokens,
pos,
failLN = 0,
currentBlockLN = 0,
needInfo = false;
var CSSPNodeType,
CSSLevel,
CSSPRules;
CSSPNodeType = {
IdentType: 'ident',
AtkeywordType: 'atkeyword',
StringType: 'string',
ShashType: 'shash',
VhashType: 'vhash',
NumberType: 'number',
PercentageType: 'percentage',
DimensionType: 'dimension',
CdoType: 'cdo',
CdcType: 'cdc',
DecldelimType: 'decldelim',
SType: 's',
AttrselectorType: 'attrselector',
AttribType: 'attrib',
NthType: 'nth',
NthselectorType: 'nthselector',
NamespaceType: 'namespace',
ClazzType: 'clazz',
PseudoeType: 'pseudoe',
PseudocType: 'pseudoc',
DelimType: 'delim',
StylesheetType: 'stylesheet',
AtrulebType: 'atruleb',
AtrulesType: 'atrules',
AtrulerqType: 'atrulerq',
AtrulersType: 'atrulers',
AtrulerType: 'atruler',
BlockType: 'block',
RulesetType: 'ruleset',
CombinatorType: 'combinator',
SimpleselectorType: 'simpleselector',
SelectorType: 'selector',
DeclarationType: 'declaration',
PropertyType: 'property',
ImportantType: 'important',
UnaryType: 'unary',
OperatorType: 'operator',
BracesType: 'braces',
ValueType: 'value',
ProgidType: 'progid',
FiltervType: 'filterv',
FilterType: 'filter',
CommentType: 'comment',
UriType: 'uri',
RawType: 'raw',
FunctionBodyType: 'functionBody',
FunktionType: 'funktion',
FunctionExpressionType: 'functionExpression',
UnknownType: 'unknown'
};
CSSPRules = {
'ident': function() { if (checkIdent(pos)) return getIdent() },
'atkeyword': function() { if (checkAtkeyword(pos)) return getAtkeyword() },
'string': function() { if (checkString(pos)) return getString() },
'shash': function() { if (checkShash(pos)) return getShash() },
'vhash': function() { if (checkVhash(pos)) return getVhash() },
'number': function() { if (checkNumber(pos)) return getNumber() },
'percentage': function() { if (checkPercentage(pos)) return getPercentage() },
'dimension': function() { if (checkDimension(pos)) return getDimension() },
// 'cdo': function() { if (checkCDO()) return getCDO() },
// 'cdc': function() { if (checkCDC()) return getCDC() },
'decldelim': function() { if (checkDecldelim(pos)) return getDecldelim() },
's': function() { if (checkS(pos)) return getS() },
'attrselector': function() { if (checkAttrselector(pos)) return getAttrselector() },
'attrib': function() { if (checkAttrib(pos)) return getAttrib() },
'nth': function() { if (checkNth(pos)) return getNth() },
'nthselector': function() { if (checkNthselector(pos)) return getNthselector() },
'namespace': function() { if (checkNamespace(pos)) return getNamespace() },
'clazz': function() { if (checkClazz(pos)) return getClazz() },
'pseudoe': function() { if (checkPseudoe(pos)) return getPseudoe() },
'pseudoc': function() { if (checkPseudoc(pos)) return getPseudoc() },
'delim': function() { if (checkDelim(pos)) return getDelim() },
'stylesheet': function() { if (checkStylesheet(pos)) return getStylesheet() },
'atruleb': function() { if (checkAtruleb(pos)) return getAtruleb() },
'atrules': function() { if (checkAtrules(pos)) return getAtrules() },
'atrulerq': function() { if (checkAtrulerq(pos)) return getAtrulerq() },
'atrulers': function() { if (checkAtrulers(pos)) return getAtrulers() },
'atruler': function() { if (checkAtruler(pos)) return getAtruler() },
'block': function() { if (checkBlock(pos)) return getBlock() },
'ruleset': function() { if (checkRuleset(pos)) return getRuleset() },
'combinator': function() { if (checkCombinator(pos)) return getCombinator() },
'simpleselector': function() { if (checkSimpleselector(pos)) return getSimpleSelector() },
'selector': function() { if (checkSelector(pos)) return getSelector() },
'declaration': function() { if (checkDeclaration(pos)) return getDeclaration() },
'property': function() { if (checkProperty(pos)) return getProperty() },
'important': function() { if (checkImportant(pos)) return getImportant() },
'unary': function() { if (checkUnary(pos)) return getUnary() },
'operator': function() { if (checkOperator(pos)) return getOperator() },
'braces': function() { if (checkBraces(pos)) return getBraces() },
'value': function() { if (checkValue(pos)) return getValue() },
'progid': function() { if (checkProgid(pos)) return getProgid() },
'filterv': function() { if (checkFilterv(pos)) return getFilterv() },
'filter': function() { if (checkFilter(pos)) return getFilter() },
'comment': function() { if (checkComment(pos)) return getComment() },
'uri': function() { if (checkUri(pos)) return getUri() },
'raw': function() { if (checkRaw(pos)) return getRaw() },
'funktion': function() { if (checkFunktion(pos)) return getFunktion() },
'functionExpression': function() { if (checkFunctionExpression(pos)) return getFunctionExpression() },
'unknown': function() { if (checkUnknown(pos)) return getUnknown() }
};
function fail(token) {
if (token && token.ln > failLN) failLN = token.ln;
}
function throwError() {
console.error('Please check the validity of the CSS block starting from the line #' + currentBlockLN);
if (process) process.exit(1);
throw new Error();
}
function _getAST(_tokens, rule, _needInfo) {
tokens = _tokens;
needInfo = _needInfo;
pos = 0;
markSC();
return rule ? CSSPRules[rule]() : CSSPRules['stylesheet']();
}
//any = braces | string | percentage | dimension | number | uri | functionExpression | funktion | ident | unary
function checkAny(_i) {
return checkBraces(_i) ||
checkString(_i) ||
checkPercentage(_i) ||
checkDimension(_i) ||
checkNumber(_i) ||
checkUri(_i) ||
checkFunctionExpression(_i) ||
checkFunktion(_i) ||
checkIdent(_i) ||
checkUnary(_i);
}
function getAny() {
if (checkBraces(pos)) return getBraces();
else if (checkString(pos)) return getString();
else if (checkPercentage(pos)) return getPercentage();
else if (checkDimension(pos)) return getDimension();
else if (checkNumber(pos)) return getNumber();
else if (checkUri(pos)) return getUri();
else if (checkFunctionExpression(pos)) return getFunctionExpression();
else if (checkFunktion(pos)) return getFunktion();
else if (checkIdent(pos)) return getIdent();
else if (checkUnary(pos)) return getUnary();
}
//atkeyword = '@' ident:x -> [#atkeyword, x]
function checkAtkeyword(_i) {
var l;
if (tokens[_i++].type !== TokenType.CommercialAt) return fail(tokens[_i - 1]);
if (l = checkIdent(_i)) return l + 1;
return fail(tokens[_i]);
}
function getAtkeyword() {
var startPos = pos;
pos++;
return needInfo?
[{ ln: tokens[startPos].ln }, CSSPNodeType.AtkeywordType, getIdent()]:
[CSSPNodeType.AtkeywordType, getIdent()];
}
//attrib = '[' sc*:s0 ident:x sc*:s1 attrselector:a sc*:s2 (ident | string):y sc*:s3 ']' -> this.concat([#attrib], s0, [x], s1, [a], s2, [y], s3)
// | '[' sc*:s0 ident:x sc*:s1 ']' -> this.concat([#attrib], s0, [x], s1),
function checkAttrib(_i) {
if (tokens[_i].type !== TokenType.LeftSquareBracket) return fail(tokens[_i]);
if (!tokens[_i].right) return fail(tokens[_i]);
return tokens[_i].right - _i + 1;
}
function checkAttrib1(_i) {
var start = _i;
_i++;
var l = checkSC(_i); // s0
if (l) _i += l;
if (l = checkIdent(_i)) _i += l; // x
else return fail(tokens[_i]);
if (l = checkSC(_i)) _i += l; // s1
if (l = checkAttrselector(_i)) _i += l; // a
else return fail(tokens[_i]);
if (l = checkSC(_i)) _i += l; // s2
if ((l = checkIdent(_i)) || (l = checkString(_i))) _i += l; // y
else return fail(tokens[_i]);
if (l = checkSC(_i)) _i += l; // s3
if (tokens[_i].type === TokenType.RightSquareBracket) return _i - start;
return fail(tokens[_i]);
}
function getAttrib1() {
var startPos = pos;
pos++;
var a = (needInfo? [{ ln: tokens[startPos].ln }, CSSPNodeType.AttribType] : [CSSPNodeType.AttribType])
.concat(getSC())
.concat([getIdent()])
.concat(getSC())
.concat([getAttrselector()])
.concat(getSC())
.concat([checkString(pos)? getString() : getIdent()])
.concat(getSC());
pos++;
return a;
}
function checkAttrib2(_i) {
var start = _i;
_i++;
var l = checkSC(_i);
if (l) _i += l;
if (l = checkIdent(_i)) _i += l;
if (l = checkSC(_i)) _i += l;
if (tokens[_i].type === TokenType.RightSquareBracket) return _i - start;
return fail(tokens[_i]);
}
function getAttrib2() {
var startPos = pos;
pos++;
var a = (needInfo? [{ ln: tokens[startPos].ln }, CSSPNodeType.AttribType] : [CSSPNodeType.AttribType])
.concat(getSC())
.concat([getIdent()])
.concat(getSC());
pos++;
return a;
}
function getAttrib() {
if (checkAttrib1(pos)) return getAttrib1();
if (checkAttrib2(pos)) return getAttrib2();
}
//attrselector = (seq('=') | seq('~=') | seq('^=') | seq('$=') | seq('*=') | seq('|=')):x -> [#attrselector, x]
function checkAttrselector(_i) {
if (tokens[_i].type === TokenType.EqualsSign) return 1;
if (tokens[_i].type === TokenType.VerticalLine && (!tokens[_i + 1] || tokens[_i + 1].type !== TokenType.EqualsSign)) return 1;
if (!tokens[_i + 1] || tokens[_i + 1].type !== TokenType.EqualsSign) return fail(tokens[_i]);
switch(tokens[_i].type) {
case TokenType.Tilde:
case TokenType.CircumflexAccent:
case TokenType.DollarSign:
case TokenType.Asterisk:
case TokenType.VerticalLine:
return 2;
}
return fail(tokens[_i]);
}
function getAttrselector() {
var startPos = pos,
s = tokens[pos++].value;
if (tokens[pos] && tokens[pos].type === TokenType.EqualsSign) s += tokens[pos++].value;
return needInfo?
[{ ln: tokens[startPos].ln }, CSSPNodeType.AttrselectorType, s] :
[CSSPNodeType.AttrselectorType, s];
}
//atrule = atruler | atruleb | atrules
function checkAtrule(_i) {
var start = _i,
l;
if (tokens[start].atrule_l !== undefined) return tokens[start].atrule_l;
if (l = checkAtruler(_i)) tokens[_i].atrule_type = 1;
else if (l = checkAtruleb(_i)) tokens[_i].atrule_type = 2;
else if (l = checkAtrules(_i)) tokens[_i].atrule_type = 3;
else return fail(tokens[start]);
tokens[start].atrule_l = l;
return l;
}
function getAtrule() {
switch (tokens[pos].atrule_type) {
case 1: return getAtruler();
case 2: return getAtruleb();
case 3: return getAtrules();
}
}
//atruleb = atkeyword:ak tset*:ap block:b -> this.concat([#atruleb, ak], ap, [b])
function checkAtruleb(_i) {
var start = _i,
l;
if (l = checkAtkeyword(_i)) _i += l;
else return fail(tokens[_i]);
if (l = checkTsets(_i)) _i += l;
if (l = checkBlock(_i)) _i += l;
else return fail(tokens[_i]);
return _i - start;
}
function getAtruleb() {
return (needInfo?
[{ ln: tokens[pos].ln }, CSSPNodeType.AtrulebType, getAtkeyword()] :
[CSSPNodeType.AtrulebType, getAtkeyword()])
.concat(getTsets())
.concat([getBlock()]);
}
//atruler = atkeyword:ak atrulerq:x '{' atrulers:y '}' -> [#atruler, ak, x, y]
function checkAtruler(_i) {
var start = _i,
l;
if (l = checkAtkeyword(_i)) _i += l;
else return fail(tokens[_i]);
if (l = checkAtrulerq(_i)) _i += l;
if (_i < tokens.length && tokens[_i].type === TokenType.LeftCurlyBracket) _i++;
else return fail(tokens[_i]);
if (l = checkAtrulers(_i)) _i += l;
if (_i < tokens.length && tokens[_i].type === TokenType.RightCurlyBracket) _i++;
else return fail(tokens[_i]);
return _i - start;
}
function getAtruler() {
var atruler = needInfo?
[{ ln: tokens[pos].ln }, CSSPNodeType.AtrulerType, getAtkeyword(), getAtrulerq()] :
[CSSPNodeType.AtrulerType, getAtkeyword(), getAtrulerq()];
pos++;
atruler.push(getAtrulers());
pos++;
return atruler;
}
//atrulerq = tset*:ap -> [#atrulerq].concat(ap)
function checkAtrulerq(_i) {
return checkTsets(_i);
}
function getAtrulerq() {
return (needInfo? [{ ln: tokens[pos].ln }, CSSPNodeType.AtrulerqType] : [CSSPNodeType.AtrulerqType]).concat(getTsets());
}
//atrulers = sc*:s0 ruleset*:r sc*:s1 -> this.concat([#atrulers], s0, r, s1)
function checkAtrulers(_i) {
var start = _i,
l;
if (l = checkSC(_i)) _i += l;
while ((l = checkRuleset(_i)) || (l = checkAtrule(_i)) || (l = checkSC(_i))) {
_i += l;
}
tokens[_i].atrulers_end = 1;
if (l = checkSC(_i)) _i += l;
return _i - start;
}
function getAtrulers() {
var atrulers = (needInfo? [{ ln: tokens[pos].ln }, CSSPNodeType.AtrulersType] : [CSSPNodeType.AtrulersType]).concat(getSC()),
x;
while (!tokens[pos].atrulers_end) {
if (checkSC(pos)) {
atrulers = atrulers.concat(getSC());
} else if (checkRuleset(pos)) {
atrulers.push(getRuleset());
} else {
atrulers.push(getAtrule());
}
}
return atrulers.concat(getSC());
}
//atrules = atkeyword:ak tset*:ap ';' -> this.concat([#atrules, ak], ap)
function checkAtrules(_i) {
var start = _i,
l;
if (l = checkAtkeyword(_i)) _i += l;
else return fail(tokens[_i]);
if (l = checkTsets(_i)) _i += l;
if (_i >= tokens.length) return _i - start;
if (tokens[_i].type === TokenType.Semicolon) _i++;
else return fail(tokens[_i]);
return _i - start;
}
function getAtrules() {
var atrules = (needInfo? [{ ln: tokens[pos].ln }, CSSPNodeType.AtrulesType, getAtkeyword()] : [CSSPNodeType.AtrulesType, getAtkeyword()]).concat(getTsets());
pos++;
return atrules;
}
//block = '{' blockdecl*:x '}' -> this.concatContent([#block], x)
function checkBlock(_i) {
if (_i < tokens.length && tokens[_i].type === TokenType.LeftCurlyBracket) return tokens[_i].right - _i + 1;
return fail(tokens[_i]);
}
function getBlock() {
var block = needInfo? [{ ln: tokens[pos].ln }, CSSPNodeType.BlockType] : [CSSPNodeType.BlockType],
end = tokens[pos].right;
pos++;
while (pos < end) {
if (checkBlockdecl(pos)) block = block.concat(getBlockdecl());
else throwError();
}
pos = end + 1;
return block;
}
//blockdecl = sc*:s0 (filter | declaration):x decldelim:y sc*:s1 -> this.concat(s0, [x], [y], s1)
// | sc*:s0 (filter | declaration):x sc*:s1 -> this.concat(s0, [x], s1)
// | sc*:s0 decldelim:x sc*:s1 -> this.concat(s0, [x], s1)
// | sc+:s0 -> s0
function checkBlockdecl(_i) {
var l;
if (l = _checkBlockdecl0(_i)) tokens[_i].bd_type = 1;
else if (l = _checkBlockdecl1(_i)) tokens[_i].bd_type = 2;
else if (l = _checkBlockdecl2(_i)) tokens[_i].bd_type = 3;
else if (l = _checkBlockdecl3(_i)) tokens[_i].bd_type = 4;
else return fail(tokens[_i]);
return l;
}
function getBlockdecl() {
switch (tokens[pos].bd_type) {
case 1: return _getBlockdecl0();
case 2: return _getBlockdecl1();
case 3: return _getBlockdecl2();
case 4: return _getBlockdecl3();
}
}
//sc*:s0 (filter | declaration):x decldelim:y sc*:s1 -> this.concat(s0, [x], [y], s1)
function _checkBlockdecl0(_i) {
var start = _i,
l;
if (l = checkSC(_i)) _i += l;
if (l = checkFilter(_i)) {
tokens[_i].bd_filter = 1;
_i += l;
} else if (l = checkDeclaration(_i)) {
tokens[_i].bd_decl = 1;
_i += l;
} else return fail(tokens[_i]);
if (_i < tokens.length && (l = checkDecldelim(_i))) _i += l;
else return fail(tokens[_i]);
if (l = checkSC(_i)) _i += l;
return _i - start;
}
function _getBlockdecl0() {
return getSC()
.concat([tokens[pos].bd_filter? getFilter() : getDeclaration()])
.concat([getDecldelim()])
.concat(getSC());
}
//sc*:s0 (filter | declaration):x sc*:s1 -> this.concat(s0, [x], s1)
function _checkBlockdecl1(_i) {
var start = _i,
l;
if (l = checkSC(_i)) _i += l;
if (l = checkFilter(_i)) {
tokens[_i].bd_filter = 1;
_i += l;
} else if (l = checkDeclaration(_i)) {
tokens[_i].bd_decl = 1;
_i += l;
} else return fail(tokens[_i]);
if (l = checkSC(_i)) _i += l;
return _i - start;
}
function _getBlockdecl1() {
return getSC()
.concat([tokens[pos].bd_filter? getFilter() : getDeclaration()])
.concat(getSC());
}
//sc*:s0 decldelim:x sc*:s1 -> this.concat(s0, [x], s1)
function _checkBlockdecl2(_i) {
var start = _i,
l;
if (l = checkSC(_i)) _i += l;
if (l = checkDecldelim(_i)) _i += l;
else return fail(tokens[_i]);
if (l = checkSC(_i)) _i += l;
return _i - start;
}
function _getBlockdecl2() {
return getSC()
.concat([getDecldelim()])
.concat(getSC());
}
//sc+:s0 -> s0
function _checkBlockdecl3(_i) {
return checkSC(_i);
}
function _getBlockdecl3() {
return getSC();
}
//braces = '(' tset*:x ')' -> this.concat([#braces, '(', ')'], x)
// | '[' tset*:x ']' -> this.concat([#braces, '[', ']'], x)
function checkBraces(_i) {
if (_i >= tokens.length ||
(tokens[_i].type !== TokenType.LeftParenthesis &&
tokens[_i].type !== TokenType.LeftSquareBracket)
) return fail(tokens[_i]);
return tokens[_i].right - _i + 1;
}
function getBraces() {
var startPos = pos,
left = pos,
right = tokens[pos].right;
pos++;
var tsets = getTsets();
pos++;
return needInfo?
[{ ln: tokens[startPos].ln }, CSSPNodeType.BracesType, tokens[left].value, tokens[right].value].concat(tsets) :
[CSSPNodeType.BracesType, tokens[left].value, tokens[right].value].concat(tsets);
}
function checkCDC(_i) {}
function checkCDO(_i) {}
// node: Clazz
function checkClazz(_i) {
var l;
if (tokens[_i].clazz_l) return tokens[_i].clazz_l;
if (tokens[_i].type === TokenType.FullStop) {
if (l = checkIdent(_i + 1)) {
tokens[_i].clazz_l = l + 1;
return l + 1;
}
}
return fail(tokens[_i]);
}
function getClazz() {
var startPos = pos;
pos++;
return needInfo?
[{ ln: tokens[startPos].ln }, CSSPNodeType.ClazzType, getIdent()] :
[CSSPNodeType.ClazzType, getIdent()];
}
// node: Combinator
function checkCombinator(_i) {
if (tokens[_i].type === TokenType.PlusSign ||
tokens[_i].type === TokenType.GreaterThanSign ||
tokens[_i].type === TokenType.Tilde) return 1;
return fail(tokens[_i]);
}
function getCombinator() {
return needInfo?
[{ ln: tokens[pos].ln }, CSSPNodeType.CombinatorType, tokens[pos++].value] :
[CSSPNodeType.CombinatorType, tokens[pos++].value];
}
// node: Comment
function checkComment(_i) {
if (tokens[_i].type === TokenType.CommentML) return 1;
return fail(tokens[_i]);
}
function getComment() {
var startPos = pos,
s = tokens[pos].value.substring(2),
l = s.length;
if (s.charAt(l - 2) === '*' && s.charAt(l - 1) === '/') s = s.substring(0, l - 2);
pos++;
return needInfo?
[{ ln: tokens[startPos].ln }, CSSPNodeType.CommentType, s] :
[CSSPNodeType.CommentType, s];
}
// declaration = property:x ':' value:y -> [#declaration, x, y]
function checkDeclaration(_i) {
var start = _i,
l;
if (l = checkProperty(_i)) _i += l;
else return fail(tokens[_i]);
if (_i < tokens.length && tokens[_i].type === TokenType.Colon) _i++;
else return fail(tokens[_i]);
if (l = checkValue(_i)) _i += l;
else return fail(tokens[_i]);
return _i - start;
}
function getDeclaration() {
var declaration = needInfo?
[{ ln: tokens[pos].ln }, CSSPNodeType.DeclarationType, getProperty()] :
[CSSPNodeType.DeclarationType, getProperty()];
pos++;
declaration.push(getValue());
return declaration;
}
// node: Decldelim
function checkDecldelim(_i) {
if (_i < tokens.length && tokens[_i].type === TokenType.Semicolon) return 1;
return fail(tokens[_i]);
}
function getDecldelim() {
var startPos = pos;
pos++;
return needInfo?
[{ ln: tokens[startPos].ln }, CSSPNodeType.DecldelimType] :
[CSSPNodeType.DecldelimType];
}
// node: Delim
function checkDelim(_i) {
if (_i < tokens.length && tokens[_i].type === TokenType.Comma) return 1;
if (_i >= tokens.length) return fail(tokens[tokens.length - 1]);
return fail(tokens[_i]);
}
function getDelim() {
var startPos = pos;
pos++;
return needInfo?
[{ ln: tokens[startPos].ln }, CSSPNodeType.DelimType] :
[CSSPNodeType.DelimType];
}
// node: Dimension
function checkDimension(_i) {
var ln = checkNumber(_i),
li;
if (!ln || (ln && _i + ln >= tokens.length)) return fail(tokens[_i]);
if (li = checkNmName2(_i + ln)) return ln + li;
return fail(tokens[_i]);
}
function getDimension() {
var startPos = pos,
n = getNumber(),
dimension = needInfo ?
[{ ln: tokens[pos].ln }, CSSPNodeType.IdentType, getNmName2()] :
[CSSPNodeType.IdentType, getNmName2()];
return needInfo?
[{ ln: tokens[startPos].ln }, CSSPNodeType.DimensionType, n, dimension] :
[CSSPNodeType.DimensionType, n, dimension];
}
//filter = filterp:x ':' filterv:y -> [#filter, x, y]
function checkFilter(_i) {
var start = _i,
l;
if (l = checkFilterp(_i)) _i += l;
else return fail(tokens[_i]);
if (tokens[_i].type === TokenType.Colon) _i++;
else return fail(tokens[_i]);
if (l = checkFilterv(_i)) _i += l;
else return fail(tokens[_i]);
return _i - start;
}
function getFilter() {
var filter = needInfo?
[{ ln: tokens[pos].ln }, CSSPNodeType.FilterType, getFilterp()] :
[CSSPNodeType.FilterType, getFilterp()];
pos++;
filter.push(getFilterv());
return filter;
}
//filterp = (seq('-filter') | seq('_filter') | seq('*filter') | seq('-ms-filter') | seq('filter')):t sc*:s0 -> this.concat([#property, [#ident, t]], s0)
function checkFilterp(_i) {
var start = _i,
l,
x;
if (_i < tokens.length) {
if (tokens[_i].value === 'filter') l = 1;
else {
x = joinValues2(_i, 2);
if (x === '-filter' || x === '_filter' || x === '*filter') l = 2;
else {
x = joinValues2(_i, 4);
if (x === '-ms-filter') l = 4;
else return fail(tokens[_i]);
}
}
tokens[start].filterp_l = l;
_i += l;
if (checkSC(_i)) _i += l;
return _i - start;
}
return fail(tokens[_i]);
}
function getFilterp() {
var startPos = pos,
x = joinValues2(pos, tokens[pos].filterp_l),
ident = needInfo? [{ ln: tokens[startPos].ln }, CSSPNodeType.IdentType, x] : [CSSPNodeType.IdentType, x];
pos += tokens[pos].filterp_l;
return (needInfo? [{ ln: tokens[startPos].ln }, CSSPNodeType.PropertyType, ident] : [CSSPNodeType.PropertyType, ident])
.concat(getSC());
}
//filterv = progid+:x -> [#filterv].concat(x)
function checkFilterv(_i) {
var start = _i,
l;
if (l = checkProgid(_i)) _i += l;
else return fail(tokens[_i]);
while (l = checkProgid(_i)) {
_i += l;
}
tokens[start].last_progid = _i;
if (_i < tokens.length && (l = checkSC(_i))) _i += l;
if (_i < tokens.length && (l = checkImportant(_i))) _i += l;
return _i - start;
}
function getFilterv() {
var filterv = needInfo? [{ ln: tokens[pos].ln }, CSSPNodeType.FiltervType] : [CSSPNodeType.FiltervType],
last_progid = tokens[pos].last_progid;
while (pos < last_progid) {
filterv.push(getProgid());
}
filterv = filterv.concat(checkSC(pos) ? getSC() : []);
if (pos < tokens.length && checkImportant(pos)) filterv.push(getImportant());
return filterv;
}
//functionExpression = ``expression('' functionExpressionBody*:x ')' -> [#functionExpression, x.join('')],
function checkFunctionExpression(_i) {
var start = _i;
if (!tokens[_i] || tokens[_i++].value !== 'expression') return fail(tokens[_i - 1]);
if (!tokens[_i] || tokens[_i].type !== TokenType.LeftParenthesis) return fail(tokens[_i]);
return tokens[_i].right - start + 1;
}
function getFunctionExpression() {
var startPos = pos;
pos++;
var e = joinValues(pos + 1, tokens[pos].right - 1);
pos = tokens[pos].right + 1;
return needInfo?
[{ ln: tokens[startPos].ln }, CSSPNodeType.FunctionExpressionType, e] :
[CSSPNodeType.FunctionExpressionType, e];
}
//funktion = ident:x '(' functionBody:y ')' -> [#funktion, x, y]
function checkFunktion(_i) {
var start = _i,
l = checkIdent(_i);
if (!l) return fail(tokens[_i]);
_i += l;
if (_i >= tokens.length || tokens[_i].type !== TokenType.LeftParenthesis) return fail(tokens[_i - 1]);
return tokens[_i].right - start + 1;
}
function getFunktion() {
var startPos = pos,
ident = getIdent();
pos++;
var body = ident[needInfo? 2 : 1] !== 'not'?
getFunctionBody() :
getNotFunctionBody(); // ok, here we have CSS3 initial draft: http://dev.w3.org/csswg/selectors3/#negation
return needInfo?
[{ ln: tokens[startPos].ln }, CSSPNodeType.FunktionType, ident, body] :
[CSSPNodeType.FunktionType, ident, body];
}
function getFunctionBody() {
var startPos = pos,
body = [],
x;
while (tokens[pos].type !== TokenType.RightParenthesis) {
if (checkTset(pos)) {
x = getTset();
if ((needInfo && typeof x[1] === 'string') || typeof x[0] === 'string') body.push(x);
else body = body.concat(x);
} else if (checkClazz(pos)) {
body.push(getClazz());
} else {
throwError();
}
}
pos++;
return (needInfo?
[{ ln: tokens[startPos].ln }, CSSPNodeType.FunctionBodyType] :
[CSSPNodeType.FunctionBodyType]
).concat(body);
}
function getNotFunctionBody() {
var startPos = pos,
body = [],
x;
while (tokens[pos].type !== TokenType.RightParenthesis) {
if (checkSimpleselector(pos)) {
body.push(getSimpleSelector());
} else {
throwError();
}
}
pos++;
return (needInfo?
[{ ln: tokens[startPos].ln }, CSSPNodeType.FunctionBodyType] :
[CSSPNodeType.FunctionBodyType]
).concat(body);
}
// node: Ident
function checkIdent(_i) {
var start = _i,
wasIdent = false;
// start char / word
if (_i < tokens.length &&
(tokens[_i].type === TokenType.HyphenMinus ||
tokens[_i].type === TokenType.LowLine ||
tokens[_i].type === TokenType.Identifier ||
tokens[_i].type === TokenType.DollarSign ||
tokens[_i].type === TokenType.Asterisk)) _i++;
else return fail(tokens[_i]);
wasIdent = tokens[_i - 1].type === TokenType.Identifier;
for (; _i < tokens.length; _i++) {
if (tokens[_i].type !== TokenType.HyphenMinus &&
tokens[_i].type !== TokenType.LowLine) {
if (tokens[_i].type !== TokenType.Identifier &&
(tokens[_i].type !== TokenType.DecimalNumber || !wasIdent)
) break;
else wasIdent = true;
}
}
if (!wasIdent && tokens[start].type !== TokenType.Asterisk) return fail(tokens[_i]);
tokens[start].ident_last = _i - 1;
return _i - start;
}
function getIdent() {
var startPos = pos,
s = joinValues(pos, tokens[pos].ident_last);
pos = tokens[pos].ident_last + 1;
return needInfo?
[{ ln: tokens[startPos].ln }, CSSPNodeType.IdentType, s] :
[CSSPNodeType.IdentType, s];
}
//important = '!' sc*:s0 seq('important') -> [#important].concat(s0)
function checkImportant(_i) {
var start = _i,
l;
if (tokens[_i++].type !== TokenType.ExclamationMark) return fail(tokens[_i - 1]);
if (l = checkSC(_i)) _i += l;
if (tokens[_i].value !== 'important') return fail(tokens[_i]);
return _i - start + 1;
}
function getImportant() {
var startPos = pos;
pos++;
var sc = getSC();
pos++;
return (needInfo? [{ ln: tokens[startPos].ln }, CSSPNodeType.ImportantType] : [CSSPNodeType.ImportantType]).concat(sc);
}
// node: Namespace
function checkNamespace(_i) {
if (tokens[_i].type === TokenType.VerticalLine) return 1;
return fail(tokens[_i]);
}
function getNamespace() {
var startPos = pos;
pos++;
return needInfo?
[{ ln: tokens[startPos].ln }, CSSPNodeType.NamespaceType] :
[CSSPNodeType.NamespaceType];
}
//nth = (digit | 'n')+:x -> [#nth, x.join('')]
// | (seq('even') | seq('odd')):x -> [#nth, x]
function checkNth(_i) {
return checkNth1(_i) || checkNth2(_i);
}
function checkNth1(_i) {
var start = _i;
for (; _i < tokens.length; _i++) {
if (tokens[_i].type !== TokenType.DecimalNumber && tokens[_i].value !== 'n') break;
}
if (_i !== start) {
tokens[start].nth_last = _i - 1;
return _i - start;
}
return fail(tokens[_i]);
}
function getNth() {
var startPos = pos;
if (tokens[pos].nth_last) {
var n = needInfo?
[{ ln: tokens[startPos].ln }, CSSPNodeType.NthType, joinValues(pos, tokens[pos].nth_last)] :
[CSSPNodeType.NthType, joinValues(pos, tokens[pos].nth_last)];
pos = tokens[pos].nth_last + 1;
return n;
}
return needInfo?
[{ ln: tokens[startPos].ln }, CSSPNodeType.NthType, tokens[pos++].value] :
[CSSPNodeType.NthType, tokens[pos++].value];
}
function checkNth2(_i) {
if (tokens[_i].value === 'even' || tokens[_i].value === 'odd') return 1;
return fail(tokens[_i]);
}
//nthf = ':' seq('nth-'):x (seq('child') | seq('last-child') | seq('of-type') | seq('last-of-type')):y -> (x + y)
function checkNthf(_i) {
var start = _i,
l = 0;
if (tokens[_i++].type !== TokenType.Colon) return fail(tokens[_i - 1]); l++;
if (tokens[_i++].value !== 'nth' || tokens[_i++].value !== '-') return fail(tokens[_i - 1]); l += 2;
if ('child' === tokens[_i].value) {
l += 1;
} else if ('last-child' === tokens[_i].value +
tokens[_i + 1].value +
tokens[_i + 2].value) {
l += 3;
} else if ('of-type' === tokens[_i].value +
tokens[_i + 1].value +
tokens[_i + 2].value) {
l += 3;
} else if ('last-of-type' === tokens[_i].value +
tokens[_i + 1].value +
tokens[_i + 2].value +
tokens[_i + 3].value +
tokens[_i + 4].value) {
l += 5;
} else return fail(tokens[_i]);
tokens[start + 1].nthf_last = start + l - 1;
return l;
}
function getNthf() {
pos++;
var s = joinValues(pos, tokens[pos].nthf_last);
pos = tokens[pos].nthf_last + 1;
return s;
}
//nthselector = nthf:x '(' (sc | unary | nth)*:y ')' -> [#nthselector, [#ident, x]].concat(y)
function checkNthselector(_i) {
var start = _i,
l;
if (l = checkNthf(_i)) _i += l;
else return fail(tokens[_i]);
if (tokens[_i].type !== TokenType.LeftParenthesis || !tokens[_i].right) return fail(tokens[_i]);
l++;
var rp = tokens[_i++].right;
while (_i < rp) {
if (l = checkSC(_i)) _i += l;
else if (l = checkUnary(_i)) _i += l;
else if (l = checkNth(_i)) _i += l;
else return fail(tokens[_i]);
}
return rp - start + 1;
}
function getNthselector() {
var startPos = pos,
nthf = needInfo?
[{ ln: tokens[pos].ln }, CSSPNodeType.IdentType, getNthf()] :
[CSSPNodeType.IdentType, getNthf()],
ns = needInfo?
[{ ln: tokens[pos].ln }, CSSPNodeType.NthselectorType, nthf] :
[CSSPNodeType.NthselectorType, nthf];
pos++;
while (tokens[pos].type !== TokenType.RightParenthesis) {
if (checkSC(pos)) ns = ns.concat(getSC());
else if (checkUnary(pos)) ns.push(getUnary());
else if (checkNth(pos)) ns.push(getNth());
}
pos++;
return ns;
}
// node: Number
function checkNumber(_i) {
if (_i < tokens.length && tokens[_i].number_l) return tokens[_i].number_l;
if (_i < tokens.length && tokens[_i].type === TokenType.DecimalNumber &&
(!tokens[_i + 1] ||
(tokens[_i + 1] && tokens[_i + 1].type !== TokenType.FullStop))
) return (tokens[_i].number_l = 1, tokens[_i].number_l); // 10
if (_i < tokens.length &&
tokens[_i].type === TokenType.DecimalNumber &&
tokens[_i + 1] && tokens[_i + 1].type === TokenType.FullStop &&
(!tokens[_i + 2] || (tokens[_i + 2].type !== TokenType.DecimalNumber))
) return (tokens[_i].number_l = 2, tokens[_i].number_l); // 10.
if (_i < tokens.length &&
tokens[_i].type === TokenType.FullStop &&
tokens[_i + 1].type === TokenType.DecimalNumber
) return (tokens[_i].number_l = 2, tokens[_i].number_l); // .10
if (_i < tokens.length &&
tokens[_i].type === TokenType.DecimalNumber &&
tokens[_i + 1] && tokens[_i + 1].type === TokenType.FullStop &&
tokens[_i + 2] && tokens[_i + 2].type === TokenType.DecimalNumber
) return (tokens[_i].number_l = 3, tokens[_i].number_l); // 10.10
return fail(tokens[_i]);
}
function getNumber() {
var s = '',
startPos = pos,
l = tokens[pos].number_l;
for (var i = 0; i < l; i++) {
s += tokens[pos + i].value;
}
pos += l;
return needInfo?
[{ ln: tokens[startPos].ln }, CSSPNodeType.NumberType, s] :
[CSSPNodeType.NumberType, s];
}
// node: Operator
function checkOperator(_i) {
if (_i < tokens.length &&
(tokens[_i].type === TokenType.Solidus ||
tokens[_i].type === TokenType.Comma ||
tokens[_i].type === TokenType.Colon ||
tokens[_i].type === TokenType.EqualsSign)) return 1;
return fail(tokens[_i]);
}
function getOperator() {
return needInfo?
[{ ln: tokens[pos].ln }, CSSPNodeType.OperatorType, tokens[pos++].value] :
[CSSPNodeType.OperatorType, tokens[pos++].value];
}
// node: Percentage
function checkPercentage(_i) {
var x = checkNumber(_i);
if (!x || (x && _i + x >= tokens.length)) return fail(tokens[_i]);
if (tokens[_i + x].type === TokenType.PercentSign) return x + 1;
return fail(tokens[_i]);
}
function getPercentage() {
var startPos = pos,
n = getNumber();
pos++;
return needInfo?
[{ ln: tokens[startPos].ln }, CSSPNodeType.PercentageType, n] :
[CSSPNodeType.PercentageType, n];
}
//progid = sc*:s0 seq('progid:DXImageTransform.Microsoft.'):x letter+:y '(' (m_string | m_comment | ~')' char)+:z ')' sc*:s1
// -> this.concat([#progid], s0, [[#raw, x + y.join('') + '(' + z.join('') + ')']], s1),
function checkProgid(_i) {
var start = _i,
l,
x;
if (l = checkSC(_i)) _i += l;
if ((x = joinValues2(_i, 6)) === 'progid:DXImageTransform.Microsoft.') {
_start = _i;
_i += 6;
} else return fail(tokens[_i - 1]);
if (l = checkIdent(_i)) _i += l;
else return fail(tokens[_i]);
if (l = checkSC(_i)) _i += l;
if (tokens[_i].type === TokenType.LeftParenthesis) {
tokens[start].progid_end = tokens[_i].right;
_i = tokens[_i].right + 1;
} else return fail(tokens[_i]);
if (l = checkSC(_i)) _i += l;
return _i - start;
}
function getProgid() {
var startPos = pos,
progid_end = tokens[pos].progid_end;
return (needInfo? [{ ln: tokens[startPos].ln }, CSSPNodeType.ProgidType] : [CSSPNodeType.ProgidType])
.concat(getSC())
.concat([_getProgid(progid_end)])
.concat(getSC());
}
function _getProgid(progid_end) {
var startPos = pos,
x = joinValues(pos, progid_end);
pos = progid_end + 1;
return needInfo?
[{ ln: tokens[startPos].ln }, CSSPNodeType.RawType, x] :
[CSSPNodeType.RawType, x];
}
//property = ident:x sc*:s0 -> this.concat([#property, x], s0)
function checkProperty(_i) {
var start = _i,
l;
if (l = checkIdent(_i)) _i += l;
else return fail(tokens[_i]);
if (l = checkSC(_i)) _i += l;
return _i - start;
}
function getProperty() {
var startPos = pos;
return (needInfo?
[{ ln: tokens[startPos].ln }, CSSPNodeType.PropertyType, getIdent()] :
[CSSPNodeType.PropertyType, getIdent()])
.concat(getSC());
}
function checkPseudo(_i) {
return checkPseudoe(_i) ||
checkPseudoc(_i);
}
function getPseudo() {
if (checkPseudoe(pos)) return getPseudoe();
if (checkPseudoc(pos)) return getPseudoc();
}
function checkPseudoe(_i) {
var l;
if (tokens[_i++].type !== TokenType.Colon) return fail(tokens[_i - 1]);
if (tokens[_i++].type !== TokenType.Colon) return fail(tokens[_i - 1]);
if (l = checkIdent(_i)) return l + 2;
return fail(tokens[_i]);
}
function getPseudoe() {
var startPos = pos;
pos += 2;
return needInfo?
[{ ln: tokens[startPos].ln }, CSSPNodeType.PseudoeType, getIdent()] :
[CSSPNodeType.PseudoeType, getIdent()];
}
//pseudoc = ':' (funktion | ident):x -> [#pseudoc, x]
function checkPseudoc(_i) {
var l;
if (tokens[_i++].type !== TokenType.Colon) return fail(tokens[_i - 1]);
if ((l = checkFunktion(_i)) || (l = checkIdent(_i))) return l + 1;
return fail(tokens[_i]);
}
function getPseudoc() {
var startPos = pos;
pos++;
return needInfo?
[{ ln: tokens[startPos].ln }, CSSPNodeType.PseudocType, checkFunktion(pos)? getFunktion() : getIdent()] :
[CSSPNodeType.PseudocType, checkFunktion(pos)? getFunktion() : getIdent()];
}
//ruleset = selector*:x block:y -> this.concat([#ruleset], x, [y])
function checkRuleset(_i) {
var start = _i,
l;
if (tokens[start].ruleset_l !== undefined) return tokens[start].ruleset_l;
while (l = checkSelector(_i)) {
_i += l;
}
if (l = checkBlock(_i)) _i += l;
else return fail(tokens[_i]);
tokens[start].ruleset_l = _i - start;
return _i - start;
}
function getRuleset() {
var ruleset = needInfo? [{ ln: tokens[pos].ln }, CSSPNodeType.RulesetType] : [CSSPNodeType.RulesetType];
while (!checkBlock(pos)) {
ruleset.push(getSelector());
}
ruleset.push(getBlock());
return ruleset;
}
// node: S
function checkS(_i) {
if (tokens[_i].ws) return tokens[_i].ws_last - _i + 1;
return fail(tokens[_i]);
}
function getS() {
var startPos = pos,
s = joinValues(pos, tokens[pos].ws_last);
pos = tokens[pos].ws_last + 1;
return needInfo? [{ ln: tokens[startPos].ln }, CSSPNodeType.SType, s] : [CSSPNodeType.SType, s];
}
function checkSC(_i) {
var l,
lsc = 0;
while (_i < tokens.length) {
if (!(l = checkS(_i)) && !(l = checkComment(_i))) break;
_i += l;
lsc += l;
}
if (lsc) return lsc;
if (_i >= tokens.length) return fail(tokens[tokens.length - 1]);
return fail(tokens[_i]);
}
function getSC() {
var sc = [];
while (pos < tokens.length) {
if (checkS(pos)) sc.push(getS());
else if (checkComment(pos)) sc.push(getComment());
else break;
}
return sc;
}
//selector = (simpleselector | delim)+:x -> this.concat([#selector], x)
function checkSelector(_i) {
var start = _i,
l;
if (_i < tokens.length) {
while (l = checkSimpleselector(_i) || checkDelim(_i)) {
_i += l;
}
tokens[start].selector_end = _i - 1;
return _i - start;
}
}
function getSelector() {
var selector = needInfo? [{ ln: tokens[pos].ln }, CSSPNodeType.SelectorType] : [CSSPNodeType.SelectorType],
selector_end = tokens[pos].selector_end;
while (pos <= selector_end) {
selector.push(checkDelim(pos) ? getDelim() : getSimpleSelector());
}
return selector;
}
// node: Shash
function checkShash(_i) {
if (tokens[_i].type !== TokenType.NumberSign) return fail(tokens[_i]);
var l = checkNmName(_i + 1);
if (l) return l + 1;
return fail(tokens[_i]);
}
function getShash() {
var startPos = pos;
pos++;
return needInfo?
[{ ln: tokens[startPos].ln }, CSSPNodeType.ShashType, getNmName()] :
[CSSPNodeType.ShashType, getNmName()];
}
//simpleselector = (nthselector | combinator | attrib | pseudo | clazz | shash | any | sc | namespace)+:x -> this.concatContent([#simpleselector], [x])
function checkSimpleselector(_i) {
var start = _i,
l;
while (_i < tokens.length) {
if (l = _checkSimpleSelector(_i)) _i += l;
else break;
}
if (_i - start) return _i - start;
if (_i >= tokens.length) return fail(tokens[tokens.length - 1]);
return fail(tokens[_i]);
}
function _checkSimpleSelector(_i) {
return checkNthselector(_i) ||
checkCombinator(_i) ||
checkAttrib(_i) ||
checkPseudo(_i) ||
checkClazz(_i) ||
checkShash(_i) ||
checkAny(_i) ||
checkSC(_i) ||
checkNamespace(_i);
}
function getSimpleSelector() {
var ss = needInfo? [{ ln: tokens[pos].ln }, CSSPNodeType.SimpleselectorType] : [CSSPNodeType.SimpleselectorType],
t;
while (pos < tokens.length && _checkSimpleSelector(pos)) {
t = _getSimpleSelector();
if ((needInfo && typeof t[1] === 'string') || typeof t[0] === 'string') ss.push(t);
else ss = ss.concat(t);
}
return ss;
}
function _getSimpleSelector() {
if (checkNthselector(pos)) return getNthselector();
else if (checkCombinator(pos)) return getCombinator();
else if (checkAttrib(pos)) return getAttrib();
else if (checkPseudo(pos)) return getPseudo();
else if (checkClazz(pos)) return getClazz();
else if (checkShash(pos)) return getShash();
else if (checkAny(pos)) return getAny();
else if (checkSC(pos)) return getSC();
else if (checkNamespace(pos)) return getNamespace();
}
// node: String
function checkString(_i) {
if (_i < tokens.length &&
(tokens[_i].type === TokenType.StringSQ || tokens[_i].type === TokenType.StringDQ)
) return 1;
return fail(tokens[_i]);
}
function getString() {
var startPos = pos;
return needInfo?
[{ ln: tokens[startPos].ln }, CSSPNodeType.StringType, tokens[pos++].value] :
[CSSPNodeType.StringType, tokens[pos++].value];
}
//stylesheet = (cdo | cdc | sc | statement)*:x -> this.concat([#stylesheet], x)
function checkStylesheet(_i) {
var start = _i,
l;
while (_i < tokens.length) {
if (l = checkSC(_i)) _i += l;
else {
currentBlockLN = tokens[_i].ln;
if (l = checkAtrule(_i)) _i += l;
else if (l = checkRuleset(_i)) _i += l;
else if (l = checkUnknown(_i)) _i += l;
else throwError();
}
}
return _i - start;
}
function getStylesheet(_i) {
var t,
stylesheet = needInfo? [{ ln: tokens[pos].ln }, CSSPNodeType.StylesheetType] : [CSSPNodeType.StylesheetType];
while (pos < tokens.length) {
if (checkSC(pos)) stylesheet = stylesheet.concat(getSC());
else {
currentBlockLN = tokens[pos].ln;
if (checkRuleset(pos)) stylesheet.push(getRuleset());
else if (checkAtrule(pos)) stylesheet.push(getAtrule());
else if (checkUnknown(pos)) stylesheet.push(getUnknown());
else throwError();
}
}
return stylesheet;
}
//tset = vhash | any | sc | operator
function checkTset(_i) {
return checkVhash(_i) ||
checkAny(_i) ||
checkSC(_i) ||
checkOperator(_i);
}
function getTset() {
if (checkVhash(pos)) return getVhash();
else if (checkAny(pos)) return getAny();
else if (checkSC(pos)) return getSC();
else if (checkOperator(pos)) return getOperator();
}
function checkTsets(_i) {
var start = _i,
l;
while (l = checkTset(_i)) {
_i += l;
}
return _i - start;
}
function getTsets() {
var tsets = [],
x;
while (x = getTset()) {
if ((needInfo && typeof x[1] === 'string') || typeof x[0] === 'string') tsets.push(x);
else tsets = tsets.concat(x);
}
return tsets;
}
// node: Unary
function checkUnary(_i) {
if (_i < tokens.length &&
(tokens[_i].type === TokenType.HyphenMinus ||
tokens[_i].type === TokenType.PlusSign)
) return 1;
return fail(tokens[_i]);
}
function getUnary() {
var startPos = pos;
return needInfo?
[{ ln: tokens[startPos].ln }, CSSPNodeType.UnaryType, tokens[pos++].value] :
[CSSPNodeType.UnaryType, tokens[pos++].value];
}
// node: Unknown
function checkUnknown(_i) {
if (_i < tokens.length && tokens[_i].type === TokenType.CommentSL) return 1;
return fail(tokens[_i]);
}
function getUnknown() {
var startPos = pos;
return needInfo?
[{ ln: tokens[startPos].ln }, CSSPNodeType.UnknownType, tokens[pos++].value] :
[CSSPNodeType.UnknownType, tokens[pos++].value];
}
// uri = seq('url(') sc*:s0 string:x sc*:s1 ')' -> this.concat([#uri], s0, [x], s1)
// | seq('url(') sc*:s0 (~')' ~m_w char)*:x sc*:s1 ')' -> this.concat([#uri], s0, [[#raw, x.join('')]], s1),
function checkUri(_i) {
var start = _i,
l;
if (_i < tokens.length && tokens[_i++].value !== 'url') return fail(tokens[_i - 1]);
if (!tokens[_i] || tokens[_i].type !== TokenType.LeftParenthesis) return fail(tokens[_i]);
return tokens[_i].right - start + 1;
}
function getUri() {
var startPos = pos,
uriExcluding = {};
pos += 2;
uriExcluding[TokenType.Space] = 1;
uriExcluding[TokenType.Tab] = 1;
uriExcluding[TokenType.Newline] = 1;
uriExcluding[TokenType.LeftParenthesis] = 1;
uriExcluding[TokenType.RightParenthesis] = 1;
if (checkUri1(pos)) {
var uri = (needInfo? [{ ln: tokens[startPos].ln }, CSSPNodeType.UriType] : [CSSPNodeType.UriType])
.concat(getSC())
.concat([getString()])
.concat(getSC());
pos++;
return uri;
} else {
var uri = (needInfo? [{ ln: tokens[startPos].ln }, CSSPNodeType.UriType] : [CSSPNodeType.UriType])
.concat(getSC()),
l = checkExcluding(uriExcluding, pos),
raw = needInfo?
[{ ln: tokens[pos].ln }, CSSPNodeType.RawType, joinValues(pos, pos + l)] :
[CSSPNodeType.RawType, joinValues(pos, pos + l)];
uri.push(raw);
pos += l + 1;
uri = uri.concat(getSC());
pos++;
return uri;
}
}
function checkUri1(_i) {
var start = _i,
l = checkSC(_i);
if (l) _i += l;
if (tokens[_i].type !== TokenType.StringDQ && tokens[_i].type !== TokenType.StringSQ) return fail(tokens[_i]);
_i++;
if (l = checkSC(_i)) _i += l;
return _i - start;
}
// value = (sc | vhash | any | block | atkeyword | operator | important)+:x -> this.concat([#value], x)
function checkValue(_i) {
var start = _i,
l;
while (_i < tokens.length) {
if (l = _checkValue(_i)) _i += l;
else break;
}
if (_i - start) return _i - start;
return fail(tokens[_i]);
}
function _checkValue(_i) {
return checkSC(_i) ||
checkVhash(_i) ||
checkAny(_i) ||
checkBlock(_i) ||
checkAtkeyword(_i) ||
checkOperator(_i) ||
checkImportant(_i);
}
function getValue() {
var ss = needInfo? [{ ln: tokens[pos].ln }, CSSPNodeType.ValueType] : [CSSPNodeType.ValueType],
t;
while (pos < tokens.length && _checkValue(pos)) {
t = _getValue();
if ((needInfo && typeof t[1] === 'string') || typeof t[0] === 'string') ss.push(t);
else ss = ss.concat(t);
}
return ss;
}
function _getValue() {
if (checkSC(pos)) return getSC();
else if (checkVhash(pos)) return getVhash();
else if (checkAny(pos)) return getAny();
else if (checkBlock(pos)) return getBlock();
else if (checkAtkeyword(pos)) return getAtkeyword();
else if (checkOperator(pos)) return getOperator();
else if (checkImportant(pos)) return getImportant();
}
// node: Vhash
function checkVhash(_i) {
if (_i >= tokens.length || tokens[_i].type !== TokenType.NumberSign) return fail(tokens[_i]);
var l = checkNmName2(_i + 1);
if (l) return l + 1;
return fail(tokens[_i]);
}
function getVhash() {
var startPos = pos;
pos++;
return needInfo?
[{ ln: tokens[startPos].ln }, CSSPNodeType.VhashType, getNmName2()] :
[CSSPNodeType.VhashType, getNmName2()];
}
function checkNmName(_i) {
var start = _i;
// start char / word
if (tokens[_i].type === TokenType.HyphenMinus ||
tokens[_i].type === TokenType.LowLine ||
tokens[_i].type === TokenType.Identifier ||
tokens[_i].type === TokenType.DecimalNumber) _i++;
else return fail(tokens[_i]);
for (; _i < tokens.length; _i++) {
if (tokens[_i].type !== TokenType.HyphenMinus &&
tokens[_i].type !== TokenType.LowLine &&
tokens[_i].type !== TokenType.Identifier &&
tokens[_i].type !== TokenType.DecimalNumber) break;
}
tokens[start].nm_name_last = _i - 1;
return _i - start;
}
function getNmName() {
var s = joinValues(pos, tokens[pos].nm_name_last);
pos = tokens[pos].nm_name_last + 1;
return s;
}
function checkNmName2(_i) {
var start = _i;
if (tokens[_i].type === TokenType.Identifier) return 1;
else if (tokens[_i].type !== TokenType.DecimalNumber) return fail(tokens[_i]);
_i++;
if (!tokens[_i] || tokens[_i].type !== TokenType.Identifier) return 1;
return 2;
}
function getNmName2() {
var s = tokens[pos].value;
if (tokens[pos++].type === TokenType.DecimalNumber &&
pos < tokens.length &&
tokens[pos].type === TokenType.Identifier
) s += tokens[pos++].value;
return s;
}
function checkExcluding(exclude, _i) {
var start = _i;
while(_i < tokens.length) {
if (exclude[tokens[_i++].type]) break;
}
return _i - start - 2;
}
function joinValues(start, finish) {
var s = '';
for (var i = start; i < finish + 1; i++) {
s += tokens[i].value;
}
return s;
}
function joinValues2(start, num) {
if (start + num - 1 >= tokens.length) return;
var s = '';
for (var i = 0; i < num; i++) {
s += tokens[start + i].value;
}
return s;
}
function markSC() {
var ws = -1, // whitespaces
sc = -1, // ws and comments
t;
for (var i = 0; i < tokens.length; i++) {
t = tokens[i];
switch (t.type) {
case TokenType.Space:
case TokenType.Tab:
case TokenType.Newline:
t.ws = true;
t.sc = true;
if (ws === -1) ws = i;
if (sc === -1) sc = i;
break;
case TokenType.CommentML:
if (ws !== -1) {
tokens[ws].ws_last = i - 1;
ws = -1;
}
t.sc = true;
break;
default:
if (ws !== -1) {
tokens[ws].ws_last = i - 1;
ws = -1;
}
if (sc !== -1) {
tokens[sc].sc_last = i - 1;
sc = -1;
}
}
}
if (ws !== -1) tokens[ws].ws_last = i - 1;
if (sc !== -1) tokens[sc].sc_last = i - 1;
}
return _getAST(_tokens, rule, _needInfo);
}
return getCSSPAST(getTokens(s), rule, _needInfo);
}