diff --git a/src/common/Color.test.ts b/src/common/Color.test.ts index 8fd2e393a1..a608908de8 100644 --- a/src/common/Color.test.ts +++ b/src/common/Color.test.ts @@ -229,6 +229,20 @@ describe('Color', () => { assert.deepEqual(css.toColor('#f0f0f0f0'), { css: '#f0f0f0f0', rgba: 0xf0f0f0f0 }); assert.deepEqual(css.toColor('#ffffffff'), { css: '#ffffffff', rgba: 0xffffffff }); }); + it('should convert the rgb() format to an IColor', () => { + assert.deepEqual(css.toColor('rgb(0, 0, 0)'), { css: 'rgb(0, 0, 0)', rgba: 0x000000ff }); + assert.deepEqual(css.toColor('rgb(80, 0, 0)'), { css: 'rgb(80, 0, 0)', rgba: 0x500000ff }); + assert.deepEqual(css.toColor('rgb(0, 80, 0)'), { css: 'rgb(0, 80, 0)', rgba: 0x005000ff }); + assert.deepEqual(css.toColor('rgb(0, 0, 80)'), { css: 'rgb(0, 0, 80)', rgba: 0x000050ff }); + assert.deepEqual(css.toColor('rgb(255, 255, 255)'), { css: 'rgb(255, 255, 255)', rgba: 0xffffffff }); + }); + it('should convert the rgba() format to an IColor', () => { + assert.deepEqual(css.toColor('rgba(0, 0, 0, 0)'), { css: 'rgba(0, 0, 0, 0)', rgba: 0x00000000 }); + assert.deepEqual(css.toColor('rgba(80, 0, 0, 80)'), { css: 'rgba(80, 0, 0, 80)', rgba: 0x50000050 }); + assert.deepEqual(css.toColor('rgba(0, 80, 0, 80)'), { css: 'rgba(0, 80, 0, 80)', rgba: 0x00500050 }); + assert.deepEqual(css.toColor('rgba(0, 0, 80, 80)'), { css: 'rgba(0, 0, 80, 80)', rgba: 0x00005050 }); + assert.deepEqual(css.toColor('rgba(255, 255, 255, 255)'), { css: 'rgba(255, 255, 255, 255)', rgba: 0xffffffff }); + }); }); }); diff --git a/src/common/Color.ts b/src/common/Color.ts index 2b9fca3ad1..3f09601f04 100644 --- a/src/common/Color.ts +++ b/src/common/Color.ts @@ -94,36 +94,50 @@ export namespace color { */ export namespace css { export function toColor(css: string): IColor { - switch (css.length) { - case 4: // #rgb - return { - css, - rgba: channels.toRgba( - parseInt(css.slice(1, 2).repeat(2), 16), - parseInt(css.slice(2, 3).repeat(2), 16), - parseInt(css.slice(3, 4).repeat(2), 16) - ) - }; - case 5: // #rgba - return { - css, - rgba: channels.toRgba( - parseInt(css.slice(1, 2).repeat(2), 16), - parseInt(css.slice(2, 3).repeat(2), 16), - parseInt(css.slice(3, 4).repeat(2), 16), - parseInt(css.slice(4, 5).repeat(2), 16) - ) - }; - case 7: // #rrggbb - return { - css, - rgba: (parseInt(css.slice(1), 16) << 8 | 0xFF) >>> 0 - }; - case 9: // #rrggbbaa - return { - css, - rgba: parseInt(css.slice(1), 16) >>> 0 - }; + if (css.match(/#[0-9a-f]{3,8}/i)) { + switch (css.length) { + case 4: // #rgb + return { + css, + rgba: channels.toRgba( + parseInt(css.slice(1, 2).repeat(2), 16), + parseInt(css.slice(2, 3).repeat(2), 16), + parseInt(css.slice(3, 4).repeat(2), 16) + ) + }; + case 5: // #rgba + return { + css, + rgba: channels.toRgba( + parseInt(css.slice(1, 2).repeat(2), 16), + parseInt(css.slice(2, 3).repeat(2), 16), + parseInt(css.slice(3, 4).repeat(2), 16), + parseInt(css.slice(4, 5).repeat(2), 16) + ) + }; + case 7: // #rrggbb + return { + css, + rgba: (parseInt(css.slice(1), 16) << 8 | 0xFF) >>> 0 + }; + case 9: // #rrggbbaa + return { + css, + rgba: parseInt(css.slice(1), 16) >>> 0 + }; + } + } + const rgbaMatch = css.match(/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(,\s*(\d{1,3})\s*)?\)/); + if (rgbaMatch) { // rgb() or rgba() + return { + css, + rgba: channels.toRgba( + parseInt(rgbaMatch[1]), // r + parseInt(rgbaMatch[2]), // g + parseInt(rgbaMatch[3]), // b + rgbaMatch[5] === undefined ? 0xFF : parseInt(rgbaMatch[5]) // a? + ) + }; } throw new Error('css.toColor: Unsupported css format'); }