From c5692363575821ef588b2260e80ad5bbffe45293 Mon Sep 17 00:00:00 2001 From: Martin Guillon Date: Tue, 10 Nov 2020 02:00:22 +0100 Subject: [PATCH] perf: faster color parsing (#9001) --- packages/core/color/color-common.ts | 4 +- packages/core/color/known-colors.ts | 296 ++++++++++++++-------------- packages/core/css/parser.ts | 237 +++++----------------- 3 files changed, 196 insertions(+), 341 deletions(-) diff --git a/packages/core/color/color-common.ts b/packages/core/color/color-common.ts index 0ee611dfe..7aa4e474b 100644 --- a/packages/core/color/color-common.ts +++ b/packages/core/color/color-common.ts @@ -23,9 +23,9 @@ export class Color implements definition.Color { this._argb = argbFromHslOrHsla(arg); } else if (knownColors.isKnownName(arg)) { // The parameter is a known color name - const hex = knownColors.getKnownColor(arg); + const argb = knownColors.getKnownColor(arg); this._name = arg; - this._argb = this._argbFromString(hex); + this._argb = argb; } else if (HEX_REGEX.test(arg)) { // The parameter is a "#AARRGGBB" formatted string const hex = this._normalizeHex(arg); diff --git a/packages/core/color/known-colors.ts b/packages/core/color/known-colors.ts index 648f8ef86..766c3315e 100644 --- a/packages/core/color/known-colors.ts +++ b/packages/core/color/known-colors.ts @@ -1,6 +1,10 @@ -const _allColors = {}; -function registerColor(name, value): string { - _allColors[name.toLowerCase()] = value; +const _allColors:{[k:string]:number} = {}; +function registerColor(name: string | string[], value: number): number { + if (Array.isArray(name)) { + name.forEach(n=>_allColors[n.toLowerCase()] = value) + } else { + _allColors[name.toLowerCase()] = value; + } return value; } @@ -13,7 +17,7 @@ export function isKnownName(name: string) { return name.toLowerCase() in _allColors; } -export function getKnownColor(name: string): string { +export function getKnownColor(name: string): number { if (!name) { return undefined; } @@ -21,145 +25,145 @@ export function getKnownColor(name: string): string { return _allColors[name.toLowerCase()]; } -export const Transparent = registerColor('Transparent', '#00000000'); -export const AliceBlue = registerColor('AliceBlue', '#F0F8FF'); -export const AntiqueWhite = registerColor('AntiqueWhite', '#FAEBD7'); -export const Aqua = registerColor('Aqua', '#00FFFF'); -export const Aquamarine = registerColor('Aquamarine', '#7FFFD4'); -export const Azure = registerColor('Azure', '#F0FFFF'); -export const Beige = registerColor('Beige', '#F5F5DC'); -export const Bisque = registerColor('Bisque', '#FFE4C4'); -export const Black = registerColor('Black', '#000000'); -export const BlanchedAlmond = registerColor('BlanchedAlmond', '#FFEBCD'); -export const Blue = registerColor('Blue', '#0000FF'); -export const BlueViolet = registerColor('BlueViolet', '#8A2BE2'); -export const Brown = registerColor('Brown', '#A52A2A'); -export const BurlyWood = registerColor('BurlyWood', '#DEB887'); -export const CadetBlue = registerColor('CadetBlue', '#5F9EA0'); -export const Chartreuse = registerColor('Chartreuse', '#7FFF00'); -export const Chocolate = registerColor('Chocolate', '#D2691E'); -export const Coral = registerColor('Coral', '#FF7F50'); -export const CornflowerBlue = registerColor('CornflowerBlue', '#6495ED'); -export const Cornsilk = registerColor('Cornsilk', '#FFF8DC'); -export const Crimson = registerColor('Crimson', '#DC143C'); -export const Cyan = registerColor('Cyan', '#00FFFF'); -export const DarkBlue = registerColor('DarkBlue', '#00008B'); -export const DarkCyan = registerColor('DarkCyan', '#008B8B'); -export const DarkGoldenRod = registerColor('DarkGoldenRod', '#B8860B'); -export const DarkGray = registerColor('DarkGray', '#A9A9A9'); -export const DarkGreen = registerColor('DarkGreen', '#006400'); -export const DarkKhaki = registerColor('DarkKhaki', '#BDB76B'); -export const DarkMagenta = registerColor('DarkMagenta', '#8B008B'); -export const DarkOliveGreen = registerColor('DarkOliveGreen', '#556B2F'); -export const DarkOrange = registerColor('DarkOrange', '#FF8C00'); -export const DarkOrchid = registerColor('DarkOrchid', '#9932CC'); -export const DarkRed = registerColor('DarkRed', '#8B0000'); -export const DarkSalmon = registerColor('DarkSalmon', '#E9967A'); -export const DarkSeaGreen = registerColor('DarkSeaGreen', '#8FBC8F'); -export const DarkSlateBlue = registerColor('DarkSlateBlue', '#483D8B'); -export const DarkSlateGray = registerColor('DarkSlateGray', '#2F4F4F'); -export const DarkTurquoise = registerColor('DarkTurquoise', '#00CED1'); -export const DarkViolet = registerColor('DarkViolet', '#9400D3'); -export const DeepPink = registerColor('DeepPink', '#FF1493'); -export const DeepSkyBlue = registerColor('DeepSkyBlue', '#00BFFF'); -export const DimGray = registerColor('DimGray', '#696969'); -export const DodgerBlue = registerColor('DodgerBlue', '#1E90FF'); -export const FireBrick = registerColor('FireBrick', '#B22222'); -export const FloralWhite = registerColor('FloralWhite', '#FFFAF0'); -export const ForestGreen = registerColor('ForestGreen', '#228B22'); -export const Fuchsia = registerColor('Fuchsia', '#FF00FF'); -export const Gainsboro = registerColor('Gainsboro', '#DCDCDC'); -export const GhostWhite = registerColor('GhostWhite', '#F8F8FF'); -export const Gold = registerColor('Gold', '#FFD700'); -export const GoldenRod = registerColor('GoldenRod', '#DAA520'); -export const Gray = registerColor('Gray', '#808080'); -export const Green = registerColor('Green', '#008000'); -export const GreenYellow = registerColor('GreenYellow', '#ADFF2F'); -export const HoneyDew = registerColor('HoneyDew', '#F0FFF0'); -export const HotPink = registerColor('HotPink', '#FF69B4'); -export const IndianRed = registerColor('IndianRed', '#CD5C5C'); -export const Indigo = registerColor('Indigo', '#4B0082'); -export const Ivory = registerColor('Ivory', '#FFFFF0'); -export const Khaki = registerColor('Khaki', '#F0E68C'); -export const Lavender = registerColor('Lavender', '#E6E6FA'); -export const LavenderBlush = registerColor('LavenderBlush', '#FFF0F5'); -export const LawnGreen = registerColor('LawnGreen', '#7CFC00'); -export const LemonChiffon = registerColor('LemonChiffon', '#FFFACD'); -export const LightBlue = registerColor('LightBlue', '#ADD8E6'); -export const LightCoral = registerColor('LightCoral', '#F08080'); -export const LightCyan = registerColor('LightCyan', '#E0FFFF'); -export const LightGoldenRodYellow = registerColor('LightGoldenRodYellow', '#FAFAD2'); -export const LightGray = registerColor('LightGray', '#D3D3D3'); -export const LightGreen = registerColor('LightGreen', '#90EE90'); -export const LightPink = registerColor('LightPink', '#FFB6C1'); -export const LightSalmon = registerColor('LightSalmon', '#FFA07A'); -export const LightSeaGreen = registerColor('LightSeaGreen', '#20B2AA'); -export const LightSkyBlue = registerColor('LightSkyBlue', '#87CEFA'); -export const LightSlateGray = registerColor('LightSlateGray', '#778899'); -export const LightSteelBlue = registerColor('LightSteelBlue', '#B0C4DE'); -export const LightYellow = registerColor('LightYellow', '#FFFFE0'); -export const Lime = registerColor('Lime', '#00FF00'); -export const LimeGreen = registerColor('LimeGreen', '#32CD32'); -export const Linen = registerColor('Linen', '#FAF0E6'); -export const Magenta = registerColor('Magenta', '#FF00FF'); -export const Maroon = registerColor('Maroon', '#800000'); -export const MediumAquaMarine = registerColor('MediumAquaMarine', '#66CDAA'); -export const MediumBlue = registerColor('MediumBlue', '#0000CD'); -export const MediumOrchid = registerColor('MediumOrchid', '#BA55D3'); -export const MediumPurple = registerColor('MediumPurple', '#9370DB'); -export const MediumSeaGreen = registerColor('MediumSeaGreen', '#3CB371'); -export const MediumSlateBlue = registerColor('MediumSlateBlue', '#7B68EE'); -export const MediumSpringGreen = registerColor('MediumSpringGreen', '#00FA9A'); -export const MediumTurquoise = registerColor('MediumTurquoise', '#48D1CC'); -export const MediumVioletRed = registerColor('MediumVioletRed', '#C71585'); -export const MidnightBlue = registerColor('MidnightBlue', '#191970'); -export const MintCream = registerColor('MintCream', '#F5FFFA'); -export const MistyRose = registerColor('MistyRose', '#FFE4E1'); -export const Moccasin = registerColor('Moccasin', '#FFE4B5'); -export const NavajoWhite = registerColor('NavajoWhite', '#FFDEAD'); -export const Navy = registerColor('Navy', '#000080'); -export const OldLace = registerColor('OldLace', '#FDF5E6'); -export const Olive = registerColor('Olive', '#808000'); -export const OliveDrab = registerColor('OliveDrab', '#6B8E23'); -export const Orange = registerColor('Orange', '#FFA500'); -export const OrangeRed = registerColor('OrangeRed', '#FF4500'); -export const Orchid = registerColor('Orchid', '#DA70D6'); -export const PaleGoldenRod = registerColor('PaleGoldenRod', '#EEE8AA'); -export const PaleGreen = registerColor('PaleGreen', '#98FB98'); -export const PaleTurquoise = registerColor('PaleTurquoise', '#AFEEEE'); -export const PaleVioletRed = registerColor('PaleVioletRed', '#DB7093'); -export const PapayaWhip = registerColor('PapayaWhip', '#FFEFD5'); -export const PeachPuff = registerColor('PeachPuff', '#FFDAB9'); -export const Peru = registerColor('Peru', '#CD853F'); -export const Pink = registerColor('Pink', '#FFC0CB'); -export const Plum = registerColor('Plum', '#DDA0DD'); -export const PowderBlue = registerColor('PowderBlue', '#B0E0E6'); -export const Purple = registerColor('Purple', '#800080'); -export const RebeccaPurple = registerColor('RebeccaPurple', '#663399'); -export const Red = registerColor('Red', '#FF0000'); -export const RosyBrown = registerColor('RosyBrown', '#BC8F8F'); -export const RoyalBlue = registerColor('RoyalBlue', '#4169E1'); -export const SaddleBrown = registerColor('SaddleBrown', '#8B4513'); -export const Salmon = registerColor('Salmon', '#FA8072'); -export const SandyBrown = registerColor('SandyBrown', '#F4A460'); -export const SeaGreen = registerColor('SeaGreen', '#2E8B57'); -export const SeaShell = registerColor('SeaShell', '#FFF5EE'); -export const Sienna = registerColor('Sienna', '#A0522D'); -export const Silver = registerColor('Silver', '#C0C0C0'); -export const SkyBlue = registerColor('SkyBlue', '#87CEEB'); -export const SlateBlue = registerColor('SlateBlue', '#6A5ACD'); -export const SlateGray = registerColor('SlateGray', '#708090'); -export const Snow = registerColor('Snow', '#FFFAFA'); -export const SpringGreen = registerColor('SpringGreen', '#00FF7F'); -export const SteelBlue = registerColor('SteelBlue', '#4682B4'); -export const Tan = registerColor('Tan', '#D2B48C'); -export const Teal = registerColor('Teal', '#008080'); -export const Thistle = registerColor('Thistle', '#D8BFD8'); -export const Tomato = registerColor('Tomato', '#FF6347'); -export const Turquoise = registerColor('Turquoise', '#40E0D0'); -export const Violet = registerColor('Violet', '#EE82EE'); -export const Wheat = registerColor('Wheat', '#F5DEB3'); -export const White = registerColor('White', '#FFFFFF'); -export const WhiteSmoke = registerColor('WhiteSmoke', '#F5F5F5'); -export const Yellow = registerColor('Yellow', '#FFFF00'); -export const YellowGreen = registerColor('YellowGreen', '#9ACD32'); +export const Transparent = registerColor('Transparent', 0x00000000); +export const AliceBlue = registerColor('AliceBlue', 0xffF0F8FF); +export const AntiqueWhite = registerColor('AntiqueWhite', 0xffFAEBD7); +export const Aqua = registerColor('Aqua', 0xff00FFFF); +export const Aquamarine = registerColor('Aquamarine', 0xff7FFFD4); +export const Azure = registerColor('Azure', 0xffF0FFFF); +export const Beige = registerColor('Beige', 0xffF5F5DC); +export const Bisque = registerColor('Bisque', 0xffFFE4C4); +export const Black = registerColor('Black', 0xff000000); +export const BlanchedAlmond = registerColor('BlanchedAlmond', 0xffFFEBCD); +export const Blue = registerColor('Blue', 0xff0000FF); +export const BlueViolet = registerColor('BlueViolet', 0xff8A2BE2); +export const Brown = registerColor('Brown', 0xffA52A2A); +export const BurlyWood = registerColor('BurlyWood', 0xffDEB887); +export const CadetBlue = registerColor('CadetBlue', 0xff5F9EA0); +export const Chartreuse = registerColor('Chartreuse', 0xff7FFF00); +export const Chocolate = registerColor('Chocolate', 0xffD2691E); +export const Coral = registerColor('Coral', 0xffFF7F50); +export const CornflowerBlue = registerColor('CornflowerBlue', 0xff6495ED); +export const Cornsilk = registerColor('Cornsilk', 0xffFFF8DC); +export const Crimson = registerColor('Crimson', 0xffDC143C); +export const Cyan = registerColor('Cyan', 0xff00FFFF); +export const DarkBlue = registerColor('DarkBlue', 0xff00008B); +export const DarkCyan = registerColor('DarkCyan', 0xff008B8B); +export const DarkGoldenRod = registerColor('DarkGoldenRod', 0xffB8860B); +export const DarkGray = registerColor(['DarkGray', 'DarkGrey'], 0xffA9A9A9); +export const DarkGreen = registerColor('DarkGreen', 0xff006400); +export const DarkKhaki = registerColor('DarkKhaki', 0xffBDB76B); +export const DarkMagenta = registerColor('DarkMagenta', 0xff8B008B); +export const DarkOliveGreen = registerColor('DarkOliveGreen', 0xff556B2F); +export const DarkOrange = registerColor('DarkOrange', 0xffFF8C00); +export const DarkOrchid = registerColor('DarkOrchid', 0xff9932CC); +export const DarkRed = registerColor('DarkRed', 0xff8B0000); +export const DarkSalmon = registerColor('DarkSalmon', 0xffE9967A); +export const DarkSeaGreen = registerColor('DarkSeaGreen', 0xff8FBC8F); +export const DarkSlateBlue = registerColor('DarkSlateBlue', 0xff483D8B); +export const DarkSlateGray = registerColor(['DarkSlateGray', 'DarkSlateGrey'], 0xff2F4F4F); +export const DarkTurquoise = registerColor('DarkTurquoise', 0xff00CED1); +export const DarkViolet = registerColor('DarkViolet', 0xff9400D3); +export const DeepPink = registerColor('DeepPink', 0xffFF1493); +export const DeepSkyBlue = registerColor('DeepSkyBlue', 0xff00BFFF); +export const DimGray = registerColor(['DimGray', 'DimGrey'], 0xff696969); +export const DodgerBlue = registerColor('DodgerBlue', 0xff1E90FF); +export const FireBrick = registerColor('FireBrick', 0xffB22222); +export const FloralWhite = registerColor('FloralWhite', 0xffFFFAF0); +export const ForestGreen = registerColor('ForestGreen', 0xff228B22); +export const Fuchsia = registerColor('Fuchsia', 0xffFF00FF); +export const Gainsboro = registerColor('Gainsboro', 0xffDCDCDC); +export const GhostWhite = registerColor('GhostWhite', 0xffF8F8FF); +export const Gold = registerColor('Gold', 0xffFFD700); +export const GoldenRod = registerColor('GoldenRod', 0xffDAA520); +export const Gray = registerColor(['Gray', 'Grey'], 0xff808080); +export const Green = registerColor('Green', 0xff008000); +export const GreenYellow = registerColor('GreenYellow', 0xffADFF2F); +export const HoneyDew = registerColor('HoneyDew', 0xffF0FFF0); +export const HotPink = registerColor('HotPink', 0xffFF69B4); +export const IndianRed = registerColor('IndianRed', 0xffCD5C5C); +export const Indigo = registerColor('Indigo', 0xff4B0082); +export const Ivory = registerColor('Ivory', 0xffFFFFF0); +export const Khaki = registerColor('Khaki', 0xffF0E68C); +export const Lavender = registerColor('Lavender', 0xffE6E6FA); +export const LavenderBlush = registerColor('LavenderBlush', 0xffFFF0F5); +export const LawnGreen = registerColor('LawnGreen', 0xff7CFC00); +export const LemonChiffon = registerColor('LemonChiffon', 0xffFFFACD); +export const LightBlue = registerColor('LightBlue', 0xffADD8E6); +export const LightCoral = registerColor('LightCoral', 0xffF08080); +export const LightCyan = registerColor('LightCyan', 0xffE0FFFF); +export const LightGoldenRodYellow = registerColor('LightGoldenRodYellow', 0xffFAFAD2); +export const LightGray = registerColor(['LightGray', 'LightGrey'], 0xffD3D3D3); +export const LightGreen = registerColor('LightGreen', 0xff90EE90); +export const LightPink = registerColor('LightPink', 0xffFFB6C1); +export const LightSalmon = registerColor('LightSalmon', 0xffFFA07A); +export const LightSeaGreen = registerColor('LightSeaGreen', 0xff20B2AA); +export const LightSkyBlue = registerColor('LightSkyBlue', 0xff87CEFA); +export const LightSlateGray = registerColor(['LightSlateGray', 'LightSlateGrey'], 0xff778899); +export const LightSteelBlue = registerColor('LightSteelBlue', 0xffB0C4DE); +export const LightYellow = registerColor('LightYellow', 0xffFFFFE0); +export const Lime = registerColor('Lime', 0xff00FF00); +export const LimeGreen = registerColor('LimeGreen', 0xff32CD32); +export const Linen = registerColor('Linen', 0xffFAF0E6); +export const Magenta = registerColor('Magenta', 0xffFF00FF); +export const Maroon = registerColor('Maroon', 0xff800000); +export const MediumAquaMarine = registerColor('MediumAquaMarine', 0xff66CDAA); +export const MediumBlue = registerColor('MediumBlue', 0xff0000CD); +export const MediumOrchid = registerColor('MediumOrchid', 0xffBA55D3); +export const MediumPurple = registerColor('MediumPurple', 0xff9370DB); +export const MediumSeaGreen = registerColor('MediumSeaGreen', 0xff3CB371); +export const MediumSlateBlue = registerColor('MediumSlateBlue', 0xff7B68EE); +export const MediumSpringGreen = registerColor('MediumSpringGreen', 0xff00FA9A); +export const MediumTurquoise = registerColor('MediumTurquoise', 0xff48D1CC); +export const MediumVioletRed = registerColor('MediumVioletRed', 0xffC71585); +export const MidnightBlue = registerColor('MidnightBlue', 0xff191970); +export const MintCream = registerColor('MintCream', 0xffF5FFFA); +export const MistyRose = registerColor('MistyRose', 0xffFFE4E1); +export const Moccasin = registerColor('Moccasin', 0xffFFE4B5); +export const NavajoWhite = registerColor('NavajoWhite', 0xffFFDEAD); +export const Navy = registerColor('Navy', 0xff000080); +export const OldLace = registerColor('OldLace', 0xffFDF5E6); +export const Olive = registerColor('Olive', 0xff808000); +export const OliveDrab = registerColor('OliveDrab', 0xff6B8E23); +export const Orange = registerColor('Orange', 0xffFFA500); +export const OrangeRed = registerColor('OrangeRed', 0xffFF4500); +export const Orchid = registerColor('Orchid', 0xffDA70D6); +export const PaleGoldenRod = registerColor('PaleGoldenRod', 0xffEEE8AA); +export const PaleGreen = registerColor('PaleGreen', 0xff98FB98); +export const PaleTurquoise = registerColor('PaleTurquoise', 0xffAFEEEE); +export const PaleVioletRed = registerColor('PaleVioletRed', 0xffDB7093); +export const PapayaWhip = registerColor('PapayaWhip', 0xffFFEFD5); +export const PeachPuff = registerColor('PeachPuff', 0xffFFDAB9); +export const Peru = registerColor('Peru', 0xffCD853F); +export const Pink = registerColor('Pink', 0xffFFC0CB); +export const Plum = registerColor('Plum', 0xffDDA0DD); +export const PowderBlue = registerColor('PowderBlue', 0xffB0E0E6); +export const Purple = registerColor('Purple', 0xff800080); +export const RebeccaPurple = registerColor('RebeccaPurple', 0xff663399); +export const Red = registerColor('Red', 0xffFF0000); +export const RosyBrown = registerColor('RosyBrown', 0xffBC8F8F); +export const RoyalBlue = registerColor('RoyalBlue', 0xff4169E1); +export const SaddleBrown = registerColor('SaddleBrown', 0xff8B4513); +export const Salmon = registerColor('Salmon', 0xffFA8072); +export const SandyBrown = registerColor('SandyBrown', 0xffF4A460); +export const SeaGreen = registerColor('SeaGreen', 0xff2E8B57); +export const SeaShell = registerColor('SeaShell', 0xffFFF5EE); +export const Sienna = registerColor('Sienna', 0xffA0522D); +export const Silver = registerColor('Silver', 0xffC0C0C0); +export const SkyBlue = registerColor('SkyBlue', 0xff87CEEB); +export const SlateBlue = registerColor('SlateBlue', 0xff6A5ACD); +export const SlateGray = registerColor(['SlateGray', 'SlateGrey'], 0xff708090); +export const Snow = registerColor('Snow', 0xffFFFAFA); +export const SpringGreen = registerColor('SpringGreen', 0xff00FF7F); +export const SteelBlue = registerColor('SteelBlue', 0xff4682B4); +export const Tan = registerColor('Tan', 0xffD2B48C); +export const Teal = registerColor('Teal', 0xff008080); +export const Thistle = registerColor('Thistle', 0xffD8BFD8); +export const Tomato = registerColor('Tomato', 0xffFF6347); +export const Turquoise = registerColor('Turquoise', 0xff40E0D0); +export const Violet = registerColor('Violet', 0xffEE82EE); +export const Wheat = registerColor('Wheat', 0xffF5DEB3); +export const White = registerColor('White', 0xffFFFFFF); +export const WhiteSmoke = registerColor('WhiteSmoke', 0xffF5F5F5); +export const Yellow = registerColor('Yellow', 0xffFFFF00); +export const YellowGreen = registerColor('YellowGreen', 0xff9ACD32); diff --git a/packages/core/css/parser.ts b/packages/core/css/parser.ts index b93e559dc..5d66dc542 100644 --- a/packages/core/css/parser.ts +++ b/packages/core/css/parser.ts @@ -1,3 +1,5 @@ +import { getKnownColor } from "../color/known-colors"; + export type Parsed = { start: number; end: number; value: V }; // Values @@ -53,7 +55,7 @@ export interface BackgroundPosition { } const urlRegEx = /\s*url\((?:('|")([^\1]*)\1|([^\)]*))\)\s*/gy; -export function parseURL(text: string, start: number = 0): Parsed { +export function parseURL(text: string, start = 0): Parsed { urlRegEx.lastIndex = start; const result = urlRegEx.exec(text); if (!result) { @@ -66,14 +68,14 @@ export function parseURL(text: string, start: number = 0): Parsed { } const hexColorRegEx = /\s*#((?:[0-9A-F]{8})|(?:[0-9A-F]{6})|(?:[0-9A-F]{3}))\s*/giy; -export function parseHexColor(text: string, start: number = 0): Parsed { +export function parseHexColor(text: string, start = 0): Parsed { hexColorRegEx.lastIndex = start; const result = hexColorRegEx.exec(text); if (!result) { return null; } const end = hexColorRegEx.lastIndex; - let hex = result[1]; + const hex = result[1]; let argb; if (hex.length === 8) { argb = parseInt('0x' + hex); @@ -86,7 +88,7 @@ export function parseHexColor(text: string, start: number = 0): Parsed { return { start, end, value: argb }; } -function rgbaToArgbNumber(r: number, g: number, b: number, a: number = 1): number | undefined { +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 { @@ -95,7 +97,7 @@ function rgbaToArgbNumber(r: number, g: number, b: number, a: number = 1): numbe } const rgbColorRegEx = /\s*(rgb\(\s*(\d*)\s*,\s*(\d*)\s*,\s*(\d*)\s*\))/gy; -export function parseRGBColor(text: string, start: number = 0): Parsed { +export function parseRGBColor(text: string, start = 0): Parsed { rgbColorRegEx.lastIndex = start; const result = rgbColorRegEx.exec(text); if (!result) { @@ -108,7 +110,7 @@ export function parseRGBColor(text: string, start: number = 0): Parsed { } const rgbaColorRegEx = /\s*(rgba\(\s*(\d*)\s*,\s*(\d*)\s*,\s*(\d*)\s*,\s*([01]?\.?\d*)\s*\))/gy; -export function parseRGBAColor(text: string, start: number = 0): Parsed { +export function parseRGBAColor(text: string, start = 0): Parsed { rgbaColorRegEx.lastIndex = start; const result = rgbaColorRegEx.exec(text); if (!result) { @@ -158,8 +160,8 @@ export function convertHSLToRGBColor(hue: number, saturation: number, lightness: }; } -function hslaToArgbNumber(h: number, s: number, l: number, a: number = 1): number | undefined { - let { r, g, b } = convertHSLToRGBColor(h, s, l); +function hslaToArgbNumber(h: number, s: number, l: number, a = 1): number | undefined { + const { r, g, b } = convertHSLToRGBColor(h, s, l); 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; @@ -169,7 +171,7 @@ function hslaToArgbNumber(h: number, s: number, l: number, a: number = 1): numbe } const hslColorRegEx = /\s*(hsl\(\s*([\d.]*)\s*,\s*([\d.]*)%\s*,\s*([\d.]*)%\s*\))/gy; -export function parseHSLColor(text: string, start: number = 0): Parsed { +export function parseHSLColor(text: string, start = 0): Parsed { hslColorRegEx.lastIndex = start; const result = hslColorRegEx.exec(text); if (!result) { @@ -182,7 +184,7 @@ export function parseHSLColor(text: string, start: number = 0): Parsed { } const hslaColorRegEx = /\s*(hsla\(\s*([\d.]*)\s*,\s*([\d.]*)%\s*,\s*([\d.]*)%\s*,\s*([01]?\.?\d*)\s*\))/gy; -export function parseHSLAColor(text: string, start: number = 0): Parsed { +export function parseHSLAColor(text: string, start = 0): Parsed { hslaColorRegEx.lastIndex = start; const result = hslaColorRegEx.exec(text); if (!result) { @@ -194,175 +196,24 @@ export function parseHSLAColor(text: string, start: number = 0): Parsed { return { start, end, value }; } -export enum colors { - transparent = 0x00000000, - aliceblue = 0xfff0f8ff, - antiquewhite = 0xfffaebd7, - aqua = 0xff00ffff, - aquamarine = 0xff7fffd4, - azure = 0xfff0ffff, - beige = 0xfff5f5dc, - bisque = 0xffffe4c4, - black = 0xff000000, - blanchedalmond = 0xffffebcd, - blue = 0xff0000ff, - blueviolet = 0xff8a2be2, - brown = 0xffa52a2a, - burlywood = 0xffdeb887, - cadetblue = 0xff5f9ea0, - chartreuse = 0xff7fff00, - chocolate = 0xffd2691e, - coral = 0xffff7f50, - cornflowerblue = 0xff6495ed, - cornsilk = 0xfffff8dc, - crimson = 0xffdc143c, - cyan = 0xff00ffff, - darkblue = 0xff00008b, - darkcyan = 0xff008b8b, - darkgoldenrod = 0xffb8860b, - darkgray = 0xffa9a9a9, - darkgreen = 0xff006400, - darkgrey = 0xffa9a9a9, - darkkhaki = 0xffbdb76b, - darkmagenta = 0xff8b008b, - darkolivegreen = 0xff556b2f, - darkorange = 0xffff8c00, - darkorchid = 0xff9932cc, - darkred = 0xff8b0000, - darksalmon = 0xffe9967a, - darkseagreen = 0xff8fbc8f, - darkslateblue = 0xff483d8b, - darkslategray = 0xff2f4f4f, - darkslategrey = 0xff2f4f4f, - darkturquoise = 0xff00ced1, - darkviolet = 0xff9400d3, - deeppink = 0xffff1493, - deepskyblue = 0xff00bfff, - dimgray = 0xff696969, - dimgrey = 0xff696969, - dodgerblue = 0xff1e90ff, - firebrick = 0xffb22222, - floralwhite = 0xfffffaf0, - forestgreen = 0xff228b22, - fuchsia = 0xffff00ff, - gainsboro = 0xffdcdcdc, - ghostwhite = 0xfff8f8ff, - gold = 0xffffd700, - goldenrod = 0xffdaa520, - gray = 0xff808080, - green = 0xff008000, - greenyellow = 0xffadff2f, - grey = 0xff808080, - honeydew = 0xfff0fff0, - hotpink = 0xffff69b4, - indianred = 0xffcd5c5c, - indigo = 0xff4b0082, - ivory = 0xfffffff0, - khaki = 0xfff0e68c, - lavender = 0xffe6e6fa, - lavenderblush = 0xfffff0f5, - lawngreen = 0xff7cfc00, - lemonchiffon = 0xfffffacd, - lightblue = 0xffadd8e6, - lightcoral = 0xfff08080, - lightcyan = 0xffe0ffff, - lightgoldenrodyellow = 0xfffafad2, - lightgray = 0xffd3d3d3, - lightgreen = 0xff90ee90, - lightgrey = 0xffd3d3d3, - lightpink = 0xffffb6c1, - lightsalmon = 0xffffa07a, - lightseagreen = 0xff20b2aa, - lightskyblue = 0xff87cefa, - lightslategray = 0xff778899, - lightslategrey = 0xff778899, - lightsteelblue = 0xffb0c4de, - lightyellow = 0xffffffe0, - lime = 0xff00ff00, - limegreen = 0xff32cd32, - linen = 0xfffaf0e6, - magenta = 0xffff00ff, - maroon = 0xff800000, - mediumaquamarine = 0xff66cdaa, - mediumblue = 0xff0000cd, - mediumorchid = 0xffba55d3, - mediumpurple = 0xff9370db, - mediumseagreen = 0xff3cb371, - mediumslateblue = 0xff7b68ee, - mediumspringgreen = 0xff00fa9a, - mediumturquoise = 0xff48d1cc, - mediumvioletred = 0xffc71585, - midnightblue = 0xff191970, - mintcream = 0xfff5fffa, - mistyrose = 0xffffe4e1, - moccasin = 0xffffe4b5, - navajowhite = 0xffffdead, - navy = 0xff000080, - oldlace = 0xfffdf5e6, - olive = 0xff808000, - olivedrab = 0xff6b8e23, - orange = 0xffffa500, - orangered = 0xffff4500, - orchid = 0xffda70d6, - palegoldenrod = 0xffeee8aa, - palegreen = 0xff98fb98, - paleturquoise = 0xffafeeee, - palevioletred = 0xffdb7093, - papayawhip = 0xffffefd5, - peachpuff = 0xffffdab9, - peru = 0xffcd853f, - pink = 0xffffc0cb, - plum = 0xffdda0dd, - powderblue = 0xffb0e0e6, - purple = 0xff800080, - rebeccapurple = 0xff663399, - red = 0xffff0000, - rosybrown = 0xffbc8f8f, - royalblue = 0xff4169e1, - saddlebrown = 0xff8b4513, - salmon = 0xfffa8072, - sandybrown = 0xfff4a460, - seagreen = 0xff2e8b57, - seashell = 0xfffff5ee, - sienna = 0xffa0522d, - silver = 0xffc0c0c0, - skyblue = 0xff87ceeb, - slateblue = 0xff6a5acd, - slategray = 0xff708090, - slategrey = 0xff708090, - snow = 0xfffffafa, - springgreen = 0xff00ff7f, - steelblue = 0xff4682b4, - tan = 0xffd2b48c, - teal = 0xff008080, - thistle = 0xffd8bfd8, - tomato = 0xffff6347, - turquoise = 0xff40e0d0, - violet = 0xffee82ee, - wheat = 0xfff5deb3, - white = 0xffffffff, - whitesmoke = 0xfff5f5f5, - yellow = 0xffffff00, - yellowgreen = 0xff9acd32, -} export function parseColorKeyword(value, start: number, keyword = parseKeyword(value, start)): Parsed { - if (keyword && keyword.value in colors) { + const parseColor = keyword && getKnownColor(keyword.value); + if (parseColor !== undefined) { const end = keyword.end; - const value = colors[keyword.value]; - + const value = parseColor; return { start, end, value }; } return null; } -export function parseColor(value: string, start: number = 0, keyword = parseKeyword(value, start)): Parsed { +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); } const keywordRegEx = /\s*([a-z][\w\-]*)\s*/giy; -function parseKeyword(text: string, start: number = 0): Parsed { +function parseKeyword(text: string, start = 0): Parsed { keywordRegEx.lastIndex = start; const result = keywordRegEx.exec(text); if (!result) { @@ -375,7 +226,7 @@ function parseKeyword(text: string, start: number = 0): Parsed { } const backgroundRepeatKeywords = new Set(['repeat', 'repeat-x', 'repeat-y', 'no-repeat']); -export function parseRepeat(value: string, start: number = 0, keyword = parseKeyword(value, start)): Parsed { +export function parseRepeat(value: string, start = 0, keyword = parseKeyword(value, start)): Parsed { if (keyword && backgroundRepeatKeywords.has(keyword.value)) { const end = keyword.end; const value = keyword.value; @@ -387,7 +238,7 @@ export function parseRepeat(value: string, start: number = 0, keyword = parseKey } const unitRegEx = /\s*([\+\-]?(?:\d+\.\d+|\d+|\.\d+)(?:[eE][\+\-]?\d+)?)([a-zA-Z]+|%)?\s*/gy; -export function parseUnit(text: string, start: number = 0): Parsed> { +export function parseUnit(text: string, start = 0): Parsed> { unitRegEx.lastIndex = start; const result = unitRegEx.exec(text); if (!result) { @@ -400,7 +251,7 @@ export function parseUnit(text: string, start: number = 0): Parsed> return { start, end, value: { value, unit } }; } -export function parsePercentageOrLength(text: string, start: number = 0): Parsed { +export function parsePercentageOrLength(text: string, start = 0): Parsed { const unitResult = parseUnit(text, start); if (unitResult) { const { start, end } = unitResult; @@ -445,7 +296,7 @@ const angleUnitsToRadMap: { value: turn * Math.PI * 2, }), }; -export function parseAngle(value: string, start: number = 0): Parsed { +export function parseAngle(value: string, start = 0): Parsed { const angleResult = parseUnit(value, start); if (angleResult) { const { start, end, value } = angleResult; @@ -457,7 +308,7 @@ export function parseAngle(value: string, start: number = 0): Parsed { } const backgroundSizeKeywords = new Set(['auto', 'contain', 'cover']); -export function parseBackgroundSize(value: string, start: number = 0, keyword = parseKeyword(value, start)): Parsed { +export function parseBackgroundSize(value: string, start = 0, keyword = parseKeyword(value, start)): Parsed { let end = start; if (keyword && backgroundSizeKeywords.has(keyword.value)) { end = keyword.end; @@ -497,7 +348,7 @@ const backgroundPositionKeywordsDirection: { top: 'y', bottom: 'y', }; -export function parseBackgroundPosition(text: string, start: number = 0, keyword = parseKeyword(text, start)): Parsed { +export function parseBackgroundPosition(text: string, start = 0, keyword = parseKeyword(text, start)): Parsed { function formatH(align: Parsed, offset: Parsed) { if (align.value === 'center') { return 'center'; @@ -521,7 +372,7 @@ export function parseBackgroundPosition(text: string, start: number = 0, keyword let end = start; if (keyword && backgroundPositionKeywords.has(keyword.value)) { end = keyword.end; - let firstDirection = backgroundPositionKeywordsDirection[keyword.value]; + const firstDirection = backgroundPositionKeywordsDirection[keyword.value]; const firstLength = firstDirection !== 'center' && parsePercentageOrLength(text, end); if (firstLength) { @@ -531,7 +382,7 @@ export function parseBackgroundPosition(text: string, start: number = 0, keyword const secondKeyword = parseKeyword(text, end); if (secondKeyword && backgroundPositionKeywords.has(secondKeyword.value)) { end = secondKeyword.end; - let secondDirection = backgroundPositionKeywordsDirection[secondKeyword.end]; + const secondDirection = backgroundPositionKeywordsDirection[secondKeyword.end]; if (firstDirection === secondDirection && firstDirection !== 'center') { return null; // Reject pair of both horizontal or both vertical alignments. @@ -641,7 +492,7 @@ const cornerDirections = { bottom: (Math.PI * 5) / 4, }, }; -function parseDirection(text: string, start: number = 0): Parsed { +function parseDirection(text: string, start = 0): Parsed { directionRegEx.lastIndex = start; const result = directionRegEx.exec(text); if (!result) { @@ -700,7 +551,7 @@ function parseArgumentsList(text: string, start: number, argument: (value: st } } -export function parseColorStop(text: string, start: number = 0): Parsed { +export function parseColorStop(text: string, start = 0): Parsed { const color = parseColor(text, start); if (!color) { return null; @@ -721,7 +572,7 @@ export function parseColorStop(text: string, start: number = 0): Parsed { +export function parseLinearGradient(text: string, start = 0): Parsed { linearGradientStartRegEx.lastIndex = start; const lgs = linearGradientStartRegEx.exec(text); if (!lgs) { @@ -772,7 +623,7 @@ function parseSlash(text: string, start: number): Parsed<'/'> { return { start, end, value: '/' }; } -export function parseBackground(text: string, start: number = 0): Parsed { +export function parseBackground(text: string, start = 0): Parsed { const value: any = {}; let end = start; while (end < text.length) { @@ -865,7 +716,7 @@ export type SelectorCombinatorPair = [SimpleSelectorSequence, Combinator]; export type Selector = SelectorCombinatorPair[]; const universalSelectorRegEx = /\*/gy; -export function parseUniversalSelector(text: string, start: number = 0): Parsed { +export function parseUniversalSelector(text: string, start = 0): Parsed { universalSelectorRegEx.lastIndex = start; const result = universalSelectorRegEx.exec(text); if (!result) { @@ -878,7 +729,7 @@ export function parseUniversalSelector(text: string, start: number = 0): Parsed< const simpleIdentifierSelectorRegEx = /(#|\.|:|\b)((?:[\w_-]|\\.)(?:[\w\d_-]|\\.)*)/guy; const unicodeEscapeRegEx = /\\([0-9a-fA-F]{1,5}\s|[0-9a-fA-F]{6})/g; -export function parseSimpleIdentifierSelector(text: string, start: number = 0): Parsed { +export function parseSimpleIdentifierSelector(text: string, start = 0): Parsed { simpleIdentifierSelectorRegEx.lastIndex = start; const result = simpleIdentifierSelectorRegEx.exec(text.replace(unicodeEscapeRegEx, (_, c) => '\\' + String.fromCodePoint(parseInt(c.trim(), 16)))); if (!result) { @@ -911,7 +762,7 @@ export function parseAttributeSelector(text: string, start: number): Parsed { +export function parseSimpleSelector(text: string, start = 0): Parsed { return parseUniversalSelector(text, start) || parseSimpleIdentifierSelector(text, start) || parseAttributeSelector(text, start); } @@ -921,7 +772,7 @@ export function parseSimpleSelectorSequence(text: string, start: number): Parsed return null; } let end = simpleSelector.end; - let value = []; + const value = []; while (simpleSelector) { value.push(simpleSelector.value); end = simpleSelector.end; @@ -932,7 +783,7 @@ export function parseSimpleSelectorSequence(text: string, start: number): Parsed } const combinatorRegEx = /\s*(\+|~|>)?\s*/gy; -export function parseCombinator(text: string, start: number = 0): Parsed { +export function parseCombinator(text: string, start = 0): Parsed { combinatorRegEx.lastIndex = start; const result = combinatorRegEx.exec(text); if (!result) { @@ -945,14 +796,14 @@ export function parseCombinator(text: string, start: number = 0): Parsed { +export function parseSelector(text: string, start = 0): Parsed { let end = start; whiteSpaceRegEx.lastIndex = end; const leadingWhiteSpace = whiteSpaceRegEx.exec(text); if (leadingWhiteSpace) { end = whiteSpaceRegEx.lastIndex; } - let value = []; + const value = []; let combinator: Parsed; let expectSimpleSelector = true; // Must have at least one let pair: SelectorCombinatorPair; @@ -1092,7 +943,7 @@ interface SimpleBlock extends InputTokenObject { values: InputToken[]; } -interface AtKeywordToken extends InputTokenObject {} +type AtKeywordToken = InputTokenObject /** * CSS parser following relatively close: @@ -1111,7 +962,7 @@ export class CSS3Parser { * This method allows us to run and assert the proper working of the tokenizer. */ tokenize(): InputToken[] { - let tokens: InputToken[] = []; + const tokens: InputToken[] = []; let inputToken: InputToken; do { inputToken = this.consumeAToken(); @@ -1127,7 +978,7 @@ export class CSS3Parser { */ private consumeAToken(): InputToken { if (this.reconsumedInputToken) { - let result = this.reconsumedInputToken; + const result = this.reconsumedInputToken; this.reconsumedInputToken = null; return result; @@ -1224,7 +1075,7 @@ export class CSS3Parser { private consumeAHashToken(): InputTokenObject { this.nextInputCodePointIndex++; - let hashName = this.consumeAName(); + const hashName = this.consumeAName(); if (hashName) { return { type: TokenObjectType.hash, text: '#' + hashName.text }; } @@ -1429,7 +1280,7 @@ export class CSS3Parser { private consumeAtKeyword(): InputTokenObject { this.nextInputCodePointIndex++; - let name = this.consumeAName(); + const name = this.consumeAName(); if (name) { return { type: TokenObjectType.atKeyword, text: name.text }; } @@ -1559,7 +1410,7 @@ export class CSS3Parser { let inputToken: InputToken; while ((inputToken = this.consumeAToken())) { if (inputToken === '{') { - let block = this.consumeASimpleBlock(inputToken); + const block = this.consumeASimpleBlock(inputToken); qualifiedRule.block = block; return qualifiedRule; @@ -1739,7 +1590,7 @@ export class CSSNativeScript { let reading: 'property' | 'value' = 'property'; for (let i = 0; i < declarationsInputTokens.length; i++) { - let inputToken = declarationsInputTokens[i]; + const inputToken = declarationsInputTokens[i]; if (reading === 'property') { if (inputToken === ':') { reading = 'value'; @@ -1773,7 +1624,7 @@ export class CSSNativeScript { } private preludeToSelectorsStringArray(prelude: InputToken[]): string[] { - let selectors = []; + const selectors = []; let selector = ''; prelude.forEach((inputToken) => { if (typeof inputToken === 'string') {