Bug 947260 - Update pdf.js to version 0.8.759. r=bdahl

This commit is contained in:
Ryan VanderMeulen
2013-12-06 18:00:32 -05:00
parent 8f8593c56f
commit cc183c47f9
9 changed files with 1281 additions and 494 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.681
Current extension version is: 0.8.759

View File

@@ -16,7 +16,7 @@
*/
/* jshint esnext:true */
/* globals Components, Services, XPCOMUtils, NetUtil, PrivateBrowsingUtils,
dump, NetworkManager, PdfJsTelemetry */
dump, NetworkManager, PdfJsTelemetry, DEFAULT_PREFERENCES */
'use strict';
@@ -33,12 +33,16 @@ const PDF_CONTENT_TYPE = 'application/pdf';
const PREF_PREFIX = 'pdfjs';
const PDF_VIEWER_WEB_PAGE = 'resource://pdf.js/web/viewer.html';
const MAX_DATABASE_LENGTH = 4096;
const MAX_STRING_PREF_LENGTH = 4096;
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/NetUtil.jsm');
Cu.import('resource://pdf.js/network.js');
// Load the default preferences.
Cu.import('resource://pdf.js/default_preferences.js');
XPCOMUtils.defineLazyModuleGetter(this, 'PrivateBrowsingUtils',
'resource://gre/modules/PrivateBrowsingUtils.jsm');
@@ -58,6 +62,10 @@ function getChromeWindow(domWindow) {
return containingBrowser.ownerDocument.defaultView;
}
function setBoolPref(pref, value) {
Services.prefs.setBoolPref(pref, value);
}
function getBoolPref(pref, def) {
try {
return Services.prefs.getBoolPref(pref);
@@ -66,6 +74,10 @@ function getBoolPref(pref, def) {
}
}
function setIntPref(pref, value) {
Services.prefs.setIntPref(pref, value);
}
function getIntPref(pref, def) {
try {
return Services.prefs.getIntPref(pref);
@@ -431,6 +443,62 @@ ChromeActions.prototype = {
}
getChromeWindow(this.domWindow).gFindBar
.updateControlState(result, findPrevious);
},
setPreferences: function(prefs) {
var prefValue, defaultValue, prefName, prefType, defaultType;
for (var key in DEFAULT_PREFERENCES) {
prefValue = prefs[key];
defaultValue = DEFAULT_PREFERENCES[key];
prefName = (PREF_PREFIX + '.' + key);
if (prefValue === undefined || prefValue === defaultValue) {
Services.prefs.clearUserPref(prefName);
} else {
prefType = typeof prefValue;
defaultType = typeof defaultValue;
if (prefType !== defaultType) {
continue;
}
switch (defaultType) {
case 'boolean':
setBoolPref(prefName, prefValue);
break;
case 'number':
setIntPref(prefName, prefValue);
break;
case 'string':
// Protect against adding arbitrarily long strings in about:config.
if (prefValue.length <= MAX_STRING_PREF_LENGTH) {
setStringPref(prefName, prefValue);
}
break;
}
}
}
},
getPreferences: function() {
var currentPrefs = {};
var defaultValue, prefName;
for (var key in DEFAULT_PREFERENCES) {
defaultValue = DEFAULT_PREFERENCES[key];
prefName = (PREF_PREFIX + '.' + key);
switch (typeof defaultValue) {
case 'boolean':
currentPrefs[key] = getBoolPref(prefName, defaultValue);
break;
case 'number':
currentPrefs[key] = getIntPref(prefName, defaultValue);
break;
case 'string':
currentPrefs[key] = getStringPref(prefName, defaultValue);
break;
}
}
return JSON.stringify(currentPrefs);
}
};
@@ -439,9 +507,12 @@ var RangedChromeActions = (function RangedChromeActionsClosure() {
* This is for range requests
*/
function RangedChromeActions(
domWindow, contentDispositionFilename, originalRequest) {
domWindow, contentDispositionFilename, originalRequest,
dataListener) {
ChromeActions.call(this, domWindow, contentDispositionFilename);
this.dataListener = dataListener;
this.originalRequest = originalRequest;
this.pdfUrl = originalRequest.URI.spec;
this.contentLength = originalRequest.contentLength;
@@ -487,11 +558,15 @@ var RangedChromeActions = (function RangedChromeActionsClosure() {
proto.constructor = RangedChromeActions;
proto.initPassiveLoading = function RangedChromeActions_initPassiveLoading() {
this.originalRequest.cancel(Cr.NS_BINDING_ABORTED);
this.originalRequest = null;
this.domWindow.postMessage({
pdfjsLoadAction: 'supportsRangedLoading',
pdfUrl: this.pdfUrl,
length: this.contentLength
length: this.contentLength,
data: this.dataListener.getData()
}, '*');
this.dataListener = null;
return true;
};
@@ -692,8 +767,8 @@ PdfStreamConverter.prototype = {
* 1. asyncConvertData stores the listener
* 2. onStartRequest creates a new channel, streams the viewer
* 3. If range requests are supported:
* 3.1. Suspends and cancels the request so we can issue range
* requests instead.
* 3.1. Leave the request open until the viewer is ready to switch to
* range requests.
*
* If range rquests are not supported:
* 3.1. Read the stream as it's loaded in onDataAvailable to send
@@ -779,18 +854,12 @@ PdfStreamConverter.prototype = {
PdfJsTelemetry.onViewerIsUsed();
PdfJsTelemetry.onDocumentSize(aRequest.contentLength);
if (!rangeRequest) {
// Creating storage for PDF data
var contentLength = aRequest.contentLength;
this.dataListener = new PdfDataListener(contentLength);
this.binaryStream = Cc['@mozilla.org/binaryinputstream;1']
.createInstance(Ci.nsIBinaryInputStream);
} else {
// Suspend the request so we're not consuming any of the stream,
// but we can't cancel the request yet. Otherwise, the original
// listener will think we do not want to go the new PDF url
aRequest.suspend();
}
// Creating storage for PDF data
var contentLength = aRequest.contentLength;
this.dataListener = new PdfDataListener(contentLength);
this.binaryStream = Cc['@mozilla.org/binaryinputstream;1']
.createInstance(Ci.nsIBinaryInputStream);
// Create a new channel that is viewer loaded as a resource.
var ioService = Services.io;
@@ -816,12 +885,8 @@ PdfStreamConverter.prototype = {
var domWindow = getDOMWindow(channel);
var actions;
if (rangeRequest) {
// We are going to be issuing range requests, so cancel the
// original request
aRequest.resume();
aRequest.cancel(Cr.NS_BINDING_ABORTED);
actions = new RangedChromeActions(domWindow,
contentDispositionFilename, aRequest);
actions = new RangedChromeActions(
domWindow, contentDispositionFilename, aRequest, dataListener);
} else {
actions = new StandardChromeActions(
domWindow, contentDispositionFilename, dataListener);

View File

@@ -20,8 +20,8 @@ if (typeof PDFJS === 'undefined') {
(typeof window !== 'undefined' ? window : this).PDFJS = {};
}
PDFJS.version = '0.8.681';
PDFJS.build = '48c672b';
PDFJS.version = '0.8.759';
PDFJS.build = 'd3b5aa3';
(function pdfjsWrapper() {
// Use strict in our context only - users might not want it
@@ -43,7 +43,7 @@ PDFJS.build = '48c672b';
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* globals Cmd, ColorSpace, Dict, MozBlobBuilder, Name, PDFJS, Ref */
/* globals Cmd, ColorSpace, Dict, MozBlobBuilder, Name, PDFJS, Ref, URL */
'use strict';
@@ -78,6 +78,98 @@ if (!globalScope.PDFJS) {
globalScope.PDFJS.pdfBug = false;
// All the possible operations for an operator list.
var OPS = PDFJS.OPS = {
// Intentionally start from 1 so it is easy to spot bad operators that will be
// 0's.
dependency: 1,
setLineWidth: 2,
setLineCap: 3,
setLineJoin: 4,
setMiterLimit: 5,
setDash: 6,
setRenderingIntent: 7,
setFlatness: 8,
setGState: 9,
save: 10,
restore: 11,
transform: 12,
moveTo: 13,
lineTo: 14,
curveTo: 15,
curveTo2: 16,
curveTo3: 17,
closePath: 18,
rectangle: 19,
stroke: 20,
closeStroke: 21,
fill: 22,
eoFill: 23,
fillStroke: 24,
eoFillStroke: 25,
closeFillStroke: 26,
closeEOFillStroke: 27,
endPath: 28,
clip: 29,
eoClip: 30,
beginText: 31,
endText: 32,
setCharSpacing: 33,
setWordSpacing: 34,
setHScale: 35,
setLeading: 36,
setFont: 37,
setTextRenderingMode: 38,
setTextRise: 39,
moveText: 40,
setLeadingMoveText: 41,
setTextMatrix: 42,
nextLine: 43,
showText: 44,
showSpacedText: 45,
nextLineShowText: 46,
nextLineSetSpacingShowText: 47,
setCharWidth: 48,
setCharWidthAndBounds: 49,
setStrokeColorSpace: 50,
setFillColorSpace: 51,
setStrokeColor: 52,
setStrokeColorN: 53,
setFillColor: 54,
setFillColorN: 55,
setStrokeGray: 56,
setFillGray: 57,
setStrokeRGBColor: 58,
setFillRGBColor: 59,
setStrokeCMYKColor: 60,
setFillCMYKColor: 61,
shadingFill: 62,
beginInlineImage: 63,
beginImageData: 64,
endInlineImage: 65,
paintXObject: 66,
markPoint: 67,
markPointProps: 68,
beginMarkedContent: 69,
beginMarkedContentProps: 70,
endMarkedContent: 71,
beginCompat: 72,
endCompat: 73,
paintFormXObjectBegin: 74,
paintFormXObjectEnd: 75,
beginGroup: 76,
endGroup: 77,
beginAnnotations: 78,
endAnnotations: 79,
beginAnnotation: 80,
endAnnotation: 81,
paintJpegXObject: 82,
paintImageMaskXObject: 83,
paintImageMaskXObjectGroup: 84,
paintImageXObject: 85,
paintInlineImageXObject: 86,
paintInlineImageXObjectGroup: 87
};
// Use only for debugging purposes. This should not be used in any code that is
// in mozilla master.
@@ -292,7 +384,7 @@ var MissingDataException = (function MissingDataExceptionClosure() {
function MissingDataException(begin, end) {
this.begin = begin;
this.end = end;
this.message = 'Missing data [begin, end)';
this.message = 'Missing data [' + begin + ', ' + end + ')';
}
MissingDataException.prototype = new Error();
@@ -865,7 +957,7 @@ var Promise = PDFJS.Promise = (function PromiseClosure() {
/**
* Builds a promise that is resolved when all the passed in promises are
* resolved.
* @param {Promise[]} promises Array of promises to wait for.
* @param {array} array of data and/or promises to wait for.
* @return {Promise} New dependant promise.
*/
Promise.all = function Promise_all(promises) {
@@ -885,7 +977,7 @@ var Promise = PDFJS.Promise = (function PromiseClosure() {
}
for (var i = 0, ii = promises.length; i < ii; ++i) {
var promise = promises[i];
promise.then((function(i) {
var resolve = (function(i) {
return function(value) {
if (deferred._status === STATUS_REJECTED) {
return;
@@ -895,11 +987,24 @@ var Promise = PDFJS.Promise = (function PromiseClosure() {
if (unresolved === 0)
deferred.resolve(results);
};
})(i), reject);
})(i);
if (Promise.isPromise(promise)) {
promise.then(resolve, reject);
} else {
resolve(promise);
}
}
return deferred;
};
/**
* Checks if the value is likely a promise (has a 'then' function).
* @return {boolean} true if x is thenable
*/
Promise.isPromise = function Promise_isPromise(value) {
return value && typeof value.then === 'function';
};
Promise.prototype = {
_status: null,
_value: null,
@@ -913,7 +1018,7 @@ var Promise = PDFJS.Promise = (function PromiseClosure() {
}
if (status == STATUS_RESOLVED &&
value && typeof(value.then) === 'function') {
Promise.isPromise(value)) {
value.then(this._updateStatus.bind(this, STATUS_RESOLVED),
this._updateStatus.bind(this, STATUS_REJECTED));
return;
@@ -1016,7 +1121,7 @@ var StatTimer = (function StatTimerClosure() {
})();
PDFJS.createBlob = function createBlob(data, contentType) {
if (typeof Blob === 'function')
if (typeof Blob !== 'undefined')
return new Blob([data], { type: contentType });
// Blob builder is deprecated in FF14 and removed in FF18.
var bb = new MozBlobBuilder();
@@ -1024,10 +1129,38 @@ PDFJS.createBlob = function createBlob(data, contentType) {
return bb.getBlob(contentType);
};
PDFJS.createObjectURL = (function createObjectURLClosure() {
if (typeof URL !== 'undefined' && URL.createObjectURL) {
return function createObjectURL(data, contentType) {
var blob = PDFJS.createBlob(data, contentType);
return URL.createObjectURL(blob);
};
}
// Blob/createObjectURL is not available, falling back to data schema.
var digits =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
return function createObjectURL(data, contentType) {
var buffer = 'data:' + contentType + ';base64,';
for (var i = 0, ii = data.length; i < ii; i += 3) {
var b1 = data[i] & 0xFF;
var b2 = data[i + 1] & 0xFF;
var b3 = data[i + 2] & 0xFF;
var d1 = b1 >> 2, d2 = ((b1 & 3) << 4) | (b2 >> 4);
var d3 = i + 1 < ii ? ((b2 & 0xF) << 2) | (b3 >> 6) : 64;
var d4 = i + 2 < ii ? (b3 & 0x3F) : 64;
buffer += digits[d1] + digits[d2] + digits[d3] + digits[d4];
}
return buffer;
};
})();
function MessageHandler(name, comObj) {
this.name = name;
this.comObj = comObj;
this.callbackIndex = 1;
this.postMessageTransfers = true;
var callbacks = this.callbacks = {};
var ah = this.actionHandler = {};
@@ -1094,8 +1227,9 @@ MessageHandler.prototype = {
* @param {String} actionName Action to call.
* @param {JSON} data JSON data to send.
* @param {function} [callback] Optional callback that will handle a reply.
* @param {Array} [transfers] Optional list of transfers/ArrayBuffers
*/
send: function messageHandlerSend(actionName, data, callback) {
send: function messageHandlerSend(actionName, data, callback, transfers) {
var message = {
action: actionName,
data: data
@@ -1105,16 +1239,20 @@ MessageHandler.prototype = {
this.callbacks[callbackId] = callback;
message.callbackId = callbackId;
}
this.comObj.postMessage(message);
if (transfers && this.postMessageTransfers) {
this.comObj.postMessage(message, transfers);
} else {
this.comObj.postMessage(message);
}
}
};
function loadJpegStream(id, imageData, objs) {
function loadJpegStream(id, imageUrl, objs) {
var img = new Image();
img.onload = (function loadJpegStream_onloadClosure() {
objs.resolve(id, img);
});
img.src = 'data:image/jpeg;base64,' + window.btoa(imageData);
img.src = imageUrl;
}
@@ -3430,9 +3568,9 @@ var Annotation = (function AnnotationClosure() {
resourcesPromise.then(function(resources) {
var opList = new OperatorList();
opList.addOp('beginAnnotation', [data.rect, transform, matrix]);
opList.addOp(OPS.beginAnnotation, [data.rect, transform, matrix]);
evaluator.getOperatorList(this.appearance, resources, opList);
opList.addOp('endAnnotation', []);
opList.addOp(OPS.endAnnotation, []);
promise.resolve(opList);
}.bind(this));
@@ -3526,12 +3664,12 @@ var Annotation = (function AnnotationClosure() {
annotationPromises.push(annotations[i].getOperatorList(partialEvaluator));
}
Promise.all(annotationPromises).then(function(datas) {
opList.addOp('beginAnnotations', []);
opList.addOp(OPS.beginAnnotations, []);
for (var i = 0, n = datas.length; i < n; ++i) {
var annotOpList = datas[i];
opList.addOpList(annotOpList);
}
opList.addOp('endAnnotations', []);
opList.addOp(OPS.endAnnotations, []);
annotationsReadyPromise.resolve();
}, reject);
@@ -3707,10 +3845,10 @@ var TextWidgetAnnotation = (function TextWidgetAnnotationClosure() {
data.rgb = [0, 0, 0];
// TODO THIS DOESN'T MAKE ANY SENSE SINCE THE fnArray IS EMPTY!
for (var i = 0, n = fnArray.length; i < n; ++i) {
var fnName = appearanceFnArray[i];
var fnId = appearanceFnArray[i];
var args = appearanceArgsArray[i];
if (fnName === 'setFont') {
if (fnId === OPS.setFont) {
data.fontRefName = args[0];
var size = args[1];
if (size < 0) {
@@ -3720,9 +3858,9 @@ var TextWidgetAnnotation = (function TextWidgetAnnotationClosure() {
data.fontDirection = 1;
data.fontSize = size;
}
} else if (fnName === 'setFillRGBColor') {
} else if (fnId === OPS.setFillRGBColor) {
data.rgb = args;
} else if (fnName === 'setFillGray') {
} else if (fnId === OPS.setFillGray) {
var rgbValue = args[0] * 255;
data.rgb = [rgbValue, rgbValue, rgbValue];
}
@@ -3973,7 +4111,9 @@ PDFJS.disableWorker = PDFJS.disableWorker === undefined ?
false : PDFJS.disableWorker;
/**
* Path and filename of the worker file. Required when the worker is enabled.
* Path and filename of the worker file. Required when the worker is enabled in
* development mode. If unspecified in the production build, the worker will be
* loaded based on the location of the pdf.js file.
* @var {String}
*/
PDFJS.workerSrc = PDFJS.workerSrc === undefined ? null : PDFJS.workerSrc;
@@ -4002,6 +4142,12 @@ PDFJS.disableAutoFetch = PDFJS.disableAutoFetch === undefined ?
*/
PDFJS.pdfBug = PDFJS.pdfBug === undefined ? false : PDFJS.pdfBug;
/**
* Enables transfer usage in postMessage for ArrayBuffers.
* @var {boolean}
*/
PDFJS.postMessageTransfers = PDFJS.postMessageTransfers === undefined ?
true : PDFJS.postMessageTransfers;
/**
* This is the main entry point for loading a PDF and interacting with it.
* NOTE: If a URL is used to fetch the PDF data a standard XMLHttpRequest(XHR)
@@ -4015,6 +4161,9 @@ PDFJS.pdfBug = PDFJS.pdfBug === undefined ? false : PDFJS.pdfBug;
* - data - A typed array with PDF data.
* - httpHeaders - Basic authentication headers.
* - password - For decrypting password-protected PDFs.
* - initialData - A typed array with the first portion or all of the pdf data.
* Used by the extension since some data is already loaded
* before the switch to range requests.
*
* @param {object} pdfDataRangeTransport is optional. It is used if you want
* to manually serve range requests for data in the PDF. See viewer.js for
@@ -4104,6 +4253,14 @@ var PDFDocumentProxy = (function PDFDocumentProxyClosure() {
getPage: function PDFDocumentProxy_getPage(number) {
return this.transport.getPage(number);
},
/**
* @param {object} Must have 'num' and 'gen' properties.
* @return {Promise} A promise that is resolved with the page index that is
* associated with the reference.
*/
getPageIndex: function PDFDocumentProxy_getPageIndex(ref) {
return this.transport.getPageIndex(ref);
},
/**
* @return {Promise} A promise that is resolved with a lookup table for
* mapping named destinations to reference numbers.
@@ -4179,6 +4336,9 @@ var PDFDocumentProxy = (function PDFDocumentProxyClosure() {
dataLoaded: function PDFDocumentProxy_dataLoaded() {
return this.transport.dataLoaded();
},
cleanup: function PDFDocumentProxy_cleanup() {
this.transport.startCleanup();
},
destroy: function PDFDocumentProxy_destroy() {
this.transport.destroy();
}
@@ -4398,10 +4558,10 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
*/
_renderPageChunk: function PDFPageProxy_renderPageChunk(operatorListChunk) {
// Add the new chunk to the current operator list.
Util.concatenateToArray(this.operatorList.fnArray,
operatorListChunk.fnArray);
Util.concatenateToArray(this.operatorList.argsArray,
operatorListChunk.argsArray);
for (var i = 0, ii = operatorListChunk.length; i < ii; i++) {
this.operatorList.fnArray.push(operatorListChunk.fnArray[i]);
this.operatorList.argsArray.push(operatorListChunk.argsArray[i]);
}
this.operatorList.lastChunk = operatorListChunk.lastChunk;
// Notify all the rendering tasks there are more operators to be consumed.
@@ -4453,9 +4613,13 @@ var WorkerTransport = (function WorkerTransportClosure() {
var messageHandler = new MessageHandler('main', worker);
this.messageHandler = messageHandler;
messageHandler.on('test', function transportTest(supportTypedArray) {
messageHandler.on('test', function transportTest(data) {
var supportTypedArray = data && data.supportTypedArray;
if (supportTypedArray) {
this.worker = worker;
if (!data.supportTransfers) {
PDFJS.postMessageTransfers = false;
}
this.setupMessageHandler(messageHandler);
workerInitializedPromise.resolve();
} else {
@@ -4467,10 +4631,16 @@ var WorkerTransport = (function WorkerTransportClosure() {
}
}.bind(this));
var testObj = new Uint8Array(1);
// Some versions of Opera throw a DATA_CLONE_ERR on
// serializing the typed array.
messageHandler.send('test', testObj);
var testObj = new Uint8Array([PDFJS.postMessageTransfers ? 255 : 0]);
// Some versions of Opera throw a DATA_CLONE_ERR on serializing the
// typed array. Also, checking if we can use transfers.
try {
messageHandler.send('test', testObj, null, [testObj.buffer]);
} catch (ex) {
info('Cannot use postMessage transfers');
testObj[0] = 0;
messageHandler.send('test', testObj);
}
return;
} catch (e) {
info('The worker has been disabled.');
@@ -4704,7 +4874,7 @@ var WorkerTransport = (function WorkerTransportClosure() {
}, this);
messageHandler.on('JpegDecode', function(data, promise) {
var imageData = data[0];
var imageUrl = data[0];
var components = data[1];
if (components != 3 && components != 1)
error('Only 3 component or 1 component can be returned');
@@ -4734,8 +4904,7 @@ var WorkerTransport = (function WorkerTransportClosure() {
}
promise.resolve({ data: buf, width: width, height: height});
}).bind(this);
var src = 'data:image/jpeg;base64,' + window.btoa(imageData);
img.src = src;
img.src = imageUrl;
});
},
@@ -4774,6 +4943,16 @@ var WorkerTransport = (function WorkerTransportClosure() {
return promise;
},
getPageIndex: function WorkerTransport_getPageIndexByRef(ref) {
var promise = new PDFJS.Promise();
this.messageHandler.send('GetPageIndex', { ref: ref },
function (pageIndex) {
promise.resolve(pageIndex);
}
);
return promise;
},
getAnnotations: function WorkerTransport_getAnnotations(pageIndex) {
this.messageHandler.send('GetAnnotationsRequest',
{ pageIndex: pageIndex });
@@ -4787,6 +4966,21 @@ var WorkerTransport = (function WorkerTransportClosure() {
}
);
return promise;
},
startCleanup: function WorkerTransport_startCleanup() {
this.messageHandler.send('Cleanup', null,
function endCleanup() {
for (var i = 0, ii = this.pageCache.length; i < ii; i++) {
var page = this.pageCache[i];
if (page) {
page.destroy();
}
}
this.commonObjs.clear();
FontLoader.clear();
}.bind(this)
);
}
};
return WorkerTransport;
@@ -5007,7 +5201,7 @@ var InternalRenderTask = (function InternalRenderTaskClosure() {
this.operatorListIdx,
this._continue.bind(this),
this.stepper);
if (this.operatorListIdx === this.operatorList.fnArray.length) {
if (this.operatorListIdx === this.operatorList.argsArray.length) {
this.running = false;
if (this.operatorList.lastChunk) {
this.gfx.endDrawing();
@@ -5536,37 +5730,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
var EO_CLIP = {};
CanvasGraphics.prototype = {
slowCommands: {
'stroke': true,
'closeStroke': true,
'fill': true,
'eoFill': true,
'fillStroke': true,
'eoFillStroke': true,
'closeFillStroke': true,
'closeEOFillStroke': true,
'showText': true,
'showSpacedText': true,
'setStrokeColorSpace': true,
'setFillColorSpace': true,
'setStrokeColor': true,
'setStrokeColorN': true,
'setFillColor': true,
'setFillColorN': true,
'setStrokeGray': true,
'setFillGray': true,
'setStrokeRGBColor': true,
'setFillRGBColor': true,
'setStrokeCMYKColor': true,
'setFillCMYKColor': true,
'paintJpegXObject': true,
'paintImageXObject': true,
'paintInlineImageXObject': true,
'paintInlineImageXObjectGroup': true,
'paintImageMaskXObject': true,
'paintImageMaskXObjectGroup': true,
'shadingFill': true
},
beginDrawing: function CanvasGraphics_beginDrawing(viewport, transparency) {
// For pdfs that use blend modes we have to clear the canvas else certain
@@ -5618,8 +5781,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
var commonObjs = this.commonObjs;
var objs = this.objs;
var fnName;
var slowCommands = this.slowCommands;
var fnId;
while (true) {
if (stepper && i === stepper.nextBreakPoint) {
@@ -5627,10 +5789,10 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
return i;
}
fnName = fnArray[i];
fnId = fnArray[i];
if (fnName !== 'dependency') {
this[fnName].apply(this, argsArray[i]);
if (fnId !== OPS.dependency) {
this[fnId].apply(this, argsArray[i]);
} else {
var deps = argsArray[i];
for (var n = 0, nn = deps.length; n < nn; n++) {
@@ -5657,10 +5819,10 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
return i;
}
// If the execution took longer then a certain amount of time, shedule
// If the execution took longer then a certain amount of time, schedule
// to continue exeution after a short delay.
// However, this is only possible if a 'continueCallback' is passed in.
if (continueCallback && slowCommands[fnName] && Date.now() > endTime) {
if (continueCallback && Date.now() > endTime) {
setTimeout(continueCallback, 0);
return i;
}
@@ -6947,6 +7109,10 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
}
};
for (var op in OPS) {
CanvasGraphics.prototype[OPS[op]] = CanvasGraphics.prototype[op];
}
return CanvasGraphics;
})();
@@ -6967,6 +7133,12 @@ var FontLoader = {
var styleSheet = styleElement.sheet;
styleSheet.insertRule(rule, styleSheet.cssRules.length);
},
clear: function fontLoaderClear() {
var styleElement = document.getElementById('PDFJS_FONT_STYLE_TAG');
if (styleElement) {
styleElement.parentNode.removeChild(styleElement);
}
},
bind: function fontLoaderBind(fonts, callback) {
assert(!isWorker, 'bind() shall be called from main thread');

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,27 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* Copyright 2013 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* globals */
'use strict';
var EXPORTED_SYMBOLS = ['DEFAULT_PREFERENCES'];
var DEFAULT_PREFERENCES = {
showPreviousViewOnLoad: true,
defaultZoomValue: '',
ifAvailableShowOutlineOnLoad: false
};

View File

@@ -240,6 +240,8 @@ var Stepper = (function StepperClosure() {
return out;
}
var opMap = null;
var glyphCommands = {
'showText': 0,
'showSpacedText': 0,
@@ -271,6 +273,12 @@ var Stepper = (function StepperClosure() {
headerRow.appendChild(c('th', 'args'));
panel.appendChild(content);
this.table = table;
if (!opMap) {
opMap = Object.create(null);
for (var key in PDFJS.OPS) {
opMap[PDFJS.OPS[key]] = key;
}
}
},
updateOperatorList: function updateOperatorList(operatorList) {
var self = this;
@@ -300,7 +308,7 @@ var Stepper = (function StepperClosure() {
breakCell.appendChild(cbox);
line.appendChild(breakCell);
line.appendChild(c('td', i.toString()));
var fn = operatorList.fnArray[i];
var fn = opMap[operatorList.fnArray[i]];
var decArgs = args;
if (fn in glyphCommands) {
var glyphIndex = glyphCommands[fn];

View File

@@ -144,7 +144,6 @@ limitations under the License.
</div>
<label id="pageNumberLabel" class="toolbarLabel" for="pageNumber" data-l10n-id="page_label">Page: </label>
<input type="number" id="pageNumber" class="toolbarField pageNumber" value="1" size="4" min="1" tabindex="8">
</input>
<span id="numPages" class="toolbarLabel"></span>
</div>
<div id="toolbarViewerRight">

View File

@@ -16,8 +16,8 @@
*/
/* globals PDFJS, PDFBug, FirefoxCom, Stats, Cache, PDFFindBar, CustomStyle,
PDFFindController, ProgressBar, TextLayerBuilder, DownloadManager,
getFileName, getOutputScale, scrollIntoView, getPDFFileNameFromURL,
PDFHistory, Settings, PageView, ThumbnailView, noContextMenuHandler,
getFileName, scrollIntoView, getPDFFileNameFromURL, PDFHistory,
Preferences, Settings, PageView, ThumbnailView, noContextMenuHandler,
SecondaryToolbar, PasswordPrompt, PresentationMode */
'use strict';
@@ -38,6 +38,7 @@ var SCALE_SELECT_CONTAINER_PADDING = 8;
var SCALE_SELECT_PADDING = 22;
var THUMBNAIL_SCROLL_MARGIN = -19;
var USE_ONLY_CSS_ZOOM = false;
var CLEANUP_TIMEOUT = 30000;
var RenderingStates = {
INITIAL: 0,
RUNNING: 1,
@@ -154,6 +155,9 @@ function scrollIntoView(element, spot) {
return;
}
while (parent.clientHeight == parent.scrollHeight) {
if (parent.dataset._scaleY) {
offsetY /= parent.dataset._scaleY;
}
offsetY += parent.offsetTop;
parent = parent.offsetParent;
if (!parent)
@@ -284,6 +288,92 @@ var Cache = function cacheCache(size) {
var EXPORTED_SYMBOLS = ['DEFAULT_PREFERENCES'];
var DEFAULT_PREFERENCES = {
showPreviousViewOnLoad: true,
defaultZoomValue: '',
ifAvailableShowOutlineOnLoad: false
};
var Preferences = (function PreferencesClosure() {
function Preferences() {
this.prefs = {};
this.initializedPromise = this.readFromStorage().then(function(prefObj) {
if (prefObj) {
this.prefs = prefObj;
}
}.bind(this));
}
Preferences.prototype = {
writeToStorage: function Preferences_writeToStorage(prefObj) {
return;
},
readFromStorage: function Preferences_readFromStorage() {
var readFromStoragePromise = new PDFJS.Promise();
return readFromStoragePromise;
},
reset: function Preferences_reset() {
if (this.initializedPromise.isResolved) {
this.prefs = {};
this.writeToStorage(this.prefs);
}
},
set: function Preferences_set(name, value) {
if (!this.initializedPromise.isResolved) {
return;
} else if (DEFAULT_PREFERENCES[name] === undefined) {
console.error('Preferences_set: \'' + name + '\' is undefined.');
return;
} else if (value === undefined) {
console.error('Preferences_set: no value is specified.');
return;
}
var valueType = typeof value;
var defaultType = typeof DEFAULT_PREFERENCES[name];
if (valueType !== defaultType) {
if (valueType === 'number' && defaultType === 'string') {
value = value.toString();
} else {
console.error('Preferences_set: \'' + value + '\' is a \"' +
valueType + '\", expected a \"' + defaultType + '\".');
return;
}
}
this.prefs[name] = value;
this.writeToStorage(this.prefs);
},
get: function Preferences_get(name) {
var defaultPref = DEFAULT_PREFERENCES[name];
if (defaultPref === undefined) {
console.error('Preferences_get: \'' + name + '\' is undefined.');
return;
} else if (this.initializedPromise.isResolved) {
var pref = this.prefs[name];
if (pref !== undefined) {
return pref;
}
}
return defaultPref;
}
};
return Preferences;
})();
var FirefoxCom = (function FirefoxComClosure() {
@@ -373,6 +463,17 @@ var DownloadManager = (function DownloadManagerClosure() {
return DownloadManager;
})();
Preferences.prototype.writeToStorage = function(prefObj) {
FirefoxCom.requestSync('setPreferences', prefObj);
};
Preferences.prototype.readFromStorage = function() {
var readFromStoragePromise = new PDFJS.Promise();
var readPrefs = JSON.parse(FirefoxCom.requestSync('getPreferences'));
readFromStoragePromise.resolve(readPrefs);
return readFromStoragePromise;
};
var cache = new Cache(CACHE_SIZE);
var currentPageNumber = 1;
@@ -580,11 +681,12 @@ var PDFFindBar = {
},
open: function() {
if (this.opened) return;
if (!this.opened) {
this.opened = true;
this.toggleButton.classList.add('toggled');
this.bar.classList.remove('hidden');
}
this.opened = true;
this.toggleButton.classList.add('toggled');
this.bar.classList.remove('hidden');
this.findField.select();
this.findField.focus();
},
@@ -797,8 +899,8 @@ var PDFFindController = {
},
nextMatch: function() {
var pages = this.pdfPageSource.pages;
var previous = this.state.findPrevious;
var currentPageIndex = this.pdfPageSource.page - 1;
var numPages = this.pdfPageSource.pages.length;
this.active = true;
@@ -807,7 +909,7 @@ var PDFFindController = {
// Need to recalculate the matches, reset everything.
this.dirtyMatch = false;
this.selected.pageIdx = this.selected.matchIdx = -1;
this.offset.pageIdx = previous ? numPages - 1 : 0;
this.offset.pageIdx = currentPageIndex;
this.offset.matchIdx = null;
this.hadMatch = false;
this.resumeCallback = null;
@@ -998,8 +1100,7 @@ var PDFHistory = {
// is opened in the web viewer.
this.reInitialized = true;
}
window.history.replaceState({ fingerprint: this.fingerprint }, '',
document.URL);
this._pushOrReplaceState({ fingerprint: this.fingerprint }, true);
}
var self = this;
@@ -1064,6 +1165,15 @@ var PDFHistory = {
state.target && state.target.hash) ? true : false;
},
_pushOrReplaceState: function pdfHistory_pushOrReplaceState(stateObj,
replace) {
if (replace) {
window.history.replaceState(stateObj, '');
} else {
window.history.pushState(stateObj, '');
}
},
get isHashChangeUnlocked() {
if (!this.initialized) {
return true;
@@ -1224,11 +1334,8 @@ var PDFHistory = {
this._pushToHistory(previousParams, false, replacePrevious);
}
}
if (overwrite || this.uid === 0) {
window.history.replaceState(this._stateObj(params), '', document.URL);
} else {
window.history.pushState(this._stateObj(params), '', document.URL);
}
this._pushOrReplaceState(this._stateObj(params),
(overwrite || this.uid === 0));
this.currentUid = this.uid++;
this.current = params;
this.updatePreviousBookmark = true;
@@ -1689,6 +1796,7 @@ var PDFView = {
lastScroll: 0,
previousPageNumber: 1,
isViewerEmbedded: (window.parent !== window),
idleTimeout: null,
// called once when the document is loaded
initialize: function pdfViewInitialize() {
@@ -1789,7 +1897,7 @@ var PDFView = {
var number = parseFloat(value);
var scale;
if (number) {
if (number > 0) {
scale = number;
resetAutoSettings = true;
} else {
@@ -1816,6 +1924,10 @@ var PDFView = {
case 'auto':
scale = Math.min(MAX_AUTO_SCALE, pageWidthScale);
break;
default:
console.error('pdfViewSetScale: \'' + value +
'\' is an unknown zoom value.');
return;
}
}
this.currentScaleValue = value;
@@ -2019,7 +2131,8 @@ var PDFView = {
switch (args.pdfjsLoadAction) {
case 'supportsRangedLoading':
PDFView.open(args.pdfUrl, 0, undefined, pdfDataRangeTransport, {
length: args.length
length: args.length,
initialData: args.data
});
break;
case 'range':
@@ -2182,9 +2295,9 @@ var PDFView = {
// Update the browsing history.
PDFHistory.push({ dest: dest, hash: destString, page: pageNumber });
} else {
self.pendingRefStrLoaded = new PDFJS.Promise();
self.pendingRefStr = destRef.num + ' ' + destRef.gen + ' R';
self.pendingRefStrLoaded.then(function() {
self.pdfDocument.getPageIndex(destRef).then(function (pageIndex) {
var pageNum = pageIndex + 1;
self.pagesRefMap[destRef.num + ' ' + destRef.gen + ' R'] = pageNum;
goToDestination(destRef);
});
}
@@ -2289,9 +2402,14 @@ var PDFView = {
},
load: function pdfViewLoad(pdfDocument, scale) {
var self = this;
var onePageRendered = new PDFJS.Promise();
function bindOnAfterDraw(pageView, thumbnailView) {
// when page is painted, using the image as thumbnail base
pageView.onAfterDraw = function pdfViewLoadOnAfterDraw() {
if (!onePageRendered.isResolved) {
onePageRendered.resolve();
}
thumbnailView.setImage(pageView.canvas);
};
}
@@ -2329,6 +2447,7 @@ var PDFView = {
mozL10n.get('page_of', {pageCount: pagesCount}, 'of {{pageCount}}');
document.getElementById('pageNumber').max = pagesCount;
var prefs = PDFView.prefs = new Preferences();
PDFView.documentFingerprint = id;
var store = PDFView.store = new Settings(id);
@@ -2339,7 +2458,6 @@ var PDFView = {
var thumbnails = this.thumbnails = [];
var pagesPromise = this.pagesPromise = new PDFJS.Promise();
var self = this;
var firstPagePromise = pdfDocument.getPage(1);
@@ -2347,7 +2465,6 @@ var PDFView = {
// viewport for all pages
firstPagePromise.then(function(pdfPage) {
var viewport = pdfPage.getViewport((scale || 1.0) * CSS_UNITS);
var pagePromises = [];
for (var pageNum = 1; pageNum <= pagesCount; ++pageNum) {
var viewportClone = viewport.clone();
var pageView = new PageView(container, pageNum, scale,
@@ -2360,56 +2477,59 @@ var PDFView = {
thumbnails.push(thumbnailView);
}
// Fetch all the pages since the viewport is needed before printing
// starts to create the correct size canvas. Wait until one page is
// rendered so we don't tie up too many resources early on.
onePageRendered.then(function () {
if (!PDFJS.disableAutoFetch) {
var getPagesLeft = pagesCount;
for (var pageNum = 1; pageNum <= pagesCount; ++pageNum) {
pdfDocument.getPage(pageNum).then(function (pageNum, pdfPage) {
var pageView = pages[pageNum - 1];
if (!pageView.pdfPage) {
pageView.setPdfPage(pdfPage);
}
var refStr = pdfPage.ref.num + ' ' + pdfPage.ref.gen + ' R';
pagesRefMap[refStr] = pageNum;
getPagesLeft--;
if (!getPagesLeft) {
pagesPromise.resolve();
}
}.bind(null, pageNum));
}
} else {
// XXX: Printing is semi-broken with auto fetch disabled.
pagesPromise.resolve();
}
});
var event = document.createEvent('CustomEvent');
event.initCustomEvent('documentload', true, true, {});
window.dispatchEvent(event);
PDFView.loadingBar.setWidth(container);
for (var pageNum = 1; pageNum <= pagesCount; ++pageNum) {
var pagePromise = pdfDocument.getPage(pageNum);
pagePromise.then(function(pdfPage) {
var pageNum = pdfPage.pageNumber;
var pageView = pages[pageNum - 1];
if (!pageView.pdfPage) {
// The pdfPage might already be set if we've already entered
// pageView.draw()
pageView.setPdfPage(pdfPage);
}
var thumbnailView = thumbnails[pageNum - 1];
if (!thumbnailView.pdfPage) {
thumbnailView.setPdfPage(pdfPage);
}
var pageRef = pdfPage.ref;
var refStr = pageRef.num + ' ' + pageRef.gen + ' R';
pagesRefMap[refStr] = pdfPage.pageNumber;
if (self.pendingRefStr && self.pendingRefStr === refStr) {
self.pendingRefStrLoaded.resolve();
}
});
pagePromises.push(pagePromise);
}
PDFFindController.firstPagePromise.resolve();
PDFJS.Promise.all(pagePromises).then(function(pages) {
pagesPromise.resolve(pages);
});
});
var prefsPromise = prefs.initializedPromise;
var storePromise = store.initializedPromise;
PDFJS.Promise.all([firstPagePromise, storePromise]).then(function() {
PDFJS.Promise.all([firstPagePromise, prefsPromise, storePromise]).
then(function() {
var showPreviousViewOnLoad = prefs.get('showPreviousViewOnLoad');
var defaultZoomValue = prefs.get('defaultZoomValue');
var storedHash = null;
if (store.get('exists', false)) {
if (showPreviousViewOnLoad && store.get('exists', false)) {
var pageNum = store.get('page', '1');
var zoom = store.get('zoom', PDFView.currentScale);
var zoom = defaultZoomValue || store.get('zoom', PDFView.currentScale);
var left = store.get('scrollLeft', '0');
var top = store.get('scrollTop', '0');
storedHash = 'page=' + pageNum + '&zoom=' + zoom + ',' +
left + ',' + top;
} else if (defaultZoomValue) {
storedHash = 'page=1&zoom=' + defaultZoomValue;
}
// Initialize the browsing history.
PDFHistory.initialize(self.documentFingerprint);
@@ -2459,6 +2579,13 @@ var PDFView = {
pdfDocument.getOutline().then(function(outline) {
self.outline = new DocumentOutlineView(outline);
document.getElementById('viewOutline').disabled = !outline;
if (outline && prefs.get('ifAvailableShowOutlineOnLoad')) {
if (!self.sidebarOpen) {
document.getElementById('sidebarToggle').click();
}
self.switchSidebarView('outline');
}
});
});
@@ -2550,6 +2677,11 @@ var PDFView = {
},
renderHighestPriority: function pdfViewRenderHighestPriority() {
if (PDFView.idleTimeout) {
clearTimeout(PDFView.idleTimeout);
PDFView.idleTimeout = null;
}
// Pages have a higher priority than thumbnails, so check them first.
var visiblePages = this.getVisiblePages();
var pageView = this.getHighestPriority(visiblePages, this.pages,
@@ -2564,9 +2696,25 @@ var PDFView = {
var thumbView = this.getHighestPriority(visibleThumbs,
this.thumbnails,
this.thumbnailViewScroll.down);
if (thumbView)
if (thumbView) {
this.renderView(thumbView, 'thumbnail');
return;
}
}
PDFView.idleTimeout = setTimeout(function () {
PDFView.cleanup();
}, CLEANUP_TIMEOUT);
},
cleanup: function pdfViewCleanup() {
for (var i = 0, ii = this.pages.length; i < ii; i++) {
if (this.pages[i] &&
this.pages[i].renderingState !== RenderingStates.FINISHED) {
this.pages[i].reset();
}
}
this.pdfDocument.cleanup();
},
getHighestPriority: function pdfViewGetHighestPriority(visible, views,
@@ -2643,28 +2791,31 @@ var PDFView = {
PDFView.navigateTo(params.nameddest);
return;
}
var pageNumber, dest;
if ('page' in params) {
var pageNumber = (params.page | 0) || 1;
if ('zoom' in params) {
var zoomArgs = params.zoom.split(','); // scale,left,top
// building destination array
pageNumber = (params.page | 0) || 1;
}
if ('zoom' in params) {
var zoomArgs = params.zoom.split(','); // scale,left,top
// building destination array
// If the zoom value, it has to get divided by 100. If it is a string,
// it should stay as it is.
var zoomArg = zoomArgs[0];
var zoomArgNumber = parseFloat(zoomArg);
if (zoomArgNumber)
zoomArg = zoomArgNumber / 100;
var dest = [null, {name: 'XYZ'},
zoomArgs.length > 1 ? (zoomArgs[1] | 0) : null,
zoomArgs.length > 2 ? (zoomArgs[2] | 0) : null,
zoomArg];
var currentPage = this.pages[pageNumber - 1];
currentPage.scrollIntoView(dest);
} else {
this.page = pageNumber; // simple page
// If the zoom value, it has to get divided by 100. If it is a string,
// it should stay as it is.
var zoomArg = zoomArgs[0];
var zoomArgNumber = parseFloat(zoomArg);
if (zoomArgNumber) {
zoomArg = zoomArgNumber / 100;
}
dest = [null, {name: 'XYZ'},
zoomArgs.length > 1 ? (zoomArgs[1] | 0) : null,
zoomArgs.length > 2 ? (zoomArgs[2] | 0) : null,
zoomArg];
}
if (dest) {
var currentPage = this.pages[(pageNumber || this.page) - 1];
currentPage.scrollIntoView(dest);
} else if (pageNumber) {
this.page = pageNumber; // simple page
}
if ('pagemode' in params) {
var toggle = document.getElementById('sidebarToggle');
@@ -2935,12 +3086,11 @@ var PageView = function pageView(container, id, scale,
this.rotation = 0;
this.scale = scale || 1.0;
this.viewport = defaultViewport;
this.pdfPageRotate = defaultViewport.rotate;
this.pdfPageRotate = defaultViewport.rotation;
this.renderingState = RenderingStates.INITIAL;
this.resume = null;
this.textContent = null;
this.textLayer = null;
this.zoomLayer = null;
@@ -2962,7 +3112,8 @@ var PageView = function pageView(container, id, scale,
this.setPdfPage = function pageViewSetPdfPage(pdfPage) {
this.pdfPage = pdfPage;
this.pdfPageRotate = pdfPage.rotate;
this.viewport = pdfPage.getViewport(this.scale * CSS_UNITS);
var totalRotation = (this.rotation + this.pdfPageRotate) % 360;
this.viewport = pdfPage.getViewport(this.scale * CSS_UNITS, totalRotation);
this.stats = pdfPage.stats;
this.reset();
};
@@ -3279,7 +3430,7 @@ var PageView = function pageView(container, id, scale,
width / CSS_UNITS;
heightScale = (PDFView.container.clientHeight - SCROLLBAR_PADDING) /
height / CSS_UNITS;
scale = Math.min(widthScale, heightScale);
scale = Math.min(Math.abs(widthScale), Math.abs(heightScale));
break;
default:
return;
@@ -3313,10 +3464,9 @@ var PageView = function pageView(container, id, scale,
};
this.getTextContent = function pageviewGetTextContent() {
if (!this.textContent) {
this.textContent = this.pdfPage.getTextContent();
}
return this.textContent;
return PDFView.getPage(this.id).then(function(pdfPage) {
return pdfPage.getTextContent();
});
};
this.draw = function pageviewDraw(callback) {
@@ -3364,8 +3514,8 @@ var PageView = function pageView(container, id, scale,
outputScale.scaled = true;
}
canvas.width = Math.floor(viewport.width * outputScale.sx);
canvas.height = Math.floor(viewport.height * outputScale.sy);
canvas.width = (Math.floor(viewport.width) * outputScale.sx) | 0;
canvas.height = (Math.floor(viewport.height) * outputScale.sy) | 0;
canvas.style.width = Math.floor(viewport.width) + 'px';
canvas.style.height = Math.floor(viewport.height) + 'px';
// Add the viewport so it's known what it was originally drawn with.
@@ -3398,6 +3548,8 @@ var PageView = function pageView(container, id, scale,
(1 / outputScale.sy) + ')';
CustomStyle.setProp('transform' , textLayerDiv, cssScale);
CustomStyle.setProp('transformOrigin' , textLayerDiv, '0% 0%');
textLayerDiv.dataset._scaleX = outputScale.sx;
textLayerDiv.dataset._scaleY = outputScale.sy;
}
// Checking if document fonts are used only once
@@ -3813,27 +3965,24 @@ var TextLayerBuilder = function textLayerBuilder(options) {
if ('isWhitespace' in textDiv.dataset) {
continue;
}
textLayerFrag.appendChild(textDiv);
ctx.font = textDiv.style.fontSize + ' ' + textDiv.style.fontFamily;
var width = ctx.measureText(textDiv.textContent).width;
if (width > 0) {
textLayerFrag.appendChild(textDiv);
var textScale = textDiv.dataset.canvasWidth / width;
var rotation = textDiv.dataset.angle;
var transform = 'scale(' + textScale + ', 1)';
transform = 'rotate(' + rotation + 'deg) ' + transform;
CustomStyle.setProp('transform' , textDiv, transform);
CustomStyle.setProp('transformOrigin' , textDiv, '0% 0%');
textLayerDiv.appendChild(textDiv);
}
}
textLayerDiv.appendChild(textLayerFrag);
this.renderingDone = true;
this.updateMatches();
textLayerDiv.appendChild(textLayerFrag);
};
this.setupRenderLayoutTimer = function textLayerSetupRenderLayoutTimer() {
@@ -4587,7 +4736,7 @@ window.addEventListener('keydown', function keydown(evt) {
switch (evt.keyCode) {
case 70: // f
if (!PDFView.supportsIntegratedFind) {
PDFFindBar.toggle();
PDFFindBar.open();
handled = true;
}
break;
@@ -4629,6 +4778,11 @@ window.addEventListener('keydown', function keydown(evt) {
SecondaryToolbar.presentationModeClick();
handled = true;
break;
case 71: // g
// focuses input#pageNumber field
document.getElementById('pageNumber').select();
handled = true;
break;
}
}

View File

@@ -5,6 +5,7 @@ content/PdfJs.jsm
content/PdfJsTelemetry.jsm
content/build/pdf.js
content/build/pdf.worker.js
content/default_preferences.js
content/network.js
content/web/debugger.js
content/web/images/annotation-check.svg