diff --git a/toolkit/components/pdfjs/content/build/pdf.mjs b/toolkit/components/pdfjs/content/build/pdf.mjs --- a/toolkit/components/pdfjs/content/build/pdf.mjs +++ b/toolkit/components/pdfjs/content/build/pdf.mjs @@ -10278,11 +10278,11 @@ worker = workerParams.port ? PDFWorker.fromPort(workerParams) : new PDFWorker(workerParams); task._worker = worker; } const docParams = { docId, - apiVersion: "5.0.365", + apiVersion: "5.1.18", data, password, disableAutoFetch, rangeChunkSize, length, @@ -10374,29 +10374,30 @@ const isRefProxy = v => typeof v === "object" && Number.isInteger(v?.num) && v.num >= 0 && Number.isInteger(v?.gen) && v.gen >= 0; const isNameProxy = v => typeof v === "object" && typeof v?.name === "string"; const isValidExplicitDest = _isValidExplicitDest.bind(null, isRefProxy, isNameProxy); class PDFDocumentLoadingTask { static #docId = 0; - constructor() { - this._capability = Promise.withResolvers(); - this._transport = null; - this._worker = null; - this.docId = `d${PDFDocumentLoadingTask.#docId++}`; - this.destroyed = false; - this.onPassword = null; - this.onProgress = null; - } + _capability = Promise.withResolvers(); + _transport = null; + _worker = null; + docId = `d${PDFDocumentLoadingTask.#docId++}`; + destroyed = false; + onPassword = null; + onProgress = null; get promise() { return this._capability.promise; } async destroy() { this.destroyed = true; await this._transport?.destroy(); this._transport = null; this._worker?.destroy(); this._worker = null; } + async getData() { + return this._transport.getData(); + } } class PDFDataRangeTransport { constructor(length, initialData, progressiveDone = false, contentDispositionFilename = null) { this.length = length; this.initialData = initialData; @@ -11909,12 +11910,12 @@ this.callback(); } } } } -const version = "5.0.365"; -const build = "8791b2474"; +const version = "5.1.18"; +const build = "cd4a30341"; ;// ./src/shared/scripting_utils.js function makeColorComp(n) { return Math.floor(Math.max(0, Math.min(1, n)) * 255).toString(16).padStart(2, "0"); } @@ -17169,10 +17170,11 @@ highlightOutlines: outliner.getOutlines(), highlightId: id, clipPathId }); editor.#addToDrawLayer(); + editor.rotate(editor.parentRotation); } return editor; } serialize(isForCopying = false) { if (this.isEmpty() || isForCopying) { @@ -21299,12 +21301,12 @@ -const pdfjsVersion = "5.0.365"; -const pdfjsBuild = "8791b2474"; +const pdfjsVersion = "5.1.18"; +const pdfjsBuild = "cd4a30341"; var __webpack_exports__AbortException = __webpack_exports__.AbortException; var __webpack_exports__AnnotationEditorLayer = __webpack_exports__.AnnotationEditorLayer; var __webpack_exports__AnnotationEditorParamsType = __webpack_exports__.AnnotationEditorParamsType; var __webpack_exports__AnnotationEditorType = __webpack_exports__.AnnotationEditorType; diff --git a/toolkit/components/pdfjs/content/build/pdf.scripting.mjs b/toolkit/components/pdfjs/content/build/pdf.scripting.mjs --- a/toolkit/components/pdfjs/content/build/pdf.scripting.mjs +++ b/toolkit/components/pdfjs/content/build/pdf.scripting.mjs @@ -4041,10 +4041,10 @@ }; } ;// ./src/pdf.scripting.js -const pdfjsVersion = "5.0.365"; -const pdfjsBuild = "8791b2474"; +const pdfjsVersion = "5.1.18"; +const pdfjsBuild = "cd4a30341"; globalThis.pdfjsScripting = { initSandbox: initSandbox }; diff --git a/toolkit/components/pdfjs/content/build/pdf.worker.mjs b/toolkit/components/pdfjs/content/build/pdf.worker.mjs --- a/toolkit/components/pdfjs/content/build/pdf.worker.mjs +++ b/toolkit/components/pdfjs/content/build/pdf.worker.mjs @@ -2534,10 +2534,17 @@ ;// ./src/core/icc_colorspace.js +function fetchSync(url) { + const xhr = new XMLHttpRequest(); + xhr.open("GET", url, false); + xhr.responseType = "arraybuffer"; + xhr.send(null); + return xhr.response; +} class IccColorSpace extends ColorSpace { #transformer; #convertPixel; static #useWasm = true; static #wasmUrl = null; @@ -2607,45 +2614,48 @@ this.#wasmUrl = wasmUrl; } static get isUsable() { let isUsable = false; if (this.#useWasm) { - try { - this._module = QCMS._module = this.#load(); - isUsable = !!this._module; - } catch (e) { - warn(`ICCBased color space: "${e}".`); + if (this.#wasmUrl) { + try { + this._module = QCMS._module = initSync({ + module: fetchSync(`${this.#wasmUrl}qcms_bg.wasm`) + }); + isUsable = !!this._module; + } catch (e) { + warn(`ICCBased color space: "${e}".`); + } + } else { + warn("No ICC color space support due to missing `wasmUrl` API option"); } } return shadow(this, "isUsable", isUsable); } - static #load() { - const filename = "qcms_bg.wasm"; - const xhr = new XMLHttpRequest(); - xhr.open("GET", `${this.#wasmUrl}${filename}`, false); - xhr.responseType = "arraybuffer"; - xhr.send(null); - return initSync({ - module: xhr.response - }); - } } class CmykICCBasedCS extends IccColorSpace { static #iccUrl; constructor() { - const filename = "CGATS001Compat-v2-micro.icc"; - const xhr = new XMLHttpRequest(); - xhr.open("GET", `${CmykICCBasedCS.#iccUrl}${filename}`, false); - xhr.responseType = "arraybuffer"; - xhr.send(null); - super(new Uint8Array(xhr.response), "DeviceCMYK", 4); + const iccProfile = new Uint8Array(fetchSync(`${CmykICCBasedCS.#iccUrl}CGATS001Compat-v2-micro.icc`)); + super(iccProfile, "DeviceCMYK", 4); } static setOptions({ iccUrl }) { this.#iccUrl = iccUrl; } + static get isUsable() { + let isUsable = false; + if (IccColorSpace.isUsable) { + if (this.#iccUrl) { + isUsable = true; + } else { + warn("No CMYK ICC profile support due to missing `iccUrl` API option"); + } + } + return shadow(this, "isUsable", isUsable); + } } ;// ./src/core/stream.js @@ -3972,11 +3982,11 @@ } static get rgba() { return shadow(this, "rgba", new DeviceRgbaCS()); } static get cmyk() { - if (IccColorSpace.isUsable) { + if (CmykICCBasedCS.isUsable) { try { return shadow(this, "cmyk", new CmykICCBasedCS()); } catch { warn("CMYK fallback: DeviceCMYK"); } @@ -3988,10 +3998,11 @@ ;// ./src/core/jpg.js + class JpegError extends BaseException { constructor(msg) { super(msg, "JpegError"); } } @@ -5039,10 +5050,15 @@ ColorSpaceUtils.cmyk.getRgbBuffer(data, 0, count, data, 0, 8, 0); return data.subarray(0, count * 3); } _convertCmykToRgba(data) { ColorSpaceUtils.cmyk.getRgbBuffer(data, 0, data.length / 4, data, 0, 8, 1); + if (ColorSpaceUtils.cmyk instanceof DeviceCmykCS) { + for (let i = 3, ii = data.length; i < ii; i += 4) { + data[i] = 255; + } + } return data; } getData({ width, height, @@ -26526,32 +26542,36 @@ } readFlag() { return this.readBits(this.context.bitsPerFlag); } readCoordinate() { - const bitsPerCoordinate = this.context.bitsPerCoordinate; + const { + bitsPerCoordinate, + decode + } = this.context; const xi = this.readBits(bitsPerCoordinate); const yi = this.readBits(bitsPerCoordinate); - const decode = this.context.decode; const scale = bitsPerCoordinate < 32 ? 1 / ((1 << bitsPerCoordinate) - 1) : 2.3283064365386963e-10; return [xi * scale * (decode[1] - decode[0]) + decode[0], yi * scale * (decode[3] - decode[2]) + decode[2]]; } readComponents() { - const numComps = this.context.numComps; - const bitsPerComponent = this.context.bitsPerComponent; + const { + bitsPerComponent, + colorFn, + colorSpace, + decode, + numComps + } = this.context; const scale = bitsPerComponent < 32 ? 1 / ((1 << bitsPerComponent) - 1) : 2.3283064365386963e-10; - const decode = this.context.decode; const components = this.tmpCompsBuf; for (let i = 0, j = 4; i < numComps; i++, j += 2) { const ci = this.readBits(bitsPerComponent); components[i] = ci * scale * (decode[j + 1] - decode[j]) + decode[j]; } const color = this.tmpCsCompsBuf; - if (this.context.colorFn) { - this.context.colorFn(components, 0, color, 0); - } - return this.context.colorSpace.getRgb(color, 0); + colorFn?.(components, 0, color, 0); + return colorSpace.getRgb(color, 0); } } let bCache = Object.create(null); function buildB(count) { const lut = []; @@ -38356,11 +38376,11 @@ return { num: 1, den: 1 }; } - const ratio = data.trim().split(/\s*:\s*/).map(x => parseFloat(x)).filter(x => !isNaN(x)); + const ratio = data.split(":", 2).map(x => parseFloat(x.trim())).filter(x => !isNaN(x)); if (ratio.length === 1) { ratio.push(1); } if (ratio.length === 0) { return { @@ -38390,11 +38410,11 @@ r, g, b }; } - const color = data.trim().split(/\s*,\s*/).map(c => MathClamp(parseInt(c.trim(), 10), 0, 255)).map(c => isNaN(c) ? 0 : c); + const color = data.split(",", 3).map(c => MathClamp(parseInt(c.trim(), 10), 0, 255)).map(c => isNaN(c) ? 0 : c); if (color.length < 3) { return { r, g, b @@ -38415,11 +38435,11 @@ y: def, width: def, height: def }; } - const bbox = data.trim().split(/\s*,\s*/).map(m => getMeasurement(m, "-1")); + const bbox = data.split(",", 4).map(m => getMeasurement(m.trim(), "-1")); if (bbox.length < 4 || bbox[2] < 0 || bbox[3] < 0) { return { x: def, y: def, width: def, @@ -46703,11 +46723,11 @@ class Range extends ContentObject { constructor(attributes) { super(CONFIG_NS_ID, "range"); } [$finalize]() { - this[$content] = this[$content].trim().split(/\s*,\s*/, 2).map(range => range.split("-").map(x => parseInt(x.trim(), 10))).filter(range => range.every(x => !isNaN(x))).map(range => { + this[$content] = this[$content].split(",", 2).map(range => range.split("-").map(x => parseInt(x.trim(), 10))).filter(range => range.every(x => !isNaN(x))).map(range => { if (range.length === 1) { range.push(range[0]); } return range; }); @@ -46939,11 +46959,11 @@ class Window extends ContentObject { constructor(attributes) { super(CONFIG_NS_ID, "window"); } [$finalize]() { - const pair = this[$content].trim().split(/\s*,\s*/, 2).map(x => parseInt(x, 10)); + const pair = this[$content].split(",", 2).map(x => parseInt(x.trim(), 10)); if (pair.some(x => isNaN(x))) { this[$content] = [0, 0]; return; } if (pair.length === 1) { @@ -47995,11 +48015,11 @@ } function checkStyle(node) { if (!node.style) { return ""; } - return node.style.trim().split(/\s*;\s*/).filter(s => !!s).map(s => s.split(/\s*:\s*/, 2)).filter(([key, value]) => { + return node.style.split(";").filter(s => !!s.trim()).map(s => s.split(":", 2).map(t => t.trim())).filter(([key, value]) => { if (key === "font-family") { node[$globalData].usedTypefaces.add(value); } return VALID_STYLES.has(key); }).map(kv => kv.join(":")).join(";"); @@ -54482,20 +54502,19 @@ warn(`getContentStream - ignoring sub-stream (${objId}): "${reason}".`); return; } throw reason; } - getContentStream() { - return this.pdfManager.ensure(this, "content").then(content => { - if (content instanceof BaseStream) { - return content; - } - if (Array.isArray(content)) { - return new StreamsSequenceStream(content, this._onSubStreamError.bind(this)); - } - return new NullStream(); - }); + async getContentStream() { + const content = await this.pdfManager.ensure(this, "content"); + if (content instanceof BaseStream) { + return content; + } + if (Array.isArray(content)) { + return new StreamsSequenceStream(content, this._onSubStreamError.bind(this)); + } + return new NullStream(); } get xfaData() { return shadow(this, "xfaData", this.xfaFactory ? { bbox: this.xfaFactory.getBoundingBox(this.pageIndex) } : null); @@ -54572,11 +54591,11 @@ changes.put(deletedRef, { data: null }); } } - save(handler, task, annotationStorage, changes) { + async save(handler, task, annotationStorage, changes) { const partialEvaluator = new PartialEvaluator({ xref: this.xref, handler, pageIndex: this.pageIndex, idFactory: this._localIdFactory, @@ -54586,29 +54605,26 @@ globalColorSpaceCache: this.globalColorSpaceCache, globalImageCache: this.globalImageCache, systemFontCache: this.systemFontCache, options: this.evaluatorOptions }); - return this._parsedAnnotations.then(function (annotations) { - const promises = []; - for (const annotation of annotations) { - promises.push(annotation.save(partialEvaluator, task, annotationStorage, changes).catch(function (reason) { - warn("save - ignoring annotation data during " + `"${task.name}" task: "${reason}".`); - return null; - })); - } - return Promise.all(promises); - }); - } - loadResources(keys) { - this.resourcesPromise ||= this.pdfManager.ensure(this, "resources"); - return this.resourcesPromise.then(() => { - const objectLoader = new ObjectLoader(this.resources, keys, this.xref); - return objectLoader.load(); - }); - } - getOperatorList({ + const annotations = await this._parsedAnnotations; + const promises = []; + for (const annotation of annotations) { + promises.push(annotation.save(partialEvaluator, task, annotationStorage, changes).catch(function (reason) { + warn("save - ignoring annotation data during " + `"${task.name}" task: "${reason}".`); + return null; + })); + } + return Promise.all(promises); + } + async loadResources(keys) { + await (this.resourcesPromise ??= this.pdfManager.ensure(this, "resources")); + const objectLoader = new ObjectLoader(this.resources, keys, this.xref); + await objectLoader.load(); + } + async getOperatorList({ handler, sink, task, intent, cacheKey, @@ -54669,85 +54685,84 @@ return null; } return AnnotationFactory.printNewAnnotations(annotationGlobals, partialEvaluator, task, newAnnots, imagePromises); }); } - const pageListPromise = Promise.all([contentStreamPromise, resourcesPromise]).then(([contentStream]) => { + const pageListPromise = Promise.all([contentStreamPromise, resourcesPromise]).then(async ([contentStream]) => { const opList = new OperatorList(intent, sink); handler.send("StartRenderPage", { transparency: partialEvaluator.hasBlendModes(this.resources, this.nonBlendModesSet), pageIndex: this.pageIndex, cacheKey }); - return partialEvaluator.getOperatorList({ + await partialEvaluator.getOperatorList({ stream: contentStream, task, resources: this.resources, operatorList: opList - }).then(() => opList); - }); - return Promise.all([pageListPromise, this._parsedAnnotations, newAnnotationsPromise]).then(function ([pageOpList, annotations, newAnnotations]) { - if (newAnnotations) { - annotations = annotations.filter(a => !(a.ref && deletedAnnotations.has(a.ref))); - for (let i = 0, ii = newAnnotations.length; i < ii; i++) { - const newAnnotation = newAnnotations[i]; - if (newAnnotation.refToReplace) { - const j = annotations.findIndex(a => a.ref && isRefsEqual(a.ref, newAnnotation.refToReplace)); - if (j >= 0) { - annotations.splice(j, 1, newAnnotation); - newAnnotations.splice(i--, 1); - ii--; - } - } - } - annotations = annotations.concat(newAnnotations); - } - if (annotations.length === 0 || intent & RenderingIntentFlag.ANNOTATIONS_DISABLE) { - pageOpList.flush(true); - return { - length: pageOpList.totalLength - }; - } - const renderForms = !!(intent & RenderingIntentFlag.ANNOTATIONS_FORMS), - isEditing = !!(intent & RenderingIntentFlag.IS_EDITING), - intentAny = !!(intent & RenderingIntentFlag.ANY), - intentDisplay = !!(intent & RenderingIntentFlag.DISPLAY), - intentPrint = !!(intent & RenderingIntentFlag.PRINT); - const opListPromises = []; - for (const annotation of annotations) { - if (intentAny || intentDisplay && annotation.mustBeViewed(annotationStorage, renderForms) && annotation.mustBeViewedWhenEditing(isEditing, modifiedIds) || intentPrint && annotation.mustBePrinted(annotationStorage)) { - opListPromises.push(annotation.getOperatorList(partialEvaluator, task, intent, annotationStorage).catch(function (reason) { - warn("getOperatorList - ignoring annotation data during " + `"${task.name}" task: "${reason}".`); - return { - opList: null, - separateForm: false, - separateCanvas: false - }; - })); - } - } - return Promise.all(opListPromises).then(function (opLists) { - let form = false, - canvas = false; - for (const { - opList, - separateForm, - separateCanvas - } of opLists) { - pageOpList.addOpList(opList); - form ||= separateForm; - canvas ||= separateCanvas; - } - pageOpList.flush(true, { - form, - canvas - }); - return { - length: pageOpList.totalLength - }; - }); - }); + }); + return opList; + }); + let [pageOpList, annotations, newAnnotations] = await Promise.all([pageListPromise, this._parsedAnnotations, newAnnotationsPromise]); + if (newAnnotations) { + annotations = annotations.filter(a => !(a.ref && deletedAnnotations.has(a.ref))); + for (let i = 0, ii = newAnnotations.length; i < ii; i++) { + const newAnnotation = newAnnotations[i]; + if (newAnnotation.refToReplace) { + const j = annotations.findIndex(a => a.ref && isRefsEqual(a.ref, newAnnotation.refToReplace)); + if (j >= 0) { + annotations.splice(j, 1, newAnnotation); + newAnnotations.splice(i--, 1); + ii--; + } + } + } + annotations = annotations.concat(newAnnotations); + } + if (annotations.length === 0 || intent & RenderingIntentFlag.ANNOTATIONS_DISABLE) { + pageOpList.flush(true); + return { + length: pageOpList.totalLength + }; + } + const renderForms = !!(intent & RenderingIntentFlag.ANNOTATIONS_FORMS), + isEditing = !!(intent & RenderingIntentFlag.IS_EDITING), + intentAny = !!(intent & RenderingIntentFlag.ANY), + intentDisplay = !!(intent & RenderingIntentFlag.DISPLAY), + intentPrint = !!(intent & RenderingIntentFlag.PRINT); + const opListPromises = []; + for (const annotation of annotations) { + if (intentAny || intentDisplay && annotation.mustBeViewed(annotationStorage, renderForms) && annotation.mustBeViewedWhenEditing(isEditing, modifiedIds) || intentPrint && annotation.mustBePrinted(annotationStorage)) { + opListPromises.push(annotation.getOperatorList(partialEvaluator, task, intent, annotationStorage).catch(function (reason) { + warn("getOperatorList - ignoring annotation data during " + `"${task.name}" task: "${reason}".`); + return { + opList: null, + separateForm: false, + separateCanvas: false + }; + })); + } + } + const opLists = await Promise.all(opListPromises); + let form = false, + canvas = false; + for (const { + opList, + separateForm, + separateCanvas + } of opLists) { + pageOpList.addOpList(opList); + form ||= separateForm; + canvas ||= separateCanvas; + } + pageOpList.flush(true, { + form, + canvas + }); + return { + length: pageOpList.totalLength + }; } async extractTextContent({ handler, task, includeMarkedContent, @@ -56871,11 +56886,11 @@ const verbosity = getVerbosityLevel(); const { docId, apiVersion } = docParams; - const workerVersion = "5.0.365"; + const workerVersion = "5.1.18"; if (apiVersion !== workerVersion) { throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`); } const workerHandlerName = docId + "_worker"; let handler = new MessageHandler(workerHandlerName, docId, port); @@ -57397,10 +57412,10 @@ } } ;// ./src/pdf.worker.js -const pdfjsVersion = "5.0.365"; -const pdfjsBuild = "8791b2474"; +const pdfjsVersion = "5.1.18"; +const pdfjsBuild = "cd4a30341"; var __webpack_exports__WorkerMessageHandler = __webpack_exports__.WorkerMessageHandler; export { __webpack_exports__WorkerMessageHandler as WorkerMessageHandler }; diff --git a/toolkit/components/pdfjs/content/web/viewer-geckoview.html b/toolkit/components/pdfjs/content/web/viewer-geckoview.html --- a/toolkit/components/pdfjs/content/web/viewer-geckoview.html +++ b/toolkit/components/pdfjs/content/web/viewer-geckoview.html @@ -40,12 +40,12 @@
-
@@ -53,18 +53,18 @@
- +
- - + +
diff --git a/toolkit/components/pdfjs/content/web/viewer-geckoview.mjs b/toolkit/components/pdfjs/content/web/viewer-geckoview.mjs --- a/toolkit/components/pdfjs/content/web/viewer-geckoview.mjs +++ b/toolkit/components/pdfjs/content/web/viewer-geckoview.mjs @@ -7013,11 +7013,11 @@ #scaleTimeoutId = null; #signatureManager = null; #supportsPinchToZoom = true; #textLayerMode = TextLayerMode.ENABLE; constructor(options) { - const viewerVersion = "5.0.365"; + const viewerVersion = "5.1.18"; if (version !== viewerVersion) { throw new Error(`The API version "${version}" does not match the Viewer version "${viewerVersion}".`); } this.container = options.container; this.viewer = options.viewer || options.container.firstElementChild; @@ -9314,11 +9314,11 @@ }); }, async download() { let data; try { - data = await this.pdfDocument.getData(); + data = await (this.pdfDocument ? this.pdfDocument.getData() : this.pdfLoadingTask.getData()); } catch {} this.downloadManager.download(data, this._downloadUrl, this._docFilename); }, async save() { if (this._saveInProgress) { @@ -10556,12 +10556,12 @@ ;// ./web/viewer-geckoview.js -const pdfjsVersion = "5.0.365"; -const pdfjsBuild = "8791b2474"; +const pdfjsVersion = "5.1.18"; +const pdfjsBuild = "cd4a30341"; const AppConstants = null; window.PDFViewerApplication = PDFViewerApplication; window.PDFViewerApplicationConstants = AppConstants; window.PDFViewerApplicationOptions = AppOptions; function getViewerConfiguration() { diff --git a/toolkit/components/pdfjs/content/web/viewer.html b/toolkit/components/pdfjs/content/web/viewer.html --- a/toolkit/components/pdfjs/content/web/viewer.html +++ b/toolkit/components/pdfjs/content/web/viewer.html @@ -40,31 +40,31 @@
- - - -
-
@@ -83,306 +83,306 @@
-
-
-
-
- +
-
-
- + + + + + + + + + + + + +
-
-
-
-
- -
-
@@ -402,313 +402,299 @@
- +
- - + +
- File name: +

-

- File size: +

-

- Title: +

-

- Author: +

-

- Subject: +

-

- Keywords: +

-

- Creation Date: +

-

- Modification Date: +

-

- Creator: +

-

- PDF Producer: +

-

- PDF Version: +

-

- Page Count: +

-

- Page Size: +

-

- Fast Web View: +

-

- +
- Choose an option - - Alt text (alternative text) helps when people can’t see the image or when it doesn’t load. - + +
- +
- - Aim for 1-2 sentences that describe the subject, setting, or actions. - +
- +
- +
- - This is used for ornamental images, like borders or watermarks. - +
- - + +
- Edit alt text (image description) +
- +
- Short description for people who can’t see the image or when the image doesn’t load. -
This alt text was created automatically and may be inaccurate. Learn more
+ +
- +
- Couldn’t create alt text automatically - Please write your own alt text or try again later. + +
- +
- - - + + +
- Image alt text settings +
- Automatic alt text +
- +
- Suggests descriptions to help people who can’t see the image or when the image doesn’t load. Learn more +
- Alt text AI model (180MB) +
- Runs locally on your device so your data stays private. Required for automatic alt text. +
- - + +
- Alt text editor +
- +
- Helps you make sure all your images have alt text. +
- +
- - This modal allows the user to create a signature to add to a PDF document. The user can edit the name (which also serves as the alt text), and optionally save the signature for repeated use. - +
- Add a signature +
- - - + + +
- +
- Draw your signature +
- +
- Drag a file here to upload +
- + - +
- +
- + - You’ve reached the limit of 5 saved signatures. Remove one to save more. +
- - + +
- Edit description +
- + - +
- - + +
@@ -716,15 +702,15 @@
diff --git a/toolkit/components/pdfjs/content/web/viewer.mjs b/toolkit/components/pdfjs/content/web/viewer.mjs --- a/toolkit/components/pdfjs/content/web/viewer.mjs +++ b/toolkit/components/pdfjs/content/web/viewer.mjs @@ -7267,10 +7267,14 @@ const DRAW_UPSCALE_FACTOR = 2; const MAX_NUM_SCALING_STEPS = 3; const THUMBNAIL_WIDTH = 98; +function zeroCanvas(c) { + c.width = 0; + c.height = 0; +} class TempImageFactory { static #tempCanvas = null; static getCanvas(width, height) { const tempCanvas = this.#tempCanvas ||= document.createElement("canvas"); tempCanvas.width = width; @@ -7283,14 +7287,12 @@ ctx.fillRect(0, 0, width, height); ctx.restore(); return [tempCanvas, tempCanvas.getContext("2d")]; } static destroyCanvas() { - const tempCanvas = this.#tempCanvas; - if (tempCanvas) { - tempCanvas.width = 0; - tempCanvas.height = 0; + if (this.#tempCanvas) { + zeroCanvas(this.#tempCanvas); } this.#tempCanvas = null; } } class PDFThumbnailView { @@ -7432,32 +7434,19 @@ image.setAttribute("data-l10n-args", this.#pageL10nArgs); image.src = reducedCanvas.toDataURL(); this.image = image; this.div.setAttribute("data-loaded", true); this._placeholderImg.replaceWith(image); - reducedCanvas.width = 0; - reducedCanvas.height = 0; - } - async #finishRenderTask(renderTask, canvas, error = null) { - if (renderTask === this.renderTask) { - this.renderTask = null; - } - if (error instanceof RenderingCancelledException) { - return; - } - this.renderingState = RenderingStates.FINISHED; - this.#convertCanvasToImage(canvas); - if (error) { - throw error; - } + zeroCanvas(reducedCanvas); } async draw() { if (this.renderingState !== RenderingStates.INITIAL) { console.error("Must be in new state before drawing"); - return undefined; - } - const { + return; + } + const { + pageColors, pdfPage } = this; if (!pdfPage) { this.renderingState = RenderingStates.FINISHED; throw new Error("pdfPage is not loaded"); @@ -7485,25 +7474,39 @@ const renderContext = { canvasContext: ctx, transform, viewport: drawViewport, optionalContentConfigPromise: this._optionalContentConfigPromise, - pageColors: this.pageColors + pageColors }; const renderTask = this.renderTask = pdfPage.render(renderContext); renderTask.onContinue = renderContinueCallback; - const resultPromise = renderTask.promise.then(() => this.#finishRenderTask(renderTask, canvas), error => this.#finishRenderTask(renderTask, canvas, error)); - resultPromise.finally(() => { - canvas.width = 0; - canvas.height = 0; - this.eventBus.dispatch("thumbnailrendered", { - source: this, - pageNumber: this.id, - pdfPage: this.pdfPage - }); - }); - return resultPromise; + let error = null; + try { + await renderTask.promise; + } catch (e) { + if (e instanceof RenderingCancelledException) { + zeroCanvas(canvas); + return; + } + error = e; + } finally { + if (renderTask === this.renderTask) { + this.renderTask = null; + } + } + this.renderingState = RenderingStates.FINISHED; + this.#convertCanvasToImage(canvas); + zeroCanvas(canvas); + this.eventBus.dispatch("thumbnailrendered", { + source: this, + pageNumber: this.id, + pdfPage + }); + if (error) { + throw error; + } } setImage(pageView) { if (this.renderingState !== RenderingStates.INITIAL) { return; } @@ -7523,18 +7526,16 @@ } this.renderingState = RenderingStates.FINISHED; this.#convertCanvasToImage(canvas); } #getReducedImageDims(canvas) { - let reducedWidth = canvas.width << MAX_NUM_SCALING_STEPS, - reducedHeight = canvas.height << MAX_NUM_SCALING_STEPS; + const width = canvas.width << MAX_NUM_SCALING_STEPS, + height = canvas.height << MAX_NUM_SCALING_STEPS; const outputScale = new OutputScale(); outputScale.sx = outputScale.sy = 1; - outputScale.limitCanvas(reducedWidth, reducedHeight, this.maxCanvasPixels, this.maxCanvasDim); - reducedWidth = reducedWidth * outputScale.sx | 0; - reducedHeight = reducedHeight * outputScale.sy | 0; - return [reducedWidth, reducedHeight]; + outputScale.limitCanvas(width, height, this.maxCanvasPixels, this.maxCanvasDim); + return [width * outputScale.sx | 0, height * outputScale.sy | 0]; } #reduceImage(img) { const { ctx, canvas @@ -10200,11 +10201,11 @@ #scaleTimeoutId = null; #signatureManager = null; #supportsPinchToZoom = true; #textLayerMode = TextLayerMode.ENABLE; constructor(options) { - const viewerVersion = "5.0.365"; + const viewerVersion = "5.1.18"; if (version !== viewerVersion) { throw new Error(`The API version "${version}" does not match the Viewer version "${viewerVersion}".`); } this.container = options.container; this.viewer = options.viewer || options.container.firstElementChild; @@ -12128,12 +12129,12 @@ }); this.#initTab(null); }, { passive: true }); - description.addEventListener("input", () => { - this.#clearDescription.disabled = description.value === ""; + this.#description.addEventListener("input", () => { + this.#clearDescription.disabled = this.#description.value === ""; }, { passive: true }); this.#clearDescription.addEventListener("click", () => { this.#description.value = ""; @@ -13920,11 +13921,11 @@ }); }, async download() { let data; try { - data = await this.pdfDocument.getData(); + data = await (this.pdfDocument ? this.pdfDocument.getData() : this.pdfLoadingTask.getData()); } catch {} this.downloadManager.download(data, this._downloadUrl, this._docFilename); }, async save() { if (this._saveInProgress) { @@ -15195,12 +15196,12 @@ ;// ./web/viewer.js -const pdfjsVersion = "5.0.365"; -const pdfjsBuild = "8791b2474"; +const pdfjsVersion = "5.1.18"; +const pdfjsBuild = "cd4a30341"; const AppConstants = null; window.PDFViewerApplication = PDFViewerApplication; window.PDFViewerApplicationConstants = AppConstants; window.PDFViewerApplicationOptions = AppOptions; function getViewerConfiguration() { diff --git a/toolkit/components/pdfjs/moz.yaml b/toolkit/components/pdfjs/moz.yaml --- a/toolkit/components/pdfjs/moz.yaml +++ b/toolkit/components/pdfjs/moz.yaml @@ -18,12 +18,12 @@ # Usually different from repository url url: https://github.com/mozilla/pdf.js # Human-readable identifier for this version/release # Generally "version NNN", "tag SSS", "bookmark SSS" - release: 8791b2474227774cf951e2880daccbf2ba25a77e (2025-03-13T15:48:50Z). - revision: 8791b2474227774cf951e2880daccbf2ba25a77e + release: cd4a30341f048d722e06d078a94911cc19bfc3a6 (2025-03-19T14:15:25Z). + revision: cd4a30341f048d722e06d078a94911cc19bfc3a6 # The package's license, where possible using the mnemonic from # https://spdx.org/licenses/ # Multiple licenses can be specified (as a YAML list) # A "LICENSE" file must exist containing the full license text diff --git a/toolkit/locales/en-US/toolkit/pdfviewer/viewer.ftl b/toolkit/locales/en-US/toolkit/pdfviewer/viewer.ftl --- a/toolkit/locales/en-US/toolkit/pdfviewer/viewer.ftl +++ b/toolkit/locales/en-US/toolkit/pdfviewer/viewer.ftl @@ -478,11 +478,10 @@ pdfjs-editor-new-alt-text-error-close-button = Close # Variables: # $totalSize (Number) - the total size (in MB) of the AI model. # $downloadedSize (Number) - the downloaded size (in MB) of the AI model. -# $percent (Number) - the percentage of the downloaded size. pdfjs-editor-new-alt-text-ai-model-downloading-progress = Downloading alt text AI model ({ $downloadedSize } of { $totalSize } MB) .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 =