Bug 1929709 - Update PDF.js to bff673896614b4b8c30f28397471cb89922a9a31 r=pdfjs-reviewers,marco

Differential Revision: https://phabricator.services.mozilla.com/D228261
This commit is contained in:
Updatebot 2024-11-11 19:14:23 +00:00
parent 5a111ff5a1
commit 3f7b4a180a
8 changed files with 1235 additions and 1177 deletions

File diff suppressed because it is too large Load Diff

View File

@ -935,115 +935,24 @@ class AForm {
this._color = color;
this._dateFormats = ["m/d", "m/d/yy", "mm/dd/yy", "mm/yy", "d-mmm", "d-mmm-yy", "dd-mmm-yy", "yy-mm-dd", "mmm-yy", "mmmm-yy", "mmm d, yyyy", "mmmm d, yyyy", "m/d/yy h:MM tt", "m/d/yy HH:MM"];
this._timeFormats = ["HH:MM", "h:MM tt", "HH:MM:ss", "h:MM:ss tt"];
this._dateActionsCache = new Map();
this._emailRegex = new RegExp("^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+" + "@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?" + "(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$");
}
_mkTargetName(event) {
return event.target ? `[ ${event.target.name} ]` : "";
}
_tryToGuessDate(cFormat, cDate) {
let actions = this._dateActionsCache.get(cFormat);
if (!actions) {
actions = [];
this._dateActionsCache.set(cFormat, actions);
cFormat.replaceAll(/(d+)|(m+)|(y+)|(H+)|(M+)|(s+)/g, function (match, d, m, y, H, M, s) {
if (d) {
actions.push((n, date) => {
if (n >= 1 && n <= 31) {
date.setDate(n);
return true;
}
return false;
});
} else if (m) {
actions.push((n, date) => {
if (n >= 1 && n <= 12) {
date.setMonth(n - 1);
return true;
}
return false;
});
} else if (y) {
actions.push((n, date) => {
if (n < 50) {
n += 2000;
} else if (n < 100) {
n += 1900;
}
date.setYear(n);
return true;
});
} else if (H) {
actions.push((n, date) => {
if (n >= 0 && n <= 23) {
date.setHours(n);
return true;
}
return false;
});
} else if (M) {
actions.push((n, date) => {
if (n >= 0 && n <= 59) {
date.setMinutes(n);
return true;
}
return false;
});
} else if (s) {
actions.push((n, date) => {
if (n >= 0 && n <= 59) {
date.setSeconds(n);
return true;
}
return false;
});
}
return "";
});
}
const number = /\d+/g;
let i = 0;
let array;
const date = new Date();
while ((array = number.exec(cDate)) !== null) {
if (i < actions.length) {
if (!actions[i++](parseInt(array[0]), date)) {
return null;
}
} else {
break;
}
}
if (i === 0) {
return null;
}
return date;
}
_parseDate(cFormat, cDate, strict = false) {
let date = null;
try {
date = this._util.scand(cFormat, cDate);
date = this._util._scand(cFormat, cDate, strict);
} catch {}
if (!date) {
if (strict) {
return null;
}
let format = cFormat;
if (/mm(?!m)/.test(format)) {
format = format.replace("mm", "m");
}
if (/dd(?!d)/.test(format)) {
format = format.replace("dd", "d");
}
try {
date = this._util.scand(format, cDate);
} catch {}
if (date) {
return date;
}
if (!date) {
date = Date.parse(cDate);
date = isNaN(date) ? this._tryToGuessDate(cFormat, cDate) : new Date(date);
if (strict) {
return null;
}
return date;
date = Date.parse(cDate);
return isNaN(date) ? null : new Date(date);
}
AFMergeChange(event = globalThis.event) {
if (event.willCommit) {
@ -3420,6 +3329,7 @@ class ProxyHandler {
;// ./src/scripting_api/util.js
class Util extends PDFObject {
#dateActionsCache = null;
constructor(data) {
super(data);
this._scandCache = new Map();
@ -3673,7 +3583,88 @@ class Util extends PDFObject {
}
return buf.join("");
}
#tryToGuessDate(cFormat, cDate) {
let actions = (this.#dateActionsCache ||= new Map()).get(cFormat);
if (!actions) {
actions = [];
this.#dateActionsCache.set(cFormat, actions);
cFormat.replaceAll(/(d+)|(m+)|(y+)|(H+)|(M+)|(s+)/g, function (match, d, m, y, H, M, s) {
if (d) {
actions.push((n, date) => {
if (n >= 1 && n <= 31) {
date.setDate(n);
return true;
}
return false;
});
} else if (m) {
actions.push((n, date) => {
if (n >= 1 && n <= 12) {
date.setMonth(n - 1);
return true;
}
return false;
});
} else if (y) {
actions.push((n, date) => {
if (n < 50) {
n += 2000;
} else if (n < 100) {
n += 1900;
}
date.setYear(n);
return true;
});
} else if (H) {
actions.push((n, date) => {
if (n >= 0 && n <= 23) {
date.setHours(n);
return true;
}
return false;
});
} else if (M) {
actions.push((n, date) => {
if (n >= 0 && n <= 59) {
date.setMinutes(n);
return true;
}
return false;
});
} else if (s) {
actions.push((n, date) => {
if (n >= 0 && n <= 59) {
date.setSeconds(n);
return true;
}
return false;
});
}
return "";
});
}
const number = /\d+/g;
let i = 0;
let array;
const date = new Date(0);
while ((array = number.exec(cDate)) !== null) {
if (i < actions.length) {
if (!actions[i++](parseInt(array[0]), date)) {
return null;
}
} else {
break;
}
}
if (i === 0) {
return null;
}
return date;
}
scand(cFormat, cDate) {
return this._scand(cFormat, cDate);
}
_scand(cFormat, cDate, strict = false) {
if (typeof cDate !== "string") {
return new Date(cDate);
}
@ -3830,7 +3821,7 @@ class Util extends PDFObject {
const [re, actions] = this._scandCache.get(cFormat);
const matches = new RegExp(`^${re}$`, "g").exec(cDate);
if (!matches || matches.length !== actions.length + 1) {
return null;
return strict ? null : this.#tryToGuessDate(cFormat, cDate);
}
const data = {
year: 2000,
@ -4028,8 +4019,8 @@ function initSandbox(params) {
;// ./src/pdf.scripting.js
const pdfjsVersion = "4.8.30";
const pdfjsBuild = "bde36f28b";
const pdfjsVersion = "4.9.14";
const pdfjsBuild = "bff673896";
globalThis.pdfjsScripting = {
initSandbox: initSandbox
};

View File

@ -229,10 +229,6 @@ const VerbosityLevel = {
WARNINGS: 1,
INFOS: 5
};
const CMapCompressionType = {
NONE: 0,
BINARY: 1
};
const OPS = {
dependency: 1,
setLineWidth: 2,
@ -770,6 +766,24 @@ const FontRenderOps = {
TRANSFORM: 7,
TRANSLATE: 8
};
function toHexUtil(arr) {
if (Uint8Array.prototype.toHex) {
return arr.toHex();
}
return Array.from(arr, num => hexNumbers[num]).join("");
}
function toBase64Util(arr) {
if (Uint8Array.prototype.toBase64) {
return arr.toBase64();
}
return btoa(bytesToString(arr));
}
function fromBase64Util(str) {
if (Uint8Array.fromBase64) {
return Uint8Array.fromBase64(str);
}
return stringToBytes(atob(str));
}
;// ./src/core/primitives.js
@ -1202,27 +1216,11 @@ function getInheritableProperty({
const ROMAN_NUMBER_MAP = ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM", "", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC", "", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"];
function toRomanNumerals(number, lowerCase = false) {
assert(Number.isInteger(number) && number > 0, "The number should be a positive integer.");
const romanBuf = [];
let pos;
while (number >= 1000) {
number -= 1000;
romanBuf.push("M");
}
pos = number / 100 | 0;
number %= 100;
romanBuf.push(ROMAN_NUMBER_MAP[pos]);
pos = number / 10 | 0;
number %= 10;
romanBuf.push(ROMAN_NUMBER_MAP[10 + pos]);
romanBuf.push(ROMAN_NUMBER_MAP[20 + number]);
const romanStr = romanBuf.join("");
return lowerCase ? romanStr.toLowerCase() : romanStr;
const roman = "M".repeat(number / 1000 | 0) + ROMAN_NUMBER_MAP[number % 1000 / 100 | 0] + ROMAN_NUMBER_MAP[10 + (number % 100 / 10 | 0)] + ROMAN_NUMBER_MAP[20 + number % 10];
return lowerCase ? roman.toLowerCase() : roman;
}
function log2(x) {
if (x <= 0) {
return 0;
}
return Math.ceil(Math.log2(x));
return x > 0 ? Math.ceil(Math.log2(x)) : 0;
}
function readInt8(data, offset) {
return data[offset] << 24 >> 24;
@ -1471,14 +1469,9 @@ function recoverJsURL(str) {
const regex = new RegExp("^\\s*(" + URL_OPEN_METHODS.join("|").replaceAll(".", "\\.") + ")\\((?:'|\")([^'\"]*)(?:'|\")(?:,\\s*(\\w+)\\)|\\))", "i");
const jsUrl = regex.exec(str);
if (jsUrl?.[2]) {
const url = jsUrl[2];
let newWindow = false;
if (jsUrl[3] === "true" && jsUrl[1] === "app.launchURL") {
newWindow = true;
}
return {
url,
newWindow
url: jsUrl[2],
newWindow: jsUrl[1] === "app.launchURL" && jsUrl[3] === "true"
};
}
return null;
@ -1524,7 +1517,7 @@ function stringToUTF16HexString(str) {
const buf = [];
for (let i = 0, ii = str.length; i < ii; i++) {
const char = str.charCodeAt(i);
buf.push((char >> 8 & 0xff).toString(16).padStart(2, "0"), (char & 0xff).toString(16).padStart(2, "0"));
buf.push(hexNumbers[char >> 8 & 0xff], hexNumbers[char & 0xff]);
}
return buf.join("");
}
@ -3285,6 +3278,7 @@ class DecodeStream extends BaseStream {
}
class StreamsSequenceStream extends DecodeStream {
constructor(streams, onError = null) {
streams = streams.filter(s => s instanceof BaseStream);
let maybeLength = 0;
for (const stream of streams) {
maybeLength += stream instanceof DecodeStream ? stream._rawMinBufferLength : stream.length;
@ -10226,17 +10220,14 @@ async function createBuiltInCMap(name, fetchBuiltInCMap) {
}
const {
cMapData,
compressionType
isCompressed
} = await fetchBuiltInCMap(name);
const cMap = new CMap(true);
if (compressionType === CMapCompressionType.BINARY) {
if (isCompressed) {
return new BinaryCMapReader().process(cMapData, cMap, useCMap => extendCMap(cMap, fetchBuiltInCMap, useCMap));
}
if (compressionType === CMapCompressionType.NONE) {
const lexer = new Lexer(new Stream(cMapData));
return parseCMap(cMap, lexer, fetchBuiltInCMap, null);
}
throw new Error(`Invalid CMap "compressionType" value: ${compressionType}`);
const lexer = new Lexer(new Stream(cMapData));
return parseCMap(cMap, lexer, fetchBuiltInCMap, null);
}
class CMapFactory {
static async create({
@ -28342,12 +28333,17 @@ const MIN_IMAGE_DIM = 2048;
const MAX_IMAGE_DIM = 65537;
const MAX_ERROR = 128;
class ImageResizer {
static #goodSquareLength = MIN_IMAGE_DIM;
static #isChrome = false;
constructor(imgData, isMask) {
this._imgData = imgData;
this._isMask = isMask;
}
static get canUseImageDecoder() {
return shadow(this, "canUseImageDecoder", this.#isChrome || typeof ImageDecoder === "undefined" ? Promise.resolve(false) : ImageDecoder.isTypeSupported("image/bmp"));
}
static needsToBeResized(width, height) {
if (width <= this._goodSquareLength && height <= this._goodSquareLength) {
if (width <= this.#goodSquareLength && height <= this.#goodSquareLength) {
return false;
}
const {
@ -28360,15 +28356,15 @@ class ImageResizer {
if (this._hasMaxArea) {
return area > this.MAX_AREA;
}
if (area < this._goodSquareLength ** 2) {
if (area < this.#goodSquareLength ** 2) {
return false;
}
if (this._areGoodDims(width, height)) {
this._goodSquareLength = Math.max(this._goodSquareLength, Math.floor(Math.sqrt(width * height)));
this.#goodSquareLength = Math.max(this.#goodSquareLength, Math.floor(Math.sqrt(width * height)));
return false;
}
this._goodSquareLength = this._guessMax(this._goodSquareLength, MAX_DIM, MAX_ERROR, 0);
const maxArea = this.MAX_AREA = this._goodSquareLength ** 2;
this.#goodSquareLength = this._guessMax(this.#goodSquareLength, MAX_DIM, MAX_ERROR, 0);
const maxArea = this.MAX_AREA = this.#goodSquareLength ** 2;
return area > maxArea;
}
static get MAX_DIM() {
@ -28376,7 +28372,7 @@ class ImageResizer {
}
static get MAX_AREA() {
this._hasMaxArea = true;
return shadow(this, "MAX_AREA", this._guessMax(ImageResizer._goodSquareLength, this.MAX_DIM, MAX_ERROR, 0) ** 2);
return shadow(this, "MAX_AREA", this._guessMax(this.#goodSquareLength, this.MAX_DIM, MAX_ERROR, 0) ** 2);
}
static set MAX_AREA(area) {
if (area >= 0) {
@ -28389,6 +28385,9 @@ class ImageResizer {
this.MAX_AREA = area >> 2;
}
}
static setOptions(opts) {
throw new Error("Not implemented: setOptions");
}
static _areGoodDims(width, height) {
try {
const canvas = new OffscreenCanvas(width, height);
@ -28418,10 +28417,27 @@ class ImageResizer {
}
async _createImage() {
const data = this._encodeBMP();
const blob = new Blob([data.buffer], {
type: "image/bmp"
});
const bitmapPromise = createImageBitmap(blob);
let decoder, imagePromise;
if (await ImageResizer.canUseImageDecoder) {
decoder = new ImageDecoder({
data,
type: "image/bmp",
preferAnimation: false,
transfer: [data.buffer]
});
imagePromise = decoder.decode().catch(reason => {
warn(`BMP image decoding failed: ${reason}`);
return createImageBitmap(new Blob([this._encodeBMP().buffer], {
type: "image/bmp"
}));
}).finally(() => {
decoder.close();
});
} else {
imagePromise = createImageBitmap(new Blob([data.buffer], {
type: "image/bmp"
}));
}
const {
MAX_AREA,
MAX_DIM
@ -28442,7 +28458,8 @@ class ImageResizer {
steps.splice(-1, 1, factor / (1 << N));
let newWidth = width;
let newHeight = height;
let bitmap = await bitmapPromise;
const result = await imagePromise;
let bitmap = result.image || result;
for (const step of steps) {
const prevWidth = newWidth;
const prevHeight = newHeight;
@ -28451,6 +28468,7 @@ class ImageResizer {
const canvas = new OffscreenCanvas(newWidth, newHeight);
const ctx = canvas.getContext("2d");
ctx.drawImage(bitmap, 0, 0, prevWidth, prevHeight, 0, 0, newWidth, newHeight);
bitmap.close();
bitmap = canvas.transferToImageBitmap();
}
imgData.data = null;
@ -28578,7 +28596,6 @@ class ImageResizer {
return bmpData;
}
}
ImageResizer._goodSquareLength = MIN_IMAGE_DIM;
;// ./src/shared/murmurhash3.js
const SEED = 0xc3d2e1f0;
@ -30016,6 +30033,7 @@ const DefaultPartialEvaluatorOptions = Object.freeze({
ignoreErrors: false,
isEvalSupported: true,
isOffscreenCanvasSupported: false,
isChrome: false,
canvasMaxAreaInBytes: -1,
fontExtraProperties: false,
useSystemFonts: true,
@ -30263,16 +30281,14 @@ class PartialEvaluator {
}
data = {
cMapData: new Uint8Array(await response.arrayBuffer()),
compressionType: CMapCompressionType.BINARY
isCompressed: true
};
} else {
data = await this.handler.sendWithPromise("FetchBuiltInCMap", {
name
});
}
if (data.compressionType !== CMapCompressionType.NONE) {
this.builtInCMapCache.set(name, data);
}
this.builtInCMapCache.set(name, data);
return data;
}
async fetchStandardFontData(name) {
@ -44119,7 +44135,7 @@ class Image extends StringObject {
return HTMLResult.EMPTY;
}
if (!buffer && this.transferEncoding === "base64") {
buffer = stringToBytes(atob(this[$content]));
buffer = fromBase64Util(this[$content]);
}
if (!buffer) {
return HTMLResult.EMPTY;
@ -44812,7 +44828,7 @@ class Para extends XFAObject {
style.paddingLeft = measureToString(this.marginLeft);
}
if (this.marginRight !== "") {
style.paddingight = measureToString(this.marginRight);
style.paddingRight = measureToString(this.marginRight);
}
if (this.spaceAbove !== "") {
style.paddingTop = measureToString(this.spaceAbove);
@ -53845,6 +53861,26 @@ class XRef {
if (this.topDict) {
return this.topDict;
}
if (!trailerDicts.length) {
for (const [num, entry] of this.entries.entries()) {
if (!entry) {
continue;
}
const ref = Ref.get(num, entry.gen);
let obj;
try {
obj = this.fetch(ref);
} catch {
continue;
}
if (obj instanceof BaseStream) {
obj = obj.dict;
}
if (obj instanceof Dict && obj.has("Root")) {
return obj;
}
}
}
throw new InvalidPDFException("Invalid PDF structure.");
}
readXRef(recoveryMode = false) {
@ -54548,7 +54584,7 @@ class Page {
}
await this._parsedAnnotations;
const structTree = await this.pdfManager.ensure(this, "_parseStructTree", [structTreeRoot]);
return structTree.serializable;
return this.pdfManager.ensure(structTree, "serializable");
}
_parseStructTree(structTreeRoot) {
const tree = new StructTreePage(structTreeRoot, this.pageDict);
@ -54647,8 +54683,6 @@ class Page {
const PDF_HEADER_SIGNATURE = new Uint8Array([0x25, 0x50, 0x44, 0x46, 0x2d]);
const STARTXREF_SIGNATURE = new Uint8Array([0x73, 0x74, 0x61, 0x72, 0x74, 0x78, 0x72, 0x65, 0x66]);
const ENDOBJ_SIGNATURE = new Uint8Array([0x65, 0x6e, 0x64, 0x6f, 0x62, 0x6a]);
const FINGERPRINT_FIRST_BYTES = 1024;
const EMPTY_FINGERPRINT = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
function find(stream, signature, limit = 1024, backwards = false) {
const signatureLength = signature.length;
const scanBytes = stream.peekBytes(limit);
@ -55181,28 +55215,22 @@ class PDFDocument {
return shadow(this, "documentInfo", docInfo);
}
get fingerprints() {
const FINGERPRINT_FIRST_BYTES = 1024;
const EMPTY_FINGERPRINT = "\x00".repeat(16);
function validate(data) {
return typeof data === "string" && data.length > 0 && data !== EMPTY_FINGERPRINT;
return typeof data === "string" && data.length === 16 && data !== EMPTY_FINGERPRINT;
}
function hexString(hash) {
const buf = [];
for (const num of hash) {
const hex = num.toString(16);
buf.push(hex.padStart(2, "0"));
}
return buf.join("");
}
const idArray = this.xref.trailer.get("ID");
const id = this.xref.trailer.get("ID");
let hashOriginal, hashModified;
if (Array.isArray(idArray) && validate(idArray[0])) {
hashOriginal = stringToBytes(idArray[0]);
if (idArray[1] !== idArray[0] && validate(idArray[1])) {
hashModified = stringToBytes(idArray[1]);
if (Array.isArray(id) && validate(id[0])) {
hashOriginal = stringToBytes(id[0]);
if (id[1] !== id[0] && validate(id[1])) {
hashModified = stringToBytes(id[1]);
}
} else {
hashOriginal = calculateMD5(this.stream.getByteRange(0, FINGERPRINT_FIRST_BYTES), 0, FINGERPRINT_FIRST_BYTES);
}
return shadow(this, "fingerprints", [hexString(hashOriginal), hashModified ? hexString(hashModified) : null]);
return shadow(this, "fingerprints", [toHexUtil(hashOriginal), hashModified ? toHexUtil(hashModified) : null]);
}
async _getLinearizationPage(pageIndex) {
const {
@ -56200,7 +56228,7 @@ class WorkerMessageHandler {
docId,
apiVersion
} = docParams;
const workerVersion = "4.8.30";
const workerVersion = "4.9.14";
if (apiVersion !== workerVersion) {
throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`);
}
@ -56273,7 +56301,8 @@ class WorkerMessageHandler {
return pdfManagerCapability.promise;
}
let pdfStream,
cachedChunks = [];
cachedChunks = [],
loaded = 0;
try {
pdfStream = new PDFWorkerStream(handler);
} catch (ex) {
@ -56299,21 +56328,6 @@ class WorkerMessageHandler {
pdfManagerCapability.reject(reason);
cancelXHRs = null;
});
let loaded = 0;
const flushChunks = function () {
const pdfFile = arrayBuffersToBytes(cachedChunks);
if (length && pdfFile.length !== length) {
warn("reported HTTP length is different from actual");
}
try {
pdfManagerArgs.source = pdfFile;
newPdfManager = new LocalPdfManager(pdfManagerArgs);
pdfManagerCapability.resolve(newPdfManager);
} catch (ex) {
pdfManagerCapability.reject(ex);
}
cachedChunks = [];
};
new Promise(function (resolve, reject) {
const readChunk = function ({
value,
@ -56323,7 +56337,14 @@ class WorkerMessageHandler {
ensureNotTerminated();
if (done) {
if (!newPdfManager) {
flushChunks();
const pdfFile = arrayBuffersToBytes(cachedChunks);
cachedChunks = [];
if (length && pdfFile.length !== length) {
warn("reported HTTP length is different from actual");
}
pdfManagerArgs.source = pdfFile;
newPdfManager = new LocalPdfManager(pdfManagerArgs);
pdfManagerCapability.resolve(newPdfManager);
}
cancelXHRs = null;
return;
@ -56731,9 +56752,7 @@ class WorkerMessageHandler {
} else {
clearGlobalCaches();
}
if (cancelXHRs) {
cancelXHRs(new AbortException("Worker was terminated."));
}
cancelXHRs?.(new AbortException("Worker was terminated."));
for (const task of WorkerTasks) {
waitOn.push(task.finished);
task.terminate();
@ -56764,8 +56783,8 @@ if (typeof window === "undefined" && !isNodeJS && typeof self !== "undefined" &&
;// ./src/pdf.worker.js
const pdfjsVersion = "4.8.30";
const pdfjsBuild = "bde36f28b";
const pdfjsVersion = "4.9.14";
const pdfjsBuild = "bff673896";
var __webpack_exports__WorkerMessageHandler = __webpack_exports__.WorkerMessageHandler;
export { __webpack_exports__WorkerMessageHandler as WorkerMessageHandler };

View File

@ -1223,7 +1223,6 @@ const {
AnnotationLayer,
AnnotationMode,
build,
CMapCompressionType,
ColorPicker,
createValidAbsoluteUrl,
DOMSVGFactory,
@ -1519,7 +1518,7 @@ class BasePreferences {
;// ./web/l10n.js
class L10n {
#dir;
#elements = new Set();
#elements;
#lang;
#l10n;
constructor({
@ -1554,7 +1553,7 @@ class L10n {
return messages[0]?.value || fallback;
}
async translate(element) {
this.#elements.add(element);
(this.#elements ||= new Set()).add(element);
try {
this.#l10n.connectRoot(element);
await this.#l10n.translateRoots();
@ -1568,10 +1567,13 @@ class L10n {
}
}
async destroy() {
for (const element of this.#elements) {
this.#l10n.disconnectRoot(element);
if (this.#elements) {
for (const element of this.#elements) {
this.#l10n.disconnectRoot(element);
}
this.#elements.clear();
this.#elements = null;
}
this.#elements.clear();
this.#l10n.pauseObserving();
}
pause() {
@ -4737,8 +4739,11 @@ class StructTreeLayerBuilder {
return promise;
}
async getAriaAttributes(annotationId) {
await this.render();
return this.#elementAttributes.get(annotationId);
try {
await this.render();
return this.#elementAttributes.get(annotationId);
} catch {}
return null;
}
hide() {
if (this.#treeDom && !this.#treeDom.hidden) {
@ -6272,7 +6277,7 @@ class PDFViewer {
#scaleTimeoutId = null;
#textLayerMode = TextLayerMode.ENABLE;
constructor(options) {
const viewerVersion = "4.8.30";
const viewerVersion = "4.9.14";
if (version !== viewerVersion) {
throw new Error(`The API version "${version}" does not match the Viewer version "${viewerVersion}".`);
}
@ -9810,8 +9815,8 @@ function beforeUnload(evt) {
const pdfjsVersion = "4.8.30";
const pdfjsBuild = "bde36f28b";
const pdfjsVersion = "4.9.14";
const pdfjsBuild = "bff673896";
const AppConstants = null;
window.PDFViewerApplication = PDFViewerApplication;
window.PDFViewerApplicationConstants = AppConstants;

View File

@ -1893,6 +1893,7 @@
.tooltip{
display:none;
word-wrap:anywhere;
&.show{
--alt-text-tooltip-bg:#f0f0f4;

View File

@ -1223,7 +1223,6 @@ const {
AnnotationLayer,
AnnotationMode,
build,
CMapCompressionType,
ColorPicker,
createValidAbsoluteUrl,
DOMSVGFactory,
@ -1519,7 +1518,7 @@ class BasePreferences {
;// ./web/l10n.js
class L10n {
#dir;
#elements = new Set();
#elements;
#lang;
#l10n;
constructor({
@ -1554,7 +1553,7 @@ class L10n {
return messages[0]?.value || fallback;
}
async translate(element) {
this.#elements.add(element);
(this.#elements ||= new Set()).add(element);
try {
this.#l10n.connectRoot(element);
await this.#l10n.translateRoots();
@ -1568,10 +1567,13 @@ class L10n {
}
}
async destroy() {
for (const element of this.#elements) {
this.#l10n.disconnectRoot(element);
if (this.#elements) {
for (const element of this.#elements) {
this.#l10n.disconnectRoot(element);
}
this.#elements.clear();
this.#elements = null;
}
this.#elements.clear();
this.#l10n.pauseObserving();
}
pause() {
@ -7893,8 +7895,11 @@ class StructTreeLayerBuilder {
return promise;
}
async getAriaAttributes(annotationId) {
await this.render();
return this.#elementAttributes.get(annotationId);
try {
await this.render();
return this.#elementAttributes.get(annotationId);
} catch {}
return null;
}
hide() {
if (this.#treeDom && !this.#treeDom.hidden) {
@ -9428,7 +9433,7 @@ class PDFViewer {
#scaleTimeoutId = null;
#textLayerMode = TextLayerMode.ENABLE;
constructor(options) {
const viewerVersion = "4.8.30";
const viewerVersion = "4.9.14";
if (version !== viewerVersion) {
throw new Error(`The API version "${version}" does not match the Viewer version "${viewerVersion}".`);
}
@ -13532,8 +13537,8 @@ function beforeUnload(evt) {
const pdfjsVersion = "4.8.30";
const pdfjsBuild = "bde36f28b";
const pdfjsVersion = "4.9.14";
const pdfjsBuild = "bff673896";
const AppConstants = null;
window.PDFViewerApplication = PDFViewerApplication;
window.PDFViewerApplicationConstants = AppConstants;

View File

@ -20,8 +20,8 @@ origin:
# Human-readable identifier for this version/release
# Generally "version NNN", "tag SSS", "bookmark SSS"
release: bde36f28bee3a01495375ae88d6ac2e3bf217c74 (2024-10-23T13:16:18Z).
revision: bde36f28bee3a01495375ae88d6ac2e3bf217c74
release: bff673896614b4b8c30f28397471cb89922a9a31 (2024-11-06T11:12:45Z).
revision: bff673896614b4b8c30f28397471cb89922a9a31
# The package's license, where possible using the mnemonic from
# https://spdx.org/licenses/

View File

@ -360,9 +360,12 @@ pdfjs-ink-canvas =
## Alt-text dialog
# Alternative text (alt text) helps when people can't see the image.
pdfjs-editor-alt-text-button =
.aria-label = Alt text
pdfjs-editor-alt-text-button-label = Alt text
pdfjs-editor-alt-text-edit-button-label = Edit alt text
pdfjs-editor-alt-text-edit-button =
.aria-label = Edit alt text
pdfjs-editor-alt-text-dialog-label = Choose an option
pdfjs-editor-alt-text-dialog-description = Alt text (alternative text) helps when people cant see the image or when it doesnt load.
pdfjs-editor-alt-text-add-description-label = Add a description
@ -457,12 +460,18 @@ pdfjs-editor-new-alt-text-ai-model-downloading-progress = Downloading alt text A
.aria-valuetext = Downloading alt text AI model ({ $downloadedSize } of { $totalSize } MB)
# This is a button that users can click to edit the alt text they have already added.
pdfjs-editor-new-alt-text-added-button =
.aria-label = Alt text added
pdfjs-editor-new-alt-text-added-button-label = Alt text added
# This is a button that users can click to open the alt text editor and add alt text when it is not present.
pdfjs-editor-new-alt-text-missing-button =
.aria-label = Missing alt text
pdfjs-editor-new-alt-text-missing-button-label = Missing alt text
# This is a button that opens up the alt text modal where users should review the alt text that was automatically generated.
pdfjs-editor-new-alt-text-to-review-button =
.aria-label = Review alt text
pdfjs-editor-new-alt-text-to-review-button-label = Review alt text
# "Created automatically" is a prefix that will be added to the beginning of any alt text that has been automatically generated. After the colon, the user will see/hear the actual alt text description. If the alt text has been edited by a human, this prefix will not appear.