7429 Commits

Author SHA1 Message Date
Jonas Jenwald
74ab1a98a6
Merge pull request #20685 from Snuffleupagus/Annotation-set-annotationType
Set the `annotationType` automatically in the `Annotation` constructor
2026-02-19 00:03:37 +01:00
Calixte Denizet
d755fba96a
Add support for deleting, cutting, copying and pasting pages (bug 2010830, 2010831) 2026-02-18 16:43:00 +01:00
Jonas Jenwald
e1cc24c595 Set the annotationType automatically in the Annotation constructor
Rather than assigning it manually in every extending class, we can utilize the fact that the `AnnotationType`-entries are simply the upper-case version of the `/Subtype` (when it exists) in the Annotation dictionary.
2026-02-18 14:47:42 +01:00
Jonas Jenwald
336cda0c64 Remove unused CanvasGraphics properties (PR 700 follow-up)
These are probably a copy-and-paste mistake, since they appear to have been unused already in PR 700 all the way back in 2011.
2026-02-17 21:36:08 +01:00
Jonas Jenwald
6323afab46 Convert the PDFObjects class to use a Map internally
This patch also adds unconditional `Map.prototype.getOrInsertComputed()` usage, which should be fine since it's [supported in the latest browsers](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/getOrInsertComputed#browser_compatibility) and it'll be polyfilled (via core-js) in the `legacy` builds.
2026-02-17 09:42:27 +01:00
Jonas Jenwald
62ac1b844a
Merge pull request #20669 from Snuffleupagus/decode-truncate
Truncate too long /Decode map entries (issue 20668)
2026-02-16 20:39:12 +01:00
Jonas Jenwald
31b4612ac0 Truncate too long /Decode map entries (issue 20668) 2026-02-16 16:22:00 +01:00
Jonas Jenwald
0a9176422e Remove Object.hasOwn usage from the src/core/xref.js file
This should not be necessary, given the following checks done early during the worker initialization: c5746949ac/src/core/worker.js (L124-L141)
2026-02-15 16:39:39 +01:00
Tim van der Meij
1d6307f5d4
Merge pull request #20657 from Snuffleupagus/unicorn-prefer-class-fields
Enable the `unicorn/prefer-class-fields` ESLint plugin rule
2026-02-14 15:26:28 +01:00
Tim van der Meij
f22fb6bbfb
Merge pull request #20652 from Snuffleupagus/ChunkedStream-sendRequest-skip-empty
Avoid parsing skipped range requests in `ChunkedStreamManager` (PR 10694 follow-up)
2026-02-14 13:55:31 +01:00
Jonas Jenwald
170599f1e7 Enable the unicorn/prefer-class-fields ESLint plugin rule
This leads to slightly shorter code[1] when initializing classes, and in some cases we can even remove the constructors, which shouldn't hurt; see https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-class-fields.md

It's probably possible to also change a lot of these class fields to private ones[2], however it's often difficult to tell at a glance if that's safe hence this patch only does this for the `PDFRenderingQueue`.

---

[1] This reduces the size of the `gulp mozcentral` output by 999 bytes, for a mostly mechanical code change.

[2] That sort of re-factoring should generally be done separately, on a class-by-class basis, to reduce the risk of regressions.
2026-02-14 12:33:34 +01:00
calixteman
45c7805daf
Fix types to make "gulp typestest" succeeding 2026-02-13 22:34:04 +01:00
Jonas Jenwald
520928719c Move and re-use the stripPath helper function more
There's a couple of spots that essentially re-implement that function.
2026-02-13 17:38:21 +01:00
calixteman
fa28ca1468
Merge pull request #20651 from Snuffleupagus/Response-bytes
Start using `Response.prototype.bytes()` in the code-base
2026-02-13 10:31:54 +01:00
calixteman
ae9fc13d8f
Merge pull request #20649 from calixteman/bug2015385
Ends the current drawing session when closing the tab (bug 2015385)
2026-02-13 08:27:16 +01:00
calixteman
1b20ba5c3f
Ends the current drawing session when closing the tab (bug 2015385) 2026-02-12 22:21:55 +01:00
Jonas Jenwald
b3c07f4b3d Avoid parsing skipped range requests in ChunkedStreamManager (PR 10694 follow-up)
While we don't dispatch the actual range request after PR 10694 we still parse the returned data, which ends up being an *empty* `ArrayBuffer` and thus cannot affect the `ChunkedStream.prototype._loadedChunks` property.
Given that no actual data arrived, it's thus pointless[1] to invoke the `ChunkedStreamManager.prototype.onReceiveData` method in this case (and it also avoids sending effectively duplicate "DocProgress" messages).

