Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions packages/render/src/index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import renderNode from './primitives/renderNode';
import addBookmarks from './operations/addBookmarks';
import addNodeBookmark from './operations/addNodeBookmark';

const render = (ctx, doc) => {
const pages = doc.children || [];
const options = { imageCache: new Map() };

pages.forEach((page) => renderNode(ctx, page, options));
const registry = {};

addBookmarks(ctx, doc);
pages.forEach((page, index) => {
renderNode(ctx, page, options);
addNodeBookmark(ctx, page, index, registry);
});

ctx.end();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ const addNodeBookmark = (ctx, node, pageNumber, registry) => {
zoom,
fit,
});

registry[bookmark.ref] = instance;
}

Expand All @@ -25,14 +24,4 @@ const addNodeBookmark = (ctx, node, pageNumber, registry) => {
);
};

const addBookmarks = (ctx, root) => {
const registry = {};

const pages = root.children || [];

pages.forEach((page, i) => {
addNodeBookmark(ctx, page, i, registry);
});
};

export default addBookmarks;
export default addNodeBookmark;
73 changes: 73 additions & 0 deletions packages/render/tests/operations/bookmarks.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { describe, expect, test } from 'vitest';

import * as P from '@react-pdf/primitives';

import PDFDocument from '../../../pdfkit/lib/pdfkit';
import render from '../../src/index';

/**
* Original issue for this test was that all bookmarks incorrectly
* pointed to the last page rather than the page for which they were created.
*/
describe('operations bookmarks', () => {
test('should create 3 pages with unique bookmarks', () => {
const ctx = new PDFDocument({ autoFirstPage: false });
const BOOKMARK1 = 'Bookmark 1';
const BOOKMARK2 = 'Bookmark 2';
const BOOKMARK3 = 'Bookmark 3';
const p1 = { bookmark: { ref: 1, title: BOOKMARK1 } };
const p2 = { bookmark: { ref: 2, title: BOOKMARK2 } };
const p3 = { bookmark: { ref: 3, title: BOOKMARK3 } };
const box = { left: 0, top: 0, width: 100, height: 100, x: 0, y: 0 };
const makeLine = (pageNumber) => {
const line = {
ascent: 16.2,
box,
descent: 0,
height: 100,
overflowLeft: 0,
overflowRight: 0,
runs: [],
string: `Page ${pageNumber}`,
decorationLines: [],
};
return line;
};
const doc = {
type: P.Document,
children: [
{
children: [{ lines: [makeLine(1)], box, props: p1, type: P.Text }],
box,
type: P.Page,
},
{
children: [{ lines: [makeLine(2)], box, props: p2, type: P.Text }],
box,
type: P.Page,
},
{
children: [{ lines: [makeLine(3)], box, props: p3, type: P.Text }],
box,
type: P.Page,
},
],
};

render(ctx, doc);

const kids = ctx._root.data.Pages.data.Kids;
expect(kids).toHaveLength(3);
// We expect unique ids
expect(
kids[0].id !== kids[1].id &&
kids[0].id !== kids[2].id &&
kids[1].id !== kids[2].id,
).toBe(true);
const children = ctx._root.document.outline.children;
expect(children).toHaveLength(3);
expect(children[0].outlineData.Title.toString()).toBe(BOOKMARK1);
expect(children[1].outlineData.Title.toString()).toBe(BOOKMARK2);
expect(children[2].outlineData.Title.toString()).toBe(BOOKMARK3);
});
});