var TAB = 9; var N = 10; var F = 12; var R = 13; var SPACE = 32; var EOF = 0; // https://drafts.csswg.org/css-syntax-3/ // § 4.2. Definitions // digit // A code point between U+0030 DIGIT ZERO (0) and U+0039 DIGIT NINE (9). function isDigit(code) { return code >= 0x0030 && code <= 0x0039; } // hex digit // A digit, or a code point between U+0041 LATIN CAPITAL LETTER A (A) and U+0046 LATIN CAPITAL LETTER F (F), // or a code point between U+0061 LATIN SMALL LETTER A (a) and U+0066 LATIN SMALL LETTER F (f). function isHexDigit(code) { return ( isDigit(code) || // 0 .. 9 (code >= 0x0041 && code <= 0x0046) || // A .. F (code >= 0x0061 && code <= 0x0066) // a .. f ); } // uppercase letter // A code point between U+0041 LATIN CAPITAL LETTER A (A) and U+005A LATIN CAPITAL LETTER Z (Z). function isUppercaseLetter(code) { return code >= 0x0041 && code <= 0x005A; } // lowercase letter // A code point between U+0061 LATIN SMALL LETTER A (a) and U+007A LATIN SMALL LETTER Z (z). function isLowercaseLetter(code) { return code >= 0x0061 && code <= 0x007A; } // letter // An uppercase letter or a lowercase letter. function isLetter(code) { return isUppercaseLetter(code) || isLowercaseLetter(code); } // non-ASCII code point // A code point with a value equal to or greater than U+0080 . function isNonAscii(code) { return code >= 0x0080; } // name-start code point // A letter, a non-ASCII code point, or U+005F LOW LINE (_). function isNameStart(code) { return isLetter(code) || isNonAscii(code) || code === 0x005F; } // name code point // A name-start code point, a digit, or U+002D HYPHEN-MINUS (-). function isName(code) { return isNameStart(code) || isDigit(code) || code === 0x002D; } // non-printable code point // A code point between U+0000 NULL and U+0008 BACKSPACE, or U+000B LINE TABULATION, // or a code point between U+000E SHIFT OUT and U+001F INFORMATION SEPARATOR ONE, or U+007F DELETE. function isNonPrintable(code) { return ( (code >= 0x0000 && code <= 0x0008) || (code === 0x000B) || (code >= 0x000E && code <= 0x001F) || (code === 0x007F) ); } // newline // U+000A LINE FEED. Note that U+000D CARRIAGE RETURN and U+000C FORM FEED are not included in this definition, // as they are converted to U+000A LINE FEED during preprocessing. // TODO: we doesn't do a preprocessing, so check a code point for U+000D CARRIAGE RETURN and U+000C FORM FEED function isNewline(code) { return code === R || code === N || code === F; } // whitespace // A newline, U+0009 CHARACTER TABULATION, or U+0020 SPACE. function isWhiteSpace(code) { return isNewline(code) || code === SPACE || code === TAB; } // § 4.3.8. Check if two code points are a valid escape function isValidEscape(first, second) { // If the first code point is not U+005C REVERSE SOLIDUS (\), return false. if (first !== 0x005C) { return false; } // Otherwise, if the second code point is a newline or EOF, return false. if (isNewline(second) || second === EOF) { return false; } // Otherwise, return true. return true; } // § 4.3.9. Check if three code points would start an identifier function isIdentifierStart(first, second, third) { // Look at the first code point: // U+002D HYPHEN-MINUS if (first === 0x002D) { // If the second code point is a name-start code point or a U+002D HYPHEN-MINUS, // or the second and third code points are a valid escape, return true. Otherwise, return false. return ( isNameStart(second) || second === 0x002D || isValidEscape(second, third) ); } // name-start code point if (isNameStart(first)) { // Return true. return true; } // U+005C REVERSE SOLIDUS (\) if (first === 0x005C) { // If the first and second code points are a valid escape, return true. Otherwise, return false. return isValidEscape(first, second); } // anything else // Return false. return false; } // § 4.3.10. Check if three code points would start a number function isNumberStart(first, second, third) { // Look at the first code point: // U+002B PLUS SIGN (+) // U+002D HYPHEN-MINUS (-) if (first === 0x002B || first === 0x002D) { // If the second code point is a digit, return true. if (isDigit(second)) { return 2; } // Otherwise, if the second code point is a U+002E FULL STOP (.) // and the third code point is a digit, return true. // Otherwise, return false. return second === 0x002E && isDigit(third) ? 3 : 0; } // U+002E FULL STOP (.) if (first === 0x002E) { // If the second code point is a digit, return true. Otherwise, return false. return isDigit(second) ? 2 : 0; } // digit if (isDigit(first)) { // Return true. return 1; } // anything else // Return false. return 0; } module.exports = { isDigit: isDigit, isHexDigit: isHexDigit, isUppercaseLetter: isUppercaseLetter, isLowercaseLetter: isLowercaseLetter, isLetter: isLetter, isNonAscii: isNonAscii, isNameStart: isNameStart, isName: isName, isNonPrintable: isNonPrintable, isNewline: isNewline, isWhiteSpace: isWhiteSpace, isValidEscape: isValidEscape, isIdentifierStart: isIdentifierStart, isNumberStart: isNumberStart };