Commit Graph

2897 Commits

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