Merge pull request #6792 from timvandermeij/popup-annotation
Implement support for Popup annotations
This commit is contained in:
		
						commit
						cba8a87f84
					
				| @ -52,8 +52,6 @@ var ColorSpace = coreColorSpace.ColorSpace; | |||||||
| var ObjectLoader = coreObj.ObjectLoader; | var ObjectLoader = coreObj.ObjectLoader; | ||||||
| var OperatorList = coreEvaluator.OperatorList; | var OperatorList = coreEvaluator.OperatorList; | ||||||
| 
 | 
 | ||||||
| var DEFAULT_ICON_SIZE = 22; // px
 |  | ||||||
| 
 |  | ||||||
| /** | /** | ||||||
|  * @class |  * @class | ||||||
|  * @alias AnnotationFactory |  * @alias AnnotationFactory | ||||||
| @ -95,6 +93,9 @@ AnnotationFactory.prototype = /** @lends AnnotationFactory.prototype */ { | |||||||
|         } |         } | ||||||
|         return new WidgetAnnotation(parameters); |         return new WidgetAnnotation(parameters); | ||||||
| 
 | 
 | ||||||
|  |       case 'Popup': | ||||||
|  |         return new PopupAnnotation(parameters); | ||||||
|  | 
 | ||||||
|       default: |       default: | ||||||
|         warn('Unimplemented annotation type "' + subtype + '", ' + |         warn('Unimplemented annotation type "' + subtype + '", ' + | ||||||
|              'falling back to base annotation'); |              'falling back to base annotation'); | ||||||
| @ -160,7 +161,7 @@ var Annotation = (function AnnotationClosure() { | |||||||
| 
 | 
 | ||||||
|     // Expose public properties using a data object.
 |     // Expose public properties using a data object.
 | ||||||
|     this.data = {}; |     this.data = {}; | ||||||
|     this.data.id = params.ref.num; |     this.data.id = params.ref.toString(); | ||||||
|     this.data.subtype = dict.get('Subtype').name; |     this.data.subtype = dict.get('Subtype').name; | ||||||
|     this.data.annotationFlags = this.flags; |     this.data.annotationFlags = this.flags; | ||||||
|     this.data.rect = this.rectangle; |     this.data.rect = this.rectangle; | ||||||
| @ -639,29 +640,35 @@ var TextWidgetAnnotation = (function TextWidgetAnnotationClosure() { | |||||||
| })(); | })(); | ||||||
| 
 | 
 | ||||||
