From 417006960f5d65a3509a243f22dec9aa50162b75 Mon Sep 17 00:00:00 2001 From: mhoennig Date: Sun, 23 Aug 2026 10:44:03 +0200 Subject: [PATCH] =?UTF-8?q?change:=20Falt-Voreinstellung=20wird=20ein=20Um?= =?UTF-8?q?schalter,=20Schwelle=20ab=20M=20abw=C3=A4rts=20(D44)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Statt eines Aufklapp-Menüs mit zwei Einträgen jetzt ein Umschalter neben „verworfene einblenden" und „günstigster Pfad". Die beiden Einträge waren nie unabhängige Befehle, sondern die zwei Stellungen einer Sache — jeder beschreibt einen vollständigen Faltzustand, zusammen decken sie ihn ab. Die Schwelle schließt M jetzt ein (atMostM statt belowM): Ein M-Paket ist selbst noch die Einheit, die man als Ganzes plant, seine Zerlegung ist schon das Innere. Offen bleiben L, XL, XXL — und Knoten ohne Größenangabe. Der Zustand des Knopfes wird bei jedem Rendern am Baum abgelesen, nicht gemerkt: Klappt jemand danach einen Knoten von Hand um, springt er von selbst heraus, statt etwas zu behaupten, das nicht mehr stimmt. Deshalb auch nicht persistiert — der Faltzustand steht im Text. Co-Authored-By: Claude Fable 5 --- docs/DECISIONS.md | 80 +++++++++++++++++++-------------- docs/SPEC.md | 22 ++++++---- frontend/CLAUDE.md | 13 +++--- frontend/index.html | 22 +++------- frontend/src/app.js | 88 +++++++++++++++---------------------- frontend/src/model.js | 13 +++--- frontend/src/style.css | 14 ------ frontend/tests/fold.test.js | 16 +++---- 8 files changed, 124 insertions(+), 144 deletions(-) diff --git a/docs/DECISIONS.md b/docs/DECISIONS.md index 693f3c3..3a7e357 100644 --- a/docs/DECISIONS.md +++ b/docs/DECISIONS.md @@ -2718,22 +2718,27 @@ und der Footer-Link rückt zwischen Versionsnummer und Copyright — zur Werkzeug-Ecke des Footers statt ans Ende hinter die Rechtstexte. Der Dateiname bleibt als Linktext (übersetzungsfrei), die Wurzel-Lage bleibt. -## D44 — Falt-Voreinstellungen: ein Menü, „unter M“ statt einer Tiefenzahl +## D44 — Falt-Umschalter: „ab M abwärts“ statt einer Tiefenzahl Einzeln zu falten (D38) reicht für einen Plan mit 167 Knoten nicht — man will den Baum am Stück auf eine Arbeitshöhe bringen. Der Diagramm-Kopf bekommt -deshalb ein Menü mit zwei Einträgen: **alle aufklappen** und **unter Größe M -zuklappen**. +dafür einen **Umschalter** neben „verworfene einblenden“ und „günstigster +Pfad“: gedrückt ist alles **ab Größe M abwärts** zugeklappt, nicht gedrückt +ist der ganze Baum offen. **Das Kriterium ist die Größe, nicht die Tiefe.** Die naheliegende Alternative wäre „bis Ebene n aufklappen“ gewesen. Die Ebene ist aber eine Eigenschaft der Schreibweise, nicht der Sache: Wie tief etwas steht, hängt davon ab, wie fein der Autor zerlegt hat, und ein sorgfältig aufgeschlüsselter Zweig verschwände bei derselben Zahl früher als ein grob notierter. Die T-Shirt-Größe sagt -dagegen etwas über die **Arbeit**, und die Notation hat dafür bereits eine -Schwelle: Ab `M` **muss** ein Element zerlegt sein (§5/D8). „Unter M“ ist also -genau die Menge, die keine Zerlegung mehr braucht — was darunter hängt, ist -Detail. Die Voreinstellung zeigt damit den Plan auf der Höhe, auf der noch -Entscheidungen anstehen. +dagegen etwas über die **Arbeit** — und weil `M` die kleinste Größe ist, die +überhaupt eine Zerlegung verlangt (§5/D8), ist „M und kleiner“ genau die +Menge, deren Inneres Detail ist. Übrig bleibt der Plan auf der Höhe von `L` +aufwärts, also dort, wo die großen Brocken stehen. + +*(Zuerst gebaut war die Schwelle **unter** M — offen blieb dann auch jedes +`M`. Der Nutzer hat sie auf `M` einschließlich korrigiert: Ein M-Paket ist +selbst noch die Einheit, die man als Ganzes plant; seine Zerlegung ist schon +das Innere.)* **Ohne Größenangabe wird nicht zugeklappt.** Der günstigste Pfad wertet eine fehlende Größe als `M` (D18) — das wäre hier der falsche Präzedenzfall: Dort @@ -2743,15 +2748,34 @@ nichts gesagt; einen Zweig deswegen zu verbergen, behandelte eine Vermutung wie eine Angabe. Ein Knoten ohne Größe bleibt also offen — und fällt dadurch angenehmerweise auf. -**Beide Einträge beschreiben einen vollständigen Zustand.** „Unter M -zuklappen“ klappt nicht nur zu, es klappt alles **andere auf**. Sonst wäre die -Wirkung vom Vorzustand abhängig und zweimal Drücken ergäbe zweierlei — für -eine Voreinstellung die falsche Eigenschaft. Der Preis: Ein von Hand gesetztes -`>` an einem großen Knoten wird dabei aufgelöst. Das ist vertretbar, weil der -Nutzer gerade ausdrücklich eine Gesamtansicht angefordert hat, und weil -**Rückgängig** den ganzen Vorgang in einem Schritt zurücknimmt (nachgemessen: -`replaceTextUndoable` schreibt genau einmal, Strg+Z stellt Text und Diagramm -wieder her). +**Ein Umschalter, kein Menü.** Zuerst gebaut war ein Aufklapp-Menü mit zwei +Einträgen („alle aufklappen“ / „zuklappen“); der Nutzer wollte einen +Umschalter. Das ist die bessere Form, und der Grund ist nicht nur Platz: Die +beiden Einträge waren nie unabhängige Befehle, sondern die **zwei Stellungen +einer Sache** — jeder beschreibt einen vollständigen Faltzustand, und +zusammen decken sie ihn ganz ab. Genau das ist ein Umschalter. Ein Menü +verlangte zwei Klicks für etwas, das einen braucht, und der Diagramm-Kopf hat +das Idiom längst zweimal (D18, D4). + +**Der Zustand wird abgelesen, nicht gemerkt.** Ein gemerktes Flag würde lügen, +sobald jemand danach einen einzelnen Knoten umklappt. Stattdessen prüft +`render()` bei jedem Durchlauf, ob **jeder** faltbare Knoten so steht, wie die +Voreinstellung ihn stellen würde; nur dann ist der Knopf gedrückt. Er springt +damit von selbst heraus, wenn man von Hand etwas aufklappt, und von selbst +wieder hinein, wenn man es zurücknimmt (beides nachgemessen). Deshalb wird er +auch **nicht** in `werkbaum-ui` persistiert: Der Faltzustand steht im Text +(D38-Nachtrag 2), der Knopf liest ihn nur ab. Sonderfall: Gäbe es gar keinen +Knoten bis `M`, wären beide Stellungen derselbe Zustand — dann bleibt der +Knopf heraußen, statt gedrückt dazusitzen, ohne dass etwas zugeklappt ist. + +**Beide Stellungen beschreiben einen vollständigen Zustand.** Zuklappen klappt +also alles **andere auf**. Sonst wäre die Wirkung vom Vorzustand abhängig und +zweimal Drücken ergäbe zweierlei — für einen Umschalter die falsche +Eigenschaft. Der Preis: Ein von Hand gesetztes `>` an einem großen Knoten wird +dabei aufgelöst. Vertretbar, weil der Nutzer gerade ausdrücklich eine +Gesamtansicht angefordert hat, und weil **Rückgängig** den ganzen Vorgang in +einem Schritt zurücknimmt (nachgemessen: `replaceTextUndoable` schreibt genau +einmal, Strg+Z stellt Text und Diagramm wieder her). **Umgesetzt über denselben Weg wie das einzelne Umklappen** — die Sitzungs-Überlagerungen setzen, dann in den Text schreiben (D38-Nachtrag 2). @@ -2762,18 +2786,10 @@ Rückfall-Kette unverändert — ist der Zustand in Marken **nicht ausdrückbar* wird nicht geschrieben und die Überlagerung trägt ihn für die Sitzung. Genau der Fall tritt im mitgelieferten Werkbaum-Plan auf und ist beim Bauen -nachgemessen worden: Zwei Knoten sind kleiner als `M` und haben Kinder -(Zeile 94 und 100), aber in Zeile 103 steht eine Fokusmarke `!!!` unterhalb -von 94 — die holt ihren Knoten immer wieder hervor, „94 eingeklappt“ ist als -Markensatz also nicht schreibbar. Das Bild stimmt trotzdem (die Überlagerung -gewinnt in `render()`), der Text bleibt unangetastet. In einem Plan ohne `!!!` -werden die Marken geschrieben: `- [ ] > Klein (S)` und `- [ ] > Teil 3 (S)`, -während `(L)`, `(XL)` und der Knoten ohne Größe offen bleiben. - -**Ein Menü, nicht zwei Knöpfe.** Der Diagramm-Kopf trägt schon acht -Bedienelemente und bricht auf dem Telefon knapp nicht um (D17). Zwei weitere -Icon-Knöpfe hätten das gekostet — und die beiden Einträge brauchen **Text**: -„unter Größe M zuklappen“ ist als Piktogramm nicht zu sagen. Dasselbe Idiom -wie das Download-Menü (D17), nur auf **allen** Bildschirmgrößen aufklappend -statt nur auf schmalen. Nachgemessen bei 375 px: Das Menü steht mit 159 px -vollständig im Bild, die Kopfzeile bleibt einzeilig. +nachgemessen worden: In Zeile 103 steht eine Fokusmarke `!!!` unterhalb eines +Knotens, der zugeklappt werden soll — die holt ihren Knoten immer wieder +hervor, dieser Markensatz ist also nicht schreibbar. Das Bild stimmt trotzdem +(die Überlagerung gewinnt in `render()`), der Text bleibt unangetastet. In +einem Plan ohne `!!!` werden die Marken geschrieben: `- [ ] > Mittel (M)`, +`- [ ] > Klein (S)` und `- [ ] > Teil 3 (M)`, während `(L)`, `(XL)` und der +Knoten ohne Größe offen bleiben. diff --git a/docs/SPEC.md b/docs/SPEC.md index 614ac0f..c9c2495 100644 --- a/docs/SPEC.md +++ b/docs/SPEC.md @@ -699,15 +699,19 @@ fokussierten Knoten (WAI-ARIA-Baum-Idiom). weil eine Fokusmarke `!!!` ihren Knoten immer wieder hervorholt): Dann wird lieber nichts geschrieben, als einen Text zu hinterlassen, der etwas anderes sagt als das Bild. -- **Für den ganzen Baum** gibt es im Diagramm-Kopf ein Menü mit zwei - Voreinstellungen: **alle aufklappen** und **unter Größe M zuklappen**. Beide - beschreiben einen **vollständigen** Faltzustand — was die Voreinstellung - nicht zuklappt, ist danach offen; „unter Größe M“ meint jeden Knoten mit - Kindern, dessen **angegebene** Größe (§5) kleiner als `M` ist. Ein Knoten - **ohne** Größenangabe wird nicht zugeklappt: Der günstigste Pfad rechnet - fehlende Größen zwar als `M` (§9), das ist aber eine Kostenannahme und keine - Aussage des Autors. Geschrieben wird wie beim einzelnen Umklappen — ein - einziger Rückgängig-Schritt für den ganzen Vorgang. Siehe D44. +- **Für den ganzen Baum** gibt es im Diagramm-Kopf einen **Umschalter**: + gedrückt ist alles **ab Größe M abwärts** zugeklappt, nicht gedrückt ist der + ganze Baum **offen**. Betroffen ist jeder Knoten mit Kindern, dessen + **angegebene** Größe (§5) `M` oder kleiner ist — offen bleiben `L`, `XL`, + `XXL`. Ein Knoten **ohne** Größenangabe wird nicht zugeklappt: Der günstigste + Pfad rechnet fehlende Größen zwar als `M` (unten), das ist aber eine + Kostenannahme und keine Aussage des Autors. +- Beide Stellungen beschreiben einen **vollständigen** Faltzustand — was der + Umschalter nicht zuklappt, ist danach offen. Sein Zustand wird **nicht + gemerkt, sondern am Baum abgelesen**: Wer danach einen Knoten von Hand + umklappt, sieht ihn von selbst herausspringen. Geschrieben wird wie beim + einzelnen Umklappen — ein einziger Rückgängig-Schritt für den ganzen + Vorgang. Siehe D44. - Faltung ist **reine Ansicht**: Warnungen aus eingeklappten Teilbäumen werden weiter gemeldet (sie gelten dem Text), und der günstigste Pfad rechnet unverändert über den ganzen Baum. diff --git a/frontend/CLAUDE.md b/frontend/CLAUDE.md index e8d9b9f..13a24b7 100644 --- a/frontend/CLAUDE.md +++ b/frontend/CLAUDE.md @@ -340,12 +340,15 @@ verworfene Elemente. Quelle sind ES-Module unter `src/`; `index.html` ist der Mobil die Tastatur hoch (`keyboardOnJump(true)`). Bei `src.readOnly` (Pad, D31) wird nicht geschrieben, dort trägt weiter `foldOverrides` — die Überlagerungen werden nach erfolgreichem Schreiben geleert, sonst maskieren - sie den Text. **Voreinstellungen** im Diagramm-Kopf (`applyFoldPreset`, D44) - gehen denselben Weg: Überlagerungen für ALLE faltbaren Knoten setzen - (`belowM(n)` bzw. `false`), dann `writeAllFoldMarks()` — der aus + sie den Text. Der **Umschalter** im Diagramm-Kopf (`applyFoldPreset`, D44) + geht denselben Weg: Überlagerungen für ALLE faltbaren Knoten setzen + (`atMostM(n)` bzw. `false`), dann `writeAllFoldMarks()` — der aus `writeFoldToText()` herausgelöste Voll-Rewrite; einen minimalen Patch gibt es - hier nicht. Ein Knoten **ohne** Größe zählt nicht als „unter M" (anders als - bei den Pfadkosten, D18). **`replaceTextUndoable()` meldet bei unveränderten Text + hier nicht. Ein Knoten **ohne** Größe zählt nicht als „bis M" (anders als + bei den Pfadkosten, D18). Sein `aria-pressed` wird **in `render()` am Baum + abgelesen**, nicht gemerkt und nicht persistiert — sonst behauptete er nach + einem einzelnen Umklappen etwas Falsches. + **`replaceTextUndoable()` meldet bei unveränderten Text `false`** (D38-Nachtrag 3): Ohne Textänderung feuert kein `input`, also läuft kein `render()` — der Aufrufer muss dann selbst zeichnen. Sonst bleibt das Bild stehen (aufgefallen beim Aufklappen eines nur per Überlagerung diff --git a/frontend/index.html b/frontend/index.html index cb00ed2..a4e0f7c 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -159,23 +159,11 @@ - -
- -
- - -
-
+ +