Bug 1899373 - Update PDF.js to 24e12d515dce2f11b392410dd6e6e9926270ac65 r=pdfjs-reviewers,frontend-codestyle-reviewers,marco

Differential Revision: https://phabricator.services.mozilla.com/D211891
This commit is contained in:
Updatebot 2024-05-30 12:35:49 +00:00
Родитель 48d2776de5
Коммит 12c12d12c3
10 изменённых файлов: 883 добавлений и 676 удалений

Просмотреть файл

@ -92,6 +92,7 @@ python/mozbuild/mozbuild/test/backend/data/build/foo.css
# This is third-party in a way: # This is third-party in a way:
toolkit/components/pdfjs/content/web/debugger.css toolkit/components/pdfjs/content/web/debugger.css
toolkit/components/pdfjs/content/web/viewer.css toolkit/components/pdfjs/content/web/viewer.css
toolkit/components/pdfjs/content/web/viewer-geckoview.css
# Ignore web-platform tests as they are not necessarily under our control. # Ignore web-platform tests as they are not necessarily under our control.
testing/web-platform/tests/ testing/web-platform/tests/

Просмотреть файл

@ -8872,7 +8872,7 @@ class TextLayer {
#textDivProperties = new WeakMap(); #textDivProperties = new WeakMap();
#transform = null; #transform = null;
static #ascentCache = new Map(); static #ascentCache = new Map();
static #canvasCtx = null; static #canvasContexts = new Map();
static #pendingTextLayers = new Set(); static #pendingTextLayers = new Set();
constructor({ constructor({
textContentSource, textContentSource,
@ -8904,7 +8904,6 @@ class TextLayer {
this.#pageWidth = pageWidth; this.#pageWidth = pageWidth;
this.#pageHeight = pageHeight; this.#pageHeight = pageHeight;
setLayerDimensions(container, viewport); setLayerDimensions(container, viewport);
TextLayer.#pendingTextLayers.add(this);
this.#capability.promise.catch(() => {}).then(() => { this.#capability.promise.catch(() => {}).then(() => {
TextLayer.#pendingTextLayers.delete(this); TextLayer.#pendingTextLayers.delete(this);
this.#layoutTextParams = null; this.#layoutTextParams = null;
@ -8928,6 +8927,7 @@ class TextLayer {
}, this.#capability.reject); }, this.#capability.reject);
}; };
this.#reader = this.#textContentSource.getReader(); this.#reader = this.#textContentSource.getReader();
TextLayer.#pendingTextLayers.add(this);
pump(); pump();
return this.#capability.promise; return this.#capability.promise;
} }
@ -9122,19 +9122,26 @@ class TextLayer {
return; return;
} }
this.#ascentCache.clear(); this.#ascentCache.clear();
this.#canvasCtx?.canvas.remove(); for (const {
this.#canvasCtx = null; canvas
} of this.#canvasContexts.values()) {
canvas.remove();
}
this.#canvasContexts.clear();
} }
static #getCtx(lang = null) { static #getCtx(lang = null) {
if (!this.#canvasCtx) { let canvasContext = this.#canvasContexts.get(lang ||= "");
if (!canvasContext) {
const canvas = document.createElement("canvas"); const canvas = document.createElement("canvas");
canvas.className = "hiddenCanvasElement"; canvas.className = "hiddenCanvasElement";
canvas.lang = lang;
document.body.append(canvas); document.body.append(canvas);
this.#canvasCtx = canvas.getContext("2d", { canvasContext = canvas.getContext("2d", {
alpha: false alpha: false
}); });
this.#canvasContexts.set(lang, canvasContext);
} }
return this.#canvasCtx; return canvasContext;
} }
static #getAscent(fontFamily, lang) { static #getAscent(fontFamily, lang) {
const cachedAscent = this.#ascentCache.get(fontFamily); const cachedAscent = this.#ascentCache.get(fontFamily);
@ -9327,7 +9334,7 @@ function getDocument(src) {
} }
const docParams = { const docParams = {
docId, docId,
apiVersion: "4.3.83", apiVersion: "4.3.138",
data, data,
password, password,
disableAutoFetch, disableAutoFetch,
@ -9351,11 +9358,13 @@ function getDocument(src) {
const transportParams = { const transportParams = {
disableFontFace, disableFontFace,
fontExtraProperties, fontExtraProperties,
enableXfa,
ownerDocument, ownerDocument,
disableAutoFetch,
pdfBug, pdfBug,
styleElement styleElement,
loadingParams: {
disableAutoFetch,
enableXfa
}
}; };
worker.promise.then(function () { worker.promise.then(function () {
if (task.destroyed) { if (task.destroyed) {
@ -10227,6 +10236,7 @@ class WorkerTransport {
ownerDocument: params.ownerDocument, ownerDocument: params.ownerDocument,
styleElement: params.styleElement styleElement: params.styleElement
}); });
this.loadingParams = params.loadingParams;
this._params = params; this._params = params;
this.canvasFactory = factory.canvasFactory; this.canvasFactory = factory.canvasFactory;
this.filterFactory = factory.filterFactory; this.filterFactory = factory.filterFactory;
@ -10768,16 +10778,6 @@ 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}`;
return this.#pageRefCache.get(refStr) ?? null; return this.#pageRefCache.get(refStr) ?? null;
} }
get loadingParams() {
const {
disableAutoFetch,
enableXfa
} = this._params;
return shadow(this, "loadingParams", {
disableAutoFetch,
enableXfa
});
}
} }
const INITIAL_DATA = Symbol("INITIAL_DATA"); const INITIAL_DATA = Symbol("INITIAL_DATA");
class PDFObjects { class PDFObjects {
@ -10989,8 +10989,8 @@ class InternalRenderTask {
} }
} }
} }
const version = "4.3.83"; const version = "4.3.138";
const build = "9ee7c07b8"; const build = "24e12d515";
;// CONCATENATED MODULE: ./src/shared/scripting_utils.js ;// CONCATENATED MODULE: ./src/shared/scripting_utils.js
function makeColorComp(n) { function makeColorComp(n) {
@ -11341,6 +11341,7 @@ class AnnotationElementFactory {
class AnnotationElement { class AnnotationElement {
#updates = null; #updates = null;
#hasBorder = false; #hasBorder = false;
#popupElement = null;
constructor(parameters, { constructor(parameters, {
isRenderable = false, isRenderable = false,
ignoreBorder = false, ignoreBorder = false,
@ -11389,12 +11390,14 @@ class AnnotationElement {
if (rect) { if (rect) {
this.#setRectEdited(rect); this.#setRectEdited(rect);
} }
this.#popupElement?.popup.updateEdited(params);
} }
resetEdited() { resetEdited() {
if (!this.#updates) { if (!this.#updates) {
return; return;
} }
this.#setRectEdited(this.#updates.rect); this.#setRectEdited(this.#updates.rect);
this.#popupElement?.popup.resetEdited();
this.#updates = null; this.#updates = null;
} }
#setRectEdited(rect) { #setRectEdited(rect) {
@ -11744,7 +11747,7 @@ class AnnotationElement {
data data
} = this; } = this;
container.setAttribute("aria-haspopup", "dialog"); container.setAttribute("aria-haspopup", "dialog");
const popup = new PopupAnnotationElement({ const popup = this.#popupElement = new PopupAnnotationElement({
data: { data: {
color: data.color, color: data.color,
titleObj: data.titleObj, titleObj: data.titleObj,
@ -12946,10 +12949,11 @@ class PopupAnnotationElement extends AnnotationElement {
isRenderable: AnnotationElement._hasPopupData(data) isRenderable: AnnotationElement._hasPopupData(data)
}); });
this.elements = elements; this.elements = elements;
this.popup = null;
} }
render() { render() {
this.container.classList.add("popupAnnotation"); this.container.classList.add("popupAnnotation");
const popup = new PopupElement({ const popup = this.popup = new PopupElement({
container: this.container, container: this.container,
color: this.data.color, color: this.data.color,
titleObj: this.data.titleObj, titleObj: this.data.titleObj,
@ -12986,9 +12990,11 @@ class PopupElement {
#parentRect = null; #parentRect = null;
#pinned = false; #pinned = false;
#popup = null; #popup = null;
#position = null;
#rect = null; #rect = null;
#richText = null; #richText = null;
#titleObj = null; #titleObj = null;
#updates = null;
#wasVisible = false; #wasVisible = false;
constructor({ constructor({
container, container,
@ -13032,19 +13038,6 @@ class PopupElement {
if (this.#popup) { if (this.#popup) {
return; return;
} }
const {
page: {
view
},
viewport: {
rawDims: {
pageWidth,
pageHeight,
pageX,
pageY
}
}
} = this.#parent;
const popup = this.#popup = document.createElement("div"); const popup = this.#popup = document.createElement("div");
popup.className = "popup"; popup.className = "popup";
if (this.#color) { if (this.#color) {
@ -13070,40 +13063,64 @@ class PopupElement {
})); }));
header.append(modificationDate); header.append(modificationDate);
} }
const contentsObj = this.#contentsObj; const html = this.#html;
const richText = this.#richText; if (html) {
if (richText?.str && (!contentsObj?.str || contentsObj.str === richText.str)) {
XfaLayer.render({ XfaLayer.render({
xfaHtml: richText.html, xfaHtml: html,
intent: "richText", intent: "richText",
div: popup div: popup
}); });
popup.lastChild.classList.add("richText", "popupContent"); popup.lastChild.classList.add("richText", "popupContent");
} else { } else {
const contents = this._formatContents(contentsObj); const contents = this._formatContents(this.#contentsObj);
popup.append(contents); popup.append(contents);
} }
let useParentRect = !!this.#parentRect;
let rect = useParentRect ? this.#parentRect : this.#rect;
for (const element of this.#elements) {
if (!rect || Util.intersect(element.data.rect, rect) !== null) {
rect = element.data.rect;
useParentRect = true;
break;
}
}
const normalizedRect = Util.normalizeRect([rect[0], view[3] - rect[1] + view[1], rect[2], view[3] - rect[3] + view[1]]);
const HORIZONTAL_SPACE_AFTER_ANNOTATION = 5;
const parentWidth = useParentRect ? rect[2] - rect[0] + HORIZONTAL_SPACE_AFTER_ANNOTATION : 0;
const popupLeft = normalizedRect[0] + parentWidth;
const popupTop = normalizedRect[1];
const {
style
} = this.#container;
style.left = `${100 * (popupLeft - pageX) / pageWidth}%`;
style.top = `${100 * (popupTop - pageY) / pageHeight}%`;
this.#container.append(popup); this.#container.append(popup);
} }
get #html() {
const richText = this.#richText;
const contentsObj = this.#contentsObj;
if (richText?.str && (!contentsObj?.str || contentsObj.str === richText.str)) {
return this.#richText.html || null;
}
return null;
}
get #fontSize() {
return this.#html?.attributes?.style?.fontSize || 0;
}
get #fontColor() {
return this.#html?.attributes?.style?.color || null;
}
#makePopupContent(text) {
const popupLines = [];
const popupContent = {
str: text,
html: {
name: "div",
attributes: {
dir: "auto"
},
children: [{
name: "p",
children: popupLines
}]
}
};
const lineAttributes = {
style: {
color: this.#fontColor,
fontSize: this.#fontSize ? `calc(${this.#fontSize}px * var(--scale-factor))` : ""
}
};
for (const line of text.split("\n")) {
popupLines.push({
name: "span",
value: line,
attributes: lineAttributes
});
}
return popupContent;
}
_formatContents({ _formatContents({
str, str,
dir dir
@ -13129,6 +13146,75 @@ class PopupElement {
this.#toggle(); this.#toggle();
} }
} }
updateEdited({
rect,
popupContent
}) {
this.#updates ||= {
contentsObj: this.#contentsObj,
richText: this.#richText
};
if (rect) {
this.#position = null;
}
if (popupContent) {
this.#richText = this.#makePopupContent(popupContent);
this.#contentsObj = null;
}
this.#popup?.remove();
this.#popup = null;
}
resetEdited() {
if (!this.#updates) {
return;
}
({
contentsObj: this.#contentsObj,
richText: this.#richText
} = this.#updates);
this.#updates = null;
this.#popup?.remove();
this.#popup = null;
this.#position = null;
}
#setPosition() {
if (this.#position !== null) {
return;
}
const {
page: {
view
},
viewport: {
rawDims: {
pageWidth,
pageHeight,
pageX,
pageY
}
}
} = this.#parent;
let useParentRect = !!this.#parentRect;
let rect = useParentRect ? this.#parentRect : this.#rect;
for (const element of this.#elements) {
if (!rect || Util.intersect(element.data.rect, rect) !== null) {
rect = element.data.rect;
useParentRect = true;
break;
}
}
const normalizedRect = Util.normalizeRect([rect[0], view[3] - rect[1] + view[1], rect[2], view[3] - rect[3] + view[1]]);
const HORIZONTAL_SPACE_AFTER_ANNOTATION = 5;
const parentWidth = useParentRect ? rect[2] - rect[0] + HORIZONTAL_SPACE_AFTER_ANNOTATION : 0;
const popupLeft = normalizedRect[0] + parentWidth;
const popupTop = normalizedRect[1];
this.#position = [100 * (popupLeft - pageX) / pageWidth, 100 * (popupTop - pageY) / pageHeight];
const {
style
} = this.#container;
style.left = `${this.#position[0]}%`;
style.top = `${this.#position[1]}%`;
}
#toggle() { #toggle() {
this.#pinned = !this.#pinned; this.#pinned = !this.#pinned;
if (this.#pinned) { if (this.#pinned) {
@ -13146,6 +13232,7 @@ class PopupElement {
this.render(); this.render();
} }
if (!this.isVisible) { if (!this.isVisible) {
this.#setPosition();
this.#container.hidden = false; this.#container.hidden = false;
this.#container.style.zIndex = parseInt(this.#container.style.zIndex) + 1000; this.#container.style.zIndex = parseInt(this.#container.style.zIndex) + 1000;
} else if (this.#pinned) { } else if (this.#pinned) {
@ -13171,6 +13258,9 @@ class PopupElement {
if (!this.#wasVisible) { if (!this.#wasVisible) {
return; return;
} }
if (!this.#popup) {
this.#show();
}
this.#wasVisible = false; this.#wasVisible = false;
this.#container.hidden = false; this.#container.hidden = false;
} }
@ -14317,7 +14407,8 @@ class FreeTextEditor extends AnnotationEditor {
} }
const padding = FreeTextEditor._internalPadding * this.parentScale; const padding = FreeTextEditor._internalPadding * this.parentScale;
annotation.updateEdited({ annotation.updateEdited({
rect: this.getRect(padding, padding) rect: this.getRect(padding, padding),
popupContent: this.#content
}); });
return content; return content;
} }
@ -16828,26 +16919,22 @@ class StampEditor extends AnnotationEditor {
const offscreen = new OffscreenCanvas(width, height); const offscreen = new OffscreenCanvas(width, height);
const ctx = offscreen.getContext("2d"); const ctx = offscreen.getContext("2d");
ctx.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height, 0, 0, width, height); ctx.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height, 0, 0, width, height);
offscreen.convertToBlob().then(blob => { this._uiManager.mlGuess({
const fileReader = new FileReader(); service: "image-to-text",
fileReader.onload = () => { request: {
const url = fileReader.result; data: ctx.getImageData(0, 0, width, height).data,
this._uiManager.mlGuess({ width,
service: "image-to-text", height,
request: { channels: 4
imageData: url }
} }).then(response => {
}).then(response => { const altText = response?.output || "";
const altText = response?.output || ""; if (this.parent && altText && !this.hasAltText()) {
if (this.parent && altText && !this.hasAltText()) { this.altTextData = {
this.altTextData = { altText,
altText, decorative: false
decorative: false };
}; }
}
});
};
fileReader.readAsDataURL(blob);
}); });
} }
const ctx = canvas.getContext("2d"); const ctx = canvas.getContext("2d");
@ -17776,8 +17863,8 @@ class DrawLayer {
const pdfjsVersion = "4.3.83"; const pdfjsVersion = "4.3.138";
const pdfjsBuild = "9ee7c07b8"; const pdfjsBuild = "24e12d515";
var __webpack_exports__AbortException = __webpack_exports__.AbortException; var __webpack_exports__AbortException = __webpack_exports__.AbortException;
var __webpack_exports__AnnotationEditorLayer = __webpack_exports__.AnnotationEditorLayer; var __webpack_exports__AnnotationEditorLayer = __webpack_exports__.AnnotationEditorLayer;

Просмотреть файл

@ -3956,8 +3956,8 @@ function initSandbox(params) {
;// CONCATENATED MODULE: ./src/pdf.scripting.js ;// CONCATENATED MODULE: ./src/pdf.scripting.js
const pdfjsVersion = "4.3.83"; const pdfjsVersion = "4.3.138";
const pdfjsBuild = "9ee7c07b8"; const pdfjsBuild = "24e12d515";
globalThis.pdfjsScripting = { globalThis.pdfjsScripting = {
initSandbox: initSandbox initSandbox: initSandbox
}; };

Просмотреть файл

@ -8844,13 +8844,17 @@ class Parser {
this.shift(); this.shift();
return imageStream; return imageStream;
} }
_findStreamLength(startPos, signature) { #findStreamLength(startPos) {
const { const {
stream stream
} = this.lexer; } = this.lexer;
stream.pos = startPos; stream.pos = startPos;
const SCAN_BLOCK_LENGTH = 2048; const SCAN_BLOCK_LENGTH = 2048;
const signatureLength = signature.length; const signatureLength = "endstream".length;
const END_SIGNATURE = new Uint8Array([0x65, 0x6e, 0x64]);
const endLength = END_SIGNATURE.length;
const PARTIAL_SIGNATURE = [new Uint8Array([0x73, 0x74, 0x72, 0x65, 0x61, 0x6d]), new Uint8Array([0x73, 0x74, 0x65, 0x61, 0x6d]), new Uint8Array([0x73, 0x74, 0x72, 0x65, 0x61])];
const normalLength = signatureLength - endLength;
while (stream.pos < stream.end) { while (stream.pos < stream.end) {
const scanBytes = stream.peekBytes(SCAN_BLOCK_LENGTH); const scanBytes = stream.peekBytes(SCAN_BLOCK_LENGTH);
const scanLength = scanBytes.length - signatureLength; const scanLength = scanBytes.length - signatureLength;
@ -8860,12 +8864,34 @@ class Parser {
let pos = 0; let pos = 0;
while (pos < scanLength) { while (pos < scanLength) {
let j = 0; let j = 0;
while (j < signatureLength && scanBytes[pos + j] === signature[j]) { while (j < endLength && scanBytes[pos + j] === END_SIGNATURE[j]) {
j++; j++;
} }
if (j >= signatureLength) { if (j >= endLength) {
stream.pos += pos; let found = false;
return stream.pos - startPos; for (const part of PARTIAL_SIGNATURE) {
const partLen = part.length;
let k = 0;
while (k < partLen && scanBytes[pos + j + k] === part[k]) {
k++;
}
if (k >= normalLength) {
found = true;
break;
}
if (k >= partLen) {
const lastByte = scanBytes[pos + j + k];
if (isWhiteSpace(lastByte)) {
info(`Found "${bytesToString([...END_SIGNATURE, ...part])}" when ` + "searching for endstream command.");
found = true;
}
break;
}
}
if (found) {
stream.pos += pos;
return stream.pos - startPos;
}
} }
pos++; pos++;
} }
@ -8888,29 +8914,10 @@ class Parser {
if (this.tryShift() && isCmd(this.buf2, "endstream")) { if (this.tryShift() && isCmd(this.buf2, "endstream")) {
this.shift(); this.shift();
} else { } else {
const ENDSTREAM_SIGNATURE = new Uint8Array([0x65, 0x6e, 0x64, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d]); length = this.#findStreamLength(startPos);
let actualLength = this._findStreamLength(startPos, ENDSTREAM_SIGNATURE); if (length < 0) {
if (actualLength < 0) { throw new FormatError("Missing endstream command.");
const MAX_TRUNCATION = 1;
for (let i = 1; i <= MAX_TRUNCATION; i++) {
const end = ENDSTREAM_SIGNATURE.length - i;
const TRUNCATED_SIGNATURE = ENDSTREAM_SIGNATURE.slice(0, end);
const maybeLength = this._findStreamLength(startPos, TRUNCATED_SIGNATURE);
if (maybeLength >= 0) {
const lastByte = stream.peekBytes(end + 1)[end];
if (!isWhiteSpace(lastByte)) {
break;
}
info(`Found "${bytesToString(TRUNCATED_SIGNATURE)}" when ` + "searching for endstream command.");
actualLength = maybeLength;
break;
}
}
if (actualLength < 0) {
throw new FormatError("Missing endstream command.");
}
} }
length = actualLength;
lexer.nextChar(); lexer.nextChar();
this.shift(); this.shift();
this.shift(); this.shift();
@ -29672,7 +29679,7 @@ class PartialEvaluator {
this.globalImageCache = globalImageCache; this.globalImageCache = globalImageCache;
this.systemFontCache = systemFontCache; this.systemFontCache = systemFontCache;
this.options = options || DefaultPartialEvaluatorOptions; this.options = options || DefaultPartialEvaluatorOptions;
this.parsingType3Font = false; this.type3FontRefs = null;
this._regionalImageCache = new RegionalImageCache(); this._regionalImageCache = new RegionalImageCache();
this._fetchBuiltInCMapBound = this.fetchBuiltInCMap.bind(this); this._fetchBuiltInCMapBound = this.fetchBuiltInCMap.bind(this);
ImageResizer.setMaxArea(this.options.canvasMaxAreaInBytes); ImageResizer.setMaxArea(this.options.canvasMaxAreaInBytes);
@ -29684,6 +29691,9 @@ class PartialEvaluator {
}); });
return shadow(this, "_pdfFunctionFactory", pdfFunctionFactory); return shadow(this, "_pdfFunctionFactory", pdfFunctionFactory);
} }
get parsingType3Font() {
return !!this.type3FontRefs;
}
clone(newOptions = null) { clone(newOptions = null) {
const newEvaluator = Object.create(this); const newEvaluator = Object.create(this);
newEvaluator.options = Object.assign(Object.create(null), this.options, newOptions); newEvaluator.options = Object.assign(Object.create(null), this.options, newOptions);
@ -30372,13 +30382,17 @@ class PartialEvaluator {
} }
} }
if (fontRef) { if (fontRef) {
if (this.parsingType3Font && this.type3FontRefs.has(fontRef)) { if (this.type3FontRefs?.has(fontRef)) {
return errorFont(); return errorFont();
} }
if (this.fontCache.has(fontRef)) { if (this.fontCache.has(fontRef)) {
return this.fontCache.get(fontRef); return this.fontCache.get(fontRef);
} }
font = this.xref.fetchIfRef(fontRef); try {
font = this.xref.fetchIfRef(fontRef);
} catch (ex) {
warn(`loadFont - lookup failed: "${ex}".`);
}
} }
if (!(font instanceof Dict)) { if (!(font instanceof Dict)) {
if (!this.options.ignoreErrors && !this.parsingType3Font) { if (!this.options.ignoreErrors && !this.parsingType3Font) {
@ -32803,7 +32817,6 @@ class TranslatedFont {
const type3Evaluator = evaluator.clone({ const type3Evaluator = evaluator.clone({
ignoreErrors: false ignoreErrors: false
}); });
type3Evaluator.parsingType3Font = true;
const type3FontRefs = new RefSet(evaluator.type3FontRefs); const type3FontRefs = new RefSet(evaluator.type3FontRefs);
if (this.dict.objId && !type3FontRefs.has(this.dict.objId)) { if (this.dict.objId && !type3FontRefs.has(this.dict.objId)) {
type3FontRefs.put(this.dict.objId); type3FontRefs.put(this.dict.objId);
@ -53665,52 +53678,49 @@ class Page {
systemFontCache: this.systemFontCache, systemFontCache: this.systemFontCache,
options: this.evaluatorOptions options: this.evaluatorOptions
}); });
const newAnnotationsByPage = !this.xfaFactory ? getNewAnnotationsMap(annotationStorage) : null; const newAnnotsByPage = !this.xfaFactory ? getNewAnnotationsMap(annotationStorage) : null;
let deletedAnnotations = null; const newAnnots = newAnnotsByPage?.get(this.pageIndex);
let newAnnotationsPromise = Promise.resolve(null); let newAnnotationsPromise = Promise.resolve(null);
if (newAnnotationsByPage) { let deletedAnnotations = null;
const newAnnotations = newAnnotationsByPage.get(this.pageIndex); if (newAnnots) {
if (newAnnotations) { const annotationGlobalsPromise = this.pdfManager.ensureDoc("annotationGlobals");
const annotationGlobalsPromise = this.pdfManager.ensureDoc("annotationGlobals"); let imagePromises;
let imagePromises; const missingBitmaps = new Set();
const missingBitmaps = new Set(); for (const {
for (const { bitmapId,
bitmapId, bitmap
bitmap } of newAnnots) {
} of newAnnotations) { if (bitmapId && !bitmap && !missingBitmaps.has(bitmapId)) {
if (bitmapId && !bitmap && !missingBitmaps.has(bitmapId)) { missingBitmaps.add(bitmapId);
missingBitmaps.add(bitmapId);
}
} }
const {
isOffscreenCanvasSupported
} = this.evaluatorOptions;
if (missingBitmaps.size > 0) {
const annotationWithBitmaps = newAnnotations.slice();
for (const [key, annotation] of annotationStorage) {
if (!key.startsWith(AnnotationEditorPrefix)) {
continue;
}
if (annotation.bitmap && missingBitmaps.has(annotation.bitmapId)) {
annotationWithBitmaps.push(annotation);
}
}
imagePromises = AnnotationFactory.generateImages(annotationWithBitmaps, this.xref, isOffscreenCanvasSupported);
} else {
imagePromises = AnnotationFactory.generateImages(newAnnotations, this.xref, isOffscreenCanvasSupported);
}
deletedAnnotations = new RefSet();
this.#replaceIdByRef(newAnnotations, deletedAnnotations, null);
newAnnotationsPromise = annotationGlobalsPromise.then(annotationGlobals => {
if (!annotationGlobals) {
return null;
}
return AnnotationFactory.printNewAnnotations(annotationGlobals, partialEvaluator, task, newAnnotations, imagePromises);
});
} }
const {
isOffscreenCanvasSupported
} = this.evaluatorOptions;
if (missingBitmaps.size > 0) {
const annotationWithBitmaps = newAnnots.slice();
for (const [key, annotation] of annotationStorage) {
if (!key.startsWith(AnnotationEditorPrefix)) {
continue;
}
if (annotation.bitmap && missingBitmaps.has(annotation.bitmapId)) {
annotationWithBitmaps.push(annotation);
}
}
imagePromises = AnnotationFactory.generateImages(annotationWithBitmaps, this.xref, isOffscreenCanvasSupported);
} else {
imagePromises = AnnotationFactory.generateImages(newAnnots, this.xref, isOffscreenCanvasSupported);
}
deletedAnnotations = new RefSet();
this.#replaceIdByRef(newAnnots, deletedAnnotations, null);
newAnnotationsPromise = annotationGlobalsPromise.then(annotationGlobals => {
if (!annotationGlobals) {
return null;
}
return AnnotationFactory.printNewAnnotations(annotationGlobals, partialEvaluator, task, newAnnots, imagePromises);
});
} }
const dataPromises = Promise.all([contentStreamPromise, resourcesPromise]); const pageListPromise = Promise.all([contentStreamPromise, resourcesPromise]).then(([contentStream]) => {
const pageListPromise = dataPromises.then(([contentStream]) => {
const opList = new OperatorList(intent, sink); const opList = new OperatorList(intent, sink);
handler.send("StartRenderPage", { handler.send("StartRenderPage", {
transparency: partialEvaluator.hasBlendModes(this.resources, this.nonBlendModesSet), transparency: partialEvaluator.hasBlendModes(this.resources, this.nonBlendModesSet),
@ -54497,7 +54507,7 @@ class PDFDocument {
if (type instanceof Ref) { if (type instanceof Ref) {
type = await xref.fetchAsync(type); type = await xref.fetchAsync(type);
} }
if (isName(type, "Page") || !obj.has("Type") && !obj.has("Kids")) { if (isName(type, "Page") || !obj.has("Type") && !obj.has("Kids") && obj.has("Contents")) {
if (!catalog.pageKidsCountCache.has(ref)) { if (!catalog.pageKidsCountCache.has(ref)) {
catalog.pageKidsCountCache.put(ref, 1); catalog.pageKidsCountCache.put(ref, 1);
} }
@ -55475,7 +55485,7 @@ class WorkerMessageHandler {
docId, docId,
apiVersion apiVersion
} = docParams; } = docParams;
const workerVersion = "4.3.83"; const workerVersion = "4.3.138";
if (apiVersion !== workerVersion) { if (apiVersion !== workerVersion) {
throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`); throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`);
} }
@ -56038,8 +56048,8 @@ if (typeof window === "undefined" && !isNodeJS && typeof self !== "undefined" &&
;// CONCATENATED MODULE: ./src/pdf.worker.js ;// CONCATENATED MODULE: ./src/pdf.worker.js
const pdfjsVersion = "4.3.83"; const pdfjsVersion = "4.3.138";
const pdfjsBuild = "9ee7c07b8"; const pdfjsBuild = "24e12d515";
var __webpack_exports__WorkerMessageHandler = __webpack_exports__.WorkerMessageHandler; var __webpack_exports__WorkerMessageHandler = __webpack_exports__.WorkerMessageHandler;
export { __webpack_exports__WorkerMessageHandler as WorkerMessageHandler }; export { __webpack_exports__WorkerMessageHandler as WorkerMessageHandler };

Просмотреть файл

@ -13,6 +13,216 @@
* limitations under the License. * limitations under the License.
*/ */
.dialog{
--dialog-bg-color:white;
--dialog-border-color:white;
--dialog-shadow:0 2px 14px 0 rgb(58 57 68 / 0.2);
--text-primary-color:#15141a;
--text-secondary-color:#5b5b66;
--hover-filter:brightness(0.9);
--focus-ring-color:#0060df;
--focus-ring-outline:2px solid var(--focus-ring-color);
--textarea-border-color:#8f8f9d;
--textarea-bg-color:white;
--textarea-fg-color:var(--text-secondary-color);
--radio-bg-color:#f0f0f4;
--radio-checked-bg-color:#fbfbfe;
--radio-border-color:#8f8f9d;
--radio-checked-border-color:#0060df;
--button-secondary-bg-color:#f0f0f4;
--button-secondary-fg-color:var(--text-primary-color);
--button-secondary-border-color:var(--button-secondary-bg-color);
--button-secondary-hover-bg-color:var(--button-secondary-bg-color);
--button-secondary-hover-fg-color:var(--button-secondary-fg-color);
--button-secondary-hover-border-color:var(--button-secondary-hover-bg-color);
--button-primary-bg-color:#0060df;
--button-primary-fg-color:#fbfbfe;
--button-primary-hover-bg-color:var(--button-primary-bg-color);
--button-primary-hover-fg-color:var(--button-primary-fg-color);
--button-primary-hover-border-color:var(--button-primary-hover-bg-color);
@media (prefers-color-scheme: dark){
--dialog-bg-color:#1c1b22;
--dialog-border-color:#1c1b22;
--dialog-shadow:0 2px 14px 0 #15141a;
--text-primary-color:#fbfbfe;
--text-secondary-color:#cfcfd8;
--focus-ring-color:#0df;
--hover-filter:brightness(1.4);
--textarea-bg-color:#42414d;
--radio-bg-color:#2b2a33;
--radio-checked-bg-color:#15141a;
--radio-checked-border-color:#0df;
--button-secondary-bg-color:#2b2a33;
--button-primary-bg-color:#0df;
--button-primary-fg-color:#15141a;
}
@media screen and (forced-colors: active){
--dialog-bg-color:Canvas;
--dialog-border-color:CanvasText;
--dialog-shadow:none;
--text-primary-color:CanvasText;
--text-secondary-color:CanvasText;
--hover-filter:none;
--focus-ring-color:ButtonBorder;
--textarea-border-color:ButtonBorder;
--textarea-bg-color:Field;
--textarea-fg-color:ButtonText;
--radio-bg-color:ButtonFace;
--radio-checked-bg-color:ButtonFace;
--radio-border-color:ButtonText;
--radio-checked-border-color:ButtonText;
--button-secondary-bg-color:ButtonFace;
--button-secondary-fg-color:ButtonText;
--button-secondary-border-color:ButtonText;
--button-secondary-hover-bg-color:AccentColor;
--button-secondary-hover-fg-color:AccentColorText;
--button-primary-bg-color:ButtonText;
--button-primary-fg-color:ButtonFace;
--button-primary-hover-bg-color:AccentColor;
--button-primary-hover-fg-color:AccentColorText;
}
font:message-box;
font-size:13px;
font-weight:400;
line-height:150%;
border-radius:4px;
padding:12px 16px;
border:1px solid var(--dialog-border-color);
background:var(--dialog-bg-color);
color:var(--text-primary-color);
box-shadow:var(--dialog-shadow);
.mainContainer{
*:focus-visible{
outline:var(--focus-ring-outline);
outline-offset:2px;
}
.radio{
display:flex;
flex-direction:column;
align-items:flex-start;
gap:4px;
> .radioButton{
display:flex;
gap:8px;
align-self:stretch;
align-items:center;
input{
appearance:none;
box-sizing:border-box;
width:16px;
height:16px;
border-radius:50%;
background-color:var(--radio-bg-color);
border:1px solid var(--radio-border-color);
&:hover{
filter:var(--hover-filter);
}
&:checked{
background-color:var(--radio-checked-bg-color);
border:4px solid var(--radio-checked-border-color);
}
}
}
> .radioLabel{
display:flex;
padding-inline-start:24px;
align-items:flex-start;
gap:10px;
align-self:stretch;
> span{
flex:1 0 0;
font-size:11px;
color:var(--text-secondary-color);
}
}
}
button{
border-radius:4px;
border:1px solid;
font:menu;
font-weight:600;
padding:4px 16px;
width:auto;
height:32px;
&:hover{
cursor:pointer;
filter:var(--hover-filter);
}
&.secondaryButton{
color:var(--button-secondary-fg-color);
background-color:var(--button-secondary-bg-color);
border-color:var(--button-secondary-border-color);
&:hover{
color:var(--button-secondary-hover-fg-color);
background-color:var(--button-secondary-hover-bg-color);
border-color:var(--button-secondary-hover-border-color);
}
}
&.primaryButton{
color:var(--button-primary-hover-fg-color);
background-color:var(--button-primary-hover-bg-color);
border-color:var(--button-primary-hover-border-color);
opacity:1;
&:hover{
color:var(--button-primary-hover-fg-color);
background-color:var(--button-primary-hover-bg-color);
border-color:var(--button-primary-hover-border-color);
}
}
}
textarea{
font:inherit;
padding:8px;
resize:none;
margin:0;
box-sizing:border-box;
border-radius:4px;
border:1px solid var(--textarea-border-color);
background:var(--textarea-bg-color);
color:var(--textarea-fg-color);
&:focus{
outline-offset:0;
border-color:transparent;
}
&:disabled{
pointer-events:none;
opacity:0.4;
}
}
}
}
.textLayer{ .textLayer{
position:absolute; position:absolute;
text-align:initial; text-align:initial;

Просмотреть файл

@ -4885,17 +4885,18 @@ class TextHighlighter {
class TextLayerBuilder { class TextLayerBuilder {
#enablePermissions = false; #enablePermissions = false;
#onAppend = null; #onAppend = null;
#textContentSource = null; #renderingDone = false;
#textLayer = null; #textLayer = null;
static #textLayers = new Map(); static #textLayers = new Map();
static #selectionChangeAbortController = null; static #selectionChangeAbortController = null;
constructor({ constructor({
pdfPage,
highlighter = null, highlighter = null,
accessibilityManager = null, accessibilityManager = null,
enablePermissions = false, enablePermissions = false,
onAppend = null onAppend = null
}) { }) {
this.renderingDone = false; this.pdfPage = pdfPage;
this.highlighter = highlighter; this.highlighter = highlighter;
this.accessibilityManager = accessibilityManager; this.accessibilityManager = accessibilityManager;
this.#enablePermissions = enablePermissions === true; this.#enablePermissions = enablePermissions === true;
@ -4905,17 +4906,14 @@ class TextLayerBuilder {
this.div.className = "textLayer"; this.div.className = "textLayer";
} }
#finishRendering() { #finishRendering() {
this.renderingDone = true; this.#renderingDone = true;
const endOfContent = document.createElement("div"); const endOfContent = document.createElement("div");
endOfContent.className = "endOfContent"; endOfContent.className = "endOfContent";
this.div.append(endOfContent); this.div.append(endOfContent);
this.#bindMouse(endOfContent); this.#bindMouse(endOfContent);
} }
async render(viewport) { async render(viewport, textContentParams = null) {
if (!this.#textContentSource) { if (this.#renderingDone && this.#textLayer) {
throw new Error('No "textContentSource" parameter specified.');
}
if (this.renderingDone && this.#textLayer) {
this.#textLayer.update({ this.#textLayer.update({
viewport, viewport,
onBefore: this.hide.bind(this) onBefore: this.hide.bind(this)
@ -4925,7 +4923,10 @@ class TextLayerBuilder {
} }
this.cancel(); this.cancel();
this.#textLayer = new TextLayer({ this.#textLayer = new TextLayer({
textContentSource: this.#textContentSource, textContentSource: this.pdfPage.streamTextContent(textContentParams || {
includeMarkedContent: true,
disableNormalization: true
}),
container: this.div, container: this.div,
viewport viewport
}); });
@ -4942,13 +4943,13 @@ class TextLayerBuilder {
this.accessibilityManager?.enable(); this.accessibilityManager?.enable();
} }
hide() { hide() {
if (!this.div.hidden && this.renderingDone) { if (!this.div.hidden && this.#renderingDone) {
this.highlighter?.disable(); this.highlighter?.disable();
this.div.hidden = true; this.div.hidden = true;
} }
} }
show() { show() {
if (this.div.hidden && this.renderingDone) { if (this.div.hidden && this.#renderingDone) {
this.div.hidden = false; this.div.hidden = false;
this.highlighter?.enable(); this.highlighter?.enable();
} }
@ -4960,10 +4961,6 @@ class TextLayerBuilder {
this.accessibilityManager?.disable(); this.accessibilityManager?.disable();
TextLayerBuilder.#removeGlobalSelectionListener(this.div); TextLayerBuilder.#removeGlobalSelectionListener(this.div);
} }
setTextContentSource(source) {
this.cancel();
this.#textContentSource = source;
}
#bindMouse(end) { #bindMouse(end) {
const { const {
div div
@ -4990,34 +4987,37 @@ class TextLayerBuilder {
} }
} }
static #enableGlobalSelectionListener() { static #enableGlobalSelectionListener() {
if (TextLayerBuilder.#selectionChangeAbortController) { if (this.#selectionChangeAbortController) {
return; return;
} }
TextLayerBuilder.#selectionChangeAbortController = new AbortController(); this.#selectionChangeAbortController = new AbortController();
const {
signal
} = this.#selectionChangeAbortController;
const reset = (end, textLayer) => { const reset = (end, textLayer) => {
end.classList.remove("active"); end.classList.remove("active");
}; };
document.addEventListener("pointerup", () => { document.addEventListener("pointerup", () => {
TextLayerBuilder.#textLayers.forEach(reset); this.#textLayers.forEach(reset);
}, { }, {
signal: TextLayerBuilder.#selectionChangeAbortController.signal signal
}); });
document.addEventListener("selectionchange", () => { document.addEventListener("selectionchange", () => {
const selection = document.getSelection(); const selection = document.getSelection();
if (selection.rangeCount === 0) { if (selection.rangeCount === 0) {
TextLayerBuilder.#textLayers.forEach(reset); this.#textLayers.forEach(reset);
return; return;
} }
const activeTextLayers = new Set(); const activeTextLayers = new Set();
for (let i = 0; i < selection.rangeCount; i++) { for (let i = 0; i < selection.rangeCount; i++) {
const range = selection.getRangeAt(i); const range = selection.getRangeAt(i);
for (const textLayerDiv of TextLayerBuilder.#textLayers.keys()) { for (const textLayerDiv of this.#textLayers.keys()) {
if (!activeTextLayers.has(textLayerDiv) && range.intersectsNode(textLayerDiv)) { if (!activeTextLayers.has(textLayerDiv) && range.intersectsNode(textLayerDiv)) {
activeTextLayers.add(textLayerDiv); activeTextLayers.add(textLayerDiv);
} }
} }
} }
for (const [textLayerDiv, endDiv] of TextLayerBuilder.#textLayers) { for (const [textLayerDiv, endDiv] of this.#textLayers) {
if (activeTextLayers.has(textLayerDiv)) { if (activeTextLayers.has(textLayerDiv)) {
endDiv.classList.add("active"); endDiv.classList.add("active");
} else { } else {
@ -5025,7 +5025,7 @@ class TextLayerBuilder {
} }
} }
}, { }, {
signal: TextLayerBuilder.#selectionChangeAbortController.signal signal
}); });
} }
} }
@ -5185,6 +5185,13 @@ class PDFPageView {
findController: this.#layerProperties.findController findController: this.#layerProperties.findController
})); }));
} }
#dispatchLayerRendered(name, error) {
this.eventBus.dispatch(name, {
source: this,
pageNumber: this.id,
error
});
}
async #renderAnnotationLayer() { async #renderAnnotationLayer() {
let error = null; let error = null;
try { try {
@ -5193,11 +5200,7 @@ class PDFPageView {
console.error(`#renderAnnotationLayer: "${ex}".`); console.error(`#renderAnnotationLayer: "${ex}".`);
error = ex; error = ex;
} finally { } finally {
this.eventBus.dispatch("annotationlayerrendered", { this.#dispatchLayerRendered("annotationlayerrendered", error);
source: this,
pageNumber: this.id,
error
});
} }
} }
async #renderAnnotationEditorLayer() { async #renderAnnotationEditorLayer() {
@ -5208,11 +5211,7 @@ class PDFPageView {
console.error(`#renderAnnotationEditorLayer: "${ex}".`); console.error(`#renderAnnotationEditorLayer: "${ex}".`);
error = ex; error = ex;
} finally { } finally {
this.eventBus.dispatch("annotationeditorlayerrendered", { this.#dispatchLayerRendered("annotationeditorlayerrendered", error);
source: this,
pageNumber: this.id,
error
});
} }
} }
async #renderDrawLayer() { async #renderDrawLayer() {
@ -5238,32 +5237,16 @@ class PDFPageView {
this.#addLayer(this.xfaLayer.div, "xfaLayer"); this.#addLayer(this.xfaLayer.div, "xfaLayer");
this.l10n.resume(); this.l10n.resume();
} }
this.eventBus.dispatch("xfalayerrendered", { this.#dispatchLayerRendered("xfalayerrendered", error);
source: this,
pageNumber: this.id,
error
});
} }
} }
async #renderTextLayer() { async #renderTextLayer() {
const { if (!this.textLayer) {
pdfPage,
textLayer,
viewport
} = this;
if (!textLayer) {
return; return;
} }
let error = null; let error = null;
try { try {
if (!textLayer.renderingDone) { await this.textLayer.render(this.viewport);
const readableStream = pdfPage.streamTextContent({
includeMarkedContent: true,
disableNormalization: true
});
textLayer.setTextContentSource(readableStream);
}
await textLayer.render(viewport);
} catch (ex) { } catch (ex) {
if (ex instanceof AbortException) { if (ex instanceof AbortException) {
return; return;
@ -5271,11 +5254,7 @@ class PDFPageView {
console.error(`#renderTextLayer: "${ex}".`); console.error(`#renderTextLayer: "${ex}".`);
error = ex; error = ex;
} }
this.eventBus.dispatch("textlayerrendered", { this.#dispatchLayerRendered("textlayerrendered", error);
source: this,
pageNumber: this.id,
error
});
this.#renderStructTreeLayer(); this.#renderStructTreeLayer();
} }
async #renderStructTreeLayer() { async #renderStructTreeLayer() {
@ -5613,6 +5592,7 @@ class PDFPageView {
if (!this.textLayer && this.#textLayerMode !== TextLayerMode.DISABLE && !pdfPage.isPureXfa) { if (!this.textLayer && this.#textLayerMode !== TextLayerMode.DISABLE && !pdfPage.isPureXfa) {
this._accessibilityManager ||= new TextAccessibilityManager(); this._accessibilityManager ||= new TextAccessibilityManager();
this.textLayer = new TextLayerBuilder({ this.textLayer = new TextLayerBuilder({
pdfPage,
highlighter: this._textHighlighter, highlighter: this._textHighlighter,
accessibilityManager: this._accessibilityManager, accessibilityManager: this._accessibilityManager,
enablePermissions: this.#textLayerMode === TextLayerMode.ENABLE_PERMISSIONS, enablePermissions: this.#textLayerMode === TextLayerMode.ENABLE_PERMISSIONS,
@ -5715,7 +5695,7 @@ class PDFPageView {
annotationCanvasMap: this._annotationCanvasMap, annotationCanvasMap: this._annotationCanvasMap,
pageColors pageColors
}; };
const renderTask = this.renderTask = this.pdfPage.render(renderContext); const renderTask = this.renderTask = pdfPage.render(renderContext);
renderTask.onContinue = renderContinueCallback; renderTask.onContinue = renderContinueCallback;
const resultPromise = renderTask.promise.then(async () => { const resultPromise = renderTask.promise.then(async () => {
showCanvas?.(true); showCanvas?.(true);
@ -5883,7 +5863,7 @@ class PDFViewer {
#scaleTimeoutId = null; #scaleTimeoutId = null;
#textLayerMode = TextLayerMode.ENABLE; #textLayerMode = TextLayerMode.ENABLE;
constructor(options) { constructor(options) {
const viewerVersion = "4.3.83"; const viewerVersion = "4.3.138";
if (version !== viewerVersion) { if (version !== viewerVersion) {
throw new Error(`The API version "${version}" does not match the Viewer version "${viewerVersion}".`); throw new Error(`The API version "${version}" does not match the Viewer version "${viewerVersion}".`);
} }
@ -6529,7 +6509,8 @@ class PDFViewer {
#setScaleUpdatePages(newScale, newValue, { #setScaleUpdatePages(newScale, newValue, {
noScroll = false, noScroll = false,
preset = false, preset = false,
drawingDelay = -1 drawingDelay = -1,
origin = null
}) { }) {
this._currentScaleValue = newValue.toString(); this._currentScaleValue = newValue.toString();
if (this.#isSameScale(newScale)) { if (this.#isSameScale(newScale)) {
@ -6554,6 +6535,7 @@ class PDFViewer {
this.refresh(); this.refresh();
}, drawingDelay); }, drawingDelay);
} }
const previousScale = this._currentScale;
this._currentScale = newScale; this._currentScale = newScale;
if (!noScroll) { if (!noScroll) {
let page = this._currentPageNumber, let page = this._currentPageNumber,
@ -6569,6 +6551,12 @@ class PDFViewer {
destArray: dest, destArray: dest,
allowNegativeOffset: true allowNegativeOffset: true
}); });
if (Array.isArray(origin)) {
const scaleDiff = newScale / previousScale - 1;
const [top, left] = this.containerTopLeft;
this.container.scrollLeft += (origin[0] - left) * scaleDiff;
this.container.scrollTop += (origin[1] - top) * scaleDiff;
}
} }
this.eventBus.dispatch("scalechanging", { this.eventBus.dispatch("scalechanging", {
source: this, source: this,
@ -7141,48 +7129,46 @@ class PDFViewer {
this.currentPageNumber = Math.max(currentPageNumber - advance, 1); this.currentPageNumber = Math.max(currentPageNumber - advance, 1);
return true; return true;
} }
increaseScale({ updateScale({
drawingDelay, drawingDelay,
scaleFactor, scaleFactor = null,
steps steps = null,
} = {}) { origin
}) {
if (steps === null && scaleFactor === null) {
throw new Error("Invalid updateScale options: either `steps` or `scaleFactor` must be provided.");
}
if (!this.pdfDocument) { if (!this.pdfDocument) {
return; return;
} }
let newScale = this._currentScale; let newScale = this._currentScale;
if (scaleFactor > 1) { if (scaleFactor > 0 && scaleFactor !== 1) {
newScale = Math.round(newScale * scaleFactor * 100) / 100; newScale = Math.round(newScale * scaleFactor * 100) / 100;
} else { } else if (steps) {
steps ??= 1; const delta = steps > 0 ? DEFAULT_SCALE_DELTA : 1 / DEFAULT_SCALE_DELTA;
const round = steps > 0 ? Math.ceil : Math.floor;
steps = Math.abs(steps);
do { do {
newScale = Math.ceil((newScale * DEFAULT_SCALE_DELTA).toFixed(2) * 10) / 10; newScale = round((newScale * delta).toFixed(2) * 10) / 10;
} while (--steps > 0 && newScale < MAX_SCALE); } while (--steps > 0);
} }
this.#setScale(Math.min(MAX_SCALE, newScale), { newScale = Math.max(MIN_SCALE, Math.min(MAX_SCALE, newScale));
this.#setScale(newScale, {
noScroll: false, noScroll: false,
drawingDelay drawingDelay,
origin
}); });
} }
decreaseScale({ increaseScale(options = {}) {
drawingDelay, this.updateScale({
scaleFactor, ...options,
steps steps: options.steps ?? 1
} = {}) { });
if (!this.pdfDocument) { }
return; decreaseScale(options = {}) {
} this.updateScale({
let newScale = this._currentScale; ...options,
if (scaleFactor > 0 && scaleFactor < 1) { steps: -(options.steps ?? 1)
newScale = Math.round(newScale * scaleFactor * 100) / 100;
} else {
steps ??= 1;
do {
newScale = Math.floor((newScale / DEFAULT_SCALE_DELTA).toFixed(2) * 10) / 10;
} while (--steps > 0 && newScale > MIN_SCALE);
}
this.#setScale(Math.max(MIN_SCALE, newScale), {
noScroll: false,
drawingDelay
}); });
} }
#updateContainerHeightCss(height = this.container.clientHeight) { #updateContainerHeightCss(height = this.container.clientHeight) {
@ -7795,25 +7781,22 @@ const PDFViewerApplication = {
get initializedPromise() { get initializedPromise() {
return this._initializedCapability.promise; return this._initializedCapability.promise;
}, },
zoomIn(steps, scaleFactor) { updateZoom(steps, scaleFactor, origin) {
if (this.pdfViewer.isInPresentationMode) { if (this.pdfViewer.isInPresentationMode) {
return; return;
} }
this.pdfViewer.increaseScale({ this.pdfViewer.updateScale({
drawingDelay: AppOptions.get("defaultZoomDelay"), drawingDelay: AppOptions.get("defaultZoomDelay"),
steps, steps,
scaleFactor scaleFactor,
origin
}); });
}, },
zoomOut(steps, scaleFactor) { zoomIn() {
if (this.pdfViewer.isInPresentationMode) { this.updateZoom(1);
return; },
} zoomOut() {
this.pdfViewer.decreaseScale({ this.updateZoom(-1);
drawingDelay: AppOptions.get("defaultZoomDelay"),
steps,
scaleFactor
});
}, },
zoomReset() { zoomReset() {
if (this.pdfViewer.isInPresentationMode) { if (this.pdfViewer.isInPresentationMode) {
@ -7951,6 +7934,7 @@ const PDFViewerApplication = {
this._contentDispositionFilename = args.filename; this._contentDispositionFilename = args.filename;
} }
AppOptions.set("docBaseUrl", this.baseUrl); AppOptions.set("docBaseUrl", this.baseUrl);
args.useSystemFonts = false;
const apiParams = AppOptions.getAll(OptionKind.API); const apiParams = AppOptions.getAll(OptionKind.API);
const loadingTask = getDocument({ const loadingTask = getDocument({
...apiParams, ...apiParams,
@ -8787,17 +8771,6 @@ const PDFViewerApplication = {
this[prop] = factor / newFactor; this[prop] = factor / newFactor;
return newFactor; return newFactor;
}, },
_centerAtPos(previousScale, x, y) {
const {
pdfViewer
} = this;
const scaleDiff = pdfViewer.currentScale / previousScale - 1;
if (scaleDiff !== 0) {
const [top, left] = pdfViewer.containerTopLeft;
pdfViewer.container.scrollLeft += (x - left) * scaleDiff;
pdfViewer.container.scrollTop += (y - top) * scaleDiff;
}
},
_unblockDocumentLoadEvent() { _unblockDocumentLoadEvent() {
document.blockUnblockOnload?.(false); document.blockUnblockOnload?.(false);
this._unblockDocumentLoadEvent = () => {}; this._unblockDocumentLoadEvent = () => {};
@ -9102,21 +9075,15 @@ function webViewerWheel(evt) {
let scaleFactor = Math.exp(-evt.deltaY / 100); let scaleFactor = Math.exp(-evt.deltaY / 100);
const isBuiltInMac = FeatureTest.platform.isMac; const isBuiltInMac = FeatureTest.platform.isMac;
const isPinchToZoom = evt.ctrlKey && !PDFViewerApplication._isCtrlKeyDown && deltaMode === WheelEvent.DOM_DELTA_PIXEL && evt.deltaX === 0 && (Math.abs(scaleFactor - 1) < 0.05 || isBuiltInMac) && evt.deltaZ === 0; const isPinchToZoom = evt.ctrlKey && !PDFViewerApplication._isCtrlKeyDown && deltaMode === WheelEvent.DOM_DELTA_PIXEL && evt.deltaX === 0 && (Math.abs(scaleFactor - 1) < 0.05 || isBuiltInMac) && evt.deltaZ === 0;
const origin = [evt.clientX, evt.clientY];
if (isPinchToZoom || evt.ctrlKey && supportsMouseWheelZoomCtrlKey || evt.metaKey && supportsMouseWheelZoomMetaKey) { if (isPinchToZoom || evt.ctrlKey && supportsMouseWheelZoomCtrlKey || evt.metaKey && supportsMouseWheelZoomMetaKey) {
evt.preventDefault(); evt.preventDefault();
if (PDFViewerApplication._isScrolling || zoomDisabledTimeout || document.visibilityState === "hidden" || PDFViewerApplication.overlayManager.active) { if (PDFViewerApplication._isScrolling || zoomDisabledTimeout || document.visibilityState === "hidden" || PDFViewerApplication.overlayManager.active) {
return; return;
} }
const previousScale = pdfViewer.currentScale;
if (isPinchToZoom && supportsPinchToZoom) { if (isPinchToZoom && supportsPinchToZoom) {
scaleFactor = PDFViewerApplication._accumulateFactor(previousScale, scaleFactor, "_wheelUnusedFactor"); scaleFactor = PDFViewerApplication._accumulateFactor(pdfViewer.currentScale, scaleFactor, "_wheelUnusedFactor");
if (scaleFactor < 1) { PDFViewerApplication.updateZoom(null, scaleFactor, origin);
PDFViewerApplication.zoomOut(null, scaleFactor);
} else if (scaleFactor > 1) {
PDFViewerApplication.zoomIn(null, scaleFactor);
} else {
return;
}
} else { } else {
const delta = normalizeWheelEventDirection(evt); const delta = normalizeWheelEventDirection(evt);
let ticks = 0; let ticks = 0;
@ -9130,15 +9097,8 @@ function webViewerWheel(evt) {
const PIXELS_PER_LINE_SCALE = 30; const PIXELS_PER_LINE_SCALE = 30;
ticks = PDFViewerApplication._accumulateTicks(delta / PIXELS_PER_LINE_SCALE, "_wheelUnusedTicks"); ticks = PDFViewerApplication._accumulateTicks(delta / PIXELS_PER_LINE_SCALE, "_wheelUnusedTicks");
} }
if (ticks < 0) { PDFViewerApplication.updateZoom(ticks, null, origin);
PDFViewerApplication.zoomOut(-ticks);
} else if (ticks > 0) {
PDFViewerApplication.zoomIn(ticks);
} else {
return;
}
} }
PDFViewerApplication._centerAtPos(previousScale, evt.clientX, evt.clientY);
} }
} }
function webViewerTouchStart(evt) { function webViewerTouchStart(evt) {
@ -9224,30 +9184,17 @@ function webViewerTouchMove(evt) {
} }
} }
evt.preventDefault(); evt.preventDefault();
const origin = [(page0X + page1X) / 2, (page0Y + page1Y) / 2];
const distance = Math.hypot(page0X - page1X, page0Y - page1Y) || 1; const distance = Math.hypot(page0X - page1X, page0Y - page1Y) || 1;
const pDistance = Math.hypot(pTouch0X - pTouch1X, pTouch0Y - pTouch1Y) || 1; const pDistance = Math.hypot(pTouch0X - pTouch1X, pTouch0Y - pTouch1Y) || 1;
const previousScale = pdfViewer.currentScale;
if (supportsPinchToZoom) { if (supportsPinchToZoom) {
const newScaleFactor = PDFViewerApplication._accumulateFactor(previousScale, distance / pDistance, "_touchUnusedFactor"); const newScaleFactor = PDFViewerApplication._accumulateFactor(pdfViewer.currentScale, distance / pDistance, "_touchUnusedFactor");
if (newScaleFactor < 1) { PDFViewerApplication.updateZoom(null, newScaleFactor, origin);
PDFViewerApplication.zoomOut(null, newScaleFactor);
} else if (newScaleFactor > 1) {
PDFViewerApplication.zoomIn(null, newScaleFactor);
} else {
return;
}
} else { } else {
const PIXELS_PER_LINE_SCALE = 30; const PIXELS_PER_LINE_SCALE = 30;
const ticks = PDFViewerApplication._accumulateTicks((distance - pDistance) / PIXELS_PER_LINE_SCALE, "_touchUnusedTicks"); const ticks = PDFViewerApplication._accumulateTicks((distance - pDistance) / PIXELS_PER_LINE_SCALE, "_touchUnusedTicks");
if (ticks < 0) { PDFViewerApplication.updateZoom(ticks, null, origin);
PDFViewerApplication.zoomOut(-ticks);
} else if (ticks > 0) {
PDFViewerApplication.zoomIn(ticks);
} else {
return;
}
} }
PDFViewerApplication._centerAtPos(previousScale, (page0X + page1X) / 2, (page0Y + page1Y) / 2);
} }
function webViewerTouchEnd(evt) { function webViewerTouchEnd(evt) {
if (!PDFViewerApplication._touchInfo) { if (!PDFViewerApplication._touchInfo) {
@ -9547,8 +9494,8 @@ function webViewerReportTelemetry({
const pdfjsVersion = "4.3.83"; const pdfjsVersion = "4.3.138";
const pdfjsBuild = "9ee7c07b8"; const pdfjsBuild = "24e12d515";
const AppConstants = null; const AppConstants = null;
window.PDFViewerApplication = PDFViewerApplication; window.PDFViewerApplication = PDFViewerApplication;
window.PDFViewerApplicationConstants = AppConstants; window.PDFViewerApplicationConstants = AppConstants;

Просмотреть файл

@ -13,6 +13,216 @@
* limitations under the License. * limitations under the License.
*/ */
.dialog{
--dialog-bg-color:white;
--dialog-border-color:white;
--dialog-shadow:0 2px 14px 0 rgb(58 57 68 / 0.2);
--text-primary-color:#15141a;
--text-secondary-color:#5b5b66;
--hover-filter:brightness(0.9);
--focus-ring-color:#0060df;
--focus-ring-outline:2px solid var(--focus-ring-color);
--textarea-border-color:#8f8f9d;
--textarea-bg-color:white;
--textarea-fg-color:var(--text-secondary-color);
--radio-bg-color:#f0f0f4;
--radio-checked-bg-color:#fbfbfe;
--radio-border-color:#8f8f9d;
--radio-checked-border-color:#0060df;
--button-secondary-bg-color:#f0f0f4;
--button-secondary-fg-color:var(--text-primary-color);
--button-secondary-border-color:var(--button-secondary-bg-color);
--button-secondary-hover-bg-color:var(--button-secondary-bg-color);
--button-secondary-hover-fg-color:var(--button-secondary-fg-color);
--button-secondary-hover-border-color:var(--button-secondary-hover-bg-color);
--button-primary-bg-color:#0060df;
--button-primary-fg-color:#fbfbfe;
--button-primary-hover-bg-color:var(--button-primary-bg-color);
--button-primary-hover-fg-color:var(--button-primary-fg-color);
--button-primary-hover-border-color:var(--button-primary-hover-bg-color);
@media (prefers-color-scheme: dark){
--dialog-bg-color:#1c1b22;
--dialog-border-color:#1c1b22;
--dialog-shadow:0 2px 14px 0 #15141a;
--text-primary-color:#fbfbfe;
--text-secondary-color:#cfcfd8;
--focus-ring-color:#0df;
--hover-filter:brightness(1.4);
--textarea-bg-color:#42414d;
--radio-bg-color:#2b2a33;
--radio-checked-bg-color:#15141a;
--radio-checked-border-color:#0df;
--button-secondary-bg-color:#2b2a33;
--button-primary-bg-color:#0df;
--button-primary-fg-color:#15141a;
}
@media screen and (forced-colors: active){
--dialog-bg-color:Canvas;
--dialog-border-color:CanvasText;
--dialog-shadow:none;
--text-primary-color:CanvasText;
--text-secondary-color:CanvasText;
--hover-filter:none;
--focus-ring-color:ButtonBorder;
--textarea-border-color:ButtonBorder;
--textarea-bg-color:Field;
--textarea-fg-color:ButtonText;
--radio-bg-color:ButtonFace;
--radio-checked-bg-color:ButtonFace;
--radio-border-color:ButtonText;
--radio-checked-border-color:ButtonText;
--button-secondary-bg-color:ButtonFace;
--button-secondary-fg-color:ButtonText;
--button-secondary-border-color:ButtonText;
--button-secondary-hover-bg-color:AccentColor;
--button-secondary-hover-fg-color:AccentColorText;
--button-primary-bg-color:ButtonText;
--button-primary-fg-color:ButtonFace;
--button-primary-hover-bg-color:AccentColor;
--button-primary-hover-fg-color:AccentColorText;
}
font:message-box;
font-size:13px;
font-weight:400;
line-height:150%;
border-radius:4px;
padding:12px 16px;
border:1px solid var(--dialog-border-color);
background:var(--dialog-bg-color);
color:var(--text-primary-color);
box-shadow:var(--dialog-shadow);
.mainContainer{
*:focus-visible{
outline:var(--focus-ring-outline);
outline-offset:2px;
}
.radio{
display:flex;
flex-direction:column;
align-items:flex-start;
gap:4px;
> .radioButton{
display:flex;
gap:8px;
align-self:stretch;
align-items:center;
input{
appearance:none;
box-sizing:border-box;
width:16px;
height:16px;
border-radius:50%;
background-color:var(--radio-bg-color);
border:1px solid var(--radio-border-color);
&:hover{
filter:var(--hover-filter);
}
&:checked{
background-color:var(--radio-checked-bg-color);
border:4px solid var(--radio-checked-border-color);
}
}
}
> .radioLabel{
display:flex;
padding-inline-start:24px;
align-items:flex-start;
gap:10px;
align-self:stretch;
> span{
flex:1 0 0;
font-size:11px;
color:var(--text-secondary-color);
}
}
}
button{
border-radius:4px;
border:1px solid;
font:menu;
font-weight:600;
padding:4px 16px;
width:auto;
height:32px;
&:hover{
cursor:pointer;
filter:var(--hover-filter);
}
&.secondaryButton{
color:var(--button-secondary-fg-color);
background-color:var(--button-secondary-bg-color);
border-color:var(--button-secondary-border-color);
&:hover{
color:var(--button-secondary-hover-fg-color);
background-color:var(--button-secondary-hover-bg-color);
border-color:var(--button-secondary-hover-border-color);
}
}
&.primaryButton{
color:var(--button-primary-hover-fg-color);
background-color:var(--button-primary-hover-bg-color);
border-color:var(--button-primary-hover-border-color);
opacity:1;
&:hover{
color:var(--button-primary-hover-fg-color);
background-color:var(--button-primary-hover-bg-color);
border-color:var(--button-primary-hover-border-color);
}
}
}
textarea{
font:inherit;
padding:8px;
resize:none;
margin:0;
box-sizing:border-box;
border-radius:4px;
border:1px solid var(--textarea-border-color);
background:var(--textarea-bg-color);
color:var(--textarea-fg-color);
&:focus{
outline-offset:0;
border-color:transparent;
}
&:disabled{
pointer-events:none;
opacity:0.4;
}
}
}
}
.textLayer{ .textLayer{
position:absolute; position:absolute;
text-align:initial; text-align:initial;
@ -1726,103 +1936,10 @@
} }
} }
#altTextDialog{ .dialog.altText{
--dialog-bg-color:white;
--dialog-border-color:white;
--dialog-shadow:0 2px 14px 0 rgb(58 57 68 / 0.2);
--text-primary-color:#15141a;
--text-secondary-color:#5b5b66;
--hover-filter:brightness(0.9);
--focus-ring-color:#0060df;
--focus-ring-outline:2px solid var(--focus-ring-color);
--textarea-border-color:#8f8f9d;
--textarea-bg-color:white;
--textarea-fg-color:var(--text-secondary-color);
--radio-bg-color:#f0f0f4;
--radio-checked-bg-color:#fbfbfe;
--radio-border-color:#8f8f9d;
--radio-checked-border-color:#0060df;
--button-cancel-bg-color:#f0f0f4;
--button-cancel-fg-color:var(--text-primary-color);
--button-cancel-border-color:var(--button-cancel-bg-color);
--button-cancel-hover-bg-color:var(--button-cancel-bg-color);
--button-cancel-hover-fg-color:var(--button-cancel-fg-color);
--button-cancel-hover-border-color:var(--button-cancel-hover-bg-color);
--button-save-bg-color:#0060df;
--button-save-fg-color:#fbfbfe;
--button-save-hover-bg-color:var(--button-save-bg-color);
--button-save-hover-fg-color:var(--button-save-fg-color);
--button-save-hover-border-color:var(--button-save-hover-bg-color);
@media (prefers-color-scheme: dark){
--dialog-bg-color:#1c1b22;
--dialog-border-color:#1c1b22;
--dialog-shadow:0 2px 14px 0 #15141a;
--text-primary-color:#fbfbfe;
--text-secondary-color:#cfcfd8;
--focus-ring-color:#0df;
--hover-filter:brightness(1.4);
--textarea-bg-color:#42414d;
--radio-bg-color:#2b2a33;
--radio-checked-bg-color:#15141a;
--radio-checked-border-color:#0df;
--button-cancel-bg-color:#2b2a33;
--button-save-bg-color:#0df;
--button-save-fg-color:#15141a;
}
@media screen and (forced-colors: active){
--dialog-bg-color:Canvas;
--dialog-border-color:CanvasText;
--dialog-shadow:none;
--text-primary-color:CanvasText;
--text-secondary-color:CanvasText;
--hover-filter:none;
--focus-ring-color:ButtonBorder;
--textarea-border-color:ButtonBorder;
--textarea-bg-color:Field;
--textarea-fg-color:ButtonText;
--radio-bg-color:ButtonFace;
--radio-checked-bg-color:ButtonFace;
--radio-border-color:ButtonText;
--radio-checked-border-color:ButtonText;
--button-cancel-bg-color:ButtonFace;
--button-cancel-fg-color:ButtonText;
--button-cancel-border-color:ButtonText;
--button-cancel-hover-bg-color:AccentColor;
--button-cancel-hover-fg-color:AccentColorText;
--button-save-bg-color:ButtonText;
--button-save-fg-color:ButtonFace;
--button-save-hover-bg-color:AccentColor;
--button-save-hover-fg-color:AccentColorText;
}
font:message-box;
font-size:13px;
font-weight:400;
line-height:150%;
border-radius:4px;
padding:12px 16px;
border:1px solid var(--dialog-border-color);
background:var(--dialog-bg-color);
color:var(--text-primary-color);
box-shadow:var(--dialog-shadow);
&::backdrop{ &::backdrop{
mask:url(#alttext-manager-mask); mask:url(#alttext-manager-mask);
} }
&.positioned{ &.positioned{
margin:0; margin:0;
} }
@ -1836,58 +1953,6 @@
align-items:flex-start; align-items:flex-start;
gap:16px; gap:16px;
& *:focus-visible{
outline:var(--focus-ring-outline);
outline-offset:2px;
}
& .radio{
display:flex;
flex-direction:column;
align-items:flex-start;
gap:4px;
& .radioButton{
display:flex;
gap:8px;
align-self:stretch;
align-items:center;
& input{
appearance:none;
box-sizing:border-box;
width:16px;
height:16px;
border-radius:50%;
background-color:var(--radio-bg-color);
border:1px solid var(--radio-border-color);
&:hover{
filter:var(--hover-filter);
}
&:checked{
background-color:var(--radio-checked-bg-color);
border:4px solid var(--radio-checked-border-color);
}
}
}
& .radioLabel{
display:flex;
padding-inline-start:24px;
align-items:flex-start;
gap:10px;
align-self:stretch;
& span{
flex:1 0 0;
font-size:11px;
color:var(--text-secondary-color);
}
}
}
& #overallDescription{ & #overallDescription{
display:flex; display:flex;
flex-direction:column; flex-direction:column;
@ -1917,27 +1982,8 @@
padding-inline:24px 10px; padding-inline:24px 10px;
textarea{ textarea{
font:inherit;
width:100%; width:100%;
min-height:75px; min-height:75px;
padding:8px;
resize:none;
margin:0;
box-sizing:border-box;
border-radius:4px;
border:1px solid var(--textarea-border-color);
background:var(--textarea-bg-color);
color:var(--textarea-fg-color);
&:focus{
outline-offset:0;
border-color:transparent;
}
&:disabled{
pointer-events:none;
opacity:0.4;
}
} }
} }
} }
@ -1948,46 +1994,6 @@
align-items:flex-start; align-items:flex-start;
gap:8px; gap:8px;
align-self:stretch; align-self:stretch;
button{
border-radius:4px;
border:1px solid;
font:menu;
font-weight:600;
padding:4px 16px;
width:auto;
height:32px;
&:hover{
cursor:pointer;
filter:var(--hover-filter);
}
&#altTextCancel{
color:var(--button-cancel-fg-color);
background-color:var(--button-cancel-bg-color);
border-color:var(--button-cancel-border-color);
&:hover{
color:var(--button-cancel-hover-fg-color);
background-color:var(--button-cancel-hover-bg-color);
border-color:var(--button-cancel-hover-border-color);
}
}
&#altTextSave{
color:var(--button-save-hover-fg-color);
background-color:var(--button-save-hover-bg-color);
border-color:var(--button-save-hover-border-color);
opacity:1;
&:hover{
color:var(--button-save-hover-fg-color);
background-color:var(--button-save-hover-bg-color);
border-color:var(--button-save-hover-border-color);
}
}
}
} }
} }
} }

