From b7f2fa53acb1259a15ef94b5e7978286611ea654 Mon Sep 17 00:00:00 2001 From: Bart Veneman <1536852+bartveneman@users.noreply.github.com> Date: Wed, 5 Apr 2023 11:35:57 +0200 Subject: [PATCH] use case-insensitive Set-like construct to avoid lot of toLowerCase() (#316) --- src/index.js | 28 ++++++++++++------- src/keyword-set.js | 25 +++++++++++++++++ src/values/animations.js | 4 ++- src/values/colors.js | 35 ++++++++++++++---------- src/values/destructure-font-shorthand.js | 6 ++-- src/values/values.js | 4 ++- 6 files changed, 73 insertions(+), 29 deletions(-) create mode 100644 src/keyword-set.js diff --git a/src/index.js b/src/index.js index b63fe30..5217f5d 100644 --- a/src/index.js +++ b/src/index.js @@ -423,18 +423,26 @@ function analyze(css) { if (nodeName.length > 20 || nodeName.length < 3) { return this.skip } - let stringified = stringifyNode(valueNode) - let lowerCased = nodeName.toLowerCase() - if (namedColors.has(lowerCased)) { + if (namedColors.has(nodeName)) { + let stringified = stringifyNode(valueNode) colors.push(stringified, property) colorFormats.push('named') - } else if (colorKeywords.has(lowerCased)) { + return + } + + if (colorKeywords.has(nodeName)) { + let stringified = stringifyNode(valueNode) colors.push(stringified, property) - colorFormats.push(lowerCased) - } else if (systemColors.has(lowerCased)) { + colorFormats.push(nodeName.toLowerCase()) + return + } + + if (systemColors.has(nodeName)) { + let stringified = stringifyNode(valueNode) colors.push(stringified, property) colorFormats.push('system') + return } return this.skip } @@ -443,11 +451,11 @@ function analyze(css) { if (strEquals('var', nodeName)) { return this.skip } - let fnName = nodeName.toLowerCase() - let stringified = stringifyNode(valueNode) - if (colorFunctions.has(fnName)) { + + if (colorFunctions.has(nodeName)) { + let stringified = stringifyNode(valueNode) colors.push(stringified, property) - colorFormats.push(fnName) + colorFormats.push(nodeName.toLowerCase()) } // No this.skip here intentionally, // otherwise we'll miss colors in linear-gradient() etc. diff --git a/src/keyword-set.js b/src/keyword-set.js new file mode 100644 index 0000000..18cf9d8 --- /dev/null +++ b/src/keyword-set.js @@ -0,0 +1,25 @@ +import { strEquals } from "./string-utils.js" + +/** + * @description A Set-like construct to search CSS keywords in a case-insensitive way + */ +export class KeywordSet { + + /** @param {string[]} items */ + constructor(items) { + /** @type {string[]} */ + this.set = items + } + + /** @param {string} item */ + has(item) { + let len = this.set.length + + for (let index = 0; index < len; index++) { + if (strEquals(this.set[index], item)) { + return true + } + } + return false + } +} \ No newline at end of file diff --git a/src/values/animations.js b/src/values/animations.js index 269e229..e8986d6 100644 --- a/src/values/animations.js +++ b/src/values/animations.js @@ -1,4 +1,6 @@ -const timingKeywords = new Set([ +import { KeywordSet } from "../keyword-set.js" + +const timingKeywords = new KeywordSet([ 'linear', 'ease', 'ease-in', diff --git a/src/values/colors.js b/src/values/colors.js index 62491a3..b148e12 100644 --- a/src/values/colors.js +++ b/src/values/colors.js @@ -1,6 +1,21 @@ -export const namedColors = new Set([ +import { KeywordSet } from "../keyword-set.js" + +export const namedColors = new KeywordSet([ // CSS Named Colors // Spec: https://drafts.csswg.org/css-color/#named-colors + + // Heuristic: popular names first for quick finding in set.has() + 'white', + 'black', + 'red', + 'blue', + 'gray', + 'grey', + 'green', + 'rebeccapurple', + 'yellow', + 'orange', + 'aliceblue', 'antiquewhite', 'aqua', @@ -8,9 +23,7 @@ export const namedColors = new Set([ 'azure', 'beige', 'bisque', - 'black', 'blanchedalmond', - 'blue', 'blueviolet', 'brown', 'burlywood', @@ -54,10 +67,7 @@ export const namedColors = new Set([ 'ghostwhite', 'gold', 'goldenrod', - 'gray', - 'green', 'greenyellow', - 'grey', 'honeydew', 'hotpink', 'indianred', @@ -106,7 +116,6 @@ export const namedColors = new Set([ 'oldlace', 'olive', 'olivedrab', - 'orange', 'orangered', 'orchid', 'palegoldenrod', @@ -120,8 +129,6 @@ export const namedColors = new Set([ 'plum', 'powderblue', 'purple', - 'rebeccapurple', - 'red', 'rosybrown', 'royalblue', 'saddlebrown', @@ -145,13 +152,11 @@ export const namedColors = new Set([ 'turquoise', 'violet', 'wheat', - 'white', 'whitesmoke', - 'yellow', 'yellowgreen', ]) -export const systemColors = new Set([ +export const systemColors = new KeywordSet([ // CSS System Colors // Spec: https://drafts.csswg.org/css-color/#css-system-colors 'canvas', @@ -176,7 +181,7 @@ export const systemColors = new Set([ // Spec: https://drafts.csswg.org/css-color/#deprecated-system-colors ]) -export const colorFunctions = new Set([ +export const colorFunctions = new KeywordSet([ 'rgb', 'rgba', 'hsl', @@ -189,7 +194,7 @@ export const colorFunctions = new Set([ 'color', ]) -export const colorKeywords = new Set([ - 'currentcolor', +export const colorKeywords = new KeywordSet([ 'transparent', + 'currentcolor', ]) diff --git a/src/values/destructure-font-shorthand.js b/src/values/destructure-font-shorthand.js index 723ef8b..c32b3d7 100644 --- a/src/values/destructure-font-shorthand.js +++ b/src/values/destructure-font-shorthand.js @@ -1,4 +1,6 @@ -const FONT_KEYWORDS = new Set([ +import { KeywordSet } from "../keyword-set.js" + +const FONT_KEYWORDS = new KeywordSet([ // Global CSS keywords 'inherit', 'initial', @@ -14,7 +16,7 @@ const FONT_KEYWORDS = new Set([ 'status-bar', ]) -const SIZE_KEYWORDS = new Set([ +const SIZE_KEYWORDS = new KeywordSet([ /* values */ 'xx-small', 'x-small', diff --git a/src/values/values.js b/src/values/values.js index a3ef049..3274fd7 100644 --- a/src/values/values.js +++ b/src/values/values.js @@ -1,4 +1,6 @@ -const keywords = new Set([ +import { KeywordSet } from "../keyword-set.js" + +const keywords = new KeywordSet([ 'auto', 'inherit', 'initial',