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.