Commit Graph

3172 Commits

Author SHA1 Message Date
Tim van der Meij
f5e973d555
Merge pull request #13197 from Snuffleupagus/issue-8233
Improve the image quality of thumbnails rendered by `PDFThumbnailView.draw` (issue 8233)
2021-04-09 21:51:42 +02:00
Tim van der Meij
03c8c89002
Merge pull request #13171 from brendandahl/struct-tree
[api-minor] Add support for basic structure tree for accessibility.
2021-04-09 21:32:44 +02:00
Tim van der Meij
b0473eb353
Merge pull request #13207 from Snuffleupagus/api-AnnotationStorage-params
[api-minor] Remove the manual passing of an `AnnotationStorage`-instance when calling various API-method
2021-04-09 21:09:16 +02:00
Brendan Dahl
fc9501a637 Add support for basic structure tree for accessibility.
When a PDF is "marked" we now generate a separate DOM that represents
the structure tree from the PDF.  This DOM is inserted into the <canvas>
element and allows screen readers to walk the tree and have more
information about headings, images, links, etc. To link the structure
tree DOM (which is empty) to the text layer aria-owns is used. This
required modifying the text layer creation so that marked items are
now tracked.
2021-04-09 09:56:28 -07:00
Jonas Jenwald
ec9e29807a Remove the enableScripting option from the PDFPageView constructor
Scripting, as implemented, requires access to a complete document/viewer in order to work. Hence it doesn't really make sense to keep the `enableScripting`-option on `PDFPageView`-instances.[1]

---
[1] Note that there's the `PDFSinglePageViewer`, which can be used in cases where you want access to all features/functionality of the viewer but only display *one* page at a time.
2021-04-09 14:20:47 +02:00
Jonas Jenwald
72ef183085 [api-minor] Remove the manual passing of an AnnotationStorage-instance when calling various API-method
Note how we purposely don't expose the `AnnotationStorage`-class directly in the official API (see `src/pdf.js`), since trying to use *multiple* ones simultaneously doesn't really make sense (e.g. in the viewer).
Instead we lazily initialize, and cache, just *one* instance via `PDFDocumentProxy.annotationStorage` which should thus be available internally in the API itself without having to be manually passed to various methods.

To support these changes, the `AnnotationStorage`-instance initialization is moved into the `WorkerTransport`-class to allow both `PDFDocumentProxy` and `PDFPageProxy` to access it.
This patch implements the following simplifications:
 - Remove the `annotationStorage`-parameter from `PDFDocumentProxy.saveDocument`, since it's already available internally.
   Furthermore, while it's currently possible to call that method without an `AnnotationStorage`-instance, that really does *not* make any sense at all. In this case you're effectively reducing `PDFDocumentProxy.saveDocument` to a "regular" `PDFDocumentProxy.getData` call, but with *a lot* more overhead, which was obviously not the intention of the `PDFDocumentProxy.saveDocument`-method.

 - Try to discourage third-party users from calling `PDFDocumentProxy.saveDocument` unconditionally, as a replacement for `PDFDocumentProxy.getData` (note the previous point).

 - Replace the `annotationStorage`-parameter, in `PDFPageProxy.render`, with a boolean `includeAnnotationStorage`-parameter which simply indicates if the (internally available) `AnnotationStorage`-instance should be used during rendering (e.g. for printing).

 - By removing the need to *manually* provide `annotationStorage`-parameters to various API-methods, using the API should become simpler (e.g. for third-parties) since you no longer need to worry about manually fetching and passing around this data.
2021-04-09 13:24:25 +02:00
Jonas Jenwald
d8e0794650 Improve the image quality of thumbnails rendered by PDFThumbnailView.draw (issue 8233)
The reason for the fairly large discrepancy, in the thumbnail quality, between the `draw`/`setImage`-methods is that in the former case we *directly* render the thumbnails at the final size that they'll appear at in the sidebar. In the latter case, we instead downsize the (generally) much larger "regular" pages.

To address this, I'm thus proposing that we let `PDFThumbnailView.draw` render thumbnails at *twice* their intended size and then downsize them to the final size.
Obviously this will increase *peak* memory usage during thumbnail rendering in `PDFThumbnailView.draw`, since doubling the width/height of a `canvas` will lead to its pixel-count increasing by a factor of `4`. Furthermore, since you need four components per pixel (given that it's RGBA-data), this will thus lead to the *temporary* thumbnail `canvas`-sizes increasing by a factor of `16` during rendering. Hence why rendering thumbnails at their "original" scale, i.e. using something like `PDFPageProxy.getViewport({ scale: 1 });`, would be an absolutely terrible idea!

To reduce the size and scope of these changes, I've tried to re-factor and re-use as much of the existing downsizing-implementation already present in `PDFThumbnailView` as possible.

While this will generally *not* make thumbnails rendered by `PDFThumbnailView.draw` look *identical* to those based on the rendered pages (via `PDFThumbnailView.setImage`), it's a considerable improvement as far as I'm concerned and enough to call the issue fixed.

*Please note:* This patch will not lead to *any* additional overhead, in either memory usage or parsing, for thumbnails which are based on the rendered pages.
2021-04-08 13:58:24 +02:00
Jonas Jenwald
32a00b9b2b Stop looping over childNodes, in PDFThumbnailView.reset, when removing the thumbnail
A loop is less efficient than just overwriting the content, which is what we've generally been using (for years) in other parts of the code-base (see e.g. `BaseViewer` and `PDFThumbnailViewer`).
2021-04-08 12:22:07 +02:00
Jonas Jenwald
8ea83f7030 Convert some properties, on PDFThumbnailView-instances, to local variables
These properties are always updated/used together, and there's no other methods which depend on just one of them, hence they're changed into local variables instead.
Looking through the history of this code, it seems they were converted *from* local variables and to properties all the way back in PR 2914; however as far as I can tell from that diff it doesn't seem to have been necessary even back then!?
2021-04-08 12:21:52 +02:00
Tim van der Meij
5945f7c4a1
Merge pull request #13186 from Snuffleupagus/rm-deprecated-code
Remove some `deprecated` code
2021-04-07 20:38:59 +02:00
Jonas Jenwald
92ec10bfca Remove the deprecated PDFLinkService.navigateTo-method (PR 12440 follow-up)
This method has been deprecated in two releases now, hence we shouldn't need to keep this code around.
2021-04-06 13:08:50 +02:00
Jonas Jenwald
b2758c3023 Remove the deprecated properties from the "presentationmodechanged" event (PR 12788 follow-up)
These properties have been deprecated in two releases now, hence we shouldn't need to keep this code around.
2021-04-06 13:04:23 +02:00
Tim van der Meij
ff393d6e96
Convert the pendingFindMatches member, in web/pdf_find_controller.js, from an object to a set
We only want to track page numbers instead of actual data, so using a
set conveys that intention more clearly and is slightly more efficient.
2021-04-05 19:33:53 +02:00
Tim van der Meij
228adbf673
Merge pull request #13172 from Snuffleupagus/cleanup-keepFonts
[api-minor] Add an option, in `PDFDocumentProxy.cleanup`, to allow fonts to remain attached to the DOM
2021-04-05 14:21:34 +02:00
Jonas Jenwald
3f59d4201a [GENERIC viewer] Avoid data loss in forms, by triggering saving when the document is closed (issue 12257)
As discussed in the issue, this is a small/simple patch that should help to prevent *outright* data loss in forms when a new document is opened in the GENERIC viewer.

While the implementation is perhaps a bit "simplistic", it does seem to work and should be fine given that this is an edge-case only relevant for the GENERIC viewer.
2021-04-03 18:16:53 +02:00
Jonas Jenwald
5b28a0bf97 Re-factor the download/save-methods, on PDFViewerApplication, to make full use of async/await
In the next patch we'll need to be able to actually wait for saving to complete, hence it's necessary to slightly re-factor the `save`-method.

As part of these changes, we can reduce some duplication in the `save`-method and slightly improve the overall code. For consistency, the `download`-method is updated similarily to improve the code (this functionality is *very* old, even pre-dating the introduction of Promises in the code-base).
2021-04-03 18:11:01 +02:00
Jonas Jenwald
a2bc6481a0 [api-minor] Add an option, in PDFDocumentProxy.cleanup, to allow fonts to remain attached to the DOM
As mentioned in the JSDoc comment, this should not be used unless you know what you're doing, since it will lead to increased memory usage. However, in some situations (e.g. SVG-rendering), we still want to be able to run general clean-up on both the main/worker-thread while keeping loaded fonts attached to the DOM.[1]

As part of these changes, `WorkerTransport.startCleanup` is converted to an async method and we'll also skip clean-up when destruction has started (since it's redundant).

