Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

document-viewer-ts

Package Overview
Dependencies
Maintainers
2
Versions
22
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

document-viewer-ts - npm Package Compare versions

Comparing version 0.1.2 to 0.2.0

8

dist/es2015/base.d.ts

@@ -1,11 +0,3 @@

export interface ViewerWindow extends Window {
viewerState: {
[key: string]: {
pageBreaks: number[];
canvasElements: HTMLCanvasElement[];
};
};
}
export declare const renderPDF: (containerDiv: Element, documentUrl: string) => Promise<unknown>;
export declare const renderDocument: (containerDiv: Element) => void;
export declare const init: (workerSrc: string) => void;

173

dist/es2015/base.js

@@ -30,15 +30,5 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

};
const vw = window;
vw.viewerState = {};
const pdfScale = 10;
const zoomedWidth = '100%';
const defaultWidth = '80%';
const recalculatePDFPageBreaks = (documentId) => {
var _a;
(vw.viewerState[documentId] || { pageBreaks: [] }).pageBreaks =
(((_a = vw.viewerState[documentId]) === null || _a === void 0 ? void 0 : _a.canvasElements) || []).reduce((acc, curr) => {
const breakPoint = (acc[(acc.length || 0) - 1] || -(curr.offsetHeight / 2 + 16)) + curr.offsetHeight + 32;
return [...acc, breakPoint];
}, []);
};
const scaleTextLayer = (textLayerDiv, textContent, pdfPage, canvas, viewport) => __awaiter(void 0, void 0, void 0, function* () {

@@ -58,17 +48,4 @@ textLayerDiv.innerHTML = '';

});
const scalePDF = (textLayerDiv, textContent, pdfPage, canvas, viewport, documentId) => {
scaleTextLayer(textLayerDiv, textContent, pdfPage, canvas, viewport);
recalculatePDFPageBreaks(documentId);
};
export const renderPDF = (containerDiv, documentUrl) => __awaiter(void 0, void 0, void 0, function* () {
const documentId = containerDiv.id;
vw.viewerState[documentId] = {
pageBreaks: [],
canvasElements: [],
};
const getPageId = (pageNumber) => `${documentId}-page-${pageNumber}`;
const getPage = (scrollTop) => {
var _a, _b;
return Math.min((((_a = vw.viewerState[documentId]) === null || _a === void 0 ? void 0 : _a.pageBreaks.filter(b => b < scrollTop).length) || 0) + 1, ((_b = vw.viewerState[documentId]) === null || _b === void 0 ? void 0 : _b.pageBreaks.length) || Infinity);
};
const canvasContainer = document.createElement('div');

@@ -80,4 +57,4 @@ canvasContainer.className = 'canvasContainer';

fullPageNumberDiv.className = 'pageNumber';
const pageNumberDiv = document.createElement('div');
pageNumberDiv.className = 'pageNumberRaw';
const pageNumberInput = document.createElement('input');
pageNumberInput.className = 'pageNumberInput';
const pageDiv = document.createElement('div');

@@ -93,15 +70,7 @@ const outOfDiv = document.createElement('div');

const loadingTask = getDocument(documentUrl);
// handle updating page number on scroll
canvasContainer.addEventListener('scroll', () => {
const pageNumber = getPage(canvasContainer.scrollTop);
pageNumberDiv.textContent = `${pageNumber}`;
if (!controlsDiv.style.opacity) {
controlsDiv.style.opacity = '1';
setTimeout(() => controlsDiv.removeAttribute('style'), 1000);
}
});
try {
const pdfDocument = yield loadingTask.promise;
const isValidPage = (page) => page <= pdfDocument.numPages && page > 0;
// initial viewer setup
pageNumberDiv.textContent = '1';
pageNumberInput.value = '1';
pageDiv.textContent = 'Page ';

@@ -111,17 +80,18 @@ outOfDiv.textContent = '/';

fullPageNumberDiv.appendChild(pageDiv);
fullPageNumberDiv.appendChild(pageNumberDiv);
fullPageNumberDiv.appendChild(pageNumberInput);
fullPageNumberDiv.appendChild(outOfDiv);
fullPageNumberDiv.appendChild(pageCountDiv);
const skipPage = (direction) => () => {
var _a;
const pageNumber = parseInt(pageNumberDiv.textContent || '1');
const nextPageNumber = pageNumber + direction;
if (nextPageNumber <= pdfDocument.numPages && nextPageNumber > 0) {
const nextPage = getPageId(nextPageNumber);
canvasContainer.scrollTo({ top: ((_a = document.getElementById(nextPage)) === null || _a === void 0 ? void 0 : _a.parentElement).offsetTop });
pageNumberDiv.textContent = `${pageNumber + direction}`;
}
};
nextButton.onclick = skipPage(1);
prevButton.onclick = skipPage(-1);
// page container setup
const pageContainer = document.createElement('div');
pageContainer.className = 'pageContainer';
pageContainer.style.width = defaultWidth;
canvasContainer.appendChild(pageContainer);
const canvas = document.createElement('canvas');
canvas.className = 'pdfViewerCanvas';
canvas.id = `${documentId}-canvas`;
pageContainer.appendChild(canvas);
// text layer setup
const textLayerDiv = document.createElement('div');
textLayerDiv.className = 'textLayer';
pageContainer.appendChild(textLayerDiv);
nextButton.innerHTML = chevronRight;

@@ -136,17 +106,5 @@ prevButton.innerHTML = chevronLeft;

containerDiv.appendChild(canvasContainer);
const canvasElements = [...Array(pdfDocument.numPages).keys()].map(page => {
const pageContainer = document.createElement('div');
pageContainer.className = 'pageContainer';
pageContainer.style.width = defaultWidth;
canvasContainer.appendChild(pageContainer);
const canvas = document.createElement('canvas');
canvas.className = 'pdfViewerCanvas';
canvas.id = getPageId(page + 1);
pageContainer.appendChild(canvas);
return { pageContainer, canvas };
});
(vw.viewerState[documentId] || { canvasElements: [] }).canvasElements = canvasElements.map(({ canvas }) => canvas);
// load pages simultaneously
yield Promise.all(canvasElements.map(({ pageContainer, canvas }, page) => __awaiter(void 0, void 0, void 0, function* () {
const pdfPage = yield pdfDocument.getPage(page + 1);
const displayPage = (page) => __awaiter(void 0, void 0, void 0, function* () {
pageNumberInput.value = `${page}`;
const pdfPage = yield pdfDocument.getPage(page);
const viewport = pdfPage.getViewport({ scale: pdfScale });

@@ -161,9 +119,5 @@ canvas.width = viewport.width;

});
const textLayerDiv = document.createElement('div');
textLayerDiv.className = 'textLayer';
const textContent = yield pdfPage.getTextContent();
pageContainer.appendChild(textLayerDiv);
scaleTextLayer(textLayerDiv, textContent, pdfPage, canvas, viewport);
// handle zoom in/out
zoomButton.addEventListener('click', () => {
zoomButton.onclick = () => {
if (pageContainer.style.width === defaultWidth) {

@@ -177,10 +131,38 @@ pageContainer.style.width = zoomedWidth;

}
scalePDF(textLayerDiv, textContent, pdfPage, canvas, viewport, documentId);
});
// make sure text selection layer and page breaks resize dynamically
window.addEventListener('resize', () => {
scalePDF(textLayerDiv, textContent, pdfPage, canvas, viewport, documentId);
});
})));
recalculatePDFPageBreaks(documentId);
scaleTextLayer(textLayerDiv, textContent, pdfPage, canvas, viewport);
};
});
const skipPage = (direction) => () => {
const pageNumber = parseInt(pageNumberInput.value || '1');
const nextPageNumber = pageNumber + direction;
if (isValidPage(nextPageNumber)) {
displayPage(nextPageNumber);
}
};
nextButton.onclick = skipPage(1);
prevButton.onclick = skipPage(-1);
pageNumberInput.onchange = () => {
const pageNumber = Math.max(Math.min(parseInt(pageNumberInput.value), pdfDocument.numPages), 1);
displayPage(pageNumber);
};
pageNumberInput.addEventListener('click', (e) => e.stopPropagation());
containerDiv.addEventListener('keydown', (e) => {
e.stopPropagation();
switch (e.key) {
case ('ArrowLeft'):
skipPage(-1)();
return;
case ('ArrowRight'):
skipPage(1)();
return;
default:
return;
}
});
containerDiv.addEventListener('click', () => {
containerDiv.focus();
});
containerDiv.setAttribute('tabIndex', '1');
containerDiv.focus();
yield displayPage(1);
}

