diff --git a/packages/layout/src/steps/resolvePagination.js b/packages/layout/src/steps/resolvePagination.js
index c4a84903e..936ed3759 100644
--- a/packages/layout/src/steps/resolvePagination.js
+++ b/packages/layout/src/steps/resolvePagination.js
@@ -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';
@@ -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;
@@ -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,
@@ -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(
@@ -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 }),
);
@@ -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,
@@ -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 = {
@@ -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];
@@ -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);
diff --git a/packages/layout/tests/steps/resolvePagination.test.js b/packages/layout/tests/steps/resolvePagination.test.js
index 8f76e178c..5ebaa2543 100644
--- a/packages/layout/tests/steps/resolvePagination.test.js
+++ b/packages/layout/tests/steps/resolvePagination.test.js
@@ -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: [
@@ -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];
@@ -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: [
@@ -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];
@@ -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: [
@@ -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];
@@ -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: [
@@ -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: [
@@ -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];
diff --git a/packages/renderer/tests/dynamicContent.test.js b/packages/renderer/tests/dynamicContent.test.js
new file mode 100644
index 000000000..9d29aeef2
--- /dev/null
+++ b/packages/renderer/tests/dynamicContent.test.js
@@ -0,0 +1,26 @@
+import { Document, Image, Page, View } from '..';
+import renderToImage from './renderComponent';
+
+const mount = async children => {
+ const image = await renderToImage(
+
+ {children}
+ ,
+ );
+
+ 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(
+ }
+ />,
+ );
+
+ expect(image).toMatchImageSnapshot();
+ }, 10000);
+});
diff --git a/packages/renderer/tests/snapshots/dynamic-content-test-js-dynamic-content-should-render-an-image-1-snap.png b/packages/renderer/tests/snapshots/dynamic-content-test-js-dynamic-content-should-render-an-image-1-snap.png
new file mode 100644
index 000000000..dbb477f1f
Binary files /dev/null and b/packages/renderer/tests/snapshots/dynamic-content-test-js-dynamic-content-should-render-an-image-1-snap.png differ