@progress/kendo-pdfviewer-common 0.3.0-dev.202409251137 → 0.3.0-dev.202409251459
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/annotations.js +68 -0
- package/dist/es/utils.js +37 -9
- package/dist/es2015/annotations.js +68 -0
- package/dist/es2015/utils.js +37 -9
- package/dist/npm/annotations.d.ts +23 -0
- package/dist/npm/annotations.js +72 -0
- package/dist/npm/utils.d.ts +7 -1
- package/dist/npm/utils.js +41 -12
- package/package.json +1 -1
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { createElement, scrollToPage } from './utils';
|
|
2
|
+
class Annotation {
|
|
3
|
+
constructor(container, viewport, annotation, pdfDoc, zoom, rootElement) {
|
|
4
|
+
this.container = container;
|
|
5
|
+
this.viewport = viewport;
|
|
6
|
+
this.zoom = zoom;
|
|
7
|
+
this.annotation = annotation;
|
|
8
|
+
this.pdfDoc = pdfDoc;
|
|
9
|
+
this.rootElement = rootElement;
|
|
10
|
+
}
|
|
11
|
+
destroy() {
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export class LinkAnnotation extends Annotation {
|
|
15
|
+
constructor(container, viewport, annotation, pdfDoc, zoom, rootElement) {
|
|
16
|
+
super(container, viewport, annotation, pdfDoc, zoom, rootElement);
|
|
17
|
+
this.onLinkClick = (e) => {
|
|
18
|
+
const destination = e.target.getAttribute('href');
|
|
19
|
+
if (destination && destination.indexOf('#') === 0) {
|
|
20
|
+
this.navigateToDestination(destination);
|
|
21
|
+
e.preventDefault();
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
this.linkElement = null;
|
|
25
|
+
this.renderAnnotation();
|
|
26
|
+
this.bindEvents();
|
|
27
|
+
}
|
|
28
|
+
destroy() {
|
|
29
|
+
this.unbindEvents();
|
|
30
|
+
}
|
|
31
|
+
bindEvents() {
|
|
32
|
+
this.linkElement.addEventListener('click', this.onLinkClick);
|
|
33
|
+
}
|
|
34
|
+
unbindEvents() {
|
|
35
|
+
this.linkElement.removeEventListener('click', this.onLinkClick);
|
|
36
|
+
}
|
|
37
|
+
navigateToDestination(destination) {
|
|
38
|
+
const dest = destination.split('#')[1];
|
|
39
|
+
this.pdfDoc.getDestination(dest).then(r => {
|
|
40
|
+
this.pdfDoc.getPageIndex(r[0]).then(i => this.goToPage(i));
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
goToPage(pageNumber) {
|
|
44
|
+
scrollToPage(this.rootElement, pageNumber);
|
|
45
|
+
}
|
|
46
|
+
renderAnnotation() {
|
|
47
|
+
const annotation = this.annotation, viewport = this.viewport, rect = annotation.rect, boundingRect = [
|
|
48
|
+
[rect[0], rect[1]],
|
|
49
|
+
[rect[2], rect[3]]
|
|
50
|
+
], rawHeight = viewport.rawDims.pageHeight;
|
|
51
|
+
const left = Math.min(boundingRect[0][0], boundingRect[1][0]) * this.zoom, top = (rawHeight - Math.max(boundingRect[0][1], boundingRect[1][1])) * this.zoom, width = (boundingRect[1][0] - boundingRect[0][0]) * this.zoom, height = (boundingRect[1][1] - boundingRect[0][1]) * this.zoom;
|
|
52
|
+
const url = annotation.url || (annotation.dest && `#${encodeURI(annotation.dest)}`);
|
|
53
|
+
const annotationElement = createElement('span', '', {
|
|
54
|
+
position: 'absolute',
|
|
55
|
+
left: left + 'pt',
|
|
56
|
+
top: top + 'pt'
|
|
57
|
+
});
|
|
58
|
+
const linkElement = this.linkElement = createElement('a', '', {
|
|
59
|
+
width: width + 'pt',
|
|
60
|
+
height: height + 'pt',
|
|
61
|
+
display: 'inline-block',
|
|
62
|
+
pointerEvents: 'auto'
|
|
63
|
+
});
|
|
64
|
+
linkElement.setAttribute('href', url);
|
|
65
|
+
annotationElement.append(linkElement);
|
|
66
|
+
this.container.append(annotationElement);
|
|
67
|
+
}
|
|
68
|
+
}
|
package/dist/es/utils.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { saveAs } from '@progress/kendo-file-saver';
|
|
2
2
|
import { detectDesktopBrowser, detectMobileOS } from '@progress/kendo-common';
|
|
3
3
|
import { getDocument, TextLayer } from 'pdfjs-dist/legacy/build/pdf.mjs';
|
|
4
|
+
import { LinkAnnotation } from './annotations';
|
|
4
5
|
const MAX_CANVAS_WIDTH_HEIGHT_CHROME = 65535;
|
|
5
6
|
const MAX_CANVAS_AREA_CHROME_SAFARI = 268435456;
|
|
6
7
|
const MAX_CANVAS_WIDTH_HEIGHT_FIREFOX = 32767;
|
|
@@ -83,7 +84,7 @@ export const download = (options, fileName = 'Document', saveOptions = {}, onDow
|
|
|
83
84
|
*/
|
|
84
85
|
export const loadPDF = (options) => {
|
|
85
86
|
const params = getDocumentParameters(options);
|
|
86
|
-
const { dom, zoom, done, error } = options;
|
|
87
|
+
const { dom, zoom, done, error, rootElement, enableAnnotations } = options;
|
|
87
88
|
const loadOnDemandPageSize = options.loadOnDemandPageSize || 2;
|
|
88
89
|
getDocument(params)
|
|
89
90
|
.promise.then((pdfDoc) => {
|
|
@@ -95,7 +96,7 @@ export const loadPDF = (options) => {
|
|
|
95
96
|
}).then(({ pages, pdfDoc }) => {
|
|
96
97
|
Promise.all(pages)
|
|
97
98
|
.then((all) => all.map((page, i) => {
|
|
98
|
-
const emptyPage = createEmptyPage(page, zoom);
|
|
99
|
+
const emptyPage = createEmptyPage(page, zoom, pdfDoc, enableAnnotations, rootElement);
|
|
99
100
|
appendPage(dom, emptyPage.pageElement, i);
|
|
100
101
|
if (options.loadOnDemand) {
|
|
101
102
|
// If LOD is enabled, render the first two(default) or X pages initially.
|
|
@@ -134,7 +135,7 @@ export const loadPDF = (options) => {
|
|
|
134
135
|
* @hidden
|
|
135
136
|
*/
|
|
136
137
|
export const reloadDocument = (params) => {
|
|
137
|
-
const { pdfDoc, zoom, dom, done, error, loadOnDemand, rootElement } = params;
|
|
138
|
+
const { pdfDoc, zoom, dom, done, error, loadOnDemand, rootElement, enableAnnotations } = params;
|
|
138
139
|
const pages = [];
|
|
139
140
|
let currentPageIndex = 0;
|
|
140
141
|
// Save the index of the current page in view before we reload the document.
|
|
@@ -148,7 +149,7 @@ export const reloadDocument = (params) => {
|
|
|
148
149
|
.then((all) => all.map((page, i) => {
|
|
149
150
|
// Set 'rendered' back to false so that the pages can be re-rendered when scrolling.
|
|
150
151
|
page._pageInfo.rendered = false;
|
|
151
|
-
const emptyPage = createEmptyPage(page, zoom);
|
|
152
|
+
const emptyPage = createEmptyPage(page, zoom, pdfDoc, enableAnnotations, rootElement);
|
|
152
153
|
appendPage(dom, emptyPage.pageElement, i);
|
|
153
154
|
// If on demand is not enabled, proceed as usual.
|
|
154
155
|
if (!loadOnDemand) {
|
|
@@ -211,13 +212,17 @@ const openPrintDialog = (dom, width, height, done, onError) => {
|
|
|
211
212
|
printDialog.addEventListener('afterprint', onAfterPrint);
|
|
212
213
|
}
|
|
213
214
|
};
|
|
214
|
-
const createEmptyPage = (page, zoom) => {
|
|
215
|
+
const createEmptyPage = (page, zoom, pdfDoc, enableAnnotations, rootElement) => {
|
|
215
216
|
const { canvasContext, viewport, pageElement, styles } = createCanvas(page, zoom, 'k-page');
|
|
216
217
|
return {
|
|
217
218
|
canvasContext,
|
|
218
219
|
viewport,
|
|
219
220
|
pageElement,
|
|
220
|
-
styles
|
|
221
|
+
styles,
|
|
222
|
+
zoom,
|
|
223
|
+
pdfDoc,
|
|
224
|
+
enableAnnotations,
|
|
225
|
+
rootElement
|
|
221
226
|
};
|
|
222
227
|
};
|
|
223
228
|
const renderCanvas = (page, done, error) => {
|
|
@@ -235,7 +240,7 @@ const renderCanvas = (page, done, error) => {
|
|
|
235
240
|
.catch(error);
|
|
236
241
|
return viewport;
|
|
237
242
|
};
|
|
238
|
-
const createElement = function (name, className, styles) {
|
|
243
|
+
export const createElement = function (name, className, styles) {
|
|
239
244
|
const element = document.createElement(name);
|
|
240
245
|
if (className) {
|
|
241
246
|
element.className = className;
|
|
@@ -250,7 +255,7 @@ const transforms = {
|
|
|
250
255
|
'270': 'rotate(270deg) translateX(-100%)'
|
|
251
256
|
};
|
|
252
257
|
export const renderPage = (page, emptyPage, error) => {
|
|
253
|
-
const { canvasContext, viewport, pageElement, styles } = emptyPage;
|
|
258
|
+
const { canvasContext, viewport, pageElement, styles, zoom, pdfDoc, enableAnnotations, rootElement } = emptyPage;
|
|
254
259
|
page._pageInfo.renderInProgress = true;
|
|
255
260
|
page.render({ canvasContext, viewport })
|
|
256
261
|
.promise.then(() => {
|
|
@@ -273,9 +278,32 @@ export const renderPage = (page, emptyPage, error) => {
|
|
|
273
278
|
el.style.fontSize = el.style.fontSize.replace(/px/g, 'pt');
|
|
274
279
|
}
|
|
275
280
|
});
|
|
276
|
-
pageElement.
|
|
281
|
+
pageElement.prepend(textLayer); // Use prepend to ensure the element is always inserted before the annotation layer.
|
|
277
282
|
}).catch(error);
|
|
278
283
|
});
|
|
284
|
+
if (enableAnnotations) {
|
|
285
|
+
page.getAnnotations({ intent: 'display' }).then((annotations) => {
|
|
286
|
+
const annotationLayer = createElement('div', 'k-annotations-layer', {
|
|
287
|
+
position: 'absolute',
|
|
288
|
+
top: '0',
|
|
289
|
+
left: '0',
|
|
290
|
+
overflow: 'hidden',
|
|
291
|
+
height: styles.height,
|
|
292
|
+
width: styles.width,
|
|
293
|
+
pointerEvents: 'none'
|
|
294
|
+
});
|
|
295
|
+
pageElement.appendChild(annotationLayer);
|
|
296
|
+
for (const annotation of annotations) {
|
|
297
|
+
switch (annotation.subtype) {
|
|
298
|
+
case 'Link':
|
|
299
|
+
new LinkAnnotation(annotationLayer, viewport, annotation, pdfDoc, zoom, rootElement);
|
|
300
|
+
break;
|
|
301
|
+
default:
|
|
302
|
+
null;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
}
|
|
279
307
|
})
|
|
280
308
|
.then(() => {
|
|
281
309
|
page._pageInfo.rendered = true;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { createElement, scrollToPage } from './utils';
|
|
2
|
+
class Annotation {
|
|
3
|
+
constructor(container, viewport, annotation, pdfDoc, zoom, rootElement) {
|
|
4
|
+
this.container = container;
|
|
5
|
+
this.viewport = viewport;
|
|
6
|
+
this.zoom = zoom;
|
|
7
|
+
this.annotation = annotation;
|
|
8
|
+
this.pdfDoc = pdfDoc;
|
|
9
|
+
this.rootElement = rootElement;
|
|
10
|
+
}
|
|
11
|
+
destroy() {
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export class LinkAnnotation extends Annotation {
|
|
15
|
+
constructor(container, viewport, annotation, pdfDoc, zoom, rootElement) {
|
|
16
|
+
super(container, viewport, annotation, pdfDoc, zoom, rootElement);
|
|
17
|
+
this.onLinkClick = (e) => {
|
|
18
|
+
const destination = e.target.getAttribute('href');
|
|
19
|
+
if (destination && destination.indexOf('#') === 0) {
|
|
20
|
+
this.navigateToDestination(destination);
|
|
21
|
+
e.preventDefault();
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
this.linkElement = null;
|
|
25
|
+
this.renderAnnotation();
|
|
26
|
+
this.bindEvents();
|
|
27
|
+
}
|
|
28
|
+
destroy() {
|
|
29
|
+
this.unbindEvents();
|
|
30
|
+
}
|
|
31
|
+
bindEvents() {
|
|
32
|
+
this.linkElement.addEventListener('click', this.onLinkClick);
|
|
33
|
+
}
|
|
34
|
+
unbindEvents() {
|
|
35
|
+
this.linkElement.removeEventListener('click', this.onLinkClick);
|
|
36
|
+
}
|
|
37
|
+
navigateToDestination(destination) {
|
|
38
|
+
const dest = destination.split('#')[1];
|
|
39
|
+
this.pdfDoc.getDestination(dest).then(r => {
|
|
40
|
+
this.pdfDoc.getPageIndex(r[0]).then(i => this.goToPage(i));
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
goToPage(pageNumber) {
|
|
44
|
+
scrollToPage(this.rootElement, pageNumber);
|
|
45
|
+
}
|
|
46
|
+
renderAnnotation() {
|
|
47
|
+
const annotation = this.annotation, viewport = this.viewport, rect = annotation.rect, boundingRect = [
|
|
48
|
+
[rect[0], rect[1]],
|
|
49
|
+
[rect[2], rect[3]]
|
|
50
|
+
], rawHeight = viewport.rawDims.pageHeight;
|
|
51
|
+
const left = Math.min(boundingRect[0][0], boundingRect[1][0]) * this.zoom, top = (rawHeight - Math.max(boundingRect[0][1], boundingRect[1][1])) * this.zoom, width = (boundingRect[1][0] - boundingRect[0][0]) * this.zoom, height = (boundingRect[1][1] - boundingRect[0][1]) * this.zoom;
|
|
52
|
+
const url = annotation.url || (annotation.dest && `#${encodeURI(annotation.dest)}`);
|
|
53
|
+
const annotationElement = createElement('span', '', {
|
|
54
|
+
position: 'absolute',
|
|
55
|
+
left: left + 'pt',
|
|
56
|
+
top: top + 'pt'
|
|
57
|
+
});
|
|
58
|
+
const linkElement = this.linkElement = createElement('a', '', {
|
|
59
|
+
width: width + 'pt',
|
|
60
|
+
height: height + 'pt',
|
|
61
|
+
display: 'inline-block',
|
|
62
|
+
pointerEvents: 'auto'
|
|
63
|
+
});
|
|
64
|
+
linkElement.setAttribute('href', url);
|
|
65
|
+
annotationElement.append(linkElement);
|
|
66
|
+
this.container.append(annotationElement);
|
|
67
|
+
}
|
|
68
|
+
}
|
package/dist/es2015/utils.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { saveAs } from '@progress/kendo-file-saver';
|
|
2
2
|
import { detectDesktopBrowser, detectMobileOS } from '@progress/kendo-common';
|
|
3
3
|
import { getDocument, TextLayer } from 'pdfjs-dist/legacy/build/pdf.mjs';
|
|
4
|
+
import { LinkAnnotation } from './annotations';
|
|
4
5
|
const MAX_CANVAS_WIDTH_HEIGHT_CHROME = 65535;
|
|
5
6
|
const MAX_CANVAS_AREA_CHROME_SAFARI = 268435456;
|
|
6
7
|
const MAX_CANVAS_WIDTH_HEIGHT_FIREFOX = 32767;
|
|
@@ -83,7 +84,7 @@ export const download = (options, fileName = 'Document', saveOptions = {}, onDow
|
|
|
83
84
|
*/
|
|
84
85
|
export const loadPDF = (options) => {
|
|
85
86
|
const params = getDocumentParameters(options);
|
|
86
|
-
const { dom, zoom, done, error } = options;
|
|
87
|
+
const { dom, zoom, done, error, rootElement, enableAnnotations } = options;
|
|
87
88
|
const loadOnDemandPageSize = options.loadOnDemandPageSize || 2;
|
|
88
89
|
getDocument(params)
|
|
89
90
|
.promise.then((pdfDoc) => {
|
|
@@ -95,7 +96,7 @@ export const loadPDF = (options) => {
|
|
|
95
96
|
}).then(({ pages, pdfDoc }) => {
|
|
96
97
|
Promise.all(pages)
|
|
97
98
|
.then((all) => all.map((page, i) => {
|
|
98
|
-
const emptyPage = createEmptyPage(page, zoom);
|
|
99
|
+
const emptyPage = createEmptyPage(page, zoom, pdfDoc, enableAnnotations, rootElement);
|
|
99
100
|
appendPage(dom, emptyPage.pageElement, i);
|
|
100
101
|
if (options.loadOnDemand) {
|
|
101
102
|
// If LOD is enabled, render the first two(default) or X pages initially.
|
|
@@ -134,7 +135,7 @@ export const loadPDF = (options) => {
|
|
|
134
135
|
* @hidden
|
|
135
136
|
*/
|
|
136
137
|
export const reloadDocument = (params) => {
|
|
137
|
-
const { pdfDoc, zoom, dom, done, error, loadOnDemand, rootElement } = params;
|
|
138
|
+
const { pdfDoc, zoom, dom, done, error, loadOnDemand, rootElement, enableAnnotations } = params;
|
|
138
139
|
const pages = [];
|
|
139
140
|
let currentPageIndex = 0;
|
|
140
141
|
// Save the index of the current page in view before we reload the document.
|
|
@@ -148,7 +149,7 @@ export const reloadDocument = (params) => {
|
|
|
148
149
|
.then((all) => all.map((page, i) => {
|
|
149
150
|
// Set 'rendered' back to false so that the pages can be re-rendered when scrolling.
|
|
150
151
|
page._pageInfo.rendered = false;
|
|
151
|
-
const emptyPage = createEmptyPage(page, zoom);
|
|
152
|
+
const emptyPage = createEmptyPage(page, zoom, pdfDoc, enableAnnotations, rootElement);
|
|
152
153
|
appendPage(dom, emptyPage.pageElement, i);
|
|
153
154
|
// If on demand is not enabled, proceed as usual.
|
|
154
155
|
if (!loadOnDemand) {
|
|
@@ -211,13 +212,17 @@ const openPrintDialog = (dom, width, height, done, onError) => {
|
|
|
211
212
|
printDialog.addEventListener('afterprint', onAfterPrint);
|
|
212
213
|
}
|
|
213
214
|
};
|
|
214
|
-
const createEmptyPage = (page, zoom) => {
|
|
215
|
+
const createEmptyPage = (page, zoom, pdfDoc, enableAnnotations, rootElement) => {
|
|
215
216
|
const { canvasContext, viewport, pageElement, styles } = createCanvas(page, zoom, 'k-page');
|
|
216
217
|
return {
|
|
217
218
|
canvasContext,
|
|
218
219
|
viewport,
|
|
219
220
|
pageElement,
|
|
220
|
-
styles
|
|
221
|
+
styles,
|
|
222
|
+
zoom,
|
|
223
|
+
pdfDoc,
|
|
224
|
+
enableAnnotations,
|
|
225
|
+
rootElement
|
|
221
226
|
};
|
|
222
227
|
};
|
|
223
228
|
const renderCanvas = (page, done, error) => {
|
|
@@ -235,7 +240,7 @@ const renderCanvas = (page, done, error) => {
|
|
|
235
240
|
.catch(error);
|
|
236
241
|
return viewport;
|
|
237
242
|
};
|
|
238
|
-
const createElement = function (name, className, styles) {
|
|
243
|
+
export const createElement = function (name, className, styles) {
|
|
239
244
|
const element = document.createElement(name);
|
|
240
245
|
if (className) {
|
|
241
246
|
element.className = className;
|
|
@@ -250,7 +255,7 @@ const transforms = {
|
|
|
250
255
|
'270': 'rotate(270deg) translateX(-100%)'
|
|
251
256
|
};
|
|
252
257
|
export const renderPage = (page, emptyPage, error) => {
|
|
253
|
-
const { canvasContext, viewport, pageElement, styles } = emptyPage;
|
|
258
|
+
const { canvasContext, viewport, pageElement, styles, zoom, pdfDoc, enableAnnotations, rootElement } = emptyPage;
|
|
254
259
|
page._pageInfo.renderInProgress = true;
|
|
255
260
|
page.render({ canvasContext, viewport })
|
|
256
261
|
.promise.then(() => {
|
|
@@ -273,9 +278,32 @@ export const renderPage = (page, emptyPage, error) => {
|
|
|
273
278
|
el.style.fontSize = el.style.fontSize.replace(/px/g, 'pt');
|
|
274
279
|
}
|
|
275
280
|
});
|
|
276
|
-
pageElement.
|
|
281
|
+
pageElement.prepend(textLayer); // Use prepend to ensure the element is always inserted before the annotation layer.
|
|
277
282
|
}).catch(error);
|
|
278
283
|
});
|
|
284
|
+
if (enableAnnotations) {
|
|
285
|
+
page.getAnnotations({ intent: 'display' }).then((annotations) => {
|
|
286
|
+
const annotationLayer = createElement('div', 'k-annotations-layer', {
|
|
287
|
+
position: 'absolute',
|
|
288
|
+
top: '0',
|
|
289
|
+
left: '0',
|
|
290
|
+
overflow: 'hidden',
|
|
291
|
+
height: styles.height,
|
|
292
|
+
width: styles.width,
|
|
293
|
+
pointerEvents: 'none'
|
|
294
|
+
});
|
|
295
|
+
pageElement.appendChild(annotationLayer);
|
|
296
|
+
for (const annotation of annotations) {
|
|
297
|
+
switch (annotation.subtype) {
|
|
298
|
+
case 'Link':
|
|
299
|
+
new LinkAnnotation(annotationLayer, viewport, annotation, pdfDoc, zoom, rootElement);
|
|
300
|
+
break;
|
|
301
|
+
default:
|
|
302
|
+
null;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
}
|
|
279
307
|
})
|
|
280
308
|
.then(() => {
|
|
281
309
|
page._pageInfo.rendered = true;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { PageViewport, PDFDocumentProxy } from 'pdfjs-dist/legacy/build/pdf.mjs';
|
|
2
|
+
declare class Annotation {
|
|
3
|
+
rootElement: HTMLElement;
|
|
4
|
+
container: HTMLElement;
|
|
5
|
+
viewport: PageViewport;
|
|
6
|
+
zoom: number;
|
|
7
|
+
annotation: any;
|
|
8
|
+
pdfDoc: PDFDocumentProxy;
|
|
9
|
+
constructor(container: any, viewport: any, annotation: any, pdfDoc: any, zoom: any, rootElement: any);
|
|
10
|
+
destroy(): any;
|
|
11
|
+
}
|
|
12
|
+
export declare class LinkAnnotation extends Annotation {
|
|
13
|
+
linkElement: HTMLAnchorElement;
|
|
14
|
+
constructor(container: any, viewport: any, annotation: any, pdfDoc: any, zoom: any, rootElement: any);
|
|
15
|
+
onLinkClick: (e: any) => void;
|
|
16
|
+
destroy(): any;
|
|
17
|
+
bindEvents(): any;
|
|
18
|
+
unbindEvents(): any;
|
|
19
|
+
navigateToDestination(destination: any): void;
|
|
20
|
+
goToPage(pageNumber: any): void;
|
|
21
|
+
renderAnnotation(): void;
|
|
22
|
+
}
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LinkAnnotation = void 0;
|
|
4
|
+
const utils_1 = require("./utils");
|
|
5
|
+
class Annotation {
|
|
6
|
+
constructor(container, viewport, annotation, pdfDoc, zoom, rootElement) {
|
|
7
|
+
this.container = container;
|
|
8
|
+
this.viewport = viewport;
|
|
9
|
+
this.zoom = zoom;
|
|
10
|
+
this.annotation = annotation;
|
|
11
|
+
this.pdfDoc = pdfDoc;
|
|
12
|
+
this.rootElement = rootElement;
|
|
13
|
+
}
|
|
14
|
+
destroy() {
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
class LinkAnnotation extends Annotation {
|
|
18
|
+
constructor(container, viewport, annotation, pdfDoc, zoom, rootElement) {
|
|
19
|
+
super(container, viewport, annotation, pdfDoc, zoom, rootElement);
|
|
20
|
+
this.onLinkClick = (e) => {
|
|
21
|
+
const destination = e.target.getAttribute('href');
|
|
22
|
+
if (destination && destination.indexOf('#') === 0) {
|
|
23
|
+
this.navigateToDestination(destination);
|
|
24
|
+
e.preventDefault();
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
this.linkElement = null;
|
|
28
|
+
this.renderAnnotation();
|
|
29
|
+
this.bindEvents();
|
|
30
|
+
}
|
|
31
|
+
destroy() {
|
|
32
|
+
this.unbindEvents();
|
|
33
|
+
}
|
|
34
|
+
bindEvents() {
|
|
35
|
+
this.linkElement.addEventListener('click', this.onLinkClick);
|
|
36
|
+
}
|
|
37
|
+
unbindEvents() {
|
|
38
|
+
this.linkElement.removeEventListener('click', this.onLinkClick);
|
|
39
|
+
}
|
|
40
|
+
navigateToDestination(destination) {
|
|
41
|
+
const dest = destination.split('#')[1];
|
|
42
|
+
this.pdfDoc.getDestination(dest).then(r => {
|
|
43
|
+
this.pdfDoc.getPageIndex(r[0]).then(i => this.goToPage(i));
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
goToPage(pageNumber) {
|
|
47
|
+
(0, utils_1.scrollToPage)(this.rootElement, pageNumber);
|
|
48
|
+
}
|
|
49
|
+
renderAnnotation() {
|
|
50
|
+
const annotation = this.annotation, viewport = this.viewport, rect = annotation.rect, boundingRect = [
|
|
51
|
+
[rect[0], rect[1]],
|
|
52
|
+
[rect[2], rect[3]]
|
|
53
|
+
], rawHeight = viewport.rawDims.pageHeight;
|
|
54
|
+
const left = Math.min(boundingRect[0][0], boundingRect[1][0]) * this.zoom, top = (rawHeight - Math.max(boundingRect[0][1], boundingRect[1][1])) * this.zoom, width = (boundingRect[1][0] - boundingRect[0][0]) * this.zoom, height = (boundingRect[1][1] - boundingRect[0][1]) * this.zoom;
|
|
55
|
+
const url = annotation.url || (annotation.dest && `#${encodeURI(annotation.dest)}`);
|
|
56
|
+
const annotationElement = (0, utils_1.createElement)('span', '', {
|
|
57
|
+
position: 'absolute',
|
|
58
|
+
left: left + 'pt',
|
|
59
|
+
top: top + 'pt'
|
|
60
|
+
});
|
|
61
|
+
const linkElement = this.linkElement = (0, utils_1.createElement)('a', '', {
|
|
62
|
+
width: width + 'pt',
|
|
63
|
+
height: height + 'pt',
|
|
64
|
+
display: 'inline-block',
|
|
65
|
+
pointerEvents: 'auto'
|
|
66
|
+
});
|
|
67
|
+
linkElement.setAttribute('href', url);
|
|
68
|
+
annotationElement.append(linkElement);
|
|
69
|
+
this.container.append(annotationElement);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.LinkAnnotation = LinkAnnotation;
|
package/dist/npm/utils.d.ts
CHANGED
|
@@ -29,8 +29,10 @@ export interface PDFReadParameters {
|
|
|
29
29
|
* @hidden
|
|
30
30
|
*/
|
|
31
31
|
export interface PDFReadOptions extends PDFReadParameters {
|
|
32
|
+
rootElement?: HTMLElement | null;
|
|
32
33
|
dom: HTMLDivElement;
|
|
33
34
|
zoom: number;
|
|
35
|
+
enableAnnotations: boolean;
|
|
34
36
|
done: DoneFn;
|
|
35
37
|
}
|
|
36
38
|
/**
|
|
@@ -40,10 +42,11 @@ export interface PDFReloadParameters {
|
|
|
40
42
|
pdfDoc: PDFDocumentProxy;
|
|
41
43
|
zoom: number;
|
|
42
44
|
dom: HTMLElement;
|
|
43
|
-
rootElement?: HTMLElement;
|
|
45
|
+
rootElement?: HTMLElement | null;
|
|
44
46
|
loadOnDemand?: boolean;
|
|
45
47
|
done: (pdfPages: PDFPageProxy[]) => void;
|
|
46
48
|
error: ErrorFn;
|
|
49
|
+
enableAnnotations: boolean;
|
|
47
50
|
}
|
|
48
51
|
/**
|
|
49
52
|
* @hidden
|
|
@@ -72,6 +75,9 @@ export declare const reloadDocument: (params: PDFReloadParameters) => void;
|
|
|
72
75
|
* @hidden
|
|
73
76
|
*/
|
|
74
77
|
export declare const print: (pages: PDFPageProxy[], done: () => void, error: ErrorFn) => void;
|
|
78
|
+
export declare const createElement: <T>(name: string, className: string, styles: {
|
|
79
|
+
[key: string]: string;
|
|
80
|
+
}) => T;
|
|
75
81
|
export declare const renderPage: (page: PDFPageProxy, emptyPage: any, error: ErrorFn) => any;
|
|
76
82
|
/**
|
|
77
83
|
* @hidden
|
package/dist/npm/utils.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.currentPage = exports.scrollToPage = exports.calculateZoomLevel = exports.goToPreviousSearchMatch = exports.goToNextSearchMatch = exports.renderPage = exports.print = exports.reloadDocument = exports.loadPDF = exports.download = exports.removeChildren = exports.DEFAULT_ZOOM_LEVEL = void 0;
|
|
3
|
+
exports.currentPage = exports.scrollToPage = exports.calculateZoomLevel = exports.goToPreviousSearchMatch = exports.goToNextSearchMatch = exports.renderPage = exports.createElement = exports.print = exports.reloadDocument = exports.loadPDF = exports.download = exports.removeChildren = exports.DEFAULT_ZOOM_LEVEL = void 0;
|
|
4
4
|
const kendo_file_saver_1 = require("@progress/kendo-file-saver");
|
|
5
5
|
const kendo_common_1 = require("@progress/kendo-common");
|
|
6
6
|
const pdf_mjs_1 = require("pdfjs-dist/legacy/build/pdf.mjs");
|
|
7
|
+
const annotations_1 = require("./annotations");
|
|
7
8
|
const MAX_CANVAS_WIDTH_HEIGHT_CHROME = 65535;
|
|
8
9
|
const MAX_CANVAS_AREA_CHROME_SAFARI = 268435456;
|
|
9
10
|
const MAX_CANVAS_WIDTH_HEIGHT_FIREFOX = 32767;
|
|
@@ -88,7 +89,7 @@ exports.download = download;
|
|
|
88
89
|
*/
|
|
89
90
|
const loadPDF = (options) => {
|
|
90
91
|
const params = getDocumentParameters(options);
|
|
91
|
-
const { dom, zoom, done, error } = options;
|
|
92
|
+
const { dom, zoom, done, error, rootElement, enableAnnotations } = options;
|
|
92
93
|
const loadOnDemandPageSize = options.loadOnDemandPageSize || 2;
|
|
93
94
|
(0, pdf_mjs_1.getDocument)(params)
|
|
94
95
|
.promise.then((pdfDoc) => {
|
|
@@ -100,7 +101,7 @@ const loadPDF = (options) => {
|
|
|
100
101
|
}).then(({ pages, pdfDoc }) => {
|
|
101
102
|
Promise.all(pages)
|
|
102
103
|
.then((all) => all.map((page, i) => {
|
|
103
|
-
const emptyPage = createEmptyPage(page, zoom);
|
|
104
|
+
const emptyPage = createEmptyPage(page, zoom, pdfDoc, enableAnnotations, rootElement);
|
|
104
105
|
appendPage(dom, emptyPage.pageElement, i);
|
|
105
106
|
if (options.loadOnDemand) {
|
|
106
107
|
// If LOD is enabled, render the first two(default) or X pages initially.
|
|
@@ -140,7 +141,7 @@ exports.loadPDF = loadPDF;
|
|
|
140
141
|
* @hidden
|
|
141
142
|
*/
|
|
142
143
|
const reloadDocument = (params) => {
|
|
143
|
-
const { pdfDoc, zoom, dom, done, error, loadOnDemand, rootElement } = params;
|
|
144
|
+
const { pdfDoc, zoom, dom, done, error, loadOnDemand, rootElement, enableAnnotations } = params;
|
|
144
145
|
const pages = [];
|
|
145
146
|
let currentPageIndex = 0;
|
|
146
147
|
// Save the index of the current page in view before we reload the document.
|
|
@@ -154,7 +155,7 @@ const reloadDocument = (params) => {
|
|
|
154
155
|
.then((all) => all.map((page, i) => {
|
|
155
156
|
// Set 'rendered' back to false so that the pages can be re-rendered when scrolling.
|
|
156
157
|
page._pageInfo.rendered = false;
|
|
157
|
-
const emptyPage = createEmptyPage(page, zoom);
|
|
158
|
+
const emptyPage = createEmptyPage(page, zoom, pdfDoc, enableAnnotations, rootElement);
|
|
158
159
|
appendPage(dom, emptyPage.pageElement, i);
|
|
159
160
|
// If on demand is not enabled, proceed as usual.
|
|
160
161
|
if (!loadOnDemand) {
|
|
@@ -219,13 +220,17 @@ const openPrintDialog = (dom, width, height, done, onError) => {
|
|
|
219
220
|
printDialog.addEventListener('afterprint', onAfterPrint);
|
|
220
221
|
}
|
|
221
222
|
};
|
|
222
|
-
const createEmptyPage = (page, zoom) => {
|
|
223
|
+
const createEmptyPage = (page, zoom, pdfDoc, enableAnnotations, rootElement) => {
|
|
223
224
|
const { canvasContext, viewport, pageElement, styles } = createCanvas(page, zoom, 'k-page');
|
|
224
225
|
return {
|
|
225
226
|
canvasContext,
|
|
226
227
|
viewport,
|
|
227
228
|
pageElement,
|
|
228
|
-
styles
|
|
229
|
+
styles,
|
|
230
|
+
zoom,
|
|
231
|
+
pdfDoc,
|
|
232
|
+
enableAnnotations,
|
|
233
|
+
rootElement
|
|
229
234
|
};
|
|
230
235
|
};
|
|
231
236
|
const renderCanvas = (page, done, error) => {
|
|
@@ -251,6 +256,7 @@ const createElement = function (name, className, styles) {
|
|
|
251
256
|
Object.keys(styles).forEach((key) => (element.style[key] = styles[key]));
|
|
252
257
|
return element;
|
|
253
258
|
};
|
|
259
|
+
exports.createElement = createElement;
|
|
254
260
|
const transforms = {
|
|
255
261
|
'0': '',
|
|
256
262
|
'90': 'rotate(90deg) translateY(-100%)',
|
|
@@ -258,12 +264,12 @@ const transforms = {
|
|
|
258
264
|
'270': 'rotate(270deg) translateX(-100%)'
|
|
259
265
|
};
|
|
260
266
|
const renderPage = (page, emptyPage, error) => {
|
|
261
|
-
const { canvasContext, viewport, pageElement, styles } = emptyPage;
|
|
267
|
+
const { canvasContext, viewport, pageElement, styles, zoom, pdfDoc, enableAnnotations, rootElement } = emptyPage;
|
|
262
268
|
page._pageInfo.renderInProgress = true;
|
|
263
269
|
page.render({ canvasContext, viewport })
|
|
264
270
|
.promise.then(() => {
|
|
265
271
|
page.getTextContent().then((textContent) => {
|
|
266
|
-
const textLayer = createElement('div', 'k-text-layer', styles);
|
|
272
|
+
const textLayer = (0, exports.createElement)('div', 'k-text-layer', styles);
|
|
267
273
|
new pdf_mjs_1.TextLayer({
|
|
268
274
|
textContentSource: textContent,
|
|
269
275
|
container: textLayer,
|
|
@@ -281,9 +287,32 @@ const renderPage = (page, emptyPage, error) => {
|
|
|
281
287
|
el.style.fontSize = el.style.fontSize.replace(/px/g, 'pt');
|
|
282
288
|
}
|
|
283
289
|
});
|
|
284
|
-
pageElement.
|
|
290
|
+
pageElement.prepend(textLayer); // Use prepend to ensure the element is always inserted before the annotation layer.
|
|
285
291
|
}).catch(error);
|
|
286
292
|
});
|
|
293
|
+
if (enableAnnotations) {
|
|
294
|
+
page.getAnnotations({ intent: 'display' }).then((annotations) => {
|
|
295
|
+
const annotationLayer = (0, exports.createElement)('div', 'k-annotations-layer', {
|
|
296
|
+
position: 'absolute',
|
|
297
|
+
top: '0',
|
|
298
|
+
left: '0',
|
|
299
|
+
overflow: 'hidden',
|
|
300
|
+
height: styles.height,
|
|
301
|
+
width: styles.width,
|
|
302
|
+
pointerEvents: 'none'
|
|
303
|
+
});
|
|
304
|
+
pageElement.appendChild(annotationLayer);
|
|
305
|
+
for (const annotation of annotations) {
|
|
306
|
+
switch (annotation.subtype) {
|
|
307
|
+
case 'Link':
|
|
308
|
+
new annotations_1.LinkAnnotation(annotationLayer, viewport, annotation, pdfDoc, zoom, rootElement);
|
|
309
|
+
break;
|
|
310
|
+
default:
|
|
311
|
+
null;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
}
|
|
287
316
|
})
|
|
288
317
|
.then(() => {
|
|
289
318
|
page._pageInfo.rendered = true;
|
|
@@ -449,8 +478,8 @@ const createCanvas = (page, zoom = 1, cssClass = '') => {
|
|
|
449
478
|
width: Math.floor(viewport.width / scaleNum) * zoom + 'pt',
|
|
450
479
|
height: Math.floor(viewport.height / scaleNum) * zoom + 'pt'
|
|
451
480
|
};
|
|
452
|
-
const pageElement = createElement('div', cssClass, styles);
|
|
453
|
-
const canvas = createElement('canvas', '', {
|
|
481
|
+
const pageElement = (0, exports.createElement)('div', cssClass, styles);
|
|
482
|
+
const canvas = (0, exports.createElement)('canvas', '', {
|
|
454
483
|
width: '100%',
|
|
455
484
|
height: '100%'
|
|
456
485
|
});
|
package/package.json
CHANGED