Skip to content

fix(converter): preserve numbering.xml definitions on round-trip (SD-2911)#3231

Open
tupizz wants to merge 1 commit into
mainfrom
tadeu/sd-2911-preserve-numbering-on-round-trip
Open

fix(converter): preserve numbering.xml definitions on round-trip (SD-2911)#3231
tupizz wants to merge 1 commit into
mainfrom
tadeu/sd-2911-preserve-numbering-on-round-trip

Conversation

@tupizz
Copy link
Copy Markdown
Contributor

@tupizz tupizz commented May 11, 2026

Summary

  • #exportNumberingFile no longer filters numbering.xml by which numIds are referenced from the document body. Every <w:abstractNum> and <w:num> the importer captured is emitted on export.
  • Removes strip-orphaned-numbering.js + its unit tests; the inline write is now four lines.

Why

Customer fixture in SD-2911:

  • Active variant (one numId used in the body): <w:abstractNum> dropped from 8 → 1, <w:num> from 8 → 1. Live numbering definitions Word would otherwise expose in the Multilevel List dropdown were silently lost.
  • Tentative variant (no numId referenced): numbering.xml was effectively wiped (2 → 0 abstractNum, 1 → 0 num).

The filter was added by PR #2223 for the lists.delete document-api operation — when a user deletes a list, the dead definition should be cleaned up. But the filter ran on every export and had no way to tell "user just deleted in this session" from "definition was always unused in the source file" (Word's tentative numbering). Both reached it with no referencing paragraph and were treated identically. Word tolerates unused definitions, so the safe default on round-trip is to preserve everything.

Test plan

  • New integration test (sd-2911-numbering-roundtrip.test.js) round-trips both customer fixtures and asserts <w:abstractNum> / <w:num> counts and ids match the input exactly.
  • Full pnpm test for super-editor (12 695 / 12 708 pass — the 13 deletions are the removed strip-orphaned-numbering.test.js unit tests).
  • Live verification in the dev app: re-exported both fixtures, opened in Word.
    • Active: numbering.xml byte-identical to input after pretty-print (8 / 8 preserved).
    • Tentative: same — numbering.xml byte-identical (2 / 1 preserved).
  • No "Word found unreadable content" prompts on open.

Verified diffs on the customer fixtures

Variant input before fix after fix
active — <w:abstractNum> 8 1 8
active — <w:num> 8 1 8
tentative — <w:abstractNum> 2 0 2
tentative — <w:num> 1 0 1

What about the lists.delete flow that originally motivated the filter?

If lists.delete needs to remove the definition for the list it deletes, that should happen at the operation site — where the deletion intent is known — not as an opportunistic GC pass at every export. There's no existing test in the repo that gates this behavior end-to-end against the document-api; adding one is out of scope for this fix.

…2911)

#exportNumberingFile filtered out every w:num whose numId wasn't referenced
from the exported document parts (including headers, footers, and footnotes).
Word's tentative numbering, where a document carries definitions for lists
the user hasn't applied yet, was therefore silently wiped: the active-numbering
fixture lost 7 of 8 definitions and the tentative fixture lost them all.

The filter was introduced for the lists.delete document-api operation, but it
couldn't distinguish "user just deleted a list in this session" from
"definition was always unused in the source file" — both arrived at the export
with no referencing paragraph and both were dropped.

Word tolerates unused definitions, so the safe default on export is to emit
every abstractNum and num the importer captured. The strip-orphaned helper is
removed entirely; the inline write in #exportNumberingFile is now four lines.

Verified: both fixtures round-trip byte-identical (after pretty-print) at the
numbering.xml level. New integration test covers both the active and tentative
variants.
@tupizz tupizz requested a review from a team as a code owner May 11, 2026 15:14
@linear
Copy link
Copy Markdown

linear Bot commented May 11, 2026

SD-2911

@codecov-commenter
Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@tupizz tupizz self-assigned this May 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants