From 7351820c551da56c5dcc3c1cb702e0d6c2cf6ab8 Mon Sep 17 00:00:00 2001 From: Dogfather Date: Tue, 29 Sep 2026 13:45:02 +0200 Subject: [PATCH] Der Waechter gegen Namensstreit gilt jetzt fuer das ganze Haus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Er wurde gestern fuer `reaktion.css` gebaut, nachdem `.stufen` dort zweimal stand und die Stufenleiter der Spenden dadurch das Aussehen der Chat-Leiste bekam -- drei Stufen nebeneinander, 572 Pixel in einer 327 Pixel schmalen Spalte, mit der waagerechten Rollleiste auf Filipes Bildschirmfoto. Eine Wache, die nur eine Datei ansieht, findet genau die Fehler dieser einen Datei. Auf alle 36 Stilvorlagen angewandt fand sie GENAU EINE weitere Stelle. DER FUND: `.wahl2__eintrag` in gate.css Zeile 1584 display: block (mit text-overflow: ellipsis) Zeile 2634 display: flex (fuer Personenbilder, 08.09.2026) Kein Streit zweier Bauteile, sondern eine spaetere Erweiterung -- und trotzdem ein echter Fehler: `text-overflow: ellipsis` wirkt bei `display: flex` NICHT auf ein anonymes Flex-Kind. Der Knopf „… eintragen" in jeder Auswahl des Hauses hat langen Text seither HART abgeschnitten statt mit „…" gekuerzt. GEMESSEN -- und nur im Bild zu sehen: `scrollWidth` ist in beiden Faellen gleich (364 px bei 200 px Breite). Die Zahlen sagten „kein Unterschied", das Bildschirmfoto zeigte einen. Ein Beleg mehr dafuer, dass zwei gleiche Zahlen nicht dasselbe Ergebnis bedeuten. REPARIERT - Der eigene Eintrag bekommt einen `.wahl2__name`-Span, wie jeder andere Eintrag auch. Damit kuerzt er wieder mit „…". - Die zwei Grundregeln sind eine. Wer die erste las, glaubte an `display: block` -- 1050 Zeilen weiter stand das Gegenteil. DIE WACHE 923 Grundregeln in 36 Stilvorlagen, keine Klasse zweimal verschieden gebaut. Gezaehlt wird nur, was sich widersprechen kann: nicht dieselbe Klasse in einem Zusammenhang (`.saal .pult`), nicht eine Variante in einer Medienabfrage, nicht „erst versteckt, dann gezeigt". Sechs Gegenproben, darunter der echte Fall vom 28.09. und eine Klasse im Kommentar. GEPRUEFT: css-klassen, freie-namen, suchfeld, tippziele alle EXIT 0. --- server/pruef-css-klassen.mjs | 85 +++++++++++++++++++++++++++++++++ workspace/anruf-probe.html | 10 ++-- workspace/app.webmanifest | 8 ++-- workspace/assets/css/gate.css | 11 ++++- workspace/assets/js/wahl.js | 11 ++++- workspace/aufgaben.html | 38 +++++++-------- workspace/automation.html | 32 ++++++------- workspace/befinden.html | 34 ++++++------- workspace/bereich.html | 44 ++++++++--------- workspace/bewerben.html | 38 +++++++-------- workspace/bewerbungen.html | 36 +++++++------- workspace/buehne.html | 2 +- workspace/calls.html | 34 ++++++------- workspace/chat.html | 40 ++++++++-------- workspace/content.html | 34 ++++++------- workspace/crew-index.html | 12 ++--- workspace/crew.webmanifest | 8 ++-- workspace/dateien.html | 34 ++++++------- workspace/entwicklung.html | 36 +++++++------- workspace/hilfe.html | 30 ++++++------ workspace/index.html | 10 ++-- workspace/kalender.html | 34 ++++++------- workspace/leistung.html | 32 ++++++------- workspace/material.html | 32 ++++++------- workspace/notizen.html | 28 +++++------ workspace/personen.html | 32 ++++++------- workspace/profil.html | 36 +++++++------- workspace/reaktion.html | 34 ++++++------- workspace/rechte.html | 34 ++++++------- workspace/report.html | 36 +++++++------- workspace/scouting.html | 32 ++++++------- workspace/start.html | 32 ++++++------- workspace/startcheck.html | 34 ++++++------- workspace/steckbrief.html | 36 +++++++------- workspace/support.html | 28 +++++------ workspace/tafel.html | 6 +-- workspace/talente.html | 36 +++++++------- workspace/team.html | 32 ++++++------- workspace/teamlage.html | 34 ++++++------- workspace/teilen.html | 30 ++++++------ workspace/treff-moderation.html | 32 ++++++------- workspace/treff-regeln.html | 32 ++++++------- workspace/uebersicht.html | 32 ++++++------- workspace/unsere-seiten.html | 30 ++++++------ workspace/unterstuetzen.html | 32 ++++++------- workspace/werdegang.html | 32 ++++++------- workspace/willkommen.html | 30 ++++++------ workspace/wissen.html | 34 ++++++------- 48 files changed, 769 insertions(+), 670 deletions(-) diff --git a/server/pruef-css-klassen.mjs b/server/pruef-css-klassen.mjs index 57e92de6..45a65aa7 100644 --- a/server/pruef-css-klassen.mjs +++ b/server/pruef-css-klassen.mjs @@ -899,5 +899,90 @@ function formfehler(text) { : `Gegenprobe: alle ${proben.length} Faelle richtig eingeordnet`); } +/* ==== ZWEI GRUNDREGELN, EIN NAME, ZWEI BAUARTEN ===================== + + Gebaut am 28.09.2026 fuer `reaktion.css`, wo `.stufen` zweimal + stand: einmal fuer die Stufenleiter der Spenden (`display: grid`), + 600 Zeilen spaeter fuer die Chat-Leiste (`display: flex`). Die + spaetere gewinnt -- und die Stufenleiter stellte ihre drei Stufen + nebeneinander, 572 Pixel in einer 327 Pixel schmalen Spalte, mit + waagerechter Rollleiste. Auf dem Bildschirmfoto sah das aus wie + ein Platzproblem. + + AB JETZT FUER ALLE STILVORLAGEN. Eine Wache, die nur eine Datei + ansieht, findet genau die Fehler dieser einen Datei -- und der + zweite Fund lag in gate.css. + + GEZAEHLT WIRD NUR, WAS SICH WIDERSPRECHEN KANN: + - Die Auswahl muss GENAU die Klasse sein. `.saal .pult { … }` + ist dieselbe Klasse in einem Zusammenhang, kein zweites + Bauteil. + - Regeln in einer Medienabfrage zaehlen nicht -- sie sind per + Definition Varianten fuer eine andere Umgebung. + - `display: none` zaehlt nicht. „Erst versteckt, dann gezeigt" + ist das haeufigste Paar im Haus; wer es meldet, baut eine + Warnung, die immer kommt. */ +{ + const ordner = join(HIER, "..", "workspace", "assets", "css"); + const ohneMedien = (t) => t.replace( + /@media[^{]*\{(?:[^{}]|\{[^{}]*\})*\}/g, + (m) => m.replace(new RegExp("[^" + String.fromCharCode(10) + "]", "g"), " ")); + const positiv = (w) => w && w !== "none" && !/^none\b/.test(w); + /* LOOKBEHIND STATT VERBRAUCHEN: Mit `(^|[};])` frisst der erste + Treffer die Klammer, die der naechste als Anfang braeuchte -- + `.a { … } .a { … }` liefert dann nur EINEN Treffer, und genau + der Fall, um den es geht, faellt durch. */ + const grundregeln = (roh) => { + const raus = {}; + const text = ohneMedien(roh.replace(/\/\*[\s\S]*?\*\//g, + (m) => m.replace(new RegExp("[^" + String.fromCharCode(10) + "]", "g"), " "))); + for (const m of text.matchAll( + /(?:^|(?<=[};]))\s*(\.(-?[a-zA-Z_][a-zA-Z0-9_-]*))\s*\{([^{}]*)\}/g)) { + const w = (m[3].match(/(?:^|[\s;])display\s*:\s*([^;]+)/) || [, ""])[1].trim(); + if (!positiv(w)) continue; + (raus[m[2]] ||= []).push(w); + } + return raus; + }; + const streitIn = (roh) => Object.entries(grundregeln(roh)) + .filter(([, was]) => new Set(was).size > 1) + .map(([name, was]) => `${name} (${[...new Set(was)].join(" vs. ")})`); + + const dateien = readdirSync(ordner).filter((n) => n.endsWith(".css")); + const funde = []; + let geprueft = 0; + for (const name of dateien) { + const roh = readFileSync(join(ordner, name), "utf8"); + geprueft += Object.keys(grundregeln(roh)).length; + for (const z of streitIn(roh)) funde.push(`${name}: ${z}`); + } + ok(geprueft > 100 && funde.length === 0, + funde.length ? `Namensstreit: ${funde.join(" | ")}` + : `${geprueft} Grundregeln in ${dateien.length} Stilvorlagen -- ` + + "keine Klasse zweimal verschieden gebaut"); + + /* GEGENPROBEN IN BEIDE RICHTUNGEN. */ + const faelle = [ + ["der Fall vom 28.09. (zwei Grundregeln, anderes display)", + ".stufen { display: grid; } .stufen { display: flex; }", true], + ["verstecken und zeigen", + ".probe { display: none; } .probe { display: grid; }", false], + ["dieselbe Klasse in einem Zusammenhang", + ".pult { display: grid; } .saal .pult { display: flex; }", false], + ["eine Variante in einer Medienabfrage", + ".paar { display: grid; } @media (pointer: coarse) { .paar { display: flex; } }", false], + ["zweimal dasselbe display", + ".gleich { display: grid; } .gleich { display: grid; }", false], + ["eine Klasse im Kommentar", + "/* .a { display: flex; } */ .a { display: grid; }", false], + ]; + const daneben = faelle + .filter(([, text, soll]) => (streitIn(text).length > 0) !== soll) + .map(([name]) => name); + ok(daneben.length === 0, + daneben.length ? `Gegenprobe daneben bei: ${daneben.join(", ")}` + : `Gegenprobe: alle ${faelle.length} Faelle richtig eingeordnet`); +} + console.log(`\n${fehler === 0 ? "ALLES IN ORDNUNG" : `${fehler} FEHLER`}`); process.exit(fehler ? 1 : 0); diff --git a/workspace/anruf-probe.html b/workspace/anruf-probe.html index 8341cf27..7dec16d9 100644 --- a/workspace/anruf-probe.html +++ b/workspace/anruf-probe.html @@ -16,8 +16,8 @@ verdeckt. Gefunden hat es pruef-struktur. Richtig sind `gate.css` (die Farbwerte des Hauses) und `haus.css`. --> - - + + - +