The "Merge PDF" integration-tests will (indirectly) invoke `PDFViewerApplication.open` as part of loading the new PDF document, which will end up creating a new `PDFWorker` instance.
Currently worker coverage is only collected at the end of each integration-test, which means that in these cases we miss the coverage data from any "previous" workers.
Currently when opening a PDF document the following code is used, where `checkFirstPage`/`checkLastPage` helps detect XRef corruption; note 86a18bd5fe/src/core/worker.js (L167-L176)
However when merging a PDF into an existing document the parsing is only "partial"; note 86a18bd5fe/src/core/worker.js (L632-L634)
It seems a little strange to not support corrupt PDFs in a consistent manner in the code-base, hence this patch adds a new `BasePdfManager` helper that handles all the relevant parsing/checking and re-uses that when merging PDFs.
This removes a little bit of code duplication, which only exist since the `src/display/canvas.js` code pre-dates the helper function by many years.
Note: Given that `OffscreenCanvas` is enabled by default there's currently not a lot of test coverage for this code-path, hence the added browser-test.
The idea is to generate two operator lists for the Yes/Off states and render them on a separate canvas.
These canvases are then attached the annotation and we modify their display depending on the input state.
It fixes#18021.
This basically extends PR 9549 to the fallback `getAllPageDicts` method, which didn't exist at the time, in order to support more cases of corrupt PDF documents.
These unit-tests used a PDF that prompted for password on document load, which meant that the on-demand password handling wasn't actually being tested as intended.
Updating the unit-tests also caused the "re-prompts for encrypted attachments after incorrect passwords" test to fail, since the `INCORRECT_PASSWORD` password reason was being accidentally "swallowed" in the worker-thread.
This removes a little bit of code duplication, which only exist since the `src/display/canvas.js` code pre-dates the helper function by many years.
*Note:* Given that `OffscreenCanvas` is enabled by default there's currently not a lot of test coverage for this code-path, hence the added browser-test.
Center each glyph within its comb cell instead of left-aligning it,
both in the HTML annotation layer and in the printed/saved appearance,
to match Acrobat. Cell width is now the single source of truth via the
--comb-width CSS variable, and field text-alignment (center/right) is
applied as a whole-cell --comb-offset that stays in sync on input,
blur, resetform and updatefromsandbox. The field no longer grows on
focus; trailing letter-spacing is clipped and cell dividers are drawn
on focus.
The print service injected the per-PDF `@page { size }` rule as an inline
<style> element, which required 'unsafe-inline' on style-src-elem.
Inject it through a constructable CSSStyleSheet attached to
document.adoptedStyleSheets instead. Constructable stylesheets aren't
subject to style-src's inline restrictions in browsers.
Compared to regular `Object`s there's a number of advantages to using `Map`s:
- They support "proper" iteration.
- They have a simple way to check for the existence of data.
- They have a simple/efficient way to check the number of elements.
If this functionality was added today, I cannot imagine that we'd choose an `Object` for this sort of data.
Furthermore, in PR 21351 the data returned by `getAttachments` changed slightly and third-party users will need to update their code anyway (hence why `[api-minor]` should be fine here).
When a read-only field (which has its own canvas) is updated by the
sandbox while its page isn't rendered, showElementAndHideCanvas
isn't called, so once the page is finally rendered the field still
shows its outdated canvas instead of the new value.
Replace the imperative canvas/element toggling with a `sandboxModified`
class, set from the annotation storage both at render time and on
sandbox updates, and let the CSS show the element and hide the canvas.
This format is obviously not very efficient however it's been supported since "forever" and there's even examples using, hence it seems like a good idea to actually test this.
Normally entire PDFs are encrypted (or not).
But it is also possible to only encrypt attachments.
It is then also possible to *only* prompt for a password when the user opens
them.
In the existing flow, prompting for passwords happens because things are decrypted.
A specific error is thrown, caught, and the user is prompted.
To keep this flow working, this PR changes to decrypting attachments on demand,
instead of eagerly.
This sounds logical: to not read attachments on startup.
I’ve extensively tested this, not only with regular attachments, but also with outline items
and attachments in annotations.
This PR builds on GH-21234.
It’s an alternative to the naïve GH-20732.
Closes GH-20049.
So that Ctrl+A, Ctrl+Z, etc. still fire on non-US keyboard layouts where
the physical "A" key produces a non-Latin character (Cyrillic, Greek,
some AZERTY combinations, ...). KeyboardManager now tries event.key first
and falls back to a US-layout translation of event.code (KeyA => a,
Digit1 => 1, Numpad1 => 1) when no shortcut is bound on event.key.
Also refactors KeyboardManager to store modifiers as a bitmask instead
of a serialized string, and treats a shortcut array without any
"mac+"-prefixed entry as applying on all platforms, letting us drop the
redundant "mac+X" duplicates of bare "X" entries across the editor code.
Identical embedded fonts and images across the merged documents are now
written once and shared, instead of being copied per source file.
And avoid to compress already compressed stream with Brotli.
The problem is that we screenshot the page itself rather than the
canvas, even though we specifically care about the latter according to
the comment, which means that we manually have to take care of hiding and
showing the annotation editor. This is problematic because even though
we signal that the annotation editor should be hidden, we don't wait
until that is actually done, which leads to a situation where we can
take the screenshot before the annotation editor is actually invisible
in the view.
This commit fixes the issue by screenshotting the canvas instead, which
avoids the need for manually hiding/showing the annotation editor. This
makes the test less fragile, and matches other tests better.
There's currently some amount of `StringStream` usage where the `dict`-parameter is manually assigned, and by updating the signature of the constructor this can be avoided.
The GitHub Actions workflow for the integration tests on Windows logs
the following line for every test:
`JavaScript warning: http://127.0.0.1:62313/build/generic/build/pdf.mjs,
line 134934: WebGPU is disabled by blocklist.`
On Linux WebGPU is disabled by default because of missing support, but on
Windows it's enabled by default since bug 1972486, so we try to obtain a
GPU adapter which fails (and logs) if there is no actual GPU like on
GitHub Actions. Coverage data confirms that our own WebGPU code is
already uncovered because of the lack of a GPU, so having WebGPU enabled
or disabled doesn't change that, but if it causes log spam it seems
better to disable it, which this commit does.
Note that Chrome doesn't seem to have a matching flag, but Chrome already
doesn't log anything about this (which is the primary driver for this
change), so that's not a problem.
Currently the viewer uses semi-private `EventBus.prototype.{_on, _off}` methods, to try and ensure that all internal viewer state is updated *before* any "external" listeners are invoked.
For all use-cases outside of the viewer, e.g in the integration-tests, the `EventBus.prototype.{on, off}` methods are supposed to be used instead.
Unfortunately this isn't currently enforced in any way, except (hopefully) during review, and generally speaking it's not really possible to prevent the semi-private methods being used (e.g. by third-party users).
Hence this patch adds a new `INTERNAL_EVT` property which is *not* exposed anywhere (neither in the API nor globally), and whose value is generated at build-time, that the viewer uses to mark its `EventBus` listeners are internal.
This allows us to remove the semi-private `EventBus` methods, which helps to simplify that class a little bit.
The two affected code paths caught and logged errors, but that wasn't
reflected in the exit code of the process, and that is what GitHub
Actions (and other tools) to determine if process execution was
successful or not. This commit fixes the issue by making sure we
consistently exit with code 1 in case of errors so that GitHub Actions
pipelines correctly reflect the outcome of the test run.
Image files dropped on or selected via the thumbnail viewer's
"add file" picker are now accepted alongside PDFs and inserted
as synthetic pages sized to the document's modal page dimensions.
The image-encoding helper previously embedded in StampAnnotation has
moved to src/core/editor/pdf_images.js so it can be shared between
stamp annotations and page synthesis.