Adds destroy method to the document loading task.

Also renames PDFPageProxy.destroy method to cleanup.
This commit is contained in:
Yury Delendik 2015-10-20 17:45:55 -05:00
parent ef85685803
commit 59c13b32aa
10 changed files with 243 additions and 78 deletions

View file

@ -265,6 +265,9 @@ PDFJS.getDocument = function getDocument(src,
pdfDataRangeTransport = Object.create(pdfDataRangeTransport);
pdfDataRangeTransport.length = src.length;
pdfDataRangeTransport.initialData = src.initialData;
if (!pdfDataRangeTransport.abort) {
pdfDataRangeTransport.abort = function () {};
}
}
src = Object.create(src);
src.range = pdfDataRangeTransport;
@ -324,6 +327,7 @@ PDFJS.getDocument = function getDocument(src,
workerInitializedCapability.promise.then(function transportInitialized() {
transport.fetchDocument(task, params);
});
task._transport = transport;
return task;
};
@ -336,6 +340,7 @@ var PDFDocumentLoadingTask = (function PDFDocumentLoadingTaskClosure() {
/** @constructs PDFDocumentLoadingTask */
function PDFDocumentLoadingTask() {
this._capability = createPromiseCapability();
this._transport = null;
/**
* Callback to request a password if wrong or no password was provided.
@ -361,7 +366,14 @@ var PDFDocumentLoadingTask = (function PDFDocumentLoadingTaskClosure() {
return this._capability.promise;
},
// TODO add cancel or abort method
/**
* Aborts all network requests and destroys worker.
* @return {Promise} A promise that is resolved after destruction activity
* is completed.
*/
destroy: function () {
return this._transport.destroy();
},
/**
* Registers callbacks to indicate the document loading completion.
@ -448,6 +460,9 @@ var PDFDataRangeTransport = (function pdfDataRangeTransportClosure() {
requestDataRange:
function PDFDataRangeTransport_requestDataRange(begin, end) {
throw new Error('Abstract method PDFDataRangeTransport.requestDataRange');
},
abort: function PDFDataRangeTransport_abort() {
}
};
return PDFDataRangeTransport;
@ -461,9 +476,10 @@ PDFJS.PDFDataRangeTransport = PDFDataRangeTransport;
* @class
*/
var PDFDocumentProxy = (function PDFDocumentProxyClosure() {
function PDFDocumentProxy(pdfInfo, transport) {
function PDFDocumentProxy(pdfInfo, transport, loadingTask) {
this.pdfInfo = pdfInfo;
this.transport = transport;
this.loadingTask = loadingTask;
}
PDFDocumentProxy.prototype = /** @lends PDFDocumentProxy.prototype */ {
/**
@ -586,7 +602,7 @@ var PDFDocumentProxy = (function PDFDocumentProxyClosure() {
* Destroys current document instance and terminates worker.
*/
destroy: function PDFDocumentProxy_destroy() {
this.transport.destroy();
return this.transport.destroy();
}
};
return PDFDocumentProxy;
@ -663,8 +679,9 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
this.commonObjs = transport.commonObjs;
this.objs = new PDFObjects();
this.cleanupAfterRender = false;
this.pendingDestroy = false;
this.pendingCleanup = false;
this.intentStates = {};
this.destroyed = false;
}
PDFPageProxy.prototype = /** @lends PDFPageProxy.prototype */ {
/**
@ -728,7 +745,7 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
// If there was a pending destroy cancel it so no cleanup happens during
// this call to render.
this.pendingDestroy = false;
this.pendingCleanup = false;
var renderingIntent = (params.intent === 'print' ? 'print' : 'display');
@ -775,7 +792,7 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
var self = this;
intentState.displayReadyCapability.promise.then(
function pageDisplayReadyPromise(transparency) {
if (self.pendingDestroy) {
if (self.pendingCleanup) {
complete();
return;
}
@ -795,9 +812,9 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
}
if (self.cleanupAfterRender) {
self.pendingDestroy = true;
self.pendingCleanup = true;
}
self._tryDestroy();
self._tryCleanup();
if (error) {
internalRenderTask.capability.reject(error);
@ -858,20 +875,47 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
pageIndex: this.pageNumber - 1
});
},
/**
* Destroys resources allocated by the page.
* Destroys page object.
*/
destroy: function PDFPageProxy_destroy() {
this.pendingDestroy = true;
this._tryDestroy();
_destroy: function PDFPageProxy_destroy() {
this.destroyed = true;
this.transport.pageCache[this.pageIndex] = null;
Object.keys(this.intentStates).forEach(function(intent) {
var intentState = this.intentStates[intent];
intentState.renderTasks.forEach(function(renderTask) {
renderTask.cancel();
});
}, this);
this.objs.clear();
this.annotationsPromise = null;
this.pendingCleanup = false;
},
/**
* Cleans up resources allocated by the page.
* Deprecated, use cleanup() instead.
*/
destroy: function() {
this.cleanup();
},
/**
* Cleans up resources allocated by the page.
*/
cleanup: function PDFPageProxy_cleanup() {
this.pendingCleanup = true;
this._tryCleanup();
},
/**
* For internal use only. Attempts to clean up if rendering is in a state
* where that's possible.
* @ignore
*/
_tryDestroy: function PDFPageProxy__destroy() {
if (!this.pendingDestroy ||
_tryCleanup: function PDFPageProxy_tryCleanup() {
if (!this.pendingCleanup ||
Object.keys(this.intentStates).some(function(intent) {
var intentState = this.intentStates[intent];
return (intentState.renderTasks.length !== 0 ||
@ -885,7 +929,7 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
}, this);
this.objs.clear();
this.annotationsPromise = null;
this.pendingDestroy = false;
this.pendingCleanup = false;
},
/**
* For internal use only.
@ -923,7 +967,7 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
if (operatorListChunk.lastChunk) {
intentState.receivingOperatorList = false;
this._tryDestroy();
this._tryCleanup();
}
}
};
@ -941,6 +985,8 @@ var WorkerTransport = (function WorkerTransportClosure() {
this.commonObjs = new PDFObjects();
this.loadingTask = null;
this.destroyed = false;
this.destroyCapability = null;
this.pageCache = [];
this.pagePromises = [];
@ -1001,6 +1047,18 @@ var WorkerTransport = (function WorkerTransportClosure() {
}
WorkerTransport.prototype = {
destroy: function WorkerTransport_destroy() {
if (this.destroyCapability) {
return this.destroyCapability.promise;
}
this.destroyed = true;
this.destroyCapability = createPromiseCapability();
this.pageCache.forEach(function (page) {
if (page) {
page._destroy();
}
});
this.pageCache = [];
this.pagePromises = [];
var self = this;
@ -1009,7 +1067,14 @@ var WorkerTransport = (function WorkerTransportClosure() {
if (self.worker) {
self.worker.terminate();
}
});
if (self.pdfDataRangeTransport) {
self.pdfDataRangeTransport.abort();
self.pdfDataRangeTransport = null;
}
self.messageHandler = null;
self.destroyCapability.resolve();
}, this.destroyCapability.reject);
return this.destroyCapability.promise;
},
setupFakeWorker: function WorkerTransport_setupFakeWorker() {
@ -1091,9 +1156,10 @@ var WorkerTransport = (function WorkerTransportClosure() {
messageHandler.on('GetDoc', function transportDoc(data) {
var pdfInfo = data.pdfInfo;
this.numPages = data.pdfInfo.numPages;
var pdfDocument = new PDFDocumentProxy(pdfInfo, this);
var loadingTask = this.loadingTask;
var pdfDocument = new PDFDocumentProxy(pdfInfo, this, loadingTask);
this.pdfDocument = pdfDocument;
this.loadingTask._capability.resolve(pdfDocument);
loadingTask._capability.resolve(pdfDocument);
}, this);
messageHandler.on('NeedPassword',
@ -1294,6 +1360,12 @@ var WorkerTransport = (function WorkerTransportClosure() {
},
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;
@ -1332,6 +1404,9 @@ var WorkerTransport = (function WorkerTransportClosure() {
var promise = this.messageHandler.sendWithPromise('GetPage', {
pageIndex: pageIndex
}).then(function (pageInfo) {
if (this.destroyed) {
throw new Error('Transport destroyed');
}
var page = new PDFPageProxy(pageIndex, pageInfo, this);
this.pageCache[pageIndex] = page;
return page;
@ -1389,7 +1464,7 @@ var WorkerTransport = (function WorkerTransportClosure() {
for (var i = 0, ii = this.pageCache.length; i < ii; i++) {
var page = this.pageCache[i];
if (page) {
page.destroy();
page.cleanup();
}
}
this.commonObjs.clear();