Giter Site home page Giter Site logo

pdftron / webviewer-ui Goto Github PK

View Code? Open in Web Editor NEW
397.0 36.0 344.0 105 MB

WebViewer UI built in React

License: Other

JavaScript 86.52% HTML 0.09% SCSS 6.89% TypeScript 6.50%
pdf-viewer react react-pdf office-viewer webviewer webviewer-ui react-pdf-viewer pdf-editor

webviewer-ui's Introduction

WebViewer UI

WebViewer UI sits on top of WebViewer, a powerful JavaScript-based PDF Library that's part of the Apryse PDF SDK. Built in React, WebViewer UI provides a slick out-of-the-box responsive UI that interacts with the core library to view, annotate and manipulate PDFs that can be embedded into any web project.

WebViewer UI

This repo is specifically designed for any users interested in advanced customizations. With the source code access, it gives developers full control to customize & style the UI, build custom controls & logic, integrate into workflows, or build a UI from scratch.

Any approved pull requests made to this repository are merged into WebViewer's internal builds, and can be accessed through the nightly builds. Any approved pull requests to the master branch will go to WebViewer's nightly experimental builds and pull requests to version number branches will go to that version's nightly stable.

Nightly stable and experimental builds can also be downloaded from WebViewer's NPM package.

Install

npm install

Install WebViewer Core Dependencies

The preferred method to install the Core dependencies is to use the WebViewer NPM package.

Once installed, copy the Core folder into the path being used by the viewer for its dependencies (/lib by default).

Run

npm start

Build

npm run build

Troubleshooting

If you are using NPM version 7 or higher, you may get an error indicating an issue with the dependency tree. There are two possible solutions for this:

  • Downgrade your version of Node to v14, which uses NPM version 6.
  • When running npm install add the flag --legacy-peer-deps. You can read more about this flag in this Stack Overflow post.

Project structure

src/
  apis/            - APIs exposed in myWebViewer.getInstance()
  components/      - React components
  constants/       - JavaScript or CSS constants
  core/            - APIs from the Core
  event-listeners/ - Listeners for the Core events
  helpers/         - Reused functions
  redux/           - Redux files for state managing
  lib/             - Lib folder created upon npm install, used for dev testing only

API documentation

See API documentation.

Contributing

See contributing.

License

See license.

webviewer-ui's People

Contributors

achenpdftron avatar andreysaf avatar awy2 avatar awy3 avatar bollain avatar daneverso avatar dependabot[bot] avatar difel110185 avatar edwinkorsten avatar jamesjypark avatar jiaqihuang-233 avatar jimmylin39 avatar jniemin avatar justinjung04 avatar khein-pdftron avatar kristianhein avatar lbittner-pdftron avatar liamross avatar luketully-pdftron avatar martis347 avatar mithyb avatar mparizeau-pdftron avatar naueramant avatar s0uldrag0n avatar sabieber avatar sisardor avatar wanboli avatar webviewer-ui avatar zhijiezhang avatar zsydyc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

webviewer-ui's Issues

Sporadic and incorrect Annotation placement in certain PDFs in IE11

This may be more for your internal support, but it also seems to be Webviewer centric (possibly in service workers or something, also). Let me know if I should retry there.

Link to PDF exhibiting behavior: https://pdfmarkupblobstore.blob.core.windows.net/sample-container/link_2pages.pdf

Symptom: In IE 11, annotations loaded from external file with the demo.pdftron.com server do not load correctly.
Correct Loading in Chrome (Messed up the loading modal with CSS, sorry):
chromeproperload

Incorrect Loading in IE11:
ie11demoserverload

In IE11: Using PDFNetJS loads the same file/annots perfectly. Demo server does not.
In Chrome: All annots load perfectly. (PdfNetJS and demo.pdftron.com)

Repro Steps:

  1. Use my PDF Url or download it.
  2. Create annotations and save them in separate XFDF.
  3. Load PDF with demo server/blackbox 'doctype'/ pdftronServer 'engineType'/setServerUrl(null)
  4. Load XFDF after 'DocumentLoaded' event (here is how we do it):
    (window as any).docViewer.on('documentLoaded', this.loadXfdf.bind(this, store));
    Which ends up calling - annotationManager.importAnnotationsAsync(xfdfString, callback, options);

Notes:
Possibly clashing with the annots.xfdf call that seems to come with XOD download?
Possibly Scaling issue for this type of PDF?
Possibly from PDF origin? Pdf was made in Microstation, we did create a very simplePDF in Microstation and had similar issues. PDFs from AutoCad did not seem to have this issue.

