Skip to content

Commit

Permalink
include sign to Number and related changes (fixes #26)
Browse files Browse the repository at this point in the history
  • Loading branch information
lahmatiy committed Sep 28, 2016
1 parent 5cf1ce3 commit 8d99d7e
Show file tree
Hide file tree
Showing 12 changed files with 361 additions and 135 deletions.
201 changes: 120 additions & 81 deletions lib/parser/index.js
Expand Up @@ -3,6 +3,7 @@
var TokenType = require('./const').TokenType;
var Scanner = require('./scanner');
var List = require('../utils/list');
var cmpChar = require('./utils').cmpChar;
var cmpStr = require('./utils').cmpStr;
var endsWith = require('./utils').endsWith;
var isHex = require('./utils').isHex;
Expand All @@ -15,7 +16,7 @@ var SPACE_NODE = { type: 'Space' };

var WHITESPACE = TokenType.Whitespace;
var IDENTIFIER = TokenType.Identifier;
var DECIMALNUMBER = TokenType.Number;
var NUMBER = TokenType.Number;
var STRING = TokenType.String;
var COMMENT = TokenType.Comment;
var EXCLAMATIONMARK = TokenType.ExclamationMark;
Expand Down Expand Up @@ -43,6 +44,7 @@ var LEFTCURLYBRACKET = TokenType.LeftCurlyBracket;
var VERTICALLINE = TokenType.VerticalLine;
var RIGHTCURLYBRACKET = TokenType.RightCurlyBracket;
var TILDE = TokenType.Tilde;
var N = 110; // 'n'.charCodeAt(0)

var SCOPE_ATRULE_EXPRESSION = {
url: getUri
Expand Down Expand Up @@ -374,7 +376,7 @@ function getSimpleSelector(nested) {
child = getNamespacedIdentifier(false);
break;

case DECIMALNUMBER:
case NUMBER:
child = getPercentage(getInfo(), readNumber());
break;

Expand Down Expand Up @@ -553,13 +555,18 @@ function getValue(nested, property) {
default:
// check for unicode range: U+0F00, U+0F00-0FFF, u+0F00??
if (scanner.tokenType === IDENTIFIER &&
scanner.lookupValue(0, 'u') &&
scanner.lookupType(1) === PLUSSIGN) {
child = getUnicodeRange();
} else {
child = getAny(SCOPE_VALUE);
scanner.lookupValue(0, 'u')) {
if (
scanner.lookupType(1) === PLUSSIGN || (
scanner.lookupType(1) === NUMBER &&
cmpChar(scanner.source, scanner.tokenEnd, PLUSSIGN)
)) {
child = getUnicodeRange();
break;
}
}

child = getAny(SCOPE_VALUE);
}

if (wasSpace) {
Expand All @@ -581,43 +588,36 @@ function getAny(scope) {
case IDENTIFIER:
break;

case FULLSTOP:
case DECIMALNUMBER:
case HYPHENMINUS:
var nextType = scanner.lookupType(1);
if (nextType === IDENTIFIER || nextType === HYPHENMINUS) {
break;
}
return getOperator();

case PLUSSIGN:
return getOperator();

case NUMBER:
var info = getInfo();
var number = readNumber();
var type = scanner.tokenType;

if (number !== null) {
if (type === PERCENTSIGN) {
return getPercentage(info, number);
}

if (type === IDENTIFIER) {
return getDimension(info, number);
}

return {
type: 'Number',
info: info,
value: number
};
if (type === PERCENTSIGN) {
return getPercentage(info, number);
}

if (type === HYPHENMINUS) {
var nextType = scanner.lookupType(1);
if (nextType === IDENTIFIER || nextType === HYPHENMINUS) {
break;
}
if (type === IDENTIFIER) {
return getDimension(info, number);
}

if (type === HYPHENMINUS ||
type === PLUSSIGN) {
return getOperator();
}
return {
type: 'Number',
info: info,
value: number
};

scanner.error('Unexpected input');
break;

default:
scanner.error('Unexpected input');
Expand Down Expand Up @@ -1160,29 +1160,28 @@ function getOldIEExpression(scope, info, name) {
};
}

// https://drafts.csswg.org/css-syntax-3/#urange
function scanUnicodeRange() {
var hexStart = scanner.tokenStart;
var hexStart = scanner.tokenStart + 1; // skip +
var hexLength = 0;

if (scanner.tokenType === DECIMALNUMBER) {
if (scanner.tokenType === PLUSSIGN || scanner.tokenType === NUMBER) {
scanner.next();
}

if (scanner.tokenType === HYPHENMINUS) {
scanner.next();
}

if (scanner.tokenType === DECIMALNUMBER) {
if (scanner.tokenType === NUMBER) {
scanner.next();
}

if (scanner.tokenType === IDENTIFIER) {
scanner.next();
}

hexLength = scanner.tokenStart - hexStart;

if (hexLength === 0) {
if (scanner.tokenStart === hexStart) {
scanner.error('Unexpected input', hexStart);
}

Expand All @@ -1192,16 +1191,31 @@ function scanUnicodeRange() {
var code = scanner.source.charCodeAt(i);

if (isHex(code) === false && (code !== HYPHENMINUS || wasHyphenMinus)) {
scanner.error('Unexpected input', hexStart + i);
scanner.error('Unexpected input', i);
}

if (code === HYPHENMINUS) {
// hex sequence shouldn't be an empty
if (hexLength === 0) {
scanner.error('Unexpected input', i);
}

wasHyphenMinus = true;
hexLength = 0;
} else {
hexLength++;

// to long hex sequence
if (hexLength > 6) {
scanner.error('Unexpected input', i);
}
}

}

// U+abc???
if (!wasHyphenMinus) {
// consume as many U+003F QUESTION MARK (?) code points as possible
for (; hexLength < 6 && !scanner.eof; scanner.next()) {
if (scanner.tokenType !== QUESTIONMARK) {
break;
Expand All @@ -1211,14 +1225,19 @@ function scanUnicodeRange() {
}
}

// If there are any code points left in text, this is an invalid <urange>,
if (scanner.tokenType === IDENTIFIER) {
scanner.error('Unexpected input');
}

return hexLength;
}

function getUnicodeRange() {
var start = scanner.tokenStart;
var info = getInfo();

scanner.skip(2); // U+ or u+
scanner.next(); // U or u
scanUnicodeRange();

return {
Expand Down Expand Up @@ -1308,6 +1327,7 @@ function getImportant() {
return true;
}

// https://drafts.csswg.org/css-syntax-3/#the-anb-type
function getNthSelector() {
var info = getInfo();
var sequence = new List();
Expand Down Expand Up @@ -1336,28 +1356,26 @@ function getNthSelector() {
value: scanner.substrToCursor(start)
});
} else {
if (scanner.tokenType === HYPHENMINUS ||
scanner.tokenType === PLUSSIGN) {
sequence.appendData(getOperator());
readSC();
}

var prefix = '';
var start = scanner.tokenStart;
var info = getInfo();

if (scanner.tokenType === DECIMALNUMBER) {
if (scanner.tokenType === HYPHENMINUS ||
scanner.tokenType === PLUSSIGN ||
scanner.tokenType === NUMBER) {
prefix = scanner.getTokenValue();
scanner.next();
}

if (scanner.tokenType === IDENTIFIER) {
if (!cmpStr(scanner.source, scanner.tokenStart, scanner.tokenStart + 1, 'n')) {
if (!cmpChar(scanner.source, scanner.tokenStart, N)) {
scanner.error('Unexpected input');
}

sequence.appendData({
type: 'Nth',
info: info,
value: scanner.source.substring(start, scanner.tokenStart + 1)
value: prefix + scanner.source.charAt(scanner.tokenStart)
});

var len = scanner.tokenEnd - scanner.tokenStart;
Expand Down Expand Up @@ -1394,43 +1412,80 @@ function getNthSelector() {
});

} else {
scanner.next();
readSC();

sequence.appendData({
type: 'Nth',
info: getInfo(),
value: scanner.getTokenValue()
});
scanner.eat(DECIMALNUMBER);
if (scanner.tokenType === NUMBER) {
if (cmpChar(scanner.source, scanner.tokenStart, PLUSSIGN) ||
cmpChar(scanner.source, scanner.tokenStart, HYPHENMINUS)) {
scanner.error('Unexpected input');
}

sequence.appendData({
type: 'Nth',
info: getInfo(),
value: scanner.getTokenValue()
});

scanner.next();
}
}

} else {
prefix = '';
scanner.next();
readSC();

if (scanner.tokenType === HYPHENMINUS ||
scanner.tokenType === PLUSSIGN) {
sequence.appendData(getOperator());

info = getInfo();
prefix = scanner.getTokenValue();
scanner.next();
readSC();
}

if (scanner.tokenType === NUMBER) {
var sign = '';

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 === '' ^ sign === '')) {
scanner.error('Unexpected input');
}

if (sign) {
scanner.tokenStart++;
}

sequence.appendData({
type: 'Operator',
info: info,
value: prefix || sign
});

sequence.appendData({
type: 'Nth',
info: getInfo(),
value: scanner.getTokenValue()
});
scanner.eat(DECIMALNUMBER);

scanner.next();
}
}
} else {
if (scanner.tokenStart === start) { // no number
if (prefix === '' || prefix === '-' || prefix === '+') { // no number
scanner.error('Number or identifier is expected');
}

sequence.appendData({
type: 'Nth',
info: info,
value: scanner.substrToCursor(start)
value: prefix
});
}
}
Expand All @@ -1442,27 +1497,11 @@ function getNthSelector() {
}

function readNumber() {
var start = scanner.tokenStart;
var wasDigits = false;
var offset = 0;
var tokenType = scanner.tokenType;

if (tokenType === HYPHENMINUS) {
tokenType = scanner.lookupType(++offset);
}

if (tokenType === DECIMALNUMBER) {
wasDigits = true;
tokenType = scanner.lookupType(++offset);
}

if (wasDigits) {
scanner.skip(offset);
var number = scanner.getTokenValue();

return scanner.substrToCursor(start);
}
scanner.eat(NUMBER);

return null;
return number;
}

// '/' | '*' | ',' | ':' | '+' | '-'
Expand Down Expand Up @@ -1650,7 +1689,7 @@ function getHash() {

scanner.eat(NUMBERSIGN);

if (scanner.tokenType !== DECIMALNUMBER &&
if (scanner.tokenType !== NUMBER &&
scanner.tokenType !== IDENTIFIER) {
scanner.error('Number or identifier is expected');
}
Expand Down

0 comments on commit 8d99d7e

Please sign in to comment.