frontend: Zeilennummern im Texteditor + Alt+Klick auch im Text
Zwei Lücken, die beim Arbeiten am Text auffallen: **Zeilennummern (D33).** Die Warnungen nennen Zeilennummern („Zeile 12: …"), das Textfeld zeigte keine — man musste abzählen. Der Streifen links vom Textfeld hebt zusätzlich die Cursor-Zeile und Zeilen mit Warnung hervor. Die Zahlen stehen auf **gemessenen** Höhen (Spiegel-`div` aus D25, ein Marker je Zeile), nicht auf „Zeilenhöhe × n": Der Text bricht weich um, eine lange Zeile belegt mehrere Bildzeilen und behält doch eine Nummer. Bei 375 px Breite brechen 134 der 143 Zeilen um — gerechnet liefe der Streifen sofort davon. Dabei fiel ein älterer Fehler im Spiegel auf: `width = src.clientWidth` bei `content-box` machte ihn um genau die 32 px Innenabstand zu breit, er brach später um als das Textfeld. Mit `box-sizing:border-box` stimmen die Umbrüche nachweislich überein (170 Bildzeilen beiderseits) — das behebt nebenbei die Zielgenauigkeit des Sprungs zu langen Zeilen (D25). **Alt+Klick im Textfeld (Nachtrag zu D25).** Die Rückrichtung lief bisher allein über die Cursor-Zeile — und die scrollt bewusst nur `nearest` und nur beim Zeilenwechsel, sonst ruckelte das Diagramm beim Tippen. Als „zeig mir das" taugt sie damit nicht. Alt+Klick im Text (Tastatur Alt+Enter) zentriert den Knoten jetzt und gibt ihm den Fokus: derselbe Modifier in beide Richtungen, und mit Fokus wird daraus ein vollständiger Hin- und Rückweg. Die Legenden-Zeile nennt beide Richtungen (kein zehnter i18n-Schlüssel), 9 Sprachen nachgezogen. SPEC §9 ergänzt, D33 angelegt, Plan-Dokument und frontend/CLAUDE.md nachgeführt. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -208,6 +208,31 @@ verworfene Elemente. Quelle sind ES-Module unter `src/`; `index.html` ist der
|
||||
die Klasse `alt` an `#out` (Cursor + Ring am Knoten unter dem Zeiger) — der
|
||||
`blur`-Handler ist Pflicht, sonst bleibt der Modus nach Alt+Tab hängen; dazu
|
||||
`jumpHint` im Knoten-Tooltip und `hint_jump` als letzte Zeile der Legende.
|
||||
- Alt+Klick **im Textfeld** (D25, Nachtrag): `focusNodeOfCaret()` zentriert den
|
||||
Knoten der Cursor-Zeile und gibt ihm den Fokus (`focus({preventScroll:true})`
|
||||
**vor** `scrollIntoView({block:'center'})` — sonst scrollt der Browser zweimal).
|
||||
Das ist nicht dasselbe wie das Mitlaufen der Cursor-Zeile: `syncCaret()` scrollt
|
||||
absichtlich nur `nearest` und nur beim Zeilenwechsel. Beim Tastaturweg
|
||||
(Alt+Enter) ist `preventDefault()` Pflicht, sonst bekommt der Text einen
|
||||
Umbruch. Die Legenden-Zeile `hint_jump` nennt **beide** Richtungen — kein
|
||||
eigener i18n-Schlüssel.
|
||||
- Zeilennummern (D33): `renderLineNos()` misst die Zeilenoberkanten am
|
||||
Spiegel-`div` (`lineTops()`) — **nicht** `Zeilenhöhe × n`, das läuft beim
|
||||
ersten weichen Umbruch davon. Der Streifen scrollt nicht selbst, sondern wird
|
||||
per `translateY(-src.scrollTop)` mitgezogen (`syncLineNoScroll()`); wer
|
||||
`src.scrollTop` **selbst** setzt, muss ihn gleich mitziehen — das
|
||||
`scroll`-Ereignis kommt erst im nächsten Bild (`scrollEditorToOffset()` tut es).
|
||||
Der Spiegel braucht `box-sizing:border-box`: `src.clientWidth` enthält die
|
||||
Innenabstände, ohne das ist er 32 px zu breit und bricht später um (betraf
|
||||
vorher auch schon das Scrollen beim Sprung, D25). Der Marker ist ein
|
||||
Inline-Kasten und sitzt in seiner Zeilenbox mittig — die Zahlen müssen um
|
||||
diesen Versatz (`drop`) nach oben, sonst stehen sie durchgehend zu tief.
|
||||
Aufgerufen wird aus `render()` (dort kommt auch die Warnungsmenge her) und aus
|
||||
einem `ResizeObserver` auf `#src` (Umbruch hängt an der Breite). Markup:
|
||||
`#srcWrap` umschließt Streifen + Textfeld; die Pad-Regeln (D31) teilen gegen
|
||||
**diese Spalte** (`.src-area.pv-both>.src-wrap`), nicht gegen das nackte
|
||||
Textfeld. `caretLine` steht deshalb **oben** bei `padView` — der Streifen liest
|
||||
sie und hängt an `render()` (temporale Todeszone, siehe D31).
|
||||
- Touch-Langdruck (D25): Der Timer (500 ms) setzt **nur** die Klasse `armed`
|
||||
(Petrol-Ring); `jumpToLine()` läuft im `touchend`-Handler. Nicht zurück in den
|
||||
Timer verlegen — **`focus()` aus einem Timer gilt in mobilen Browsern nicht als
|
||||
|
||||
Reference in New Issue
Block a user