From d8bbc7858622b6d9c278469aab701ca0b609cddf Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 15 May 2024 05:35:49 +0200 Subject: Merging upstream version 126.0. Signed-off-by: Daniel Baumann --- toolkit/components/pdfjs/content/PdfJs.sys.mjs | 2 +- .../components/pdfjs/content/PdfJsNetwork.sys.mjs | 6 +- .../pdfjs/content/PdfJsTelemetry.sys.mjs | 14 +- .../pdfjs/content/PdfStreamConverter.sys.mjs | 10 +- .../components/pdfjs/content/PdfjsParent.sys.mjs | 2 +- toolkit/components/pdfjs/content/build/pdf.mjs | 219 +++++++++------- .../pdfjs/content/build/pdf.scripting.mjs | 4 +- .../components/pdfjs/content/build/pdf.worker.mjs | 274 +++++++++++---------- .../pdfjs/content/web/viewer-geckoview.mjs | 114 +++++---- toolkit/components/pdfjs/content/web/viewer.css | 4 +- toolkit/components/pdfjs/content/web/viewer.mjs | 169 ++++++------- toolkit/components/pdfjs/moz.yaml | 4 +- .../test/browser_pdfjs_editing_contextmenu.js | 2 +- .../components/pdfjs/test/browser_pdfjs_find.js | 2 +- .../test/browser_pdfjs_force_opening_files.js | 4 +- .../pdfjs/test/browser_pdfjs_fullscreen.js | 2 +- .../pdfjs/test/browser_pdfjs_navigation.js | 2 +- .../pdfjs/test/browser_pdfjs_octet_stream.js | 2 +- .../pdfjs/test/browser_pdfjs_savedialog.js | 2 +- 19 files changed, 450 insertions(+), 388 deletions(-) (limited to 'toolkit/components/pdfjs') diff --git a/toolkit/components/pdfjs/content/PdfJs.sys.mjs b/toolkit/components/pdfjs/content/PdfJs.sys.mjs index fd6757737e..430a153ae2 100644 --- a/toolkit/components/pdfjs/content/PdfJs.sys.mjs +++ b/toolkit/components/pdfjs/content/PdfJs.sys.mjs @@ -242,7 +242,7 @@ export var PdfJs = { }, // nsIObserver - observe(aSubject, aTopic, aData) { + observe() { this.checkIsDefault(); }, }; diff --git a/toolkit/components/pdfjs/content/PdfJsNetwork.sys.mjs b/toolkit/components/pdfjs/content/PdfJsNetwork.sys.mjs index dd3ebc6bf5..a36f889539 100644 --- a/toolkit/components/pdfjs/content/PdfJsNetwork.sys.mjs +++ b/toolkit/components/pdfjs/content/PdfJsNetwork.sys.mjs @@ -33,7 +33,7 @@ export class NetworkManager { this.getXhr = args.getXhr || function NetworkManager_getXhr() { - return new XMLHttpRequest(); + return new XMLHttpRequest({ mozAnon: false }); }; this.currXhrId = 0; @@ -79,7 +79,7 @@ export class NetworkManager { xhr.responseType = "arraybuffer"; if (args.onError) { - xhr.onerror = function (evt) { + xhr.onerror = function () { args.onError(xhr.status); }; } @@ -109,7 +109,7 @@ export class NetworkManager { } } - onStateChange(xhrId, evt) { + onStateChange(xhrId) { var pendingRequest = this.pendingRequests[xhrId]; if (!pendingRequest) { // Maybe abortRequest was called... diff --git a/toolkit/components/pdfjs/content/PdfJsTelemetry.sys.mjs b/toolkit/components/pdfjs/content/PdfJsTelemetry.sys.mjs index 16e4e85d58..4724f25c33 100644 --- a/toolkit/components/pdfjs/content/PdfJsTelemetry.sys.mjs +++ b/toolkit/components/pdfjs/content/PdfJsTelemetry.sys.mjs @@ -47,7 +47,7 @@ export class PdfJsTelemetry { } static onTimeToView(ms) { - Glean.pdfjs.timeToView.accumulateSamples([ms]); + Glean.pdfjs.timeToView.accumulateSingleSample(ms); } static onEditing({ type, data }) { @@ -99,9 +99,9 @@ export class PdfJsTelemetry { Glean.pdfjsEditingHighlight.method[data.methodOfCreation].add(1); Glean.pdfjsEditingHighlight.color[data.color].add(1); if (data.type === "free_highlight") { - Glean.pdfjsEditingHighlight.thickness.accumulateSamples([ - data.thickness, - ]); + Glean.pdfjsEditingHighlight.thickness.accumulateSingleSample( + data.thickness + ); } break; case "color_changed": @@ -109,9 +109,9 @@ export class PdfJsTelemetry { Glean.pdfjsEditingHighlight.colorChanged.add(1); break; case "thickness_changed": - Glean.pdfjsEditingHighlight.thickness.accumulateSamples([ - data.thickness, - ]); + Glean.pdfjsEditingHighlight.thickness.accumulateSingleSample( + data.thickness + ); Glean.pdfjsEditingHighlight.thicknessChanged.add(1); break; case "deleted": diff --git a/toolkit/components/pdfjs/content/PdfStreamConverter.sys.mjs b/toolkit/components/pdfjs/content/PdfStreamConverter.sys.mjs index 2a56cbb935..ce9c6898e3 100644 --- a/toolkit/components/pdfjs/content/PdfStreamConverter.sys.mjs +++ b/toolkit/components/pdfjs/content/PdfStreamConverter.sys.mjs @@ -296,7 +296,7 @@ class ChromeActions { } } - download(data, sendResponse) { + download(data) { const { originalUrl, options } = data; const blobUrl = data.blobUrl || originalUrl; let { filename } = data; @@ -361,7 +361,7 @@ class ChromeActions { actor.sendAsyncMessage("PDFJS:Parent:getNimbus"); Services.obs.addObserver( { - observe(aSubject, aTopic, aData) { + observe(aSubject, aTopic) { if (aTopic === "pdfjs-getNimbus") { Services.obs.removeObserver(this, aTopic); sendResponse(aSubject && JSON.stringify(aSubject.wrappedJSObject)); @@ -545,7 +545,7 @@ class RangedChromeActions extends ChromeActions { } }; var getXhr = function getXhr() { - var xhr = new XMLHttpRequest(); + var xhr = new XMLHttpRequest({ mozAnon: false }); xhr.addEventListener("readystatechange", xhr_onreadystatechange); return xhr; }; @@ -790,7 +790,7 @@ PdfStreamConverter.prototype = { */ // nsIStreamConverter::convert - convert(aFromStream, aFromType, aToType, aCtxt) { + convert() { throw Components.Exception("", Cr.NS_ERROR_NOT_IMPLEMENTED); }, @@ -1063,7 +1063,7 @@ PdfStreamConverter.prototype = { // request(aRequest) below so we don't overwrite the original channel and // trigger an assertion. var proxy = { - onStartRequest(request) { + onStartRequest() { listener.onStartRequest(aRequest); }, onDataAvailable(request, inputStream, offset, count) { diff --git a/toolkit/components/pdfjs/content/PdfjsParent.sys.mjs b/toolkit/components/pdfjs/content/PdfjsParent.sys.mjs index a11d68ef02..32bb3d65b7 100644 --- a/toolkit/components/pdfjs/content/PdfjsParent.sys.mjs +++ b/toolkit/components/pdfjs/content/PdfjsParent.sys.mjs @@ -187,7 +187,7 @@ export class PdfjsParent extends JSWindowActorParent { let newBrowser = aEvent.detail; newBrowser.addEventListener( "EndSwapDocShells", - evt => { + () => { this._hookupEventListeners(newBrowser); }, { once: true } diff --git a/toolkit/components/pdfjs/content/build/pdf.mjs b/toolkit/components/pdfjs/content/build/pdf.mjs index 4e51efdb78..dbba618862 100644 --- a/toolkit/components/pdfjs/content/build/pdf.mjs +++ b/toolkit/components/pdfjs/content/build/pdf.mjs @@ -70,7 +70,6 @@ __webpack_require__.d(__webpack_exports__, { PasswordResponses: () => (/* reexport */ PasswordResponses), PermissionFlag: () => (/* reexport */ PermissionFlag), PixelsPerInch: () => (/* reexport */ PixelsPerInch), - PromiseCapability: () => (/* reexport */ PromiseCapability), RenderingCancelledException: () => (/* reexport */ RenderingCancelledException), UnexpectedResponseException: () => (/* reexport */ UnexpectedResponseException), Util: () => (/* reexport */ Util), @@ -789,24 +788,6 @@ function getModificationDate(date = new Date()) { const buffer = [date.getUTCFullYear().toString(), (date.getUTCMonth() + 1).toString().padStart(2, "0"), date.getUTCDate().toString().padStart(2, "0"), date.getUTCHours().toString().padStart(2, "0"), date.getUTCMinutes().toString().padStart(2, "0"), date.getUTCSeconds().toString().padStart(2, "0")]; return buffer.join(""); } -class PromiseCapability { - #settled = false; - constructor() { - this.promise = new Promise((resolve, reject) => { - this.resolve = data => { - this.#settled = true; - resolve(data); - }; - this.reject = reason => { - this.#settled = true; - reject(reason); - }; - }); - } - get settled() { - return this.#settled; - } -} let NormalizeRegex = null; let NormalizationMap = null; function normalizeUnicode(str) { @@ -820,6 +801,17 @@ function getUuid() { return crypto.randomUUID(); } const AnnotationPrefix = "pdfjs_internal_id_"; +const FontRenderOps = { + BEZIER_CURVE_TO: 0, + MOVE_TO: 1, + LINE_TO: 2, + QUADRATIC_CURVE_TO: 3, + RESTORE: 4, + SAVE: 5, + SCALE: 6, + TRANSFORM: 7, + TRANSLATE: 8 +}; ;// CONCATENATED MODULE: ./src/display/base_factory.js @@ -1742,11 +1734,11 @@ class HighlightToolbar { const button = document.createElement("button"); button.className = "highlightButton"; button.tabIndex = 0; - button.setAttribute("data-l10n-id", `pdfjs-highlight-floating-button`); + button.setAttribute("data-l10n-id", `pdfjs-highlight-floating-button1`); const span = document.createElement("span"); button.append(span); span.className = "visuallyHidden"; - span.setAttribute("data-l10n-id", "pdfjs-editor-highlight-button-label"); + span.setAttribute("data-l10n-id", "pdfjs-highlight-floating-button-label"); button.addEventListener("contextmenu", noContextMenu); button.addEventListener("click", () => { this.#uiManager.highlightSelection("floating_button"); @@ -3431,6 +3423,7 @@ class AnnotationEditor { #editToolbar = null; #focusedResizerName = ""; #hasBeenClicked = false; + #initialPosition = null; #isEditing = false; #isInEditMode = false; #isResizerEnabledForKeyboard = false; @@ -3656,12 +3649,14 @@ class AnnotationEditor { this.#translate(this.parentDimensions, x, y); } translateInPage(x, y) { + this.#initialPosition ||= [this.x, this.y]; this.#translate(this.pageDimensions, x, y); this.div.scrollIntoView({ block: "nearest" }); } drag(tx, ty) { + this.#initialPosition ||= [this.x, this.y]; const [parentWidth, parentHeight] = this.parentDimensions; this.x += tx / parentWidth; this.y += ty / parentHeight; @@ -3688,6 +3683,9 @@ class AnnotationEditor { block: "nearest" }); } + get _hasBeenMoved() { + return !!this.#initialPosition && (this.#initialPosition[0] !== this.x || this.#initialPosition[1] !== this.y); + } getBaseTranslation() { const [parentWidth, parentHeight] = this.parentDimensions; const { @@ -4911,7 +4909,6 @@ class FontLoader { } class FontFaceObject { constructor(translatedData, { - isEvalSupported = true, disableFontFace = false, ignoreErrors = false, inspectFont = null @@ -4920,7 +4917,6 @@ class FontFaceObject { for (const i in translatedData) { this[i] = translatedData[i]; } - this.isEvalSupported = isEvalSupported !== false; this.disableFontFace = disableFontFace === true; this.ignoreErrors = ignoreErrors === true; this._inspectFont = inspectFont; @@ -4975,22 +4971,72 @@ class FontFaceObject { throw ex; } warn(`getPathGenerator - ignoring character: "${ex}".`); + } + if (!Array.isArray(cmds) || cmds.length === 0) { return this.compiledGlyphs[character] = function (c, size) {}; } - if (this.isEvalSupported && util_FeatureTest.isEvalSupported) { - const jsBuf = []; - for (const current of cmds) { - const args = current.args !== undefined ? current.args.join(",") : ""; - jsBuf.push("c.", current.cmd, "(", args, ");\n"); + const commands = []; + for (let i = 0, ii = cmds.length; i < ii;) { + switch (cmds[i++]) { + case FontRenderOps.BEZIER_CURVE_TO: + { + const [a, b, c, d, e, f] = cmds.slice(i, i + 6); + commands.push(ctx => ctx.bezierCurveTo(a, b, c, d, e, f)); + i += 6; + } + break; + case FontRenderOps.MOVE_TO: + { + const [a, b] = cmds.slice(i, i + 2); + commands.push(ctx => ctx.moveTo(a, b)); + i += 2; + } + break; + case FontRenderOps.LINE_TO: + { + const [a, b] = cmds.slice(i, i + 2); + commands.push(ctx => ctx.lineTo(a, b)); + i += 2; + } + break; + case FontRenderOps.QUADRATIC_CURVE_TO: + { + const [a, b, c, d] = cmds.slice(i, i + 4); + commands.push(ctx => ctx.quadraticCurveTo(a, b, c, d)); + i += 4; + } + break; + case FontRenderOps.RESTORE: + commands.push(ctx => ctx.restore()); + break; + case FontRenderOps.SAVE: + commands.push(ctx => ctx.save()); + break; + case FontRenderOps.SCALE: + assert(commands.length === 2, "Scale command is only valid at the third position."); + break; + case FontRenderOps.TRANSFORM: + { + const [a, b, c, d, e, f] = cmds.slice(i, i + 6); + commands.push(ctx => ctx.transform(a, b, c, d, e, f)); + i += 6; + } + break; + case FontRenderOps.TRANSLATE: + { + const [a, b] = cmds.slice(i, i + 2); + commands.push(ctx => ctx.translate(a, b)); + i += 2; + } + break; } - return this.compiledGlyphs[character] = new Function("c", "size", jsBuf.join("")); } - return this.compiledGlyphs[character] = function (c, size) { - for (const current of cmds) { - if (current.cmd === "scale") { - current.args = [size, -size]; - } - c[current.cmd].apply(c, current.args); + return this.compiledGlyphs[character] = function glyphDrawer(ctx, size) { + commands[0](ctx); + commands[1](ctx); + ctx.scale(size, -size); + for (let i = 2, ii = commands.length; i < ii; i++) { + commands[i](ctx); } }; } @@ -7951,7 +7997,7 @@ class TextLayerRenderTask { this._reader = null; this._textDivProperties = textDivProperties || new WeakMap(); this._canceled = false; - this._capability = new PromiseCapability(); + this._capability = Promise.withResolvers(); this._layoutTextParams = { prevFontSize: null, prevFontFamily: null, @@ -8019,7 +8065,11 @@ class TextLayerRenderTask { } } _render() { - const capability = new PromiseCapability(); + const { + promise, + resolve, + reject + } = Promise.withResolvers(); let styleCache = Object.create(null); if (this._isReadableStream) { const pump = () => { @@ -8028,13 +8078,13 @@ class TextLayerRenderTask { done }) => { if (done) { - capability.resolve(); + resolve(); return; } Object.assign(styleCache, value.styles); this._processItems(value.items, styleCache); pump(); - }, capability.reject); + }, reject); }; this._reader = this._textContentSource.getReader(); pump(); @@ -8044,11 +8094,11 @@ class TextLayerRenderTask { styles } = this._textContentSource; this._processItems(items, styles); - capability.resolve(); + resolve(); } else { throw new Error('No "textContentSource" parameter specified.'); } - capability.promise.then(() => { + promise.then(() => { styleCache = null; render(this); }, this._capability.reject); @@ -8241,7 +8291,7 @@ class MessageHandler { } sendWithPromise(actionName, data, transfers) { const callbackId = this.callbackId++; - const capability = new PromiseCapability(); + const capability = Promise.withResolvers(); this.callbackCapabilities[callbackId] = capability; try { this.comObj.postMessage({ @@ -8263,7 +8313,7 @@ class MessageHandler { comObj = this.comObj; return new ReadableStream({ start: controller => { - const startCapability = new PromiseCapability(); + const startCapability = Promise.withResolvers(); this.streamControllers[streamId] = { controller, startCall: startCapability, @@ -8282,7 +8332,7 @@ class MessageHandler { return startCapability.promise; }, pull: controller => { - const pullCapability = new PromiseCapability(); + const pullCapability = Promise.withResolvers(); this.streamControllers[streamId].pullCall = pullCapability; comObj.postMessage({ sourceName, @@ -8295,7 +8345,7 @@ class MessageHandler { }, cancel: reason => { assert(reason instanceof Error, "cancel must have a valid reason"); - const cancelCapability = new PromiseCapability(); + const cancelCapability = Promise.withResolvers(); this.streamControllers[streamId].cancelCall = cancelCapability; this.streamControllers[streamId].isClosed = true; comObj.postMessage({ @@ -8324,7 +8374,7 @@ class MessageHandler { const lastDesiredSize = this.desiredSize; this.desiredSize -= size; if (lastDesiredSize > 0 && this.desiredSize <= 0) { - this.sinkCapability = new PromiseCapability(); + this.sinkCapability = Promise.withResolvers(); this.ready = this.sinkCapability.promise; } comObj.postMessage({ @@ -8362,7 +8412,7 @@ class MessageHandler { reason: wrapReason(reason) }); }, - sinkCapability: new PromiseCapability(), + sinkCapability: Promise.withResolvers(), onPull: null, onCancel: null, isCancelled: false, @@ -8975,7 +9025,7 @@ class PDFDataTransportStreamReader { done: true }; } - const requestCapability = new PromiseCapability(); + const requestCapability = Promise.withResolvers(); this._requests.push(requestCapability); return requestCapability.promise; } @@ -9047,7 +9097,7 @@ class PDFDataTransportStreamRangeReader { done: true }; } - const requestCapability = new PromiseCapability(); + const requestCapability = Promise.withResolvers(); this._requests.push(requestCapability); return requestCapability.promise; } @@ -9205,7 +9255,7 @@ function getDocument(src) { } const fetchDocParams = { docId, - apiVersion: "4.1.342", + apiVersion: "4.1.379", data, password, disableAutoFetch, @@ -9228,7 +9278,6 @@ function getDocument(src) { }; const transportParams = { ignoreErrors, - isEvalSupported, disableFontFace, fontExtraProperties, enableXfa, @@ -9294,7 +9343,7 @@ function getDataProp(val) { class PDFDocumentLoadingTask { static #docId = 0; constructor() { - this._capability = new PromiseCapability(); + this._capability = Promise.withResolvers(); this._transport = null; this._worker = null; this.docId = `d${PDFDocumentLoadingTask.#docId++}`; @@ -9335,7 +9384,7 @@ class PDFDataRangeTransport { this._progressListeners = []; this._progressiveReadListeners = []; this._progressiveDoneListeners = []; - this._readyCapability = new PromiseCapability(); + this._readyCapability = Promise.withResolvers(); } addRangeListener(listener) { this._rangeListeners.push(listener); @@ -9588,7 +9637,7 @@ class PDFPageProxy { } const intentPrint = !!(renderingIntent & RenderingIntentFlag.PRINT); if (!intentState.displayReadyCapability) { - intentState.displayReadyCapability = new PromiseCapability(); + intentState.displayReadyCapability = Promise.withResolvers(); intentState.operatorList = { fnArray: [], argsArray: [], @@ -9934,7 +9983,7 @@ class PDFWorker { this.name = name; this.destroyed = false; this.verbosity = verbosity; - this._readyCapability = new PromiseCapability(); + this._readyCapability = Promise.withResolvers(); this._port = null; this._webWorker = null; this._messageHandler = null; @@ -10110,7 +10159,7 @@ class WorkerTransport { this._networkStream = networkStream; this._fullReader = null; this._lastProgress = null; - this.downloadInfoCapability = new PromiseCapability(); + this.downloadInfoCapability = Promise.withResolvers(); this.setupMessageHandler(); } #cacheSimpleMethod(name, data = null) { @@ -10171,7 +10220,7 @@ class WorkerTransport { return this.destroyCapability.promise; } this.destroyed = true; - this.destroyCapability = new PromiseCapability(); + this.destroyCapability = Promise.withResolvers(); this.#passwordCapability?.reject(new Error("Worker was destroyed during onPassword callback")); const waitOn = []; for (const page of this.#pageCache.values()) { @@ -10239,7 +10288,7 @@ class WorkerTransport { }; }); messageHandler.on("ReaderHeadersReady", data => { - const headersCapability = new PromiseCapability(); + const headersCapability = Promise.withResolvers(); const fullReader = this._fullReader; fullReader.headersReady.then(() => { if (!fullReader.isStreamingSupported || !fullReader.isRangeSupported) { @@ -10325,7 +10374,7 @@ class WorkerTransport { loadingTask._capability.reject(reason); }); messageHandler.on("PasswordRequest", exception => { - this.#passwordCapability = new PromiseCapability(); + this.#passwordCapability = Promise.withResolvers(); if (loadingTask.onPassword) { const updatePassword = password => { if (password instanceof Error) { @@ -10378,7 +10427,6 @@ class WorkerTransport { } const inspectFont = params.pdfBug && globalThis.FontInspector?.enabled ? (font, url) => globalThis.FontInspector.fontAdded(font, url) : null; const font = new FontFaceObject(exportedData, { - isEvalSupported: params.isEvalSupported, disableFontFace: params.disableFontFace, ignoreErrors: params.ignoreErrors, inspectFont @@ -10639,34 +10687,35 @@ class WorkerTransport { }); } } +const INITIAL_DATA = Symbol("INITIAL_DATA"); class PDFObjects { #objs = Object.create(null); #ensureObj(objId) { return this.#objs[objId] ||= { - capability: new PromiseCapability(), - data: null + ...Promise.withResolvers(), + data: INITIAL_DATA }; } get(objId, callback = null) { if (callback) { const obj = this.#ensureObj(objId); - obj.capability.promise.then(() => callback(obj.data)); + obj.promise.then(() => callback(obj.data)); return null; } const obj = this.#objs[objId]; - if (!obj?.capability.settled) { + if (!obj || obj.data === INITIAL_DATA) { throw new Error(`Requesting object that isn't resolved yet ${objId}.`); } return obj.data; } has(objId) { const obj = this.#objs[objId]; - return obj?.capability.settled ?? false; + return !!obj && obj.data !== INITIAL_DATA; } resolve(objId, data = null) { const obj = this.#ensureObj(objId); obj.data = data; - obj.capability.resolve(); + obj.resolve(); } clear() { for (const objId in this.#objs) { @@ -10680,10 +10729,9 @@ class PDFObjects { *[Symbol.iterator]() { for (const objId in this.#objs) { const { - capability, data } = this.#objs[objId]; - if (!capability.settled) { + if (data === INITIAL_DATA) { continue; } yield [objId, data]; @@ -10748,7 +10796,7 @@ class InternalRenderTask { this.graphicsReady = false; this._useRequestAnimationFrame = useRequestAnimationFrame === true && typeof window !== "undefined"; this.cancelled = false; - this.capability = new PromiseCapability(); + this.capability = Promise.withResolvers(); this.task = new RenderTask(this); this._cancelBound = this.cancel.bind(this); this._continueBound = this._continue.bind(this); @@ -10849,8 +10897,8 @@ class InternalRenderTask { } } } -const version = "4.1.342"; -const build = "e384df6f1"; +const version = "4.1.379"; +const build = "017e49244"; ;// CONCATENATED MODULE: ./src/shared/scripting_utils.js function makeColorComp(n) { @@ -13708,7 +13756,6 @@ class FreeTextEditor extends AnnotationEditor { } onceAdded() { if (this.width) { - this.#cheatInitialRect(); return; } this.enableEditMode(); @@ -14085,22 +14132,9 @@ class FreeTextEditor extends AnnotationEditor { value, fontSize, color, - rect, pageIndex } = this.#initialData; - return serialized.value !== value || serialized.fontSize !== fontSize || serialized.rect.some((x, i) => Math.abs(x - rect[i]) >= 1) || serialized.color.some((c, i) => c !== color[i]) || serialized.pageIndex !== pageIndex; - } - #cheatInitialRect(delayed = false) { - if (!this.annotationElementId) { - return; - } - this.#setEditorDimensions(); - if (!delayed && (this.width === 0 || this.height === 0)) { - setTimeout(() => this.#cheatInitialRect(true), 0); - return; - } - const padding = FreeTextEditor._internalPadding * this.parentScale; - this.#initialData.rect = this.getRect(padding, padding); + return this._hasBeenMoved || serialized.value !== value || serialized.fontSize !== fontSize || serialized.color.some((c, i) => c !== color[i]) || serialized.pageIndex !== pageIndex; } } @@ -15315,10 +15349,8 @@ class HighlightEditor extends AnnotationEditor { } const div = super.render(); if (this.#text) { - const mark = document.createElement("mark"); - div.append(mark); - mark.append(document.createTextNode(this.#text)); - mark.className = "visuallyHidden"; + div.setAttribute("aria-label", this.#text); + div.setAttribute("role", "mark"); } if (this.#isFreeHighlight) { div.classList.add("free"); @@ -17534,8 +17566,8 @@ class DrawLayer { -const pdfjsVersion = "4.1.342"; -const pdfjsBuild = "e384df6f1"; +const pdfjsVersion = "4.1.379"; +const pdfjsBuild = "017e49244"; var __webpack_exports__AbortException = __webpack_exports__.AbortException; var __webpack_exports__AnnotationEditorLayer = __webpack_exports__.AnnotationEditorLayer; @@ -17561,7 +17593,6 @@ var __webpack_exports__PDFWorker = __webpack_exports__.PDFWorker; var __webpack_exports__PasswordResponses = __webpack_exports__.PasswordResponses; var __webpack_exports__PermissionFlag = __webpack_exports__.PermissionFlag; var __webpack_exports__PixelsPerInch = __webpack_exports__.PixelsPerInch; -var __webpack_exports__PromiseCapability = __webpack_exports__.PromiseCapability; var __webpack_exports__RenderingCancelledException = __webpack_exports__.RenderingCancelledException; var __webpack_exports__UnexpectedResponseException = __webpack_exports__.UnexpectedResponseException; var __webpack_exports__Util = __webpack_exports__.Util; @@ -17583,4 +17614,4 @@ var __webpack_exports__setLayerDimensions = __webpack_exports__.setLayerDimensio var __webpack_exports__shadow = __webpack_exports__.shadow; var __webpack_exports__updateTextLayer = __webpack_exports__.updateTextLayer; var __webpack_exports__version = __webpack_exports__.version; -export { __webpack_exports__AbortException as AbortException, __webpack_exports__AnnotationEditorLayer as AnnotationEditorLayer, __webpack_exports__AnnotationEditorParamsType as AnnotationEditorParamsType, __webpack_exports__AnnotationEditorType as AnnotationEditorType, __webpack_exports__AnnotationEditorUIManager as AnnotationEditorUIManager, __webpack_exports__AnnotationLayer as AnnotationLayer, __webpack_exports__AnnotationMode as AnnotationMode, __webpack_exports__CMapCompressionType as CMapCompressionType, __webpack_exports__ColorPicker as ColorPicker, __webpack_exports__DOMSVGFactory as DOMSVGFactory, __webpack_exports__DrawLayer as DrawLayer, __webpack_exports__FeatureTest as FeatureTest, __webpack_exports__GlobalWorkerOptions as GlobalWorkerOptions, __webpack_exports__ImageKind as ImageKind, __webpack_exports__InvalidPDFException as InvalidPDFException, __webpack_exports__MissingPDFException as MissingPDFException, __webpack_exports__OPS as OPS, __webpack_exports__Outliner as Outliner, __webpack_exports__PDFDataRangeTransport as PDFDataRangeTransport, __webpack_exports__PDFDateString as PDFDateString, __webpack_exports__PDFWorker as PDFWorker, __webpack_exports__PasswordResponses as PasswordResponses, __webpack_exports__PermissionFlag as PermissionFlag, __webpack_exports__PixelsPerInch as PixelsPerInch, __webpack_exports__PromiseCapability as PromiseCapability, __webpack_exports__RenderingCancelledException as RenderingCancelledException, __webpack_exports__UnexpectedResponseException as UnexpectedResponseException, __webpack_exports__Util as Util, __webpack_exports__VerbosityLevel as VerbosityLevel, __webpack_exports__XfaLayer as XfaLayer, __webpack_exports__build as build, __webpack_exports__createValidAbsoluteUrl as createValidAbsoluteUrl, __webpack_exports__fetchData as fetchData, __webpack_exports__getDocument as getDocument, __webpack_exports__getFilenameFromUrl as getFilenameFromUrl, __webpack_exports__getPdfFilenameFromUrl as getPdfFilenameFromUrl, __webpack_exports__getXfaPageViewport as getXfaPageViewport, __webpack_exports__isDataScheme as isDataScheme, __webpack_exports__isPdfFile as isPdfFile, __webpack_exports__noContextMenu as noContextMenu, __webpack_exports__normalizeUnicode as normalizeUnicode, __webpack_exports__renderTextLayer as renderTextLayer, __webpack_exports__setLayerDimensions as setLayerDimensions, __webpack_exports__shadow as shadow, __webpack_exports__updateTextLayer as updateTextLayer, __webpack_exports__version as version }; +export { __webpack_exports__AbortException as AbortException, __webpack_exports__AnnotationEditorLayer as AnnotationEditorLayer, __webpack_exports__AnnotationEditorParamsType as AnnotationEditorParamsType, __webpack_exports__AnnotationEditorType as AnnotationEditorType, __webpack_exports__AnnotationEditorUIManager as AnnotationEditorUIManager, __webpack_exports__AnnotationLayer as AnnotationLayer, __webpack_exports__AnnotationMode as AnnotationMode, __webpack_exports__CMapCompressionType as CMapCompressionType, __webpack_exports__ColorPicker as ColorPicker, __webpack_exports__DOMSVGFactory as DOMSVGFactory, __webpack_exports__DrawLayer as DrawLayer, __webpack_exports__FeatureTest as FeatureTest, __webpack_exports__GlobalWorkerOptions as GlobalWorkerOptions, __webpack_exports__ImageKind as ImageKind, __webpack_exports__InvalidPDFException as InvalidPDFException, __webpack_exports__MissingPDFException as MissingPDFException, __webpack_exports__OPS as OPS, __webpack_exports__Outliner as Outliner, __webpack_exports__PDFDataRangeTransport as PDFDataRangeTransport, __webpack_exports__PDFDateString as PDFDateString, __webpack_exports__PDFWorker as PDFWorker, __webpack_exports__PasswordResponses as PasswordResponses, __webpack_exports__PermissionFlag as PermissionFlag, __webpack_exports__PixelsPerInch as PixelsPerInch, __webpack_exports__RenderingCancelledException as RenderingCancelledException, __webpack_exports__UnexpectedResponseException as UnexpectedResponseException, __webpack_exports__Util as Util, __webpack_exports__VerbosityLevel as VerbosityLevel, __webpack_exports__XfaLayer as XfaLayer, __webpack_exports__build as build, __webpack_exports__createValidAbsoluteUrl as createValidAbsoluteUrl, __webpack_exports__fetchData as fetchData, __webpack_exports__getDocument as getDocument, __webpack_exports__getFilenameFromUrl as getFilenameFromUrl, __webpack_exports__getPdfFilenameFromUrl as getPdfFilenameFromUrl, __webpack_exports__getXfaPageViewport as getXfaPageViewport, __webpack_exports__isDataScheme as isDataScheme, __webpack_exports__isPdfFile as isPdfFile, __webpack_exports__noContextMenu as noContextMenu, __webpack_exports__normalizeUnicode as normalizeUnicode, __webpack_exports__renderTextLayer as renderTextLayer, __webpack_exports__setLayerDimensions as setLayerDimensions, __webpack_exports__shadow as shadow, __webpack_exports__updateTextLayer as updateTextLayer, __webpack_exports__version as version }; diff --git a/toolkit/components/pdfjs/content/build/pdf.scripting.mjs b/toolkit/components/pdfjs/content/build/pdf.scripting.mjs index f590e83af3..8f4c2a7762 100644 --- a/toolkit/components/pdfjs/content/build/pdf.scripting.mjs +++ b/toolkit/components/pdfjs/content/build/pdf.scripting.mjs @@ -3957,8 +3957,8 @@ function initSandbox(params) { ;// CONCATENATED MODULE: ./src/pdf.scripting.js -const pdfjsVersion = "4.1.342"; -const pdfjsBuild = "e384df6f1"; +const pdfjsVersion = "4.1.379"; +const pdfjsBuild = "017e49244"; globalThis.pdfjsScripting = { initSandbox: initSandbox }; diff --git a/toolkit/components/pdfjs/content/build/pdf.worker.mjs b/toolkit/components/pdfjs/content/build/pdf.worker.mjs index e2cd54cf56..76770f6556 100644 --- a/toolkit/components/pdfjs/content/build/pdf.worker.mjs +++ b/toolkit/components/pdfjs/content/build/pdf.worker.mjs @@ -744,24 +744,6 @@ function getModificationDate(date = new Date()) { const buffer = [date.getUTCFullYear().toString(), (date.getUTCMonth() + 1).toString().padStart(2, "0"), date.getUTCDate().toString().padStart(2, "0"), date.getUTCHours().toString().padStart(2, "0"), date.getUTCMinutes().toString().padStart(2, "0"), date.getUTCSeconds().toString().padStart(2, "0")]; return buffer.join(""); } -class PromiseCapability { - #settled = false; - constructor() { - this.promise = new Promise((resolve, reject) => { - this.resolve = data => { - this.#settled = true; - resolve(data); - }; - this.reject = reason => { - this.#settled = true; - reject(reason); - }; - }); - } - get settled() { - return this.#settled; - } -} let NormalizeRegex = null; let NormalizationMap = null; function normalizeUnicode(str) { @@ -775,6 +757,17 @@ function getUuid() { return crypto.randomUUID(); } const AnnotationPrefix = "pdfjs_internal_id_"; +const FontRenderOps = { + BEZIER_CURVE_TO: 0, + MOVE_TO: 1, + LINE_TO: 2, + QUADRATIC_CURVE_TO: 3, + RESTORE: 4, + SAVE: 5, + SCALE: 6, + TRANSFORM: 7, + TRANSLATE: 8 +}; ;// CONCATENATED MODULE: ./src/core/primitives.js @@ -1789,7 +1782,7 @@ class ChunkedStreamManager { this._promisesByRequest = new Map(); this.progressiveDataLength = 0; this.aborted = false; - this._loadedStreamCapability = new PromiseCapability(); + this._loadedStreamCapability = Promise.withResolvers(); } sendRequest(begin, end) { const rangeReader = this.pdfNetworkStream.getRangeReader(begin, end); @@ -1852,7 +1845,7 @@ class ChunkedStreamManager { if (chunksNeeded.size === 0) { return Promise.resolve(); } - const capability = new PromiseCapability(); + const capability = Promise.withResolvers(); this._promisesByRequest.set(requestId, capability); const chunksToRequest = []; for (const chunk of chunksNeeded) { @@ -5075,6 +5068,18 @@ function decodeTextRegion(huffman, refinement, width, height, defaultPixelValue, symbolHeight += rdh; symbolBitmap = decodeRefinement(symbolWidth, symbolHeight, refinementTemplateIndex, symbolBitmap, (rdw >> 1) + rdx, (rdh >> 1) + rdy, false, refinementAt, decodingContext); } + let increment = 0; + if (!transposed) { + if (referenceCorner > 1) { + currentS += symbolWidth - 1; + } else { + increment = symbolWidth - 1; + } + } else if (!(referenceCorner & 1)) { + currentS += symbolHeight - 1; + } else { + increment = symbolHeight - 1; + } const offsetT = t - (referenceCorner & 1 ? 0 : symbolHeight - 1); const offsetS = currentS - (referenceCorner & 2 ? symbolWidth - 1 : 0); let s2, t2, symbolRow; @@ -5101,7 +5106,6 @@ function decodeTextRegion(huffman, refinement, width, height, defaultPixelValue, throw new Jbig2Error(`operator ${combinationOperator} is not supported`); } } - currentS += symbolHeight - 1; } else { for (t2 = 0; t2 < symbolHeight; t2++) { row = bitmap[offsetT + t2]; @@ -5124,14 +5128,13 @@ function decodeTextRegion(huffman, refinement, width, height, defaultPixelValue, throw new Jbig2Error(`operator ${combinationOperator} is not supported`); } } - currentS += symbolWidth - 1; } i++; const deltaS = huffman ? huffmanTables.tableDeltaS.decode(huffmanInput) : decodeInteger(contextCache, "IADS", decoder); if (deltaS === null) { break; } - currentS += deltaS + dsOffset; + currentS += increment + deltaS + dsOffset; } while (true); } return bitmap; @@ -18702,22 +18705,13 @@ function lookupCmap(ranges, unicode) { } function compileGlyf(code, cmds, font) { function moveTo(x, y) { - cmds.push({ - cmd: "moveTo", - args: [x, y] - }); + cmds.add(FontRenderOps.MOVE_TO, [x, y]); } function lineTo(x, y) { - cmds.push({ - cmd: "lineTo", - args: [x, y] - }); + cmds.add(FontRenderOps.LINE_TO, [x, y]); } function quadraticCurveTo(xa, ya, x, y) { - cmds.push({ - cmd: "quadraticCurveTo", - args: [xa, ya, x, y] - }); + cmds.add(FontRenderOps.QUADRATIC_CURVE_TO, [xa, ya, x, y]); } let i = 0; const numberOfContours = getInt16(code, i); @@ -18774,17 +18768,11 @@ function compileGlyf(code, cmds, font) { } const subglyph = font.glyphs[glyphIndex]; if (subglyph) { - cmds.push({ - cmd: "save" - }, { - cmd: "transform", - args: [scaleX, scale01, scale10, scaleY, x, y] - }); + cmds.add(FontRenderOps.SAVE); + cmds.add(FontRenderOps.TRANSFORM, [scaleX, scale01, scale10, scaleY, x, y]); if (!(flags & 0x02)) {} compileGlyf(subglyph, cmds, font); - cmds.push({ - cmd: "restore" - }); + cmds.add(FontRenderOps.RESTORE); } } while (flags & 0x20); } else { @@ -18874,22 +18862,13 @@ function compileGlyf(code, cmds, font) { } function compileCharString(charStringCode, cmds, font, glyphId) { function moveTo(x, y) { - cmds.push({ - cmd: "moveTo", - args: [x, y] - }); + cmds.add(FontRenderOps.MOVE_TO, [x, y]); } function lineTo(x, y) { - cmds.push({ - cmd: "lineTo", - args: [x, y] - }); + cmds.add(FontRenderOps.LINE_TO, [x, y]); } function bezierCurveTo(x1, y1, x2, y2, x, y) { - cmds.push({ - cmd: "bezierCurveTo", - args: [x1, y1, x2, y2, x, y] - }); + cmds.add(FontRenderOps.BEZIER_CURVE_TO, [x1, y1, x2, y2, x, y]); } const stack = []; let x = 0, @@ -19059,17 +19038,11 @@ function compileCharString(charStringCode, cmds, font, glyphId) { const bchar = stack.pop(); y = stack.pop(); x = stack.pop(); - cmds.push({ - cmd: "save" - }, { - cmd: "translate", - args: [x, y] - }); + cmds.add(FontRenderOps.SAVE); + cmds.add(FontRenderOps.TRANSLATE, [x, y]); let cmap = lookupCmap(font.cmap, String.fromCharCode(font.glyphNameMap[StandardEncoding[achar]])); compileCharString(font.glyphs[cmap.glyphId], cmds, font, cmap.glyphId); - cmds.push({ - cmd: "restore" - }); + cmds.add(FontRenderOps.RESTORE); cmap = lookupCmap(font.cmap, String.fromCharCode(font.glyphNameMap[StandardEncoding[bchar]])); compileCharString(font.glyphs[cmap.glyphId], cmds, font, cmap.glyphId); } @@ -19236,6 +19209,22 @@ function compileCharString(charStringCode, cmds, font, glyphId) { parse(charStringCode); } const NOOP = []; +class Commands { + cmds = []; + add(cmd, args) { + if (args) { + if (args.some(arg => typeof arg !== "number")) { + warn(`Commands.add - "${cmd}" has at least one non-number arg: "${args}".`); + const newArgs = args.map(arg => typeof arg === "number" ? arg : 0); + this.cmds.push(cmd, ...newArgs); + } else { + this.cmds.push(cmd, ...args); + } + } else { + this.cmds.push(cmd); + } + } +} class CompiledFont { constructor(fontMatrix) { if (this.constructor === CompiledFont) { @@ -19253,8 +19242,7 @@ class CompiledFont { let fn = this.compiledGlyphs[glyphId]; if (!fn) { try { - fn = this.compileGlyph(this.glyphs[glyphId], glyphId); - this.compiledGlyphs[glyphId] = fn; + fn = this.compiledGlyphs[glyphId] = this.compileGlyph(this.glyphs[glyphId], glyphId); } catch (ex) { this.compiledGlyphs[glyphId] = NOOP; if (this.compiledCharCodeToGlyphId[charCode] === undefined) { @@ -19282,20 +19270,13 @@ class CompiledFont { warn("Invalid fd index for glyph index."); } } - const cmds = [{ - cmd: "save" - }, { - cmd: "transform", - args: fontMatrix.slice() - }, { - cmd: "scale", - args: ["size", "-size"] - }]; + const cmds = new Commands(); + cmds.add(FontRenderOps.SAVE); + cmds.add(FontRenderOps.TRANSFORM, fontMatrix.slice()); + cmds.add(FontRenderOps.SCALE); this.compileGlyphImpl(code, cmds, glyphId); - cmds.push({ - cmd: "restore" - }); - return cmds; + cmds.add(FontRenderOps.RESTORE); + return cmds.cmds; } compileGlyphImpl() { unreachable("Children classes should implement this."); @@ -25941,14 +25922,18 @@ class Font { charCodeToGlyphId[mapping.charCode] = mapping.glyphId; } forcePostTable = true; - } else { + } else if (cmapPlatformId === 3 && cmapEncodingId === 0) { for (const mapping of cmapMappings) { let charCode = mapping.charCode; - if (cmapPlatformId === 3 && charCode >= 0xf000 && charCode <= 0xf0ff) { + if (charCode >= 0xf000 && charCode <= 0xf0ff) { charCode &= 0xff; } charCodeToGlyphId[charCode] = mapping.glyphId; } + } else { + for (const mapping of cmapMappings) { + charCodeToGlyphId[mapping.charCode] = mapping.glyphId; + } } if (properties.glyphNames && (baseEncoding.length || this.differences.length)) { for (let i = 0; i < 256; ++i) { @@ -27080,7 +27065,13 @@ class MeshShading extends BaseShading { } } getIR() { - return ["Mesh", this.shadingType, this.coords, this.colors, this.figures, this.bounds, this.bbox, this.background]; + const { + bounds + } = this; + if (bounds[2] - bounds[0] === 0 || bounds[3] - bounds[1] === 0) { + throw new FormatError(`Invalid MeshShading bounds: [${bounds}].`); + } + return ["Mesh", this.shadingType, this.coords, this.colors, this.figures, bounds, this.bbox, this.background]; } } class DummyShading extends BaseShading { @@ -31794,7 +31785,10 @@ class PartialEvaluator { if (font.cacheKey && this.fontCache.has(font.cacheKey)) { return this.fontCache.get(font.cacheKey); } - const fontCapability = new PromiseCapability(); + const { + promise, + resolve + } = Promise.withResolvers(); let preEvaluatedFont; try { preEvaluatedFont = this.preEvaluateFont(font); @@ -31831,14 +31825,14 @@ class PartialEvaluator { } assert(fontID?.startsWith("f"), 'The "fontID" must be (correctly) defined.'); if (fontRefIsRef) { - this.fontCache.put(fontRef, fontCapability.promise); + this.fontCache.put(fontRef, promise); } else { font.cacheKey = `cacheKey_${fontID}`; - this.fontCache.put(font.cacheKey, fontCapability.promise); + this.fontCache.put(font.cacheKey, promise); } font.loadedName = `${this.idFactory.getDocId()}_${fontID}`; this.translateFont(preEvaluatedFont).then(translatedFont => { - fontCapability.resolve(new TranslatedFont({ + resolve(new TranslatedFont({ loadedName: font.loadedName, font: translatedFont, dict: font, @@ -31846,14 +31840,14 @@ class PartialEvaluator { })); }).catch(reason => { warn(`loadFont - translateFont failed: "${reason}".`); - fontCapability.resolve(new TranslatedFont({ + resolve(new TranslatedFont({ loadedName: font.loadedName, font: new ErrorFont(reason instanceof Error ? reason.message : reason), dict: font, evaluatorOptions: this.options })); }); - return fontCapability.promise; + return promise; } buildPath(operatorList, fn, args, parsingText = false) { const lastIndex = operatorList.length - 1; @@ -31937,19 +31931,33 @@ class PartialEvaluator { localShadingPatternCache }) { let id = localShadingPatternCache.get(shading); - if (!id) { - var shadingFill = Pattern.parseShading(shading, this.xref, resources, this._pdfFunctionFactory, localColorSpaceCache); - const patternIR = shadingFill.getIR(); - id = `pattern_${this.idFactory.createObjId()}`; - if (this.parsingType3Font) { - id = `${this.idFactory.getDocId()}_type3_${id}`; + if (id) { + return id; + } + let patternIR; + try { + const shadingFill = Pattern.parseShading(shading, this.xref, resources, this._pdfFunctionFactory, localColorSpaceCache); + patternIR = shadingFill.getIR(); + } catch (reason) { + if (reason instanceof AbortException) { + return null; } - localShadingPatternCache.set(shading, id); - if (this.parsingType3Font) { - this.handler.send("commonobj", [id, "Pattern", patternIR]); - } else { - this.handler.send("obj", [id, this.pageIndex, "Pattern", patternIR]); + if (this.options.ignoreErrors) { + warn(`parseShading - ignoring shading: "${reason}".`); + localShadingPatternCache.set(shading, null); + return null; } + throw reason; + } + id = `pattern_${this.idFactory.createObjId()}`; + if (this.parsingType3Font) { + id = `${this.idFactory.getDocId()}_type3_${id}`; + } + localShadingPatternCache.set(shading, id); + if (this.parsingType3Font) { + this.handler.send("commonobj", [id, "Pattern", patternIR]); + } else { + this.handler.send("obj", [id, this.pageIndex, "Pattern", patternIR]); } return id; } @@ -31975,14 +31983,16 @@ class PartialEvaluator { return this.handleTilingType(fn, color, resources, pattern, dict, operatorList, task, localTilingPatternCache); } else if (typeNum === PatternType.SHADING) { const shading = dict.get("Shading"); - const matrix = dict.getArray("Matrix"); const objId = this.parseShading({ shading, resources, localColorSpaceCache, localShadingPatternCache }); - operatorList.addOp(fn, ["Shading", objId, matrix]); + if (objId) { + const matrix = dict.getArray("Matrix"); + operatorList.addOp(fn, ["Shading", objId, matrix]); + } return undefined; } throw new FormatError(`Unknown PatternType: ${typeNum}`); @@ -32393,6 +32403,9 @@ class PartialEvaluator { localColorSpaceCache, localShadingPatternCache }); + if (!patternId) { + continue; + } args = [patternId]; fn = OPS.shadingFill; break; @@ -33998,6 +34011,10 @@ class PartialEvaluator { systemFontInfo = getFontSubstitution(this.systemFontCache, this.idFactory, this.options.standardFontDataUrl, fontName.name, standardFontName); } } + let fontMatrix = dict.getArray("FontMatrix"); + if (!Array.isArray(fontMatrix) || fontMatrix.length !== 6 || fontMatrix.some(x => typeof x !== "number")) { + fontMatrix = FONT_IDENTITY_MATRIX; + } const properties = { type, name: fontName.name, @@ -34010,7 +34027,7 @@ class PartialEvaluator { loadedName: baseDict.loadedName, composite, fixedPitch: false, - fontMatrix: dict.getArray("FontMatrix") || FONT_IDENTITY_MATRIX, + fontMatrix, firstChar, lastChar, toUnicode, @@ -35327,7 +35344,8 @@ function pickPlatformItem(dict) { return null; } class FileSpec { - constructor(root, xref) { + #contentAvailable = false; + constructor(root, xref, skipContent = false) { if (!(root instanceof Dict)) { return; } @@ -35340,10 +35358,12 @@ class FileSpec { if (root.has("RF")) { warn("Related file specifications are not supported"); } - this.contentAvailable = true; - if (!root.has("EF")) { - this.contentAvailable = false; - warn("Non-embedded file specifications are not supported"); + if (!skipContent) { + if (root.has("EF")) { + this.#contentAvailable = true; + } else { + warn("Non-embedded file specifications are not supported"); + } } } get filename() { @@ -35354,7 +35374,7 @@ class FileSpec { return this._filename; } get content() { - if (!this.contentAvailable) { + if (!this.#contentAvailable) { return null; } if (!this.contentRef && this.root) { @@ -38563,7 +38583,7 @@ class Catalog { continue; } if (!outlineDict.has("Title")) { - throw new FormatError("Invalid outline item encountered."); + warn("Invalid outline item encountered."); } const data = { url: null, @@ -38592,7 +38612,7 @@ class Catalog { unsafeUrl: data.unsafeUrl, newWindow: data.newWindow, setOCGState: data.setOCGState, - title: stringToPDFString(title), + title: typeof title === "string" ? stringToPDFString(title) : "", color: rgbColor, count: Number.isInteger(count) ? count : undefined, bold: !!(flags & 2), @@ -39598,7 +39618,11 @@ class Catalog { case "GoToR": const urlDict = action.get("F"); if (urlDict instanceof Dict) { - url = urlDict.get("F") || null; + const fs = new FileSpec(urlDict, null, true); + const { + filename + } = fs.serializable; + url = filename; } else if (typeof urlDict === "string") { url = urlDict; } @@ -51360,7 +51384,7 @@ class AnnotationBorderStyle { } } setDashArray(dashArray, forceStyle = false) { - if (Array.isArray(dashArray) && dashArray.length > 0) { + if (Array.isArray(dashArray)) { let isValid = true; let allZeros = true; for (const element of dashArray) { @@ -51372,7 +51396,7 @@ class AnnotationBorderStyle { allZeros = false; } } - if (isValid && !allZeros) { + if (dashArray.length === 0 || isValid && !allZeros) { this.dashArray = dashArray; if (forceStyle) { this.setStyle(Name.get("D")); @@ -56282,7 +56306,7 @@ class MessageHandler { } sendWithPromise(actionName, data, transfers) { const callbackId = this.callbackId++; - const capability = new PromiseCapability(); + const capability = Promise.withResolvers(); this.callbackCapabilities[callbackId] = capability; try { this.comObj.postMessage({ @@ -56304,7 +56328,7 @@ class MessageHandler { comObj = this.comObj; return new ReadableStream({ start: controller => { - const startCapability = new PromiseCapability(); + const startCapability = Promise.withResolvers(); this.streamControllers[streamId] = { controller, startCall: startCapability, @@ -56323,7 +56347,7 @@ class MessageHandler { return startCapability.promise; }, pull: controller => { - const pullCapability = new PromiseCapability(); + const pullCapability = Promise.withResolvers(); this.streamControllers[streamId].pullCall = pullCapability; comObj.postMessage({ sourceName, @@ -56336,7 +56360,7 @@ class MessageHandler { }, cancel: reason => { assert(reason instanceof Error, "cancel must have a valid reason"); - const cancelCapability = new PromiseCapability(); + const cancelCapability = Promise.withResolvers(); this.streamControllers[streamId].cancelCall = cancelCapability; this.streamControllers[streamId].isClosed = true; comObj.postMessage({ @@ -56365,7 +56389,7 @@ class MessageHandler { const lastDesiredSize = this.desiredSize; this.desiredSize -= size; if (lastDesiredSize > 0 && this.desiredSize <= 0) { - this.sinkCapability = new PromiseCapability(); + this.sinkCapability = Promise.withResolvers(); this.ready = this.sinkCapability.promise; } comObj.postMessage({ @@ -56403,7 +56427,7 @@ class MessageHandler { reason: wrapReason(reason) }); }, - sinkCapability: new PromiseCapability(), + sinkCapability: Promise.withResolvers(), onPull: null, onCancel: null, isCancelled: false, @@ -56681,7 +56705,7 @@ class WorkerTask { constructor(name) { this.name = name; this.terminated = false; - this._capability = new PromiseCapability(); + this._capability = Promise.withResolvers(); } get finished() { return this._capability.promise; @@ -56725,7 +56749,7 @@ class WorkerMessageHandler { docId, apiVersion } = docParams; - const workerVersion = "4.1.342"; + const workerVersion = "4.1.379"; if (apiVersion !== workerVersion) { throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`); } @@ -56785,7 +56809,7 @@ class WorkerMessageHandler { password, rangeChunkSize }; - const pdfManagerCapability = new PromiseCapability(); + const pdfManagerCapability = Promise.withResolvers(); let newPdfManager; if (data) { try { @@ -57287,8 +57311,8 @@ if (typeof window === "undefined" && !isNodeJS && typeof self !== "undefined" && ;// CONCATENATED MODULE: ./src/pdf.worker.js -const pdfjsVersion = "4.1.342"; -const pdfjsBuild = "e384df6f1"; +const pdfjsVersion = "4.1.379"; +const pdfjsBuild = "017e49244"; var __webpack_exports__WorkerMessageHandler = __webpack_exports__.WorkerMessageHandler; export { __webpack_exports__WorkerMessageHandler as WorkerMessageHandler }; diff --git a/toolkit/components/pdfjs/content/web/viewer-geckoview.mjs b/toolkit/components/pdfjs/content/web/viewer-geckoview.mjs index 866c4a405a..c309f8cf12 100644 --- a/toolkit/components/pdfjs/content/web/viewer-geckoview.mjs +++ b/toolkit/components/pdfjs/content/web/viewer-geckoview.mjs @@ -529,7 +529,6 @@ function toggleExpandedBtn(button, toggle, view = null) { } ;// CONCATENATED MODULE: ./web/app_options.js -const compatibilityParams = Object.create(null); const OptionKind = { BROWSER: 0x01, VIEWER: 0x02, @@ -772,11 +771,8 @@ class AppOptions { constructor() { throw new Error("Cannot initialize AppOptions."); } - static getCompat(name) { - return compatibilityParams[name] ?? undefined; - } static get(name) { - return userOptions[name] ?? compatibilityParams[name] ?? defaultOptions[name]?.value ?? undefined; + return userOptions[name] ?? defaultOptions[name]?.value ?? undefined; } static getAll(kind = null, defaultOnly = false) { const options = Object.create(null); @@ -785,7 +781,7 @@ class AppOptions { if (kind && !(kind & defaultOption.kind)) { continue; } - options[name] = defaultOnly ? defaultOption.value : userOptions[name] ?? compatibilityParams[name] ?? defaultOption.value; + options[name] = defaultOnly ? defaultOption.value : userOptions[name] ?? defaultOption.value; } return options; } @@ -1252,7 +1248,6 @@ const { PDFWorker, PermissionFlag, PixelsPerInch, - PromiseCapability, RenderingCancelledException, renderTextLayer, setLayerDimensions, @@ -1270,35 +1265,38 @@ const WaitOnType = { EVENT: "event", TIMEOUT: "timeout" }; -function waitOnEventOrTimeout({ +async function waitOnEventOrTimeout({ target, name, delay = 0 }) { - return new Promise(function (resolve, reject) { - if (typeof target !== "object" || !(name && typeof name === "string") || !(Number.isInteger(delay) && delay >= 0)) { - throw new Error("waitOnEventOrTimeout - invalid parameters."); - } - function handler(type) { - if (target instanceof EventBus) { - target._off(name, eventHandler); - } else { - target.removeEventListener(name, eventHandler); - } - if (timeout) { - clearTimeout(timeout); - } - resolve(type); - } - const eventHandler = handler.bind(null, WaitOnType.EVENT); + if (typeof target !== "object" || !(name && typeof name === "string") || !(Number.isInteger(delay) && delay >= 0)) { + throw new Error("waitOnEventOrTimeout - invalid parameters."); + } + const { + promise, + resolve + } = Promise.withResolvers(); + function handler(type) { if (target instanceof EventBus) { - target._on(name, eventHandler); + target._off(name, eventHandler); } else { - target.addEventListener(name, eventHandler); + target.removeEventListener(name, eventHandler); } - const timeoutHandler = handler.bind(null, WaitOnType.TIMEOUT); - const timeout = setTimeout(timeoutHandler, delay); - }); + if (timeout) { + clearTimeout(timeout); + } + resolve(type); + } + const eventHandler = handler.bind(null, WaitOnType.EVENT); + if (target instanceof EventBus) { + target._on(name, eventHandler); + } else { + target.addEventListener(name, eventHandler); + } + const timeoutHandler = handler.bind(null, WaitOnType.TIMEOUT); + const timeout = setTimeout(timeoutHandler, delay); + return promise; } class EventBus { #listeners = Object.create(null); @@ -2200,10 +2198,8 @@ class PasswordPrompt { this.dialog.addEventListener("close", this.#cancel.bind(this)); } async open() { - if (this.#activeCapability) { - await this.#activeCapability.promise; - } - this.#activeCapability = new PromiseCapability(); + await this.#activeCapability?.promise; + this.#activeCapability = Promise.withResolvers(); try { await this.overlayManager.open(this.dialog); } catch (ex) { @@ -2326,7 +2322,6 @@ function getNormalizeWithNFKC() { ;// CONCATENATED MODULE: ./web/pdf_find_controller.js - const FindState = { FOUND: 0, NOT_FOUND: 1, @@ -2664,7 +2659,7 @@ class PDFFindController { this._dirtyMatch = false; clearTimeout(this._findTimeout); this._findTimeout = null; - this._firstPageCapability = new PromiseCapability(); + this._firstPageCapability = Promise.withResolvers(); } get #query() { const { @@ -2827,14 +2822,17 @@ class PDFFindController { if (this._extractTextPromises.length > 0) { return; } - let promise = Promise.resolve(); + let deferred = Promise.resolve(); const textOptions = { disableNormalization: true }; for (let i = 0, ii = this._linkService.pagesCount; i < ii; i++) { - const extractTextCapability = new PromiseCapability(); - this._extractTextPromises[i] = extractTextCapability.promise; - promise = promise.then(() => { + const { + promise, + resolve + } = Promise.withResolvers(); + this._extractTextPromises[i] = promise; + deferred = deferred.then(() => { return this._pdfDocument.getPage(i + 1).then(pdfPage => pdfPage.getTextContent(textOptions)).then(textContent => { const strBuf = []; for (const textItem of textContent.items) { @@ -2844,13 +2842,13 @@ class PDFFindController { } } [this._pageContents[i], this._pageDiffs[i], this._hasDiacritics[i]] = normalize(strBuf.join("")); - extractTextCapability.resolve(); + resolve(); }, reason => { console.error(`Unable to get text content for page ${i + 1}`, reason); this._pageContents[i] = ""; this._pageDiffs[i] = null; this._hasDiacritics[i] = false; - extractTextCapability.resolve(); + resolve(); }); }); } @@ -3982,7 +3980,7 @@ class PDFScriptingManager { return; } await this.#willPrintCapability?.promise; - this.#willPrintCapability = new PromiseCapability(); + this.#willPrintCapability = Promise.withResolvers(); try { await this.#scripting.dispatchEventInSandbox({ id: "doc", @@ -4111,7 +4109,7 @@ class PDFScriptingManager { const pdfDocument = this.#pdfDocument, visitedPages = this._visitedPages; if (initialize) { - this.#closeCapability = new PromiseCapability(); + this.#closeCapability = Promise.withResolvers(); } if (!this.#closeCapability) { return; @@ -4161,7 +4159,7 @@ class PDFScriptingManager { }); } #initScripting() { - this.#destroyCapability = new PromiseCapability(); + this.#destroyCapability = Promise.withResolvers(); if (this.#scripting) { throw new Error("#initScripting: Scripting already exists."); } @@ -5116,7 +5114,7 @@ class PDFPageView { this.#textLayerMode = options.textLayerMode ?? TextLayerMode.ENABLE; this.#annotationMode = options.annotationMode ?? AnnotationMode.ENABLE_FORMS; this.imageResourcesPath = options.imageResourcesPath || ""; - this.maxCanvasPixels = options.maxCanvasPixels ?? (AppOptions.getCompat("maxCanvasPixels") || 2 ** 25); + this.maxCanvasPixels = options.maxCanvasPixels ?? AppOptions.get("maxCanvasPixels"); this.pageColors = options.pageColors || null; this.eventBus = options.eventBus; this.renderingQueue = options.renderingQueue; @@ -5922,7 +5920,7 @@ class PDFViewer { #scaleTimeoutId = null; #textLayerMode = TextLayerMode.ENABLE; constructor(options) { - const viewerVersion = "4.1.342"; + const viewerVersion = "4.1.379"; if (version !== viewerVersion) { throw new Error(`The API version "${version}" does not match the Viewer version "${viewerVersion}".`); } @@ -5977,7 +5975,7 @@ class PDFViewer { return new Set(this.#buffer); } get pageViewsReady() { - return this._pagesCapability.settled && this._pages.every(pageView => pageView?.pdfPage); + return this._pages.every(pageView => pageView?.pdfPage); } get renderForms() { return this.#annotationMode === AnnotationMode.ENABLE_FORMS; @@ -6280,7 +6278,7 @@ class PDFViewer { }; this.eventBus._on("pagerender", this._onBeforeDraw); this._onAfterDraw = evt => { - if (evt.cssTransform || this._onePageRenderedCapability.settled) { + if (evt.cssTransform) { return; } this._onePageRenderedCapability.resolve({ @@ -6452,9 +6450,9 @@ class PDFViewer { this._location = null; this._pagesRotation = 0; this._optionalContentConfigPromise = null; - this._firstPageCapability = new PromiseCapability(); - this._onePageRenderedCapability = new PromiseCapability(); - this._pagesCapability = new PromiseCapability(); + this._firstPageCapability = Promise.withResolvers(); + this._onePageRenderedCapability = Promise.withResolvers(); + this._pagesCapability = Promise.withResolvers(); this._scrollMode = ScrollMode.VERTICAL; this._previousScrollMode = ScrollMode.UNKNOWN; this._spreadMode = SpreadMode.NONE; @@ -7475,7 +7473,10 @@ const ViewOnLoad = { }; const PDFViewerApplication = { initialBookmark: document.location.hash.substring(1), - _initializedCapability: new PromiseCapability(), + _initializedCapability: { + ...Promise.withResolvers(), + settled: false + }, appConfig: null, pdfDocument: null, pdfLoadingTask: null, @@ -7550,6 +7551,7 @@ const PDFViewerApplication = { await this._initializeViewerComponents(); this.bindEvents(); this.bindWindowEvents(); + this._initializedCapability.settled = true; this._initializedCapability.resolve(); }, async _parseHashParams() { @@ -8608,6 +8610,10 @@ const PDFViewerApplication = { mediaQueryList.addEventListener("change", addWindowResolutionChange, { once: true }); + _boundEvents.removeWindowResolutionChange ||= function () { + mediaQueryList.removeEventListener("change", addWindowResolutionChange); + _boundEvents.removeWindowResolutionChange = null; + }; } addWindowResolutionChange(); _boundEvents.windowResize = () => { @@ -9531,8 +9537,8 @@ function webViewerReportTelemetry({ -const pdfjsVersion = "4.1.342"; -const pdfjsBuild = "e384df6f1"; +const pdfjsVersion = "4.1.379"; +const pdfjsBuild = "017e49244"; const AppConstants = null; window.PDFViewerApplication = PDFViewerApplication; window.PDFViewerApplicationConstants = AppConstants; diff --git a/toolkit/components/pdfjs/content/web/viewer.css b/toolkit/components/pdfjs/content/web/viewer.css index 2999c89f3a..063fa1632b 100644 --- a/toolkit/components/pdfjs/content/web/viewer.css +++ b/toolkit/components/pdfjs/content/web/viewer.css @@ -3513,7 +3513,7 @@ a:is(.toolbarButton, .secondaryToolbarButton)[href="#"]{ transition-property:none; .loadingInput:has(> &.loading)::after{ - display: block; + display:block; visibility:visible; transition-property:visibility; @@ -3525,7 +3525,7 @@ a:is(.toolbarButton, .secondaryToolbarButton)[href="#"]{ &::after{ position:absolute; visibility:hidden; - display: none; + display:none; top:calc(50% - 8px); width:16px; height:16px; diff --git a/toolkit/components/pdfjs/content/web/viewer.mjs b/toolkit/components/pdfjs/content/web/viewer.mjs index 778ce57e1a..864140b624 100644 --- a/toolkit/components/pdfjs/content/web/viewer.mjs +++ b/toolkit/components/pdfjs/content/web/viewer.mjs @@ -529,7 +529,6 @@ function toggleExpandedBtn(button, toggle, view = null) { } ;// CONCATENATED MODULE: ./web/app_options.js -const compatibilityParams = Object.create(null); const OptionKind = { BROWSER: 0x01, VIEWER: 0x02, @@ -772,11 +771,8 @@ class AppOptions { constructor() { throw new Error("Cannot initialize AppOptions."); } - static getCompat(name) { - return compatibilityParams[name] ?? undefined; - } static get(name) { - return userOptions[name] ?? compatibilityParams[name] ?? defaultOptions[name]?.value ?? undefined; + return userOptions[name] ?? defaultOptions[name]?.value ?? undefined; } static getAll(kind = null, defaultOnly = false) { const options = Object.create(null); @@ -785,7 +781,7 @@ class AppOptions { if (kind && !(kind & defaultOption.kind)) { continue; } - options[name] = defaultOnly ? defaultOption.value : userOptions[name] ?? compatibilityParams[name] ?? defaultOption.value; + options[name] = defaultOnly ? defaultOption.value : userOptions[name] ?? defaultOption.value; } return options; } @@ -1252,7 +1248,6 @@ const { PDFWorker, PermissionFlag, PixelsPerInch, - PromiseCapability, RenderingCancelledException, renderTextLayer, setLayerDimensions, @@ -1270,35 +1265,38 @@ const WaitOnType = { EVENT: "event", TIMEOUT: "timeout" }; -function waitOnEventOrTimeout({ +async function waitOnEventOrTimeout({ target, name, delay = 0 }) { - return new Promise(function (resolve, reject) { - if (typeof target !== "object" || !(name && typeof name === "string") || !(Number.isInteger(delay) && delay >= 0)) { - throw new Error("waitOnEventOrTimeout - invalid parameters."); - } - function handler(type) { - if (target instanceof EventBus) { - target._off(name, eventHandler); - } else { - target.removeEventListener(name, eventHandler); - } - if (timeout) { - clearTimeout(timeout); - } - resolve(type); - } - const eventHandler = handler.bind(null, WaitOnType.EVENT); + if (typeof target !== "object" || !(name && typeof name === "string") || !(Number.isInteger(delay) && delay >= 0)) { + throw new Error("waitOnEventOrTimeout - invalid parameters."); + } + const { + promise, + resolve + } = Promise.withResolvers(); + function handler(type) { if (target instanceof EventBus) { - target._on(name, eventHandler); + target._off(name, eventHandler); } else { - target.addEventListener(name, eventHandler); + target.removeEventListener(name, eventHandler); } - const timeoutHandler = handler.bind(null, WaitOnType.TIMEOUT); - const timeout = setTimeout(timeoutHandler, delay); - }); + if (timeout) { + clearTimeout(timeout); + } + resolve(type); + } + const eventHandler = handler.bind(null, WaitOnType.EVENT); + if (target instanceof EventBus) { + target._on(name, eventHandler); + } else { + target.addEventListener(name, eventHandler); + } + const timeoutHandler = handler.bind(null, WaitOnType.TIMEOUT); + const timeout = setTimeout(timeoutHandler, delay); + return promise; } class EventBus { #listeners = Object.create(null); @@ -2480,10 +2478,8 @@ class PasswordPrompt { this.dialog.addEventListener("close", this.#cancel.bind(this)); } async open() { - if (this.#activeCapability) { - await this.#activeCapability.promise; - } - this.#activeCapability = new PromiseCapability(); + await this.#activeCapability?.promise; + this.#activeCapability = Promise.withResolvers(); try { await this.overlayManager.open(this.dialog); } catch (ex) { @@ -2642,7 +2638,7 @@ class PDFAttachmentViewer extends BaseTreeViewer { super.reset(); this._attachments = null; if (!keepRenderedCapability) { - this._renderedCapability = new PromiseCapability(); + this._renderedCapability = Promise.withResolvers(); } this._pendingDispatchEvent = false; } @@ -3039,7 +3035,7 @@ class PDFDocumentProperties { #reset() { this.pdfDocument = null; this.#fieldData = null; - this._dataAvailableCapability = new PromiseCapability(); + this._dataAvailableCapability = Promise.withResolvers(); this._currentPageNumber = 1; this._pagesRotation = 0; } @@ -3214,7 +3210,6 @@ function getNormalizeWithNFKC() { ;// CONCATENATED MODULE: ./web/pdf_find_controller.js - const FindState = { FOUND: 0, NOT_FOUND: 1, @@ -3552,7 +3547,7 @@ class PDFFindController { this._dirtyMatch = false; clearTimeout(this._findTimeout); this._findTimeout = null; - this._firstPageCapability = new PromiseCapability(); + this._firstPageCapability = Promise.withResolvers(); } get #query() { const { @@ -3715,14 +3710,17 @@ class PDFFindController { if (this._extractTextPromises.length > 0) { return; } - let promise = Promise.resolve(); + let deferred = Promise.resolve(); const textOptions = { disableNormalization: true }; for (let i = 0, ii = this._linkService.pagesCount; i < ii; i++) { - const extractTextCapability = new PromiseCapability(); - this._extractTextPromises[i] = extractTextCapability.promise; - promise = promise.then(() => { + const { + promise, + resolve + } = Promise.withResolvers(); + this._extractTextPromises[i] = promise; + deferred = deferred.then(() => { return this._pdfDocument.getPage(i + 1).then(pdfPage => pdfPage.getTextContent(textOptions)).then(textContent => { const strBuf = []; for (const textItem of textContent.items) { @@ -3732,13 +3730,13 @@ class PDFFindController { } } [this._pageContents[i], this._pageDiffs[i], this._hasDiacritics[i]] = normalize(strBuf.join("")); - extractTextCapability.resolve(); + resolve(); }, reason => { console.error(`Unable to get text content for page ${i + 1}`, reason); this._pageContents[i] = ""; this._pageDiffs[i] = null; this._hasDiacritics[i] = false; - extractTextCapability.resolve(); + resolve(); }); }); } @@ -4722,7 +4720,6 @@ class PDFLayerViewer extends BaseTreeViewer { ;// CONCATENATED MODULE: ./web/pdf_outline_viewer.js - class PDFOutlineViewer extends BaseTreeViewer { constructor(options) { super(options); @@ -4735,9 +4732,7 @@ class PDFOutlineViewer extends BaseTreeViewer { }); this.eventBus._on("pagesloaded", evt => { this._isPagesLoaded = !!evt.pagesCount; - if (this._currentOutlineItemCapability && !this._currentOutlineItemCapability.settled) { - this._currentOutlineItemCapability.resolve(this._isPagesLoaded); - } + this._currentOutlineItemCapability?.resolve(this._isPagesLoaded); }); this.eventBus._on("sidebarviewchanged", evt => { this._sidebarView = evt.view; @@ -4749,13 +4744,11 @@ class PDFOutlineViewer extends BaseTreeViewer { this._pageNumberToDestHashCapability = null; this._currentPageNumber = 1; this._isPagesLoaded = null; - if (this._currentOutlineItemCapability && !this._currentOutlineItemCapability.settled) { - this._currentOutlineItemCapability.resolve(false); - } + this._currentOutlineItemCapability?.resolve(false); this._currentOutlineItemCapability = null; } _dispatchEvent(outlineCount) { - this._currentOutlineItemCapability = new PromiseCapability(); + this._currentOutlineItemCapability = Promise.withResolvers(); if (outlineCount === 0 || this._pdfDocument?.loadingParams.disableAutoFetch) { this._currentOutlineItemCapability.resolve(false); } else if (this._isPagesLoaded !== null) { @@ -4937,7 +4930,7 @@ class PDFOutlineViewer extends BaseTreeViewer { if (this._pageNumberToDestHashCapability) { return this._pageNumberToDestHashCapability.promise; } - this._pageNumberToDestHashCapability = new PromiseCapability(); + this._pageNumberToDestHashCapability = Promise.withResolvers(); const pageNumberToDestHash = new Map(), pageNumberNesting = new Map(); const queue = [{ @@ -5752,7 +5745,7 @@ class PDFScriptingManager { return; } await this.#willPrintCapability?.promise; - this.#willPrintCapability = new PromiseCapability(); + this.#willPrintCapability = Promise.withResolvers(); try { await this.#scripting.dispatchEventInSandbox({ id: "doc", @@ -5881,7 +5874,7 @@ class PDFScriptingManager { const pdfDocument = this.#pdfDocument, visitedPages = this._visitedPages; if (initialize) { - this.#closeCapability = new PromiseCapability(); + this.#closeCapability = Promise.withResolvers(); } if (!this.#closeCapability) { return; @@ -5931,7 +5924,7 @@ class PDFScriptingManager { }); } #initScripting() { - this.#destroyCapability = new PromiseCapability(); + this.#destroyCapability = Promise.withResolvers(); if (this.#scripting) { throw new Error("#initScripting: Scripting already exists."); } @@ -6409,7 +6402,7 @@ class PDFThumbnailView { } this.resume = null; } - _getPageDrawContext(upscaleFactor = 1) { + #getPageDrawContext(upscaleFactor = 1) { const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d", { alpha: false @@ -6424,11 +6417,11 @@ class PDFThumbnailView { transform }; } - _convertCanvasToImage(canvas) { + #convertCanvasToImage(canvas) { if (this.renderingState !== RenderingStates.FINISHED) { - throw new Error("_convertCanvasToImage: Rendering has not finished."); + throw new Error("#convertCanvasToImage: Rendering has not finished."); } - const reducedCanvas = this._reduceImage(canvas); + const reducedCanvas = this.#reduceImage(canvas); const image = document.createElement("img"); image.className = "thumbnailImage"; image.setAttribute("data-l10n-id", "pdfjs-thumb-page-canvas"); @@ -6448,7 +6441,7 @@ class PDFThumbnailView { return; } this.renderingState = RenderingStates.FINISHED; - this._convertCanvasToImage(canvas); + this.#convertCanvasToImage(canvas); if (error) { throw error; } @@ -6470,7 +6463,7 @@ class PDFThumbnailView { ctx, canvas, transform - } = this._getPageDrawContext(DRAW_UPSCALE_FACTOR); + } = this.#getPageDrawContext(DRAW_UPSCALE_FACTOR); const drawViewport = this.viewport.clone({ scale: DRAW_UPSCALE_FACTOR * this.scale }); @@ -6525,13 +6518,13 @@ class PDFThumbnailView { return; } this.renderingState = RenderingStates.FINISHED; - this._convertCanvasToImage(canvas); + this.#convertCanvasToImage(canvas); } - _reduceImage(img) { + #reduceImage(img) { const { ctx, canvas - } = this._getPageDrawContext(); + } = this.#getPageDrawContext(); if (img.width <= 2 * canvas.width) { ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height); return canvas; @@ -6585,16 +6578,16 @@ class PDFThumbnailViewer { this.linkService = linkService; this.renderingQueue = renderingQueue; this.pageColors = pageColors || null; - this.scroll = watchScroll(this.container, this._scrollUpdated.bind(this)); - this._resetView(); + this.scroll = watchScroll(this.container, this.#scrollUpdated.bind(this)); + this.#resetView(); } - _scrollUpdated() { + #scrollUpdated() { this.renderingQueue.renderHighestPriority(); } getThumbnail(index) { return this._thumbnails[index]; } - _getVisibleThumbs() { + #getVisibleThumbs() { return getVisibleElements({ scrollEl: this.container, views: this._thumbnails @@ -6618,7 +6611,7 @@ class PDFThumbnailViewer { first, last, views - } = this._getVisibleThumbs(); + } = this.#getVisibleThumbs(); if (views.length > 0) { let shouldScroll = false; if (pageNumber <= first.id || pageNumber >= last.id) { @@ -6672,7 +6665,7 @@ class PDFThumbnailViewer { } TempImageFactory.destroyCanvas(); } - _resetView() { + #resetView() { this._thumbnails = []; this._currentPageNumber = 1; this._pageLabels = null; @@ -6681,8 +6674,8 @@ class PDFThumbnailViewer { } setDocument(pdfDocument) { if (this.pdfDocument) { - this._cancelRendering(); - this._resetView(); + this.#cancelRendering(); + this.#resetView(); } this.pdfDocument = pdfDocument; if (!pdfDocument) { @@ -6717,7 +6710,7 @@ class PDFThumbnailViewer { console.error("Unable to initialize thumbnail viewer", reason); }); } - _cancelRendering() { + #cancelRendering() { for (const thumbnail of this._thumbnails) { thumbnail.cancelRendering(); } @@ -6762,7 +6755,7 @@ class PDFThumbnailViewer { return this.scroll.down; } forceRendering() { - const visibleThumbs = this._getVisibleThumbs(); + const visibleThumbs = this.#getVisibleThumbs(); const scrollAhead = this.#getScrollAhead(visibleThumbs); const thumbView = this.renderingQueue.getHighestPriority(visibleThumbs, this._thumbnails, scrollAhead); if (thumbView) { @@ -7694,7 +7687,7 @@ class PDFPageView { this.#textLayerMode = options.textLayerMode ?? TextLayerMode.ENABLE; this.#annotationMode = options.annotationMode ?? AnnotationMode.ENABLE_FORMS; this.imageResourcesPath = options.imageResourcesPath || ""; - this.maxCanvasPixels = options.maxCanvasPixels ?? (AppOptions.getCompat("maxCanvasPixels") || 2 ** 25); + this.maxCanvasPixels = options.maxCanvasPixels ?? AppOptions.get("maxCanvasPixels"); this.pageColors = options.pageColors || null; this.eventBus = options.eventBus; this.renderingQueue = options.renderingQueue; @@ -8500,7 +8493,7 @@ class PDFViewer { #scaleTimeoutId = null; #textLayerMode = TextLayerMode.ENABLE; constructor(options) { - const viewerVersion = "4.1.342"; + const viewerVersion = "4.1.379"; if (version !== viewerVersion) { throw new Error(`The API version "${version}" does not match the Viewer version "${viewerVersion}".`); } @@ -8555,7 +8548,7 @@ class PDFViewer { return new Set(this.#buffer); } get pageViewsReady() { - return this._pagesCapability.settled && this._pages.every(pageView => pageView?.pdfPage); + return this._pages.every(pageView => pageView?.pdfPage); } get renderForms() { return this.#annotationMode === AnnotationMode.ENABLE_FORMS; @@ -8858,7 +8851,7 @@ class PDFViewer { }; this.eventBus._on("pagerender", this._onBeforeDraw); this._onAfterDraw = evt => { - if (evt.cssTransform || this._onePageRenderedCapability.settled) { + if (evt.cssTransform) { return; } this._onePageRenderedCapability.resolve({ @@ -9030,9 +9023,9 @@ class PDFViewer { this._location = null; this._pagesRotation = 0; this._optionalContentConfigPromise = null; - this._firstPageCapability = new PromiseCapability(); - this._onePageRenderedCapability = new PromiseCapability(); - this._pagesCapability = new PromiseCapability(); + this._firstPageCapability = Promise.withResolvers(); + this._onePageRenderedCapability = Promise.withResolvers(); + this._pagesCapability = Promise.withResolvers(); this._scrollMode = ScrollMode.VERTICAL; this._previousScrollMode = ScrollMode.UNKNOWN; this._spreadMode = SpreadMode.NONE; @@ -10543,7 +10536,10 @@ const ViewOnLoad = { }; const PDFViewerApplication = { initialBookmark: document.location.hash.substring(1), - _initializedCapability: new PromiseCapability(), + _initializedCapability: { + ...Promise.withResolvers(), + settled: false + }, appConfig: null, pdfDocument: null, pdfLoadingTask: null, @@ -10617,6 +10613,7 @@ const PDFViewerApplication = { await this._initializeViewerComponents(); this.bindEvents(); this.bindWindowEvents(); + this._initializedCapability.settled = true; this._initializedCapability.resolve(); }, async _parseHashParams() { @@ -11708,6 +11705,10 @@ const PDFViewerApplication = { mediaQueryList.addEventListener("change", addWindowResolutionChange, { once: true }); + _boundEvents.removeWindowResolutionChange ||= function () { + mediaQueryList.removeEventListener("change", addWindowResolutionChange); + _boundEvents.removeWindowResolutionChange = null; + }; } addWindowResolutionChange(); _boundEvents.windowResize = () => { @@ -12631,8 +12632,8 @@ function webViewerReportTelemetry({ -const pdfjsVersion = "4.1.342"; -const pdfjsBuild = "e384df6f1"; +const pdfjsVersion = "4.1.379"; +const pdfjsBuild = "017e49244"; const AppConstants = null; window.PDFViewerApplication = PDFViewerApplication; window.PDFViewerApplicationConstants = AppConstants; diff --git a/toolkit/components/pdfjs/moz.yaml b/toolkit/components/pdfjs/moz.yaml index bd85f67f5a..0938b8d987 100644 --- a/toolkit/components/pdfjs/moz.yaml +++ b/toolkit/components/pdfjs/moz.yaml @@ -20,8 +20,8 @@ origin: # Human-readable identifier for this version/release # Generally "version NNN", "tag SSS", "bookmark SSS" - release: e384df6f16b9ad1c55d1bc325bcae7e096ef3f9b (2024-03-27T19:54:30Z). - revision: e384df6f16b9ad1c55d1bc325bcae7e096ef3f9b + release: a208d6bca72f8cb700f7bb506ea1bc3e76cbaec0 (2024-04-09T07:48:17Z). + revision: a208d6bca72f8cb700f7bb506ea1bc3e76cbaec0 # The package's license, where possible using the mnemonic from # https://spdx.org/licenses/ diff --git a/toolkit/components/pdfjs/test/browser_pdfjs_editing_contextmenu.js b/toolkit/components/pdfjs/test/browser_pdfjs_editing_contextmenu.js index 779a3a6ad4..f13d03d643 100644 --- a/toolkit/components/pdfjs/test/browser_pdfjs_editing_contextmenu.js +++ b/toolkit/components/pdfjs/test/browser_pdfjs_editing_contextmenu.js @@ -130,7 +130,7 @@ function assertMenuitems(menuitems, expected) { elmt => !elmt.id.includes("-sep-") && !elmt.hidden && - ["", "false"].includes(elmt.getAttribute("disabled")) + [null, "false"].includes(elmt.getAttribute("disabled")) ) .map(elmt => elmt.id), expected diff --git a/toolkit/components/pdfjs/test/browser_pdfjs_find.js b/toolkit/components/pdfjs/test/browser_pdfjs_find.js index 24a3a50967..b3b3e11152 100644 --- a/toolkit/components/pdfjs/test/browser_pdfjs_find.js +++ b/toolkit/components/pdfjs/test/browser_pdfjs_find.js @@ -13,7 +13,7 @@ const OS_PDF_URL = TESTROOT + "file_pdfjs_object_stream.pdf"; const TEST_PDF_URL = TESTROOT + "file_pdfjs_test.pdf"; add_task(async function test_find_octet_stream_pdf() { - await BrowserTestUtils.withNewTab(OS_PDF_URL, async browser => { + await BrowserTestUtils.withNewTab(OS_PDF_URL, async () => { let findEls = ["cmd_find", "cmd_findAgain", "cmd_findPrevious"].map(id => document.getElementById(id) ); diff --git a/toolkit/components/pdfjs/test/browser_pdfjs_force_opening_files.js b/toolkit/components/pdfjs/test/browser_pdfjs_force_opening_files.js index 0490a6eec3..f09581daa7 100644 --- a/toolkit/components/pdfjs/test/browser_pdfjs_force_opening_files.js +++ b/toolkit/components/pdfjs/test/browser_pdfjs_force_opening_files.js @@ -13,7 +13,7 @@ add_task(async function test_file_opening() { // the default - because files from disk should always use pdfjs, unless // it is forcibly disabled. let openedWindow = false; - let windowOpenedPromise = new Promise((resolve, reject) => { + let windowOpenedPromise = new Promise(resolve => { addWindowListener( "chrome://mozapps/content/downloads/unknownContentType.xhtml", () => { @@ -82,7 +82,7 @@ function addWindowListener(aURL, aCallback) { aCallback(); }, domwindow); }, - onCloseWindow(aXULWindow) {}, + onCloseWindow() {}, }; Services.wm.addListener(listener); listenerCleanup = () => Services.wm.removeListener(listener); diff --git a/toolkit/components/pdfjs/test/browser_pdfjs_fullscreen.js b/toolkit/components/pdfjs/test/browser_pdfjs_fullscreen.js index d53e4cfa74..4add7a4715 100644 --- a/toolkit/components/pdfjs/test/browser_pdfjs_fullscreen.js +++ b/toolkit/components/pdfjs/test/browser_pdfjs_fullscreen.js @@ -8,7 +8,7 @@ function waitForFullScreenState(browser, state) { return new Promise(resolve => { let eventReceived = false; - let observe = (subject, topic, data) => { + let observe = () => { if (!eventReceived) { return; } diff --git a/toolkit/components/pdfjs/test/browser_pdfjs_navigation.js b/toolkit/components/pdfjs/test/browser_pdfjs_navigation.js index 9851150e80..5fda1ac8b2 100644 --- a/toolkit/components/pdfjs/test/browser_pdfjs_navigation.js +++ b/toolkit/components/pdfjs/test/browser_pdfjs_navigation.js @@ -229,7 +229,7 @@ async function contentSetUp() { return new Promise(resolve => { document.addEventListener( "pagerendered", - function (e) { + function () { document.querySelector("#viewer").click(); resolve(); }, diff --git a/toolkit/components/pdfjs/test/browser_pdfjs_octet_stream.js b/toolkit/components/pdfjs/test/browser_pdfjs_octet_stream.js index d2b4fe310f..8e81ddb2c5 100644 --- a/toolkit/components/pdfjs/test/browser_pdfjs_octet_stream.js +++ b/toolkit/components/pdfjs/test/browser_pdfjs_octet_stream.js @@ -88,7 +88,7 @@ add_task(async function test_octet_stream_in_frame() { await BrowserTestUtils.withNewTab( { gBrowser, url: `data:text/html,