Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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, i) => {
renderNode(ctx, page, options);
addNodeBookmark(ctx, page, i, 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;
75 changes: 75 additions & 0 deletions packages/render/tests/operations/bookmarks.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
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 };
// eslint-disable-next-line prettier/prettier
const makeLine = (pageNumber) => {
const line = {
ascent: 16.2,
box,
descent: 0,
height: 100,
overflowLeft: 0,
overflowRight: 0,
runs: [],
string: `Page ${pageNumber}`,
decorationLines: [],
};
return line;
// eslint-disable-next-line prettier/prettier
};
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()).toEqual(BOOKMARK1);
expect(children[1].outlineData.Title.toString()).toEqual(BOOKMARK2);
expect(children[2].outlineData.Title.toString()).toEqual(BOOKMARK3);
});
});