From 3ef4a1bdd3152b12ef9148e21027527381e053d7 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Fri, 5 Nov 2021 06:07:04 -0400 Subject: [PATCH 1/7] first pass at accessibility report in checkTheme --- package-lock.json | 39 +++++++++++++++++++++++- package.json | 3 +- tools/checkTheme.js | 74 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 114 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 877b12bf68..453caeb25e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,7 +38,8 @@ "should": "^13.2.3", "terser": "^5.7.0", "tiny-worker": "^2.3.0", - "typescript": "^4.4.4" + "typescript": "^4.4.4", + "wcag-contrast": "^3.0.0" }, "engines": { "node": ">=12.0.0" @@ -3358,6 +3359,15 @@ "node": ">=8" } }, + "node_modules/relative-luminance": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/relative-luminance/-/relative-luminance-2.0.1.tgz", + "integrity": "sha512-wFuITNthJilFPwkK7gNJcULxXBcfFZvZORsvdvxeOdO44wCeZnuQkf3nFFzOR/dpJNxYsdRZJLsepWbyKhnMww==", + "dev": true, + "dependencies": { + "esm": "^3.0.84" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -4075,6 +4085,15 @@ "node": ">=12" } }, + "node_modules/wcag-contrast": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/wcag-contrast/-/wcag-contrast-3.0.0.tgz", + "integrity": "sha512-RWbpg/S7FOXDCwqC2oFhN/vh8dHzj0OS6dpyOSDHyQFSmqmR+lAUStV/ziTT1GzDqL9wol+nZQB4vCi5yEak+w==", + "dev": true, + "dependencies": { + "relative-luminance": "^2.0.0" + } + }, "node_modules/webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", @@ -6839,6 +6858,15 @@ "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", "dev": true }, + "relative-luminance": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/relative-luminance/-/relative-luminance-2.0.1.tgz", + "integrity": "sha512-wFuITNthJilFPwkK7gNJcULxXBcfFZvZORsvdvxeOdO44wCeZnuQkf3nFFzOR/dpJNxYsdRZJLsepWbyKhnMww==", + "dev": true, + "requires": { + "esm": "^3.0.84" + } + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -7399,6 +7427,15 @@ "xml-name-validator": "^4.0.0" } }, + "wcag-contrast": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/wcag-contrast/-/wcag-contrast-3.0.0.tgz", + "integrity": "sha512-RWbpg/S7FOXDCwqC2oFhN/vh8dHzj0OS6dpyOSDHyQFSmqmR+lAUStV/ziTT1GzDqL9wol+nZQB4vCi5yEak+w==", + "dev": true, + "requires": { + "relative-luminance": "^2.0.0" + } + }, "webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", diff --git a/package.json b/package.json index a6376bd740..5777491df6 100644 --- a/package.json +++ b/package.json @@ -84,6 +84,7 @@ "should": "^13.2.3", "terser": "^5.7.0", "tiny-worker": "^2.3.0", - "typescript": "^4.4.4" + "typescript": "^4.4.4", + "wcag-contrast": "^3.0.0" } } diff --git a/tools/checkTheme.js b/tools/checkTheme.js index e40c391ff5..28064024f9 100755 --- a/tools/checkTheme.js +++ b/tools/checkTheme.js @@ -2,6 +2,12 @@ const fs = require("fs"); const css = require("css"); +const wcagContrast = require("wcag-contrast"); +const Table = require('cli-table'); +// const colors = require('colors/safe.js'); + + + require("colors"); const CODE = { @@ -184,6 +190,72 @@ function check_group(group, rules) { } } +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")?.value; + this.fg = rule.declarations.find(x => x.property =="color")?.value; + + // inherit from body if we're missing fg or bg + if (this.hasColor) { + if (!this.bg) this.bg = body.background; + if (!this.fg) this.fg = body.foreground; + } + } + } + get background() { + return this.bg + } + + get foreground() { + return this.fg + } + get hasColor() { + if (!this.rule.declarations) return false; + return this.fg || this.bg; + } + toString() { + return ` ${this.foreground} on ${this.background}` + } + + contrastRatio() { + 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); + + var hljs = rules.find (x => x.selectors && x.selectors.includes(".hljs")); + var body = new CSSRule(hljs); + const table = new Table({ + chars: {'mid': '', 'left-mid': '', 'mid-mid': '', 'right-mid': ''}, + head: ['ratio', 'selector', 'fg', 'bg'], + colWidths: [7, 40, 10, 10], + style: { + head: ['grey'] + } + }); + + rules.forEach(rule => { + var color = new CSSRule(rule, body); + if (!color.hasColor) return; + table.push([ + color.contrastRatio(), + rule.selectors, + color.foreground, + color.background + ]) + // console.log(r.selectors[0], color.contrastRatio(), color.toString()); + }) + console.log(table.toString()) +} + function validate(data) { const rules = data.stylesheet.rules; @@ -195,6 +267,8 @@ function validate(data) { check_group(CODE, rules); check_group(OTHER, rules); check_group(HIGH_FIDELITY, rules); + + contrast_report(rules); } process.argv.shift(); From e5b6e11b1dc6eae01ccfbdd21a0c0a66fb727e6d Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Tue, 16 Nov 2021 07:26:58 -0500 Subject: [PATCH 2/7] resolve CSS color names when necessary --- package-lock.json | 16 ++++++++++++++++ package.json | 1 + tools/checkTheme.js | 8 ++++++++ 3 files changed, 25 insertions(+) diff --git a/package-lock.json b/package-lock.json index 453caeb25e..55b90dec9d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "colors": "^1.1.2", "commander": "8.2", "css": "^3.0.0", + "css-color-names": "^1.0.1", "deep-freeze-es6": "^1.4.1", "del": "^6.0.0", "dependency-resolver": "^2.0.1", @@ -1043,6 +1044,15 @@ "source-map-resolve": "^0.6.0" } }, + "node_modules/css-color-names": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-1.0.1.tgz", + "integrity": "sha512-/loXYOch1qU1biStIFsHH8SxTmOseh1IJqFvy8IujXOm1h+QjUdDhkzOrR5HG8K8mlxREj0yfi8ewCHx0eMxzA==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/cssom": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", @@ -5130,6 +5140,12 @@ "source-map-resolve": "^0.6.0" } }, + "css-color-names": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-1.0.1.tgz", + "integrity": "sha512-/loXYOch1qU1biStIFsHH8SxTmOseh1IJqFvy8IujXOm1h+QjUdDhkzOrR5HG8K8mlxREj0yfi8ewCHx0eMxzA==", + "dev": true + }, "cssom": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", diff --git a/package.json b/package.json index 5777491df6..985b47fdd6 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,7 @@ "colors": "^1.1.2", "commander": "8.2", "css": "^3.0.0", + "css-color-names": "^1.0.1", "deep-freeze-es6": "^1.4.1", "del": "^6.0.0", "dependency-resolver": "^2.0.1", diff --git a/tools/checkTheme.js b/tools/checkTheme.js index 28064024f9..bc6d769ec4 100755 --- a/tools/checkTheme.js +++ b/tools/checkTheme.js @@ -4,6 +4,7 @@ const fs = require("fs"); const css = require("css"); const wcagContrast = require("wcag-contrast"); const Table = require('cli-table'); +const csscolors = require('css-color-names'); // const colors = require('colors/safe.js'); @@ -199,6 +200,13 @@ class CSSRule { this.bg = rule.declarations.find(x => x.property =="background")?.value; this.fg = rule.declarations.find(x => x.property =="color")?.value; + if (this.bg) { + this.bg = csscolors[this.bg] || this.bg; + } + if (this.fg) { + this.fg = csscolors[this.fg] || this.fg; + } + // inherit from body if we're missing fg or bg if (this.hasColor) { if (!this.bg) this.bg = body.background; From 19d3457d6ace215493aaa30a8157523850d8d410 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Tue, 16 Nov 2021 07:29:28 -0500 Subject: [PATCH 3/7] (enh) default Dark theme is WCAG AAA wrt contrast --- src/styles/dark.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/styles/dark.css b/src/styles/dark.css index 34708897f3..052dbc94f1 100644 --- a/src/styles/dark.css +++ b/src/styles/dark.css @@ -6,7 +6,7 @@ Dark style from softwaremaniacs.org (c) Ivan Sagalaev Date: Tue, 16 Nov 2021 07:50:03 -0500 Subject: [PATCH 4/7] (enh) improve accessibility of default theme --- src/styles/default.css | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/styles/default.css b/src/styles/default.css index b34cccf640..e4df55462b 100644 --- a/src/styles/default.css +++ b/src/styles/default.css @@ -26,7 +26,7 @@ code.hljs { /* end baseline CSS */ .hljs { - background: #F0F0F0; + background: #F3F3F3; color: #444; } @@ -43,7 +43,7 @@ code.hljs { .hljs-params {} .hljs-comment { - color: #888888; + color: #697070; } .hljs-tag, .hljs-punctuation { @@ -94,13 +94,13 @@ code.hljs { .hljs-selector-attr, .hljs-operator, .hljs-selector-pseudo { - color: #BC6060; + color: #ab5656; } /* Language color: hue: 90; */ .hljs-literal { - color: #78A960; + color: #695; } .hljs-built_in, @@ -118,7 +118,7 @@ code.hljs { } .hljs-meta .hljs-string { - color: #4d99bf; + color: #38a; } From c77be2f455e28247228a1faa1f83bbc9433a0d1f Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Tue, 16 Nov 2021 12:19:22 -0500 Subject: [PATCH 5/7] changelog --- CHANGES.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 5ca677923e..c1dfe61fdb 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,4 +1,11 @@ -## Version 11.3.2 (most likely) +## Version 11.4 (most likely) + +Themes: + +- `Default` is now much closer WCAG AA (contrast) (#3402) [Josh Goebel] +- `Dark` now meets WCAG AA (contrast) (#3402) [Josh Goebel] + +These changes should be for the better and should not be super noticeable but if you're super picky about your colors you may want to intervene here or copy over the older themes from 11.3 or prior. Grammars: From c9c65f70d19b6d9858fecb15956be949e1c955d2 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Thu, 9 Dec 2021 10:41:50 -0500 Subject: [PATCH 6/7] Update tools/checkTheme.js Co-authored-by: Vladimir Jimenez --- tools/checkTheme.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tools/checkTheme.js b/tools/checkTheme.js index bc6d769ec4..2287bd2dfb 100755 --- a/tools/checkTheme.js +++ b/tools/checkTheme.js @@ -5,10 +5,6 @@ const css = require("css"); const wcagContrast = require("wcag-contrast"); const Table = require('cli-table'); const csscolors = require('css-color-names'); -// const colors = require('colors/safe.js'); - - - require("colors"); const CODE = { From 96169f2ae4f3d408e2c176d0f49d2237ddfde8cc Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Thu, 9 Dec 2021 10:42:04 -0500 Subject: [PATCH 7/7] Update tools/checkTheme.js Co-authored-by: Vladimir Jimenez --- tools/checkTheme.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/checkTheme.js b/tools/checkTheme.js index 2287bd2dfb..bd2587e6d0 100755 --- a/tools/checkTheme.js +++ b/tools/checkTheme.js @@ -227,7 +227,7 @@ class CSSRule { contrastRatio() { if (!this.foreground) return "unknown (no fg)" - if (!this.background) return "unknown(no bg)" + if (!this.background) return "unknown (no bg)" return round2(wcagContrast.hex(this.foreground, this.background)); } }