REGRESSION: note editor lost Craft-style modes (single click selects block, double click edits text) #182

Closed
opened 2026-09-26 14:34:41 +00:00 by kayg · 9 comments
Owner

Owner 2026-09-26: the block editor had two modes, Craft-style: a single click selects a block (block selection mode: move, delete, copy link, drag), a double click on a text element enters text editing. Now clicks go straight into text editing. The code still exists (packages/editor/src/blockSelection.ts, blockSelectDecoration.ts, moveBlock.ts, apps/web/src/lib/notes/NoteEditorSurface.svelte). Bisect on dev to find the commit that broke it (candidates: live collab editor wiring, 'notes render flush' d209852c, glass menus 532f8202, table scroll 8e013795), restore the behaviour, and add an e2e that fails without it: single click → block selected (visible selection, keyboard arrows move between blocks, Enter/double click → text edit, Esc → back to block selection), on touch: single tap selects block, double tap edits text. Coordinate with #182 heading links (a heading's link icon click copies and must not change the mode). Screenshots of block selection in light and dark for Claude's review.

Owner 2026-09-26: the block editor had two modes, Craft-style: a single click selects a block (block selection mode: move, delete, copy link, drag), a double click on a text element enters text editing. Now clicks go straight into text editing. The code still exists (packages/editor/src/blockSelection.ts, blockSelectDecoration.ts, moveBlock.ts, apps/web/src/lib/notes/NoteEditorSurface.svelte). Bisect on dev to find the commit that broke it (candidates: live collab editor wiring, 'notes render flush' d209852c, glass menus 532f8202, table scroll 8e013795), restore the behaviour, and add an e2e that fails without it: single click → block selected (visible selection, keyboard arrows move between blocks, Enter/double click → text edit, Esc → back to block selection), on touch: single tap selects block, double tap edits text. Coordinate with #182 heading links (a heading's link icon click copies and must not change the mode). Screenshots of block selection in light and dark for Claude's review.
Author
Owner

Correction: the heading-link issue is a separate issue filed next (not this one).

Correction: the heading-link issue is a separate issue filed next (not this one).
Author
Owner

Starting #182 on job/editor-modes, based on dev 6e1e5656036eaeb060df3089043519aab2066376. I’m tracing the candidate commits against NoteEditorSurface and the existing block-selection extensions, then I’ll restore the click/tap state transition and add the requested browser e2e coverage.

Starting #182 on `job/editor-modes`, based on dev `6e1e5656036eaeb060df3089043519aab2066376`. I’m tracing the candidate commits against NoteEditorSurface and the existing block-selection extensions, then I’ll restore the click/tap state transition and add the requested browser e2e coverage.
Author
Owner

Bisect finding: the regression is in the live Notes surface wiring (ceb70c6f), not the three later candidates. That commit introduced NoteEditorSurface.svelte with only focus/blur-based reading vs editing. Its header says the block-selection controller was excluded from the port. The current surface still has CSS gated by .is-block-interactions, but its root never sets that class or mounts a selection controller. The candidate diffs are presentation-only: d209852c changes heading margins, 532f8202 changes floating-menu material, and 8e013795 adds table overflow and a cell minimum. I’m restoring the interaction using the existing selectionBlocks, setBlockSelectionPos, and editor block helpers, then adding the requested Notes e2e coverage.

Bisect finding: the regression is in the live Notes surface wiring (`ceb70c6f`), not the three later candidates. That commit introduced `NoteEditorSurface.svelte` with only focus/blur-based reading vs editing. Its header says the block-selection controller was excluded from the port. The current surface still has CSS gated by `.is-block-interactions`, but its root never sets that class or mounts a selection controller. The candidate diffs are presentation-only: `d209852c` changes heading margins, `532f8202` changes floating-menu material, and `8e013795` adds table overflow and a cell minimum. I’m restoring the interaction using the existing `selectionBlocks`, `setBlockSelectionPos`, and editor block helpers, then adding the requested Notes e2e coverage.
Author
Owner

Finding: getent ahosts localhost returns ::1 first in this environment, while the notes e2e server bound only to 127.0.0.1; Chromium failed at the app root with net::ERR_CONNECTION_REFUSED. The harness now binds IPv6 loopback and waits for the localhost listener before navigation. node --check apps/web/e2e/notes.mjs passes, and the run now reaches the first block-mode assertion after server startup, owner setup, and fixture creation.

That selection run used a reusable server binary from another worktree. calternal-server embeds apps/web/build through RustEmbed, so it served older frontend assets. I am rebuilding the server in this worktree before assessing the selection behavior.

Finding: `getent ahosts localhost` returns `::1` first in this environment, while the notes e2e server bound only to `127.0.0.1`; Chromium failed at the app root with `net::ERR_CONNECTION_REFUSED`. The harness now binds IPv6 loopback and waits for the localhost listener before navigation. `node --check apps/web/e2e/notes.mjs` passes, and the run now reaches the first block-mode assertion after server startup, owner setup, and fixture creation. That selection run used a reusable server binary from another worktree. `calternal-server` embeds `apps/web/build` through `RustEmbed`, so it served older frontend assets. I am rebuilding the server in this worktree before assessing the selection behavior.
Author
Owner

Started continuation in job/editor-modes. Base dev SHA: 2520f2d07e111a8717e986f57e1ca3c51242c486. Current checkpoint: cf20175d6d. Reading prior report and validating the restored block selection/edit modes.

Started continuation in job/editor-modes. Base dev SHA: 2520f2d07e111a8717e986f57e1ca3c51242c486. Current checkpoint: cf20175d6da07d84298ba90511af7e1884b1e940. Reading prior report and validating the restored block selection/edit modes.
Author
Owner

Completed: editor interaction modes (#182)

The Notes editor again uses Craft-style block selection and text editing. The regression came from ceb70c6f: the live NoteEditorSurface wired focus and blur only and omitted the block-selection controller. The later heading spacing, menu material and table overflow commits did not cause it.

A single pointer click or tap selects a block and shows the existing block-selection decoration. Arrow keys move the selection; Enter or a double click/tap enters text editing; Escape returns to the edited block. Selection is announced to assistive technology. Selection changes use metadata-only editor transactions, so they do not change Markdown or the undo history. A heading Copy link from the context menu keeps block selection active.

The Notes e2e passed against a freshly built production web app embedded in a real local server. It covers mouse selection, the visible cue, arrow navigation, Enter, double click, Escape, heading Copy link, touch tap/double tap, and captures the block-selection review images in both themes.

Files

  • apps/web/src/lib/notes/NoteEditorSurface.svelte
  • apps/web/e2e/notes.mjs
  • artifacts/editor-modes-review/ (26 screenshots; the selected-block Paper and Tokyo Night images were refreshed from the passing run)

Review images:

  • artifacts/editor-modes-review/block-selection-1440-paper-white.png
  • artifacts/editor-modes-review/block-selection-1440-tokyo-night.png

Commits

  • 45cd046a Restore note block selection and text editing modes
  • 1364f397 test(editor): refresh block selection review screenshots
  • Merged current dev tip 2527f0d0 in 4eef21ad

Head SHA: 1364f3973068a1ea7a2b132594d70ae117fb6a67

Gate output

cargo fmt --check: no stdout; exit status 0.

cargo clippy --all-targets -- -D warnings (exit status 0):

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 23m 47s

cargo test (exit status 0):

    Finished `test` profile [unoptimized + debuginfo] target(s) in 9m 08s

test result: ok. 476 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.49s

bun run check (exit status 0):

svelte-check found 0 errors and 0 warnings

bun run test (exit status 0):

 Test Files  55 passed (55)
      Tests  432 passed (432)
   Start at  21:34:18
   Duration  25.71s (transform 67%, import 15%, environment 11%, tests 7%)

Production e2e output:

notes e2e: ok

Decisions and known gaps

  • The design sets the single/double gesture but not its timing. Mouse double click uses the native click count or a 500 ms, 28 px fallback. Touch double tap uses 450 ms and 28 px; movement above 10 px cancels a tap.
  • The selected-block cue uses the accent-soft color mix and a 2 px accent ring. The two screenshots are provided for Claude’s visual review.
  • The heading link icon behavior is tracked separately per the issue correction. This change verifies that the heading Copy link context-menu action preserves selection.
  • Vitest printed jsdom Not implemented: Window's scrollTo() method notices, while all 55 files and 432 tests passed. Rust tests that need external model assets or run performance benchmarks remain intentionally ignored.

Generated Rust and web build outputs were cleaned after the gates.

## Completed: editor interaction modes (#182) The Notes editor again uses Craft-style block selection and text editing. The regression came from `ceb70c6f`: the live `NoteEditorSurface` wired focus and blur only and omitted the block-selection controller. The later heading spacing, menu material and table overflow commits did not cause it. A single pointer click or tap selects a block and shows the existing block-selection decoration. Arrow keys move the selection; Enter or a double click/tap enters text editing; Escape returns to the edited block. Selection is announced to assistive technology. Selection changes use metadata-only editor transactions, so they do not change Markdown or the undo history. A heading Copy link from the context menu keeps block selection active. The Notes e2e passed against a freshly built production web app embedded in a real local server. It covers mouse selection, the visible cue, arrow navigation, Enter, double click, Escape, heading Copy link, touch tap/double tap, and captures the block-selection review images in both themes. ### Files - `apps/web/src/lib/notes/NoteEditorSurface.svelte` - `apps/web/e2e/notes.mjs` - `artifacts/editor-modes-review/` (26 screenshots; the selected-block Paper and Tokyo Night images were refreshed from the passing run) Review images: - `artifacts/editor-modes-review/block-selection-1440-paper-white.png` - `artifacts/editor-modes-review/block-selection-1440-tokyo-night.png` ### Commits - `45cd046a` Restore note block selection and text editing modes - `1364f397` test(editor): refresh block selection review screenshots - Merged current `dev` tip `2527f0d0` in `4eef21ad` Head SHA: `1364f3973068a1ea7a2b132594d70ae117fb6a67` ### Gate output `cargo fmt --check`: no stdout; exit status 0. `cargo clippy --all-targets -- -D warnings` (exit status 0): ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 23m 47s ``` `cargo test` (exit status 0): ```text Finished `test` profile [unoptimized + debuginfo] target(s) in 9m 08s test result: ok. 476 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.49s ``` `bun run check` (exit status 0): ```text svelte-check found 0 errors and 0 warnings ``` `bun run test` (exit status 0): ```text Test Files 55 passed (55) Tests 432 passed (432) Start at 21:34:18 Duration 25.71s (transform 67%, import 15%, environment 11%, tests 7%) ``` Production e2e output: ```text notes e2e: ok ``` ### Decisions and known gaps - The design sets the single/double gesture but not its timing. Mouse double click uses the native click count or a 500 ms, 28 px fallback. Touch double tap uses 450 ms and 28 px; movement above 10 px cancels a tap. - The selected-block cue uses the accent-soft color mix and a 2 px accent ring. The two screenshots are provided for Claude’s visual review. - The heading link icon behavior is tracked separately per the issue correction. This change verifies that the heading Copy link context-menu action preserves selection. - Vitest printed jsdom `Not implemented: Window's scrollTo() method` notices, while all 55 files and 432 tests passed. Rust tests that need external model assets or run performance benchmarks remain intentionally ignored. Generated Rust and web build outputs were cleaned after the gates.
Author
Owner

Correction to the gate excerpt above: 476 passed is the verbatim result for the calternal-notes-core test target, not an aggregate count for the full workspace. The complete cargo test command exited 0; all non-ignored test targets passed. Some targets report ignored benchmark or pinned-model tests, as noted in the report.

Correction to the gate excerpt above: `476 passed` is the verbatim result for the `calternal-notes-core` test target, not an aggregate count for the full workspace. The complete `cargo test` command exited 0; all non-ignored test targets passed. Some targets report ignored benchmark or pinned-model tests, as noted in the report.
Author
Owner

Merged into dev at e3b30ab8 after Claude's screenshot review (single click selects a block with the accent ring, double click edits). Deploy status on #203.

Merged into dev at e3b30ab8 after Claude's screenshot review (single click selects a block with the accent ring, double click edits). Deploy status on #203.
kayg referenced this issue from a commit 2026-09-26 19:42:09 +00:00
kayg closed this issue 2026-09-26 19:42:10 +00:00
Author
Owner

Post-merge Notes E2E check at c2ff7b40 had one intermittent block-selection timeout after double-clicking a paragraph and pressing Escape. At timeout the document focus was BODY and the editor surface was in reading mode, with no selected block. An immediate full rerun passed single-click selection, keyboard movement, Escape, heading context-menu behavior, touch tap/double-tap, and ended with CSP REPORTS notes: 0 across 3 pages. I did not reproduce a product failure on retry.

Post-merge Notes E2E check at c2ff7b40 had one intermittent block-selection timeout after double-clicking a paragraph and pressing Escape. At timeout the document focus was BODY and the editor surface was in reading mode, with no selected block. An immediate full rerun passed single-click selection, keyboard movement, Escape, heading context-menu behavior, touch tap/double-tap, and ended with CSP REPORTS notes: 0 across 3 pages. I did not reproduce a product failure on retry.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal#182
No description provided.