Commit Graph

2734 Commits

Author SHA1 Message Date
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