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 495559 9ec67697066f7aeeaeac57cc25c5d214d00c0179
parent 495558 a858092c4df7c1db13935762fea281a5f9911a98
child 495560 0cf6d7594c4897d43321b825ab663a7b8a4e17af
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbdahl
bugs1496753
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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