Make sure that the print service is stopped as soon as possible when
aborted, and that it is not possible for a (slow) promise to
accidentally wipe the state of a print job that was started later.
There's no mention of our `#{pagenum}` form in http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/pdf_open_parameters.pdf, and Adobe Reader doesn't seem to support it either.
Hence this patch removes support for it in the extensions, but keeps it in the `GENERIC` build with a deprecation warning and a fallback to handle it as a destination.
Fixes 7746.
This patch implements the page label functionality in a similar way as Adobe Reader.
For documents with page labels, if a non-existent page label is entered we'll try to fallback to the page number instead.
The patch also includes a preference (`disablePageLabels`), to make it easy to opt-out of using page labels if the user/implementor so wishes.
The way that `get/set currentPageLabel` is implemented in `PDFViewer`, is as wrappers for the corresponding `get/set currentPageNumber` functions, since that seemed like the cleanest solution.
The page labels are purposely *only* added to the page controls in the viewer UI, and not stored in e.g. the `ViewHistory`. Since doing so would mean adding unnecessary code complexity, without any real added value, and would also mean delaying the inital loading of PDF documents.
Note that this patch will ignore page labels if they are identical to standard page numbering, since in this case displaying the page labels adds no value (but only UI noise). The reason for handling this case specially, is that in practice a surprising number of PDF files include "pointless" page labels.
The following reasoning was used for deciding to remove the "Page: " label, and replace it with a tooltip, from the main toolbar:
- We have no other visible labels in the *main* toolbar (e.g. the Zoom dropdown doesn't have a label, but only a tooltip).
- We already hide the "Page: " label when the viewer is narrow.
- The varying width of the "Page: " label in different locales is already causing issues for many languages, with overlap in the main toolbar as a result.
Trying to create responsive CSS styles that works well in all locales is already difficult, and if we add support for page labels that will only further compound the issues.
- Some PDF viewers (e.g. Adobe Reader, pdfium in Chrome) doesn't show labels in the UI by default.
In some PDF files, the first element (i.e. the one containing either a `Ref` or a `Number` pointing to a page) of the explicit destination Array may be bogus.
One such example is actually the file `pdf.pdf` in the test-suite, where some destinations are incompletely specified. One such example being the `G1.998360` destination whose explicit destination Array contains `[null, /XYZ, 54, 488, null]`, i.e. the destination page is `null`.
Hence this patch adds a bit more validation for that case. It also adds an additional check to ensure that the resulting `pageNumber` is non-negative, and finally a couple more error messages for existing cases of malformed data.
Note that in `FIREFOX/MOZCENTRAL/CHROME` builds of the standard viewer the `docBaseUrl` parameter will be set by default, since in that case it makes sense to use the current URL as a base.
For the `GENERIC` viewer, or the API itself, it doesn't make sense to try and set the `docBaseUrl` by default. However, custom deployments/implementations may still find the parameter useful.
This not only reduces code duplication, but it also allow us to easily support the same kind of URLs we currently do for Link annotations in the Outline as well.
The outline toggle button has a feature where it can be double-clicked
to expand/collapse all items shown therein. Although this is described
in the FAQ, can go potentially unnoticed. This, however, being a useful
feature, advertise on the tool tip itself.
l10n translation for en-US and IDs updated.
Signed-off-by: Jeenu Viswambharan <jeenuv@gmail.com>
When opening a PDF file that triggers the browser fallback bar in the Firefox addon/built-in version, e.g. http://web.archive.org/web/20110918100215/http://www.irs.gov/pub/irs-pdf/f1040.pdf (with forms *disabled*), and then reloading the document an error can be thrown.
The reason is that displaying the fallback bar triggers 'resize' events, and they can arrive *before* the viewer has had a chance to run all the necessary initialization code.
If interactive forms are enabled, then the display layer takes care of
rendering the form elements. There is no need to draw them on the canvas
as well. This also leads to issues when values are prefilled, because
the text fields are transparent, so the contents that have been rendered
onto the canvas will be visible too.
We address this issue by passing the `renderInteractiveForms` parameter
to the render task and handling it when the page is rendered (i.e., when
the canvas is rendered).
There's really no good reason to attempt to adjust the `max-height` of the `SecondaryToolbar` when it's not visible, so let's not do that anymore.
Also, we can listen for the `resize` event in `SecondaryToolbar`, to avoid having to manually call the `max-height` adjust function from various event handlers in `app.js`. Please note that by always adjusting the `max-height` when the toolbar is opened we no longer need the `localized` event, since it was mainly used to set a correct inital `max-height` value.
Please note that this is a hack, but I think that it should be OK for now to atleast get the preference landed. Refer to the code comment for further information.
Re: issue 7584 and PR 7586.
This patch is the first step towards implementing support for
interactive forms (AcroForms). It makes it possible to render text
widget annotations exactly like Adobe Reader/Acrobat.
Everything we implement for AcroForms is disabled by default using a
preference, mainly because it is not ready to use yet, but has to
implemented in many steps to avoid complexity. The preference allows us
to work with the code while not exposing the behavior by default. Mainly
storing entered values and printing them is still absent, which would be
minimal requirements for enabling this by default.
When clicking on the `pageNumber` input, or when using the keyboard shortcut <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>G</kbd>, the element isn't just focused but its contents is actually *selected* so that the user doesn't need to clear the input before entering a new `pageNumber`.
However, the `GoToPage` named action is only using `focus`, so let's change this to be consistent.
The following document can be used for testing: http://www2.informatik.uni-freiburg.de/~frank/ENG/beamer/example/Beamer-class-example1.pdf#zoom=page-fit
[screeenshot]
1. Expanding divs to improve text selection. (Yury)
2. Adding enhanceTextSelection as an option.
3. Moving feature functionality from text_layer_builder.js to text_layer.js.
4. Added expandTextDivs method to only load expanded divs on first click, and only show on subsequent clicks
In the `zoom{In, Out}` functions in `PDFViewerApplication`, we prevent the zoom value from becoming smaller/larger than `MIN_SCALE/MAX_SCALE`.
However, if the user sets the zoom level through the hash parameter the zoom buttons might not be correctly disabled; try http://mozilla.github.io/pdf.js/web/viewer.html#zoom=10.
Note that this issue has been present since "forever", but given that the solution is so simple I think that we should just fix this. (I'm also fixing a stupid typo I previously made in the JSDoc comment.)
With the viewer code now being split into various components/files, having an obsolete comment in `PDFViewer` that references thumbnails despite there being no other mentions of them in the entire file seems strange.
*Note:* This comment is simply a left-over from older versions of PDF.js, where the *entire* default viewer code was placed in just one file (and where we unconditionally created thumbnails, regardless whether they were visible or not).
There are PDF generators which create destinations with e.g. too large top values, which cause the wrong page to be scrolled into view because the offset becomes negative.
By ignoring negative offsets, we can prevent this issue, and get a similar behaviour as in Adobe Reader.
However, since we're also using `PDFViewer_scrollPageIntoView` in more cases than just when links (in the document/outline) are clicked, the patch adds a way to allow the caller to opt-out of this behaviour.
In e.g. the following situations, I think that we still want to be able to allow negative offsets: when restoring a position from the `ViewHistory`, when the `viewBookmark` button is used to obtain a link to the current position, or when maintaining the current position on zooming.
Rather than adding another parameter to `PDFViewer_scrollPageIntoView`, I've changed the signature to take an parameter object instead. To maintain backwards compatibility, I've added fallback code enclosed in a `GENERIC` preprocessor tag.
Fixes https://bugzilla.mozilla.org/show_bug.cgi?id=874482.
With PR 7502 we no longer dispatch an event when the `val` is out of bounds, so to better communicate why nothing happens this patch logs an error in that case (similar to the logging of errors when trying to set an invalid scale).
The way that the default viewer is currently implemented, means that e.g. keyboard short-cuts could trigger the new error. Hence this patch also adds the necessary validation code, both to `app.js` and `pdf_link_service.js` to prevent unnecessary errors.
This patch attempts to cleanup a couple of things:
- Remove the `previousPageNumber` paramater. Prior to PR 7289, when the events were dispatched even when the active page didn't change, it made sense to be able to detect that in an event listener. However, now that's no longer the case, and furthermore other similar events (e.g. `scalechanging`/`scalechange`) don't include information about the previous state.
- Don't dispatch the events when the value passed to `set currentPageNumber` is out of bounds. Given that the active page doesn't change in this case, again similar to PR 7289, I don't think that the events should actually be dispatched in this case.
- Ensure that the value passed to `set currentPageNumber` is actually an integer, to avoid any issues (note how e.g. `set currentScale` has similar validation code).
Given that these changes could possibly affect the PDF.js `mochitest` integration tests in mozilla-central, in particular https://dxr.mozilla.org/mozilla-central/source/browser/extensions/pdfjs/test/browser_pdfjs_navigation.js, I ran the tests locally with this patch applied to ensure that they still pass.
From the discussion in issue 7445, it seems that there may be cases where an API consumer would want to get the text content as is, without combined text items.
After PR 7289, we'll now reset the current page view in cases where I don't think we should. To avoid this, this patch ensures that we'll not modify the position when the page number is out-of-bounds.
**STR:**
1. Open http://mozilla.github.io/pdf.js/web/viewer.html#page=1&zoom=auto,-98,696
2. Enter an invalid number, e.g. `1000`, in the `pageNumber` input.
**ER:**
The current position in the document shouldn't change, since the page number wasn't valid.
**AR:**
The document resets to the top of the page `1`.
The method signature was improved in PR 6546, which was included in the `1.2.109` release from last November.
Hence I think that we should now be able to remove the fallback code for the old method signature. Note that this patch now throws an `Error` in `GENERIC` builds, to clearly indicate that the `open` callsite must be modified.
In PR 7273, we simplified the `MOZCENTRAL` specific check for fullscreen support. Unfortunately I've just, by coincidence, found out about https://bugzilla.mozilla.org/show_bug.cgi?id=1268749, which disabled the unprefixed fullscreen support in release versions of Firefox. If we do nothing, this will lead to Presentation Mode being unavailable in future Firefox releases.
This patch should fix things for now, and I'm afraid that we'll need to uplift it to Firefox 49 as well.
With the changes in PR 7289, we no longer dispatch a 'pagechanging' event on load. Since most PDF documents open on the first page, this means that the `previous` and `firstPage` buttons are no longer correctly disabled.
To avoid this, this patch moves the code that updates various UI toolbar state into one method, which is then called on document initialization and from the various existing event handling functions.
Move the Chromium-specific URL rewriting code to the top of viewer.js
(before the PDF.js library) to make sure that the URL is as expected.
This ensures that variables that synchronously depends on the URL
(e.g. PDFViewerApplication.initialBookmark) are properly set.
Use chrome.storage.sync to store preferences instead of
chrome.storage.local, to allow settings to be synchronized if the user
chooses to sign in in Chrome and enables synchronization of extension
preferences.
Currently for explicit destinations, compared to named destinations, we manually try to build a hash that often times is a quite poor representation of the *actual* destination. (Currently this only, kind of, works for `\XYZ` destinations.)
For PDF files using explicit destinations, this can make it difficult/impossible to obtain a link to a specific section of the document through the URL.
Note that in practice most PDF files, especially newer ones, use named destinations and these are thus unnaffected by this patch.
This patch also fixes an existing issue in `PDFLinkService_getDestinationHash`, where a named destination consisting of only a number would not be handled correctly.
With the added, and already existing, type checks in place for destinations, I really don't think that this patch exposes any "sensitive" internal destination code not already accessible through normal hash parameters.
*Please note:* Just trying to improve the algorithm that generates the hash is unfortunately not possible in general, since there are a number of cases where it will simply never work well.
- First of all, note that `getDestinationHash` currently relies on the `_pagesRefCache`, hence it's possible that the hash returned is empty during e.g. ranged/streamed loading of a PDF file.
- Second of all, the currently computed hash is actually dependent on the document rotation. With named destinations, the fetched internal destination array is rotational invariant (as it should be), but this will not hold in general for the hash. We can easily avoid this issue by using a stringified destination array.
- Third of all, note that according to the PDF specification[1], `GoToR` destinations may actually contain explicit destination arrays. Since we cannot really construct a hash in `annotation.js`, we currently have no good way to support those. Even though this case seems *very* rare in practice (I've not actually seen such a PDF file), it's in the specification, and this patch allows us to support that for "free".
---
[1] http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/PDF32000_2008.pdf#G11.1951685
These have been found using `gulp lint` in combination with the `unused:
true` parameter for JSHint. Unfortunately there are too many false
positives to enable this feature, but now that most globals have been
removed because of the conversion to UMD the results are much more
useful than before.
This was only ever useful for the Opera extension because the API
requires a whitelisted extension ID. Opera ditched PDF.js from their
extension gallery, so we don't need to keep this in the tree.
I've seen the above error occasionally when the scale is updated many times in quick succession, but I've not been able to pinpoint exactly why it happens.
Since the error isn't caught, this means that the `pageViewDrawCallback` function doesn't run to completion.
Unfortunately, given the very intermittent nature of the issue, I haven't got any good STR for reliably reproducing this issue. However, I hope that this patch can be accepted anyway, since it's simple and should help prevent unnecessary errors.
We're already, since quite some time, using the standard Fullscreen API provided that it's available in the browser. The warning is only caused by the code that checks if the Fullscreen API is supported.
This patch uses a simple preprocessor tag to avoid the warning, since I'm assuming that in general, we want to try and remain backwards compatible with the prefixed versions of the Fullscreen API.
Fixes 7270.
When Firefox is run in e10s mode, which will soon be the default, the PDF.js zoom dropdown menu doesn't look right. This is apparently because the `<select>` DOM element is rendered in the parent, and that all the necessary style information isn't sent up from the child. See the discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=910022.
Besides this causing the PDF.js UI to *look* worse in e10s, notably it also means that the `customScaleOption` isn't hidden like it ought to be.
To work-around that, this patch utilizes the `hidden` attribute, since https://bugzilla.mozilla.org/show_bug.cgi?id=1242450 at least made that work in e10s.
Fixes https://bugzilla.mozilla.org/show_bug.cgi?id=1194700.
Furthermore we introduce two new methods named `setCallback` and
`setReason` so external code does not change the properties of the class
directly. Finally we update various names of properties and methods to
be more self-explanatory.
With the recent PR 7172, which made the viewer modular, there's now a couple of modules that are no longer easily accessible (e.g. through the console).
This can make testing/debugging more difficult, and means that e.g. https://github.com/mozilla/pdf.js/wiki/Debugging-PDF.js#enabling no longer works in the generic viewer.
For now, as a simple solution, this patch just exposes those non-classes on `PDFViewerApplication` to ensure that they are available, and to avoid polluting the `window` scope.
Persist the state of content sidebar while browsing away from viewer and
initializing the same on returning back to the viewer. The state is saved
in persistent store preferences and used upon viewer initialization.
Fixes#6935
We cannot piggy-back on the `updateviewarea` event in order to update the stored sidebar state, since there're a number of cases where opening/switching the sidebar view won't fire a `updateviewarea` event.
Note that `updateviewarea` only fires when the position changes in the *viewer*, which means that it won't fire if e.g. the viewer is narrow, such that the sidebar overlays the document transparently; or when switching views, without the document position also changing.
This patch also moves the handling of `forceOpen` parameter in `PDFSidebar_switchView`, to prevent triggering back-to-back rendering and dispatching of events.
This is a regression from PR 7097.
(Also, out of scope for this PR, but I think that a `setTimeout` value of `1000 ms` is too large. Switching from scrolling to zooming can fell sluggish, and give the impression that nothing happens.)
[PDFThumbnailView] Re-factor the `canvas` to `image` conversion such that we always render to a `canvas`, and then replace it with an `image` once rendering is done
Functionality wise, `ensureThumbnailVisible` is essentially just a shorthand for `scrollThumbnailIntoView`. (And note that `PDFViewer` doesn't implement a `ensurePageVisible` method.)
The only remaining usage of `PDFThumbnailViewer_ensureThumbnailVisible` is inside `PDFPresentationMode`, which introduces an otherwise unnecessary `PDFThumbnailViewer` dependency there.
We're already relying on the `presentationmodechanged` event, in various files, to track the state of Presentation Mode. Thus we can simply listen for that event in `PDFSidebar` too, and update the thumbnails if necessary.
*This is a follow-up to PRs 6299 and 6441.*
The patch also adds an option to `PDFThumbnailView`, that disables the canvas-to-image conversion entirely, which might be useful in the context of issue 7026.
The sidebar code has, except for minor fixes/additions (such as attachments), been largely untouch for years.
To avoid having a bunch of sidebar code sprinkled throughout viewer.js, this patch moves the sidebar code into a separate file (pdf_sidebar.js), similar to how most other functionality has been moved in the last few years.
Besides simply moving code around, this patch also has the added benefit that we now keep track of the sidebar state (not just opened/closed).
This now makes it possible to handle both `Preferences` *and* `ViewHistory` settings for the sidebar state in a cleaner way, preventing strange and confusing interactions between the two.
Changes `PDFOutlineView`/`PDFAttachmentView` to be initialized once, since we're always creating them, and refactor their `render` methods to instead pass in the `outline`/`attachments`.
For consistency with other "classes", the `PDFOutlineView`/`PDFAttachmentView` are renamed to `PDFOutlineViewer`/`PDFAttachmentViewer`.
Also, make sure that the outline/attachments are reset when the document is closed. Currently we keep the old ones around until the `getOutline`/`getAttachments` API calls are resolved for a new document.
To reduce code duplication, the initialization code now uses the `reset` method.
Also, this patch moves `charactersToNormalize` out of `PDFFindController`, since it seemed better suited to be a "constant".
Open http://www.puolustusvoimat.fi/wcm/61ba4180411e702ea19ee9e364705c96/luonnonmuonaohjelmalumo1985.pdf?MOD=AJPERES#pagemode=bookmarks.
Note how the outline looks entirely empty, but hovering over it you'll see that there are entries present. There's two separate issues here, first of all the fact that you cannot visually make out the outline items, and secondly that the lack of text means that the clickable area becomes too small.
In Adobe Reader this issue is somewhat mitigated, since they use an icon for every item. For PDF.js, the easist way to address this seems to be making use of a default title.
This issue should be *very* rare in practice, but given the simplicity of the solution I think that we should fix this.
The `hasImage` property is a left-over from older thumbnail code, and has been made obsolete by `renderingState`.
Having two different properties tracking (basically) the same state is asking for trouble, since it's very easy to forget to update one of them, with annoying bugs as the result.
This is required to be able to use it in the annotation display code,
where we now apply it to sanitize the filename of the FileAttachment
annotation. The PDF file from https://bugzilla.mozilla.org/show_bug.cgi?id=1230933 has shown that some PDF generators include the path of the file rather than the filename, which causes filenames with weird initial characters. PDF viewers handle this differently (for example Foxit Reader just replaces forward slashes with spaces), but we think it's better to only show the filename as intended.
Additionally we add unit tests for the `getFilenameFromUrl` helper
function.
The Chrome extension enforces that local files cannot be embedded in
non-local web pages. The previous check was too strict (because the
origin of a file:-URL is "null"), and prevented local PDF from being
viewed in local files).
This patch fixes that problem, by querying the actual tab URL via the
background page.
Steps to verify:
1. Create a HTML file: `<iframe src=test.pdf width=100% height=100%>`
2. Build and load the extension.
3. Allow file access to the extension at `chrome://extensions`
4. Open the HTML file from a file:// URL.
5. VERIFY: The extension should attempt to load the PDF file.
6. Now open the following (replace ID with the extension ID, which you
can find at `chrome://extensions`):
`data:text/html,<iframe src="chrome-extension://ID/file:///test.pdf">`
7. VERIFY: The next error should be displayed:
"Refused to load a local file in a non-local page for security reasons."
Fixes 6898.
Note that this doesn't prevent the warning for PDF files that *do* ask for a password, e.g. http://async5.org/moz/passwordOU.pdf, but it's not clear to me if/how we could avoid that.
Re: issue 5089.
(Note that since there are other outline features that we currently don't support, e.g. bold/italic text and custom colours, I thus think we can keep the referenced issue open.)
Apparently some PDF files can have annotations with `URI` entries ending with `null` characters, thus breaking the links.
To handle this edge-case of bad PDFs, this patch moves the already existing utility function from `ui_utils.js` into `util.js`, in order to fix those URLs.
Fixes 6832.
Most code for Popup annotations is already present for Text annotations.
This patch extracts the popup creation logic from the Text annotation
code so it can be reused for Popup annotations.
Not only does this add support for Popup annotations, the Text
annotation code is also considerably easier. If a `Popup` entry is
available for a Text annotation, it will not be more than an image. The
popup will be handled by the Popup annotation. However, it is also
possible for Text annotations to not have a separate Popup annotation,
in which case the Text annotation handles the popup creation itself.
This patch makes the naming consistent with the `TextLayerBuilder`, and also the new `AnnotationLayer`, and should thus help reduce possible confusion when working with the code.
Please note that the files were renamed using `git mv`, in order to preserve blame.
Additionally simplify the div creation logic (it needs to happen only
once, so it should not be in the for-loop) and remove/rename variables
for shorter code.
This patch goes a bit further than issue 6612 requires, and replaces all kinds of whitespace with standard spaces.
When testing this locally, it actually seemed to slightly improve two existing test-cases (`tracemonkey-text` and `taro-text`).
Fixes 6612.
Currently `getAnnotations` will *only* fetch annotations that are either `viewable` or `printable`. This is "hidden" inside the `core.js` file, meaning that API consumers might be confused as to why they are not recieving *all* the annotations present for a page.
I thus think that the API should, by default, return *all* available annotations unless specifically told otherwise. In e.g. the default viewer, we obviously only want to display annotations that are `viewable`, hence this patch adds an `intent` parameter to `getAnnotations` that makes it possible to decide if only `viewable` or `printable` annotations should be fetched.
In my opinion, this event shouldn't be dispatched in `PDFPageView.cssTransform`, since that would cause *two* events to be fired when "normal" zooming is used (once in `PDFPageView.cssTransform`, and once in `PDFPageView.draw`).
Fixes 6463.
For documents with different page sizes, ensure that the correct page becomes visible on load when e.g. the 'page' hash parameter was provided (bug 1191279, issue 6393)
This is a quick fix to get `scrollIntoView` working again for search results, but we really ought to re-write that function since it seems way too brittle.
Fixes 6596.
This patch contains an alternative solution (see the referenced PRs in 4718), in order for the indeterminate loading bar to have a consistent speed regardless of width.
Fixes 4718.
Currently this constant is present in `viewer.js`, but it is not used there at all. Instead, it is used in `view_history.js` where we have a global for it. We might as well move the constant to `view_history.js` as that is the only place where it is used, thereby removing a global and an unused constant from `viewer.js`.
If your Internet Explorer 11 default compatibility settings are set to "I.E 7 Compatibility", the PDF plugin will not load. This fix is the same one used by AngularJS to force the browser to use HTML5 mode.
*This regressed in PR 5356.*
Rather than just backing out the offending code, this patch restores scrolling in PresentationMode by making the `overflow: hidden;` check optional and letting the callers that need it (e.g. `PDFFindController`) opt-in to use it.
When the user edits the URL and changes the reference fragment (hash),
PDF.js intercepts this action, and saves the then-current history state
in the previous history entry. This is implemented by navigating back,
editing the history and navigating forward again.
The current logic has a flaw: It assumes that calling history.back() and
history.forward() immediately updates the history state. This is however
not guaranteed by the web standards, which states that calling e.g.
history.back "must traverse the history by a delta -1", which means that
the browser must QUEUE a task to traverse the session history, per spec:
http://w3.org/TR/2011/WD-html5-20110113/history.html#dom-history-backhttps://html.spec.whatwg.org/multipage/browsers.html#dom-history-back
Firefox and Internet Explorer deviate from the standards by immediately
changing the history state instead of queuing the navigation.
WebKit derived browsers (Chrome, Opera, Safari) and Opera presto do not.
The user-visible consequence of strictly adhering to the standards in
PDF.js can be shown as follows:
1. Edit the URL.
2. Append #page=2 for example.
3. Press Enter.
-> Presto and WebKit: PDF.js reverts to the previous URL.
-> Gecko and Trident: PDF.js keeps the new URL, as expected.
To fix the issue, modification of the previous history item happens in
a few asynchronous steps, guided by the popstate event to detect when
the history navigation request has been committed.
--
Some more implementation notes:
I have removed the preventDefault and stopPropagation calls, because
popstate is not cancelable, and window is already the last target of the
event propagation.
The previous allowHashChange logic was hard to follow, because it did
not explain that hashchange will be called twice; once during the
popstate handler for history.back() (which will reset allowHashChange),
and again for history.forward() (where allowHashChange will be false).
The purpose of allowHashChange is now more explicit, by incorporating
the logic in the replacePreviousHistoryState helper function.
*This regressed in PR 4920.*
The main motivation for PR 4920 was to quickly get rid of old canvases when pages are evicted from the `PDFPageViewBuffer` cache. However it inadvertently broke the use-case where the `canvas` is used as a preview, on scale or rotation changes, until the re-rendering is finished.
Fixes 6467.
In PR 5552, specifically commit 9f384bbb41, the meaning of `this.annotationLayer` changed in `PDFPageView`. Previously it referred directly to a DOM element, but now it's instead an instance of `AnnotationsLayerBuilder`.
This patch tweaks things so that we won't try to hide a non-existent `annotationLayer` div in `PDFPageView_reset`, and also so that we don't attempt to insert empty (`null`) DOM elements in `PDFPageView_draw`.
*Follow-up to PR 6299.*
This patch reduces unnecessary code duplication for the `canvas` to `image` conversion. It also does a bit of re-ordering (and adds new lines) in `_getPageDrawContext`, since that function currently is a bit hard to read.
Since some browsers render `null` characters, and others don't, this patch adds a way to remove them to prevent display issues in the viewer UI.
Given that documents may contain very long outlines, I've added a utility function to avoid creating a lot of unnecessary `RegExp` objects.
To avoid any future issues, this utility function is used for both the outline and the attachments.
Fixes 6416.
Prior to PR 6242, the width of all outline items was set such that their right (or left, in RTL locales) edges lined up vertically. In my opinion that looked more consistent, therefore this patch adjusts the CSS to make sure that this will be the case again.
The patch also makes the `border-radius` values of outline items a bit more consistent.
This issue is actually, in a sense, "caused" by the fact that the API/viewer supports partial loading/rendering. Previously when the *entire* document was always fetched before rendering begun, we knew all page sizes in advance and this issue didn't exist.
Now we use the size of *one* page in order to set the initial size of every page, until we've fetched the pages and thus know their correct sizes.
This means that during loading the size of the pages can change, which may cause the initial position to become scrolled out of view.
The most naive solution to this problem would perhaps be to delay setting the initial position on load for all documents, until all pages are fetched. However I think that would be a *really* bad idea, since doing so would make the initial rendering slower and make it feel sluggish for most documents.
Since there is generally no way of knowing if a document has different sized pages prior to loading it, we can only check once the pages are available.
Hence this patch, which treats documents with different sized pages as a special case, by re-applying the initial position when all pages have become available.
It appears to me that the `expanded/collapsed` part of the names got switched around, since I'd expect the following convention:
- `v` == expanded
- `>` == collapsed
- This commit adds a '>' before every outline item that has subitems.
- Click on the '>' to collapse all subitems under that item (which turns
the '>' in a 'v').
- Shift + click expands/collapses all descendant items under that tree.
- Double-clicking on the "Show Document Outline" button in the toolbar
expands/collapses all outline items.
The JSON file is generated as follows.
1. Go to the src/chrome/app/resources directory of Chromium's source.
2. Find the translation ID of the "Allow access to file URLs" string:
grep 'Allow access to file URLs' generated_resources_en-GB.xtb
3. With the ID that you've found, locate the other translations.
grep 3341703758641437857 generated_resources_*.xtb
4. If the result looks OK, serialize the result as JSON and save it.
> path/to/pdf.js/web/chrome-i18n-allow-access-to-file-urls.json \
python -c "import json;print(json.dumps({ \
$(grep 3341703758641437857 generated_resources_*.xtb | \
sed "s@generated_resources_\([^.]\+\)\.xtb:<translation[^>]\+>\(.\+\)</translation>@'\1':'''\2''',@" \
)}, sort_keys=True, indent=2))"
(Strings are taken from Chromium 45.0.2448.0 (ccrev.com/337313).
Currently in `switchSidebarView` there is code that attempts to handle the `outline` or `attachments` being disabled. However, given the placement of it, that code does not actually accomplish anything. Even more strange is the fact that the way that the buttons are disabled, that code won't ever be hit.
(Looking back with `git blame`, it seems that it has never worked as you'd expect.)
Hence this patch, which correctly disables switching to the `outline` or `attachments` views when they are disabled.
Once PR 6314 restores the 'pagemode' hash parameter, this patch thus makes it impossible to switch to a disabled sidebar view by modifying the 'pagemode' hash of an already loaded document.
This regressed in 0ef6212b64.
Since the 'pagemode' hash parameter requires certain viewer functionality (e.g. thumbnails and an outline) in order to work, it seemed reasonable to move the functionality from `pdf_link_service.js` into `viewer.js`.
Similar to `namedaction`, this patch makes use of an event to forward the 'pagemode' parameter.
Built-in DOM properties are slower than plain JS properties.
A few lines before, textContent is assigned as follows:
textDiv.textContent = geom.str;
So replacing textDiv.textContent.length with geom.str.length slightly
improves performance without side effects.
Since the zoom value should be in percent, using `PDFViewer.currentScale` will be wrong by a factor of 100, potentially causing the zoom level of the document to become wrong on load.
*This fixes a regression from PR 6192.*
Under some circumstances, the `resize` event handler in `viewer.js` is fired before the scale has been set. This can lead to PDF documents being rendered at the wrong zoom level when they are opened.
It seems that a way to reliably trigger this is to, using the Firefox addon, open a PDF file that triggers the `fallback` bar, in a new background tab (i.e. middle clicking on a link, or use the context menu).
Prior to PR 6192, we checked the selected option in the `scaleSelect` dropdown instead. Since `pageAutoOption` is selected by default in `viewer.html`, this should explain why the issue wasn't visible previously.
Fixes#6106
To avoid future regressions, two new unit tests were added:
1. A new PDF based on the report from #6106, which contains an
OpenAction of type JavaScript and a string "this.print({...}".
2. An existing PDF from https://bugzil.la/1001080 (from #4698).
Although it does not matter, since we don't execute the JavaScript code,
I have also changed "print(true)" to "print({})" since the print method
takes an object (not a boolean). See "Printing PDF documents", page 62:
http://adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/js_developer_guide.pdf
The special handling of the 'custom' scale value is only relevant for the `scaleSelect` dropdown in the standard viewer, hence I think that it should be placed in `viewer.js` instead.
Ordinarily, local files cannot be embedded in a non-local website. Until
this commit, the extension allowed websites to embed local PDF files on
non-local (e.g. http(s)) websites. This unintended feature is now
disabled, to align better with Chrome's existing security policies
(=local file:-URLs cannot be loaded in a tab unless expicitly allowed).
After the creation of `PDFViewer`, its `_resetView` method takes care of resetting, among other things, the page number property. Hence we don't need to set `pdfViewer.currentPageNumber = 1;` here any more, and the comment is no longer accurate either.
*With this patch we're getting very close to fixing 6158.*
The only use-case for `PDFViewerApplication.updateScaleControls` is to try and avoid calling `selectScaleOption` from the `scalechange` event handler in viewer.js.
This will *only* happen when the user has manually changed the scale by using the `<select>` dropdown, which means that in reality this is just a micro optimization. Furthermore, `selectScaleOption` is only skipped for the "named" scale values (e.g. `auto`, `page-actual`, `page-fit`, `page-width`), thus further reducing the value of this code.
Also, since we're updating the scale `<select>` dropdown from an event handler, we're currently depending on the event being dispatched (and handled) completely before the next `scalechange` event. Relying on the execution order of the code in this way, even though it currently works, seems unfortunate since it *could* potentially cause the internal scale value and the UI from getting out of sync.
*This is the next step towards fixing 6158.*
This patch removes the dependency on the state of the scale `<select>` dropdown from the `resize` event handler, and instead uses the (in `PDFViewer`) stored `currentScaleValue`.
I believe that the way this code is currently written is purely for historical reasons, since originally *only* the numerical scale was stored internally (hence there was no other way to access the scale value).
However, since we now store the scale value, we should use it instead of quering the DOM. This helps ensure that the internally stored scale value is always accurately displayed in the UI (which should be good since, after the creation of `PDFViewer`, the `<select>` DOM element is now updated by an event handler).
*The next step towards fixing issue 6158.*
We can just as well access `pdfViewer.currentScaleValue` directly in `PDFViewerApplication`, instead of having a helper function which just acts as a wrapper for it.
Currently if the zoom level is reset multiple times in a row, i.e. by pressing <kbd>Ctrl</kbd>+<kbd>0</kbd>, the pages can be re-rendered each time even though their size shouldn't change. Whether this happens can depend on the size of the viewer, but documents with pages in landscape mode seem to be very susceptible to this. (An example is: https://wiki.mozilla.org/images/5/55/MobileOpportunity.pdf.)
This can also effect documents with pages in portrait mode, when they are displayed in Presentation Mode.
The reason for this unnecessary re-rendering is that due to limited numerical precision, the new scale value may change in *only* the last decimal place.
This is similar to the already existing, separate, CSS file used for the `textLayer`, and it's necessary in order for the `pageviewer` components example to actually show annotations correctly.
Considering that most methods of `SimpleLinkService` are complete stubs, or practically "useless" considering what they return, we can actually simplify it even more.
*Note:* This depends on the previous patch, that did a small amount of refactoring of `PDFViewer_scrollPageIntoView`, since `PDFViewer.linkService.page` is no longer accessed.
----------
Currently the `pageviewer` components example doesn't work correctly (an error is printed in the console), since no `linkService` is present when the `AnnotationsLayerBuilder` is created.
*Note:* Given that this uses the `SimpleLinkService`, clicking on e.g. internal links won't actually do anything. However, given that internal links (and similar features) are pretty much useless when only *one* page is loaded the `pageviewer` example, I don't think that really matters.
Also, using the complete `PDFLinkService` would require a `PDFViewer` instance. That would significantly complicate the example, thus making it both less clear and less self contained.
Currently in `PDFViewer_scrollPageIntoView`, we're accessing a number of properties in an indirect and overly complicated way. In particular, using `this.linkService.page` is a *very* roundabout way to access `this.currentPageNumber`.
The reason for this appears to be entirely historical, since prior to PR 5361 the code was placed in `PDFPageView` (or `PageView` as it was called at the time).
This patch is the the first step towards to addressing issue 6158, which will be done by refactoring the code for setting/getting the current scale in `viewer.js`.
Before this patch, zooming in/out via the scroll wheel caused the page
to be zoomed relative to the upper-left corner of the page, i.e. the
upper-left corner of the page stays at a fixed position.
After this patch, the page is zoomed relative to the cursor position,
i.e. after zooming in/out, the part under the cursor 'has not moved'.
This only applies when the page does not fit in the viewport, because
pages smaller than the viewpoer are always centered.
In `viewer.js` we have code that ensures that the document is re-rendered on zooming and rotation. However, for `components` based viewers this might not work correctly, since there's currently no code which handles that.
Note that there is a good chance that this "just works" in many `components` viewers already, thanks to the `watchScroll` function.
The explanation is that zooming or rotation, most of the time, causes the viewer to change its (scrollable) size, thus triggering `PDFViewer_update` through `PDFViewer_scrollUpdate`.
However, in general there's no guarantee that this will actually work (since zooming and rotation doesn't necessarily change the size of the viewer for all documents), and requiring every viewer `components` implementer to provide methods for this doesn't seem like a great idea.
The reason that this code can be moved is that the `if (this.loading && page === 1)` check, in the `pagechange` event handler in viewer.js, is never satisfied since `this.loading` is not defined in that scope.
This *could* be considered a regression from PR 5295, since prior to that `this.loading` was using the `PDFViewerApplication` scope (or `PDFView` as it were).
However, I don't think that we need to fix that since we've been shipping this code in no less than *three* Firefox releases (uplifted in https://bugzilla.mozilla.org/show_bug.cgi?id=1084158), without breaking the world.
An explanation of why the `pagechange` code works, despite `this.loading === undefined`, is that `set currentPageNumber` (in `PDFViewer`) returns early whenever `this.pdfDocument` isn't set. This check is, for all intents and purposes, functionally equivalent to checking `PDFViewerApplication.loading`.
Hence we can move the page switching code into `PDFViewer`, and also remove `PDFViewerApplication.loading` since it's not used any more.
(The `this.loading` property was added in PR 686, which was before the current viewer even existed.)
*Note:* The changes in this patch should also be beneficial to the viewer `components`, since requiring every implementer to provide their own `pagechange` event handler just to get `PDFViewer.currentPageNumber` to actually work seems like an unnecessary complication.
Fixes https://bugzilla.mozilla.org/show_bug.cgi?id=1170063.
The bug only mentions the <kbd>Meta</kbd> key, but given that a similar situation can occur for <kbd>Ctrl</kbd>, it seemed reasonable to also handle that case in the same patch.
The only possible caveat with the patch is that because of the use of `shadow`, things won't work perfectly if either of the prefs are changed *while* the viewer is active. In this case a reload is required in order for it to work correctly, but given that the issue this patch fixes should be quite rare anyway, that seems OK.
Currently `PDFLinkService` requires access to a `PDFHistory` instance in order for it to work correctly (and to avoid errors). If we want `PDFLinkService` to be more useful in custom viewers, I don't think that we actually want to force it to have a `PDFHistory` instance.
Hence this patch, which contains a very simply approach to make `PDFHistory` optional.
Reuse the existing getOutputScale() machinery to render and/or rescale
thumbnail images to the native display resolution. Fixes blurry thumbnails on
HiDPI displays making it a lot easier to make out the content.