---
[1] With the *possible* exception of `disableAutoFetch === false` being set, see f24768d7b4/src/core/chunked_stream.js (L499-L517) however that never happens when streaming is being used; note f24768d7b4/src/core/worker.js (L237-L238)
2026-02-12 18:01:54 +01:00
Jonas Jenwald
722f1ffbc6 Remove type === "arraybuffer" support from the fetchData helper function
After the previous patch there's no longer any call-site using that type.
2026-02-12 11:23:28 +01:00
Jonas Jenwald
8ba83e73fa Start using Response.prototype.bytes() in the code-base
In all cases where we currently use `Response.prototype.arrayBuffer()` the result is immediately wrapped in a `Uint8Array`, which can be avoided by instead using the newer `Response.prototype.bytes()` method; see https://developer.mozilla.org/en-US/docs/Web/API/Response/bytes
2026-02-12 11:20:05 +01:00
Jonas Jenwald
c1b824f2e5 Convert PDFPageProxy.prototype.getTextContent to an asynchronous method
This is a tiny bit shorter, which cannot hurt.
2026-02-11 19:14:10 +01:00
calixteman
9870d898b4
Merge pull request #20640 from calixteman/issue20629
Set a pages mapper per loaded document
2026-02-09 10:27:33 +01:00
calixteman
babd030a77
Merge pull request #20638 from calixteman/avoid_branching
Avoid branching in convertBlackAndWhiteToRGBA
2026-02-08 21:16:29 +01:00
calixteman
4b4ab10c54
Set a pages mapper per loaded document
It fixes #20629.
2026-02-08 21:09:27 +01:00
calixteman
a9870adfa3
Avoid branching in convertBlackAndWhiteToRGBA
The function is now almost 8x faster than before.
And make the code in the file slightly more readable.
2026-02-08 18:36:40 +01:00
Jonas Jenwald
6a3d5fea6c Replace a few cases of "manual" font name normalization with the normalizeFontName helper function 2026-02-08 16:56:50 +01:00
Jonas Jenwald
e9c509aca9 Normalize the font name in getBaseFontMetrics (issue 20246)
We tried to lookup the font metrics using the font name as-is, which didn't work since the PDF file in question has non-embedded fonts with names that include commas.
Hence the font names need to be normalized here as well, similar to elsewhere in the font code.
2026-02-08 16:56:15 +01:00
Jonas Jenwald
0306e6c7ed Re-use the getArrayBuffer helper from src/display/fetch_stream.js with PDFNodeStreamReader and PDFNodeStreamRangeReader
Given that the Node.js code uses standard `ReadableStream`s now, see PR 20594, it can use the same `getArrayBuffer` as the Fetch API implementation.

Also, change the `getArrayBuffer` fallback case to an Error (rather than a warning) since that should never actually happen.
2026-02-08 13:20:55 +01:00
Jonas Jenwald
916b58a027 Add a helper function to resolve pending requests in src/display/transport_stream.js and src/display/network.js
Currently the same identical code is duplicated four times per file, which seems completely unnecessary.
Note that the function isn't placed in `src/display/network_utils.js`, since that file isn't included in MOZCENTRAL builds.
2026-02-08 13:20:50 +01:00
Jonas Jenwald
2d643efce5 Ensure that pending requests are resolved when calling PDFDataTransportStreamReader.prototype.progressiveDone
Doing skip-cache reloading of https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/PDF32000_2008.pdf#disableRange=true in the latest Firefox Nightly version I noticed an *intermittent* bug, where the loadingBar would fill up but without the PDF ever rendering.
Initially I was quite worried that the changes in PR 20602 had somehow caused this, however after a bunch of testing in a slightly older Nightly I was able to reproduce the problem there as well.[1]

