UNPKG

@peergrade/react-pdf

Version:

Display PDFs in your React app as easily as if they were images.

147 lines (120 loc) 3.17 kB
import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import PageContext from '../PageContext'; import TextLayerItem from './TextLayerItem'; import { callIfDefined, cancelRunningTask, errorOnDev, makeCancellable, } from '../shared/utils'; import { isPage, isRotate } from '../shared/propTypes'; export class TextLayerInternal extends PureComponent { state = { textItems: null, } componentDidMount() { if (!this.props.page) { throw new Error('Attempted to load page text content, but no page was specified.'); } this.loadTextItems(); } componentDidUpdate(prevProps) { if (prevProps.page && (this.props.page !== prevProps.page)) { this.loadTextItems(); } } componentWillUnmount() { cancelRunningTask(this.runningTask); } loadTextItems = async () => { const { page } = this.props; try { const cancellable = makeCancellable(page.getTextContent()); this.runningTask = cancellable; const { items: textItems } = await cancellable.promise; this.setState({ textItems }, this.onLoadSuccess); } catch (error) { this.setState({ textItems: false }); this.onLoadError(error); } } onLoadSuccess = () => { callIfDefined( this.props.onGetTextSuccess, this.state.textItems, ); } onLoadError = (error) => { if ( error.name === 'RenderingCancelledException' || error.name === 'PromiseCancelledException' ) { return; } errorOnDev(error); callIfDefined( this.props.onGetTextError, error, ); } get unrotatedViewport() { const { page, scale } = this.props; return page.getViewport(scale); } /** * It might happen that the page is rotated by default. In such cases, we shouldn't rotate * text content. */ get rotate() { const { page, rotate } = this.props; return rotate - page.rotate; } renderTextItems() { const { textItems } = this.state; if (!textItems) { return null; } return textItems.map((textItem, itemIndex) => ( <TextLayerItem // eslint-disable-next-line react/no-array-index-key key={itemIndex} itemIndex={itemIndex} {...textItem} /> )); } render() { const { unrotatedViewport: viewport, rotate } = this; return ( <div className="react-pdf__Page__textContent" style={{ position: 'absolute', top: '50%', left: '50%', width: `${viewport.width}px`, height: `${viewport.height}px`, color: 'transparent', transform: `translate(-50%, -50%) rotate(${rotate}deg)`, pointerEvents: 'none', }} > {this.renderTextItems()} </div> ); } } TextLayerInternal.propTypes = { onGetTextError: PropTypes.func, onGetTextSuccess: PropTypes.func, page: isPage.isRequired, rotate: isRotate, scale: PropTypes.number, }; const TextLayer = props => ( <PageContext.Consumer> {context => <TextLayerInternal {...context} {...props} />} </PageContext.Consumer> ); export default TextLayer;