Skip to content

Commit 8061333

Browse files
committed
Refactor a bit page mapping stuff in order to be able to support delete/copy pages
1 parent 48df8a5 commit 8061333

24 files changed

Lines changed: 505 additions & 376 deletions

src/core/document.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,8 @@ class Page {
464464
task,
465465
intent,
466466
cacheKey,
467+
pageId = this.pageIndex,
468+
pageIndex = this.pageIndex,
467469
annotationStorage = null,
468470
modifiedIds = null,
469471
}) {
@@ -549,13 +551,12 @@ class Page {
549551
RESOURCES_KEYS_OPERATOR_LIST
550552
);
551553
const opList = new OperatorList(intent, sink);
552-
553554
handler.send("StartRenderPage", {
554555
transparency: partialEvaluator.hasBlendModes(
555556
resources,
556557
this.nonBlendModesSet
557558
),
558-
pageIndex: this.pageIndex,
559+
pageIndex,
559560
cacheKey,
560561
});
561562

src/core/worker.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -853,8 +853,8 @@ class WorkerMessageHandler {
853853
);
854854

855855
handler.on("GetOperatorList", function (data, sink) {
856-
const pageIndex = data.pageIndex;
857-
pdfManager.getPage(pageIndex).then(function (page) {
856+
const { pageId, pageIndex } = data;
857+
pdfManager.getPage(pageId).then(function (page) {
858858
const task = new WorkerTask(`GetOperatorList: page ${pageIndex}`);
859859
startWorkerTask(task);
860860

@@ -871,6 +871,7 @@ class WorkerMessageHandler {
871871
cacheKey: data.cacheKey,
872872
annotationStorage: data.annotationStorage,
873873
modifiedIds: data.modifiedIds,
874+
pageIndex,
874875
})
875876
.then(
876877
function (operatorListInfo) {
@@ -899,9 +900,10 @@ class WorkerMessageHandler {
899900
});
900901

901902
handler.on("GetTextContent", function (data, sink) {
902-
const { pageIndex, includeMarkedContent, disableNormalization } = data;
903+
const { pageId, pageIndex, includeMarkedContent, disableNormalization } =
904+
data;
903905

904-
pdfManager.getPage(pageIndex).then(function (page) {
906+
pdfManager.getPage(pageId).then(function (page) {
905907
const task = new WorkerTask("GetTextContent: page " + pageIndex);
906908
startWorkerTask(task);
907909

src/display/annotation_layer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ class AnnotationElement {
293293
this.annotationStorage.setValue(`${AnnotationEditorPrefix}${data.id}`, {
294294
id: data.id,
295295
annotationType: data.annotationType,
296-
pageIndex: this.parent.page._pageIndex,
296+
page: this.parent.page,
297297
popup,
298298
popupRef: data.popupRef,
299299
modificationDate: new Date(),

src/display/annotation_storage.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,10 @@ class AnnotationStorage {
196196
val instanceof AnnotationEditor
197197
? val.serialize(/* isForCopying = */ false, context)
198198
: val;
199+
if (val.page) {
200+
val.pageIndex = val.page._pageIndex;
201+
delete val.page;
202+
}
199203
if (serialized) {
200204
map.set(key, serialized);
201205

src/display/api.js

Lines changed: 59 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import {
4040
deprecated,
4141
isDataScheme,
4242
isValidFetchUrl,
43+
PagesMapper,
4344
PageViewport,
4445
RenderingCancelledException,
4546
StatTimer,
@@ -1328,6 +1329,8 @@ class PDFDocumentProxy {
13281329
class PDFPageProxy {
13291330
#pendingCleanup = false;
13301331

1332+
#pagesMapper = PagesMapper.instance;
1333+
13311334
constructor(pageIndex, pageInfo, transport, pdfBug = false) {
13321335
this._pageIndex = pageIndex;
13331336
this._pageInfo = pageInfo;
@@ -1350,6 +1353,13 @@ class PDFPageProxy {
13501353
return this._pageIndex + 1;
13511354
}
13521355

1356+
/**
1357+
* @param {number} value - The page number to set. First page is 1.
1358+
*/
1359+
set pageNumber(value) {
1360+
this._pageIndex = value - 1;
1361+
}
1362+
13531363
/**
13541364
* @type {number} The number of degrees the page is rotated clockwise.
13551365
*/
@@ -1699,6 +1709,7 @@ class PDFPageProxy {
16991709
return this._transport.messageHandler.sendWithStream(
17001710
"GetTextContent",
17011711
{
1712+
pageId: this.#pagesMapper.getPageId(this._pageIndex + 1) - 1,
17021713
pageIndex: this._pageIndex,
17031714
includeMarkedContent: includeMarkedContent === true,
17041715
disableNormalization: disableNormalization === true,
@@ -1884,6 +1895,7 @@ class PDFPageProxy {
18841895
const readableStream = this._transport.messageHandler.sendWithStream(
18851896
"GetOperatorList",
18861897
{
1898+
pageId: this.#pagesMapper.getPageId(this._pageIndex + 1) - 1,
18871899
pageIndex: this._pageIndex,
18881900
intent: renderingIntent,
18891901
cacheKey,
@@ -2389,6 +2401,8 @@ class WorkerTransport {
23892401

23902402
#passwordCapability = null;
23912403

2404+
#pagesMapper = PagesMapper.instance;
2405+
23922406
constructor(
23932407
messageHandler,
23942408
loadingTask,
@@ -2424,6 +2438,8 @@ class WorkerTransport {
24242438

24252439
this.setupMessageHandler();
24262440

2441+
this.#pagesMapper.addListener(this.#updateCaches.bind(this));
2442+
24272443
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
24282444
// For testing purposes.
24292445
Object.defineProperty(this, "getNetworkStreamName", {
@@ -2448,6 +2464,24 @@ class WorkerTransport {
24482464
}
24492465
}
24502466

2467+
#updateCaches() {
2468+
const newPageCache = new Map();
2469+
const newPromiseCache = new Map();
2470+
for (let i = 0, ii = this.#pagesMapper.pagesNumber; i < ii; i++) {
2471+
const prevPageIndex = this.#pagesMapper.getPrevPageNumber(i + 1) - 1;
2472+
const page = this.#pageCache.get(prevPageIndex);
2473+
if (page) {
2474+
newPageCache.set(i, page);
2475+
}
2476+
const promise = this.#pagePromises.get(prevPageIndex);
2477+
if (promise) {
2478+
newPromiseCache.set(i, promise);
2479+
}
2480+
}
2481+
this.#pageCache = newPageCache;
2482+
this.#pagePromises = newPromiseCache;
2483+
}
2484+
24512485
#cacheSimpleMethod(name, data = null) {
24522486
const cachedPromise = this.#methodPromises.get(name);
24532487
if (cachedPromise) {
@@ -2710,6 +2744,7 @@ class WorkerTransport {
27102744
});
27112745

27122746
messageHandler.on("GetDoc", ({ pdfInfo }) => {
2747+
this.#pagesMapper.pagesNumber = pdfInfo.numPages;
27132748
this._numPages = pdfInfo.numPages;
27142749
this._htmlForXfa = pdfInfo.htmlForXfa;
27152750
delete pdfInfo.htmlForXfa;
@@ -2932,26 +2967,27 @@ class WorkerTransport {
29322967
if (
29332968
!Number.isInteger(pageNumber) ||
29342969
pageNumber <= 0 ||
2935-
pageNumber > this._numPages
2970+
pageNumber > this.#pagesMapper.pagesNumber
29362971
) {
29372972
return Promise.reject(new Error("Invalid page request."));
29382973
}
2974+
const pageIndex = pageNumber - 1;
2975+
const newPageIndex = this.#pagesMapper.getPageId(pageNumber) - 1;
29392976

2940-
const pageIndex = pageNumber - 1,
2941-
cachedPromise = this.#pagePromises.get(pageIndex);
2977+
const cachedPromise = this.#pagePromises.get(pageIndex);
29422978
if (cachedPromise) {
29432979
return cachedPromise;
29442980
}
29452981
const promise = this.messageHandler
29462982
.sendWithPromise("GetPage", {
2947-
pageIndex,
2983+
pageIndex: newPageIndex,
29482984
})
29492985
.then(pageInfo => {
29502986
if (this.destroyed) {
29512987
throw new Error("Transport destroyed");
29522988
}
29532989
if (pageInfo.refStr) {
2954-
this.#pageRefCache.set(pageInfo.refStr, pageNumber);
2990+
this.#pageRefCache.set(pageInfo.refStr, newPageIndex);
29552991
}
29562992

29572993
const page = new PDFPageProxy(
@@ -2967,19 +3003,20 @@ class WorkerTransport {
29673003
return promise;
29683004
}
29693005

2970-
getPageIndex(ref) {
3006+
async getPageIndex(ref) {
29713007
if (!isRefProxy(ref)) {
2972-
return Promise.reject(new Error("Invalid pageIndex request."));
3008+
throw new Error("Invalid pageIndex request.");
29733009
}
2974-
return this.messageHandler.sendWithPromise("GetPageIndex", {
3010+
const index = await this.messageHandler.sendWithPromise("GetPageIndex", {
29753011
num: ref.num,
29763012
gen: ref.gen,
29773013
});
3014+
return this.#pagesMapper.getPageNumber(index + 1) - 1;
29783015
}
29793016

29803017
getAnnotations(pageIndex, intent) {
29813018
return this.messageHandler.sendWithPromise("GetAnnotations", {
2982-
pageIndex,
3019+
pageIndex: this.#pagesMapper.getPageId(pageIndex + 1) - 1,
29833020
intent,
29843021
});
29853022
}
@@ -3046,13 +3083,13 @@ class WorkerTransport {
30463083

30473084
getPageJSActions(pageIndex) {
30483085
return this.messageHandler.sendWithPromise("GetPageJSActions", {
3049-
pageIndex,
3086+
pageIndex: this.#pagesMapper.getPageId(pageIndex + 1) - 1,
30503087
});
30513088
}
30523089

30533090
getStructTree(pageIndex) {
30543091
return this.messageHandler.sendWithPromise("GetStructTree", {
3055-
pageIndex,
3092+
pageIndex: this.#pagesMapper.getPageId(pageIndex + 1) - 1,
30563093
});
30573094
}
30583095

@@ -3122,15 +3159,18 @@ class WorkerTransport {
31223159
return null;
31233160
}
31243161
const refStr = ref.gen === 0 ? `${ref.num}R` : `${ref.num}R${ref.gen}`;
3125-
return this.#pageRefCache.get(refStr) ?? null;
3162+
const pageIndex = this.#pageRefCache.get(refStr);
3163+
return pageIndex >= 0
3164+
? this.#pagesMapper.getPageNumber(pageIndex + 1)
3165+
: null;
31263166
}
31273167
}
31283168

31293169
/**
31303170
* Allows controlling of the rendering tasks.
31313171
*/
31323172
class RenderTask {
3133-
#internalRenderTask = null;
3173+
_internalRenderTask = null;
31343174

31353175
/**
31363176
* Callback for incremental rendering -- a function that will be called
@@ -3151,12 +3191,12 @@ class RenderTask {
31513191
onError = null;
31523192

31533193
constructor(internalRenderTask) {
3154-
this.#internalRenderTask = internalRenderTask;
3194+
this._internalRenderTask = internalRenderTask;
31553195

31563196
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
31573197
// For testing purposes.
31583198
Object.defineProperty(this, "getOperatorList", {
3159-
value: () => this.#internalRenderTask.operatorList,
3199+
value: () => this._internalRenderTask.operatorList,
31603200
});
31613201
}
31623202
}
@@ -3166,7 +3206,7 @@ class RenderTask {
31663206
* @type {Promise<void>}
31673207
*/
31683208
get promise() {
3169-
return this.#internalRenderTask.capability.promise;
3209+
return this._internalRenderTask.capability.promise;
31703210
}
31713211

31723212
/**
@@ -3177,19 +3217,19 @@ class RenderTask {
31773217
* @param {number} [extraDelay]
31783218
*/
31793219
cancel(extraDelay = 0) {
3180-
this.#internalRenderTask.cancel(/* error = */ null, extraDelay);
3220+
this._internalRenderTask.cancel(/* error = */ null, extraDelay);
31813221
}
31823222

31833223
/**
31843224
* Whether form fields are rendered separately from the main operatorList.
31853225
* @type {boolean}
31863226
*/
31873227
get separateAnnots() {
3188-
const { separateAnnots } = this.#internalRenderTask.operatorList;
3228+
const { separateAnnots } = this._internalRenderTask.operatorList;
31893229
if (!separateAnnots) {
31903230
return false;
31913231
}
3192-
const { annotationCanvasMap } = this.#internalRenderTask;
3232+
const { annotationCanvasMap } = this._internalRenderTask;
31933233
return (
31943234
separateAnnots.form ||
31953235
(separateAnnots.canvas && annotationCanvasMap?.size > 0)
@@ -3389,7 +3429,6 @@ class InternalRenderTask {
33893429
if (this.operatorList.lastChunk) {
33903430
this.gfx.endDrawing();
33913431
InternalRenderTask.#canvasInUse.delete(this._canvas);
3392-
33933432
this.callback();
33943433
}
33953434
}

0 commit comments

Comments
 (0)