1
1
/*global Tokens, TokenStreamBase*/
2
2
3
3
var 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 / ;
6
7
7
8
//-----------------------------------------------------------------------------
8
9
// Helper functions
@@ -18,15 +19,15 @@ function isDigit(c){
18
19
}
19
20
20
21
function isWhitespace ( c ) {
21
- return c !== null && / \s / . test ( c ) ;
22
+ return c !== null && whitespace . test ( c ) ;
22
23
}
23
24
24
25
function isNewLine ( c ) {
25
26
return c !== null && nl . test ( c ) ;
26
27
}
27
28
28
29
function isNameStart ( c ) {
29
- return c !== null && ( / [ a - z _ \u0080 - \uFFFF \\ ] / i. test ( c ) ) ;
30
+ return c !== null && ( / [ a - z _ \u00A0 - \uFFFF \\ ] / i. test ( c ) ) ;
30
31
}
31
32
32
33
function isNameChar ( c ) {
@@ -213,6 +214,19 @@ TokenStream.prototype = mix(new TokenStreamBase(), {
213
214
token = this . htmlCommentStartToken ( c , startLine , startCol ) ;
214
215
break ;
215
216
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
+
216
230
/*
217
231
* Potential tokens:
218
232
* - UNICODE_RANGE
@@ -941,8 +955,13 @@ TokenStream.prototype = mix(new TokenStreamBase(), {
941
955
942
956
while ( true ) {
943
957
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
+ }
946
965
} else if ( c && isNameChar ( c ) ) {
947
966
ident += reader . read ( ) ;
948
967
c = reader . peek ( ) ;
@@ -954,7 +973,7 @@ TokenStream.prototype = mix(new TokenStreamBase(), {
954
973
return ident ;
955
974
} ,
956
975
957
- readEscape : function ( first ) {
976
+ readEscape : function ( first , unescape ) {
958
977
var reader = this . _reader ,
959
978
cssEscape = first || "" ,
960
979
i = 0 ,
@@ -967,13 +986,31 @@ TokenStream.prototype = mix(new TokenStreamBase(), {
967
986
} while ( c && isHexDigit ( c ) && ++ i < 6 ) ;
968
987
}
969
988
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 ) ) {
972
991
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 ( ) ;
973
1005
} else {
974
1006
c = "" ;
975
1007
}
976
1008
1009
+ if ( unescape ) {
1010
+ var cp = parseInt ( cssEscape . slice ( first . length ) , 16 ) ;
1011
+ return String . fromCodePoint ? String . fromCodePoint ( cp ) :
1012
+ String . fromCharCode ( cp ) ;
1013
+ }
977
1014
return cssEscape + c ;
978
1015
} ,
979
1016
0 commit comments