Integrating PDFTron into Ontra

image description

SHARE THIS ARTICLE

Published On
image description
Engineering

By Carmen Wick, Lead Front-End Engineer at Ontra

PDFTron is one of our most critical third-party libraries at Ontra. It’s responsible for displaying all PDF documents in the application and managing the highlighting of key document clauses.

Compared to our previous PDF library, PDFTron is significantly faster and handles a wider variety of materials — for example, documents rotated by a few degrees (a common occurrence in poorly scanned documents).

After deciding to switch to PDFTron, I needed to find the best way to integrate this library into our Ember application. I came up with the following technical requirements:

  • Full control over the position and style of the PDF viewer and full control over the viewer controls and the ability to implement custom controls.
  • The ability to use the PDF viewer in many different places in the application and not have to know any details about PDFTron to do so.
  • Fault tolerance — if the PDFTron library throws an exception, it shouldn’t crash the entire application.
  • Only open when necessary; the PDFTron library shouldn’t load until it is actually needed (when the user starts viewing a PDF document).

PDFTron offers two ways to integrate their web PDF library. You can use their pre-made PDF Viewer UI or roll your own UI. With the first method, you embed their PDF Viewer app into your page using a JS snippet, and you get a full-featured PDF viewer and editor. This is called Webviewer UI. The UI offers some degree of customization, such as the ability to hide certain buttons or change the color scheme, but you’re pretty much stuck with what the UI provides.

By rolling your own UI, you bypass the default UI completely and use what they call the Core engine. Using the Core engine gets you a PDF viewer with all of the built-in UI elements removed. Since I wanted full control over the UI, I opted for the second method and used the PDFTron Core engine directly.

Wrapping PDFTron into the system

There are two parts of our PDFTron integration: a PDF Viewer iframe and an Ember component.

The iframe is the part that loads the PDFTron JavaScript library. This library is actually a thin wrapper around a WebAssembly module that does the actual PDF rendering. The reasons for loading the library in an iframe are twofold. The first is isolation; PDFTron likes to create a lot of new properties on the global window object, so loading in an iframe keeps our global namespace clean and protects against crashes and bugs in the library. The second is to guard against memory leaks. When it comes time to unload the library, all we have to do is destroy the iframe to automatically free all resources used by the PDFTron library.

The other part of the PDFTron integration is a custom Ember component. It encapsulates all the details of initializing the iframe and provides a nice declarative Ember component interface for displaying PDF documents. This is responsible for translating components’ args into PDFTron library calls. For example, when setting the @url arg, the Ember component calls the appropriate methods in the PDFTron library to load and display a new document from a URL.

Note that our PDF viewer Ember component doesn’t expose any kind of UI, such as page navigation or search. These UI elements are implemented in separate components which use the programmatic interface exposed by the PDF viewer component to do their work. This allows us a great deal of flexibility when designing and testing PDF navigation components.

We’ve been using PDFTron in production for over a year with no major issues. Now, we can handle documents over 1,300 pages long. PDFTron displays them with excellent performance. In the future, we may leverage other PDFTron features, such as the ability to edit documents right from the browser. In all, PDFTron is a tremendous addition to our stack, and I’m looking forward to its future within Ontra.

Interested in becoming a part of Ontra?