chore(web): veraltete Kommentare, Theme-Skript in IIFE, CARD_W/CARD_H und reportsLabel nur aus einer Quelle

- publish.ts und editor-page.ts: Kommentare zum Aufräumen bzw. zur Adresse /gestalten?karte= stimmen wieder.
- index.html: Inline-Skript für Hell/Dunkel in einer sofort aufgerufenen Funktion (keine globale Variable theme);
  Test führt es aus und vergleicht mit initialTheme().
- CARD_W/CARD_H nur noch aus card/geometry.ts (Startseite, Detailseite, Raster), Vorschauhöhe des Rasters daraus abgeleitet;
  reportsLabel nur aus pages/format.ts. Ein Test sorgt dafür, dass es dabei bleibt.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-10-04 16:40:17 +00:00
1 parent f6b9917b07
commit a3523d3316
11 files changed
+124 -30

No files matched your search

+53
View File
@@ -1,7 +1,9 @@
import { readFileSync } from 'node:fs';
import { resolve } from 'node:path';
import { runInNewContext } from 'node:vm';
import { describe, expect, it } from 'vitest';
import indexHtml from '../index.html?raw';
import { initialTheme } from './shell/theme';
const publicFile = (name: string) => readFileSync(resolve(import.meta.dirname, '../public', name));
@@ -47,3 +49,54 @@ describe('Icon-Dateien', () => {
expect(pngInfo(publicFile('apple-touch-icon.png'))).toEqual({ width: 180, height: 180, colorType: 2 });
});
});
describe('Inline-Skript für Hell/Dunkel in index.html', () => {
const script = /<script>([\s\S]*?)<\/script>/.exec(indexHtml)?.[1] ?? '';
/** Führt das Skript in einer leeren Umgebung aus (kein Browser) und liefert, was es gesetzt hat. */
function run(stored: string | null, prefersDark: boolean, storageThrows = false) {
const attributes: Record<string, string> = {};
const sandbox: Record<string, unknown> = {
localStorage: {
getItem: () => {
if (storageThrows) throw new Error('gesperrt');
return stored;
},
},
window: { matchMedia: () => ({ matches: prefersDark }) },
document: { documentElement: { setAttribute: (name: string, value: string) => (attributes[name] = value) } },
};
runInNewContext(script, sandbox);
return { attributes, sandbox };
}
it('ist da und läuft ohne Browser-Umgebung durch', () => {
expect(script).toContain('data-theme');
expect(() => run(null, true)).not.toThrow();
});
it('legt keine globale Variable an (Skript steckt in einer sofort aufgerufenen Funktion)', () => {
const { sandbox } = run('dark', false);
expect(Object.keys(sandbox).sort()).toEqual(['document', 'localStorage', 'window']);
expect('theme' in sandbox).toBe(false);
});
it.each([
['dark', false],
['light', true],
['dark', true],
['light', false],
['blau', true],
['blau', false],
['', true],
[null, true],
[null, false],
] as const)('gleiche Regel wie initialTheme(): gespeichert %j, Systemvorgabe dunkel %s', (stored, prefersDark) => {
expect(run(stored, prefersDark).attributes['data-theme']).toBe(initialTheme(stored, prefersDark));
});
it('gesperrter localStorage: es gilt die Systemvorgabe', () => {
expect(run(null, true, true).attributes['data-theme']).toBe('dark');
expect(run(null, false, true).attributes['data-theme']).toBe('light');
});
});