Просмотреть файл

@ -441,8 +441,8 @@ See https://github.com/adobe-type-tools/cmap-resources
<button id="documentPropertiesClose" class="dialogButton"><span data-l10n-id="pdfjs-document-properties-close-button">Close</span></button> <button id="documentPropertiesClose" class="dialogButton"><span data-l10n-id="pdfjs-document-properties-close-button">Close</span></button>
</div> </div>
</dialog> </dialog>
<dialog id="altTextDialog" aria-labelledby="dialogLabel" aria-describedby="dialogDescription"> <dialog class="dialog altText" id="altTextDialog" aria-labelledby="dialogLabel" aria-describedby="dialogDescription">
<div id="altTextContainer"> <div id="altTextContainer" class="mainContainer">
<div id="overallDescription"> <div id="overallDescription">
<span id="dialogLabel" data-l10n-id="pdfjs-editor-alt-text-dialog-label" class="title">Choose an option</span> <span id="dialogLabel" data-l10n-id="pdfjs-editor-alt-text-dialog-label" class="title">Choose an option</span>
<span id="dialogDescription" data-l10n-id="pdfjs-editor-alt-text-dialog-description"> <span id="dialogDescription" data-l10n-id="pdfjs-editor-alt-text-dialog-description">
@ -479,8 +479,8 @@ See https://github.com/adobe-type-tools/cmap-resources
</div> </div>
</div> </div>
<div id="buttons"> <div id="buttons">
<button id="altTextCancel" tabindex="0"><span data-l10n-id="pdfjs-editor-alt-text-cancel-button">Cancel</span></button> <button id="altTextCancel" class="secondaryButton" tabindex="0"><span data-l10n-id="pdfjs-editor-alt-text-cancel-button">Cancel</span></button>
<button id="altTextSave" tabindex="0"><span data-l10n-id="pdfjs-editor-alt-text-save-button">Save</span></button> <button id="altTextSave" class="primaryButton" tabindex="0"><span data-l10n-id="pdfjs-editor-alt-text-save-button">Save</span></button>
</div> </div>
</div> </div>
</dialog> </dialog>

