fix: support paragraph bar borders (w:pBdr/w:bar)#2742
fix: support paragraph bar borders (w:pBdr/w:bar)#2742Abdeltoto wants to merge 5 commits intosuperdoc-dev:mainfrom
Conversation
Add bar to ParagraphBorders type in contracts, include it in normalizeParagraphBorders so it flows through the pm-adapter, render it as a left-side vertical line in DomPainter, and include it in the paragraph border hash for grouping parity. Closes superdoc-dev#2282 Made-with: Cursor
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 974ecf97af
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (borders.bar && borders.bar.style !== 'none') { | ||
| setBorderSideStyle(element, 'left', borders.bar); |
There was a problem hiding this comment.
Include bar border in left-side geometry calculations
Applying borders.bar directly to border-left here introduces a rendering mismatch: the layer box is still expanded from borders.left only (computeBorderSpaceExpansion and computeRenderedBorderWidths), so bar.width/bar.space are not reserved. In paragraphs with only w:bar (or with a wider bar than left), the new bar border is drawn into the content box and can overlap text instead of being offset outward like other paragraph borders.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Good catch — fixed in f0162e0. Added a getEffectiveLeftBorder helper and used it in computeBorderSpaceExpansion, computeRenderedBorderWidths and applyParagraphBorderStyles so the layout and paint paths agree on which border occupies the left slot. Bar-only and wider-than-left cases now reserve the right amount of room.
The bar border (OOXML 17.3.1.4) is rendered on the CSS border-left slot when present, overriding w:left. But computeBorderSpaceExpansion and computeRenderedBorderWidths only inspected borders.left, so the layer box was sized without reserving room for bar.width / bar.space. Result: paragraphs with only w:bar (or with a wider bar than left) had the bar drawn into the content box, overlapping text. Introduced a small getEffectiveLeftBorder helper and used it in all three sites (geometry helpers + applyParagraphBorderStyles), so layout and paint stay in sync on which border occupies the left slot. Closes the Codex P1 finding on the PR. Made-with: Cursor
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Word ignores w:bar in every observed configuration, and ECMA-376 §17.3.1.4 explicitly permits ignoring the element. Rendering it on the CSS border-left slot created two regressions vs Word: 1. When a paragraph has both w:left and w:bar (e.g. the spec example in §17.3.1.4), the original w:left border became invisible because bar overrode it on the same slot. Word keeps w:left. 2. Including bar in the painter-dom grouping hash broke between-border grouping for consecutive paragraphs that differed only in w:bar. Word groups such paragraphs normally. This keeps the useful part of the original change — bar flows through the contract and the pm-adapter normalize step for round-trip fidelity — and drops the rendering. Removes getEffectiveLeftBorder and the bar entry in hashParagraphBorders. Adds tests pinning the new behaviour: bar normalizes alongside other sides, bar is excluded from the grouping hash, and two paragraphs that differ only in bar hash identically so they still group.
Adds 3 tests to between-borders.test.ts asserting that applyParagraphBorderStyles: - does not set border-left when only w:bar is set - keeps w:left intact when both w:left and w:bar are present - does not affect top/right/bottom when bar is set Guards against a future refactor accidentally reintroducing bar-on-the-left-slot rendering, which would diverge from Word's output.
|
@Abdeltoto thanks for digging in. Tested in Word: w:bar is never drawn on screen, only kept in the The save-loss concern in #2282 wasn't real either — our converter Closing — the issue itself was a wrong assumption, not your code. |
Pull request was closed
Summary
bartoParagraphBorderstype in contracts so it flows through the data modelbarinnormalizeParagraphBorders()in the pm-adapter so the OOXML property is forwarded to the layout formatapplyParagraphBorderStyles()in DomPainterbarin the paragraph border hash for correct grouping comparisonsFiles changed
contracts/src/index.ts—bar?: ParagraphBorderonParagraphBorderspm-adapter/src/attributes/borders.ts—barin sides arraypainters/dom/src/features/paragraph-borders/border-layer.ts— render bar as CSS left borderpainters/dom/src/paragraph-hash-utils.ts— include bar in hashTest plan
w:pBdr/w:barelementsCloses #2282