feat(converter): preserve row-level content control wrappers in table round-trip (SD-3291)#3567
Open
luccas-harbour wants to merge 6 commits into
Conversation
Content controls that wrap a whole table row (<w:sdt> containing a <w:tr>, ECMA-376 §17.5.2.30 CT_SdtRow) were dropped on import, breaking round-trip. Add normalizeTableRowChildren to unwrap single-row SDT wrappers and attach their w:sdtPr/w:sdtEndPr as rowSdt metadata on the tableRow node, then rebuild the <w:sdt> envelope on export. Multi-row wrappers are imported defensively by emitting inner rows in order without wrapper metadata. Extract the shared getSdtEnvelopeParts helper and reuse it from the cell-level path. Route table-row enumeration through the normalizer in the table translator and legacy cell handler so rowspan and width calculations see SDT-wrapped rows. Generalize CellSdtMetadata into a scoped SdtMetadata<Scope> type and add RowSdtMetadata.
Contributor
|
The calls keep returning "not granted yet," so I'll pause here. To run the spec verification I need you to approve the
Go ahead and grant access (or tell me to proceed using my own knowledge of the spec without the tools), and I'll produce the PASS/FAIL review. |
There was a problem hiding this comment.
No issues found across 20 files
Tip: cubic could auto-approve low-risk PRs like this, if it thinks it's safe to merge. Learn more
Re-trigger cubic
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Word lets a user wrap a whole table row in a content control (a
<w:sdt>around a<w:tr>) — for example, a repeating section that controls a row. Before this change, the table importer read rows directly and ignored any row wrapped in<w:sdt>, so the wrapped row never entered the editable document data: it was missing from the editor, absent from text search, and dropped on export back to DOCX.This is the row-level analog of the cell-level content control bug fixed in SD-3289 / IT-1119. This PR extends that fix to rows and factors the now-shared logic into common helpers so the two scopes stay in lockstep.
What changed
New shared helpers —
super-converter/v3/handlers/w/sdt/helpers/sdt-envelope.jsgetSdtEnvelopeParts— pullssdtPr/sdtEndPr/sdtContentout of a<w:sdt>(replaces inlinefind(w:sdtContent)across five SDT handlers).normalizeSdtContentChildren— on import, unwraps a single child (w:trorw:tc) from its<w:sdt>and preserves the envelope (sdtPr,sdtEndPr, and anycontentBefore/contentAftersiblings) as opaque metadata.wrapSdtContentChildren— on export, reconstructs the<w:sdt>envelope around the exported child from that metadata.Row-level wiring
tbl-translator.jsattachesrowSdtmetadata on import and re-wraps rows on export; row enumeration (incl. the first-row width helper) now goes through the normalizer so wrapped rows are included.table-row.jsregisters arowSdtschema attribute (default: null,rendered: false).legacy-handle-table-cell-node.jsnow finds vMerge continuations inside row-level SDT wrappers.Cell-level path now routes through the same shared helpers (
tr-translator.js,row-cell-children.js), and additionally gainedcontentBefore/contentAftersibling preservation as a side effect of the extraction.Types —
node-attributes.tsintroduces a sharedSdtMetadata<Scope>withCellSdtMetadata/RowSdtMetadataaliases; addsrowSdttoTableRowAttrs.Tests
table-row-children.test.js— normalizer unit tests (direct rows, single-row unwrap + metadata, content siblings, multi-row wrappers, empty SDTs).tbl-translator.row-sdt.integration.test.js— full encode → export round-trip with no mocks; wrapped row renders, text is findable,<w:sdt>reconstructed.tbl-translator.test.js,tr-translator.cell-sdt.test.js— encode/decode coverage for both scopes.legacy-handle-table-cell-node.test.js— vMerge across cell- and row-level SDT wrappers.Known limitations
<w:sdt>wrapping more than one<w:tr>imports defensively — the rows survive but the wrapper metadata is dropped (SuperDoc doesn't yet model a single control spanning rows). Documented and tested.<w:sdt>directly wrapping one<w:tr>. If a given Word version emits the nestedrepeatingSection > repeatingSectionItem > w:trshape, that row is not yet unwrapped — worth confirming against a real fixture.