From ec55b627a56501876b122e72ac84627fdb6df4e5 Mon Sep 17 00:00:00 2001 From: Josh Fee Date: Thu, 18 Jul 2024 14:56:34 -0400 Subject: [PATCH 1/2] Prevent infinite loop while splitting pages --- .../layout/src/steps/resolvePagination.js | 20 ++++++---- .../tests/steps/resolvePagination.test.js | 40 +++++++++++++++++++ 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/packages/layout/src/steps/resolvePagination.js b/packages/layout/src/steps/resolvePagination.js index 98d6f3135..02b1db19e 100644 --- a/packages/layout/src/steps/resolvePagination.js +++ b/packages/layout/src/steps/resolvePagination.js @@ -100,13 +100,19 @@ const splitNodes = (height, contentArea, nodes) => { // All children are moved to the next page, it doesn't make sense to show the parent on the current page if (child.children.length > 0 && currentChild.children.length === 0) { - const box = Object.assign({}, child.box, { - top: child.box.top - height, - }); - const next = Object.assign({}, child, { box }); - - currentChildren.push(...futureFixedNodes); - nextChildren.push(next, ...futureNodes); + // But if the current page is empty then we can just include the parent on the current page + if (currentChildren.length === 0) { + currentChildren.push(child, ...futureFixedNodes); + nextChildren.push(...futureNodes); + } else { + const box = Object.assign({}, child.box, { + top: child.box.top - height, + }); + const next = Object.assign({}, child, { box }); + + currentChildren.push(...futureFixedNodes); + nextChildren.push(next, ...futureNodes); + } break; } diff --git a/packages/layout/tests/steps/resolvePagination.test.js b/packages/layout/tests/steps/resolvePagination.test.js index f84ba7215..a71d077e1 100644 --- a/packages/layout/tests/steps/resolvePagination.test.js +++ b/packages/layout/tests/steps/resolvePagination.test.js @@ -249,4 +249,44 @@ describe('pagination step', () => { expect(page2.children.length).toBe(1); expect(page2.children[0].box.height).toBe(40); }); + + test('should not infinitely loop when splitting pages', async () => { + const yoga = await loadYoga(); + + const root = { + type: 'DOCUMENT', + yoga, + children: [ + { + type: 'PAGE', + box: {}, + style: { + height: 400, + }, + children: [ + { + type: 'VIEW', + box: {}, + style: { height: 401 }, + children: [ + { + type: 'VIEW', + box: {}, + style: { + height: 400, + }, + props: { wrap: false, break: true }, + }, + ], + }, + ], + }, + ], + }; + + calcLayout(root); + + // If calcLayout returns then we did not hit an infinite loop + expect(true).toBe(true); + }); }); From 36f1e7511ef9acce2303b5bc31d25382d3b3e92b Mon Sep 17 00:00:00 2001 From: Diego Muracciole Date: Sun, 22 Sep 2024 16:13:49 +0200 Subject: [PATCH 2/2] chore: add changeset --- .changeset/fair-rocks-leave.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/fair-rocks-leave.md diff --git a/.changeset/fair-rocks-leave.md b/.changeset/fair-rocks-leave.md new file mode 100644 index 000000000..e52296079 --- /dev/null +++ b/.changeset/fair-rocks-leave.md @@ -0,0 +1,5 @@ +--- +"@react-pdf/layout": patch +--- + +fix: prevent infinite loop while splitting pages