Просмотреть файл

@ -7449,17 +7449,18 @@ class TextHighlighter {
class TextLayerBuilder { class TextLayerBuilder {
#enablePermissions = false; #enablePermissions = false;
#onAppend = null; #onAppend = null;
#textContentSource = null; #renderingDone = false;
#textLayer = null; #textLayer = null;
static #textLayers = new Map(); static #textLayers = new Map();
static #selectionChangeAbortController = null; static #selectionChangeAbortController = null;
constructor({ constructor({
pdfPage,
highlighter = null, highlighter = null,
accessibilityManager = null, accessibilityManager = null,
enablePermissions = false, enablePermissions = false,
onAppend = null onAppend = null
}) { }) {
this.renderingDone = false; this.pdfPage = pdfPage;
this.highlighter = highlighter; this.highlighter = highlighter;
this.accessibilityManager = accessibilityManager; this.accessibilityManager = accessibilityManager;
this.#enablePermissions = enablePermissions === true; this.#enablePermissions = enablePermissions === true;
@ -7469,17 +7470,14 @@ class TextLayerBuilder {
this.div.className = "textLayer"; this.div.className = "textLayer";
} }
#finishRendering() { #finishRendering() {
this.renderingDone = true; this.#renderingDone = true;
const endOfContent = document.createElement("div"); const endOfContent = document.createElement("div");
endOfContent.className = "endOfContent"; endOfContent.className = "endOfContent";
this.div.append(endOfContent); this.div.append(endOfContent);
this.#bindMouse(endOfContent); this.#bindMouse(endOfContent);
} }
async render(viewport) { async render(viewport, textContentParams = null) {
if (!this.#textContentSource) { if (this.#renderingDone && this.#textLayer) {
throw new Error('No "textContentSource" parameter specified.');
}
if (this.renderingDone && this.#textLayer) {
this.#textLayer.update({ this.#textLayer.update({
viewport, viewport,
onBefore: this.hide.bind(this) onBefore: this.hide.bind(this)
@ -7489,7 +7487,10 @@ class TextLayerBuilder {
} }
this.cancel(); this.cancel();
this.#textLayer = new TextLayer({ this.#textLayer = new TextLayer({
textContentSource: this.#textContentSource, textContentSource: this.pdfPage.streamTextContent(textContentParams || {
includeMarkedContent: true,
disableNormalization: true
}),
container: this.div, container: this.div,
viewport viewport
}); });
@ -7506,13 +7507,13 @@ class TextLayerBuilder {
this.accessibilityManager?.enable(); this.accessibilityManager?.enable();
} }
hide() { hide() {
if (!this.div.hidden && this.renderingDone) { if (!this.div.hidden && this.#renderingDone) {
this.highlighter?.disable(); this.highlighter?.disable();
this.div.hidden = true; this.div.hidden = true;
} }
} }
show() { show() {
if (this.div.hidden && this.renderingDone) { if (this.div.hidden && this.#renderingDone) {
this.div.hidden = false; this.div.hidden = false;
this.highlighter?.enable(); this.highlighter?.enable();
} }
@ -7524,10 +7525,6 @@ class TextLayerBuilder {
this.accessibilityManager?.disable(); this.accessibilityManager?.disable();
TextLayerBuilder.#removeGlobalSelectionListener(this.div); TextLayerBuilder.#removeGlobalSelectionListener(this.div);
} }
setTextContentSource(source) {
this.cancel();
this.#textContentSource = source;
}
#bindMouse(end) { #bindMouse(end) {
const { const {
div div
@ -7554,34 +7551,37 @@ class TextLayerBuilder {
} }
} }
static #enableGlobalSelectionListener() { static #enableGlobalSelectionListener() {
if (TextLayerBuilder.#selectionChangeAbortController) { if (this.#selectionChangeAbortController) {
return; return;
} }
TextLayerBuilder.#selectionChangeAbortController = new AbortController(); this.#selectionChangeAbortController = new AbortController();
const {
signal
} = this.#selectionChangeAbortController;
const reset = (end, textLayer) => { const reset = (end, textLayer) => {
end.classList.remove("active"); end.classList.remove("active");
}; };
document.addEventListener("pointerup", () => { document.addEventListener("pointerup", () => {
TextLayerBuilder.#textLayers.forEach(reset); this.#textLayers.forEach(reset);
}, { }, {
signal: TextLayerBuilder.#selectionChangeAbortController.signal signal
}); });
document.addEventListener("selectionchange", () => { document.addEventListener("selectionchange", () => {
const selection = document.getSelection(); const selection = document.getSelection();
if (selection.rangeCount === 0) { if (selection.rangeCount === 0) {
TextLayerBuilder.#textLayers.forEach(reset); this.#textLayers.forEach(reset);
return; return;
} }
const activeTextLayers = new Set(); const activeTextLayers = new Set();
for (let i = 0; i < selection.rangeCount; i++) { for (let i = 0; i < selection.rangeCount; i++) {
const range = selection.getRangeAt(i); const range = selection.getRangeAt(i);
for (const textLayerDiv of TextLayerBuilder.#textLayers.keys()) { for (const textLayerDiv of this.#textLayers.keys()) {
if (!activeTextLayers.has(textLayerDiv) && range.intersectsNode(textLayerDiv)) { if (!activeTextLayers.has(textLayerDiv) && range.intersectsNode(textLayerDiv)) {
activeTextLayers.add(textLayerDiv); activeTextLayers.add(textLayerDiv);
} }
} }
} }
for (const [textLayerDiv, endDiv] of TextLayerBuilder.#textLayers) { for (const [textLayerDiv, endDiv] of this.#textLayers) {
if (activeTextLayers.has(textLayerDiv)) { if (activeTextLayers.has(textLayerDiv)) {
endDiv.classList.add("active"); endDiv.classList.add("active");
} else { } else {
@ -7589,7 +7589,7 @@ class TextLayerBuilder {
} }
} }
}, { }, {
signal: TextLayerBuilder.#selectionChangeAbortController.signal signal
}); });
} }
} }
@ -7749,6 +7749,13 @@ class PDFPageView {
findController: this.#layerProperties.findController findController: this.#layerProperties.findController
})); }));
} }
#dispatchLayerRendered(name, error) {
this.eventBus.dispatch(name, {
source: this,
pageNumber: this.id,
error
});
}
async #renderAnnotationLayer() { async #renderAnnotationLayer() {
let error = null; let error = null;
try { try {
@ -7757,11 +7764,7 @@ class PDFPageView {
console.error(`#renderAnnotationLayer: "${ex}".`); console.error(`#renderAnnotationLayer: "${ex}".`);
error = ex; error = ex;
} finally { } finally {
this.eventBus.dispatch("annotationlayerrendered", { this.#dispatchLayerRendered("annotationlayerrendered", error);
source: this,
pageNumber: this.id,
error
});
} }
} }
async #renderAnnotationEditorLayer() { async #renderAnnotationEditorLayer() {
@ -7772,11 +7775,7 @@ class PDFPageView {
console.error(`#renderAnnotationEditorLayer: "${ex}".`); console.error(`#renderAnnotationEditorLayer: "${ex}".`);
error = ex; error = ex;
} finally { } finally {
this.eventBus.dispatch("annotationeditorlayerrendered", { this.#dispatchLayerRendered("annotationeditorlayerrendered", error);
source: this,
pageNumber: this.id,
error
});
} }
} }
async #renderDrawLayer() { async #renderDrawLayer() {
@ -7802,32 +7801,16 @@ class PDFPageView {
this.#addLayer(this.xfaLayer.div, "xfaLayer"); this.#addLayer(this.xfaLayer.div, "xfaLayer");
this.l10n.resume(); this.l10n.resume();
} }
this.eventBus.dispatch("xfalayerrendered", { this.#dispatchLayerRendered("xfalayerrendered", error);
source: this,
pageNumber: this.id,
error
});
} }
} }
async #renderTextLayer() { async #renderTextLayer() {
const { if (!this.textLayer) {
pdfPage,
textLayer,
viewport
} = this;
if (!textLayer) {
return; return;
} }
let error = null; let error = null;
try { try {
if (!textLayer.renderingDone) { await this.textLayer.render(this.viewport);
const readableStream = pdfPage.streamTextContent({
includeMarkedContent: true,
disableNormalization: true
});
textLayer.setTextContentSource(readableStream);
}
await textLayer.render(viewport);
} catch (ex) { } catch (ex) {
if (ex instanceof AbortException) { if (ex instanceof AbortException) {
return; return;
@ -7835,11 +7818,7 @@ class PDFPageView {
console.error(`#renderTextLayer: "${ex}".`); console.error(`#renderTextLayer: "${ex}".`);
error = ex; error = ex;
} }
this.eventBus.dispatch("textlayerrendered", { this.#dispatchLayerRendered("textlayerrendered", error);
source: this,
pageNumber: this.id,
error
});
this.#renderStructTreeLayer(); this.#renderStructTreeLayer();
} }
async #renderStructTreeLayer() { async #renderStructTreeLayer() {
@ -8177,6 +8156,7 @@ class PDFPageView {
if (!this.textLayer && this.#textLayerMode !== TextLayerMode.DISABLE && !pdfPage.isPureXfa) { if (!this.textLayer && this.#textLayerMode !== TextLayerMode.DISABLE && !pdfPage.isPureXfa) {
this._accessibilityManager ||= new TextAccessibilityManager(); this._accessibilityManager ||= new TextAccessibilityManager();
this.textLayer = new TextLayerBuilder({ this.textLayer = new TextLayerBuilder({
pdfPage,
highlighter: this._textHighlighter, highlighter: this._textHighlighter,
accessibilityManager: this._accessibilityManager, accessibilityManager: this._accessibilityManager,
enablePermissions: this.#textLayerMode === TextLayerMode.ENABLE_PERMISSIONS, enablePermissions: this.#textLayerMode === TextLayerMode.ENABLE_PERMISSIONS,
@ -8279,7 +8259,7 @@ class PDFPageView {
annotationCanvasMap: this._annotationCanvasMap, annotationCanvasMap: this._annotationCanvasMap,
pageColors pageColors
}; };
const renderTask = this.renderTask = this.pdfPage.render(renderContext); const renderTask = this.renderTask = pdfPage.render(renderContext);
renderTask.onContinue = renderContinueCallback; renderTask.onContinue = renderContinueCallback;
const resultPromise = renderTask.promise.then(async () => { const resultPromise = renderTask.promise.then(async () => {
showCanvas?.(true); showCanvas?.(true);
@ -8447,7 +8427,7 @@ class PDFViewer {
#scaleTimeoutId = null; #scaleTimeoutId = null;
#textLayerMode = TextLayerMode.ENABLE; #textLayerMode = TextLayerMode.ENABLE;
constructor(options) { constructor(options) {
const viewerVersion = "4.3.83"; const viewerVersion = "4.3.138";
if (version !== viewerVersion) { if (version !== viewerVersion) {
throw new Error(`The API version "${version}" does not match the Viewer version "${viewerVersion}".`); throw new Error(`The API version "${version}" does not match the Viewer version "${viewerVersion}".`);
} }
@ -9093,7 +9073,8 @@ class PDFViewer {
#setScaleUpdatePages(newScale, newValue, { #setScaleUpdatePages(newScale, newValue, {
noScroll = false, noScroll = false,
preset = false, preset = false,
drawingDelay = -1 drawingDelay = -1,
origin = null
}) { }) {
this._currentScaleValue = newValue.toString(); this._currentScaleValue = newValue.toString();
if (this.#isSameScale(newScale)) { if (this.#isSameScale(newScale)) {
@ -9118,6 +9099,7 @@ class PDFViewer {
this.refresh(); this.refresh();
}, drawingDelay); }, drawingDelay);
} }
const previousScale = this._currentScale;
this._currentScale = newScale; this._currentScale = newScale;
if (!noScroll) { if (!noScroll) {
let page = this._currentPageNumber, let page = this._currentPageNumber,
@ -9133,6 +9115,12 @@ class PDFViewer {
destArray: dest, destArray: dest,
allowNegativeOffset: true allowNegativeOffset: true
}); });
if (Array.isArray(origin)) {
const scaleDiff = newScale / previousScale - 1;
const [top, left] = this.containerTopLeft;
this.container.scrollLeft += (origin[0] - left) * scaleDiff;
this.container.scrollTop += (origin[1] - top) * scaleDiff;
}
} }
this.eventBus.dispatch("scalechanging", { this.eventBus.dispatch("scalechanging", {
source: this, source: this,
@ -9735,48 +9723,46 @@ class PDFViewer {
this.currentPageNumber = Math.max(currentPageNumber - advance, 1); this.currentPageNumber = Math.max(currentPageNumber - advance, 1);
return true; return true;
} }
increaseScale({ updateScale({
drawingDelay, drawingDelay,
scaleFactor, scaleFactor = null,
steps steps = null,
} = {}) { origin
}) {
if (steps === null && scaleFactor === null) {
throw new Error("Invalid updateScale options: either `steps` or `scaleFactor` must be provided.");
}
if (!this.pdfDocument) { if (!this.pdfDocument) {
return; return;
} }
let newScale = this._currentScale; let newScale = this._currentScale;
if (scaleFactor > 1) { if (scaleFactor > 0 && scaleFactor !== 1) {
newScale = Math.round(newScale * scaleFactor * 100) / 100; newScale = Math.round(newScale * scaleFactor * 100) / 100;
} else { } else if (steps) {
steps ??= 1; const delta = steps > 0 ? DEFAULT_SCALE_DELTA : 1 / DEFAULT_SCALE_DELTA;
const round = steps > 0 ? Math.ceil : Math.floor;
steps = Math.abs(steps);
do { do {
newScale = Math.ceil((newScale * DEFAULT_SCALE_DELTA).toFixed(2) * 10) / 10; newScale = round((newScale * delta).toFixed(2) * 10) / 10;
} while (--steps > 0 && newScale < MAX_SCALE); } while (--steps > 0);
} }
this.#setScale(Math.min(MAX_SCALE, newScale), { newScale = Math.max(MIN_SCALE, Math.min(MAX_SCALE, newScale));
this.#setScale(newScale, {
noScroll: false, noScroll: false,
drawingDelay drawingDelay,
origin
}); });
} }
decreaseScale({ increaseScale(options = {}) {
drawingDelay, this.updateScale({
scaleFactor, ...options,
steps steps: options.steps ?? 1
} = {}) { });
if (!this.pdfDocument) { }
return; decreaseScale(options = {}) {
} this.updateScale({
let newScale = this._currentScale; ...options,
if (scaleFactor > 0 && scaleFactor < 1) { steps: -(options.steps ?? 1)
newScale = Math.round(newScale * scaleFactor * 100) / 100;
} else {
steps ??= 1;
do {
newScale = Math.floor((newScale / DEFAULT_SCALE_DELTA).toFixed(2) * 10) / 10;
} while (--steps > 0 && newScale > MIN_SCALE);
}
this.#setScale(Math.max(MIN_SCALE, newScale), {
noScroll: false,
drawingDelay
}); });
} }
#updateContainerHeightCss(height = this.container.clientHeight) { #updateContainerHeightCss(height = this.container.clientHeight) {
@ -10852,25 +10838,22 @@ const PDFViewerApplication = {
get initializedPromise() { get initializedPromise() {
return this._initializedCapability.promise; return this._initializedCapability.promise;
}, },
zoomIn(steps, scaleFactor) { updateZoom(steps, scaleFactor, origin) {
if (this.pdfViewer.isInPresentationMode) { if (this.pdfViewer.isInPresentationMode) {
return; return;
} }
this.pdfViewer.increaseScale({ this.pdfViewer.updateScale({
drawingDelay: AppOptions.get("defaultZoomDelay"), drawingDelay: AppOptions.get("defaultZoomDelay"),
steps, steps,
scaleFactor scaleFactor,
origin
}); });
}, },
zoomOut(steps, scaleFactor) { zoomIn() {
if (this.pdfViewer.isInPresentationMode) { this.updateZoom(1);
return; },
} zoomOut() {
this.pdfViewer.decreaseScale({ this.updateZoom(-1);
drawingDelay: AppOptions.get("defaultZoomDelay"),
steps,
scaleFactor
});
}, },
zoomReset() { zoomReset() {
if (this.pdfViewer.isInPresentationMode) { if (this.pdfViewer.isInPresentationMode) {
@ -11877,17 +11860,6 @@ const PDFViewerApplication = {
this[prop] = factor / newFactor; this[prop] = factor / newFactor;
return newFactor; return newFactor;
}, },
_centerAtPos(previousScale, x, y) {
const {
pdfViewer
} = this;
const scaleDiff = pdfViewer.currentScale / previousScale - 1;
if (scaleDiff !== 0) {
const [top, left] = pdfViewer.containerTopLeft;
pdfViewer.container.scrollLeft += (x - left) * scaleDiff;
pdfViewer.container.scrollTop += (y - top) * scaleDiff;
}
},
_unblockDocumentLoadEvent() { _unblockDocumentLoadEvent() {
document.blockUnblockOnload?.(false); document.blockUnblockOnload?.(false);
this._unblockDocumentLoadEvent = () => {}; this._unblockDocumentLoadEvent = () => {};
@ -12192,21 +12164,15 @@ function webViewerWheel(evt) {
let scaleFactor = Math.exp(-evt.deltaY / 100); let scaleFactor = Math.exp(-evt.deltaY / 100);
const isBuiltInMac = FeatureTest.platform.isMac; const isBuiltInMac = FeatureTest.platform.isMac;
const isPinchToZoom = evt.ctrlKey && !PDFViewerApplication._isCtrlKeyDown && deltaMode === WheelEvent.DOM_DELTA_PIXEL && evt.deltaX === 0 && (Math.abs(scaleFactor - 1) < 0.05 || isBuiltInMac) && evt.deltaZ === 0; const isPinchToZoom = evt.ctrlKey && !PDFViewerApplication._isCtrlKeyDown && deltaMode === WheelEvent.DOM_DELTA_PIXEL && evt.deltaX === 0 && (Math.abs(scaleFactor - 1) < 0.05 || isBuiltInMac) && evt.deltaZ === 0;
const origin = [evt.clientX, evt.clientY];
if (isPinchToZoom || evt.ctrlKey && supportsMouseWheelZoomCtrlKey || evt.metaKey && supportsMouseWheelZoomMetaKey) { if (isPinchToZoom || evt.ctrlKey && supportsMouseWheelZoomCtrlKey || evt.metaKey && supportsMouseWheelZoomMetaKey) {
evt.preventDefault(); evt.preventDefault();
if (PDFViewerApplication._isScrolling || zoomDisabledTimeout || document.visibilityState === "hidden" || PDFViewerApplication.overlayManager.active) { if (PDFViewerApplication._isScrolling || zoomDisabledTimeout || document.visibilityState === "hidden" || PDFViewerApplication.overlayManager.active) {
return; return;
} }
const previousScale = pdfViewer.currentScale;
if (isPinchToZoom && supportsPinchToZoom) { if (isPinchToZoom && supportsPinchToZoom) {
scaleFactor = PDFViewerApplication._accumulateFactor(previousScale, scaleFactor, "_wheelUnusedFactor"); scaleFactor = PDFViewerApplication._accumulateFactor(pdfViewer.currentScale, scaleFactor, "_wheelUnusedFactor");
if (scaleFactor < 1) { PDFViewerApplication.updateZoom(null, scaleFactor, origin);
PDFViewerApplication.zoomOut(null, scaleFactor);
} else if (scaleFactor > 1) {
PDFViewerApplication.zoomIn(null, scaleFactor);
} else {
return;
}
} else { } else {
const delta = normalizeWheelEventDirection(evt); const delta = normalizeWheelEventDirection(evt);
let ticks = 0; let ticks = 0;
@ -12220,15 +12186,8 @@ function webViewerWheel(evt) {
const PIXELS_PER_LINE_SCALE = 30; const PIXELS_PER_LINE_SCALE = 30;
ticks = PDFViewerApplication._accumulateTicks(delta / PIXELS_PER_LINE_SCALE, "_wheelUnusedTicks"); ticks = PDFViewerApplication._accumulateTicks(delta / PIXELS_PER_LINE_SCALE, "_wheelUnusedTicks");
} }
if (ticks < 0) { PDFViewerApplication.updateZoom(ticks, null, origin);
PDFViewerApplication.zoomOut(-ticks);
} else if (ticks > 0) {
PDFViewerApplication.zoomIn(ticks);
} else {
return;
}
} }
PDFViewerApplication._centerAtPos(previousScale, evt.clientX, evt.clientY);
} }
} }
function webViewerTouchStart(evt) { function webViewerTouchStart(evt) {
@ -12314,30 +12273,17 @@ function webViewerTouchMove(evt) {
} }
} }
evt.preventDefault(); evt.preventDefault();
const origin = [(page0X + page1X) / 2, (page0Y + page1Y) / 2];
const distance = Math.hypot(page0X - page1X, page0Y - page1Y) || 1; const distance = Math.hypot(page0X - page1X, page0Y - page1Y) || 1;
const pDistance = Math.hypot(pTouch0X - pTouch1X, pTouch0Y - pTouch1Y) || 1; const pDistance = Math.hypot(pTouch0X - pTouch1X, pTouch0Y - pTouch1Y) || 1;
const previousScale = pdfViewer.currentScale;
if (supportsPinchToZoom) { if (supportsPinchToZoom) {
const newScaleFactor = PDFViewerApplication._accumulateFactor(previousScale, distance / pDistance, "_touchUnusedFactor"); const newScaleFactor = PDFViewerApplication._accumulateFactor(pdfViewer.currentScale, distance / pDistance, "_touchUnusedFactor");
if (newScaleFactor < 1) { PDFViewerApplication.updateZoom(null, newScaleFactor, origin);
PDFViewerApplication.zoomOut(null, newScaleFactor);
} else if (newScaleFactor > 1) {
PDFViewerApplication.zoomIn(null, newScaleFactor);
} else {
return;
}
} else { } else {
const PIXELS_PER_LINE_SCALE = 30; const PIXELS_PER_LINE_SCALE = 30;
const ticks = PDFViewerApplication._accumulateTicks((distance - pDistance) / PIXELS_PER_LINE_SCALE, "_touchUnusedTicks"); const ticks = PDFViewerApplication._accumulateTicks((distance - pDistance) / PIXELS_PER_LINE_SCALE, "_touchUnusedTicks");
if (ticks < 0) { PDFViewerApplication.updateZoom(ticks, null, origin);
PDFViewerApplication.zoomOut(-ticks);
} else if (ticks > 0) {
PDFViewerApplication.zoomIn(ticks);
} else {
return;
}
} }
PDFViewerApplication._centerAtPos(previousScale, (page0X + page1X) / 2, (page0Y + page1Y) / 2);
} }
function webViewerTouchEnd(evt) { function webViewerTouchEnd(evt) {
if (!PDFViewerApplication._touchInfo) { if (!PDFViewerApplication._touchInfo) {
@ -12637,8 +12583,8 @@ function webViewerReportTelemetry({
const pdfjsVersion = "4.3.83"; const pdfjsVersion = "4.3.138";
const pdfjsBuild = "9ee7c07b8"; const pdfjsBuild = "24e12d515";
const AppConstants = null; const AppConstants = null;
window.PDFViewerApplication = PDFViewerApplication; window.PDFViewerApplication = PDFViewerApplication;
window.PDFViewerApplicationConstants = AppConstants; window.PDFViewerApplicationConstants = AppConstants;

Просмотреть файл

@ -20,8 +20,8 @@ origin:
# Human-readable identifier for this version/release # Human-readable identifier for this version/release
# Generally "version NNN", "tag SSS", "bookmark SSS" # Generally "version NNN", "tag SSS", "bookmark SSS"
release: 9ee7c07b837d0a849ed75272d48947eb33812a45 (2024-05-21T10:28:28Z). release: 24e12d515dce2f11b392410dd6e6e9926270ac65 (2024-05-28T16:48:09Z).
revision: 9ee7c07b837d0a849ed75272d48947eb33812a45 revision: 24e12d515dce2f11b392410dd6e6e9926270ac65
# The package's license, where possible using the mnemonic from # The package's license, where possible using the mnemonic from
# https://spdx.org/licenses/ # https://spdx.org/licenses/