[api-minor] Allow specifying an extra-delay, in RenderTask.cancel, for worker-thread aborting of operatorList parsing

This is done to support upcoming viewer-changes, and in order to prevent third-party users from outright breaking things we'll simply ignore too large values.
This commit is contained in:
Jonas Jenwald 2022-12-14 12:34:16 +01:00
parent e182597cb1
commit 91524d1a60
3 changed files with 20 additions and 6 deletions

View File

@ -1828,10 +1828,19 @@ class PDFPageProxy {
// cancelled, since that will unnecessarily delay re-rendering when (for // cancelled, since that will unnecessarily delay re-rendering when (for
// partially parsed pages) e.g. zooming/rotation occurs in the viewer. // partially parsed pages) e.g. zooming/rotation occurs in the viewer.
if (reason instanceof RenderingCancelledException) { if (reason instanceof RenderingCancelledException) {
let delay = RENDERING_CANCELLED_TIMEOUT;
if (reason.extraDelay > 0 && reason.extraDelay < /* ms = */ 1000) {
// Above, we prevent the total delay from becoming arbitrarily large.
delay += reason.extraDelay;
}
if (intentState.streamReaderCancelTimeout) {
clearTimeout(intentState.streamReaderCancelTimeout);
}
intentState.streamReaderCancelTimeout = setTimeout(() => { intentState.streamReaderCancelTimeout = setTimeout(() => {
this._abortOperatorList({ intentState, reason, force: true }); this._abortOperatorList({ intentState, reason, force: true });
intentState.streamReaderCancelTimeout = null; intentState.streamReaderCancelTimeout = null;
}, RENDERING_CANCELLED_TIMEOUT); }, delay);
return; return;
} }
} }
@ -3147,9 +3156,11 @@ class RenderTask {
* Cancels the rendering task. If the task is currently rendering it will * Cancels the rendering task. If the task is currently rendering it will
* not be cancelled until graphics pauses with a timeout. The promise that * not be cancelled until graphics pauses with a timeout. The promise that
* this object extends will be rejected when cancelled. * this object extends will be rejected when cancelled.
*
* @param {number} [extraDelay]
*/ */
cancel() { cancel(extraDelay = 0) {
this.#internalRenderTask.cancel(); this.#internalRenderTask.cancel(/* error = */ null, extraDelay);
} }
/** /**
@ -3266,7 +3277,7 @@ class InternalRenderTask {
this.graphicsReadyCallback?.(); this.graphicsReadyCallback?.();
} }
cancel(error = null) { cancel(error = null, extraDelay = 0) {
this.running = false; this.running = false;
this.cancelled = true; this.cancelled = true;
this.gfx?.endDrawing(); this.gfx?.endDrawing();
@ -3278,7 +3289,8 @@ class InternalRenderTask {
error || error ||
new RenderingCancelledException( new RenderingCancelledException(
`Rendering cancelled, page ${this._pageIndex + 1}`, `Rendering cancelled, page ${this._pageIndex + 1}`,
"canvas" "canvas",
extraDelay
) )
); );
} }

View File

@ -332,9 +332,10 @@ class PageViewport {
} }
class RenderingCancelledException extends BaseException { class RenderingCancelledException extends BaseException {
constructor(msg, type) { constructor(msg, type, extraDelay = 0) {
super(msg, "RenderingCancelledException"); super(msg, "RenderingCancelledException");
this.type = type; this.type = type;
this.extraDelay = extraDelay;
} }
} }

View File

@ -2870,6 +2870,7 @@ Caron Broadcasting, Inc., an Ohio corporation (“Lessee”).`)
expect(reason instanceof RenderingCancelledException).toEqual(true); expect(reason instanceof RenderingCancelledException).toEqual(true);
expect(reason.message).toEqual("Rendering cancelled, page 1"); expect(reason.message).toEqual("Rendering cancelled, page 1");
expect(reason.type).toEqual("canvas"); expect(reason.type).toEqual("canvas");
expect(reason.extraDelay).toEqual(0);
} }
CanvasFactory.destroy(canvasAndCtx); CanvasFactory.destroy(canvasAndCtx);