Print option in drop down does not work most of the time

In the beta you had a PrintModal that popped up when you hit print. That seems to still exist, but it either is no longer hooked up (it definitely seemed unfinished at the time) or is for different cases than we are using. I honestly haven't looked into that too much.

However, if you just open up https://www.pdftron.com/webviewer/demo/

  1. Attempt to print the default PDF you display in just about any browser.
  • Results
    -- Chrome opens new tab and shows 'preparing to print'. Sometimes it actually shows the Chrome Print popup...but not usually.
    -- Firefox does pretty much the same thing. Opens a new tab and does nothing.
    -- IE11 displays the loading modal indefinitely
    -- Edge displays the loading modal indefinitely

Expected Behavior: Printing displays modal or opens up browser specific print dialog that allows user to print the PDF.

Disabling pageNavOverlay causes JavaScript error in PageNavOverlay.js

The recent commit "[bugfix] Fixed where current page number is cut off on the side in Edge" broke the ability to disable the pageNavOverlay. Now if you specify that as part of disabledElements, you'll get a JavaScript error with this code:

this.textInput.current.style.width = (this.props.totalPages.toString().length * 11.5) + 'px';

As this.textInput.current is null.

Change events are not including necessary data

For example pageChanged, zoomChanged, toolModeChanged, etc we are simply firing the event and not including the page number, zoom level or toolmode. These events are used by the webviewer.js wrapper and this should be updated to match the behavior of the legacy UI.

setNotesPanelSort won't trigger resorting

Calling the function multiple times with different or altered objects (e.g. for applying filters) won't retrigger the sorting/displaying of the annotations in the annotations panel.

Improvement to Notes Panel Reply Open/Closed states

Reply text box should remain open if you click off or onto the the PDF as long as you do not select another annotation.

If there are a lot of annotations and you click off it makes every annotation look the same (closed state), so it can be hard to tell where you were just typing. Also, since you have many annotations, any usage of the mousewheel to scroll will scroll the Notes Panel instead of the document, so you must click out to scroll (which makes you lose your annotation in the list).

Could be something for individual users to sort out, but we thought it was more of an overall improvement to the UI.

The text area / text box in question:

image

Global onkey listeners interfering with normal use

Key listeners are causing problems when using other parts of the application.

Example/How to reproduce

  1. Create an annotation
  2. Open the notes panel
  3. Create several comments on the annotation
  4. Try to copy text from another comment using ctrl + C and try to paste it into the reply text area with ctrl + V. You should notice that you have ended up creating a copy of the annotation that was selected.

We noticed this when implementing a custom modal and these actions were being performed behind our modal. If there is a way to avoid these issues that would be helpful.

PDF document is requested twice when calling loadDocument from viewerLoaded event

To reproduce don't set the initialDoc parameter and have code like the following in a config file:

$(document).on('viewerLoaded', function() {
  var fileUrl = 'https://pdftron.s3.amazonaws.com/downloads/pl/webviewer-demo-annotated.pdf';
  readerControl.loadDocument(fileUrl);
});

You can see from the network tab that the document is requested twice. This seems to be happening because first loadDocument has been called from the config file and it calls actions.setDocumentPath to set the path on redux state. It then needs to do some asynchronous things before it actually calls core.loadAsync.

At this point DocumentContainer still hasn't actually rendered yet. While the asynchronous things are happening DocumentContainer mounts and componentDidMount is called. Inside there it checks if "hasPath" is true and then calls loadDocument.

One possibility to fix this is to distinguish between initialDoc and document path. So that componentDidMount only looks for initialDoc on the state and not a path that would have been set later.

API for customizing page number labels

Some books start their page numbers with Roman Numerals and then 1, 2, 3... API is requested to make this customization possible so that users won't be confused for page numbers not matching correctly.

Notes Panel Annotation/Reply Text Improvements

As seen on Demo website:

When typing text in the NotesPanel you receive the 'red squiggles' indicating misspelled words (among other things). Usually the normal context menu for the browser would display and allow you to change the word, but since you override the menu it just shows the Document Container context menu.

I would think that for the panels, you would allow the normal browsers menu to show instead of the PDF context menus.

Examples:

image

image

API for customizing thumbnails in thumbnail panel

As already discussed in the google group (topic) we need an API for customizing the rendered content of the Thumbnails in the ThumbnailsPanel.

