11/*global Tokens, TokenStreamBase*/
22
33var h = / ^ [ 0 - 9 a - f A - F ] $ / ,
4- nonascii = / ^ [ \u0080 - \uFFFF ] $ / ,
5- nl = / \n | \r \n | \r | \f / ;
4+ nonascii = / ^ [ \u00A0 - \uFFFF ] $ / ,
5+ nl = / \n | \r \n | \r | \f / ,
6+ whitespace = / \u0009 | \u000a | \u000c | \u000d | \u0020 / ;
67
78//-----------------------------------------------------------------------------
89// Helper functions
@@ -18,15 +19,15 @@ function isDigit(c){
1819}
1920
2021function isWhitespace ( c ) {
21- return c !== null && / \s / . test ( c ) ;
22+ return c !== null && whitespace . test ( c ) ;
2223}
2324
2425function isNewLine ( c ) {
2526 return c !== null && nl . test ( c ) ;
2627}
2728
2829function isNameStart ( c ) {
29- return c !== null && ( / [ a - z _ \u0080 - \uFFFF \\ ] / i. test ( c ) ) ;
30+ return c !== null && ( / [ a - z _ \u00A0 - \uFFFF \\ ] / i. test ( c ) ) ;
3031}
3132
3233function isNameChar ( c ) {
@@ -213,6 +214,19 @@ TokenStream.prototype = mix(new TokenStreamBase(), {
213214 token = this . htmlCommentStartToken ( c , startLine , startCol ) ;
214215 break ;
215216
217+ /*
218+ * Potential tokens:
219+ * - IDENT
220+ * - CHAR
221+ */
222+ case "\\" :
223+ if ( / [ ^ \r \n \f ] / . test ( reader . peek ( ) ) ) {
224+ token = this . identOrFunctionToken ( c , startLine , startCol ) ;
225+ } else {
226+ token = this . charToken ( c , startLine , startCol ) ;
227+ }
228+ break ;
229+
216230 /*
217231 * Potential tokens:
218232 * - UNICODE_RANGE
@@ -941,8 +955,13 @@ TokenStream.prototype = mix(new TokenStreamBase(), {
941955
942956 while ( true ) {
943957 if ( c == "\\" ) {
944- ident += this . readEscape ( reader . read ( ) ) ;
945- c = reader . peek ( ) ;
958+ if ( / ^ [ ^ \r \n \f ] $ / . test ( reader . peek ( 2 ) ) ) {
959+ ident += this . readEscape ( reader . read ( ) , true ) ;
960+ c = reader . peek ( ) ;
961+ } else {
962+ // Bad escape sequence.
963+ break ;
964+ }
946965 } else if ( c && isNameChar ( c ) ) {
947966 ident += reader . read ( ) ;
948967 c = reader . peek ( ) ;
@@ -954,7 +973,7 @@ TokenStream.prototype = mix(new TokenStreamBase(), {
954973 return ident ;
955974 } ,
956975
957- readEscape : function ( first ) {
976+ readEscape : function ( first , unescape ) {
958977 var reader = this . _reader ,
959978 cssEscape = first || "" ,
960979 i = 0 ,
@@ -967,13 +986,31 @@ TokenStream.prototype = mix(new TokenStreamBase(), {
967986 } while ( c && isHexDigit ( c ) && ++ i < 6 ) ;
968987 }
969988
970- if ( cssEscape . length == 3 && / \s / . test ( c ) ||
971- cssEscape . length == 7 || cssEscape . length == 1 ) {
989+ if ( cssEscape . length === 1 ) {
990+ if ( / ^ [ ^ \r \n \f 0 - 9 a - f ] $ / . test ( c ) ) {
972991 reader . read ( ) ;
992+ if ( unescape ) { return c ; }
993+ } else {
994+ // We should never get here (readName won't call readEscape
995+ // if the escape sequence is bad).
996+ throw new Error ( "Bad escape sequence." ) ;
997+ }
998+ } else if ( c === '\r' ) {
999+ reader . read ( ) ;
1000+ if ( reader . peek ( ) === '\n' ) {
1001+ c += reader . read ( ) ;
1002+ }
1003+ } else if ( / ^ [ \t \n \f ] $ / . test ( c ) ) {
1004+ reader . read ( ) ;
9731005 } else {
9741006 c = "" ;
9751007 }
9761008
1009+ if ( unescape ) {
1010+ var cp = parseInt ( cssEscape . slice ( first . length ) , 16 ) ;
1011+ return String . fromCodePoint ? String . fromCodePoint ( cp ) :
1012+ String . fromCharCode ( cp ) ;
1013+ }
9771014 return cssEscape + c ;
9781015 } ,
9791016
0 commit comments