Bug 1228603 - Update pdf.js to version 1.3.42. r=bdahl

--HG--
extra : rebase_source : 83b4d456ae8aac695bd1b852b2fac80af83d68cb
extra : source : 2f801d6ef06489fa9dfbdf160350fcd7e4afbc5d
This commit is contained in:
Ryan VanderMeulen 2015-11-30 15:53:49 -05:00
Родитель b864bcf349
Коммит 7d23abf82e
7 изменённых файлов: 670 добавлений и 301 удалений

Просмотреть файл

@ -1,3 +1,3 @@
This is the pdf.js project output, https://github.com/mozilla/pdf.js This is the pdf.js project output, https://github.com/mozilla/pdf.js
Current extension version is: 1.3.14 Current extension version is: 1.3.42

Просмотреть файл

@ -12,6 +12,11 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/* jshint esnext:true */
/* globals Components, Services, XPCOMUtils, PdfjsChromeUtils,
PdfjsContentUtils, DEFAULT_PREFERENCES, PdfStreamConverter */
'use strict';
var EXPORTED_SYMBOLS = ['PdfJs']; var EXPORTED_SYMBOLS = ['PdfJs'];

Просмотреть файл

@ -12,6 +12,10 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/* jshint esnext:true */
/* globals Components, Services, XPCOMUtils, DEFAULT_PREFERENCES */
'use strict';
var EXPORTED_SYMBOLS = ['PdfjsChromeUtils']; var EXPORTED_SYMBOLS = ['PdfjsChromeUtils'];

Просмотреть файл

