Convert PDFPageProxy, in src/display/api.js, to an ES6 class

This changes all occurrences of `var` to `let`/`const` in this code, and updates the signatures of a couple of methods to use object destructuring.
Finally, when creating `InternalRenderTask` instances *only* the necessary parameter are now provided, since passing through the `RenderParameters` as-is seems completely unnecessary.
This commit is contained in:
Jonas Jenwald 2018-11-08 14:13:42 +01:00
parent 2c003a82d5
commit 5a0d64a6de

View File

@ -850,56 +850,60 @@ class PDFDocumentProxy {
/** /**
* Proxy to a PDFPage in the worker thread. * Proxy to a PDFPage in the worker thread.
* @class
* @alias PDFPageProxy * @alias PDFPageProxy
*/ */
var PDFPageProxy = (function PDFPageProxyClosure() { class PDFPageProxy {
function PDFPageProxy(pageIndex, pageInfo, transport, pdfBug = false) { constructor(pageIndex, pageInfo, transport, pdfBug = false) {
this.pageIndex = pageIndex; this.pageIndex = pageIndex;
this._pageInfo = pageInfo; this._pageInfo = pageInfo;
this.transport = transport; this._transport = transport;
this._stats = (pdfBug ? new StatTimer() : DummyStatTimer); this._stats = (pdfBug ? new StatTimer() : DummyStatTimer);
this._pdfBug = pdfBug; this._pdfBug = pdfBug;
this.commonObjs = transport.commonObjs; this.commonObjs = transport.commonObjs;
this.objs = new PDFObjects(); this.objs = new PDFObjects();
this.cleanupAfterRender = false; this.cleanupAfterRender = false;
this.pendingCleanup = false; this.pendingCleanup = false;
this.intentStates = Object.create(null); this.intentStates = Object.create(null);
this.destroyed = false; this.destroyed = false;
} }
PDFPageProxy.prototype = /** @lends PDFPageProxy.prototype */ {
/** /**
* @return {number} Page number of the page. First page is 1. * @return {number} Page number of the page. First page is 1.
*/ */
get pageNumber() { get pageNumber() {
return this.pageIndex + 1; return this.pageIndex + 1;
}, }
/** /**
* @return {number} The number of degrees the page is rotated clockwise. * @return {number} The number of degrees the page is rotated clockwise.
*/ */
get rotate() { get rotate() {
return this._pageInfo.rotate; return this._pageInfo.rotate;
}, }
/** /**
* @return {Object} The reference that points to this page. It has 'num' and * @return {Object} The reference that points to this page. It has 'num' and
* 'gen' properties. * 'gen' properties.
*/ */
get ref() { get ref() {
return this._pageInfo.ref; return this._pageInfo.ref;
}, }
/** /**
* @return {number} The default size of units in 1/72nds of an inch. * @return {number} The default size of units in 1/72nds of an inch.
*/ */
get userUnit() { get userUnit() {
return this._pageInfo.userUnit; return this._pageInfo.userUnit;
}, }
/** /**
* @return {Array} An array of the visible portion of the PDF page in the * @return {Array} An array of the visible portion of the PDF page in the
* user space units - [x1, y1, x2, y2]. * user space units - [x1, y1, x2, y2].
*/ */
get view() { get view() {
return this._pageInfo.view; return this._pageInfo.view;
}, }
/** /**
* @param {number} scale The desired scale of the viewport. * @param {number} scale The desired scale of the viewport.
@ -916,46 +920,48 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
rotation: rotate, rotation: rotate,
dontFlip, dontFlip,
}); });
}, }
/** /**
* @param {GetAnnotationsParameters} params - Annotation parameters. * @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(params) { getAnnotations({ intent = null, } = {}) {
var intent = (params && params.intent) || null;
if (!this.annotationsPromise || this.annotationsIntent !== intent) { if (!this.annotationsPromise || this.annotationsIntent !== intent) {
this.annotationsPromise = this.transport.getAnnotations(this.pageIndex, this.annotationsPromise = this._transport.getAnnotations(this.pageIndex,
intent); intent);
this.annotationsIntent = intent; this.annotationsIntent = intent;
} }
return this.annotationsPromise; return this.annotationsPromise;
}, }
/** /**
* Begins the process of rendering a page to the desired context. * Begins the process of rendering a page to the desired context.
* @param {RenderParameters} params Page render parameters. * @param {RenderParameters} params Page render parameters.
* @return {RenderTask} An object that contains the promise, which * @return {RenderTask} An object that contains the promise, which
* is resolved when the page finishes rendering. * is resolved when the page finishes rendering.
*/ */
render: function PDFPageProxy_render(params) { render({ canvasContext, viewport, intent = 'display', enableWebGL = false,
let stats = this._stats; renderInteractiveForms = false, transform = null, imageLayer = null,
canvasFactory = null, background = null, }) {
const stats = this._stats;
stats.time('Overall'); stats.time('Overall');
// If there was a pending destroy cancel it so no cleanup happens during // If there was a pending destroy cancel it so no cleanup happens during
// this call to render. // this call to render.
this.pendingCleanup = false; this.pendingCleanup = false;
var renderingIntent = (params.intent === 'print' ? 'print' : 'display'); const renderingIntent = (intent === 'print' ? 'print' : 'display');
var canvasFactory = params.canvasFactory || new DOMCanvasFactory(); const canvasFactoryInstance = canvasFactory || new DOMCanvasFactory();
let webGLContext = new WebGLContext({ const webGLContext = new WebGLContext({
enable: params.enableWebGL, enable: enableWebGL,
}); });
if (!this.intentStates[renderingIntent]) { if (!this.intentStates[renderingIntent]) {
this.intentStates[renderingIntent] = Object.create(null); this.intentStates[renderingIntent] = Object.create(null);
} }
var intentState = this.intentStates[renderingIntent]; const intentState = this.intentStates[renderingIntent];
// If there's no displayReadyCapability yet, then the operatorList // If there's no displayReadyCapability yet, then the operatorList
// was never requested before. Make the request and create the promise. // was never requested before. Make the request and create the promise.
@ -969,15 +975,15 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
}; };
stats.time('Page Request'); stats.time('Page Request');
this.transport.messageHandler.send('RenderPageRequest', { this._transport.messageHandler.send('RenderPageRequest', {
pageIndex: this.pageNumber - 1, pageIndex: this.pageNumber - 1,
intent: renderingIntent, intent: renderingIntent,
renderInteractiveForms: (params.renderInteractiveForms === true), renderInteractiveForms: renderInteractiveForms === true,
}); });
} }
var complete = (error) => { const complete = (error) => {
var i = intentState.renderTasks.indexOf(internalRenderTask); const i = intentState.renderTasks.indexOf(internalRenderTask);
if (i >= 0) { if (i >= 0) {
intentState.renderTasks.splice(i, 1); intentState.renderTasks.splice(i, 1);
} }
@ -996,12 +1002,18 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
stats.timeEnd('Overall'); stats.timeEnd('Overall');
}; };
var internalRenderTask = new InternalRenderTask(complete, params, const internalRenderTask = new InternalRenderTask(complete, {
canvasContext,
viewport,
transform,
imageLayer,
background,
},
this.objs, this.objs,
this.commonObjs, this.commonObjs,
intentState.operatorList, intentState.operatorList,
this.pageNumber, this.pageNumber,
canvasFactory, canvasFactoryInstance,
webGLContext, webGLContext,
this._pdfBug); this._pdfBug);
internalRenderTask.useRequestAnimationFrame = renderingIntent !== 'print'; internalRenderTask.useRequestAnimationFrame = renderingIntent !== 'print';
@ -1009,7 +1021,7 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
intentState.renderTasks = []; intentState.renderTasks = [];
} }
intentState.renderTasks.push(internalRenderTask); intentState.renderTasks.push(internalRenderTask);
var renderTask = internalRenderTask.task; const renderTask = internalRenderTask.task;
intentState.displayReadyCapability.promise.then((transparency) => { intentState.displayReadyCapability.promise.then((transparency) => {
if (this.pendingCleanup) { if (this.pendingCleanup) {
@ -1022,30 +1034,30 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
}).catch(complete); }).catch(complete);
return renderTask; return renderTask;
}, }
/** /**
* @return {Promise} A promise resolved with an {@link PDFOperatorList} * @return {Promise} A promise resolved with an {@link PDFOperatorList}
* object that represents page's operator list. * object that represents page's operator list.
*/ */
getOperatorList: function PDFPageProxy_getOperatorList() { getOperatorList() {
function operatorListChanged() { function operatorListChanged() {
if (intentState.operatorList.lastChunk) { if (intentState.operatorList.lastChunk) {
intentState.opListReadCapability.resolve(intentState.operatorList); intentState.opListReadCapability.resolve(intentState.operatorList);
var i = intentState.renderTasks.indexOf(opListTask); const i = intentState.renderTasks.indexOf(opListTask);
if (i >= 0) { if (i >= 0) {
intentState.renderTasks.splice(i, 1); intentState.renderTasks.splice(i, 1);
} }
} }
} }
var renderingIntent = 'oplist'; const renderingIntent = 'oplist';
if (!this.intentStates[renderingIntent]) { if (!this.intentStates[renderingIntent]) {
this.intentStates[renderingIntent] = Object.create(null); this.intentStates[renderingIntent] = Object.create(null);
} }
var intentState = this.intentStates[renderingIntent]; const intentState = this.intentStates[renderingIntent];
var opListTask; let opListTask;
if (!intentState.opListReadCapability) { if (!intentState.opListReadCapability) {
opListTask = {}; opListTask = {};
@ -1061,40 +1073,41 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
}; };
this._stats.time('Page Request'); this._stats.time('Page Request');
this.transport.messageHandler.send('RenderPageRequest', { this._transport.messageHandler.send('RenderPageRequest', {
pageIndex: this.pageIndex, pageIndex: this.pageIndex,
intent: renderingIntent, intent: renderingIntent,
}); });
} }
return intentState.opListReadCapability.promise; return intentState.opListReadCapability.promise;
}, }
/** /**
* @param {getTextContentParameters} params - getTextContent parameters. * @param {getTextContentParameters} params - getTextContent parameters.
* @return {ReadableStream} ReadableStream to read textContent chunks. * @return {ReadableStream} ReadableStream to read textContent chunks.
*/ */
streamTextContent(params = {}) { streamTextContent({ normalizeWhitespace = false,
disableCombineTextItems = false, } = {}) {
const TEXT_CONTENT_CHUNK_SIZE = 100; const TEXT_CONTENT_CHUNK_SIZE = 100;
return this.transport.messageHandler.sendWithStream('GetTextContent', {
return this._transport.messageHandler.sendWithStream('GetTextContent', {
pageIndex: this.pageNumber - 1, pageIndex: this.pageNumber - 1,
normalizeWhitespace: (params.normalizeWhitespace === true), normalizeWhitespace: normalizeWhitespace === true,
combineTextItems: (params.disableCombineTextItems !== true), combineTextItems: disableCombineTextItems !== true,
}, { }, {
highWaterMark: TEXT_CONTENT_CHUNK_SIZE, highWaterMark: TEXT_CONTENT_CHUNK_SIZE,
size(textContent) { size(textContent) {
return textContent.items.length; return textContent.items.length;
}, },
}); });
}, }
/** /**
* @param {getTextContentParameters} params - getTextContent parameters. * @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(params) { getTextContent(params = {}) {
params = params || {}; const readableStream = this.streamTextContent(params);
let readableStream = this.streamTextContent(params);
return new Promise(function(resolve, reject) { return new Promise(function(resolve, reject) {
function pump() { function pump() {
@ -1109,32 +1122,31 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
}, reject); }, reject);
} }
let reader = readableStream.getReader(); const reader = readableStream.getReader();
let textContent = { const textContent = {
items: [], items: [],
styles: Object.create(null), styles: Object.create(null),
}; };
pump(); pump();
}); });
}, }
/** /**
* Destroys page object. * Destroys page object.
*/ */
_destroy: function PDFPageProxy_destroy() { _destroy() {
this.destroyed = true; this.destroyed = true;
this.transport.pageCache[this.pageIndex] = null; this._transport.pageCache[this.pageIndex] = null;
var waitOn = []; const waitOn = [];
Object.keys(this.intentStates).forEach(function(intent) { Object.keys(this.intentStates).forEach(function(intent) {
if (intent === 'oplist') { if (intent === 'oplist') {
// Avoid errors below, since the renderTasks are just stubs. // Avoid errors below, since the renderTasks are just stubs.
return; return;
} }
var intentState = this.intentStates[intent]; const intentState = this.intentStates[intent];
intentState.renderTasks.forEach(function(renderTask) { intentState.renderTasks.forEach(function(renderTask) {
var renderCompleted = renderTask.capability.promise. const renderCompleted = renderTask.capability.promise.
catch(function() {}); // ignoring failures catch(function() {}); // ignoring failures
waitOn.push(renderCompleted); waitOn.push(renderCompleted);
renderTask.cancel(); renderTask.cancel();
@ -1144,7 +1156,7 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
this.annotationsPromise = null; this.annotationsPromise = null;
this.pendingCleanup = false; this.pendingCleanup = false;
return Promise.all(waitOn); return Promise.all(waitOn);
}, }
/** /**
* Cleans up resources allocated by the page. * Cleans up resources allocated by the page.
@ -1154,7 +1166,8 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
cleanup(resetStats = false) { cleanup(resetStats = false) {
this.pendingCleanup = true; this.pendingCleanup = true;
this._tryCleanup(resetStats); this._tryCleanup(resetStats);
}, }
/** /**
* For internal use only. Attempts to clean up if rendering is in a state * For internal use only. Attempts to clean up if rendering is in a state
* where that's possible. * where that's possible.
@ -1163,7 +1176,7 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
_tryCleanup(resetStats = false) { _tryCleanup(resetStats = false) {
if (!this.pendingCleanup || if (!this.pendingCleanup ||
Object.keys(this.intentStates).some(function(intent) { Object.keys(this.intentStates).some(function(intent) {
var intentState = this.intentStates[intent]; const intentState = this.intentStates[intent];
return (intentState.renderTasks.length !== 0 || return (intentState.renderTasks.length !== 0 ||
intentState.receivingOperatorList); intentState.receivingOperatorList);
}, this)) { }, this)) {
@ -1179,30 +1192,29 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
this._stats = new StatTimer(); this._stats = new StatTimer();
} }
this.pendingCleanup = false; this.pendingCleanup = false;
}, }
/** /**
* For internal use only. * For internal use only.
* @ignore * @ignore
*/ */
_startRenderPage: function PDFPageProxy_startRenderPage(transparency, _startRenderPage(transparency, intent) {
intent) { const intentState = this.intentStates[intent];
var intentState = this.intentStates[intent];
// TODO Refactor RenderPageRequest to separate rendering // TODO Refactor RenderPageRequest to separate rendering
// and operator list logic // and operator list logic
if (intentState.displayReadyCapability) { if (intentState.displayReadyCapability) {
intentState.displayReadyCapability.resolve(transparency); intentState.displayReadyCapability.resolve(transparency);
} }
}, }
/** /**
* For internal use only. * For internal use only.
* @ignore * @ignore
*/ */
_renderPageChunk: function PDFPageProxy_renderPageChunk(operatorListChunk, _renderPageChunk(operatorListChunk, intent) {
intent) { const intentState = this.intentStates[intent];
var intentState = this.intentStates[intent];
var i, ii;
// Add the new chunk to the current operator list. // Add the new chunk to the current operator list.
for (i = 0, ii = operatorListChunk.length; i < ii; i++) { for (let i = 0, ii = operatorListChunk.length; i < ii; i++) {
intentState.operatorList.fnArray.push(operatorListChunk.fnArray[i]); intentState.operatorList.fnArray.push(operatorListChunk.fnArray[i]);
intentState.operatorList.argsArray.push( intentState.operatorList.argsArray.push(
operatorListChunk.argsArray[i]); operatorListChunk.argsArray[i]);
@ -1210,7 +1222,7 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
intentState.operatorList.lastChunk = operatorListChunk.lastChunk; intentState.operatorList.lastChunk = operatorListChunk.lastChunk;
// Notify all the rendering tasks there are more operators to be consumed. // Notify all the rendering tasks there are more operators to be consumed.
for (i = 0; i < intentState.renderTasks.length; i++) { for (let i = 0; i < intentState.renderTasks.length; i++) {
intentState.renderTasks[i].operatorListChanged(); intentState.renderTasks[i].operatorListChanged();
} }
@ -1218,17 +1230,15 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
intentState.receivingOperatorList = false; intentState.receivingOperatorList = false;
this._tryCleanup(); this._tryCleanup();
} }
}, }
/** /**
* @return {Object} Returns page stats, if enabled. * @return {Object} Returns page stats, if enabled.
*/ */
get stats() { get stats() {
return (this._stats instanceof StatTimer ? this._stats : null); return (this._stats instanceof StatTimer ? this._stats : null);
}, }
}; }
return PDFPageProxy;
})();
class LoopbackPort { class LoopbackPort {
constructor(defer = true) { constructor(defer = true) {