Commit Graph

377 Commits

Author SHA1 Message Date
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
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
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
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
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
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
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
Brendan Dahl
956fcab967
Merge pull request #12631 from calixteman/app
JS -- Implement app object
2020-12-01 16:50:16 -08: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
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
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
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
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
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
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
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
Calixte Denizet
e76a96892a JS - Add the basic architecture to be able to execute embedded js 2020-10-21 19:00:56 +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
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
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
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
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
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
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
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
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
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
DesWurstes
72f48ee089 Return the query with the findcontrols 2020-08-20 11:18:43 +01: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