Bug 1496753 - Update pdf.js to version 2.0.911. r=bdahl
authorRyan VanderMeulen <ryanvm@gmail.com>
Fri, 05 Oct 2018 11:26:45 -0400
changeset 488134 9ec67697066f7aeeaeac57cc25c5d214d00c0179
parent 488133 a858092c4df7c1db13935762fea281a5f9911a98
child 488135 0cf6d7594c4897d43321b825ab663a7b8a4e17af
push id246
push userfmarier@mozilla.com
push dateSat, 13 Oct 2018 00:15:40 +0000
reviewersbdahl
bugs1496753
milestone64.0a1
Bug 1496753 - Update pdf.js to version 2.0.911. r=bdahl
browser/extensions/pdfjs/README.mozilla
browser/extensions/pdfjs/content/build/pdf.js
browser/extensions/pdfjs/content/build/pdf.worker.js
browser/extensions/pdfjs/content/web/viewer.css
browser/extensions/pdfjs/content/web/viewer.js
browser/extensions/pdfjs/moz.yaml
--- a/browser/extensions/pdfjs/README.mozilla
+++ b/browser/extensions/pdfjs/README.mozilla
@@ -1,5 +1,5 @@
 This is the PDF.js project output, https://github.com/mozilla/pdf.js
 
-Current extension version is: 2.0.892
+Current extension version is: 2.0.911
 
