diff --git a/web/pdf_attachment_viewer.js b/web/pdf_attachment_viewer.js
index 3720b4751..62c957b21 100644
--- a/web/pdf_attachment_viewer.js
+++ b/web/pdf_attachment_viewer.js
@@ -30,16 +30,13 @@ import {
  * @property {Array|null} attachments - An array of attachment objects.
  */
 
-/**
- * @class
- */
-var PDFAttachmentViewer = (function PDFAttachmentViewerClosure() {
+class PDFAttachmentViewer {
   /**
-   * @constructs PDFAttachmentViewer
    * @param {PDFAttachmentViewerOptions} options
    */
-  function PDFAttachmentViewer(options) {
+  constructor(options) {
     this.attachments = null;
+
     this.container = options.container;
     this.eventBus = options.eventBus;
     this.downloadManager = options.downloadManager;
@@ -49,152 +46,145 @@ var PDFAttachmentViewer = (function PDFAttachmentViewerClosure() {
       this._appendAttachment.bind(this));
   }
 
-  PDFAttachmentViewer.prototype = {
-    reset: function PDFAttachmentViewer_reset(keepRenderedCapability) {
-      this.attachments = null;
+  reset(keepRenderedCapability = false) {
+    this.attachments = null;
 
-      // Remove the attachments from the DOM.
-      this.container.textContent = '';
+    // Remove the attachments from the DOM.
+    this.container.textContent = '';
 
-      if (!keepRenderedCapability) {
-        // NOTE: The *only* situation in which the `_renderedCapability` should
-        //       not be replaced is when appending file attachment annotations.
-        this._renderedCapability = createPromiseCapability();
-      }
-    },
-
-    /**
-     * @private
-     */
-    _dispatchEvent:
-        function PDFAttachmentViewer_dispatchEvent(attachmentsCount) {
-      this.eventBus.dispatch('attachmentsloaded', {
-        source: this,
-        attachmentsCount: attachmentsCount,
-      });
+    if (!keepRenderedCapability) {
+      // NOTE: The *only* situation in which the `_renderedCapability` should
+      //       not be replaced is when appending file attachment annotations.
+      this._renderedCapability = createPromiseCapability();
+    }
+  }
+
+  /**
+   * @private
+   */
+  _dispatchEvent(attachmentsCount) {
+    this.eventBus.dispatch('attachmentsloaded', {
+      source: this,
+      attachmentsCount,
+    });
 
-      this._renderedCapability.resolve();
-    },
+    this._renderedCapability.resolve();
+  }
 
-    /**
-     * @private
-     */
-    _bindPdfLink(button, content, filename) {
-      if (PDFJS.disableCreateObjectURL) {
-        throw new Error('bindPdfLink: ' +
-                        'Unsupported "PDFJS.disableCreateObjectURL" value.');
+  /**
+   * @private
+   */
+  _bindPdfLink(button, content, filename) {
+    if (PDFJS.disableCreateObjectURL) {
+      throw new Error('bindPdfLink: ' +
+                      'Unsupported "PDFJS.disableCreateObjectURL" value.');
+    }
+    var blobUrl;
+    button.onclick = function() {
+      if (!blobUrl) {
+        blobUrl = createObjectURL(content, 'application/pdf');
       }
-      var blobUrl;
-      button.onclick = function() {
-        if (!blobUrl) {
-          blobUrl = createObjectURL(content, 'application/pdf');
-        }
-        var viewerUrl;
-        if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {
-          // The current URL is the viewer, let's use it and append the file.
-          viewerUrl = '?file=' + encodeURIComponent(blobUrl + '#' + filename);
-        } else if (PDFJSDev.test('CHROME')) {
-          // In the Chrome extension, the URL is rewritten using the history API
-          // in viewer.js, so an absolute URL must be generated.
-          // eslint-disable-next-line no-undef
-          viewerUrl = chrome.runtime.getURL('/content/web/viewer.html') +
-            '?file=' + encodeURIComponent(blobUrl + '#' + filename);
-        } else if (PDFJSDev.test('FIREFOX || MOZCENTRAL')) {
-          // Let Firefox's content handler catch the URL and display the PDF.
-          viewerUrl = blobUrl + '?' + encodeURIComponent(filename);
-        }
-        window.open(viewerUrl);
-        return false;
-      };
-    },
-
-    /**
-     * @private
-     */
-    _bindLink:
-        function PDFAttachmentViewer_bindLink(button, content, filename) {
-      button.onclick = function downloadFile(e) {
-        this.downloadManager.downloadData(content, filename, '');
-        return false;
-      }.bind(this);
-    },
-
-    /**
-     * @param {PDFAttachmentViewerRenderParameters} params
-     */
-    render: function PDFAttachmentViewer_render(params) {
-      params = params || {};
-      var attachments = params.attachments || null;
-      var attachmentsCount = 0;
-
-      if (this.attachments) {
-        var keepRenderedCapability = params.keepRenderedCapability === true;
-        this.reset(keepRenderedCapability);
+      var viewerUrl;
+      if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {
+        // The current URL is the viewer, let's use it and append the file.
+        viewerUrl = '?file=' + encodeURIComponent(blobUrl + '#' + filename);
+      } else if (PDFJSDev.test('CHROME')) {
+        // In the Chrome extension, the URL is rewritten using the history API
+        // in viewer.js, so an absolute URL must be generated.
+        // eslint-disable-next-line no-undef
+        viewerUrl = chrome.runtime.getURL('/content/web/viewer.html') +
+          '?file=' + encodeURIComponent(blobUrl + '#' + filename);
+      } else if (PDFJSDev.test('FIREFOX || MOZCENTRAL')) {
+        // Let Firefox's content handler catch the URL and display the PDF.
+        viewerUrl = blobUrl + '?' + encodeURIComponent(filename);
       }
-      this.attachments = attachments;
+      window.open(viewerUrl);
+      return false;
+    };
+  }
 
-      if (!attachments) {
-        this._dispatchEvent(attachmentsCount);
-        return;
-      }
+  /**
+   * @private
+   */
+  _bindLink(button, content, filename) {
+    button.onclick = () => {
+      this.downloadManager.downloadData(content, filename, '');
+      return false;
+    };
+  }
 
-      var names = Object.keys(attachments).sort(function(a, b) {
-        return a.toLowerCase().localeCompare(b.toLowerCase());
-      });
-      attachmentsCount = names.length;
-
-      for (var i = 0; i < attachmentsCount; i++) {
-        var item = attachments[names[i]];
-        var filename = removeNullCharacters(getFilenameFromUrl(item.filename));
-
-        var div = document.createElement('div');
-        div.className = 'attachmentsItem';
-        var button = document.createElement('button');
-        button.textContent = filename;
-        if (/\.pdf$/i.test(filename) && !PDFJS.disableCreateObjectURL) {
-          this._bindPdfLink(button, item.content, filename);
-        } else {
-          this._bindLink(button, item.content, filename);
-        }
+  /**
+   * @param {PDFAttachmentViewerRenderParameters} params
+   */
+  render(params = {}) {
+    var attachments = params.attachments || null;
+    var attachmentsCount = 0;
 
-        div.appendChild(button);
-        this.container.appendChild(div);
-      }
+    if (this.attachments) {
+      var keepRenderedCapability = params.keepRenderedCapability === true;
+      this.reset(keepRenderedCapability);
+    }
+    this.attachments = attachments;
 
+    if (!attachments) {
       this._dispatchEvent(attachmentsCount);
-    },
-
-    /**
-     * Used to append FileAttachment annotations to the sidebar.
-     * @private
-     */
-    _appendAttachment: function PDFAttachmentViewer_appendAttachment(item) {
-      this._renderedCapability.promise.then(function (id, filename, content) {
-        var attachments = this.attachments;
-
-        if (!attachments) {
-          attachments = Object.create(null);
-        } else {
-          for (var name in attachments) {
-            if (id === name) {
-              return; // Ignore the new attachment if it already exists.
-            }
+      return;
+    }
+
+    var names = Object.keys(attachments).sort(function(a, b) {
+      return a.toLowerCase().localeCompare(b.toLowerCase());
+    });
+    attachmentsCount = names.length;
+
+    for (var i = 0; i < attachmentsCount; i++) {
+      var item = attachments[names[i]];
+      var filename = removeNullCharacters(getFilenameFromUrl(item.filename));
+
+      var div = document.createElement('div');
+      div.className = 'attachmentsItem';
+      var button = document.createElement('button');
+      button.textContent = filename;
+      if (/\.pdf$/i.test(filename) && !PDFJS.disableCreateObjectURL) {
+        this._bindPdfLink(button, item.content, filename);
+      } else {
+        this._bindLink(button, item.content, filename);
+      }
+
+      div.appendChild(button);
+      this.container.appendChild(div);
+    }
+
+    this._dispatchEvent(attachmentsCount);
+  }
+
+  /**
+   * Used to append FileAttachment annotations to the sidebar.
+   * @private
+   */
+  _appendAttachment(item) {
+    this._renderedCapability.promise.then(function (id, filename, content) {
+      var attachments = this.attachments;
+
+      if (!attachments) {
+        attachments = Object.create(null);
+      } else {
+        for (var name in attachments) {
+          if (id === name) {
+            return; // Ignore the new attachment if it already exists.
           }
         }
-        attachments[id] = {
-          filename: filename,
-          content: content,
-        };
-        this.render({
-          attachments: attachments,
-          keepRenderedCapability: true,
-        });
-      }.bind(this, item.id, item.filename, item.content));
-    },
-  };
-
-  return PDFAttachmentViewer;
-})();
+      }
+      attachments[id] = {
+        filename,
+        content,
+      };
+      this.render({
+        attachments,
+        keepRenderedCapability: true,
+      });
+    }.bind(this, item.id, item.filename, item.content));
+  }
+}
 
 export {
   PDFAttachmentViewer,
diff --git a/web/pdf_outline_viewer.js b/web/pdf_outline_viewer.js
index 5a2052b6a..42fc90e51 100644
--- a/web/pdf_outline_viewer.js
+++ b/web/pdf_outline_viewer.js
@@ -17,7 +17,7 @@ import {
   addLinkAttributes, PDFJS, removeNullCharacters
 } from './pdfjs';
 
-var DEFAULT_TITLE = '\u2013';
+const DEFAULT_TITLE = '\u2013';
 
 /**
  * @typedef {Object} PDFOutlineViewerOptions
@@ -31,194 +31,187 @@ var DEFAULT_TITLE = '\u2013';
  * @property {Array|null} outline - An array of outline objects.
  */
 
-/**
- * @class
- */
-var PDFOutlineViewer = (function PDFOutlineViewerClosure() {
+class PDFOutlineViewer {
   /**
-   * @constructs PDFOutlineViewer
    * @param {PDFOutlineViewerOptions} options
    */
-  function PDFOutlineViewer(options) {
+  constructor(options) {
     this.outline = null;
     this.lastToggleIsShow = true;
+
     this.container = options.container;
     this.linkService = options.linkService;
     this.eventBus = options.eventBus;
   }
 
-  PDFOutlineViewer.prototype = {
-    reset: function PDFOutlineViewer_reset() {
-      this.outline = null;
-      this.lastToggleIsShow = true;
-
-      // Remove the outline from the DOM.
-      this.container.textContent = '';
-      // Ensure that the left (right in RTL locales) margin is always reset,
-      // to prevent incorrect outline alignment if a new document is opened.
-      this.container.classList.remove('outlineWithDeepNesting');
-    },
-
-    /**
-     * @private
-     */
-    _dispatchEvent: function PDFOutlineViewer_dispatchEvent(outlineCount) {
-      this.eventBus.dispatch('outlineloaded', {
-        source: this,
-        outlineCount: outlineCount
+  reset() {
+    this.outline = null;
+    this.lastToggleIsShow = true;
+
+    // Remove the outline from the DOM.
+    this.container.textContent = '';
+
+    // Ensure that the left (right in RTL locales) margin is always reset,
+    // to prevent incorrect outline alignment if a new document is opened.
+    this.container.classList.remove('outlineWithDeepNesting');
+  }
+
+  /**
+   * @private
+   */
+  _dispatchEvent(outlineCount) {
+    this.eventBus.dispatch('outlineloaded', {
+      source: this,
+      outlineCount,
+    });
+  }
+
+  /**
+   * @private
+   */
+  _bindLink(element, item) {
+    if (item.url) {
+      addLinkAttributes(element, {
+        url: item.url,
+        target: (item.newWindow ? PDFJS.LinkTarget.BLANK : undefined),
       });
-    },
-
-    /**
-     * @private
-     */
-    _bindLink: function PDFOutlineViewer_bindLink(element, item) {
-      if (item.url) {
-        addLinkAttributes(element, {
-          url: item.url,
-          target: (item.newWindow ? PDFJS.LinkTarget.BLANK : undefined),
-        });
-        return;
-      }
-      var self = this, destination = item.dest;
+      return;
+    }
+    var destination = item.dest;
 
-      element.href = self.linkService.getDestinationHash(destination);
-      element.onclick = function () {
-        if (destination) {
-          self.linkService.navigateTo(destination);
-        }
-        return false;
-      };
-    },
-
-    /**
-     * @private
-     */
-    _setStyles: function PDFOutlineViewer_setStyles(element, item) {
-      var styleStr = '';
-      if (item.bold) {
-        styleStr += 'font-weight: bold;';
-      }
-      if (item.italic) {
-        styleStr += 'font-style: italic;';
+    element.href = this.linkService.getDestinationHash(destination);
+    element.onclick = () => {
+      if (destination) {
+        this.linkService.navigateTo(destination);
       }
+      return false;
+    };
+  }
 
-      if (styleStr) {
-        element.setAttribute('style', styleStr);
-      }
-    },
-
-    /**
-     * Prepend a button before an outline item which allows the user to toggle
-     * the visibility of all outline items at that level.
-     *
-     * @private
-     */
-    _addToggleButton: function PDFOutlineViewer_addToggleButton(div) {
-      var toggler = document.createElement('div');
-      toggler.className = 'outlineItemToggler';
-      toggler.onclick = function(event) {
-        event.stopPropagation();
-        toggler.classList.toggle('outlineItemsHidden');
-
-        if (event.shiftKey) {
-          var shouldShowAll = !toggler.classList.contains('outlineItemsHidden');
-          this._toggleOutlineItem(div, shouldShowAll);
-        }
-      }.bind(this);
-      div.insertBefore(toggler, div.firstChild);
-    },
-
-    /**
-     * Toggle the visibility of the subtree of an outline item.
-     *
-     * @param {Element} root - the root of the outline (sub)tree.
-     * @param {boolean} show - whether to show the outline (sub)tree. If false,
-     *   the outline subtree rooted at |root| will be collapsed.
-     *
-     * @private
-     */
-    _toggleOutlineItem:
-        function PDFOutlineViewer_toggleOutlineItem(root, show) {
-      this.lastToggleIsShow = show;
-      var togglers = root.querySelectorAll('.outlineItemToggler');
-      for (var i = 0, ii = togglers.length; i < ii; ++i) {
-        togglers[i].classList[show ? 'remove' : 'add']('outlineItemsHidden');
-      }
-    },
-
-    /**
-     * Collapse or expand all subtrees of the outline.
-     */
-    toggleOutlineTree: function PDFOutlineViewer_toggleOutlineTree() {
-      if (!this.outline) {
-        return;
-      }
-      this._toggleOutlineItem(this.container, !this.lastToggleIsShow);
-    },
-
-    /**
-     * @param {PDFOutlineViewerRenderParameters} params
-     */
-    render: function PDFOutlineViewer_render(params) {
-      var outline = (params && params.outline) || null;
-      var outlineCount = 0;
-
-      if (this.outline) {
-        this.reset();
-      }
-      this.outline = outline;
+  /**
+   * @private
+   */
+  _setStyles(element, item) {
+    var styleStr = '';
+    if (item.bold) {
+      styleStr += 'font-weight: bold;';
+    }
+    if (item.italic) {
+      styleStr += 'font-style: italic;';
+    }
 
-      if (!outline) {
-        this._dispatchEvent(outlineCount);
-        return;
-      }
+    if (styleStr) {
+      element.setAttribute('style', styleStr);
+    }
+  }
 
-      var fragment = document.createDocumentFragment();
-      var queue = [{ parent: fragment, items: this.outline }];
-      var hasAnyNesting = false;
-      while (queue.length > 0) {
-        var levelData = queue.shift();
-        for (var i = 0, len = levelData.items.length; i < len; i++) {
-          var item = levelData.items[i];
-
-          var div = document.createElement('div');
-          div.className = 'outlineItem';
-
-          var element = document.createElement('a');
-          this._bindLink(element, item);
-          this._setStyles(element, item);
-          element.textContent =
-            removeNullCharacters(item.title) || DEFAULT_TITLE;
-
-          div.appendChild(element);
-
-          if (item.items.length > 0) {
-            hasAnyNesting = true;
-            this._addToggleButton(div);
-
-            var itemsDiv = document.createElement('div');
-            itemsDiv.className = 'outlineItems';
-            div.appendChild(itemsDiv);
-            queue.push({ parent: itemsDiv, items: item.items });
-          }
-
-          levelData.parent.appendChild(div);
-          outlineCount++;
-        }
-      }
-      if (hasAnyNesting) {
-        this.container.classList.add('outlineWithDeepNesting');
+  /**
+   * Prepend a button before an outline item which allows the user to toggle
+   * the visibility of all outline items at that level.
+   *
+   * @private
+   */
+  _addToggleButton(div) {
+    var toggler = document.createElement('div');
+    toggler.className = 'outlineItemToggler';
+    toggler.onclick = (evt) => {
+      evt.stopPropagation();
+      toggler.classList.toggle('outlineItemsHidden');
+
+      if (evt.shiftKey) {
+        var shouldShowAll = !toggler.classList.contains('outlineItemsHidden');
+        this._toggleOutlineItem(div, shouldShowAll);
       }
+    };
+    div.insertBefore(toggler, div.firstChild);
+  }
 
-      this.container.appendChild(fragment);
+  /**
+   * Toggle the visibility of the subtree of an outline item.
+   *
+   * @param {Element} root - the root of the outline (sub)tree.
+   * @param {boolean} show - whether to show the outline (sub)tree. If false,
+   *   the outline subtree rooted at |root| will be collapsed.
+   *
+   * @private
+   */
+  _toggleOutlineItem(root, show) {
+    this.lastToggleIsShow = show;
+    var togglers = root.querySelectorAll('.outlineItemToggler');
+    for (var i = 0, ii = togglers.length; i < ii; ++i) {
+      togglers[i].classList[show ? 'remove' : 'add']('outlineItemsHidden');
+    }
+  }
 
+  /**
+   * Collapse or expand all subtrees of the outline.
+   */
+  toggleOutlineTree() {
+    if (!this.outline) {
+      return;
+    }
+    this._toggleOutlineItem(this.container, !this.lastToggleIsShow);
+  }
+
+  /**
+   * @param {PDFOutlineViewerRenderParameters} params
+   */
+  render(params = {}) {
+    var outline = params.outline || null;
+    var outlineCount = 0;
+
+    if (this.outline) {
+      this.reset();
+    }
+    this.outline = outline;
+
+    if (!outline) {
       this._dispatchEvent(outlineCount);
+      return;
+    }
+
+    var fragment = document.createDocumentFragment();
+    var queue = [{ parent: fragment, items: this.outline }];
+    var hasAnyNesting = false;
+    while (queue.length > 0) {
+      var levelData = queue.shift();
+      for (var i = 0, len = levelData.items.length; i < len; i++) {
+        var item = levelData.items[i];
+
+        var div = document.createElement('div');
+        div.className = 'outlineItem';
+
+        var element = document.createElement('a');
+        this._bindLink(element, item);
+        this._setStyles(element, item);
+        element.textContent =
+          removeNullCharacters(item.title) || DEFAULT_TITLE;
+
+        div.appendChild(element);
+
+        if (item.items.length > 0) {
+          hasAnyNesting = true;
+          this._addToggleButton(div);
+
+          var itemsDiv = document.createElement('div');
+          itemsDiv.className = 'outlineItems';
+          div.appendChild(itemsDiv);
+          queue.push({ parent: itemsDiv, items: item.items });
+        }
+
+        levelData.parent.appendChild(div);
+        outlineCount++;
+      }
     }
-  };
+    if (hasAnyNesting) {
+      this.container.classList.add('outlineWithDeepNesting');
+    }
+
+    this.container.appendChild(fragment);
 
-  return PDFOutlineViewer;
-})();
+    this._dispatchEvent(outlineCount);
+  }
+}
 
 export {
   PDFOutlineViewer,