|
|
@@ -11,6 +11,39 @@
|
|
|
// https://github.com/tabatkins/parse-css
|
|
|
this.parseCss = this.parseCss || (() => {
|
|
|
|
|
|
+ const BAD_STRING_TOKEN_TYPE = "BADSTRING";
|
|
|
+ const BAD_URL_TOKEN_TYPE = "BADURL";
|
|
|
+ const WHITESPACE_TOKEN_TYPE = "WHITESPACE";
|
|
|
+ const CDO_TOKEN_TYPE = "CDO";
|
|
|
+ const CDC_TOKEN_TYPE = "CDO";
|
|
|
+ const COLON_TOKEN_TYPE = ":";
|
|
|
+ const SEMICOLON_TOKEN_TYPE = ";";
|
|
|
+ const COMMA_TOKEN_TYPE = ",";
|
|
|
+ const OPEN_CURLY_TOKEN_TYPE = "{";
|
|
|
+ const CLOSE_CURLY_TOKEN_TYPE = "}";
|
|
|
+ const OPEN_SQUARE_TOKEN_TYPE = "[";
|
|
|
+ const CLOSE_SQUARE_TOKEN_TYPE = "]";
|
|
|
+ const OPEN_PAREN_TOKEN_TYPE = "(";
|
|
|
+ const CLOSE_PAREN_TOKEN_TYPE = ";";
|
|
|
+ const INCLUDE_MATCH_TOKEN_TYPE = "~=";
|
|
|
+ const DASH_MATCH_TOKEN_TYPE = "|=";
|
|
|
+ const PREFIX_MATCH_TOKEN_TYPE = "^=";
|
|
|
+ const SUFFIX_MATCH_TOKEN_TYPE = "$=";
|
|
|
+ const SUBSTRING_MATCH_TOKEN_TYPE = "*=";
|
|
|
+ const COLUMN_TOKEN_TYPE = "||";
|
|
|
+ const EOF_TOKEN_TYPE = "EOF";
|
|
|
+ const DELIM_TOKEN_TYPE = "DELIM";
|
|
|
+ const IDENT_TOKEN_TYPE = "IDENT";
|
|
|
+ const FUNCTION_TOKEN_TYPE = "FUNCTION";
|
|
|
+ const HASH_TOKEN_TYPE = "HASH";
|
|
|
+ const STRING_TOKEN_TYPE = "STRING";
|
|
|
+ const URL_TOKEN_TYPE = "URL";
|
|
|
+ const NUMBER_TOKEN_TYPE = "NUMBER";
|
|
|
+ const PERCENTAGE_TOKEN_TYPE = "PERCENTAGE";
|
|
|
+ const DIMENSION_TOKEN_TYPE = "DIMENSION";
|
|
|
+ const DECLARATION_TYPE = "DECLARATION";
|
|
|
+ const FUNCTION_TYPE = "FUNCTION";
|
|
|
+
|
|
|
function between(num, first, last) { return num >= first && num <= last; }
|
|
|
function digit(code) { return between(code, 0x30, 0x39); }
|
|
|
function hexdigit(code) { return digit(code) || between(code, 0x41, 0x46) || between(code, 0x61, 0x66); }
|
|
|
@@ -26,12 +59,6 @@ this.parseCss = this.parseCss || (() => {
|
|
|
|
|
|
const maximumallowedcodepoint = 0x10ffff;
|
|
|
|
|
|
- const InvalidCharacterError = function (message) {
|
|
|
- this.message = message;
|
|
|
- };
|
|
|
- InvalidCharacterError.prototype = new Error;
|
|
|
- InvalidCharacterError.prototype.name = "InvalidCharacterError";
|
|
|
-
|
|
|
function preprocess(str) {
|
|
|
// Turn a string into an array of code points,
|
|
|
// following the preprocessing cleanup rules.
|
|
|
@@ -64,41 +91,6 @@ this.parseCss = this.parseCss || (() => {
|
|
|
return String.fromCharCode(lead) + String.fromCharCode(trail);
|
|
|
}
|
|
|
|
|
|
- const BAD_STRING_TOKEN_TYPE = "BADSTRING";
|
|
|
- const BAD_URL_TOKEN_TYPE = "BADURL";
|
|
|
- const WHITESPACE_TOKEN_TYPE = "WHITESPACE";
|
|
|
- const CDO_TOKEN_TYPE = "CDO";
|
|
|
- const CDC_TOKEN_TYPE = "CDO";
|
|
|
- const COLON_TOKEN_TYPE = ":";
|
|
|
- const SEMICOLON_TOKEN_TYPE = ";";
|
|
|
- const COMMA_TOKEN_TYPE = ",";
|
|
|
- const OPEN_CURLY_TOKEN_TYPE = "{";
|
|
|
- const CLOSE_CURLY_TOKEN_TYPE = "}";
|
|
|
- const OPEN_SQUARE_TOKEN_TYPE = "[";
|
|
|
- const CLOSE_SQUARE_TOKEN_TYPE = "]";
|
|
|
- const OPEN_PAREN_TOKEN_TYPE = "(";
|
|
|
- const CLOSE_PAREN_TOKEN_TYPE = ";";
|
|
|
- const INCLUDE_MATCH_TOKEN_TYPE = "~=";
|
|
|
- const DASH_MATCH_TOKEN_TYPE = "|=";
|
|
|
- const PREFIX_MATCH_TOKEN_TYPE = "^=";
|
|
|
- const SUFFIX_MATCH_TOKEN_TYPE = "$=";
|
|
|
- const SUBSTRING_MATCH_TOKEN_TYPE = "*=";
|
|
|
- const COLUMN_TOKEN_TYPE = "||";
|
|
|
- const EOF_TOKEN_TYPE = "EOF";
|
|
|
- const DELIM_TOKEN_TYPE = "DELIM";
|
|
|
- const IDENT_TOKEN_TYPE = "IDENT";
|
|
|
- const FUNCTION_TOKEN_TYPE = "FUNCTION";
|
|
|
- const HASH_TOKEN_TYPE = "HASH";
|
|
|
- const STRING_TOKEN_TYPE = "STRING";
|
|
|
- const URL_TOKEN_TYPE = "URL";
|
|
|
- const NUMBER_TOKEN_TYPE = "NUMBER";
|
|
|
- const PERCENTAGE_TOKEN_TYPE = "PERCENTAGE";
|
|
|
- const DIMENSION_TOKEN_TYPE = "DIMENSION";
|
|
|
-
|
|
|
- function ASCIIMatch(str) {
|
|
|
- return this.value.toLowerCase() == str.toLowerCase();
|
|
|
- }
|
|
|
-
|
|
|
function tokenize(str) {
|
|
|
str = preprocess(str);
|
|
|
let i = -1;
|
|
|
@@ -346,9 +338,7 @@ this.parseCss = this.parseCss || (() => {
|
|
|
consume();
|
|
|
return new Token(FUNCTION_TOKEN_TYPE, str);
|
|
|
} else {
|
|
|
- const token = new Token(IDENT_TOKEN_TYPE, str);
|
|
|
- token.ASCIIMatch = ASCIIMatch;
|
|
|
- return token;
|
|
|
+ return new Token(IDENT_TOKEN_TYPE, str);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
@@ -571,35 +561,43 @@ this.parseCss = this.parseCss || (() => {
|
|
|
return tokens;
|
|
|
}
|
|
|
|
|
|
- function Token(tokenType, value) {
|
|
|
- this.tokenType = tokenType;
|
|
|
- this.value = value;
|
|
|
+ class Token {
|
|
|
+ constructor(tokenType, value) {
|
|
|
+ this.tokenType = tokenType;
|
|
|
+ this.value = value;
|
|
|
+ this.repr = null;
|
|
|
+ this.type = null;
|
|
|
+ this.unit = null;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// ---
|
|
|
- function TokenStream(tokens) {
|
|
|
- // Assume that tokens is an array.
|
|
|
- this.tokens = tokens;
|
|
|
- this.i = -1;
|
|
|
+ class TokenStream {
|
|
|
+ constructor(tokens) {
|
|
|
+ // Assume that tokens is an array.
|
|
|
+ this.tokens = tokens;
|
|
|
+ this.i = -1;
|
|
|
+ }
|
|
|
+ tokenAt(i) {
|
|
|
+ if (i < this.tokens.length)
|
|
|
+ return this.tokens[i];
|
|
|
+ return { tokenType: EOF_TOKEN_TYPE };
|
|
|
+ }
|
|
|
+ consume(num) {
|
|
|
+ if (num === undefined)
|
|
|
+ num = 1;
|
|
|
+ this.i += num;
|
|
|
+ this.token = this.tokenAt(this.i);
|
|
|
+ //console.log(this.i, this.token);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ next() {
|
|
|
+ return this.tokenAt(this.i + 1);
|
|
|
+ }
|
|
|
+ reconsume() {
|
|
|
+ this.i--;
|
|
|
+ }
|
|
|
}
|
|
|
- TokenStream.prototype.tokenAt = function (i) {
|
|
|
- if (i < this.tokens.length)
|
|
|
- return this.tokens[i];
|
|
|
- return { tokenType: EOF_TOKEN_TYPE };
|
|
|
- };
|
|
|
- TokenStream.prototype.consume = function (num) {
|
|
|
- if (num === undefined) num = 1;
|
|
|
- this.i += num;
|
|
|
- this.token = this.tokenAt(this.i);
|
|
|
- //console.log(this.i, this.token);
|
|
|
- return true;
|
|
|
- };
|
|
|
- TokenStream.prototype.next = function () {
|
|
|
- return this.tokenAt(this.i + 1);
|
|
|
- };
|
|
|
- TokenStream.prototype.reconsume = function () {
|
|
|
- this.i--;
|
|
|
- };
|
|
|
|
|
|
function parseerror(s, msg) {
|
|
|
throw new Error("Parse error at token " + s.i + ": " + s.token + ".\n" + msg);
|
|
|
@@ -646,7 +644,7 @@ this.parseCss = this.parseCss || (() => {
|
|
|
for (let i = decl.value.length - 1; i >= 0; i--) {
|
|
|
if (decl.value[i].tokenType == WHITESPACE_TOKEN_TYPE) {
|
|
|
continue;
|
|
|
- } else if (decl.value[i].tokenType == IDENT_TOKEN_TYPE && decl.value[i].ASCIIMatch("important")) {
|
|
|
+ } else if (decl.value[i].tokenType == IDENT_TOKEN_TYPE && decl.value[i].value.toLowerCase() == "important") {
|
|
|
foundImportant = true;
|
|
|
} else if (foundImportant && decl.value[i].tokenType == DELIM_TOKEN_TYPE && decl.value[i].value == "!") {
|
|
|
decl.value.splice(i, decl.value.length);
|
|
|
@@ -688,21 +686,22 @@ this.parseCss = this.parseCss || (() => {
|
|
|
s = normalizeInput(s);
|
|
|
return consumeAListOfDeclarations(s);
|
|
|
}
|
|
|
-
|
|
|
- function Declaration(name) {
|
|
|
- this.name = name;
|
|
|
- this.value = [];
|
|
|
- this.important = false;
|
|
|
- return this;
|
|
|
+ class Declaration {
|
|
|
+ constructor(name) {
|
|
|
+ this.name = name;
|
|
|
+ this.value = [];
|
|
|
+ this.important = false;
|
|
|
+ this.type = DECLARATION_TYPE;
|
|
|
+ }
|
|
|
}
|
|
|
- Declaration.prototype.type = "DECLARATION";
|
|
|
|
|
|
- function Func(name) {
|
|
|
- this.name = name;
|
|
|
- this.value = [];
|
|
|
- return this;
|
|
|
+ class Func {
|
|
|
+ constructor(name) {
|
|
|
+ this.name = name;
|
|
|
+ this.value = [];
|
|
|
+ this.type = FUNCTION_TYPE;
|
|
|
+ }
|
|
|
}
|
|
|
- Func.prototype.type = "FUNCTION";
|
|
|
|
|
|
// Exportation.
|
|
|
|