-Taken from upstream commit: ec10cae5
+Taken from upstream commit: ff2df9c5
--- a/browser/extensions/pdfjs/content/build/pdf.js
+++ b/browser/extensions/pdfjs/content/build/pdf.js
@@ -118,18 +118,18 @@ return /******/ (function(modules) { // 
 /************************************************************************/
 /******/ ([
 /* 0 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
 
 
-var pdfjsVersion = '2.0.892';
-var pdfjsBuild = 'ec10cae5';
+var pdfjsVersion = '2.0.911';
+var pdfjsBuild = 'ff2df9c5';
 var pdfjsSharedUtil = __w_pdfjs_require__(1);
 var pdfjsDisplayAPI = __w_pdfjs_require__(7);
 var pdfjsDisplayTextLayer = __w_pdfjs_require__(19);
 var pdfjsDisplayAnnotationLayer = __w_pdfjs_require__(20);
 var pdfjsDisplayDOMUtils = __w_pdfjs_require__(8);
 var pdfjsDisplaySVG = __w_pdfjs_require__(21);
 let pdfjsDisplayWorkerOptions = __w_pdfjs_require__(13);
 let pdfjsDisplayAPICompatibility = __w_pdfjs_require__(10);
@@ -4221,17 +4221,17 @@ function _fetchDocument(worker, source, 
     return Promise.reject(new Error('Worker was destroyed'));
   }
   if (pdfDataRangeTransport) {
     source.length = pdfDataRangeTransport.length;
     source.initialData = pdfDataRangeTransport.initialData;
   }
   return worker.messageHandler.sendWithPromise('GetDocRequest', {
     docId,
-    apiVersion: '2.0.892',
+    apiVersion: '2.0.911',
     source: {
       data: source.data,
       url: source.url,
       password: source.password,
       disableAutoFetch: source.disableAutoFetch,
       rangeChunkSize: source.rangeChunkSize,
       length: source.length
     },
@@ -5548,18 +5548,18 @@ var InternalRenderTask = function Intern
         }
       });
     }
   };
   return InternalRenderTask;
 }();
 var version, build;
 {
-  exports.version = version = '2.0.892';
-  exports.build = build = 'ec10cae5';
+  exports.version = version = '2.0.911';
+  exports.build = build = 'ff2df9c5';
 }
 exports.getDocument = getDocument;
 exports.LoopbackPort = LoopbackPort;
 exports.PDFDataRangeTransport = PDFDataRangeTransport;
 exports.PDFWorker = PDFWorker;
 exports.PDFDocumentProxy = PDFDocumentProxy;
 exports.PDFPageProxy = PDFPageProxy;
 exports.setPDFNetworkStreamFactory = setPDFNetworkStreamFactory;
@@ -5880,134 +5880,215 @@ exports.loadScript = loadScript;
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.FontLoader = exports.FontFaceObject = undefined;
 
 var _util = __w_pdfjs_require__(1);
 
-function FontLoader(docId) {
-  this.docId = docId;
-  this.styleElement = null;
-}
-FontLoader.prototype = {
-  insertRule: function fontLoaderInsertRule(rule) {
-    var styleElement = this.styleElement;
+class BaseFontLoader {
+  constructor(docId) {
+    if (this.constructor === BaseFontLoader) {
+      (0, _util.unreachable)('Cannot initialize BaseFontLoader.');
+    }
+    this.docId = docId;
+    this.nativeFontFaces = [];
+    this.styleElement = null;
+    this.loadingContext = {
+      requests: [],
+      nextRequestId: 0
+    };
+  }
+  addNativeFontFace(nativeFontFace) {
+    this.nativeFontFaces.push(nativeFontFace);
+    document.fonts.add(nativeFontFace);
+  }
+  insertRule(rule) {
+    let styleElement = this.styleElement;
     if (!styleElement) {
       styleElement = this.styleElement = document.createElement('style');
-      styleElement.id = 'PDFJS_FONT_STYLE_TAG_' + this.docId;
+      styleElement.id = `PDFJS_FONT_STYLE_TAG_${this.docId}`;
       document.documentElement.getElementsByTagName('head')[0].appendChild(styleElement);
     }
-    var styleSheet = styleElement.sheet;
+    const styleSheet = styleElement.sheet;
     styleSheet.insertRule(rule, styleSheet.cssRules.length);
-  },
-  clear: function fontLoaderClear() {
+  }
+  clear() {
+    this.nativeFontFaces.forEach(function (nativeFontFace) {
+      document.fonts.delete(nativeFontFace);
+    });
+    this.nativeFontFaces.length = 0;
     if (this.styleElement) {
       this.styleElement.remove();
       this.styleElement = null;
     }
   }
-};
-{
-  FontLoader.prototype.bind = function fontLoaderBind(fonts, callback) {
-    for (var i = 0, ii = fonts.length; i < ii; i++) {
-      var font = fonts[i];
-      if (font.attached) {
+  bind(fonts, callback) {
+    const rules = [];
+    const fontsToLoad = [];
+    const fontLoadPromises = [];
+    const getNativeFontPromise = function (nativeFontFace) {
+      return nativeFontFace.loaded.catch(function (reason) {
+        (0, _util.warn)(`Failed to load font "${nativeFontFace.family}": ${reason}`);
+      });
+    };
+    for (const font of fonts) {
+      if (font.attached || font.missingFile) {
         continue;
       }
       font.attached = true;
-      var rule = font.createFontFaceRule();
-      if (rule) {
-        this.insertRule(rule);
-      }
-    }
-    setTimeout(callback);
+      if (this.isFontLoadingAPISupported) {
+        const nativeFontFace = font.createNativeFontFace();
+        if (nativeFontFace) {
+          this.addNativeFontFace(nativeFontFace);
+          fontLoadPromises.push(getNativeFontPromise(nativeFontFace));
+        }
+      } else {
+        const rule = font.createFontFaceRule();
+        if (rule) {
+          this.insertRule(rule);
+          rules.push(rule);
+          fontsToLoad.push(font);
+        }
+      }
+    }
+    const request = this._queueLoadingCallback(callback);
+    if (this.isFontLoadingAPISupported) {
+      Promise.all(fontLoadPromises).then(request.complete);
+    } else if (rules.length > 0 && !this.isSyncFontLoadingSupported) {
+      this._prepareFontLoadEvent(rules, fontsToLoad, request);
+    } else {
+      request.complete();
+    }
+  }
+  _queueLoadingCallback(callback) {
+    function completeRequest() {
+      (0, _util.assert)(!request.done, 'completeRequest() cannot be called twice.');
+      request.done = true;
+      while (context.requests.length > 0 && context.requests[0].done) {
+        const otherRequest = context.requests.shift();
+        setTimeout(otherRequest.callback, 0);
+      }
+    }
+    const context = this.loadingContext;
+    const request = {
+      id: `pdfjs-font-loading-${context.nextRequestId++}`,
+      done: false,
+      complete: completeRequest,
+      callback
+    };
+    context.requests.push(request);
+    return request;
+  }
+  get isFontLoadingAPISupported() {
+    (0, _util.unreachable)('Abstract method `isFontLoadingAPISupported`.');
+  }
+  get isSyncFontLoadingSupported() {
+    (0, _util.unreachable)('Abstract method `isSyncFontLoadingSupported`.');
+  }
+  get _loadTestFont() {
+    (0, _util.unreachable)('Abstract method `_loadTestFont`.');
+  }
+  _prepareFontLoadEvent(rules, fontsToLoad, request) {
+    (0, _util.unreachable)('Abstract method `_prepareFontLoadEvent`.');
+  }
+}
+let FontLoader;
+{
+  exports.FontLoader = FontLoader = class MozcentralFontLoader extends BaseFontLoader {
+    get isFontLoadingAPISupported() {
+      return (0, _util.shadow)(this, 'isFontLoadingAPISupported', typeof document !== 'undefined' && !!document.fonts);
+    }
+    get isSyncFontLoadingSupported() {
+      return (0, _util.shadow)(this, 'isSyncFontLoadingSupported', true);
+    }
   };
 }
-;
-;
-var IsEvalSupportedCached = {
+const IsEvalSupportedCached = {
   get value() {
     return (0, _util.shadow)(this, 'value', (0, _util.isEvalSupported)());
   }
 };
-var FontFaceObject = function FontFaceObjectClosure() {
-  function FontFaceObject(translatedData, { isEvalSupported = true, disableFontFace = false, ignoreErrors = false, onUnsupportedFeature = null, fontRegistry = null }) {
+class FontFaceObject {
+  constructor(translatedData, { isEvalSupported = true, disableFontFace = false, ignoreErrors = false, onUnsupportedFeature = null, fontRegistry = null }) {
     this.compiledGlyphs = Object.create(null);
-    for (var i in translatedData) {
+    for (let i in translatedData) {
       this[i] = translatedData[i];
     }
     this.isEvalSupported = isEvalSupported !== false;
     this.disableFontFace = disableFontFace === true;
     this.ignoreErrors = ignoreErrors === true;
     this._onUnsupportedFeature = onUnsupportedFeature;
     this.fontRegistry = fontRegistry;
   }
-  FontFaceObject.prototype = {
-    createNativeFontFace: function FontFaceObject_createNativeFontFace() {
-      throw new Error('Not implemented: createNativeFontFace');
-    },
-    createFontFaceRule: function FontFaceObject_createFontFaceRule() {
-      if (!this.data || this.disableFontFace) {
-        return null;
-      }
-      var data = (0, _util.bytesToString)(new Uint8Array(this.data));
-      var fontName = this.loadedName;
-      var url = 'url(data:' + this.mimetype + ';base64,' + btoa(data) + ');';
-      var rule = '@font-face { font-family:"' + fontName + '";src:' + url + '}';
-      if (this.fontRegistry) {
-        this.fontRegistry.registerFont(this, url);
-      }
-      return rule;
-    },
-    getPathGenerator(objs, character) {
-      if (this.compiledGlyphs[character] !== undefined) {
-        return this.compiledGlyphs[character];
-      }
-      let cmds, current;
-      try {
-        cmds = objs.get(this.loadedName + '_path_' + character);
-      } catch (ex) {
-        if (!this.ignoreErrors) {
-          throw ex;
-        }
-        if (this._onUnsupportedFeature) {
-          this._onUnsupportedFeature({ featureId: _util.UNSUPPORTED_FEATURES.font });
-        }
-        (0, _util.warn)(`getPathGenerator - ignoring character: "${ex}".`);
-        return this.compiledGlyphs[character] = function (c, size) {};
-      }
-      if (this.isEvalSupported && IsEvalSupportedCached.value) {
-        let args,
-            js = '';
-        for (let i = 0, ii = cmds.length; i < ii; i++) {
-          current = cmds[i];
-          if (current.args !== undefined) {
-            args = current.args.join(',');
-          } else {
-            args = '';
-          }
-          js += 'c.' + current.cmd + '(' + args + ');\n';
-        }
-        return this.compiledGlyphs[character] = new Function('c', 'size', js);
-      }
-      return this.compiledGlyphs[character] = function (c, size) {
-        for (let i = 0, ii = cmds.length; i < ii; i++) {
-          current = cmds[i];
-          if (current.cmd === 'scale') {
-            current.args = [size, -size];
-          }
-          c[current.cmd].apply(c, current.args);
-        }
-      };
-    }
-  };
-  return FontFaceObject;
-}();
+  createNativeFontFace() {
+    if (!this.data || this.disableFontFace) {
+      return null;
+    }
+    const nativeFontFace = new FontFace(this.loadedName, this.data, {});
+    if (this.fontRegistry) {
+      this.fontRegistry.registerFont(this);
+    }
+    return nativeFontFace;
+  }
+  createFontFaceRule() {
+    if (!this.data || this.disableFontFace) {
+      return null;
+    }
+    const data = (0, _util.bytesToString)(new Uint8Array(this.data));
+    const url = `url(data:${this.mimetype};base64,${btoa(data)});`;
+    const rule = `@font-face {font-family:"${this.loadedName}";src:${url}}`;
+    if (this.fontRegistry) {
+      this.fontRegistry.registerFont(this, url);
+    }
+    return rule;
+  }
+  getPathGenerator(objs, character) {
+    if (this.compiledGlyphs[character] !== undefined) {
+      return this.compiledGlyphs[character];
+    }
+    let cmds, current;
+    try {
+      cmds = objs.get(this.loadedName + '_path_' + character);
+    } catch (ex) {
+      if (!this.ignoreErrors) {
+        throw ex;
+      }
+      if (this._onUnsupportedFeature) {
+        this._onUnsupportedFeature({ featureId: _util.UNSUPPORTED_FEATURES.font });
+      }
+      (0, _util.warn)(`getPathGenerator - ignoring character: "${ex}".`);
+      return this.compiledGlyphs[character] = function (c, size) {};
+    }
+    if (this.isEvalSupported && IsEvalSupportedCached.value) {
+      let args,
+          js = '';
+      for (let i = 0, ii = cmds.length; i < ii; i++) {
+        current = cmds[i];
+        if (current.args !== undefined) {
+          args = current.args.join(',');
+        } else {
+          args = '';
+        }
+        js += 'c.' + current.cmd + '(' + args + ');\n';
+      }
+      return this.compiledGlyphs[character] = new Function('c', 'size', js);
+    }
+    return this.compiledGlyphs[character] = function (c, size) {
+      for (let i = 0, ii = cmds.length; i < ii; i++) {
+        current = cmds[i];
+        if (current.cmd === 'scale') {
+          current.args = [size, -size];
+        }
+        c[current.cmd].apply(c, current.args);
+      }
+    };
+  }
+}
 exports.FontFaceObject = FontFaceObject;
 exports.FontLoader = FontLoader;
 
 /***/ }),
 /* 10 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
@@ -10184,16 +10265,18 @@ class AnnotationElementFactory {
       case _util.AnnotationType.LINE:
         return new LineAnnotationElement(parameters);
       case _util.AnnotationType.SQUARE:
         return new SquareAnnotationElement(parameters);
       case _util.AnnotationType.CIRCLE:
         return new CircleAnnotationElement(parameters);
       case _util.AnnotationType.POLYLINE:
         return new PolylineAnnotationElement(parameters);
+      case _util.AnnotationType.INK:
+        return new InkAnnotationElement(parameters);
       case _util.AnnotationType.POLYGON:
         return new PolygonAnnotationElement(parameters);
       case _util.AnnotationType.HIGHLIGHT:
         return new HighlightAnnotationElement(parameters);
       case _util.AnnotationType.UNDERLINE:
         return new UnderlineAnnotationElement(parameters);
       case _util.AnnotationType.SQUIGGLY:
         return new SquigglyAnnotationElement(parameters);
@@ -10500,17 +10583,17 @@ class ChoiceWidgetAnnotationElement exte
   }
 }
 class PopupAnnotationElement extends AnnotationElement {
   constructor(parameters) {
     let isRenderable = !!(parameters.data.title || parameters.data.contents);
     super(parameters, isRenderable);
   }
   render() {
-    const IGNORE_TYPES = ['Line', 'Square', 'Circle', 'PolyLine', 'Polygon'];
+    const IGNORE_TYPES = ['Line', 'Square', 'Circle', 'PolyLine', 'Polygon', 'Ink'];
     this.container.className = 'popupAnnotation';
     if (IGNORE_TYPES.includes(this.data.parentType)) {
       return this.container;
     }
     let selector = '[data-annotation-id="' + this.data.parentId + '"]';
     let parentElement = this.layer.querySelector(selector);
     if (!parentElement) {
       return this.container;
@@ -10716,16 +10799,52 @@ class PolylineAnnotationElement extends 
 }
 class PolygonAnnotationElement extends PolylineAnnotationElement {
   constructor(parameters) {
     super(parameters);
     this.containerClassName = 'polygonAnnotation';
     this.svgElementName = 'svg:polygon';
   }
 }
+class InkAnnotationElement extends AnnotationElement {
+  constructor(parameters) {
+    let isRenderable = !!(parameters.data.hasPopup || parameters.data.title || parameters.data.contents);
+    super(parameters, isRenderable, true);
+    this.containerClassName = 'inkAnnotation';
+    this.svgElementName = 'svg:polyline';
+  }
+  render() {
+    this.container.className = this.containerClassName;
+    let data = this.data;
+    let width = data.rect[2] - data.rect[0];
+    let height = data.rect[3] - data.rect[1];
+    let svg = this.svgFactory.create(width, height);
+    let inkLists = data.inkLists;
+    for (let i = 0, ii = inkLists.length; i < ii; i++) {
+      let inkList = inkLists[i];
+      let points = [];
+      for (let j = 0, jj = inkList.length; j < jj; j++) {
+        let x = inkList[j].x - data.rect[0];
+        let y = data.rect[3] - inkList[j].y;
+        points.push(x + ',' + y);
+      }
+      points = points.join(' ');
+      let borderWidth = data.borderStyle.width;
+      let polyline = this.svgFactory.createElement(this.svgElementName);
+      polyline.setAttribute('points', points);
+      polyline.setAttribute('stroke-width', borderWidth);
+      polyline.setAttribute('stroke', 'transparent');
+      polyline.setAttribute('fill', 'none');
+      this._createPopup(this.container, polyline, data);
+      svg.appendChild(polyline);
+    }
+    this.container.append(svg);
+    return this.container;
+  }
+}
 class HighlightAnnotationElement extends AnnotationElement {
   constructor(parameters) {
     let isRenderable = !!(parameters.data.hasPopup || parameters.data.title || parameters.data.contents);
     super(parameters, isRenderable, true);
   }
   render() {
     this.container.className = 'highlightAnnotation';
     if (!this.data.hasPopup) {
@@ -10784,24 +10903,27 @@ class StampAnnotationElement extends Ann
       this._createPopup(this.container, null, this.data);
     }
     return this.container;
   }
 }
 class FileAttachmentAnnotationElement extends AnnotationElement {
   constructor(parameters) {
     super(parameters, true);
-    let file = this.data.file;
-    this.filename = (0, _dom_utils.getFilenameFromUrl)(file.filename);
-    this.content = file.content;
-    this.linkService.onFileAttachmentAnnotation({
-      id: (0, _util.stringToPDFString)(file.filename),
-      filename: file.filename,
-      content: file.content
-    });
+    const { filename, content } = this.data.file;
+    this.filename = (0, _dom_utils.getFilenameFromUrl)(filename);
+    this.content = content;
+    if (this.linkService.eventBus) {
+      this.linkService.eventBus.dispatch('fileattachmentannotation', {
+        source: this,
+        id: (0, _util.stringToPDFString)(filename),
+        filename,
+        content
+      });
+    }
   }
   render() {
     this.container.className = 'fileAttachmentAnnotation';
     let trigger = document.createElement('div');
     trigger.style.height = this.container.style.height;
     trigger.style.width = this.container.style.width;
     trigger.addEventListener('dblclick', this._download.bind(this));
     if (!this.data.hasPopup && (this.data.title || this.data.contents)) {
--- a/browser/extensions/pdfjs/content/build/pdf.worker.js
+++ b/browser/extensions/pdfjs/content/build/pdf.worker.js
@@ -118,18 +118,18 @@ return /******/ (function(modules) { // 
 /************************************************************************/
 /******/ ([
 /* 0 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
 
 
-var pdfjsVersion = '2.0.892';
-var pdfjsBuild = 'ec10cae5';
+var pdfjsVersion = '2.0.911';
+var pdfjsBuild = 'ff2df9c5';
 var pdfjsCoreWorker = __w_pdfjs_require__(1);
 exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;
 
 /***/ }),
 /* 1 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
@@ -322,17 +322,17 @@ var WorkerMessageHandler = {
     });
   },
   createDocumentHandler(docParams, port) {
     var pdfManager;
     var terminated = false;
     var cancelXHRs = null;
     var WorkerTasks = [];
     let apiVersion = docParams.apiVersion;
-    let workerVersion = '2.0.892';
+    let workerVersion = '2.0.911';
     if (apiVersion !== workerVersion) {
       throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`);
     }
     var docId = docParams.docId;
     var docBaseUrl = docParams.docBaseUrl;
     var workerHandlerName = docParams.docId + '_worker';
     var handler = new _message_handler.MessageHandler(workerHandlerName, docId, port);
     handler.postMessageTransfers = docParams.postMessageTransfers;
@@ -17700,16 +17700,18 @@ class AnnotationFactory {
       case 'Square':
         return new SquareAnnotation(parameters);
       case 'Circle':
         return new CircleAnnotation(parameters);
       case 'PolyLine':
         return new PolylineAnnotation(parameters);
       case 'Polygon':
         return new PolygonAnnotation(parameters);
+      case 'Ink':
+        return new InkAnnotation(parameters);
       case 'Highlight':
         return new HighlightAnnotation(parameters);
       case 'Underline':
         return new UnderlineAnnotation(parameters);
       case 'Squiggly':
         return new SquigglyAnnotation(parameters);
       case 'StrikeOut':
         return new StrikeOutAnnotation(parameters);
@@ -18290,16 +18292,36 @@ class PolylineAnnotation extends Annotat
   }
 }
 class PolygonAnnotation extends PolylineAnnotation {
   constructor(parameters) {
     super(parameters);
     this.data.annotationType = _util.AnnotationType.POLYGON;
   }
 }
+class InkAnnotation extends Annotation {
+  constructor(parameters) {
+    super(parameters);
+    this.data.annotationType = _util.AnnotationType.INK;
+    let dict = parameters.dict;
+    const xref = parameters.xref;
+    let originalInkLists = dict.getArray('InkList');
+    this.data.inkLists = [];
+    for (let i = 0, ii = originalInkLists.length; i < ii; ++i) {
+      this.data.inkLists.push([]);
+      for (let j = 0, jj = originalInkLists[i].length; j < jj; j += 2) {
+        this.data.inkLists[i].push({
+          x: xref.fetchIfRef(originalInkLists[i][j]),
+          y: xref.fetchIfRef(originalInkLists[i][j + 1])
+        });
+      }
+    }
+    this._preparePopup(dict);
+  }
+}
 class HighlightAnnotation extends Annotation {
   constructor(parameters) {
     super(parameters);
     this.data.annotationType = _util.AnnotationType.HIGHLIGHT;
     this._preparePopup(parameters.dict);
   }
 }
 class UnderlineAnnotation extends Annotation {
@@ -22676,17 +22698,16 @@ var Font = function FontClosure() {
     this.data = data;
     this.fontType = getFontType(type, subtype);
     this.fontMatrix = properties.fontMatrix;
     this.widths = properties.widths;
     this.defaultWidth = properties.defaultWidth;
     this.toUnicode = properties.toUnicode;
     this.encoding = properties.baseEncoding;
     this.seacMap = properties.seacMap;
-    this.loading = true;
   }
   Font.getFontID = function () {
     var ID = 1;
     return function Font_getFontID() {
       return String(ID++);
     };
   }();
   function int16(b0, b1) {
@@ -23137,17 +23158,16 @@ var Font = function FontClosure() {
             if (unicode !== -1) {
               unicodeCharCode = unicode;
             }
           }
           this.toFontChar[charCode] = unicodeCharCode;
         });
       }
       this.loadedName = fontName.split('-')[0];
-      this.loading = false;
       this.fontType = getFontType(type, subtype);
     },
     checkAndRepair: function Font_checkAndRepair(name, font, properties) {
       const VALID_TABLES = ['OS/2', 'cmap', 'head', 'hhea', 'hmtx', 'maxp', 'name', 'post', 'loca', 'glyf', 'fpgm', 'prep', 'cvt ', 'CFF '];
       function readTables(file, numTables) {
         let tables = Object.create(null);
         tables['OS/2'] = null;
         tables['cmap'] = null;
@@ -24429,17 +24449,17 @@ var Font = function FontClosure() {
     }
   };
   return Font;
 }();
 var ErrorFont = function ErrorFontClosure() {
   function ErrorFont(error) {
     this.error = error;
     this.loadedName = 'g_font_error';
-    this.loading = false;
+    this.missingFile = true;
   }
   ErrorFont.prototype = {
     charsToGlyphs: function ErrorFont_charsToGlyphs() {
       return [];
     },
     exportData: function ErrorFont_exportData() {
       return { error: this.error };
     }
--- a/browser/extensions/pdfjs/content/web/viewer.css
+++ b/browser/extensions/pdfjs/content/web/viewer.css
@@ -249,16 +249,17 @@
 .annotationLayer .underlineAnnotation,
 .annotationLayer .squigglyAnnotation,
 .annotationLayer .strikeoutAnnotation,
 .annotationLayer .lineAnnotation svg line,
 .annotationLayer .squareAnnotation svg rect,
 .annotationLayer .circleAnnotation svg ellipse,
 .annotationLayer .polylineAnnotation svg polyline,
 .annotationLayer .polygonAnnotation svg polygon,
+.annotationLayer .inkAnnotation svg polyline,
 .annotationLayer .stampAnnotation,
 .annotationLayer .fileAttachmentAnnotation {
   cursor: pointer;
 }
 
 .pdfViewer .canvasWrapper {
   overflow: hidden;
 }
--- a/browser/extensions/pdfjs/content/web/viewer.js
+++ b/browser/extensions/pdfjs/content/web/viewer.js
@@ -473,17 +473,17 @@ let PDFViewerApplication = {
     this.l10n = this.externalServices.createL10n({ locale: _app_options.AppOptions.get('locale') });
     const dir = await this.l10n.getDirection();
     document.getElementsByTagName('html')[0].dir = dir;
   },
   async _initializeViewerComponents() {
     const appConfig = this.appConfig;
     this.overlayManager = new _overlay_manager.OverlayManager();
     const dispatchToDOM = _app_options.AppOptions.get('eventBusDispatchToDOM');
-    let eventBus = appConfig.eventBus || (0, _dom_events.getGlobalEventBus)(dispatchToDOM);
+    const eventBus = appConfig.eventBus || (0, _dom_events.getGlobalEventBus)(dispatchToDOM);
     this.eventBus = eventBus;
     let pdfRenderingQueue = new _pdf_rendering_queue.PDFRenderingQueue();
     pdfRenderingQueue.onIdle = this.cleanup.bind(this);
     this.pdfRenderingQueue = pdfRenderingQueue;
     let pdfLinkService = new _pdf_link_service.PDFLinkService({
       eventBus,
       externalLinkTarget: _app_options.AppOptions.get('externalLinkTarget'),
       externalLinkRel: _app_options.AppOptions.get('externalLinkRel')
@@ -526,19 +526,17 @@ let PDFViewerApplication = {
       l10n: this.l10n
     });
     pdfRenderingQueue.setThumbnailViewer(this.pdfThumbnailViewer);
     this.pdfHistory = new _pdf_history.PDFHistory({
       linkService: pdfLinkService,
       eventBus
     });
     pdfLinkService.setHistory(this.pdfHistory);
-    let findBarConfig = Object.create(appConfig.findBar);
-    findBarConfig.eventBus = eventBus;
-    this.findBar = new _pdf_find_bar.PDFFindBar(findBarConfig, this.l10n);
+    this.findBar = new _pdf_find_bar.PDFFindBar(appConfig.findBar, eventBus, this.l10n);
     this.pdfDocumentProperties = new _pdf_document_properties.PDFDocumentProperties(appConfig.documentProperties, this.overlayManager, eventBus, this.l10n);
     this.pdfCursorTools = new _pdf_cursor_tools.PDFCursorTools({
       container,
       eventBus,
       cursorToolOnLoad: _app_options.AppOptions.get('cursorToolOnLoad')
     });
     this.toolbar = new _toolbar.Toolbar(appConfig.toolbar, container, eventBus, this.l10n);
     this.secondaryToolbar = new _secondary_toolbar.SecondaryToolbar(appConfig.secondaryToolbar, container, eventBus);
@@ -560,19 +558,17 @@ let PDFViewerApplication = {
     this.pdfAttachmentViewer = new _pdf_attachment_viewer.PDFAttachmentViewer({
       container: appConfig.sidebar.attachmentsView,
       eventBus,
       downloadManager
     });
     let sidebarConfig = Object.create(appConfig.sidebar);
     sidebarConfig.pdfViewer = this.pdfViewer;
     sidebarConfig.pdfThumbnailViewer = this.pdfThumbnailViewer;
-    sidebarConfig.pdfOutlineViewer = this.pdfOutlineViewer;
-    sidebarConfig.eventBus = eventBus;
-    this.pdfSidebar = new _pdf_sidebar.PDFSidebar(sidebarConfig, this.l10n);
+    this.pdfSidebar = new _pdf_sidebar.PDFSidebar(sidebarConfig, eventBus, this.l10n);
     this.pdfSidebar.onToggled = this.forceRendering.bind(this);
     this.pdfSidebarResizer = new _pdf_sidebar_resizer.PDFSidebarResizer(appConfig.sidebarResizer, eventBus, this.l10n);
   },
   run(config) {
     this.initialize(config).then(webViewerInitialized);
   },
   zoomIn(ticks) {
     let newScale = this.pdfViewer.currentScale;
@@ -687,17 +683,16 @@ let PDFViewerApplication = {
     errorWrapper.setAttribute('hidden', 'true');
     if (!this.pdfLoadingTask) {
       return;
     }
     let promise = this.pdfLoadingTask.destroy();
     this.pdfLoadingTask = null;
     if (this.pdfDocument) {
       this.pdfDocument = null;
-      this.findController.setDocument(null);
       this.pdfThumbnailViewer.setDocument(null);
       this.pdfViewer.setDocument(null);
       this.pdfLinkService.setDocument(null);
       this.pdfDocumentProperties.setDocument(null);
     }
     this.store = null;
     this.isInitialViewSet = false;
     this.downloadComplete = false;
@@ -868,17 +863,16 @@ let PDFViewerApplication = {
       });
     });
     let pageModePromise = pdfDocument.getPageMode().catch(function () {});
     this.toolbar.setPagesCount(pdfDocument.numPages, false);
     this.secondaryToolbar.setPagesCount(pdfDocument.numPages);
     const store = this.store = new _view_history.ViewHistory(pdfDocument.fingerprint);
     let baseDocumentUrl;
     baseDocumentUrl = this.baseUrl;
-    this.findController.setDocument(pdfDocument);
     this.pdfLinkService.setDocument(pdfDocument, baseDocumentUrl);
     this.pdfDocumentProperties.setDocument(pdfDocument, this.url);
     let pdfViewer = this.pdfViewer;
     pdfViewer.setDocument(pdfDocument);
     let firstPagePromise = pdfViewer.firstPagePromise;
     let pagesPromise = pdfViewer.pagesPromise;
     let onePageRendered = pdfViewer.onePageRendered;
     let pdfThumbnailViewer = this.pdfThumbnailViewer;
@@ -2833,35 +2827,34 @@ var _pdf_rendering_queue = __webpack_req
 const UI_NOTIFICATION_CLASS = 'pdfSidebarNotification';
 const SidebarView = {
   NONE: 0,
   THUMBS: 1,
   OUTLINE: 2,
   ATTACHMENTS: 3
 };
 class PDFSidebar {
-  constructor(options, l10n = _ui_utils.NullL10n) {
+  constructor(options, eventBus, l10n = _ui_utils.NullL10n) {
     this.isOpen = false;
     this.active = SidebarView.THUMBS;
     this.isInitialViewSet = false;
     this.onToggled = null;
     this.pdfViewer = options.pdfViewer;
     this.pdfThumbnailViewer = options.pdfThumbnailViewer;
-    this.pdfOutlineViewer = options.pdfOutlineViewer;
     this.outerContainer = options.outerContainer;
     this.viewerContainer = options.viewerContainer;
-    this.eventBus = options.eventBus;
     this.toggleButton = options.toggleButton;
     this.thumbnailButton = options.thumbnailButton;
     this.outlineButton = options.outlineButton;
     this.attachmentsButton = options.attachmentsButton;
     this.thumbnailView = options.thumbnailView;
     this.outlineView = options.outlineView;
     this.attachmentsView = options.attachmentsView;
     this.disableNotification = options.disableNotification || false;
+    this.eventBus = eventBus;
     this.l10n = l10n;
     this._addEventListeners();
   }
   reset() {
     this.isInitialViewSet = false;
     this._hideUINotification(null);
     this.switchView(SidebarView.THUMBS);
     this.outlineButton.disabled = false;
@@ -3070,17 +3063,17 @@ class PDFSidebar {
     });
     this.thumbnailButton.addEventListener('click', () => {
       this.switchView(SidebarView.THUMBS);
     });
     this.outlineButton.addEventListener('click', () => {
       this.switchView(SidebarView.OUTLINE);
     });
     this.outlineButton.addEventListener('dblclick', () => {
-      this.pdfOutlineViewer.toggleOutlineTree();
+      this.eventBus.dispatch('toggleoutlinetree', { source: this });
     });
     this.attachmentsButton.addEventListener('click', () => {
       this.switchView(SidebarView.ATTACHMENTS);
     });
     this.eventBus.on('outlineloaded', evt => {
       let outlineCount = evt.outlineCount;
       this.outlineButton.disabled = !outlineCount;
       if (outlineCount) {
@@ -3992,35 +3985,35 @@ exports.PDFDocumentProperties = PDFDocum
 "use strict";
 
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.PDFFindBar = undefined;
 
+var _ui_utils = __webpack_require__(2);
+
 var _pdf_find_controller = __webpack_require__(16);
 
-var _ui_utils = __webpack_require__(2);
-
 const MATCHES_COUNT_LIMIT = 1000;
 class PDFFindBar {
-  constructor(options, l10n = _ui_utils.NullL10n) {
+  constructor(options, eventBus = (0, _ui_utils.getGlobalEventBus)(), l10n = _ui_utils.NullL10n) {
     this.opened = false;
     this.bar = options.bar || null;
     this.toggleButton = options.toggleButton || null;
     this.findField = options.findField || null;
     this.highlightAll = options.highlightAllCheckbox || null;
     this.caseSensitive = options.caseSensitiveCheckbox || null;
     this.entireWord = options.entireWordCheckbox || null;
     this.findMsg = options.findMsg || null;
     this.findResultsCount = options.findResultsCount || null;
     this.findPreviousButton = options.findPreviousButton || null;
     this.findNextButton = options.findNextButton || null;
-    this.eventBus = options.eventBus;
+    this.eventBus = eventBus;
     this.l10n = l10n;
     this.toggleButton.addEventListener('click', () => {
       this.toggle();
     });
     this.findField.addEventListener('input', () => {
       this.dispatchEvent('');
     });
     this.bar.addEventListener('keydown', e => {
@@ -4201,23 +4194,17 @@ const CHARACTERS_TO_NORMALIZE = {
   '\u00BD': '1/2',
   '\u00BE': '3/4'
 };
 class PDFFindController {
   constructor({ linkService, eventBus = (0, _dom_events.getGlobalEventBus)() }) {
     this._linkService = linkService;
     this._eventBus = eventBus;
     this._reset();
-    eventBus.on('findbarclose', () => {
-      this._highlightMatches = false;
-      eventBus.dispatch('updatetextlayermatches', {
-        source: this,
-        pageIndex: -1
-      });
-    });
+    eventBus.on('findbarclose', this._onFindBarClose.bind(this));
     const replace = Object.keys(CHARACTERS_TO_NORMALIZE).join('');
     this._normalizationRegex = new RegExp(`[${replace}]`, 'g');
   }
   get highlightMatches() {
     return this._highlightMatches;
   }
   get pageMatches() {
     return this._pageMatches;
@@ -4234,31 +4221,39 @@ class PDFFindController {
   setDocument(pdfDocument) {
     if (this._pdfDocument) {
       this._reset();
     }
     if (!pdfDocument) {
       return;
     }
     this._pdfDocument = pdfDocument;
+    this._firstPageCapability.resolve();
   }
   executeCommand(cmd, state) {
-    if (!this._pdfDocument) {
-      return;
-    }
+    const pdfDocument = this._pdfDocument;
     if (this._state === null || cmd !== 'findagain') {
       this._dirtyMatch = true;
     }
     this._state = state;
     this._updateUIState(FindState.PENDING);
-    this._firstPagePromise.then(() => {
+    this._firstPageCapability.promise.then(() => {
+      if (!this._pdfDocument || pdfDocument && this._pdfDocument !== pdfDocument) {
+        return;
+      }
       this._extractText();
-      clearTimeout(this._findTimeout);
+      if (this._findTimeout) {
+        clearTimeout(this._findTimeout);
+        this._findTimeout = null;
+      }
       if (cmd === 'find') {
-        this._findTimeout = setTimeout(this._nextMatch.bind(this), FIND_TIMEOUT);
+        this._findTimeout = setTimeout(() => {
+          this._nextMatch();
+          this._findTimeout = null;
+        }, FIND_TIMEOUT);
       } else {
         this._nextMatch();
       }
     });
   }
   _reset() {
     this._highlightMatches = false;
     this._pdfDocument = null;
@@ -4275,24 +4270,19 @@ class PDFFindController {
     };
     this._extractTextPromises = [];
     this._pageContents = [];
     this._matchesCountTotal = 0;
     this._pagesToSearch = null;
     this._pendingFindMatches = Object.create(null);
     this._resumePageIdx = null;
     this._dirtyMatch = false;
+    clearTimeout(this._findTimeout);
     this._findTimeout = null;
-    this._firstPagePromise = new Promise(resolve => {
-      const eventBus = this._eventBus;
-      eventBus.on('pagesinit', function onPagesInit() {
-        eventBus.off('pagesinit', onPagesInit);
-        resolve();
-      });
-    });
+    this._firstPageCapability = (0, _pdfjsLib.createPromiseCapability)();
   }
   _normalize(text) {
     return text.replace(this._normalizationRegex, function (ch) {
       return CHARACTERS_TO_NORMALIZE[ch];
     });
   }
   _prepareMatches(matchesWithLength, matches, matchesLength) {
     function isSubTerm(matchesWithLength, currentIndex) {
@@ -4556,16 +4546,34 @@ class PDFFindController {
         this._updatePage(previousPage);
       }
     }
     this._updateUIState(state, this._state.findPrevious);
     if (this._selected.pageIdx !== -1) {
       this._updatePage(this._selected.pageIdx);
     }
   }
+  _onFindBarClose(evt) {
+    const pdfDocument = this._pdfDocument;
+    this._firstPageCapability.promise.then(() => {
+      if (!this._pdfDocument || pdfDocument && this._pdfDocument !== pdfDocument) {
+        return;
+      }
+      if (this._findTimeout) {
+        clearTimeout(this._findTimeout);
+        this._findTimeout = null;
+        this._updateUIState(FindState.FOUND);
+      }
+      this._highlightMatches = false;
+      this._eventBus.dispatch('updatetextlayermatches', {
+        source: this,
+        pageIndex: -1
+      });
+    });
+  }
   _requestMatchesCount() {
     const { pageIdx, matchIdx } = this._selected;
     let current = 0,
         total = this._matchesCountTotal;
     if (matchIdx !== -1) {
       for (let i = 0; i < pageIdx; i++) {
         current += this._pageMatches[i] && this._pageMatches[i].length || 0;
       }
@@ -5284,24 +5292,16 @@ class PDFLinkService {
       default:
         break;
     }
     this.eventBus.dispatch('namedaction', {
       source: this,
       action
     });
   }
-  onFileAttachmentAnnotation({ id, filename, content }) {
-    this.eventBus.dispatch('fileattachmentannotation', {
-      source: this,
-      id,
-      filename,
-      content
-    });
-  }
   cachePageRef(pageNum, pageRef) {
     if (!pageRef) {
       return;
     }
     let refStr = pageRef.num + ' ' + pageRef.gen + ' R';
     this._pagesRefCache[refStr] = pageNum;
   }
   _cachedPageNumber(pageRef) {
@@ -5377,17 +5377,16 @@ class SimpleLinkService {
   getDestinationHash(dest) {
     return '#';
   }
   getAnchorUrl(hash) {
     return '#';
   }
   setHash(hash) {}
   executeNamedAction(action) {}
-  onFileAttachmentAnnotation({ id, filename, content }) {}
   cachePageRef(pageNum, pageRef) {}
 }
 exports.PDFLinkService = PDFLinkService;
 exports.SimpleLinkService = SimpleLinkService;
 
 /***/ }),
 /* 20 */
 /***/ (function(module, exports, __webpack_require__) {
@@ -5404,16 +5403,17 @@ var _pdfjsLib = __webpack_require__(3);
 
 const DEFAULT_TITLE = '\u2013';
 class PDFOutlineViewer {
   constructor({ container, linkService, eventBus }) {
     this.container = container;
     this.linkService = linkService;
     this.eventBus = eventBus;
     this.reset();
+    eventBus.on('toggleoutlinetree', this.toggleOutlineTree.bind(this));
   }
   reset() {
     this.outline = null;
     this.lastToggleIsShow = true;
     this.container.textContent = '';
     this.container.classList.remove('outlineWithDeepNesting');
   }
   _dispatchEvent(outlineCount) {
@@ -6779,16 +6779,19 @@ class BaseViewer {
   }
   get _setDocumentViewerElement() {
     throw new Error('Not implemented: _setDocumentViewerElement');
   }
   setDocument(pdfDocument) {
     if (this.pdfDocument) {
       this._cancelRendering();
       this._resetView();
+      if (this.findController) {
+        this.findController.setDocument(null);
+      }
     }
     this.pdfDocument = pdfDocument;
     if (!pdfDocument) {
       return;
     }
     let pagesCount = pdfDocument.numPages;
     let pagesCapability = (0, _pdfjsLib.createPromiseCapability)();
     this.pagesPromise = pagesCapability.promise;
@@ -6867,16 +6870,19 @@ class BaseViewer {
             console.error(`Unable to get page ${pageNum} to initialize viewer`, reason);
             if (--getPagesLeft === 0) {
               pagesCapability.resolve();
             }
           });
         }
       });
       this.eventBus.dispatch('pagesinit', { source: this });
+      if (this.findController) {
+        this.findController.setDocument(pdfDocument);
+      }
       if (this.defaultRenderingQueue) {
         this.update();
       }
     }).catch(reason => {
       console.error('Unable to initialize viewer', reason);
     });
   }
   setPageLabels(labels) {
--- a/browser/extensions/pdfjs/moz.yaml
+++ b/browser/extensions/pdfjs/moz.yaml
@@ -15,15 +15,15 @@ origin:
   description: Portable Document Format (PDF) viewer that is built with HTML5
 
   # Full URL for the package's homepage/etc
   # Usually different from repository url
   url: https://github.com/mozilla/pdf.js
 
   # Human-readable identifier for this version/release
   # Generally "version NNN", "tag SSS", "bookmark SSS"
-  release: version 2.0.892
+  release: version 2.0.911
 
   # The package's license, where possible using the mnemonic from
   # https://spdx.org/licenses/
   # Multiple licenses can be specified (as a YAML list)
   # A "LICENSE" file must exist containing the full license text
   license: Apache-2.0