@@ -98,7 +98,7 @@ var kCSSColorTable = {
98
98
"yellow" : [ 255 , 255 , 0 , 1 ] , "yellowgreen" : [ 154 , 205 , 50 , 1 ] }
99
99
100
100
function clamp_css_byte ( i ) { // Clamp to integer 0 .. 255.
101
- i = i >> 0 ;
101
+ i = Math . round ( i ) ; // Seems to be what Chrome does (vs truncation).
102
102
return i < 0 ? 0 : i > 255 ? 255 : i ;
103
103
}
104
104
@@ -118,6 +118,16 @@ function parse_css_float(str) { // float or percentage.
118
118
return clamp_css_float ( parseFloat ( str ) ) ;
119
119
}
120
120
121
+ function css_hue_to_rgb ( m1 , m2 , h ) {
122
+ if ( h < 0 ) h += 1 ;
123
+ else if ( h > 1 ) h -= 1 ;
124
+
125
+ if ( h * 6 < 1 ) return m1 + ( m2 - m1 ) * h * 6 ;
126
+ if ( h * 2 < 1 ) return m2 ;
127
+ if ( h * 3 < 2 ) return m1 + ( m2 - m1 ) * ( 2 / 3 - h ) * 6 ;
128
+ return m1 ;
129
+ }
130
+
121
131
function parseCSSColor ( css_str ) {
122
132
// Remove all whitespace, not compliant, but should just be more accepting.
123
133
var str = css_str . replace ( / / g, '' ) . toLowerCase ( ) ;
@@ -150,20 +160,35 @@ function parseCSSColor(css_str) {
150
160
if ( op !== - 1 && ep + 1 === str . length ) {
151
161
var fname = str . substr ( 0 , op ) ;
152
162
var params = str . substr ( op + 1 , ep - ( op + 1 ) ) . split ( ',' ) ;
163
+ var alpha = 1 ; // To allow case fallthrough.
153
164
switch ( fname ) {
165
+ case 'rgba' :
166
+ if ( params . length !== 4 ) return null ;
167
+ alpha = parse_css_float ( params . pop ( ) ) ;
168
+ // Fall through.
154
169
case 'rgb' :
155
170
if ( params . length !== 3 ) return null ;
156
171
return [ parse_css_int ( params [ 0 ] ) ,
157
172
parse_css_int ( params [ 1 ] ) ,
158
173
parse_css_int ( params [ 2 ] ) ,
159
- 1 ] ;
160
- case 'rgba ' :
174
+ alpha ] ;
175
+ case 'hsla ' :
161
176
if ( params . length !== 4 ) return null ;
162
- return [ parse_css_int ( params [ 0 ] ) ,
163
- parse_css_int ( params [ 1 ] ) ,
164
- parse_css_int ( params [ 2 ] ) ,
165
- parse_css_float ( params [ 3 ] ) ] ;
166
- // TODO(deanm): HSL / HSV.
177
+ alpha = parse_css_float ( params . pop ( ) ) ;
178
+ // Fall through.
179
+ case 'hsl' :
180
+ if ( params . length !== 3 ) return null ;
181
+ var h = ( ( ( parseFloat ( params [ 0 ] ) % 360 ) + 360 ) % 360 ) / 360 ; // 0 .. 1
182
+ // NOTE(deanm): According to the CSS spec s/l should only be
183
+ // percentages, but we don't bother and let float or percentage.
184
+ var s = parse_css_float ( params [ 1 ] ) ;
185
+ var l = parse_css_float ( params [ 2 ] ) ;
186
+ var m2 = l <= 0.5 ? l * ( s + 1 ) : l + s - l * s ;
187
+ var m1 = l * 2 - m2 ;
188
+ return [ clamp_css_byte ( css_hue_to_rgb ( m1 , m2 , h + 1 / 3 ) * 255 ) ,
189
+ clamp_css_byte ( css_hue_to_rgb ( m1 , m2 , h ) * 255 ) ,
190
+ clamp_css_byte ( css_hue_to_rgb ( m1 , m2 , h - 1 / 3 ) * 255 ) ,
191
+ alpha ] ;
167
192
default :
168
193
return null ;
169
194
}
0 commit comments