@ -20,8 +20,8 @@ if (typeof PDFJS === 'undefined') {
(typeof window !== 'undefined' ? window : this).PDFJS = {}; (typeof window !== 'undefined' ? window : this).PDFJS = {};
} }
PDFJS.version = '1.3.14'; PDFJS.version = '1.3.42';
PDFJS.build = 'df46b64'; PDFJS.build = '84a47f8';
(function pdfjsWrapper() { (function pdfjsWrapper() {
// Use strict in our context only - users might not want it // Use strict in our context only - users might not want it
@ -60,6 +60,19 @@ var AnnotationType = {
LINK: 3 LINK: 3
}; };
var AnnotationFlag = {
INVISIBLE: 0x01,
HIDDEN: 0x02,
PRINT: 0x04,
NOZOOM: 0x08,
NOROTATE: 0x10,
NOVIEW: 0x20,
READONLY: 0x40,
LOCKED: 0x80,
TOGGLENOVIEW: 0x100,
LOCKEDCONTENTS: 0x200
};
var AnnotationBorderStyleType = { var AnnotationBorderStyleType = {
SOLID: 1, SOLID: 1,
DASHED: 2, DASHED: 2,
@ -1186,26 +1199,20 @@ PDFJS.createObjectURL = (function createObjectURLClosure() {
}; };
})(); })();
function MessageHandler(name, comObj) { function MessageHandler(sourceName, targetName, comObj) {
this.name = name; this.sourceName = sourceName;
this.targetName = targetName;
this.comObj = comObj; this.comObj = comObj;
this.callbackIndex = 1; this.callbackIndex = 1;
this.postMessageTransfers = true; this.postMessageTransfers = true;
var callbacksCapabilities = this.callbacksCapabilities = {}; var callbacksCapabilities = this.callbacksCapabilities = {};
var ah = this.actionHandler = {}; var ah = this.actionHandler = {};
ah['console_log'] = [function ahConsoleLog(data) { this._onComObjOnMessage = function messageHandlerComObjOnMessage(event) {
console.log.apply(console, data);
}];
ah['console_error'] = [function ahConsoleError(data) {
console.error.apply(console, data);
}];
ah['_unsupported_feature'] = [function ah_unsupportedFeature(data) {
UnsupportedManager.notify(data);
}];
comObj.onmessage = function messageHandlerComObjOnMessage(event) {
var data = event.data; var data = event.data;
if (data.targetName !== this.sourceName) {
return;
}
if (data.isReply) { if (data.isReply) {
var callbackId = data.callbackId; var callbackId = data.callbackId;
if (data.callbackId in callbacksCapabilities) { if (data.callbackId in callbacksCapabilities) {
@ -1222,10 +1229,14 @@ function MessageHandler(name, comObj) {
} else if (data.action in ah) { } else if (data.action in ah) {
var action = ah[data.action]; var action = ah[data.action];
if (data.callbackId) { if (data.callbackId) {
var sourceName = this.sourceName;
var targetName = data.sourceName;
Promise.resolve().then(function () { Promise.resolve().then(function () {
return action[0].call(action[1], data.data); return action[0].call(action[1], data.data);
}).then(function (result) { }).then(function (result) {
comObj.postMessage({ comObj.postMessage({
sourceName: sourceName,
targetName: targetName,
isReply: true, isReply: true,
callbackId: data.callbackId, callbackId: data.callbackId,
data: result data: result
@ -1236,6 +1247,8 @@ function MessageHandler(name, comObj) {
reason = reason + ''; reason = reason + '';
} }
comObj.postMessage({ comObj.postMessage({
sourceName: sourceName,
targetName: targetName,
isReply: true, isReply: true,
callbackId: data.callbackId, callbackId: data.callbackId,
error: reason error: reason
@ -1247,7 +1260,8 @@ function MessageHandler(name, comObj) {
} else { } else {
error('Unknown action from worker: ' + data.action); error('Unknown action from worker: ' + data.action);
} }
}; }.bind(this);
comObj.addEventListener('message', this._onComObjOnMessage);
} }
MessageHandler.prototype = { MessageHandler.prototype = {
@ -1266,6 +1280,8 @@ MessageHandler.prototype = {
*/ */
send: function messageHandlerSend(actionName, data, transfers) { send: function messageHandlerSend(actionName, data, transfers) {
var message = { var message = {
sourceName: this.sourceName,
targetName: this.targetName,
action: actionName, action: actionName,
data: data data: data
}; };
@ -1283,6 +1299,8 @@ MessageHandler.prototype = {
function messageHandlerSendWithPromise(actionName, data, transfers) { function messageHandlerSendWithPromise(actionName, data, transfers) {
var callbackId = this.callbackIndex++; var callbackId = this.callbackIndex++;
var message = { var message = {
sourceName: this.sourceName,
targetName: this.targetName,
action: actionName, action: actionName,
data: data, data: data,
callbackId: callbackId callbackId: callbackId
@ -1308,6 +1326,10 @@ MessageHandler.prototype = {
} else { } else {
this.comObj.postMessage(message); this.comObj.postMessage(message);
} }
},
destroy: function () {
this.comObj.removeEventListener('message', this._onComObjOnMessage);
} }
}; };
@ -1476,6 +1498,9 @@ PDFJS.maxCanvasPixels = (PDFJS.maxCanvasPixels === undefined ?
/** /**
* (Deprecated) Opens external links in a new window if enabled. * (Deprecated) Opens external links in a new window if enabled.
* The default behavior opens external links in the PDF.js window. * The default behavior opens external links in the PDF.js window.
*
* NOTE: This property has been deprecated, please use
* `PDFJS.externalLinkTarget = PDFJS.LinkTarget.BLANK` instead.
* @var {boolean} * @var {boolean}
*/ */
PDFJS.openExternalLinksInNewWindow = ( PDFJS.openExternalLinksInNewWindow = (
@ -1525,6 +1550,8 @@ PDFJS.isEvalSupported = (PDFJS.isEvalSupported === undefined ?
* @property {number} rangeChunkSize - Optional parameter to specify * @property {number} rangeChunkSize - Optional parameter to specify
* maximum number of bytes fetched per range request. The default value is * maximum number of bytes fetched per range request. The default value is
* 2^16 = 65536. * 2^16 = 65536.
* @property {PDFWorker} worker - The worker that will be used for the loading
* and parsing of the PDF data.
*/ */
/** /**
@ -1587,7 +1614,6 @@ PDFJS.getDocument = function getDocument(src,
task.onPassword = passwordCallback || null; task.onPassword = passwordCallback || null;
task.onProgress = progressCallback || null; task.onProgress = progressCallback || null;
var workerInitializedCapability, transport;
var source; var source;
if (typeof src === 'string') { if (typeof src === 'string') {
source = { url: src }; source = { url: src };
@ -1608,12 +1634,18 @@ PDFJS.getDocument = function getDocument(src,
} }
var params = {}; var params = {};
var rangeTransport = null;
var worker = null;
for (var key in source) { for (var key in source) {
if (key === 'url' && typeof window !== 'undefined') { if (key === 'url' && typeof window !== 'undefined') {
// The full path is required in the 'url' field. // The full path is required in the 'url' field.
params[key] = combineUrl(window.location.href, source[key]); params[key] = combineUrl(window.location.href, source[key]);
continue; continue;
} else if (key === 'range') { } else if (key === 'range') {
rangeTransport = source[key];
continue;
} else if (key === 'worker') {
worker = source[key];
continue; continue;
} else if (key === 'data' && !(source[key] instanceof Uint8Array)) { } else if (key === 'data' && !(source[key] instanceof Uint8Array)) {
// Converting string or array-like data to Uint8Array. // Converting string or array-like data to Uint8Array.
@ -1634,27 +1666,98 @@ PDFJS.getDocument = function getDocument(src,
params[key] = source[key]; params[key] = source[key];
} }
params.rangeChunkSize = source.rangeChunkSize || DEFAULT_RANGE_CHUNK_SIZE; params.rangeChunkSize = params.rangeChunkSize || DEFAULT_RANGE_CHUNK_SIZE;
workerInitializedCapability = createPromiseCapability(); if (!worker) {
transport = new WorkerTransport(workerInitializedCapability, source.range); // Worker was not provided -- creating and owning our own.
workerInitializedCapability.promise.then(function transportInitialized() { worker = new PDFWorker();
transport.fetchDocument(task, params); task._worker = worker;
}); }
task._transport = transport; var docId = task.docId;
worker.promise.then(function () {
if (task.destroyed) {
throw new Error('Loading aborted');
}
return _fetchDocument(worker, params, rangeTransport, docId).then(
function (workerId) {
if (task.destroyed) {
throw new Error('Loading aborted');
}
var messageHandler = new MessageHandler(docId, workerId, worker.port);
messageHandler.send('Ready', null);
var transport = new WorkerTransport(messageHandler, task, rangeTransport);
task._transport = transport;
});
}, task._capability.reject);
return task; return task;
}; };
/**
* Starts fetching of specified PDF document/data.
* @param {PDFWorker} worker
* @param {Object} source
* @param {PDFDataRangeTransport} pdfDataRangeTransport
* @param {string} docId Unique document id, used as MessageHandler id.
* @returns {Promise} The promise, which is resolved when worker id of
* MessageHandler is known.
* @private
*/
function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
if (worker.destroyed) {
return Promise.reject(new Error('Worker was destroyed'));
}
source.disableAutoFetch = PDFJS.disableAutoFetch;
source.disableStream = PDFJS.disableStream;
source.chunkedViewerLoading = !!pdfDataRangeTransport;
if (pdfDataRangeTransport) {
source.length = pdfDataRangeTransport.length;
source.initialData = pdfDataRangeTransport.initialData;
}
return worker.messageHandler.sendWithPromise('GetDocRequest', {
docId: docId,
source: source,
disableRange: PDFJS.disableRange,
maxImageSize: PDFJS.maxImageSize,
cMapUrl: PDFJS.cMapUrl,
cMapPacked: PDFJS.cMapPacked,
disableFontFace: PDFJS.disableFontFace,
disableCreateObjectURL: PDFJS.disableCreateObjectURL,
verbosity: PDFJS.verbosity
}).then(function (workerId) {
if (worker.destroyed) {
throw new Error('Worker was destroyed');
}
return workerId;
});
}
/** /**
* PDF document loading operation. * PDF document loading operation.
* @class * @class
* @alias PDFDocumentLoadingTask * @alias PDFDocumentLoadingTask
*/ */
var PDFDocumentLoadingTask = (function PDFDocumentLoadingTaskClosure() { var PDFDocumentLoadingTask = (function PDFDocumentLoadingTaskClosure() {
var nextDocumentId = 0;
/** @constructs PDFDocumentLoadingTask */
function PDFDocumentLoadingTask() { function PDFDocumentLoadingTask() {
this._capability = createPromiseCapability(); this._capability = createPromiseCapability();
this._transport = null; this._transport = null;
this._worker = null;
/**
* Unique document loading task id -- used in MessageHandlers.
* @type {string}
*/
this.docId = 'd' + (nextDocumentId++);
/**
* Shows if loading task is destroyed.
* @type {boolean}
*/
this.destroyed = false;
/** /**
* Callback to request a password if wrong or no password was provided. * Callback to request a password if wrong or no password was provided.
@ -1686,7 +1789,17 @@ var PDFDocumentLoadingTask = (function PDFDocumentLoadingTaskClosure() {
* is completed. * is completed.
*/ */
destroy: function () { destroy: function () {
return this._transport.destroy(); this.destroyed = true;
var transportDestroyed = !this._transport ? Promise.resolve() :
this._transport.destroy();
return transportDestroyed.then(function () {
this._transport = null;
if (this._worker) {
this._worker.destroy();
this._worker = null;
}
}.bind(this));
}, },
/** /**
@ -1915,12 +2028,20 @@ var PDFDocumentProxy = (function PDFDocumentProxyClosure() {
* Destroys current document instance and terminates worker. * Destroys current document instance and terminates worker.
*/ */
destroy: function PDFDocumentProxy_destroy() { destroy: function PDFDocumentProxy_destroy() {
return this.transport.destroy(); return this.loadingTask.destroy();
} }
}; };
return PDFDocumentProxy; return PDFDocumentProxy;
})(); })();
/**
* Page getTextContent parameters.
*
* @typedef {Object} getTextContentParameters
* @param {boolean} normalizeWhitespace - replaces all occurrences of
* whitespace with standard spaces (0x20). The default value is `false`.
*/
/** /**
* Page text content. * Page text content.
* *
@ -1952,6 +2073,16 @@ var PDFDocumentProxy = (function PDFDocumentProxyClosure() {
* @property {string} fontFamily - possible font family * @property {string} fontFamily - possible font family
*/ */
/**
* Page annotation parameters.
*
* @typedef {Object} GetAnnotationsParameters
* @param {string} intent - Determines the annotations that will be fetched,
* can be either 'display' (viewable annotations) or 'print'
* (printable annotations).
* If the parameter is omitted, all annotations are fetched.
*/
/** /**
* Page render parameters. * Page render parameters.
* *
@ -2040,12 +2171,17 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
return new PDFJS.PageViewport(this.view, scale, rotate, 0, 0); return new PDFJS.PageViewport(this.view, scale, rotate, 0, 0);
}, },
/** /**
* @param {GetAnnotationsParameters} params - Annotation parameters.
* @return {Promise} A promise that is resolved with an {Array} of the * @return {Promise} A promise that is resolved with an {Array} of the
* annotation objects. * annotation objects.
*/ */
getAnnotations: function PDFPageProxy_getAnnotations() { getAnnotations: function PDFPageProxy_getAnnotations(params) {
if (!this.annotationsPromise) { var intent = (params && params.intent) || null;
this.annotationsPromise = this.transport.getAnnotations(this.pageIndex);
if (!this.annotationsPromise || this.annotationsIntent !== intent) {
this.annotationsPromise = this.transport.getAnnotations(this.pageIndex,
intent);
this.annotationsIntent = intent;
} }
return this.annotationsPromise; return this.annotationsPromise;
}, },
@ -2184,12 +2320,16 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
}, },
/** /**
* @param {getTextContentParameters} params - getTextContent parameters.
* @return {Promise} That is resolved a {@link TextContent} * @return {Promise} That is resolved a {@link TextContent}
* object that represent the page text content. * object that represent the page text content.
*/ */
getTextContent: function PDFPageProxy_getTextContent() { getTextContent: function PDFPageProxy_getTextContent(params) {
var normalizeWhitespace = (params && params.normalizeWhitespace) || false;
return this.transport.messageHandler.sendWithPromise('GetTextContent', { return this.transport.messageHandler.sendWithPromise('GetTextContent', {
pageIndex: this.pageNumber - 1 pageIndex: this.pageNumber - 1,
normalizeWhitespace: normalizeWhitespace,
}); });
}, },
@ -2296,17 +2436,202 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
return PDFPageProxy; return PDFPageProxy;
})(); })();
/**
* PDF.js web worker abstraction, it controls instantiation of PDF documents and
* WorkerTransport for them. If creation of a web worker is not possible,
* a "fake" worker will be used instead.
* @class
*/
var PDFWorker = (function PDFWorkerClosure() {
var nextFakeWorkerId = 0;
// Loads worker code into main thread.
function setupFakeWorkerGlobal() {
if (!PDFJS.fakeWorkerFilesLoadedCapability) {
PDFJS.fakeWorkerFilesLoadedCapability = createPromiseCapability();
// In the developer build load worker_loader which in turn loads all the
// other files and resolves the promise. In production only the
// pdf.worker.js file is needed.
Util.loadScript(PDFJS.workerSrc, function() {
PDFJS.fakeWorkerFilesLoadedCapability.resolve();
});
}
return PDFJS.fakeWorkerFilesLoadedCapability.promise;
}
function PDFWorker(name) {
this.name = name;
this.destroyed = false;
this._readyCapability = createPromiseCapability();
this._port = null;
this._webWorker = null;
this._messageHandler = null;
this._initialize();
}
PDFWorker.prototype = /** @lends PDFWorker.prototype */ {
get promise() {
return this._readyCapability.promise;
},
get port() {
return this._port;
},
get messageHandler() {
return this._messageHandler;
},
_initialize: function PDFWorker_initialize() {
// If worker support isn't disabled explicit and the browser has worker
// support, create a new web worker and test if it/the browser fullfills
// all requirements to run parts of pdf.js in a web worker.
// Right now, the requirement is, that an Uint8Array is still an
// Uint8Array as it arrives on the worker. (Chrome added this with v.15.)
if (!globalScope.PDFJS.disableWorker && typeof Worker !== 'undefined') {
var workerSrc = PDFJS.workerSrc;
if (!workerSrc) {
error('No PDFJS.workerSrc specified');
}
try {
// Some versions of FF can't create a worker on localhost, see:
// https://bugzilla.mozilla.org/show_bug.cgi?id=683280
var worker = new Worker(workerSrc);
var messageHandler = new MessageHandler('main', 'worker', worker);
messageHandler.on('test', function PDFWorker_test(data) {
if (this.destroyed) {
this._readyCapability.reject(new Error('Worker was destroyed'));
messageHandler.destroy();
worker.terminate();
return; // worker was destroyed
}
var supportTypedArray = data && data.supportTypedArray;
if (supportTypedArray) {
this._messageHandler = messageHandler;
this._port = worker;
this._webWorker = worker;
if (!data.supportTransfers) {
PDFJS.postMessageTransfers = false;
}
this._readyCapability.resolve();
} else {
this._setupFakeWorker();
messageHandler.destroy();
worker.terminate();
}
}.bind(this));
messageHandler.on('console_log', function (data) {
console.log.apply(console, data);
});
messageHandler.on('console_error', function (data) {
console.error.apply(console, data);
});
messageHandler.on('_unsupported_feature', function (data) {
UnsupportedManager.notify(data);
});
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, [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.');
}
}
// Either workers are disabled, not supported or have thrown an exception.
// Thus, we fallback to a faked worker.
this._setupFakeWorker();
},
_setupFakeWorker: function PDFWorker_setupFakeWorker() {
warn('Setting up fake worker.');
globalScope.PDFJS.disableWorker = true;
setupFakeWorkerGlobal().then(function () {
if (this.destroyed) {
this._readyCapability.reject(new Error('Worker was destroyed'));
return;
}
// If we don't use a worker, just post/sendMessage to the main thread.
var port = {
_listeners: [],
postMessage: function (obj) {
var e = {data: obj};
this._listeners.forEach(function (listener) {
listener.call(this, e);
}, this);
},
addEventListener: function (name, listener) {
this._listeners.push(listener);
},
removeEventListener: function (name, listener) {
var i = this._listeners.indexOf(listener);
this._listeners.splice(i, 1);
},
terminate: function () {}
};
this._port = port;
// All fake workers use the same port, making id unique.
var id = 'fake' + (nextFakeWorkerId++);
// If the main thread is our worker, setup the handling for the
// messages -- the main thread sends to it self.
var workerHandler = new MessageHandler(id + '_worker', id, port);
PDFJS.WorkerMessageHandler.setup(workerHandler, port);
var messageHandler = new MessageHandler(id, id + '_worker', port);
this._messageHandler = messageHandler;
this._readyCapability.resolve();
}.bind(this));
},
/**
* Destroys the worker instance.
*/
destroy: function PDFWorker_destroy() {
this.destroyed = true;
if (this._webWorker) {
// We need to terminate only web worker created resource.
this._webWorker.terminate();
this._webWorker = null;
}
this._port = null;
if (this._messageHandler) {
this._messageHandler.destroy();
this._messageHandler = null;
}
}
};
return PDFWorker;
})();
PDFJS.PDFWorker = PDFWorker;
/** /**
* For internal use only. * For internal use only.
* @ignore * @ignore
*/ */
var WorkerTransport = (function WorkerTransportClosure() { var WorkerTransport = (function WorkerTransportClosure() {
function WorkerTransport(workerInitializedCapability, pdfDataRangeTransport) { function WorkerTransport(messageHandler, loadingTask, pdfDataRangeTransport) {
this.messageHandler = messageHandler;
this.loadingTask = loadingTask;
this.pdfDataRangeTransport = pdfDataRangeTransport; this.pdfDataRangeTransport = pdfDataRangeTransport;
this.workerInitializedCapability = workerInitializedCapability;
this.commonObjs = new PDFObjects(); this.commonObjs = new PDFObjects();
this.fontLoader = new FontLoader(loadingTask.docId);
this.loadingTask = null;
this.destroyed = false; this.destroyed = false;
this.destroyCapability = null; this.destroyCapability = null;
@ -2314,56 +2639,7 @@ var WorkerTransport = (function WorkerTransportClosure() {
this.pagePromises = []; this.pagePromises = [];
this.downloadInfoCapability = createPromiseCapability(); this.downloadInfoCapability = createPromiseCapability();
// If worker support isn't disabled explicit and the browser has worker this.setupMessageHandler();
// support, create a new web worker and test if it/the browser fullfills
// all requirements to run parts of pdf.js in a web worker.
// Right now, the requirement is, that an Uint8Array is still an Uint8Array
// as it arrives on the worker. Chrome added this with version 15.
if (!globalScope.PDFJS.disableWorker && typeof Worker !== 'undefined') {
var workerSrc = PDFJS.workerSrc;
if (!workerSrc) {
error('No PDFJS.workerSrc specified');
}
try {
// Some versions of FF can't create a worker on localhost, see:
// https://bugzilla.mozilla.org/show_bug.cgi?id=683280
var worker = new Worker(workerSrc);
var messageHandler = new MessageHandler('main', worker);
this.messageHandler = messageHandler;
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);
workerInitializedCapability.resolve();
} else {
this.setupFakeWorker();
}
}.bind(this));
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, [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.');
}
}
// Either workers are disabled, not supported or have thrown an exception.
// Thus, we fallback to a faked worker.
this.setupFakeWorker();
} }
WorkerTransport.prototype = { WorkerTransport.prototype = {
destroy: function WorkerTransport_destroy() { destroy: function WorkerTransport_destroy() {
@ -2389,56 +2665,23 @@ var WorkerTransport = (function WorkerTransportClosure() {
var terminated = this.messageHandler.sendWithPromise('Terminate', null); var terminated = this.messageHandler.sendWithPromise('Terminate', null);
waitOn.push(terminated); waitOn.push(terminated);
Promise.all(waitOn).then(function () { Promise.all(waitOn).then(function () {
FontLoader.clear(); self.fontLoader.clear();
if (self.worker) {
self.worker.terminate();
}
if (self.pdfDataRangeTransport) { if (self.pdfDataRangeTransport) {
self.pdfDataRangeTransport.abort(); self.pdfDataRangeTransport.abort();
self.pdfDataRangeTransport = null; self.pdfDataRangeTransport = null;
} }
self.messageHandler = null; if (self.messageHandler) {
self.messageHandler.destroy();
self.messageHandler = null;
}
self.destroyCapability.resolve(); self.destroyCapability.resolve();
}, this.destroyCapability.reject); }, this.destroyCapability.reject);
return this.destroyCapability.promise; return this.destroyCapability.promise;
}, },
setupFakeWorker: function WorkerTransport_setupFakeWorker() {
globalScope.PDFJS.disableWorker = true;
if (!PDFJS.fakeWorkerFilesLoadedCapability) {
PDFJS.fakeWorkerFilesLoadedCapability = createPromiseCapability();
// In the developer build load worker_loader which in turn loads all the
// other files and resolves the promise. In production only the
// pdf.worker.js file is needed.
Util.loadScript(PDFJS.workerSrc, function() {
PDFJS.fakeWorkerFilesLoadedCapability.resolve();
});
}
PDFJS.fakeWorkerFilesLoadedCapability.promise.then(function () {
warn('Setting up fake worker.');
// If we don't use a worker, just post/sendMessage to the main thread.
var fakeWorker = {
postMessage: function WorkerTransport_postMessage(obj) {
fakeWorker.onmessage({data: obj});
},
terminate: function WorkerTransport_terminate() {}
};
var messageHandler = new MessageHandler('main', fakeWorker);
this.setupMessageHandler(messageHandler);
// If the main thread is our worker, setup the handling for the messages
// the main thread sends to it self.
PDFJS.WorkerMessageHandler.setup(messageHandler);
this.workerInitializedCapability.resolve();
}.bind(this));
},
setupMessageHandler: setupMessageHandler:
function WorkerTransport_setupMessageHandler(messageHandler) { function WorkerTransport_setupMessageHandler() {
this.messageHandler = messageHandler; var messageHandler = this.messageHandler;
function updatePassword(password) { function updatePassword(password) {
messageHandler.send('UpdatePassword', password); messageHandler.send('UpdatePassword', password);
@ -2578,7 +2821,7 @@ var WorkerTransport = (function WorkerTransportClosure() {
font = new FontFaceObject(exportedData); font = new FontFaceObject(exportedData);
} }
FontLoader.bind( this.fontLoader.bind(
[font], [font],
function fontReady(fontObjs) { function fontReady(fontObjs) {
this.commonObjs.resolve(id, font); this.commonObjs.resolve(id, font);
@ -2703,34 +2946,6 @@ var WorkerTransport = (function WorkerTransportClosure() {
}, this); }, this);
}, },
fetchDocument: function WorkerTransport_fetchDocument(loadingTask, source) {
if (this.destroyed) {
loadingTask._capability.reject(new Error('Loading aborted'));
this.destroyCapability.resolve();
return;
}
this.loadingTask = loadingTask;
source.disableAutoFetch = PDFJS.disableAutoFetch;
source.disableStream = PDFJS.disableStream;
source.chunkedViewerLoading = !!this.pdfDataRangeTransport;
if (this.pdfDataRangeTransport) {
source.length = this.pdfDataRangeTransport.length;
source.initialData = this.pdfDataRangeTransport.initialData;
}
this.messageHandler.send('GetDocRequest', {
source: source,
disableRange: PDFJS.disableRange,
maxImageSize: PDFJS.maxImageSize,
cMapUrl: PDFJS.cMapUrl,
cMapPacked: PDFJS.cMapPacked,
disableFontFace: PDFJS.disableFontFace,
disableCreateObjectURL: PDFJS.disableCreateObjectURL,
verbosity: PDFJS.verbosity
});
},
getData: function WorkerTransport_getData() { getData: function WorkerTransport_getData() {
return this.messageHandler.sendWithPromise('GetData', null); return this.messageHandler.sendWithPromise('GetData', null);
}, },
@ -2763,9 +2978,11 @@ var WorkerTransport = (function WorkerTransportClosure() {
return this.messageHandler.sendWithPromise('GetPageIndex', { ref: ref }); return this.messageHandler.sendWithPromise('GetPageIndex', { ref: ref });
}, },
getAnnotations: function WorkerTransport_getAnnotations(pageIndex) { getAnnotations: function WorkerTransport_getAnnotations(pageIndex, intent) {
return this.messageHandler.sendWithPromise('GetAnnotations', return this.messageHandler.sendWithPromise('GetAnnotations', {
{ pageIndex: pageIndex }); pageIndex: pageIndex,
intent: intent,
});
}, },
getDestinations: function WorkerTransport_getDestinations() { getDestinations: function WorkerTransport_getDestinations() {
@ -2773,7 +2990,7 @@ var WorkerTransport = (function WorkerTransportClosure() {
}, },
getDestination: function WorkerTransport_getDestination(id) { getDestination: function WorkerTransport_getDestination(id) {
return this.messageHandler.sendWithPromise('GetDestination', { id: id } ); return this.messageHandler.sendWithPromise('GetDestination', { id: id });
}, },
getAttachments: function WorkerTransport_getAttachments() { getAttachments: function WorkerTransport_getAttachments() {
@ -2812,7 +3029,7 @@ var WorkerTransport = (function WorkerTransportClosure() {
} }
} }
this.commonObjs.clear(); this.commonObjs.clear();
FontLoader.clear(); this.fontLoader.clear();
}.bind(this)); }.bind(this));
} }
}; };
@ -6161,12 +6378,16 @@ var TilingPattern = (function TilingPatternClosure() {
PDFJS.disableFontFace = false; PDFJS.disableFontFace = false;
var FontLoader = { function FontLoader(docId) {
this.docId = docId;
this.styleElement = null;
}
FontLoader.prototype = {
insertRule: function fontLoaderInsertRule(rule) { insertRule: function fontLoaderInsertRule(rule) {
var styleElement = document.getElementById('PDFJS_FONT_STYLE_TAG'); var styleElement = this.styleElement;
if (!styleElement) { if (!styleElement) {
styleElement = document.createElement('style'); styleElement = this.styleElement = document.createElement('style');
styleElement.id = 'PDFJS_FONT_STYLE_TAG'; styleElement.id = 'PDFJS_FONT_STYLE_TAG_' + this.docId;
document.documentElement.getElementsByTagName('head')[0].appendChild( document.documentElement.getElementsByTagName('head')[0].appendChild(
styleElement); styleElement);
} }
@ -6176,7 +6397,7 @@ var FontLoader = {
}, },
clear: function fontLoaderClear() { clear: function fontLoaderClear() {
var styleElement = document.getElementById('PDFJS_FONT_STYLE_TAG'); var styleElement = this.styleElement;
if (styleElement) { if (styleElement) {
styleElement.parentNode.removeChild(styleElement); styleElement.parentNode.removeChild(styleElement);
} }
@ -6191,7 +6412,10 @@ var FontLoader = {
} }
font.attached = true; font.attached = true;
font.bindDOM() var rule = font.createFontFaceRule();
if (rule) {
this.insertRule(rule);
}
} }
setTimeout(callback); setTimeout(callback);
@ -6199,20 +6423,31 @@ var FontLoader = {
}; };
var FontFaceObject = (function FontFaceObjectClosure() { var FontFaceObject = (function FontFaceObjectClosure() {
function FontFaceObject(name, file, properties) { function FontFaceObject(translatedData) {
this.compiledGlyphs = {}; this.compiledGlyphs = {};
if (arguments.length === 1) { // importing translated data
// importing translated data for (var i in translatedData) {
var data = arguments[0]; this[i] = translatedData[i];
for (var i in data) {
this[i] = data[i];
}
return;
} }
} }
Object.defineProperty(FontFaceObject, 'isEvalSupported', {
get: function () {
var evalSupport = false;
if (PDFJS.isEvalSupported) {
try {
/* jshint evil: true */
new Function('');
evalSupport = true;
} catch (e) {}
}
return shadow(this, 'isEvalSupported', evalSupport);
},
enumerable: true,
configurable: true
});
FontFaceObject.prototype = { FontFaceObject.prototype = {
bindDOM: function FontFaceObject_bindDOM() { createFontFaceRule: function FontFaceObject_createFontFaceRule() {
if (!this.data) { if (!this.data) {
return null; return null;
} }
@ -6229,7 +6464,6 @@ var FontFaceObject = (function FontFaceObjectClosure() {
var url = ('url(data:' + this.mimetype + ';base64,' + var url = ('url(data:' + this.mimetype + ';base64,' +
window.btoa(data) + ');'); window.btoa(data) + ');');
var rule = '@font-face { font-family:"' + fontName + '";src:' + url + '}'; var rule = '@font-face { font-family:"' + fontName + '";src:' + url + '}';
FontLoader.insertRule(rule);
if (PDFJS.pdfBug && 'FontInspector' in globalScope && if (PDFJS.pdfBug && 'FontInspector' in globalScope &&
globalScope['FontInspector'].enabled) { globalScope['FontInspector'].enabled) {
@ -6239,13 +6473,14 @@ var FontFaceObject = (function FontFaceObjectClosure() {
return rule; return rule;
}, },
getPathGenerator: function FontLoader_getPathGenerator(objs, character) { getPathGenerator:
function FontFaceObject_getPathGenerator(objs, character) {
if (!(character in this.compiledGlyphs)) { if (!(character in this.compiledGlyphs)) {
var cmds = objs.get(this.loadedName + '_path_' + character); var cmds = objs.get(this.loadedName + '_path_' + character);
var current, i, len; var current, i, len;
// If we can, compile cmds into JS for MAXIMUM SPEED // If we can, compile cmds into JS for MAXIMUM SPEED
if (FontLoader.isEvalSupported) { if (FontFaceObject.isEvalSupported) {
var args, js = ''; var args, js = '';
for (i = 0, len = cmds.length; i < len; i++) { for (i = 0, len = cmds.length; i < len; i++) {
current = cmds[i]; current = cmds[i];

Просмотреть файл

@ -20,8 +20,8 @@ if (typeof PDFJS === 'undefined') {
(typeof window !== 'undefined' ? window : this).PDFJS = {}; (typeof window !== 'undefined' ? window : this).PDFJS = {};
} }
PDFJS.version = '1.3.14'; PDFJS.version = '1.3.42';
PDFJS.build = 'df46b64'; PDFJS.build = '84a47f8';
(function pdfjsWrapper() { (function pdfjsWrapper() {
// Use strict in our context only - users might not want it // Use strict in our context only - users might not want it
@ -60,6 +60,19 @@ var AnnotationType = {
LINK: 3 LINK: 3
}; };
var AnnotationFlag = {
INVISIBLE: 0x01,
HIDDEN: 0x02,
PRINT: 0x04,
NOZOOM: 0x08,
NOROTATE: 0x10,
NOVIEW: 0x20,
READONLY: 0x40,
LOCKED: 0x80,
TOGGLENOVIEW: 0x100,
LOCKEDCONTENTS: 0x200
};
var AnnotationBorderStyleType = { var AnnotationBorderStyleType = {
SOLID: 1, SOLID: 1,
DASHED: 2, DASHED: 2,
@ -1186,26 +1199,20 @@ PDFJS.createObjectURL = (function createObjectURLClosure() {
}; };
})(); })();
function MessageHandler(name, comObj) { function MessageHandler(sourceName, targetName, comObj) {
this.name = name; this.sourceName = sourceName;
this.targetName = targetName;
this.comObj = comObj; this.comObj = comObj;
this.callbackIndex = 1; this.callbackIndex = 1;
this.postMessageTransfers = true; this.postMessageTransfers = true;
var callbacksCapabilities = this.callbacksCapabilities = {}; var callbacksCapabilities = this.callbacksCapabilities = {};
var ah = this.actionHandler = {}; var ah = this.actionHandler = {};
ah['console_log'] = [function ahConsoleLog(data) { this._onComObjOnMessage = function messageHandlerComObjOnMessage(event) {
console.log.apply(console, data);
}];
ah['console_error'] = [function ahConsoleError(data) {
console.error.apply(console, data);
}];
ah['_unsupported_feature'] = [function ah_unsupportedFeature(data) {
UnsupportedManager.notify(data);
}];
comObj.onmessage = function messageHandlerComObjOnMessage(event) {
var data = event.data; var data = event.data;
if (data.targetName !== this.sourceName) {
return;
}
if (data.isReply) { if (data.isReply) {
var callbackId = data.callbackId; var callbackId = data.callbackId;
if (data.callbackId in callbacksCapabilities) { if (data.callbackId in callbacksCapabilities) {
@ -1222,10 +1229,14 @@ function MessageHandler(name, comObj) {
} else if (data.action in ah) { } else if (data.action in ah) {
var action = ah[data.action]; var action = ah[data.action];
if (data.callbackId) { if (data.callbackId) {
var sourceName = this.sourceName;
var targetName = data.sourceName;
Promise.resolve().then(function () { Promise.resolve().then(function () {
return action[0].call(action[1], data.data); return action[0].call(action[1], data.data);
}).then(function (result) { }).then(function (result) {
comObj.postMessage({ comObj.postMessage({
sourceName: sourceName,
targetName: targetName,
isReply: true, isReply: true,
callbackId: data.callbackId, callbackId: data.callbackId,
data: result data: result
@ -1236,6 +1247,8 @@ function MessageHandler(name, comObj) {
reason = reason + ''; reason = reason + '';
} }
comObj.postMessage({ comObj.postMessage({
sourceName: sourceName,
targetName: targetName,
isReply: true, isReply: true,
callbackId: data.callbackId, callbackId: data.callbackId,
error: reason error: reason
@ -1247,7 +1260,8 @@ function MessageHandler(name, comObj) {
} else { } else {
error('Unknown action from worker: ' + data.action); error('Unknown action from worker: ' + data.action);
} }
}; }.bind(this);
comObj.addEventListener('message', this._onComObjOnMessage);
} }
MessageHandler.prototype = { MessageHandler.prototype = {
@ -1266,6 +1280,8 @@ MessageHandler.prototype = {
*/ */
send: function messageHandlerSend(actionName, data, transfers) { send: function messageHandlerSend(actionName, data, transfers) {
var message = { var message = {
sourceName: this.sourceName,
targetName: this.targetName,
action: actionName, action: actionName,
data: data data: data
}; };
@ -1283,6 +1299,8 @@ MessageHandler.prototype = {
function messageHandlerSendWithPromise(actionName, data, transfers) { function messageHandlerSendWithPromise(actionName, data, transfers) {
var callbackId = this.callbackIndex++; var callbackId = this.callbackIndex++;
var message = { var message = {
sourceName: this.sourceName,
targetName: this.targetName,
action: actionName, action: actionName,
data: data, data: data,
callbackId: callbackId callbackId: callbackId
@ -1308,6 +1326,10 @@ MessageHandler.prototype = {
} else { } else {
this.comObj.postMessage(message); this.comObj.postMessage(message);
} }
},
destroy: function () {
this.comObj.removeEventListener('message', this._onComObjOnMessage);
} }
}; };
@ -1861,6 +1883,10 @@ var BasePdfManager = (function BasePdfManagerClosure() {
} }
BasePdfManager.prototype = { BasePdfManager.prototype = {
get docId() {
return this._docId;
},
onLoadedStream: function BasePdfManager_onLoadedStream() { onLoadedStream: function BasePdfManager_onLoadedStream() {
throw new NotImplementedException(); throw new NotImplementedException();
}, },
@ -1922,7 +1948,8 @@ var BasePdfManager = (function BasePdfManagerClosure() {
})(); })();
var LocalPdfManager = (function LocalPdfManagerClosure() { var LocalPdfManager = (function LocalPdfManagerClosure() {
function LocalPdfManager(data, password) { function LocalPdfManager(docId, data, password) {
this._docId = docId;
var stream = new Stream(data); var stream = new Stream(data);
this.pdfDocument = new PDFDocument(this, stream, password); this.pdfDocument = new PDFDocument(this, stream, password);
this._loadedStreamCapability = createPromiseCapability(); this._loadedStreamCapability = createPromiseCapability();
@ -1973,8 +2000,8 @@ var LocalPdfManager = (function LocalPdfManagerClosure() {
})(); })();
var NetworkPdfManager = (function NetworkPdfManagerClosure() { var NetworkPdfManager = (function NetworkPdfManagerClosure() {
function NetworkPdfManager(args, msgHandler) { function NetworkPdfManager(docId, args, msgHandler) {
this._docId = docId;
this.msgHandler = msgHandler; this.msgHandler = msgHandler;
var params = { var params = {
@ -2251,7 +2278,8 @@ var Page = (function PageClosure() {
}); });
}, },
extractTextContent: function Page_extractTextContent(task) { extractTextContent: function Page_extractTextContent(task,
normalizeWhitespace) {
var handler = { var handler = {
on: function nullHandlerOn() {}, on: function nullHandlerOn() {},
send: function nullHandlerSend() {} send: function nullHandlerSend() {}
@ -2281,14 +2309,22 @@ var Page = (function PageClosure() {
return partialEvaluator.getTextContent(contentStream, return partialEvaluator.getTextContent(contentStream,
task, task,
self.resources); self.resources,
/* stateManager = */ null,
normalizeWhitespace);
}); });
}, },
getAnnotationsData: function Page_getAnnotationsData() { getAnnotationsData: function Page_getAnnotationsData(intent) {
var annotations = this.annotations; var annotations = this.annotations;
var annotationsData = []; var annotationsData = [];
for (var i = 0, n = annotations.length; i < n; ++i) { for (var i = 0, n = annotations.length; i < n; ++i) {
if (intent) {
if (!(intent === 'display' && annotations[i].viewable) &&
!(intent === 'print' && annotations[i].printable)) {
continue;
}
}
annotationsData.push(annotations[i].data); annotationsData.push(annotations[i].data);
} }
return annotationsData; return annotationsData;
@ -2301,8 +2337,7 @@ var Page = (function PageClosure() {
for (var i = 0, n = annotationRefs.length; i < n; ++i) { for (var i = 0, n = annotationRefs.length; i < n; ++i) {
var annotationRef = annotationRefs[i]; var annotationRef = annotationRefs[i];
var annotation = annotationFactory.create(this.xref, annotationRef); var annotation = annotationFactory.create(this.xref, annotationRef);
if (annotation && if (annotation) {
(annotation.isViewable() || annotation.isPrintable())) {
annotations.push(annotation); annotations.push(annotation);
} }
} }
@ -4511,7 +4546,9 @@ var Annotation = (function AnnotationClosure() {
var data = this.data = {}; var data = this.data = {};
data.subtype = dict.get('Subtype').name; data.subtype = dict.get('Subtype').name;
data.annotationFlags = dict.get('F');
this.setFlags(dict.get('F'));
data.annotationFlags = this.flags;
this.setRectangle(dict.get('Rect')); this.setRectangle(dict.get('Rect'));
data.rect = this.rectangle; data.rect = this.rectangle;
@ -4528,6 +4565,64 @@ var Annotation = (function AnnotationClosure() {
} }
Annotation.prototype = { Annotation.prototype = {
/**
* @return {boolean}
*/
get viewable() {
if (this.flags) {
return !this.hasFlag(AnnotationFlag.INVISIBLE) &&
!this.hasFlag(AnnotationFlag.HIDDEN) &&
!this.hasFlag(AnnotationFlag.NOVIEW);
}
return true;
},
/**
* @return {boolean}
*/
get printable() {
if (this.flags) {
return this.hasFlag(AnnotationFlag.PRINT) &&
!this.hasFlag(AnnotationFlag.INVISIBLE) &&
!this.hasFlag(AnnotationFlag.HIDDEN);
}
return false;
},
/**
* Set the flags.
*
* @public
* @memberof Annotation
* @param {number} flags - Unsigned 32-bit integer specifying annotation
* characteristics
* @see {@link shared/util.js}
*/
setFlags: function Annotation_setFlags(flags) {
if (isInt(flags)) {
this.flags = flags;
} else {
this.flags = 0;
}
},
/**
* Check if a provided flag is set.
*
* @public
* @memberof Annotation
* @param {number} flag - Hexadecimal representation for an annotation
* characteristic
* @return {boolean}
* @see {@link shared/util.js}
*/
hasFlag: function Annotation_hasFlag(flag) {
if (this.flags) {
return (this.flags & flag) > 0;
}
return false;
},
/** /**
* Set the rectangle. * Set the rectangle.
* *
@ -4627,32 +4722,6 @@ var Annotation = (function AnnotationClosure() {
} }
}, },
isInvisible: function Annotation_isInvisible() {
var data = this.data;
return !!(data &&
data.annotationFlags && // Default: not invisible
data.annotationFlags & 0x1); // Invisible
},
isViewable: function Annotation_isViewable() {
var data = this.data;
return !!(!this.isInvisible() &&
data &&
(!data.annotationFlags ||
!(data.annotationFlags & 0x22)) && // Hidden or NoView
data.rect); // rectangle is necessary
},
isPrintable: function Annotation_isPrintable() {
var data = this.data;
return !!(!this.isInvisible() &&
data &&
data.annotationFlags && // Default: not printable
data.annotationFlags & 0x4 && // Print
!(data.annotationFlags & 0x2) && // Hidden
data.rect); // rectangle is necessary
},
loadResources: function Annotation_loadResources(keys) { loadResources: function Annotation_loadResources(keys) {
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
this.appearance.dict.getAsync('Resources').then(function (resources) { this.appearance.dict.getAsync('Resources').then(function (resources) {
@ -4719,8 +4788,8 @@ var Annotation = (function AnnotationClosure() {
var annotationPromises = []; var annotationPromises = [];
for (var i = 0, n = annotations.length; i < n; ++i) { for (var i = 0, n = annotations.length; i < n; ++i) {
if (intent === 'display' && annotations[i].isViewable() || if (intent === 'display' && annotations[i].viewable ||
intent === 'print' && annotations[i].isPrintable()) { intent === 'print' && annotations[i].printable) {
annotationPromises.push( annotationPromises.push(
annotations[i].getOperatorList(partialEvaluator, task)); annotations[i].getOperatorList(partialEvaluator, task));
} }
@ -4896,6 +4965,12 @@ var WidgetAnnotation = (function WidgetAnnotationClosure() {
data.fieldFlags = Util.getInheritableProperty(dict, 'Ff') || 0; data.fieldFlags = Util.getInheritableProperty(dict, 'Ff') || 0;
this.fieldResources = Util.getInheritableProperty(dict, 'DR') || Dict.empty; this.fieldResources = Util.getInheritableProperty(dict, 'DR') || Dict.empty;
// Hide unsupported Widget signatures.
if (data.fieldType === 'Sig') {
warn('unimplemented annotation type: Widget signature');
this.setFlags(AnnotationFlag.HIDDEN);
}
// Building the full field name by collecting the field and // Building the full field name by collecting the field and
// its ancestors 'T' data and joining them using '.'. // its ancestors 'T' data and joining them using '.'.
var fieldName = []; var fieldName = [];
@ -4929,17 +5004,7 @@ var WidgetAnnotation = (function WidgetAnnotationClosure() {
data.fullName = fieldName.join('.'); data.fullName = fieldName.join('.');
} }
var parent = Annotation.prototype; Util.inherit(WidgetAnnotation, Annotation, {});
Util.inherit(WidgetAnnotation, Annotation, {
isViewable: function WidgetAnnotation_isViewable() {
if (this.data.fieldType === 'Sig') {
warn('unimplemented annotation type: Widget signature');
return false;
}
return parent.isViewable.call(this);
}
});
return WidgetAnnotation; return WidgetAnnotation;
})(); })();
@ -5038,7 +5103,7 @@ var LinkAnnotation = (function LinkAnnotationClosure() {
if (!isValidUrl(url, false)) { if (!isValidUrl(url, false)) {
url = ''; url = '';
} }
// According to ISO 32000-1:2008, section 12.6.4.7, // According to ISO 32000-1:2008, section 12.6.4.7,
// URI should to be encoded in 7-bit ASCII. // URI should to be encoded in 7-bit ASCII.
// Some bad PDFs may have URIs in UTF-8 encoding, see Bugzilla 1122280. // Some bad PDFs may have URIs in UTF-8 encoding, see Bugzilla 1122280.
try { try {
@ -10562,6 +10627,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
return translated.loadType3Data(self, resources, operatorList, task). return translated.loadType3Data(self, resources, operatorList, task).
then(function () { then(function () {
return translated; return translated;
}, function (reason) {
return new TranslatedFont('g_font_error',
new ErrorFont('Type3 font load error: ' + reason), translated.font);
}); });
}).then(function (translated) { }).then(function (translated) {
state.font = translated.font; state.font = translated.font;
@ -10770,7 +10838,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
// Keep track of each font we translated so the caller can // Keep track of each font we translated so the caller can
// load them asynchronously before calling display on a page. // load them asynchronously before calling display on a page.
font.loadedName = 'g_font_' + (fontRefIsDict ? font.loadedName = 'g_' + this.pdfManager.docId + '_f' + (fontRefIsDict ?
fontName.replace(/\W/g, '') : fontID); fontName.replace(/\W/g, '') : fontID);
font.translated = fontCapability.promise; font.translated = fontCapability.promise;
@ -11149,12 +11217,15 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
}); });
}, },
getTextContent: function PartialEvaluator_getTextContent(stream, task, getTextContent:
resources, function PartialEvaluator_getTextContent(stream, task, resources,
stateManager) { stateManager,
normalizeWhitespace) {
stateManager = (stateManager || new StateManager(new TextState())); stateManager = (stateManager || new StateManager(new TextState()));
var WhitespaceRegexp = /\s/g;
var textContent = { var textContent = {
items: [], items: [],
styles: Object.create(null) styles: Object.create(null)
@ -11268,11 +11339,23 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
return textContentItem; return textContentItem;
} }
function replaceWhitespace(str) {
// Replaces all whitespaces with standard spaces (0x20), to avoid
// alignment issues between the textLayer and the canvas if the text
// contains e.g. tabs (fixes issue6612.pdf).
var i = 0, ii = str.length, code;
while (i < ii && (code = str.charCodeAt(i)) >= 0x20 && code <= 0x7F) {
i++;
}
return (i < ii ? str.replace(WhitespaceRegexp, ' ') : str);
}
function runBidiTransform(textChunk) { function runBidiTransform(textChunk) {
var str = textChunk.str.join(''); var str = textChunk.str.join('');
var bidiResult = PDFJS.bidi(str, -1, textChunk.vertical); var bidiResult = PDFJS.bidi(str, -1, textChunk.vertical);
return { return {
str: bidiResult.str, str: (normalizeWhitespace ? replaceWhitespace(bidiResult.str) :
bidiResult.str),
dir: bidiResult.dir, dir: bidiResult.dir,
width: textChunk.width, width: textChunk.width,
height: textChunk.height, height: textChunk.height,
@ -11593,8 +11676,8 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
} }
return self.getTextContent(xobj, task, return self.getTextContent(xobj, task,
xobj.dict.get('Resources') || resources, stateManager). xobj.dict.get('Resources') || resources, stateManager,
then(function (formTextContent) { normalizeWhitespace).then(function (formTextContent) {
Util.appendToArray(textContent.items, formTextContent.items); Util.appendToArray(textContent.items, formTextContent.items);
Util.extendObj(textContent.styles, formTextContent.styles); Util.extendObj(textContent.styles, formTextContent.styles);
stateManager.restore(); stateManager.restore();
@ -33837,12 +33920,51 @@ var WorkerTask = (function WorkerTaskClosure() {
})(); })();
var WorkerMessageHandler = PDFJS.WorkerMessageHandler = { var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
setup: function wphSetup(handler) { setup: function wphSetup(handler, port) {
handler.on('test', function wphSetupTest(data) {
// check if Uint8Array can be sent to worker
if (!(data instanceof Uint8Array)) {
handler.send('test', 'main', false);
return;
}
// making sure postMessage transfers are working
var supportTransfers = data[0] === 255;
handler.postMessageTransfers = supportTransfers;
// check if the response property is supported by xhr
var xhr = new XMLHttpRequest();
var responseExists = 'response' in xhr;
// check if the property is actually implemented
try {
var dummy = xhr.responseType;
} catch (e) {
responseExists = false;
}
if (!responseExists) {
handler.send('test', false);
return;
}
handler.send('test', {
supportTypedArray: true,
supportTransfers: supportTransfers
});
});
handler.on('GetDocRequest', function wphSetupDoc(data) {
return WorkerMessageHandler.createDocumentHandler(data, port);
});
},
createDocumentHandler: function wphCreateDocumentHandler(docParams, port) {
// This context is actually holds references on pdfManager and handler,
// until the latter is destroyed.
var pdfManager; var pdfManager;
var terminated = false; var terminated = false;
var cancelXHRs = null; var cancelXHRs = null;
var WorkerTasks = []; var WorkerTasks = [];
var docId = docParams.docId;
var workerHandlerName = docParams.docId + '_worker';
var handler = new MessageHandler(workerHandlerName, docId, port);
function ensureNotTerminated() { function ensureNotTerminated() {
if (terminated) { if (terminated) {
throw new Error('Worker was terminated'); throw new Error('Worker was terminated');
@ -33900,7 +34022,7 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
var disableRange = data.disableRange; var disableRange = data.disableRange;
if (source.data) { if (source.data) {
try { try {
pdfManager = new LocalPdfManager(source.data, source.password); pdfManager = new LocalPdfManager(docId, source.data, source.password);
pdfManagerCapability.resolve(pdfManager); pdfManagerCapability.resolve(pdfManager);
} catch (ex) { } catch (ex) {
pdfManagerCapability.reject(ex); pdfManagerCapability.reject(ex);
@ -33908,7 +34030,7 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
return pdfManagerCapability.promise; return pdfManagerCapability.promise;
} else if (source.chunkedViewerLoading) { } else if (source.chunkedViewerLoading) {
try { try {
pdfManager = new NetworkPdfManager(source, handler); pdfManager = new NetworkPdfManager(docId, source, handler);
pdfManagerCapability.resolve(pdfManager); pdfManagerCapability.resolve(pdfManager);
} catch (ex) { } catch (ex) {
pdfManagerCapability.reject(ex); pdfManagerCapability.reject(ex);
@ -33965,7 +34087,7 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
} }
try { try {
pdfManager = new NetworkPdfManager(source, handler); pdfManager = new NetworkPdfManager(docId, source, handler);
pdfManagerCapability.resolve(pdfManager); pdfManagerCapability.resolve(pdfManager);
} catch (ex) { } catch (ex) {
pdfManagerCapability.reject(ex); pdfManagerCapability.reject(ex);
@ -34010,7 +34132,7 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
// the data is array, instantiating directly from it // the data is array, instantiating directly from it
try { try {
pdfManager = new LocalPdfManager(pdfFile, source.password); pdfManager = new LocalPdfManager(docId, pdfFile, source.password);
pdfManagerCapability.resolve(pdfManager); pdfManagerCapability.resolve(pdfManager);
} catch (ex) { } catch (ex) {
pdfManagerCapability.reject(ex); pdfManagerCapability.reject(ex);
@ -34048,35 +34170,7 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
return pdfManagerCapability.promise; return pdfManagerCapability.promise;
} }
handler.on('test', function wphSetupTest(data) { var setupDoc = function(data) {
// check if Uint8Array can be sent to worker
if (!(data instanceof Uint8Array)) {
handler.send('test', false);
return;
}
// making sure postMessage transfers are working
var supportTransfers = data[0] === 255;
handler.postMessageTransfers = supportTransfers;
// check if the response property is supported by xhr
var xhr = new XMLHttpRequest();
var responseExists = 'response' in xhr;
// check if the property is actually implemented
try {
var dummy = xhr.responseType;
} catch (e) {
responseExists = false;
}
if (!responseExists) {
handler.send('test', false);
return;
}
handler.send('test', {
supportTypedArray: true,
supportTransfers: supportTransfers
});
});
handler.on('GetDocRequest', function wphSetupDoc(data) {
var onSuccess = function(doc) { var onSuccess = function(doc) {
ensureNotTerminated(); ensureNotTerminated();
handler.send('GetDoc', { pdfInfo: doc }); handler.send('GetDoc', { pdfInfo: doc });
@ -34121,7 +34215,6 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
} }
pdfManager = newPdfManager; pdfManager = newPdfManager;
handler.send('PDFManagerReady', null); handler.send('PDFManagerReady', null);
pdfManager.onLoadedStream().then(function(stream) { pdfManager.onLoadedStream().then(function(stream) {
handler.send('DataLoaded', { length: stream.bytes.byteLength }); handler.send('DataLoaded', { length: stream.bytes.byteLength });
@ -34152,7 +34245,7 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
}); });
}, onFailure); }, onFailure);
}, onFailure); }, onFailure);
}); };
handler.on('GetPage', function wphSetupGetPage(data) { handler.on('GetPage', function wphSetupGetPage(data) {
return pdfManager.getPage(data.pageIndex).then(function(page) { return pdfManager.getPage(data.pageIndex).then(function(page) {
@ -34185,7 +34278,7 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
handler.on('GetDestination', handler.on('GetDestination',
function wphSetupGetDestination(data) { function wphSetupGetDestination(data) {
return pdfManager.ensureCatalog('getDestination', [ data.id ]); return pdfManager.ensureCatalog('getDestination', [data.id]);
} }
); );
@ -34233,7 +34326,7 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
handler.on('GetAnnotations', function wphSetupGetAnnotations(data) { handler.on('GetAnnotations', function wphSetupGetAnnotations(data) {
return pdfManager.getPage(data.pageIndex).then(function(page) { return pdfManager.getPage(data.pageIndex).then(function(page) {
return pdfManager.ensure(page, 'getAnnotationsData', []); return pdfManager.ensure(page, 'getAnnotationsData', [data.intent]);
}); });
}); });
@ -34292,12 +34385,14 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
handler.on('GetTextContent', function wphExtractText(data) { handler.on('GetTextContent', function wphExtractText(data) {
var pageIndex = data.pageIndex; var pageIndex = data.pageIndex;
var normalizeWhitespace = data.normalizeWhitespace;
return pdfManager.getPage(pageIndex).then(function(page) { return pdfManager.getPage(pageIndex).then(function(page) {
var task = new WorkerTask('GetTextContent: page ' + pageIndex); var task = new WorkerTask('GetTextContent: page ' + pageIndex);
startWorkerTask(task); startWorkerTask(task);
var pageNum = pageIndex + 1; var pageNum = pageIndex + 1;
var start = Date.now(); var start = Date.now();
return page.extractTextContent(task).then(function(textContent) { return page.extractTextContent(task, normalizeWhitespace).then(
function(textContent) {
finishWorkerTask(task); finishWorkerTask(task);
info('text indexing: page=' + pageNum + ' - time=' + info('text indexing: page=' + pageNum + ' - time=' +
(Date.now() - start) + 'ms'); (Date.now() - start) + 'ms');
@ -34332,8 +34427,19 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
task.terminate(); task.terminate();
}); });
return Promise.all(waitOn).then(function () {}); return Promise.all(waitOn).then(function () {
// Notice that even if we destroying handler, resolved response promise
// must be sent back.
handler.destroy();
handler = null;
});
}); });
handler.on('Ready', function wphReady(data) {
setupDoc(docParams);
docParams = null; // we don't need docParams anymore -- saving memory.
});
return workerHandlerName;
} }
}; };
@ -34343,6 +34449,7 @@ var workerConsole = {
log: function log() { log: function log() {
var args = Array.prototype.slice.call(arguments); var args = Array.prototype.slice.call(arguments);
globalScope.postMessage({ globalScope.postMessage({
targetName: 'main',
action: 'console_log', action: 'console_log',
data: args data: args
}); });
@ -34351,6 +34458,7 @@ var workerConsole = {
error: function error() { error: function error() {
var args = Array.prototype.slice.call(arguments); var args = Array.prototype.slice.call(arguments);
globalScope.postMessage({ globalScope.postMessage({
targetName: 'main',
action: 'console_error', action: 'console_error',
data: args data: args
}); });
@ -34380,13 +34488,14 @@ if (typeof window === 'undefined') {
// Listen for unsupported features so we can pass them on to the main thread. // Listen for unsupported features so we can pass them on to the main thread.
PDFJS.UnsupportedManager.listen(function (msg) { PDFJS.UnsupportedManager.listen(function (msg) {
globalScope.postMessage({ globalScope.postMessage({
targetName: 'main',
action: '_unsupported_feature', action: '_unsupported_feature',
data: msg data: msg
}); });
}); });
var handler = new MessageHandler('worker_processor', this); var handler = new MessageHandler('worker', 'main', this);
WorkerMessageHandler.setup(handler); WorkerMessageHandler.setup(handler, this);
} }

Просмотреть файл

@ -12,6 +12,18 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/* globals PDFJS, PDFBug, FirefoxCom, Stats, Cache, ProgressBar,
DownloadManager, getFileName, getPDFFileNameFromURL,
PDFHistory, Preferences, SidebarView, ViewHistory, Stats,
PDFThumbnailViewer, URL, noContextMenuHandler, SecondaryToolbar,
PasswordPrompt, PDFPresentationMode, PDFDocumentProperties, HandTool,
Promise, PDFLinkService, PDFOutlineView, PDFAttachmentView,
OverlayManager, PDFFindController, PDFFindBar, PDFViewer,
PDFRenderingQueue, PresentationModeState, parseQueryString,
RenderingStates, UNKNOWN_SCALE, DEFAULT_SCALE_VALUE,
IGNORE_CURRENT_POSITION_ON_ZOOM: true */
'use strict';
var DEFAULT_URL = 'compressed.tracemonkey-pldi-09.pdf'; var DEFAULT_URL = 'compressed.tracemonkey-pldi-09.pdf';
var DEFAULT_SCALE_DELTA = 1.1; var DEFAULT_SCALE_DELTA = 1.1;
@ -1027,7 +1039,6 @@ var PDFFindController = (function PDFFindControllerClosure() {
'\u00BC': '1/4', // Vulgar fraction one quarter '\u00BC': '1/4', // Vulgar fraction one quarter
'\u00BD': '1/2', // Vulgar fraction one half '\u00BD': '1/2', // Vulgar fraction one half
'\u00BE': '3/4', // Vulgar fraction three quarters '\u00BE': '3/4', // Vulgar fraction three quarters
'\u00A0': ' ' // No-break space
}; };
this.findBar = options.findBar || null; this.findBar = options.findBar || null;
@ -3675,7 +3686,7 @@ var PDFPageView = (function PDFPageViewClosure() {
} }
if (redrawAnnotations && this.annotationLayer) { if (redrawAnnotations && this.annotationLayer) {
this.annotationLayer.setupAnnotations(this.viewport); this.annotationLayer.setupAnnotations(this.viewport, 'display');
} }
}, },
@ -3878,7 +3889,7 @@ var PDFPageView = (function PDFPageViewClosure() {
function pdfPageRenderCallback() { function pdfPageRenderCallback() {
pageViewDrawCallback(null); pageViewDrawCallback(null);
if (textLayer) { if (textLayer) {
self.pdfPage.getTextContent().then( self.pdfPage.getTextContent({ normalizeWhitespace: true }).then(
function textContentResolved(textContent) { function textContentResolved(textContent) {
textLayer.setTextContent(textContent); textLayer.setTextContent(textContent);
textLayer.render(TEXT_LAYER_RENDER_DELAY); textLayer.render(TEXT_LAYER_RENDER_DELAY);
@ -3896,7 +3907,7 @@ var PDFPageView = (function PDFPageViewClosure() {
this.annotationLayer = this.annotationsLayerFactory. this.annotationLayer = this.annotationsLayerFactory.
createAnnotationsLayerBuilder(div, this.pdfPage); createAnnotationsLayerBuilder(div, this.pdfPage);
} }
this.annotationLayer.setupAnnotations(this.viewport); this.annotationLayer.setupAnnotations(this.viewport, 'display');
} }
div.setAttribute('data-loaded', true); div.setAttribute('data-loaded', true);
@ -4313,9 +4324,10 @@ var AnnotationsLayerBuilder = (function AnnotationsLayerBuilderClosure() {
/** /**
* @param {PageViewport} viewport * @param {PageViewport} viewport
* @param {string} intent (default value is 'display')
*/ */
setupAnnotations: setupAnnotations:
function AnnotationsLayerBuilder_setupAnnotations(viewport) { function AnnotationsLayerBuilder_setupAnnotations(viewport, intent) {
function bindLink(link, dest) { function bindLink(link, dest) {
link.href = linkService.getDestinationHash(dest); link.href = linkService.getDestinationHash(dest);
link.onclick = function annotationsLayerBuilderLinksOnclick() { link.onclick = function annotationsLayerBuilderLinksOnclick() {
@ -4341,8 +4353,12 @@ var AnnotationsLayerBuilder = (function AnnotationsLayerBuilderClosure() {
var linkService = this.linkService; var linkService = this.linkService;
var pdfPage = this.pdfPage; var pdfPage = this.pdfPage;
var self = this; var self = this;
var getAnnotationsParams = {
intent: (intent === undefined ? 'display' : intent),
};
pdfPage.getAnnotations().then(function (annotationsData) { pdfPage.getAnnotations(getAnnotationsParams).then(
function (annotationsData) {
viewport = viewport.clone({ dontFlip: true }); viewport = viewport.clone({ dontFlip: true });
var transform = viewport.transform; var transform = viewport.transform;
var transformStr = 'matrix(' + transform.join(',') + ')'; var transformStr = 'matrix(' + transform.join(',') + ')';
@ -4882,7 +4898,7 @@ var PDFViewer = (function pdfViewer() {
if (!this.pdfDocument) { if (!this.pdfDocument) {
return; return;
} }
var pageView = this._pages[pageNumber - 1]; var pageView = this._pages[pageNumber - 1];
if (this.isInPresentationMode) { if (this.isInPresentationMode) {
@ -5140,7 +5156,7 @@ var PDFViewer = (function pdfViewer() {
getPageTextContent: function (pageIndex) { getPageTextContent: function (pageIndex) {
return this.pdfDocument.getPage(pageIndex + 1).then(function (page) { return this.pdfDocument.getPage(pageIndex + 1).then(function (page) {
return page.getTextContent(); return page.getTextContent({ normalizeWhitespace: true });
}); });
}, },
@ -7389,7 +7405,7 @@ document.addEventListener('textlayerrendered', function (e) {
if (pageView.textLayer && pageView.textLayer.textDivs && if (pageView.textLayer && pageView.textLayer.textDivs &&
pageView.textLayer.textDivs.length > 0 && pageView.textLayer.textDivs.length > 0 &&
!PDFViewerApplication.supportsDocumentColors) { !PDFViewerApplication.supportsDocumentColors) {
console.error(mozL10n.get('document_colors_disabled', null, console.error(mozL10n.get('document_colors_not_allowed', null,
'PDF documents are not allowed to use their own colors: ' + 'PDF documents are not allowed to use their own colors: ' +
'\'Allow pages to choose their own colors\' ' + '\'Allow pages to choose their own colors\' ' +
'is deactivated in the browser.')); 'is deactivated in the browser.'));

Просмотреть файл

@ -170,4 +170,4 @@ password_cancel=Cancel
printing_not_supported=Warning: Printing is not fully supported by this browser. printing_not_supported=Warning: Printing is not fully supported by this browser.
printing_not_ready=Warning: The PDF is not fully loaded for printing. printing_not_ready=Warning: The PDF is not fully loaded for printing.
web_fonts_disabled=Web fonts are disabled: unable to use embedded PDF fonts. web_fonts_disabled=Web fonts are disabled: unable to use embedded PDF fonts.
document_colors_disabled=PDF documents are not allowed to use their own colors: \'Allow pages to choose their own colors\' is deactivated in the browser. document_colors_not_allowed=PDF documents are not allowed to use their own colors: 'Allow pages to choose their own colors' is deactivated in the browser.