EANCH-WP-0004: HtmlViewer scroll parity and viewer-shell workplan
Export HtmlViewerAdapter from package root, add scrollRequestKey parity, register finished workplan, update SCOPE.
This commit is contained in:
parent
49d9810c93
commit
bbeba96173
4 changed files with 119 additions and 5 deletions
5
SCOPE.md
5
SCOPE.md
|
|
@ -51,10 +51,9 @@ Selector *behavior* lives here; selector *type interfaces* live in
|
|||
During the umbrella-first MVP these belong to the appropriate citation-evidence
|
||||
subsystem. This repo may depend on **`citation-engine` only** (DependencyMap §4).
|
||||
|
||||
### Still deferred (beyond EANCH-WP-0002 / EANCH-WP-0003)
|
||||
### Still deferred (beyond EANCH-WP-0004)
|
||||
|
||||
- `FragmentSelector` (export-only deep links)
|
||||
- wiring `HtmlViewerAdapter` into `citation-work` / the umbrella review shell
|
||||
- human-confirmation UI for ambiguous/fuzzy matches
|
||||
|
||||
---
|
||||
|
|
@ -81,7 +80,7 @@ subsystem. This repo may depend on **`citation-engine` only** (DependencyMap §4
|
|||
- Status: active — standalone package consumed by `citation-evidence`
|
||||
- Implementation: PDF + HTML/Markdown selector paths, stale/orphan/fuzzy resolution,
|
||||
`PdfViewerAdapter`, and `HtmlViewerAdapter` (`evidence-anchor/dom`)
|
||||
- Stability: evolving — shared contracts stable; viewer wiring in the umbrella is next
|
||||
- Stability: evolving — shared contracts stable; HTML/MD wired in `citation-work` ViewerShell
|
||||
- Usage: internal (consumed by `citation-evidence` during MVP)
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -32,6 +32,11 @@ export interface HtmlViewerAdapterProps {
|
|||
readonly representation: DocumentRepresentation;
|
||||
readonly storedAnnotations?: readonly StoredHtmlAnnotation[];
|
||||
readonly scrollToAnnotationId?: string;
|
||||
/**
|
||||
* Bumps when the same annotation should be re-scrolled (e.g. repeat click).
|
||||
* Format is opaque — typically `${annotationId}:${version}`.
|
||||
*/
|
||||
readonly scrollRequestKey?: string;
|
||||
readonly activeAnnotationId?: string | null;
|
||||
readonly debug?: HtmlViewerDebugOptions;
|
||||
onSelectionCaptured?(capture: DomSelectionCapture, selectors: Selector[]): void;
|
||||
|
|
@ -50,6 +55,7 @@ export function HtmlViewerAdapter(props: HtmlViewerAdapterProps): ReactNode {
|
|||
representation,
|
||||
storedAnnotations = [],
|
||||
scrollToAnnotationId,
|
||||
scrollRequestKey,
|
||||
activeAnnotationId,
|
||||
debug,
|
||||
onSelectionCaptured,
|
||||
|
|
@ -91,12 +97,13 @@ export function HtmlViewerAdapter(props: HtmlViewerAdapterProps): ReactNode {
|
|||
}, [html, storedAnnotations, representation, activeAnnotationId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!scrollToAnnotationId || !rootRef.current) return;
|
||||
const requestKey = scrollRequestKey ?? scrollToAnnotationId ?? null;
|
||||
if (!requestKey || !scrollToAnnotationId || !rootRef.current) return;
|
||||
const mark = rootRef.current.querySelector(
|
||||
`[data-highlight-id="${CSS.escape(scrollToAnnotationId)}"]`,
|
||||
);
|
||||
mark?.scrollIntoView({ block: "center", behavior: "smooth" });
|
||||
}, [scrollToAnnotationId, renderedHtml]);
|
||||
}, [scrollToAnnotationId, scrollRequestKey, renderedHtml]);
|
||||
|
||||
return (
|
||||
<div
|
||||
|
|
|
|||
14
src/index.ts
14
src/index.ts
|
|
@ -20,6 +20,20 @@ export {
|
|||
type CreateSelectorsOptions,
|
||||
} from "./selectors";
|
||||
|
||||
// DOM adapter (re-exported from the src/dom/ boundary).
|
||||
export {
|
||||
HtmlViewerAdapter,
|
||||
resolveHtmlSelectors,
|
||||
scrollToHtmlTarget,
|
||||
renderHtmlHighlight,
|
||||
captureFromRange,
|
||||
domPathToNode,
|
||||
nodeAtPath,
|
||||
type HtmlViewerAdapterProps,
|
||||
type HtmlViewerDebugOptions,
|
||||
type StoredHtmlAnnotation,
|
||||
} from "./dom";
|
||||
|
||||
// PDF adapter + helpers (re-exported from the src/pdf/ boundary).
|
||||
export {
|
||||
PdfViewerAdapter,
|
||||
|
|
|
|||
94
workplans/EANCH-WP-0004-viewer-shell-dom-wiring.md
Normal file
94
workplans/EANCH-WP-0004-viewer-shell-dom-wiring.md
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
---
|
||||
id: EANCH-WP-0004
|
||||
type: workplan
|
||||
title: "Wire HtmlViewerAdapter into the review workspace viewer shell"
|
||||
domain: infotech
|
||||
repo: evidence-anchor
|
||||
status: finished
|
||||
owner: codex
|
||||
topic_slug: citation_evidence_mvp
|
||||
created: "2026-07-09"
|
||||
updated: "2026-07-09"
|
||||
spec_refs:
|
||||
- INTENT.md
|
||||
- SCOPE.md
|
||||
- ../citation-evidence/wiki/SharedContracts.md
|
||||
- src/dom/html-viewer-adapter.tsx
|
||||
---
|
||||
|
||||
# EANCH-WP-0004 — Viewer Shell DOM Wiring
|
||||
|
||||
## Goal
|
||||
|
||||
Connect `HtmlViewerAdapter` (`evidence-anchor/dom`) to the citation-evidence
|
||||
review workspace so users can upload, view, select, annotate, and reopen
|
||||
HTML/Markdown documents — not only PDFs.
|
||||
|
||||
## Task Breakdown
|
||||
|
||||
## T01 — Browser upload path for HTML/Markdown
|
||||
|
||||
```task
|
||||
id: EANCH-WP-0004-T01
|
||||
status: done
|
||||
priority: high
|
||||
```
|
||||
|
||||
Add `ingestHtmlFromFile` / `ingestMarkdownFromFile` and `resolveDomViewerHtml`
|
||||
to `evidence-source/browser`, extending the byte store to hold non-PDF bytes.
|
||||
|
||||
## T02 — Upload dropzone accepts HTML/Markdown
|
||||
|
||||
```task
|
||||
id: EANCH-WP-0004-T02
|
||||
status: done
|
||||
priority: high
|
||||
depends_on: [T01]
|
||||
```
|
||||
|
||||
Extend `citation-work` `UploadDropzone` to ingest `.html` / `.md` files via
|
||||
the new browser helpers.
|
||||
|
||||
## T03 — ViewerShell routes by representation type
|
||||
|
||||
```task
|
||||
id: EANCH-WP-0004-T03
|
||||
status: done
|
||||
priority: high
|
||||
depends_on: [T02]
|
||||
```
|
||||
|
||||
Branch `ViewerShell` on `representationType`: PDF → `PdfViewerAdapter`,
|
||||
`html-dom` / `markdown-rendered` → `HtmlViewerAdapter`. Widen
|
||||
`PendingSelection` to `SelectionCapture`.
|
||||
|
||||
## T04 — HtmlViewerAdapter scroll parity
|
||||
|
||||
```task
|
||||
id: EANCH-WP-0004-T04
|
||||
status: done
|
||||
priority: medium
|
||||
depends_on: [T03]
|
||||
```
|
||||
|
||||
Add `scrollRequestKey` to `HtmlViewerAdapter` so repeat-click re-scroll works
|
||||
like the PDF adapter.
|
||||
|
||||
## T05 — Verification + close-out
|
||||
|
||||
```task
|
||||
id: EANCH-WP-0004-T05
|
||||
status: done
|
||||
priority: high
|
||||
depends_on: [T04]
|
||||
```
|
||||
|
||||
Tests green in `evidence-source`, `evidence-anchor`, `citation-work`, and
|
||||
`citation-evidence`; `fix-consistency` clean; progress note.
|
||||
|
||||
**Verification (2026-07-09):**
|
||||
|
||||
- `evidence-source`: 82 tests (browser view-html + upload).
|
||||
- `evidence-anchor`: 42 tests; `HtmlViewerAdapter` scroll parity.
|
||||
- `citation-work`: 12 tests including `ViewerShell.dom.test.tsx`.
|
||||
- `citation-evidence`: typecheck clean.
|
||||
Loading…
Add table
Add a link
Reference in a new issue