Bug 928358 - Update pdf.js to version 0.8.629. r=yury

This commit is contained in:
Ryan VanderMeulen 2013-10-18 10:12:33 -04:00
parent 11d7c8b855
commit 84f3acb515
6 changed files with 891 additions and 397 deletions

View File

@ -1,4 +1,4 @@
This is the pdf.js project output, https://github.com/mozilla/pdf.js
Current extension version is: 0.8.558
Current extension version is: 0.8.629

View File

@ -20,8 +20,8 @@ if (typeof PDFJS === 'undefined') {
(typeof window !== 'undefined' ? window : this).PDFJS = {};
}
PDFJS.version = '0.8.558';
PDFJS.build = 'ea50c07';
PDFJS.version = '0.8.629';
PDFJS.build = 'b16b3be';
(function pdfjsWrapper() {
// Use strict in our context only - users might not want it
@ -1231,6 +1231,11 @@ var ColorSpace = (function ColorSpaceClosure() {
return this.singletons.rgb;
case 'DeviceCmykCS':
return this.singletons.cmyk;
case 'CalGrayCS':
var whitePoint = IR[1].WhitePoint;
var blackPoint = IR[1].BlackPoint;
var gamma = IR[1].Gamma;
return new CalGrayCS(whitePoint, blackPoint, gamma);
case 'PatternCS':
var basePatternCS = IR[1];
if (basePatternCS)
@ -1306,7 +1311,8 @@ var ColorSpace = (function ColorSpaceClosure() {
case 'CMYK':
return 'DeviceCmykCS';
case 'CalGray':
return 'DeviceGrayCS';
var params = cs[1].getAll();
return ['CalGrayCS', params];
case 'CalRGB':
return 'DeviceRgbCS';
case 'ICCBased':
@ -1726,6 +1732,113 @@ var DeviceCmykCS = (function DeviceCmykCSClosure() {
return DeviceCmykCS;
})();
//
// CalGrayCS: Based on "PDF Reference, Sixth Ed", p.245
//
var CalGrayCS = (function CalGrayCSClosure() {
function CalGrayCS(whitePoint, blackPoint, gamma) {
this.name = 'CalGray';
this.numComps = 3;
this.defaultColor = new Float32Array([0, 0, 0]);
if (!whitePoint) {
error('WhitePoint missing - required for color space CalGray');
}
blackPoint = blackPoint || [0, 0, 0];
gamma = gamma || 1;
// Translate arguments to spec variables.
this.XW = whitePoint[0];
this.YW = whitePoint[1];
this.ZW = whitePoint[2];
this.XB = blackPoint[0];
this.YB = blackPoint[1];
this.ZB = blackPoint[2];
this.G = gamma;
// Validate variables as per spec.
if (this.XW < 0 || this.ZW < 0 || this.YW !== 1) {
error('Invalid WhitePoint components for ' + this.name +
', no fallback available');
}
if (this.XB < 0 || this.YB < 0 || this.ZB < 0) {
info('Invalid BlackPoint for ' + this.name + ', falling back to default');
this.XB = this.YB = this.ZB = 0;
}
if (this.XB !== 0 || this.YB !== 0 || this.ZB !== 0) {
TODO(this.name + ', BlackPoint: XB: ' + this.XB + ', YB: ' + this.YB +
', ZB: ' + this.ZB + ', only default values are supported.');
}
if (this.G < 1) {
info('Invalid Gamma: ' + this.G + ' for ' + this.name +
', falling back to default');
this.G = 1;
}
}
CalGrayCS.prototype = {
getRgb: function CalGrayCS_getRgb(src, srcOffset) {
var rgb = new Uint8Array(3);
this.getRgbItem(src, srcOffset, rgb, 0);
return rgb;
},
getRgbItem: function CalGrayCS_getRgbItem(src, srcOffset,
dest, destOffset) {
// A represents a gray component of a calibrated gray space.
// A <---> AG in the spec
var A = src[srcOffset];
var AG = Math.pow(A, this.G);
// Computes intermediate variables M, L, N as per spec.
// Except if other than default BlackPoint values are used.
var M = this.XW * AG;
var L = this.YW * AG;
var N = this.ZW * AG;
// Decode XYZ, as per spec.
var X = M;
var Y = L;
var Z = N;
// http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html, Ch 4.
// This yields values in range [0, 100].
var Lstar = Math.max(116 * Math.pow(Y, 1 / 3) - 16, 0);
// Convert values to rgb range [0, 255].
dest[destOffset] = Lstar * 255 / 100;
dest[destOffset + 1] = Lstar * 255 / 100;
dest[destOffset + 2] = Lstar * 255 / 100;
},
getRgbBuffer: function CalGrayCS_getRgbBuffer(src, srcOffset, count,
dest, destOffset, bits) {
// TODO: This part is copied from DeviceGray. Make this utility function.
var scale = 255 / ((1 << bits) - 1);
var j = srcOffset, q = destOffset;
for (var i = 0; i < count; ++i) {
var c = (scale * src[j++]) | 0;
dest[q++] = c;
dest[q++] = c;
dest[q++] = c;
}
},
getOutputLength: function CalGrayCS_getOutputLength(inputLength) {
return inputLength * 3;
},
isPassthrough: ColorSpace.prototype.isPassthrough,
createRgbBuffer: ColorSpace.prototype.createRgbBuffer,
isDefaultDecode: function CalGrayCS_isDefaultDecode(decodeMap) {
return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
},
usesZeroToOneRange: true
};
return CalGrayCS;
})();
//
// LabCS: Based on "PDF Reference, Sixth Ed", p.250
//
@ -1868,6 +1981,7 @@ var LabCS = (function LabCSClosure() {
})();
var PatternType = {
AXIAL: 2,
RADIAL: 3
@ -3831,8 +3945,54 @@ PDFJS.maxImageSize = PDFJS.maxImageSize === undefined ? -1 : PDFJS.maxImageSize;
* @var {Boolean}
*/
PDFJS.disableFontFace = PDFJS.disableFontFace === undefined ?
false :
PDFJS.disableFontFace;
false : PDFJS.disableFontFace;
/**
* Path for image resources, mainly for annotation icons. Include trailing
* slash.
* @var {String}
*/
PDFJS.imageResourcesPath = PDFJS.imageResourcesPath === undefined ?
'' : PDFJS.imageResourcesPath;
/**
* Disable the web worker and run all code on the main thread. This will happen
* automatically if the browser doesn't support workers or sending typed arrays
* to workers.
* @var {Boolean}
*/
PDFJS.disableWorker = PDFJS.disableWorker === undefined ?
false : PDFJS.disableWorker;
/**
* Path and filename of the worker file. Required when the worker is enabled.
* @var {String}
*/
PDFJS.workerSrc = PDFJS.workerSrc === undefined ? null : PDFJS.workerSrc;
/**
* Disable range request loading of PDF files. When enabled and if the server
* supports partial content requests then the PDF will be fetched in chunks.
* Enabled (false) by default.
* @var {Boolean}
*/
PDFJS.disableRange = PDFJS.disableRange === undefined ?
false : PDFJS.disableRange;
/**
* Disable pre-fetching of PDF file data. When range requests are enabled PDF.js
* will automatically keep fetching more data even if it isn't needed to display
* the current page. This default behavior can be disabled.
* @var {Boolean}
*/
PDFJS.disableAutoFetch = PDFJS.disableAutoFetch === undefined ?
false : PDFJS.disableAutoFetch;
/**
* Enables special hooks for debugging PDF.js.
* @var {Boolean}
*/
PDFJS.pdfBug = PDFJS.pdfBug === undefined ? false : PDFJS.pdfBug;
/**
* This is the main entry point for loading a PDF and interacting with it.
@ -4274,7 +4434,7 @@ var WorkerTransport = (function WorkerTransportClosure() {
// as it arrives on the worker. Chrome added this with version 15.
if (!globalScope.PDFJS.disableWorker && typeof Worker !== 'undefined') {
var workerSrc = PDFJS.workerSrc;
if (typeof workerSrc === 'undefined') {
if (!workerSrc) {
error('No PDFJS.workerSrc specified');
}
@ -6618,7 +6778,8 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
var heightScale = Math.max(Math.sqrt(c * c + d * d), 1);
var imgToPaint;
if (imgData instanceof HTMLElement) {
// instanceof HTMLElement does not work in jsdom node.js module
if (imgData instanceof HTMLElement || !imgData.data) {
imgToPaint = imgData;
} else {
var tmpCanvas = CachedCanvases.getCanvas('inlineImage', width, height);

View File

@ -20,8 +20,8 @@ if (typeof PDFJS === 'undefined') {
(typeof window !== 'undefined' ? window : this).PDFJS = {};
}
PDFJS.version = '0.8.558';
PDFJS.build = 'ea50c07';
PDFJS.version = '0.8.629';
PDFJS.build = 'b16b3be';
(function pdfjsWrapper() {
// Use strict in our context only - users might not want it
@ -4170,22 +4170,16 @@ var PDFDocument = (function PDFDocumentClosure() {
return shadow(this, 'documentInfo', docInfo);
},
get fingerprint() {
var xref = this.xref, fileID;
var xref = this.xref, hash, fileID = '';
if (xref.trailer.has('ID')) {
fileID = '';
var id = xref.trailer.get('ID')[0];
id.split('').forEach(function(el) {
fileID += Number(el.charCodeAt(0)).toString(16);
});
hash = stringToBytes(xref.trailer.get('ID')[0]);
} else {
// If we got no fileID, then we generate one,
// from the first 100 bytes of PDF
var data = this.stream.bytes.subarray(0, 100);
var hash = calculateMD5(data, 0, data.length);
fileID = '';
for (var i = 0, length = hash.length; i < length; i++) {
fileID += Number(hash[i]).toString(16);
}
hash = calculateMD5(this.stream.bytes.subarray(0, 100), 0, 100);
}
for (var i = 0, n = hash.length; i < n; i++) {
fileID += hash[i].toString(16);
}
return shadow(this, 'fingerprint', fileID);
@ -12573,6 +12567,11 @@ var ColorSpace = (function ColorSpaceClosure() {
return this.singletons.rgb;
case 'DeviceCmykCS':
return this.singletons.cmyk;
case 'CalGrayCS':
var whitePoint = IR[1].WhitePoint;
var blackPoint = IR[1].BlackPoint;
var gamma = IR[1].Gamma;
return new CalGrayCS(whitePoint, blackPoint, gamma);
case 'PatternCS':
var basePatternCS = IR[1];
if (basePatternCS)
@ -12648,7 +12647,8 @@ var ColorSpace = (function ColorSpaceClosure() {
case 'CMYK':
return 'DeviceCmykCS';
case 'CalGray':
return 'DeviceGrayCS';
var params = cs[1].getAll();
return ['CalGrayCS', params];
case 'CalRGB':
return 'DeviceRgbCS';
case 'ICCBased':
@ -13068,6 +13068,113 @@ var DeviceCmykCS = (function DeviceCmykCSClosure() {
return DeviceCmykCS;
})();
//
// CalGrayCS: Based on "PDF Reference, Sixth Ed", p.245
//
var CalGrayCS = (function CalGrayCSClosure() {
function CalGrayCS(whitePoint, blackPoint, gamma) {
this.name = 'CalGray';
this.numComps = 3;
this.defaultColor = new Float32Array([0, 0, 0]);
if (!whitePoint) {
error('WhitePoint missing - required for color space CalGray');
}
blackPoint = blackPoint || [0, 0, 0];
gamma = gamma || 1;
// Translate arguments to spec variables.
this.XW = whitePoint[0];
this.YW = whitePoint[1];
this.ZW = whitePoint[2];
this.XB = blackPoint[0];
this.YB = blackPoint[1];
this.ZB = blackPoint[2];
this.G = gamma;
// Validate variables as per spec.
if (this.XW < 0 || this.ZW < 0 || this.YW !== 1) {
error('Invalid WhitePoint components for ' + this.name +
', no fallback available');
}
if (this.XB < 0 || this.YB < 0 || this.ZB < 0) {
info('Invalid BlackPoint for ' + this.name + ', falling back to default');
this.XB = this.YB = this.ZB = 0;
}
if (this.XB !== 0 || this.YB !== 0 || this.ZB !== 0) {
TODO(this.name + ', BlackPoint: XB: ' + this.XB + ', YB: ' + this.YB +
', ZB: ' + this.ZB + ', only default values are supported.');
}
if (this.G < 1) {
info('Invalid Gamma: ' + this.G + ' for ' + this.name +
', falling back to default');
this.G = 1;
}
}
CalGrayCS.prototype = {
getRgb: function CalGrayCS_getRgb(src, srcOffset) {
var rgb = new Uint8Array(3);
this.getRgbItem(src, srcOffset, rgb, 0);
return rgb;
},
getRgbItem: function CalGrayCS_getRgbItem(src, srcOffset,
dest, destOffset) {
// A represents a gray component of a calibrated gray space.
// A <---> AG in the spec
var A = src[srcOffset];
var AG = Math.pow(A, this.G);
// Computes intermediate variables M, L, N as per spec.
// Except if other than default BlackPoint values are used.
var M = this.XW * AG;
var L = this.YW * AG;
var N = this.ZW * AG;
// Decode XYZ, as per spec.
var X = M;
var Y = L;
var Z = N;
// http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html, Ch 4.
// This yields values in range [0, 100].
var Lstar = Math.max(116 * Math.pow(Y, 1 / 3) - 16, 0);
// Convert values to rgb range [0, 255].
dest[destOffset] = Lstar * 255 / 100;
dest[destOffset + 1] = Lstar * 255 / 100;
dest[destOffset + 2] = Lstar * 255 / 100;
},
getRgbBuffer: function CalGrayCS_getRgbBuffer(src, srcOffset, count,
dest, destOffset, bits) {
// TODO: This part is copied from DeviceGray. Make this utility function.
var scale = 255 / ((1 << bits) - 1);
var j = srcOffset, q = destOffset;
for (var i = 0; i < count; ++i) {
var c = (scale * src[j++]) | 0;
dest[q++] = c;
dest[q++] = c;
dest[q++] = c;
}
},
getOutputLength: function CalGrayCS_getOutputLength(inputLength) {
return inputLength * 3;
},
isPassthrough: ColorSpace.prototype.isPassthrough,
createRgbBuffer: ColorSpace.prototype.createRgbBuffer,
isDefaultDecode: function CalGrayCS_isDefaultDecode(decodeMap) {
return ColorSpace.isDefaultDecode(decodeMap, this.numComps);
},
usesZeroToOneRange: true
};
return CalGrayCS;
})();
//
// LabCS: Based on "PDF Reference, Sixth Ed", p.250
//
@ -13210,6 +13317,7 @@ var LabCS = (function LabCSClosure() {
})();
var ARCFourCipher = (function ARCFourCipherClosure() {
function ARCFourCipher(key) {
this.a = 0;
@ -20951,18 +21059,22 @@ var CFFFont = (function CFFFontClosure() {
var unassignedUnicodeItems = [];
var inverseEncoding = [];
var gidStart = 0;
// Even though the CFF font may not actually be a CID font is could have
// CID information in the font descriptor.
if (this.properties.cidSystemInfo) {
// According to section 9.7.4.2 if the font is actually a CID font then
// we should use the charset to map CIDs to GIDs. If it is not actually
// a CID font then CIDs can be mapped directly to GIDs.
// According to section 9.7.4.2 CIDFontType0C glyph selection should be
// handled differently.
if (this.properties.subtype === 'CIDFontType0C') {
if (this.cff.isCIDFont) {
// If the font is actually a CID font then we should use the charset
// to map CIDs to GIDs.
inverseEncoding = charsets;
} else {
for (var i = 0, ii = charsets.length; i < charsets.length; i++) {
// If it is NOT actually a CID font then CIDs should be mapped
// directly to GIDs.
inverseEncoding = [];
for (var i = 0, ii = cff.charStrings.count; i < ii; i++) {
inverseEncoding.push(i);
}
// Use the identity map for charsets as well.
charsets = inverseEncoding;
}
} else {
for (var charcode in encoding) {
@ -35872,6 +35984,19 @@ var JpxImage = (function JpxImageClosure() {
}
return ll;
};
Transform.prototype.expand = function expand(buffer, bufferPadding, step) {
// Section F.3.7 extending... using max extension of 4
var i1 = bufferPadding - 1, j1 = bufferPadding + 1;
var i2 = bufferPadding + step - 2, j2 = bufferPadding + step;
buffer[i1--] = buffer[j1++];
buffer[j2++] = buffer[i2--];
buffer[i1--] = buffer[j1++];
buffer[j2++] = buffer[i2--];
buffer[i1--] = buffer[j1++];
buffer[j2++] = buffer[i2--];
buffer[i1--] = buffer[j1++];
buffer[j2++] = buffer[i2--];
};
Transform.prototype.iterate = function Transform_iterate(ll, hl, lh, hh,
u0, v0) {
var llWidth = ll.width, llHeight = ll.height, llItems = ll.items;
@ -35925,18 +36050,7 @@ var JpxImage = (function JpxImageClosure() {
for (var u = 0; u < width; u++, k++, l++)
buffer[l] = items[k];
// Section F.3.7 extending... using max extension of 4
var i1 = bufferPadding - 1, j1 = bufferPadding + 1;
var i2 = bufferPadding + width - 2, j2 = bufferPadding + width;
buffer[i1--] = buffer[j1++];
buffer[j2++] = buffer[i2--];
buffer[i1--] = buffer[j1++];
buffer[j2++] = buffer[i2--];
buffer[i1--] = buffer[j1++];
buffer[j2++] = buffer[i2--];
buffer[i1--] = buffer[j1++];
buffer[j2++] = buffer[i2--];
this.expand(buffer, bufferPadding, width);
this.filter(buffer, bufferPadding, width, u0, bufferOut);
k = v * width;
@ -35960,18 +36074,7 @@ var JpxImage = (function JpxImageClosure() {
for (var v = 0; v < height; v++, k += width, l++)
buffer[l] = items[k];
// Section F.3.7 extending... using max extension of 4
var i1 = bufferPadding - 1, j1 = bufferPadding + 1;
var i2 = bufferPadding + height - 2, j2 = bufferPadding + height;
buffer[i1--] = buffer[j1++];
buffer[j2++] = buffer[i2--];
buffer[i1--] = buffer[j1++];
buffer[j2++] = buffer[i2--];
buffer[i1--] = buffer[j1++];
buffer[j2++] = buffer[i2--];
buffer[i1--] = buffer[j1++];
buffer[j2++] = buffer[i2--];
this.expand(buffer, bufferPadding, height);
this.filter(buffer, bufferPadding, height, v0, bufferOut);
k = u;
@ -36624,10 +36727,6 @@ var Jbig2Image = (function Jbig2ImageClosure() {
var decoder = decodingContext.decoder;
var contextCache = decodingContext.contextCache;
if (transposed)
error('JBIG2 error: transposed is not supported');
var stripT = -decodeInteger(contextCache, 'IADT', decoder); // 6.4.6
var firstS = 0;
var i = 0;
@ -36662,28 +36761,60 @@ var Jbig2Image = (function Jbig2ImageClosure() {
}
var offsetT = t - ((referenceCorner & 1) ? 0 : symbolHeight);
var offsetS = currentS - ((referenceCorner & 2) ? symbolWidth : 0);
for (var t2 = 0; t2 < symbolHeight; t2++) {
var row = bitmap[offsetT + t2];
if (!row) continue;
var symbolRow = symbolBitmap[t2];
switch (combinationOperator) {
case 0: // OR
for (var s2 = 0; s2 < symbolWidth; s2++)
row[offsetS + s2] |= symbolRow[s2];
break;
case 2: // XOR
for (var s2 = 0; s2 < symbolWidth; s2++)
row[offsetS + s2] ^= symbolRow[s2];
break;
default:
error('JBIG2 error: operator ' + combinationOperator +
' is not supported');
if (transposed) {
// Place Symbol Bitmap from T1,S1
for (var s2 = 0; s2 < symbolHeight; s2++) {
var row = bitmap[offsetS + s2];
if (!row) {
continue;
}
var symbolRow = symbolBitmap[s2];
// To ignore Parts of Symbol bitmap which goes
// outside bitmap region
var maxWidth = Math.min(width - offsetT, symbolWidth);
switch (combinationOperator) {
case 0: // OR
for (var t2 = 0; t2 < maxWidth; t2++) {
row[offsetT + t2] |= symbolRow[t2];
}
break;
case 2: // XOR
for (var t2 = 0; t2 < maxWidth; t2++) {
row[offsetT + t2] ^= symbolRow[t2];
}
break;
default:
error('JBIG2 error: operator ' + combinationOperator +
' is not supported');
}
}
currentS += symbolHeight - 1;
} else {
for (var t2 = 0; t2 < symbolHeight; t2++) {
var row = bitmap[offsetT + t2];
if (!row) {
continue;
}
var symbolRow = symbolBitmap[t2];
switch (combinationOperator) {
case 0: // OR
for (var s2 = 0; s2 < symbolWidth; s2++) {
row[offsetS + s2] |= symbolRow[s2];
}
break;
case 2: // XOR
for (var s2 = 0; s2 < symbolWidth; s2++) {
row[offsetS + s2] ^= symbolRow[s2];
}
break;
default:
error('JBIG2 error: operator ' + combinationOperator +
' is not supported');
}
}
currentS += symbolWidth - 1;
}
currentS += symbolWidth - 1;
i++;
var deltaS = decodeInteger(contextCache, 'IADS', decoder); // 6.4.8
if (deltaS === null)
break; // OOB

View File

@ -20,6 +20,8 @@
html {
height: 100%;
/* Font size is needed to make the activity bar the corect size. */
font-size: 10px;
}
body {
@ -80,7 +82,16 @@ select {
display: none;
}
#viewerContainer.presentationControls {
:-moz-full-screen .textLayer > div {
cursor: none;
}
:fullscreen .textLayer > div {
cursor: none;
}
#viewerContainer.presentationControls,
#viewerContainer.presentationControls .textLayer > div {
cursor: default;
}
@ -113,6 +124,7 @@ html[dir='rtl'] .innerCenter {
#outerContainer {
width: 100%;
height: 100%;
position: relative;
}
#sidebarContainer {
@ -328,6 +340,7 @@ html[dir='rtl'] .secondaryToolbar {
max-width: 200px;
max-height: 400px;
overflow-y: auto;
margin-bottom: -4px;
}
.doorHanger,
@ -803,19 +816,24 @@ html[dir="rtl"] .secondaryToolbarButton.print::before {
content: url(images/toolbarButton-download.png);
}
.toolbarButton.bookmark {
.toolbarButton.bookmark,
.secondaryToolbarButton.bookmark {
-moz-box-sizing: border-box;
box-sizing: border-box;
margin-top: 3px;
padding-top: 4px;
text-decoration: none;
}
.secondaryToolbarButton.bookmark {
padding-top: 5px;
}
#viewBookmark[href='#'] {
.bookmark[href='#'] {
opacity: .5;
pointer-events: none;
}
.toolbarButton.bookmark::before {
.toolbarButton.bookmark::before,
.secondaryToolbarButton.bookmark::before {
content: url(images/toolbarButton-bookmark.png);
}
@ -852,9 +870,11 @@ html[dir="rtl"] .secondaryToolbarButton {
padding-right: 24px;
text-align: right;
}
#secondaryToolbarButtonContainer :last-child {
margin-bottom: 0;
html[dir="ltr"] .secondaryToolbarButton.bookmark {
padding-left: 27px;
}
html[dir="rtl"] .secondaryToolbarButton.bookmark {
padding-right: 27px;
}
html[dir="ltr"] .secondaryToolbarButton > span {
@ -971,6 +991,11 @@ html[dir='rtl'] .verticalToolbarSeparator {
.thumbnail {
float: left;
margin-bottom: 5px;
}
#thumbnailView > a:last-of-type > .thumbnail {
margin-bottom: 10px;
}
.thumbnail:not([data-loaded]) {

View File

@ -98,21 +98,25 @@ limitations under the License.
<span data-l10n-id="download_label">Download</span>
</button>
<a href="#" id="secondaryViewBookmark" class="secondaryToolbarButton bookmark visibleSmallView" title="Current view (copy or open in new window)" tabindex="22" data-l10n-id="bookmark">
<span data-l10n-id="bookmark_label">Current View</span>
</a>
<div class="horizontalToolbarSeparator visibleLargeView"></div>
<button id="firstPage" class="secondaryToolbarButton firstPage" title="Go to First Page" tabindex="22" data-l10n-id="first_page">
<button id="firstPage" class="secondaryToolbarButton firstPage" title="Go to First Page" tabindex="23" data-l10n-id="first_page">
<span data-l10n-id="first_page_label">Go to First Page</span>
</button>
<button id="lastPage" class="secondaryToolbarButton lastPage" title="Go to Last Page" tabindex="23" data-l10n-id="last_page">
<button id="lastPage" class="secondaryToolbarButton lastPage" title="Go to Last Page" tabindex="24" data-l10n-id="last_page">
<span data-l10n-id="last_page_label">Go to Last Page</span>
</button>
<div class="horizontalToolbarSeparator"></div>
<button id="pageRotateCw" class="secondaryToolbarButton rotateCw" title="Rotate Clockwise" tabindex="24" data-l10n-id="page_rotate_cw">
<button id="pageRotateCw" class="secondaryToolbarButton rotateCw" title="Rotate Clockwise" tabindex="25" data-l10n-id="page_rotate_cw">
<span data-l10n-id="page_rotate_cw_label">Rotate Clockwise</span>
</button>
<button id="pageRotateCcw" class="secondaryToolbarButton rotateCcw" title="Rotate Counterclockwise" tabindex="25" data-l10n-id="page_rotate_ccw">
<button id="pageRotateCcw" class="secondaryToolbarButton rotateCcw" title="Rotate Counterclockwise" tabindex="26" data-l10n-id="page_rotate_ccw">
<span data-l10n-id="page_rotate_ccw_label">Rotate Counterclockwise</span>
</button>
</div>
@ -160,7 +164,9 @@ limitations under the License.
<span data-l10n-id="download_label">Download</span>
</button>
<!-- <div class="toolbarButtonSpacer"></div> -->
<a href="#" id="viewBookmark" class="toolbarButton bookmark hiddenSmallView" title="Current view (copy or open in new window)" tabindex="16" data-l10n-id="bookmark"><span data-l10n-id="bookmark_label">Current View</span></a>
<a href="#" id="viewBookmark" class="toolbarButton bookmark hiddenSmallView" title="Current view (copy or open in new window)" tabindex="16" data-l10n-id="bookmark">
<span data-l10n-id="bookmark_label">Current View</span>
</a>
<div class="verticalToolbarSeparator hiddenSmallView"></div>

File diff suppressed because it is too large Load Diff