In my opinion it would be best for everyone if this was a generic API that could be used by a lot of users so I would like to implement such API.

Would there be requirements that I need to match so the proposed API would be merged by you?

My first idea would be a setter for providing an activator/customizor function that is called when a Thumbnail is rendered to alter the DOM contents. Does this sound like a good idea for general use?

What we really need is to display two small buttons next to the page number on the Thumbnail (one for download and one for another feature of our customized viewer).

Loader is jittery in IE/Edge

Looks like IE and (to a smaller degree) Edge cannot render a perfect circle through animations. If you hold the loader up for very long in IE you can really tell that there is a lot of jitter.

We have tried to implement some ad-hoc buttons and header items that display loaders until the information is ready. Trying to keep with the same style, we used the CSS for your loader (so the problem crops up more often for us). This is something that could definitely be fixed on our end, but I thought it might be something you might want to change, also. We'd like to keep with your style whenever possible.

Here's the best SO post I found:
https://stackoverflow.com/questions/34597433/css-rotation-in-ie-is-jittery

Possible unintended re-rendering with importAnnotationsAsync()

V4.0.2.68331
In Chrome

Load annotation file (*.xfdf) with multiple annotations using 'importAnnotationsAsync()' Note this may apply to other functions also. For every annotation imported the OnAnnotationChanged event triggers.

In the NotesPanel, at least for us, this triggers a re-render of every note in the notespanel for each annotation imported. So, if we have 30 annotations in the .XFDF, the NotesPanel re-renders 30 times.

We haven't put a whole lot of thought into the consequences of this, or how this actually affects performance with a lot of annotations for us. However, I would think that the NotesPanel should only re-render a single note at a time when each is imported. It seems that the full list of annotations are sent in the Change event (hence every annotation is re-rendered).

As an addition, when an 'onAnnotationChanged()' event triggers in the notes panel, you grab the unsorted annotations from 'Core' and then sort the entire list for every event. Meaning, not only are you re-rendering 30 times, but you are also re-sorting the exact same list of annotations 30 times the exact same way.

So, this may be intended and we may be over-analyzing the situation, but if not I felt it worth asking the question here. It's difficult to reproduce the exact scenario for each of our problems on your base viewer, so let me know if there's anything else I can supply.

We have debated keeping a stateful list of notes in the NotesPanel and using an 'insert/delete' function for each new mutation to the list after the initial and each subsequent sort. However, like i said we haven't yet come across any significant performance problems related to this as of yet. We will likely test this out with a large annotation set our next sprint.

getPassword callback

The getPassword callback to automatically pass in the pdf password and bypass the user prompt does not work in the new UI - if we use the legacy UI it works as expected.

Is this call back still available in the new UI and if so how do we use it, can’t find anything in the docs?

Swiping on mobile devices in double page mode only changes by single page

When using the WebViewer on a mobile device in double page mode a swipe should result in turing to the next double page so going from page 2 to page 4.
Instead currently it only goes from 2 to 3 in a single page resulting in the user to having to swipe twice to actually see the next pages.

Opacity Slider vanishes after dragging it to 0%

Result

Annotation is invisible and there is no way to make it visible again. Only option is to delete and recreate the annotation possibly losing all replies added to the annotation.

Steps to reproduce

  1. Open the WebViewer Demo
  2. Create any annotation with the possibility to change opacity (e.g. Rectangle)
  3. Open the style options popup
  4. Drag the opacity slider to the left until 0% is hit
  5. Slider vanishes and won't reappear when reopening the popup

Possible improvement to Annotation Popup behavior

On current Demo Viewer -

  1. Create Rectangle Annotation
  2. Select the same annotation
  3. Click again on the annotation (in between the white circle indicators on the annot).
  4. Annotation Popup disappears

Popup only reappears if you click on the white indicators while still selected.

Possible Desired/expected functionality -
Clicking anywhere on the selected annotation pops up the menu. Popup only goes away if one of it's button's are clicked.

Users had a very hard time getting back the popup until they were able to figure out clicking on the white indicators got it back. We had a few complain about it until we explained the usage.


Also, possibly separate issue -
You are unable to recover back to the popup form the style menu. The only way to get out of the popup style menu is to click off the menu. A small back or X button somewhere would allow the user to backtrack and keep the annotation selected.

Have priority for enable/disableElements

Elements that have been enabled/disabled by calling viewerInstance.enable/disableElements should have higher priority than calling enable/disable feature related APIs.
For example:

