1111use Dompdf \Dompdf ;
1212use Dompdf \Helpers ;
1313use Dompdf \Frame ;
14+ use Dompdf \FrameDecorator \Table as TableFrameDecorator ;
15+ use Dompdf \FrameDecorator \TableRow as TableRowFrameDecorator ;
1416use Dompdf \Renderer ;
1517
1618/**
@@ -192,7 +194,6 @@ function check_forced_page_break(Frame $frame)
192194 }
193195
194196 if (in_array ($ style ->page_break_before , $ page_breaks )) {
195-
196197 // Prevent cascading splits
197198 $ frame ->split (null , true );
198199 // We have to grab the style again here because split() resets
@@ -277,7 +278,6 @@ function check_forced_page_break(Frame $frame)
277278 */
278279 protected function _page_break_allowed (Frame $ frame )
279280 {
280-
281281 $ block_types = array ("block " , "list-item " , "table " , "-dompdf-image " );
282282 Helpers::dompdf_debug ("page-break " , "_page_break_allowed( " . $ frame ->get_node ()->nodeName . ") " );
283283 $ display = $ frame ->get_style ()->display ;
@@ -399,13 +399,14 @@ protected function _page_break_allowed(Frame $frame)
399399
400400 return true ;
401401
402- // Table-rows
402+ // Table-rows
403403 } else {
404404 if ($ display === "table-row " ) {
405405 // Simply check if the parent table's page_break_inside property is
406406 // not 'avoid'
407- $ p = Table::find_parent_table ($ frame );
407+ $ table = Table::find_parent_table ($ frame );
408408
409+ $ p = $ table ;
409410 while ($ p ) {
410411 if ($ p ->get_style ()->page_break_inside === "avoid " ) {
411412 Helpers::dompdf_debug ("page-break " , "parent->inside: avoid " );
@@ -416,7 +417,7 @@ protected function _page_break_allowed(Frame $frame)
416417 }
417418
418419 // Avoid breaking after the first row of a table
419- if ($ p && $ p ->get_first_child () === $ frame ) {
420+ if ($ table && $ table -> get_first_child () === $ frame || $ table -> get_first_child () ->get_first_child () === $ frame ) {
420421 Helpers::dompdf_debug ("page-break " , "table: first-row " );
421422
422423 return false ;
@@ -460,30 +461,55 @@ protected function _page_break_allowed(Frame $frame)
460461 */
461462 function check_page_break (Frame $ frame )
462463 {
464+ //FIXME: should not need to do this since we're tracking table status in `$this->_in_table`
465+ $ p = $ frame ;
466+ $ in_table = false ;
467+ while ($ p ) {
468+ if ($ p ->is_table ()) { $ in_table = true ; break ; }
469+ $ p = $ p ->get_parent ();
470+ }
463471 // Do not split if we have already or if the frame was already
464472 // pushed to the next page (prevents infinite loops)
465- if ($ this ->_page_full || $ frame ->_already_pushed ) {
473+ if ($ in_table ) {
474+ if ($ this ->_page_full && $ frame ->_already_pushed ) {
475+ return false ;
476+ }
477+ } elseif ($ this ->_page_full || $ frame ->_already_pushed ) {
478+ return false ;
479+ }
480+
481+ //FIXME: work-around for infinite loop due to tables
482+ if ($ in_table && $ frame ->_already_pushed ) {
466483 return false ;
467484 }
485+ $ p = $ frame ;
486+ do {
487+ $ display = $ p ->get_style ()->display ;
488+ if ($ display == "table-row " ) {
489+ if ($ p ->_already_pushed ) { return false ; }
490+ }
491+ } while ($ p = $ p ->get_parent ());
468492
469493 // If the frame is absolute of fixed it shouldn't break
470494 $ p = $ frame ;
471495 do {
472496 if ($ p ->is_absolute ()) {
473497 return false ;
474498 }
499+
500+ // FIXME If the row is taller than the page and
501+ // if it the first of the page, we don't break
502+ $ display = $ p ->get_style ()->display ;
503+ if ($ display === "table-row "
504+ && !$ p ->get_prev_sibling ()
505+ && $ p ->get_margin_height () > $ this ->get_margin_height ()
506+ ) {
507+ return false ;
508+ }
475509 } while ($ p = $ p ->get_parent ());
476510
477511 $ margin_height = $ frame ->get_margin_height ();
478512
479- // FIXME If the row is taller than the page and
480- // if it the first of the page, we don't break
481- if ($ frame ->get_style ()->display === "table-row " &&
482- !$ frame ->get_prev_sibling () &&
483- $ margin_height > $ this ->get_margin_height ()
484- )
485- return false ;
486-
487513 // Determine the frame's maximum y value
488514 $ max_y = (float )$ frame ->get_position ("y " ) + $ margin_height ;
489515
@@ -578,11 +604,15 @@ function check_page_break(Frame $frame)
578604 // If we are in a table, backtrack to the nearest top-level table row
579605 if ($ this ->_in_table ) {
580606 $ iter = $ frame ;
581- while ($ iter && $ iter ->get_style ()->display !== "table-row " && $ iter ->get_style ()->display !== 'table-row-group ' ) {
607+ while ($ iter && $ iter ->get_style ()->display !== "table-row " && $ iter ->get_style ()->display !== 'table-row-group ' && $ iter -> _already_pushed === false ) {
582608 $ iter = $ iter ->get_parent ();
583609 }
584610
585- $ iter ->split (null , true );
611+ if ($ iter ) {
612+ $ iter ->split (null , true );
613+ } else {
614+ return false ;
615+ }
586616 } else {
587617 $ frame ->split (null , true );
588618 }
0 commit comments