diff --git a/package.json b/package.json
index 0cb50dc167e6e..b615a2ace3363 100644
--- a/package.json
+++ b/package.json
@@ -18,9 +18,12 @@
"@testing-library/jest-dom": "^5.11.0",
"axios": "^0.19.2",
"axios-mock-adapter": "^1.18.1",
+ "color-contrast-checker": "^2.1.0",
"css-to-object": "^1.1.0",
+ "hjson": "^3.2.2",
"husky": "^4.2.5",
"jest": "^26.1.0",
+ "lodash.snakecase": "^4.1.1",
"parse-diff": "^0.7.0"
},
"dependencies": {
diff --git a/scripts/preview-theme.js b/scripts/preview-theme.js
index 31622c6a7d400..f9be3f99989b8 100644
--- a/scripts/preview-theme.js
+++ b/scripts/preview-theme.js
@@ -1,6 +1,10 @@
const core = require("@actions/core");
const github = require("@actions/github");
const parse = require("parse-diff");
+const Hjson = require("hjson");
+const snakeCase = require("lodash.snakecase");
+const ColorContrastChecker = require("color-contrast-checker");
+
require("dotenv").config();
function getPrNumber() {
@@ -21,6 +25,8 @@ const themeContribGuidelines = `
async function run() {
try {
+ const ccc = new ColorContrastChecker();
+ const warnings = [];
const token = core.getInput("token");
const octokit = github.getOctokit(token || process.env.PERSONAL_TOKEN);
const pullRequestId = getPrNumber();
@@ -30,7 +36,7 @@ async function run() {
return;
}
- let res = await octokit.pulls.get({
+ const res = await octokit.pulls.get({
owner: "anuraghazra",
repo: "github-readme-stats",
pull_number: pullRequestId,
@@ -39,15 +45,20 @@ async function run() {
},
});
- let diff = parse(res.data);
- let colorStrings = diff
+ const diff = parse(res.data);
+ const content = diff
.find((file) => file.to === "themes/index.js")
.chunks[0].changes.filter((c) => c.type === "add")
.map((c) => c.content.replace("+", ""))
.join("");
- let matches = colorStrings.match(/(title_color:.*bg_color.*\")/);
- let colors = matches && matches[0].split(",");
+ const themeObject = Hjson.parse(content);
+ const themeName = Object.keys(themeObject)[0];
+ const colors = themeObject[themeName];
+
+ if (themeName !== snakeCase(themeName)) {
+ warnings.push("Theme name isn't in snake_case");
+ }
if (!colors) {
await octokit.issues.createComment({
@@ -64,22 +75,39 @@ async function run() {
});
return;
}
- colors = colors.map((color) =>
- color.replace(/.*\:\s/, "").replace(/\"/g, ""),
- );
-
- const titleColor = colors[0];
- const iconColor = colors[1];
- const textColor = colors[2];
- const bgColor = colors[3];
+
+ const titleColor = colors.title_color;
+ const iconColor = colors.icon_color;
+ const textColor = colors.text_color;
+ const bgColor = colors.bg_color;
const url = `https://github-readme-stats.vercel.app/api?username=anuraghazra&title_color=${titleColor}&icon_color=${iconColor}&text_color=${textColor}&bg_color=${bgColor}&show_icons=true`;
+ const colorPairs = {
+ title_color: [titleColor, bgColor],
+ icon_color: [iconColor, bgColor],
+ text_color: [textColor, bgColor],
+ };
+
+ // check color contrast
+ Object.keys(colorPairs).forEach((key) => {
+ const color1 = colorPairs[key][0];
+ const color2 = colorPairs[key][1];
+ if (!ccc.isLevelAA(`#${color1}`, `#${color2}`)) {
+ const permalink = `https://webaim.org/resources/contrastchecker/?fcolor=${color1}&bcolor=${color2}`;
+ warnings.push(
+ `\`${key}\` does not passes [AA contrast ratio](${permalink})`,
+ );
+ }
+ });
+
await octokit.issues.createComment({
owner: "anuraghazra",
repo: "github-readme-stats",
body: `
\r**Automated Theme preview**
+ \r${warnings.map((warning) => `- :warning: ${warning}\n`).join("")}
+
\ntitle_color: #${titleColor}
| icon_color: #${iconColor}
| text_color: #${textColor}
| bg_color: #${bgColor}
\r[Preview Link](${url})