Skip to content

Commit dbeb0b5

Browse files
authored
Merge pull request #1 from mskec/issue-2064/image-inside-dynamic-content
fix: fetch assets inside dynamic content (diegomura#1369, diegomura#1587, diegomura#1630, diegomura#1936,…
2 parents a37d927 + b1fce3b commit dbeb0b5

File tree

4 files changed

+72
-36
lines changed

4 files changed

+72
-36
lines changed

packages/layout/src/steps/resolvePagination.js

+36-25
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/* eslint-disable prefer-destructuring */
33

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

77
import isFixed from '../node/isFixed';
88
import splitText from '../text/splitText';
@@ -15,6 +15,7 @@ import shouldNodeBreak from '../node/shouldBreak';
1515
import resolveTextLayout from './resolveTextLayout';
1616
import resolveInheritance from './resolveInheritance';
1717
import { resolvePageDimensions } from './resolveDimensions';
18+
import resolveAssets from './resolveAssets';
1819

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

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

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

33-
const relayoutPage = compose(
34+
const relayoutPage = asyncCompose(
35+
resolveAssets,
3436
resolveTextLayout,
3537
resolveInheritance,
3638
resolvePageDimensions,
@@ -172,19 +174,20 @@ const resolveDynamicNodes = (props, node) => {
172174
return Object.assign({}, node, { box, lines, children });
173175
};
174176

175-
const resolveDynamicPage = (props, page, fontStore) => {
177+
const resolveDynamicPage = async (props, page, fontStore) => {
176178
if (shouldResolveDynamicNodes(page)) {
177179
const resolvedPage = resolveDynamicNodes(props, page);
178-
return relayoutPage(resolvedPage, fontStore);
180+
const relayoutedPage = await relayoutPage(resolvedPage, fontStore);
181+
return relayoutedPage;
179182
}
180183

181184
return page;
182185
};
183186

184-
const splitPage = (page, pageNumber, fontStore) => {
187+
const splitPage = async (page, pageNumber, fontStore) => {
185188
const wrapArea = getWrapArea(page);
186189
const contentArea = getContentArea(page);
187-
const dynamicPage = resolveDynamicPage({ pageNumber }, page, fontStore);
190+
const dynamicPage = await resolveDynamicPage({ pageNumber }, page, fontStore);
188191
const height = page.style.height;
189192

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

196-
const relayout = node => relayoutPage(node, fontStore);
199+
const relayout = async node => relayoutPage(node, fontStore);
197200

198201
const currentBox = { ...page.box, height };
199-
const currentPage = relayout(
202+
const currentPage = await relayout(
200203
Object.assign({}, page, { box: currentBox, children: currentChilds }),
201204
);
202205

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

209-
const nextPage = relayout(
212+
const nextPage = await relayout(
210213
Object.assign({}, page, {
211214
props: nextProps,
212215
box: nextBox,
@@ -217,7 +220,7 @@ const splitPage = (page, pageNumber, fontStore) => {
217220
return [currentPage, nextPage];
218221
};
219222

220-
const resolvePageIndices = (fontStore, page, pageNumber, pages) => {
223+
const resolvePageIndices = async (fontStore, page, pageNumber, pages) => {
221224
const totalPages = pages.length;
222225

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

245-
const paginate = (page, pageNumber, fontStore) => {
248+
const paginate = async (page, pageNumber, fontStore) => {
246249
if (!page) return [];
247250

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

250-
let splittedPage = splitPage(page, pageNumber, fontStore);
253+
let splittedPage = await splitPage(page, pageNumber, fontStore);
251254

252255
const pages = [splittedPage[0]];
253256
let nextPage = splittedPage[1];
254257

255258
while (nextPage !== null) {
256-
splittedPage = splitPage(nextPage, pageNumber + pages.length, fontStore);
259+
// eslint-disable-next-line no-await-in-loop
260+
splittedPage = await splitPage(
261+
nextPage,
262+
pageNumber + pages.length,
263+
fontStore,
264+
);
257265

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

265273
/**
266-
* Performs pagination. This is the step responsible of breaking the whole document
267-
* into pages following pagiation rules, such as `fixed`, `break` and dynamic nodes.
274+
* Performs pagination. This is the step responsible for breaking the whole document
275+
* into pages following pagination rules, such as `fixed`, `break` and dynamic nodes.
268276
*
269277
* @param {Object} node
270278
* @param {Object} fontStore font store
271279
* @returns {Object} layout node
272280
*/
273-
const resolvePagination = (doc, fontStore) => {
281+
const resolvePagination = async (doc, fontStore) => {
274282
let pages = [];
275283
let pageNumber = 1;
276284

277-
for (let i = 0; i < doc.children.length; i += 1) {
278-
const page = doc.children[i];
279-
let subpages = paginate(page, pageNumber, fontStore);
285+
await Promise.all(
286+
doc.children.map(async page => {
287+
let subpages = await paginate(page, pageNumber, fontStore);
280288

281-
subpages = assocSubPageData(subpages);
282-
pageNumber += subpages.length;
283-
pages = pages.concat(subpages);
284-
}
289+
subpages = assocSubPageData(subpages);
290+
pageNumber += subpages.length;
291+
pages.push(...subpages);
292+
}),
293+
);
285294

286-
pages = pages.map((...args) =>
287-
dissocSubPageData(resolvePageIndices(fontStore, ...args)),
295+
pages = await Promise.all(
296+
pages.map(async (...args) =>
297+
dissocSubPageData(await resolvePageIndices(fontStore, ...args)),
298+
),
288299
);
289300

290301
return assingChildren(pages, doc);

packages/layout/tests/steps/resolvePagination.test.js

+10-11
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import resolveDimensions from '../../src/steps/resolveDimensions';
55
const calcLayout = node => resolvePagination(resolveDimensions(node));
66

77
describe('pagination step', () => {
8-
test('should stretch absolute block to full page size', () => {
8+
test('should stretch absolute block to full page size', async () => {
99
const root = {
1010
type: 'DOCUMENT',
1111
children: [
@@ -46,7 +46,7 @@ describe('pagination step', () => {
4646
],
4747
};
4848

49-
const layout = calcLayout(root);
49+
const layout = await calcLayout(root);
5050

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

58-
test('should force new height for split nodes', () => {
58+
test('should force new height for split nodes', async () => {
5959
const root = {
6060
type: 'DOCUMENT',
6161
children: [
@@ -93,7 +93,7 @@ describe('pagination step', () => {
9393
],
9494
};
9595

96-
const layout = calcLayout(root);
96+
const layout = await calcLayout(root);
9797

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

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

130-
const layout = calcLayout(root);
130+
const layout = await calcLayout(root);
131131

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

141-
test('should not wrap page with false wrap prop', () => {
141+
test('should not wrap page with false wrap prop', async () => {
142142
const root = {
143143
type: 'DOCUMENT',
144144
children: [
@@ -165,12 +165,12 @@ describe('pagination step', () => {
165165
],
166166
};
167167

168-
const layout = calcLayout(root);
168+
const layout = await calcLayout(root);
169169

170170
expect(layout.children.length).toBe(1);
171171
});
172172

173-
test('should break on a container whose children can not fit on a page', () => {
173+
test('should break on a container whose children can not fit on a page', async () => {
174174
const root = {
175175
type: 'DOCUMENT',
176176
children: [
@@ -219,8 +219,7 @@ describe('pagination step', () => {
219219
],
220220
};
221221

222-
const layout = calcLayout(root);
223-
console.log(layout.children[0].children);
222+
const layout = await calcLayout(root);
224223

225224
const page1 = layout.children[0];
226225
const page2 = layout.children[1];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { Document, Image, Page, View } from '..';
2+
import renderToImage from './renderComponent';
3+
4+
const mount = async children => {
5+
const image = await renderToImage(
6+
<Document>
7+
<Page size={[244, 280]}>{children}</Page>
8+
</Document>,
9+
);
10+
11+
return image;
12+
};
13+
14+
describe('dynamic content', () => {
15+
test('should render an image', async () => {
16+
const url =
17+
'https://user-images.githubusercontent.com/5600341/27505816-c8bc37aa-587f-11e7-9a86-08a2d081a8b9.png';
18+
const image = await mount(
19+
<View
20+
render={() => <Image src={url} style={{ width: 244, height: 280 }} />}
21+
/>,
22+
);
23+
24+
expect(image).toMatchImageSnapshot();
25+
}, 10000);
26+
});

0 commit comments

Comments
 (0)