Commit graph

4 commits

Author SHA1 Message Date
mwiegand
54842f71c6
fix(editor-v2): fix cm6 to rows-derived height, eliminate layout shift
CLS verified zero (0.00000) on /blueprints/1 and /overlays/1 via
PerformanceObserver({type: 'layout-shift', buffered: true}) on a
real browser session — previously CLS=0.00859 from a 253 px shift
when cm6 mounted into a display:none slot.

Mechanism:
- editor-entry.js: mount() accepts `rows`. When provided, prepends
  an EditorView.theme that pins
    .cm-editor { height: calc(rows * 1.84rem + 1.125rem) }
  and sets .cm-scroller overflow:auto. cm6 renders at a fixed,
  predictable height; long content scrolls internally (same UX the
  raw <textarea rows="N"> used to give).
- editor.js: reads textarea.rows attribute and passes it to mount().
- editor.css: new .editor-mount wrapper uses the same calc on
  min-height keyed off an inline --editor-rows CSS custom property,
  so the slot is pre-reserved BEFORE cm6 mounts. Wrapper and cm6
  match exactly (browser-measured 254 / 254 px for rows=8 and
  607 / 607 px for rows=20).
- Templates: each editor textarea wrapped in
  <div class="editor-mount" style="--editor-rows: N">. Single source
  of truth on N (only the rows attribute + the inline custom prop
  vary per call site).

Per-row metric 1.84 rem derived empirically: 253 px for rows=8 minus
1.125 rem chrome = 235 px content, ÷ 8 ≈ 29.4 px = 1.84 rem.

Fast suite + e2e suite still green (3 + 2 pass, 0 fail).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 10:27:28 +02:00
mwiegand
19bc0afaa9
test(editor-v2): Playwright e2e + Tab→acceptCompletion fix
Two e2e tests:
- test_blueprint_autocomplete_accept_writes_into_hidden_textarea:
  loads /blueprints/1, types 'sv_che', asserts the cm6 autocomplete
  popup shows 'sv_cheats', presses Tab to accept, fires a synthetic
  submit on the form, and reads the hidden textarea value back.
  Exercises both the autocomplete extension and the submit-time copy
  bridge in editor.js end-to-end.
- test_copy_preserves_newlines_across_lines: regression gate for
  bug class 1 from v1 (Prism+contenteditable collapsed multi-line
  selections). cm6 preserves linebreaks in its doc by construction;
  we verify via the per-textarea controller's getValue().

editor-entry.js: discovered during the e2e debug that cm6's default
completionKeymap does NOT bind Tab. Added an explicit
`{ key: "Tab", run: acceptCompletion }` ahead of the rest of the
keymap stack so Tab accepts when the popup is open and falls through
to indentWithTab otherwise. Bundle rebuilt + SHA refreshed.

Tests also surfaced a 200ms popup-settle timing race: the popup is
*visible* on the same tick acceptCompletion runs against null
selectedCompletion. A page.wait_for_timeout(200) before pressing
the accept key bridges the gap reliably in CI.

Chromium runs fine in Claude Code's default sandbox — the stale note
in the handoff doc about Mach-port IPC sandbox-blocking is no longer
accurate.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 02:15:51 +02:00
mwiegand
bfc8b82c00
feat(editor-v2): editor-entry façade wiring all extensions
Replaces the Task 1 stub. Builds an EditorView with:
- history, line numbers, active-line highlight, bracket matching,
  close brackets, indent-on-input
- default + custom HighlightStyle
- light/dark theme via matchMedia-driven Compartment with a
  prefers-color-scheme change listener
- language via Compartment (swappable for the files-modal dropdown)
- autocomplete via Compartment (only if vocab is provided)
- keymap stack: closeBrackets, default, history, completion, indentWithTab

Mounts the EditorView immediately before the textarea, hides the
textarea. Exposes window.__editor.mount(textarea, opts) returning a
controller with getValue / setContent / setLanguage / destroy.

bash language comes via @codemirror/legacy-modes/mode/shell wrapped
in StreamLanguage.define — same mechanism as srccfg.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 01:57:23 +02:00
mwiegand
ce20c1abff
scaffold(editor-v2): pin cm6 deps + editor-src skeleton
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 01:54:06 +02:00