fix(pdf): stop a flowing day stranding its header at the foot of a page

Keeping a stay whole moved its cards to the next sheet, and the header bar
stayed behind on the old one — empty, above a stretch of white, with the
same day printed again overhead. The repeat itself is the continuation
marker from #1471; what was wrong is that there was nothing left to
continue from.

break-after on the thead and break-before on the tbody are both ignored by
Chromium here, measured rather than assumed. Holding the whole day together
is what works: a day that fits moves as one, and a day too long for a page
still breaks and still repeats its header. Scoped to the flowing layout,
since a day that starts its own page can never strand one.
This commit is contained in:
Maurice
2026-07-29 20:30:20 +02:00
committed by Maurice
parent eb817dea65
commit 129f952db4
2 changed files with 25 additions and 0 deletions
+16
View File
@@ -1014,4 +1014,20 @@ describe('page breaks between days (#1292)', () => {
const rule = html.slice(html.indexOf('.day-accommodation {'))
expect(rule.slice(0, rule.indexOf('}'))).toContain('break-inside: avoid')
})
// Measured against Chromium: with the days flowing, a header bar could be left
// at the foot of a sheet while its content moved on, and the repeat from #1471
// then read as the same day printed twice. break-after on the thead and
// break-before on the tbody are both ignored; holding the day together is what
// works, and a day too long for one page still breaks and still repeats.
it('FE-PDF-BREAK-008: a flowing day is held together so its header is never stranded', async () => {
localStorage.setItem('trek_pdf_page_break_per_day', '0')
await downloadTripPDF(twoDays)
const html = getIframe()!.srcdoc
expect(html).toContain('.pdf-flow .day-section { break-inside: avoid; page-break-inside: avoid; }')
// Scoped: a day that starts its own page cannot strand a header.
const at = html.indexOf('.day-section { break-inside: avoid')
expect(html.slice(at - 10, at)).toContain('.pdf-flow ')
})
})
+9
View File
@@ -542,6 +542,15 @@ export async function downloadTripPDF({ trip, days, places, assignments = {}, ca
.day-break { page-break-before: always; }
.pdf-flow .day-break { page-break-before: auto; }
.pdf-flow .day-section + .day-section { margin-top: 18px; }
/* Hold a flowing day together. Without this the header bar can be placed at the
foot of a sheet while its content moves to the next one, which then repeats
the header (#1471) and reads as the same day printed twice. A day too long
for one page still breaks and still repeats its header — the engine only
honours this where it can. Days that start a page of their own cannot strand
a header, so it is scoped to the flowing layout.
Measured, not assumed: break-after on the thead and break-before on the tbody
are both ignored by Chromium here. */
.pdf-flow .day-section { break-inside: avoid; page-break-inside: avoid; }
.day-section { width: 100%; border-collapse: collapse; table-layout: fixed; }
.day-header-bar {
background: #0f172a; padding: 11px 28px;