Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: wojtekmaj/react-pdf
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v6.1.0
Choose a base ref
...
head repository: wojtekmaj/react-pdf
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v6.1.1
Choose a head ref
  • 4 commits
  • 7 files changed
  • 1 contributor

Commits on Nov 17, 2022

  1. Verified

    This commit was signed with the committer’s verified signature.
    MrAlias Tyler Yahn
    Copy the full SHA
    afdc586 View commit details
  2. Verified

    This commit was signed with the committer’s verified signature.
    MrAlias Tyler Yahn
    Copy the full SHA
    7c1c925 View commit details

Commits on Nov 20, 2022

  1. Verified

    This commit was signed with the committer’s verified signature.
    MrAlias Tyler Yahn
    Copy the full SHA
    b8d41fc View commit details
  2. v6.1.1

    wojtekmaj committed Nov 20, 2022

    Verified

    This commit was signed with the committer’s verified signature.
    MrAlias Tyler Yahn
    Copy the full SHA
    2f67369 View commit details
Showing with 196 additions and 130 deletions.
  1. +1 −1 package.json
  2. +4 −4 src/Document.spec.jsx
  3. +4 −4 src/OutlineItem.spec.jsx
  4. +68 −64 src/Page.spec.jsx
  5. +35 −36 src/Page/AnnotationLayer.spec.jsx
  6. +3 −1 src/Page/TextLayer.jsx
  7. +81 −20 src/Page/TextLayer.spec.jsx
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-pdf",
"version": "6.1.0",
"version": "6.1.1",
"description": "Display PDFs in your React app as easily as if they were images.",
"main": "dist/cjs/entry.js",
"module": "dist/esm/entry.js",
8 changes: 4 additions & 4 deletions src/Document.spec.jsx
Original file line number Diff line number Diff line change
@@ -140,11 +140,11 @@ describe('Document', () => {

expect.assertions(1);

return onSourceErrorPromise.then((error) => {
expect(error).toMatchObject(expect.any(Error));
const error = await onSourceErrorPromise;

restoreConsole();
});
expect(error).toMatchObject(expect.any(Error));

restoreConsole();
});

