react-pdf-annotations
Version:
Set of React components for PDF annotation
166 lines (138 loc) • 4.42 kB
JavaScript
// @flow
import React, { Component } from "react";
import type { T_PDFJS, T_PDFJS_Document } from "../types";
// import { getDocument, GlobalWorkerOptions } from "pdfjs-dist/lib/pdf";
// import PdfjsWorker from "pdfjs-dist/lib/pdf.worker";
// setPdfWorker(PdfjsWorker);
// export function setPdfWorker(workerSrcOrClass: any) {
// if (typeof window !== "undefined") delete window.pdfjsWorker;
// delete GlobalWorkerOptions.workerSrc;
// delete GlobalWorkerOptions.workerPort;
//
// if (typeof workerSrcOrClass === "string") {
// GlobalWorkerOptions.workerSrc = workerSrcOrClass;
// } else if (typeof workerSrcOrClass === "function") {
// GlobalWorkerOptions.workerPort = workerSrcOrClass();
// } else if (workerSrcOrClass instanceof Worker) {
// GlobalWorkerOptions.workerPort = workerSrcOrClass;
// } else if (typeof window !== "undefined" && workerSrcOrClass) {
// window.pdfjsWorker = workerSrcOrClass;
// }
// }
type Props = {
url: string,
beforeLoad: React$Element<*>,
errorMessage?: React$Element<*>,
children: (pdfDocument: T_PDFJS_Document) => React$Element<*>,
onError?: (error: Error) => void,
cMapUrl?: string,
cMapPacked?: boolean,
headers?: object,
};
type State = {
pdfDocument: ?T_PDFJS_Document,
error: ?Error
};
class PdfLoader extends Component<Props, State> {
containerNode;
eventBus;
linkService;
pdfDocument;
state = {
pdfDocument: null,
error: null
};
documentRef = React.createRef<HTMLElement>();
// componentDidMount() {
// this.init();
// }
componentWillUnmount() {
const { pdfDocument: discardedDocument } = this.state;
if (discardedDocument) {
discardedDocument.destroy();
}
}
componentDidUpdate({ url }: Props) {
if (this.props.url !== url) {
this.init();
}
}
componentDidCatch(error: Error, info?: any) {
const { onError } = this.props;
if (onError) {
onError(error);
}
this.setState({ pdfDocument: null, error });
}
init() {
const { url, cMapUrl, cMapPacked, headers: httpHeaders = {} } = this.props;
this.setState({ pdfDocument: null, error: null });
Promise.resolve()
.then(() => this.pdfDocument && this.pdfDocument.destroy())
.then(
async () => {
if (url) {
const pdfjsViewer = await import('pdfjs-dist/web/pdf_viewer');
this.eventBus = new pdfjsViewer.EventBus();
this.linkService = new pdfjsViewer.PDFLinkService();
// @ts-ignore
this.viewer = new pdfjsViewer.PDFViewer({
container: this.containerNode,
eventBus: this.eventBus,
linkService: this.linkService,
enhanceTextSelection: true,
removePageBorders: true,
});
}
const pdfJS = await import('pdfjs-dist/build/pdf');
pdfJS.GlobalWorkerOptions.workerSrc = window.location.origin + '/pdf.worker.min.js';
await pdfJS.getDocument({ url, ownerDocument, cMapUrl, cMapPacked, httpHeaders, withCredentials: true }).promise
.then((pdfDocument) => {
this.pdfDocument = pdfDocument;
this.viewer.setDocument(pdfDocument);
})
// getDocument({ url, ownerDocument, cMapUrl, cMapPacked, httpHeaders, withCredentials: true }).promise.then(
// pdfDocument => {
// this.setState({ pdfDocument });
// }
// )
}
)
.catch(e => this.componentDidCatch(e));
}
attachRef = (ref) => {
this.containerNode = ref;
this.init();
};
render() {
// const { children, beforeLoad } = this.props;
// const { pdfDocument, error } = this.state;
return (
<div
ref={this.attachRef}
className="PdfHighlighter"
onContextMenu={e => e.preventDefault()}
>
<div className="pdfViewer" />
</div>
);
// return (
// <>
// <span ref={this.documentRef} />
// {error
// ? this.renderError()
// : !pdfDocument || !children
// ? beforeLoad
// : children(pdfDocument)}
// </>
// );
}
renderError() {
const { errorMessage } = this.props;
if (errorMessage) {
return React.cloneElement(errorMessage, { error: this.state.error });
}
return null;
}
}
export default PdfLoader;