From 5b66ad626dc7db35dcf43e3a087d87a92d6acc28 Mon Sep 17 00:00:00 2001 From: Tim van der Meij Date: Thu, 17 Dec 2015 15:55:11 +0100 Subject: [PATCH] Refactor annotation display layer code to use classes --- src/display/annotation_layer.js | 758 ++++++++++++++++++++------------ web/annotation_layer_builder.js | 13 +- 2 files changed, 484 insertions(+), 287 deletions(-) diff --git a/src/display/annotation_layer.js b/src/display/annotation_layer.js index 5d52b3e4b..65d337dd5 100644 --- a/src/display/annotation_layer.js +++ b/src/display/annotation_layer.js @@ -38,341 +38,531 @@ var CustomStyle = displayDOMUtils.CustomStyle; var ANNOT_MIN_SIZE = 10; // px -var AnnotationLayer = (function AnnotationLayerClosure() { - // TODO(mack): This dupes some of the logic in CanvasGraphics.setFont() - function setTextStyles(element, item, fontObj) { - var style = element.style; - style.fontSize = item.fontSize + 'px'; - style.direction = item.fontDirection < 0 ? 'rtl': 'ltr'; +/** + * @typedef {Object} AnnotationElementParameters + * @property {Object} data + * @property {PDFPage} page + * @property {PageViewport} viewport + * @property {IPDFLinkService} linkService + */ - if (!fontObj) { - return; +/** + * @class + * @alias AnnotationElementFactory + */ +function AnnotationElementFactory() {} +AnnotationElementFactory.prototype = + /** @lends AnnotationElementFactory.prototype */ { + /** + * @param {AnnotationElementParameters} parameters + * @returns {AnnotationElement} + */ + create: function AnnotationElementFactory_create(parameters) { + var subtype = parameters.data.annotationType; + + switch (subtype) { + case AnnotationType.LINK: + return new LinkAnnotationElement(parameters); + + case AnnotationType.TEXT: + return new TextAnnotationElement(parameters); + + case AnnotationType.WIDGET: + return new WidgetAnnotationElement(parameters); + + default: + throw new Error('Unimplemented annotation type "' + subtype + '"'); } + } +}; - style.fontWeight = fontObj.black ? - (fontObj.bold ? 'bolder' : 'bold') : - (fontObj.bold ? 'bold' : 'normal'); - style.fontStyle = fontObj.italic ? 'italic' : 'normal'; +/** + * @class + * @alias AnnotationElement + */ +var AnnotationElement = (function AnnotationElementClosure() { + function AnnotationElement(parameters) { + this.data = parameters.data; + this.page = parameters.page; + this.viewport = parameters.viewport; + this.linkService = parameters.linkService; - var fontName = fontObj.loadedName; - var fontFamily = fontName ? '"' + fontName + '", ' : ''; - // Use a reasonable default font if the font doesn't specify a fallback - var fallbackName = fontObj.fallbackName || 'Helvetica, sans-serif'; - style.fontFamily = fontFamily + fallbackName; + this.container = this._createContainer(); } - function getContainer(data, page, viewport) { - var container = document.createElement('section'); - var width = data.rect[2] - data.rect[0]; - var height = data.rect[3] - data.rect[1]; + AnnotationElement.prototype = /** @lends AnnotationElement.prototype */ { + /** + * Create an empty container for the annotation's HTML element. + * + * @private + * @memberof AnnotationElement + * @returns {HTMLSectionElement} + */ + _createContainer: function AnnotationElement_createContainer() { + var data = this.data, page = this.page, viewport = this.viewport; + var container = document.createElement('section'); + var width = data.rect[2] - data.rect[0]; + var height = data.rect[3] - data.rect[1]; - container.setAttribute('data-annotation-id', data.id); + container.setAttribute('data-annotation-id', data.id); - data.rect = Util.normalizeRect([ - data.rect[0], - page.view[3] - data.rect[1] + page.view[1], - data.rect[2], - page.view[3] - data.rect[3] + page.view[1] - ]); + data.rect = Util.normalizeRect([ + data.rect[0], + page.view[3] - data.rect[1] + page.view[1], + data.rect[2], + page.view[3] - data.rect[3] + page.view[1] + ]); - CustomStyle.setProp('transform', container, - 'matrix(' + viewport.transform.join(',') + ')'); - CustomStyle.setProp('transformOrigin', container, - -data.rect[0] + 'px ' + -data.rect[1] + 'px'); + CustomStyle.setProp('transform', container, + 'matrix(' + viewport.transform.join(',') + ')'); + CustomStyle.setProp('transformOrigin', container, + -data.rect[0] + 'px ' + -data.rect[1] + 'px'); - if (data.borderStyle.width > 0) { - container.style.borderWidth = data.borderStyle.width + 'px'; - if (data.borderStyle.style !== AnnotationBorderStyleType.UNDERLINE) { - // Underline styles only have a bottom border, so we do not need - // to adjust for all borders. This yields a similar result as - // Adobe Acrobat/Reader. - width = width - 2 * data.borderStyle.width; - height = height - 2 * data.borderStyle.width; - } - - var horizontalRadius = data.borderStyle.horizontalCornerRadius; - var verticalRadius = data.borderStyle.verticalCornerRadius; - if (horizontalRadius > 0 || verticalRadius > 0) { - var radius = horizontalRadius + 'px / ' + verticalRadius + 'px'; - CustomStyle.setProp('borderRadius', container, radius); - } - - switch (data.borderStyle.style) { - case AnnotationBorderStyleType.SOLID: - container.style.borderStyle = 'solid'; - break; - - case AnnotationBorderStyleType.DASHED: - container.style.borderStyle = 'dashed'; - break; - - case AnnotationBorderStyleType.BEVELED: - warn('Unimplemented border style: beveled'); - break; - - case AnnotationBorderStyleType.INSET: - warn('Unimplemented border style: inset'); - break; - - case AnnotationBorderStyleType.UNDERLINE: - container.style.borderBottomStyle = 'solid'; - break; - - default: - break; - } - - if (data.color) { - container.style.borderColor = - Util.makeCssRgb(data.color[0] | 0, - data.color[1] | 0, - data.color[2] | 0); - } else { - // Transparent (invisible) border, so do not draw it at all. - container.style.borderWidth = 0; - } - } - - container.style.left = data.rect[0] + 'px'; - container.style.top = data.rect[1] + 'px'; - - container.style.width = width + 'px'; - container.style.height = height + 'px'; - - return container; - } - - function getHtmlElementForTextWidgetAnnotation(item, page, viewport) { - var container = getContainer(item, page, viewport); - - var content = document.createElement('div'); - content.textContent = item.fieldValue; - var textAlignment = item.textAlignment; - content.style.textAlign = ['left', 'center', 'right'][textAlignment]; - content.style.verticalAlign = 'middle'; - content.style.display = 'table-cell'; - - var fontObj = item.fontRefName ? - page.commonObjs.getData(item.fontRefName) : null; - setTextStyles(content, item, fontObj); - - container.appendChild(content); - - return container; - } - - function getHtmlElementForTextAnnotation(item, page, viewport) { - var rect = item.rect; - - // sanity check because of OOo-generated PDFs - if ((rect[3] - rect[1]) < ANNOT_MIN_SIZE) { - rect[3] = rect[1] + ANNOT_MIN_SIZE; - } - if ((rect[2] - rect[0]) < ANNOT_MIN_SIZE) { - rect[2] = rect[0] + (rect[3] - rect[1]); // make it square - } - - var container = getContainer(item, page, viewport); - container.className = 'annotText'; - - var image = document.createElement('img'); - image.style.height = container.style.height; - image.style.width = container.style.width; - var iconName = item.name; - image.src = PDFJS.imageResourcesPath + 'annotation-' + - iconName.toLowerCase() + '.svg'; - image.alt = '[{{type}} Annotation]'; - image.dataset.l10nId = 'text_annotation_type'; - image.dataset.l10nArgs = JSON.stringify({type: iconName}); - - var contentWrapper = document.createElement('div'); - contentWrapper.className = 'annotTextContentWrapper'; - contentWrapper.style.left = Math.floor(rect[2] - rect[0] + 5) + 'px'; - contentWrapper.style.top = '-10px'; - - var content = document.createElement('div'); - content.className = 'annotTextContent'; - content.setAttribute('hidden', true); - - var i, ii; - if (item.hasBgColor && item.color) { - var color = item.color; - - // Enlighten the color (70%) - var BACKGROUND_ENLIGHT = 0.7; - var r = BACKGROUND_ENLIGHT * (255 - color[0]) + color[0]; - var g = BACKGROUND_ENLIGHT * (255 - color[1]) + color[1]; - var b = BACKGROUND_ENLIGHT * (255 - color[2]) + color[2]; - content.style.backgroundColor = Util.makeCssRgb(r | 0, g | 0, b | 0); - } - - var title = document.createElement('h1'); - var text = document.createElement('p'); - title.textContent = item.title; - - if (!item.content && !item.title) { - content.setAttribute('hidden', true); - } else { - var e = document.createElement('span'); - var lines = item.content.split(/(?:\r\n?|\n)/); - for (i = 0, ii = lines.length; i < ii; ++i) { - var line = lines[i]; - e.appendChild(document.createTextNode(line)); - if (i < (ii - 1)) { - e.appendChild(document.createElement('br')); + if (data.borderStyle.width > 0) { + container.style.borderWidth = data.borderStyle.width + 'px'; + if (data.borderStyle.style !== AnnotationBorderStyleType.UNDERLINE) { + // Underline styles only have a bottom border, so we do not need + // to adjust for all borders. This yields a similar result as + // Adobe Acrobat/Reader. + width = width - 2 * data.borderStyle.width; + height = height - 2 * data.borderStyle.width; } - } - text.appendChild(e); - var pinned = false; + var horizontalRadius = data.borderStyle.horizontalCornerRadius; + var verticalRadius = data.borderStyle.verticalCornerRadius; + if (horizontalRadius > 0 || verticalRadius > 0) { + var radius = horizontalRadius + 'px / ' + verticalRadius + 'px'; + CustomStyle.setProp('borderRadius', container, radius); + } - var showAnnotation = function showAnnotation(pin) { - if (pin) { - pinned = true; - } - if (content.hasAttribute('hidden')) { - container.style.zIndex += 1; - content.removeAttribute('hidden'); - } - }; + switch (data.borderStyle.style) { + case AnnotationBorderStyleType.SOLID: + container.style.borderStyle = 'solid'; + break; - var hideAnnotation = function hideAnnotation(unpin) { - if (unpin) { - pinned = false; - } - if (!content.hasAttribute('hidden') && !pinned) { - container.style.zIndex -= 1; - content.setAttribute('hidden', true); - } - }; + case AnnotationBorderStyleType.DASHED: + container.style.borderStyle = 'dashed'; + break; - var toggleAnnotation = function toggleAnnotation() { - if (pinned) { - hideAnnotation(true); + case AnnotationBorderStyleType.BEVELED: + warn('Unimplemented border style: beveled'); + break; + + case AnnotationBorderStyleType.INSET: + warn('Unimplemented border style: inset'); + break; + + case AnnotationBorderStyleType.UNDERLINE: + container.style.borderBottomStyle = 'solid'; + break; + + default: + break; + } + + if (data.color) { + container.style.borderColor = + Util.makeCssRgb(data.color[0] | 0, + data.color[1] | 0, + data.color[2] | 0); } else { - showAnnotation(true); + // Transparent (invisible) border, so do not draw it at all. + container.style.borderWidth = 0; } - }; + } - image.addEventListener('click', function image_clickHandler() { - toggleAnnotation(); - }, false); - image.addEventListener('mouseover', function image_mouseOverHandler() { - showAnnotation(); - }, false); - image.addEventListener('mouseout', function image_mouseOutHandler() { - hideAnnotation(); - }, false); + container.style.left = data.rect[0] + 'px'; + container.style.top = data.rect[1] + 'px'; - content.addEventListener('click', function content_clickHandler() { - hideAnnotation(true); - }, false); + container.style.width = width + 'px'; + container.style.height = height + 'px'; + + return container; + }, + + /** + * Render the annotation's HTML element in the empty container. + * + * @public + * @memberof AnnotationElement + */ + render: function AnnotationElement_render() { + throw new Error('Abstract method AnnotationElement.render called'); } + }; - content.appendChild(title); - content.appendChild(text); - contentWrapper.appendChild(content); - container.appendChild(image); - container.appendChild(contentWrapper); + return AnnotationElement; +})(); - return container; +/** + * @class + * @alias LinkAnnotationElement + */ +var LinkAnnotationElement = (function LinkAnnotationElementClosure() { + function LinkAnnotationElement(parameters) { + AnnotationElement.call(this, parameters); } - function getHtmlElementForLinkAnnotation(item, page, viewport, linkService) { - function bindLink(link, dest) { - link.href = linkService.getDestinationHash(dest); - link.onclick = function annotationsLayerBuilderLinksOnclick() { - if (dest) { - linkService.navigateTo(dest); + Util.inherit(LinkAnnotationElement, AnnotationElement, { + /** + * Render the link annotation's HTML element in the empty container. + * + * @public + * @memberof LinkAnnotationElement + * @returns {HTMLSectionElement} + */ + render: function LinkAnnotationElement_render() { + this.container.className = 'annotLink'; + + var link = document.createElement('a'); + link.href = link.title = this.data.url || ''; + + if (this.data.url && isExternalLinkTargetSet()) { + link.target = LinkTargetStringMap[PDFJS.externalLinkTarget]; + } + + // Strip referrer from the URL. + if (this.data.url) { + link.rel = PDFJS.externalLinkRel; + } + + if (!this.data.url) { + if (this.data.action) { + this._bindNamedAction(link, this.data.action); + } else { + this._bindLink(link, ('dest' in this.data) ? this.data.dest : null); + } + } + + this.container.appendChild(link); + return this.container; + }, + + /** + * Bind internal links to the link element. + * + * @private + * @param {Object} link + * @param {Object} destination + * @memberof LinkAnnotationElement + */ + _bindLink: function LinkAnnotationElement_bindLink(link, destination) { + var self = this; + + link.href = this.linkService.getDestinationHash(destination); + link.onclick = function() { + if (destination) { + self.linkService.navigateTo(destination); } return false; }; - if (dest) { + if (destination) { link.className = 'internalLink'; } - } + }, - function bindNamedAction(link, action) { - link.href = linkService.getAnchorUrl(''); - link.onclick = function annotationsLayerBuilderNamedActionOnClick() { - linkService.executeNamedAction(action); + /** + * Bind named actions to the link element. + * + * @private + * @param {Object} link + * @param {Object} action + * @memberof LinkAnnotationElement + */ + _bindNamedAction: + function LinkAnnotationElement_bindNamedAction(link, action) { + var self = this; + + link.href = this.linkService.getAnchorUrl(''); + link.onclick = function() { + self.linkService.executeNamedAction(action); return false; }; link.className = 'internalLink'; } + }); - var container = getContainer(item, page, viewport); - container.className = 'annotLink'; + return LinkAnnotationElement; +})(); - var link = document.createElement('a'); - link.href = link.title = item.url || ''; +/** + * @class + * @alias TextAnnotationElement + */ +var TextAnnotationElement = (function TextAnnotationElementClosure() { + function TextAnnotationElement(parameters) { + AnnotationElement.call(this, parameters); - if (item.url && isExternalLinkTargetSet()) { - link.target = LinkTargetStringMap[PDFJS.externalLinkTarget]; - } + this.pinned = false; + } - // Strip referrer - if (item.url) { - link.rel = PDFJS.externalLinkRel; - } + Util.inherit(TextAnnotationElement, AnnotationElement, { + /** + * Render the text annotation's HTML element in the empty container. + * + * @public + * @memberof TextAnnotationElement + * @returns {HTMLSectionElement} + */ + render: function TextAnnotationElement_render() { + var rect = this.data.rect, container = this.container; - if (!item.url) { - if (item.action) { - bindNamedAction(link, item.action); + // Sanity check because of OOo-generated PDFs. + if ((rect[3] - rect[1]) < ANNOT_MIN_SIZE) { + rect[3] = rect[1] + ANNOT_MIN_SIZE; + } + if ((rect[2] - rect[0]) < ANNOT_MIN_SIZE) { + rect[2] = rect[0] + (rect[3] - rect[1]); // make it square + } + + container.className = 'annotText'; + + var image = document.createElement('img'); + image.style.height = container.style.height; + image.style.width = container.style.width; + var iconName = this.data.name; + image.src = PDFJS.imageResourcesPath + 'annotation-' + + iconName.toLowerCase() + '.svg'; + image.alt = '[{{type}} Annotation]'; + image.dataset.l10nId = 'text_annotation_type'; + image.dataset.l10nArgs = JSON.stringify({type: iconName}); + + var contentWrapper = document.createElement('div'); + contentWrapper.className = 'annotTextContentWrapper'; + contentWrapper.style.left = Math.floor(rect[2] - rect[0] + 5) + 'px'; + contentWrapper.style.top = '-10px'; + + var content = this.content = document.createElement('div'); + content.className = 'annotTextContent'; + content.setAttribute('hidden', true); + + var i, ii; + if (this.data.hasBgColor && this.data.color) { + var color = this.data.color; + + // Enlighten the color (70%). + var BACKGROUND_ENLIGHT = 0.7; + var r = BACKGROUND_ENLIGHT * (255 - color[0]) + color[0]; + var g = BACKGROUND_ENLIGHT * (255 - color[1]) + color[1]; + var b = BACKGROUND_ENLIGHT * (255 - color[2]) + color[2]; + content.style.backgroundColor = Util.makeCssRgb(r | 0, g | 0, b | 0); + } + + var title = document.createElement('h1'); + var text = document.createElement('p'); + title.textContent = this.data.title; + + if (!this.data.content && !this.data.title) { + content.setAttribute('hidden', true); } else { - bindLink(link, ('dest' in item) ? item.dest : null); - } - } + var e = document.createElement('span'); + var lines = this.data.content.split(/(?:\r\n?|\n)/); + for (i = 0, ii = lines.length; i < ii; ++i) { + var line = lines[i]; + e.appendChild(document.createTextNode(line)); + if (i < (ii - 1)) { + e.appendChild(document.createElement('br')); + } + } + text.appendChild(e); - container.appendChild(link); - - return container; - } - - function getHtmlElement(data, page, viewport, linkService) { - switch (data.annotationType) { - case AnnotationType.WIDGET: - return getHtmlElementForTextWidgetAnnotation(data, page, viewport); - case AnnotationType.TEXT: - return getHtmlElementForTextAnnotation(data, page, viewport); - case AnnotationType.LINK: - return getHtmlElementForLinkAnnotation(data, page, viewport, - linkService); - default: - throw new Error('Unsupported annotationType: ' + data.annotationType); - } - } - - function render(viewport, div, annotations, page, linkService) { - for (var i = 0, ii = annotations.length; i < ii; i++) { - var data = annotations[i]; - if (!data || !data.hasHtml) { - continue; + image.addEventListener('click', this._toggle.bind(this)); + image.addEventListener('mouseover', this._show.bind(this, false)); + image.addEventListener('mouseout', this._hide.bind(this, false)); + content.addEventListener('click', this._hide.bind(this, true)); } - var element = getHtmlElement(data, page, viewport, linkService); - div.appendChild(element); - } - } + content.appendChild(title); + content.appendChild(text); + contentWrapper.appendChild(content); + container.appendChild(image); + container.appendChild(contentWrapper); + return container; + }, - function update(viewport, div, annotations) { - for (var i = 0, ii = annotations.length; i < ii; i++) { - var data = annotations[i]; - var element = div.querySelector( - '[data-annotation-id="' + data.id + '"]'); - if (element) { - CustomStyle.setProp('transform', element, - 'matrix(' + viewport.transform.join(',') + ')'); + /** + * Toggle the visibility of the content box. + * + * @private + * @memberof TextAnnotationElement + */ + _toggle: function TextAnnotationElement_toggle() { + if (this.pinned) { + this._hide(true); + } else { + this._show(true); + } + }, + + /** + * Show the content box. + * + * @private + * @param {boolean} pin + * @memberof TextAnnotationElement + */ + _show: function TextAnnotationElement_show(pin) { + if (pin) { + this.pinned = true; + } + if (this.content.hasAttribute('hidden')) { + this.container.style.zIndex += 1; + this.content.removeAttribute('hidden'); + } + }, + + /** + * Hide the content box. + * + * @private + * @param {boolean} unpin + * @memberof TextAnnotationElement + */ + _hide: function TextAnnotationElement_hide(unpin) { + if (unpin) { + this.pinned = false; + } + if (!this.content.hasAttribute('hidden') && !this.pinned) { + this.container.style.zIndex -= 1; + this.content.setAttribute('hidden', true); } } - div.removeAttribute('hidden'); + }); + + return TextAnnotationElement; +})(); + +/** + * @class + * @alias WidgetAnnotationElement + */ +var WidgetAnnotationElement = (function WidgetAnnotationElementClosure() { + function WidgetAnnotationElement(parameters) { + AnnotationElement.call(this, parameters); } + Util.inherit(WidgetAnnotationElement, AnnotationElement, { + /** + * Render the widget annotation's HTML element in the empty container. + * + * @public + * @memberof WidgetAnnotationElement + * @returns {HTMLSectionElement} + */ + render: function WidgetAnnotationElement_render() { + var content = document.createElement('div'); + content.textContent = this.data.fieldValue; + var textAlignment = this.data.textAlignment; + content.style.textAlign = ['left', 'center', 'right'][textAlignment]; + content.style.verticalAlign = 'middle'; + content.style.display = 'table-cell'; + + var font = (this.data.fontRefName ? + this.page.commonObjs.getData(this.data.fontRefName) : null); + this._setTextStyle(content, font); + + this.container.appendChild(content); + return this.container; + }, + + /** + * Apply text styles to the text in the element. + * + * @private + * @param {HTMLDivElement} element + * @param {Object} font + * @memberof WidgetAnnotationElement + */ + _setTextStyle: + function WidgetAnnotationElement_setTextStyle(element, font) { + // TODO: This duplicates some of the logic in CanvasGraphics.setFont(). + var style = element.style; + style.fontSize = this.data.fontSize + 'px'; + style.direction = (this.data.fontDirection < 0 ? 'rtl': 'ltr'); + + if (!font) { + return; + } + + style.fontWeight = (font.black ? + (font.bold ? '900' : 'bold') : + (font.bold ? 'bold' : 'normal')); + style.fontStyle = (font.italic ? 'italic' : 'normal'); + + // Use a reasonable default font if the font doesn't specify a fallback. + var fontFamily = font.loadedName ? '"' + font.loadedName + '", ' : ''; + var fallbackName = font.fallbackName || 'Helvetica, sans-serif'; + style.fontFamily = fontFamily + fallbackName; + } + }); + + return WidgetAnnotationElement; +})(); + +/** + * @typedef {Object} AnnotationLayerParameters + * @property {PageViewport} viewport + * @property {HTMLDivElement} div + * @property {Array} annotations + * @property {PDFPage} page + * @property {IPDFLinkService} linkService + */ + +/** + * @class + * @alias AnnotationLayer + */ +var AnnotationLayer = (function AnnotationLayerClosure() { return { - render: render, - update: update + /** + * Render a new annotation layer with all annotation elements. + * + * @public + * @param {AnnotationLayerParameters} parameters + * @memberof AnnotationLayer + */ + render: function AnnotationLayer_render(parameters) { + var annotationElementFactory = new AnnotationElementFactory(); + + for (var i = 0, ii = parameters.annotations.length; i < ii; i++) { + var data = parameters.annotations[i]; + if (!data || !data.hasHtml) { + continue; + } + + var properties = { + data: data, + page: parameters.page, + viewport: parameters.viewport, + linkService: parameters.linkService + }; + var element = annotationElementFactory.create(properties); + parameters.div.appendChild(element.render()); + } + }, + + /** + * Update the annotation elements on existing annotation layer. + * + * @public + * @param {AnnotationLayerParameters} parameters + * @memberof AnnotationLayer + */ + update: function AnnotationLayer_update(parameters) { + for (var i = 0, ii = parameters.annotations.length; i < ii; i++) { + var data = parameters.annotations[i]; + var element = parameters.div.querySelector( + '[data-annotation-id="' + data.id + '"]'); + if (element) { + CustomStyle.setProp('transform', element, + 'matrix(' + parameters.viewport.transform.join(',') + ')'); + } + } + parameters.div.removeAttribute('hidden'); + } }; })(); + PDFJS.AnnotationLayer = AnnotationLayer; exports.AnnotationLayer = AnnotationLayer; diff --git a/web/annotation_layer_builder.js b/web/annotation_layer_builder.js index 0462aa3d5..3f5a32900 100644 --- a/web/annotation_layer_builder.js +++ b/web/annotation_layer_builder.js @@ -54,11 +54,18 @@ var AnnotationLayerBuilder = (function AnnotationLayerBuilderClosure() { this.pdfPage.getAnnotations(parameters).then(function (annotations) { viewport = viewport.clone({ dontFlip: true }); + parameters = { + viewport: viewport, + div: self.div, + annotations: annotations, + page: self.pdfPage, + linkService: self.linkService + }; if (self.div) { // If an annotationLayer already exists, refresh its children's // transformation matrices. - PDFJS.AnnotationLayer.update(viewport, self.div, annotations); + PDFJS.AnnotationLayer.update(parameters); } else { // Create an annotation layer div and render the annotations // if there is at least one annotation. @@ -69,9 +76,9 @@ var AnnotationLayerBuilder = (function AnnotationLayerBuilderClosure() { self.div = document.createElement('div'); self.div.className = 'annotationLayer'; self.pageDiv.appendChild(self.div); + parameters.div = self.div; - PDFJS.AnnotationLayer.render(viewport, self.div, annotations, - self.pdfPage, self.linkService); + PDFJS.AnnotationLayer.render(parameters); if (typeof mozL10n !== 'undefined') { mozL10n.translate(self.div); }