Instead I believe that this problem goes all the back to PR 10675, so still my fault, since the `progressiveDone` handling there was incomplete.
Note how we only set the `this._done` property, but don't actually resolve any still pending requests. For reference, compare with the handling in the `PDFDataTransportStreamRangeReader.prototype._enqueue` method.
Depending on the exact order in which the `PDFDataTransportStreamReader.prototype.{_enqueue, read, progressiveDone}` methods are invoked, which depends on how/when the PDF data arrives, the bug might occur.

The reason that this bug hasn't been caught before now is likely that `disableRange=true` isn't used by default and Firefox users are unlikely to manually set that in e.g. `about:config`.

---
[1] Possibly some timings changed to make it slightly more common, but given the intermittent nature of this it's difficult to tell.
2026-02-07 22:24:20 +01:00
calixteman
58ac273f1f
Merge pull request #20503 from andriivitiv/Fix-Worker-was-terminated-error
Fix `Worker was terminated` error when loading is cancelled
2026-02-06 09:59:05 +01:00
calixteman
b92bdf80a2
Merge pull request #20628 from calixteman/bug2014399
Cap the max canvas dimensions in order to avoid to downscale large images in the worker (bug 2014399)
2026-02-06 09:42:04 +01:00
Tim van der Meij
f302323c7e
Merge pull request #20627 from Snuffleupagus/ChunkedStream-onReceiveData-rm-copy
Improve progress reporting in `ChunkedStreamManager`, and prevent unnecessary data copy in `ChunkedStream.prototype.onReceiveData`
2026-02-05 21:27:42 +01:00
Calixte Denizet
ff42c0bd50
Cap the max canvas dimensions in order to avoid to downscale large images in the worker (bug 2014399) 2026-02-05 20:25:36 +01:00
Jonas Jenwald
b3cd042ded Prevent unnecessary data copy in ChunkedStream.prototype.onReceiveData
This method is only invoked via `ChunkedStreamManager.prototype.sendRequest`, which currently returns data in `Uint8Array` format (since it potentially combines multiple `ArrayBuffer`s).
Hence we end up doing a short-lived, but still completely unnecessary, data copy[1] in `ChunkedStream.prototype.onReceiveData` when handling range requests. In practice this is unlikely to be a big problem by default, given that streaming is used and the (low) value of the `rangeChunkSize` API-option. (However, in custom PDF.js deployments it might affect things more.)

Given that no data copy is better than a short lived one, let's fix this small oversight and add non-production `assert`s to keep it working as intended.
This way we also improve consistency, since all other streaming and range request methods (see e.g. `BasePDFStream` and related code) only return `ArrayBuffer` data.

---
[1] Remember that `new Uint8Array(arrayBuffer)` only creates a view of the underlying `arrayBuffer`, whereas `new Uint8Array(typedArray)` actually creates a copy of the `typedArray`.
2026-02-05 16:16:36 +01:00
Jonas Jenwald
01deb085f8 Improve progress reporting in the ChunkedStreamManager
Currently there's two small bugs, which have existed around a decade, in the `loaded` property that's sent via the "DocProgress" message from the `ChunkedStreamManager.prototype.onReceiveData` method.

 - When the entire PDF has loaded the `loaded` property can become larger than the `total` property, which obviously doesn't make sense.
   This happens whenever the size of the PDF is *not* a multiple of the `rangeChunkSize` API-option, which is a very common situation.

 - When streaming is being used, the `loaded` property can become smaller than the actually loaded amount of data.
   This happens whenever the size of a streamed chunk is *not* a multiple of the `rangeChunkSize` API-option, which is a common situation.
