Clean up parser code

This commit is contained in:
Andrey Sitnik
2014-11-06 13:22:04 +03:00
parent feb1419a90
commit 3cb1d9cdc1
+50 -39
View File
@@ -177,14 +177,7 @@ class Parser {
if ( token[0] == ':' ) {
break;
} else if ( token[0] != 'space' && token[0] != 'comment' ) {
if ( this.opts.safe ) {
node.source.start = token[2];
node.before += node.prop + node.between;
node.prop = tokens.shift()[1];
node.between = '';
} else {
this.error('Unknown word', token[2]);
}
this.unknownWord(node, token);
}
}
@@ -196,46 +189,20 @@ class Parser {
var i;
for ( i = 2; i < tokens.length; i++ ) {
if ( tokens[i][0] == ':' ) {
if ( this.opts.safe ) {
var split;
for ( split = i - 1; split >= 0; split-- ) {
if ( tokens[split][0] == 'word' ) break;
}
for ( split -= 1; split >= 0; split-- ) {
if ( tokens[split][0] != 'space' ) {
split += 1;
break;
}
}
var other = tokens.splice(split, tokens.length - split);
this.decl(other);
} else {
var founded = 0;
for ( var j = i - 1; j >= 0; j-- ) {
token = tokens[j];
if ( token[0] != 'space' ) {
founded += 1;
if ( founded == 2 ) break;
}
}
this.error('Missed semicolon', token[3]);
}
}
if ( tokens[i][0] == ':' ) this.missedSemicolon(tokens, i);
}
for ( i = tokens.length - 1; i > 0; i-- ) {
token = tokens[i];
if ( token[0] == 'word' && token[1] == '!important' ) {
if ( token[1] == '!important' ) {
node.important = true;
var string = this
.map(tokens.splice(i, tokens.length - i), i => i[1] )
.join('');
var string = this.stringFrom(tokens, i);
string = this.spacesFromEnd(tokens) + string;
if ( string != ' !important' ) node._important = string;
break;
} else if ( token[0] != 'space' && token[0] != 'comment' ) {
break;
}
if ( token[0] != 'space' && token[0] != 'comment' ) break;
}
this.raw(node, 'value', tokens);
@@ -327,6 +294,45 @@ class Parser {
}
}
unknownWord(node, token) {
if ( this.opts.safe ) {
node.source.start = token[2];
node.before += node.prop + node.between;
node.prop = tokens.shift()[1];
node.between = '';
} else {
this.error('Unknown word', token[2]);
}
}
missedSemicolon(tokens, colon) {
if ( this.opts.safe ) {
var split;
for ( split = colon - 1; split >= 0; split-- ) {
if ( tokens[split][0] == 'word' ) break;
}
for ( split -= 1; split >= 0; split-- ) {
if ( tokens[split][0] != 'space' ) {
split += 1;
break;
}
}
var other = tokens.splice(split, tokens.length - split);
this.decl(other);
} else {
var token;
var founded = 0;
for ( var j = colon - 1; j >= 0; j-- ) {
token = tokens[j];
if ( token[0] != 'space' ) {
founded += 1;
if ( founded == 2 ) break;
}
}
this.error('Missed semicolon', token[3]);
}
}
// Helpers
error(message, pos) {
@@ -388,6 +394,11 @@ class Parser {
return spaces;
}
stringFrom(tokens, i) {
var part = tokens.splice(i, tokens.length - i);
return this.map(part, i => i[1] ).join('');
}
map(array, callback) {
var mapped = [];
for ( var i = 0; i < array.length; i++ ) {