Commit 797b0b4
feat(layout): enable odd/even header-footer support (w:evenAndOddHeaders) (#2804)
* feat(layout): enable odd/even header-footer support (w:evenAndOddHeaders)
Thread alternateHeaders from document settings through the layout
engine so the paginator selects the correct header/footer variant
per page. Fixes margin calculation for documents with different
odd and even page headers.
Also fixes getVariantTypeForPage to use document page number
(not section-relative) for even/odd selection, matching the
rendering side (headerFooterUtils.ts).
Closes #2803
* fix: address PR review — type guard + multi-section/footer/fallback tests
- Guard alternateHeaders behind isSemanticFlow check to match
ResolvedLayoutOptions type (paginated-only field)
- Add multi-section test: section 2 starting on page 4 (even by document
number, verifies the documentPageNumber fix)
- Add footer test: even/odd footer heights with alternateHeaders
- Add default-only fallback test: only default header defined
* test(layout): strengthen alternateHeaders tests and thread flag via resolver
Review round 2 follow-ups on PR #2804.
Tests
- Footer test now goes through sectionMetadata.footerRefs + footerContentHeightsByRId
(the real path) and asserts page.margins.bottom. The old test only checked body-top
y, which is footer-independent — stubbing getFooterHeightForPage to always return 0
left that assertion passing. Mutation-tested: forcing getVariantTypeForPage to
always return 'default' now breaks it.
- Default-only fallback test now exercises the production path (headerRefs.default +
per-rId heights) and asserts the correct outcome (y ~= 90 via the step-3 default
fallback). Old assertion of y ~= 50 codified a code path that never runs in
production because document imports always supply section refs. Mutation-tested:
removing the step-3 fallback breaks this test.
- New combined test: multi-section + titlePg + alternateHeaders, where section 2
has titlePg=true and starts on an even document page. Guards both the titlePg
interaction across a section boundary AND the documentPageNumber (not
sectionPageNumber) rule on pages 5 and 6. Mutation-tested: reverting to
sectionPageNumber breaks this test alongside the original multi-section case.
Layout engine
- getVariantTypeForPage now takes a named-params object. Two adjacent `number`
params (sectionPageNumber, documentPageNumber) are swap-vulnerable.
- JSDoc on LayoutOptions.alternateHeaders cross-references
getHeaderFooterTypeForSection in layout-bridge — the two sides must agree on
variant selection and the pointer helps future maintainers keep them in sync.
PresentationEditor
- alternateHeaders is now populated inside #resolveLayoutOptions, alongside the
other paginated-only fields (columns, sectionMetadata). The render-site spread
collapses back to the single ternary it was before, and the
`as EditorWithConverter` cast there disappears. types.ts didn't need changes —
the field was already declared on the paginated variant of ResolvedLayoutOptions
but unpopulated; it's now legitimately set by the resolver.
* test(alternate-headers): add unit + integration + behavior coverage
Follow-up to round 2 review. Closes the three test gaps flagged in the
gap analysis:
Unit (PresentationEditor threading)
- 3 tests in PresentationEditor.test.ts assert that
`converter.pageStyles.alternateHeaders` is forwarded to the layout
options that reach `incrementalLayout`. Covers true, unset, and
falsy-non-boolean cases. A refactor that drops the threading no
longer passes silently.
Unit (docxImporter)
- Export `isAlternatingHeadersOddEven` and add 4 tests covering the
import-side signal: `<w:evenAndOddHeaders/>` present, absent,
missing settings.xml, empty settings. Pins the contract between
OOXML settings and `pageStyles.alternateHeaders`.
Behavior (Playwright)
- `tests/headers/odd-even-header-variants.spec.ts` loads
`h_f-normal-odd-even.docx` (already in the corpus) and asserts:
- pages 1/3 render the default/odd header text, pages 2/4 render
the even header text
- page 1 and page 3 use the same `data-block-id` (same rId) but
differ from page 2 — catches regressions that produce the right
text from the wrong rId
- footers follow the same alternation
The existing layout/visual corpus already includes
`h_f-normal-odd-even*.docx` and `sd-2234-even-odd-headers.docx`, so
rendering regressions show up in `pnpm test:layout` and
`pnpm test:visual` without any additional wiring.
---------
Co-authored-by: Caio Pizzol <caio@harbourshare.com>
Co-authored-by: Caio Pizzol <97641911+caio-pizzol@users.noreply.github.com>1 parent 1f827f4 commit 797b0b4
8 files changed
Lines changed: 535 additions & 15 deletions
File tree
- packages
- layout-engine/layout-engine/src
- super-editor/src/editors/v1/core
- presentation-editor
- tests
- super-converter/v2/importer
- tests/behavior/tests/headers
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5587 | 5587 | | |
5588 | 5588 | | |
5589 | 5589 | | |
| 5590 | + | |
| 5591 | + | |
| 5592 | + | |
| 5593 | + | |
| 5594 | + | |
| 5595 | + | |
| 5596 | + | |
| 5597 | + | |
| 5598 | + | |
| 5599 | + | |
| 5600 | + | |
| 5601 | + | |
| 5602 | + | |
| 5603 | + | |
| 5604 | + | |
| 5605 | + | |
| 5606 | + | |
| 5607 | + | |
| 5608 | + | |
| 5609 | + | |
| 5610 | + | |
| 5611 | + | |
| 5612 | + | |
| 5613 | + | |
| 5614 | + | |
| 5615 | + | |
| 5616 | + | |
| 5617 | + | |
| 5618 | + | |
| 5619 | + | |
| 5620 | + | |
| 5621 | + | |
| 5622 | + | |
| 5623 | + | |
| 5624 | + | |
| 5625 | + | |
| 5626 | + | |
| 5627 | + | |
| 5628 | + | |
| 5629 | + | |
| 5630 | + | |
| 5631 | + | |
| 5632 | + | |
| 5633 | + | |
| 5634 | + | |
| 5635 | + | |
| 5636 | + | |
| 5637 | + | |
| 5638 | + | |
| 5639 | + | |
| 5640 | + | |
| 5641 | + | |
| 5642 | + | |
| 5643 | + | |
| 5644 | + | |
| 5645 | + | |
| 5646 | + | |
| 5647 | + | |
| 5648 | + | |
| 5649 | + | |
| 5650 | + | |
| 5651 | + | |
| 5652 | + | |
| 5653 | + | |
| 5654 | + | |
| 5655 | + | |
| 5656 | + | |
| 5657 | + | |
| 5658 | + | |
| 5659 | + | |
| 5660 | + | |
| 5661 | + | |
| 5662 | + | |
| 5663 | + | |
| 5664 | + | |
| 5665 | + | |
| 5666 | + | |
| 5667 | + | |
| 5668 | + | |
| 5669 | + | |
| 5670 | + | |
| 5671 | + | |
| 5672 | + | |
| 5673 | + | |
| 5674 | + | |
| 5675 | + | |
| 5676 | + | |
| 5677 | + | |
| 5678 | + | |
| 5679 | + | |
| 5680 | + | |
| 5681 | + | |
| 5682 | + | |
| 5683 | + | |
| 5684 | + | |
| 5685 | + | |
| 5686 | + | |
| 5687 | + | |
| 5688 | + | |
| 5689 | + | |
| 5690 | + | |
| 5691 | + | |
| 5692 | + | |
| 5693 | + | |
| 5694 | + | |
| 5695 | + | |
| 5696 | + | |
| 5697 | + | |
| 5698 | + | |
| 5699 | + | |
| 5700 | + | |
| 5701 | + | |
| 5702 | + | |
| 5703 | + | |
| 5704 | + | |
| 5705 | + | |
| 5706 | + | |
| 5707 | + | |
| 5708 | + | |
| 5709 | + | |
| 5710 | + | |
| 5711 | + | |
| 5712 | + | |
| 5713 | + | |
| 5714 | + | |
| 5715 | + | |
| 5716 | + | |
| 5717 | + | |
| 5718 | + | |
| 5719 | + | |
| 5720 | + | |
| 5721 | + | |
| 5722 | + | |
| 5723 | + | |
| 5724 | + | |
| 5725 | + | |
| 5726 | + | |
| 5727 | + | |
| 5728 | + | |
| 5729 | + | |
| 5730 | + | |
| 5731 | + | |
| 5732 | + | |
| 5733 | + | |
| 5734 | + | |
| 5735 | + | |
| 5736 | + | |
| 5737 | + | |
| 5738 | + | |
| 5739 | + | |
| 5740 | + | |
| 5741 | + | |
| 5742 | + | |
| 5743 | + | |
| 5744 | + | |
| 5745 | + | |
| 5746 | + | |
| 5747 | + | |
| 5748 | + | |
| 5749 | + | |
| 5750 | + | |
| 5751 | + | |
| 5752 | + | |
| 5753 | + | |
| 5754 | + | |
| 5755 | + | |
| 5756 | + | |
| 5757 | + | |
| 5758 | + | |
| 5759 | + | |
| 5760 | + | |
| 5761 | + | |
| 5762 | + | |
| 5763 | + | |
| 5764 | + | |
| 5765 | + | |
| 5766 | + | |
| 5767 | + | |
| 5768 | + | |
| 5769 | + | |
| 5770 | + | |
| 5771 | + | |
| 5772 | + | |
| 5773 | + | |
| 5774 | + | |
| 5775 | + | |
| 5776 | + | |
| 5777 | + | |
| 5778 | + | |
| 5779 | + | |
| 5780 | + | |
| 5781 | + | |
| 5782 | + | |
| 5783 | + | |
| 5784 | + | |
| 5785 | + | |
| 5786 | + | |
| 5787 | + | |
| 5788 | + | |
| 5789 | + | |
| 5790 | + | |
| 5791 | + | |
| 5792 | + | |
| 5793 | + | |
| 5794 | + | |
| 5795 | + | |
| 5796 | + | |
| 5797 | + | |
| 5798 | + | |
| 5799 | + | |
| 5800 | + | |
| 5801 | + | |
| 5802 | + | |
| 5803 | + | |
| 5804 | + | |
| 5805 | + | |
| 5806 | + | |
| 5807 | + | |
| 5808 | + | |
| 5809 | + | |
| 5810 | + | |
| 5811 | + | |
| 5812 | + | |
| 5813 | + | |
| 5814 | + | |
| 5815 | + | |
| 5816 | + | |
| 5817 | + | |
| 5818 | + | |
| 5819 | + | |
| 5820 | + | |
| 5821 | + | |
| 5822 | + | |
| 5823 | + | |
| 5824 | + | |
| 5825 | + | |
| 5826 | + | |
| 5827 | + | |
| 5828 | + | |
| 5829 | + | |
| 5830 | + | |
| 5831 | + | |
| 5832 | + | |
| 5833 | + | |
| 5834 | + | |
| 5835 | + | |
| 5836 | + | |
| 5837 | + | |
| 5838 | + | |
| 5839 | + | |
| 5840 | + | |
| 5841 | + | |
| 5842 | + | |
| 5843 | + | |
| 5844 | + | |
| 5845 | + | |
| 5846 | + | |
| 5847 | + | |
| 5848 | + | |
| 5849 | + | |
| 5850 | + | |
| 5851 | + | |
| 5852 | + | |
| 5853 | + | |
| 5854 | + | |
| 5855 | + | |
| 5856 | + | |
| 5857 | + | |
| 5858 | + | |
| 5859 | + | |
| 5860 | + | |
| 5861 | + | |
| 5862 | + | |
| 5863 | + | |
| 5864 | + | |
| 5865 | + | |
| 5866 | + | |
| 5867 | + | |
| 5868 | + | |
| 5869 | + | |
| 5870 | + | |
| 5871 | + | |
| 5872 | + | |
| 5873 | + | |
| 5874 | + | |
| 5875 | + | |
| 5876 | + | |
| 5877 | + | |
| 5878 | + | |
| 5879 | + | |
| 5880 | + | |
| 5881 | + | |
| 5882 | + | |
| 5883 | + | |
| 5884 | + | |
| 5885 | + | |
| 5886 | + | |
| 5887 | + | |
| 5888 | + | |
| 5889 | + | |
| 5890 | + | |
| 5891 | + | |
| 5892 | + | |
| 5893 | + | |
| 5894 | + | |
| 5895 | + | |
| 5896 | + | |
| 5897 | + | |
| 5898 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
528 | 528 | | |
529 | 529 | | |
530 | 530 | | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
| 534 | + | |
| 535 | + | |
| 536 | + | |
| 537 | + | |
| 538 | + | |
| 539 | + | |
| 540 | + | |
| 541 | + | |
531 | 542 | | |
532 | 543 | | |
533 | 544 | | |
| |||
669 | 680 | | |
670 | 681 | | |
671 | 682 | | |
672 | | - | |
| 683 | + | |
| 684 | + | |
| 685 | + | |
| 686 | + | |
| 687 | + | |
673 | 688 | | |
674 | | - | |
| 689 | + | |
675 | 690 | | |
676 | 691 | | |
677 | | - | |
678 | | - | |
679 | | - | |
680 | | - | |
681 | | - | |
| 692 | + | |
| 693 | + | |
| 694 | + | |
| 695 | + | |
| 696 | + | |
| 697 | + | |
682 | 698 | | |
683 | | - | |
| 699 | + | |
684 | 700 | | |
685 | 701 | | |
686 | | - | |
687 | | - | |
688 | | - | |
| 702 | + | |
| 703 | + | |
| 704 | + | |
| 705 | + | |
689 | 706 | | |
690 | 707 | | |
691 | 708 | | |
| |||
1295 | 1312 | | |
1296 | 1313 | | |
1297 | 1314 | | |
1298 | | - | |
1299 | | - | |
| 1315 | + | |
1300 | 1316 | | |
1301 | 1317 | | |
1302 | | - | |
| 1318 | + | |
| 1319 | + | |
| 1320 | + | |
| 1321 | + | |
| 1322 | + | |
| 1323 | + | |
1303 | 1324 | | |
1304 | 1325 | | |
1305 | 1326 | | |
| |||
0 commit comments