diff --git a/src/core/editor/pdf_editor.js b/src/core/editor/pdf_editor.js index 8a726a496..0ecb141b5 100644 --- a/src/core/editor/pdf_editor.js +++ b/src/core/editor/pdf_editor.js @@ -616,15 +616,20 @@ class PDFEditor { if (newIndex !== -1) { newPageIndex = newIndex++; } else { + // Find the first available index in the newPages array. + // This is needed when the pageIndices option is used since the + // pages can be added in any order. for ( newPageIndex = 0; - this.oldPages[newPageIndex] === undefined; + this.oldPages[newPageIndex] !== undefined; newPageIndex++ ) { /* empty */ } } } + // Reserve the slot immediately because the page fetch is async. + this.oldPages[newPageIndex] = null; promises.push( document.getPage(i).then(page => { this.oldPages[newPageIndex] = new PageData(page, documentData); diff --git a/test/unit/api_spec.js b/test/unit/api_spec.js index c7bdfe23e..02b8b960c 100644 --- a/test/unit/api_spec.js +++ b/test/unit/api_spec.js @@ -6222,6 +6222,44 @@ small scripts as well as for`); await loadingTask.destroy(); }); + + it("fills missing pageIndices with the first free slots", async function () { + let loadingTask = getDocument( + buildGetDocumentParams("tracemonkey.pdf") + ); + let pdfDoc = await loadingTask.promise; + const data = await pdfDoc.extractPages([ + { document: null, includePages: [1, 3, 5], pageIndices: [1] }, + ]); + await loadingTask.destroy(); + + loadingTask = getDocument(data); + pdfDoc = await loadingTask.promise; + + expect(pdfDoc.numPages).toEqual(3); + + // Page 4 in the original document should occupy the first free slot. + let pdfPage = await pdfDoc.getPage(1); + let { items: textItems } = await pdfPage.getTextContent(); + expect(mergeText(textItems).includes("3. Trace Trees")).toBeTrue(); + + // Page 2 in the original document keeps its explicit destination slot. + pdfPage = await pdfDoc.getPage(2); + ({ items: textItems } = await pdfPage.getTextContent()); + expect( + mergeText(textItems).includes("2. Overview: Example Tracing Run") + ).toBeTrue(); + + // Page 6 in the original document should occupy the remaining free + // slot. + pdfPage = await pdfDoc.getPage(3); + ({ items: textItems } = await pdfPage.getTextContent()); + expect( + mergeText(textItems).includes("4. Nested Trace Tree Formation") + ).toBeTrue(); + + await loadingTask.destroy(); + }); }); describe("AcroForm", function () {