Repository navigation
Conversation
A reviewer's <w:ins>/<w:del> inside word/header{N}.xml / footer{N}.xml was
invisible: headers list and the docx:header hint dropped the insertion,
track-changes list didn't enumerate it, so accept/reject couldn't reach it.
- read.ts: readMarginalTrackedChanges registers run-level revisions in each
header/footer part (once per part) after the notes, blockId = hdrN/ftrN.
- marginalText reads the accepted view via isWrapperVisibleInView.
- list reads a note/marginal wrapper's text off its own runs.
- computeMaxRevisionId scans the header/footer parts too.
|
🤖 docx-cli triage Thanks @xsvm, this is a real gap and the fix goes in the right place. I reviewed What the PR claimsA tracked Before/after reproSetup:
Other results:
The follow-up commit (
|
…within a line - Text-box revisions in a header were listed twice (Choice and Fallback carry the same story); rejecting the Fallback copy exited 0 and the save-time Choice->Fallback mirror undid it. The run walk now descends an mc:AlternateContent through its chosen branch only. - Revisions inside a block-level <w:sdt> (Word's page-number gallery) or a header table were never registered, so accept --all reported 0 changes and left them in place. registerMarginalBlockChanges walks sdt, tables and AlternateContent down to every paragraph. - A note's "" and a marginal's hdrN/ftrN name a whole part, so revision groups there now also require a shared container: a deletion in one header line and an insertion in the next are no longer one revN. - wrapperRunText moves to core/parser/run-ops.ts and replaces the identical collectGlyphText in task-list/detect.ts; registerNoteRunChanges is renamed registerStandaloneRunChanges; marginal refs resolve once per read; marginalText descends wrappers via wrapperContent. Follows the triage review on kklimuk#28.
|
Thanks for the review. Before changing anything I reproduced all three bugs on
There are four new tests in One related gap I noticed but left alone: |
|
🤖 docx-cli triage Thanks @xsvm. I re-reviewed Prior review items
Checks
Before/after (one header with a same-line replace, an sdt, a table cell, and a del and an ins on separate lines)
I also checked these on the PR:
Minor gaps (not blocking, could be follow-ups)
Open product questions (carried over; only the maintainer can answer these)
Action needed: approve/merge — answer the questions above, then approve and merge PR #28. @xsvm made the last push, so your own approval satisfies the last-push rule. Generated by Claude Code |
|
@xsvm hold off from making further changes till i've had a bit of time to read through and do my own reviews, it's gonna take me a few days. |
Summary
A tracked change inside a page header or footer was invisible to an agent. Repro (header saved by Word 365):
<w:r><w:t>Header text</w:t></w:r><w:ins …><w:r><w:t> edited</w:t></w:r></w:ins>:headers listand thedocx:headerhint read justHeader textmarginalTextonly looked inside<w:hyperlink>, so it skipped<w:ins>track-changes listprintedno tracked changes, so accept/reject couldn't reach itThe fix reuses the existing paths
readMarginalTrackedChanges(ast/read.ts) runs afterreadNoteTrackedChangesand registers each header/footer part's run-levelins/del/moveFrom/moveTothrough the existingregisterNoteRunChanges, which now takes ablockId. TheblockIdis the marginal'shdrN/ftrN, solistsays where the change is. A part shared by several sections is registered once.tcNids still come from the one walk, continuing after the notes.marginalTextdecides what to show with the existingisWrapperVisibleInView(tag, "accepted"): insertions show and deletions stay hidden.applyedits the part tree in place andMarginalsView.writeTosaves it. A paragraph-mark lookup byhdrNfinds nothing, so these stay run-level.listreads a note or header wrapper's text from its own runs (wrapperRunText). Before this, note-body edits showed as "¶ paragraph mark".computeMaxRevisionIdalso scans header/footer parts, so a newly created revision id can't collide with one already in a header.After:
accept --allgivesHeader text editedandreject --allgivesHeader text old. Both results passdocx validate.Not covered: revisions inside a table in a header, paragraph-mark revisions in a header, and
<w:rPrChange>(already documented as out of scope).Note: this overlaps with #27 in
list-view.ts, since both fill inlisttext for runs the body loop doesn't see. Whichever merges second needs a small rebase.Test plan
bun run checktests/cli/headers-footers.test.ts: read view,list, accept, rejectbun test: the only failures are the existing Windows-only ones (benchmark metrics timeout, render/bin/shprobe, compiled-binary upgrade)