fix(converter): preserve tracked-change-wrapped fields during DOCX import (SD-2858)#3175
Conversation
…aragraphs When a field (w:fldChar begin/separate/end) is wrapped in a w:del or w:ins tracked-change element and split across paragraphs, the field pre-processor would crash on the unpaired end or strip the tracked-change wrapper. Detect track-change wrappers and flag the field as `preserveRaw` so the raw nodes are emitted untouched, and handle an unpaired end at the top level by passing the node through with `unpairedEnd = true`.
Guard against a missing `Relationships` element and entries without an `attributes` map when scanning `document.xml.rels` for headers/footers, so docs that omit either no longer throw during import.
|
The ecma-spec MCP tools need permission to be granted. Could you approve them? Without that I can still do a manual spec review — let me know which you'd prefer. In the meantime, I can share what I see from direct spec knowledge: The diff touches a fairly narrow set of OOXML constructs:
One thing worth checking once the tools are approved: the test places Please approve the ecma-spec tool calls and I'll do the full verification. |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
… tracked-change wrapper When a field's `end` fldChar is wrapped in a tracked-change element (`w:del`/`w:ins`), the field cannot be safely re-emitted from the collected instruction tokens — round-tripping would drop the tracked deletion markup. Propagate a new `unpairedEndPreserveRaw` flag up through nested children so the active field is marked `preserveRaw` once it finalizes, keeping the original w:r/w:del nodes intact.
…SD-2858) When a field's `end` fldChar surfaces through nested wrappers (e.g. w:sdt/w:sdtContent or tracked-change elements) and there is no active field still collecting at this level, push the original `rawNode` rather than the processed `node`. The processed copy can have its child runs rewritten by the recursive pass, dropping the fldChar and breaking round-trip; the raw subtree preserves the input verbatim. Adds a regression test covering the non-collecting wrapper path.
caio-pizzol
left a comment
There was a problem hiding this comment.
hey @luccas-harbour! lgtm :)
follow-up: same shape but with an inserted (instead of deleted) field also used to drop on import. now the text shows up but the link is gone - user sees plain text where Word shows a clickable link. fine for deletes and moves since that text goes away on accept, but for inserts it stays visible. tracked in SD-2973.
|
🎉 This PR is included in @superdoc-dev/mcp v0.3.0-next.62 The release is available on GitHub release |
|
🎉 This PR is included in @superdoc-dev/react v1.2.0-next.104 The release is available on GitHub release |
|
🎉 This PR is included in vscode-ext v2.3.0-next.106 |
|
🎉 This PR is included in superdoc-cli v0.8.0-next.78 The release is available on GitHub release |
|
🎉 This PR is included in superdoc v1.30.0-next.60 The release is available on GitHub release |
|
🎉 This PR is included in superdoc-sdk v1.8.0-next.60 |
|
🎉 This PR is included in superdoc-cli v0.9.0 The release is available on GitHub release |
|
🎉 This PR is included in superdoc v1.32.0 The release is available on GitHub release |
|
🎉 This PR is included in @superdoc-dev/mcp v0.4.0 The release is available on GitHub release |
|
🎉 This PR is included in @superdoc-dev/react v1.3.0 The release is available on GitHub release |
|
🎉 This PR is included in vscode-ext v2.4.0 |
Summary
Fixes DOCX import handling for fields wrapped in tracked changes when the field spans multiple nodes or paragraphs.
This preserves the original raw OOXML for tracked-change-wrapped fields instead of trying to collapse/process them as normal field references. That avoids import failures fordocuments where a field begins inside one tracked deletion/insertion wrapper and ends inside another.
Also makes header/footer relationship filtering more defensive by tolerating missing relationship elements or relationship nodes without attributes.
Changes
w:delorw:inswrappers.elementsorattributes.