react-pdf
Advanced tools
Comparing version 1.6.0 to 1.6.1
@@ -0,1 +1,7 @@ | ||
'use strict'; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; | ||
@@ -5,2 +11,8 @@ | ||
var _react = require('react'); | ||
var _react2 = _interopRequireDefault(_react); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
@@ -12,4 +24,2 @@ | ||
import React, { Component, PropTypes } from 'react'; | ||
require('pdfjs-dist/web/compatibility'); | ||
@@ -22,428 +32,428 @@ require('pdfjs-dist/build/pdf'); | ||
var ReactPDF = function (_Component) { | ||
_inherits(ReactPDF, _Component); | ||
_inherits(ReactPDF, _Component); | ||
function ReactPDF() { | ||
var _ref; | ||
function ReactPDF() { | ||
var _ref; | ||
var _temp, _this, _ret; | ||
var _temp, _this, _ret; | ||
_classCallCheck(this, ReactPDF); | ||
_classCallCheck(this, ReactPDF); | ||
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | ||
args[_key] = arguments[_key]; | ||
} | ||
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = ReactPDF.__proto__ || Object.getPrototypeOf(ReactPDF)).call.apply(_ref, [this].concat(args))), _this), _initialiseProps.call(_this), _temp), _possibleConstructorReturn(_this, _ret); | ||
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | ||
args[_key] = arguments[_key]; | ||
} | ||
_createClass(ReactPDF, [{ | ||
key: 'componentDidMount', | ||
value: function componentDidMount() { | ||
this.handleFileLoad(); | ||
} | ||
}, { | ||
key: 'componentWillReceiveProps', | ||
value: function componentWillReceiveProps(nextProps) { | ||
if (this.isParameterObject(nextProps.file)) { | ||
// File is a parameter object | ||
if (nextProps.file && !this.props.file || nextProps.file.data !== this.props.file.data || nextProps.file.range !== this.props.file.range || nextProps.file.url !== this.props.file.url) { | ||
this.handleFileLoad(nextProps); | ||
return; | ||
} | ||
} else if (nextProps.file && nextProps.file !== this.props.file) { | ||
// File is a normal object or not an object at all | ||
this.handleFileLoad(nextProps); | ||
return; | ||
} | ||
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = ReactPDF.__proto__ || Object.getPrototypeOf(ReactPDF)).call.apply(_ref, [this].concat(args))), _this), _initialiseProps.call(_this), _temp), _possibleConstructorReturn(_this, _ret); | ||
} | ||
if (this.state.pdf && typeof nextProps.pageIndex !== 'undefined' && nextProps.pageIndex !== this.props.pageIndex) { | ||
this.loadPage(nextProps.pageIndex); | ||
} | ||
_createClass(ReactPDF, [{ | ||
key: 'componentDidMount', | ||
value: function componentDidMount() { | ||
this.handleFileLoad(); | ||
} | ||
}, { | ||
key: 'componentWillReceiveProps', | ||
value: function componentWillReceiveProps(nextProps) { | ||
if (this.isParameterObject(nextProps.file)) { | ||
// File is a parameter object | ||
if (nextProps.file && !this.props.file || nextProps.file.data !== this.props.file.data || nextProps.file.range !== this.props.file.range || nextProps.file.url !== this.props.file.url) { | ||
this.handleFileLoad(nextProps); | ||
return; | ||
} | ||
}, { | ||
key: 'shouldComponentUpdate', | ||
value: function shouldComponentUpdate(nextProps, nextState) { | ||
return nextState.pdf !== this.state.pdf || nextState.page !== this.state.page || nextProps.width !== this.props.width || nextProps.scale !== this.props.scale; | ||
} | ||
} else if (nextProps.file && nextProps.file !== this.props.file) { | ||
// File is a normal object or not an object at all | ||
this.handleFileLoad(nextProps); | ||
return; | ||
} | ||
/** | ||
* Called when a document is loaded successfully. | ||
*/ | ||
if (this.state.pdf && typeof nextProps.pageIndex !== 'undefined' && nextProps.pageIndex !== this.props.pageIndex) { | ||
this.loadPage(nextProps.pageIndex); | ||
} | ||
} | ||
}, { | ||
key: 'shouldComponentUpdate', | ||
value: function shouldComponentUpdate(nextProps, nextState) { | ||
return nextState.pdf !== this.state.pdf || nextState.page !== this.state.page || nextProps.width !== this.props.width || nextProps.scale !== this.props.scale; | ||
} | ||
/** | ||
* Called when a document is loaded successfully. | ||
*/ | ||
/** | ||
* Called when a document fails to load. | ||
*/ | ||
/** | ||
* Called when a document fails to load. | ||
*/ | ||
/** | ||
* Called when a page is loaded successfully. | ||
*/ | ||
/** | ||
* Called when a page is loaded successfully. | ||
*/ | ||
/** | ||
* Called when a page is rendered successfully. | ||
*/ | ||
/** | ||
* Called when a page is rendered successfully. | ||
*/ | ||
/** | ||
* Called when a page fails to load or render. | ||
*/ | ||
}, { | ||
key: 'getPageScale', | ||
value: function getPageScale() { | ||
var page = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.state.page; | ||
var _props = this.props, | ||
scale = _props.scale, | ||
width = _props.width; | ||
/** | ||
* Called when a page fails to load or render. | ||
*/ | ||
// Be default, we'll render page at 100% * scale width. | ||
}, { | ||
key: 'getPageScale', | ||
value: function getPageScale() { | ||
var page = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.state.page; | ||
var _props = this.props, | ||
scale = _props.scale, | ||
width = _props.width; | ||
var pageScale = 1; | ||
// Be default, we'll render page at 100% * scale width. | ||
// If width is defined, calculate the scale of the page so it could be of desired width. | ||
if (width) { | ||
pageScale = width / page.getViewport(scale).width; | ||
} | ||
var pageScale = 1; | ||
return scale * pageScale; | ||
} | ||
}, { | ||
key: 'handleFileLoad', | ||
value: function handleFileLoad() { | ||
var _this2 = this; | ||
// If width is defined, calculate the scale of the page so it could be of desired width. | ||
if (width) { | ||
pageScale = width / page.getViewport(scale).width; | ||
} | ||
var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props; | ||
var file = props.file; | ||
return scale * pageScale; | ||
} | ||
}, { | ||
key: 'handleFileLoad', | ||
value: function handleFileLoad() { | ||
var _this2 = this; | ||
var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props; | ||
var file = props.file; | ||
if (!file || this.isParameterObject(file) && !file.data && !file.range && !file.url) { | ||
return null; | ||
} | ||
this.setState({ | ||
page: null, | ||
pdf: null | ||
}); | ||
if (!file || this.isParameterObject(file) && !file.data && !file.range && !file.url) { | ||
return null; | ||
} | ||
// File is a string | ||
if (typeof file === 'string') { | ||
// File is not data URI | ||
if (!this.isDataURI(file)) { | ||
if (window.location.protocol === 'file:') { | ||
this.displayCORSWarning(); | ||
} | ||
this.setState({ | ||
page: null, | ||
pdf: null | ||
}); | ||
return this.loadDocument(file); | ||
} | ||
// File is a string | ||
if (typeof file === 'string') { | ||
// File is not data URI | ||
if (!this.isDataURI(file)) { | ||
if (window.location.protocol === 'file:') { | ||
this.displayCORSWarning(); | ||
} | ||
// File is data URI | ||
file = this.dataURItoBlob(file); | ||
return this.loadDocument(file); | ||
} | ||
// Fall through to "File is a blob" | ||
} | ||
// File is data URI | ||
file = this.dataURItoBlob(file); | ||
// File is a Blob | ||
if (file instanceof Blob) { | ||
file = URL.createObjectURL(file); | ||
// Fall through to "File is a blob" | ||
} | ||
return this.loadDocument(file); | ||
} | ||
// File is a Blob | ||
if (file instanceof Blob) { | ||
file = URL.createObjectURL(file); | ||
// File is a File | ||
if (file instanceof File) { | ||
var _ret2 = function () { | ||
var reader = new FileReader(); | ||
return this.loadDocument(file); | ||
} | ||
reader.onloadend = function () { | ||
_this2.loadDocument(new Uint8Array(reader.result)); | ||
}; | ||
// File is a File | ||
if (file instanceof File) { | ||
var _ret2 = function () { | ||
var reader = new FileReader(); | ||
return { | ||
v: reader.readAsArrayBuffer(file) | ||
}; | ||
}(); | ||
reader.onloadend = function () { | ||
_this2.loadDocument(new Uint8Array(reader.result)); | ||
}; | ||
if ((typeof _ret2 === 'undefined' ? 'undefined' : _typeof(_ret2)) === "object") return _ret2.v; | ||
} | ||
return { | ||
v: reader.readAsArrayBuffer(file) | ||
}; | ||
}(); | ||
// File is an ArrayBuffer | ||
if (file instanceof ArrayBuffer) { | ||
return this.loadDocument(file); | ||
} | ||
if ((typeof _ret2 === 'undefined' ? 'undefined' : _typeof(_ret2)) === "object") return _ret2.v; | ||
} | ||
// File is a parameter object | ||
if (this.isParameterObject(file)) { | ||
if (file.url && window.location.protocol === 'file:') { | ||
this.displayCORSWarning(); | ||
} | ||
// File is an ArrayBuffer | ||
if (file instanceof ArrayBuffer) { | ||
return this.loadDocument(file); | ||
} | ||
// Prevent from modifying props | ||
file = Object.assign({}, file); | ||
// File is a parameter object | ||
if (this.isParameterObject(file)) { | ||
if (file.url && window.location.protocol === 'file:') { | ||
this.displayCORSWarning(); | ||
} | ||
// File is data URI | ||
if (file.url && this.isDataURI(file.url)) { | ||
file = URL.createObjectURL(this.dataURItoBlob(file.url)); | ||
} | ||
// Prevent from modifying props | ||
file = Object.assign({}, file); | ||
return this.loadDocument(file); | ||
} | ||
throw new Error('Unrecognized input type.'); | ||
// File is data URI | ||
if (file.url && this.isDataURI(file.url)) { | ||
file = URL.createObjectURL(this.dataURItoBlob(file.url)); | ||
} | ||
}, { | ||
key: 'loadDocument', | ||
value: function loadDocument() { | ||
var _PDFJS; | ||
(_PDFJS = PDFJS).getDocument.apply(_PDFJS, arguments).then(this.onDocumentLoad).catch(this.onDocumentError); | ||
} | ||
}, { | ||
key: 'loadPage', | ||
value: function loadPage(pageIndex) { | ||
var pdf = this.state.pdf; | ||
return this.loadDocument(file); | ||
} | ||
throw new Error('Unrecognized input type.'); | ||
} | ||
}, { | ||
key: 'loadDocument', | ||
value: function loadDocument() { | ||
var _PDFJS; | ||
if (!pdf) { | ||
throw new Error('Unexpected call to getPage() before the document has been loaded.'); | ||
} | ||
(_PDFJS = PDFJS).getDocument.apply(_PDFJS, arguments).then(this.onDocumentLoad).catch(this.onDocumentError); | ||
} | ||
}, { | ||
key: 'loadPage', | ||
value: function loadPage(pageIndex) { | ||
var pdf = this.state.pdf; | ||
var pageNumber = pageIndex + 1; | ||
if (!pageIndex || pageNumber < 1) { | ||
pageNumber = 1; | ||
} else if (pageNumber >= pdf.numPages) { | ||
pageNumber = pdf.numPages; | ||
} | ||
if (!pdf) { | ||
throw new Error('Unexpected call to getPage() before the document has been loaded.'); | ||
} | ||
pdf.getPage(pageNumber).then(this.onPageLoad).catch(this.onPageError); | ||
} | ||
}, { | ||
key: 'renderNoData', | ||
value: function renderNoData() { | ||
return React.createElement( | ||
'div', | ||
null, | ||
this.props.noData | ||
); | ||
} | ||
}, { | ||
key: 'renderError', | ||
value: function renderError() { | ||
return React.createElement( | ||
'div', | ||
null, | ||
this.props.error | ||
); | ||
} | ||
}, { | ||
key: 'renderLoader', | ||
value: function renderLoader() { | ||
return React.createElement( | ||
'div', | ||
null, | ||
this.props.loading | ||
); | ||
} | ||
}, { | ||
key: 'render', | ||
value: function render() { | ||
var _this3 = this; | ||
var pageNumber = pageIndex + 1; | ||
var file = this.props.file; | ||
var _state = this.state, | ||
pdf = _state.pdf, | ||
page = _state.page; | ||
if (!pageIndex || pageNumber < 1) { | ||
pageNumber = 1; | ||
} else if (pageNumber >= pdf.numPages) { | ||
pageNumber = pdf.numPages; | ||
} | ||
pdf.getPage(pageNumber).then(this.onPageLoad).catch(this.onPageError); | ||
} | ||
}, { | ||
key: 'renderNoData', | ||
value: function renderNoData() { | ||
return _react2.default.createElement( | ||
'div', | ||
null, | ||
this.props.noData | ||
); | ||
} | ||
}, { | ||
key: 'renderError', | ||
value: function renderError() { | ||
return _react2.default.createElement( | ||
'div', | ||
null, | ||
this.props.error | ||
); | ||
} | ||
}, { | ||
key: 'renderLoader', | ||
value: function renderLoader() { | ||
return _react2.default.createElement( | ||
'div', | ||
null, | ||
this.props.loading | ||
); | ||
} | ||
}, { | ||
key: 'render', | ||
value: function render() { | ||
var _this3 = this; | ||
if (!file) { | ||
return this.renderNoData(); | ||
} | ||
var file = this.props.file; | ||
var _state = this.state, | ||
pdf = _state.pdf, | ||
page = _state.page; | ||
if (pdf === false || page === false) { | ||
return this.renderError(); | ||
} | ||
if (pdf === null || page === null) { | ||
return this.renderLoader(); | ||
} | ||
if (!file) { | ||
return this.renderNoData(); | ||
} | ||
return React.createElement('canvas', { | ||
ref: function ref(_ref2) { | ||
if (!_ref2) return; | ||
if (pdf === false || page === false) { | ||
return this.renderError(); | ||
} | ||
var canvas = _ref2; | ||
if (pdf === null || page === null) { | ||
return this.renderLoader(); | ||
} | ||
var pixelRatio = window.devicePixelRatio || 1; | ||
var viewport = page.getViewport(_this3.getPageScale() * pixelRatio); | ||
return _react2.default.createElement('canvas', { | ||
ref: function ref(_ref2) { | ||
if (!_ref2) return; | ||
canvas.height = viewport.height; | ||
canvas.width = viewport.width; | ||
var canvas = _ref2; | ||
canvas.style.height = viewport.height / pixelRatio + 'px'; | ||
canvas.style.width = viewport.width / pixelRatio + 'px'; | ||
var pixelRatio = window.devicePixelRatio || 1; | ||
var viewport = page.getViewport(_this3.getPageScale() * pixelRatio); | ||
var canvasContext = canvas.getContext('2d'); | ||
canvas.height = viewport.height; | ||
canvas.width = viewport.width; | ||
var renderContext = { | ||
canvasContext: canvasContext, | ||
viewport: viewport | ||
}; | ||
canvas.style.height = viewport.height / pixelRatio + 'px'; | ||
canvas.style.width = viewport.width / pixelRatio + 'px'; | ||
// If another render is in progress, let's cancel it | ||
/* eslint-disable no-underscore-dangle */ | ||
if (_this3.renderer && _this3.renderer._internalRenderTask.running) { | ||
_this3.renderer._internalRenderTask.cancel(); | ||
} | ||
/* eslint-enable no-underscore-dangle */ | ||
var canvasContext = canvas.getContext('2d'); | ||
_this3.renderer = page.render(renderContext); | ||
var renderContext = { | ||
canvasContext: canvasContext, | ||
viewport: viewport | ||
}; | ||
_this3.renderer.then(_this3.onPageRender).catch(function (dismiss) { | ||
if (dismiss === 'cancelled') { | ||
// Everything's alright | ||
return; | ||
} | ||
// If another render is in progress, let's cancel it | ||
/* eslint-disable no-underscore-dangle */ | ||
if (_this3.renderer && _this3.renderer._internalRenderTask.running) { | ||
_this3.renderer._internalRenderTask.cancel(); | ||
} | ||
/* eslint-enable no-underscore-dangle */ | ||
_this3.onPageError(dismiss); | ||
}); | ||
} | ||
}); | ||
_this3.renderer = page.render(renderContext); | ||
_this3.renderer.then(_this3.onPageRender).catch(function (dismiss) { | ||
if (dismiss === 'cancelled') { | ||
// Everything's alright | ||
return; | ||
} | ||
_this3.onPageError(dismiss); | ||
}); | ||
} | ||
}]); | ||
}); | ||
} | ||
}]); | ||
return ReactPDF; | ||
}(Component); | ||
return ReactPDF; | ||
}(_react.Component); | ||
var _initialiseProps = function _initialiseProps() { | ||
var _this4 = this; | ||
var _this4 = this; | ||
this.state = { | ||
pdf: null, | ||
page: null | ||
}; | ||
this.state = { | ||
pdf: null, | ||
page: null | ||
}; | ||
this.onDocumentLoad = function (pdf) { | ||
_this4.callIfDefined(_this4.props.onDocumentLoad, { | ||
total: pdf.numPages | ||
}); | ||
this.onDocumentLoad = function (pdf) { | ||
_this4.callIfDefined(_this4.props.onDocumentLoad, { | ||
total: pdf.numPages | ||
}); | ||
_this4.setState({ pdf: pdf }); | ||
_this4.setState({ pdf: pdf }); | ||
_this4.loadPage(_this4.props.pageIndex); | ||
}; | ||
_this4.loadPage(_this4.props.pageIndex); | ||
}; | ||
this.onDocumentError = function (error) { | ||
_this4.callIfDefined(_this4.props.onDocumentError, error); | ||
this.onDocumentError = function (error) { | ||
_this4.callIfDefined(_this4.props.onDocumentError, error); | ||
_this4.setState({ pdf: false }); | ||
}; | ||
_this4.setState({ pdf: false }); | ||
}; | ||
this.onPageLoad = function (page) { | ||
var scale = _this4.getPageScale(page); | ||
this.onPageLoad = function (page) { | ||
var scale = _this4.getPageScale(page); | ||
_this4.callIfDefined(_this4.props.onPageLoad, { | ||
pageIndex: page.pageIndex, | ||
pageNumber: page.pageNumber, | ||
get width() { | ||
return page.view[2] * scale; | ||
}, | ||
get height() { | ||
return page.view[3] * scale; | ||
}, | ||
scale: scale, | ||
get originalWidth() { | ||
return page.view[2]; | ||
}, | ||
get originalHeight() { | ||
return page.view[3]; | ||
} | ||
}); | ||
_this4.callIfDefined(_this4.props.onPageLoad, { | ||
pageIndex: page.pageIndex, | ||
pageNumber: page.pageNumber, | ||
get width() { | ||
return page.view[2] * scale; | ||
}, | ||
get height() { | ||
return page.view[3] * scale; | ||
}, | ||
scale: scale, | ||
get originalWidth() { | ||
return page.view[2]; | ||
}, | ||
get originalHeight() { | ||
return page.view[3]; | ||
} | ||
}); | ||
_this4.setState({ page: page }); | ||
}; | ||
_this4.setState({ page: page }); | ||
}; | ||
this.onPageRender = function () { | ||
_this4.renderer = null; | ||
this.onPageRender = function () { | ||
_this4.renderer = null; | ||
_this4.callIfDefined(_this4.props.onPageRender); | ||
}; | ||
_this4.callIfDefined(_this4.props.onPageRender); | ||
}; | ||
this.onPageError = function (error) { | ||
_this4.callIfDefined(_this4.props.onPageError, error); | ||
this.onPageError = function (error) { | ||
_this4.callIfDefined(_this4.props.onPageError, error); | ||
_this4.setState({ page: false }); | ||
}; | ||
_this4.setState({ page: false }); | ||
}; | ||
this.callIfDefined = function (fn, args) { | ||
if (fn && typeof fn === 'function') { | ||
fn(args); | ||
} | ||
}; | ||
this.callIfDefined = function (fn, args) { | ||
if (fn && typeof fn === 'function') { | ||
fn(args); | ||
} | ||
}; | ||
this.displayCORSWarning = function () { | ||
// eslint-disable-next-line no-console | ||
console.warn('Loading PDF as base64 strings/URLs might not work on protocols other than HTTP/HTTPS. On Google Chrome, you can use --allow-file-access-from-files flag for debugging purposes.'); | ||
}; | ||
this.displayCORSWarning = function () { | ||
// eslint-disable-next-line no-console | ||
console.warn('Loading PDF as base64 strings/URLs might not work on protocols other than HTTP/HTTPS. On Google Chrome, you can use --allow-file-access-from-files flag for debugging purposes.'); | ||
}; | ||
this.isParameterObject = function (object) { | ||
return object && (typeof object === 'undefined' ? 'undefined' : _typeof(object)) === 'object' && ['file', 'range', 'url'].some(function (key) { | ||
return Object.keys(object).includes(key); | ||
}); | ||
}; | ||
this.isParameterObject = function (object) { | ||
return object && (typeof object === 'undefined' ? 'undefined' : _typeof(object)) === 'object' && ['file', 'range', 'url'].some(function (key) { | ||
return Object.keys(object).includes(key); | ||
}); | ||
}; | ||
this.isDataURI = function (str) { | ||
return (/^data:/.test(str) | ||
); | ||
}; | ||
this.isDataURI = function (str) { | ||
return (/^data:/.test(str) | ||
); | ||
}; | ||
this.dataURItoBlob = function (dataURI) { | ||
var byteString = void 0; | ||
if (dataURI.split(',')[0].indexOf('base64') >= 0) { | ||
byteString = atob(dataURI.split(',')[1]); | ||
} else { | ||
byteString = unescape(dataURI.split(',')[1]); | ||
} | ||
this.dataURItoBlob = function (dataURI) { | ||
var byteString = void 0; | ||
if (dataURI.split(',')[0].indexOf('base64') >= 0) { | ||
byteString = atob(dataURI.split(',')[1]); | ||
} else { | ||
byteString = unescape(dataURI.split(',')[1]); | ||
} | ||
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; | ||
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; | ||
var ia = new Uint8Array(byteString.length); | ||
for (var i = 0; i < byteString.length; i += 1) { | ||
ia[i] = byteString.charCodeAt(i); | ||
} | ||
var ia = new Uint8Array(byteString.length); | ||
for (var i = 0; i < byteString.length; i += 1) { | ||
ia[i] = byteString.charCodeAt(i); | ||
} | ||
return new Blob([ia], { type: mimeString }); | ||
}; | ||
return new Blob([ia], { type: mimeString }); | ||
}; | ||
}; | ||
export default ReactPDF; | ||
exports.default = ReactPDF; | ||
ReactPDF.defaultProps = { | ||
pageIndex: 0, | ||
scale: 1.0, | ||
error: 'Failed to load PDF file.', | ||
loading: 'Loading PDF…', | ||
noData: 'No PDF file specified.' | ||
pageIndex: 0, | ||
scale: 1.0, | ||
error: 'Failed to load PDF file.', | ||
loading: 'Loading PDF…', | ||
noData: 'No PDF file specified.' | ||
}; | ||
ReactPDF.propTypes = { | ||
error: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), | ||
file: PropTypes.oneOfType([PropTypes.string, PropTypes.instanceOf(File), PropTypes.instanceOf(Blob), PropTypes.shape({ | ||
data: PropTypes.object, | ||
httpHeaders: PropTypes.object, | ||
range: PropTypes.object, | ||
url: PropTypes.string | ||
})]), | ||
loading: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), | ||
noData: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), | ||
onDocumentError: PropTypes.func, | ||
onDocumentLoad: PropTypes.func, | ||
onPageError: PropTypes.func, | ||
onPageLoad: PropTypes.func, | ||
onPageRender: PropTypes.func, | ||
pageIndex: PropTypes.number, | ||
scale: PropTypes.number, | ||
width: PropTypes.number | ||
error: _react.PropTypes.oneOfType([_react.PropTypes.string, _react.PropTypes.node]), | ||
file: _react.PropTypes.oneOfType([_react.PropTypes.string, _react.PropTypes.instanceOf(File), _react.PropTypes.instanceOf(Blob), _react.PropTypes.shape({ | ||
data: _react.PropTypes.object, | ||
httpHeaders: _react.PropTypes.object, | ||
range: _react.PropTypes.object, | ||
url: _react.PropTypes.string | ||
})]), | ||
loading: _react.PropTypes.oneOfType([_react.PropTypes.string, _react.PropTypes.node]), | ||
noData: _react.PropTypes.oneOfType([_react.PropTypes.string, _react.PropTypes.node]), | ||
onDocumentError: _react.PropTypes.func, | ||
onDocumentLoad: _react.PropTypes.func, | ||
onPageError: _react.PropTypes.func, | ||
onPageLoad: _react.PropTypes.func, | ||
onPageRender: _react.PropTypes.func, | ||
pageIndex: _react.PropTypes.number, | ||
scale: _react.PropTypes.number, | ||
width: _react.PropTypes.number | ||
}; |
{ | ||
"name": "react-pdf", | ||
"version": "1.6.0", | ||
"version": "1.6.1", | ||
"description": "Easily display PDF files in your React application.", | ||
@@ -14,4 +14,3 @@ "main": "es5/react-pdf.js", | ||
"prepublish": "npm run build", | ||
"test": "npm run build-test && echo Open ./test/index.html", | ||
"watch": "webpack --watch" | ||
"test": "npm run eslint" | ||
}, | ||
@@ -39,3 +38,3 @@ "keywords": [ | ||
"dependencies": { | ||
"pdfjs-dist": "^1.7.244", | ||
"pdfjs-dist": "^1.7.339", | ||
"react": ">=15.0", | ||
@@ -45,18 +44,19 @@ "react-dom": ">=15.0" | ||
"devDependencies": { | ||
"babel": "^6.5.2", | ||
"babel-cli": "^6.22.2", | ||
"babel-core": "^6.22.1", | ||
"babel": "^6.23.0", | ||
"babel-cli": "^6.23.0", | ||
"babel-core": "^6.23.1", | ||
"babel-eslint": "^7.1.1", | ||
"babel-loader": "^6.2.10", | ||
"babel-plugin-transform-class-properties": "^6.22.0", | ||
"babel-loader": "^6.3.2", | ||
"babel-plugin-transform-class-properties": "^6.23.0", | ||
"babel-plugin-add-module-exports": "^0.2.1", | ||
"babel-preset-es2015": "^6.22.0", | ||
"babel-preset-react": "^6.22.0", | ||
"babel-preset-react": "^6.23.0", | ||
"babel-preset-stage-2": "^6.22.0", | ||
"css-loader": "^0.26.1", | ||
"eslint": "^3.15.0", | ||
"eslint-config-airbnb": "^14.0.0", | ||
"css-loader": "latest", | ||
"eslint": "^3.17.0", | ||
"eslint-config-airbnb": "^14.1.0", | ||
"eslint-plugin-class-property": "^1.0.3", | ||
"eslint-plugin-import": "^2.2.0", | ||
"eslint-plugin-jsx-a11y": "^3.0.2", | ||
"eslint-plugin-react": "^6.9.0", | ||
"eslint-plugin-jsx-a11y": "^4.0.0", | ||
"eslint-plugin-react": "^6.10.0", | ||
"file-loader": "latest", | ||
@@ -63,0 +63,0 @@ "less": "^2.7.2", |
@@ -8,73 +8,73 @@ import React, { Component } from 'react'; | ||
class Example extends Component { | ||
state = { | ||
file: './sample.pdf', | ||
pageIndex: null, | ||
pageNumber: null, | ||
total: null, | ||
} | ||
state = { | ||
file: './sample.pdf', | ||
pageIndex: null, | ||
pageNumber: null, | ||
total: null, | ||
} | ||
onFileChange = (event) => { | ||
this.setState({ | ||
file: event.target.files[0], | ||
}); | ||
} | ||
onFileChange = (event) => { | ||
this.setState({ | ||
file: event.target.files[0], | ||
}); | ||
} | ||
onDocumentLoad = ({ total }) => { | ||
this.setState({ total }); | ||
} | ||
onDocumentLoad = ({ total }) => { | ||
this.setState({ total }); | ||
} | ||
onPageLoad = ({ pageIndex, pageNumber }) => { | ||
this.setState({ pageIndex, pageNumber }); | ||
} | ||
onPageLoad = ({ pageIndex, pageNumber }) => { | ||
this.setState({ pageIndex, pageNumber }); | ||
} | ||
changePage(by) { | ||
this.setState(prevState => ({ | ||
pageIndex: prevState.pageIndex + by, | ||
})); | ||
} | ||
changePage(by) { | ||
this.setState(prevState => ({ | ||
pageIndex: prevState.pageIndex + by, | ||
})); | ||
} | ||
render() { | ||
const { file, pageIndex, pageNumber, total } = this.state; | ||
render() { | ||
const { file, pageIndex, pageNumber, total } = this.state; | ||
return ( | ||
<div className="Example"> | ||
<h1>react-pdf sample page</h1> | ||
<div className="Example__container"> | ||
<div className="Example__container__load"> | ||
<label htmlFor="file">Load from file:</label> | ||
<input | ||
type="file" | ||
onChange={this.onFileChange} | ||
/> | ||
</div> | ||
<div className="Example__container__preview"> | ||
<ReactPDF | ||
file={file} | ||
onDocumentLoad={this.onDocumentLoad} | ||
onPageLoad={this.onPageLoad} | ||
pageIndex={pageIndex} | ||
width={300} | ||
/> | ||
</div> | ||
<div className="Example__container__controls"> | ||
<button | ||
disabled={pageNumber <= 1} | ||
onClick={() => this.changePage(-1)} | ||
> | ||
Previous | ||
</button> | ||
<span>Page {pageNumber || '--'} of {total || '--'}</span> | ||
<button | ||
disabled={pageNumber >= total} | ||
onClick={() => this.changePage(1)} | ||
> | ||
Next | ||
</button> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
} | ||
return ( | ||
<div className="Example"> | ||
<h1>react-pdf sample page</h1> | ||
<div className="Example__container"> | ||
<div className="Example__container__load"> | ||
<label htmlFor="file">Load from file:</label> | ||
<input | ||
type="file" | ||
onChange={this.onFileChange} | ||
/> | ||
</div> | ||
<div className="Example__container__preview"> | ||
<ReactPDF | ||
file={file} | ||
onDocumentLoad={this.onDocumentLoad} | ||
onPageLoad={this.onPageLoad} | ||
pageIndex={pageIndex} | ||
width={300} | ||
/> | ||
</div> | ||
<div className="Example__container__controls"> | ||
<button | ||
disabled={pageNumber <= 1} | ||
onClick={() => this.changePage(-1)} | ||
> | ||
Previous | ||
</button> | ||
<span>Page {pageNumber || '--'} of {total || '--'}</span> | ||
<button | ||
disabled={pageNumber >= total} | ||
onClick={() => this.changePage(1)} | ||
> | ||
Next | ||
</button> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
} | ||
} | ||
ReactDOM.render(<Example />, document.getElementById('react-container')); |
@@ -12,13 +12,13 @@ import React, { Component } from 'react'; | ||
class WrappedReactPDF extends ReactPDF { | ||
componentDidMount() { | ||
super.componentDidMount(); | ||
} | ||
componentDidMount() { | ||
super.componentDidMount(); | ||
} | ||
componentWillReceiveProps(nextProps) { | ||
super.componentWillReceiveProps(nextProps); | ||
} | ||
componentWillReceiveProps(nextProps) { | ||
super.componentWillReceiveProps(nextProps); | ||
} | ||
componentWillUpdate() { | ||
componentRenderCount += 1; | ||
} | ||
componentWillUpdate() { | ||
componentRenderCount += 1; | ||
} | ||
} | ||
@@ -29,204 +29,204 @@ | ||
class Test extends Component { | ||
state = { | ||
file: null, | ||
pageIndex: null, | ||
pageNumber: null, | ||
passObj: false, | ||
pageRenderCount: 0, | ||
pageWidth: 300, | ||
total: null, | ||
} | ||
state = { | ||
file: null, | ||
pageIndex: null, | ||
pageNumber: null, | ||
passObj: false, | ||
pageRenderCount: 0, | ||
pageWidth: 300, | ||
total: null, | ||
} | ||
onFileChange = (event) => { | ||
this.setState({ | ||
file: event.target.files[0], | ||
}); | ||
} | ||
onFileChange = (event) => { | ||
this.setState({ | ||
file: event.target.files[0], | ||
}); | ||
} | ||
onFileUintChange = (event) => { | ||
const reader = new FileReader(); | ||
onFileUintChange = (event) => { | ||
const reader = new FileReader(); | ||
reader.onloadend = () => { | ||
this.setState({ | ||
file: reader.result, | ||
}); | ||
}; | ||
reader.onloadend = () => { | ||
this.setState({ | ||
file: reader.result, | ||
}); | ||
}; | ||
reader.readAsArrayBuffer(event.target.files[0]); | ||
} | ||
reader.readAsArrayBuffer(event.target.files[0]); | ||
} | ||
onURLChange = (event) => { | ||
event.preventDefault(); | ||
onURLChange = (event) => { | ||
event.preventDefault(); | ||
const url = event.target.querySelector('input').value; | ||
const url = event.target.querySelector('input').value; | ||
if (!url) { | ||
return; | ||
} | ||
this.setState({ | ||
file: url, | ||
}); | ||
if (!url) { | ||
return; | ||
} | ||
onRequestChange = (event) => { | ||
event.preventDefault(); | ||
this.setState({ | ||
file: url, | ||
}); | ||
} | ||
const url = event.target.querySelector('input').value; | ||
onRequestChange = (event) => { | ||
event.preventDefault(); | ||
if (!url) { | ||
return; | ||
} | ||
const url = event.target.querySelector('input').value; | ||
fetch(url).then(response => response.blob()).then((blob) => { | ||
this.setState({ | ||
file: blob, | ||
}); | ||
}); | ||
if (!url) { | ||
return; | ||
} | ||
onUseImported = () => { | ||
this.setState({ | ||
file: samplePDF, | ||
}); | ||
} | ||
fetch(url).then(response => response.blob()).then((blob) => { | ||
this.setState({ | ||
file: blob, | ||
}); | ||
}); | ||
} | ||
onPassObjChange = (event) => { | ||
this.setState({ passObj: event.target.checked }); | ||
} | ||
onUseImported = () => { | ||
this.setState({ | ||
file: samplePDF, | ||
}); | ||
} | ||
onPageWidthChange = (event) => { | ||
const width = event.target.value; | ||
onPassObjChange = (event) => { | ||
this.setState({ passObj: event.target.checked }); | ||
} | ||
if (!width) { | ||
return; | ||
} | ||
onPageWidthChange = (event) => { | ||
const width = event.target.value; | ||
this.setState({ | ||
pageWidth: parseInt(width, 10), | ||
}); | ||
if (!width) { | ||
return; | ||
} | ||
onDocumentLoad = ({ total }) => { | ||
this.setState({ total }); | ||
} | ||
this.setState({ | ||
pageWidth: parseInt(width, 10), | ||
}); | ||
} | ||
onDocumentError = ({ message }) => { | ||
// eslint-disable-next-line no-console | ||
console.error(message); | ||
} | ||
onDocumentLoad = ({ total }) => { | ||
this.setState({ total }); | ||
} | ||
onPageLoad = ({ pageIndex, pageNumber }) => { | ||
this.setState({ pageIndex, pageNumber }); | ||
} | ||
onDocumentError = ({ message }) => { | ||
// eslint-disable-next-line no-console | ||
console.error(message); | ||
} | ||
onPageRender = () => { | ||
this.setState({ pageRenderCount: (this.state.pageRenderCount + 1) }); | ||
} | ||
onPageLoad = ({ pageIndex, pageNumber }) => { | ||
this.setState({ pageIndex, pageNumber }); | ||
} | ||
get transformedFile() { | ||
if (!this.state.passObj) { | ||
return this.state.file; | ||
} | ||
onPageRender = () => { | ||
this.setState({ pageRenderCount: (this.state.pageRenderCount + 1) }); | ||
} | ||
const result = {}; | ||
if (typeof this.state.file === 'string') { | ||
result.url = this.state.file; | ||
} else { | ||
return this.state.file; | ||
} | ||
return result; | ||
get transformedFile() { | ||
if (!this.state.passObj) { | ||
return this.state.file; | ||
} | ||
changePage(by) { | ||
this.setState(prevState => ({ | ||
pageIndex: prevState.pageIndex + by, | ||
})); | ||
const result = {}; | ||
if (typeof this.state.file === 'string') { | ||
result.url = this.state.file; | ||
} else { | ||
return this.state.file; | ||
} | ||
return result; | ||
} | ||
render() { | ||
const { pageIndex, pageNumber, pageRenderCount, pageWidth, total } = this.state; | ||
changePage(by) { | ||
this.setState(prevState => ({ | ||
pageIndex: prevState.pageIndex + by, | ||
})); | ||
} | ||
return ( | ||
<div className="Example"> | ||
<h1>react-pdf test page</h1> | ||
<div className="Example__container"> | ||
<div className="Example__container__load"> | ||
<label htmlFor="file">Load from file:</label> | ||
<input | ||
type="file" | ||
onChange={this.onFileChange} | ||
/> | ||
<br /><br /> | ||
<label htmlFor="file">Load from file to Uint8Array:</label> | ||
<input | ||
type="file" | ||
onChange={this.onFileUintChange} | ||
/> | ||
<br /><br /> | ||
<form onSubmit={this.onURLChange}> | ||
<label htmlFor="url">Load from URL:</label> | ||
<input type="text" /> | ||
<button type="submit">Apply</button> | ||
</form> | ||
<br /> | ||
<form onSubmit={this.onRequestChange}> | ||
<label htmlFor="url">Fetch and pass:</label> | ||
<input type="text" /> | ||
<button type="submit">Apply</button> | ||
</form> | ||
<br /> | ||
<button onClick={this.onUseImported}>Use imported file</button> | ||
<br /><br /> | ||
<input id="passobj" type="checkbox" onChange={this.onPassObjChange} /> | ||
<label htmlFor="passobj">Pass as an object (URLs and imports only)</label> | ||
<br /> | ||
<br /> | ||
<form onSubmit={this.onPageWidthChange}> | ||
<label htmlFor="pageWidth">Page width:</label> | ||
<input | ||
type="number" | ||
value={pageWidth} | ||
onChange={this.onPageWidthChange} | ||
/> | ||
</form> | ||
<br /> | ||
</div> | ||
<div className="Example__container__preview"> | ||
<div className="Example__container__preview__out"> | ||
<WrappedReactPDF | ||
file={this.transformedFile} | ||
onDocumentLoad={this.onDocumentLoad} | ||
onPageLoad={this.onPageLoad} | ||
onPageRender={this.onPageRender} | ||
pageIndex={pageIndex} | ||
width={pageWidth} | ||
/> | ||
</div> | ||
<div className="Example__container__preview__controls"> | ||
<button | ||
disabled={pageNumber <= 1} | ||
onClick={() => this.changePage(-1)} | ||
> | ||
Previous | ||
</button> | ||
<span>Page {pageNumber || '--'} of {total || '--'}</span> | ||
<button | ||
disabled={pageNumber >= total} | ||
onClick={() => this.changePage(1)} | ||
> | ||
Next | ||
</button> | ||
</div> | ||
<div className="Example__container__preview__info"> | ||
Page render count: {pageRenderCount}<br /> | ||
Component render count: {componentRenderCount} | ||
</div> | ||
</div> | ||
</div> | ||
render() { | ||
const { pageIndex, pageNumber, pageRenderCount, pageWidth, total } = this.state; | ||
return ( | ||
<div className="Example"> | ||
<h1>react-pdf test page</h1> | ||
<div className="Example__container"> | ||
<div className="Example__container__load"> | ||
<label htmlFor="file">Load from file:</label> | ||
<input | ||
type="file" | ||
onChange={this.onFileChange} | ||
/> | ||
<br /><br /> | ||
<label htmlFor="file">Load from file to Uint8Array:</label> | ||
<input | ||
type="file" | ||
onChange={this.onFileUintChange} | ||
/> | ||
<br /><br /> | ||
<form onSubmit={this.onURLChange}> | ||
<label htmlFor="url">Load from URL:</label> | ||
<input type="text" /> | ||
<button type="submit">Apply</button> | ||
</form> | ||
<br /> | ||
<form onSubmit={this.onRequestChange}> | ||
<label htmlFor="url">Fetch and pass:</label> | ||
<input type="text" /> | ||
<button type="submit">Apply</button> | ||
</form> | ||
<br /> | ||
<button onClick={this.onUseImported}>Use imported file</button> | ||
<br /><br /> | ||
<input id="passobj" type="checkbox" onChange={this.onPassObjChange} /> | ||
<label htmlFor="passobj">Pass as an object (URLs and imports only)</label> | ||
<br /> | ||
<br /> | ||
<form onSubmit={this.onPageWidthChange}> | ||
<label htmlFor="pageWidth">Page width:</label> | ||
<input | ||
type="number" | ||
value={pageWidth} | ||
onChange={this.onPageWidthChange} | ||
/> | ||
</form> | ||
<br /> | ||
</div> | ||
<div className="Example__container__preview"> | ||
<div className="Example__container__preview__out"> | ||
<WrappedReactPDF | ||
file={this.transformedFile} | ||
onDocumentLoad={this.onDocumentLoad} | ||
onPageLoad={this.onPageLoad} | ||
onPageRender={this.onPageRender} | ||
pageIndex={pageIndex} | ||
width={pageWidth} | ||
/> | ||
</div> | ||
); | ||
} | ||
<div className="Example__container__preview__controls"> | ||
<button | ||
disabled={pageNumber <= 1} | ||
onClick={() => this.changePage(-1)} | ||
> | ||
Previous | ||
</button> | ||
<span>Page {pageNumber || '--'} of {total || '--'}</span> | ||
<button | ||
disabled={pageNumber >= total} | ||
onClick={() => this.changePage(1)} | ||
> | ||
Next | ||
</button> | ||
</div> | ||
<div className="Example__container__preview__info"> | ||
Page render count: {pageRenderCount}<br /> | ||
Component render count: {componentRenderCount} | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
} | ||
} | ||
ReactDOM.render(<Test />, document.getElementById('react-container')); |
@@ -10,397 +10,397 @@ import React, { Component, PropTypes } from 'react'; | ||
export default class ReactPDF extends Component { | ||
state = { | ||
pdf: null, | ||
page: null, | ||
state = { | ||
pdf: null, | ||
page: null, | ||
} | ||
componentDidMount() { | ||
this.handleFileLoad(); | ||
} | ||
componentWillReceiveProps(nextProps) { | ||
if (this.isParameterObject(nextProps.file)) { | ||
// File is a parameter object | ||
if ( | ||
(nextProps.file && !this.props.file) || | ||
nextProps.file.data !== this.props.file.data || | ||
nextProps.file.range !== this.props.file.range || | ||
nextProps.file.url !== this.props.file.url | ||
) { | ||
this.handleFileLoad(nextProps); | ||
return; | ||
} | ||
} else if (nextProps.file && nextProps.file !== this.props.file) { | ||
// File is a normal object or not an object at all | ||
this.handleFileLoad(nextProps); | ||
return; | ||
} | ||
componentDidMount() { | ||
this.handleFileLoad(); | ||
if ( | ||
this.state.pdf && | ||
typeof nextProps.pageIndex !== 'undefined' && | ||
nextProps.pageIndex !== this.props.pageIndex | ||
) { | ||
this.loadPage(nextProps.pageIndex); | ||
} | ||
} | ||
componentWillReceiveProps(nextProps) { | ||
if (this.isParameterObject(nextProps.file)) { | ||
// File is a parameter object | ||
if ( | ||
(nextProps.file && !this.props.file) || | ||
nextProps.file.data !== this.props.file.data || | ||
nextProps.file.range !== this.props.file.range || | ||
nextProps.file.url !== this.props.file.url | ||
) { | ||
this.handleFileLoad(nextProps); | ||
return; | ||
} | ||
} else if (nextProps.file && nextProps.file !== this.props.file) { | ||
// File is a normal object or not an object at all | ||
this.handleFileLoad(nextProps); | ||
return; | ||
} | ||
shouldComponentUpdate(nextProps, nextState) { | ||
return ( | ||
nextState.pdf !== this.state.pdf || | ||
nextState.page !== this.state.page || | ||
nextProps.width !== this.props.width || | ||
nextProps.scale !== this.props.scale | ||
); | ||
} | ||
if ( | ||
this.state.pdf && | ||
typeof nextProps.pageIndex !== 'undefined' && | ||
nextProps.pageIndex !== this.props.pageIndex | ||
) { | ||
this.loadPage(nextProps.pageIndex); | ||
} | ||
} | ||
/** | ||
* Called when a document is loaded successfully. | ||
*/ | ||
onDocumentLoad = (pdf) => { | ||
this.callIfDefined( | ||
this.props.onDocumentLoad, | ||
{ | ||
total: pdf.numPages, | ||
}, | ||
); | ||
shouldComponentUpdate(nextProps, nextState) { | ||
return ( | ||
nextState.pdf !== this.state.pdf || | ||
nextState.page !== this.state.page || | ||
nextProps.width !== this.props.width || | ||
nextProps.scale !== this.props.scale | ||
); | ||
} | ||
this.setState({ pdf }); | ||
/** | ||
* Called when a document is loaded successfully. | ||
*/ | ||
onDocumentLoad = (pdf) => { | ||
this.callIfDefined( | ||
this.props.onDocumentLoad, | ||
{ | ||
total: pdf.numPages, | ||
}, | ||
); | ||
this.loadPage(this.props.pageIndex); | ||
} | ||
this.setState({ pdf }); | ||
/** | ||
* Called when a document fails to load. | ||
*/ | ||
onDocumentError = (error) => { | ||
this.callIfDefined( | ||
this.props.onDocumentError, | ||
error, | ||
); | ||
this.loadPage(this.props.pageIndex); | ||
} | ||
this.setState({ pdf: false }); | ||
} | ||
/** | ||
* Called when a document fails to load. | ||
*/ | ||
onDocumentError = (error) => { | ||
this.callIfDefined( | ||
this.props.onDocumentError, | ||
error, | ||
); | ||
/** | ||
* Called when a page is loaded successfully. | ||
*/ | ||
onPageLoad = (page) => { | ||
const scale = this.getPageScale(page); | ||
this.setState({ pdf: false }); | ||
} | ||
this.callIfDefined( | ||
this.props.onPageLoad, | ||
{ | ||
pageIndex: page.pageIndex, | ||
pageNumber: page.pageNumber, | ||
get width() { return page.view[2] * scale; }, | ||
get height() { return page.view[3] * scale; }, | ||
scale, | ||
get originalWidth() { return page.view[2]; }, | ||
get originalHeight() { return page.view[3]; }, | ||
}, | ||
); | ||
/** | ||
* Called when a page is loaded successfully. | ||
*/ | ||
onPageLoad = (page) => { | ||
const scale = this.getPageScale(page); | ||
this.setState({ page }); | ||
} | ||
this.callIfDefined( | ||
this.props.onPageLoad, | ||
{ | ||
pageIndex: page.pageIndex, | ||
pageNumber: page.pageNumber, | ||
get width() { return page.view[2] * scale; }, | ||
get height() { return page.view[3] * scale; }, | ||
scale, | ||
get originalWidth() { return page.view[2]; }, | ||
get originalHeight() { return page.view[3]; }, | ||
}, | ||
); | ||
/** | ||
* Called when a page is rendered successfully. | ||
*/ | ||
onPageRender = () => { | ||
this.renderer = null; | ||
this.setState({ page }); | ||
} | ||
this.callIfDefined(this.props.onPageRender); | ||
} | ||
/** | ||
* Called when a page is rendered successfully. | ||
*/ | ||
onPageRender = () => { | ||
this.renderer = null; | ||
/** | ||
* Called when a page fails to load or render. | ||
*/ | ||
onPageError = (error) => { | ||
this.callIfDefined( | ||
this.props.onPageError, | ||
error, | ||
); | ||
this.callIfDefined(this.props.onPageRender); | ||
this.setState({ page: false }); | ||
} | ||
getPageScale(page = this.state.page) { | ||
const { scale, width } = this.props; | ||
// Be default, we'll render page at 100% * scale width. | ||
let pageScale = 1; | ||
// If width is defined, calculate the scale of the page so it could be of desired width. | ||
if (width) { | ||
pageScale = width / page.getViewport(scale).width; | ||
} | ||
/** | ||
* Called when a page fails to load or render. | ||
*/ | ||
onPageError = (error) => { | ||
this.callIfDefined( | ||
this.props.onPageError, | ||
error, | ||
); | ||
return scale * pageScale; | ||
} | ||
this.setState({ page: false }); | ||
callIfDefined = (fn, args) => { | ||
if (fn && typeof fn === 'function') { | ||
fn(args); | ||
} | ||
} | ||
getPageScale(page = this.state.page) { | ||
const { scale, width } = this.props; | ||
displayCORSWarning = () => { | ||
// eslint-disable-next-line no-console | ||
console.warn('Loading PDF as base64 strings/URLs might not work on protocols other than HTTP/HTTPS. On Google Chrome, you can use --allow-file-access-from-files flag for debugging purposes.'); | ||
} | ||
// Be default, we'll render page at 100% * scale width. | ||
let pageScale = 1; | ||
isParameterObject = object => | ||
object && | ||
typeof object === 'object' && | ||
['file', 'range', 'url'].some(key => Object.keys(object).includes(key)) | ||
// If width is defined, calculate the scale of the page so it could be of desired width. | ||
if (width) { | ||
pageScale = width / page.getViewport(scale).width; | ||
} | ||
isDataURI = str => /^data:/.test(str) | ||
return scale * pageScale; | ||
dataURItoBlob = (dataURI) => { | ||
let byteString; | ||
if (dataURI.split(',')[0].indexOf('base64') >= 0) { | ||
byteString = atob(dataURI.split(',')[1]); | ||
} else { | ||
byteString = unescape(dataURI.split(',')[1]); | ||
} | ||
callIfDefined = (fn, args) => { | ||
if (fn && typeof fn === 'function') { | ||
fn(args); | ||
} | ||
} | ||
const mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; | ||
displayCORSWarning = () => { | ||
// eslint-disable-next-line no-console | ||
console.warn('Loading PDF as base64 strings/URLs might not work on protocols other than HTTP/HTTPS. On Google Chrome, you can use --allow-file-access-from-files flag for debugging purposes.'); | ||
const ia = new Uint8Array(byteString.length); | ||
for (let i = 0; i < byteString.length; i += 1) { | ||
ia[i] = byteString.charCodeAt(i); | ||
} | ||
isParameterObject = object => | ||
object && | ||
typeof object === 'object' && | ||
['file', 'range', 'url'].some(key => Object.keys(object).includes(key)) | ||
return new Blob([ia], { type: mimeString }); | ||
} | ||
isDataURI = str => /^data:/.test(str) | ||
handleFileLoad(props = this.props) { | ||
let { file } = props; | ||
dataURItoBlob = (dataURI) => { | ||
let byteString; | ||
if (dataURI.split(',')[0].indexOf('base64') >= 0) { | ||
byteString = atob(dataURI.split(',')[1]); | ||
} else { | ||
byteString = unescape(dataURI.split(',')[1]); | ||
} | ||
if ( | ||
!file || | ||
( | ||
this.isParameterObject(file) && | ||
!file.data && !file.range && !file.url | ||
) | ||
) { | ||
return null; | ||
} | ||
const mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; | ||
this.setState({ | ||
page: null, | ||
pdf: null, | ||
}); | ||
const ia = new Uint8Array(byteString.length); | ||
for (let i = 0; i < byteString.length; i += 1) { | ||
ia[i] = byteString.charCodeAt(i); | ||
// File is a string | ||
if (typeof file === 'string') { | ||
// File is not data URI | ||
if (!this.isDataURI(file)) { | ||
if (window.location.protocol === 'file:') { | ||
this.displayCORSWarning(); | ||
} | ||
return new Blob([ia], { type: mimeString }); | ||
} | ||
return this.loadDocument(file); | ||
} | ||
handleFileLoad(props = this.props) { | ||
let { file } = props; | ||
// File is data URI | ||
file = this.dataURItoBlob(file); | ||
if ( | ||
!file || | ||
( | ||
this.isParameterObject(file) && | ||
!file.data && !file.range && !file.url | ||
) | ||
) { | ||
return null; | ||
} | ||
// Fall through to "File is a blob" | ||
} | ||
this.setState({ | ||
page: null, | ||
pdf: null, | ||
}); | ||
// File is a Blob | ||
if (file instanceof Blob) { | ||
file = URL.createObjectURL(file); | ||
// File is a string | ||
if (typeof file === 'string') { | ||
// File is not data URI | ||
if (!this.isDataURI(file)) { | ||
if (window.location.protocol === 'file:') { | ||
this.displayCORSWarning(); | ||
} | ||
return this.loadDocument(file); | ||
} | ||
return this.loadDocument(file); | ||
} | ||
// File is a File | ||
if (file instanceof File) { | ||
const reader = new FileReader(); | ||
// File is data URI | ||
file = this.dataURItoBlob(file); | ||
reader.onloadend = () => { | ||
this.loadDocument(new Uint8Array(reader.result)); | ||
}; | ||
// Fall through to "File is a blob" | ||
} | ||
return reader.readAsArrayBuffer(file); | ||
} | ||
// File is a Blob | ||
if (file instanceof Blob) { | ||
file = URL.createObjectURL(file); | ||
// File is an ArrayBuffer | ||
if (file instanceof ArrayBuffer) { | ||
return this.loadDocument(file); | ||
} | ||
return this.loadDocument(file); | ||
} | ||
// File is a parameter object | ||
if (this.isParameterObject(file)) { | ||
if ( | ||
file.url && | ||
window.location.protocol === 'file:' | ||
) { | ||
this.displayCORSWarning(); | ||
} | ||
// File is a File | ||
if (file instanceof File) { | ||
const reader = new FileReader(); | ||
// Prevent from modifying props | ||
file = Object.assign({}, file); | ||
reader.onloadend = () => { | ||
this.loadDocument(new Uint8Array(reader.result)); | ||
}; | ||
// File is data URI | ||
if (file.url && this.isDataURI(file.url)) { | ||
file = URL.createObjectURL(this.dataURItoBlob(file.url)); | ||
} | ||
return reader.readAsArrayBuffer(file); | ||
} | ||
return this.loadDocument(file); | ||
} | ||
// File is an ArrayBuffer | ||
if (file instanceof ArrayBuffer) { | ||
return this.loadDocument(file); | ||
} | ||
throw new Error('Unrecognized input type.'); | ||
} | ||
// File is a parameter object | ||
if (this.isParameterObject(file)) { | ||
if ( | ||
file.url && | ||
window.location.protocol === 'file:' | ||
) { | ||
this.displayCORSWarning(); | ||
} | ||
loadDocument(...args) { | ||
PDFJS.getDocument(...args) | ||
.then(this.onDocumentLoad) | ||
.catch(this.onDocumentError); | ||
} | ||
// Prevent from modifying props | ||
file = Object.assign({}, file); | ||
loadPage(pageIndex) { | ||
const { pdf } = this.state; | ||
// File is data URI | ||
if (file.url && this.isDataURI(file.url)) { | ||
file = URL.createObjectURL(this.dataURItoBlob(file.url)); | ||
} | ||
if (!pdf) { | ||
throw new Error('Unexpected call to getPage() before the document has been loaded.'); | ||
} | ||
return this.loadDocument(file); | ||
} | ||
let pageNumber = pageIndex + 1; | ||
throw new Error('Unrecognized input type.'); | ||
if (!pageIndex || pageNumber < 1) { | ||
pageNumber = 1; | ||
} else if (pageNumber >= pdf.numPages) { | ||
pageNumber = pdf.numPages; | ||
} | ||
loadDocument(...args) { | ||
PDFJS.getDocument(...args) | ||
.then(this.onDocumentLoad) | ||
.catch(this.onDocumentError); | ||
} | ||
pdf.getPage(pageNumber) | ||
.then(this.onPageLoad) | ||
.catch(this.onPageError); | ||
} | ||
loadPage(pageIndex) { | ||
const { pdf } = this.state; | ||
renderNoData() { | ||
return ( | ||
<div>{this.props.noData}</div> | ||
); | ||
} | ||
if (!pdf) { | ||
throw new Error('Unexpected call to getPage() before the document has been loaded.'); | ||
} | ||
renderError() { | ||
return ( | ||
<div>{this.props.error}</div> | ||
); | ||
} | ||
let pageNumber = pageIndex + 1; | ||
renderLoader() { | ||
return ( | ||
<div>{this.props.loading}</div> | ||
); | ||
} | ||
if (!pageIndex || pageNumber < 1) { | ||
pageNumber = 1; | ||
} else if (pageNumber >= pdf.numPages) { | ||
pageNumber = pdf.numPages; | ||
} | ||
render() { | ||
const { file } = this.props; | ||
const { pdf, page } = this.state; | ||
pdf.getPage(pageNumber) | ||
.then(this.onPageLoad) | ||
.catch(this.onPageError); | ||
if (!file) { | ||
return this.renderNoData(); | ||
} | ||
renderNoData() { | ||
return ( | ||
<div>{this.props.noData}</div> | ||
); | ||
if (pdf === false || page === false) { | ||
return this.renderError(); | ||
} | ||
renderError() { | ||
return ( | ||
<div>{this.props.error}</div> | ||
); | ||
if (pdf === null || page === null) { | ||
return this.renderLoader(); | ||
} | ||
renderLoader() { | ||
return ( | ||
<div>{this.props.loading}</div> | ||
); | ||
} | ||
return ( | ||
<canvas | ||
ref={(ref) => { | ||
if (!ref) return; | ||
render() { | ||
const { file } = this.props; | ||
const { pdf, page } = this.state; | ||
const canvas = ref; | ||
if (!file) { | ||
return this.renderNoData(); | ||
} | ||
const pixelRatio = window.devicePixelRatio || 1; | ||
const viewport = page.getViewport(this.getPageScale() * pixelRatio); | ||
if (pdf === false || page === false) { | ||
return this.renderError(); | ||
} | ||
canvas.height = viewport.height; | ||
canvas.width = viewport.width; | ||
if (pdf === null || page === null) { | ||
return this.renderLoader(); | ||
} | ||
canvas.style.height = `${viewport.height / pixelRatio}px`; | ||
canvas.style.width = `${viewport.width / pixelRatio}px`; | ||
return ( | ||
<canvas | ||
ref={(ref) => { | ||
if (!ref) return; | ||
const canvasContext = canvas.getContext('2d'); | ||
const canvas = ref; | ||
const renderContext = { | ||
canvasContext, | ||
viewport, | ||
}; | ||
const pixelRatio = window.devicePixelRatio || 1; | ||
const viewport = page.getViewport(this.getPageScale() * pixelRatio); | ||
// If another render is in progress, let's cancel it | ||
/* eslint-disable no-underscore-dangle */ | ||
if (this.renderer && this.renderer._internalRenderTask.running) { | ||
this.renderer._internalRenderTask.cancel(); | ||
} | ||
/* eslint-enable no-underscore-dangle */ | ||
canvas.height = viewport.height; | ||
canvas.width = viewport.width; | ||
this.renderer = page.render(renderContext); | ||
canvas.style.height = `${viewport.height / pixelRatio}px`; | ||
canvas.style.width = `${viewport.width / pixelRatio}px`; | ||
this.renderer | ||
.then(this.onPageRender) | ||
.catch((dismiss) => { | ||
if (dismiss === 'cancelled') { | ||
// Everything's alright | ||
return; | ||
} | ||
const canvasContext = canvas.getContext('2d'); | ||
const renderContext = { | ||
canvasContext, | ||
viewport, | ||
}; | ||
// If another render is in progress, let's cancel it | ||
/* eslint-disable no-underscore-dangle */ | ||
if (this.renderer && this.renderer._internalRenderTask.running) { | ||
this.renderer._internalRenderTask.cancel(); | ||
} | ||
/* eslint-enable no-underscore-dangle */ | ||
this.renderer = page.render(renderContext); | ||
this.renderer | ||
.then(this.onPageRender) | ||
.catch((dismiss) => { | ||
if (dismiss === 'cancelled') { | ||
// Everything's alright | ||
return; | ||
} | ||
this.onPageError(dismiss); | ||
}); | ||
}} | ||
/> | ||
); | ||
} | ||
this.onPageError(dismiss); | ||
}); | ||
}} | ||
/> | ||
); | ||
} | ||
} | ||
ReactPDF.defaultProps = { | ||
pageIndex: 0, | ||
scale: 1.0, | ||
error: 'Failed to load PDF file.', | ||
loading: 'Loading PDF…', | ||
noData: 'No PDF file specified.', | ||
pageIndex: 0, | ||
scale: 1.0, | ||
error: 'Failed to load PDF file.', | ||
loading: 'Loading PDF…', | ||
noData: 'No PDF file specified.', | ||
}; | ||
ReactPDF.propTypes = { | ||
error: PropTypes.oneOfType([ | ||
PropTypes.string, | ||
PropTypes.node, | ||
]), | ||
file: PropTypes.oneOfType([ | ||
PropTypes.string, | ||
PropTypes.instanceOf(File), | ||
PropTypes.instanceOf(Blob), | ||
PropTypes.shape({ | ||
data: PropTypes.object, | ||
httpHeaders: PropTypes.object, | ||
range: PropTypes.object, | ||
url: PropTypes.string, | ||
}), | ||
]), | ||
loading: PropTypes.oneOfType([ | ||
PropTypes.string, | ||
PropTypes.node, | ||
]), | ||
noData: PropTypes.oneOfType([ | ||
PropTypes.string, | ||
PropTypes.node, | ||
]), | ||
onDocumentError: PropTypes.func, | ||
onDocumentLoad: PropTypes.func, | ||
onPageError: PropTypes.func, | ||
onPageLoad: PropTypes.func, | ||
onPageRender: PropTypes.func, | ||
pageIndex: PropTypes.number, | ||
scale: PropTypes.number, | ||
width: PropTypes.number, | ||
error: PropTypes.oneOfType([ | ||
PropTypes.string, | ||
PropTypes.node, | ||
]), | ||
file: PropTypes.oneOfType([ | ||
PropTypes.string, | ||
PropTypes.instanceOf(File), | ||
PropTypes.instanceOf(Blob), | ||
PropTypes.shape({ | ||
data: PropTypes.object, | ||
httpHeaders: PropTypes.object, | ||
range: PropTypes.object, | ||
url: PropTypes.string, | ||
}), | ||
]), | ||
loading: PropTypes.oneOfType([ | ||
PropTypes.string, | ||
PropTypes.node, | ||
]), | ||
noData: PropTypes.oneOfType([ | ||
PropTypes.string, | ||
PropTypes.node, | ||
]), | ||
onDocumentError: PropTypes.func, | ||
onDocumentLoad: PropTypes.func, | ||
onPageError: PropTypes.func, | ||
onPageLoad: PropTypes.func, | ||
onPageRender: PropTypes.func, | ||
pageIndex: PropTypes.number, | ||
scale: PropTypes.number, | ||
width: PropTypes.number, | ||
}; |
const webpack = require('webpack'); | ||
module.exports = { | ||
context: __dirname, | ||
entry: [ | ||
'./src-sample/index.html', | ||
'./src-sample/sample.jsx', | ||
'./src-sample/sample.pdf', | ||
], | ||
output: { | ||
path: './sample', | ||
filename: 'sample.js', | ||
chunkFilename: 'sample.js', | ||
}, | ||
resolve: { | ||
extensions: ['.js', '.jsx'], | ||
}, | ||
module: { | ||
rules: [ | ||
{ | ||
test: /\.html$/, | ||
use: 'file-loader?name=[name].[ext]', | ||
}, | ||
{ | ||
test: /\.pdf$/, | ||
use: 'url-loader', | ||
}, | ||
{ | ||
test: /\.less$/, | ||
use: [ | ||
'style-loader', | ||
'css-loader', | ||
'less-loader', | ||
], | ||
}, | ||
{ | ||
test: /\.(js|jsx)$/, | ||
exclude: /node_modules/, | ||
use: 'babel-loader', | ||
}, | ||
context: __dirname, | ||
entry: [ | ||
'./src-sample/index.html', | ||
'./src-sample/sample.jsx', | ||
'./src-sample/sample.pdf', | ||
], | ||
output: { | ||
path: './sample', | ||
filename: 'sample.js', | ||
chunkFilename: 'sample.js', | ||
}, | ||
resolve: { | ||
extensions: ['.js', '.jsx'], | ||
}, | ||
module: { | ||
rules: [ | ||
{ | ||
test: /\.html$/, | ||
use: 'file-loader?name=[name].[ext]', | ||
}, | ||
{ | ||
test: /\.pdf$/, | ||
use: 'url-loader', | ||
}, | ||
{ | ||
test: /\.less$/, | ||
use: [ | ||
'style-loader', | ||
'css-loader', | ||
'less-loader', | ||
], | ||
}, | ||
plugins: [ | ||
new webpack.DefinePlugin({ | ||
'process.env': { | ||
NODE_ENV: JSON.stringify('production'), | ||
}, | ||
}), | ||
new webpack.optimize.UglifyJsPlugin(), | ||
}, | ||
{ | ||
test: /\.(js|jsx)$/, | ||
exclude: /node_modules/, | ||
use: 'babel-loader', | ||
}, | ||
], | ||
}, | ||
plugins: [ | ||
new webpack.DefinePlugin({ | ||
'process.env': { | ||
NODE_ENV: JSON.stringify('production'), | ||
}, | ||
}), | ||
new webpack.optimize.UglifyJsPlugin(), | ||
], | ||
}; |
module.exports = { | ||
context: __dirname, | ||
devtool: 'source-map', | ||
entry: [ | ||
'./src-test/index.html', | ||
'./src-test/test.jsx', | ||
'./src-test/test.pdf', | ||
context: __dirname, | ||
devtool: 'source-map', | ||
entry: [ | ||
'./src-test/index.html', | ||
'./src-test/test.jsx', | ||
'./src-test/test.pdf', | ||
], | ||
output: { | ||
path: './test', | ||
filename: 'test.js', | ||
chunkFilename: 'test.js', | ||
}, | ||
resolve: { | ||
extensions: ['.js', '.jsx'], | ||
}, | ||
module: { | ||
rules: [ | ||
{ | ||
test: /\.html$/, | ||
use: 'file-loader?name=[name].[ext]', | ||
}, | ||
{ | ||
test: /\.pdf$/, | ||
use: 'url-loader', | ||
}, | ||
{ | ||
test: /\.less$/, | ||
use: [ | ||
'style-loader', | ||
'css-loader', | ||
'less-loader', | ||
], | ||
}, | ||
{ | ||
test: /\.(js|jsx)$/, | ||
exclude: /node_modules/, | ||
use: 'babel-loader', | ||
}, | ||
], | ||
output: { | ||
path: './test', | ||
filename: 'test.js', | ||
chunkFilename: 'test.js', | ||
}, | ||
resolve: { | ||
extensions: ['.js', '.jsx'], | ||
}, | ||
module: { | ||
rules: [ | ||
{ | ||
test: /\.html$/, | ||
use: 'file-loader?name=[name].[ext]', | ||
}, | ||
{ | ||
test: /\.pdf$/, | ||
use: 'url-loader', | ||
}, | ||
{ | ||
test: /\.less$/, | ||
use: [ | ||
'style-loader', | ||
'css-loader', | ||
'less-loader', | ||
], | ||
}, | ||
{ | ||
test: /\.(js|jsx)$/, | ||
exclude: /node_modules/, | ||
use: 'babel-loader', | ||
}, | ||
], | ||
}, | ||
}, | ||
}; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
28
87204
0
6467926
23
Updatedpdfjs-dist@^1.7.339