@@ -98,7 +98,7 @@ var kCSSColorTable = {
9898 "yellow" : [ 255 , 255 , 0 , 1 ] , "yellowgreen" : [ 154 , 205 , 50 , 1 ] }
9999
100100function 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).
102102 return i < 0 ? 0 : i > 255 ? 255 : i ;
103103}
104104
@@ -118,6 +118,16 @@ function parse_css_float(str) { // float or percentage.
118118 return clamp_css_float ( parseFloat ( str ) ) ;
119119}
120120
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+
121131function parseCSSColor ( css_str ) {
122132 // Remove all whitespace, not compliant, but should just be more accepting.
123133 var str = css_str . replace ( / / g, '' ) . toLowerCase ( ) ;
@@ -150,20 +160,35 @@ function parseCSSColor(css_str) {
150160 if ( op !== - 1 && ep + 1 === str . length ) {
151161 var fname = str . substr ( 0 , op ) ;
152162 var params = str . substr ( op + 1 , ep - ( op + 1 ) ) . split ( ',' ) ;
163+ var alpha = 1 ; // To allow case fallthrough.
153164 switch ( fname ) {
165+ case 'rgba' :
166+ if ( params . length !== 4 ) return null ;
167+ alpha = parse_css_float ( params . pop ( ) ) ;
168+ // Fall through.
154169 case 'rgb' :
155170 if ( params . length !== 3 ) return null ;
156171 return [ parse_css_int ( params [ 0 ] ) ,
157172 parse_css_int ( params [ 1 ] ) ,
158173 parse_css_int ( params [ 2 ] ) ,
159- 1 ] ;
160- case 'rgba ' :
174+ alpha ] ;
175+ case 'hsla ' :
161176 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 ] ;
167192 default :
168193 return null ;
169194 }
0 commit comments