Skip to content

Fix review control surfaces found on the NVCA charter - #51

Merged
JSv4 merged 1 commit into
mainfrom
fix/nvca-review-control-surfaces
Sep 25, 2026
Merged

JSv4 merged 1 commit into
mainfrom
fix/nvca-review-control-surfaces

Conversation

@JSv4

@JSv4 JSv4 commented Sep 24, 2026

Copy link
Copy Markdown
Owner

Summary

GUI QA on the NVCA Model COI (50 pages) turned up several control-surface problems with tracked edits, labels and comments. The main one was the reported bug: after labelling a passage, selecting other text and clicking Label did nothing visible, or labelled the previously selected paragraph.

Root causes and fixes

Labels and selection

  • An injected .annot-label counted as paragraph text. The canvas text no longer matched the native text, so every labelled paragraph became contenteditable=false. Labels are now treated as generated content, both in canvasDom and in the viewer's selection mapping.
  • A selection inside a read-only block reached only onAnchorSelect. The workspace then preferred the stale editor selection (editor.selection ?? requestedAnchor), so Label applied to the wrong block. The viewer now reports text selections in read-only blocks even when a canvas editor is attached, and the workspace uses whichever selection is newest.
  • Labels and comments ignored the text selection and always covered the whole paragraph. AnnotationsPanel and CommentsPanel now accept a span, preview their target ("Selected text / Selected block"), and accept a focusRequest.
  • In the demo, the quick-action bar shows the quoted target, comes back for each new selection after being dismissed, and focuses the Label/Comment field.

Tracked changes

  • Every pure insertion used to borrow a neighbouring character. Typing after "stock." recorded del "." + ins ". This…". Docxodus 12.6.2 accepts zero-width replaceMatch spans, so insertions are now zero-width, which yields one clean w:ins that inherits the neighbour's rPr. The borrowed write stays as a fallback if the engine refuses.
  • Documents saved with w:trackRevisions reopened with tracking off. DocxSessionController.open now honours the setting unless the host passes trackedChanges explicitly.
  • The workspace had no tracking indicator, the toggle was buried in the Edit sidebar, and revisions were authored "docxodus" while comments and labels used "Reviewer". There's now an always-visible tracking toggle and a single revisionAuthor.

Presentation

  • Engine .annot-highlight padding (1px 2px on each run fragment) opened gaps ("General .", "“ Certificate ”"). The viewer shadow root now sets padding-inline: 0.
  • annotationMode: 'above' labels covered the preceding line. The workspace now uses tooltip.
  • The formatting toolbar disappeared on non-Edit panels. It now stays on every panel.

Comments

  • Replies were listed at the bottom, detached from their thread. They're now threaded under the root.
  • Comment cards had no context. CommentsPanel takes an optional describeComment callback; the workspace supplies the highlighted text and page order.
  • "Show comment" right after reply/resolve reported "not available in the current page layout" because re-pagination was still running. The workspace now retries when pagination completes, and only non-block anchors skip select() (which raised "Choose a paragraph or heading to edit").

New public API

  • useSelectionTarget hook and the SelectionTarget type
  • span / focusRequest props on AnnotationsPanel and CommentsPanel
  • describeComment prop on CommentsPanel and the CommentContext type

Test plan

  • npm run check (lint, 92 unit tests, build, API audit)
  • npm run test:browser: 74 passed, 2 skipped (opt-in NVCA stress and PDF)
  • New unit tests: zero-width insertion diffs, w:trackRevisions detection
  • New browser tests: tracked end-of-paragraph typing gives a single insertion; an annotated paragraph stays editable; workspace labels/comments the selected word, including inside an already-labelled paragraph, and quick actions return after dismissal
  • Manual pass on the NVCA charter: tracked append/replace/delete (4 clean revisions authored "Reviewer"), span labels and comments, reply/resolve/show, save → reopen keeps tracking on, and the original document opens untracked

🤖 Generated with Claude Code

Labels and comments now target the selected text instead of the whole
paragraph, and the quick-action bar shows what it will act on. Selecting
text inside an already-labelled or otherwise read-only paragraph updates
the target, so Label no longer applies to the previously selected block.

- Exclude injected annotation labels from canvas and selection text, so
  annotated paragraphs stay editable and their offsets stay native.
- Report selections made in read-only blocks when a canvas editor is
  attached.
- Record pure insertions as zero-width native edits; appending after a
  period no longer produces a spurious tracked deletion. The borrowed
  neighbour write remains as a fallback for inline structures.
- Honour Word's w:trackRevisions setting when opening a document.
- AnnotationsPanel/CommentsPanel accept a span, preview their target,
  take focus requests, and comments thread replies under their parent
  with optional host-supplied quoted context and document order.
- Workspace: always-visible tracking toggle, one reviewer identity for
  revisions, comments and labels, formatting toolbar on every panel,
  quick actions that return for each new selection, tooltip labels that
  no longer cover neighbouring lines, no per-fragment highlight padding,
  and Show comment waits for an in-flight re-pagination.
@JSv4
JSv4 merged commit 3c99c41 into main Sep 25, 2026
4 checks passed
@JSv4
JSv4 deleted the fix/nvca-review-control-surfaces branch September 25, 2026 01:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant