Skip to content

Docx Editor

v@eigenpal/[email protected] Bugfix

This release fixes issues for SREs watching stability and regressions.

✓ No known CVEs patched
Read the diff → Tool health → What is this tool? →

✓ No known CVEs patched in this version

Topics

docx docx-editor editor javascript msword next
+7 more
prosemirror react vite vue word word-editor wysiwyg

Summary

AI summary

Fixes selection highlight bleed‑through into headers/footers and improves inline image rendering in table cells.

Full changelog

Patch Changes

  • 5fd14f9: Fix selection highlights bleeding from body into headers and footers. When body and header content shared low PM positions (because each is parsed as a separate ProseMirror document), the DOM-based selection painter matched both trees and drew phantom rectangles on every header and footer. Selection rectangles and caret lookups are now scoped to .layout-page-content.

  • 11abc2d: Four header/footer fidelity follow-ups from the unification refactor:

    • #379RenderContext.positioning controls renderer outer position. renderTableFragment and renderParagraphFragment now pick position: absolute vs position: relative based on context, so HF / textbox callers don't have to flip inline styles after the fact. Removes the post-render style.position flips at three call sites.
    • #380 — Inline-vs-inherited paragraph spacing strip. normalizeHeaderFooterMeasureBlocks now strips spaceBefore / spaceAfter ONLY when they were resolved from a paragraph style (e.g. Normal's default 8pt-after) and not specified inline on the HF paragraph itself. Inline <w:spacing> is preserved per ECMA-376 §17.3.1.33; previously the blanket strip collapsed intentional Word spacing.
    • #381 — Trailing empty paragraph after a table renders at zero height. OOXML requires a trailing block-level element after the last <w:tbl> (the canonical convention is an empty <w:p/>). Word renders that paragraph as a zero-height anchor; we previously added ~14pt of phantom space. The new suppressEmptyParagraphHeight flag on ParagraphAttrs opts the empty paragraph out of the default empty-line height fallback during measurement, while keeping the block itself for click-to-position.
    • #382 — Floating tables (<w:tblpPr>) honor tblpX / tblpY in headers/footers. New resolveHeaderFooterFloatingTablePosition resolves the anchor (page / margin / text) per ECMA-376 §17.4.57 and positions the table at the requested coordinates instead of inline at cursorY. Floating tables don't advance cursorY — surrounding HF blocks flow as if the table weren't there, matching Word's no-wrap behavior.

    normalizeHeaderFooterMeasureBlocks extracted into its own file to enable unit testing.

    Closes #379, #380, #381, #382.

  • 0d3581d: Set package homepage to https://docx-editor.dev/.

  • 4e194d7: Inline images in table cells now have visual breathing room. Previously when an image was taller than the parent paragraph's text line height, the line height was overwritten with the bare image height — so an image alone in a table cell rendered flush with the cell borders. Word treats an inline image as a tall glyph sitting on the text baseline: the image extends above the baseline (full ascent) and the line still reserves the parent font's normal descent + leading below. The line now grows to image-height + text-line-height, giving cells natural padding around image-dominant lines.

  • e12c337: Footnote rendering now routes through the body pipeline (footnoteToProseDoc → toFlowBlocks → measureBlocks), eliminating the shadow stack in footnoteLayout.ts. Footnotes inherit the full block-kind support of the body — paragraph, table, image, textBox, fields. Pre-PR a footnote that contained a table silently dropped the table; same for inline images and PAGE/NUMPAGES fields.

    The fix mirrors the header/footer unification (#356/#357/#358):

    • Parser: parseFootnote and parseEndnote now walk all child blocks (<w:p> + <w:tbl>) in document order. The Footnote.content and Endnote.content types widen from Paragraph[] to (Paragraph | Table)[] to match the body / HeaderFooter / TableCell shape and reflect ECMA-376 §17.11.10.
    • Converter: new footnoteToProseDoc next to headerFooterToProseDoc; takes (Paragraph | Table)[] and produces a PM doc using the same convertParagraphWithTextBoxes / convertTable machinery the body uses.
    • Render adapter: convertFootnoteToContent and buildFootnoteContentMap move from core/layout-bridge/footnoteLayout.ts to react/.../PagedEditor.tsx, parallel to convertHeaderFooterToContent. Footnote-specific presentation (default 8pt font, prepended display number as superscript) lives as a small post-process layer (applyFootnotePresentation).
    • Cleanup: footnoteLayout.ts shrinks from 293 lines to ~80 — only the page-mapping helpers remain (collectFootnoteRefs, mapFootnotesToPages, calculateFootnoteReservedHeights).

    Refs #378.

  • 4aee2e0: Consolidate body-scoped data-pm-start DOM lookups behind findBodyPmSpans / findBodyEmptyRuns / findBodyPmAnchors / findBodyPmAnchor helpers in @eigenpal/docx-core/layout-bridge. Removes the lingering risk that body-only operations (caret resolution, selection painting, scroll restore, image NodeSelection lookup, sidebar anchor positioning, visual-line navigation) accidentally match a header or footer run whose ProseMirror position collides with a body position. Same bug class as #391; this finishes the cleanup started in #406.

  • 274d858: Run-level OOXML attributes that were already parsed and held as ProseMirror marks now reach the painted DOM. The layout-bridge's extractRunFormatting had no case arm for several run-level marks, so the visible renderer silently dropped them while the hidden ProseMirror toDOM rendered them correctly:

    • w:caps (§17.3.2.4) — allCaps — uppercase styling on heading runs is no longer lowercased.
    • w:smallCaps (§17.3.2.32) — smallCaps — small-caps styling reaches the painted DOM.
    • w:position (§17.3.2.24) — baseline shift in half-points now applies as vertical-align.
    • w:w (§17.3.2.43) — horizontal text scale (e.g. 90% tracking on branded templates) applies as a transform: scaleX(...) on an inline-block.
    • w:kern (§17.3.2.18) — kerning threshold gate enables font-kerning: normal when the run's font size is at or above the threshold.

    The four w:position / w:w / w:kern properties share a single PM mark (characterSpacing) with a multi-attribute container; previously only its spacing attribute was bridged, so the other three sat in the model unread.

    Refs #410.

    Also propagates the cosmetic-effect marks (emboss, imprint, textShadow, textOutline, emphasisMark) which were the same defect class — PM marks parsed correctly but the layout-bridge had no case arm, so painted runs lost the effect. Each maps to the same CSS recipe the hidden PM toDOM uses, so editable + painted views stay visually identical.

    Adjacent fix for #392: paragraph runs without an explicit fontFamily mark now inherit the paragraph's resolved style font (from the basedOn → docDefaults cascade) instead of falling back to the painter's hardcoded Calibri stack. Same mechanism applies to fontSize — runs that don't override fall through to the paragraph's resolved default. Closes the per-run side of the rFonts cascade gap from #412.

    Refs #410, #412, fixes #392.

  • 7ff0b6f: Fix style-cascade gaps for runs without an explicit <w:rStyle> and tables without an explicit <w:tblStyle>. Per ECMA-376 §17.7.4.18, both should inherit from the document's default style of the same type (the one marked w:default="1"); pre-PR the default character style was skipped entirely (only docDefaults.rPr reached such runs), and the table-borders cascade was hardcoded to look up styleId "TableGrid" instead of the parsed default flag.

    • StyleResolver.getDefaultCharacterStyle() finds the default by w:default="1" flag (varies by language: "Default Paragraph Font", "FontePadrao", "Fontepargpadro", etc.).
    • resolveRunStyle() now applies the cascade docDefaults.rPr → default character style → explicit character style, matching the cellMargins / paragraph cascade pattern.
    • resolveTextFormatting() no longer short-circuits when a run has no styleId — it always consults the full cascade.
    • Table borders cascade replaces the hardcoded getStyle('TableGrid') with getDefaultTableStyle(), matching the cellMargins cascade and working for documents whose default table style has any styleId.

    5 new unit tests cover the default character style cascade and the getDefaultCharacterStyle() helper. All 449 core tests pass (was 445).

    Refs #412.

  • 4e194d7: Three Word-fidelity fixes surfaced by the Metal Nobre "DC_Template_Descricao_Cargo" template:

    • Inline images no longer overflow their containing line. Browsers compute a non-integer height for <img> from the natural aspect ratio when only width/height attributes are set, which clipped images sized in EMU (e.g. wp:extent 1771650×278918 rounds to 186×29 px but the natural ratio gave 29.29 px). Width/height are now also pinned via inline style, and the inline-image vertical alignment is the default baseline rather than middlemiddle adds half-x-height of parent-font leading and pushed the image past the bottom of any line sized to fit just the image (the typical "image alone in a table cell" case).
    • Explicit w:before is honored on the first paragraph of a page/column. The paginator was unconditionally zeroing spaceBefore whenever the cursor was at topMargin, which dropped Word-authored leading space (e.g. w:before="1800" on the title paragraph). Word 2013+ honors explicit before-spacing at the top of a page; trailing-spacing is already reset on new-page so applying it here does not carry spacing across page breaks.
    • A hard <w:br w:type="page"/> in an otherwise-empty paragraph now forces a page break. paragraphHasPageBreak previously required preceding visible content (relying on renderedPageBreakBefore to cover leading breaks), but that attr is informational only and not honored at layout, so an empty paragraph containing just a page-break run silently dropped the break.

Weekly OSS security release digest.

The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.

No spam, unsubscribe anytime.

Share this release

Track Docx Editor

Get notified when new releases ship.

Sign up free

About Docx Editor

All releases →

Related context

Earlier breaking changes

Beta — feedback welcome: [email protected]