---
[1] The SVG-rendering mode is obviously not officially supported, since it's both rather incomplete and inherently slower. However with recent changes, whereby we cache repeated images on the document rather than the page level, memory usage can be *a lot* worse than before if we never attempt to release e.g. cached image-data when the viewer is in SVG-rendering mode.
2021-04-02 12:32:31 +02:00
Tim van der Meij
70915d34ed
Merge pull request #13157 from Snuffleupagus/webViewerOpenFileViaURL-cleanup
Remove the `file://`-URL special-case from `webViewerOpenFileViaURL`
2021-03-31 20:24:08 +02:00
Tim van der Meij
d47b30ef54
Merge pull request #13156 from Snuffleupagus/outline-destRef-null
Prevent errors, in `PDFOutlineViewer._getPageNumberToDestHash`, for invalid `destRef` values (PR 12777 follow-up)
2021-03-31 20:20:35 +02:00
calixteman
b3528868c1
XFA - Add support for few ui elements (#13115)
- input;
  - layout;
  - border;
  - margin;
  - color.
2021-03-31 15:42:21 +02:00
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
32b7bbaced Remove the file://-URL special-case from webViewerOpenFileViaURL
Given that *all* data has been loaded on the main-thread, and then transferred to the worker-thread, ever since PR 8617 (almost four years ago) it should no longer be necessary to keep this special-case around.
2021-03-28 18:15:17 +02:00
Jonas Jenwald
0a03843e5f Re-factor the pre-processor statements used with webViewerOpenFileViaURL
Given that the `webViewerOpenFileViaURL` helper function is being defined in *all* builds anyway, the current pre-processor usage doesn't really improve readability in my opinion.
2021-03-28 18:09:43 +02:00
Jonas Jenwald
14fc9db73d Prevent errors, in PDFOutlineViewer._getPageNumberToDestHash, for invalid destRef values (PR 12777 follow-up)
Currently `destRef === null`, which will only happen in documents with corrupt destinations, will (unsurprisingly) throw when trying to lookup the pageNumber. To avoid this, we can simply use the same format as in 1a2cdaffc5/web/pdf_link_service.js (L128)
2021-03-28 17:36:51 +02: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
Jonas Jenwald
6fd899dc44 [api-minor] Support the Content-Disposition filename in the Firefox PDF Viewer (bug 1694556, PR 9379 follow-up)
As can be seen [in the mozilla-central code](https://searchfox.org/mozilla-central/rev/a6db3bd67367aa9ddd9505690cab09b47e65a762/toolkit/components/pdfjs/content/PdfStreamConverter.jsm#1222-1225), we're already getting the Content-Disposition filename. However, that data isn't passed through to the viewer nor to the `PDFDataTransportStream`-implementation, which explains why it's currently being ignored.

*Please note:* This will also require a small mozilla-central patch, see https://bugzilla.mozilla.org/show_bug.cgi?id=1694556, to forward the necessary data to the viewer.
2021-02-26 10:50:29 +01:00
Tim van der Meij
061637d3f4
Merge pull request #13021 from Snuffleupagus/createObjectURL-rm-shadow
Remove the, strictly unnecessary, closure and variable shadowing from `createObjectURL`
2021-02-25 23:35:17 +01:00
Tim van der Meij
163a840a1e
Merge pull request #13020 from Snuffleupagus/rm-some-NullL10n-use
Remove the `NullL10n` default value from viewer components not included in the `COMPONENTS`-bundle
2021-02-25 23:27:49 +01:00
Jonas Jenwald
70d1869fe5 Remove the, strictly unnecessary, closure and variable shadowing from createObjectURL
Note that this particular helper function is, with the exception of the `GENERIC` default viewer and the (unsupported) SVG-backend, mostly unused at this point in time. Hence we should be able to clean-up this helper function slightly.

Also, fixes a small inconsistency in the `SVGGraphics` initialization in the viewer, by passing in the `disableCreateObjectURL` compatibility-option. Given that the SVG-backend isn't officially supported/recommended this shouldn't have been an issue, but given that I spotted this it can't hurt to fix it.
2021-02-25 16:34:23 +01:00
Jonas Jenwald
85251da218 Remove the NullL10n default value from viewer components not included in the COMPONENTS-bundle
For any viewer component not listed in `web/pdf_viewer.component.js`, it shouldn't be necessary to provide a default value for the `l10n`-parameters.
Note also that these *specific* components are heavily tailored towards the default viewer use-case, rather than for general usage.
2021-02-25 16:08:04 +01:00
Jonas Jenwald
c277e39b0b Remove the findResultsCount-check from PDFFindBar.updateResultsCount, and unnecessary defaults from the constructor
Given that `PDFFindBar` is written *specifically* for the default viewer, rather than general usage (as opposed to the `PDFFindController`), we should be able to simply assume that the `findResultsCount` DOM-element is always present. Even more so, when we're purposely not doing any similar checks for other DOM-elements in this code.

Also, remove unnecessary `null` defaults for the various DOM-element options in the constructor, since the code simply assumes that all of the relevant DOM-elements are in fact available.
2021-02-25 16:05:07 +01:00
Jonas Jenwald
df931ef685 Move the opening of PDF file attachments into the DownloadManager-implementations
Note how the `PDFAttachmentViewer` handles PDF file attachments specially, by opening them in a new window/tab, rather than forcing them to be downloaded. This is done to improve the overall UX, since browsers in general are able to handle PDF files internally.
However, for file *annotations* we're currently not attempting to do the same thing and are instead just downloading them directly. In order to unify the behaviour, without having to duplicate a lot of code, the opening of PDF file attachments is thus moved into a new `DownloadManager.openOrDownloadData` method.
2021-02-23 13:44:23 +01:00
Tim van der Meij
4619b1b568
Merge pull request #12997 from Snuffleupagus/metadata-worker
Move the Metadata parsing to the worker-thread
2021-02-17 20:57:46 +01:00
Jonas Jenwald
cc3a6563ee Move the Metadata parsing to the worker-thread
The only reason, as far as I can tell, for parsing the Metadata on the main-thread is how it was originally implemented. When Metadata support was first implemented, it utilized the [`DOMParser`](https://developer.mozilla.org/en-US/docs/Web/API/DOMParser) which isn't available in workers.
Today, with the custom XML-parser being used, that's no longer an issue and it seems reasonable to move the Metadata parsing to the worker-thread[1], since that's where all parsing should happen (for performance reasons).

Based on these changes, we'll be able to reduce the now unnecessary duplication of the XML-parser (and related code) in both of the *built* `pdf.js`/`pdf.worker.js` files.

Finally, this patch changes the `_repair` method to use "Array + join" rather than string concatenation.

---
[1] This needed the previous patch, to enable sending of `Map`s between threads with workers disabled.
2021-02-17 13:12:01 +01:00
Jonas Jenwald
0a28e51e40 Simplify the default value handling of renderInteractiveForms in the viewer components
I happened to look at this code, and I can't for the life of me figure out why I didn't just implement it like this patch in the first place (since the current format feels overly verbose).
2021-02-17 10:47:55 +01:00
Jonas Jenwald
9887644702 Stop showing the fallback bar for "errorFontMissing" errors (PR 11218 follow-up)
*This is somewhat similar to PR 12931.*

For PDF documents where fonts are completely missing in the /Resources dictionaries, there's basically no "correct" way of rendering the document.
Hence it's very unlikely that another PDF viewer will do a better job than PDF.js in these cases, and consequently it seems highly questionable if the fallback bar really helps here.
2021-02-16 16:29:13 +01:00
Tim van der Meij
f892c00275
Merge pull request #12991 from Snuffleupagus/viewer-Firefox-rm-misc-code
Stop including unused/unnecessary code in the viewer, for `MOZCENTRAL`-builds
2021-02-14 15:17:16 +01:00
Jonas Jenwald
209fe60472 Use a more compact format for the fallback EventBus-listeners in PDFViewerApplication_initializeJavaScript
Given that these event listeners should essentially never be needed, but are included simply to avoid breakage in edge-cases, it can't hurt to make this code slightly less verbose.
2021-02-14 12:37:37 +01:00
Jonas Jenwald
48f4580991 A couple of small BaseViewer tweaks
- Mark `BaseViewer.initializeScriptingEvents` as an `async` method, since that's actually how it's being used in the default viewer (see `PDFViewerApplication-_initializeJavaScript`).

 - Change `BaseViewer._pageWidthScaleFactor` to access the *internal* scroll/spread-modes directly, rather than using the getters, since that's consistent with the rest of the code (and not just for these properties).
2021-02-14 12:32:50 +01:00
Jonas Jenwald
4c107d8d7c Remove the useless PresentationModeState.CHANGING-case in PDFCursorTools (PR 12788 follow-up)
For reasons that I now can't for the life of me understand, I included handling of the `PresentationModeState.CHANGING`-case despite it not actually doing anything.
2021-02-14 10:39:49 +01:00
Jonas Jenwald
1ca816d724 Directly use requestIdleCallback in MOZCENTRAL-builds
Given the following compatibility information, we really shouldn't need to check for the availability of `requestIdleCallback` in Firefox; see https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback#browser_compatibility
2021-02-14 10:39:42 +01:00
Jonas Jenwald
7f8a9b12d9 Stop including the "errorWrapper" HTML code in MOZCENTRAL-builds
Given that these HTML elements are not being used at all in `MOZCENTRAL`-builds, note the preprocessor check in `PDFViewerApplication._otherError`, we obviously don't need the HTML code either.
2021-02-14 10:39:34 +01:00
Tim van der Meij
d5cad9ad3f
Merge pull request #12981 from Snuffleupagus/app-localizeMessage
Collect the l10n error/warning message lookup, in `web/app.js`, in a new helper method
2021-02-12 00:14:05 +01:00
Jonas Jenwald
4733f163e8 Replace a few new Date().getTime() instances with Date.now()
The former format is not only more verbose, but it's also *slightly* less efficient since it creates a new `Date` object.
2021-02-11 23:00:42 +01:00
Jonas Jenwald
fe3f074f6d Collect the l10n error/warning message lookup, in web/app.js, in a new helper method
Some of the localization strings (e.g. "loading_error") are repeated multiple times throughout the `web/app.js` file, which means that we need to duplicate the fallback strings as well. Furthermore, the signature of the `IL10n.get` method makes the call-sites quite verbose.

By adding a new helper method, in `PDFViewerApplication`, we're able to gather the localization fallback strings in one central spot in `web/app.js` and also make the lookup of the error/warning messages more compact.
2021-02-11 12:30:53 +01:00
Jonas Jenwald
25b581c2a9 Slightly simplify the parameter handling in initPassiveLoading.onOpenWithURL 2021-02-10 18:13:44 +01:00
Jonas Jenwald
b375a867eb Use arrow functions in PDFViewerApplication.initPassiveLoading
This code is *very* old and it even predates the existence of arrow functions. Hence we can now reduce the overall verbosity by not having to explicitly spell out `PDFViewerApplication` everywhere.
2021-02-10 18:13:43 +01:00
Jonas Jenwald
31098c404d
Use Math.hypot, instead of Math.sqrt with manual squaring (#12973)
When the PDF.js project started `Math.hypot` didn't exist yet, and until recently we still supported browsers (IE 11) without a native `Math.hypot` implementation; please see this compatibility information: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/hypot#browser_compatibility

Furthermore, somewhat recently there were performance improvements of `Math.hypot` in Firefox; see https://bugzilla.mozilla.org/show_bug.cgi?id=1648820

Finally, this patch also replaces a couple of multiplications with the exponentiation operator.
2021-02-10 12:28:49 +01:00
Tim van der Meij
3a2c259b57
Merge pull request #12972 from Snuffleupagus/pr-12354-followup
[GENERIC viewer] Skip the `iframe`-case when checking if the `container` div, on `BaseViewer`-instances, is absolutely positioned (PR 12354 follow-up)
2021-02-10 00:18:02 +01:00
Jonas Jenwald
32a4a30f3a Remove the contentmenu usage, from PresentationMode, since it's no longer working
This feature was Firefox-specific, and it's now been removed from the HTML specification and it's disabled by default starting with Firefox 85. Hence it seems completely unnecessary to keep this code in the default viewer.

Please refer to https://groups.google.com/g/mozilla.dev.platform/c/tc11BCenm2c and the resources that it links to.
2021-02-09 14:29:48 +01:00
Jonas Jenwald
9fa20ad8c5 [GENERIC viewer] Skip the iframe-case when checking if the container div, on BaseViewer-instances, is absolutely positioned (PR 12354 follow-up)
Given that `getComputedStyle` only works on visible elements, the result of PR 12354 is that if the viewer is placed in a *hidden* `iframe` the viewer will now be broken. This obviously wasn't the intention of that PR, hence I believe that we should limit the `position: absolute;` check slightly to avoid this.
2021-02-09 12:07:20 +01:00
Tim van der Meij
884c65c602
Merge pull request #12971 from nt1m/bool-attrs
Use DOM hidden property instead of attribute methods
2021-02-08 20:14:44 +01:00
Tim Nguyen
2ca886baee Use DOM hidden property instead of attribute methods 2021-02-08 00:21:49 +01:00
Jonas Jenwald
27727234ba Split PDFViewerApplication.error into two methods, for PDF document loading/parsing errors vs other errors (PR 11647 follow-up)
With these changes, we can easily unblock the "load" event regardless of where an error occurred.
2021-02-07 22:28:53 +01:00
Tim van der Meij
6263a21fb5
Merge pull request #12961 from Snuffleupagus/web-optional-chaining
Use optional chaining, where possible, in the `web/`-folder
2021-02-06 19:27:15 +01:00
Tim van der Meij
d2a21a1171
Merge pull request #12941 from justinribeiro/resolve-button-aria-expanded
fix(a11y): resolve sidebar, find, toolbar missing aria-expanded and aria-controls state
2021-02-06 19:16:48 +01:00
Justin Ribeiro
374da648dd
fix(a11y): resolve sidebar, find, toolbar missing aria-expanded and
aria-controls state

In testing, screen readers such as JAWS have trouble understanding the expanded state of the buttons that expand hidden menus due to lacking aria-expanded attribute. Also, given that the buttons do not contain the controlled/shown element, they should also define the aria-controls attribute with associated element id per https://www.w3.org/TR/wai-aria-1.1/#aria-expanded

This fixes adds these requirements for the sidebar, find, and secondary toolbar buttons.
2021-02-05 16:08:29 -08:00
Jonas Jenwald
08c23c12dc [Firefox] Block the "load" event until all pages are loaded, to ensure that printing works (bug 1618553) 2021-02-05 22:01:57 +01:00
Jonas Jenwald
063a072742 Use optional chaining, where possible, in the web/-folder
By using optional chaining, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining, it's possible to reduce unnecessary code-repetition in many cases.
2021-02-05 17:50:11 +01:00
Jonas Jenwald
dc19965d78 Slightly re-factor how the BaseViewer/PDFThumbnailViewer handle page labels internally, to make the null default value clearer
Currently it's not *immediately* clear from the code itself, unless you look at the definition of `this._pageLabels`, that the default value is `null`.[1]
We can improve this, and also reduce the amount of code, by using modern ECMAScript features such as optional chaining and nullish coalescing.

---
[1] Keep in mind that an *empty* string is actually a valid page label, according to the PDF specification.
2021-02-05 17:50:07 +01:00
Jonas Jenwald
d1586bbbe7 Don't focus the PasswordPrompt input-field on load, when the viewer is embedded in e.g. an iframe (issue 12951)
Given that we don't focus the viewer *itself* (among other things) when the viewer is embedded, I suppose that it makes some sense to not focus the `PasswordPrompt` input-field either on load.
In order to improve the overall UX here, if an *incorrect* password was provided we'll still focus the input-field.

Fixes 12951 (assuming we care to do so, of course).
2021-02-03 15:48:40 +01:00
Jonas Jenwald
1c802e0e6c Remove prefixed fullscreen properties/methods from the MOZCENTRAL builds
The unprefixed version of the fullscreen API has been enabled for quite some time in Firefox, see below, hence we can (slightly) clean-up the relevant code.

 - https://developer.mozilla.org/en-us/docs/Web/API/Document/fullscreenEnabled#browser_compatibility
 - https://developer.mozilla.org/en-US/docs/Web/API/Element/requestFullScreen#browser_compatibility
2021-01-31 13:45:14 +01:00
Jonas Jenwald
5a522a5c71 Stop showing the fallback bar for "errorFontLoadNative" errors (PR 10539 follow-up)
With PR 10539, we'll now always attempt to fallback to the PDF.js built-in font renderer for fonts that fail to load (i.e. are rejected by the sanitizer). Generally speaking, these errors are the result of insufficient validation in the PDF.js font code, however in almost all cases we've seen thus far our built-in font renderer manages just fine.
However, we still trigger the `onUnsupportedFeature` reporting, which in Firefox causes the fallback bar to be displayed. Given that, in a majority of cases[1], things look fine it seems unfortunate to bother the user with the fallback bar here.

Note that even though we no longer show the fallback bar in this case, we still report telemetry as before.

---
[1] The only *known* case where things aren't fine with the built-in font renderer is issue 10232, however that document is sufficiently broken that there's a couple of other things that will trigger the fallback bar.
2021-01-29 16:48:51 +01:00
Jonas Jenwald
a2b592f4a2 Add previous/next-page functionality that takes scroll/spread-modes into account (issue 11946)
- For wrapped scrolling, we unfortunately need to do a fair bit of parsing of the *current* page layout. Compared to e.g. the spread-modes, where we can easily tell how the pages are laid out, with wrapped scrolling we cannot tell without actually checking. In particular documents with varying page sizes require some care, since we need to check all pages on the "row" of the current page are visible and that there aren't any "holes" present. Otherwise, in the general case, there's a risk that we'd skip over pages if we'd simply always advance to the previous/next "row" in wrapped scrolling.

 - For horizontal scrolling, this patch simply maintains the current behaviour of advancing *one* page at a time. The reason for this is to prevent inconsistent behaviour for the next and previous cases, since those cannot be handled identically. For the next-case, it'd obviously be simple to advance to the first not completely visible page. However for the previous-case, we'd only be able to go back *one* page since it's not possible to (easily) determine the page layout of non-visible pages (documents with varying page sizes being a particular issue).

 - For vertical scrolling, this patch maintains the current behaviour by default. When spread-modes are being used, we'll now attempt to advance to the next *spread*, rather than just the next page, whenever possible. To prevent skipping over a page, this two-page advance will only apply when both pages of the current spread are visible (to avoid breaking documents with varying page sizes) and when the second page in the current spread is fully visible *horizontally* (to handle larger zoom values).

In order to reduce the performance impact of these changes, note that the previous/next-functionality will only call `getVisibleElements` for the scroll/spread-modes where that's necessary and that "normal" vertical scrolling is thus unaffected by these changes.

To support these changes, the `getVisibleElements` helper function will now also include the `widthPercent` in addition to the existing `percent` property.
The `PDFViewer._updateHelper` method is changed slightly w.r.t. updating the `currentPageNumber` for the non-vertical/spread modes, i.e. won't affect "normal" vertical scrolling, since that helped simplify the overall calculation of the page advance.

Finally, these new `BaseViewer` methods also allow (some) simplification of previous/next-page functionality in various viewer components.

*Please note:* There's one thing that this patch does not attempt to change, namely disabling of the previous/next toolbarButtons respectively the firstPage/lastPage secondaryToolbarButtons. The reason for this is that doing so would add quite a bit of complexity in general, and if for some reason `BaseViewer._getPageAdvance` would get things wrong we could end up incorrectly disabling the buttons. Hence it seemed overall safer to *not* touch this, and accept that the buttons won't be `disabled` despite in some edge-cases no further scrolling being possible.
2021-01-22 21:38:15 +01:00
Jonas Jenwald
38c9f1a37a Enable the Stylelint shorthand-property-no-redundant-values rule
Note that these changes were done automatically, using `gulp lint --fix`; this rule will help avoid unnecessary repetition in the CSS.

Please find additional details about the Stylelint rule at https://stylelint.io/user-guide/rules/shorthand-property-no-redundant-values
2021-01-22 14:36:02 +01:00
Jonas Jenwald
e997f60656 Only display a notification on the sidebarToggle-button, and not the individual view-buttons (PR 7959 follow-up)
The whole purpose of showing a notification on the `sidebarToggle` button, when the sidebar is closed, was to give users *some* kind of indication that the PDF document contains outline/attachments/layers without having to manually open the sidebar to check.
However, in the implementation in PR 7959, I also added notifications for each view-buttons in the sidebar. Looking back at this, I've always questioned the value of the last part, since the view-buttons already have a `disabled`-state which shows if they're available or not. Hence we're actually, in a sense, duplicating notifications for the outline/attachments/layers-buttons without adding (in my opinion) all that much overall value.

All-in-all, I'm thus proposing that we only display the notification on the `sidebarToggle`-button itself, since that should really be sufficient here, which also allows us to simplify the relevant code a fair bit.
2021-01-18 11:36:42 +01:00
Tim van der Meij
dcd1589b2c
Merge pull request #12855 from Snuffleupagus/find-normalization
[api-minor] Highlight search results correctly for normalized text (PR 9448)
2021-01-12 22:04:10 +01:00
Jonas Jenwald
f1749f03e3 Ensure that PDFViewerApplication.close has a *consistent* return value 2021-01-12 20:28:52 +01:00
Jonas Jenwald
13742eb82d Inlude the JS actions for the page when dispatching the "pageopen"-event in the BaseViewer
Note first of all how the `PDFDocumentProxy.getJSActions` method in the API caches the result, which makes repeated lookups cheap enough to not really be an issue.
Secondly, with the previous patch, we're now only dispatching "pageopen"/"pageclose"-events when there's actually a sandbox that listens for them.

All-in-all, with these changes we can thus simplify the default-viewer "pageopen"-event handler a fair bit.
2021-01-12 20:28:50 +01:00
Ross Johnson
6dae2677d5 [api-minor] Highlight search results correctly for normalized text (PR 9448)
This patch is a rebased *and* refactored version of PR 9448, such that it applies cleanly given that `PDFFindController` has changed since that PR was opened; obviously keeping the original author information intact.

This patch will thus ensure that e.g. fractions, and other things that we normalize before searching, will still be highlighted correctly in the textLayer.

Furthermore, this patch also adds basic unit-tests for this functionality.

*Note:* The `[api-minor]` tag is added, since third-party implementations of the `PDFFindController` must now always use the `pageMatchesLength` property to get accurate length information (see the `web/text_layer_builder.js` changes).

Co-authored-by: Ross Johnson <ross@mazira.com>
Co-authored-by: Jonas Jenwald <jonas.jenwald@gmail.com>
2021-01-12 18:08:08 +01:00
Jonas Jenwald
a882a85446 Fix the initialization/resetting of scripting-related events in the BaseViewer
The "pageopen"/"pageclose"-events are only necessary if, and only if, there's actually a sandbox to dispatch the events in. Hence we shouldn't dispatch those events unconditionally, as soon as `enableScripting` is set, but rather initialize that functionality only when needed.

Furthermore, in `web/app.js`, there's currently a bug since we're attempting to *manually* simulate a "pageopen"-event for a page that may not actually have been rendered at the time. With the modified `BaseViewer.initializeScriptingEvents` method, we'll now dispatch a correct "pageopen"-event here.
2021-01-12 14:28:09 +01:00
calixteman
1de1ae0be6
Merge pull request #12838 from calixteman/authors
[api-minor] Change the "dc:creator" Metadata field to an Array
2021-01-12 02:44:58 -08:00
Calixte Denizet
43d5512f5c [api-minor] Change the "dc:creator" Metadata field to an Array
- add scripting support for doc.info.authors
 - doc.info.metadata is the raw string with xml code
2021-01-11 21:34:07 +01:00
Tim van der Meij
36e6ae5b2f
Correctly align annotation content in horizontal/spread scrolling modes
Not only was long text in popups no longer wrapped correctly, the
alignment was also center instead of left (or right, depending on the
locale used) for both text in popups and the other parts within the
annotation's section, such as the icon.
2021-01-10 18:58:13 +01:00
Jonas Jenwald
246a6f9d13 Enable the Stylelint length-zero-no-unit rule
Note that these changes were done automatically, using `gulp lint --fix`.
With this rule, we'll thus enforce a *consistent* formatting of zero-lengths in our CSS files.

Please find additional details about the Stylelint rule at https://stylelint.io/user-guide/rules/length-zero-no-unit
2021-01-10 14:09:36 +01:00
Jonas Jenwald
ccbee6d2be Remove unnecessary dir-dependent CSS rules, and simplify som findbar-button rules (PR 11077 follow-up)
With the updated default viewer UI, some `dir`-dependent CSS rules are now redundant since *identical* rules are being specified for both LTR and RTL mode; after PR 12807 landed I've found even more of these cases.

Note in particular that the findbar-button rules can be simplified quite a bit, since there's a fair amount of unnecessary duplication in the CSS.
2021-01-10 13:30:36 +01:00
Jonas Jenwald
81525fd446 Use ESLint to ensure that exports are sorted alphabetically
There's built-in ESLint rule, see `sort-imports`, to ensure that all `import`-statements are sorted alphabetically, since that often helps with readability.
Unfortunately there's no corresponding rule to sort `export`-statements alphabetically, however there's an ESLint plugin which does this; please see https://www.npmjs.com/package/eslint-plugin-sort-exports

The only downside here is that it's not automatically fixable, but the re-ordering is a one-time "cost" and the plugin will help maintain a *consistent* ordering of `export`-statements in the future.
*Note:* To reduce the possibility of introducing any errors here, the re-ordering was done by simply selecting the relevant lines and then using the built-in sort-functionality of my editor.
2021-01-09 20:37:51 +01:00
Jani Pehkonen
492a8171b3 Add an icon for the "find/highlight the current outlineItem" functionality 2021-01-09 16:09:46 +01:00
Jonas Jenwald
5729c0b32f Add support for finding/highlighting the outlineItem, corresponding to the currently visible page, in the sidebar (issue 7557, bug 1253820, bug 1499050)
This implementation is inspired by the behaviour in (recent versions of) Adobe Reader, since it leads to reasonably simple and straightforward code as far as I'm concerned.
*Specifically:* We'll only consider *one* destination per page when finding/highlighting the current outline item, which is similar to e.g. Adobe Reader, and we choose the *first* outline item at the *lowest* level of the outline tree.

Given that this functionality requires not only parsing of the `outline`, but looking up *all* of the destinations in the document, this feature can when initialized have a non-trivial performance overhead for larger PDF documents.
In an attempt to reduce the performance impact, the following steps are taken here:

 - The "find current outline item"-functionality will only be enabled once *one* page has rendered and *all* the pages have been loaded[1], to prevent it interfering with data regular fetching/parsing early on during document loading and viewer initialization.

 - With the exception of a couple of small and simple `eventBus`-listeners, in `PDFOutlineViewer`, this new functionality is initialized *lazily* the first time that the user clicks on the `currentOutlineItem`-button.

 - The entire "find current outline item"-functionality is disabled when `disableAutoFetch = true` is set, since it can easily lead to the setting becoming essentially pointless[2] by triggering *a lot* of data fetching from a relatively minor viewer-feature.

 - Fetch the destinations *individually*, since that's generally more efficient than using `PDFDocumentProxy.getDestinations` to fetch them all at once. Despite making the overall parsing code *more* asynchronous, and leading to a lot more main/worker-thread message passing, in practice this seems faster for larger documents.

Finally, we'll now always highlight an outline item that the user manually clicked on, since only highlighting when the new "find current outline item"-functionality is used seemed inconsistent.

---
[1] Keep in mind that the `outline` itself already isn't fetched/parsed until at least *one* page has been rendered in the viewer.

[2] And also quite slow, since it can take a fair amount of time to fetch all of the necessary `destinations` data when `disableAutoFetch = true` is set.
2021-01-09 16:09:44 +01:00
Jonas Jenwald
373230185a Unconditionally initialize the this._pageOpenPendingSet in BaseViewer._initializeScriptingEvents (PR 12747 follow-up)
With the code dispatching a "pageopen" event on the existing (general) `BaseViewer` event "pagesinit", in practice this means that the `Set` is always being created. Hence we can simplify the method overall, by always initializing the `this._pageOpenPendingSet` property.
2021-01-07 23:11:31 +01:00
Jonas Jenwald
32b0e00ba7 Don't dispatch "pageclose" events if a "pageopen" wasn't dispatched for the page (PR 12747 follow-up)
Given that "pageopen" events are not guaranteed to occur, if the page becomes inactive *before* it finishes rendering, we should probably also avoid dispatching a "pageclose" event in that case to avoid confusing/inconsistent state in any event handlers.
2021-01-07 23:11:31 +01:00
Tim van der Meij
ac5168a23f
Merge pull request #12822 from Snuffleupagus/scripting-contentLength
Improve the `PDFViewerApplication._contentLength` handling in the viewer, related mostly to scripting
2021-01-07 23:02:53 +01:00
Jonas Jenwald
7d3632d5d5 Improve the PDFViewerApplication._contentLength handling in the viewer, related mostly to scripting
Ensure that `PDFViewerApplication._contentLength` is always updated with the *correct* length, as returned by `PDFDocumentProxy.getDownloadInfo`, and only let the `PDFViewerApplication._initializeMetadata` method overwrite if it's not already been set.

Finally, in `PDFViewerApplication._initializeJavaScript`, the fallback `_contentLength` handling is now moved to just after the fallback `documentInfo` handling, such that all the fallback code is in one place within the method.
2021-01-07 10:33:48 +01:00
Calixte Denizet
6523f8880b JS -- Plug PageOpen and PageClose actions 2021-01-06 13:31:15 +01:00
Jonas Jenwald
94f1020769 Remove unnecessary dir-dependent CSS rules, and add a missing CSS variable (PR 11077 follow-up)
With the updated default viewer UI, a couple of `dir`-dependent CSS rules have now become redundant since *identical* rules are being specified for both LTR and RTL mode.

Furthermore, there's also some unnecessary re-defining of the `toolbarButton`/`secondaryToolbarButton`-icon related CSS rules.

Finally, for the toggle-buttons there's a particular styling applied to the `:hover:active` state, however the color wasn't defined with CSS variables.
2021-01-03 15:01:03 +01:00
Tim van der Meij
1810e65d96
Merge pull request #12804 from Snuffleupagus/DownloadManager-rm-onerror
Remove the `DownloadManager.onerror` functionality, since its only usage is unlikely to be helpful
2021-01-03 12:42:42 +01:00
Jonas Jenwald
5cb31a7ab6 Remove unnecessary toolbarButton icon-flipping in RTL mode (PR 11077 follow-up)
With the updated default viewer UI, a couple of the toolbarButton icons are now *vertically* symmetrical; hence we can remove some now unneeded `transform: scaleX(-1);` rules from the viewer CSS.
2021-01-02 14:04:31 +01:00
Jonas Jenwald
775d45b36a Remove the DownloadManager.onerror functionality, since its only usage is unlikely to be helpful
Note how the `onerror` functionality is not being used in the GENERIC `DownloadManager`, since we have no way of knowing if downloading succeeded.
Hence this functionality is only *possibly* useful in MOZCENTRAL builds, however as outlined in the existing comments it's unlikely to be helpful in practice. Generally speaking, if downloading failed once in [`PdfStreamConverter.jsm`](https://searchfox.org/mozilla-central/rev/809ac3660845fef6faf18ec210232fdadc0f1ad9/toolkit/components/pdfjs/content/PdfStreamConverter.jsm#294-406) it seems very likely that it would fail again; all-in-all I'm thus suggesting that we just remove the `onerror` functionality altogether here.
2021-01-02 13:25:42 +01:00
Jonas Jenwald
c4b95d925f Add a new helper method, on PDFViewerApplication, to determine the document filename
Currently this code is duplicated no less than three times in the `web/app.js` file, and by introducing a helper method we can avoid unnecessary repetition.
2021-01-02 12:37:08 +01:00
Jonas Jenwald
a49b3e04d5 Add a new FirefoxCom.requestAsync method, to simplify the code in web/firefoxcom.js
There's a fair number of cases where `FirefoxCom.request`-calls are manually wrapped in a Promise to make it asynchronous. We can reduce the amount of boilerplate code in these cases by introducing a new `FirefoxCom.requestAsync` method instead.

Furthermore, a couple of `FirefoxCom.request`-calls in the `DownloadManager` are also changed to be asynchronous rather than using callback-functions.
With this patch, we're thus able to replace a lot of *direct* usages of `FirefoxCom.request` with the new `FirefoxCom.requestAsync` method instead.
2021-01-01 15:39:26 +01:00
Jonas Jenwald
0caf72d5bd Convert FirefoxCom to a class, with static methods
*Please note:* It's highly recommended to ignore whitespace-only changes when looking at this patch.

Besides modernizing this code, by converting it to a standard class, the existing JSDoc comments are updated to actually agree better with the way that this functionality is used now. (The next patch will reduce usage of `FirefoxCom.request` significantly, hence the JSDocs for the optional `callback` is removed to not unnecessarily advertise that functionality.)

Finally, the unnecessary/unused `return` statement at the end of `FirefoxCom.request` is also removed.
2021-01-01 14:42:06 +01:00
Jonas Jenwald
8b3b542447 Ensure that the "pdf.js.response" event listener, in FirefoxCom.request, actually applies to the current Text node
Given that the event listener is registered on the document, there could in *theory* be more than one of these listeners present at any one time.
In practice this doesn't currently happen, since all of the `actions` invoked in [`PdfStreamConverter.jsm`](https://searchfox.org/mozilla-central/rev/bfbacfb6a4efd98247e83d3305e912ca4f7e106a/toolkit/components/pdfjs/content/PdfStreamConverter.jsm#933-952) are *synchronous* methods. However, there's no guarantee that this will always be the case, and it's easy enough to prevent any future issues here by simply registering the "pdf.js.response" event listener on the `Text` node instead. This works since, as can be seen in [`PdfStreamConverter.jsm`](https://searchfox.org/mozilla-central/rev/bfbacfb6a4efd98247e83d3305e912ca4f7e106a/toolkit/components/pdfjs/content/PdfStreamConverter.jsm#919,943), the event is dispatched on the element itself rather than the document.
2020-12-31 16:17:42 +01:00
Jonas Jenwald
99b1a62c97 Use remove, rather than removeChild, when removing the temporary Text nodes used in FirefoxCom
This is the "modern" way of removing a node from the DOM, which has the benefit of being a lot shorter and more concise.

Also, this patch removes the `return` statement from the "pdf.js.response" event listener, since it's always `undefined`, given that none of the `callback`-functions used here ever return anything (and don't need to either). Generally speaking, returning a value from an event listener isn't normally necessary either.
2020-12-31 14:47:39 +01:00
Jonas Jenwald
cc49b65a11 Use the once: true option, rather than manually removing the "pdf.js.response" event listener in FirefoxCom.request
When this code was originally added, the `once` option didn't exist yet.
2020-12-31 13:31:28 +01:00
Jonas Jenwald
11ec2b7530 Convert DefaultExternalServices.fallback to an asynchronous method
This method currently accepts a callback-function, which does feel a bit old fashioned now. At the time that this code was introduced, native Promises didn't exist yet and there's a custom Promise-implementation used instead.

However, today with Promises and async/await being used *a lot* it seems reasonable to change `DefaultExternalServices.fallback` to an `async` method instead such that the callback-function can be removed.
2020-12-30 20:48:40 +01:00
Jonas Jenwald
03f10739d8 Extract common functionality into a new BaseTreeViewer._finishRendering method
Note how the end of the `{PDFOutlineViewer, PDFAttachmentViewer, PDFLayerViewer}.render` methods share *almost* identical code, hence we can reduce some duplication by introducing the new `BaseTreeViewer` helper method here.

Furthermore, setting `this._lastToggleIsShow` can be made ever so slightly more efficient, since we don't care about the number of ".treeItemsHidden"-classes but only want to know if at least one exists.
2020-12-30 13:48:58 +01:00
Jonas Jenwald
739d7c6d77 Support the once option, when registering EventBus listeners
This follows the same principle as the `once` option that exists in the native `addEventListener` method, and will thus automatically remove an `EventBus` listener when it's invoked; see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Parameters

Finally, this patch also tweaks some the existing `EventBus`-code to use modern features such as optional chaining and logical assignment operators.
2020-12-29 16:49:13 +01:00
Jonas Jenwald
c185061757 Include the state in the "presentationmodechanged" event, and remove the separate active/switchInProgress properties
Given that we already have a `PresentationModeState`-enumeration, we should use that with the "presentationmodechanged" event rather than including separate properties. Note that this new behaviour, of including an enumeration-value in the event, is consistent with lots of other existing viewer-events.

To hopefully avoid issues in custom implementations of the default viewer, any attempt to access the removed properties will now throw.
2020-12-28 20:31:17 +01:00
Jonas Jenwald
e8b8020667 Remove unused .noResults CSS-rule
This CSS-rule was added all the way back in PR 1808, however it's been completely unused for years (I didn't bother finding out *exactly* when that happened). Looking at its only usage, see https://github.com/mozilla/pdf.js/pull/1808/files#diff-987d91686287a25ac2405baaf17b699a5fc1a176a53f8ea347a72ef486001f7bR795, it's already clear from the surrounding code that it's indeed unnecessary now.
2020-12-26 13:04:32 +01:00
calixteman
df53e7811c
Merge pull request #12773 from Snuffleupagus/move-sandboxBundleSrc
Pass in the "sandboxBundleSrc" option when calling `DefaultExternalServices.createScripting`
2020-12-24 02:50:04 -08:00
Jonas Jenwald
47ff3195e4 Pass in the "sandboxBundleSrc" option when calling DefaultExternalServices.createScripting
Similar to e.g. the "locale" option, this in *only* done for those build-targets where the "sandboxBundleSrc" is actually defined.
With these changes we can remove an `AppOptions` dependency from the `web/generic_scripting.js` file, thus limiting *direct* `AppOptions` usage in the default viewer files.
2020-12-23 14:05:49 +01:00
Jonas Jenwald
a4786c9689 [Scripting] Await manually triggered dispatchEventInSandbox calls in the viewer
Given that the `dispatchEventInSandbox` method (on the scripting-classes) is asynchronous, there's a very real risk that the events won't be dispatched/handled until *after* their associated functionality has actually run (with the "Will..." events being particularily susceptible to this issue).
To reduce the likelihood of that happening, we can simply `await` the `dispatchEventInSandbox` calls as necessary. A couple of methods are now marked as `async` to support these changes, however that shouldn't be a problem as far as I can tell.

*Please note:* Given that the browser "beforeprint"/"afterprint" events are *synchronous*, we unfortunately cannot await the `WillPrint`/`DidPrint` event dispatching. To fix this properly the web-platform would need support for asynchronous printing, and we'll thus have to hope that things work correctly anyway.
2020-12-23 12:03:21 +01:00
Jonas Jenwald
0daf51c340 [Scripting] Try to ensure that the WillPrint/DidPrint respectively DidSave events are always dispatched
Note that currently the `DidSave` event is not *guaranteed* to actually be dispatched if there's any errors during saving, which is easily fixed by simply moving it to occur in the `finally`-handler in `PDFViewerApplication.save` method.

For the `WillPrint`/`DidPrint` events, things are unfortunately more complicated. Currently these events will *only* be dispatched iff the printing request comes from within the viewer itself (e.g. by the user clicking on the "Print" toolbar button), however printing can be triggered in a few additional ways:
 - In the GENERIC viewer:
   - By the <kbd>Ctrl</kbd>+<kbd>P</kbd> keyboard shortcut.
 - In the MOZCENTRAL viewer, i.e. the Firefox built-in viewer:
   - By the <kbd>Ctrl</kbd>+<kbd>P</kbd> keyboard shortcut.
   - By the "Print" item, as found in either the Firefox "Hamburger menu" or in the browser-window menu.

In either of the cases described above, no `WillPrint`/`DidPrint` events will be dispatched. In order to *guarantee* that things work in the general case, we thus have to move the `dispatchEventInSandbox` calls to the "beforeprint"/"afterprint" event handlers instead.
2020-12-23 11:52:56 +01:00
Jonas Jenwald
7bab8350c0 Avoid the getJavaScript API-call in PDFViewerApplication._initializeAutoPrint when "enableScripting" is set
Rather than calling `getJavaScript` in the API and then ignoring the result, when "enableScripting" is set, it should be more efficient/faster to simply skip it altogether instead.

Finally, the `setTimeout` call at the end of `PDFViewerApplication._initializeAutoPrint` is removed, since it doesn't seem necessary any more as far as I can tell.[1]
Note that when this functionality was originally added, back in PR 2839, it seems that `pagesPromise` simply waited for the `getPage` calls of *all* pages to resolve. Today, on the other hand, the viewer fetches *and* renders the first page *before* doing the remaining `getPage` calls, and only afterwards is `pagesPromise` resolved. Hence it's not really clear why we now need to delay printing even further with a `setTimeout` call.

---
[1] The patch was tested with the following documents: https://github.com/mozilla/pdf.js/blob/master/test/pdfs/bug1001080.pdf and https://github.com/mozilla/pdf.js/blob/master/test/pdfs/issue6106.pdf
2020-12-21 12:08:17 +01:00
Tim van der Meij
1c8ead133a
Merge pull request #12758 from Snuffleupagus/AnnotationStorage-rm-event
Run `AnnotationStorage.resetModified` when destroying the `PDFDocumentLoadingTask`/`PDFDocumentProxy`
2020-12-19 21:13:28 +01:00
Jonas Jenwald
517af6b6ab Delay initialization of the AnnotationStorage callbacks slightly in the default viewer
These callbacks should not be necessary *before* the document has been initialized. Furthermore, move the functionality to a new helper-method since `PDFViewerApplication.load` is already quite large.
2020-12-19 13:06:32 +01:00
Jonas Jenwald
958ea2be8b Move the functionality of the webViewerDownloadOrSave function into a new PDFViewerApplication method instead
Given that this relies on accessing properties on the `PDFDocumentProxy`-instance, it seems more appropriate for this code to live in `PDFViewerApplication`.
2020-12-19 12:38:10 +01:00
Jonas Jenwald
6f40f4e7c2 Remove the arbitrary timeout in the "must check that first text field has focus" integration-test (PR 12702 follow-up)
It seems that the timeout is way too short in practice, since this new integration-test failed *intermittently* already in PR 12702 (which is where the test was added).

The ideal solution here would be to simply await an event, dispatched by the viewer, however that unfortunately doesn't appear to be supported by Puppeteer.
Instead, the solution implemented here is to add a new method in `PDFViewerApplication` which Puppeteer can query to check if the scripting/sandbox has been fully initialized.
2020-12-19 09:32:58 +01:00
Jonas Jenwald
54f45dc935 Don't dispatch a "doc/Open" event in the sandbox when creating it failed
There's really no point, as far as I can tell, to attempt to dispatch an event in a non-existent sandbox. Generally speaking, even trying to do this *could* possibly even lead to errors in some cases.

Furthermore, utilize optional chaining to simplify some `dispatchEventInSandbox` calls throughout the viewer.

Finally, replace superfluous `return` statements with `break` in the switch-statement in the `updateFromSandbox` event-handler.
2020-12-19 09:13:12 +01:00
Jonas Jenwald
c78f153bda Remove the ENABLE_SCRIPTING build-target, since it's not necessary
There's no really compelling reason, as far as I can tell, to introduce the `ENABLE_SCRIPTING` build-target, instead of simply re-using the existing `TESTING` build-target for the new `gulp integrationtest` task.

In general there should be no problem with just always enable scripting in TESTING-builds, and if I were to *guess* the reason that this didn't seem to work was most likely because the Preferences ended up over-writing the `AppOptions`.
As it turns out the GENERIC-viewer has already has built-in support for disabling of Preferences, via the `AppOptions`, and this can be utilized in TESTING-builds as well to ensure that whatever `AppOptions` are set they're always respected.
2020-12-18 22:10:36 +01:00
Jonas Jenwald
eff4d8182d Update the events, used with scripting, to use lower-case names and avoid using DOM events internally in the viewer
For DOM events all event names are lower-case, and the newly added PDF.js scripting-events thus "stick out" quite a bit. Even more so, considering that our internal `eventBus`-events follow the same naming convention.
Hence this patch, which changes the "updateFromSandbox"/"dispatchEventInSandbox" events to be lower-case instead.

Furthermore, using DOM events for communication *within* the PDF.js code itself (i.e. between code in `web/app.js` and `src/display/annotation_layer.js/`) feels *really* out of place.
That's exactly the reason that we have the `EventBus` abstraction, since it allowed us to remove prior use of DOM events, and this patch thus re-factors the code to make use of the `EventBus` instead for scripting-related events.
Obviously for events targeting a *specific element* using DOM events is still fine, but the "updatefromsandbox"/"dispatcheventinsandbox" ones should be using the `EventBus` internally.

*Drive-by change:* Use the `BaseViewer.currentScaleValue` setter unconditionally in `PDFViewerApplication._initializeJavaScript`, since it accepts either a string or a number.
2020-12-18 22:10:32 +01:00
Jonas Jenwald
6dc39cb873 Tweak the new mouseState parameter, and its usage, in the viewer components and the AnnotationLayer
- Actually remove the `isDown` property when destroying the scripting-instance.

 - Mark all `mouseState` usage as "private" in the various classes.

 - Ensure that the `AnnotationLayer` actually treats the parameter as properly *optional*, the same way that the viewer components do.

 - For now remove the `mouseState` parameter from the `PDFPageView` class, and keep it only on the `BaseViewer`, since it's questionable if all of the scripting-functionality will work all that well without e.g. a full `BaseViewer`.

 - Append the `mouseState` to the JSDoc for the `AnnotationElement` class, and just move its definition into the base-`AnnotationElement` class.
2020-12-18 22:03:41 +01:00
calixteman
e6e2809825
Merge pull request #12702 from calixteman/doc_actions
JS - Collect and execute actions at doc level
2020-12-18 21:33:32 +01:00
Tim van der Meij
6efd350993
Merge pull request #12747 from Snuffleupagus/pageopen-pageclose
Add new "pageopen"/"pageclose" events for usage with JavaScript actions
2020-12-18 21:31:20 +01:00
Calixte Denizet
1e2173f038 JS - Collect and execute actions at doc and pages level
* the goal is to execute actions like Open or OpenAction
 * can be tested with issue6106.pdf (auto-print)
 * once #12701 is merged, we can add page actions
2020-12-18 20:03:59 +01:00
Calixte Denizet
4ae9064d60 Dispatch an event on sandbox creation
* the goal is to be able to know when the sandbox is ready for mochitest in m-c
2020-12-18 19:12:43 +01:00
Jonas Jenwald
0e69973d71 Add a new "pagesdestroy" event, dispatched *before* the BaseViewer removes an existing document
This new event essentially mirrors the existing "pagesinit" event, and will allow e.g. a custom implementation of the viewer to be notified before the current PDF document is removed from the viewer.

By using this new event, we're thus able to dispatch a "pageclose" event for JavaScript actions when closing the existing document.
2020-12-17 15:26:20 +01:00
Jonas Jenwald
2a83c965e8 Add new "pageopen"/"pageclose" events for usage with JavaScript actions
Having looked at the Acrobat JavaScript specification, see https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/AcrobatDC_js_api_reference.pdf#G5.1963437, I suppose that introducing these two new events is probably the easiest solution overall.

However there's a number of things that, as far as I'm concerned, will help the overall implementation:
 - Only dispatch these new events when `enableScripting = true` is set.
 - Handle them *separately* from the existing "pagechanging" event dispatching, to avoid too much clutter.
 - Don't dispatch either of the events if the page didn't actually change.
 - When waiting for pages to render, don't dispatch "pageopen" if the page is no longer active when rendering finishes.
 - Ensure that we only use *one* "pagerendered" event listener.
 - Ensure that "pageopen" is actually dispatched when the document loads.

I suppose that we *could* avoid adding the "pageclose" event, and use the existing "pagechanging" event instead, however having a separate event might allow more flexibility in the future. (E.g. I don't know if we'll possibly want to dispatch "pageclose" on document close, as mentioned briefly in the specification.)
2020-12-17 15:26:20 +01:00
Calixte Denizet
8bff4f1ea9 In order to simplify m-c code, move some in pdf.js
* move set/clear|Timeout/Interval and crackURL code in pdf.js
 * remove the "backdoor" in the proxy (used to dispatch event) and so return the dispatch function in the initializer
 * remove listeners if an error occured during sandbox initialization
 * add support for alert and prompt in the sandbox
 * add a function to eval in the global scope
2020-12-17 15:03:26 +01:00
Calixte Denizet
6502ae889d JS -- Send events to the sandbox from annotation layer 2020-12-15 16:28:47 +01:00
Tim van der Meij
a825b9195b
Merge pull request #12700 from calixteman/12699
Fix automatic zoom under spread mode
2020-12-14 23:39:48 +01:00
Calixte Denizet
785487c558 Fix automatic zoom under spread mode (#12699)
Reset scale when update spread mode
2020-12-14 17:57:00 +01:00
Brendan Dahl
31ea30ab25
Merge pull request #12668 from calixteman/interaction
Add some integration tests using puppeteer
2020-12-10 12:52:03 -08:00
Calixte Denizet
5b42ac364a Add some integration tests using puppeteer and Jasmine
* run with `gulp integrationtest`
2020-12-10 20:55:15 +01:00
Tim van der Meij
93b3ba2abb
Merge pull request #12712 from Snuffleupagus/issue-12704
Attempt to handle collapsed outline items, in the default viewer, according to the specification (issue 12704, PR 10890 follow-up)
2020-12-09 23:43:07 +01:00
Jonas Jenwald
6218b9a512 Re-factor/re-name the scripting getter, on the externalServices-implementations, to a createScripting method
Given that the GENERIC default viewer supports opening more than one document, and that a unique scripting-instance is now used for each document, the changes made in this patch seem appropriate.
2020-12-09 22:15:50 +01:00
Jonas Jenwald
a7230eb033 Move the GenericScripting class to its own file, such that it can be used in the Chromium-extension
While it's not entirely clear to me that it's ultimately desirable to use the `pdf.sandbox.js` in the Chromium-extension, given that the MOZCENTRAL-build uses `pdf.scripting.js` directly in a *custom* sandbox, the current state isn't that great since setting `enableScripting = true` with the Chromium-extension will currently fail completely.

Hence this patch, which should at least unbreak things for now.
2020-12-09 22:15:50 +01:00
Jonas Jenwald
6c807f3f86 Move destroying of the scripting-instance from PDFViewerApplication.close and into its own helper method
Since the `close` method has become quite large, this small re-factoring shouldn't hurt (and may also be useful with future changes to the `_initializeJavaScript` method).
2020-12-09 22:15:50 +01:00
Jonas Jenwald
8d72981c18 Move cancelling of idleCallbacks from PDFViewerApplication.close and into its own helper method
Since the `close` method has become quite large, this small re-factoring shouldn't hurt.
2020-12-09 22:15:50 +01:00
Jonas Jenwald
7ce6634c51 Ensure that the pdf.sandbox.js scriptElement is also removed from the DOM (PR 12695 follow-up)
I completely missed this previously, but we obviously should remove the scriptElement as well to *really* clean-up everything properly.

Given that there's multiple existing usages of `loadScript` in the code-base, the safest/quickest solution seemed to be to have call-sites opt-in to remove the scriptElement using a new parameter.
2020-12-09 22:15:47 +01:00
Jonas Jenwald
09f79ffa92 Attempt to handle collapsed outline items, in the default viewer, according to the specification (issue 12704, PR 10890 follow-up)
This patch *attempts* to actually implement what's described for the `Count`-entry in the PDF specification, see https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/PDF32000_2008.pdf#G11.2095911, which I mostly ignored back in PR 10890 since it seemed unnecessarily complicated[1].

Besides issue 12704, I've also tested a couple of other documents (e.g. the PDF specification) and these changes don't *seem* to break anything else; additional testing would be helpful though!

---
[1] At the time, all PDF documents that I tested worked even with a very simple approach and I thus hoped that it'd would suffice.
2020-12-09 20:48:36 +01:00
Jonas Jenwald
b2dfb55136 Re-factor the scripting getter in GENERIC-builds, since using the same sandbox for *multiple* PDF documents seems highly questionable
Similar to the previous patch, the GENERIC default viewer is capable of opening more than *one* PDF document and we should ensure that we handle that case correctly.
2020-12-06 14:21:49 +01:00
Jonas Jenwald
1e007f9285 Actually remove a scripting-instance, and its global events, upon document closing
I was actually quite surprised to find that, despite the various `scripting`-getters implementing `destroySandbox` methods, there were no attempts at actually cleaning-up either the "sandbox" or removing the globally registered event listeners.
2020-12-06 14:20:43 +01:00
Jonas Jenwald
f4d8a427f0 Ensure that the *correct* PDF document is still active after *every* asynchronous API-call in PDFViewerApplication._initializeJavaScript
This patch also changes the method to skip *all* data fetching when "enableScripting" isn't active. Finally, simplifies some event-data accesses in the "updateFromSandbox" listener.
2020-12-06 14:18:10 +01:00
Jonas Jenwald
1f2f8c907b Tweak the "filesize" handling in PDFViewerApplication._initializeJavaScript
Another possible option here could be to use the `contentLength`, when it exists, and then using e.g. a custom event to always update the "filesize" in the sandbox "after the fact" with the result of the `getDownloadInfo`-call.
2020-12-06 13:08:36 +01:00
Jonas Jenwald
bfdb39a1e6 Stop re-fetching the metadata unconditionally in PDFViewerApplication._initializeJavaScript
We can easily avoid unnecessary API-calls here, since most of the time the `metadata` will already be available here. In the *rare* case that it's not available, we can simply wait for the existing `getMetadata`-call to resolve.
2020-12-06 12:42:56 +01:00
Jonas Jenwald
f8ea83609f Dispatch a metadataloaded event once the PDFViewerApplication._initializeMetadata method is done
This will be useful in the following patch, and note that there's also an old issue (see 5765) which asked for such an event. However, given that the use-case wasn't *clearly* specified, and that we didn't have an internal use for it at the time it wasn't implemented.

Also, ensure that all of the metadata-related properties are actually reset when the document is closed.
2020-12-06 12:30:33 +01:00
Jonas Jenwald
c39f1aedb2 Re-implement working dev-sandbox/watch-dev-sandbox gulp-tasks
Compared to the, previously removed, `sandbox`/`watch-sandbox` gulp-tasks, these ones should work even when run against an non-existent/empty `build`-folder.

Also, to ensure that the development viewer actually works out-of-the-box, `gulp server` will now also include `gulp watch-dev-sandbox` to remove the need to *manually* invoke the build-tasks.

Finally, this patch also removes the `web/devcom.js` file since it shouldn't actually be needed, assuming that the "sandbox"-loading code in the `web/genericcom.js` file is actually *correctly* implemented.
2020-12-05 23:04:34 +01:00
Tim van der Meij
a618b02e62
Merge pull request #12682 from Snuffleupagus/findbar-notFound
[Generic viewer] Re-factor how the `notFound` appearance is set on the "findInput" in the `PDFFindBar`
2020-12-02 22:00:41 +01:00
Jonas Jenwald
313ee28436 [Generic viewer] Re-factor how the notFound appearance is set on the "findInput" in the PDFFindBar
Rather than having two slightly different ways of setting the pending/notFound appearance on the "findInput", we can simply use "data-status" in both cases since they're obviously mutually exclusive.
2020-12-02 15:23:20 +01:00
Jonas Jenwald
488a81a7bc Fix the treeitem-expanded/treeitem-collapsed images in dark-mode (PR 12666 follow-up)
I completely missed updating these in PR 12666; sorry about that!
2020-12-02 11:48:32 +01:00
Brendan Dahl
956fcab967
Merge pull request #12631 from calixteman/app
JS -- Implement app object
2020-12-01 16:50:16 -08:00
Jonas Jenwald
f2ec546cbb Use the same SVG images, in the default viewer, regardless of the CSS theme
As mentioned in https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions#faq-support, PDF.js version `2.6.347` is the last release with IE 11/Edge support.
Hence we should now be able to reduce unnecessary duplication in the default viewer image resources, note the files in the `web/images/` folder with a `-dark` suffix, by using only *one* SVG-image for each icon and letting the `background-color` depend on the CSS theme instead.

For the `gulp mozcentral` build-target, the resulting `web/images/` folder is reduced from `43 997` to `28 566` bytes (~35 percent).

*Please note:* I don't really know if this implementation is necessarily the *best* solution, but it seems to work well enough in e.g. Firefox Nightly and Google Chrome Beta as far as my testing goes.
2020-12-01 11:45:09 +01:00
Jonas Jenwald
4615815cc7 Convert the PDFDocumentProperties.open method to be async
By using `await`, rather than chaining promises, this method becomes more compact and slightly easier to reason about (at least in my opinion).
2020-11-21 13:54:36 +01:00
Calixte Denizet
283aac4c53 JS -- Implement app object
* https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/AcrobatDC_js_api_reference.pdf
 * Add color, fullscreen objects + few constants.
2020-11-20 15:46:52 +01:00
Jonas Jenwald
01d12b465c [api-minor] Add "contentLength" to the information returned by the getMetadata method
Given that we already include the "Content-Disposition"-header filename, when it exists, it shouldn't hurt to also include the information from the "Content-Length"-header.
For PDF documents opened via a URL, which should be a very common way for the PDF.js library to be used, this will[1] thus provide a way of getting the PDF filesize without having to wait for the `getDownloadInfo`-promise to resolve[2].

With these API improvements, we can also simplify the filesize handling in the `PDFDocumentProperties` class.

---
[1] Assuming that the server is correctly configured, of course.

[2] Since that's not *guaranteed* to happen in general, with e.g. `disableAutoFetch = true` set.
2020-11-20 15:30:36 +01:00
Calixte Denizet
c7974e9996 JS -- Add a sandbox based on quickjs
* quickjs-eval.js has been generated using https://github.com/mozilla/pdf.js.quickjs/
 * lazy load of sandbox code
 * Rewrite tests to use the sandbox
 * Add a task `watch-sandbox` which update bundle pdf.sandbox.js on change in the sandbox code
2020-11-19 13:40:46 +01:00
Jonas Jenwald
cc861c34e9 Add an AppOptions.setAll method, and use it in PDFViewerApplication._readPreferences
Given that it's generally faster to call *one* function and have it loop through an object, rather than looping through an object and calling a function for every iteration, this patch will reduce the total time spent in `PDFViewerApplication._readPreferences` ever so slightly.
Also, over time we've been adding more and more preferences, rather than removing them, so using the new `AppOptions.setAll` method should be generally beneficial as well.

While the effect of these changes is quite small, it does reduces the time it takes for the preferences to be fully initialized. Given the amount of asynchronous code during viewer initialization, every bit of time that we can save should thus help.
Especially considering the recently added `viewerCssTheme` preference, which needs to be read very early to reduce the risk of the viewer UI "flashing" visibly as the theme changes, I figured that a couple of small patches reducing the time spend reading preferences cannot hurt.
2020-11-18 12:10:21 +01:00
Jonas Jenwald
4886a7cf69 Skip Promise.all in PDFViewerApplication._parseHashParameters unless actually necessary
Given that only two debugging hash parameters (i.e. `disableWorker` and `pdfBug`) will make this method asynchronous, we can avoid what's most of the time is an unnecessary `Promise.all` invocation.
2020-11-18 11:45:18 +01:00
Tim van der Meij
a06f487bd4
Merge pull request #12630 from Snuffleupagus/BasePreferences-less-async
Reduce, now unnecessary, asynchronicity in the `BasePreferences` constructor
2020-11-17 00:07:06 +01:00
Jonas Jenwald
40a4d53fb3 Add a new preference, viewerCssTheme, to allow forcing the use of the light/dark viewer CSS themes (issue 12290)
While this does work pretty well in my quick testing, it's *very much* a hack since as far as I can tell there's no support in the CSS specification for using e.g. a CSS variable to override a `@media (prefers-color-scheme: dark) {...}` block.

The solution implemented here is thus to *edit* the viewer CSS, by either removing the entire `@media ...` block in light-mode or by ensuring that its rules become *unconditionally* applied in dark-mode.
To simplify the overall implementation, since all of this does seem like somewhat of an edge-case, the `viewerCssTheme` preference will *only* be read during viewer initialization. (Similar to many other existing preferences, a reload is thus required when changing it.)
2020-11-16 21:13:13 +01:00
Brendan Dahl
f39d87bff1
Merge pull request #12569 from calixteman/events
JS -- Fix events dispatchment and add tests
2020-11-16 10:26:29 -08:00
Jonas Jenwald
7adcb90a2d Reduce, now unnecessary, asynchronicity in the BasePreferences constructor
Originally the default preferences were defined in a JSON-file checked into the repository, which was loaded using SystemJS in development mode.
Over the years a number of changes have been made to this code, most notably:
 - The preferences JSON-file is now generated automatically, during building, from the `AppOptions` abstraction.
 - All SystemJS usage has been removed from the development viewer.

Hence the default preferences are now available *synchronously* even in the development viewer, and it's thus no longer necessary to defer to the microtask queue (since `getDefaultPreferences` is async) just to get the default preferences.

While the effect of these changes is quite small, it *does* reduces the time it takes for the preferences to be fully initialized. Given the amount of asynchronous code during viewer initialization, every bit of time that we can save should thus help.
2020-11-16 14:19:54 +01:00
Tim van der Meij
2aefc406b4
Merge pull request #12622 from Snuffleupagus/hasJSActions-cleanup
Some `hasJSActions`, and general annotation-code, related cleanup in the viewer and API
2020-11-14 17:04:15 +01:00
Tim van der Meij
1bf640bb86
Merge pull request #12618 from Snuffleupagus/thumbnails-render-transform
Ensure that rendering of thumbnails work correctly on HiDPI displays (issue 9820)
2020-11-14 16:32:09 +01:00
Jonas Jenwald
de628cec59 Some hasJSActions, and general annotation-code, related cleanup in the viewer and API
- Add support for logical assignment operators, i.e. `&&=`, `||=`, and `??=`, with a Babel-plugin. Given that these required incrementing the ECMAScript version in the ESLint and Acorn configurations, and that platform/browser support is still fairly limited, always transpiling them seems appropriate for now.

 - Cache the `hasJSActions` promise in the API, similar to the existing `getAnnotations` caching. With this implemented, the lookup should now be cheap enough that it can be called unconditionally in the viewer.

 - Slightly improve cleanup of resources when destroying the `WorkerTransport`.

 - Remove the `annotationStorage`-property from the `PDFPageView` constructor, since it's not necessary and also brings it more inline with the `BaseViewer`.

 - Update the `BaseViewer.createAnnotationLayerBuilder` method to actaually agree with the `IPDFAnnotationLayerFactory` interface.[1]

 - Slightly tweak a couple of JSDoc comments.

---
[1] We probably ought to re-factor both the `IPDFTextLayerFactory` and `IPDFAnnotationLayerFactory` interfaces to take parameter objects instead, since especially the `IPDFAnnotationLayerFactory` one is becoming quite unwieldy. Given that that would likely be a breaking change for any custom viewer-components implementation, this probably requires careful deprecation.
2020-11-14 13:58:35 +01:00
Jonas Jenwald
2e551acc8d Ensure that rendering of thumbnails work correctly on HiDPI displays (issue 9820)
*Note that I wasn't able to reproduce the issue in Firefox, but only in Chromium-browsers.*

The bug, and it's feels almost trivial once you've found it, is that we're not passing the `transform` parameter as intended to `PDFPageProxy.render` when drawing thumbnails on HiDPI displays. Instead the canvas context is, for reasons that I don't even pretent to understand, *manually* scaled in `PDFThumbnailView._getPageDrawContext`, which thus doesn't guarantee that the `baseTransform` property on the `CanvasGraphics`-instances becomes correct.

The solution is really simple though, just handle the `transform` the same way in `PDFThumbnailView.draw` as in `PDFPageView.paintOnCanvas` and things should just work.
2020-11-13 17:12:36 +01:00
Jonas Jenwald
1a22836dcb Improve the cleanup functionality for thumbnails
*This is a pre-existing issue that I noticed while working on PR 12613, and fixing this also brings the thumbnail code inline with the page code.*

Given the intermittent nature of all of this, it's somewhat difficult to reproduce it consistently; however the following steps should at least provide an outline:
 1. Open the sidebar, and the thumbnailView, and start scrolling around.
 2. *Quickly* close the sidebar, so that all thumbnails won't have time to finish rendering.
 3. Either wait for the cleanup-timeout to occur, or simply run `PDFViewerApplication.cleanup()` in the console.

What *intermittently* happens here is that `WorkerTransport.startCleanup` rejects, and consequently that cleanup doesn't complete as intended, since some of the thumbnails are left in a *pending* renderingState[1].
Fixing this is simple though, and only requires updating `PDFThumbnailViewer.cleanup` along the lines of `BaseViewer.cleanup`.

---
[1] Keep in mind that thumbnails will *only* render when the thumbnailView is visible, to reduce resource usage.
2020-11-13 13:31:01 +01:00
Jonas Jenwald
4a9994b54c Trigger cleanup, once rendering has finished, in PDFThumbnailView.draw
This patch will help reduce memory usage, especially for longer documents, when the user scrolls around in the thumbnailView (in the sidebar).

Note how the `PDFPageProxy.cleanup` method will, assuming it's safe to do so, release main-thread resources associated with the page. These include things such as e.g. image data (which can be arbitrarily large), and also the operatorList (which can also be quite large).
Hence when pages are evicted from the `PDFPageViewBuffer`, on the `BaseViewer`-instance, the `PDFPageView.destroy` method is invoked which will (among other things) call `PDFPageProxy.cleanup` in the API.

However, looking at the `PDFThumbnailViewer`/`PDFThumbnailView` classes you'll notice that there's no attempt to ever call `PDFPageProxy.cleanup`, which implies that in certain circumstances we'll essentially keep all resources allocated permanently on the `PDFPageProxy`-instances in the API.
In particular, this happens when the users opens the sidebar and starts scrolling around in the thumbnails. Generally speaking you obviously need to keep all thumbnail *images* around, since otherwise the thumbnailView is useless, but there's still room for improvement here.

Please note that the case where a *rendered page* is used to create the thumbnail is (obviously) completely unaffected by the issues described above, and this rather only applies to thumbnails being explicitly rendered by the `PDFThumbnailView.draw` method.
For the latter case, we can fix these issues simply by calling `PDFPageProxy.cleanup` once rendering has finished. To prevent *accidentally* pulling the rug out from under `PDFPageViewBuffer` in the viewer, which expects data to be available, this required adding a couple of new methods[1] to enable checking that it's indeed safe to call `PDFPageProxy.cleanup` from the `PDFThumbnailView.draw` method.

It's really quite fascinating that no one has noticed this issue before, since it's been around since basically "forever".

---
[1] While it should be *very* rare for `PDFThumbnailView.draw` to be called for a pageView that's also in the `PDFPageViewBuffer`, given that pages are rendered before thumbnails and that the *rendered page* is used to create the thumbnail, it can still happen since rendering is asynchronous.
Furthermore, it's also possible for `PDFThumbnailView.setImage` to be disabled, in which case checking the `PDFPageViewBuffer` for active pageViews *really* matters.
2020-11-12 17:09:47 +01:00
Jonas Jenwald
8b5bc8d7f9 Improve the pageNumber validation in BaseViewer.isPageVisible (PR 10217 follow-up) 2020-11-12 15:24:36 +01:00
Calixte Denizet
2dfac4cb41 JS -- Fix events dispatchment and add tests
* dispatch event to take into account calculation order
 * use a map for actions in Field
2020-11-10 17:26:29 +01:00
Calixte Denizet
8de98079ca JS -- Implement doc object
* https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/js_api_reference.pdf#page=335
 * it has all the properties/methods defined in the spec
 * unimplemented methods are there but with an empty body to avoid exception when calling an undefined method
 * implement zoom, zoomType, layout, pageNum, ...
2020-11-10 16:16:42 +01:00
Calixte Denizet
a5279897a7 JS -- Add listener for sandbox events only if there are some actions
* When no actions then set it to null instead of empty object
* Even if a field has no actions, it needs to listen to events from the sandbox in order to be updated if an action changes something in it.
2020-11-09 18:37:59 +01:00
Jonas Jenwald
9602844368 Enable the ESLint no-useless-escape rule (PR 12551 follow-up)
Note that a number of these cases are covered by existing unit-tests, and a few others only matter for the development/build scripts.
Furthermore, I've also tried to the best of my ability to test each case *manually* to hopefully further reduce the likelihood of this patch introducing any bugs.

Please find additional details about the ESLint rule at https://eslint.org/docs/rules/no-useless-escape
2020-11-07 13:06:24 +01:00
Jonas Jenwald
ba761e42f0 Change the getVisibleElements helper function to take a parameter object
Given the number of parameters, and the fact that many of them are booleans, the call-sites are no longer particularly easy to read and understand. Furthermore, this slightly improves the formatting of the JSDoc-comment, since it needed updating as part of these changes anyway.

Finally, this removes an unnecessary `numViews === 0` check from `getVisibleElements`, since that should be *very* rare and more importantly that the `binarySearchFirstItem` function already has a fast-path for that particular case.
2020-11-04 12:15:04 +01:00
Jonas Jenwald
322b1072af Use optional chaining in web/pdf_history.js
Since we're now free to use e.g. optional chaining everywhere *except* for the worker, we can thus simplify this code a bit.
2020-11-02 11:36:17 +01:00
Jonas Jenwald
911948c5c0 Also update the browser history when the user *manually* change pages using the pageNumber-input (PR 12493 follow-up)
This patch addresses a review comment, which pointed out that we should *also* handle the pageNumber-input, from PR 12493.

Given that a user *manually* changing pages using the pageNumber-input, on the toolbar, could be regarded as a pretty strong indication of user-intent w.r.t. navigation in the document, hence I suppose that updating the browser history in this case as well probably won't hurt.
2020-11-01 15:37:24 +01:00
Jonas Jenwald
4eaa058c16 Add early returns to a couple of PDFLinkService methods, when there's no active PDF document
All of these methods will, in one way or another, cause e.g. scrolling or zooming to occur and consequently they don't really make sense unless there's an active PDF document. Especially since all of these methods end up calling into a `BaseViewer`-instance, which already contains similar early returns in essentially all of it's methods and setters.
2020-11-01 15:37:24 +01:00
Jonas Jenwald
a177afc206 Fix some static static analyzer warnings (issue 11965)
This fixes only those warnings, as reported by https://lgtm.com/projects/g/mozilla/pdf.js?mode=list, that make sense (as far as I'm concerned).

Hence this patch leaves the following things unaddressed:
 - The "recommendation"-category, since it only complains about unused variables. However, note that all of those cases are purposely included and that there's thus ESLint-disable comments added to explictly allow them.
 - The "warning"-category, which still contains two complaints. However, as far as I can tell, they are both false positives.

Given first of all the false positives of the LGTM static analyzer, and secondly that we'd need to add (essentially duplicated) disable-comments for the unused variable cases, it's not entirely clear to me if we actually want to work towards including LGTM in the PDF.js project (e.g. running alongside Travis) or if we should just close issue 11965.
2020-11-01 12:08:38 +01:00
Tim van der Meij
e341e6e542
Merge pull request #12525 from brendandahl/mark-info
[api-minor] Implement API to get MarkInfo from the catalog.
2020-10-31 00:05:19 +01:00
Brendan Dahl
8a8b4f9697 Collect telemetry in the viewer on whether a PDF is tagged. 2020-10-30 10:59:45 -07:00
Jonas Jenwald
62b19f7e9a Ensure that the same version of PDF.js is used in both the API and the Viewer (PR 8959 follow-up)
Given that we're now accessing certain API-functionality *directly* in this file, e.g. the AnnotationStorage and Optional Content configuration, ensuring that there's not a version mismatch definitely seem like a good idea to prevent any *subtle* future bugs.
2020-10-27 17:09:42 +01:00
Jonas Jenwald
d9084c0be2 Load the fake worker, in non-PRODUCTION mode, with native async import
This removes the last SystemJS usage from both the API and the default viewer.
2020-10-26 11:11:48 +01:00
Tim van der Meij
0d1a874358
Merge pull request #12464 from baloone/Fix_getVisibleElements_in_rtl_direction
Fix getVisibleElements helper in RTL-locales
2020-10-24 17:03:57 +02:00
Tim van der Meij
e8e029dfb5
Merge pull request #12522 from Snuffleupagus/_initializeJavaScript-fixes
Fix a couple of edge-cases in `PDFViewerApplication._initializeJavaScript` (PR 12432 follow-up)
2020-10-24 16:11:06 +02:00
Jonas Jenwald
9f8d9802f9 A couple of small (viewer) tweaks of tooltip-only Annotations (PR 12333 follow-up)
Ensure that these tooltip-only Annotations are handled as "internalLink"s, to ensure that they behave as expected in PresentationMode (e.g. they should still use a `pointer`-cursor).

Ensure that `PDFLinkService.getDestinationHash` won't create links with empty hashes, since those don't really make a lot of sense in general (this improves things for tooltip-only Annotations).

This PDF file can be used for testing: http://mirrors.ctan.org/macros/latex/contrib/pdfcomment/doc/pdfcomment.pdf#page=14
2020-10-23 14:31:45 +02:00
Jonas Jenwald
7bf9a872ed Fix a couple of edge-cases in PDFViewerApplication._initializeJavaScript (PR 12432 follow-up)
- Return early in `PDFViewerApplication._initializeJavaScript` for PDF documents without any `fieldObjects`, which is the vast majority of all documents, to prevent errors when trying to parse a non-existent object.

 - Similar to the other `PDFViewerApplication._initialize*` methods, ignore the `fieldObjects` if the document was closed before the data resolved.

 - Fix the JSDoc comment for the `generateRandomStringForSandbox` helper function, since there's currently a bit too much copy-and-paste going on :-)

 - Change `FirefoxScripting` to a class with static methods, which is consistent with the surrounding code in `web/firefoxcom.js`.
2020-10-23 12:28:44 +02:00
Brendan Dahl
1eaf9c961b
Merge pull request #12432 from calixteman/scripting_api
JS - Add the basic architecture to be able to execute embedded js
2020-10-22 19:57:58 -07:00
Calixte Denizet
e76a96892a JS - Add the basic architecture to be able to execute embedded js 2020-10-21 19:00:56 +02:00
Mohamed
b7b048e36c Fix getVisibleElements helper in RTL-locales 2020-10-20 23:34:09 +02:00
Jonas Jenwald
b302fd3a6e Move updating of this._maxUid into PDFHistory._updateInternalState
There's no compelling reason to update this property *manually* in multiple places, since that's error-prone with any future code changes, given that `_updateInternalState` is always called just before anyway.
2020-10-18 16:29:15 +02:00
Jonas Jenwald
295716f496 Support adding pages, in addition to regular destinations, to the browser history and use it with thumbnails (issue 12440)
While the referenced issue could very well be seen as an edge-case, this patch adds support for updating of the browser history when interacting with the thumbnails in the sidebar (assuming we want to do this).

The main reason for adding the history implementation in the first place, was to simplify navigating back to a previous position in the document when named/explicit destinations are used (e.g. when clicking on "links" or when using the outline in the sidebar).
As such, it never really crossed by mind to update the browser history when the thumbnails are used. However, a user clicking on thumbnails could be regarded as a pretty strong indication of user-intent w.r.t. navigation in the document, hence I suppose that updating the browser history in this particular case probably won't hurt.
2020-10-18 16:04:00 +02:00
Jonas Jenwald
8431cfe482 Re-name and re-factor the PDFLinkService.navigateTo method
This modernizes and improves the code, by using `async`/`await` and by extracting the helper function to its own method.
To hopefully avoid confusion, given the next patch, the method is also re-named to `goToDestination` to make is slightly clearer what it actually does.
2020-10-18 14:29:59 +02:00
Jonas Jenwald
e7437a0b67 Use standard import statements when loading PDFViewerApplication/AppOptions in web/viewer
Given that we're no longer using SystemJS to load the `web/` files, see PR 11919, there's nothing that prevents us from using standard `ìmport` statements in this file.
Obviously it's still necessary to load part of the code conditionally on the build type, however this still allows us to clean-up and simplify at least some of this file.
2020-10-11 14:06:47 +02:00
Jonas Jenwald
ba079453bf Enable the ESLint no-debugger and no-alert rules
The `debugger`-statement would only, potentially, make sense during development and we thus want to prevent it from being accidentally included when landing code.
The `alert`, `confirm`, and `prompt` functions should generally be avoided, with the few intended cases manually allowed.

Please find additional details about the ESLint rules at:
 - https://eslint.org/docs/rules/no-debugger
 - https://eslint.org/docs/rules/no-alert
2020-10-05 13:41:06 +02:00
Jonas Jenwald
069ddc8686 [Firefox] Stop logging RenderingCancelledExceptions as errors when printing
In the rest of the viewer code-base, we purposely don't treat `RenderingCancelledException`s as actual errors (since they aren't) and consequently we never log them.
Hence it makes sense, as far as I'm concerned, to simply treat `RenderingCancelledException`s the same way when printing in Firefox.

While I don't print a whole lot, I cannot remember seeing these "errors" logged when printing until *very* recently[1]. Given that the browser print functionality and UI, in Firefox, is under active development it's certainly possible that there's some recent changes to the related timings which make `RenderingCancelledException`s more likely now.

---
[1] Interestingly, only some PDF documents seem to be affected as well; I'm able to reproduce this pretty consistently by opening https://www.uni-muenster.de/imperia/md/content/ziv/pdf/printpay_flyer.pdf in Firefox and then repeating the following sequence:
Clicking on the PDF.js print button, and then cancelling printing.
2020-10-04 20:25:31 +02:00
Jonas Jenwald
eb0cc7f9c3 Add version/build info at the top of the *built* web/viewer.js file
This should be helpful to easily determine the *exact* version of the viewer itself, when looking at a *built* `web/viewer.js` file.
Note that we're already including this information in other built files, such as e.g. `pdf.js`, `pdf.worker.js`, `pdf_viewer.js`, and `pdf.image_decoders.js`.
2020-10-03 09:19:53 +02:00
Jonas Jenwald
89ce326d12 Re-factor how printing is triggered in the default viewer
This adds a new `PDFViewerApplication.triggerPrinting` method, which takes care of checking that printing is actually supported before calling `window.print`, to remove the need to duplicate that code in multiple places.

Also, removes the `PDFViewerApplication.printing` getter since it's not really necessary any more.
2020-09-30 15:10:19 +02:00
Tim van der Meij
d49b2f6cc2
Merge pull request #12422 from Snuffleupagus/find-not-shiftKey
Don't trigger searching, in the `GENERIC` viewer, when <kbd>Shift</kbd> is used together with the regular keyboard shortcut (issue 12421)
2020-09-29 22:30:53 +02:00
Jonas Jenwald
db4cefbac3 Add basic support for the optional chaining operator ?.
For now we need to use a Babel-plugin, since part of our build system doesn't support this fully (e.g. Babel-loader, Webpack 4.x, and SystemJS).

While the `?.` operator will thus always be transpiled by Babel, even in modern builds, simply supporting it for development purposes seems like a step in the right direction.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
2020-09-29 15:56:34 +02:00
Jonas Jenwald
f399ac7f16 Don't trigger searching, in the GENERIC viewer, when <kbd>Shift</kbd> is used together with the regular keyboard shortcut (issue 12421)
Please note that this change won't affect the Firefox built-in PDF Viewer, since it uses the native browser findbar. However, it brings the `GENERIC` viewer inline with how searching is normally triggered in browsers.

Note that in Firefox searching is only triggered by <kbd>Ctrl</kbd>+<kbd>F</kbd> (or <kbd>command</kbd>+<kbd>F</kbd> on Mac), but <kbd>Shift</kbd> isn't used; see https://support.mozilla.org/en-US/kb/keyboard-shortcuts-perform-firefox-tasks-quickly#w_search

Furthermore, looking at the "Miscellaneous" section of https://support.mozilla.org/en-US/kb/keyboard-shortcuts-perform-firefox-tasks-quickly#firefox:mac:fx81 the <kbd>command</kbd>+<kbd>Shift</kbd>+<kbd>F</kbd> shortcut is even reserved for the "Toggle Full Screen" functionality on Mac.
2020-09-29 11:50:20 +02:00
Tim van der Meij
6728c8fa61
Merge pull request #12405 from nickyc975/fixed-active-element-in-shadow-dom
Fixed keydown event handling problem with shadow DOM.
2020-09-26 23:02:13 +02:00
Jonas Jenwald
2043596035 Use template strings when calculating the CSS transforms, in the PDFPageView.cssTransform method
In my opinion this slightly improves readability, by grouping related properties together.
2020-09-25 14:42:55 +02:00
Jonas Jenwald
8467f45ab7 Change the finishRenderTask helper function, in PDFThumbnailView.draw, to be asynchronous
This simplifies the implementation slightly, and is also (almost) identical to the `finishPaintTask` helper function in `PDFPageView.draw`.
2020-09-25 14:42:46 +02:00
Jonas Jenwald
a4e5458774 Update all BaseViewer.getPageView/PDFThumbnailViewer.getThumbnail call-sites, in web/app.js, to check the returned value properly
Given how those are used, there *should* not be any situation in which e.g. `undefined` is ever returned. However, actually checking that the pageView/thumbnail is defined cannot hurt.

Also, re-factor `webViewerPageRendered` slightly since the `pageView` is no longer unconditionally necessary after the previous patches; note in particular that the thumbnails will only be updated when the sidebar *and* the thumbnailView is visible.

Finally, fixes a bug in `webViewerPageChanging` whereby an empty string would not be treated as a valid pageLabel and instead be replaced by `null`.
2020-09-25 14:42:46 +02:00
Jonas Jenwald
e46055a92c Remove the PDFPageView.stats property, and fetch it manually only when debugging is enabled
Given that the default viewer only uses the "page stats" when debugging is enabled, it seems much simpler and more straightforward to simply query the API *directly* when this information is actually required. That way, there's a bit less information that needs to be stored/updated on each `PDFPageView`-instance.

Finally, since the `EventBus` now exists, we no longer need to handle the "page stats"-case in the regular listeners in `web/app.js`, but can instead add special "page stats"-listeners only when debugging is enabled.
2020-09-25 14:42:44 +02:00
Jonas Jenwald
9efc1784b2 Remove the PDFPageView.error property, and simply include Errors in the "pagerendered" event instead
The way that rendering errors are handled in `PDFPageView` is *very* old, and predates e.g. the introduction of the `EventBus` by several years.
Hence we should be able to simplify things a bit here, by including the Error (when it exists) in the "pagerendered" event and thus avoid having to reach into `PDFPageView` for it.
2020-09-25 14:21:12 +02:00
Jonas Jenwald
7b15094cdf Ignore RenderingCancelledException when logging errors in PDFRenderingQueue.renderView
Note that a `RenderingCancelledException` *should* never actually reach this method, but better safe than sorry I suppose, considering that both `PDFPageView` and `PDFThumbnailView` are already catching `RenderingCancelledException`s since those are *not* Errors in the normal sense of the word.
2020-09-25 14:21:05 +02:00
Nicky Chen
252e258a59 Fixed keydown event handling problem with shadow DOM.
Editable elements in shadow DOMs can not be detected in old version.
2020-09-24 08:17:56 +08:00
Jonathan Grimes
d37a445369 Refactor the container/viewer checks in the BaseViewer constructor
The previous checks prevented specifying a container/viewer that was in another
document/window.
Fixes #12385
2020-09-17 20:29:10 +00:00
Jonas Jenwald
17a507016a Let the loadingBar have the same width as the viewerContainer
For years the loadingBar and sidebarContainer has had a slightly annoying and unfortunate dependency, since the loadingBar width follows the main toolbar width[1].
To prevent the loadingBar from obscuring part of the sidebarContainer, especially the buttons, the sidebarContainer is thus moved down when the loadingBar is visible. This has always annoyed me[2], since it means that the buttons in the sidebar may thus move vertically which seems bad from a UX perspective.

Now that CSS variables are available in all supported browsers[3] however, fixing the loadingBar/sidebarContainer overlap issues are finally easy. The solution is simply to let the sidebarContainer, when visible, control the loadingBar left position (right in RTL locales) in the same way that the viewerContainer is handled. Hence the sidebarContainer can now have a *consistent* vertical postition, without the loadingBar overlapping it.

---
[1] Obviously the right position (left in RTL locales) of the loadingBar is, potentially, reduced to account for a scrollbar.

[2] I've tried to fix this a few times, but it always seemed like more trouble than it's worth.

[3] https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties#Browser_compatibility
2020-09-10 17:16:24 +02:00
Tim van der Meij
e8822e1912
Merge pull request #12352 from Snuffleupagus/sidebar-resizer-CSS-vars
Remove CSS variables feature-testing from `PDFSidebarResizer`
2020-09-09 22:41:29 +02:00
Jonas Jenwald
01c1d87171 Remove CSS variables feature-testing from PDFSidebarResizer
CSS variables are now supported in all reasonably modern browsers, according to:
 - https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties#Browser_compatibility
 - https://caniuse.com/css-variables
2020-09-09 22:26:08 +02:00
Jonas Jenwald
c27dcf2b03 Ensure that the container div, on BaseViewer-instances, is absolutely positioned
The `getVisibleElements` helper function currently requires the viewerContainer to be absolutely positioned; possibly fixing this is tracked in issue 11626.

Without `position: absolute;` set, in the CSS, there's a number of things that won't work correctly such as e.g.
 - Determining which pages are currently visible, thus forcing all of them to render on load and increasing resource usage significantly; note https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions#allthepages

 - Scrolling pages into view, by using the `BaseViewer.currentPageNumber` setter or similar.

Based on the number of opened issues over the years, the fact that `position: absolute;` is required has shown to be something that users can very easily overlook unless they follow e.g. the `simpleviewer` example to the letter.
Hence, to improve things until such a time that issue 11626 is fixed, we'll now refuse to initialize a `BaseViewer` instance unless the `container` has the required CSS set. (Forcibly setting `position: absolute;` on the viewerContainer element is bound to cause significantly more issues/confusion, hence the current approach of throwing an Error.)
2020-09-09 15:24:47 +02:00
Jonas Jenwald
2594f0c738 Revert "[PDFSidebarResizer] Refactor the clamping in _updateWidth"
This reverts commit 9e4552d792 for causing the sidebar to become too narrow when the entire viewer is resized.

**Steps to reproduce:**
 1. Load the viewer.
 2. Open the sidebar.
 3. Resize the sidebar, making it wider.
 4. Resize the entire viewer, i.e. the browser window, making it *narrower* than 400 pixels.

**Expected result:**
 The sidebar width is clamped at 200 pixels.

**Actual result:**
 The sidebar becomes too narrow.

The cause of this bug is, in hindsight, quite obvious since the `clamp` helper function implicitly assumes that the `min`/`max` arguments are correctly sorted. At viewer widths *below* 400 pixels, that assumption is broken which explains the bug.
2020-09-09 13:26:38 +02:00
Jonas Jenwald
7b1418368d Remove some code/comments relevant for old (pre-Chromium) versions of Opera 2020-09-08 12:54:51 +02:00
Jonas Jenwald
f78b348cff Support broken /FitH destinations that are missing the "top" value (bug 1663390)
See https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/PDF32000_2008.pdf#G11.2095870
2020-09-07 10:28:55 +02:00
Tim van der Meij
83e1bbea6e
Merge pull request #12328 from Snuffleupagus/rm-web-IE
Remove code-paths only relevant for IE 11/Edge (non-Chromium based) from the `web/` folder
2020-09-06 14:15:49 +02:00
Jonas Jenwald
cdeeec966d Rename the --outline-... CSS variables to --treeitem-... instead (PR 11077 follow-up)
Given that the outlineView/attachmentsView/layersView all share a common base-class and CSS rules, see PRs 12169 and 12170, the names of the CSS variables in question feels slightly strange now.
2020-09-05 23:06:44 +02:00
Jonas Jenwald
87b002c52f Remove code-paths only relevant for IE 11/Edge (non-Chromium based) from the web/ folder
This patch purposely starts small, by removing IE-specific code from various JS/CSS files in the `web/` folder.

There's obviously lots of potential for additional clean-up, especially the removal of no longer necessary polyfills in `src/shared/compatibility.js`, however that will require some care considering that certain polyfills may also be necessary for e.g. Node.js or the Chromium-extension as well.
Generally speaking, once we start removing polyfills it's probably a good idea to consult the compatibility information on https://developer.mozilla.org/ and also https://caniuse.com/ first. (Deciding on the lowest supported Chromium version, for the extension, would also seem like a good idea.)
2020-09-05 17:18:15 +02:00
Jonas Jenwald
a52e229ca6 Revert "Download, rather than opening, PDF attachments in Firefox (bug 1661259, PR 12286 follow-up)"
This reverts commit 2a0de0b66b.

I can no longer reproduce these issues locally, and if ad blockers are still interfering with this functionality we really ought to pursue a mozilla-central solution to the problem instead. (Also, I'm no longer getting an "Open with Firefox"-option in the "Open with"-dialog making the PDF attachments experience worse for all users.)
2020-09-04 12:07:34 +02:00
Jonas Jenwald
89f6bb0fc6 Ensure that the viewer property, on BaseViewer-instances, is a valid div-element (issue 12320)
This should help prevent future issues, caused by the user omitting the `viewer` option and/or providing an incorrect `container` option, when initializing a `BaseViewer`-instance.
2020-09-03 15:06:36 +02:00
Emilio Cobos Álvarez
f4f4ec30f4
print: Make the firefox printing code able to fail and be re-invoked.
This fixes a set of issues described in Mozilla bug 1662426[1].

In particular, once the print callback fails once (because the printing
operation has been canceled in Gecko / replaced by a newer one, for example) it
can't be re-invoked.

This patch fixes it by properly cancelling the render task if it throws, or if
the print callback is called again while ongoing.

[1]: https://bugzilla.mozilla.org/show_bug.cgi?id=1662426
2020-09-02 22:56:21 +02:00
Jonas Jenwald
695523712c Add support for /Print and /SaveAs named actions in the viewer (issue 12308)
All of the core/display functionality needed to support this already exists, we simply need to handle these named actions in the viewer and the buttons will "just" work.

Unfortunately there's not really any good way of testing this, but given the size and scope of the patch that's hopefully OK.
2020-09-01 09:24:38 +02:00
Jonas Jenwald
8aa2718d22 Re-format all web/*.css files using Stylelint/Prettier
This was done automatically, using `gulp lint --fix`.
2020-08-30 21:49:08 +02:00
Jonas Jenwald
7b5a540a52 Add (basic) support for Stylelint, to allow linting of CSS files
This is *similar* to the existing linting for JavaScript files, but covers CSS files instead.
While there's a lot of rules that could potentially be used, the main advantage of using Stylelint is that it has Prettier integration which means that we can automatically enforce a *consistent* style for our CSS files as well.

As a proof of concept, this patch is purposely limited to:
 - Adding a simple rule, here `block-no-empty` is chosen; see https://stylelint.io/user-guide/rules/block-no-empty
 - Adding Prettier integration, to unify the style of our CSS files.

Please find additional information at https://stylelint.io/
2020-08-30 21:48:35 +02:00
Jonas Jenwald
66aabe3ec7 [api-minor] Add support for toggling of Optional Content in the viewer (issue 12096)
*Besides, obviously, adding viewer support:* This patch attempts to improve the general API for Optional Content Groups slightly, by adding a couple of new methods for interacting with the (more complex) data structures of `OptionalContentConfig`-instances. (Thus allowing us to mark some of the data as "private", given that it probably shouldn't be manipulated directly.)

By utilizing not just the "raw" Optional Content Groups, but the data from the `/Order` array when available, we can thus display the Layers in a proper tree-structure with collapsible headings for PDF documents that utilizes that feature.

Note that it's possible to reset all Optional Content Groups to their default visibility state, simply by double-clicking on the Layers-button in the sidebar.
(Currently that's indicated in the Layers-button tooltip, which is obviously easy to overlook, however it's probably the best we can do for now without adding more buttons, or even a dropdown-toolbar, to the sidebar.)

Also, the current Layers-button icons are a little rough around the edges, quite literally, but given that the viewer will soon have its UI modernized anyway they hopefully suffice in the meantime.

To give users *full* control of the visibility of the various Optional Content Groups, even those which according to the `/Order` array should not (by default) be toggleable in the UI, this patch will place those under a *custom* heading which:
 - Is collapsed by default, and placed at the bottom of the Layers-tree, to be a bit less obtrusive.
 - Uses a slightly different formatting, compared to the "regular" headings.
 - Is localizable.

Finally, note that the thumbnails are *purposely* always rendered with all Optional Content Groups at their default visibility state, since that seems the most useful and it's also consistent with other viewers.
To ensure that this works as intended, we'll thus disable the `PDFThumbnailView.setImage` functionality when the Optional Content Groups have been changed in the viewer. (This obviously means that we'll re-render thumbnails instead of using the rendered pages. However, this situation ought to be rare enough for this to not really be a problem.)
2020-08-30 16:28:40 +02:00
Tim van der Meij
ef5a5c142a
Merge pull request #12299 from Snuffleupagus/progressBar-indeterminate
Update the indeterminate progressBar to the new design (PR 11077 follow-up)
2020-08-30 16:14:01 +02:00
Tim van der Meij
d1cc382383
Merge pull request #12300 from Snuffleupagus/findbar-hover
Fix various :hover effects in the findbar (PR 11077 follow-up)
2020-08-30 16:07:43 +02:00
Jonas Jenwald
931f2cff1e Fix various :hover effects in the findbar (PR 11077 follow-up)
This patch:
 - Removes the :hover effect from the `findMsg` element, since it's a simple span and clicking it *obviously* does nothing.
 - Given the way that the checkboxes are visually hidden, with `opacity: 0;` and absolute positioning, they are unfortunately still focusable (fixed by adding `pointer-events: none;`). To reproduce this, in `master`: Place the mouse pointer over the upper left-hand corner of the "Highlight all"-option, and notice that the :hover effect vanishes and clicking toggles the "Match case"-option instead.
2020-08-29 15:44:51 +02:00
Jonas Jenwald
55e1dda52a Update the indeterminate progressBar to the new design (PR 11077 follow-up)
This special progressBar is only used in the (fortunately) rare case when a server doesn't provide a valid `Content-Length` header. Since this progressBar isn't normally seen, when testing the default viewer, it's certainly very easy to see why these CSS rules were missed during review.

Furthermore, this patch also makes a couple of *small* progressBar CSS tweaks not related to the colours.
2020-08-28 16:18:41 +02:00
Jonas Jenwald
16f5080bef Tweak the vertical positions of the findbar and secondaryToolbar (PR 11077 follow-up)
With the changes in PR 11077, these panels are no longer aligned exactly with the *center* of the corresponding toolbar buttons. This is especially noticeable for the `findbar` at narrow viewer width.
2020-08-28 13:04:10 +02:00
Jonas Jenwald
2a0de0b66b Download, rather than opening, PDF attachments in Firefox (bug 1661259, PR 12286 follow-up)
Unfortunately the work-around implemented in PR 12286 didn't actually work in all cases, please refer to the previous commit messages.
To prevent opening of PDF attachments from being completely broken for some users, we'll simply force-download them for now in MOZCENTRAL-builds to unbreak things. (Given that the "Open with" dialog now features a "Open with Firefox"-option, this is less bad than it previously would've been.)
2020-08-27 16:30:15 +02:00
Jonas Jenwald
a23079c2dd Ensure that PDFAttachmentViewer._bindLink assigns the correct contentType when downloading PDF attachments
This should provide better filetype detection when downloading PDF attachments in the viewer.

Also, to avoid creating the "is PDF file" regular expression more than once it's extracted into a global constant instead.
2020-08-27 16:30:15 +02:00
Jonas Jenwald
de932573dd Revert "Use a link, rather than window.open, when opening PDF attachments in Firefox (bug 1661259)"
This reverts commit 1e5d4b6a80, since it unfortunately doesn't work in all situations.

Please note that I did *successfully* test the patch in a local Firefox build, obviously with an ad blocker installed.
However, I've now tested the *latest* Nightly-build with my default profile, and unfortunately I can still reproduce the bug there!?
2020-08-27 16:30:05 +02:00
Tim van der Meij
a6f66891cc
Merge pull request #12286 from Snuffleupagus/bug-1661259
Use a link, rather than `window.open`, when opening PDF attachments in Firefox (bug 1661259)
2020-08-26 22:25:56 +02:00
Jonas Jenwald
1e5d4b6a80 Use a link, rather than window.open, when opening PDF attachments in Firefox (bug 1661259)
Unfortunately e.g. ad blockers can interfere with `window.open` calls, thus preventing PDF attachments from being opened/viewed. For the MOZCENTRAL-build, we can work-around this problem by using a (hidden) link instead.
2020-08-26 19:02:51 +02:00
Jonas Jenwald
77a1e531c2 Ensure that the sourceEventType parameter is actually optional in PDFViewerApplication.{download, save} (PR 12248 follow-up)
Without these changes, clicking on the "Open With Different Viewer"-button on the Firefox fallback bar won't actually do anything and the following is printed in the web-console:
```
Uncaught TypeError: (destructured parameter) is undefined
    download resource://pdf.js/web/viewer.js:956
    response resource://pdf.js/web/viewer.js:1054
    listener resource://pdf.js/web/viewer.js:11891
viewer.js:956:1
```

Furthermore, this patch also fixes `PDFViewerApplication.fallback` to pass in an explicit `sourceEventType` when triggering downloading. While this, on its own, would obviously have been sufficient to fix the bug described above, it seems wrong to outright break backwards compatibility of any older `PDFViewerApplication.download` calls.
2020-08-26 11:45:25 +02:00
Tim van der Meij
280207c740
Redo the form type detection logic and include unit tests
Good form type detection is important to get reliable telemetry and to
only show the fallback bar if a form cannot be filled out by the user.

PDF.js only supports AcroForm data, so XFA data is explicitly unsupported
(tracked in issue #2373). However, the previous form type detection
couldn't separate AcroForm and XFA well enough, causing form type
telemetry to be incorrect sometimes and the fallback bar to be shown for
forms that could in fact be filled out by the user.

The solution in this commit is found by studying the specification and
the form documents that are available to us. In a nutshell the rules are:

- There is XFA data if the `XFA` entry is a non-empty array or stream.
- There is AcroForm data if the `Fields` entry is a non-empty array and
  it doesn't consist of only document signatures.

The document signatures part was not handled in the old code, causing a
document with only XFA data to also be marked as having AcroForm data.
Moreover, the old code didn't check all the data types.

Now that AcroForm and XFA can be distinguished, the viewer is configured
to only show the fallback bar for documents that only have XFA data. If
a document also has AcroForm data, the viewer can use that to render the
form. We have not found documents where the XFA data was necessary in
that case.

Finally, we include unit tests to ensure that all cases are covered and
move the form type detection out of the `parse` function so that it's
only executed if the document information is actually requested
(potentially making initial parsing a tiny bit faster).
2020-08-25 23:28:55 +02:00
Jonas Jenwald
7762205c52 Reduce the leading padding for the numPages span (PR 11077 follow-up)
Currently there's enough leading padding that the `numPages` span feels somewhat "disconnected" from the `pageNumber` input, which seems unfortunate when they contain related state.
2020-08-23 16:21:07 +02:00
Jonas Jenwald
f2e3d6c819 Don't warn when navigating away from a modified form, if printing has occurred (issue 12262)
This solution is obviously *not* perfect, since printing being cancelled will thus remove the warning as well. However, a similar problem already exists for saving, since the user may cancel that one as well.

All-in-all, since way cannot really detect with absolute certainty that either saving or printing actually finished, this seems good enough for now.
2020-08-22 17:49:56 +02:00
Jonas Jenwald
a8de614a9f Also enable renderInteractiveForms by default in the viewer components (PR 12201 follow-up)
Given that `renderInteractiveForms` is now enabled by default in "full" viewer, it seems reasonable to enable it by default in the viewer components as well.
Especially considering that it's simple to disable, when creating the affected components, for anyone implementing their own viewer.
2020-08-22 14:24:04 +02:00
utopianknight
43a439643d Replaced menu dropdown icon 2020-08-22 12:10:51 +04:00
Aki Sasaki
b1423336c3 #12241 followup - move event listener to PDFViewerApplication.load 2020-08-21 09:53:39 -07:00
Brendan Dahl
8023175103 Support file save triggered from the Firefox integrated version.
Related to https://bugzilla.mozilla.org/show_bug.cgi?id=1659753

This allows Firefox trigger a "save" event from ctrl/cmd+s or the "Save
Page As" context menu, which in turn lets pdf.js generate a new PDF if
there is form data to save.

I also now use `sourceEventType` on downloads so Firefox can determine if
it should launch the "open with" dialog or "save as" dialog.
2020-08-20 18:05:08 -07:00
Brendan Dahl
10f61b8c96
Merge pull request #12241 from escapewindow/prevent-default
confirm if leaving a modified form without saving
2020-08-20 17:56:59 -07:00
Aki Sasaki
83365a3756 confirm if leaving a modified form without saving 2020-08-20 17:23:06 -07:00
Tim van der Meij
2e95d08f12
Merge pull request #12251 from DesWurstes/master
Return the query with the findcontrolstate
2020-08-21 00:08:02 +02:00
DesWurstes
72f48ee089 Return the query with the findcontrols 2020-08-20 11:18:43 +01:00
Jonas Jenwald
2683f44b40 Update the zoom dropdown width calculation to work better in locales with long zoom-strings (PR 11077 follow-up)
With the changes in PR 11077, the zoom dropdown now looks "squashed" in locales with longer than average zoom-strings[1]. The reason is that the zoom-value and the dropdown-icon are too close together, which doesn't look good in affected locales.

To fix this, the following changes are made:
 - Increase the calculated dropdown width, in `Toolbar._adjustScaleWidth`, to account for the much wider icon (7 px -> 16 px) and the increased padding.
 - Move the dropdown-icon *slightly* outwards, and also *slightly* reduce the left (right in RTL locales) padding of the dropdown-contents.
 - Finally, remove the right (left in RTL locales) padding to reduce the chance of the *default* browser dropdown-icon being visible.

---
[1] This affects e.g. the `de` and `nl` locales, but there's probably other examples as well.
2020-08-20 09:57:42 +02:00
Tim van der Meij
965d20db2a
Merge pull request #11077 from utopianknight/modern-look
Implement Photon design for the viewer
2020-08-19 22:53:11 +02:00
utopianknight
c0b671d91b Photon Design 2020-08-19 14:21:13 +04:00
Brendan Dahl
7bba4931ad Dispatch event when annotations have finished rendering.
This is needed for some smoke tests in mozilla central for testing forms
in pdf.js.

Note: AnnotationLayerBuilder.render() doesn't really need to be async, but
we're talking of making the annotation's render functions async, so this
will make that switch easier.
2020-08-17 14:29:24 -07:00
Tim van der Meij
192afb87e3
Merge pull request #12203 from staktrace/zoomfix
Bug 1392361 - Fix zooming sensitivity on macOS
2020-08-16 22:36:37 +02:00
Tim van der Meij
66bbe82cc5
Merge pull request #12212 from staktrace/touchfix
Bug 1643508 - Disable touch-based pinch zooming on pdf.js.
2020-08-16 22:12:02 +02:00
Kartikaya Gupta
c6e5686b6a Bug 1643508 - Disable touch-based pinch zooming on pdf.js.
Currently using a touchscreen with pdf.js doesn't work so well. In Firefox,
with apz.allow_zooming = false (default on current release/beta), it does a
reflow zoom which makes the UI elements bigger. And with apz.allow_zooming = true
(default on current Firefox nightly), or in Chrome, it does a smooth pinch-zoom
but that also scales up the entire UI. Neither of these is a particularly good
experience, so this patch just disables any multi-touch gestures. Touch-based
panning (which involves a single touch point) is left unaffected.
2020-08-13 09:22:30 -04:00
Jonas Jenwald
22cb59e7d0 Wait until saving has finished before resetting PDFViewerApplication._saveInProgress (PR 12137 follow-up)
I obviously missed this during review, but currently `PDFViewerApplication._saveInProgress` is reset *synchronously* in `PDFViewerApplication.save`.
That was probably not intended, since it essentially renders the `PDFViewerApplication._saveInProgress` check pointless given that the actual saving is an *asynchronous* operation.
2020-08-13 13:00:29 +02:00
Kartikaya Gupta
213676b5e8 Bug 1392361 - Fix zooming sensitivity on macOS
The original code would get a long sequence of miniscule "tick" values while
pinch-zooming, and each tick value would cause a 1.1x zoom. So even the smallest
pinch gesture on a trackpad would cause high amounts of zoom. This patch
accumulates the wheel deltas until they reach an integer threshold (with a
tweak of the scaling factor to make it feel more natural) at which point it
triggers the zoom based on the integer component of the accumulated delta. The
fractional part is retained in the accumulator.
2020-08-12 17:18:50 -04:00
Brendan Dahl
da62be0685 Enable renderInteractiveForms by default. 2020-08-12 10:28:27 -07:00
Calixte Denizet
1a6816ba98 Add support for saving forms 2020-08-12 10:32:59 +02:00
Tim van der Meij
3380f2a7fc
Merge pull request #12191 from Snuffleupagus/rm-AppOptions-disableCreateObjectURL
Remove the `disableCreateObjectURL` option from `web/app_options.js`
2020-08-12 00:08:27 +02:00
Jonas Jenwald
8e32c17e85 Set direction: ltr; on the canvases used during printing (bug 1335712)
This essentially mirrors the CSS rules used for the viewer itself, see `web/pdf_viewer.css`, and according to my very quick tests it seems to fix https://bugzilla.mozilla.org/show_bug.cgi?id=1335712
2020-08-10 18:35:56 +02:00