mirror of
https://github.com/mozilla/pdf.js.git
synced 2026-08-02 12:27:21 +02:00
Merge pull request #20640 from calixteman/issue20629
Set a pages mapper per loaded document
This commit is contained in:
commit
9870d898b4
@ -233,6 +233,9 @@ const RENDERING_CANCELLED_TIMEOUT = 100; // ms
|
|||||||
* The default value is {DOMFilterFactory}.
|
* The default value is {DOMFilterFactory}.
|
||||||
* @property {boolean} [enableHWA] - Enables hardware acceleration for
|
* @property {boolean} [enableHWA] - Enables hardware acceleration for
|
||||||
* rendering. The default value is `false`.
|
* rendering. The default value is `false`.
|
||||||
|
* @property {Object} [pagesMapper] - The pages mapper that will be used to map
|
||||||
|
* page ids and page numbers. It's used when the page order is changed or some
|
||||||
|
* pages are removed, cloned, etc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -342,6 +345,7 @@ function getDocument(src = {}) {
|
|||||||
: DOMFilterFactory);
|
: DOMFilterFactory);
|
||||||
const enableHWA = src.enableHWA === true;
|
const enableHWA = src.enableHWA === true;
|
||||||
const useWasm = src.useWasm !== false;
|
const useWasm = src.useWasm !== false;
|
||||||
|
const pagesMapper = src.pagesMapper || new PagesMapper();
|
||||||
|
|
||||||
// Parameters whose default values depend on other parameters.
|
// Parameters whose default values depend on other parameters.
|
||||||
const length = rangeTransport ? rangeTransport.length : (src.length ?? NaN);
|
const length = rangeTransport ? rangeTransport.length : (src.length ?? NaN);
|
||||||
@ -511,7 +515,8 @@ function getDocument(src = {}) {
|
|||||||
task,
|
task,
|
||||||
networkStream,
|
networkStream,
|
||||||
transportParams,
|
transportParams,
|
||||||
transportFactory
|
transportFactory,
|
||||||
|
pagesMapper
|
||||||
);
|
);
|
||||||
task._transport = transport;
|
task._transport = transport;
|
||||||
messageHandler.send("Ready", null);
|
messageHandler.send("Ready", null);
|
||||||
@ -761,6 +766,13 @@ class PDFDocumentProxy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {PagesMapper} The pages mapper instance.
|
||||||
|
*/
|
||||||
|
get pagesMapper() {
|
||||||
|
return this._transport.pagesMapper;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {AnnotationStorage} Storage for annotation data in forms.
|
* @type {AnnotationStorage} Storage for annotation data in forms.
|
||||||
*/
|
*/
|
||||||
@ -1324,9 +1336,9 @@ class PDFDocumentProxy {
|
|||||||
class PDFPageProxy {
|
class PDFPageProxy {
|
||||||
#pendingCleanup = false;
|
#pendingCleanup = false;
|
||||||
|
|
||||||
#pagesMapper = PagesMapper.instance;
|
#pagesMapper = null;
|
||||||
|
|
||||||
constructor(pageIndex, pageInfo, transport, pdfBug = false) {
|
constructor(pageIndex, pageInfo, transport, pagesMapper, pdfBug = false) {
|
||||||
this._pageIndex = pageIndex;
|
this._pageIndex = pageIndex;
|
||||||
this._pageInfo = pageInfo;
|
this._pageInfo = pageInfo;
|
||||||
this._transport = transport;
|
this._transport = transport;
|
||||||
@ -1339,6 +1351,7 @@ class PDFPageProxy {
|
|||||||
this._intentStates = new Map();
|
this._intentStates = new Map();
|
||||||
this.destroyed = false;
|
this.destroyed = false;
|
||||||
this.recordedBBoxes = null;
|
this.recordedBBoxes = null;
|
||||||
|
this.#pagesMapper = pagesMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2402,9 +2415,14 @@ class WorkerTransport {
|
|||||||
|
|
||||||
#passwordCapability = null;
|
#passwordCapability = null;
|
||||||
|
|
||||||
#pagesMapper = PagesMapper.instance;
|
constructor(
|
||||||
|
messageHandler,
|
||||||
constructor(messageHandler, loadingTask, networkStream, params, factory) {
|
loadingTask,
|
||||||
|
networkStream,
|
||||||
|
params,
|
||||||
|
factory,
|
||||||
|
pagesMapper
|
||||||
|
) {
|
||||||
this.messageHandler = messageHandler;
|
this.messageHandler = messageHandler;
|
||||||
this.loadingTask = loadingTask;
|
this.loadingTask = loadingTask;
|
||||||
this.#networkStream = networkStream;
|
this.#networkStream = networkStream;
|
||||||
@ -2429,7 +2447,8 @@ class WorkerTransport {
|
|||||||
|
|
||||||
this.setupMessageHandler();
|
this.setupMessageHandler();
|
||||||
|
|
||||||
this.#pagesMapper.addListener(this.#updateCaches.bind(this));
|
this.pagesMapper = pagesMapper;
|
||||||
|
this.pagesMapper.addListener(this.#updateCaches.bind(this));
|
||||||
|
|
||||||
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
|
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
|
||||||
// For testing purposes.
|
// For testing purposes.
|
||||||
@ -2458,8 +2477,8 @@ class WorkerTransport {
|
|||||||
#updateCaches() {
|
#updateCaches() {
|
||||||
const newPageCache = new Map();
|
const newPageCache = new Map();
|
||||||
const newPromiseCache = new Map();
|
const newPromiseCache = new Map();
|
||||||
for (let i = 0, ii = this.#pagesMapper.pagesNumber; i < ii; i++) {
|
for (let i = 0, ii = this.pagesMapper.pagesNumber; i < ii; i++) {
|
||||||
const prevPageIndex = this.#pagesMapper.getPrevPageNumber(i + 1) - 1;
|
const prevPageIndex = this.pagesMapper.getPrevPageNumber(i + 1) - 1;
|
||||||
const page = this.#pageCache.get(prevPageIndex);
|
const page = this.#pageCache.get(prevPageIndex);
|
||||||
if (page) {
|
if (page) {
|
||||||
newPageCache.set(i, page);
|
newPageCache.set(i, page);
|
||||||
@ -2730,7 +2749,7 @@ class WorkerTransport {
|
|||||||
});
|
});
|
||||||
|
|
||||||
messageHandler.on("GetDoc", ({ pdfInfo }) => {
|
messageHandler.on("GetDoc", ({ pdfInfo }) => {
|
||||||
this.#pagesMapper.pagesNumber = pdfInfo.numPages;
|
this.pagesMapper.pagesNumber = pdfInfo.numPages;
|
||||||
this._numPages = pdfInfo.numPages;
|
this._numPages = pdfInfo.numPages;
|
||||||
this._htmlForXfa = pdfInfo.htmlForXfa;
|
this._htmlForXfa = pdfInfo.htmlForXfa;
|
||||||
delete pdfInfo.htmlForXfa;
|
delete pdfInfo.htmlForXfa;
|
||||||
@ -2947,12 +2966,12 @@ class WorkerTransport {
|
|||||||
if (
|
if (
|
||||||
!Number.isInteger(pageNumber) ||
|
!Number.isInteger(pageNumber) ||
|
||||||
pageNumber <= 0 ||
|
pageNumber <= 0 ||
|
||||||
pageNumber > this.#pagesMapper.pagesNumber
|
pageNumber > this.pagesMapper.pagesNumber
|
||||||
) {
|
) {
|
||||||
return Promise.reject(new Error("Invalid page request."));
|
return Promise.reject(new Error("Invalid page request."));
|
||||||
}
|
}
|
||||||
const pageIndex = pageNumber - 1;
|
const pageIndex = pageNumber - 1;
|
||||||
const newPageIndex = this.#pagesMapper.getPageId(pageNumber) - 1;
|
const newPageIndex = this.pagesMapper.getPageId(pageNumber) - 1;
|
||||||
|
|
||||||
const cachedPromise = this.#pagePromises.get(pageIndex);
|
const cachedPromise = this.#pagePromises.get(pageIndex);
|
||||||
if (cachedPromise) {
|
if (cachedPromise) {
|
||||||
@ -2974,6 +2993,7 @@ class WorkerTransport {
|
|||||||
pageIndex,
|
pageIndex,
|
||||||
pageInfo,
|
pageInfo,
|
||||||
this,
|
this,
|
||||||
|
this.pagesMapper,
|
||||||
this._params.pdfBug
|
this._params.pdfBug
|
||||||
);
|
);
|
||||||
this.#pageCache.set(pageIndex, page);
|
this.#pageCache.set(pageIndex, page);
|
||||||
@ -2991,12 +3011,12 @@ class WorkerTransport {
|
|||||||
num: ref.num,
|
num: ref.num,
|
||||||
gen: ref.gen,
|
gen: ref.gen,
|
||||||
});
|
});
|
||||||
return this.#pagesMapper.getPageNumber(index + 1) - 1;
|
return this.pagesMapper.getPageNumber(index + 1) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
getAnnotations(pageIndex, intent) {
|
getAnnotations(pageIndex, intent) {
|
||||||
return this.messageHandler.sendWithPromise("GetAnnotations", {
|
return this.messageHandler.sendWithPromise("GetAnnotations", {
|
||||||
pageIndex: this.#pagesMapper.getPageId(pageIndex + 1) - 1,
|
pageIndex: this.pagesMapper.getPageId(pageIndex + 1) - 1,
|
||||||
intent,
|
intent,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -3063,13 +3083,13 @@ class WorkerTransport {
|
|||||||
|
|
||||||
getPageJSActions(pageIndex) {
|
getPageJSActions(pageIndex) {
|
||||||
return this.messageHandler.sendWithPromise("GetPageJSActions", {
|
return this.messageHandler.sendWithPromise("GetPageJSActions", {
|
||||||
pageIndex: this.#pagesMapper.getPageId(pageIndex + 1) - 1,
|
pageIndex: this.pagesMapper.getPageId(pageIndex + 1) - 1,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getStructTree(pageIndex) {
|
getStructTree(pageIndex) {
|
||||||
return this.messageHandler.sendWithPromise("GetStructTree", {
|
return this.messageHandler.sendWithPromise("GetStructTree", {
|
||||||
pageIndex: this.#pagesMapper.getPageId(pageIndex + 1) - 1,
|
pageIndex: this.pagesMapper.getPageId(pageIndex + 1) - 1,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3141,7 +3161,7 @@ class WorkerTransport {
|
|||||||
const refStr = ref.gen === 0 ? `${ref.num}R` : `${ref.num}R${ref.gen}`;
|
const refStr = ref.gen === 0 ? `${ref.num}R` : `${ref.num}R${ref.gen}`;
|
||||||
const pageIndex = this.#pageRefCache.get(refStr);
|
const pageIndex = this.#pageRefCache.get(refStr);
|
||||||
return pageIndex >= 0
|
return pageIndex >= 0
|
||||||
? this.#pagesMapper.getPageNumber(pageIndex + 1)
|
? this.pagesMapper.getPageNumber(pageIndex + 1)
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1045,38 +1045,38 @@ class PagesMapper {
|
|||||||
* Maps page IDs to their corresponding page numbers.
|
* Maps page IDs to their corresponding page numbers.
|
||||||
* @type {Uint32Array|null}
|
* @type {Uint32Array|null}
|
||||||
*/
|
*/
|
||||||
static #idToPageNumber = null;
|
#idToPageNumber = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps page numbers to their corresponding page IDs.
|
* Maps page numbers to their corresponding page IDs.
|
||||||
* @type {Uint32Array|null}
|
* @type {Uint32Array|null}
|
||||||
*/
|
*/
|
||||||
static #pageNumberToId = null;
|
#pageNumberToId = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Previous mapping of page IDs to page numbers.
|
* Previous mapping of page IDs to page numbers.
|
||||||
* @type {Uint32Array|null}
|
* @type {Uint32Array|null}
|
||||||
*/
|
*/
|
||||||
static #prevIdToPageNumber = null;
|
#prevIdToPageNumber = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The total number of pages.
|
* The total number of pages.
|
||||||
* @type {number}
|
* @type {number}
|
||||||
*/
|
*/
|
||||||
static #pagesNumber = 0;
|
#pagesNumber = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listeners for page changes.
|
* Listeners for page changes.
|
||||||
* @type {Array<function>}
|
* @type {Array<function>}
|
||||||
*/
|
*/
|
||||||
static #listeners = [];
|
#listeners = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the total number of pages.
|
* Gets the total number of pages.
|
||||||
* @returns {number} The number of pages.
|
* @returns {number} The number of pages.
|
||||||
*/
|
*/
|
||||||
get pagesNumber() {
|
get pagesNumber() {
|
||||||
return PagesMapper.#pagesNumber;
|
return this.#pagesNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1085,52 +1085,49 @@ class PagesMapper {
|
|||||||
* @param {number} n - The total number of pages.
|
* @param {number} n - The total number of pages.
|
||||||
*/
|
*/
|
||||||
set pagesNumber(n) {
|
set pagesNumber(n) {
|
||||||
if (PagesMapper.#pagesNumber === n) {
|
if (this.#pagesNumber === n) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PagesMapper.#pagesNumber = n;
|
this.#pagesNumber = n;
|
||||||
if (n === 0) {
|
if (n === 0) {
|
||||||
PagesMapper.#pageNumberToId = null;
|
this.#pageNumberToId = null;
|
||||||
PagesMapper.#idToPageNumber = null;
|
this.#idToPageNumber = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addListener(listener) {
|
addListener(listener) {
|
||||||
PagesMapper.#listeners.push(listener);
|
this.#listeners.push(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeListener(listener) {
|
removeListener(listener) {
|
||||||
const index = PagesMapper.#listeners.indexOf(listener);
|
const index = this.#listeners.indexOf(listener);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
PagesMapper.#listeners.splice(index, 1);
|
this.#listeners.splice(index, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#updateListeners() {
|
#updateListeners() {
|
||||||
for (const listener of PagesMapper.#listeners) {
|
for (const listener of this.#listeners) {
|
||||||
listener();
|
listener();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#init(mustInit) {
|
#init(mustInit) {
|
||||||
if (PagesMapper.#pageNumberToId) {
|
if (this.#pageNumberToId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const n = PagesMapper.#pagesNumber;
|
const n = this.#pagesNumber;
|
||||||
|
|
||||||
// Allocate a single array for better memory locality.
|
// Allocate a single array for better memory locality.
|
||||||
const array = new Uint32Array(3 * n);
|
const array = new Uint32Array(3 * n);
|
||||||
const pageNumberToId = (PagesMapper.#pageNumberToId = array.subarray(0, n));
|
const pageNumberToId = (this.#pageNumberToId = array.subarray(0, n));
|
||||||
const idToPageNumber = (PagesMapper.#idToPageNumber = array.subarray(
|
const idToPageNumber = (this.#idToPageNumber = array.subarray(n, 2 * n));
|
||||||
n,
|
|
||||||
2 * n
|
|
||||||
));
|
|
||||||
if (mustInit) {
|
if (mustInit) {
|
||||||
for (let i = 0; i < n; i++) {
|
for (let i = 0; i < n; i++) {
|
||||||
pageNumberToId[i] = idToPageNumber[i] = i + 1;
|
pageNumberToId[i] = idToPageNumber[i] = i + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PagesMapper.#prevIdToPageNumber = array.subarray(2 * n);
|
this.#prevIdToPageNumber = array.subarray(2 * n);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1143,9 +1140,9 @@ class PagesMapper {
|
|||||||
*/
|
*/
|
||||||
movePages(selectedPages, pagesToMove, index) {
|
movePages(selectedPages, pagesToMove, index) {
|
||||||
this.#init(true);
|
this.#init(true);
|
||||||
const pageNumberToId = PagesMapper.#pageNumberToId;
|
const pageNumberToId = this.#pageNumberToId;
|
||||||
const idToPageNumber = PagesMapper.#idToPageNumber;
|
const idToPageNumber = this.#idToPageNumber;
|
||||||
PagesMapper.#prevIdToPageNumber.set(idToPageNumber);
|
this.#prevIdToPageNumber.set(idToPageNumber);
|
||||||
const movedCount = pagesToMove.length;
|
const movedCount = pagesToMove.length;
|
||||||
const mappedPagesToMove = new Uint32Array(movedCount);
|
const mappedPagesToMove = new Uint32Array(movedCount);
|
||||||
let removedBeforeTarget = 0;
|
let removedBeforeTarget = 0;
|
||||||
@ -1158,7 +1155,7 @@ class PagesMapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const pagesNumber = PagesMapper.#pagesNumber;
|
const pagesNumber = this.#pagesNumber;
|
||||||
// target index after removing elements that were before it
|
// target index after removing elements that were before it
|
||||||
let adjustedTarget = index - removedBeforeTarget;
|
let adjustedTarget = index - removedBeforeTarget;
|
||||||
const remainingLen = pagesNumber - movedCount;
|
const remainingLen = pagesNumber - movedCount;
|
||||||
@ -1201,7 +1198,7 @@ class PagesMapper {
|
|||||||
* @returns {boolean} True if the mappings have been altered, false otherwise.
|
* @returns {boolean} True if the mappings have been altered, false otherwise.
|
||||||
*/
|
*/
|
||||||
hasBeenAltered() {
|
hasBeenAltered() {
|
||||||
return PagesMapper.#pageNumberToId !== null;
|
return this.#pageNumberToId !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1211,16 +1208,14 @@ class PagesMapper {
|
|||||||
getPageMappingForSaving() {
|
getPageMappingForSaving() {
|
||||||
// Saving is index-based.
|
// Saving is index-based.
|
||||||
return {
|
return {
|
||||||
pageIndices: PagesMapper.#idToPageNumber
|
pageIndices: this.#idToPageNumber
|
||||||
? PagesMapper.#idToPageNumber.map(x => x - 1)
|
? this.#idToPageNumber.map(x => x - 1)
|
||||||
: null,
|
: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
getPrevPageNumber(pageNumber) {
|
getPrevPageNumber(pageNumber) {
|
||||||
return PagesMapper.#prevIdToPageNumber[
|
return this.#prevIdToPageNumber[this.#pageNumberToId[pageNumber - 1] - 1];
|
||||||
PagesMapper.#pageNumberToId[pageNumber - 1] - 1
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1229,7 +1224,7 @@ class PagesMapper {
|
|||||||
* @returns {number} The page number, or the ID itself if no mapping exists.
|
* @returns {number} The page number, or the ID itself if no mapping exists.
|
||||||
*/
|
*/
|
||||||
getPageNumber(id) {
|
getPageNumber(id) {
|
||||||
return PagesMapper.#idToPageNumber?.[id - 1] ?? id;
|
return this.#idToPageNumber?.[id - 1] ?? id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1239,19 +1234,11 @@ class PagesMapper {
|
|||||||
* exists.
|
* exists.
|
||||||
*/
|
*/
|
||||||
getPageId(pageNumber) {
|
getPageId(pageNumber) {
|
||||||
return PagesMapper.#pageNumberToId?.[pageNumber - 1] ?? pageNumber;
|
return this.#pageNumberToId?.[pageNumber - 1] ?? pageNumber;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets or creates a singleton instance of PagesMapper.
|
|
||||||
* @returns {PagesMapper} The singleton instance.
|
|
||||||
*/
|
|
||||||
static get instance() {
|
|
||||||
return shadow(this, "instance", new PagesMapper());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getMapping() {
|
getMapping() {
|
||||||
return PagesMapper.#pageNumberToId.subarray(0, this.pagesNumber);
|
return this.#pageNumberToId.subarray(0, this.pagesNumber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -57,7 +57,6 @@ import {
|
|||||||
isPdfFile,
|
isPdfFile,
|
||||||
noContextMenu,
|
noContextMenu,
|
||||||
OutputScale,
|
OutputScale,
|
||||||
PagesMapper,
|
|
||||||
PDFDateString,
|
PDFDateString,
|
||||||
PixelsPerInch,
|
PixelsPerInch,
|
||||||
RenderingCancelledException,
|
RenderingCancelledException,
|
||||||
@ -129,7 +128,6 @@ globalThis.pdfjsLib = {
|
|||||||
normalizeUnicode,
|
normalizeUnicode,
|
||||||
OPS,
|
OPS,
|
||||||
OutputScale,
|
OutputScale,
|
||||||
PagesMapper,
|
|
||||||
PasswordResponses,
|
PasswordResponses,
|
||||||
PDFDataRangeTransport,
|
PDFDataRangeTransport,
|
||||||
PDFDateString,
|
PDFDateString,
|
||||||
@ -189,7 +187,6 @@ export {
|
|||||||
normalizeUnicode,
|
normalizeUnicode,
|
||||||
OPS,
|
OPS,
|
||||||
OutputScale,
|
OutputScale,
|
||||||
PagesMapper,
|
|
||||||
PasswordResponses,
|
PasswordResponses,
|
||||||
PDFDataRangeTransport,
|
PDFDataRangeTransport,
|
||||||
PDFDateString,
|
PDFDateString,
|
||||||
|
|||||||
@ -104,12 +104,12 @@ function movePages(page, selectedPages, atIndex) {
|
|||||||
return page.evaluate(
|
return page.evaluate(
|
||||||
(selected, index) => {
|
(selected, index) => {
|
||||||
const viewer = window.PDFViewerApplication.pdfViewer;
|
const viewer = window.PDFViewerApplication.pdfViewer;
|
||||||
|
const pagesMapper = viewer.pdfDocument.pagesMapper;
|
||||||
const pagesToMove = Array.from(selected).sort((a, b) => a - b);
|
const pagesToMove = Array.from(selected).sort((a, b) => a - b);
|
||||||
viewer.pagesMapper.pagesNumber =
|
pagesMapper.pagesNumber = document.querySelectorAll(".page").length;
|
||||||
document.querySelectorAll(".page").length;
|
pagesMapper.movePages(new Set(pagesToMove), pagesToMove, index);
|
||||||
viewer.pagesMapper.movePages(new Set(pagesToMove), pagesToMove, index);
|
|
||||||
window.PDFViewerApplication.eventBus.dispatch("pagesedited", {
|
window.PDFViewerApplication.eventBus.dispatch("pagesedited", {
|
||||||
pagesMapper: viewer.pagesMapper,
|
pagesMapper,
|
||||||
index,
|
index,
|
||||||
pagesToMove,
|
pagesToMove,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -5403,6 +5403,36 @@ small scripts as well as for`);
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("Multiple documents and pages mapper", function () {
|
||||||
|
it("should load multiple documents in parallel", async function () {
|
||||||
|
const loadingTask1 = getDocument(buildGetDocumentParams("pdkids.pdf"));
|
||||||
|
const loadingTask2 = getDocument(
|
||||||
|
buildGetDocumentParams("page_with_number.pdf")
|
||||||
|
);
|
||||||
|
const loadingTask3 = getDocument(buildGetDocumentParams("empty.pdf"));
|
||||||
|
|
||||||
|
const [pdfDoc1, pdfDoc2, pdfDoc3] = await Promise.all([
|
||||||
|
loadingTask1.promise,
|
||||||
|
loadingTask2.promise,
|
||||||
|
loadingTask3.promise,
|
||||||
|
]);
|
||||||
|
// Each document has its own pages mapper, so the number of pages
|
||||||
|
// should be correct for each document.
|
||||||
|
expect(pdfDoc1.numPages).toEqual(55);
|
||||||
|
expect(pdfDoc1.pagesMapper.pagesNumber).toEqual(55);
|
||||||
|
expect(pdfDoc2.numPages).toEqual(17);
|
||||||
|
expect(pdfDoc2.pagesMapper.pagesNumber).toEqual(17);
|
||||||
|
expect(pdfDoc3.numPages).toEqual(1);
|
||||||
|
expect(pdfDoc3.pagesMapper.pagesNumber).toEqual(1);
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
loadingTask1.destroy(),
|
||||||
|
loadingTask2.destroy(),
|
||||||
|
loadingTask3.destroy(),
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("PDF page editing", function () {
|
describe("PDF page editing", function () {
|
||||||
const getPageRefs = async pdfDoc => {
|
const getPageRefs = async pdfDoc => {
|
||||||
const refs = [];
|
const refs = [];
|
||||||
|
|||||||
@ -48,7 +48,6 @@ import {
|
|||||||
isPdfFile,
|
isPdfFile,
|
||||||
noContextMenu,
|
noContextMenu,
|
||||||
OutputScale,
|
OutputScale,
|
||||||
PagesMapper,
|
|
||||||
PDFDateString,
|
PDFDateString,
|
||||||
PixelsPerInch,
|
PixelsPerInch,
|
||||||
RenderingCancelledException,
|
RenderingCancelledException,
|
||||||
@ -113,7 +112,6 @@ const expectedAPI = Object.freeze({
|
|||||||
normalizeUnicode,
|
normalizeUnicode,
|
||||||
OPS,
|
OPS,
|
||||||
OutputScale,
|
OutputScale,
|
||||||
PagesMapper,
|
|
||||||
PasswordResponses,
|
PasswordResponses,
|
||||||
PDFDataRangeTransport,
|
PDFDataRangeTransport,
|
||||||
PDFDateString,
|
PDFDateString,
|
||||||
|
|||||||
@ -25,7 +25,7 @@ import {
|
|||||||
isValidRotation,
|
isValidRotation,
|
||||||
watchScroll,
|
watchScroll,
|
||||||
} from "./ui_utils.js";
|
} from "./ui_utils.js";
|
||||||
import { MathClamp, noContextMenu, PagesMapper, stopEvent } from "pdfjs-lib";
|
import { MathClamp, noContextMenu, stopEvent } from "pdfjs-lib";
|
||||||
import { Menu } from "./menu.js";
|
import { Menu } from "./menu.js";
|
||||||
import { PDFThumbnailView } from "./pdf_thumbnail_view.js";
|
import { PDFThumbnailView } from "./pdf_thumbnail_view.js";
|
||||||
import { RenderingStates } from "./renderable_view.js";
|
import { RenderingStates } from "./renderable_view.js";
|
||||||
@ -109,7 +109,7 @@ class PDFThumbnailViewer {
|
|||||||
|
|
||||||
#currentScrollTop = 0;
|
#currentScrollTop = 0;
|
||||||
|
|
||||||
#pagesMapper = PagesMapper.instance;
|
#pagesMapper = null;
|
||||||
|
|
||||||
#manageSaveAsButton = null;
|
#manageSaveAsButton = null;
|
||||||
|
|
||||||
@ -275,6 +275,7 @@ class PDFThumbnailViewer {
|
|||||||
if (!pdfDocument) {
|
if (!pdfDocument) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this.#pagesMapper = pdfDocument.pagesMapper;
|
||||||
const firstPagePromise = pdfDocument.getPage(1);
|
const firstPagePromise = pdfDocument.getPage(1);
|
||||||
const optionalContentConfigPromise = pdfDocument.getOptionalContentConfig({
|
const optionalContentConfigPromise = pdfDocument.getOptionalContentConfig({
|
||||||
intent: "display",
|
intent: "display",
|
||||||
|
|||||||
@ -30,7 +30,6 @@ import {
|
|||||||
AnnotationEditorUIManager,
|
AnnotationEditorUIManager,
|
||||||
AnnotationMode,
|
AnnotationMode,
|
||||||
MathClamp,
|
MathClamp,
|
||||||
PagesMapper,
|
|
||||||
PermissionFlag,
|
PermissionFlag,
|
||||||
PixelsPerInch,
|
PixelsPerInch,
|
||||||
shadow,
|
shadow,
|
||||||
@ -286,8 +285,6 @@ class PDFViewer {
|
|||||||
|
|
||||||
#viewerAlert = null;
|
#viewerAlert = null;
|
||||||
|
|
||||||
#pagesMapper = PagesMapper.instance;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {PDFViewerOptions} options
|
* @param {PDFViewerOptions} options
|
||||||
*/
|
*/
|
||||||
@ -299,9 +296,6 @@ class PDFViewer {
|
|||||||
`The API version "${version}" does not match the Viewer version "${viewerVersion}".`
|
`The API version "${version}" does not match the Viewer version "${viewerVersion}".`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
|
|
||||||
this.pagesMapper = PagesMapper.instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.container = options.container;
|
this.container = options.container;
|
||||||
this.viewer = options.viewer || options.container.firstElementChild;
|
this.viewer = options.viewer || options.container.firstElementChild;
|
||||||
@ -880,7 +874,6 @@ class PDFViewer {
|
|||||||
this.#annotationEditorMode = AnnotationEditorType.NONE;
|
this.#annotationEditorMode = AnnotationEditorType.NONE;
|
||||||
|
|
||||||
this.#printingAllowed = true;
|
this.#printingAllowed = true;
|
||||||
this.#pagesMapper.pagesNumber = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.pdfDocument = pdfDocument;
|
this.pdfDocument = pdfDocument;
|
||||||
|
|||||||
@ -49,7 +49,6 @@ const {
|
|||||||
normalizeUnicode,
|
normalizeUnicode,
|
||||||
OPS,
|
OPS,
|
||||||
OutputScale,
|
OutputScale,
|
||||||
PagesMapper,
|
|
||||||
PasswordResponses,
|
PasswordResponses,
|
||||||
PDFDataRangeTransport,
|
PDFDataRangeTransport,
|
||||||
PDFDateString,
|
PDFDateString,
|
||||||
@ -109,7 +108,6 @@ export {
|
|||||||
normalizeUnicode,
|
normalizeUnicode,
|
||||||
OPS,
|
OPS,
|
||||||
OutputScale,
|
OutputScale,
|
||||||
PagesMapper,
|
|
||||||
PasswordResponses,
|
PasswordResponses,
|
||||||
PDFDataRangeTransport,
|
PDFDataRangeTransport,
|
||||||
PDFDateString,
|
PDFDateString,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user