From f20b1b0f12fd3498b6ed3f76fcd9f92c7e8a564b Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Thu, 6 Oct 2016 20:38:50 -0400 Subject: [PATCH] Bug 1308362 - Update pdf.js to version 1.6.221. r=bdahl --- browser/extensions/pdfjs/README.mozilla | 2 +- browser/extensions/pdfjs/content/build/pdf.js | 78 +++++++++++++++-- .../pdfjs/content/build/pdf.worker.js | 83 +++++++++++++++++-- .../extensions/pdfjs/content/web/viewer.css | 19 +++-- .../extensions/pdfjs/content/web/viewer.js | 24 +++--- 5 files changed, 167 insertions(+), 39 deletions(-) diff --git a/browser/extensions/pdfjs/README.mozilla b/browser/extensions/pdfjs/README.mozilla index 1eff6c973b4e..54ebb0b7f0f1 100644 --- a/browser/extensions/pdfjs/README.mozilla +++ b/browser/extensions/pdfjs/README.mozilla @@ -1,3 +1,3 @@ This is the pdf.js project output, https://github.com/mozilla/pdf.js -Current extension version is: 1.5.498 +Current extension version is: 1.6.221 diff --git a/browser/extensions/pdfjs/content/build/pdf.js b/browser/extensions/pdfjs/content/build/pdf.js index 78fe9b7a0718..e1a6df5d3e79 100644 --- a/browser/extensions/pdfjs/content/build/pdf.js +++ b/browser/extensions/pdfjs/content/build/pdf.js @@ -28,8 +28,8 @@ factory((root.pdfjsDistBuildPdf = {})); // Use strict in our context only - users might not want it 'use strict'; -var pdfjsVersion = '1.5.498'; -var pdfjsBuild = '1564dc3'; +var pdfjsVersion = '1.6.221'; +var pdfjsBuild = 'f8bd3d4'; var pdfjsFilePath = typeof document !== 'undefined' && document.currentScript ? @@ -851,15 +851,15 @@ var Util = (function UtilClosure() { } }; - Util.getInheritableProperty = function Util_getInheritableProperty(dict, - name) { + Util.getInheritableProperty = + function Util_getInheritableProperty(dict, name, getArray) { while (dict && !dict.has(name)) { dict = dict.get('Parent'); } if (!dict) { return null; } - return dict.get(name); + return getArray ? dict.getArray(name) : dict.get(name); }; Util.inherit = function Util_inherit(sub, base, prototype) { @@ -1993,6 +1993,8 @@ AnnotationElementFactory.prototype = switch (fieldType) { case 'Tx': return new TextWidgetAnnotationElement(parameters); + case 'Ch': + return new ChoiceWidgetAnnotationElement(parameters); } return new WidgetAnnotationElement(parameters); @@ -2317,9 +2319,7 @@ var TextAnnotationElement = (function TextAnnotationElementClosure() { * @alias WidgetAnnotationElement */ var WidgetAnnotationElement = (function WidgetAnnotationElementClosure() { - function WidgetAnnotationElement(parameters) { - var isRenderable = parameters.renderInteractiveForms || - (!parameters.data.hasAppearance && !!parameters.data.fieldValue); + function WidgetAnnotationElement(parameters, isRenderable) { AnnotationElement.call(this, parameters, isRenderable); } @@ -2349,7 +2349,9 @@ var TextWidgetAnnotationElement = ( var TEXT_ALIGNMENT = ['left', 'center', 'right']; function TextWidgetAnnotationElement(parameters) { - WidgetAnnotationElement.call(this, parameters); + var isRenderable = parameters.renderInteractiveForms || + (!parameters.data.hasAppearance && !!parameters.data.fieldValue); + WidgetAnnotationElement.call(this, parameters, isRenderable); } Util.inherit(TextWidgetAnnotationElement, WidgetAnnotationElement, { @@ -2445,6 +2447,64 @@ var TextWidgetAnnotationElement = ( return TextWidgetAnnotationElement; })(); +/** + * @class + * @alias ChoiceWidgetAnnotationElement + */ +var ChoiceWidgetAnnotationElement = ( + function ChoiceWidgetAnnotationElementClosure() { + function ChoiceWidgetAnnotationElement(parameters) { + WidgetAnnotationElement.call(this, parameters, + parameters.renderInteractiveForms); + } + + Util.inherit(ChoiceWidgetAnnotationElement, WidgetAnnotationElement, { + /** + * Render the choice widget annotation's HTML element in the empty + * container. + * + * @public + * @memberof ChoiceWidgetAnnotationElement + * @returns {HTMLSectionElement} + */ + render: function ChoiceWidgetAnnotationElement_render() { + this.container.className = 'choiceWidgetAnnotation'; + + var selectElement = document.createElement('select'); + selectElement.disabled = this.data.readOnly; + + if (!this.data.combo) { + // List boxes have a size and (optionally) multiple selection. + selectElement.size = this.data.options.length; + + if (this.data.multiSelect) { + selectElement.multiple = true; + } + } + + // Insert the options into the choice field. + for (var i = 0, ii = this.data.options.length; i < ii; i++) { + var option = this.data.options[i]; + + var optionElement = document.createElement('option'); + optionElement.textContent = option.displayValue; + optionElement.value = option.exportValue; + + if (this.data.fieldValue.indexOf(option.displayValue) >= 0) { + optionElement.setAttribute('selected', true); + } + + selectElement.appendChild(optionElement); + } + + this.container.appendChild(selectElement); + return this.container; + } + }); + + return ChoiceWidgetAnnotationElement; +})(); + /** * @class * @alias PopupAnnotationElement diff --git a/browser/extensions/pdfjs/content/build/pdf.worker.js b/browser/extensions/pdfjs/content/build/pdf.worker.js index 29e0b547176b..04ff398aeefd 100644 --- a/browser/extensions/pdfjs/content/build/pdf.worker.js +++ b/browser/extensions/pdfjs/content/build/pdf.worker.js @@ -28,8 +28,8 @@ factory((root.pdfjsDistBuildPdfWorker = {})); // Use strict in our context only - users might not want it 'use strict'; -var pdfjsVersion = '1.5.498'; -var pdfjsBuild = '1564dc3'; +var pdfjsVersion = '1.6.221'; +var pdfjsBuild = 'f8bd3d4'; var pdfjsFilePath = typeof document !== 'undefined' && document.currentScript ? @@ -1837,15 +1837,15 @@ var Util = (function UtilClosure() { } }; - Util.getInheritableProperty = function Util_getInheritableProperty(dict, - name) { + Util.getInheritableProperty = + function Util_getInheritableProperty(dict, name, getArray) { while (dict && !dict.has(name)) { dict = dict.get('Parent'); } if (!dict) { return null; } - return dict.get(name); + return getArray ? dict.getArray(name) : dict.get(name); }; Util.inherit = function Util_inherit(sub, base, prototype) { @@ -24660,7 +24660,10 @@ var Parser = (function ParserClosure() { return stream; }, makeFilter: function Parser_makeFilter(stream, name, maybeLength, params) { - if (stream.dict.get('Length') === 0 && !maybeLength) { + // Since the 'Length' entry in the stream dictionary can be completely + // wrong, e.g. zero for non-empty streams, only skip parsing the stream + // when we can be absolutely certain that it actually is empty. + if (maybeLength === 0) { warn('Empty "' + name + '" stream.'); return new NullStream(stream); } @@ -39368,6 +39371,8 @@ AnnotationFactory.prototype = /** @lends AnnotationFactory.prototype */ { switch (fieldType) { case 'Tx': return new TextWidgetAnnotation(parameters); + case 'Ch': + return new ChoiceWidgetAnnotation(parameters); } warn('Unimplemented widget field type "' + fieldType + '", ' + 'falling back to base field type.'); @@ -39881,8 +39886,8 @@ var WidgetAnnotation = (function WidgetAnnotationClosure() { var data = this.data; data.annotationType = AnnotationType.WIDGET; - data.fieldValue = stringToPDFString( - Util.getInheritableProperty(dict, 'V') || ''); + data.fieldValue = Util.getInheritableProperty(dict, 'V', + /* getArray = */ true); data.alternativeText = stringToPDFString(dict.get('TU') || ''); data.defaultAppearance = Util.getInheritableProperty(dict, 'DA') || ''; var fieldType = Util.getInheritableProperty(dict, 'FT'); @@ -39894,6 +39899,8 @@ var WidgetAnnotation = (function WidgetAnnotationClosure() { data.fieldFlags = 0; } + data.readOnly = this.hasFieldFlag(AnnotationFieldFlag.READONLY); + // Hide signatures because we cannot validate them. if (data.fieldType === 'Sig') { this.setFlags(AnnotationFlag.HIDDEN); @@ -39955,6 +39962,9 @@ var TextWidgetAnnotation = (function TextWidgetAnnotationClosure() { function TextWidgetAnnotation(params) { WidgetAnnotation.call(this, params); + // The field value is always a string. + this.data.fieldValue = stringToPDFString(this.data.fieldValue || ''); + // Determine the alignment of text in the field. var alignment = Util.getInheritableProperty(params.dict, 'Q'); if (!isInt(alignment) || alignment < 0 || alignment > 2) { @@ -39970,7 +39980,6 @@ var TextWidgetAnnotation = (function TextWidgetAnnotationClosure() { this.data.maxLen = maximumLength; // Process field flags for the display layer. - this.data.readOnly = this.hasFieldFlag(AnnotationFieldFlag.READONLY); this.data.multiLine = this.hasFieldFlag(AnnotationFieldFlag.MULTILINE); this.data.comb = this.hasFieldFlag(AnnotationFieldFlag.COMB) && !this.hasFieldFlag(AnnotationFieldFlag.MULTILINE) && @@ -40014,6 +40023,62 @@ var TextWidgetAnnotation = (function TextWidgetAnnotationClosure() { return TextWidgetAnnotation; })(); +var ChoiceWidgetAnnotation = (function ChoiceWidgetAnnotationClosure() { + function ChoiceWidgetAnnotation(params) { + WidgetAnnotation.call(this, params); + + // Determine the options. The options array may consist of strings or + // arrays. If the array consists of arrays, then the first element of + // each array is the export value and the second element of each array is + // the display value. If the array consists of strings, then these + // represent both the export and display value. In this case, we convert + // it to an array of arrays as well for convenience in the display layer. + this.data.options = []; + + var options = params.dict.getArray('Opt'); + if (isArray(options)) { + for (var i = 0, ii = options.length; i < ii; i++) { + var option = options[i]; + + this.data.options[i] = { + exportValue: isArray(option) ? option[0] : option, + displayValue: isArray(option) ? option[1] : option, + }; + } + } + + // Determine the field value. In this case, it may be a string or an + // array of strings. For convenience in the display layer, convert the + // string to an array of one string as well. + if (!isArray(this.data.fieldValue)) { + this.data.fieldValue = [this.data.fieldValue]; + } + + // Process field flags for the display layer. + this.data.combo = this.hasFieldFlag(AnnotationFieldFlag.COMBO); + this.data.multiSelect = this.hasFieldFlag(AnnotationFieldFlag.MULTISELECT); + } + + Util.inherit(ChoiceWidgetAnnotation, WidgetAnnotation, { + getOperatorList: + function ChoiceWidgetAnnotation_getOperatorList(evaluator, task, + renderForms) { + var operatorList = new OperatorList(); + + // Do not render form elements on the canvas when interactive forms are + // enabled. The display layer is responsible for rendering them instead. + if (renderForms) { + return Promise.resolve(operatorList); + } + + return Annotation.prototype.getOperatorList.call(this, evaluator, task, + renderForms); + } + }); + + return ChoiceWidgetAnnotation; +})(); + var TextAnnotation = (function TextAnnotationClosure() { var DEFAULT_ICON_SIZE = 22; // px diff --git a/browser/extensions/pdfjs/content/web/viewer.css b/browser/extensions/pdfjs/content/web/viewer.css index 574a600dca20..4e62fac4ebd6 100644 --- a/browser/extensions/pdfjs/content/web/viewer.css +++ b/browser/extensions/pdfjs/content/web/viewer.css @@ -102,7 +102,8 @@ } .annotationLayer .textWidgetAnnotation input, -.annotationLayer .textWidgetAnnotation textarea { +.annotationLayer .textWidgetAnnotation textarea, +.annotationLayer .choiceWidgetAnnotation select { background-color: rgba(0, 54, 255, 0.13); border: 1px solid transparent; box-sizing: border-box; @@ -120,19 +121,22 @@ } .annotationLayer .textWidgetAnnotation input[disabled], -.annotationLayer .textWidgetAnnotation textarea[disabled] { +.annotationLayer .textWidgetAnnotation textarea[disabled], +.annotationLayer .choiceWidgetAnnotation select[disabled] { background: none; border: 1px solid transparent; cursor: not-allowed; } .annotationLayer .textWidgetAnnotation input:hover, -.annotationLayer .textWidgetAnnotation textarea:hover { +.annotationLayer .textWidgetAnnotation textarea:hover, +.annotationLayer .choiceWidgetAnnotation select:hover { border: 1px solid #000; } .annotationLayer .textWidgetAnnotation input:focus, -.annotationLayer .textWidgetAnnotation textarea:focus { +.annotationLayer .textWidgetAnnotation textarea:focus, +.annotationLayer .choiceWidgetAnnotation select:focus { background: none; border: 1px solid transparent; } @@ -1936,8 +1940,11 @@ html[dir='rtl'] #documentPropertiesOverlay .row > * { position: relative; top: 0; left: 0; - height: 100%; - overflow: hidden; + width: 1px; + height: 1px; + overflow: visible; + page-break-after: always; + page-break-inside: avoid; } #printContainer canvas { display: block; diff --git a/browser/extensions/pdfjs/content/web/viewer.js b/browser/extensions/pdfjs/content/web/viewer.js index b448cc76b755..0f924833d95b 100644 --- a/browser/extensions/pdfjs/content/web/viewer.js +++ b/browser/extensions/pdfjs/content/web/viewer.js @@ -5668,22 +5668,18 @@ var PDFPageView = (function PDFPageViewClosure() { var pdfPage = this.pdfPage; var viewport = pdfPage.getViewport(1); - // Use the same hack we use for high dpi displays for printing to get - // better output until bug 811002 is fixed in FF. - var PRINT_OUTPUT_SCALE = 2; + var canvas = document.createElement('canvas'); - // The logical size of the canvas. - canvas.width = Math.floor(viewport.width) * PRINT_OUTPUT_SCALE; - canvas.height = Math.floor(viewport.height) * PRINT_OUTPUT_SCALE; + // The size of the canvas in pixels for printing. + var PRINT_RESOLUTION = 150; + var PRINT_UNITS = PRINT_RESOLUTION / 72.0; + canvas.width = Math.floor(viewport.width * PRINT_UNITS); + canvas.height = Math.floor(viewport.height * PRINT_UNITS); - // The rendered size of the canvas, relative to the size of canvasWrapper. - canvas.style.width = (PRINT_OUTPUT_SCALE * 100) + '%'; - - var cssScale = 'scale(' + (1 / PRINT_OUTPUT_SCALE) + ', ' + - (1 / PRINT_OUTPUT_SCALE) + ')'; - CustomStyle.setProp('transform' , canvas, cssScale); - CustomStyle.setProp('transformOrigin' , canvas, '0% 0%'); + // The physical size of the canvas as specified by the PDF document. + canvas.style.width = Math.floor(viewport.width * CSS_UNITS) + 'px'; + canvas.style.height = Math.floor(viewport.height * CSS_UNITS) + 'px'; var canvasWrapper = document.createElement('div'); canvasWrapper.appendChild(canvas); @@ -5696,10 +5692,10 @@ var PDFPageView = (function PDFPageViewClosure() { ctx.fillStyle = 'rgb(255, 255, 255)'; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.restore(); - ctx.scale(PRINT_OUTPUT_SCALE, PRINT_OUTPUT_SCALE); var renderContext = { canvasContext: ctx, + transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0], viewport: viewport, intent: 'print' };