Skip to content

fix: declare namespace prefixes that are not in scope when saving (#456) - #458

Merged
baseballyama merged 2 commits into
mainfrom
fix/issue-456-undeclared-prefix
Oct 12, 2026
Merged

baseballyama merged 2 commits into
mainfrom
fix/issue-456-undeclared-prefix

Conversation

@baseballyama

Copy link
Copy Markdown
Member

Summary

Saving no longer writes an element or attribute whose namespace prefix is unbound. Edits such as duplicateSlide and addSlideImage add r:id / r:embed to new elements; when the template declared xmlns:r on individual elements rather than on the part root, the saved part did not parse and the file could not be loaded again.

Motivation

Reported with a reproduction in #456. Namespaces in XML allows declaring a prefix on any ancestor of the element that uses it, and some producers do exactly that. Elements built with elem(...) carry no declarations of their own, so they relied on the part root declaring their prefix.

Closes #456

Changes

  • serializeXml tracks the prefix → URI bindings in scope and, on each element, declares any prefix its name or prefixed attributes use that is unbound or bound to a different URI. Declarations the input already had are written exactly as before, so parsed parts serialize byte-for-byte as before; only hand-built elements that previously produced unbound prefixes change.
  • One prefix needed with two URIs on the same element is an internal bug and now throws instead of writing ambiguous XML.
  • serializeFragment (used for comparison keys) is unchanged.
  • getShapeXmlString now writes the shape as a fragment, keeping its output identical to before; it serialized a subtree as if it were a document root, which with the change above would have added xmlns:a / xmlns:p to the shape's elements.

Testing

  • test/issue-456-undeclared-prefix.test.ts: both reproductions from the issue (duplicate slide with per-element xmlns:r, then save + reload and remove; image on a slide whose root omits xmlns:r), plus serializer unit cases (declare only where needed, redeclare a rebound prefix, default namespace, conflicting binding). All fail on main.
  • Full suite: pnpm typecheck && pnpm lint && pnpm format:check && pnpm test, plus pnpm --filter @office-kit/pptx-editor test and pnpm --filter @office-kit/pptx-dev test.
pnpm vitest run test/issue-456-undeclared-prefix.test.ts

Breaking changes

None

Checklist

  • I have read CLAUDE.md and followed the project's conventions.
  • I have added or updated tests for the change.
  • I have added or updated documentation where user-visible behavior changed.
  • If this is a breaking change, I have added a changeset / CHANGELOG entry and
    flagged it above.
  • I have re-read my own diff and removed dead code, debug prints, and stale
    comments.
  • If I used an LLM to draft this PR, I have verified each change myself, this
    PR represents real work that warrants a maintainer's review, and I am
    willing to defend each line in review.

🤖 Generated with Claude Code

Elements built in code carry no namespace declarations and relied on an
ancestor declaring their prefixes. Namespaces in XML lets a producer
declare a prefix on the element that uses it instead of the part root,
so new `<p:sldId r:id>` / `<a:blip r:embed>` elements could be written
with an unbound prefix and the saved part no longer parsed.

The serializer now tracks the prefixes in scope and declares any that
an element's name or attributes need. Parsed trees are unaffected:
their declarations already cover every prefix. getShapeXmlString keeps
writing the shape as a fragment so its output does not change.

Closes #456

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 12, 2026 14:43
@baseballyama baseballyama added the bug Something isn't working label Oct 12, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@baseballyama
baseballyama merged commit 5de41e0 into main Oct 12, 2026
14 checks passed
@baseballyama
baseballyama deleted the fix/issue-456-undeclared-prefix branch October 12, 2026 15:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: duplicateSlide / addSlideImage write an undeclared r: prefix, so the saved file can't be parsed

2 participants