From 8bb441870ad485be5afd1851d1755a4dfa8095ae Mon Sep 17 00:00:00 2001 From: claude_code Date: Wed, 24 Jun 2026 04:36:39 +0300 Subject: [PATCH] =?UTF-8?q?test(editor):=20address=20PR=20#147=20review=20?= =?UTF-8?q?=E2=80=94=20reflow=20tests,=20code-block=20guard,=20a11y?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolve the pre-merge review items for the #146 NodeView content-first fix: - Export collectScrollAncestors/reflowAfterPaste and add editor-paste-handler unit tests covering ancestor selection (overlay included, non-overflowing auto excluded, X axis), the scrollHeight>clientHeight gate, scrollingElement dedup, the docEl==null branch, and the double-rAF nudge. - Extend the structural guard with CodeBlockView and merge the two it.each blocks into one document-order assertion (handles the
 nesting where the
  contentDOM is not the literal first child).
- Simplify the post-paste nudge to a single scrollTo(scrollLeft, scrollTop).
- Document that the post-paste reflow runs on every paste path intentionally,
  and cross-reference the two #146 mitigations in both fixes.
- a11y: aria-hidden the decorative footnotes heading and number marker, and
  label the footnotes list via role="group" + aria-label so the visual reorder
  does not break screen-reader reading order (WCAG 1.3.2).
- CHANGELOG: add a Fixed entry noting the caret fix is macOS-verified manually.

Co-Authored-By: Claude Opus 4.8 
---
 CHANGELOG.md                                  |  12 ++
 .../components/code-block/code-block-view.tsx |   3 +-
 .../common/editor-paste-handler.test.ts       | 160 ++++++++++++++++++
 .../common/editor-paste-handler.tsx           |  28 +--
 .../footnote/footnote-definition-view.tsx     |   9 +-
 .../footnote-views.structure.test.tsx         |  94 +++++++---
 .../footnote/footnotes-list-view.tsx          |  17 +-
 7 files changed, 286 insertions(+), 37 deletions(-)
 create mode 100644 apps/client/src/features/editor/components/common/editor-paste-handler.test.ts

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 43255596..b843e912 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -19,6 +19,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
   cut from 300 to 100 on upgrade. Set `SHARE_AI_WORKSPACE_MAX_PER_HOUR` to
   keep the previous limit. (#62)
 
+### Fixed
+
+- **Editor: caret/selection landed on the wrong line when clicking inside code
+  blocks and footnotes.** The affected NodeViews rendered their non-editable
+  chrome (language menu, footnotes heading, footnote number marker) before the
+  editable content, so the browser's click hit-testing missed the contentDOM and
+  snapped the caret to a previous node. Content now renders first in the DOM
+  (chrome is lifted back into place via CSS flex `order`), and scroll containers
+  are nudged after a paste to refresh stale hit-testing geometry. The caret
+  symptom is macOS-specific and was confirmed manually on macOS; the automated
+  guard pins the DOM-order invariant, not the caret behavior itself. (#146, #147)
+
 ## [0.93.0] - 2026-06-21
 
 This release builds on the 0.91.0 AI foundation: admin-defined AI agent roles,
diff --git a/apps/client/src/features/editor/components/code-block/code-block-view.tsx b/apps/client/src/features/editor/components/code-block/code-block-view.tsx
index 1b67ddf6..1930f182 100644
--- a/apps/client/src/features/editor/components/code-block/code-block-view.tsx
+++ b/apps/client/src/features/editor/components/code-block/code-block-view.tsx
@@ -53,7 +53,8 @@ export default function CodeBlockView(props: NodeViewProps) {
           menu is rendered after it and lifted back above visually via flex
           `order: -1` (the `.codeBlock` wrapper is a flex column — see
           code-block.module.css). It stays fully in flow as a full-width row
-          above the code: no overlay/absolute positioning. */}
+          above the code: no overlay/absolute positioning. The second #146
+          mitigation lives in editor-paste-handler.tsx (reflowAfterPaste). */}