mirror of
https://github.com/go-gitea/gitea.git
synced 2026-05-11 11:25:42 +02:00
Improve dark diff contrast
Co-authored-by: Hermes Agent (GPT-5.5) <hermes-agent@nousresearch.com> Signed-off-by: cyphercodes <cyphercodes@users.noreply.github.com>
This commit is contained in:
parent
0ba862cb97
commit
40bcb68030
@ -1728,6 +1728,11 @@ tbody.commit-list {
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
|
||||
.diff-file-header .tw-text-diff-added-fg,
|
||||
.diff-file-header .tw-text-diff-removed-fg {
|
||||
font-weight: var(--font-weight-semibold);
|
||||
}
|
||||
|
||||
.diff-stats-bar {
|
||||
display: inline-block;
|
||||
background-color: var(--color-diff-removed-fg); /* the background is used as "text foreground color" */
|
||||
|
||||
@ -8,11 +8,11 @@ gitea-theme-meta-info {
|
||||
|
||||
/* red/green colorblind-friendly colors */
|
||||
:root {
|
||||
--color-diff-added-fg: #58a6ff;
|
||||
--color-diff-added-fg: #65adff;
|
||||
--color-diff-added-linenum-bg: #243d5d;
|
||||
--color-diff-added-row-bg: #132339;
|
||||
--color-diff-added-word-bg: #214d87;
|
||||
--color-diff-removed-fg: #f0883e;
|
||||
--color-diff-removed-fg: #f2964f;
|
||||
--color-diff-removed-linenum-bg: #5b361c;
|
||||
--color-diff-removed-row-bg: #3c2419;
|
||||
--color-diff-removed-word-bg: #824e1f;
|
||||
|
||||
@ -8,7 +8,7 @@ gitea-theme-meta-info {
|
||||
|
||||
/* blue/yellow colorblind-friendly colors */
|
||||
:root {
|
||||
--color-diff-added-fg: #58a6ff;
|
||||
--color-diff-added-fg: #65adff;
|
||||
--color-diff-added-linenum-bg: #243d5d;
|
||||
--color-diff-added-row-bg: #132339;
|
||||
--color-diff-added-word-bg: #214d87;
|
||||
|
||||
@ -146,14 +146,14 @@ gitea-theme-meta-info {
|
||||
--color-grey-light: #898d96;
|
||||
--color-gold: #b1983b;
|
||||
--color-white: #ffffff;
|
||||
--color-diff-added-fg: #87ab63;
|
||||
--color-diff-added-fg: #93b373;
|
||||
--color-diff-added-linenum-bg: #274227;
|
||||
--color-diff-added-row-bg: #203224;
|
||||
--color-diff-added-row-border: #314a37;
|
||||
--color-diff-added-word-bg: #3c653c;
|
||||
--color-diff-moved-row-bg: #818044;
|
||||
--color-diff-moved-row-border: #bcca6f;
|
||||
--color-diff-removed-fg: #cc4848;
|
||||
--color-diff-removed-fg: #ff8585;
|
||||
--color-diff-removed-linenum-bg: #482121;
|
||||
--color-diff-removed-row-bg: #301e1e;
|
||||
--color-diff-removed-row-border: #634343;
|
||||
@ -253,8 +253,8 @@ gitea-theme-meta-info {
|
||||
--color-syntax-keyword: #ff8854;
|
||||
--color-syntax-bool: #25bbc9;
|
||||
--color-syntax-control: #dd9e17;
|
||||
--color-syntax-name: #c7a618;
|
||||
--color-syntax-type: #eb8cb3;
|
||||
--color-syntax-name: #fabd2f;
|
||||
--color-syntax-type: #fabd2f;
|
||||
--color-syntax-number: #63b2dd;
|
||||
--color-syntax-operator: #ff8854;
|
||||
--color-syntax-regexp: #b89de4;
|
||||
|
||||
66
web_src/js/utils/theme-contrast.test.ts
Normal file
66
web_src/js/utils/theme-contrast.test.ts
Normal file
@ -0,0 +1,66 @@
|
||||
import {readFile} from 'node:fs/promises';
|
||||
import * as path from 'node:path';
|
||||
|
||||
type CssVariables = Record<string, string>;
|
||||
|
||||
async function loadThemeVariables(fileName: string, baseVariables: CssVariables = {}): Promise<CssVariables> {
|
||||
const themePath = path.join(import.meta.dirname, '../../css/themes', fileName);
|
||||
const css = await readFile(themePath, 'utf8');
|
||||
const variables = {...baseVariables};
|
||||
for (const match of css.matchAll(/(--[\w-]+):\s*(#[\dA-Fa-f]{6});/g)) {
|
||||
variables[match[1]] = match[2];
|
||||
}
|
||||
return variables;
|
||||
}
|
||||
|
||||
function relativeLuminance(hex: string): number {
|
||||
const rgb = [
|
||||
Number.parseInt(hex.slice(1, 3), 16),
|
||||
Number.parseInt(hex.slice(3, 5), 16),
|
||||
Number.parseInt(hex.slice(5, 7), 16),
|
||||
].map((value) => {
|
||||
const channel = value / 255;
|
||||
return channel <= 0.04045 ? channel / 12.92 : ((channel + 0.055) / 1.055) ** 2.4;
|
||||
});
|
||||
return 0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2];
|
||||
}
|
||||
|
||||
function contrastRatio(foreground: string, background: string): number {
|
||||
const foregroundLuminance = relativeLuminance(foreground);
|
||||
const backgroundLuminance = relativeLuminance(background);
|
||||
return (Math.max(foregroundLuminance, backgroundLuminance) + 0.05) /
|
||||
(Math.min(foregroundLuminance, backgroundLuminance) + 0.05);
|
||||
}
|
||||
|
||||
function expectWcagAaaContrast(label: string, foreground: string, background: string): void {
|
||||
expect(contrastRatio(foreground, background), label).toBeGreaterThanOrEqual(7);
|
||||
}
|
||||
|
||||
test('dark diff stat colors have WCAG AAA contrast', async () => {
|
||||
const darkVariables = await loadThemeVariables('theme-gitea-dark.css');
|
||||
const colorblindVariables = await loadThemeVariables('theme-gitea-dark-protanopia-deuteranopia.css', darkVariables);
|
||||
const tritanopiaVariables = await loadThemeVariables('theme-gitea-dark-tritanopia.css', darkVariables);
|
||||
const themes: Array<[string, CssVariables, string]> = [
|
||||
['dark added', darkVariables, '--color-diff-added-fg'],
|
||||
['dark removed', darkVariables, '--color-diff-removed-fg'],
|
||||
['dark protanopia/deuteranopia added', colorblindVariables, '--color-diff-added-fg'],
|
||||
['dark protanopia/deuteranopia removed', colorblindVariables, '--color-diff-removed-fg'],
|
||||
['dark tritanopia added', tritanopiaVariables, '--color-diff-added-fg'],
|
||||
];
|
||||
|
||||
for (const [label, variables, colorVariable] of themes) {
|
||||
expectWcagAaaContrast(label, variables[colorVariable], darkVariables['--color-body']);
|
||||
}
|
||||
});
|
||||
|
||||
test('dark syntax name colors have WCAG AAA contrast on diff rows', async () => {
|
||||
const variables = await loadThemeVariables('theme-gitea-dark.css');
|
||||
const backgrounds = ['--color-diff-added-row-bg', '--color-diff-removed-row-bg'] as const;
|
||||
const foregrounds = ['--color-syntax-name', '--color-syntax-type'] as const;
|
||||
|
||||
for (const foreground of foregrounds) {
|
||||
for (const background of backgrounds) {
|
||||
expectWcagAaaContrast(`${foreground} on ${background}`, variables[foreground], variables[background]);
|
||||
}
|
||||
}
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user