Files
ModelForge-Public/frontend/scripts/accessibility-contrast.mjs
T

50 lines
2.3 KiB
JavaScript

import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
const styles = readFileSync(new URL("../src/styles.css", import.meta.url), "utf8");
function cssBlock(selector) {
const escapedSelector = selector.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const block = styles.match(new RegExp(`${escapedSelector}\\s*\\{([^}]+)\\}`))?.[1];
assert.ok(block, `Missing CSS token block ${selector}`);
return block;
}
function token(block, name) {
const value = block.match(new RegExp(`--${name}:\\s*(#[\\da-fA-F]{6})`))?.[1];
assert.ok(value, `Missing color token --${name}`);
return value;
}
function luminance(hex) {
const color = Number.parseInt(hex.slice(1), 16);
const channels = [(color >> 16) & 255, (color >> 8) & 255, color & 255].map((channel) => {
const srgb = channel / 255;
return srgb <= 0.04045 ? srgb / 12.92 : ((srgb + 0.055) / 1.055) ** 2.4;
});
return 0.2126 * channels[0] + 0.7152 * channels[1] + 0.0722 * channels[2];
}
function contrastRatio(foreground, background) {
const foregroundLuminance = luminance(foreground);
const backgroundLuminance = luminance(background);
return (Math.max(foregroundLuminance, backgroundLuminance) + 0.05) /
(Math.min(foregroundLuminance, backgroundLuminance) + 0.05);
}
const dark = cssBlock(":root");
const darkFaint = token(dark, "text-faint");
const darkCardRatio = contrastRatio(darkFaint, token(dark, "n-02"));
const darkRaisedRatio = contrastRatio(darkFaint, token(dark, "n-03"));
assert.ok(darkCardRatio >= 4.5, `Dark faint text on --n-02 is ${darkCardRatio.toFixed(2)}:1`);
assert.ok(darkRaisedRatio >= 4.5, `Dark faint text on --n-03 is ${darkRaisedRatio.toFixed(2)}:1`);
const light = cssBlock(':root[data-theme="light"]');
const lightFaint = token(light, "text-faint");
const lightSurfaceRatio = contrastRatio(lightFaint, token(light, "n-01"));
const lightCardRatio = contrastRatio(lightFaint, token(light, "n-02"));
assert.ok(lightSurfaceRatio >= 4.5, `Light faint text on --n-01 is ${lightSurfaceRatio.toFixed(2)}:1`);
assert.ok(lightCardRatio >= 4.5, `Light faint text on --n-02 is ${lightCardRatio.toFixed(2)}:1`);
console.log(`Contrast token gate passed (dark ${darkCardRatio.toFixed(2)}:1/${darkRaisedRatio.toFixed(2)}:1; light ${lightSurfaceRatio.toFixed(2)}:1/${lightCardRatio.toFixed(2)}:1).`);