2026-02-05 16:04:45 +01:00
calixteman
22b97d1741
Flush the text content chunk only on real font changes (bug 2013793) 2026-02-03 23:11:31 +01:00
calixteman
1c12b07726
Merge pull request #20613 from calixteman/ccittfax_pdfium
Use the ccittfax decoder from pdfium
2026-02-02 15:07:53 +01:00
calixteman
88c2051698
Use the ccittfax decoder from pdfium
The decoder is a dependency of the jbig2 one and is already
included in pdf.js, so we just need to wire it up.
It improves the performance of documents using ccittfax images.
2026-02-02 11:10:32 +01:00
Jonas Jenwald
bfd17b2586
Merge pull request #20615 from Snuffleupagus/transport-onProgress
Report loading progress "automatically" when using the `PDFDataTransportStream` class, and remove the `PDFDataRangeTransport.prototype.onDataProgress` method
2026-02-01 22:36:43 +01:00
Jonas Jenwald
d152e92185
Merge pull request #20614 from Snuffleupagus/BasePDFStream-url
Change all relevant `BasePDFStream` implementations to take an actual `URL` instance
2026-02-01 22:13:28 +01:00
Tim van der Meij
f4326e17c4
Merge pull request #20610 from calixteman/brotli
Add support for Brotli decompression
2026-02-01 20:41:06 +01:00
Jonas Jenwald
6509fdb1d6 Assert that PDFFetchStream is only used with HTTP(S) URLs
Note how `getDocument` checks the protocol, via the `isValidFetchUrl` helper, before attempting to use the `PDFFetchStream` implementation.
2026-02-01 18:21:27 +01:00
Jonas Jenwald
586e85888b Change all relevant BasePDFStream implementations to take an actual URL instance
Currently this code expects a "url string", rather than a proper `URL` instance, which seems completely unnecessary now. The explanation for this is, as so often is the case, "historical reasons" since a lot of this code predates the general availability of `URL`.
2026-02-01 18:21:13 +01:00
Jonas Jenwald
76dabeddb3 Limit the Math.sumPrecise polyfill to non-MOZCENTRAL builds
After https://bugzilla.mozilla.org/show_bug.cgi?id=1985121 this functionality is now guaranteed to be available in Firefox.
Unfortunately general browser support is still somewhat lacking; see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sumPrecise#browser_compatibility

Also, while unrelated, use the `MathClamp` helper in the `applyOpacity` function.
2026-02-01 18:20:29 +01:00
Jonas Jenwald
d25f13d1fd Report loading progress "automatically" when using the PDFDataTransportStream class, and remove the PDFDataRangeTransport.prototype.onDataProgress method
This is consistent with the other `BasePDFStream` implementations, and simplifies the API surface of the `PDFDataRangeTransport` class (note the changes in the viewer).
Given that the `onDataProgress` method was changed to a no-op this won't affect third-party users, assuming there even are any since this code was written specifically for the Firefox PDF Viewer.
2026-02-01 18:20:19 +01:00
Jonas Jenwald
839c257f87 Replace the IDownloadManager interface with an abstract BaseDownloadManager class
This should help reduce the maintenance burden of the code, since you no longer need to remember to update separate code when touching the different `DownloadManager` classes.
2026-02-01 17:56:03 +01:00
Jonas Jenwald
50a12e3e67 Remove the IL10n interface
Given that we either use the `L10n` class directly or extend it via `GenericL10n`, it should no longer be necessary to keep the interface-definition.
This should help reduce the maintenance burden of the code, since you no longer need to remember to update separate code when touching the `L10n` class.
2026-02-01 17:53:45 +01:00
Jonas Jenwald
b517b5c597 Remove the IPDFLinkService interface
Given that `SimpleLinkService` now extends the regular `PDFLinkService` class, see PR 18013, it should no longer be necessary to keep the interface-definition.
This should help reduce the maintenance burden of the code, since you no longer need to remember to update separate code when touching the `PDFLinkService` class.
2026-02-01 17:53:45 +01:00
Jonas Jenwald
ecb09d62fc Add the current loading percentage to the onPassword callback
The percentage calculation is currently "spread out" across various viewer functionality, which we can avoid by having the API handle that instead.

Also, remove the `this.#lastProgress` special-case[1] and just register a "normal" `fullReader.onProgress` callback unconditionally. Once `headersReady` is resolved the callback can simply be removed when not needed, since the "worst" thing that could theoretically happen is that the loadingBar (in the viewer) updates sooner this way. In practice though, since `fullReader.read` cannot return data until `headersReady` is resolved, this change is not actually observable in the API.

---

[1] This was added in PR 8617, close to a decade ago, but it's not obvious to me that it was ever necessary to implement it that way.
2026-01-31 16:33:58 +01:00
calixteman
43273fde27
Add support for Brotli decompression
For now, `BrotliDecode` hasn't been specified but it should be in a
close future.
So when it's possible we use the native `DecompressionStream` API
with "brotli" as argument.
If that fails or if we've to decompress in a sync context, we fallback
to `BrotliStream` which a pure js implementation (see README in external/brotli).
2026-01-31 16:25:53 +01:00