Größen zählen für diese eine Prüfung als Bereiche (Untergrenzen verdoppeln sich, XXL nach oben offen); Konflikt erst, wenn selbst die günstigste Lesart der Kinder die großzügigste des Elternknotens erreicht. Warnung sizeConflict an der Elternzeile, Badge in --warn, Grund in Tooltip und aria-label. Nichts wird automatisch korrigiert. Nebenbefund behoben: der Grafikexport zeichnete das Größen-Badge mit festen Farben — das invertierte implizite M stand seit jeher gefüllt im Bild. Die acht berechtigten Konflikte im eigenen Plan sind nachgezogen. 372 Tests, 16 neue. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
93 lines
4.9 KiB
JavaScript
93 lines
4.9 KiB
JavaScript
/* Vereinheitlichtes Warnungs-Modell.
|
|
Producer (Renderer, künftig auch Parser) liefern strukturierte Objekte
|
|
{ type, line, ...data }
|
|
statt fertig formatierter Strings — so bleiben Typ und Zeilennummer
|
|
maschinenlesbar (sortierbar, filterbar, testbar). Die i18n-/HTML-Aufbereitung
|
|
passiert an genau einer Stelle: formatWarning(). Vgl. SPEC §3 (gemischte
|
|
Gates) und TASKS Phase 2 (unbekannte Statuszeichen).
|
|
|
|
Bekannte Typen:
|
|
- mixedGate { line, label } — Geschwister mit gemischtem Gate (SPEC §3)
|
|
- unknownStatus { line, code } — unbekanntes Statuszeichen (Phase 2)
|
|
- xorConflict { line, label } — weitere realisierte Alternative in einer
|
|
`=`-Gruppe (SPEC §3/D35); je Zeile eine
|
|
Warnung, damit sie dorthin zeigt
|
|
- duplicateId { line, id, firstLine } — Knoten-ID doppelt vergeben
|
|
(SPEC §1/D36); gemeldet an der späteren
|
|
Zeile, die erste wird genannt
|
|
- unknownDep { line, id } — Abhängigkeit auf eine ID ohne Knoten
|
|
(SPEC §1/D37); Zyklen sind dagegen
|
|
zulässig und warnen nie
|
|
- unknownDesc { line, id } — Beschreibungsblock für eine ID ohne
|
|
Knoten (SPEC §11/D40)
|
|
- descStray { line } — Beschreibungszeile ohne Bezug: `"`-Zeile
|
|
ohne Knoten davor bzw. Zeile im
|
|
Beschreibungsteil ohne #id-Block; meldet
|
|
auch die von einem versehentlichen
|
|
`---` verschluckten Knotenzeilen
|
|
- sizeConflict { line, size } — Teilpakete übersteigen zusammen die
|
|
angegebene Größe des Elternknotens, selbst
|
|
in der günstigsten Bereichs-Lesart
|
|
(SPEC §5/D62); Zeile = Elternknoten
|
|
- cheapApprox { } — günstigster Pfad nur gierig geschätzt:
|
|
zu viele gekoppelte Gruppen für die
|
|
exakte Suche (D42); zeilenlos
|
|
- sourceLoad { url, error } — ?sourceUrl= nicht ladbar (D23); ohne
|
|
Zeilennummer, erscheint dadurch zuoberst
|
|
- padRateLimit { seconds } — zu früh nachgeladen; Werkbaum hat gar nicht
|
|
erst geholt, um Etherpads Grenze nicht
|
|
auszulösen (D31)
|
|
- sourceTimeout { url, seconds } — Abruf abgebrochen, Gegenseite zu langsam
|
|
(D31). Eigener Typ, weil `sourceLoad` auf
|
|
CORS zeigt — bei einem Zeitablauf schickt
|
|
das den Leser auf die falsche Fährte */
|
|
|
|
import { esc } from './render.js';
|
|
|
|
/* Strukturierte Warnung -> lokalisierter Anzeigetext (HTML-escaped Daten).
|
|
`t` ist die i18n-Funktion (key, vars) -> String. */
|
|
export function formatWarning(w, t){
|
|
return build(w, t, esc);
|
|
}
|
|
|
|
/* Dasselbe als **Klartext**, ohne HTML-Escaping — für Senken, die kein HTML
|
|
sind: der `title` der Zeilennummer (D33-Nachtrag). Dort stünde sonst
|
|
„Drag & Drop“ statt „Drag & Drop“; die Vorlagen selbst enthalten kein
|
|
Markup, escaped werden ohnehin nur die eingesetzten Daten. */
|
|
export function warningText(w, t){
|
|
return build(w, t, s => String(s));
|
|
}
|
|
|
|
/* Der Parameter verdeckt das importierte `esc` bewusst: So bleibt der Rumpf
|
|
unverändert und es gibt nur **eine** Stelle, die die Typen kennt. */
|
|
function build(w, t, esc){
|
|
switch(w.type){
|
|
case 'mixedGate':
|
|
return t('mixedWarn', {line: w.line, label: esc(w.label)});
|
|
case 'unknownStatus':
|
|
return t('unknownStatusWarn', {line: w.line, code: esc(w.code)});
|
|
case 'xorConflict':
|
|
return t('xorConflictWarn', {line: w.line, label: esc(w.label)});
|
|
case 'duplicateId':
|
|
return t('duplicateIdWarn', {line: w.line, id: esc(w.id), firstLine: w.firstLine});
|
|
case 'unknownDep':
|
|
return t('unknownDepWarn', {line: w.line, id: esc(w.id)});
|
|
case 'unknownDesc':
|
|
return t('unknownDescWarn', {line: w.line, id: esc(w.id)});
|
|
case 'descStray':
|
|
return t('descStrayWarn', {line: w.line});
|
|
case 'sizeConflict':
|
|
return t('sizeConflictWarn', {line: w.line, size: esc(w.size)});
|
|
case 'cheapApprox':
|
|
return t('cheapApproxWarn');
|
|
case 'sourceLoad':
|
|
return t('sourceLoadWarn', {url: esc(w.url), error: esc(w.error)});
|
|
case 'padRateLimit':
|
|
return t('padRateLimitWarn', {seconds: w.seconds});
|
|
case 'sourceTimeout':
|
|
return t('sourceTimeoutWarn', {url: esc(w.url), seconds: w.seconds});
|
|
default:
|
|
return `${esc(String(w.type))} (${w.line ?? '?'})`;
|
|
}
|
|
}
|