@@ -201,2 +183,8 @@ catch (err) {

};
const renderTxt = (containerDiv, documentUrl) => {
const embed = document.createElement('embed');
embed.className = 'txtEmbed';
embed.setAttribute('src', documentUrl);
containerDiv.appendChild(embed);
};
export const renderDocument = (containerDiv) => {

@@ -210,11 +198,28 @@ var _a;

const extension = (_a = splitOnPeriods[(splitOnPeriods.length - 1)]) === null || _a === void 0 ? void 0 : _a.split('?')[0];
if (extension === 'pdf') {
renderPDF(containerDiv, documentUrl);
switch (extension) {
case 'pdf':
renderPDF(containerDiv, documentUrl);
return;
case 'doc':
case 'docx':
case 'ppt':
case 'pptx':
case 'xls':
case 'xlsx':
case 'xlt':
case 'xlsm':
case 'xlw':
case 'pps':
case 'ppxs':
case 'ppsm':
case 'sldx':
case 'sldm':
renderDocx(containerDiv, documentUrl);
return;
case 'txt':
renderTxt(containerDiv, documentUrl);
return;
default:
throw new Error('This file type is not supported for viewing in a web browser. Please click the “Download” button to view this document.');
}
else if (extension === 'doc' || extension === 'docx') {
renderDocx(containerDiv, documentUrl);
}
else {
throw new Error('Unsupported file type');
}
}

@@ -221,0 +226,0 @@ catch (err) {

@@ -1,11 +0,3 @@

export interface ViewerWindow extends Window {
viewerState: {
[key: string]: {
pageBreaks: number[];
canvasElements: HTMLCanvasElement[];
};
};
}
export declare const renderPDF: (containerDiv: Element, documentUrl: string) => Promise<unknown>;
export declare const renderDocument: (containerDiv: Element) => void;
export declare const init: (workerSrc: string) => void;

@@ -33,15 +33,5 @@ "use strict";

};
const vw = window;
vw.viewerState = {};
const pdfScale = 10;
const zoomedWidth = '100%';
const defaultWidth = '80%';
const recalculatePDFPageBreaks = (documentId) => {
var _a;
(vw.viewerState[documentId] || { pageBreaks: [] }).pageBreaks =
(((_a = vw.viewerState[documentId]) === null || _a === void 0 ? void 0 : _a.canvasElements) || []).reduce((acc, curr) => {
const breakPoint = (acc[(acc.length || 0) - 1] || -(curr.offsetHeight / 2 + 16)) + curr.offsetHeight + 32;
return [...acc, breakPoint];
}, []);
};
const scaleTextLayer = (textLayerDiv, textContent, pdfPage, canvas, viewport) => __awaiter(void 0, void 0, void 0, function* () {

@@ -61,17 +51,4 @@ textLayerDiv.innerHTML = '';

});
const scalePDF = (textLayerDiv, textContent, pdfPage, canvas, viewport, documentId) => {
scaleTextLayer(textLayerDiv, textContent, pdfPage, canvas, viewport);
recalculatePDFPageBreaks(documentId);
};
const renderPDF = (containerDiv, documentUrl) => __awaiter(void 0, void 0, void 0, function* () {
const documentId = containerDiv.id;
vw.viewerState[documentId] = {
pageBreaks: [],
canvasElements: [],
};
const getPageId = (pageNumber) => `${documentId}-page-${pageNumber}`;
const getPage = (scrollTop) => {
var _a, _b;
return Math.min((((_a = vw.viewerState[documentId]) === null || _a === void 0 ? void 0 : _a.pageBreaks.filter(b => b < scrollTop).length) || 0) + 1, ((_b = vw.viewerState[documentId]) === null || _b === void 0 ? void 0 : _b.pageBreaks.length) || Infinity);
};
const canvasContainer = document.createElement('div');

@@ -83,4 +60,4 @@ canvasContainer.className = 'canvasContainer';

fullPageNumberDiv.className = 'pageNumber';
const pageNumberDiv = document.createElement('div');
pageNumberDiv.className = 'pageNumberRaw';
const pageNumberInput = document.createElement('input');
pageNumberInput.className = 'pageNumberInput';
const pageDiv = document.createElement('div');

@@ -96,15 +73,7 @@ const outOfDiv = document.createElement('div');

const loadingTask = (0, pdfjs_dist_1.getDocument)(documentUrl);
// handle updating page number on scroll
canvasContainer.addEventListener('scroll', () => {
const pageNumber = getPage(canvasContainer.scrollTop);
pageNumberDiv.textContent = `${pageNumber}`;
if (!controlsDiv.style.opacity) {
controlsDiv.style.opacity = '1';
setTimeout(() => controlsDiv.removeAttribute('style'), 1000);
}
});
try {
const pdfDocument = yield loadingTask.promise;
const isValidPage = (page) => page <= pdfDocument.numPages && page > 0;
// initial viewer setup
pageNumberDiv.textContent = '1';
pageNumberInput.value = '1';
pageDiv.textContent = 'Page ';

@@ -114,17 +83,18 @@ outOfDiv.textContent = '/';

fullPageNumberDiv.appendChild(pageDiv);
fullPageNumberDiv.appendChild(pageNumberDiv);
fullPageNumberDiv.appendChild(pageNumberInput);
fullPageNumberDiv.appendChild(outOfDiv);
fullPageNumberDiv.appendChild(pageCountDiv);
const skipPage = (direction) => () => {
var _a;
const pageNumber = parseInt(pageNumberDiv.textContent || '1');
const nextPageNumber = pageNumber + direction;
if (nextPageNumber <= pdfDocument.numPages && nextPageNumber > 0) {
const nextPage = getPageId(nextPageNumber);
canvasContainer.scrollTo({ top: ((_a = document.getElementById(nextPage)) === null || _a === void 0 ? void 0 : _a.parentElement).offsetTop });
pageNumberDiv.textContent = `${pageNumber + direction}`;
}
};
nextButton.onclick = skipPage(1);
prevButton.onclick = skipPage(-1);
// page container setup
const pageContainer = document.createElement('div');
pageContainer.className = 'pageContainer';
pageContainer.style.width = defaultWidth;
canvasContainer.appendChild(pageContainer);
const canvas = document.createElement('canvas');
canvas.className = 'pdfViewerCanvas';
canvas.id = `${documentId}-canvas`;
pageContainer.appendChild(canvas);
// text layer setup
const textLayerDiv = document.createElement('div');
textLayerDiv.className = 'textLayer';
pageContainer.appendChild(textLayerDiv);
nextButton.innerHTML = chevronRight;

@@ -139,17 +109,5 @@ prevButton.innerHTML = chevronLeft;

containerDiv.appendChild(canvasContainer);
const canvasElements = [...Array(pdfDocument.numPages).keys()].map(page => {
const pageContainer = document.createElement('div');
pageContainer.className = 'pageContainer';
pageContainer.style.width = defaultWidth;
canvasContainer.appendChild(pageContainer);
const canvas = document.createElement('canvas');
canvas.className = 'pdfViewerCanvas';
canvas.id = getPageId(page + 1);
pageContainer.appendChild(canvas);
return { pageContainer, canvas };
});
(vw.viewerState[documentId] || { canvasElements: [] }).canvasElements = canvasElements.map(({ canvas }) => canvas);
// load pages simultaneously
yield Promise.all(canvasElements.map(({ pageContainer, canvas }, page) => __awaiter(void 0, void 0, void 0, function* () {
const pdfPage = yield pdfDocument.getPage(page + 1);
const displayPage = (page) => __awaiter(void 0, void 0, void 0, function* () {
pageNumberInput.value = `${page}`;
const pdfPage = yield pdfDocument.getPage(page);
const viewport = pdfPage.getViewport({ scale: pdfScale });

@@ -164,9 +122,5 @@ canvas.width = viewport.width;

});
const textLayerDiv = document.createElement('div');
textLayerDiv.className = 'textLayer';
const textContent = yield pdfPage.getTextContent();
pageContainer.appendChild(textLayerDiv);
scaleTextLayer(textLayerDiv, textContent, pdfPage, canvas, viewport);
// handle zoom in/out
zoomButton.addEventListener('click', () => {
zoomButton.onclick = () => {
if (pageContainer.style.width === defaultWidth) {

@@ -180,10 +134,38 @@ pageContainer.style.width = zoomedWidth;

}
scalePDF(textLayerDiv, textContent, pdfPage, canvas, viewport, documentId);
});
// make sure text selection layer and page breaks resize dynamically
window.addEventListener('resize', () => {
scalePDF(textLayerDiv, textContent, pdfPage, canvas, viewport, documentId);
});
})));
recalculatePDFPageBreaks(documentId);
scaleTextLayer(textLayerDiv, textContent, pdfPage, canvas, viewport);
};
});
const skipPage = (direction) => () => {
const pageNumber = parseInt(pageNumberInput.value || '1');
const nextPageNumber = pageNumber + direction;
if (isValidPage(nextPageNumber)) {
displayPage(nextPageNumber);
}
};
nextButton.onclick = skipPage(1);
prevButton.onclick = skipPage(-1);
pageNumberInput.onchange = () => {
const pageNumber = Math.max(Math.min(parseInt(pageNumberInput.value), pdfDocument.numPages), 1);
displayPage(pageNumber);
};
pageNumberInput.addEventListener('click', (e) => e.stopPropagation());
containerDiv.addEventListener('keydown', (e) => {
e.stopPropagation();
switch (e.key) {
case ('ArrowLeft'):
skipPage(-1)();
return;
case ('ArrowRight'):
skipPage(1)();
return;
default:
return;
}
});
containerDiv.addEventListener('click', () => {
containerDiv.focus();
});
containerDiv.setAttribute('tabIndex', '1');
containerDiv.focus();
yield displayPage(1);
}

@@ -205,2 +187,8 @@ catch (err) {

};
const renderTxt = (containerDiv, documentUrl) => {
const embed = document.createElement('embed');
embed.className = 'txtEmbed';
embed.setAttribute('src', documentUrl);
containerDiv.appendChild(embed);
};
const renderDocument = (containerDiv) => {

@@ -214,11 +202,28 @@ var _a;

const extension = (_a = splitOnPeriods[(splitOnPeriods.length - 1)]) === null || _a === void 0 ? void 0 : _a.split('?')[0];
if (extension === 'pdf') {
(0, exports.renderPDF)(containerDiv, documentUrl);
switch (extension) {
case 'pdf':
(0, exports.renderPDF)(containerDiv, documentUrl);
return;
case 'doc':
case 'docx':
case 'ppt':
case 'pptx':
case 'xls':
case 'xlsx':
case 'xlt':
case 'xlsm':
case 'xlw':
case 'pps':
case 'ppxs':
case 'ppsm':
case 'sldx':
case 'sldm':
renderDocx(containerDiv, documentUrl);
return;
case 'txt':
renderTxt(containerDiv, documentUrl);
return;
default:
throw new Error('This file type is not supported for viewing in a web browser. Please click the “Download” button to view this document.');
}
else if (extension === 'doc' || extension === 'docx') {
renderDocx(containerDiv, documentUrl);
}
else {
throw new Error('Unsupported file type');
}
}

@@ -225,0 +230,0 @@ catch (err) {

{
"name": "document-viewer-ts",
"version": "0.1.2",
"version": "0.2.0",
"description": "PDF and MS Doc viewer written in TypeScript for React and vanilla JavaScript",

@@ -5,0 +5,0 @@ "main": "dist/lib/index.js",

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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc