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 @@