it('replaces a file properly', async () => {
8 changes: 4 additions & 4 deletions src/OutlineItem.spec.jsx
Original file line number Diff line number Diff line change
@@ -40,7 +40,7 @@ describe('OutlineItem', () => {
expect(subitems).toHaveLength(outlineItem.items.length);
});

it('calls onClick with proper arguments when clicked a link', () => {
it('calls onClick with proper arguments when clicked a link', async () => {
const { func: onClick, promise: onClickPromise } = makeAsyncCallback();

render(<OutlineItem item={outlineItem} onClick={onClick} pdf={pdf} />);
@@ -49,9 +49,9 @@ describe('OutlineItem', () => {
const link = getAllByRole(item, 'link')[0];
fireEvent.click(link);

return onClickPromise.then(() => {
expect(onClick).toHaveBeenCalled();
});
await onClickPromise;

expect(onClick).toHaveBeenCalled();
});
});
});
132 changes: 68 additions & 64 deletions src/Page.spec.jsx
Original file line number Diff line number Diff line change
@@ -65,20 +65,21 @@ describe('Page', () => {
await expect(onLoadSuccessPromise).resolves.toMatchObject(desiredLoadedPage);
});

it('returns all desired parameters in onLoadSuccess callback', () => {
it('returns all desired parameters in onLoadSuccess callback', async () => {
const { func: onLoadSuccess, promise: onLoadSuccessPromise } = makeAsyncCallback();

render(<Page onLoadSuccess={onLoadSuccess} pageIndex={0} pdf={pdf} />);

expect.assertions(5);
return onLoadSuccessPromise.then((page) => {
expect(page.width).toBeDefined();
expect(page.height).toBeDefined();
expect(page.originalWidth).toBeDefined();
expect(page.originalHeight).toBeDefined();
// Example of a method that got stripped away in the past
expect(page.getTextContent).toBeInstanceOf(Function);
});

const page = await onLoadSuccessPromise;

expect(page.width).toBeDefined();
expect(page.height).toBeDefined();
expect(page.originalWidth).toBeDefined();
expect(page.originalHeight).toBeDefined();
// Example of a method that got stripped away in the past
expect(page.getTextContent).toBeInstanceOf(Function);
});

it('calls onLoadError when failed to load a page', async () => {
@@ -94,26 +95,28 @@ describe('Page', () => {
restoreConsole();
});

it('loads page when given pageIndex', () => {
it('loads page when given pageIndex', async () => {
const { func: onLoadSuccess, promise: onLoadSuccessPromise } = makeAsyncCallback();

render(<Page onLoadSuccess={onLoadSuccess} pageIndex={0} pdf={pdf} />);

expect.assertions(1);
return onLoadSuccessPromise.then((page) => {
expect(page).toMatchObject(desiredLoadedPage);
});

const page = await onLoadSuccessPromise;

expect(page).toMatchObject(desiredLoadedPage);
});

it('loads page when given pageNumber', () => {
it('loads page when given pageNumber', async () => {
const { func: onLoadSuccess, promise: onLoadSuccessPromise } = makeAsyncCallback();

render(<Page onLoadSuccess={onLoadSuccess} pageNumber={1} pdf={pdf} />);

expect.assertions(1);
return onLoadSuccessPromise.then((page) => {
expect(page).toMatchObject(desiredLoadedPage);
});

const page = await onLoadSuccessPromise;

expect(page).toMatchObject(desiredLoadedPage);
});

it('calls registerPage when loaded a page', async () => {
@@ -277,16 +280,16 @@ describe('Page', () => {
expect(loading).toHaveTextContent('Loading');
});

it('ignores pageIndex when given pageIndex and pageNumber', () => {
it('ignores pageIndex when given pageIndex and pageNumber', async () => {
const { func: onLoadSuccess, promise: onLoadSuccessPromise } = makeAsyncCallback();

render(<Page onLoadSuccess={onLoadSuccess} pageIndex={1} pageNumber={1} pdf={pdf} />);

expect.assertions(1);

return onLoadSuccessPromise.then((page) => {
expect(page).toMatchObject(desiredLoadedPage);
});
const page = await onLoadSuccessPromise;

expect(page).toMatchObject(desiredLoadedPage);
});

it('requests page to be rendered with default rotation when given nothing', async () => {
@@ -326,20 +329,21 @@ describe('Page', () => {
expect(pageCanvas).toBeInTheDocument();
});

it('requests page not to be rendered when given renderMode = "none"', () => {
it('requests page not to be rendered when given renderMode = "none"', async () => {
const { func: onLoadSuccess, promise: onLoadSuccessPromise } = makeAsyncCallback();

const { container } = render(
<Page onLoadSuccess={onLoadSuccess} pageIndex={0} pdf={pdf} renderMode="none" />,
);

expect.assertions(2);
return onLoadSuccessPromise.then(() => {
const pageCanvas = container.querySelector('.react-pdf__Page__canvas');
const pageSVG = container.querySelector('.react-pdf__Page__svg');
expect(pageCanvas).not.toBeInTheDocument();
expect(pageSVG).not.toBeInTheDocument();
});

await onLoadSuccessPromise;

const pageCanvas = container.querySelector('.react-pdf__Page__canvas');
const pageSVG = container.querySelector('.react-pdf__Page__svg');
expect(pageCanvas).not.toBeInTheDocument();
expect(pageSVG).not.toBeInTheDocument();
});

it('requests page to be rendered in canvas mode when given renderMode = "canvas"', async () => {
@@ -577,45 +581,45 @@ describe('Page', () => {
expect(instance.current.childContext.renderForms).toBeFalsy();
});

it('requests page to be rendered at its original size given nothing', () => {
it('requests page to be rendered at its original size given nothing', async () => {
const { func: onLoadSuccess, promise: onLoadSuccessPromise } = makeAsyncCallback();

render(<Page onLoadSuccess={onLoadSuccess} pageIndex={0} pdf={pdf} />);

expect.assertions(1);

return onLoadSuccessPromise.then((page) => {
expect(page.width).toEqual(page.originalWidth);
});
const page = await onLoadSuccessPromise;

expect(page.width).toEqual(page.originalWidth);
});

it('requests page to be rendered with a proper scale when given scale', () => {
it('requests page to be rendered with a proper scale when given scale', async () => {
const { func: onLoadSuccess, promise: onLoadSuccessPromise } = makeAsyncCallback();
const scale = 1.5;

render(<Page onLoadSuccess={onLoadSuccess} pageIndex={0} pdf={pdf} scale={scale} />);

expect.assertions(1);

return onLoadSuccessPromise.then((page) => {
expect(page.width).toEqual(page.originalWidth * scale);
});
const page = await onLoadSuccessPromise;

expect(page.width).toEqual(page.originalWidth * scale);
});

it('requests page to be rendered with a proper scale when given width', () => {
it('requests page to be rendered with a proper scale when given width', async () => {
const { func: onLoadSuccess, promise: onLoadSuccessPromise } = makeAsyncCallback();
const width = 600;

render(<Page onLoadSuccess={onLoadSuccess} pageIndex={0} pdf={pdf} width={width} />);

expect.assertions(1);

return onLoadSuccessPromise.then((page) => {
expect(page.width).toEqual(width);
});
const page = await onLoadSuccessPromise;

expect(page.width).toEqual(width);
});

it('requests page to be rendered with a proper scale when given width and scale (multiplies)', () => {
it('requests page to be rendered with a proper scale when given width and scale (multiplies)', async () => {
const { func: onLoadSuccess, promise: onLoadSuccessPromise } = makeAsyncCallback();
const width = 600;
const scale = 1.5;
@@ -626,25 +630,25 @@ describe('Page', () => {

expect.assertions(1);

return onLoadSuccessPromise.then((page) => {
expect(page.width).toBeCloseTo(width * scale);
});
const page = await onLoadSuccessPromise;

expect(page.width).toBeCloseTo(width * scale);
});

it('requests page to be rendered with a proper scale when given height', () => {
it('requests page to be rendered with a proper scale when given height', async () => {
const { func: onLoadSuccess, promise: onLoadSuccessPromise } = makeAsyncCallback();
const height = 850;

render(<Page height={height} onLoadSuccess={onLoadSuccess} pageIndex={0} pdf={pdf} />);

expect.assertions(1);

return onLoadSuccessPromise.then((page) => {
expect(page.height).toEqual(height);
});
const page = await onLoadSuccessPromise;

expect(page.height).toEqual(height);
});

it('requests page to be rendered with a proper scale when given height and scale (multiplies)', () => {
it('requests page to be rendered with a proper scale when given height and scale (multiplies)', async () => {
const { func: onLoadSuccess, promise: onLoadSuccessPromise } = makeAsyncCallback();
const height = 850;
const scale = 1.5;
@@ -655,12 +659,12 @@ describe('Page', () => {

expect.assertions(1);

return onLoadSuccessPromise.then((page) => {
expect(page.height).toBeCloseTo(height * scale);
});
const page = await onLoadSuccessPromise;

expect(page.height).toBeCloseTo(height * scale);
});

it('requests page to be rendered with a proper scale when given width and height (ignores height)', () => {
it('requests page to be rendered with a proper scale when given width and height (ignores height)', async () => {
const { func: onLoadSuccess, promise: onLoadSuccessPromise } = makeAsyncCallback();
const width = 600;
const height = 100;
@@ -671,14 +675,14 @@ describe('Page', () => {

expect.assertions(2);

return onLoadSuccessPromise.then((page) => {
expect(page.width).toEqual(width);
// Expect proportions to be correct even though invalid height was provided
expect(page.height).toEqual(page.originalHeight * (page.width / page.originalWidth));
});
const page = await onLoadSuccessPromise;

expect(page.width).toEqual(width);
// Expect proportions to be correct even though invalid height was provided
expect(page.height).toEqual(page.originalHeight * (page.width / page.originalWidth));
});

it('requests page to be rendered with a proper scale when given width, height and scale (ignores height, multiplies)', () => {
it('requests page to be rendered with a proper scale when given width, height and scale (ignores height, multiplies)', async () => {
const { func: onLoadSuccess, promise: onLoadSuccessPromise } = makeAsyncCallback();
const width = 600;
const height = 100;
@@ -697,11 +701,11 @@ describe('Page', () => {

expect.assertions(2);

return onLoadSuccessPromise.then((page) => {
expect(page.width).toBeCloseTo(width * scale);
// Expect proportions to be correct even though invalid height was provided
expect(page.height).toEqual(page.originalHeight * (page.width / page.originalWidth));
});
const page = await onLoadSuccessPromise;

expect(page.width).toBeCloseTo(width * scale);
// Expect proportions to be correct even though invalid height was provided
expect(page.height).toEqual(page.originalHeight * (page.width / page.originalWidth));
});

it('calls onClick callback when clicked a page (sample of mouse events family)', () => {
71 changes: 35 additions & 36 deletions src/Page/AnnotationLayer.spec.jsx
Original file line number Diff line number Diff line change
@@ -124,11 +124,10 @@ describe('AnnotationLayer', () => {

expect.assertions(1);

return onRenderAnnotationLayerSuccessPromise.then(() => {
const annotationItems = [...container.firstChild.children];
await onRenderAnnotationLayerSuccessPromise;

expect(annotationItems).toHaveLength(desiredAnnotations.length);
});
const annotationItems = [...container.firstChild.children];
expect(annotationItems).toHaveLength(desiredAnnotations.length);
});

it.each`
@@ -140,7 +139,7 @@ describe('AnnotationLayer', () => {
${'_top'} | ${'_top'}
`(
'renders all links with target $target given externalLinkTarget = $externalLinkTarget',
({ externalLinkTarget, target }) => {
async ({ externalLinkTarget, target }) => {
const {
func: onRenderAnnotationLayerSuccess,
promise: onRenderAnnotationLayerSuccessPromise,
@@ -160,14 +159,14 @@ describe('AnnotationLayer', () => {

expect.assertions(desiredAnnotations.length);

return onRenderAnnotationLayerSuccessPromise.then(() => {
const annotationItems = [...container.firstChild.children];
const annotationLinkItems = annotationItems
.map((item) => item.firstChild)
.filter((item) => item.tagName === 'A');
await onRenderAnnotationLayerSuccessPromise;

const annotationItems = [...container.firstChild.children];
const annotationLinkItems = annotationItems
.map((item) => item.firstChild)
.filter((item) => item.tagName === 'A');

annotationLinkItems.forEach((link) => expect(link.getAttribute('target')).toBe(target));
});
annotationLinkItems.forEach((link) => expect(link.getAttribute('target')).toBe(target));
},
);

@@ -177,7 +176,7 @@ describe('AnnotationLayer', () => {
${'noopener'} | ${'noopener'}
`(
'renders all links with rel $rel given externalLinkRel = $externalLinkRel',
({ externalLinkRel, rel }) => {
async ({ externalLinkRel, rel }) => {
const {
func: onRenderAnnotationLayerSuccess,
promise: onRenderAnnotationLayerSuccessPromise,
@@ -197,14 +196,14 @@ describe('AnnotationLayer', () => {

expect.assertions(desiredAnnotations.length);

return onRenderAnnotationLayerSuccessPromise.then(() => {
const annotationItems = [...container.firstChild.children];
const annotationLinkItems = annotationItems
.map((item) => item.firstChild)
.filter((item) => item.tagName === 'A');
await onRenderAnnotationLayerSuccessPromise;

const annotationItems = [...container.firstChild.children];
const annotationLinkItems = annotationItems
.map((item) => item.firstChild)
.filter((item) => item.tagName === 'A');

annotationLinkItems.forEach((link) => expect(link.getAttribute('rel')).toBe(rel));
});
annotationLinkItems.forEach((link) => expect(link.getAttribute('rel')).toBe(rel));
},
);

@@ -227,11 +226,11 @@ describe('AnnotationLayer', () => {
);

expect.assertions(1);
return onRenderAnnotationLayerSuccessPromise.then(() => {
const { viewport } = instance.current;

expect(viewport.rotation).toEqual(rotate);
});
await onRenderAnnotationLayerSuccessPromise;

const { viewport } = instance.current;
expect(viewport.rotation).toEqual(rotate);
});

it('renders annotations at a given scale', async () => {
@@ -253,11 +252,11 @@ describe('AnnotationLayer', () => {
);

expect.assertions(1);
return onRenderAnnotationLayerSuccessPromise.then(() => {
const { viewport } = instance.current;

expect(viewport.scale).toEqual(scale);
});
await onRenderAnnotationLayerSuccessPromise;

const { viewport } = instance.current;
expect(viewport.scale).toEqual(scale);
});

it('renders annotations with the default imageResourcesPath given no imageResourcesPath', async () => {
@@ -282,11 +281,11 @@ describe('AnnotationLayer', () => {
);

expect.assertions(1);
return onRenderAnnotationLayerSuccessPromise.then(() => {
const stringifiedAnnotationLayerNode = container.outerHTML;

expect(stringifiedAnnotationLayerNode).toMatch(desiredImageTagRegExp);
});
await onRenderAnnotationLayerSuccessPromise;

const stringifiedAnnotationLayerNode = container.outerHTML;
expect(stringifiedAnnotationLayerNode).toMatch(desiredImageTagRegExp);
});

it('renders annotations with the specified imageResourcesPath given imageResourcesPath', async () => {
@@ -312,11 +311,11 @@ describe('AnnotationLayer', () => {
);

expect.assertions(1);
return onRenderAnnotationLayerSuccessPromise.then(() => {
const stringifiedAnnotationLayerNode = container.outerHTML;

expect(stringifiedAnnotationLayerNode).toMatch(desiredImageTagRegExp);
});
await onRenderAnnotationLayerSuccessPromise;

const stringifiedAnnotationLayerNode = container.outerHTML;
expect(stringifiedAnnotationLayerNode).toMatch(desiredImageTagRegExp);
});
});
});
4 changes: 3 additions & 1 deletion src/Page/TextLayer.jsx
Original file line number Diff line number Diff line change
@@ -169,7 +169,8 @@ export class TextLayerInternal extends PureComponent {
this.endElement.current = end;

if (customTextRenderer) {
textContent.items.forEach((item, itemIndex) => {
let itemIndex = 0;
textContent.items.forEach((item) => {
const child = this.layerElement.current.children[itemIndex];

const content = customTextRenderer({
@@ -178,6 +179,7 @@ export class TextLayerInternal extends PureComponent {
});

child.innerHTML = content;
itemIndex += item.str && item.hasEOL ? 2 : 1;
});
}

101 changes: 81 additions & 20 deletions src/Page/TextLayer.spec.jsx
Original file line number Diff line number Diff line change
@@ -91,40 +91,100 @@ describe('TextLayer', () => {
);

expect.assertions(1);
return onRenderTextLayerSuccessPromise.then(() => {
const textItems = [...container.firstChild.children];

expect(textItems).toHaveLength(desiredTextItems.length + 1);
});
await onRenderTextLayerSuccessPromise;

const textItems = [...container.firstChild.children];
expect(textItems).toHaveLength(desiredTextItems.length + 1);
});

it('calls customTextRenderer with necessary arguments', () => {
it('renders text content properly given customTextRenderer', async () => {
const { func: onRenderTextLayerSuccess, promise: onRenderTextLayerSuccessPromise } =
makeAsyncCallback();

const customTextRenderer = jest.fn();

render(
const { container } = render(
<TextLayer
customTextRenderer={customTextRenderer}
onRenderTextLayerSuccess={onRenderTextLayerSuccess}
page={page}
/>,
);

expect.assertions(2);
return onRenderTextLayerSuccessPromise.then(() => {
expect(customTextRenderer).toHaveBeenCalledTimes(desiredTextItems.length);
expect(customTextRenderer).toHaveBeenCalledWith(
expect.objectContaining({
str: expect.any(String),
itemIndex: expect.any(Number),
}),
);
});
expect.assertions(1);

await onRenderTextLayerSuccessPromise;

const textItems = [...container.firstChild.children];
expect(textItems).toHaveLength(desiredTextItems.length + 1);
});

it('renders text content properly given customTextRenderer', () => {
it('maps textContent items to actual TextLayer children properly', async () => {
const { func: onRenderTextLayerSuccess, promise: onRenderTextLayerSuccessPromise } =
makeAsyncCallback();

const { container, rerender } = render(
<TextLayer onRenderTextLayerSuccess={onRenderTextLayerSuccess} page={page} />,
);

expect.assertions(1);

await onRenderTextLayerSuccessPromise;

const innerHTML = container.firstChild.innerHTML;

const { func: onRenderTextLayerSuccess2, promise: onRenderTextLayerSuccessPromise2 } =
makeAsyncCallback();

const customTextRenderer = (item) => item.str;

rerender(
<TextLayer
customTextRenderer={customTextRenderer}
onRenderTextLayerSuccess={onRenderTextLayerSuccess2}
page={page}
/>,
);

await onRenderTextLayerSuccessPromise2;

const innerHTML2 = container.firstChild.innerHTML;

expect(innerHTML).toEqual(innerHTML2);
});

it('calls customTextRenderer with necessary arguments', async () => {
const { func: onRenderTextLayerSuccess, promise: onRenderTextLayerSuccessPromise } =
makeAsyncCallback();

const customTextRenderer = jest.fn();

const { container } = render(
<TextLayer
customTextRenderer={customTextRenderer}
onRenderTextLayerSuccess={onRenderTextLayerSuccess}
page={page}
/>,
);

expect.assertions(3);

await onRenderTextLayerSuccessPromise;

const textItems = [...container.firstChild.children];
expect(textItems).toHaveLength(desiredTextItems.length + 1);

expect(customTextRenderer).toHaveBeenCalledTimes(desiredTextItems.length);
expect(customTextRenderer).toHaveBeenCalledWith(
expect.objectContaining({
str: expect.any(String),
itemIndex: expect.any(Number),
}),
);
});

it('renders text content properly given customTextRenderer', async () => {
const { func: onRenderTextLayerSuccess, promise: onRenderTextLayerSuccessPromise } =
makeAsyncCallback();

@@ -139,9 +199,10 @@ describe('TextLayer', () => {
);

expect.assertions(1);
return onRenderTextLayerSuccessPromise.then(() => {
expect(container).toHaveTextContent('Test value');
});

await onRenderTextLayerSuccessPromise;

expect(container).toHaveTextContent('Test value');
});
});
});