Auto-sizing cell editor, multi-ref F4, and Alt+Enter line breaks

1. In-cell editor width/height ("nur in der Breite der Zelle angezeigt"):
   the editor now lives as an overlay (like the clip/fill markers) instead
   of inside its <td>, so it can grow past the cell -- width first, up to
   an approximated display-width cap, then wrapping and growing height.
   Sized via a hidden mirror element (same font/padding, real DOM
   measurement -- a <textarea> can't self-size to content with CSS alone).

2. F4 now cycles every reference a real text selection overlaps, each from
   its own lock state, not just the one at the caret -- select a stretch of
   formula spanning several references and F4 adjusts all of them at once,
   same as Excel. cycleReferenceLock(formula, caret) -> cycleReferenceLocks
   (formula, start, end); a collapsed selection (start === end) keeps the
   old single-reference caret behaviour. Wired into both the in-cell editor
   and the formula bar.

3. Alt+Enter inserts a literal newline in the editor instead of committing
   (explicit splice at the caret, not relying on the textarea's native
   Enter handling, which isn't consistently reachable for Alt+Enter). A
   cell holding a newline displays it wrapped (.cell.multiline) instead of
   collapsing to one ellipsised line.

Along the way: a <td>'s own max-height doesn't cap table-row growth in any
browser (a table-layout quirk) -- a wrapped multi-line cell was silently
growing its row past rowH(r), which would have desynced every pixel
position computed from rowH()/rowTop() (the overlays, sticky frozen panes,
the row-resize handle). Fixed by moving cell text into its own block-level
.cell-content child, which *does* respect max-height + overflow:hidden.

Verified interactively against the dev server with Playwright: a long
formula gets a ~300px editor instead of the 104px cell; Alt+Enter produces
a real "\n" that survives commit and displays wrapped, with the row height
unchanged (26px, not the ~40px it grew to before the .cell-content fix);
F4 on a full-formula selection turns every reference absolute in one press
and keeps cycling all of them on repeated presses; existing selection,
copy/paste and fill-handle behaviour all regression-checked clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
wkh
2026-09-02 11:04:45 +02:00
co-authored by Claude Sonnet 5
parent 830dcb8eeb
commit cc76ea547f
7 changed files with 297 additions and 76 deletions
+5 -3
View File
@@ -15,7 +15,7 @@ löst `Umsatz!B2` (bzw. `Umsatz::B2`) von jedem Blatt aus identisch auf.
| `parser.ts` | Recursive-Descent → AST. Grammatik als EBNF-Kommentarblock im Kopf der Datei. |
| `evaluator.ts` | AST + `EngineHost` → `CellValue`. Numerisches Auswertungsmodell, Fehler-Propagierung. |
| `graph.ts` | Dokumentweiter Abhängigkeitsgraph: `affected()`, `topoOrder()`, Zirkel-Erkennung (iterative DFS, white/grey/black). |
| `refs.ts` | A1 ↔ `(col,row)` inkl. `$`-Sperrachsen, Spaltenbuchstaben, Bereichs-Expansion, `F4`-Zyklus (`cycleReferenceLock`). |
| `refs.ts` | A1 ↔ `(col,row)` inkl. `$`-Sperrachsen, Spaltenbuchstaben, Bereichs-Expansion, `F4`-Zyklus (`cycleReferenceLocks`). |
| `functions.ts` | `SUM/AVG/MIN/MAX/COUNT` (+ Alias `AVERAGE`) als Tabelle `{ NAME → fn(values) }`. |
| `workbook.ts` | Bindeglied: flache Liste von **Tabellen** + rohe Eingaben + ASTs + Werte + Graph. Inkrementelle Neuberechnung. Implementiert `EngineHost`. |
| `types.ts` | Gemeinsame Typen, `FormulaError`, `keyOf()`. |
@@ -66,8 +66,10 @@ ausschließlich beim **Kopieren/Ausschneiden** aus (`shiftFormula` in
beim *Kopieren* exakt wie eingegeben stehen, folgt aber beim *Ausschneiden*
trotzdem der verschobenen Zelle (dort verschiebt sich die referenzierte Zelle
selbst – `$` ändert nur, ob eine *Kopie* mitzieht, nicht wohin ein *Verschieben*
zeigt). `refs.ts#cycleReferenceLock` implementiert den `F4`-Zyklus
(relativ → `$A$1` → `A$1` → `$A1` → relativ) für Formelleiste und Zell-Editor.
zeigt). `refs.ts#cycleReferenceLocks` implementiert den `F4`-Zyklus
(relativ → `$A$1` → `A$1` → `$A1` → relativ) für Formelleiste und Zell-Editor
— mit Cursor nur den einen Bezug dort, mit echter Textauswahl **jeden**
darin gefundenen Bezug auf einmal, jeden ausgehend vom eigenen Zustand.
Tabellennamen werden **case-insensitiv** und whitespace-tolerant aufgelöst:
`Kosten!A2`, `'Kosten'!A2`, `kosten!a2`, `Kosten::A2` sind identisch.