From db7fdfb3ebe5ec202662ce7465b941e1de819a8e Mon Sep 17 00:00:00 2001 From: biodiscus Date: Wed, 1 Jan 2025 14:55:48 +0100 Subject: [PATCH] refactor(tools): replace @colors/colors with smaller and faster ansis - replace @colors/colors with ansis - add color preview for selectors used in CSS - fix ESLint errors in tools code --- package-lock.json | 33 +++++++++++------------ package.json | 2 +- tools/checkAutoDetect.js | 28 ++++++++++---------- tools/checkTheme.js | 56 +++++++++++++++++++++------------------- 4 files changed, 62 insertions(+), 57 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6a1e9e09c0..0d42663477 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,13 +9,13 @@ "version": "11.11.1", "license": "BSD-3-Clause", "devDependencies": { - "@colors/colors": "^1.6.0", "@rollup/plugin-commonjs": "^28.0.1", "@rollup/plugin-json": "^6.0.1", "@rollup/plugin-node-resolve": "^15.3.0", "@types/mocha": "^10.0.2", "@typescript-eslint/eslint-plugin": "^7.15.0", "@typescript-eslint/parser": "^7.15.0", + "ansis": "^3.5.2", "clean-css": "^5.3.2", "cli-table": "^0.3.1", "commander": "^12.1.0", @@ -57,15 +57,6 @@ "node": ">=0.10.0" } }, - "node_modules/@colors/colors": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", - "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", - "dev": true, - "engines": { - "node": ">=0.1.90" - } - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -1153,6 +1144,16 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/ansis": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ansis/-/ansis-3.5.2.tgz", + "integrity": "sha512-5uGcUZRbORJeEppVdWfZOSybTMz+Ou+84HepgK081Yk5+pPMMzWf/XGxiAT6bfBqCghRB4MwBtYn0CHqINRVag==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, "node_modules/anymatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", @@ -5819,12 +5820,6 @@ "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", "dev": true }, - "@colors/colors": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", - "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", - "dev": true - }, "@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -6467,6 +6462,12 @@ "color-convert": "^2.0.1" } }, + "ansis": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ansis/-/ansis-3.5.2.tgz", + "integrity": "sha512-5uGcUZRbORJeEppVdWfZOSybTMz+Ou+84HepgK081Yk5+pPMMzWf/XGxiAT6bfBqCghRB4MwBtYn0CHqINRVag==", + "dev": true + }, "anymatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", diff --git a/package.json b/package.json index 61236936b6..3196757e18 100644 --- a/package.json +++ b/package.json @@ -58,13 +58,13 @@ "node": ">=12.0.0" }, "devDependencies": { - "@colors/colors": "^1.6.0", "@rollup/plugin-commonjs": "^28.0.1", "@rollup/plugin-json": "^6.0.1", "@rollup/plugin-node-resolve": "^15.3.0", "@types/mocha": "^10.0.2", "@typescript-eslint/eslint-plugin": "^7.15.0", "@typescript-eslint/parser": "^7.15.0", + "ansis": "^3.5.2", "clean-css": "^5.3.2", "cli-table": "^0.3.1", "commander": "^12.1.0", diff --git a/tools/checkAutoDetect.js b/tools/checkAutoDetect.js index 1b4715e45a..8f077df647 100755 --- a/tools/checkAutoDetect.js +++ b/tools/checkAutoDetect.js @@ -6,7 +6,7 @@ const hljs = require('../build/lib/index.js'); const path = require('path'); const utility = require('../test/utility.js'); const Table = require('cli-table'); -const colors = require('@colors/colors/safe.js'); +const { red, grey, green, yellow } = require('ansis'); const resultTable = new Table({ head: ['expected', 'actual', 'score', '2nd best', 'score', 'info'], @@ -29,19 +29,19 @@ function testAutoDetection(language, index, languages) { if (actual.language !== expected && actual.secondBest.language !== expected) { return resultTable.push([ expected, - colors.red(actual.language), - actual.relevance ? actual.relevance : colors.grey('None'), - colors.red(actual.secondBest.language), - actual.secondBest.relevance ? actual.secondBest.relevance : colors.grey('None') + red(actual.language), + actual.relevance ? actual.relevance : grey('None'), + red(actual.secondBest.language), + actual.secondBest.relevance ? actual.secondBest.relevance : grey('None') ]); } if (actual.language !== expected) { return resultTable.push([ expected, - colors.yellow(actual.language), - actual.relevance ? actual.relevance : colors.grey('None'), - colors.yellow(actual.secondBest.language), - actual.secondBest.relevance ? actual.secondBest.relevance : colors.grey('None') + yellow(actual.language), + actual.relevance ? actual.relevance : grey('None'), + yellow(actual.secondBest.language), + actual.secondBest.relevance ? actual.secondBest.relevance : grey('None') ]); } // equal relevance is flagged @@ -49,9 +49,9 @@ function testAutoDetection(language, index, languages) { return resultTable.push([ expected, actual.language, - actual.relevance ? colors.yellow(actual.relevance) : colors.grey('None'), + actual.relevance ? yellow(actual.relevance) : grey('None'), actual.secondBest.language, - actual.secondBest.relevance ? colors.yellow(actual.secondBest.relevance) : colors.grey('None'), + actual.secondBest.relevance ? yellow(actual.secondBest.relevance) : grey('None'), "Relevance match." ]); } @@ -65,7 +65,7 @@ if (process.env.ONLY_LANGUAGES) { languages = hljs.listLanguages().filter(hljs.autoDetection); } -console.log('Checking auto-highlighting for ' + colors.grey(languages.length) + ' languages...'); +console.log('Checking auto-highlighting for ' + grey(languages.length) + ' languages...'); languages.forEach((lang, index) => { if (index % 60 === 0) { console.log(""); } testAutoDetection(lang); @@ -74,10 +74,10 @@ languages.forEach((lang, index) => { console.log("\n"); if (resultTable.length === 0) { - console.log(colors.green('SUCCESS') + ' - ' + colors.green(languages.length) + ' of ' + colors.gray(languages.length) + ' languages passed auto-highlight check!'); + console.log(green('SUCCESS') + ' - ' + green(languages.length) + ' of ' + grey(languages.length) + ' languages passed auto-highlight check!'); } else { console.log( - colors.red('ISSUES') + ' - ' + colors.red(resultTable.length) + ' of ' + colors.gray(languages.length) + ' languages have potential issues.' + red('ISSUES') + ' - ' + red(resultTable.length) + ' of ' + grey(languages.length) + ' languages have potential issues.' + '\n' + resultTable.toString()); } diff --git a/tools/checkTheme.js b/tools/checkTheme.js index c5e49bfd02..a2bc0aed96 100755 --- a/tools/checkTheme.js +++ b/tools/checkTheme.js @@ -5,7 +5,7 @@ const css = require("css"); const wcagContrast = require("wcag-contrast"); const Table = require('cli-table'); const csscolors = require('css-color-names'); -require("@colors/colors"); +const { cyan, green, yellow, magentaBright, hex } = require('ansis'); const CODE = { name: "program code", @@ -167,37 +167,36 @@ function check_group(group, rules) { return [scope, has_rule(selector, rules), skips_rule(selector, rules)]; }); - const doesNotSupport = has_rules.map(x => x[1]).includes(false); const skipped = has_rules.find(x => x[2]); if (doesNotSupport || skipped) { - console.log(group.name.yellow); + console.log(yellow(group.name)); if (doesNotSupport) { - console.log(`- Theme does not fully support.`.brightMagenta); + console.log(magentaBright`- Theme does not fully support.`); } has_rules.filter(x => !x[1]).forEach(([scope, _]) => { const selector = scopeToSelector(scope); - console.log(`- scope ${scope.cyan} is not highlighted\n (css: ${selector.green})`); + console.log(`- scope ${cyan(scope)} is not highlighted\n (css: ${green(selector)})`); }); has_rules.filter(x => x[2]).forEach(([scope, _]) => { - console.log(` - scope ${scope.cyan} [purposely] un-highlighted.`.cyan); + console.log(` - scope ${cyan(scope)} [purposely] un-highlighted.`); }); console.log(); } } -const round2 = (x) => Math.round(x*100)/100; +const round2 = (x) => Math.round(x * 100) / 100; class CSSRule { constructor(rule, body) { this.rule = rule; if (rule.declarations) { - this.bg = rule.declarations.find(x => x.property == "background-color")?.value; + this.bg = rule.declarations.find(x => x.property === "background-color")?.value; if (!this.bg) { - this.bg = rule.declarations.find(x => x.property == "background")?.value; + this.bg = rule.declarations.find(x => x.property === "background")?.value; } - this.fg = rule.declarations.find(x => x.property =="color")?.value; + this.fg = rule.declarations.find(x => x.property === "color")?.value; if (this.bg) { this.bg = csscolors[this.bg] || this.bg; @@ -213,54 +212,58 @@ class CSSRule { } } } + get background() { - return this.bg + return this.bg; } get foreground() { - return this.fg + return this.fg; } + get hasColor() { if (!this.rule.declarations) return false; return this.fg || this.bg; } + toString() { - return ` ${this.foreground} on ${this.background}` + return ` ${this.foreground} on ${this.background}`; } contrastRatio() { - if (!this.foreground) return "unknown (no fg)" - if (!this.background) return "unknown (no bg)" + if (!this.foreground) return "unknown (no fg)"; + if (!this.background) return "unknown (no bg)"; return round2(wcagContrast.hex(this.foreground, this.background)); } } function contrast_report(rules) { - console.log("Accessibility Report".yellow); + console.log(yellow`Accessibility Report`); - var hljs = rules.find (x => x.selectors && x.selectors.includes(".hljs")); - var body = new CSSRule(hljs); + const hljs = rules.find(x => x.selectors && x.selectors.includes(".hljs")); + const body = new CSSRule(hljs); const table = new Table({ - chars: {'mid': '', 'left-mid': '', 'mid-mid': '', 'right-mid': ''}, + chars: { mid: '', 'left-mid': '', 'mid-mid': '', 'right-mid': '' }, head: ['ratio', 'selector', 'fg', 'bg'], - colWidths: [7, 40, 10, 10], + colWidths: [7, 40, 12, 12], style: { head: ['grey'] } }); rules.forEach(rule => { - var color = new CSSRule(rule, body); + const color = new CSSRule(rule, body); if (!color.hasColor) return; table.push([ color.contrastRatio(), rule.selectors, - color.foreground, - color.background - ]) + // colorize the foreground and background colors + hex(color.foreground)('██') + ' ' + color.foreground, + hex(color.background)('██') + ' ' + color.background + ]); // console.log(r.selectors[0], color.contrastRatio(), color.toString()); - }) - console.log(table.toString()) + }); + console.log(table.toString()); } function validate(data) { @@ -275,6 +278,7 @@ function validate(data) { check_group(OTHER, rules); check_group(HIGH_FIDELITY, rules); + contrast_report(rules); }