From 2005bd59274c91adfb7f6838fc938fdce82b43ac Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Sat, 7 Aug 2021 15:14:24 +0200 Subject: [PATCH] fix: css faster color parsing --- packages/core/css/parser.ts | 85 +++++---------------- packages/core/ui/styling/linear-gradient.ts | 2 +- 2 files changed, 19 insertions(+), 68 deletions(-) diff --git a/packages/core/css/parser.ts b/packages/core/css/parser.ts index 0cea27eed..a2c2a546a 100644 --- a/packages/core/css/parser.ts +++ b/packages/core/css/parser.ts @@ -4,7 +4,6 @@ import { getKnownColor } from '../color/known-colors'; export type Parsed = { start: number; end: number; value: V }; // Values -export type ARGB = number; export type URL = string; export type Angle = number; export interface Unit { @@ -16,7 +15,7 @@ export type Percentage = Unit<'%'>; export type LengthPercentage = Length | Percentage; export type Keyword = string; export interface ColorStop { - argb: ARGB; + color: Color; offset?: LengthPercentage; } export interface LinearGradient { @@ -68,49 +67,31 @@ export function parseURL(text: string, start = 0): Parsed { return { start, end, value }; } -const hexColorRegEx = /\s*#((?:[0-9A-F]{8})|(?:[0-9A-F]{6})|(?:[0-9A-F]{3}))\s*/giy; -export function parseHexColor(text: string, start = 0): Parsed { +const hexColorRegEx = /\s*#((?:[0-9A-F]{8})|(?:[0-9A-F]{6})|(?:[0-9A-F]{4})|(?:[0-9A-F]{3}))\s*/giy; +export function parseHexColor(text: string, start = 0): Parsed { hexColorRegEx.lastIndex = start; const result = hexColorRegEx.exec(text); if (!result) { return null; } const end = hexColorRegEx.lastIndex; - return { start, end, value: new Color('#'+ result[1]).argb }; + return { start, end, value: new Color('#'+ result[1]) }; } -function rgbaToArgbNumber(r: number, g: number, b: number, a = 1): number | undefined { - if (r >= 0 && r <= 255 && g >= 0 && g <= 255 && b >= 0 && b <= 255 && a >= 0 && a <= 1) { - return Math.round(a * 0xff) * 0x01000000 + r * 0x010000 + g * 0x000100 + b; - } else { - return null; - } -} - -const rgbColorRegEx = /\s*(rgb\(\s*(\d*)\s*,\s*(\d*)\s*,\s*(\d*)\s*\))/gy; -export function parseRGBColor(text: string, start = 0): Parsed { - rgbColorRegEx.lastIndex = start; - const result = rgbColorRegEx.exec(text); +const cssColorRegEx = /\s*((?:rgb|rgba|hsl|hsla|hsv|hsva)\([^\(\)]\))/gy; +export function parseCssColor(text: string, start = 0): Parsed { + cssColorRegEx.lastIndex = start; + const result = cssColorRegEx.exec(text); if (!result) { return null; } - const end = rgbColorRegEx.lastIndex; - const value = result[1] && rgbaToArgbNumber(parseInt(result[2]), parseInt(result[3]), parseInt(result[4])); - - return { start, end, value }; -} - -const rgbaColorRegEx = /\s*(rgba\(\s*(\d*)\s*,\s*(\d*)\s*,\s*(\d*)\s*,\s*([01]?\.?\d*)\s*\))/gy; -export function parseRGBAColor(text: string, start = 0): Parsed { - rgbaColorRegEx.lastIndex = start; - const result = rgbaColorRegEx.exec(text); - if (!result) { + const end = cssColorRegEx.lastIndex; + try { + return { start, end, value: new Color(text) }; + } catch { return null; } - const end = rgbaColorRegEx.lastIndex; - const value = rgbaToArgbNumber(parseInt(result[2]), parseInt(result[3]), parseInt(result[4]), parseFloat(result[5])); - return { start, end, value }; } export function convertHSLToRGBColor(hue: number, saturation: number, lightness: number): { r: number; g: number; b: number } { @@ -151,49 +132,19 @@ export function convertHSLToRGBColor(hue: number, saturation: number, lightness: }; } -function hslaToArgbNumber(h: number, s: number, l: number, a = 1): number | undefined { - const { r, g, b } = convertHSLToRGBColor(h, s, l); - return rgbaToArgbNumber(r, g, b, a); -} -const hslColorRegEx = /\s*(hsl\(\s*([\d.]*)\s*,\s*([\d.]*)%\s*,\s*([\d.]*)%\s*\))/gy; -export function parseHSLColor(text: string, start = 0): Parsed { - hslColorRegEx.lastIndex = start; - const result = hslColorRegEx.exec(text); - if (!result) { - return null; - } - const end = hslColorRegEx.lastIndex; - const value = result[1] && hslaToArgbNumber(parseFloat(result[2]), parseFloat(result[3]), parseFloat(result[4])); - - return { start, end, value }; -} - -const hslaColorRegEx = /\s*(hsla\(\s*([\d.]*)\s*,\s*([\d.]*)%\s*,\s*([\d.]*)%\s*,\s*([01]?\.?\d*)\s*\))/gy; -export function parseHSLAColor(text: string, start = 0): Parsed { - hslaColorRegEx.lastIndex = start; - const result = hslaColorRegEx.exec(text); - if (!result) { - return null; - } - const end = hslaColorRegEx.lastIndex; - const value = hslaToArgbNumber(parseFloat(result[2]), parseFloat(result[3]), parseFloat(result[4]), parseFloat(result[5])); - - return { start, end, value }; -} - -export function parseColorKeyword(value, start: number, keyword = parseKeyword(value, start)): Parsed { +export function parseColorKeyword(value, start: number, keyword = parseKeyword(value, start)): Parsed { const parseColor = keyword && getKnownColor(keyword.value); if (parseColor != null) { const end = keyword.end; const value = parseColor; - return { start, end, value }; + return { start, end, value: new Color(parseColor) }; } return null; } -export function parseColor(value: string, start = 0, keyword = parseKeyword(value, start)): Parsed { - return parseHexColor(value, start) || parseColorKeyword(value, start, keyword) || parseRGBColor(value, start) || parseRGBAColor(value, start) || parseHSLColor(value, start) || parseHSLAColor(value, start); +export function parseColor(value: string, start = 0, keyword = parseKeyword(value, start)): Parsed { + return parseHexColor(value, start) || parseColorKeyword(value, start, keyword) || parseCssColor(value, start); } const keywordRegEx = /\s*([a-z][\w\-]*)\s*/giy; @@ -549,11 +500,11 @@ export function parseColorStop(text: string, start = 0): Parsed { return { start, end, - value: { argb: color.value, offset: offset.value }, + value: { color: color.value, offset: offset.value }, }; } - return { start, end, value: { argb: color.value } }; + return { start, end, value: { color: color.value } }; } const linearGradientStartRegEx = /\s*linear-gradient\s*/gy; diff --git a/packages/core/ui/styling/linear-gradient.ts b/packages/core/ui/styling/linear-gradient.ts index ddf308a4b..72b3cad6a 100644 --- a/packages/core/ui/styling/linear-gradient.ts +++ b/packages/core/ui/styling/linear-gradient.ts @@ -22,7 +22,7 @@ export class LinearGradient { } return { - color: new Color(color.argb), + color: color.color, offset: offsetUnit, }; });