Skip to content

Commit

Permalink
Add support for page-break-before: avoid; and page-break-after: avoid…
Browse files Browse the repository at this point in the history
…; for <tr> elements
  • Loading branch information
carli2 committed Apr 2, 2024
1 parent db09952 commit d99a83b
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ New features
* Watermark text can now be colored using \Mpdf\Watermark DTO. \Mpdf\WatermarkImage DTO for images. (#1876)
* Added support for `psr/http-message` v2 without dropping v1. (@markdorison, @apotek, @greg-1-anderson, @NigelCunningham #1907)
* PHP 8.3 support in mPDF 8.2.1
* Add support for `page-break-before: avoid;` and `page-break-after: avoid;` for tr elements inside tables

mPDF 8.1.x
===========================
Expand Down
8 changes: 7 additions & 1 deletion src/Mpdf.php
Original file line number Diff line number Diff line change
Expand Up @@ -22238,7 +22238,13 @@ function _tableWrite(&$table, $split = false, $startrow = 0, $startcol = 0, $spl
$extra = $table['max_cell_border_width']['B'] / 2;
}

if ($j == $startcol && ((($y + $maxrowheight + $extra ) > ($pagetrigger + 0.001)) || (($this->keepColumns || !$this->ColActive) && !empty($tablefooter) && ($y + $maxrowheight + $tablefooterrowheight + $extra) > $pagetrigger) && ($this->tableLevel == 1 && $i < ($numrows - $table['headernrows']))) && ($y0 > 0 || $x0 > 0) && !$this->InFooter && $this->autoPageBreak) {
// lookahead for pagebreak
$pagebreaklookahead = 1;
while (isset($table['pagebreak-before']) && isset($table['pagebreak-before'][$i + $pagebreaklookahead]) && $table['pagebreak-before'][$i + $pagebreaklookahead] == 'avoid') {
// pagebreak-after is mapped to pagebreak-before on i+1 in Tags/Tr.php
$pagebreaklookahead++;
}
if ($j == $startcol && ((($y + $pagebreaklookahead * $maxrowheight + $extra ) > ($pagetrigger + 0.001)) || (($this->keepColumns || !$this->ColActive) && !empty($tablefooter) && ($y + $maxrowheight + $tablefooterrowheight + $extra) > $pagetrigger) && ($this->tableLevel == 1 && $i < ($numrows - $table['headernrows']))) && ($y0 > 0 || $x0 > 0) && !$this->InFooter && $this->autoPageBreak) {
if (!$skippage) {
$finalSpread = true;
$firstSpread = true;
Expand Down
2 changes: 1 addition & 1 deletion src/Tag/BlockTag.php
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ public function open($attr, &$ahtml, &$ihtml)
/* -- END CSS-PAGE -- */

// If page-box has changed AND/OR PAGE-BREAK-BEFORE
// mPDF 6 (uses $p - preview of properties so blklvl can be imcremented after page-break)
// mPDF 6 (uses $p - preview of properties so blklvl can be incremented after page-break)
if (!$this->mpdf->tableLevel && (($pagesel && (!$this->mpdf->page_box['current'] || $pagesel != $this->mpdf->page_box['current']))
|| (isset($p['PAGE-BREAK-BEFORE']) && $p['PAGE-BREAK-BEFORE']))) {
// mPDF 6 pagebreaktype
Expand Down
11 changes: 11 additions & 0 deletions src/Tag/Tr.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,17 @@ public function open($attr, &$ahtml, &$ihtml)
$this->mpdf->col = -1;
$properties = $this->cssManager->MergeCSS('TABLE', 'TR', $attr);

// write pagebreak markers into row list, so _tableWrite can respect it
if (isset($properties['PAGE-BREAK-BEFORE']) && strtoupper($properties['PAGE-BREAK-BEFORE']) === 'AVOID'
&& !$this->mpdf->ColActive && !$this->mpdf->keep_block_together && !isset($attr['PAGEBREAKAVOIDCHECKED'])) {
$this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['pagebreak-before'][$this->mpdf->row] = 'avoid';
}

if (isset($properties['PAGE-BREAK-AFTER']) && strtoupper($properties['PAGE-BREAK-AFTER']) === 'AVOID'
&& !$this->mpdf->ColActive && !$this->mpdf->keep_block_together && !isset($attr['PAGEBREAKAVOIDCHECKED'])) {
$this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['pagebreak-before'][$this->mpdf->row + 1] = 'avoid';
}

if (!$this->mpdf->simpleTables && (!isset($this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['borders_separate'])
|| !$this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['borders_separate'])) {
if (!empty($properties['BORDER-LEFT'])) {
Expand Down
27 changes: 27 additions & 0 deletions tests/Issues/Issue2004Test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace Issues;

class Issue2004Test extends \Yoast\PHPUnitPolyfills\TestCases\TestCase
{

public function testPdfTableBreakAvoid()
{
// test case: spill items that take about a bit more than half a page, no page-break-avoid would fit them on two pages, with page-break it will be three
$mpdf = new \Mpdf\Mpdf();
$html = '';
$itemsPerTwothirdsPage = 28;
for ($i = 0; $i < 3*$itemsPerTwothirdsPage; $i++) {
if ($i % $itemsPerTwothirdsPage == 0) {
$html .= '<tr style=""><td>groupheader</td></tr>';
} else {
$html .= '<tr style="page-break-before: avoid; background: lime;"><td>content</td></tr>';
}
}
$mpdf->WriteHTML('<html><body><h1>Test</h1>
<table>'.$html.'</table>
</html>');
$this->assertEquals($mpdf->page, 3);
}

}

0 comments on commit d99a83b

Please sign in to comment.