Following a redline through the engine
The path a draft takes from baseline-plus-current text to email-safe redline HTML — the doc section first, then the modules that do the work.
Workflow 1 — Draft redline (Start tracking → Insert Redline)
State lives in src/hooks/useTracking.ts:
a TrackingSnapshot (baseline + optional selection anchors), a
loadingAction flag, and redlineInserted.
sequenceDiagram
participant U as User
participant H as useTracking
participant O as src/outlook
participant R as src/redline
U->>H: Start tracking
H->>O: getSelectedText() + getBodyHtml()
alt selection made
O-->>H: captureComposeSelectionAnchors()<br/>(48-char prefix/suffix anchors)
H->>H: snapshot {scope:'selection', anchors, baselineHtml}
else no selection
H->>H: snapshot {scope:'full', baselineHtml}
end
U->>U: edits draft freely in Outlook
U->>H: Insert Redline
H->>O: getBodyHtml() (current state)
alt selection scope
O-->>H: extractRegionHtml(bodyHtml, anchors)
H->>R: buildRegionRedline(baseline, currentRegion)
R-->>H: redline HTML
H->>O: replaceRegionInHtml(...) → setBodyHtml()
else full scope
H->>R: buildFullDraftRedline(baseline, bodyHtml)
R-->>H: redline HTML (envelope preserved)
H->>O: setBodyHtml(result.html)
end
The body-region system (src/outlook/bodyRegion.ts)
is what lets a selection survive the user's edits: at capture time it stores
48-character prefix/suffix anchors plus plain-text offsets (ANCHOR_LEN = 48,
line 19); at insert time it relocates the region with a 512-char hint window
(REGION_HINT_WINDOW = 512, line 20), line-ending normalization, and
bullet-prefix-tolerant fuzzy matching, then splices the redline back into the
full body HTML without disturbing blocks outside the region
(replaceRegionInHtml, src/outlook/bodyRegion.ts:930).