Commit Graph

2899 Commits

Author SHA1 Message Date
calixteman
84d7cccb1d
JS - Handle correctly hierarchy of fields (#13133)
* JS - Handle correctly hierarchy of fields
  - it aims to fix #13132;
  - annotations can inherit their actions from the parent field;
  - there are some fields which act as a container for other fields:
    - they can be access through js so need to add them with an empty type (nothing in the spec about that but checked in Acrobat);
    - calculation order list (CO) can reference them so need make them through this.getField;
    - getArray method must return kids.
  - field values are number, string, ... depending of their type but nothing in the spec on how to know what's the type:
    - according to the comment for Canonical Format: https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/PDF32000_2008.pdf#page=461
    - it seems that this "type" can be guessed from js action Format (when setting a type in Acrobat DC, the only affected thing is this action).
  - util.scand with an empty string returns the current date.
2021-03-30 08:50:35 -07:00
Jonas Jenwald
19c2dfbb96 Move rotation normalization from PDFViewerApplication and into BaseViewer
The rotation handling that's currently living in `PDFViewerApplication` is *very* old, and pre-dates the introduction of the viewer components by years.
As can be seen in the `BaseViewer.pagesRotation` setter, we're not actually normalizing the rotation as intended and instead rely on the caller to handle that correctly. This is first of all inconsistent, given how other setters are implemented, and secondly it could also lead to the rotation being set to a value outside of the `[0, 360)`-range.

Finally, for improved consistency the rotation handling in `PageViewport` is updated similarly. Please note that this case, it's *not* changing the pre-existing logic.
2021-03-28 14:19:58 +02:00
Tim van der Meij
ba76dd4000
Merge pull request #13056 from Snuffleupagus/Doc-WillClose
Dispatch a "Doc/WillClose" event, when scripting is enabled, when closing the document
2021-03-26 22:00:40 +01:00
Tim van der Meij
69c88d119d
Merge pull request #13138 from Snuffleupagus/PDFHistory-pushPage-dest
[PDFHistory] Correctly simulate an internal destination in the `pushPage`-method (PR 12493 follow-up)
2021-03-26 21:57:51 +01:00
Jonas Jenwald
b11b7aaa38 [GrabToPan] Use Element.matches() rather than prefixed ...matchesSelector versions
At this point in time all of the browsers that PDF.js support now implements, with some margin based on the version numbers, `Element.matches()` according to the following compatibility information:
 - https://developer.mozilla.org/en-US/docs/Web/API/Element/matches#browser_compatibility
 - https://caniuse.com/matchesselector
2021-03-26 21:37:51 +01:00
Tim van der Meij
ebd2dfbae0
Merge pull request #13145 from emilio/print-oversized
print: Improve rendering of oversized pages.
2021-03-26 21:33:52 +01:00
Emilio Cobos Álvarez
81c7f905bc print: Improve rendering of oversized pages.
This improves and simplifies #13102 in order to make printing of test-cases
like the one in bug 1698414 (where the real page is bigger than the target
page) much better, see incoming screenshots.

The reason why we need to stop setting .style.width / .style.height is to get
the right auto-sizing behavior in both axes. This shouldn't change behavior as
long as the print resolution is >= the CSS resolution, which seems like a
reasonable assumption.

If you try to print with a lower resolution than CSS, then instead of an
stretched canvas, you'd get a centered CSS-quality canvas, which seems
sensible. This could maybe be fixed with some CSS hackery (some combination of
min / max and viewport units perhaps?), but I think it's more trouble than it's
worth.
2021-03-26 16:07:49 +01:00
Jonas Jenwald
34184a89f9 Remove *unconditional* browser sniffing in web/grab_to_pan.js
According to https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons#browser_compatibility, and manual testing in an up-to-date version of Google Chrome, the *unconditional* browser sniffing in `web/grab_to_pan.js` is no longer necessary.
In particular, this code is definitely not necessary in MOZCENTRAL-builds.
2021-03-25 16:08:16 +01:00
Jonas Jenwald
3c3cbe78ae Remove the remaining IE-specific checks from web/grab_to_pan.js (PR 12328 follow-up)
Given that all versions of Internet Explorer are now *explicitly* unsupported, we can remove some more dead code in this file.
2021-03-25 16:08:12 +01:00
calixteman
63471bcbbe
XFA - Convert some template properties into CSS ones (#13082)
- implement few positioning properties: position, width, height, anchor;
  - implement font element;
  - implement fill element (used by font) and its children (linear, radial, ...);
  - font property is inherited from ancestor container (see https://www.pdfa.org/wp-content/uploads/2020/07/XFA-3_3.pdf#page=43) so let CSS handles that stuff;
  - in order to reduce the number of properties to set, only set non default properties and put the default in CSS;
  - set a background to some containers to be able to see them (will be removed in a future commit).
2021-03-25 13:02:39 +01:00
Jonas Jenwald
a10f87c7ea [PDFHistory] Correctly simulate an internal destination in the pushPage-method (PR 12493 follow-up)
The intention, in PR 12493, was that the page we're adding to the browser history should behave as if it were a "regular" internal destination (to properly convey user intent).
Unfortunately, since I didn't consider all the edge-cases correctly, it ended up behaving like a URL-hash instead which obviously wasn't intended. Note that currently this isn't a problem, however it can become an issue (in some cases) with upcoming re-factoring around `PDFHistory` and OpenAction support[1].

---
[1] I've started working on fixing the following TODO, which will require a couple of smaller tweaks here and there: 9d0ce6e79f/web/app.js (L1680-L1681)
2021-03-25 12:24:28 +01:00
Jonas Jenwald
685a60055e [PDFHistory] Reduce unnecessary duplication, by introducing a helper-method for validating pageNumbers 2021-03-24 22:01:53 +01:00
Tim van der Meij
9d0ce6e79f
Merge pull request #13128 from Snuffleupagus/BasePreferences-loops
Re-factor how the `BasePreferences.prefs`-property is initialized; remove some *indirect* loops
2021-03-24 20:47:45 +01:00
Ikko Ashimine
0de15d59b8
Fix typo in pdf_history.js
occuring -> occurring
2021-03-24 23:18:40 +09:00
Jonas Jenwald
be52183211 Remove some *indirect* loops in the BasePreferences.getAll-method
In the `getAll`-method, we can have just one *explicit* loop rather than two indirect ones via the old `Object.assign`-call.

Also, changes the `get`-method to be slightly more compact (while keeping the logic intact).
2021-03-22 14:38:05 +01:00
Jonas Jenwald
4b27f58625 Re-factor how the BasePreferences.prefs-property is initialized
Looking at this now, I cannot understand why we'd need to initialize `this.prefs` with all of the values from `this.defaults`.
Not only does this *indirectly* require one extra loop, via the `Object.assign`-call, but it also means that in GENERIC-builds changes to default-preference values might not be picked-up unless the the existing user-prefs are cleared (if the user had *manually* set prefs previously).
2021-03-22 14:37:56 +01:00
Jonas Jenwald
35a088ffc1 Don't provide the enableXfa parameter to the BaseViewer constructor, and avoid the fallback bar with enableXfa = true set (PR 13069 follow-up)
Given that the `enableXfa` parameter must to be passed to the API/Worker, and thus included in the `getDocument` call, it's not necessary to include it when initializing the `PDFViewer`-instance used in the default viewer. (Also, in `AppOptions`, the parameter is clearly marked with `OptionKind.API`.)

Furthermore, we probably don't want to display the fallback bar (in Firefox) for XFA documents when `enableXfa = true` is set.
2021-03-21 10:52:01 +01:00
Tim van der Meij
c6b44d1516
Merge pull request #13117 from Snuffleupagus/defaultPreferences-builds
Re-factor the default preferences generation to support build targets (PR 10548)
2021-03-20 18:40:29 +01:00
Jonas Jenwald
71e61c3533 Tweak the pre-processor condition, for Node.js environments, in the animationStarted helper (issue 13057)
While it's still not entirely clear if this would've prevented the issue as reported, given that the particular use-case reported apparently no longer applies, this small change really cannot hurt in general *and* it won't effect "regular" viewer builds in any way.
2021-03-20 13:34:38 +01:00
Jonas Jenwald
7bcfabc43c Fix an edge-case related to compatibility-values in various AppOptions-methods
Given how the compatibility-values are being handled, it's not actually possible to override a *truthy* default-value with a *falsy* compatibility-value.
This is a simple oversight on my part, and with modern ECMAScript features this is very easy to support.
2021-03-20 13:12:09 +01:00
Jonas Jenwald
18bc59eb34 [Chromium extension] Remove the special handling of the "disableTelemetry" preference
With the changes made in the previous patch, we can now list "disableTelemetry" in the `AppOptions` only for the `CHROME`-builds and thus remove the special-casing in the `checkChromePreferencesFile` helper function.
2021-03-20 13:12:09 +01:00
Jonas Jenwald
56e1d7746a Re-factor the default preferences generation to support build targets (PR 10548)
Originally the default preferences where simply placed in a JSON-file, checked into the repository, which over time became impractical, annoying, and error-prone to maintain; please see PR 10548.
While that improved the overall situation a fair bit, it however inherited one quite unfortunate property of the old JSON-based solution[1]: It's still not possible for *different* build targets to specify their *own* default preference values.

With some preferences, such as e.g. `enableScripting`, it's not inconceivable that you'd want to (at least) support build-specific default preference values. Currently that's not really possible, which is why this PR re-factors the default preferences generation to support this.

---
[1] This fact isn't really clear from the `AppOptions` implementation, unless you're familiar with the `gulpfile.js` code, which could lead to some confusion for those new to this part of the code-base.
2021-03-20 11:50:48 +01:00
Tim van der Meij
d775616fd4
Merge pull request #13118 from brendandahl/page-aria
Add landmark region and aria-label for each page.
2021-03-19 23:17:55 +01:00
Tim van der Meij
8269ddbd16
Merge pull request #13105 from Snuffleupagus/BasePdfManager-parseDocBaseUrl
Improve memory usage around the `BasePdfManager.docBaseUrl` parameter (PR 7689 follow-up)
2021-03-19 23:03:20 +01:00
Tim van der Meij
e7e0ecf9c8
Merge pull request #13113 from Snuffleupagus/scripting-PresentationMode-events
Ignore some *scripting* events which don't make sense in PresentationMode
2021-03-19 22:52:15 +01:00
Tim van der Meij
92d3a93897
Merge pull request #13116 from Snuffleupagus/enableScripting-true
Enable scripting by default in the viewer (PR 13053 follow-up)
2021-03-19 22:48:57 +01:00
Brendan Dahl
9fb0f3b0da Add landmark region and aria-label for each page.
Allows screen readers to jump landmarks and announce
the page. Since landmarks must have content, I also added
aria labels for the loading images.
2021-03-19 14:13:51 -07:00
Jonas Jenwald
1fa5ce7f48 Ignore some *scripting* events which don't make sense in PresentationMode
A number of the currently supported *scripting* events only make sense in the "normal" viewer mode, and not when PresentationMode is active. For example:
 - Changing the zoom-level will outright break rendering in PresentationMode, since it relies on "page-fit" being used.
 - Focusing a particular (AcroForm) element won't work, and could break keyboard navigation, since forms should not be editable in PresentationMode (see issue 12232).
2021-03-19 13:54:21 +01:00
Jonas Jenwald
30c06849d8 Rotate landscape pages, during printing, by default in the viewer (enablePrintAutoRotate = true)
While this will perhaps not be perfect for *every* PDF document with mixed page orientation, based on the large number of bugs/issues seen over the years I'm however pretty convinced that it'll be an overall improvement in a majority of cases.

In order to improve things further, we'd probably need Firefox to support e.g. `@page` such that the viewer can provide better information to the print engine.
2021-03-19 12:39:37 +01:00
Jonas Jenwald
1de466896d Remove one loop from BaseViewer.getPagesOverview
Currently, with `enablePrintAutoRotate = true` set, we're forced to loop through all the pages *twice* when checking for any landscape pages.
This seems completely unnecessary now, and using only *one* loop should be marginally more efficient in general.
2021-03-19 12:38:46 +01:00
Jonas Jenwald
3ce94a9f6d Change how landscape pages are rotated, for printing, with enablePrintAutoRotate = true set
Currently landscape pages are rotated *clockwise*, which for most documents feel wrong since holding the printed pages at their *left* edge causes the landscape pages to be viewed "upside down".
In general, since most documents are LTR ones, it feels more appropriate to instead rotate landscape pages *counterclockwise* for printing.
2021-03-19 12:37:57 +01:00
calixteman
24e598a895
XFA - Add a layer to display XFA forms (#13069)
- add an option to enable XFA rendering if any;
  - for now, let the canvas layer: it could be useful to implement XFAF forms (embedded pdf in xml stream for the background and xfa form for the foreground);
  - ui elements in template DOM are pretty close to their html counterpart so we generate a fake html DOM from template one:
    - it makes easier to translate template properties to html ones;
    - it makes faster the creation of the html element in the main thread.
2021-03-19 10:11:40 +01:00
Jonas Jenwald
2d727e6e68 Enable scripting by default in the viewer (PR 13053 follow-up)
Given that https://bugzilla.mozilla.org/show_bug.cgi?id=1699219 has enabled scripting for all Firefox-channels, it seems reasonable to simply set `enableScripting = true` unconditionally in the viewer preferences/options.

For now, this patch leaves the standalone viewer-components alone (such as e.g. `BaseViewer`), and if those are used scripting will thus have to be manually enabled (see e.g. the "simpleviewer"/"singlepageviewer" examples).
2021-03-17 21:14:08 +01:00
Jonas Jenwald
bd9dee1544 Move the getPdfFilenameFromUrl helper function from web/ui_utils.js and into src/display/display_utils.js
It seems reasonable to place this alongside the *similar* `getFilenameFromUrl` helper function. This way, with the changes in the next patch, we also avoid having to expose the `isDataScheme` function in the API itself and we instead expose `getPdfFilenameFromUrl` in the API (which feels overall more appropriate).
2021-03-17 15:48:24 +01:00
Jonas Jenwald
d92b77e87f
Ensure that printing, triggered from scripting, won't accidentally throw in PDFScriptingManager._updateFromSandbox (#13104)
The issue that this patch fixes is extremely unlikely, but still theoretically possible, and I really should've caught this earlier.
Note how `BaseViewer.pagesPromise` will only be defined when a document is active, see below, and that if a printing event (triggered from scripting) arrives while the document is been closed there's a small chance that the promise isn't defined.

eb92ed12f2/web/base_viewer.js (L426-L428)
2021-03-16 14:22:39 +01:00
Emilio Cobos Álvarez
1d70bfe6e6 print: RFC: Center when printing a PDF with smaller size than the output page.
This builds on top of #13100, but this changes printing behavior intentionally
so I thought it was worth discussing separately, to improve the rendering on
test-cases like the one in https://bugzil.la/1697778.

This matches what e.g.  Evince does when you print the PDF in there on an A4
printer.

We use margins to center horizontally, and flex to center vertically. The
reasoning for this is that it should have better browser support (though maybe
pdf.js no longer supports browsers without flex support?) and it's just as
simple.
2021-03-15 09:51:53 +01:00
Tim van der Meij
eb92ed12f2
Merge pull request #13100 from emilio/container-overflow
print: Ensure print containers have the right size and don't create overflow.
2021-03-14 15:53:50 +01:00
Emilio Cobos Álvarez
b932eaf6a7 print: Remove invalid @supports condition.
@supports() is not supposed to report support for page descriptors, this is
depending on a Chromium bug, which doesn't treat as invalid:

```
<div style="size: 1pt 1pt">
```

Even though it should. That is
https://bugs.chromium.org/p/chromium/issues/detail?id=1079214

There's no need to use @supports for this. If the descriptor is not accepted it
will just be ignored.

That way, when Firefox implements @page { size }, which is in progress, it will
get the right behavior.
2021-03-14 15:15:04 +01:00
Emilio Cobos Álvarez
baed09f1ff
print: Ensure print containers have the right size and don't create overflow.
First, there's just no need to do something like this, this is simpler and
closer to what the screen renderer does.

Second, this causes overflow, which Firefox tries to compensate for when
fitting to page width, and fails at it. That is tracked in:

https://bugzilla.mozilla.org/show_bug.cgi?id=1698136

But this bug works around it by not causing overflow.

For modern browsers, we could avoid the duplication setting the style attribute
by using something like width: min/max-content, but this is not a big deal I
think, let me know if you'd prefer that.

Also I had to add a max-height for Chromium not to create extra pages. This
is harmless in Firefox and workarounds the Chromium bug, so so be it.
2021-03-14 14:49:46 +01:00
Jonas Jenwald
5b5061afa8 Enable the ESLint no-var rule globally
A significant portion of the code-base has now been converted to use `let`/`const`, rather than `var`, hence it should be possible to simply enable the ESLint `no-var` rule globally.
This way we can ensure that new code won't accidentally use `var`, and it also removes the need to manually enable the rule in various folders.

Obviously it makes sense to continue the efforts to replace `var`, but that should probably happen on a file and/or folder basis.

Please note that this patch excludes the following code:
 - The `extensions/` folder, since that seemed easiest for now (and I don't know exactly what the support situation is for the Chromium-extension).

 - The entire `external/` folder is ignored, since most of it's currently excluded from linting.
   For the code that isn't imported from elsewhere (and should be ignored), we should probably (at some point) bring the code up to the same linting/formatting standard as the rest of the code-base.

 - Various files in the `test/` folder are ignored, as necessary, since the way that a lot of this code is loaded will require some care (or perhaps larger re-factoring) when removing `var` usage.
2021-03-13 16:12:53 +01:00
Jonas Jenwald
412f01aeaf Dispatch a "Doc/WillClose" event, when scripting is enabled, when closing the document
This event is mentioned in the specification, see https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/AcrobatDC_js_api_reference.pdf#G5.1963176, and it's also listed as a valid type in fb87704b38/src/shared/util.js (L164-L170)

Since we're already dispatching a "PageClose" event in this case, it seems reasonable to *also* dispatch a "Doc/WillClose" event as well.
2021-03-13 13:21:05 +01:00
Jonas Jenwald
52a598915f Re-factor the PDFScriptingManager._destroyScripting method (PR 13042 follow-up)
*Please note:* Given the pre-existing issues raised in PR 13056, which seem to block immediate progress there, this patch extracts some *overall* improvements of the scripting/sandbox destruction in `PDFScriptingManager`.

As can be seen in `BaseViewer.setDocument`, it's currently necessary to *manually* delay the `PDFScriptingManager`-destruction in order for things to work correctly. This is, in hindsight, obviously an *extremely poor* design choice on my part; sorry about the churn here!

In order to improve things overall, the `PDFScriptingManager._destroyScripting`-method is re-factored to wait for the relevant events to be dispatched *before* sandbox-destruction occurs.
To avoid the scripting/sandbox-destruction hanging indefinitely, we utilize a timeout to force-destroy the sandbox after a short time (currently set to 1 second).
2021-03-10 13:08:19 +01:00
Jonas Jenwald
bc13932ac1 Use more optional chaining in the web/-folder (PR 12961 follow-up)
I overlooked these cases previously, but there's no reason why optional chaining (and nullish coalescing) cannot be used here as well.
2021-03-07 16:20:52 +01:00
Jonas Jenwald
bdde621366 Avoid unnecessary size_kb calculation, for large files, in PDFDocumentProperties._parseFileSize (PR 13050 follow-up) 2021-03-07 16:10:11 +01:00
Jonas Jenwald
87dd93b7fc Move handling of the PageOpen/PageClose events into the PDFScriptingManager (PR 13042 follow-up)
By moving this code from the `BaseViewer` and into `PDFScriptingManager`, all of the scripting initialization/handling code is now limited to just one file/class which help overall readability (in my opinion). Also, this patch is a *net reduction* in number of lines of code which can never hurt.

As part of these changes, the intermediary "pageopen"/"pageclose" events are now removed in favor of using the "regular" viewer events directly in `PDFScriptingManager`. Hence this removes some (strictly unnecessary) indirection in the current code, when handling PageOpen/PageClose events, which leads to overall fewer function calls in this part of the code.
2021-03-06 10:12:32 +01:00
Jonas Jenwald
a6d1cba38c [api-minor] Move the viewer scripting initialization/handling into a new PDFScriptingManager class
The *main* purpose of this patch is to allow scripting to be used together with the viewer components, note the updated "simpleviewer"/"singlepageviewer" examples, in addition to the full default viewer.
Given how the scripting functionality is currently implemented in the default viewer, trying to re-use this with the standalone viewer components would be *very* hard and ideally you'd want it to work out-of-the-box.

For an initial implementation, in the default viewer, of the scripting functionality it probably made sense to simply dump all of the code in the `app.js` file, however that cannot be used with the viewer components.
To address this, the functionality is moved into a new `PDFScriptingManager` class which can thus be handled in the same way as all other viewer components (and e.g. be passed to the `BaseViewer`-implementations).

Obviously the scripting functionality needs quite a lot of data, during its initialization, and for the default viewer we want to maintain the current way of doing the lookups since that helps avoid a number of redundant API-calls.
To that end, the `PDFScriptingManager` implementation accepts (optional) factories/functions such that we can maintain the current behaviour for the default viewer. For the viewer components specifically, fallback code-paths are provided to ensure that scripting will "just work"[1].

Besides moving the viewer handling of the scripting code to its own file/class, this patch also takes the opportunity to re-factor the functionality into a number of helper methods to improve overall readability[2].
Note that it's definitely possible that the `PDFScriptingManager` class could be improved even further (e.g. for general re-use), since it's still heavily tailored to the default viewer use-case, however I believe that this patch is still a good step forward overall.

---

[1] Obviously *all* the relevant document properties might not be available in the viewer components use-case (e.g. the various URLs), but most things should work just fine.

[2] The old `PDFViewerApplication._initializeJavaScript` method, where everything was simply inlined, have over time (in my opinion) become quite large and somewhat difficult to *easily* reason about.
2021-03-05 20:31:48 +01:00
Jonas Jenwald
5b9638329c Move apiPageLayoutToSpreadMode and apiPageModeToSidebarView from web/app.js and into web/ui_utils.js
These changes will be necessary for the next patch, since we don't want to accidentally pull in the entire default viewer in the standalone viewer components.
2021-03-05 20:31:48 +01:00
Jonas Jenwald
7dc1bbf05e Enable scripting by default in the development viewer
Given that scripting is now enabled in Firefox Nightly (but only there), it seems weird to not have scripting enabled by default in `gulp server` mode.
2021-03-04 23:56:51 +01:00
Jonas Jenwald
038668bf8c Collect all l10n fallback strings, used in the viewer, in one helper function (PR 12981 follow-up)
Rather than having to spell out the English fallback strings at *every* single `IL10n.get` call-site throughout the viewer, we can simplify things by collecting them in *one* central spot.
This provides a much better overview of the fallback l10n strings used, which makes future changes easier and ensures that fallback strings occuring in multiple places cannot accidentally get out of sync.
Furthermore, by making the `fallback` parameter of the `IL10n.get` method *optional*[1] many of the call-sites (and their surrounding code) become a lot less verbose.

---
[1] It's obviously still possible to pass in a fallback string, it's just not required.
2021-03-04 11:34:51 +01:00
Jonas Jenwald
7c52c01267 Change the background to ensure that the sidebar is visible/readable when the viewer is narrow (issue 13036)
This is more fallout from PR 11077.
2021-03-01 18:27:27 +01:00