| var TextAnnotation = (function TextAnnotationClosure() { | var TextAnnotation = (function TextAnnotationClosure() { | ||||||
|   function TextAnnotation(params) { |   var DEFAULT_ICON_SIZE = 22; // px
 | ||||||
|     Annotation.call(this, params); |  | ||||||
| 
 | 
 | ||||||
|     var dict = params.dict; |   function TextAnnotation(parameters) { | ||||||
|     var data = this.data; |     Annotation.call(this, parameters); | ||||||
| 
 | 
 | ||||||
|     var content = dict.get('Contents'); |     this.data.annotationType = AnnotationType.TEXT; | ||||||
|     var title = dict.get('T'); |     this.data.hasHtml = true; | ||||||
|     data.annotationType = AnnotationType.TEXT; |  | ||||||
|     data.content = stringToPDFString(content || ''); |  | ||||||
|     data.title = stringToPDFString(title || ''); |  | ||||||
|     data.hasHtml = true; |  | ||||||
| 
 | 
 | ||||||
|     if (data.hasAppearance) { |     var dict = parameters.dict; | ||||||
|       data.name = 'NoIcon'; |     if (this.data.hasAppearance) { | ||||||
|  |       this.data.name = 'NoIcon'; | ||||||
|     } else { |     } else { | ||||||
|       data.rect[1] = data.rect[3] - DEFAULT_ICON_SIZE; |       this.data.rect[1] = this.data.rect[3] - DEFAULT_ICON_SIZE; | ||||||
|       data.rect[2] = data.rect[0] + DEFAULT_ICON_SIZE; |       this.data.rect[2] = this.data.rect[0] + DEFAULT_ICON_SIZE; | ||||||
|       data.name = dict.has('Name') ? dict.get('Name').name : 'Note'; |       this.data.name = dict.has('Name') ? dict.get('Name').name : 'Note'; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (dict.has('C')) { |     if (!dict.has('C')) { | ||||||
|       data.hasBgColor = true; |       // Fall back to the default background color.
 | ||||||
|  |       this.data.color = null; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     this.data.hasPopup = dict.has('Popup'); | ||||||
|  |     if (!this.data.hasPopup) { | ||||||
|  |       // There is no associated Popup annotation, so the Text annotation
 | ||||||
|  |       // must create its own popup.
 | ||||||
|  |       this.data.title = stringToPDFString(dict.get('T') || ''); | ||||||
|  |       this.data.contents = stringToPDFString(dict.get('Contents') || ''); | ||||||
|  |       this.data.hasHtml = (this.data.title || this.data.contents); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @ -746,6 +753,39 @@ var LinkAnnotation = (function LinkAnnotationClosure() { | |||||||
|   return LinkAnnotation; |   return LinkAnnotation; | ||||||
| })(); | })(); | ||||||
| 
 | 
 | ||||||
|  | var PopupAnnotation = (function PopupAnnotationClosure() { | ||||||
|  |   function PopupAnnotation(parameters) { | ||||||
|  |     Annotation.call(this, parameters); | ||||||
|  | 
 | ||||||
|  |     this.data.annotationType = AnnotationType.POPUP; | ||||||
|  | 
 | ||||||
|  |     var dict = parameters.dict; | ||||||
|  |     var parentItem = dict.get('Parent'); | ||||||
|  |     if (!parentItem) { | ||||||
|  |       warn('Popup annotation has a missing or invalid parent annotation.'); | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     this.data.parentId = dict.getRaw('Parent').toString(); | ||||||
|  |     this.data.title = stringToPDFString(parentItem.get('T') || ''); | ||||||
|  |     this.data.contents = stringToPDFString(parentItem.get('Contents') || ''); | ||||||
|  | 
 | ||||||
|  |     if (!parentItem.has('C')) { | ||||||
|  |       // Fall back to the default background color.
 | ||||||
|  |       this.data.color = null; | ||||||
|  |     } else { | ||||||
|  |       this.setColor(parentItem.get('C')); | ||||||
|  |       this.data.color = this.color; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     this.data.hasHtml = (this.data.title || this.data.contents); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   Util.inherit(PopupAnnotation, Annotation, {}); | ||||||
|  | 
 | ||||||
|  |   return PopupAnnotation; | ||||||
|  | })(); | ||||||
|  | 
 | ||||||
| exports.Annotation = Annotation; | exports.Annotation = Annotation; | ||||||
| exports.AnnotationBorderStyle = AnnotationBorderStyle; | exports.AnnotationBorderStyle = AnnotationBorderStyle; | ||||||
| exports.AnnotationFactory = AnnotationFactory; | exports.AnnotationFactory = AnnotationFactory; | ||||||
|  | |||||||
| @ -36,11 +36,10 @@ var LinkTargetStringMap = sharedUtil.LinkTargetStringMap; | |||||||
| var warn = sharedUtil.warn; | var warn = sharedUtil.warn; | ||||||
| var CustomStyle = displayDOMUtils.CustomStyle; | var CustomStyle = displayDOMUtils.CustomStyle; | ||||||
| 
 | 
 | ||||||
| var ANNOT_MIN_SIZE = 10; // px
 |  | ||||||
| 
 |  | ||||||
| /** | /** | ||||||
|  * @typedef {Object} AnnotationElementParameters |  * @typedef {Object} AnnotationElementParameters | ||||||
|  * @property {Object} data |  * @property {Object} data | ||||||
|  |  * @property {HTMLDivElement} layer | ||||||
|  * @property {PDFPage} page |  * @property {PDFPage} page | ||||||
|  * @property {PageViewport} viewport |  * @property {PageViewport} viewport | ||||||
|  * @property {IPDFLinkService} linkService |  * @property {IPDFLinkService} linkService | ||||||
| @ -70,6 +69,9 @@ AnnotationElementFactory.prototype = | |||||||
|       case AnnotationType.WIDGET: |       case AnnotationType.WIDGET: | ||||||
|         return new WidgetAnnotationElement(parameters); |         return new WidgetAnnotationElement(parameters); | ||||||
| 
 | 
 | ||||||
|  |       case AnnotationType.POPUP: | ||||||
|  |         return new PopupAnnotationElement(parameters); | ||||||
|  | 
 | ||||||
|       default: |       default: | ||||||
|         throw new Error('Unimplemented annotation type "' + subtype + '"'); |         throw new Error('Unimplemented annotation type "' + subtype + '"'); | ||||||
|     } |     } | ||||||
| @ -83,6 +85,7 @@ AnnotationElementFactory.prototype = | |||||||
| var AnnotationElement = (function AnnotationElementClosure() { | var AnnotationElement = (function AnnotationElementClosure() { | ||||||
|   function AnnotationElement(parameters) { |   function AnnotationElement(parameters) { | ||||||
|     this.data = parameters.data; |     this.data = parameters.data; | ||||||
|  |     this.layer = parameters.layer; | ||||||
|     this.page = parameters.page; |     this.page = parameters.page; | ||||||
|     this.viewport = parameters.viewport; |     this.viewport = parameters.viewport; | ||||||
|     this.linkService = parameters.linkService; |     this.linkService = parameters.linkService; | ||||||
| @ -292,8 +295,6 @@ var LinkAnnotationElement = (function LinkAnnotationElementClosure() { | |||||||
| var TextAnnotationElement = (function TextAnnotationElementClosure() { | var TextAnnotationElement = (function TextAnnotationElementClosure() { | ||||||
|   function TextAnnotationElement(parameters) { |   function TextAnnotationElement(parameters) { | ||||||
|     AnnotationElement.call(this, parameters); |     AnnotationElement.call(this, parameters); | ||||||
| 
 |  | ||||||
|     this.pinned = false; |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   Util.inherit(TextAnnotationElement, AnnotationElement, { |   Util.inherit(TextAnnotationElement, AnnotationElement, { | ||||||
| @ -305,127 +306,35 @@ var TextAnnotationElement = (function TextAnnotationElementClosure() { | |||||||
|      * @returns {HTMLSectionElement} |      * @returns {HTMLSectionElement} | ||||||
|      */ |      */ | ||||||
|     render: function TextAnnotationElement_render() { |     render: function TextAnnotationElement_render() { | ||||||
|       var rect = this.data.rect, container = this.container; |       this.container.className = 'textAnnotation'; | ||||||
| 
 | 
 | ||||||
|       // Sanity check because of OOo-generated PDFs.
 |       var image = document.createElement('img'); | ||||||
|       if ((rect[3] - rect[1]) < ANNOT_MIN_SIZE) { |       image.style.height = this.container.style.height; | ||||||
|         rect[3] = rect[1] + ANNOT_MIN_SIZE; |       image.style.width = this.container.style.width; | ||||||
|       } |  | ||||||
|       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-' + |       image.src = PDFJS.imageResourcesPath + 'annotation-' + | ||||||
|         iconName.toLowerCase() + '.svg'; |         this.data.name.toLowerCase() + '.svg'; | ||||||
|       image.alt = '[{{type}} Annotation]'; |       image.alt = '[{{type}} Annotation]'; | ||||||
|       image.dataset.l10nId = 'text_annotation_type'; |       image.dataset.l10nId = 'text_annotation_type'; | ||||||
|       image.dataset.l10nArgs = JSON.stringify({type: iconName}); |       image.dataset.l10nArgs = JSON.stringify({type: this.data.name}); | ||||||
| 
 | 
 | ||||||
|       var contentWrapper = document.createElement('div'); |       if (!this.data.hasPopup) { | ||||||
|       contentWrapper.className = 'annotTextContentWrapper'; |         var popupElement = new PopupElement({ | ||||||
|       contentWrapper.style.left = Math.floor(rect[2] - rect[0] + 5) + 'px'; |           parentContainer: this.container, | ||||||
|       contentWrapper.style.top = '-10px'; |           parentTrigger: image, | ||||||
|  |           color: this.data.color, | ||||||
|  |           title: this.data.title, | ||||||
|  |           contents: this.data.contents | ||||||
|  |         }); | ||||||
|  |         var popup = popupElement.render(); | ||||||
| 
 | 
 | ||||||
|       var content = this.content = document.createElement('div'); |         // Position the popup next to the Text annotation's container.
 | ||||||
|       content.className = 'annotTextContent'; |         popup.style.left = image.style.width; | ||||||
|       content.setAttribute('hidden', true); |  | ||||||
| 
 | 
 | ||||||
|       var i, ii; |         this.container.appendChild(popup); | ||||||
|       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'); |       this.container.appendChild(image); | ||||||
|       var text = document.createElement('p'); |       return this.container; | ||||||
|       title.textContent = this.data.title; |  | ||||||
| 
 |  | ||||||
|       if (!this.data.content && !this.data.title) { |  | ||||||
|         content.setAttribute('hidden', true); |  | ||||||
|       } else { |  | ||||||
|         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); |  | ||||||
| 
 |  | ||||||
|         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)); |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       content.appendChild(title); |  | ||||||
|       content.appendChild(text); |  | ||||||
|       contentWrapper.appendChild(content); |  | ||||||
|       container.appendChild(image); |  | ||||||
|       container.appendChild(contentWrapper); |  | ||||||
|       return container; |  | ||||||
|     }, |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 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); |  | ||||||
|       } |  | ||||||
|     } |     } | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
| @ -499,6 +408,189 @@ var WidgetAnnotationElement = (function WidgetAnnotationElementClosure() { | |||||||
|   return WidgetAnnotationElement; |   return WidgetAnnotationElement; | ||||||
| })(); | })(); | ||||||
| 
 | 
 | ||||||
|  | /** | ||||||
|  |  * @class | ||||||
|  |  * @alias PopupAnnotationElement | ||||||
|  |  */ | ||||||
|  | var PopupAnnotationElement = (function PopupAnnotationElementClosure() { | ||||||
|  |   function PopupAnnotationElement(parameters) { | ||||||
|  |     AnnotationElement.call(this, parameters); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   Util.inherit(PopupAnnotationElement, AnnotationElement, { | ||||||
|  |     /** | ||||||
|  |      * Render the popup annotation's HTML element in the empty container. | ||||||
|  |      * | ||||||
|  |      * @public | ||||||
|  |      * @memberof PopupAnnotationElement | ||||||
|  |      * @returns {HTMLSectionElement} | ||||||
|  |      */ | ||||||
|  |     render: function PopupAnnotationElement_render() { | ||||||
|  |       this.container.className = 'popupAnnotation'; | ||||||
|  | 
 | ||||||
|  |       var selector = '[data-annotation-id="' + this.data.parentId + '"]'; | ||||||
|  |       var parentElement = this.layer.querySelector(selector); | ||||||
|  |       if (!parentElement) { | ||||||
|  |         return this.container; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       var popup = new PopupElement({ | ||||||
|  |         parentContainer: parentElement, | ||||||
|  |         parentTrigger: parentElement, | ||||||
|  |         color: this.data.color, | ||||||
|  |         title: this.data.title, | ||||||
|  |         contents: this.data.contents | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       // Position the popup next to the parent annotation's container.
 | ||||||
|  |       // PDF viewers ignore a popup annotation's rectangle.
 | ||||||
|  |       var parentLeft = parseFloat(parentElement.style.left); | ||||||
|  |       var parentWidth = parseFloat(parentElement.style.width); | ||||||
|  |       CustomStyle.setProp('transformOrigin', this.container, | ||||||
|  |                           -(parentLeft + parentWidth) + 'px -' + | ||||||
|  |                           parentElement.style.top); | ||||||
|  |       this.container.style.left = (parentLeft + parentWidth) + 'px'; | ||||||
|  | 
 | ||||||
|  |       this.container.appendChild(popup.render()); | ||||||
|  |       return this.container; | ||||||
|  |     } | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   return PopupAnnotationElement; | ||||||
|  | })(); | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * @class | ||||||
|  |  * @alias PopupElement  | ||||||
|  |  */ | ||||||
|  | var PopupElement = (function PopupElementClosure() { | ||||||
|  |   var BACKGROUND_ENLIGHT = 0.7; | ||||||
|  | 
 | ||||||
|  |   function PopupElement(parameters) { | ||||||
|  |     this.parentContainer = parameters.parentContainer; | ||||||
|  |     this.parentTrigger = parameters.parentTrigger; | ||||||
|  |     this.color = parameters.color; | ||||||
|  |     this.title = parameters.title; | ||||||
|  |     this.contents = parameters.contents; | ||||||
|  | 
 | ||||||
|  |     this.pinned = false; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   PopupElement.prototype = /** @lends PopupElement.prototype */ { | ||||||
|  |     /** | ||||||
|  |      * Render the popup's HTML element. | ||||||
|  |      * | ||||||
|  |      * @public | ||||||
|  |      * @memberof PopupElement | ||||||
|  |      * @returns {HTMLSectionElement} | ||||||
|  |      */ | ||||||
|  |     render: function PopupElement_render() { | ||||||
|  |       var wrapper = document.createElement('div'); | ||||||
|  |       wrapper.className = 'popupWrapper'; | ||||||
|  | 
 | ||||||
|  |       var popup = this.popup = document.createElement('div'); | ||||||
|  |       popup.className = 'popup'; | ||||||
|  |       popup.setAttribute('hidden', true); | ||||||
|  | 
 | ||||||
|  |       var color = this.color; | ||||||
|  |       if (color) { | ||||||
|  |         // Enlighten the color.
 | ||||||
|  |         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]; | ||||||
|  |         popup.style.backgroundColor = Util.makeCssRgb(r | 0, g | 0, b | 0); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       var contents = this._formatContents(this.contents); | ||||||
|  |       var title = document.createElement('h1'); | ||||||
|  |       title.textContent = this.title; | ||||||
|  | 
 | ||||||
|  |       // Attach the event listeners to the trigger element.
 | ||||||
|  |       var trigger = this.parentTrigger; | ||||||
|  |       trigger.addEventListener('click', this._toggle.bind(this)); | ||||||
|  |       trigger.addEventListener('mouseover', this._show.bind(this, false)); | ||||||
|  |       trigger.addEventListener('mouseout', this._hide.bind(this, false)); | ||||||
|  |       popup.addEventListener('click', this._hide.bind(this, true)); | ||||||
|  | 
 | ||||||
|  |       popup.appendChild(title); | ||||||
|  |       popup.appendChild(contents); | ||||||
|  |       wrapper.appendChild(popup); | ||||||
|  |       return wrapper; | ||||||
|  |     }, | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Format the contents of the popup by adding newlines where necessary. | ||||||
|  |      * | ||||||
|  |      * @private | ||||||
|  |      * @param {string} contents | ||||||
|  |      * @memberof PopupElement | ||||||
|  |      * @returns {HTMLParagraphElement} | ||||||
|  |      */ | ||||||
|  |     _formatContents: function PopupElement_formatContents(contents) { | ||||||
|  |       var p = document.createElement('p'); | ||||||
|  |       var lines = contents.split(/(?:\r\n?|\n)/); | ||||||
|  |       for (var i = 0, ii = lines.length; i < ii; ++i) { | ||||||
|  |         var line = lines[i]; | ||||||
|  |         p.appendChild(document.createTextNode(line)); | ||||||
|  |         if (i < (ii - 1)) { | ||||||
|  |           p.appendChild(document.createElement('br')); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       return p; | ||||||
|  |     }, | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Toggle the visibility of the popup. | ||||||
|  |      * | ||||||
|  |      * @private | ||||||
|  |      * @memberof PopupElement | ||||||
|  |      */ | ||||||
|  |     _toggle: function PopupElement_toggle() { | ||||||
|  |       if (this.pinned) { | ||||||
|  |         this._hide(true); | ||||||
|  |       } else { | ||||||
|  |         this._show(true); | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Show the popup. | ||||||
|  |      * | ||||||
|  |      * @private | ||||||
|  |      * @param {boolean} pin | ||||||
|  |      * @memberof PopupElement | ||||||
|  |      */ | ||||||
|  |     _show: function PopupElement_show(pin) { | ||||||
|  |       if (pin) { | ||||||
|  |         this.pinned = true; | ||||||
|  |       } | ||||||
|  |       if (this.popup.hasAttribute('hidden')) { | ||||||
|  |         this.popup.removeAttribute('hidden'); | ||||||
|  |         this.parentContainer.style.zIndex += 1; | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Hide the popup. | ||||||
|  |      * | ||||||
|  |      * @private | ||||||
|  |      * @param {boolean} unpin | ||||||
|  |      * @memberof PopupElement | ||||||
|  |      */ | ||||||
|  |     _hide: function PopupElement_hide(unpin) { | ||||||
|  |       if (unpin) { | ||||||
|  |         this.pinned = false; | ||||||
|  |       } | ||||||
|  |       if (!this.popup.hasAttribute('hidden') && !this.pinned) { | ||||||
|  |         this.popup.setAttribute('hidden', true); | ||||||
|  |         this.parentContainer.style.zIndex -= 1; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   return PopupElement; | ||||||
|  | })(); | ||||||
|  | 
 | ||||||
| /** | /** | ||||||
|  * @typedef {Object} AnnotationLayerParameters |  * @typedef {Object} AnnotationLayerParameters | ||||||
|  * @property {PageViewport} viewport |  * @property {PageViewport} viewport | ||||||
| @ -532,6 +624,7 @@ var AnnotationLayer = (function AnnotationLayerClosure() { | |||||||
| 
 | 
 | ||||||
|         var properties = { |         var properties = { | ||||||
|           data: data, |           data: data, | ||||||
|  |           layer: parameters.div, | ||||||
|           page: parameters.page, |           page: parameters.page, | ||||||
|           viewport: parameters.viewport, |           viewport: parameters.viewport, | ||||||
|           linkService: parameters.linkService |           linkService: parameters.linkService | ||||||
|  | |||||||
| @ -39,35 +39,37 @@ | |||||||
|   box-shadow: 0px 2px 10px #ff0; |   box-shadow: 0px 2px 10px #ff0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .annotationLayer .annotText > img { | .annotationLayer .textAnnotation img { | ||||||
|   position: absolute; |   position: absolute; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .annotationLayer .annotTextContentWrapper { | .annotationLayer .popupWrapper { | ||||||
|   position: absolute; |   position: absolute; | ||||||
|   width: 20em; |   width: 20em; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .annotationLayer .annotTextContent { | .annotationLayer .popup { | ||||||
|  |   position: absolute; | ||||||
|   z-index: 200; |   z-index: 200; | ||||||
|   float: left; |  | ||||||
|   max-width: 20em; |   max-width: 20em; | ||||||
|   background-color: #FFFF99; |   background-color: #FFFF99; | ||||||
|   box-shadow: 0px 2px 5px #333; |   box-shadow: 0px 2px 5px #333; | ||||||
|   border-radius: 2px; |   border-radius: 2px; | ||||||
|   padding: 0.6em; |   padding: 0.6em; | ||||||
|  |   margin-left: 5px; | ||||||
|   display: block !important; |   display: block !important; | ||||||
|   font: message-box; |   font: message-box; | ||||||
|  |   word-wrap: break-word; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .annotationLayer .annotTextContent > h1 { | .annotationLayer .popup h1 { | ||||||
|   font-size: 1em; |   font-size: 1em; | ||||||
|   border-bottom: 1px solid #000000; |   border-bottom: 1px solid #000000; | ||||||
|   margin: 0; |   margin: 0; | ||||||
|   padding: 0 0 0.2em 0; |   padding: 0 0 0.2em 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .annotationLayer .annotTextContent > p { | .annotationLayer .popup p { | ||||||
|   margin: 0; |   margin: 0; | ||||||
|   padding: 0.2em 0 0 0; |   padding: 0.2em 0 0 0; | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								test/pdfs/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								test/pdfs/.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -198,3 +198,5 @@ | |||||||
| !issue6108.pdf | !issue6108.pdf | ||||||
| !issue6113.pdf | !issue6113.pdf | ||||||
| !openoffice.pdf | !openoffice.pdf | ||||||
|  | !annotation-link-text-popup.pdf | ||||||
|  | !annotation-text-without-popup.pdf | ||||||
|  | |||||||
							
								
								
									
										
											BIN
										
									
								
								test/pdfs/annotation-link-text-popup.pdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/pdfs/annotation-link-text-popup.pdf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/pdfs/annotation-text-without-popup.pdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/pdfs/annotation-text-without-popup.pdf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| @ -2616,6 +2616,21 @@ | |||||||
|        "rounds": 1, |        "rounds": 1, | ||||||
|        "type": "load" |        "type": "load" | ||||||
|     }, |     }, | ||||||
|  |     {  "id": "annotation-link-text-popup", | ||||||
|  |        "file": "pdfs/annotation-link-text-popup.pdf", | ||||||
|  |        "md5": "4bbf56e81d47232de5f305124ab0ba27", | ||||||
|  |        "rounds": 1, | ||||||
|  |        "type": "eq", | ||||||
|  |        "annotations": true | ||||||
|  |     }, | ||||||
|  |     {  "id": "annotation-text-without-popup", | ||||||
|  |        "file": "pdfs/annotation-text-without-popup.pdf", | ||||||
|  |        "md5": "7c2d241babe00139e34b9f8369a909eb", | ||||||
|  |        "rounds": 1, | ||||||
|  |        "type": "eq", | ||||||
|  |        "annotations": true, | ||||||
|  |        "about": "Text annotation without a separate Popup annotation" | ||||||
|  |     }, | ||||||
|     {  "id": "issue6108", |     {  "id": "issue6108", | ||||||
|        "file": "pdfs/issue6108.pdf", |        "file": "pdfs/issue6108.pdf", | ||||||
|        "md5": "8961cb55149495989a80bf0487e0f076", |        "md5": "8961cb55149495989a80bf0487e0f076", | ||||||
|  | |||||||
| @ -23,34 +23,36 @@ | |||||||
|   box-shadow: 0px 2px 10px #ff0; |   box-shadow: 0px 2px 10px #ff0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .annotationLayer .annotText > img { | .annotationLayer .textAnnotation img { | ||||||
|   position: absolute; |   position: absolute; | ||||||
|   cursor: pointer; |   cursor: pointer; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .annotationLayer .annotTextContentWrapper { | .annotationLayer .popupWrapper { | ||||||
|   position: absolute; |   position: absolute; | ||||||
|   width: 20em; |   width: 20em; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .annotationLayer .annotTextContent { | .annotationLayer .popup { | ||||||
|  |   position: absolute; | ||||||
|   z-index: 200; |   z-index: 200; | ||||||
|   float: left; |  | ||||||
|   max-width: 20em; |   max-width: 20em; | ||||||
|   background-color: #FFFF99; |   background-color: #FFFF99; | ||||||
|   box-shadow: 0px 2px 5px #333; |   box-shadow: 0px 2px 5px #333; | ||||||
|   border-radius: 2px; |   border-radius: 2px; | ||||||
|   padding: 0.6em; |   padding: 0.6em; | ||||||
|  |   margin-left: 5px; | ||||||
|   cursor: pointer; |   cursor: pointer; | ||||||
|  |   word-wrap: break-word; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .annotationLayer .annotTextContent > h1 { | .annotationLayer .popup h1 { | ||||||
|   font-size: 1em; |   font-size: 1em; | ||||||
|   border-bottom: 1px solid #000000; |   border-bottom: 1px solid #000000; | ||||||
|   padding-bottom: 0.2em; |   padding-bottom: 0.2em; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .annotationLayer .annotTextContent > p { | .annotationLayer .popup p { | ||||||
|   padding-top: 0.2em; |   padding-top: 0.2em; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user