├── .babelrc ├── .eslintignore ├── .eslintrc ├── .gitignore ├── .npmignore ├── .travis.yml ├── LICENSE ├── README.md ├── package.json ├── src ├── Pdf.js └── index.js ├── webpack.config.base.js ├── webpack.config.development.js └── webpack.config.production.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "stage": 0, 3 | "optional": "runtime", 4 | "loose": "all", 5 | "plugins": [ 6 | "typecheck" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | webpack.config*.js 2 | node_modules 3 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "eslint-config-airbnb", 3 | "env": { 4 | "browser": true, 5 | "mocha": true, 6 | "node": true 7 | }, 8 | "rules": { 9 | "react/jsx-uses-react": 2, 10 | "react/jsx-uses-vars": 2, 11 | "react/react-in-jsx-scope": 2, 12 | "comma-dangle": 0, // not sure why airbnb turned this on. gross! 13 | "indent": [2, 2, {"SwitchCase": 1}], 14 | "spaced-comment": 0, 15 | 16 | //Temporarirly disabled due to a possible bug in babel-eslint (todomvc example) 17 | "block-scoped-var": 0, 18 | // Temporarily disabled for test/* until babel/babel-eslint#33 is resolved 19 | "padded-blocks": 0 20 | }, 21 | "plugins": [ 22 | "react" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | node_modules 3 | dist 4 | lib 5 | npm-debug.log 6 | .DS_Store 7 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .babelrc 2 | .eslint* 3 | .idea 4 | .npmignore 5 | .travis.yml 6 | webpack.* 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - "4.0" 5 | - "4" 6 | - "stable" 7 | 8 | script: 9 | - npm run lint 10 | - npm test -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Erik Rasmussen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #react-pdfjs 2 | --- 3 | [![NPM Version](https://img.shields.io/npm/v/react-pdfjs.svg?style=flat-square)](https://www.npmjs.com/package/react-pdfjs) 4 | [![NPM Downloads](https://img.shields.io/npm/dm/react-pdfjs.svg?style=flat-square)](https://www.npmjs.com/package/react-pdfjs) 5 | [![Build Status](https://img.shields.io/travis/erikras/react-pdfjs/master.svg?style=flat-square)](https://travis-ci.org/erikras/react-pdfjs) 6 | [![devDependency Status](https://david-dm.org/erikras/react-pdfjs/dev-status.svg)](https://david-dm.org/erikras/react-pdfjs#info=devDependencies) 7 | 8 | `react-pdfjs` provides a component for rendering PDF documents using [PDF.js](http://mozilla.github.io/pdf.js/). 9 | 10 | --- 11 | 12 | ## Installation 13 | 14 | ```bash 15 | npm install --save react-pdfjs 16 | ``` 17 | 18 | ## Support 19 | 20 | This project will not be supported. It is a port of [react-pdf](https://github.com/nnarhinen/react-pdf) to ES6 and 21 | React 0.14. Don't expect any response if you submit an issue, but if you submit a well-written pull request, it _might_ 22 | be merged in. 23 | 24 | ## Credit 25 | 26 | As stated above, this is a port of [react-pdf](https://github.com/nnarhinen/react-pdf), so thank you to 27 | [its authors](https://github.com/nnarhinen/react-pdf#author). 28 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-pdfjs", 3 | "version": "1.0.7", 4 | "description": "A React component to wrap PDF.js", 5 | "main": "./lib/index.js", 6 | "jsnext:main": "./src/index.js", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/erikras/react-pdfjs" 10 | }, 11 | "scripts": { 12 | "build": "npm run build:lib && npm run build:umd && npm run build:umd:min", 13 | "build:lib": "babel src --out-dir lib", 14 | "build:umd": "webpack src/index.js dist/react-pdfjs.js --config webpack.config.development.js", 15 | "build:umd:min": "webpack src/index.js dist/react-pdfjs.min.js --config webpack.config.production.js", 16 | "clean": "rimraf dist lib", 17 | "lint": "eslint src", 18 | "prepublish": "npm run lint && npm run clean && npm run build" 19 | }, 20 | "keywords": [ 21 | "react", 22 | "reactjs", 23 | "pdf", 24 | "pdfjs" 25 | ], 26 | "author": "Erik Rasmussen (http://github.com/erikras)", 27 | "license": "MIT", 28 | "bugs": { 29 | "url": "https://github.com/erikras/react-pdfjs/issues" 30 | }, 31 | "homepage": "https://github.com/erikras/react-pdfjs", 32 | "dependencies": { 33 | "pdfjs-dist": "^1.5.296" 34 | }, 35 | "devDependencies": { 36 | "babel": "^5.8.23", 37 | "babel-core": "^5.8.25", 38 | "babel-eslint": "^4.1.3", 39 | "babel-loader": "^5.3.2", 40 | "babel-plugin-react-transform": "^1.1.1", 41 | "babel-plugin-typecheck": "^1.3.0", 42 | "babel-runtime": "^5.8.25", 43 | "eslint": "^1.9.0", 44 | "eslint-config-airbnb": "^0.1.0", 45 | "eslint-plugin-react": "^3.5.1", 46 | "react": "^0.14.0", 47 | "rifraf": "^2.0.2", 48 | "rimraf": "^2.4.3", 49 | "webpack": "^1.12.3" 50 | }, 51 | "npmName": "react-pdfjs", 52 | "npmFileMap": [ 53 | { 54 | "files": [ 55 | "dist/*.js", 56 | "lib/*.js", 57 | "src/*.js" 58 | ] 59 | } 60 | ] 61 | } 62 | -------------------------------------------------------------------------------- /src/Pdf.js: -------------------------------------------------------------------------------- 1 | import React, {Component, PropTypes} from 'react'; 2 | 3 | if (typeof window !== 'undefined') { 4 | require('pdfjs-dist/build/pdf.combined'); 5 | require('pdfjs-dist/web/compatibility'); 6 | } 7 | 8 | class Pdf extends Component { 9 | constructor(props) { 10 | super(props); 11 | this.onDocumentComplete = this.onDocumentComplete.bind(this); 12 | this.onPageComplete = this.onPageComplete.bind(this); 13 | } 14 | 15 | state = {}; 16 | 17 | componentDidMount() { 18 | this.loadPDFDocument(this.props); 19 | this.renderPdf(); 20 | } 21 | 22 | componentWillReceiveProps(newProps) { 23 | const {pdf} = this.state; 24 | if ((newProps.file && newProps.file !== this.props.file) || 25 | (newProps.content && newProps.content !== this.props.content)) { 26 | this.loadPDFDocument(newProps); 27 | } 28 | 29 | if (pdf && ((newProps.page && newProps.page !== this.props.page) || 30 | (newProps.scale && newProps.scale !== this.props.scale)) || 31 | ((newProps.rotate || newProps.rotate === 0) && newProps.rotate !== this.props.rotate)) { 32 | this.setState({page: null}); 33 | pdf.getPage(newProps.page).then(this.onPageComplete); 34 | } 35 | } 36 | 37 | onDocumentComplete(pdf) { 38 | this.setState({pdf: pdf}); 39 | const {onDocumentComplete} = this.props; 40 | if (typeof onDocumentComplete === 'function') { 41 | onDocumentComplete(pdf.numPages); 42 | } 43 | pdf.getPage(this.props.page).then(this.onPageComplete); 44 | } 45 | 46 | onPageComplete(page) { 47 | this.setState({page: page}); 48 | this.renderPdf(); 49 | const {onPageComplete} = this.props; 50 | if (typeof onPageComplete === 'function') { 51 | onPageComplete(page.pageIndex + 1); 52 | } 53 | } 54 | 55 | loadByteArray(byteArray) { 56 | window.PDFJS.getDocument(byteArray).then(this.onDocumentComplete); 57 | } 58 | 59 | loadPDFDocument(props) { 60 | if (!!props.file) { 61 | if (typeof props.file === 'string') { 62 | return window.PDFJS.getDocument(props.file) 63 | .then(this.onDocumentComplete); 64 | } 65 | // Is a File object 66 | const reader = new FileReader(); 67 | reader.onloadend = () => 68 | this.loadByteArray(new Uint8Array(reader.result)); 69 | reader.readAsArrayBuffer(props.file); 70 | } else if (!!props.content) { 71 | const bytes = window.atob(props.content); 72 | const byteLength = bytes.length; 73 | const byteArray = new Uint8Array(new ArrayBuffer(byteLength)); 74 | for (let index = 0; index < byteLength; index++) { 75 | byteArray[index] = bytes.charCodeAt(index); 76 | } 77 | this.loadByteArray(byteArray); 78 | } else { 79 | throw new Error('React-PDFjs works with a file(URL) or (base64)content. At least one needs to be provided!'); 80 | } 81 | } 82 | 83 | renderPdf() { 84 | const {page} = this.state; 85 | if (page) { 86 | let {canvas} = this.refs; 87 | if (canvas.getDOMNode) { // compatible with react 0.13 88 | canvas = canvas.getDOMNode(); 89 | } 90 | const canvasContext = canvas.getContext('2d'); 91 | const {scale, rotate} = this.props; 92 | const viewport = page.getViewport(scale, rotate); 93 | canvas.height = viewport.height; 94 | canvas.width = viewport.width; 95 | page.render({canvasContext, viewport}); 96 | } 97 | } 98 | 99 | render() { 100 | const {loading, style} = this.props; 101 | const {page} = this.state; 102 | return page ? : loading ||
Loading PDF...
; 103 | } 104 | } 105 | Pdf.displayName = 'React-PDFjs'; 106 | Pdf.propTypes = { 107 | content: PropTypes.string, 108 | file: PropTypes.string, 109 | loading: PropTypes.any, 110 | page: PropTypes.number, 111 | scale: PropTypes.number, 112 | rotate: PropTypes.number, 113 | onDocumentComplete: PropTypes.func, 114 | onPageComplete: PropTypes.func, 115 | style: PropTypes.object, 116 | }; 117 | Pdf.defaultProps = {page: 1, scale: 1.0}; 118 | 119 | export default Pdf; 120 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import Pdf from './Pdf'; 2 | export default Pdf; 3 | -------------------------------------------------------------------------------- /webpack.config.base.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var webpack = require('webpack'); 3 | 4 | var reactExternal = { 5 | root: 'React', 6 | commonjs2: 'react', 7 | commonjs: 'react', 8 | amd: 'react' 9 | }; 10 | 11 | module.exports = { 12 | externals: { 13 | 'react': reactExternal 14 | }, 15 | module: { 16 | loaders: [ 17 | { test: /\.js$/, loaders: ['babel-loader'], exclude: /node_modules/ } 18 | ] 19 | }, 20 | output: { 21 | library: 'ReduxForm', 22 | libraryTarget: 'umd' 23 | }, 24 | resolve: { 25 | extensions: ['', '.js'] 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /webpack.config.development.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var webpack = require('webpack'); 4 | var baseConfig = require('./webpack.config.base'); 5 | 6 | var config = Object.create(baseConfig); 7 | config.plugins = [ 8 | new webpack.optimize.OccurenceOrderPlugin(), 9 | new webpack.DefinePlugin({ 10 | 'process.env.NODE_ENV': JSON.stringify('development') 11 | }) 12 | 13 | ]; 14 | 15 | module.exports = config; 16 | -------------------------------------------------------------------------------- /webpack.config.production.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var webpack = require('webpack'); 4 | var baseConfig = require('./webpack.config.base'); 5 | 6 | var config = Object.create(baseConfig); 7 | config.plugins = [ 8 | new webpack.optimize.OccurenceOrderPlugin(), 9 | new webpack.DefinePlugin({ 10 | 'process.env.NODE_ENV': JSON.stringify('production') 11 | }), 12 | new webpack.optimize.UglifyJsPlugin({ 13 | compressor: { 14 | screw_ie8: true, 15 | warnings: false 16 | } 17 | }) 18 | ]; 19 | 20 | module.exports = config; 21 | --------------------------------------------------------------------------------