From 9b89fdbe72f0d6ba7ae24d396fa246ce9c2c498c Mon Sep 17 00:00:00 2001 From: Younes Regaieg Date: Tue, 12 Sep 2017 12:52:24 +0200 Subject: [PATCH] MNT-17527 Add support for annotation layer (responsible for displaying links) to the OOTB PDFJS viewer. --- .../main/webapp/components/preview/PdfJs.css | 64 ++++++++++++++ .../main/webapp/components/preview/PdfJs.js | 83 ++++++++++++++++++- 2 files changed, 144 insertions(+), 3 deletions(-) diff --git a/share/src/main/webapp/components/preview/PdfJs.css b/share/src/main/webapp/components/preview/PdfJs.css index d58a3c783..e37383ce7 100644 --- a/share/src/main/webapp/components/preview/PdfJs.css +++ b/share/src/main/webapp/components/preview/PdfJs.css @@ -441,6 +441,70 @@ canvas { background-color: rgba(0, 100, 0, 0.2); } +.annotationLayer section { + position: absolute; +} + +.annotationLayer .linkAnnotation > a { + position: absolute; + font-size: 1em; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.annotationLayer .linkAnnotation > a /* -ms-a */ { + background: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7") 0 0 repeat; +} + +.annotationLayer .linkAnnotation > a:hover { + opacity: 0.2; + background: #ff0; + box-shadow: 0px 2px 10px #ff0; +} + +.annotationLayer .textAnnotation img { + position: absolute; + cursor: pointer; +} + +.annotationLayer .popupWrapper { + position: absolute; + width: 20em; +} + +.annotationLayer .popup { + position: absolute; + z-index: 200; + max-width: 20em; + background-color: #FFFF99; + box-shadow: 0px 2px 5px #333; + border-radius: 2px; + padding: 0.6em; + margin-left: 5px; + cursor: pointer; + word-wrap: break-word; +} + +.annotationLayer .popup h1 { + font-size: 1em; + border-bottom: 1px solid #000000; + padding-bottom: 0.2em; +} + +.annotationLayer .popup p { + padding-top: 0.2em; +} + +.annotationLayer .highlightAnnotation, +.annotationLayer .underlineAnnotation, +.annotationLayer .squigglyAnnotation, +.annotationLayer .strikeoutAnnotation, +.annotationLayer .fileAttachmentAnnotation { + cursor: pointer; +} + /* TODO: file FF bug to support ::-moz-selection:window-inactive so we can override the opaque grey background when the window is inactive; see https://bugzilla.mozilla.org/show_bug.cgi?id=706209 */ diff --git a/share/src/main/webapp/components/preview/PdfJs.js b/share/src/main/webapp/components/preview/PdfJs.js index a371eb543..e1fe2fc35 100644 --- a/share/src/main/webapp/components/preview/PdfJs.js +++ b/share/src/main/webapp/components/preview/PdfJs.js @@ -34,6 +34,7 @@ * @author Peter Lofgren Loftux AB * @author Will Abson * @author Kevin Roast + * @author Younes Regaieg */ (function() @@ -181,6 +182,16 @@ */ disableTextLayer : "false", + /** + * Whether annotation overlays on pages should be disabled. Annotations allow users to click links + * from their documents within the preview but reduce rendering performance. + * + * @property disableAnnotationLayer + * @type String + * @default "false" + */ + disableAnnotationLayer : "false", + /** * Whether to use HTML5 browser storage to persist the page number and zoom level of previously-viewed documents * @@ -1902,7 +1913,7 @@ this.textLayerDiv = null; this.config = config || {}; this.textContent = null; - this.textLayerDiv = null; + this.annotationLayerDiv = null; this.pdfJsPlugin = pdfJsPlugin; } @@ -1986,6 +1997,16 @@ this.textLayerDiv = textLayerDiv; this.textLayer = textLayerDiv ? new TextLayerBuilder(textLayerDiv, this.id - 1, this.pdfJsPlugin, viewport) : null; + var annotationLayerDiv = null; + if (!this.parent.config.disableAnnotationLayer) + { + annotationLayerDiv = document.createElement('div'); + annotationLayerDiv.className = 'annotationLayer'; + this.container.appendChild(annotationLayerDiv); + } + this.annotationLayerDiv = annotationLayerDiv; + this.annotationLayer = annotationLayerDiv ? new AnnotationLayerBuilder(annotationLayerDiv) : null; + var content = this.content, view = content.view, ctx = canvas.getContext('2d'); @@ -1994,7 +2015,8 @@ var renderContext = { canvasContext : ctx, viewport : viewport, - textLayer : this.textLayer + textLayer : this.textLayer, + annotationLayer: this.annotationLayer }; var startTime = 0; @@ -2013,7 +2035,12 @@ { this.getTextContent().then(setTextFn); } - + + if (this.annotationLayer) + { + this.annotationLayer.render(this, this.content, viewport); + } + // Hide the loading icon and make the canvas visible again if (this.loadingIconDiv) { @@ -2944,6 +2971,56 @@ var TextLayerBuilder = function textLayerBuilder(textLayerDiv, pageIdx, pdfJsPlu }; }; +/** +* Copied from pdf.js viewer and adjusted. +*/ +/** +* @class +*/ +var AnnotationLayerBuilder = function annotationLayerBuilder(annotationLayerDiv) { + + this.annotationLayerDiv = annotationLayerDiv; + + + /** + * @param {PageViewport} viewport + * @param {string} intent (default value is 'display') + */ + this.render = function AnnotationLayerBuilder_render(self, pdfPage, viewport) { + var intent = 'display'; + self.viewport = viewport; + var parameters = { + intent: (intent === undefined ? 'display' : intent), + }; + + pdfPage.getAnnotations(parameters).then(function (annotations) { + var viewport = self.viewport.clone({ dontFlip: true }); + parameters = { + viewport: viewport, + div: self.annotationLayerDiv, + annotations: annotations, + page: pdfPage, + linkService: self.linkService, + downloadManager: self.downloadManager + }; + + if (self.annotationLayerDiv) { + // If an annotationLayer already exists, refresh its children's + // transformation matrices. + PDFJS.AnnotationLayer.render(parameters); + } else { + console.warn("Annotation DIV does not exist"); + } + }); + }; + + this.hide = function AnnotationLayerBuilder_hide() { + if (!this.annotationLayerDiv) { + return; + } + this.annotationLayerDiv.setAttribute('hidden', 'true'); + } +}; /** * PDFFindController - copied from pdf.js project, file viewer.js Changes