From 4a30fe7522a15d2286728b2fde6b1b1853cd9ed9 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Tue, 15 Sep 2015 17:03:08 -0400 Subject: [PATCH 01/16] Bug 1205051 - Update pdf.js to version 1.1.469. r=bdahl --- browser/extensions/pdfjs/README.mozilla | 2 +- browser/extensions/pdfjs/content/build/pdf.js | 15 +- .../pdfjs/content/build/pdf.worker.js | 73 ++++++---- .../web/images/treeitem-collapsed-rtl.png | Bin 0 -> 183 bytes .../web/images/treeitem-collapsed-rtl@2x.png | Bin 0 -> 205 bytes .../content/web/images/treeitem-collapsed.png | Bin 0 -> 128 bytes .../web/images/treeitem-collapsed@2x.png | Bin 0 -> 149 bytes .../content/web/images/treeitem-expanded.png | Bin 0 -> 125 bytes .../web/images/treeitem-expanded@2x.png | Bin 0 -> 172 bytes .../extensions/pdfjs/content/web/viewer.css | 63 ++++++++- .../extensions/pdfjs/content/web/viewer.js | 128 ++++++++++++++++-- .../locales/en-US/pdfviewer/viewer.properties | 6 + 12 files changed, 241 insertions(+), 46 deletions(-) create mode 100644 browser/extensions/pdfjs/content/web/images/treeitem-collapsed-rtl.png create mode 100644 browser/extensions/pdfjs/content/web/images/treeitem-collapsed-rtl@2x.png create mode 100644 browser/extensions/pdfjs/content/web/images/treeitem-collapsed.png create mode 100644 browser/extensions/pdfjs/content/web/images/treeitem-collapsed@2x.png create mode 100644 browser/extensions/pdfjs/content/web/images/treeitem-expanded.png create mode 100644 browser/extensions/pdfjs/content/web/images/treeitem-expanded@2x.png diff --git a/browser/extensions/pdfjs/README.mozilla b/browser/extensions/pdfjs/README.mozilla index 56be1a5359f..369c738d38b 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.1.403 +Current extension version is: 1.1.469 diff --git a/browser/extensions/pdfjs/content/build/pdf.js b/browser/extensions/pdfjs/content/build/pdf.js index 8eefd83efce..d4bb55c4d0b 100644 --- a/browser/extensions/pdfjs/content/build/pdf.js +++ b/browser/extensions/pdfjs/content/build/pdf.js @@ -22,8 +22,8 @@ if (typeof PDFJS === 'undefined') { (typeof window !== 'undefined' ? window : this).PDFJS = {}; } -PDFJS.version = '1.1.403'; -PDFJS.build = '88e0326'; +PDFJS.version = '1.1.469'; +PDFJS.build = 'f06aa6a'; (function pdfjsWrapper() { // Use strict in our context only - users might not want it @@ -3953,6 +3953,9 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { this.current = this.stateStack.pop(); this.ctx.restore(); + // Ensure that the clipping path is reset (fixes issue6413.pdf). + this.pendingClip = null; + this.cachedGetSinglePixelWidth = null; } }, @@ -4340,6 +4343,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { var textHScale = current.textHScale * fontDirection; var glyphsLength = glyphs.length; var vertical = font.vertical; + var spacingDir = vertical ? 1 : -1; var defaultVMetrics = font.defaultVMetrics; var widthAdvanceScale = fontSize * current.fontMatrix[0]; @@ -4386,7 +4390,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { x += fontDirection * wordSpacing; continue; } else if (isNum(glyph)) { - x += -glyph * fontSize * 0.001; + x += spacingDir * glyph * fontSize / 1000; continue; } @@ -4456,6 +4460,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { var font = current.font; var fontSize = current.fontSize; var fontDirection = current.fontDirection; + var spacingDir = font.vertical ? 1 : -1; var charSpacing = current.charSpacing; var wordSpacing = current.wordSpacing; var textHScale = current.textHScale * fontDirection; @@ -4463,7 +4468,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { var glyphsLength = glyphs.length; var isTextInvisible = current.textRenderingMode === TextRenderingMode.INVISIBLE; - var i, glyph, width; + var i, glyph, width, spacingLength; if (isTextInvisible || fontSize === 0) { return; @@ -4484,7 +4489,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { current.x += wordSpacing * textHScale; continue; } else if (isNum(glyph)) { - var spacingLength = -glyph * 0.001 * fontSize; + spacingLength = spacingDir * glyph * fontSize / 1000; this.ctx.translate(spacingLength, 0); current.x += spacingLength * textHScale; continue; diff --git a/browser/extensions/pdfjs/content/build/pdf.worker.js b/browser/extensions/pdfjs/content/build/pdf.worker.js index 3675648b94e..36ec94e990a 100644 --- a/browser/extensions/pdfjs/content/build/pdf.worker.js +++ b/browser/extensions/pdfjs/content/build/pdf.worker.js @@ -22,8 +22,8 @@ if (typeof PDFJS === 'undefined') { (typeof window !== 'undefined' ? window : this).PDFJS = {}; } -PDFJS.version = '1.1.403'; -PDFJS.build = '88e0326'; +PDFJS.version = '1.1.469'; +PDFJS.build = 'f06aa6a'; (function pdfjsWrapper() { // Use strict in our context only - users might not want it @@ -2506,12 +2506,11 @@ var PDFDocument = (function PDFDocumentClosure() { return shadow(this, 'documentInfo', docInfo); }, get fingerprint() { - var xref = this.xref, idArray, hash, fileID = ''; + var xref = this.xref, hash, fileID = ''; + var idArray = xref.trailer.get('ID'); - if (xref.trailer.has('ID')) { - idArray = xref.trailer.get('ID'); - } - if (idArray && isArray(idArray) && idArray[0] !== EMPTY_FINGERPRINT) { + if (idArray && isArray(idArray) && idArray[0] && isString(idArray[0]) && + idArray[0] !== EMPTY_FINGERPRINT) { hash = stringToBytes(idArray[0]); } else { if (this.stream.ensureRange) { @@ -10902,11 +10901,12 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { var arr = args[0]; var combinedGlyphs = []; var arrLength = arr.length; + var state = stateManager.state; for (i = 0; i < arrLength; ++i) { var arrItem = arr[i]; if (isString(arrItem)) { Array.prototype.push.apply(combinedGlyphs, - self.handleText(arrItem, stateManager.state)); + self.handleText(arrItem, state)); } else if (isNum(arrItem)) { combinedGlyphs.push(arrItem); } @@ -11302,17 +11302,26 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { if (typeof items[j] === 'string') { buildTextGeometry(items[j], textChunk); } else { - var val = items[j] / 1000; - if (!textState.font.vertical) { - offset = -val * textState.fontSize * textState.textHScale * - textState.textMatrix[0]; - textState.translateTextMatrix(offset, 0); - textChunk.width += offset; - } else { - offset = -val * textState.fontSize * - textState.textMatrix[3]; + // PDF Specification 5.3.2 states: + // The number is expressed in thousandths of a unit of text + // space. + // This amount is subtracted from the current horizontal or + // vertical coordinate, depending on the writing mode. + // In the default coordinate system, a positive adjustment + // has the effect of moving the next glyph painted either to + // the left or down by the given amount. + var val = items[j] * textState.fontSize / 1000; + if (textState.font.vertical) { + offset = val * textState.textMatrix[3]; textState.translateTextMatrix(0, offset); + // Value needs to be added to height to paint down. textChunk.height += offset; + } else { + offset = val * textState.textHScale * + textState.textMatrix[0]; + textState.translateTextMatrix(offset, 0); + // Value needs to be subtracted from width to paint left. + textChunk.width -= offset; } if (items[j] < 0 && textState.font.spaceWidth > 0) { var fakeSpaces = -items[j] / textState.font.spaceWidth; @@ -17036,7 +17045,7 @@ var Font = (function FontClosure() { * Read the appropriate subtable from the cmap according to 9.6.6.4 from * PDF spec */ - function readCmapTable(cmap, font, isSymbolicFont) { + function readCmapTable(cmap, font, isSymbolicFont, hasEncoding) { var segment; var start = (font.start ? font.start : 0) + cmap.offset; font.pos = start; @@ -17067,7 +17076,7 @@ var Font = (function FontClosure() { // Continue the loop since there still may be a higher priority // table. } else if (platformId === 3 && encodingId === 1 && - (!isSymbolicFont || !potentialTable)) { + ((!isSymbolicFont && hasEncoding) || !potentialTable)) { useTable = true; if (!isSymbolicFont) { canBreak = true; @@ -17204,7 +17213,13 @@ var Font = (function FontClosure() { }); } } else { - error('cmap table has unsupported format: ' + format); + warn('cmap table has unsupported format: ' + format); + return { + platformId: -1, + encodingId: -1, + mappings: [], + hasShortCmap: false + }; } // removing duplicate entries @@ -18010,13 +18025,14 @@ var Font = (function FontClosure() { } else { // Most of the following logic in this code branch is based on the // 9.6.6.4 of the PDF spec. - var cmapTable = readCmapTable(tables.cmap, font, this.isSymbolicFont); + var hasEncoding = + properties.differences.length > 0 || !!properties.baseEncodingName; + var cmapTable = + readCmapTable(tables.cmap, font, this.isSymbolicFont, hasEncoding); var cmapPlatformId = cmapTable.platformId; var cmapEncodingId = cmapTable.encodingId; var cmapMappings = cmapTable.mappings; var cmapMappingsLength = cmapMappings.length; - var hasEncoding = properties.differences.length || - !!properties.baseEncodingName; // The spec seems to imply that if the font is symbolic the encoding // should be ignored, this doesn't appear to work for 'preistabelle.pdf' @@ -29894,6 +29910,9 @@ var Parser = (function ParserClosure() { this.shift(); return true; } catch (e) { + if (e instanceof MissingDataException) { + throw e; + } // Upon failure, the caller should reset this.lexer.pos to a known good // state and call this.shift() twice to reset the buffers. return false; @@ -30361,6 +30380,7 @@ var Parser = (function ParserClosure() { }, makeFilter: function Parser_makeFilter(stream, name, maybeLength, params) { if (stream.dict.get('Length') === 0 && !maybeLength) { + warn('Empty "' + name + '" stream.'); return new NullStream(stream); } try { @@ -38862,14 +38882,13 @@ var bidi = PDFJS.bidi = (function bidiClosure() { // don't mirror as characters are already mirrored in the pdf // Finally, return string - var result = ''; for (i = 0, ii = chars.length; i < ii; ++i) { var ch = chars[i]; - if (ch !== '<' && ch !== '>') { - result += ch; + if (ch === '<' || ch === '>') { + chars[i] = ''; } } - return createBidiText(result, isLTR); + return createBidiText(chars.join(''), isLTR); } return bidi; diff --git a/browser/extensions/pdfjs/content/web/images/treeitem-collapsed-rtl.png b/browser/extensions/pdfjs/content/web/images/treeitem-collapsed-rtl.png new file mode 100644 index 0000000000000000000000000000000000000000..1c8b9f7010cae8edd6ca3a1146c6f07f68f5931e GIT binary patch literal 183 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>0wld=oSO}#SkfJR9T^xl_H+M9WCik>lDyqr z82-2SpV<%Ov6p!Iy0YKrWaF2XJ+}I0Cs4@O)5S4_<9c#}1C#!gI3K5HU3*qk7JfP^ zDKY)8>!ogI{c{Zp9jCt>`hHZ5LtHJS<$+UcLsOsrwZ)u_tda3Y_T1=KVi6Oo2<%Hy cUbUNH=6`p$$8L6yfCe*oy85}Sb4q9e0CZwJr2qf` literal 0 HcmV?d00001 diff --git a/browser/extensions/pdfjs/content/web/images/treeitem-collapsed-rtl@2x.png b/browser/extensions/pdfjs/content/web/images/treeitem-collapsed-rtl@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..84279368d985d74ba324ea3433b08ea5974bcc62 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+0wn(&ce?|mSkfJR9T^xl_H+M9WCik>lDyqr z82-2SpV<%Ov6p!Iy0YKrWaF2XJ+}I0Cr~Ka)5S4F<9u?$0p>W5{V$RatZw-0daHY} z{<#OiNxzd0cN;5o92e?flIcpA_8_oj153M7i1!AKLt9v!1$YfeZs0{*8S1d;7*d)WUfO=0=x|MWgTe~DWM4fAaX}J literal 0 HcmV?d00001 diff --git a/browser/extensions/pdfjs/content/web/images/treeitem-collapsed.png b/browser/extensions/pdfjs/content/web/images/treeitem-collapsed.png new file mode 100644 index 0000000000000000000000000000000000000000..06d4d3769672390920ddd9d423f52d7908fcfb36 GIT binary patch literal 128 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>0wld=oSO}#+&x_!LpZJ{CnQuDzHAj@)~YCc zcJ!pUslH1WIk z$<$8#)-<<4$>7e1Lt^WdBv>MS0tC+_?dkdu(KF##vY``K|4|Ok95LarEgxHDk6!z_ xe}ZGN#WGb9Hnl@SJ`EdME-hi&#=_6Qka7RV*Qd`VTY>g4c)I$ztaD0e0sz~DGV1^U literal 0 HcmV?d00001 diff --git a/browser/extensions/pdfjs/content/web/images/treeitem-expanded.png b/browser/extensions/pdfjs/content/web/images/treeitem-expanded.png new file mode 100644 index 0000000000000000000000000000000000000000..c8d557351cd2fc80c3abd4b19e52924cd74780d5 GIT binary patch literal 125 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>0wld=oSO}#Ts&PILn;`P75MhNs4Zk;-DbE) zpt_L5GvPZo^g4)z4*}Q$iB}$ABb+ literal 0 HcmV?d00001 diff --git a/browser/extensions/pdfjs/content/web/images/treeitem-expanded@2x.png b/browser/extensions/pdfjs/content/web/images/treeitem-expanded@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..3b3b6103b356200d05caf7fa692cadf2c1e89043 GIT binary patch literal 172 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+0wn(&ce?|mialK%Ln;`P7Z_I .thumbnail > .thumbnailSelectionRing, padding: 3px 4px 0; } +html[dir='ltr'] .outlineWithDeepNesting > .outlineItem, html[dir='ltr'] .outlineItem > .outlineItems { margin-left: 20px; } +html[dir='rtl'] .outlineWithDeepNesting > .outlineItem, html[dir='rtl'] .outlineItem > .outlineItems { margin-right: 20px; } @@ -1248,6 +1250,8 @@ html[dir='rtl'] .outlineItem > .outlineItems { text-decoration: none; display: inline-block; min-width: 95%; + min-width: calc(100% - 4px); /* Subtract the right padding (left, in RTL mode) + of the container. */ height: auto; margin-bottom: 1px; border-radius: 2px; @@ -1266,7 +1270,7 @@ html[dir='rtl'] .outlineItem > .outlineItems { } html[dir='ltr'] .outlineItem > a { - padding: 2px 0 5px 10px; + padding: 2px 0 5px 4px; } html[dir='ltr'] .attachmentsItem > button { padding: 2px 0 3px 7px; @@ -1274,13 +1278,49 @@ html[dir='ltr'] .attachmentsItem > button { } html[dir='rtl'] .outlineItem > a { - padding: 2px 10px 5px 0; + padding: 2px 4px 5px 0; } html[dir='rtl'] .attachmentsItem > button { padding: 2px 7px 3px 0; text-align: right; } +.outlineItemToggler { + position: relative; + height: 0; + width: 0; + color: hsla(0,0%,100%,.5); +} +.outlineItemToggler::before { + content: url(images/treeitem-expanded.png); + display: inline-block; + position: absolute; +} +html[dir='ltr'] .outlineItemToggler.outlineItemsHidden::before { + content: url(images/treeitem-collapsed.png); +} +html[dir='rtl'] .outlineItemToggler.outlineItemsHidden::before { + content: url(images/treeitem-collapsed-rtl.png); +} +.outlineItemToggler.outlineItemsHidden ~ .outlineItems { + display: none; +} +html[dir='ltr'] .outlineItemToggler { + float: left; +} +html[dir='rtl'] .outlineItemToggler { + float: right; +} +html[dir='ltr'] .outlineItemToggler::before { + right: 4px; +} +html[dir='rtl'] .outlineItemToggler::before { + left: 4px; +} + +.outlineItemToggler:hover, +.outlineItemToggler:hover + a, +.outlineItemToggler:hover ~ .outlineItems, .outlineItem > a:hover, .attachmentsItem > button:hover { background-color: hsla(0,0%,100%,.02); @@ -1289,6 +1329,7 @@ html[dir='rtl'] .attachmentsItem > button { box-shadow: 0 1px 0 hsla(0,0%,100%,.05) inset, 0 0 1px hsla(0,0%,100%,.2) inset, 0 0 1px hsla(0,0%,0%,.2); + border-radius: 2px; color: hsla(0,0%,100%,.9); } @@ -1704,6 +1745,24 @@ html[dir='rtl'] #documentPropertiesOverlay .row > * { .secondaryToolbarButton.documentProperties::before { content: url(images/secondaryToolbarButton-documentProperties@2x.png); } + + .outlineItemToggler::before { + transform: scale(0.5); + top: -1px; + content: url(images/treeitem-expanded@2x.png); + } + html[dir='ltr'] .outlineItemToggler.outlineItemsHidden::before { + content: url(images/treeitem-collapsed@2x.png); + } + html[dir='rtl'] .outlineItemToggler.outlineItemsHidden::before { + content: url(images/treeitem-collapsed-rtl@2x.png); + } + html[dir='ltr'] .outlineItemToggler::before { + right: 0; + } + html[dir='rtl'] .outlineItemToggler::before { + left: 0; + } } @media print { diff --git a/browser/extensions/pdfjs/content/web/viewer.js b/browser/extensions/pdfjs/content/web/viewer.js index 8d538f87372..f3e896466a1 100644 --- a/browser/extensions/pdfjs/content/web/viewer.js +++ b/browser/extensions/pdfjs/content/web/viewer.js @@ -104,6 +104,12 @@ var CustomStyle = (function CustomStyleClosure() { return CustomStyle; })(); +var NullCharactersRegExp = /\x00/g; + +function removeNullCharacters(str) { + return str.replace(NullCharactersRegExp, ''); +} + function getFileName(url) { var anchor = url.indexOf('#'); var query = url.indexOf('?'); @@ -5373,6 +5379,10 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() { this.canvas.height = 0; delete this.canvas; } + if (this.image) { + this.image.removeAttribute('src'); + delete this.image; + } }, update: function PDFThumbnailView_update(rotation) { @@ -5393,28 +5403,53 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() { _getPageDrawContext: function PDFThumbnailView_getPageDrawContext(noCtxScale) { var canvas = document.createElement('canvas'); - canvas.id = this.renderingId; - - canvas.className = 'thumbnailImage'; - canvas.setAttribute('aria-label', mozL10n.get('thumb_page_canvas', - {page: this.id}, 'Thumbnail of Page {{page}}')); - this.canvas = canvas; - this.div.setAttribute('data-loaded', true); - this.ring.appendChild(canvas); var ctx = canvas.getContext('2d'); var outputScale = getOutputScale(ctx); + canvas.width = (this.canvasWidth * outputScale.sx) | 0; canvas.height = (this.canvasHeight * outputScale.sy) | 0; canvas.style.width = this.canvasWidth + 'px'; canvas.style.height = this.canvasHeight + 'px'; + if (!noCtxScale && outputScale.scaled) { ctx.scale(outputScale.sx, outputScale.sy); } + + var image = document.createElement('img'); + this.image = image; + + image.id = this.renderingId; + image.className = 'thumbnailImage'; + image.setAttribute('aria-label', mozL10n.get('thumb_page_canvas', + { page: this.id }, 'Thumbnail of Page {{page}}')); + + image.style.width = canvas.style.width; + image.style.height = canvas.style.height; + return ctx; }, + /** + * @private + */ + _convertCanvasToImage: function PDFThumbnailView_convertCanvasToImage() { + if (!this.canvas) { + return; + } + this.image.src = this.canvas.toDataURL(); + + this.div.setAttribute('data-loaded', true); + this.ring.appendChild(this.image); + + // Zeroing the width and height causes Firefox to release graphics + // resources immediately, which can greatly reduce memory consumption. + this.canvas.width = 0; + this.canvas.height = 0; + delete this.canvas; + }, + draw: function PDFThumbnailView_draw() { if (this.renderingState !== RenderingStates.INITIAL) { console.error('Must be in new state before drawing'); @@ -5444,6 +5479,7 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() { return; } self.renderingState = RenderingStates.FINISHED; + self._convertCanvasToImage(); if (!error) { resolveRenderPromise(undefined); @@ -5501,6 +5537,7 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() { if (img.width <= 2 * canvas.width) { ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height); + this._convertCanvasToImage(); return; } // drawImage does an awful job of rescaling the image, doing it gradually. @@ -5525,6 +5562,7 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() { } ctx.drawImage(reducedImage, 0, 0, reducedWidth, reducedHeight, 0, 0, canvas.width, canvas.height); + this._convertCanvasToImage(); } }; @@ -5736,6 +5774,7 @@ var PDFOutlineView = (function PDFOutlineViewClosure() { this.container = options.container; this.outline = options.outline; this.linkService = options.linkService; + this.lastToggleIsShow = true; } PDFOutlineView.prototype = { @@ -5744,6 +5783,7 @@ var PDFOutlineView = (function PDFOutlineViewClosure() { while (container.firstChild) { container.removeChild(container.firstChild); } + this.lastToggleIsShow = true; }, /** @@ -5769,6 +5809,51 @@ var PDFOutlineView = (function PDFOutlineViewClosure() { }; }, + /** + * Prepend a button before an outline item which allows the user to toggle + * the visibility of all outline items at that level. + * + * @private + */ + _addToggleButton: function PDFOutlineView_addToggleButton(div) { + var toggler = document.createElement('div'); + toggler.className = 'outlineItemToggler'; + toggler.onclick = function(event) { + event.stopPropagation(); + toggler.classList.toggle('outlineItemsHidden'); + + if (event.shiftKey) { + var shouldShowAll = !toggler.classList.contains('outlineItemsHidden'); + this._toggleOutlineItem(div, shouldShowAll); + } + }.bind(this); + div.insertBefore(toggler, div.firstChild); + }, + + /** + * Toggle the visibility of the subtree of an outline item. + * + * @param {Element} root - the root of the outline (sub)tree. + * @param {boolean} state - whether to show the outline (sub)tree. If false, + * the outline subtree rooted at |root| will be collapsed. + * + * @private + */ + _toggleOutlineItem: function PDFOutlineView_toggleOutlineItem(root, show) { + this.lastToggleIsShow = show; + var togglers = root.querySelectorAll('.outlineItemToggler'); + for (var i = 0, ii = togglers.length; i < ii; ++i) { + togglers[i].classList[show ? 'remove' : 'add']('outlineItemsHidden'); + } + }, + + /** + * Collapse or expand all subtrees of the outline. + */ + toggleOutlineTree: function PDFOutlineView_toggleOutlineTree() { + this._toggleOutlineItem(this.container, !this.lastToggleIsShow); + }, + render: function PDFOutlineView_render() { var outline = this.outline; var outlineCount = 0; @@ -5780,7 +5865,9 @@ var PDFOutlineView = (function PDFOutlineViewClosure() { return; } - var queue = [{ parent: this.container, items: this.outline }]; + var fragment = document.createDocumentFragment(); + var queue = [{ parent: fragment, items: this.outline }]; + var hasAnyNesting = false; while (queue.length > 0) { var levelData = queue.shift(); for (var i = 0, len = levelData.items.length; i < len; i++) { @@ -5789,10 +5876,13 @@ var PDFOutlineView = (function PDFOutlineViewClosure() { div.className = 'outlineItem'; var element = document.createElement('a'); this._bindLink(element, item); - element.textContent = item.title; + element.textContent = removeNullCharacters(item.title); div.appendChild(element); if (item.items.length > 0) { + hasAnyNesting = true; + this._addToggleButton(div); + var itemsDiv = document.createElement('div'); itemsDiv.className = 'outlineItems'; div.appendChild(itemsDiv); @@ -5803,6 +5893,11 @@ var PDFOutlineView = (function PDFOutlineViewClosure() { outlineCount++; } } + if (hasAnyNesting) { + this.container.classList.add('outlineWithDeepNesting'); + } + + this.container.appendChild(fragment); this._dispatchEvent(outlineCount); } @@ -5885,7 +5980,7 @@ var PDFAttachmentView = (function PDFAttachmentViewClosure() { div.className = 'attachmentsItem'; var button = document.createElement('button'); this._bindLink(button, item.content, filename); - button.textContent = filename; + button.textContent = removeNullCharacters(filename); div.appendChild(button); this.container.appendChild(div); } @@ -6083,6 +6178,12 @@ var PDFViewerApplication = { } PDFJS.disableRange = value; }), + Preferences.get('disableStream').then(function resolved(value) { + if (PDFJS.disableStream === true) { + return; + } + PDFJS.disableStream = value; + }), Preferences.get('disableAutoFetch').then(function resolved(value) { PDFJS.disableAutoFetch = value; }), @@ -7072,6 +7173,11 @@ function webViewerInitialized() { PDFViewerApplication.switchSidebarView('outline'); }); + document.getElementById('viewOutline').addEventListener('dblclick', + function() { + PDFViewerApplication.outline.toggleOutlineTree(); + }); + document.getElementById('viewAttachments').addEventListener('click', function() { PDFViewerApplication.switchSidebarView('attachments'); diff --git a/browser/locales/en-US/pdfviewer/viewer.properties b/browser/locales/en-US/pdfviewer/viewer.properties index 4a3a6aaa2ca..5c43b50575e 100644 --- a/browser/locales/en-US/pdfviewer/viewer.properties +++ b/browser/locales/en-US/pdfviewer/viewer.properties @@ -67,7 +67,11 @@ document_properties.title=Document Properties… document_properties_label=Document Properties… document_properties_file_name=File name: document_properties_file_size=File size: +# LOCALIZATION NOTE (document_properties_kb): "{{size_kb}}" and "{{size_b}}" +# will be replaced by the PDF file size in kilobytes, respectively in bytes. document_properties_kb={{size_kb}} KB ({{size_b}} bytes) +# LOCALIZATION NOTE (document_properties_mb): "{{size_mb}}" and "{{size_b}}" +# will be replaced by the PDF file size in megabytes, respectively in bytes. document_properties_mb={{size_mb}} MB ({{size_b}} bytes) document_properties_title=Title: document_properties_author=Author: @@ -75,6 +79,8 @@ document_properties_subject=Subject: document_properties_keywords=Keywords: document_properties_creation_date=Creation Date: document_properties_modification_date=Modification Date: +# LOCALIZATION NOTE (document_properties_date_string): "{{date}}" and "{{time}}" +# will be replaced by the creation/modification date, and time, of the PDF file. document_properties_date_string={{date}}, {{time}} document_properties_creator=Creator: document_properties_producer=PDF Producer: From 820fb63cbcf00776dc373301947597fb45741b7b Mon Sep 17 00:00:00 2001 From: Matteo Ferretti Date: Tue, 15 Sep 2015 00:32:00 -0400 Subject: [PATCH 02/16] Bug 1132475 - Refactor LayoutHelpers.jsm to avoid dependencies. r=pbrosset --- browser/devtools/framework/selection.js | 7 +- ...r_inspector_highlighter-csstransform_02.js | 2 +- browser/devtools/markupview/markup-view.js | 6 +- .../test/browser_layoutHelpers-getBoxQuads.js | 75 +-- .../shared/test/browser_layoutHelpers.js | 20 +- browser/devtools/shared/test/test-actor.js | 8 +- browser/devtools/shared/widgets/Graphs.js | 4 +- .../tilt/test/browser_tilt_utils05.js | 6 +- .../tilt/test/browser_tilt_utils07.js | 6 +- browser/devtools/tilt/test/head.js | 2 +- browser/devtools/tilt/tilt-utils.js | 5 +- docshell/base/nsDocShell.cpp | 19 + docshell/base/nsIDocShell.idl | 44 +- toolkit/devtools/gcli/commands/screenshot.js | 5 +- toolkit/devtools/layout-helpers.js | 584 ---------------- toolkit/devtools/layout/utils.js | 637 ++++++++++++++++++ toolkit/devtools/moz.build | 5 +- toolkit/devtools/server/actors/highlighter.js | 84 ++- toolkit/devtools/server/actors/inspector.js | 28 +- toolkit/devtools/server/actors/storage.js | 9 +- toolkit/devtools/styleinspector/css-logic.js | 6 +- toolkit/devtools/webconsole/utils.js | 14 +- 22 files changed, 835 insertions(+), 741 deletions(-) delete mode 100644 toolkit/devtools/layout-helpers.js create mode 100644 toolkit/devtools/layout/utils.js diff --git a/browser/devtools/framework/selection.js b/browser/devtools/framework/selection.js index 609e2690ed6..9f4552685cb 100644 --- a/browser/devtools/framework/selection.js +++ b/browser/devtools/framework/selection.js @@ -6,9 +6,10 @@ "use strict"; -const {Cu, Ci} = require("chrome"); +const { Cu, Ci } = require("chrome"); +const { getRootBindingParent } = require("devtools/toolkit/layout/utils"); + let EventEmitter = require("devtools/toolkit/event-emitter"); -let LayoutHelpers = require("devtools/toolkit/layout-helpers"); /** * API @@ -228,7 +229,7 @@ Selection.prototype = { let doc = this.document; if (doc && doc.defaultView) { let docEl = doc.documentElement; - let bindingParent = LayoutHelpers.getRootBindingParent(rawNode); + let bindingParent = getRootBindingParent(rawNode); if (docEl.contains(bindingParent)) { return true; diff --git a/browser/devtools/inspector/test/browser_inspector_highlighter-csstransform_02.js b/browser/devtools/inspector/test/browser_inspector_highlighter-csstransform_02.js index 6449541de63..27c2a71a762 100644 --- a/browser/devtools/inspector/test/browser_inspector_highlighter-csstransform_02.js +++ b/browser/devtools/inspector/test/browser_inspector_highlighter-csstransform_02.js @@ -9,7 +9,7 @@ Bug 1014547 - CSS transforms highlighter Test that the highlighter elements created have the right size and coordinates. Note that instead of hard-coding values here, the assertions are made by -comparing with the result of LayoutHelpers.getAdjustedQuads. +comparing with the result of getAdjustedQuads. There's a separate test for checking that getAdjustedQuads actually returns sensible values diff --git a/browser/devtools/markupview/markup-view.js b/browser/devtools/markupview/markup-view.js index c299a9b0a5b..e44af44577f 100644 --- a/browser/devtools/markupview/markup-view.js +++ b/browser/devtools/markupview/markup-view.js @@ -32,7 +32,7 @@ const {setTimeout, clearTimeout, setInterval, clearInterval} = require("sdk/time const {parseAttribute} = require("devtools/shared/node-attribute-parser"); const ELLIPSIS = Services.prefs.getComplexValue("intl.ellipsis", Ci.nsIPrefLocalizedString).data; const {Task} = require("resource://gre/modules/Task.jsm"); -const LayoutHelpers = require("devtools/toolkit/layout-helpers"); +const {scrollIntoViewIfNeeded} = require("devtools/toolkit/layout/utils"); Cu.import("resource://gre/modules/devtools/Templater.jsm"); Cu.import("resource://gre/modules/Services.jsm"); @@ -75,8 +75,6 @@ function MarkupView(aInspector, aFrame, aControllerWindow) { this._elt = this.doc.querySelector("#root"); this.htmlEditor = new HTMLEditor(this.doc); - this.layoutHelpers = new LayoutHelpers(this.doc.defaultView); - try { this.maxChildren = Services.prefs.getIntPref("devtools.markup.pagesize"); } catch(ex) { @@ -940,7 +938,7 @@ MarkupView.prototype = { } return this._ensureVisible(aNode); }).then(() => { - this.layoutHelpers.scrollIntoViewIfNeeded(this.getContainer(aNode).editor.elt, centered); + scrollIntoViewIfNeeded(this.getContainer(aNode).editor.elt, centered); }, e => { // Only report this rejection as an error if the panel hasn't been // destroyed in the meantime. diff --git a/browser/devtools/shared/test/browser_layoutHelpers-getBoxQuads.js b/browser/devtools/shared/test/browser_layoutHelpers-getBoxQuads.js index 4ff5f582dfa..1616cf742b4 100644 --- a/browser/devtools/shared/test/browser_layoutHelpers-getBoxQuads.js +++ b/browser/devtools/shared/test/browser_layoutHelpers-getBoxQuads.js @@ -1,45 +1,42 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ -// Tests that LayoutHelpers.getAdjustedQuads works properly in a variety of use -// cases including iframes, scroll and zoom +// Tests getAdjustedQuads works properly in a variety of use cases including +// iframes, scroll and zoom const {utils: Cu} = Components; -const LayoutHelpers = require("devtools/toolkit/layout-helpers"); +let {getAdjustedQuads} = require("devtools/toolkit/layout/utils"); const TEST_URI = TEST_URI_ROOT + "browser_layoutHelpers-getBoxQuads.html"; function test() { addTab(TEST_URI, function(browser, tab) { let doc = browser.contentDocument; - let win = doc.defaultView; - info("Creating a new LayoutHelpers instance for the test window"); - let helper = new LayoutHelpers(win); - ok(helper.getAdjustedQuads, "getAdjustedQuads is defined"); + ok(typeof getAdjustedQuads === "function", "getAdjustedQuads is defined"); info("Running tests"); - returnsTheRightDataStructure(doc, helper); - isEmptyForMissingNode(doc, helper); - isEmptyForHiddenNodes(doc, helper); - defaultsToBorderBoxIfNoneProvided(doc, helper); - returnsLikeGetBoxQuadsInSimpleCase(doc, helper); - takesIframesOffsetsIntoAccount(doc, helper); - takesScrollingIntoAccount(doc, helper); - takesZoomIntoAccount(doc, helper); - returnsMultipleItemsForWrappingInlineElements(doc, helper); + returnsTheRightDataStructure(doc); + isEmptyForMissingNode(doc); + isEmptyForHiddenNodes(doc); + defaultsToBorderBoxIfNoneProvided(doc); + returnsLikeGetBoxQuadsInSimpleCase(doc); + takesIframesOffsetsIntoAccount(doc); + takesScrollingIntoAccount(doc); + takesZoomIntoAccount(doc); + returnsMultipleItemsForWrappingInlineElements(doc); gBrowser.removeCurrentTab(); finish(); }); } -function returnsTheRightDataStructure(doc, helper) { +function returnsTheRightDataStructure(doc) { info("Checks that the returned data contains bounds and 4 points"); let node = doc.querySelector("body"); - let [res] = helper.getAdjustedQuads(node, "content"); + let [res] = getAdjustedQuads(doc.defaultView, node, "content"); ok("bounds" in res, "The returned data has a bounds property"); ok("p1" in res, "The returned data has a p1 property"); @@ -59,33 +56,33 @@ function returnsTheRightDataStructure(doc, helper) { } } -function isEmptyForMissingNode(doc, helper) { +function isEmptyForMissingNode(doc) { info("Checks that null is returned for invalid nodes"); for (let input of [null, undefined, "", 0]) { - is(helper.getAdjustedQuads(input).length, 0, "A 0-length array is returned" + + is(getAdjustedQuads(doc.defaultView, input).length, 0, "A 0-length array is returned" + "for input " + input); } } -function isEmptyForHiddenNodes(doc, helper) { +function isEmptyForHiddenNodes(doc) { info("Checks that null is returned for nodes that aren't rendered"); let style = doc.querySelector("#styles"); - is(helper.getAdjustedQuads(style).length, 0, + is(getAdjustedQuads(doc.defaultView, style).length, 0, "null is returned for a