viewerInstance.disableElement('stickyToolButton'); 
viewerInstance.enableAnnotations(); // stickyToolButton should still be disabled

API for adding custom modals or popups

I really like the new API for adding custom panels to the left panel.
Could you add something similar for modals and popups so APIs like closeElement and openElement can be accessed there too?

When loading document via 'Downloader' option, SetPages Action may be called incorrectly

Note, this may also happen when using XOD and/or PDFTron Server option, also.
Also note that this is not currently causing any problems on my end besides being a little annoying during document download, yet my brain says it could possibly be an issue somewhere now or down the line.

When loading with downloader option, SetPages is continually hit (most likely each new downloaded chunk triggers this) and updates the Redux store. However, every action just sets the page count to the same page.

So if you have a 650 page 150MB document and are running with the logger on you just see a ton of 'SET_PAGES = 650'. The action never actually updates the page count because the very first call sets it to the last possible page via the downloaded meta data in the PDF (I believe).

There are a couple possible problems with this:

  1. Redux store is updated numerous times and is at least a miniscule performance hit during one of the more crucial times in the application. (Edit: I guess the store would only truly be updated when mutated?)
  2. Redux store is continually updated with redundant and/or incorrect information. Since the page count is being set to the very last page, I assume that this page count is used in other calculations and is user facing via the page indicator in the bottom left.
    image

Since the last page (in this case page 650) will not download for another 20-30 seconds it may give the user a false sense of what he can do in the document and could possibly be the source of some bugs.

So, if you keep the trigger to continually set the pages, it may be better set them incrementally as they download (if possible). This might trigger more UI updates since the page count would continually rise with each chunk.

If you don't, then you might be able to just set the page count once to 650 instead of on every chunk downloaded.

I guess it really depends on how your Core works.

Improve mobile usability

  1. Prevent swipe from happening when we are not in default tool mode
  2. Turn off auto switch when using tablet/mobile devices and instead having a button to manually switch between text select and default tool mode

Callout annotation broken when it's a single line

Version 4.0.2.68331 of Webviewer
In Chrome

Only seems to break when creating a callout with a single line:

  1. Select callout annotation tool
  2. Click on a document to start annotation
  3. Double click somewhere on the document to end the annotation.
  4. No text box appears, cannot select callout, callout disappears and is not saved/exported.

File extension check should ignore URL query string

When creating a PDFTron.WebViewer instance, if pdftronServer is set and initialDoc points to a URL with query string parameters (cache busting, etc) the browser dev tools get spammed with an error about an invalid file extension.

The file extension check should be chopping off the URL query string before trying to determine the file extension.

Thumbnails do not always render for PDF files

Repro Steps - v1 React UI

First:

  1. https://www.pdftron.com/webviewer/demo/
  2. Grab almost any PDF on your computer and upload it via the 'Open file' menu.
  3. Watch as no thumbnails are rendered.

Most of the PDFs loaded by 'Open by url' work decently.

Second:
In our modified version v1 (v4?) webviewer UI, we cannot get any PDFs to load thumbnails. In the beta UI, everything loaded just fine.

Our webviewer constructor -

    ` <script src='~/webviewer.min.js'></script>
    <script>
      var myWebViewer = new PDFTron.WebViewer({
          path: './',
          html5Path: './ui/index.html',
          l: 'Our license',
          enableAnnotations: true,
          documentType: "pdf",
          showLocalFilePicker: true
      }, 
      document.getElementById('pdfViewer'));        
      </script>`

Extra settings we are using -

(window as any).readerControl.enableAnnotations();
store.dispatch(actions.setDocumentPath(url));  // This is to any PDF url
store.dispatch(actions.setDocumentType("pdf"));
store.dispatch(actions.setEngineType('pdfnetjs'));
store.dispatch(actions.setUseDownloader(false));
store.dispatch(actions.setServerUrl(null));
store.dispatch(actions.openElement('loadingModal'));
loadDocument(store.getState(), store.dispatch);

So, for us NO pdf will display rendered thumbnails at all. And your demo viewer only displays them when loading from a URL, but not from a local file.

I've only tested in Chrome. I'm not sure if the demo issue is associated with us not being able to view any thumbnails or not, but it seems like it is. I have not reproduced this specifically in the open source version of the UI, so let me know if I need to give you more information.

Also, this might not specifically be related to the UI, so my apologies if this issue is errant.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.