Skip to content

Commit

Permalink
fix: fetch assets inside dynamic content (diegomura#1369, diegomura#1587
Browse files Browse the repository at this point in the history
  • Loading branch information
mskec committed Mar 10, 2023
1 parent 1f09582 commit b1fce3b
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 36 deletions.
61 changes: 36 additions & 25 deletions packages/layout/src/steps/resolvePagination.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/* eslint-disable prefer-destructuring */

import * as P from '@react-pdf/primitives';
import { isNil, omit, compose } from '@react-pdf/fns';
import { isNil, omit, asyncCompose } from '@react-pdf/fns';

import isFixed from '../node/isFixed';
import splitText from '../text/splitText';
Expand All @@ -15,6 +15,7 @@ import shouldNodeBreak from '../node/shouldBreak';
import resolveTextLayout from './resolveTextLayout';
import resolveInheritance from './resolveInheritance';
import { resolvePageDimensions } from './resolveDimensions';
import resolveAssets from './resolveAssets';

const isText = node => node.type === P.Text;

Expand All @@ -30,7 +31,8 @@ const allFixed = nodes => nodes.every(isFixed);

const isDynamic = node => !isNil(node.props?.render);

const relayoutPage = compose(
const relayoutPage = asyncCompose(
resolveAssets,
resolveTextLayout,
resolveInheritance,
resolvePageDimensions,
Expand Down Expand Up @@ -172,19 +174,20 @@ const resolveDynamicNodes = (props, node) => {
return Object.assign({}, node, { box, lines, children });
};

const resolveDynamicPage = (props, page, fontStore) => {
const resolveDynamicPage = async (props, page, fontStore) => {
if (shouldResolveDynamicNodes(page)) {
const resolvedPage = resolveDynamicNodes(props, page);
return relayoutPage(resolvedPage, fontStore);
const relayoutedPage = await relayoutPage(resolvedPage, fontStore);
return relayoutedPage;
}

return page;
};

const splitPage = (page, pageNumber, fontStore) => {
const splitPage = async (page, pageNumber, fontStore) => {
const wrapArea = getWrapArea(page);
const contentArea = getContentArea(page);
const dynamicPage = resolveDynamicPage({ pageNumber }, page, fontStore);
const dynamicPage = await resolveDynamicPage({ pageNumber }, page, fontStore);
const height = page.style.height;

const [currentChilds, nextChilds] = splitNodes(
Expand All @@ -193,10 +196,10 @@ const splitPage = (page, pageNumber, fontStore) => {
dynamicPage.children,
);

const relayout = node => relayoutPage(node, fontStore);
const relayout = async node => relayoutPage(node, fontStore);

const currentBox = { ...page.box, height };
const currentPage = relayout(
const currentPage = await relayout(
Object.assign({}, page, { box: currentBox, children: currentChilds }),
);

Expand All @@ -206,7 +209,7 @@ const splitPage = (page, pageNumber, fontStore) => {
const nextBox = omit('height', page.box);
const nextProps = omit('bookmark', page.props);

const nextPage = relayout(
const nextPage = await relayout(
Object.assign({}, page, {
props: nextProps,
box: nextBox,
Expand All @@ -217,7 +220,7 @@ const splitPage = (page, pageNumber, fontStore) => {
return [currentPage, nextPage];
};

const resolvePageIndices = (fontStore, page, pageNumber, pages) => {
const resolvePageIndices = async (fontStore, page, pageNumber, pages) => {
const totalPages = pages.length;

const props = {
Expand All @@ -242,18 +245,23 @@ const dissocSubPageData = page => {
return omit(['subPageNumber', 'subPageTotalPages'], page);
};

const paginate = (page, pageNumber, fontStore) => {
const paginate = async (page, pageNumber, fontStore) => {
if (!page) return [];

if (page.props?.wrap === false) return [page];

let splittedPage = splitPage(page, pageNumber, fontStore);
let splittedPage = await splitPage(page, pageNumber, fontStore);

const pages = [splittedPage[0]];
let nextPage = splittedPage[1];

while (nextPage !== null) {
splittedPage = splitPage(nextPage, pageNumber + pages.length, fontStore);
// eslint-disable-next-line no-await-in-loop
splittedPage = await splitPage(
nextPage,
pageNumber + pages.length,
fontStore,
);

pages.push(splittedPage[0]);
nextPage = splittedPage[1];
Expand All @@ -263,28 +271,31 @@ const paginate = (page, pageNumber, fontStore) => {
};

/**
* Performs pagination. This is the step responsible of breaking the whole document
* into pages following pagiation rules, such as `fixed`, `break` and dynamic nodes.
* Performs pagination. This is the step responsible for breaking the whole document
* into pages following pagination rules, such as `fixed`, `break` and dynamic nodes.
*
* @param {Object} node
* @param {Object} fontStore font store
* @returns {Object} layout node
*/
const resolvePagination = (doc, fontStore) => {
const resolvePagination = async (doc, fontStore) => {
let pages = [];
let pageNumber = 1;

for (let i = 0; i < doc.children.length; i += 1) {
const page = doc.children[i];
let subpages = paginate(page, pageNumber, fontStore);
await Promise.all(
doc.children.map(async page => {
let subpages = await paginate(page, pageNumber, fontStore);

subpages = assocSubPageData(subpages);
pageNumber += subpages.length;
pages = pages.concat(subpages);
}
subpages = assocSubPageData(subpages);
pageNumber += subpages.length;
pages.push(...subpages);
}),
);

pages = pages.map((...args) =>
dissocSubPageData(resolvePageIndices(fontStore, ...args)),
pages = await Promise.all(
pages.map(async (...args) =>
dissocSubPageData(await resolvePageIndices(fontStore, ...args)),
),
);

return assingChildren(pages, doc);
Expand Down
21 changes: 10 additions & 11 deletions packages/layout/tests/steps/resolvePagination.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import resolveDimensions from '../../src/steps/resolveDimensions';
const calcLayout = node => resolvePagination(resolveDimensions(node));

describe('pagination step', () => {
test('should stretch absolute block to full page size', () => {
test('should stretch absolute block to full page size', async () => {
const root = {
type: 'DOCUMENT',
children: [
Expand Down Expand Up @@ -46,7 +46,7 @@ describe('pagination step', () => {
],
};

const layout = calcLayout(root);
const layout = await calcLayout(root);

const page = layout.children[0];
const view = layout.children[0].children[0];
Expand All @@ -55,7 +55,7 @@ describe('pagination step', () => {
expect(view.box.height).toBe(100);
});

test('should force new height for split nodes', () => {
test('should force new height for split nodes', async () => {
const root = {
type: 'DOCUMENT',
children: [
Expand Down Expand Up @@ -93,7 +93,7 @@ describe('pagination step', () => {
],
};

const layout = calcLayout(root);
const layout = await calcLayout(root);

const view1 = layout.children[0].children[0];
const view2 = layout.children[1].children[0];
Expand All @@ -102,7 +102,7 @@ describe('pagination step', () => {
expect(view2.box.height).not.toBe(60);
});

test('should force new height for split nodes with fixed height', () => {
test('should force new height for split nodes with fixed height', async () => {
const root = {
type: 'DOCUMENT',
children: [
Expand All @@ -127,7 +127,7 @@ describe('pagination step', () => {
],
};

const layout = calcLayout(root);
const layout = await calcLayout(root);

const view1 = layout.children[0].children[0];
const view2 = layout.children[1].children[0];
Expand All @@ -138,7 +138,7 @@ describe('pagination step', () => {
expect(view3.box.height).toBe(10);
});

test('should not wrap page with false wrap prop', () => {
test('should not wrap page with false wrap prop', async () => {
const root = {
type: 'DOCUMENT',
children: [
Expand All @@ -165,12 +165,12 @@ describe('pagination step', () => {
],
};

const layout = calcLayout(root);
const layout = await calcLayout(root);

expect(layout.children.length).toBe(1);
});

test('should break on a container whose children can not fit on a page', () => {
test('should break on a container whose children can not fit on a page', async () => {
const root = {
type: 'DOCUMENT',
children: [
Expand Down Expand Up @@ -219,8 +219,7 @@ describe('pagination step', () => {
],
};

const layout = calcLayout(root);
console.log(layout.children[0].children);
const layout = await calcLayout(root);

const page1 = layout.children[0];
const page2 = layout.children[1];
Expand Down
26 changes: 26 additions & 0 deletions packages/renderer/tests/dynamicContent.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Document, Image, Page, View } from '..';
import renderToImage from './renderComponent';

const mount = async children => {
const image = await renderToImage(
<Document>
<Page size={[244, 280]}>{children}</Page>
</Document>,
);

return image;
};

describe('dynamic content', () => {
test('should render an image', async () => {
const url =
'https://user-images.githubusercontent.com/5600341/27505816-c8bc37aa-587f-11e7-9a86-08a2d081a8b9.png';
const image = await mount(
<View
render={() => <Image src={url} style={{ width: 244, height: 280 }} />}
/>,
);

expect(image).toMatchImageSnapshot();
}, 10000);
});
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit b1fce3b

Please sign in to comment.