0
0
mirror of https://github.com/go-gitea/gitea.git synced 2026-05-10 09:41:52 +02:00

Merge 1a1d349b85f0f86f455ac812c1ae03faaf115eb5 into a5d81d9ce230aaa6e1021b6236ca01cb6d2b56c3

This commit is contained in:
Rayan Salhab 2026-05-09 13:10:20 +08:00 committed by GitHub
commit a40528bdcc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 75 additions and 9 deletions

View File

@ -6,8 +6,8 @@
{{if or .Addition .Deletion}}
<div class="flex-text-block tw-flex-shrink-0 tw-text-[13px] {{if .Classes}}{{.Classes}}{{end}}">
<span>
{{if .Addition}}<span class="tw-text-diff-added-fg">+{{.Addition}}</span>{{end}}
{{if .Deletion}}<span class="tw-text-diff-removed-fg">-{{.Deletion}}</span>{{end}}
{{if .Addition}}<strong class="tw-text-diff-added-fg">+{{.Addition}}</strong>{{end}}
{{if .Deletion}}<strong class="tw-text-diff-removed-fg">-{{.Deletion}}</strong>{{end}}
</span>
<span class="diff-stats-bar" data-tooltip-content="{{ctx.Locale.Tr "repo.diff.stats_desc_file" (Eval .Addition "+" .Deletion) .Addition .Deletion}}">
{{/* if the denominator is zero, then the float result is "width: NaNpx", as before, it just works */}}

View File

@ -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;

View File

@ -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;

View File

@ -163,14 +163,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;
@ -270,8 +270,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;

View File

@ -0,0 +1,66 @@
import {readFile} from 'node:fs/promises';
import {join} from 'node:path';
type CssVariables = Record<string, string>;
async function loadThemeVariables(fileName: string, baseVariables: CssVariables = {}): Promise<CssVariables> {
const themePath = 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]);
}
}
});