Browse Source

PDF.js version 2.1.266 - See https://github.com/mozilla/pdf.js/releases/tag/v2.1.266

pdfjsbot 6 years ago
parent
commit
089acef15b
100 changed files with 21539 additions and 7429 deletions
  1. 1 1
      bower.json
  2. 369 177
      build/pdf.js
  3. 0 0
      build/pdf.js.map
  4. 0 0
      build/pdf.min.js
  5. 715 1511
      build/pdf.worker.js
  6. 0 0
      build/pdf.worker.js.map
  7. 0 0
      build/pdf.worker.min.js
  8. 627 0
      external/url/url-lib.js
  9. 7247 0
      image_decoders/pdf.image_decoders.js
  10. 0 0
      image_decoders/pdf.image_decoders.js.map
  11. 0 0
      image_decoders/pdf.image_decoders.min.js
  12. 301 88
      lib/core/annotation.js
  13. 275 245
      lib/core/arithmetic_decoder.js
  14. 65 6
      lib/core/bidi.js
  15. 173 18
      lib/core/ccitt.js
  16. 15 6
      lib/core/ccitt_stream.js
  17. 6 6
      lib/core/cff_parser.js
  18. 3 2
      lib/core/charsets.js
  19. 387 149
      lib/core/chunked_stream.js
  20. 25 7
      lib/core/cmap.js
  21. 674 457
      lib/core/colorspace.js
  22. 77 9
      lib/core/crypto.js
  23. 545 260
      lib/core/document.js
  24. 4 2
      lib/core/encodings.js
  25. 286 92
      lib/core/evaluator.js
  26. 331 97
      lib/core/font_renderer.js
  27. 27 16
      lib/core/fonts.js
  28. 227 68
      lib/core/function.js
  29. 3 2
      lib/core/glyphlist.js
  30. 168 61
      lib/core/image.js
  31. 210 28
      lib/core/jbig2.js
  32. 19 8
      lib/core/jbig2_stream.js
  33. 38 13
      lib/core/jpeg_stream.js
  34. 252 29
      lib/core/jpg.js
  35. 216 6
      lib/core/jpx.js
  36. 18 6
      lib/core/jpx_stream.js
  37. 4 4
      lib/core/metrics.js
  38. 24 6
      lib/core/murmurhash3.js
  39. 694 377
      lib/core/obj.js
  40. 108 6
      lib/core/operator_list.js
  41. 278 63
      lib/core/parser.js
  42. 145 13
      lib/core/pattern.js
  43. 321 133
      lib/core/pdf_manager.js
  44. 75 22
      lib/core/primitives.js
  45. 134 45
      lib/core/ps_parser.js
  46. 10 10
      lib/core/standard_fonts.js
  47. 102 16
      lib/core/stream.js
  48. 143 13
      lib/core/type1_parser.js
  49. 31 4
      lib/core/unicode.js
  50. 210 66
      lib/core/worker.js
  51. 291 89
      lib/display/annotation_layer.js
  52. 513 212
      lib/display/api.js
  53. 11 13
      lib/display/api_compatibility.js
  54. 202 18
      lib/display/canvas.js
  55. 83 32
      lib/display/content_disposition.js
  56. 226 41
      lib/display/dom_utils.js
  57. 208 84
      lib/display/fetch_stream.js
  58. 465 236
      lib/display/font_loader.js
  59. 38 16
      lib/display/metadata.js
  60. 216 51
      lib/display/network.js
  61. 32 19
      lib/display/network_utils.js
  62. 352 169
      lib/display/node_stream.js
  63. 58 7
      lib/display/pattern_helper.js
  64. 238 26
      lib/display/svg.js
  65. 132 18
      lib/display/text_layer.js
  66. 171 42
      lib/display/transport_stream.js
  67. 64 18
      lib/display/webgl.js
  68. 5 4
      lib/display/worker_options.js
  69. 166 53
      lib/display/xml_parser.js
  70. 57 4
      lib/examples/node/domstubs.js
  71. 21 4
      lib/pdf.js
  72. 5 3
      lib/pdf.worker.js
  73. 158 564
      lib/shared/compatibility.js
  74. 2 2
      lib/shared/global_scope.js
  75. 4 4
      lib/shared/is_node.js
  76. 521 0
      lib/shared/message_handler.js
  77. 21 17
      lib/shared/streams_polyfill.js
  78. 56 0
      lib/shared/url_polyfill.js
  79. 295 650
      lib/shared/util.js
  80. 439 263
      lib/test/unit/annotation_spec.js
  81. 326 186
      lib/test/unit/api_spec.js
  82. 7 7
      lib/test/unit/bidi_spec.js
  83. 40 11
      lib/test/unit/cff_parser_spec.js
  84. 9 7
      lib/test/unit/clitests_helper.js
  85. 80 26
      lib/test/unit/cmap_spec.js
  86. 99 52
      lib/test/unit/colorspace_spec.js
  87. 17 5
      lib/test/unit/crypto_spec.js
  88. 41 53
      lib/test/unit/custom_spec.js
  89. 33 17
      lib/test/unit/display_svg_spec.js
  90. 3 3
      lib/test/unit/document_spec.js
  91. 9 9
      lib/test/unit/dom_utils_spec.js
  92. 25 45
      lib/test/unit/encodings_spec.js
  93. 34 9
      lib/test/unit/evaluator_spec.js
  94. 0 81
      lib/test/unit/fonts_spec.js
  95. 17 5
      lib/test/unit/function_spec.js
  96. 31 18
      lib/test/unit/jasmine-boot.js
  97. 41 69
      lib/test/unit/message_handler_spec.js
  98. 71 11
      lib/test/unit/metadata_spec.js
  99. 3 3
      lib/test/unit/murmurhash3_spec.js
  100. 20 5
      lib/test/unit/network_spec.js

+ 1 - 1
bower.json

@@ -1,6 +1,6 @@
 {
   "name": "pdfjs-dist",
-  "version": "2.0.489",
+  "version": "2.1.266",
   "main": [
     "build/pdf.js",
     "build/pdf.worker.js"

File diff suppressed because it is too large
+ 369 - 177
build/pdf.js


File diff suppressed because it is too large
+ 0 - 0
build/pdf.js.map


File diff suppressed because it is too large
+ 0 - 0
build/pdf.min.js


File diff suppressed because it is too large
+ 715 - 1511
build/pdf.worker.js


File diff suppressed because it is too large
+ 0 - 0
build/pdf.worker.js.map


File diff suppressed because it is too large
+ 0 - 0
build/pdf.worker.min.js


+ 627 - 0
external/url/url-lib.js

@@ -0,0 +1,627 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+// Polyfill obtained from: https://github.com/Polymer/URL
+
+(function URLConstructorClosure() {
+  'use strict';
+
+  var relative = Object.create(null);
+  relative['ftp'] = 21;
+  relative['file'] = 0;
+  relative['gopher'] = 70;
+  relative['http'] = 80;
+  relative['https'] = 443;
+  relative['ws'] = 80;
+  relative['wss'] = 443;
+
+  var relativePathDotMapping = Object.create(null);
+  relativePathDotMapping['%2e'] = '.';
+  relativePathDotMapping['.%2e'] = '..';
+  relativePathDotMapping['%2e.'] = '..';
+  relativePathDotMapping['%2e%2e'] = '..';
+
+  function isRelativeScheme(scheme) {
+    return relative[scheme] !== undefined;
+  }
+
+  function invalid() {
+    clear.call(this);
+    this._isInvalid = true;
+  }
+
+  function IDNAToASCII(h) {
+    if (h === '') {
+      invalid.call(this);
+    }
+    // XXX
+    return h.toLowerCase();
+  }
+
+  function percentEscape(c) {
+    var unicode = c.charCodeAt(0);
+    if (unicode > 0x20 &&
+       unicode < 0x7F &&
+       // " # < > ? `
+       [0x22, 0x23, 0x3C, 0x3E, 0x3F, 0x60].indexOf(unicode) === -1
+      ) {
+      return c;
+    }
+    return encodeURIComponent(c);
+  }
+
+  function percentEscapeQuery(c) {
+    // XXX This actually needs to encode c using encoding and then
+    // convert the bytes one-by-one.
+
+    var unicode = c.charCodeAt(0);
+    if (unicode > 0x20 &&
+       unicode < 0x7F &&
+       // " # < > ` (do not escape '?')
+       [0x22, 0x23, 0x3C, 0x3E, 0x60].indexOf(unicode) === -1
+      ) {
+      return c;
+    }
+    return encodeURIComponent(c);
+  }
+
+  var EOF, ALPHA = /[a-zA-Z]/,
+      ALPHANUMERIC = /[a-zA-Z0-9\+\-\.]/;
+
+  function parse(input, stateOverride, base) {
+    function err(message) {
+      errors.push(message);
+    }
+
+    var state = stateOverride || 'scheme start',
+        cursor = 0,
+        buffer = '',
+        seenAt = false,
+        seenBracket = false,
+        errors = [];
+
+    loop: while ((input[cursor - 1] !== EOF || cursor === 0) &&
+                 !this._isInvalid) {
+      var c = input[cursor];
+      switch (state) {
+        case 'scheme start':
+          if (c && ALPHA.test(c)) {
+            buffer += c.toLowerCase(); // ASCII-safe
+            state = 'scheme';
+          } else if (!stateOverride) {
+            buffer = '';
+            state = 'no scheme';
+            continue;
+          } else {
+            err('Invalid scheme.');
+            break loop;
+          }
+          break;
+
+        case 'scheme':
+          if (c && ALPHANUMERIC.test(c)) {
+            buffer += c.toLowerCase(); // ASCII-safe
+          } else if (c === ':') {
+            this._scheme = buffer;
+            buffer = '';
+            if (stateOverride) {
+              break loop;
+            }
+            if (isRelativeScheme(this._scheme)) {
+              this._isRelative = true;
+            }
+            if (this._scheme === 'file') {
+              state = 'relative';
+            } else if (this._isRelative && base &&
+                       base._scheme === this._scheme) {
+              state = 'relative or authority';
+            } else if (this._isRelative) {
+              state = 'authority first slash';
+            } else {
+              state = 'scheme data';
+            }
+          } else if (!stateOverride) {
+            buffer = '';
+            cursor = 0;
+            state = 'no scheme';
+            continue;
+          } else if (c === EOF) {
+            break loop;
+          } else {
+            err('Code point not allowed in scheme: ' + c);
+            break loop;
+          }
+          break;
+
+        case 'scheme data':
+          if (c === '?') {
+            this._query = '?';
+            state = 'query';
+          } else if (c === '#') {
+            this._fragment = '#';
+            state = 'fragment';
+          } else {
+            // XXX error handling
+            if (c !== EOF && c !== '\t' && c !== '\n' && c !== '\r') {
+              this._schemeData += percentEscape(c);
+            }
+          }
+          break;
+
+        case 'no scheme':
+          if (!base || !(isRelativeScheme(base._scheme))) {
+            err('Missing scheme.');
+            invalid.call(this);
+          } else {
+            state = 'relative';
+            continue;
+          }
+          break;
+
+        case 'relative or authority':
+          if (c === '/' && input[cursor + 1] === '/') {
+            state = 'authority ignore slashes';
+          } else {
+            err('Expected /, got: ' + c);
+            state = 'relative';
+            continue;
+          }
+          break;
+
+        case 'relative':
+          this._isRelative = true;
+          if (this._scheme !== 'file') {
+            this._scheme = base._scheme;
+          }
+          if (c === EOF) {
+            this._host = base._host;
+            this._port = base._port;
+            this._path = base._path.slice();
+            this._query = base._query;
+            this._username = base._username;
+            this._password = base._password;
+            break loop;
+          } else if (c === '/' || c === '\\') {
+            if (c === '\\') {
+              err('\\ is an invalid code point.');
+            }
+            state = 'relative slash';
+          } else if (c === '?') {
+            this._host = base._host;
+            this._port = base._port;
+            this._path = base._path.slice();
+            this._query = '?';
+            this._username = base._username;
+            this._password = base._password;
+            state = 'query';
+          } else if (c === '#') {
+            this._host = base._host;
+            this._port = base._port;
+            this._path = base._path.slice();
+            this._query = base._query;
+            this._fragment = '#';
+            this._username = base._username;
+            this._password = base._password;
+            state = 'fragment';
+          } else {
+            var nextC = input[cursor + 1];
+            var nextNextC = input[cursor + 2];
+            if (this._scheme !== 'file' || !ALPHA.test(c) ||
+                (nextC !== ':' && nextC !== '|') ||
+                (nextNextC !== EOF && nextNextC !== '/' && nextNextC !== '\\' &&
+                 nextNextC !== '?' && nextNextC !== '#')) {
+              this._host = base._host;
+              this._port = base._port;
+              this._username = base._username;
+              this._password = base._password;
+              this._path = base._path.slice();
+              this._path.pop();
+            }
+            state = 'relative path';
+            continue;
+          }
+          break;
+
+        case 'relative slash':
+          if (c === '/' || c === '\\') {
+            if (c === '\\') {
+              err('\\ is an invalid code point.');
+            }
+            if (this._scheme === 'file') {
+              state = 'file host';
+            } else {
+              state = 'authority ignore slashes';
+            }
+          } else {
+            if (this._scheme !== 'file') {
+              this._host = base._host;
+              this._port = base._port;
+              this._username = base._username;
+              this._password = base._password;
+            }
+            state = 'relative path';
+            continue;
+          }
+          break;
+
+        case 'authority first slash':
+          if (c === '/') {
+            state = 'authority second slash';
+          } else {
+            err('Expected \'/\', got: ' + c);
+            state = 'authority ignore slashes';
+            continue;
+          }
+          break;
+
+        case 'authority second slash':
+          state = 'authority ignore slashes';
+          if (c !== '/') {
+            err('Expected \'/\', got: ' + c);
+            continue;
+          }
+          break;
+
+        case 'authority ignore slashes':
+          if (c !== '/' && c !== '\\') {
+            state = 'authority';
+            continue;
+          } else {
+            err('Expected authority, got: ' + c);
+          }
+          break;
+
+        case 'authority':
+          if (c === '@') {
+            if (seenAt) {
+              err('@ already seen.');
+              buffer += '%40';
+            }
+            seenAt = true;
+            for (var i = 0; i < buffer.length; i++) {
+              var cp = buffer[i];
+              if (cp === '\t' || cp === '\n' || cp === '\r') {
+                err('Invalid whitespace in authority.');
+                continue;
+              }
+              // XXX check URL code points
+              if (cp === ':' && this._password === null) {
+                this._password = '';
+                continue;
+              }
+              var tempC = percentEscape(cp);
+              if (this._password !== null) {
+                this._password += tempC;
+              } else {
+                this._username += tempC;
+              }
+            }
+            buffer = '';
+          } else if (c === EOF || c === '/' || c === '\\' ||
+                     c === '?' || c === '#') {
+            cursor -= buffer.length;
+            buffer = '';
+            state = 'host';
+            continue;
+          } else {
+            buffer += c;
+          }
+          break;
+
+        case 'file host':
+          if (c === EOF || c === '/' || c === '\\' || c === '?' || c === '#') {
+            if (buffer.length === 2 && ALPHA.test(buffer[0]) &&
+                (buffer[1] === ':' || buffer[1] === '|')) {
+              state = 'relative path';
+            } else if (buffer.length === 0) {
+              state = 'relative path start';
+            } else {
+              this._host = IDNAToASCII.call(this, buffer);
+              buffer = '';
+              state = 'relative path start';
+            }
+            continue;
+          } else if (c === '\t' || c === '\n' || c === '\r') {
+            err('Invalid whitespace in file host.');
+          } else {
+            buffer += c;
+          }
+          break;
+
+        case 'host':
+        case 'hostname':
+          if (c === ':' && !seenBracket) {
+            // XXX host parsing
+            this._host = IDNAToASCII.call(this, buffer);
+            buffer = '';
+            state = 'port';
+            if (stateOverride === 'hostname') {
+              break loop;
+            }
+          } else if (c === EOF || c === '/' ||
+                     c === '\\' || c === '?' || c === '#') {
+            this._host = IDNAToASCII.call(this, buffer);
+            buffer = '';
+            state = 'relative path start';
+            if (stateOverride) {
+              break loop;
+            }
+            continue;
+          } else if (c !== '\t' && c !== '\n' && c !== '\r') {
+            if (c === '[') {
+              seenBracket = true;
+            } else if (c === ']') {
+              seenBracket = false;
+            }
+            buffer += c;
+          } else {
+            err('Invalid code point in host/hostname: ' + c);
+          }
+          break;
+
+        case 'port':
+          if (/[0-9]/.test(c)) {
+            buffer += c;
+          } else if (c === EOF || c === '/' || c === '\\' ||
+                     c === '?' || c === '#' || stateOverride) {
+            if (buffer !== '') {
+              var temp = parseInt(buffer, 10);
+              if (temp !== relative[this._scheme]) {
+                this._port = temp + '';
+              }
+              buffer = '';
+            }
+            if (stateOverride) {
+              break loop;
+            }
+            state = 'relative path start';
+            continue;
+          } else if (c === '\t' || c === '\n' || c === '\r') {
+            err('Invalid code point in port: ' + c);
+          } else {
+            invalid.call(this);
+          }
+          break;
+
+        case 'relative path start':
+          if (c === '\\') {
+            err('\'\\\' not allowed in path.');
+          }
+          state = 'relative path';
+          if (c !== '/' && c !== '\\') {
+            continue;
+          }
+          break;
+
+        case 'relative path':
+          if (c === EOF || c === '/' || c === '\\' ||
+              (!stateOverride && (c === '?' || c === '#'))) {
+            if (c === '\\') {
+              err('\\ not allowed in relative path.');
+            }
+            var tmp;
+            if ((tmp = relativePathDotMapping[buffer.toLowerCase()])) {
+              buffer = tmp;
+            }
+            if (buffer === '..') {
+              this._path.pop();
+              if (c !== '/' && c !== '\\') {
+                this._path.push('');
+              }
+            } else if (buffer === '.' && c !== '/' && c !== '\\') {
+              this._path.push('');
+            } else if (buffer !== '.') {
+              if (this._scheme === 'file' && this._path.length === 0 &&
+                  buffer.length === 2 && ALPHA.test(buffer[0]) &&
+                  buffer[1] === '|') {
+                buffer = buffer[0] + ':';
+              }
+              this._path.push(buffer);
+            }
+            buffer = '';
+            if (c === '?') {
+              this._query = '?';
+              state = 'query';
+            } else if (c === '#') {
+              this._fragment = '#';
+              state = 'fragment';
+            }
+          } else if (c !== '\t' && c !== '\n' && c !== '\r') {
+            buffer += percentEscape(c);
+          }
+          break;
+
+        case 'query':
+          if (!stateOverride && c === '#') {
+            this._fragment = '#';
+            state = 'fragment';
+          } else if (c !== EOF && c !== '\t' && c !== '\n' && c !== '\r') {
+            this._query += percentEscapeQuery(c);
+          }
+          break;
+
+        case 'fragment':
+          if (c !== EOF && c !== '\t' && c !== '\n' && c !== '\r') {
+            this._fragment += c;
+          }
+          break;
+      }
+
+      cursor++;
+    }
+  }
+
+  function clear() {
+    this._scheme = '';
+    this._schemeData = '';
+    this._username = '';
+    this._password = null;
+    this._host = '';
+    this._port = '';
+    this._path = [];
+    this._query = '';
+    this._fragment = '';
+    this._isInvalid = false;
+    this._isRelative = false;
+  }
+
+  // Does not process domain names or IP addresses.
+  // Does not handle encoding for the query parameter.
+  function JURL(url, base /* , encoding */) {
+    if (base !== undefined && !(base instanceof JURL)) {
+      base = new JURL(String(base));
+    }
+
+    this._url = url;
+    clear.call(this);
+
+    var input = url.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g, '');
+    // encoding = encoding || 'utf-8'
+
+    parse.call(this, input, null, base);
+  }
+
+  JURL.prototype = {
+    toString() {
+      return this.href;
+    },
+    get href() {
+      if (this._isInvalid) {
+        return this._url;
+      }
+      var authority = '';
+      if (this._username !== '' || this._password !== null) {
+        authority = this._username +
+          (this._password !== null ? ':' + this._password : '') + '@';
+      }
+
+      return this.protocol +
+          (this._isRelative ? '//' + authority + this.host : '') +
+          this.pathname + this._query + this._fragment;
+    },
+    // The named parameter should be different from the setter's function name.
+    // Otherwise Safari 5 will throw an error (see issue 8541)
+    set href(value) {
+      clear.call(this);
+      parse.call(this, value);
+    },
+
+    get protocol() {
+      return this._scheme + ':';
+    },
+    set protocol(value) {
+      if (this._isInvalid) {
+        return;
+      }
+      parse.call(this, value + ':', 'scheme start');
+    },
+
+    get host() {
+      return this._isInvalid ? '' : this._port ?
+          this._host + ':' + this._port : this._host;
+    },
+    set host(value) {
+      if (this._isInvalid || !this._isRelative) {
+        return;
+      }
+      parse.call(this, value, 'host');
+    },
+
+    get hostname() {
+      return this._host;
+    },
+    set hostname(value) {
+      if (this._isInvalid || !this._isRelative) {
+        return;
+      }
+      parse.call(this, value, 'hostname');
+    },
+
+    get port() {
+      return this._port;
+    },
+    set port(value) {
+      if (this._isInvalid || !this._isRelative) {
+        return;
+      }
+      parse.call(this, value, 'port');
+    },
+
+    get pathname() {
+      return this._isInvalid ? '' : this._isRelative ?
+          '/' + this._path.join('/') : this._schemeData;
+    },
+    set pathname(value) {
+      if (this._isInvalid || !this._isRelative) {
+        return;
+      }
+      this._path = [];
+      parse.call(this, value, 'relative path start');
+    },
+
+    get search() {
+      return this._isInvalid || !this._query || this._query === '?' ?
+          '' : this._query;
+    },
+    set search(value) {
+      if (this._isInvalid || !this._isRelative) {
+        return;
+      }
+      this._query = '?';
+      if (value[0] === '?') {
+        value = value.slice(1);
+      }
+      parse.call(this, value, 'query');
+    },
+
+    get hash() {
+      return this._isInvalid || !this._fragment || this._fragment === '#' ?
+          '' : this._fragment;
+    },
+    set hash(value) {
+      if (this._isInvalid) {
+        return;
+      }
+      this._fragment = '#';
+      if (value[0] === '#') {
+        value = value.slice(1);
+      }
+      parse.call(this, value, 'fragment');
+    },
+
+    get origin() {
+      var host;
+      if (this._isInvalid || !this._scheme) {
+        return '';
+      }
+      // javascript: Gecko returns String(""), WebKit/Blink String("null")
+      // Gecko throws error for "data://"
+      // data: Gecko returns "", Blink returns "data://", WebKit returns "null"
+      // Gecko returns String("") for file: mailto:
+      // WebKit/Blink returns String("SCHEME://") for file: mailto:
+      switch (this._scheme) {
+        case 'data':
+        case 'file':
+        case 'javascript':
+        case 'mailto':
+          return 'null';
+        case 'blob':
+          // Special case of blob: -- returns valid origin of _schemeData.
+          try {
+            return new JURL(this._schemeData).origin || 'null';
+          } catch (_) {
+            // Invalid _schemeData origin -- ignoring errors.
+          }
+          return 'null';
+      }
+      host = this.host;
+      if (!host) {
+        return '';
+      }
+      return this._scheme + '://' + host;
+    },
+  };
+
+  exports.URL = JURL;
+})();

File diff suppressed because it is too large
+ 7247 - 0
image_decoders/pdf.image_decoders.js


File diff suppressed because it is too large
+ 0 - 0
image_decoders/pdf.image_decoders.js.map


File diff suppressed because it is too large
+ 0 - 0
image_decoders/pdf.image_decoders.min.js


File diff suppressed because it is too large
+ 301 - 88
lib/core/annotation.js


+ 275 - 245
lib/core/arithmetic_decoder.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -24,244 +24,257 @@
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-var ArithmeticDecoder = function ArithmeticDecoderClosure() {
-  var QeTable = [{
-    qe: 0x5601,
-    nmps: 1,
-    nlps: 1,
-    switchFlag: 1
-  }, {
-    qe: 0x3401,
-    nmps: 2,
-    nlps: 6,
-    switchFlag: 0
-  }, {
-    qe: 0x1801,
-    nmps: 3,
-    nlps: 9,
-    switchFlag: 0
-  }, {
-    qe: 0x0AC1,
-    nmps: 4,
-    nlps: 12,
-    switchFlag: 0
-  }, {
-    qe: 0x0521,
-    nmps: 5,
-    nlps: 29,
-    switchFlag: 0
-  }, {
-    qe: 0x0221,
-    nmps: 38,
-    nlps: 33,
-    switchFlag: 0
-  }, {
-    qe: 0x5601,
-    nmps: 7,
-    nlps: 6,
-    switchFlag: 1
-  }, {
-    qe: 0x5401,
-    nmps: 8,
-    nlps: 14,
-    switchFlag: 0
-  }, {
-    qe: 0x4801,
-    nmps: 9,
-    nlps: 14,
-    switchFlag: 0
-  }, {
-    qe: 0x3801,
-    nmps: 10,
-    nlps: 14,
-    switchFlag: 0
-  }, {
-    qe: 0x3001,
-    nmps: 11,
-    nlps: 17,
-    switchFlag: 0
-  }, {
-    qe: 0x2401,
-    nmps: 12,
-    nlps: 18,
-    switchFlag: 0
-  }, {
-    qe: 0x1C01,
-    nmps: 13,
-    nlps: 20,
-    switchFlag: 0
-  }, {
-    qe: 0x1601,
-    nmps: 29,
-    nlps: 21,
-    switchFlag: 0
-  }, {
-    qe: 0x5601,
-    nmps: 15,
-    nlps: 14,
-    switchFlag: 1
-  }, {
-    qe: 0x5401,
-    nmps: 16,
-    nlps: 14,
-    switchFlag: 0
-  }, {
-    qe: 0x5101,
-    nmps: 17,
-    nlps: 15,
-    switchFlag: 0
-  }, {
-    qe: 0x4801,
-    nmps: 18,
-    nlps: 16,
-    switchFlag: 0
-  }, {
-    qe: 0x3801,
-    nmps: 19,
-    nlps: 17,
-    switchFlag: 0
-  }, {
-    qe: 0x3401,
-    nmps: 20,
-    nlps: 18,
-    switchFlag: 0
-  }, {
-    qe: 0x3001,
-    nmps: 21,
-    nlps: 19,
-    switchFlag: 0
-  }, {
-    qe: 0x2801,
-    nmps: 22,
-    nlps: 19,
-    switchFlag: 0
-  }, {
-    qe: 0x2401,
-    nmps: 23,
-    nlps: 20,
-    switchFlag: 0
-  }, {
-    qe: 0x2201,
-    nmps: 24,
-    nlps: 21,
-    switchFlag: 0
-  }, {
-    qe: 0x1C01,
-    nmps: 25,
-    nlps: 22,
-    switchFlag: 0
-  }, {
-    qe: 0x1801,
-    nmps: 26,
-    nlps: 23,
-    switchFlag: 0
-  }, {
-    qe: 0x1601,
-    nmps: 27,
-    nlps: 24,
-    switchFlag: 0
-  }, {
-    qe: 0x1401,
-    nmps: 28,
-    nlps: 25,
-    switchFlag: 0
-  }, {
-    qe: 0x1201,
-    nmps: 29,
-    nlps: 26,
-    switchFlag: 0
-  }, {
-    qe: 0x1101,
-    nmps: 30,
-    nlps: 27,
-    switchFlag: 0
-  }, {
-    qe: 0x0AC1,
-    nmps: 31,
-    nlps: 28,
-    switchFlag: 0
-  }, {
-    qe: 0x09C1,
-    nmps: 32,
-    nlps: 29,
-    switchFlag: 0
-  }, {
-    qe: 0x08A1,
-    nmps: 33,
-    nlps: 30,
-    switchFlag: 0
-  }, {
-    qe: 0x0521,
-    nmps: 34,
-    nlps: 31,
-    switchFlag: 0
-  }, {
-    qe: 0x0441,
-    nmps: 35,
-    nlps: 32,
-    switchFlag: 0
-  }, {
-    qe: 0x02A1,
-    nmps: 36,
-    nlps: 33,
-    switchFlag: 0
-  }, {
-    qe: 0x0221,
-    nmps: 37,
-    nlps: 34,
-    switchFlag: 0
-  }, {
-    qe: 0x0141,
-    nmps: 38,
-    nlps: 35,
-    switchFlag: 0
-  }, {
-    qe: 0x0111,
-    nmps: 39,
-    nlps: 36,
-    switchFlag: 0
-  }, {
-    qe: 0x0085,
-    nmps: 40,
-    nlps: 37,
-    switchFlag: 0
-  }, {
-    qe: 0x0049,
-    nmps: 41,
-    nlps: 38,
-    switchFlag: 0
-  }, {
-    qe: 0x0025,
-    nmps: 42,
-    nlps: 39,
-    switchFlag: 0
-  }, {
-    qe: 0x0015,
-    nmps: 43,
-    nlps: 40,
-    switchFlag: 0
-  }, {
-    qe: 0x0009,
-    nmps: 44,
-    nlps: 41,
-    switchFlag: 0
-  }, {
-    qe: 0x0005,
-    nmps: 45,
-    nlps: 42,
-    switchFlag: 0
-  }, {
-    qe: 0x0001,
-    nmps: 45,
-    nlps: 43,
-    switchFlag: 0
-  }, {
-    qe: 0x5601,
-    nmps: 46,
-    nlps: 46,
-    switchFlag: 0
-  }];
+exports.ArithmeticDecoder = void 0;
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
+
+function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
+
+var QeTable = [{
+  qe: 0x5601,
+  nmps: 1,
+  nlps: 1,
+  switchFlag: 1
+}, {
+  qe: 0x3401,
+  nmps: 2,
+  nlps: 6,
+  switchFlag: 0
+}, {
+  qe: 0x1801,
+  nmps: 3,
+  nlps: 9,
+  switchFlag: 0
+}, {
+  qe: 0x0AC1,
+  nmps: 4,
+  nlps: 12,
+  switchFlag: 0
+}, {
+  qe: 0x0521,
+  nmps: 5,
+  nlps: 29,
+  switchFlag: 0
+}, {
+  qe: 0x0221,
+  nmps: 38,
+  nlps: 33,
+  switchFlag: 0
+}, {
+  qe: 0x5601,
+  nmps: 7,
+  nlps: 6,
+  switchFlag: 1
+}, {
+  qe: 0x5401,
+  nmps: 8,
+  nlps: 14,
+  switchFlag: 0
+}, {
+  qe: 0x4801,
+  nmps: 9,
+  nlps: 14,
+  switchFlag: 0
+}, {
+  qe: 0x3801,
+  nmps: 10,
+  nlps: 14,
+  switchFlag: 0
+}, {
+  qe: 0x3001,
+  nmps: 11,
+  nlps: 17,
+  switchFlag: 0
+}, {
+  qe: 0x2401,
+  nmps: 12,
+  nlps: 18,
+  switchFlag: 0
+}, {
+  qe: 0x1C01,
+  nmps: 13,
+  nlps: 20,
+  switchFlag: 0
+}, {
+  qe: 0x1601,
+  nmps: 29,
+  nlps: 21,
+  switchFlag: 0
+}, {
+  qe: 0x5601,
+  nmps: 15,
+  nlps: 14,
+  switchFlag: 1
+}, {
+  qe: 0x5401,
+  nmps: 16,
+  nlps: 14,
+  switchFlag: 0
+}, {
+  qe: 0x5101,
+  nmps: 17,
+  nlps: 15,
+  switchFlag: 0
+}, {
+  qe: 0x4801,
+  nmps: 18,
+  nlps: 16,
+  switchFlag: 0
+}, {
+  qe: 0x3801,
+  nmps: 19,
+  nlps: 17,
+  switchFlag: 0
+}, {
+  qe: 0x3401,
+  nmps: 20,
+  nlps: 18,
+  switchFlag: 0
+}, {
+  qe: 0x3001,
+  nmps: 21,
+  nlps: 19,
+  switchFlag: 0
+}, {
+  qe: 0x2801,
+  nmps: 22,
+  nlps: 19,
+  switchFlag: 0
+}, {
+  qe: 0x2401,
+  nmps: 23,
+  nlps: 20,
+  switchFlag: 0
+}, {
+  qe: 0x2201,
+  nmps: 24,
+  nlps: 21,
+  switchFlag: 0
+}, {
+  qe: 0x1C01,
+  nmps: 25,
+  nlps: 22,
+  switchFlag: 0
+}, {
+  qe: 0x1801,
+  nmps: 26,
+  nlps: 23,
+  switchFlag: 0
+}, {
+  qe: 0x1601,
+  nmps: 27,
+  nlps: 24,
+  switchFlag: 0
+}, {
+  qe: 0x1401,
+  nmps: 28,
+  nlps: 25,
+  switchFlag: 0
+}, {
+  qe: 0x1201,
+  nmps: 29,
+  nlps: 26,
+  switchFlag: 0
+}, {
+  qe: 0x1101,
+  nmps: 30,
+  nlps: 27,
+  switchFlag: 0
+}, {
+  qe: 0x0AC1,
+  nmps: 31,
+  nlps: 28,
+  switchFlag: 0
+}, {
+  qe: 0x09C1,
+  nmps: 32,
+  nlps: 29,
+  switchFlag: 0
+}, {
+  qe: 0x08A1,
+  nmps: 33,
+  nlps: 30,
+  switchFlag: 0
+}, {
+  qe: 0x0521,
+  nmps: 34,
+  nlps: 31,
+  switchFlag: 0
+}, {
+  qe: 0x0441,
+  nmps: 35,
+  nlps: 32,
+  switchFlag: 0
+}, {
+  qe: 0x02A1,
+  nmps: 36,
+  nlps: 33,
+  switchFlag: 0
+}, {
+  qe: 0x0221,
+  nmps: 37,
+  nlps: 34,
+  switchFlag: 0
+}, {
+  qe: 0x0141,
+  nmps: 38,
+  nlps: 35,
+  switchFlag: 0
+}, {
+  qe: 0x0111,
+  nmps: 39,
+  nlps: 36,
+  switchFlag: 0
+}, {
+  qe: 0x0085,
+  nmps: 40,
+  nlps: 37,
+  switchFlag: 0
+}, {
+  qe: 0x0049,
+  nmps: 41,
+  nlps: 38,
+  switchFlag: 0
+}, {
+  qe: 0x0025,
+  nmps: 42,
+  nlps: 39,
+  switchFlag: 0
+}, {
+  qe: 0x0015,
+  nmps: 43,
+  nlps: 40,
+  switchFlag: 0
+}, {
+  qe: 0x0009,
+  nmps: 44,
+  nlps: 41,
+  switchFlag: 0
+}, {
+  qe: 0x0005,
+  nmps: 45,
+  nlps: 42,
+  switchFlag: 0
+}, {
+  qe: 0x0001,
+  nmps: 45,
+  nlps: 43,
+  switchFlag: 0
+}, {
+  qe: 0x5601,
+  nmps: 46,
+  nlps: 46,
+  switchFlag: 0
+}];
+
+var ArithmeticDecoder =
+/*#__PURE__*/
+function () {
   function ArithmeticDecoder(data, start, end) {
+    _classCallCheck(this, ArithmeticDecoder);
+
     this.data = data;
     this.bp = start;
     this.dataEnd = end;
@@ -273,13 +286,15 @@ var ArithmeticDecoder = function ArithmeticDecoderClosure() {
     this.ct -= 7;
     this.a = 0x8000;
   }
-  ArithmeticDecoder.prototype = {
-    byteIn: function ArithmeticDecoder_byteIn() {
+
+  _createClass(ArithmeticDecoder, [{
+    key: "byteIn",
+    value: function byteIn() {
       var data = this.data;
       var bp = this.bp;
+
       if (data[bp] === 0xFF) {
-        var b1 = data[bp + 1];
-        if (b1 > 0x8F) {
+        if (data[bp + 1] > 0x8F) {
           this.clow += 0xFF00;
           this.ct = 8;
         } else {
@@ -294,18 +309,22 @@ var ArithmeticDecoder = function ArithmeticDecoderClosure() {
         this.ct = 8;
         this.bp = bp;
       }
+
       if (this.clow > 0xFFFF) {
         this.chigh += this.clow >> 16;
         this.clow &= 0xFFFF;
       }
-    },
-    readBit: function ArithmeticDecoder_readBit(contexts, pos) {
+    }
+  }, {
+    key: "readBit",
+    value: function readBit(contexts, pos) {
       var cx_index = contexts[pos] >> 1,
           cx_mps = contexts[pos] & 1;
       var qeTableIcx = QeTable[cx_index];
       var qeIcx = qeTableIcx.qe;
       var d;
       var a = this.a - qeIcx;
+
       if (this.chigh < qeIcx) {
         if (a < qeIcx) {
           a = qeIcx;
@@ -314,42 +333,53 @@ var ArithmeticDecoder = function ArithmeticDecoderClosure() {
         } else {
           a = qeIcx;
           d = 1 ^ cx_mps;
+
           if (qeTableIcx.switchFlag === 1) {
             cx_mps = d;
           }
+
           cx_index = qeTableIcx.nlps;
         }
       } else {
         this.chigh -= qeIcx;
+
         if ((a & 0x8000) !== 0) {
           this.a = a;
           return cx_mps;
         }
+
         if (a < qeIcx) {
           d = 1 ^ cx_mps;
+
           if (qeTableIcx.switchFlag === 1) {
             cx_mps = d;
           }
+
           cx_index = qeTableIcx.nlps;
         } else {
           d = cx_mps;
           cx_index = qeTableIcx.nmps;
         }
       }
+
       do {
         if (this.ct === 0) {
           this.byteIn();
         }
+
         a <<= 1;
         this.chigh = this.chigh << 1 & 0xFFFF | this.clow >> 15 & 1;
         this.clow = this.clow << 1 & 0xFFFF;
         this.ct--;
       } while ((a & 0x8000) === 0);
+
       this.a = a;
       contexts[pos] = cx_index << 1 | cx_mps;
       return d;
     }
-  };
+  }]);
+
   return ArithmeticDecoder;
 }();
+
 exports.ArithmeticDecoder = ArithmeticDecoder;

+ 65 - 6
lib/core/bidi.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,36 +19,42 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.bidi = undefined;
+exports.bidi = bidi;
 
-var _util = require('../shared/util');
+var _util = require("../shared/util");
 
 var baseTypes = ['BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'S', 'B', 'S', 'WS', 'B', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'B', 'B', 'B', 'S', 'WS', 'ON', 'ON', 'ET', 'ET', 'ET', 'ON', 'ON', 'ON', 'ON', 'ON', 'ES', 'CS', 'ES', 'CS', 'CS', 'EN', 'EN', 'EN', 'EN', 'EN', 'EN', 'EN', 'EN', 'EN', 'EN', 'CS', 'ON', 'ON', 'ON', 'ON', 'ON', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'ON', 'ON', 'ON', 'ON', 'ON', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'ON', 'ON', 'ON', 'ON', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'B', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'CS', 'ON', 'ET', 'ET', 'ET', 'ET', 'ON', 'ON', 'ON', 'ON', 'L', 'ON', 'ON', 'BN', 'ON', 'ON', 'ET', 'ET', 'EN', 'EN', 'ON', 'L', 'ON', 'ON', 'ON', 'EN', 'L', 'ON', 'ON', 'ON', 'ON', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'ON', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L'];
 var arabicTypes = ['AN', 'AN', 'AN', 'AN', 'AN', 'AN', 'ON', 'ON', 'AL', 'ET', 'ET', 'AL', 'CS', 'AL', 'ON', 'ON', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'AL', 'AL', '', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'AN', 'AN', 'AN', 'AN', 'AN', 'AN', 'AN', 'AN', 'AN', 'AN', 'ET', 'AN', 'AN', 'AL', 'AL', 'AL', 'NSM', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'AN', 'ON', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'NSM', 'AL', 'AL', 'NSM', 'NSM', 'ON', 'NSM', 'NSM', 'NSM', 'NSM', 'AL', 'AL', 'EN', 'EN', 'EN', 'EN', 'EN', 'EN', 'EN', 'EN', 'EN', 'EN', 'AL', 'AL', 'AL', 'AL', 'AL', 'AL'];
+
 function isOdd(i) {
   return (i & 1) !== 0;
 }
+
 function isEven(i) {
   return (i & 1) === 0;
 }
+
 function findUnequal(arr, start, value) {
   for (var j = start, jj = arr.length; j < jj; ++j) {
     if (arr[j] !== value) {
       return j;
     }
   }
+
   return j;
 }
+
 function setValues(arr, start, end, value) {
   for (var j = start; j < end; ++j) {
     arr[j] = value;
   }
 }
+
 function reverseValues(arr, start, end) {
   for (var i = start, j = end - 1; i < j; ++i, --j) {
     var temp = arr[i];
@@ -56,49 +62,61 @@ function reverseValues(arr, start, end) {
     arr[j] = temp;
   }
 }
+
 function createBidiText(str, isLTR, vertical) {
   return {
     str: str,
     dir: vertical ? 'ttb' : isLTR ? 'ltr' : 'rtl'
   };
 }
+
 var chars = [];
 var types = [];
+
 function bidi(str, startLevel, vertical) {
   var isLTR = true;
   var strLength = str.length;
+
   if (strLength === 0 || vertical) {
     return createBidiText(str, isLTR, vertical);
   }
+
   chars.length = strLength;
   types.length = strLength;
   var numBidi = 0;
   var i, ii;
+
   for (i = 0; i < strLength; ++i) {
     chars[i] = str.charAt(i);
     var charCode = str.charCodeAt(i);
     var charType = 'L';
+
     if (charCode <= 0x00ff) {
       charType = baseTypes[charCode];
     } else if (0x0590 <= charCode && charCode <= 0x05f4) {
       charType = 'R';
     } else if (0x0600 <= charCode && charCode <= 0x06ff) {
       charType = arabicTypes[charCode & 0xff];
+
       if (!charType) {
         (0, _util.warn)('Bidi: invalid Unicode character ' + charCode.toString(16));
       }
     } else if (0x0700 <= charCode && charCode <= 0x08AC) {
       charType = 'AL';
     }
+
     if (charType === 'R' || charType === 'AL' || charType === 'AN') {
       numBidi++;
     }
+
     types[i] = charType;
   }
+
   if (numBidi === 0) {
     isLTR = true;
     return createBidiText(str, isLTR);
   }
+
   if (startLevel === -1) {
     if (numBidi / strLength < 0.3) {
       isLTR = true;
@@ -108,14 +126,18 @@ function bidi(str, startLevel, vertical) {
       startLevel = 1;
     }
   }
+
   var levels = [];
+
   for (i = 0; i < strLength; ++i) {
     levels[i] = startLevel;
   }
+
   var e = isOdd(startLevel) ? 'R' : 'L';
   var sor = e;
   var eor = sor;
   var lastType = sor;
+
   for (i = 0; i < strLength; ++i) {
     if (types[i] === 'NSM') {
       types[i] = lastType;
@@ -123,92 +145,120 @@ function bidi(str, startLevel, vertical) {
       lastType = types[i];
     }
   }
+
   lastType = sor;
   var t;
+
   for (i = 0; i < strLength; ++i) {
     t = types[i];
+
     if (t === 'EN') {
       types[i] = lastType === 'AL' ? 'AN' : 'EN';
     } else if (t === 'R' || t === 'L' || t === 'AL') {
       lastType = t;
     }
   }
+
   for (i = 0; i < strLength; ++i) {
     t = types[i];
+
     if (t === 'AL') {
       types[i] = 'R';
     }
   }
+
   for (i = 1; i < strLength - 1; ++i) {
     if (types[i] === 'ES' && types[i - 1] === 'EN' && types[i + 1] === 'EN') {
       types[i] = 'EN';
     }
+
     if (types[i] === 'CS' && (types[i - 1] === 'EN' || types[i - 1] === 'AN') && types[i + 1] === types[i - 1]) {
       types[i] = types[i - 1];
     }
   }
+
   for (i = 0; i < strLength; ++i) {
     if (types[i] === 'EN') {
       var j;
+
       for (j = i - 1; j >= 0; --j) {
         if (types[j] !== 'ET') {
           break;
         }
+
         types[j] = 'EN';
       }
+
       for (j = i + 1; j < strLength; ++j) {
         if (types[j] !== 'ET') {
           break;
         }
+
         types[j] = 'EN';
       }
     }
   }
+
   for (i = 0; i < strLength; ++i) {
     t = types[i];
+
     if (t === 'WS' || t === 'ES' || t === 'ET' || t === 'CS') {
       types[i] = 'ON';
     }
   }
+
   lastType = sor;
+
   for (i = 0; i < strLength; ++i) {
     t = types[i];
+
     if (t === 'EN') {
       types[i] = lastType === 'L' ? 'L' : 'EN';
     } else if (t === 'R' || t === 'L') {
       lastType = t;
     }
   }
+
   for (i = 0; i < strLength; ++i) {
     if (types[i] === 'ON') {
       var end = findUnequal(types, i + 1, 'ON');
       var before = sor;
+
       if (i > 0) {
         before = types[i - 1];
       }
+
       var after = eor;
+
       if (end + 1 < strLength) {
         after = types[end + 1];
       }
+
       if (before !== 'L') {
         before = 'R';
       }
+
       if (after !== 'L') {
         after = 'R';
       }
+
       if (before === after) {
         setValues(types, i, end, before);
       }
+
       i = end - 1;
     }
   }
+
   for (i = 0; i < strLength; ++i) {
     if (types[i] === 'ON') {
       types[i] = e;
     }
   }
+
   for (i = 0; i < strLength; ++i) {
     t = types[i];
+
     if (isEven(levels[i])) {
       if (t === 'R') {
         levels[i] += 1;
@@ -221,20 +271,26 @@ function bidi(str, startLevel, vertical) {
       }
     }
   }
+
   var highestLevel = -1;
   var lowestOddLevel = 99;
   var level;
+
   for (i = 0, ii = levels.length; i < ii; ++i) {
     level = levels[i];
+
     if (highestLevel < level) {
       highestLevel = level;
     }
+
     if (lowestOddLevel > level && isOdd(level)) {
       lowestOddLevel = level;
     }
   }
+
   for (level = highestLevel; level >= lowestOddLevel; --level) {
     var start = -1;
+
     for (i = 0, ii = levels.length; i < ii; ++i) {
       if (levels[i] < level) {
         if (start >= 0) {
@@ -245,16 +301,19 @@ function bidi(str, startLevel, vertical) {
         start = i;
       }
     }
+
     if (start >= 0) {
       reverseValues(chars, start, levels.length);
     }
   }
+
   for (i = 0, ii = chars.length; i < ii; ++i) {
     var ch = chars[i];
+
     if (ch === '<' || ch === '>') {
       chars[i] = '';
     }
   }
+
   return createBidiText(chars.join(''), isLTR);
-}
-exports.bidi = bidi;
+}

+ 173 - 18
lib/core/ccitt.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,14 +19,14 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.CCITTFaxDecoder = undefined;
+exports.CCITTFaxDecoder = void 0;
 
-var _util = require('../shared/util');
+var _util = require("../shared/util");
 
 var CCITTFaxDecoder = function CCITTFaxDecoder() {
   var ccittEOL = -2;
@@ -46,12 +46,14 @@ var CCITTFaxDecoder = function CCITTFaxDecoder() {
   var blackTable1 = [[-1, -1], [-1, -1], [12, ccittEOL], [12, ccittEOL], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [11, 1792], [11, 1792], [11, 1792], [11, 1792], [12, 1984], [12, 1984], [12, 2048], [12, 2048], [12, 2112], [12, 2112], [12, 2176], [12, 2176], [12, 2240], [12, 2240], [12, 2304], [12, 2304], [11, 1856], [11, 1856], [11, 1856], [11, 1856], [11, 1920], [11, 1920], [11, 1920], [11, 1920], [12, 2368], [12, 2368], [12, 2432], [12, 2432], [12, 2496], [12, 2496], [12, 2560], [12, 2560], [10, 18], [10, 18], [10, 18], [10, 18], [10, 18], [10, 18], [10, 18], [10, 18], [12, 52], [12, 52], [13, 640], [13, 704], [13, 768], [13, 832], [12, 55], [12, 55], [12, 56], [12, 56], [13, 1280], [13, 1344], [13, 1408], [13, 1472], [12, 59], [12, 59], [12, 60], [12, 60], [13, 1536], [13, 1600], [11, 24], [11, 24], [11, 24], [11, 24], [11, 25], [11, 25], [11, 25], [11, 25], [13, 1664], [13, 1728], [12, 320], [12, 320], [12, 384], [12, 384], [12, 448], [12, 448], [13, 512], [13, 576], [12, 53], [12, 53], [12, 54], [12, 54], [13, 896], [13, 960], [13, 1024], [13, 1088], [13, 1152], [13, 1216], [10, 64], [10, 64], [10, 64], [10, 64], [10, 64], [10, 64], [10, 64], [10, 64]];
   var blackTable2 = [[8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [8, 13], [11, 23], [11, 23], [12, 50], [12, 51], [12, 44], [12, 45], [12, 46], [12, 47], [12, 57], [12, 58], [12, 61], [12, 256], [10, 16], [10, 16], [10, 16], [10, 16], [10, 17], [10, 17], [10, 17], [10, 17], [12, 48], [12, 49], [12, 62], [12, 63], [12, 30], [12, 31], [12, 32], [12, 33], [12, 40], [12, 41], [11, 22], [11, 22], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [8, 14], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 10], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [7, 11], [9, 15], [9, 15], [9, 15], [9, 15], [9, 15], [9, 15], [9, 15], [9, 15], [12, 128], [12, 192], [12, 26], [12, 27], [12, 28], [12, 29], [11, 19], [11, 19], [11, 20], [11, 20], [12, 34], [12, 35], [12, 36], [12, 37], [12, 38], [12, 39], [11, 21], [11, 21], [12, 42], [12, 43], [10, 0], [10, 0], [10, 0], [10, 0], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12], [7, 12]];
   var blackTable3 = [[-1, -1], [-1, -1], [-1, -1], [-1, -1], [6, 9], [6, 8], [5, 7], [5, 7], [4, 6], [4, 6], [4, 6], [4, 6], [4, 5], [4, 5], [4, 5], [4, 5], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2]];
+
   function CCITTFaxDecoder(source) {
     var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
 
     if (!source || typeof source.next !== 'function') {
       throw new Error('CCITTFaxDecoder - invalid "source" parameter.');
     }
+
     this.source = source;
     this.eof = false;
     this.encoding = options['K'] || 0;
@@ -60,9 +62,11 @@ var CCITTFaxDecoder = function CCITTFaxDecoder() {
     this.columns = options['Columns'] || 1728;
     this.rows = options['Rows'] || 0;
     var eoblock = options['EndOfBlock'];
+
     if (eoblock === null || eoblock === undefined) {
       eoblock = true;
     }
+
     this.eoblock = eoblock;
     this.black = options['BlackIs1'] || false;
     this.codingLine = new Uint32Array(this.columns + 1);
@@ -75,66 +79,79 @@ var CCITTFaxDecoder = function CCITTFaxDecoder() {
     this.inputBuf = 0;
     this.outputBits = 0;
     this.rowsDone = false;
-    var code1 = void 0;
+    var code1;
+
     while ((code1 = this._lookBits(12)) === 0) {
       this._eatBits(1);
     }
+
     if (code1 === 1) {
       this._eatBits(12);
     }
+
     if (this.encoding > 0) {
       this.nextLine2D = !this._lookBits(1);
+
       this._eatBits(1);
     }
   }
+
   CCITTFaxDecoder.prototype = {
     readNextChar: function readNextChar() {
       if (this.eof) {
         return -1;
       }
+
       var refLine = this.refLine;
       var codingLine = this.codingLine;
       var columns = this.columns;
-      var refPos = void 0,
-          blackPixels = void 0,
-          bits = void 0,
-          i = void 0;
+      var refPos, blackPixels, bits, i;
+
       if (this.outputBits === 0) {
         if (this.rowsDone) {
           this.eof = true;
         }
+
         if (this.eof) {
           return -1;
         }
+
         this.err = false;
-        var code1 = void 0,
-            code2 = void 0,
-            code3 = void 0;
+        var code1, code2, code3;
+
         if (this.nextLine2D) {
           for (i = 0; codingLine[i] < columns; ++i) {
             refLine[i] = codingLine[i];
           }
+
           refLine[i++] = columns;
           refLine[i] = columns;
           codingLine[0] = 0;
           this.codingPos = 0;
           refPos = 0;
           blackPixels = 0;
+
           while (codingLine[this.codingPos] < columns) {
             code1 = this._getTwoDimCode();
+
             switch (code1) {
               case twoDimPass:
                 this._addPixels(refLine[refPos + 1], blackPixels);
+
                 if (refLine[refPos + 1] < columns) {
                   refPos += 2;
                 }
+
                 break;
+
               case twoDimHoriz:
                 code1 = code2 = 0;
+
                 if (blackPixels) {
                   do {
                     code1 += code3 = this._getBlackCode();
                   } while (code3 >= 64);
+
                   do {
                     code2 += code3 = this._getWhiteCode();
                   } while (code3 >= 64);
@@ -142,107 +159,152 @@ var CCITTFaxDecoder = function CCITTFaxDecoder() {
                   do {
                     code1 += code3 = this._getWhiteCode();
                   } while (code3 >= 64);
+
                   do {
                     code2 += code3 = this._getBlackCode();
                   } while (code3 >= 64);
                 }
+
                 this._addPixels(codingLine[this.codingPos] + code1, blackPixels);
+
                 if (codingLine[this.codingPos] < columns) {
                   this._addPixels(codingLine[this.codingPos] + code2, blackPixels ^ 1);
                 }
+
                 while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) {
                   refPos += 2;
                 }
+
                 break;
+
               case twoDimVertR3:
                 this._addPixels(refLine[refPos] + 3, blackPixels);
+
                 blackPixels ^= 1;
+
                 if (codingLine[this.codingPos] < columns) {
                   ++refPos;
+
                   while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) {
                     refPos += 2;
                   }
                 }
+
                 break;
+
               case twoDimVertR2:
                 this._addPixels(refLine[refPos] + 2, blackPixels);
+
                 blackPixels ^= 1;
+
                 if (codingLine[this.codingPos] < columns) {
                   ++refPos;
+
                   while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) {
                     refPos += 2;
                   }
                 }
+
                 break;
+
               case twoDimVertR1:
                 this._addPixels(refLine[refPos] + 1, blackPixels);
+
                 blackPixels ^= 1;
+
                 if (codingLine[this.codingPos] < columns) {
                   ++refPos;
+
                   while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) {
                     refPos += 2;
                   }
                 }
+
                 break;
+
               case twoDimVert0:
                 this._addPixels(refLine[refPos], blackPixels);
+
                 blackPixels ^= 1;
+
                 if (codingLine[this.codingPos] < columns) {
                   ++refPos;
+
                   while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) {
                     refPos += 2;
                   }
                 }
+
                 break;
+
               case twoDimVertL3:
                 this._addPixelsNeg(refLine[refPos] - 3, blackPixels);
+
                 blackPixels ^= 1;
+
                 if (codingLine[this.codingPos] < columns) {
                   if (refPos > 0) {
                     --refPos;
                   } else {
                     ++refPos;
                   }
+
                   while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) {
                     refPos += 2;
                   }
                 }
+
                 break;
+
               case twoDimVertL2:
                 this._addPixelsNeg(refLine[refPos] - 2, blackPixels);
+
                 blackPixels ^= 1;
+
                 if (codingLine[this.codingPos] < columns) {
                   if (refPos > 0) {
                     --refPos;
                   } else {
                     ++refPos;
                   }
+
                   while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) {
                     refPos += 2;
                   }
                 }
+
                 break;
+
               case twoDimVertL1:
                 this._addPixelsNeg(refLine[refPos] - 1, blackPixels);
+
                 blackPixels ^= 1;
+
                 if (codingLine[this.codingPos] < columns) {
                   if (refPos > 0) {
                     --refPos;
                   } else {
                     ++refPos;
                   }
+
                   while (refLine[refPos] <= codingLine[this.codingPos] && refLine[refPos] < columns) {
                     refPos += 2;
                   }
                 }
+
                 break;
+
               case ccittEOF:
                 this._addPixels(columns, 0);
+
                 this.eof = true;
                 break;
+
               default:
                 (0, _util.info)('bad 2d code');
+
                 this._addPixels(columns, 0);
+
                 this.err = true;
             }
           }
@@ -250,8 +312,10 @@ var CCITTFaxDecoder = function CCITTFaxDecoder() {
           codingLine[0] = 0;
           this.codingPos = 0;
           blackPixels = 0;
+
           while (codingLine[this.codingPos] < columns) {
             code1 = 0;
+
             if (blackPixels) {
               do {
                 code1 += code3 = this._getBlackCode();
@@ -261,92 +325,125 @@ var CCITTFaxDecoder = function CCITTFaxDecoder() {
                 code1 += code3 = this._getWhiteCode();
               } while (code3 >= 64);
             }
+
             this._addPixels(codingLine[this.codingPos] + code1, blackPixels);
+
             blackPixels ^= 1;
           }
         }
+
         var gotEOL = false;
+
         if (this.byteAlign) {
           this.inputBits &= ~7;
         }
+
         if (!this.eoblock && this.row === this.rows - 1) {
           this.rowsDone = true;
         } else {
           code1 = this._lookBits(12);
+
           if (this.eoline) {
             while (code1 !== ccittEOF && code1 !== 1) {
               this._eatBits(1);
+
               code1 = this._lookBits(12);
             }
           } else {
             while (code1 === 0) {
               this._eatBits(1);
+
               code1 = this._lookBits(12);
             }
           }
+
           if (code1 === 1) {
             this._eatBits(12);
+
             gotEOL = true;
           } else if (code1 === ccittEOF) {
             this.eof = true;
           }
         }
+
         if (!this.eof && this.encoding > 0 && !this.rowsDone) {
           this.nextLine2D = !this._lookBits(1);
+
           this._eatBits(1);
         }
+
         if (this.eoblock && gotEOL && this.byteAlign) {
           code1 = this._lookBits(12);
+
           if (code1 === 1) {
             this._eatBits(12);
+
             if (this.encoding > 0) {
               this._lookBits(1);
+
               this._eatBits(1);
             }
+
             if (this.encoding >= 0) {
               for (i = 0; i < 4; ++i) {
                 code1 = this._lookBits(12);
+
                 if (code1 !== 1) {
                   (0, _util.info)('bad rtc code: ' + code1);
                 }
+
                 this._eatBits(12);
+
                 if (this.encoding > 0) {
                   this._lookBits(1);
+
                   this._eatBits(1);
                 }
               }
             }
+
             this.eof = true;
           }
         } else if (this.err && this.eoline) {
           while (true) {
             code1 = this._lookBits(13);
+
             if (code1 === ccittEOF) {
               this.eof = true;
               return -1;
             }
+
             if (code1 >> 1 === 1) {
               break;
             }
+
             this._eatBits(1);
           }
+
           this._eatBits(12);
+
           if (this.encoding > 0) {
             this._eatBits(1);
+
             this.nextLine2D = !(code1 & 1);
           }
         }
+
         if (codingLine[0] > 0) {
           this.outputBits = codingLine[this.codingPos = 0];
         } else {
           this.outputBits = codingLine[this.codingPos = 1];
         }
+
         this.row++;
       }
-      var c = void 0;
+
+      var c;
+
       if (this.outputBits >= 8) {
         c = this.codingPos & 1 ? 0 : 0xFF;
         this.outputBits -= 8;
+
         if (this.outputBits === 0 && codingLine[this.codingPos] < columns) {
           this.codingPos++;
           this.outputBits = codingLine[this.codingPos] - codingLine[this.codingPos - 1];
@@ -354,21 +451,27 @@ var CCITTFaxDecoder = function CCITTFaxDecoder() {
       } else {
         bits = 8;
         c = 0;
+
         do {
           if (this.outputBits > bits) {
             c <<= bits;
+
             if (!(this.codingPos & 1)) {
               c |= 0xFF >> 8 - bits;
             }
+
             this.outputBits -= bits;
             bits = 0;
           } else {
             c <<= this.outputBits;
+
             if (!(this.codingPos & 1)) {
               c |= 0xFF >> 8 - this.outputBits;
             }
+
             bits -= this.outputBits;
             this.outputBits = 0;
+
             if (codingLine[this.codingPos] < columns) {
               this.codingPos++;
               this.outputBits = codingLine[this.codingPos] - codingLine[this.codingPos - 1];
@@ -379,39 +482,48 @@ var CCITTFaxDecoder = function CCITTFaxDecoder() {
           }
         } while (bits);
       }
+
       if (this.black) {
         c ^= 0xFF;
       }
+
       return c;
     },
     _addPixels: function _addPixels(a1, blackPixels) {
       var codingLine = this.codingLine;
       var codingPos = this.codingPos;
+
       if (a1 > codingLine[codingPos]) {
         if (a1 > this.columns) {
           (0, _util.info)('row is wrong length');
           this.err = true;
           a1 = this.columns;
         }
+
         if (codingPos & 1 ^ blackPixels) {
           ++codingPos;
         }
+
         codingLine[codingPos] = a1;
       }
+
       this.codingPos = codingPos;
     },
     _addPixelsNeg: function _addPixelsNeg(a1, blackPixels) {
       var codingLine = this.codingLine;
       var codingPos = this.codingPos;
+
       if (a1 > codingLine[codingPos]) {
         if (a1 > this.columns) {
           (0, _util.info)('row is wrong length');
           this.err = true;
           a1 = this.columns;
         }
+
         if (codingPos & 1 ^ blackPixels) {
           ++codingPos;
         }
+
         codingLine[codingPos] = a1;
       } else if (a1 < codingLine[codingPos]) {
         if (a1 < 0) {
@@ -419,91 +531,119 @@ var CCITTFaxDecoder = function CCITTFaxDecoder() {
           this.err = true;
           a1 = 0;
         }
+
         while (codingPos > 0 && a1 < codingLine[codingPos - 1]) {
           --codingPos;
         }
+
         codingLine[codingPos] = a1;
       }
+
       this.codingPos = codingPos;
     },
     _findTableCode: function _findTableCode(start, end, table, limit) {
       var limitValue = limit || 0;
+
       for (var i = start; i <= end; ++i) {
         var code = this._lookBits(i);
+
         if (code === ccittEOF) {
           return [true, 1, false];
         }
+
         if (i < end) {
           code <<= end - i;
         }
+
         if (!limitValue || code >= limitValue) {
           var p = table[code - limitValue];
+
           if (p[0] === i) {
             this._eatBits(i);
+
             return [true, p[1], true];
           }
         }
       }
+
       return [false, 0, false];
     },
     _getTwoDimCode: function _getTwoDimCode() {
       var code = 0;
-      var p = void 0;
+      var p;
+
       if (this.eoblock) {
         code = this._lookBits(7);
         p = twoDimTable[code];
+
         if (p && p[0] > 0) {
           this._eatBits(p[0]);
+
           return p[1];
         }
       } else {
         var result = this._findTableCode(1, 7, twoDimTable);
+
         if (result[0] && result[2]) {
           return result[1];
         }
       }
+
       (0, _util.info)('Bad two dim code');
       return ccittEOF;
     },
     _getWhiteCode: function _getWhiteCode() {
       var code = 0;
-      var p = void 0;
+      var p;
+
       if (this.eoblock) {
         code = this._lookBits(12);
+
         if (code === ccittEOF) {
           return 1;
         }
+
         if (code >> 5 === 0) {
           p = whiteTable1[code];
         } else {
           p = whiteTable2[code >> 3];
         }
+
         if (p[0] > 0) {
           this._eatBits(p[0]);
+
           return p[1];
         }
       } else {
         var result = this._findTableCode(1, 9, whiteTable2);
+
         if (result[0]) {
           return result[1];
         }
+
         result = this._findTableCode(11, 12, whiteTable1);
+
         if (result[0]) {
           return result[1];
         }
       }
+
       (0, _util.info)('bad white code');
+
       this._eatBits(1);
+
       return 1;
     },
     _getBlackCode: function _getBlackCode() {
-      var code = void 0,
-          p = void 0;
+      var code, p;
+
       if (this.eoblock) {
         code = this._lookBits(13);
+
         if (code === ccittEOF) {
           return 1;
         }
+
         if (code >> 7 === 0) {
           p = blackTable1[code];
         } else if (code >> 9 === 0 && code >> 7 !== 0) {
@@ -511,40 +651,54 @@ var CCITTFaxDecoder = function CCITTFaxDecoder() {
         } else {
           p = blackTable3[code >> 7];
         }
+
         if (p[0] > 0) {
           this._eatBits(p[0]);
+
           return p[1];
         }
       } else {
         var result = this._findTableCode(2, 6, blackTable3);
+
         if (result[0]) {
           return result[1];
         }
+
         result = this._findTableCode(7, 12, blackTable2, 64);
+
         if (result[0]) {
           return result[1];
         }
+
         result = this._findTableCode(10, 13, blackTable1);
+
         if (result[0]) {
           return result[1];
         }
       }
+
       (0, _util.info)('bad black code');
+
       this._eatBits(1);
+
       return 1;
     },
     _lookBits: function _lookBits(n) {
-      var c = void 0;
+      var c;
+
       while (this.inputBits < n) {
         if ((c = this.source.next()) === -1) {
           if (this.inputBits === 0) {
             return ccittEOF;
           }
+
           return this.inputBuf << n - this.inputBits & 0xFFFF >> 16 - n;
         }
+
         this.inputBuf = this.inputBuf << 8 | c;
         this.inputBits += 8;
       }
+
       return this.inputBuf >> this.inputBits - n & 0xFFFF >> 16 - n;
     },
     _eatBits: function _eatBits(n) {
@@ -555,4 +709,5 @@ var CCITTFaxDecoder = function CCITTFaxDecoder() {
   };
   return CCITTFaxDecoder;
 }();
+
 exports.CCITTFaxDecoder = CCITTFaxDecoder;

+ 15 - 6
lib/core/ccitt_stream.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,26 +19,28 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.CCITTFaxStream = undefined;
+exports.CCITTFaxStream = void 0;
 
-var _primitives = require('./primitives');
+var _primitives = require("./primitives");
 
-var _ccitt = require('./ccitt');
+var _ccitt = require("./ccitt");
 
-var _stream = require('./stream');
+var _stream = require("./stream");
 
 var CCITTFaxStream = function CCITTFaxStreamClosure() {
   function CCITTFaxStream(str, maybeLength, params) {
     this.str = str;
     this.dict = str.dict;
+
     if (!(0, _primitives.isDict)(params)) {
       params = _primitives.Dict.empty;
     }
+
     var source = {
       next: function next() {
         return str.getByte();
@@ -53,20 +55,27 @@ var CCITTFaxStream = function CCITTFaxStreamClosure() {
       EndOfBlock: params.get('EndOfBlock'),
       BlackIs1: params.get('BlackIs1')
     });
+
     _stream.DecodeStream.call(this, maybeLength);
   }
+
   CCITTFaxStream.prototype = Object.create(_stream.DecodeStream.prototype);
+
   CCITTFaxStream.prototype.readBlock = function () {
     while (!this.eof) {
       var c = this.ccittFaxDecoder.readNextChar();
+
       if (c === -1) {
         this.eof = true;
         return;
       }
+
       this.ensureBuffer(this.bufferLength + 1);
       this.buffer[this.bufferLength++] = c;
     }
   };
+
   return CCITTFaxStream;
 }();
+
 exports.CCITTFaxStream = CCITTFaxStream;

File diff suppressed because it is too large
+ 6 - 6
lib/core/cff_parser.js


File diff suppressed because it is too large
+ 3 - 2
lib/core/charsets.js


+ 387 - 149
lib/core/chunked_stream.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,17 +19,27 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.ChunkedStreamManager = exports.ChunkedStream = undefined;
+exports.ChunkedStreamManager = exports.ChunkedStream = void 0;
 
-var _util = require('../shared/util');
+var _util = require("../shared/util");
 
-var ChunkedStream = function ChunkedStreamClosure() {
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
+
+function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
+
+var ChunkedStream =
+/*#__PURE__*/
+function () {
   function ChunkedStream(length, chunkSize, manager) {
+    _classCallCheck(this, ChunkedStream);
+
     this.bytes = new Uint8Array(length);
     this.start = 0;
     this.pos = 0;
@@ -42,203 +52,286 @@ var ChunkedStream = function ChunkedStreamClosure() {
     this.progressiveDataLength = 0;
     this.lastSuccessfulEnsureByteChunk = -1;
   }
-  ChunkedStream.prototype = {
-    getMissingChunks: function ChunkedStream_getMissingChunks() {
+
+  _createClass(ChunkedStream, [{
+    key: "getMissingChunks",
+    value: function getMissingChunks() {
       var chunks = [];
+
       for (var chunk = 0, n = this.numChunks; chunk < n; ++chunk) {
         if (!this.loadedChunks[chunk]) {
           chunks.push(chunk);
         }
       }
+
       return chunks;
-    },
-    getBaseStreams: function ChunkedStream_getBaseStreams() {
+    }
+  }, {
+    key: "getBaseStreams",
+    value: function getBaseStreams() {
       return [this];
-    },
-    allChunksLoaded: function ChunkedStream_allChunksLoaded() {
+    }
+  }, {
+    key: "allChunksLoaded",
+    value: function allChunksLoaded() {
       return this.numChunksLoaded === this.numChunks;
-    },
-    onReceiveData: function ChunkedStream_onReceiveData(begin, chunk) {
-      var end = begin + chunk.byteLength;
-      if (begin % this.chunkSize !== 0) {
-        throw new Error('Bad begin offset: ' + begin);
+    }
+  }, {
+    key: "onReceiveData",
+    value: function onReceiveData(begin, chunk) {
+      var chunkSize = this.chunkSize;
+
+      if (begin % chunkSize !== 0) {
+        throw new Error("Bad begin offset: ".concat(begin));
       }
-      var length = this.bytes.length;
-      if (end % this.chunkSize !== 0 && end !== length) {
-        throw new Error('Bad end offset: ' + end);
+
+      var end = begin + chunk.byteLength;
+
+      if (end % chunkSize !== 0 && end !== this.bytes.length) {
+        throw new Error("Bad end offset: ".concat(end));
       }
+
       this.bytes.set(new Uint8Array(chunk), begin);
-      var chunkSize = this.chunkSize;
       var beginChunk = Math.floor(begin / chunkSize);
       var endChunk = Math.floor((end - 1) / chunkSize) + 1;
-      var curChunk;
-      for (curChunk = beginChunk; curChunk < endChunk; ++curChunk) {
+
+      for (var curChunk = beginChunk; curChunk < endChunk; ++curChunk) {
         if (!this.loadedChunks[curChunk]) {
           this.loadedChunks[curChunk] = true;
           ++this.numChunksLoaded;
         }
       }
-    },
-    onReceiveProgressiveData: function ChunkedStream_onReceiveProgressiveData(data) {
+    }
+  }, {
+    key: "onReceiveProgressiveData",
+    value: function onReceiveProgressiveData(data) {
       var position = this.progressiveDataLength;
       var beginChunk = Math.floor(position / this.chunkSize);
       this.bytes.set(new Uint8Array(data), position);
       position += data.byteLength;
       this.progressiveDataLength = position;
       var endChunk = position >= this.end ? this.numChunks : Math.floor(position / this.chunkSize);
-      var curChunk;
-      for (curChunk = beginChunk; curChunk < endChunk; ++curChunk) {
+
+      for (var curChunk = beginChunk; curChunk < endChunk; ++curChunk) {
         if (!this.loadedChunks[curChunk]) {
           this.loadedChunks[curChunk] = true;
           ++this.numChunksLoaded;
         }
       }
-    },
-    ensureByte: function ChunkedStream_ensureByte(pos) {
+    }
+  }, {
+    key: "ensureByte",
+    value: function ensureByte(pos) {
       var chunk = Math.floor(pos / this.chunkSize);
+
       if (chunk === this.lastSuccessfulEnsureByteChunk) {
         return;
       }
+
       if (!this.loadedChunks[chunk]) {
         throw new _util.MissingDataException(pos, pos + 1);
       }
+
       this.lastSuccessfulEnsureByteChunk = chunk;
-    },
-    ensureRange: function ChunkedStream_ensureRange(begin, end) {
+    }
+  }, {
+    key: "ensureRange",
+    value: function ensureRange(begin, end) {
       if (begin >= end) {
         return;
       }
+
       if (end <= this.progressiveDataLength) {
         return;
       }
+
       var chunkSize = this.chunkSize;
       var beginChunk = Math.floor(begin / chunkSize);
       var endChunk = Math.floor((end - 1) / chunkSize) + 1;
+
       for (var chunk = beginChunk; chunk < endChunk; ++chunk) {
         if (!this.loadedChunks[chunk]) {
           throw new _util.MissingDataException(begin, end);
         }
       }
-    },
-    nextEmptyChunk: function ChunkedStream_nextEmptyChunk(beginChunk) {
-      var chunk,
-          numChunks = this.numChunks;
+    }
+  }, {
+    key: "nextEmptyChunk",
+    value: function nextEmptyChunk(beginChunk) {
+      var numChunks = this.numChunks;
+
       for (var i = 0; i < numChunks; ++i) {
-        chunk = (beginChunk + i) % numChunks;
+        var chunk = (beginChunk + i) % numChunks;
+
         if (!this.loadedChunks[chunk]) {
           return chunk;
         }
       }
+
       return null;
-    },
-    hasChunk: function ChunkedStream_hasChunk(chunk) {
+    }
+  }, {
+    key: "hasChunk",
+    value: function hasChunk(chunk) {
       return !!this.loadedChunks[chunk];
-    },
-    get length() {
-      return this.end - this.start;
-    },
-    get isEmpty() {
-      return this.length === 0;
-    },
-    getByte: function ChunkedStream_getByte() {
+    }
+  }, {
+    key: "getByte",
+    value: function getByte() {
       var pos = this.pos;
+
       if (pos >= this.end) {
         return -1;
       }
+
       this.ensureByte(pos);
       return this.bytes[this.pos++];
-    },
-    getUint16: function ChunkedStream_getUint16() {
+    }
+  }, {
+    key: "getUint16",
+    value: function getUint16() {
       var b0 = this.getByte();
       var b1 = this.getByte();
+
       if (b0 === -1 || b1 === -1) {
         return -1;
       }
+
       return (b0 << 8) + b1;
-    },
-    getInt32: function ChunkedStream_getInt32() {
+    }
+  }, {
+    key: "getInt32",
+    value: function getInt32() {
       var b0 = this.getByte();
       var b1 = this.getByte();
       var b2 = this.getByte();
       var b3 = this.getByte();
       return (b0 << 24) + (b1 << 16) + (b2 << 8) + b3;
-    },
-    getBytes: function ChunkedStream_getBytes(length) {
+    }
+  }, {
+    key: "getBytes",
+    value: function getBytes(length) {
+      var forceClamped = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
       var bytes = this.bytes;
       var pos = this.pos;
       var strEnd = this.end;
+
       if (!length) {
         this.ensureRange(pos, strEnd);
-        return bytes.subarray(pos, strEnd);
+
+        var _subarray = bytes.subarray(pos, strEnd);
+
+        return forceClamped ? new Uint8ClampedArray(_subarray) : _subarray;
       }
+
       var end = pos + length;
+
       if (end > strEnd) {
         end = strEnd;
       }
+
       this.ensureRange(pos, end);
       this.pos = end;
-      return bytes.subarray(pos, end);
-    },
-    peekByte: function ChunkedStream_peekByte() {
+      var subarray = bytes.subarray(pos, end);
+      return forceClamped ? new Uint8ClampedArray(subarray) : subarray;
+    }
+  }, {
+    key: "peekByte",
+    value: function peekByte() {
       var peekedByte = this.getByte();
       this.pos--;
       return peekedByte;
-    },
-    peekBytes: function ChunkedStream_peekBytes(length) {
-      var bytes = this.getBytes(length);
+    }
+  }, {
+    key: "peekBytes",
+    value: function peekBytes(length) {
+      var forceClamped = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
+      var bytes = this.getBytes(length, forceClamped);
       this.pos -= bytes.length;
       return bytes;
-    },
-    getByteRange: function ChunkedStream_getBytes(begin, end) {
+    }
+  }, {
+    key: "getByteRange",
+    value: function getByteRange(begin, end) {
       this.ensureRange(begin, end);
       return this.bytes.subarray(begin, end);
-    },
-    skip: function ChunkedStream_skip(n) {
+    }
+  }, {
+    key: "skip",
+    value: function skip(n) {
       if (!n) {
         n = 1;
       }
+
       this.pos += n;
-    },
-    reset: function ChunkedStream_reset() {
+    }
+  }, {
+    key: "reset",
+    value: function reset() {
       this.pos = this.start;
-    },
-    moveStart: function ChunkedStream_moveStart() {
+    }
+  }, {
+    key: "moveStart",
+    value: function moveStart() {
       this.start = this.pos;
-    },
-    makeSubStream: function ChunkedStream_makeSubStream(start, length, dict) {
+    }
+  }, {
+    key: "makeSubStream",
+    value: function makeSubStream(start, length, dict) {
       this.ensureRange(start, start + length);
+
       function ChunkedStreamSubstream() {}
+
       ChunkedStreamSubstream.prototype = Object.create(this);
+
       ChunkedStreamSubstream.prototype.getMissingChunks = function () {
         var chunkSize = this.chunkSize;
         var beginChunk = Math.floor(this.start / chunkSize);
         var endChunk = Math.floor((this.end - 1) / chunkSize) + 1;
         var missingChunks = [];
+
         for (var chunk = beginChunk; chunk < endChunk; ++chunk) {
           if (!this.loadedChunks[chunk]) {
             missingChunks.push(chunk);
           }
         }
+
         return missingChunks;
       };
+
       var subStream = new ChunkedStreamSubstream();
       subStream.pos = subStream.start = start;
       subStream.end = start + length || this.end;
       subStream.dict = dict;
       return subStream;
     }
-  };
+  }, {
+    key: "length",
+    get: function get() {
+      return this.end - this.start;
+    }
+  }, {
+    key: "isEmpty",
+    get: function get() {
+      return this.length === 0;
+    }
+  }]);
+
   return ChunkedStream;
 }();
-var ChunkedStreamManager = function ChunkedStreamManagerClosure() {
+
+exports.ChunkedStream = ChunkedStream;
+
+var ChunkedStreamManager =
+/*#__PURE__*/
+function () {
   function ChunkedStreamManager(pdfNetworkStream, args) {
-    var chunkSize = args.rangeChunkSize;
-    var length = args.length;
-    this.stream = new ChunkedStream(length, chunkSize, this);
-    this.length = length;
-    this.chunkSize = chunkSize;
+    _classCallCheck(this, ChunkedStreamManager);
+
+    this.length = args.length;
+    this.chunkSize = args.rangeChunkSize;
+    this.stream = new ChunkedStream(this.length, this.chunkSize, this);
     this.pdfNetworkStream = pdfNetworkStream;
-    this.url = args.url;
     this.disableAutoFetch = args.disableAutoFetch;
     this.msgHandler = args.msgHandler;
     this.currRequestId = 0;
@@ -249,20 +342,25 @@ var ChunkedStreamManager = function ChunkedStreamManagerClosure() {
     this.aborted = false;
     this._loadedStreamCapability = (0, _util.createPromiseCapability)();
   }
-  ChunkedStreamManager.prototype = {
-    onLoadedStream: function ChunkedStreamManager_getLoadedStream() {
+
+  _createClass(ChunkedStreamManager, [{
+    key: "onLoadedStream",
+    value: function onLoadedStream() {
       return this._loadedStreamCapability.promise;
-    },
-    sendRequest: function ChunkedStreamManager_sendRequest(begin, end) {
+    }
+  }, {
+    key: "sendRequest",
+    value: function sendRequest(begin, end) {
       var _this = this;
 
       var rangeReader = this.pdfNetworkStream.getRangeReader(begin, end);
+
       if (!rangeReader.isStreamingSupported) {
         rangeReader.onProgress = this.onProgress.bind(this);
       }
+
       var chunks = [],
           loaded = 0;
-      var manager = this;
       var promise = new Promise(function (resolve, reject) {
         var readChunk = function readChunk(chunk) {
           try {
@@ -270,12 +368,17 @@ var ChunkedStreamManager = function ChunkedStreamManagerClosure() {
               var data = chunk.value;
               chunks.push(data);
               loaded += (0, _util.arrayByteLength)(data);
+
               if (rangeReader.isStreamingSupported) {
-                manager.onProgress({ loaded: loaded });
+                _this.onProgress({
+                  loaded: loaded
+                });
               }
+
               rangeReader.read().then(readChunk, reject);
               return;
             }
+
             var chunkData = (0, _util.arraysToBytes)(chunks);
             chunks = null;
             resolve(chunkData);
@@ -283,98 +386,188 @@ var ChunkedStreamManager = function ChunkedStreamManagerClosure() {
             reject(e);
           }
         };
+
         rangeReader.read().then(readChunk, reject);
       });
       promise.then(function (data) {
         if (_this.aborted) {
           return;
         }
+
         _this.onReceiveData({
           chunk: data,
           begin: begin
         });
       });
-    },
-    requestAllChunks: function ChunkedStreamManager_requestAllChunks() {
+    }
+  }, {
+    key: "requestAllChunks",
+    value: function requestAllChunks() {
       var missingChunks = this.stream.getMissingChunks();
+
       this._requestChunks(missingChunks);
+
       return this._loadedStreamCapability.promise;
-    },
-    _requestChunks: function ChunkedStreamManager_requestChunks(chunks) {
+    }
+  }, {
+    key: "_requestChunks",
+    value: function _requestChunks(chunks) {
       var requestId = this.currRequestId++;
-      var i, ii;
       var chunksNeeded = Object.create(null);
       this.chunksNeededByRequest[requestId] = chunksNeeded;
-      for (i = 0, ii = chunks.length; i < ii; i++) {
-        if (!this.stream.hasChunk(chunks[i])) {
-          chunksNeeded[chunks[i]] = true;
+      var _iteratorNormalCompletion = true;
+      var _didIteratorError = false;
+      var _iteratorError = undefined;
+
+      try {
+        for (var _iterator = chunks[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+          var _chunk = _step.value;
+
+          if (!this.stream.hasChunk(_chunk)) {
+            chunksNeeded[_chunk] = true;
+          }
+        }
+      } catch (err) {
+        _didIteratorError = true;
+        _iteratorError = err;
+      } finally {
+        try {
+          if (!_iteratorNormalCompletion && _iterator.return != null) {
+            _iterator.return();
+          }
+        } finally {
+          if (_didIteratorError) {
+            throw _iteratorError;
+          }
         }
       }
+
       if ((0, _util.isEmptyObj)(chunksNeeded)) {
         return Promise.resolve();
       }
+
       var capability = (0, _util.createPromiseCapability)();
       this.promisesByRequest[requestId] = capability;
       var chunksToRequest = [];
+
       for (var chunk in chunksNeeded) {
         chunk = chunk | 0;
+
         if (!(chunk in this.requestsByChunk)) {
           this.requestsByChunk[chunk] = [];
           chunksToRequest.push(chunk);
         }
+
         this.requestsByChunk[chunk].push(requestId);
       }
+
       if (!chunksToRequest.length) {
         return capability.promise;
       }
+
       var groupedChunksToRequest = this.groupChunks(chunksToRequest);
-      for (i = 0; i < groupedChunksToRequest.length; ++i) {
-        var groupedChunk = groupedChunksToRequest[i];
-        var begin = groupedChunk.beginChunk * this.chunkSize;
-        var end = Math.min(groupedChunk.endChunk * this.chunkSize, this.length);
-        this.sendRequest(begin, end);
+      var _iteratorNormalCompletion2 = true;
+      var _didIteratorError2 = false;
+      var _iteratorError2 = undefined;
+
+      try {
+        for (var _iterator2 = groupedChunksToRequest[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
+          var groupedChunk = _step2.value;
+          var begin = groupedChunk.beginChunk * this.chunkSize;
+          var end = Math.min(groupedChunk.endChunk * this.chunkSize, this.length);
+          this.sendRequest(begin, end);
+        }
+      } catch (err) {
+        _didIteratorError2 = true;
+        _iteratorError2 = err;
+      } finally {
+        try {
+          if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
+            _iterator2.return();
+          }
+        } finally {
+          if (_didIteratorError2) {
+            throw _iteratorError2;
+          }
+        }
       }
+
       return capability.promise;
-    },
-    getStream: function ChunkedStreamManager_getStream() {
+    }
+  }, {
+    key: "getStream",
+    value: function getStream() {
       return this.stream;
-    },
-    requestRange: function ChunkedStreamManager_requestRange(begin, end) {
+    }
+  }, {
+    key: "requestRange",
+    value: function requestRange(begin, end) {
       end = Math.min(end, this.length);
       var beginChunk = this.getBeginChunk(begin);
       var endChunk = this.getEndChunk(end);
       var chunks = [];
+
       for (var chunk = beginChunk; chunk < endChunk; ++chunk) {
         chunks.push(chunk);
       }
+
       return this._requestChunks(chunks);
-    },
-    requestRanges: function ChunkedStreamManager_requestRanges(ranges) {
-      ranges = ranges || [];
+    }
+  }, {
+    key: "requestRanges",
+    value: function requestRanges() {
+      var ranges = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
       var chunksToRequest = [];
-      for (var i = 0; i < ranges.length; i++) {
-        var beginChunk = this.getBeginChunk(ranges[i].begin);
-        var endChunk = this.getEndChunk(ranges[i].end);
-        for (var chunk = beginChunk; chunk < endChunk; ++chunk) {
-          if (!chunksToRequest.includes(chunk)) {
-            chunksToRequest.push(chunk);
+      var _iteratorNormalCompletion3 = true;
+      var _didIteratorError3 = false;
+      var _iteratorError3 = undefined;
+
+      try {
+        for (var _iterator3 = ranges[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
+          var range = _step3.value;
+          var beginChunk = this.getBeginChunk(range.begin);
+          var endChunk = this.getEndChunk(range.end);
+
+          for (var chunk = beginChunk; chunk < endChunk; ++chunk) {
+            if (!chunksToRequest.includes(chunk)) {
+              chunksToRequest.push(chunk);
+            }
+          }
+        }
+      } catch (err) {
+        _didIteratorError3 = true;
+        _iteratorError3 = err;
+      } finally {
+        try {
+          if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
+            _iterator3.return();
+          }
+        } finally {
+          if (_didIteratorError3) {
+            throw _iteratorError3;
           }
         }
       }
+
       chunksToRequest.sort(function (a, b) {
         return a - b;
       });
       return this._requestChunks(chunksToRequest);
-    },
-    groupChunks: function ChunkedStreamManager_groupChunks(chunks) {
+    }
+  }, {
+    key: "groupChunks",
+    value: function groupChunks(chunks) {
       var groupedChunks = [];
       var beginChunk = -1;
       var prevChunk = -1;
-      for (var i = 0; i < chunks.length; ++i) {
+
+      for (var i = 0, ii = chunks.length; i < ii; ++i) {
         var chunk = chunks[i];
+
         if (beginChunk < 0) {
           beginChunk = chunk;
         }
+
         if (prevChunk >= 0 && prevChunk + 1 !== chunk) {
           groupedChunks.push({
             beginChunk: beginChunk,
@@ -382,104 +575,149 @@ var ChunkedStreamManager = function ChunkedStreamManagerClosure() {
           });
           beginChunk = chunk;
         }
+
         if (i + 1 === chunks.length) {
           groupedChunks.push({
             beginChunk: beginChunk,
             endChunk: chunk + 1
           });
         }
+
         prevChunk = chunk;
       }
+
       return groupedChunks;
-    },
-    onProgress: function ChunkedStreamManager_onProgress(args) {
-      var bytesLoaded = this.stream.numChunksLoaded * this.chunkSize + args.loaded;
+    }
+  }, {
+    key: "onProgress",
+    value: function onProgress(args) {
       this.msgHandler.send('DocProgress', {
-        loaded: bytesLoaded,
+        loaded: this.stream.numChunksLoaded * this.chunkSize + args.loaded,
         total: this.length
       });
-    },
-    onReceiveData: function ChunkedStreamManager_onReceiveData(args) {
+    }
+  }, {
+    key: "onReceiveData",
+    value: function onReceiveData(args) {
       var chunk = args.chunk;
       var isProgressive = args.begin === undefined;
       var begin = isProgressive ? this.progressiveDataLength : args.begin;
       var end = begin + chunk.byteLength;
       var beginChunk = Math.floor(begin / this.chunkSize);
       var endChunk = end < this.length ? Math.floor(end / this.chunkSize) : Math.ceil(end / this.chunkSize);
+
       if (isProgressive) {
         this.stream.onReceiveProgressiveData(chunk);
         this.progressiveDataLength = end;
       } else {
         this.stream.onReceiveData(begin, chunk);
       }
+
       if (this.stream.allChunksLoaded()) {
         this._loadedStreamCapability.resolve(this.stream);
       }
+
       var loadedRequests = [];
-      var i, requestId;
-      for (chunk = beginChunk; chunk < endChunk; ++chunk) {
-        var requestIds = this.requestsByChunk[chunk] || [];
-        delete this.requestsByChunk[chunk];
-        for (i = 0; i < requestIds.length; ++i) {
-          requestId = requestIds[i];
-          var chunksNeeded = this.chunksNeededByRequest[requestId];
-          if (chunk in chunksNeeded) {
-            delete chunksNeeded[chunk];
+
+      for (var _chunk2 = beginChunk; _chunk2 < endChunk; ++_chunk2) {
+        var requestIds = this.requestsByChunk[_chunk2] || [];
+        delete this.requestsByChunk[_chunk2];
+        var _iteratorNormalCompletion4 = true;
+        var _didIteratorError4 = false;
+        var _iteratorError4 = undefined;
+
+        try {
+          for (var _iterator4 = requestIds[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
+            var requestId = _step4.value;
+            var chunksNeeded = this.chunksNeededByRequest[requestId];
+
+            if (_chunk2 in chunksNeeded) {
+              delete chunksNeeded[_chunk2];
+            }
+
+            if (!(0, _util.isEmptyObj)(chunksNeeded)) {
+              continue;
+            }
+
+            loadedRequests.push(requestId);
           }
-          if (!(0, _util.isEmptyObj)(chunksNeeded)) {
-            continue;
+        } catch (err) {
+          _didIteratorError4 = true;
+          _iteratorError4 = err;
+        } finally {
+          try {
+            if (!_iteratorNormalCompletion4 && _iterator4.return != null) {
+              _iterator4.return();
+            }
+          } finally {
+            if (_didIteratorError4) {
+              throw _iteratorError4;
+            }
           }
-          loadedRequests.push(requestId);
         }
       }
+
       if (!this.disableAutoFetch && (0, _util.isEmptyObj)(this.requestsByChunk)) {
         var nextEmptyChunk;
+
         if (this.stream.numChunksLoaded === 1) {
           var lastChunk = this.stream.numChunks - 1;
+
           if (!this.stream.hasChunk(lastChunk)) {
             nextEmptyChunk = lastChunk;
           }
         } else {
           nextEmptyChunk = this.stream.nextEmptyChunk(endChunk);
         }
+
         if (Number.isInteger(nextEmptyChunk)) {
           this._requestChunks([nextEmptyChunk]);
         }
       }
-      for (i = 0; i < loadedRequests.length; ++i) {
-        requestId = loadedRequests[i];
-        var capability = this.promisesByRequest[requestId];
-        delete this.promisesByRequest[requestId];
+
+      for (var _i = 0; _i < loadedRequests.length; _i++) {
+        var _requestId = loadedRequests[_i];
+        var capability = this.promisesByRequest[_requestId];
+        delete this.promisesByRequest[_requestId];
         capability.resolve();
       }
+
       this.msgHandler.send('DocProgress', {
         loaded: this.stream.numChunksLoaded * this.chunkSize,
         total: this.length
       });
-    },
-    onError: function ChunkedStreamManager_onError(err) {
+    }
+  }, {
+    key: "onError",
+    value: function onError(err) {
       this._loadedStreamCapability.reject(err);
-    },
-    getBeginChunk: function ChunkedStreamManager_getBeginChunk(begin) {
-      var chunk = Math.floor(begin / this.chunkSize);
-      return chunk;
-    },
-    getEndChunk: function ChunkedStreamManager_getEndChunk(end) {
-      var chunk = Math.floor((end - 1) / this.chunkSize) + 1;
-      return chunk;
-    },
-    abort: function ChunkedStreamManager_abort() {
+    }
+  }, {
+    key: "getBeginChunk",
+    value: function getBeginChunk(begin) {
+      return Math.floor(begin / this.chunkSize);
+    }
+  }, {
+    key: "getEndChunk",
+    value: function getEndChunk(end) {
+      return Math.floor((end - 1) / this.chunkSize) + 1;
+    }
+  }, {
+    key: "abort",
+    value: function abort() {
       this.aborted = true;
+
       if (this.pdfNetworkStream) {
         this.pdfNetworkStream.cancelAllRequests('abort');
       }
+
       for (var requestId in this.promisesByRequest) {
-        var capability = this.promisesByRequest[requestId];
-        capability.reject(new Error('Request was aborted'));
+        this.promisesByRequest[requestId].reject(new Error('Request was aborted'));
       }
     }
-  };
+  }]);
+
   return ChunkedStreamManager;
 }();
-exports.ChunkedStream = ChunkedStream;
+
 exports.ChunkedStreamManager = ChunkedStreamManager;

File diff suppressed because it is too large
+ 25 - 7
lib/core/cmap.js


File diff suppressed because it is too large
+ 674 - 457
lib/core/colorspace.js


File diff suppressed because it is too large
+ 77 - 9
lib/core/crypto.js


+ 545 - 260
lib/core/document.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,41 +19,57 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.PDFDocument = exports.Page = undefined;
+exports.PDFDocument = exports.Page = void 0;
 
-var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
+var _util = require("../shared/util");
 
-var _obj = require('./obj');
+var _obj = require("./obj");
 
-var _primitives = require('./primitives');
+var _primitives = require("./primitives");
 
-var _util = require('../shared/util');
+var _stream2 = require("./stream");
 
-var _stream = require('./stream');
+var _annotation = require("./annotation");
 
-var _annotation = require('./annotation');
+var _crypto = require("./crypto");
 
-var _crypto = require('./crypto');
+var _parser = require("./parser");
 
-var _parser = require('./parser');
+var _operator_list = require("./operator_list");
 
-var _operator_list = require('./operator_list');
+var _evaluator = require("./evaluator");
 
-var _evaluator = require('./evaluator');
+var _function = require("./function");
 
-var _function = require('./function');
+function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
 
-var Page = function PageClosure() {
-  var DEFAULT_USER_UNIT = 1.0;
-  var LETTER_SIZE_MEDIABOX = [0, 0, 612, 792];
-  function isAnnotationRenderable(annotation, intent) {
-    return intent === 'display' && annotation.viewable || intent === 'print' && annotation.printable;
-  }
+function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
+
+function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
+
+function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
+
+function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
+
+var DEFAULT_USER_UNIT = 1.0;
+var LETTER_SIZE_MEDIABOX = [0, 0, 612, 792];
+
+function isAnnotationRenderable(annotation, intent) {
+  return intent === 'display' && annotation.viewable || intent === 'print' && annotation.printable;
+}
+
+var Page =
+/*#__PURE__*/
+function () {
   function Page(_ref) {
     var pdfManager = _ref.pdfManager,
         xref = _ref.xref,
@@ -64,6 +80,8 @@ var Page = function PageClosure() {
         builtInCMapCache = _ref.builtInCMapCache,
         pdfFunctionFactory = _ref.pdfFunctionFactory;
 
+    _classCallCheck(this, Page);
+
     this.pdfManager = pdfManager;
     this.pageIndex = pageIndex;
     this.pageDict = pageDict;
@@ -74,118 +92,103 @@ var Page = function PageClosure() {
     this.pdfFunctionFactory = pdfFunctionFactory;
     this.evaluatorOptions = pdfManager.evaluatorOptions;
     this.resourcesPromise = null;
-    var uniquePrefix = 'p' + this.pageIndex + '_';
-    var idCounters = { obj: 0 };
+    var uniquePrefix = "p".concat(this.pageIndex, "_");
+    var idCounters = {
+      obj: 0
+    };
     this.idFactory = {
       createObjId: function createObjId() {
         return uniquePrefix + ++idCounters.obj;
       }
     };
   }
-  Page.prototype = {
-    _getInheritableProperty: function _getInheritableProperty(key) {
-      var getArray = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
 
+  _createClass(Page, [{
+    key: "_getInheritableProperty",
+    value: function _getInheritableProperty(key) {
+      var getArray = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
       var value = (0, _util.getInheritableProperty)({
         dict: this.pageDict,
         key: key,
         getArray: getArray,
         stopWhenFound: false
       });
+
       if (!Array.isArray(value)) {
         return value;
       }
+
       if (value.length === 1 || !(0, _primitives.isDict)(value[0])) {
         return value[0];
       }
-      return _primitives.Dict.merge(this.xref, value);
-    },
 
-    get content() {
-      return this.pageDict.get('Contents');
-    },
-    get resources() {
-      return (0, _util.shadow)(this, 'resources', this._getInheritableProperty('Resources') || _primitives.Dict.empty);
-    },
-    get mediaBox() {
-      var mediaBox = this._getInheritableProperty('MediaBox', true);
-      if (!Array.isArray(mediaBox) || mediaBox.length !== 4) {
-        return (0, _util.shadow)(this, 'mediaBox', LETTER_SIZE_MEDIABOX);
-      }
-      return (0, _util.shadow)(this, 'mediaBox', mediaBox);
-    },
-    get cropBox() {
-      var cropBox = this._getInheritableProperty('CropBox', true);
-      if (!Array.isArray(cropBox) || cropBox.length !== 4) {
-        return (0, _util.shadow)(this, 'cropBox', this.mediaBox);
-      }
-      return (0, _util.shadow)(this, 'cropBox', cropBox);
-    },
-    get userUnit() {
-      var obj = this.pageDict.get('UserUnit');
-      if (!(0, _util.isNum)(obj) || obj <= 0) {
-        obj = DEFAULT_USER_UNIT;
-      }
-      return (0, _util.shadow)(this, 'userUnit', obj);
-    },
-    get view() {
-      var mediaBox = this.mediaBox,
-          cropBox = this.cropBox;
-      if (mediaBox === cropBox) {
-        return (0, _util.shadow)(this, 'view', mediaBox);
-      }
-      var intersection = _util.Util.intersect(cropBox, mediaBox);
-      return (0, _util.shadow)(this, 'view', intersection || mediaBox);
-    },
-    get rotate() {
-      var rotate = this._getInheritableProperty('Rotate') || 0;
-      if (rotate % 90 !== 0) {
-        rotate = 0;
-      } else if (rotate >= 360) {
-        rotate = rotate % 360;
-      } else if (rotate < 0) {
-        rotate = (rotate % 360 + 360) % 360;
-      }
-      return (0, _util.shadow)(this, 'rotate', rotate);
-    },
-    getContentStream: function Page_getContentStream() {
+      return _primitives.Dict.merge(this.xref, value);
+    }
+  }, {
+    key: "getContentStream",
+    value: function getContentStream() {
       var content = this.content;
       var stream;
+
       if (Array.isArray(content)) {
         var xref = this.xref;
-        var i,
-            n = content.length;
         var streams = [];
-        for (i = 0; i < n; ++i) {
-          streams.push(xref.fetchIfRef(content[i]));
+        var _iteratorNormalCompletion = true;
+        var _didIteratorError = false;
+        var _iteratorError = undefined;
+
+        try {
+          for (var _iterator = content[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+            var _stream = _step.value;
+            streams.push(xref.fetchIfRef(_stream));
+          }
+        } catch (err) {
+          _didIteratorError = true;
+          _iteratorError = err;
+        } finally {
+          try {
+            if (!_iteratorNormalCompletion && _iterator.return != null) {
+              _iterator.return();
+            }
+          } finally {
+            if (_didIteratorError) {
+              throw _iteratorError;
+            }
+          }
         }
-        stream = new _stream.StreamsSequenceStream(streams);
+
+        stream = new _stream2.StreamsSequenceStream(streams);
       } else if ((0, _primitives.isStream)(content)) {
         stream = content;
       } else {
-        stream = new _stream.NullStream();
+        stream = new _stream2.NullStream();
       }
+
       return stream;
-    },
-    loadResources: function Page_loadResources(keys) {
+    }
+  }, {
+    key: "loadResources",
+    value: function loadResources(keys) {
       var _this = this;
 
       if (!this.resourcesPromise) {
         this.resourcesPromise = this.pdfManager.ensure(this, 'resources');
       }
+
       return this.resourcesPromise.then(function () {
         var objectLoader = new _obj.ObjectLoader(_this.resources, keys, _this.xref);
         return objectLoader.load();
       });
-    },
-    getOperatorList: function getOperatorList(_ref2) {
+    }
+  }, {
+    key: "getOperatorList",
+    value: function getOperatorList(_ref2) {
       var _this2 = this;
 
       var handler = _ref2.handler,
           task = _ref2.task,
           intent = _ref2.intent,
           renderInteractiveForms = _ref2.renderInteractiveForms;
-
       var contentStreamPromise = this.pdfManager.ensure(this, 'getContentStream');
       var resourcesPromise = this.loadResources(['ExtGState', 'ColorSpace', 'Pattern', 'Shading', 'XObject', 'Font']);
       var partialEvaluator = new _evaluator.PartialEvaluator({
@@ -219,8 +222,7 @@ var Page = function PageClosure() {
           return opList;
         });
       });
-      var annotationsPromise = this.pdfManager.ensure(this, 'annotations');
-      return Promise.all([pageListPromise, annotationsPromise]).then(function (_ref5) {
+      return Promise.all([pageListPromise, this._parsedAnnotations]).then(function (_ref5) {
         var _ref6 = _slicedToArray(_ref5, 2),
             pageOpList = _ref6[0],
             annotations = _ref6[1];
@@ -229,26 +231,70 @@ var Page = function PageClosure() {
           pageOpList.flush(true);
           return pageOpList;
         }
-        var i,
-            ii,
-            opListPromises = [];
-        for (i = 0, ii = annotations.length; i < ii; i++) {
-          if (isAnnotationRenderable(annotations[i], intent)) {
-            opListPromises.push(annotations[i].getOperatorList(partialEvaluator, task, renderInteractiveForms));
+
+        var opListPromises = [];
+        var _iteratorNormalCompletion2 = true;
+        var _didIteratorError2 = false;
+        var _iteratorError2 = undefined;
+
+        try {
+          for (var _iterator2 = annotations[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
+            var annotation = _step2.value;
+
+            if (isAnnotationRenderable(annotation, intent)) {
+              opListPromises.push(annotation.getOperatorList(partialEvaluator, task, renderInteractiveForms));
+            }
+          }
+        } catch (err) {
+          _didIteratorError2 = true;
+          _iteratorError2 = err;
+        } finally {
+          try {
+            if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
+              _iterator2.return();
+            }
+          } finally {
+            if (_didIteratorError2) {
+              throw _iteratorError2;
+            }
           }
         }
+
         return Promise.all(opListPromises).then(function (opLists) {
           pageOpList.addOp(_util.OPS.beginAnnotations, []);
-          for (i = 0, ii = opLists.length; i < ii; i++) {
-            pageOpList.addOpList(opLists[i]);
+          var _iteratorNormalCompletion3 = true;
+          var _didIteratorError3 = false;
+          var _iteratorError3 = undefined;
+
+          try {
+            for (var _iterator3 = opLists[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
+              var opList = _step3.value;
+              pageOpList.addOpList(opList);
+            }
+          } catch (err) {
+            _didIteratorError3 = true;
+            _iteratorError3 = err;
+          } finally {
+            try {
+              if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
+                _iterator3.return();
+              }
+            } finally {
+              if (_didIteratorError3) {
+                throw _iteratorError3;
+              }
+            }
           }
+
           pageOpList.addOp(_util.OPS.endAnnotations, []);
           pageOpList.flush(true);
           return pageOpList;
         });
       });
-    },
-    extractTextContent: function extractTextContent(_ref7) {
+    }
+  }, {
+    key: "extractTextContent",
+    value: function extractTextContent(_ref7) {
       var _this3 = this;
 
       var handler = _ref7.handler,
@@ -256,7 +302,6 @@ var Page = function PageClosure() {
           normalizeWhitespace = _ref7.normalizeWhitespace,
           sink = _ref7.sink,
           combineTextItems = _ref7.combineTextItems;
-
       var contentStreamPromise = this.pdfManager.ensure(this, 'getContentStream');
       var resourcesPromise = this.loadResources(['ExtGState', 'XObject', 'Font']);
       var dataPromises = Promise.all([contentStreamPromise, resourcesPromise]);
@@ -284,103 +329,205 @@ var Page = function PageClosure() {
           sink: sink
         });
       });
-    },
-
-    getAnnotationsData: function Page_getAnnotationsData(intent) {
-      var annotations = this.annotations;
-      var annotationsData = [];
-      for (var i = 0, n = annotations.length; i < n; ++i) {
-        if (!intent || isAnnotationRenderable(annotations[i], intent)) {
-          annotationsData.push(annotations[i].data);
+    }
+  }, {
+    key: "getAnnotationsData",
+    value: function getAnnotationsData(intent) {
+      return this._parsedAnnotations.then(function (annotations) {
+        var annotationsData = [];
+
+        for (var i = 0, ii = annotations.length; i < ii; i++) {
+          if (!intent || isAnnotationRenderable(annotations[i], intent)) {
+            annotationsData.push(annotations[i].data);
+          }
         }
+
+        return annotationsData;
+      });
+    }
+  }, {
+    key: "content",
+    get: function get() {
+      return this.pageDict.get('Contents');
+    }
+  }, {
+    key: "resources",
+    get: function get() {
+      return (0, _util.shadow)(this, 'resources', this._getInheritableProperty('Resources') || _primitives.Dict.empty);
+    }
+  }, {
+    key: "mediaBox",
+    get: function get() {
+      var mediaBox = this._getInheritableProperty('MediaBox', true);
+
+      if (!Array.isArray(mediaBox) || mediaBox.length !== 4) {
+        return (0, _util.shadow)(this, 'mediaBox', LETTER_SIZE_MEDIABOX);
       }
-      return annotationsData;
-    },
-    get annotations() {
-      var annotations = [];
-      var annotationRefs = this._getInheritableProperty('Annots') || [];
-      for (var i = 0, n = annotationRefs.length; i < n; ++i) {
-        var annotationRef = annotationRefs[i];
-        var annotation = _annotation.AnnotationFactory.create(this.xref, annotationRef, this.pdfManager, this.idFactory);
-        if (annotation) {
-          annotations.push(annotation);
-        }
+
+      return (0, _util.shadow)(this, 'mediaBox', mediaBox);
+    }
+  }, {
+    key: "cropBox",
+    get: function get() {
+      var cropBox = this._getInheritableProperty('CropBox', true);
+
+      if (!Array.isArray(cropBox) || cropBox.length !== 4) {
+        return (0, _util.shadow)(this, 'cropBox', this.mediaBox);
       }
-      return (0, _util.shadow)(this, 'annotations', annotations);
+
+      return (0, _util.shadow)(this, 'cropBox', cropBox);
+    }
+  }, {
+    key: "userUnit",
+    get: function get() {
+      var obj = this.pageDict.get('UserUnit');
+
+      if (!(0, _util.isNum)(obj) || obj <= 0) {
+        obj = DEFAULT_USER_UNIT;
+      }
+
+      return (0, _util.shadow)(this, 'userUnit', obj);
     }
-  };
+  }, {
+    key: "view",
+    get: function get() {
+      var mediaBox = this.mediaBox,
+          cropBox = this.cropBox;
+
+      if (mediaBox === cropBox) {
+        return (0, _util.shadow)(this, 'view', mediaBox);
+      }
+
+      var intersection = _util.Util.intersect(cropBox, mediaBox);
+
+      return (0, _util.shadow)(this, 'view', intersection || mediaBox);
+    }
+  }, {
+    key: "rotate",
+    get: function get() {
+      var rotate = this._getInheritableProperty('Rotate') || 0;
+
+      if (rotate % 90 !== 0) {
+        rotate = 0;
+      } else if (rotate >= 360) {
+        rotate = rotate % 360;
+      } else if (rotate < 0) {
+        rotate = (rotate % 360 + 360) % 360;
+      }
+
+      return (0, _util.shadow)(this, 'rotate', rotate);
+    }
+  }, {
+    key: "annotations",
+    get: function get() {
+      return (0, _util.shadow)(this, 'annotations', this._getInheritableProperty('Annots') || []);
+    }
+  }, {
+    key: "_parsedAnnotations",
+    get: function get() {
+      var _this4 = this;
+
+      var parsedAnnotations = this.pdfManager.ensure(this, 'annotations').then(function () {
+        var annotationRefs = _this4.annotations;
+        var annotationPromises = [];
+
+        for (var i = 0, ii = annotationRefs.length; i < ii; i++) {
+          annotationPromises.push(_annotation.AnnotationFactory.create(_this4.xref, annotationRefs[i], _this4.pdfManager, _this4.idFactory));
+        }
+
+        return Promise.all(annotationPromises).then(function (annotations) {
+          return annotations.filter(function isDefined(annotation) {
+            return !!annotation;
+          });
+        }, function (reason) {
+          (0, _util.warn)("_parsedAnnotations: \"".concat(reason, "\"."));
+          return [];
+        });
+      });
+      return (0, _util.shadow)(this, '_parsedAnnotations', parsedAnnotations);
+    }
+  }]);
+
   return Page;
 }();
-var PDFDocument = function PDFDocumentClosure() {
-  var FINGERPRINT_FIRST_BYTES = 1024;
-  var EMPTY_FINGERPRINT = '\x00\x00\x00\x00\x00\x00\x00' + '\x00\x00\x00\x00\x00\x00\x00\x00\x00';
+
+exports.Page = Page;
+var FINGERPRINT_FIRST_BYTES = 1024;
+var EMPTY_FINGERPRINT = '\x00\x00\x00\x00\x00\x00\x00' + '\x00\x00\x00\x00\x00\x00\x00\x00\x00';
+
+function find(stream, needle, limit, backwards) {
+  var pos = stream.pos;
+  var end = stream.end;
+
+  if (pos + limit > end) {
+    limit = end - pos;
+  }
+
+  var strBuf = [];
+
+  for (var i = 0; i < limit; ++i) {
+    strBuf.push(String.fromCharCode(stream.getByte()));
+  }
+
+  var str = strBuf.join('');
+  stream.pos = pos;
+  var index = backwards ? str.lastIndexOf(needle) : str.indexOf(needle);
+
+  if (index === -1) {
+    return false;
+  }
+
+  stream.pos += index;
+  return true;
+}
+
+var PDFDocument =
+/*#__PURE__*/
+function () {
   function PDFDocument(pdfManager, arg) {
+    _classCallCheck(this, PDFDocument);
+
     var stream;
+
     if ((0, _primitives.isStream)(arg)) {
       stream = arg;
     } else if ((0, _util.isArrayBuffer)(arg)) {
-      stream = new _stream.Stream(arg);
+      stream = new _stream2.Stream(arg);
     } else {
       throw new Error('PDFDocument: Unknown argument type');
     }
+
     if (stream.length <= 0) {
-      throw new Error('PDFDocument: stream must have data');
+      throw new Error('PDFDocument: Stream must have data');
     }
+
     this.pdfManager = pdfManager;
     this.stream = stream;
     this.xref = new _obj.XRef(stream, pdfManager);
-    var evaluatorOptions = pdfManager.evaluatorOptions;
     this.pdfFunctionFactory = new _function.PDFFunctionFactory({
       xref: this.xref,
-      isEvalSupported: evaluatorOptions.isEvalSupported
+      isEvalSupported: pdfManager.evaluatorOptions.isEvalSupported
     });
+    this._pagePromises = [];
   }
-  function find(stream, needle, limit, backwards) {
-    var pos = stream.pos;
-    var end = stream.end;
-    var strBuf = [];
-    if (pos + limit > end) {
-      limit = end - pos;
-    }
-    for (var n = 0; n < limit; ++n) {
-      strBuf.push(String.fromCharCode(stream.getByte()));
-    }
-    var str = strBuf.join('');
-    stream.pos = pos;
-    var index = backwards ? str.lastIndexOf(needle) : str.indexOf(needle);
-    if (index === -1) {
-      return false;
-    }
-    stream.pos += index;
-    return true;
-  }
-  var DocumentInfoValidators = {
-    get entries() {
-      return (0, _util.shadow)(this, 'entries', {
-        Title: _util.isString,
-        Author: _util.isString,
-        Subject: _util.isString,
-        Keywords: _util.isString,
-        Creator: _util.isString,
-        Producer: _util.isString,
-        CreationDate: _util.isString,
-        ModDate: _util.isString,
-        Trapped: _primitives.isName
-      });
-    }
-  };
-  PDFDocument.prototype = {
-    parse: function PDFDocument_parse(recoveryMode) {
+
+  _createClass(PDFDocument, [{
+    key: "parse",
+    value: function parse(recoveryMode) {
       this.setup(recoveryMode);
       var version = this.catalog.catDict.get('Version');
+
       if ((0, _primitives.isName)(version)) {
         this.pdfFormatVersion = version.name;
       }
+
       try {
         this.acroForm = this.catalog.catDict.get('AcroForm');
+
         if (this.acroForm) {
           this.xfa = this.acroForm.get('XFA');
           var fields = this.acroForm.get('Fields');
+
           if ((!fields || !Array.isArray(fields) || fields.length === 0) && !this.xfa) {
             this.acroForm = null;
           }
@@ -389,178 +536,316 @@ var PDFDocument = function PDFDocumentClosure() {
         if (ex instanceof _util.MissingDataException) {
           throw ex;
         }
-        (0, _util.info)('Something wrong with AcroForm entry');
+
+        (0, _util.info)('Cannot fetch AcroForm entry; assuming no AcroForms are present');
         this.acroForm = null;
       }
-    },
-    get linearization() {
-      var linearization = null;
-      if (this.stream.length) {
-        try {
-          linearization = _parser.Linearization.create(this.stream);
-        } catch (err) {
-          if (err instanceof _util.MissingDataException) {
-            throw err;
+    }
+  }, {
+    key: "checkHeader",
+    value: function checkHeader() {
+      var stream = this.stream;
+      stream.reset();
+
+      if (!find(stream, '%PDF-', 1024)) {
+        return;
+      }
+
+      stream.moveStart();
+      var MAX_PDF_VERSION_LENGTH = 12;
+      var version = '',
+          ch;
+
+      while ((ch = stream.getByte()) > 0x20) {
+        if (version.length >= MAX_PDF_VERSION_LENGTH) {
+          break;
+        }
+
+        version += String.fromCharCode(ch);
+      }
+
+      if (!this.pdfFormatVersion) {
+        this.pdfFormatVersion = version.substring(5);
+      }
+    }
+  }, {
+    key: "parseStartXRef",
+    value: function parseStartXRef() {
+      this.xref.setStartXRef(this.startXRef);
+    }
+  }, {
+    key: "setup",
+    value: function setup(recoveryMode) {
+      this.xref.parse(recoveryMode);
+      this.catalog = new _obj.Catalog(this.pdfManager, this.xref);
+    }
+  }, {
+    key: "_getLinearizationPage",
+    value: function _getLinearizationPage(pageIndex) {
+      var catalog = this.catalog,
+          linearization = this.linearization;
+      (0, _util.assert)(linearization && linearization.pageFirst === pageIndex);
+      var ref = new _primitives.Ref(linearization.objectNumberFirst, 0);
+      return this.xref.fetchAsync(ref).then(function (obj) {
+        if ((0, _primitives.isDict)(obj, 'Page') || (0, _primitives.isDict)(obj) && !obj.has('Type') && obj.has('Contents')) {
+          if (ref && !catalog.pageKidsCountCache.has(ref)) {
+            catalog.pageKidsCountCache.put(ref, 1);
           }
-          (0, _util.info)(err);
+
+          return [obj, ref];
         }
+
+        throw new _util.FormatError('The Linearization dictionary doesn\'t point ' + 'to a valid Page dictionary.');
+      }).catch(function (reason) {
+        (0, _util.info)(reason);
+        return catalog.getPageDict(pageIndex);
+      });
+    }
+  }, {
+    key: "getPage",
+    value: function getPage(pageIndex) {
+      var _this5 = this;
+
+      if (this._pagePromises[pageIndex] !== undefined) {
+        return this._pagePromises[pageIndex];
       }
+
+      var catalog = this.catalog,
+          linearization = this.linearization;
+      var promise = linearization && linearization.pageFirst === pageIndex ? this._getLinearizationPage(pageIndex) : catalog.getPageDict(pageIndex);
+      return this._pagePromises[pageIndex] = promise.then(function (_ref10) {
+        var _ref11 = _slicedToArray(_ref10, 2),
+            pageDict = _ref11[0],
+            ref = _ref11[1];
+
+        return new Page({
+          pdfManager: _this5.pdfManager,
+          xref: _this5.xref,
+          pageIndex: pageIndex,
+          pageDict: pageDict,
+          ref: ref,
+          fontCache: catalog.fontCache,
+          builtInCMapCache: catalog.builtInCMapCache,
+          pdfFunctionFactory: _this5.pdfFunctionFactory
+        });
+      });
+    }
+  }, {
+    key: "checkFirstPage",
+    value: function checkFirstPage() {
+      var _this6 = this;
+
+      return this.getPage(0).catch(function (reason) {
+        if (reason instanceof _util.XRefEntryException) {
+          _this6._pagePromises.length = 0;
+
+          _this6.cleanup();
+
+          throw new _util.XRefParseException();
+        }
+      });
+    }
+  }, {
+    key: "fontFallback",
+    value: function fontFallback(id, handler) {
+      return this.catalog.fontFallback(id, handler);
+    }
+  }, {
+    key: "cleanup",
+    value: function cleanup() {
+      return this.catalog.cleanup();
+    }
+  }, {
+    key: "linearization",
+    get: function get() {
+      var linearization = null;
+
+      try {
+        linearization = _parser.Linearization.create(this.stream);
+      } catch (err) {
+        if (err instanceof _util.MissingDataException) {
+          throw err;
+        }
+
+        (0, _util.info)(err);
+      }
+
       return (0, _util.shadow)(this, 'linearization', linearization);
-    },
-    get startXRef() {
+    }
+  }, {
+    key: "startXRef",
+    get: function get() {
       var stream = this.stream;
       var startXRef = 0;
-      var linearization = this.linearization;
-      if (linearization) {
+
+      if (this.linearization) {
         stream.reset();
+
         if (find(stream, 'endobj', 1024)) {
           startXRef = stream.pos + 6;
         }
       } else {
         var step = 1024;
+        var startXRefLength = 'startxref'.length;
         var found = false,
             pos = stream.end;
+
         while (!found && pos > 0) {
-          pos -= step - 'startxref'.length;
+          pos -= step - startXRefLength;
+
           if (pos < 0) {
             pos = 0;
           }
+
           stream.pos = pos;
           found = find(stream, 'startxref', step, true);
         }
+
         if (found) {
           stream.skip(9);
           var ch;
+
           do {
             ch = stream.getByte();
           } while ((0, _util.isSpace)(ch));
+
           var str = '';
+
           while (ch >= 0x20 && ch <= 0x39) {
             str += String.fromCharCode(ch);
             ch = stream.getByte();
           }
+
           startXRef = parseInt(str, 10);
+
           if (isNaN(startXRef)) {
             startXRef = 0;
           }
         }
       }
-      return (0, _util.shadow)(this, 'startXRef', startXRef);
-    },
-    get mainXRefEntriesOffset() {
-      var mainXRefEntriesOffset = 0;
-      var linearization = this.linearization;
-      if (linearization) {
-        mainXRefEntriesOffset = linearization.mainXRefEntriesOffset;
-      }
-      return (0, _util.shadow)(this, 'mainXRefEntriesOffset', mainXRefEntriesOffset);
-    },
-    checkHeader: function PDFDocument_checkHeader() {
-      var stream = this.stream;
-      stream.reset();
-      if (find(stream, '%PDF-', 1024)) {
-        stream.moveStart();
-        var MAX_VERSION_LENGTH = 12;
-        var version = '',
-            ch;
-        while ((ch = stream.getByte()) > 0x20) {
-          if (version.length >= MAX_VERSION_LENGTH) {
-            break;
-          }
-          version += String.fromCharCode(ch);
-        }
-        if (!this.pdfFormatVersion) {
-          this.pdfFormatVersion = version.substring(5);
-        }
-        return;
-      }
-    },
-    parseStartXRef: function PDFDocument_parseStartXRef() {
-      var startXRef = this.startXRef;
-      this.xref.setStartXRef(startXRef);
-    },
-    setup: function PDFDocument_setup(recoveryMode) {
-      var _this4 = this;
 
-      this.xref.parse(recoveryMode);
-      var pageFactory = {
-        createPage: function createPage(pageIndex, dict, ref, fontCache, builtInCMapCache) {
-          return new Page({
-            pdfManager: _this4.pdfManager,
-            xref: _this4.xref,
-            pageIndex: pageIndex,
-            pageDict: dict,
-            ref: ref,
-            fontCache: fontCache,
-            builtInCMapCache: builtInCMapCache,
-            pdfFunctionFactory: _this4.pdfFunctionFactory
-          });
-        }
-      };
-      this.catalog = new _obj.Catalog(this.pdfManager, this.xref, pageFactory);
-    },
-    get numPages() {
+      return (0, _util.shadow)(this, 'startXRef', startXRef);
+    }
+  }, {
+    key: "numPages",
+    get: function get() {
       var linearization = this.linearization;
       var num = linearization ? linearization.numPages : this.catalog.numPages;
       return (0, _util.shadow)(this, 'numPages', num);
-    },
-    get documentInfo() {
+    }
+  }, {
+    key: "documentInfo",
+    get: function get() {
+      var DocumentInfoValidators = {
+        Title: _util.isString,
+        Author: _util.isString,
+        Subject: _util.isString,
+        Keywords: _util.isString,
+        Creator: _util.isString,
+        Producer: _util.isString,
+        CreationDate: _util.isString,
+        ModDate: _util.isString,
+        Trapped: _primitives.isName
+      };
       var docInfo = {
         PDFFormatVersion: this.pdfFormatVersion,
+        IsLinearized: !!this.linearization,
         IsAcroFormPresent: !!this.acroForm,
         IsXFAPresent: !!this.xfa
       };
       var infoDict;
+
       try {
         infoDict = this.xref.trailer.get('Info');
       } catch (err) {
         if (err instanceof _util.MissingDataException) {
           throw err;
         }
+
         (0, _util.info)('The document information dictionary is invalid.');
       }
-      if (infoDict) {
-        var validEntries = DocumentInfoValidators.entries;
-        for (var key in validEntries) {
-          if (infoDict.has(key)) {
+
+      if ((0, _primitives.isDict)(infoDict)) {
+        var _iteratorNormalCompletion4 = true;
+        var _didIteratorError4 = false;
+        var _iteratorError4 = undefined;
+
+        try {
+          for (var _iterator4 = infoDict.getKeys()[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
+            var key = _step4.value;
             var value = infoDict.get(key);
-            if (validEntries[key](value)) {
-              docInfo[key] = typeof value !== 'string' ? value : (0, _util.stringToPDFString)(value);
-            } else {
-              (0, _util.info)('Bad value in document info for "' + key + '"');
+
+            if (DocumentInfoValidators[key]) {
+              if (DocumentInfoValidators[key](value)) {
+                docInfo[key] = typeof value !== 'string' ? value : (0, _util.stringToPDFString)(value);
+              } else {
+                (0, _util.info)("Bad value in document info for \"".concat(key, "\"."));
+              }
+            } else if (typeof key === 'string') {
+              var customValue = void 0;
+
+              if ((0, _util.isString)(value)) {
+                customValue = (0, _util.stringToPDFString)(value);
+              } else if ((0, _primitives.isName)(value) || (0, _util.isNum)(value) || (0, _util.isBool)(value)) {
+                customValue = value;
+              } else {
+                (0, _util.info)("Unsupported value in document info for (custom) \"".concat(key, "\"."));
+                continue;
+              }
+
+              if (!docInfo['Custom']) {
+                docInfo['Custom'] = Object.create(null);
+              }
+
+              docInfo['Custom'][key] = customValue;
+            }
+          }
+        } catch (err) {
+          _didIteratorError4 = true;
+          _iteratorError4 = err;
+        } finally {
+          try {
+            if (!_iteratorNormalCompletion4 && _iterator4.return != null) {
+              _iterator4.return();
+            }
+          } finally {
+            if (_didIteratorError4) {
+              throw _iteratorError4;
             }
           }
         }
       }
+
       return (0, _util.shadow)(this, 'documentInfo', docInfo);
-    },
-    get fingerprint() {
-      var xref = this.xref,
-          hash,
-          fileID = '';
-      var idArray = xref.trailer.get('ID');
+    }
+  }, {
+    key: "fingerprint",
+    get: function get() {
+      var hash;
+      var idArray = this.xref.trailer.get('ID');
+
       if (Array.isArray(idArray) && idArray[0] && (0, _util.isString)(idArray[0]) && idArray[0] !== EMPTY_FINGERPRINT) {
         hash = (0, _util.stringToBytes)(idArray[0]);
       } else {
         if (this.stream.ensureRange) {
           this.stream.ensureRange(0, Math.min(FINGERPRINT_FIRST_BYTES, this.stream.end));
         }
+
         hash = (0, _crypto.calculateMD5)(this.stream.bytes.subarray(0, FINGERPRINT_FIRST_BYTES), 0, FINGERPRINT_FIRST_BYTES);
       }
-      for (var i = 0, n = hash.length; i < n; i++) {
+
+      var fingerprint = '';
+
+      for (var i = 0, ii = hash.length; i < ii; i++) {
         var hex = hash[i].toString(16);
-        fileID += hex.length === 1 ? '0' + hex : hex;
+        fingerprint += hex.length === 1 ? '0' + hex : hex;
       }
-      return (0, _util.shadow)(this, 'fingerprint', fileID);
-    },
-    getPage: function PDFDocument_getPage(pageIndex) {
-      return this.catalog.getPage(pageIndex);
-    },
-    cleanup: function PDFDocument_cleanup() {
-      return this.catalog.cleanup();
+
+      return (0, _util.shadow)(this, 'fingerprint', fingerprint);
     }
-  };
+  }]);
+
   return PDFDocument;
 }();
-exports.Page = Page;
+
 exports.PDFDocument = PDFDocument;

File diff suppressed because it is too large
+ 4 - 2
lib/core/encodings.js


File diff suppressed because it is too large
+ 286 - 92
lib/core/evaluator.js


+ 331 - 97
lib/core/font_renderer.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,66 +19,99 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.FontRendererFactory = undefined;
+exports.FontRendererFactory = void 0;
 
-var _util = require('../shared/util');
+var _util = require("../shared/util");
 
-var _cff_parser = require('./cff_parser');
+var _cff_parser = require("./cff_parser");
 
-var _glyphlist = require('./glyphlist');
+var _glyphlist = require("./glyphlist");
 
-var _encodings = require('./encodings');
+var _encodings = require("./encodings");
 
-var _stream = require('./stream');
+var _stream = require("./stream");
+
+function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
+
+function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
+
+function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
+
+function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
+
+function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
+
+function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
 
 var FontRendererFactory = function FontRendererFactoryClosure() {
   function getLong(data, offset) {
     return data[offset] << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3];
   }
+
   function getUshort(data, offset) {
     return data[offset] << 8 | data[offset + 1];
   }
+
   function parseCmap(data, start, end) {
     var offset = getUshort(data, start + 2) === 1 ? getLong(data, start + 8) : getLong(data, start + 16);
     var format = getUshort(data, start + offset);
     var ranges, p, i;
+
     if (format === 4) {
       getUshort(data, start + offset + 2);
       var segCount = getUshort(data, start + offset + 6) >> 1;
       p = start + offset + 14;
       ranges = [];
+
       for (i = 0; i < segCount; i++, p += 2) {
-        ranges[i] = { end: getUshort(data, p) };
+        ranges[i] = {
+          end: getUshort(data, p)
+        };
       }
+
       p += 2;
+
       for (i = 0; i < segCount; i++, p += 2) {
         ranges[i].start = getUshort(data, p);
       }
+
       for (i = 0; i < segCount; i++, p += 2) {
         ranges[i].idDelta = getUshort(data, p);
       }
+
       for (i = 0; i < segCount; i++, p += 2) {
         var idOffset = getUshort(data, p);
+
         if (idOffset === 0) {
           continue;
         }
+
         ranges[i].ids = [];
+
         for (var j = 0, jj = ranges[i].end - ranges[i].start + 1; j < jj; j++) {
           ranges[i].ids[j] = getUshort(data, p + idOffset);
           idOffset += 2;
         }
       }
+
       return ranges;
     } else if (format === 12) {
       getLong(data, start + offset + 4);
       var groups = getLong(data, start + offset + 12);
       p = start + offset + 16;
       ranges = [];
+
       for (i = 0; i < groups; i++) {
         ranges.push({
           start: getLong(data, p),
@@ -87,10 +120,13 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
         });
         p += 12;
       }
+
       return ranges;
     }
-    throw new _util.FormatError('unsupported cmap: ' + format);
+
+    throw new _util.FormatError("unsupported cmap: ".concat(format));
   }
+
   function parseCff(data, start, end, seacAnalysisEnabled) {
     var properties = {};
     var parser = new _cff_parser.CFFParser(new _stream.Stream(data, start, end - start), properties, seacAnalysisEnabled);
@@ -104,49 +140,62 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
       fdArray: cff.fdArray
     };
   }
+
   function parseGlyfTable(glyf, loca, isGlyphLocationsLong) {
     var itemSize, itemDecode;
+
     if (isGlyphLocationsLong) {
       itemSize = 4;
+
       itemDecode = function fontItemDecodeLong(data, offset) {
         return data[offset] << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3];
       };
     } else {
       itemSize = 2;
+
       itemDecode = function fontItemDecode(data, offset) {
         return data[offset] << 9 | data[offset + 1] << 1;
       };
     }
+
     var glyphs = [];
     var startOffset = itemDecode(loca, 0);
+
     for (var j = itemSize; j < loca.length; j += itemSize) {
       var endOffset = itemDecode(loca, j);
       glyphs.push(glyf.subarray(startOffset, endOffset));
       startOffset = endOffset;
     }
+
     return glyphs;
   }
+
   function lookupCmap(ranges, unicode) {
-    var code = unicode.charCodeAt(0),
+    var code = unicode.codePointAt(0),
         gid = 0;
     var l = 0,
         r = ranges.length - 1;
+
     while (l < r) {
       var c = l + r + 1 >> 1;
+
       if (code < ranges[c].start) {
         r = c - 1;
       } else {
         l = c;
       }
     }
+
     if (ranges[l].start <= code && code <= ranges[l].end) {
       gid = ranges[l].idDelta + (ranges[l].ids ? ranges[l].ids[code - ranges[l].start] : code) & 0xFFFF;
     }
+
     return {
       charCode: code,
       glyphId: gid
     };
   }
+
   function compileGlyf(code, cmds, font) {
     function moveTo(x, y) {
       cmds.push({
@@ -154,30 +203,35 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
         args: [x, y]
       });
     }
+
     function lineTo(x, y) {
       cmds.push({
         cmd: 'lineTo',
         args: [x, y]
       });
     }
+
     function quadraticCurveTo(xa, ya, x, y) {
       cmds.push({
         cmd: 'quadraticCurveTo',
         args: [xa, ya, x, y]
       });
     }
+
     var i = 0;
     var numberOfContours = (code[i] << 24 | code[i + 1] << 16) >> 16;
     var flags;
     var x = 0,
         y = 0;
     i += 10;
+
     if (numberOfContours < 0) {
       do {
         flags = code[i] << 8 | code[i + 1];
         var glyphIndex = code[i + 2] << 8 | code[i + 3];
         i += 4;
         var arg1, arg2;
+
         if (flags & 0x01) {
           arg1 = (code[i] << 24 | code[i + 1] << 16) >> 16;
           arg2 = (code[i + 2] << 24 | code[i + 3] << 16) >> 16;
@@ -186,6 +240,7 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
           arg1 = code[i++];
           arg2 = code[i++];
         }
+
         if (flags & 0x02) {
           x = arg1;
           y = arg2;
@@ -193,10 +248,12 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
           x = 0;
           y = 0;
         }
+
         var scaleX = 1,
             scaleY = 1,
             scale01 = 0,
             scale10 = 0;
+
         if (flags & 0x08) {
           scaleX = scaleY = (code[i] << 24 | code[i + 1] << 16) / 1073741824;
           i += 2;
@@ -211,72 +268,96 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
           scaleY = (code[i + 6] << 24 | code[i + 7] << 16) / 1073741824;
           i += 8;
         }
+
         var subglyph = font.glyphs[glyphIndex];
+
         if (subglyph) {
-          cmds.push({ cmd: 'save' });
+          cmds.push({
+            cmd: 'save'
+          });
           cmds.push({
             cmd: 'transform',
             args: [scaleX, scale01, scale10, scaleY, x, y]
           });
           compileGlyf(subglyph, cmds, font);
-          cmds.push({ cmd: 'restore' });
+          cmds.push({
+            cmd: 'restore'
+          });
         }
       } while (flags & 0x20);
     } else {
       var endPtsOfContours = [];
       var j, jj;
+
       for (j = 0; j < numberOfContours; j++) {
         endPtsOfContours.push(code[i] << 8 | code[i + 1]);
         i += 2;
       }
+
       var instructionLength = code[i] << 8 | code[i + 1];
       i += 2 + instructionLength;
       var numberOfPoints = endPtsOfContours[endPtsOfContours.length - 1] + 1;
       var points = [];
+
       while (points.length < numberOfPoints) {
         flags = code[i++];
         var repeat = 1;
+
         if (flags & 0x08) {
           repeat += code[i++];
         }
+
         while (repeat-- > 0) {
-          points.push({ flags: flags });
+          points.push({
+            flags: flags
+          });
         }
       }
+
       for (j = 0; j < numberOfPoints; j++) {
         switch (points[j].flags & 0x12) {
           case 0x00:
             x += (code[i] << 24 | code[i + 1] << 16) >> 16;
             i += 2;
             break;
+
           case 0x02:
             x -= code[i++];
             break;
+
           case 0x12:
             x += code[i++];
             break;
         }
+
         points[j].x = x;
       }
+
       for (j = 0; j < numberOfPoints; j++) {
         switch (points[j].flags & 0x24) {
           case 0x00:
             y += (code[i] << 24 | code[i + 1] << 16) >> 16;
             i += 2;
             break;
+
           case 0x04:
             y -= code[i++];
             break;
+
           case 0x24:
             y += code[i++];
             break;
         }
+
         points[j].y = y;
       }
+
       var startPoint = 0;
+
       for (i = 0; i < numberOfContours; i++) {
         var endPoint = endPtsOfContours[i];
         var contour = points.slice(startPoint, endPoint + 1);
+
         if (contour[0].flags & 1) {
           contour.push(contour[0]);
         } else if (contour[contour.length - 1].flags & 1) {
@@ -290,7 +371,9 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
           contour.unshift(p);
           contour.push(p);
         }
+
         moveTo(contour[0].x, contour[0].y);
+
         for (j = 1, jj = contour.length; j < jj; j++) {
           if (contour[j].flags & 1) {
             lineTo(contour[j].x, contour[j].y);
@@ -301,82 +384,103 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
             quadraticCurveTo(contour[j].x, contour[j].y, (contour[j].x + contour[j + 1].x) / 2, (contour[j].y + contour[j + 1].y) / 2);
           }
         }
+
         startPoint = endPoint + 1;
       }
     }
   }
+
   function compileCharString(code, cmds, font, glyphId) {
     var stack = [];
     var x = 0,
         y = 0;
     var stems = 0;
+
     function moveTo(x, y) {
       cmds.push({
         cmd: 'moveTo',
         args: [x, y]
       });
     }
+
     function lineTo(x, y) {
       cmds.push({
         cmd: 'lineTo',
         args: [x, y]
       });
     }
+
     function bezierCurveTo(x1, y1, x2, y2, x, y) {
       cmds.push({
         cmd: 'bezierCurveTo',
         args: [x1, y1, x2, y2, x, y]
       });
     }
+
     function parse(code) {
       var i = 0;
+
       while (i < code.length) {
         var stackClean = false;
         var v = code[i++];
         var xa, xb, ya, yb, y1, y2, y3, n, subrCode;
+
         switch (v) {
           case 1:
             stems += stack.length >> 1;
             stackClean = true;
             break;
+
           case 3:
             stems += stack.length >> 1;
             stackClean = true;
             break;
+
           case 4:
             y += stack.pop();
             moveTo(x, y);
             stackClean = true;
             break;
+
           case 5:
             while (stack.length > 0) {
               x += stack.shift();
               y += stack.shift();
               lineTo(x, y);
             }
+
             break;
+
           case 6:
             while (stack.length > 0) {
               x += stack.shift();
               lineTo(x, y);
+
               if (stack.length === 0) {
                 break;
               }
+
               y += stack.shift();
               lineTo(x, y);
             }
+
             break;
+
           case 7:
             while (stack.length > 0) {
               y += stack.shift();
               lineTo(x, y);
+
               if (stack.length === 0) {
                 break;
               }
+
               x += stack.shift();
               lineTo(x, y);
             }
+
             break;
+
           case 8:
             while (stack.length > 0) {
               xa = x + stack.shift();
@@ -387,18 +491,24 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
               y = yb + stack.shift();
               bezierCurveTo(xa, ya, xb, yb, x, y);
             }
+
             break;
+
           case 10:
             n = stack.pop();
             subrCode = null;
+
             if (font.isCFFCIDFont) {
               var fdIndex = font.fdSelect.getFDIndex(glyphId);
+
               if (fdIndex >= 0 && fdIndex < font.fdArray.length) {
                 var fontDict = font.fdArray[fdIndex],
                     subrs = void 0;
+
                 if (fontDict.privateDict && fontDict.privateDict.subrsIndex) {
                   subrs = fontDict.privateDict.subrsIndex.objects;
                 }
+
                 if (subrs) {
                   var numSubrs = subrs.length;
                   n += numSubrs < 1240 ? 107 : numSubrs < 33900 ? 1131 : 32768;
@@ -410,14 +520,19 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
             } else {
               subrCode = font.subrs[n + font.subrsBias];
             }
+
             if (subrCode) {
               parse(subrCode);
             }
+
             break;
+
           case 11:
             return;
+
           case 12:
             v = code[i++];
+
             switch (v) {
               case 34:
                 xa = x + stack.shift();
@@ -430,6 +545,7 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
                 x = xb + stack.shift();
                 bezierCurveTo(xa, y1, xb, y, x, y);
                 break;
+
               case 35:
                 xa = x + stack.shift();
                 ya = y + stack.shift();
@@ -447,6 +563,7 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
                 bezierCurveTo(xa, ya, xb, yb, x, y);
                 stack.pop();
                 break;
+
               case 36:
                 xa = x + stack.shift();
                 y1 = y + stack.shift();
@@ -460,6 +577,7 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
                 x = xb + stack.shift();
                 bezierCurveTo(xa, y2, xb, y3, x, y);
                 break;
+
               case 37:
                 var x0 = x,
                     y0 = y;
@@ -476,64 +594,81 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
                 yb = ya + stack.shift();
                 x = xb;
                 y = yb;
+
                 if (Math.abs(x - x0) > Math.abs(y - y0)) {
                   x += stack.shift();
                 } else {
                   y += stack.shift();
                 }
+
                 bezierCurveTo(xa, ya, xb, yb, x, y);
                 break;
+
               default:
-                throw new _util.FormatError('unknown operator: 12 ' + v);
+                throw new _util.FormatError("unknown operator: 12 ".concat(v));
             }
+
             break;
+
           case 14:
             if (stack.length >= 4) {
               var achar = stack.pop();
               var bchar = stack.pop();
               y = stack.pop();
               x = stack.pop();
-              cmds.push({ cmd: 'save' });
+              cmds.push({
+                cmd: 'save'
+              });
               cmds.push({
                 cmd: 'translate',
                 args: [x, y]
               });
               var cmap = lookupCmap(font.cmap, String.fromCharCode(font.glyphNameMap[_encodings.StandardEncoding[achar]]));
               compileCharString(font.glyphs[cmap.glyphId], cmds, font, cmap.glyphId);
-              cmds.push({ cmd: 'restore' });
+              cmds.push({
+                cmd: 'restore'
+              });
               cmap = lookupCmap(font.cmap, String.fromCharCode(font.glyphNameMap[_encodings.StandardEncoding[bchar]]));
               compileCharString(font.glyphs[cmap.glyphId], cmds, font, cmap.glyphId);
             }
+
             return;
+
           case 18:
             stems += stack.length >> 1;
             stackClean = true;
             break;
+
           case 19:
             stems += stack.length >> 1;
             i += stems + 7 >> 3;
             stackClean = true;
             break;
+
           case 20:
             stems += stack.length >> 1;
             i += stems + 7 >> 3;
             stackClean = true;
             break;
+
           case 21:
             y += stack.pop();
             x += stack.pop();
             moveTo(x, y);
             stackClean = true;
             break;
+
           case 22:
             x += stack.pop();
             moveTo(x, y);
             stackClean = true;
             break;
+
           case 23:
             stems += stack.length >> 1;
             stackClean = true;
             break;
+
           case 24:
             while (stack.length > 2) {
               xa = x + stack.shift();
@@ -544,16 +679,19 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
               y = yb + stack.shift();
               bezierCurveTo(xa, ya, xb, yb, x, y);
             }
+
             x += stack.shift();
             y += stack.shift();
             lineTo(x, y);
             break;
+
           case 25:
             while (stack.length > 6) {
               x += stack.shift();
               y += stack.shift();
               lineTo(x, y);
             }
+
             xa = x + stack.shift();
             ya = y + stack.shift();
             xb = xa + stack.shift();
@@ -562,10 +700,12 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
             y = yb + stack.shift();
             bezierCurveTo(xa, ya, xb, yb, x, y);
             break;
+
           case 26:
             if (stack.length % 2) {
               x += stack.shift();
             }
+
             while (stack.length > 0) {
               xa = x;
               ya = y + stack.shift();
@@ -575,11 +715,14 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
               y = yb + stack.shift();
               bezierCurveTo(xa, ya, xb, yb, x, y);
             }
+
             break;
+
           case 27:
             if (stack.length % 2) {
               y += stack.shift();
             }
+
             while (stack.length > 0) {
               xa = x + stack.shift();
               ya = y;
@@ -589,18 +732,24 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
               y = yb;
               bezierCurveTo(xa, ya, xb, yb, x, y);
             }
+
             break;
+
           case 28:
             stack.push((code[i] << 24 | code[i + 1] << 16) >> 16);
             i += 2;
             break;
+
           case 29:
             n = stack.pop() + font.gsubrsBias;
             subrCode = font.gsubrs[n];
+
             if (subrCode) {
               parse(subrCode);
             }
+
             break;
+
           case 30:
             while (stack.length > 0) {
               xa = x;
@@ -610,9 +759,11 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
               x = xb + stack.shift();
               y = yb + (stack.length === 1 ? stack.shift() : 0);
               bezierCurveTo(xa, ya, xb, yb, x, y);
+
               if (stack.length === 0) {
                 break;
               }
+
               xa = x + stack.shift();
               ya = y;
               xb = xa + stack.shift();
@@ -621,7 +772,9 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
               x = xb + (stack.length === 1 ? stack.shift() : 0);
               bezierCurveTo(xa, ya, xb, yb, x, y);
             }
+
             break;
+
           case 31:
             while (stack.length > 0) {
               xa = x + stack.shift();
@@ -631,9 +784,11 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
               y = yb + stack.shift();
               x = xb + (stack.length === 1 ? stack.shift() : 0);
               bezierCurveTo(xa, ya, xb, yb, x, y);
+
               if (stack.length === 0) {
                 break;
               }
+
               xa = x;
               ya = y + stack.shift();
               xb = xa + stack.shift();
@@ -642,11 +797,14 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
               y = yb + (stack.length === 1 ? stack.shift() : 0);
               bezierCurveTo(xa, ya, xb, yb, x, y);
             }
+
             break;
+
           default:
             if (v < 32) {
-              throw new _util.FormatError('unknown operator: ' + v);
+              throw new _util.FormatError("unknown operator: ".concat(v));
             }
+
             if (v < 247) {
               stack.push(v - 139);
             } else if (v < 251) {
@@ -657,134 +815,210 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
               stack.push((code[i] << 24 | code[i + 1] << 16 | code[i + 2] << 8 | code[i + 3]) / 65536);
               i += 4;
             }
+
             break;
         }
+
         if (stackClean) {
           stack.length = 0;
         }
       }
     }
+
     parse(code);
   }
-  var noop = '';
-  function CompiledFont(fontMatrix) {
-    this.compiledGlyphs = Object.create(null);
-    this.compiledCharCodeToGlyphId = Object.create(null);
-    this.fontMatrix = fontMatrix;
-  }
-  CompiledFont.prototype = {
-    getPathJs: function getPathJs(unicode) {
-      var cmap = lookupCmap(this.cmap, unicode);
-      var fn = this.compiledGlyphs[cmap.glyphId];
-      if (!fn) {
-        fn = this.compileGlyph(this.glyphs[cmap.glyphId], cmap.glyphId);
-        this.compiledGlyphs[cmap.glyphId] = fn;
-      }
-      if (this.compiledCharCodeToGlyphId[cmap.charCode] === undefined) {
-        this.compiledCharCodeToGlyphId[cmap.charCode] = cmap.glyphId;
+
+  var NOOP = [];
+
+  var CompiledFont =
+  /*#__PURE__*/
+  function () {
+    function CompiledFont(fontMatrix) {
+      _classCallCheck(this, CompiledFont);
+
+      if (this.constructor === CompiledFont) {
+        (0, _util.unreachable)('Cannot initialize CompiledFont.');
       }
-      return fn;
-    },
-    compileGlyph: function compileGlyph(code, glyphId) {
-      if (!code || code.length === 0 || code[0] === 14) {
-        return noop;
+
+      this.fontMatrix = fontMatrix;
+      this.compiledGlyphs = Object.create(null);
+      this.compiledCharCodeToGlyphId = Object.create(null);
+    }
+
+    _createClass(CompiledFont, [{
+      key: "getPathJs",
+      value: function getPathJs(unicode) {
+        var cmap = lookupCmap(this.cmap, unicode);
+        var fn = this.compiledGlyphs[cmap.glyphId];
+
+        if (!fn) {
+          fn = this.compileGlyph(this.glyphs[cmap.glyphId], cmap.glyphId);
+          this.compiledGlyphs[cmap.glyphId] = fn;
+        }
+
+        if (this.compiledCharCodeToGlyphId[cmap.charCode] === undefined) {
+          this.compiledCharCodeToGlyphId[cmap.charCode] = cmap.glyphId;
+        }
+
+        return fn;
       }
-      var fontMatrix = this.fontMatrix;
-      if (this.isCFFCIDFont) {
-        var fdIndex = this.fdSelect.getFDIndex(glyphId);
-        if (fdIndex >= 0 && fdIndex < this.fdArray.length) {
-          var fontDict = this.fdArray[fdIndex];
-          fontMatrix = fontDict.getByName('FontMatrix') || _util.FONT_IDENTITY_MATRIX;
-        } else {
-          (0, _util.warn)('Invalid fd index for glyph index.');
+    }, {
+      key: "compileGlyph",
+      value: function compileGlyph(code, glyphId) {
+        if (!code || code.length === 0 || code[0] === 14) {
+          return NOOP;
         }
+
+        var fontMatrix = this.fontMatrix;
+
+        if (this.isCFFCIDFont) {
+          var fdIndex = this.fdSelect.getFDIndex(glyphId);
+
+          if (fdIndex >= 0 && fdIndex < this.fdArray.length) {
+            var fontDict = this.fdArray[fdIndex];
+            fontMatrix = fontDict.getByName('FontMatrix') || _util.FONT_IDENTITY_MATRIX;
+          } else {
+            (0, _util.warn)('Invalid fd index for glyph index.');
+          }
+        }
+
+        var cmds = [];
+        cmds.push({
+          cmd: 'save'
+        });
+        cmds.push({
+          cmd: 'transform',
+          args: fontMatrix.slice()
+        });
+        cmds.push({
+          cmd: 'scale',
+          args: ['size', '-size']
+        });
+        this.compileGlyphImpl(code, cmds, glyphId);
+        cmds.push({
+          cmd: 'restore'
+        });
+        return cmds;
       }
-      var cmds = [];
-      cmds.push({ cmd: 'save' });
-      cmds.push({
-        cmd: 'transform',
-        args: fontMatrix.slice()
-      });
-      cmds.push({
-        cmd: 'scale',
-        args: ['size', '-size']
-      });
-      this.compileGlyphImpl(code, cmds, glyphId);
-      cmds.push({ cmd: 'restore' });
-      return cmds;
-    },
-    compileGlyphImpl: function compileGlyphImpl() {
-      (0, _util.unreachable)('Children classes should implement this.');
-    },
-    hasBuiltPath: function hasBuiltPath(unicode) {
-      var cmap = lookupCmap(this.cmap, unicode);
-      return this.compiledGlyphs[cmap.glyphId] !== undefined && this.compiledCharCodeToGlyphId[cmap.charCode] !== undefined;
-    }
-  };
-  function TrueTypeCompiled(glyphs, cmap, fontMatrix) {
-    fontMatrix = fontMatrix || [0.000488, 0, 0, 0.000488, 0, 0];
-    CompiledFont.call(this, fontMatrix);
-    this.glyphs = glyphs;
-    this.cmap = cmap;
-  }
-  _util.Util.inherit(TrueTypeCompiled, CompiledFont, {
-    compileGlyphImpl: function compileGlyphImpl(code, cmds) {
-      compileGlyf(code, cmds, this);
+    }, {
+      key: "compileGlyphImpl",
+      value: function compileGlyphImpl() {
+        (0, _util.unreachable)('Children classes should implement this.');
+      }
+    }, {
+      key: "hasBuiltPath",
+      value: function hasBuiltPath(unicode) {
+        var cmap = lookupCmap(this.cmap, unicode);
+        return this.compiledGlyphs[cmap.glyphId] !== undefined && this.compiledCharCodeToGlyphId[cmap.charCode] !== undefined;
+      }
+    }]);
+
+    return CompiledFont;
+  }();
+
+  var TrueTypeCompiled =
+  /*#__PURE__*/
+  function (_CompiledFont) {
+    _inherits(TrueTypeCompiled, _CompiledFont);
+
+    function TrueTypeCompiled(glyphs, cmap, fontMatrix) {
+      var _this;
+
+      _classCallCheck(this, TrueTypeCompiled);
+
+      _this = _possibleConstructorReturn(this, _getPrototypeOf(TrueTypeCompiled).call(this, fontMatrix || [0.000488, 0, 0, 0.000488, 0, 0]));
+      _this.glyphs = glyphs;
+      _this.cmap = cmap;
+      return _this;
     }
-  });
-  function Type2Compiled(cffInfo, cmap, fontMatrix, glyphNameMap) {
-    fontMatrix = fontMatrix || [0.001, 0, 0, 0.001, 0, 0];
-    CompiledFont.call(this, fontMatrix);
-    this.glyphs = cffInfo.glyphs;
-    this.gsubrs = cffInfo.gsubrs || [];
-    this.subrs = cffInfo.subrs || [];
-    this.cmap = cmap;
-    this.glyphNameMap = glyphNameMap || (0, _glyphlist.getGlyphsUnicode)();
-    this.gsubrsBias = this.gsubrs.length < 1240 ? 107 : this.gsubrs.length < 33900 ? 1131 : 32768;
-    this.subrsBias = this.subrs.length < 1240 ? 107 : this.subrs.length < 33900 ? 1131 : 32768;
-    this.isCFFCIDFont = cffInfo.isCFFCIDFont;
-    this.fdSelect = cffInfo.fdSelect;
-    this.fdArray = cffInfo.fdArray;
-  }
-  _util.Util.inherit(Type2Compiled, CompiledFont, {
-    compileGlyphImpl: function compileGlyphImpl(code, cmds, glyphId) {
-      compileCharString(code, cmds, this, glyphId);
+
+    _createClass(TrueTypeCompiled, [{
+      key: "compileGlyphImpl",
+      value: function compileGlyphImpl(code, cmds) {
+        compileGlyf(code, cmds, this);
+      }
+    }]);
+
+    return TrueTypeCompiled;
+  }(CompiledFont);
+
+  var Type2Compiled =
+  /*#__PURE__*/
+  function (_CompiledFont2) {
+    _inherits(Type2Compiled, _CompiledFont2);
+
+    function Type2Compiled(cffInfo, cmap, fontMatrix, glyphNameMap) {
+      var _this2;
+
+      _classCallCheck(this, Type2Compiled);
+
+      _this2 = _possibleConstructorReturn(this, _getPrototypeOf(Type2Compiled).call(this, fontMatrix || [0.001, 0, 0, 0.001, 0, 0]));
+      _this2.glyphs = cffInfo.glyphs;
+      _this2.gsubrs = cffInfo.gsubrs || [];
+      _this2.subrs = cffInfo.subrs || [];
+      _this2.cmap = cmap;
+      _this2.glyphNameMap = glyphNameMap || (0, _glyphlist.getGlyphsUnicode)();
+      _this2.gsubrsBias = _this2.gsubrs.length < 1240 ? 107 : _this2.gsubrs.length < 33900 ? 1131 : 32768;
+      _this2.subrsBias = _this2.subrs.length < 1240 ? 107 : _this2.subrs.length < 33900 ? 1131 : 32768;
+      _this2.isCFFCIDFont = cffInfo.isCFFCIDFont;
+      _this2.fdSelect = cffInfo.fdSelect;
+      _this2.fdArray = cffInfo.fdArray;
+      return _this2;
     }
-  });
+
+    _createClass(Type2Compiled, [{
+      key: "compileGlyphImpl",
+      value: function compileGlyphImpl(code, cmds, glyphId) {
+        compileCharString(code, cmds, this, glyphId);
+      }
+    }]);
+
+    return Type2Compiled;
+  }(CompiledFont);
+
   return {
     create: function FontRendererFactory_create(font, seacAnalysisEnabled) {
       var data = new Uint8Array(font.data);
       var cmap, glyf, loca, cff, indexToLocFormat, unitsPerEm;
       var numTables = getUshort(data, 4);
+
       for (var i = 0, p = 12; i < numTables; i++, p += 16) {
         var tag = (0, _util.bytesToString)(data.subarray(p, p + 4));
         var offset = getLong(data, p + 8);
         var length = getLong(data, p + 12);
+
         switch (tag) {
           case 'cmap':
             cmap = parseCmap(data, offset, offset + length);
             break;
+
           case 'glyf':
             glyf = data.subarray(offset, offset + length);
             break;
+
           case 'loca':
             loca = data.subarray(offset, offset + length);
             break;
+
           case 'head':
             unitsPerEm = getUshort(data, offset + 18);
             indexToLocFormat = getUshort(data, offset + 50);
             break;
+
           case 'CFF ':
             cff = parseCff(data, offset, offset + length, seacAnalysisEnabled);
             break;
         }
       }
+
       if (glyf) {
         var fontMatrix = !unitsPerEm ? font.fontMatrix : [1 / unitsPerEm, 0, 0, 1 / unitsPerEm, 0, 0];
         return new TrueTypeCompiled(parseGlyfTable(glyf, loca, indexToLocFormat), cmap, fontMatrix);
       }
+
       return new Type2Compiled(cff, cmap, font.fontMatrix, font.glyphNameMap);
     }
   };
 }();
+
 exports.FontRendererFactory = FontRendererFactory;

File diff suppressed because it is too large
+ 27 - 16
lib/core/fonts.js


File diff suppressed because it is too large
+ 227 - 68
lib/core/function.js


+ 3 - 2
lib/core/glyphlist.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,9 +19,10 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 var getLookupTableFactory = require('../shared/util').getLookupTableFactory;
+
 var getGlyphsUnicode = getLookupTableFactory(function (t) {
   t['A'] = 0x0041;
   t['AE'] = 0x00C6;

+ 168 - 61
lib/core/image.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,26 +19,32 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.PDFImage = undefined;
+exports.PDFImage = void 0;
 
-var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
+var _util = require("../shared/util");
 
-var _util = require('../shared/util');
+var _primitives = require("./primitives");
 
-var _primitives = require('./primitives');
+var _colorspace = require("./colorspace");
 
-var _colorspace = require('./colorspace');
+var _stream = require("./stream");
 
-var _stream = require('./stream');
+var _jpeg_stream = require("./jpeg_stream");
 
-var _jpeg_stream = require('./jpeg_stream');
+var _jpx = require("./jpx");
 
-var _jpx = require('./jpx');
+function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
+
+function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
+
+function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
+
+function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
 
 var PDFImage = function PDFImageClosure() {
   function handleImageData(image, nativeDecoder) {
@@ -48,12 +54,15 @@ var PDFImage = function PDFImageClosure() {
         return image;
       });
     }
+
     return Promise.resolve(image);
   }
+
   function decodeAndClamp(value, addend, coefficient, max) {
     value = addend + value * coefficient;
     return value < 0 ? 0 : value > max ? max : value;
   }
+
   function resizeImageMask(src, bpc, w1, h1, w2, h2) {
     var length = w2 * h2;
     var dest = bpc <= 8 ? new Uint8Array(length) : bpc <= 16 ? new Uint16Array(length) : new Uint32Array(length);
@@ -66,103 +75,140 @@ var PDFImage = function PDFImageClosure() {
         oldIndex;
     var xScaled = new Uint16Array(w2);
     var w1Scanline = w1;
+
     for (i = 0; i < w2; i++) {
       xScaled[i] = Math.floor(i * xRatio);
     }
+
     for (i = 0; i < h2; i++) {
       py = Math.floor(i * yRatio) * w1Scanline;
+
       for (j = 0; j < w2; j++) {
         oldIndex = py + xScaled[j];
         dest[newIndex++] = src[oldIndex];
       }
     }
+
     return dest;
   }
+
   function PDFImage(_ref) {
     var xref = _ref.xref,
         res = _ref.res,
         image = _ref.image,
         _ref$isInline = _ref.isInline,
-        isInline = _ref$isInline === undefined ? false : _ref$isInline,
+        isInline = _ref$isInline === void 0 ? false : _ref$isInline,
         _ref$smask = _ref.smask,
-        smask = _ref$smask === undefined ? null : _ref$smask,
+        smask = _ref$smask === void 0 ? null : _ref$smask,
         _ref$mask = _ref.mask,
-        mask = _ref$mask === undefined ? null : _ref$mask,
+        mask = _ref$mask === void 0 ? null : _ref$mask,
         _ref$isMask = _ref.isMask,
-        isMask = _ref$isMask === undefined ? false : _ref$isMask,
+        isMask = _ref$isMask === void 0 ? false : _ref$isMask,
         pdfFunctionFactory = _ref.pdfFunctionFactory;
-
     this.image = image;
     var dict = image.dict;
-    if (dict.has('Filter')) {
-      var filter = dict.get('Filter').name;
-      if (filter === 'JPXDecode') {
-        var jpxImage = new _jpx.JpxImage();
-        jpxImage.parseImageProperties(image.stream);
-        image.stream.reset();
-        image.bitsPerComponent = jpxImage.bitsPerComponent;
-        image.numComps = jpxImage.componentsCount;
-      } else if (filter === 'JBIG2Decode') {
-        image.bitsPerComponent = 1;
-        image.numComps = 1;
+    var filter = dict.get('Filter');
+
+    if ((0, _primitives.isName)(filter)) {
+      switch (filter.name) {
+        case 'JPXDecode':
+          var jpxImage = new _jpx.JpxImage();
+          jpxImage.parseImageProperties(image.stream);
+          image.stream.reset();
+          image.width = jpxImage.width;
+          image.height = jpxImage.height;
+          image.bitsPerComponent = jpxImage.bitsPerComponent;
+          image.numComps = jpxImage.componentsCount;
+          break;
+
+        case 'JBIG2Decode':
+          image.bitsPerComponent = 1;
+          image.numComps = 1;
+          break;
       }
     }
-    this.width = dict.get('Width', 'W');
-    this.height = dict.get('Height', 'H');
-    if (this.width < 1 || this.height < 1) {
-      throw new _util.FormatError('Invalid image width: ' + this.width + ' or ' + ('height: ' + this.height));
+
+    var width = dict.get('Width', 'W');
+    var height = dict.get('Height', 'H');
+
+    if (Number.isInteger(image.width) && image.width > 0 && Number.isInteger(image.height) && image.height > 0 && (image.width !== width || image.height !== height)) {
+      (0, _util.warn)('PDFImage - using the Width/Height of the image data, ' + 'rather than the image dictionary.');
+      width = image.width;
+      height = image.height;
     }
+
+    if (width < 1 || height < 1) {
+      throw new _util.FormatError("Invalid image width: ".concat(width, " or ") + "height: ".concat(height));
+    }
+
+    this.width = width;
+    this.height = height;
     this.interpolate = dict.get('Interpolate', 'I') || false;
     this.imageMask = dict.get('ImageMask', 'IM') || false;
     this.matte = dict.get('Matte') || false;
     var bitsPerComponent = image.bitsPerComponent;
+
     if (!bitsPerComponent) {
       bitsPerComponent = dict.get('BitsPerComponent', 'BPC');
+
       if (!bitsPerComponent) {
         if (this.imageMask) {
           bitsPerComponent = 1;
         } else {
-          throw new _util.FormatError('Bits per component missing in image: ' + this.imageMask);
+          throw new _util.FormatError("Bits per component missing in image: ".concat(this.imageMask));
         }
       }
     }
+
     this.bpc = bitsPerComponent;
+
     if (!this.imageMask) {
       var colorSpace = dict.get('ColorSpace', 'CS');
+
       if (!colorSpace) {
         (0, _util.info)('JPX images (which do not require color spaces)');
+
         switch (image.numComps) {
           case 1:
             colorSpace = _primitives.Name.get('DeviceGray');
             break;
+
           case 3:
             colorSpace = _primitives.Name.get('DeviceRGB');
             break;
+
           case 4:
             colorSpace = _primitives.Name.get('DeviceCMYK');
             break;
+
           default:
-            throw new Error('JPX images with ' + this.numComps + ' ' + 'color components not supported.');
+            throw new Error("JPX images with ".concat(image.numComps, " ") + 'color components not supported.');
         }
       }
+
       var resources = isInline ? res : null;
       this.colorSpace = _colorspace.ColorSpace.parse(colorSpace, xref, resources, pdfFunctionFactory);
       this.numComps = this.colorSpace.numComps;
     }
+
     this.decode = dict.getArray('Decode', 'D');
     this.needsDecode = false;
-    if (this.decode && (this.colorSpace && !this.colorSpace.isDefaultDecode(this.decode) || isMask && !_colorspace.ColorSpace.isDefaultDecode(this.decode, 1))) {
+
+    if (this.decode && (this.colorSpace && !this.colorSpace.isDefaultDecode(this.decode, bitsPerComponent) || isMask && !_colorspace.ColorSpace.isDefaultDecode(this.decode, 1))) {
       this.needsDecode = true;
       var max = (1 << bitsPerComponent) - 1;
       this.decodeCoefficients = [];
       this.decodeAddends = [];
+      var isIndexed = this.colorSpace && this.colorSpace.name === 'Indexed';
+
       for (var i = 0, j = 0; i < this.decode.length; i += 2, ++j) {
         var dmin = this.decode[i];
         var dmax = this.decode[i + 1];
-        this.decodeCoefficients[j] = dmax - dmin;
-        this.decodeAddends[j] = max * dmin;
+        this.decodeCoefficients[j] = isIndexed ? (dmax - dmin) / max : dmax - dmin;
+        this.decodeAddends[j] = isIndexed ? dmin : max * dmin;
       }
     }
+
     if (smask) {
       this.smask = new PDFImage({
         xref: xref,
@@ -175,6 +221,7 @@ var PDFImage = function PDFImageClosure() {
       if ((0, _primitives.isStream)(mask)) {
         var maskDict = mask.dict,
             imageMask = maskDict.get('ImageMask', 'IM');
+
         if (!imageMask) {
           (0, _util.warn)('Ignoring /Mask in image without /ImageMask.');
         } else {
@@ -192,27 +239,29 @@ var PDFImage = function PDFImageClosure() {
       }
     }
   }
+
   PDFImage.buildImage = function (_ref2) {
     var handler = _ref2.handler,
         xref = _ref2.xref,
         res = _ref2.res,
         image = _ref2.image,
         _ref2$isInline = _ref2.isInline,
-        isInline = _ref2$isInline === undefined ? false : _ref2$isInline,
+        isInline = _ref2$isInline === void 0 ? false : _ref2$isInline,
         _ref2$nativeDecoder = _ref2.nativeDecoder,
-        nativeDecoder = _ref2$nativeDecoder === undefined ? null : _ref2$nativeDecoder,
+        nativeDecoder = _ref2$nativeDecoder === void 0 ? null : _ref2$nativeDecoder,
         pdfFunctionFactory = _ref2.pdfFunctionFactory;
-
     var imagePromise = handleImageData(image, nativeDecoder);
     var smaskPromise;
     var maskPromise;
     var smask = image.dict.get('SMask');
     var mask = image.dict.get('Mask');
+
     if (smask) {
       smaskPromise = handleImageData(smask, nativeDecoder);
       maskPromise = Promise.resolve(null);
     } else {
       smaskPromise = Promise.resolve(null);
+
       if (mask) {
         if ((0, _primitives.isStream)(mask)) {
           maskPromise = handleImageData(mask, nativeDecoder);
@@ -226,6 +275,7 @@ var PDFImage = function PDFImageClosure() {
         maskPromise = Promise.resolve(null);
       }
     }
+
     return Promise.all([imagePromise, smaskPromise, maskPromise]).then(function (_ref3) {
       var _ref4 = _slicedToArray(_ref3, 3),
           imageData = _ref4[0],
@@ -243,47 +293,54 @@ var PDFImage = function PDFImageClosure() {
       });
     });
   };
+
   PDFImage.createMask = function (_ref5) {
     var imgArray = _ref5.imgArray,
         width = _ref5.width,
         height = _ref5.height,
         imageIsFromDecodeStream = _ref5.imageIsFromDecodeStream,
         inverseDecode = _ref5.inverseDecode;
-
     var computedLength = (width + 7 >> 3) * height;
     var actualLength = imgArray.byteLength;
     var haveFullData = computedLength === actualLength;
     var data, i;
+
     if (imageIsFromDecodeStream && (!inverseDecode || haveFullData)) {
       data = imgArray;
     } else if (!inverseDecode) {
-      data = new Uint8Array(actualLength);
+      data = new Uint8ClampedArray(actualLength);
       data.set(imgArray);
     } else {
-      data = new Uint8Array(computedLength);
+      data = new Uint8ClampedArray(computedLength);
       data.set(imgArray);
+
       for (i = actualLength; i < computedLength; i++) {
         data[i] = 0xff;
       }
     }
+
     if (inverseDecode) {
       for (i = 0; i < actualLength; i++) {
         data[i] ^= 0xFF;
       }
     }
+
     return {
       data: data,
       width: width,
       height: height
     };
   };
+
   PDFImage.prototype = {
     get drawWidth() {
       return Math.max(this.width, this.smask && this.smask.width || 0, this.mask && this.mask.width || 0);
     },
+
     get drawHeight() {
       return Math.max(this.height, this.smask && this.smask.height || 0, this.mask && this.mask.height || 0);
     },
+
     decodeBuffer: function decodeBuffer(buffer) {
       var bpc = this.bpc;
       var numComps = this.numComps;
@@ -291,13 +348,17 @@ var PDFImage = function PDFImageClosure() {
       var decodeCoefficients = this.decodeCoefficients;
       var max = (1 << bpc) - 1;
       var i, ii;
+
       if (bpc === 1) {
         for (i = 0, ii = buffer.length; i < ii; i++) {
           buffer[i] = +!buffer[i];
         }
+
         return;
       }
+
       var index = 0;
+
       for (i = 0, ii = this.width * this.height; i < ii; i++) {
         for (var j = 0; j < numComps; j++) {
           buffer[index] = decodeAndClamp(buffer[index], decodeAddends[j], decodeCoefficients[j], max);
@@ -307,9 +368,11 @@ var PDFImage = function PDFImageClosure() {
     },
     getComponents: function getComponents(buffer) {
       var bpc = this.bpc;
+
       if (bpc === 8) {
         return buffer;
       }
+
       var width = this.width;
       var height = this.height;
       var numComps = this.numComps;
@@ -321,11 +384,14 @@ var PDFImage = function PDFImageClosure() {
       var i = 0,
           ii,
           buf;
+
       if (bpc === 1) {
         var mask, loop1End, loop2End;
+
         for (var j = 0; j < height; j++) {
           loop1End = i + (rowComps & ~7);
           loop2End = i + rowComps;
+
           while (i < loop1End) {
             buf = buffer[bufferPos++];
             output[i] = buf >> 7 & 1;
@@ -338,9 +404,11 @@ var PDFImage = function PDFImageClosure() {
             output[i + 7] = buf & 1;
             i += 8;
           }
+
           if (i < loop2End) {
             buf = buffer[bufferPos++];
             mask = 128;
+
             while (i < loop2End) {
               output[i++] = +!!(buf & mask);
               mask >>= 1;
@@ -350,15 +418,18 @@ var PDFImage = function PDFImageClosure() {
       } else {
         var bits = 0;
         buf = 0;
+
         for (i = 0, ii = length; i < ii; ++i) {
           if (i % rowComps === 0) {
             buf = 0;
             bits = 0;
           }
+
           while (bits < bpc) {
             buf = buf << 8 | buffer[bufferPos++];
             bits += 8;
           }
+
           var remainingBits = bits - bpc;
           var value = buf >> remainingBits;
           output[i] = value < 0 ? 0 : value > max ? max : value;
@@ -366,17 +437,20 @@ var PDFImage = function PDFImageClosure() {
           bits = remainingBits;
         }
       }
+
       return output;
     },
     fillOpacity: function fillOpacity(rgbaBuf, width, height, actualHeight, image) {
       var smask = this.smask;
       var mask = this.mask;
       var alphaBuf, sw, sh, i, ii, j;
+
       if (smask) {
         sw = smask.width;
         sh = smask.height;
-        alphaBuf = new Uint8Array(sw * sh);
+        alphaBuf = new Uint8ClampedArray(sw * sh);
         smask.fillGrayBuffer(alphaBuf);
+
         if (sw !== width || sh !== height) {
           alphaBuf = resizeImageMask(alphaBuf, smask.bpc, sw, sh, width, height);
         }
@@ -384,35 +458,42 @@ var PDFImage = function PDFImageClosure() {
         if (mask instanceof PDFImage) {
           sw = mask.width;
           sh = mask.height;
-          alphaBuf = new Uint8Array(sw * sh);
+          alphaBuf = new Uint8ClampedArray(sw * sh);
           mask.numComps = 1;
           mask.fillGrayBuffer(alphaBuf);
+
           for (i = 0, ii = sw * sh; i < ii; ++i) {
             alphaBuf[i] = 255 - alphaBuf[i];
           }
+
           if (sw !== width || sh !== height) {
             alphaBuf = resizeImageMask(alphaBuf, mask.bpc, sw, sh, width, height);
           }
         } else if (Array.isArray(mask)) {
-          alphaBuf = new Uint8Array(width * height);
+          alphaBuf = new Uint8ClampedArray(width * height);
           var numComps = this.numComps;
+
           for (i = 0, ii = width * height; i < ii; ++i) {
             var opacity = 0;
             var imageOffset = i * numComps;
+
             for (j = 0; j < numComps; ++j) {
               var color = image[imageOffset + j];
               var maskOffset = j * 2;
+
               if (color < mask[maskOffset] || color > mask[maskOffset + 1]) {
                 opacity = 255;
                 break;
               }
             }
+
             alphaBuf[i] = opacity;
           }
         } else {
           throw new _util.FormatError('Unknown mask format.');
         }
       }
+
       if (alphaBuf) {
         for (i = 0, j = 3, ii = width * actualHeight; i < ii; ++i, j += 4) {
           rgbaBuf[j] = alphaBuf[i];
@@ -425,40 +506,42 @@ var PDFImage = function PDFImageClosure() {
     },
     undoPreblend: function undoPreblend(buffer, width, height) {
       var matte = this.smask && this.smask.matte;
+
       if (!matte) {
         return;
       }
+
       var matteRgb = this.colorSpace.getRgb(matte, 0);
       var matteR = matteRgb[0];
       var matteG = matteRgb[1];
       var matteB = matteRgb[2];
       var length = width * height * 4;
-      var r, g, b;
+
       for (var i = 0; i < length; i += 4) {
         var alpha = buffer[i + 3];
+
         if (alpha === 0) {
           buffer[i] = 255;
           buffer[i + 1] = 255;
           buffer[i + 2] = 255;
           continue;
         }
+
         var k = 255 / alpha;
-        r = (buffer[i] - matteR) * k + matteR;
-        g = (buffer[i + 1] - matteG) * k + matteG;
-        b = (buffer[i + 2] - matteB) * k + matteB;
-        buffer[i] = r <= 0 ? 0 : r >= 255 ? 255 : r | 0;
-        buffer[i + 1] = g <= 0 ? 0 : g >= 255 ? 255 : g | 0;
-        buffer[i + 2] = b <= 0 ? 0 : b >= 255 ? 255 : b | 0;
+        buffer[i] = (buffer[i] - matteR) * k + matteR;
+        buffer[i + 1] = (buffer[i + 1] - matteG) * k + matteG;
+        buffer[i + 2] = (buffer[i + 2] - matteB) * k + matteB;
       }
     },
     createImageData: function createImageData() {
       var forceRGBA = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
-
       var drawWidth = this.drawWidth;
       var drawHeight = this.drawHeight;
       var imgData = {
         width: drawWidth,
-        height: drawHeight
+        height: drawHeight,
+        kind: 0,
+        data: null
       };
       var numComps = this.numComps;
       var originalWidth = this.width;
@@ -466,37 +549,47 @@ var PDFImage = function PDFImageClosure() {
       var bpc = this.bpc;
       var rowBytes = originalWidth * numComps * bpc + 7 >> 3;
       var imgArray;
+
       if (!forceRGBA) {
         var kind;
+
         if (this.colorSpace.name === 'DeviceGray' && bpc === 1) {
           kind = _util.ImageKind.GRAYSCALE_1BPP;
         } else if (this.colorSpace.name === 'DeviceRGB' && bpc === 8 && !this.needsDecode) {
           kind = _util.ImageKind.RGB_24BPP;
         }
+
         if (kind && !this.smask && !this.mask && drawWidth === originalWidth && drawHeight === originalHeight) {
           imgData.kind = kind;
           imgArray = this.getImageBytes(originalHeight * rowBytes);
+
           if (this.image instanceof _stream.DecodeStream) {
             imgData.data = imgArray;
           } else {
-            var newArray = new Uint8Array(imgArray.length);
+            var newArray = new Uint8ClampedArray(imgArray.length);
             newArray.set(imgArray);
             imgData.data = newArray;
           }
+
           if (this.needsDecode) {
-            (0, _util.assert)(kind === _util.ImageKind.GRAYSCALE_1BPP);
+            (0, _util.assert)(kind === _util.ImageKind.GRAYSCALE_1BPP, 'PDFImage.createImageData: The image must be grayscale.');
             var buffer = imgData.data;
+
             for (var i = 0, ii = buffer.length; i < ii; i++) {
               buffer[i] ^= 0xff;
             }
           }
+
           return imgData;
         }
+
         if (this.image instanceof _jpeg_stream.JpegStream && !this.smask && !this.mask) {
           var imageLength = originalHeight * rowBytes;
+
           switch (this.colorSpace.name) {
             case 'DeviceGray':
               imageLength *= 3;
+
             case 'DeviceRGB':
             case 'DeviceCMYK':
               imgData.kind = _util.ImageKind.RGB_24BPP;
@@ -505,36 +598,44 @@ var PDFImage = function PDFImageClosure() {
           }
         }
       }
+
       imgArray = this.getImageBytes(originalHeight * rowBytes);
       var actualHeight = 0 | imgArray.length / rowBytes * drawHeight / originalHeight;
       var comps = this.getComponents(imgArray);
       var alpha01, maybeUndoPreblend;
+
       if (!forceRGBA && !this.smask && !this.mask) {
         imgData.kind = _util.ImageKind.RGB_24BPP;
-        imgData.data = new Uint8Array(drawWidth * drawHeight * 3);
+        imgData.data = new Uint8ClampedArray(drawWidth * drawHeight * 3);
         alpha01 = 0;
         maybeUndoPreblend = false;
       } else {
         imgData.kind = _util.ImageKind.RGBA_32BPP;
-        imgData.data = new Uint8Array(drawWidth * drawHeight * 4);
+        imgData.data = new Uint8ClampedArray(drawWidth * drawHeight * 4);
         alpha01 = 1;
         maybeUndoPreblend = true;
         this.fillOpacity(imgData.data, drawWidth, drawHeight, actualHeight, comps);
       }
+
       if (this.needsDecode) {
         this.decodeBuffer(comps);
       }
+
       this.colorSpace.fillRgb(imgData.data, originalWidth, originalHeight, drawWidth, drawHeight, actualHeight, bpc, comps, alpha01);
+
       if (maybeUndoPreblend) {
         this.undoPreblend(imgData.data, drawWidth, actualHeight);
       }
+
       return imgData;
     },
     fillGrayBuffer: function fillGrayBuffer(buffer) {
       var numComps = this.numComps;
+
       if (numComps !== 1) {
-        throw new _util.FormatError('Reading gray scale from a color image: ' + numComps);
+        throw new _util.FormatError("Reading gray scale from a color image: ".concat(numComps));
       }
+
       var width = this.width;
       var height = this.height;
       var bpc = this.bpc;
@@ -542,8 +643,10 @@ var PDFImage = function PDFImageClosure() {
       var imgArray = this.getImageBytes(height * rowBytes);
       var comps = this.getComponents(imgArray);
       var i, length;
+
       if (bpc === 1) {
         length = width * height;
+
         if (this.needsDecode) {
           for (i = 0; i < length; ++i) {
             buffer[i] = comps[i] - 1 & 255;
@@ -553,27 +656,31 @@ var PDFImage = function PDFImageClosure() {
             buffer[i] = -comps[i] & 255;
           }
         }
+
         return;
       }
+
       if (this.needsDecode) {
         this.decodeBuffer(comps);
       }
+
       length = width * height;
       var scale = 255 / ((1 << bpc) - 1);
+
       for (i = 0; i < length; ++i) {
-        buffer[i] = scale * comps[i] | 0;
+        buffer[i] = scale * comps[i];
       }
     },
     getImageBytes: function getImageBytes(length, drawWidth, drawHeight) {
       var forceRGB = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
-
       this.image.reset();
       this.image.drawWidth = drawWidth || this.width;
       this.image.drawHeight = drawHeight || this.height;
       this.image.forceRGB = !!forceRGB;
-      return this.image.getBytes(length);
+      return this.image.getBytes(length, true);
     }
   };
   return PDFImage;
 }();
+
 exports.PDFImage = PDFImage;

File diff suppressed because it is too large
+ 210 - 28
lib/core/jbig2.js


+ 19 - 8
lib/core/jbig2_stream.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,20 +19,20 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.Jbig2Stream = undefined;
+exports.Jbig2Stream = void 0;
 
-var _primitives = require('./primitives');
+var _primitives = require("./primitives");
 
-var _stream = require('./stream');
+var _stream = require("./stream");
 
-var _jbig = require('./jbig2');
+var _jbig = require("./jbig2");
 
-var _util = require('../shared/util');
+var _util = require("../shared/util");
 
 var Jbig2Stream = function Jbig2StreamClosure() {
   function Jbig2Stream(stream, maybeLength, dict, params) {
@@ -40,25 +40,31 @@ var Jbig2Stream = function Jbig2StreamClosure() {
     this.maybeLength = maybeLength;
     this.dict = dict;
     this.params = params;
+
     _stream.DecodeStream.call(this, maybeLength);
   }
+
   Jbig2Stream.prototype = Object.create(_stream.DecodeStream.prototype);
   Object.defineProperty(Jbig2Stream.prototype, 'bytes', {
     get: function get() {
       return (0, _util.shadow)(this, 'bytes', this.stream.getBytes(this.maybeLength));
     },
-
     configurable: true
   });
+
   Jbig2Stream.prototype.ensureBuffer = function (requested) {};
+
   Jbig2Stream.prototype.readBlock = function () {
     if (this.eof) {
       return;
     }
+
     var jbig2Image = new _jbig.Jbig2Image();
     var chunks = [];
+
     if ((0, _primitives.isDict)(this.params)) {
       var globalsStream = this.params.get('JBIG2Globals');
+
       if ((0, _primitives.isStream)(globalsStream)) {
         var globals = globalsStream.getBytes();
         chunks.push({
@@ -68,6 +74,7 @@ var Jbig2Stream = function Jbig2StreamClosure() {
         });
       }
     }
+
     chunks.push({
       data: this.bytes,
       start: 0,
@@ -75,13 +82,17 @@ var Jbig2Stream = function Jbig2StreamClosure() {
     });
     var data = jbig2Image.parseChunks(chunks);
     var dataLength = data.length;
+
     for (var i = 0; i < dataLength; i++) {
       data[i] ^= 0xFF;
     }
+
     this.buffer = data;
     this.bufferLength = dataLength;
     this.eof = true;
   };
+
   return Jbig2Stream;
 }();
+
 exports.Jbig2Stream = Jbig2Stream;

+ 38 - 13
lib/core/jpeg_stream.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,36 +19,40 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.JpegStream = undefined;
+exports.JpegStream = void 0;
 
-var _util = require('../shared/util');
+var _util = require("../shared/util");
 
-var _stream = require('./stream');
+var _stream = require("./stream");
 
-var _primitives = require('./primitives');
+var _primitives = require("./primitives");
 
-var _jpg = require('./jpg');
+var _jpg = require("./jpg");
 
 var JpegStream = function JpegStreamClosure() {
   function JpegStream(stream, maybeLength, dict, params) {
-    var ch = void 0;
+    var ch;
+
     while ((ch = stream.getByte()) !== -1) {
       if (ch === 0xFF) {
         stream.skip(-1);
         break;
       }
     }
+
     this.stream = stream;
     this.maybeLength = maybeLength;
     this.dict = dict;
     this.params = params;
+
     _stream.DecodeStream.call(this, maybeLength);
   }
+
   JpegStream.prototype = Object.create(_stream.DecodeStream.prototype);
   Object.defineProperty(JpegStream.prototype, 'bytes', {
     get: function JpegStream_bytes() {
@@ -56,47 +60,68 @@ var JpegStream = function JpegStreamClosure() {
     },
     configurable: true
   });
+
   JpegStream.prototype.ensureBuffer = function (requested) {};
+
   JpegStream.prototype.readBlock = function () {
     if (this.eof) {
       return;
     }
-    var jpegImage = new _jpg.JpegImage();
+
+    var jpegOptions = {
+      decodeTransform: undefined,
+      colorTransform: undefined
+    };
     var decodeArr = this.dict.getArray('Decode', 'D');
+
     if (this.forceRGB && Array.isArray(decodeArr)) {
       var bitsPerComponent = this.dict.get('BitsPerComponent') || 8;
       var decodeArrLength = decodeArr.length;
       var transform = new Int32Array(decodeArrLength);
       var transformNeeded = false;
       var maxValue = (1 << bitsPerComponent) - 1;
+
       for (var i = 0; i < decodeArrLength; i += 2) {
         transform[i] = (decodeArr[i + 1] - decodeArr[i]) * 256 | 0;
         transform[i + 1] = decodeArr[i] * maxValue | 0;
+
         if (transform[i] !== 256 || transform[i + 1] !== 0) {
           transformNeeded = true;
         }
       }
+
       if (transformNeeded) {
-        jpegImage.decodeTransform = transform;
+        jpegOptions.decodeTransform = transform;
       }
     }
+
     if ((0, _primitives.isDict)(this.params)) {
       var colorTransform = this.params.get('ColorTransform');
+
       if (Number.isInteger(colorTransform)) {
-        jpegImage.colorTransform = colorTransform;
+        jpegOptions.colorTransform = colorTransform;
       }
     }
+
+    var jpegImage = new _jpg.JpegImage(jpegOptions);
     jpegImage.parse(this.bytes);
-    var data = jpegImage.getData(this.drawWidth, this.drawHeight, this.forceRGB);
+    var data = jpegImage.getData({
+      width: this.drawWidth,
+      height: this.drawHeight,
+      forceRGB: this.forceRGB,
+      isSourcePDF: true
+    });
     this.buffer = data;
     this.bufferLength = data.length;
     this.eof = true;
   };
+
   JpegStream.prototype.getIR = function () {
     var forceDataSchema = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
-
     return (0, _util.createObjectURL)(this.bytes, 'image/jpeg', forceDataSchema);
   };
+
   return JpegStream;
 }();
+
 exports.JpegStream = JpegStream;

+ 252 - 29
lib/core/jpg.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,36 +19,51 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.JpegImage = undefined;
+exports.JpegImage = void 0;
 
-var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
+var _util = require("../shared/util");
 
-var _util = require('../shared/util');
+function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
 
 var JpegError = function JpegErrorClosure() {
   function JpegError(msg) {
     this.message = 'JPEG error: ' + msg;
   }
+
   JpegError.prototype = new Error();
   JpegError.prototype.name = 'JpegError';
   JpegError.constructor = JpegError;
   return JpegError;
 }();
+
 var DNLMarkerError = function DNLMarkerErrorClosure() {
   function DNLMarkerError(message, scanLines) {
     this.message = message;
     this.scanLines = scanLines;
   }
+
   DNLMarkerError.prototype = new Error();
   DNLMarkerError.prototype.name = 'DNLMarkerError';
   DNLMarkerError.constructor = DNLMarkerError;
   return DNLMarkerError;
 }();
+
+var EOIMarkerError = function EOIMarkerErrorClosure() {
+  function EOIMarkerError(message) {
+    this.message = message;
+  }
+
+  EOIMarkerError.prototype = new Error();
+  EOIMarkerError.prototype.name = 'EOIMarkerError';
+  EOIMarkerError.constructor = EOIMarkerError;
+  return EOIMarkerError;
+}();
+
 var JpegImage = function JpegImageClosure() {
   var dctZigZag = new Uint8Array([0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63]);
   var dctCos1 = 4017;
@@ -59,34 +74,48 @@ var JpegImage = function JpegImageClosure() {
   var dctSin6 = 3784;
   var dctSqrt2 = 5793;
   var dctSqrt1d2 = 2896;
+
   function JpegImage() {
-    this.decodeTransform = null;
-    this.colorTransform = -1;
+    var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
+        _ref$decodeTransform = _ref.decodeTransform,
+        decodeTransform = _ref$decodeTransform === void 0 ? null : _ref$decodeTransform,
+        _ref$colorTransform = _ref.colorTransform,
+        colorTransform = _ref$colorTransform === void 0 ? -1 : _ref$colorTransform;
+
+    this._decodeTransform = decodeTransform;
+    this._colorTransform = colorTransform;
   }
+
   function buildHuffmanTable(codeLengths, values) {
     var k = 0,
         code = [],
         i,
         j,
         length = 16;
+
     while (length > 0 && !codeLengths[length - 1]) {
       length--;
     }
+
     code.push({
       children: [],
       index: 0
     });
     var p = code[0],
         q;
+
     for (i = 0; i < length; i++) {
       for (j = 0; j < codeLengths[i]; j++) {
         p = code.pop();
         p.children[p.index] = values[k];
+
         while (p.index > 0) {
           p = code.pop();
         }
+
         p.index++;
         code.push(p);
+
         while (code.length <= i) {
           code.push(q = {
             children: [],
@@ -95,8 +124,10 @@ var JpegImage = function JpegImageClosure() {
           p.children[p.index] = q.children;
           p = q;
         }
+
         k++;
       }
+
       if (i + 1 < length) {
         code.push(q = {
           children: [],
@@ -106,143 +137,184 @@ var JpegImage = function JpegImageClosure() {
         p = q;
       }
     }
+
     return code[0].children;
   }
+
   function getBlockBufferOffset(component, row, col) {
     return 64 * ((component.blocksPerLine + 1) * row + col);
   }
+
   function decodeScan(data, offset, frame, components, resetInterval, spectralStart, spectralEnd, successivePrev, successive) {
     var parseDNLMarker = arguments.length > 9 && arguments[9] !== undefined ? arguments[9] : false;
-
     var mcusPerLine = frame.mcusPerLine;
     var progressive = frame.progressive;
     var startOffset = offset,
         bitsData = 0,
         bitsCount = 0;
+
     function readBit() {
       if (bitsCount > 0) {
         bitsCount--;
         return bitsData >> bitsCount & 1;
       }
+
       bitsData = data[offset++];
+
       if (bitsData === 0xFF) {
         var nextByte = data[offset++];
+
         if (nextByte) {
           if (nextByte === 0xDC && parseDNLMarker) {
             offset += 2;
             var scanLines = data[offset++] << 8 | data[offset++];
+
             if (scanLines > 0 && scanLines !== frame.scanLines) {
               throw new DNLMarkerError('Found DNL marker (0xFFDC) while parsing scan data', scanLines);
             }
+          } else if (nextByte === 0xD9) {
+            throw new EOIMarkerError('Found EOI marker (0xFFD9) while parsing scan data');
           }
-          throw new JpegError('unexpected marker ' + (bitsData << 8 | nextByte).toString(16));
+
+          throw new JpegError("unexpected marker ".concat((bitsData << 8 | nextByte).toString(16)));
         }
       }
+
       bitsCount = 7;
       return bitsData >>> 7;
     }
+
     function decodeHuffman(tree) {
       var node = tree;
+
       while (true) {
         node = node[readBit()];
+
         if (typeof node === 'number') {
           return node;
         }
-        if ((typeof node === 'undefined' ? 'undefined' : _typeof(node)) !== 'object') {
+
+        if (_typeof(node) !== 'object') {
           throw new JpegError('invalid huffman sequence');
         }
       }
     }
+
     function receive(length) {
       var n = 0;
+
       while (length > 0) {
         n = n << 1 | readBit();
         length--;
       }
+
       return n;
     }
+
     function receiveAndExtend(length) {
       if (length === 1) {
         return readBit() === 1 ? 1 : -1;
       }
+
       var n = receive(length);
+
       if (n >= 1 << length - 1) {
         return n;
       }
+
       return n + (-1 << length) + 1;
     }
+
     function decodeBaseline(component, offset) {
       var t = decodeHuffman(component.huffmanTableDC);
       var diff = t === 0 ? 0 : receiveAndExtend(t);
       component.blockData[offset] = component.pred += diff;
       var k = 1;
+
       while (k < 64) {
         var rs = decodeHuffman(component.huffmanTableAC);
         var s = rs & 15,
             r = rs >> 4;
+
         if (s === 0) {
           if (r < 15) {
             break;
           }
+
           k += 16;
           continue;
         }
+
         k += r;
         var z = dctZigZag[k];
         component.blockData[offset + z] = receiveAndExtend(s);
         k++;
       }
     }
+
     function decodeDCFirst(component, offset) {
       var t = decodeHuffman(component.huffmanTableDC);
       var diff = t === 0 ? 0 : receiveAndExtend(t) << successive;
       component.blockData[offset] = component.pred += diff;
     }
+
     function decodeDCSuccessive(component, offset) {
       component.blockData[offset] |= readBit() << successive;
     }
+
     var eobrun = 0;
+
     function decodeACFirst(component, offset) {
       if (eobrun > 0) {
         eobrun--;
         return;
       }
+
       var k = spectralStart,
           e = spectralEnd;
+
       while (k <= e) {
         var rs = decodeHuffman(component.huffmanTableAC);
         var s = rs & 15,
             r = rs >> 4;
+
         if (s === 0) {
           if (r < 15) {
             eobrun = receive(r) + (1 << r) - 1;
             break;
           }
+
           k += 16;
           continue;
         }
+
         k += r;
         var z = dctZigZag[k];
         component.blockData[offset + z] = receiveAndExtend(s) * (1 << successive);
         k++;
       }
     }
+
     var successiveACState = 0,
         successiveACNextValue;
+
     function decodeACSuccessive(component, offset) {
       var k = spectralStart;
       var e = spectralEnd;
       var r = 0;
       var s;
       var rs;
+
       while (k <= e) {
         var offsetZ = offset + dctZigZag[k];
         var sign = component.blockData[offsetZ] < 0 ? -1 : 1;
+
         switch (successiveACState) {
           case 0:
             rs = decodeHuffman(component.huffmanTableAC);
             s = rs & 15;
             r = rs >> 4;
+
             if (s === 0) {
               if (r < 15) {
                 eobrun = receive(r) + (1 << r);
@@ -255,21 +327,27 @@ var JpegImage = function JpegImageClosure() {
               if (s !== 1) {
                 throw new JpegError('invalid ACn encoding');
               }
+
               successiveACNextValue = receiveAndExtend(s);
               successiveACState = r ? 2 : 3;
             }
+
             continue;
+
           case 1:
           case 2:
             if (component.blockData[offsetZ]) {
               component.blockData[offsetZ] += sign * (readBit() << successive);
             } else {
               r--;
+
               if (r === 0) {
                 successiveACState = successiveACState === 2 ? 3 : 0;
               }
             }
+
             break;
+
           case 3:
             if (component.blockData[offsetZ]) {
               component.blockData[offsetZ] += sign * (readBit() << successive);
@@ -277,22 +355,29 @@ var JpegImage = function JpegImageClosure() {
               component.blockData[offsetZ] = successiveACNextValue << successive;
               successiveACState = 0;
             }
+
             break;
+
           case 4:
             if (component.blockData[offsetZ]) {
               component.blockData[offsetZ] += sign * (readBit() << successive);
             }
+
             break;
         }
+
         k++;
       }
+
       if (successiveACState === 4) {
         eobrun--;
+
         if (eobrun === 0) {
           successiveACState = 0;
         }
       }
     }
+
     function decodeMcu(component, decode, mcu, row, col) {
       var mcuRow = mcu / mcusPerLine | 0;
       var mcuCol = mcu % mcusPerLine;
@@ -301,15 +386,18 @@ var JpegImage = function JpegImageClosure() {
       var offset = getBlockBufferOffset(component, blockRow, blockCol);
       decode(component, offset);
     }
+
     function decodeBlock(component, decode, mcu) {
       var blockRow = mcu / component.blocksPerLine | 0;
       var blockCol = mcu % component.blocksPerLine;
       var offset = getBlockBufferOffset(component, blockRow, blockCol);
       decode(component, offset);
     }
+
     var componentsLength = components.length;
     var component, i, j, k, n;
     var decodeFn;
+
     if (progressive) {
       if (spectralStart === 0) {
         decodeFn = successivePrev === 0 ? decodeDCFirst : decodeDCSuccessive;
@@ -319,23 +407,31 @@ var JpegImage = function JpegImageClosure() {
     } else {
       decodeFn = decodeBaseline;
     }
+
     var mcu = 0,
         fileMarker;
     var mcuExpected;
+
     if (componentsLength === 1) {
       mcuExpected = components[0].blocksPerLine * components[0].blocksPerColumn;
     } else {
       mcuExpected = mcusPerLine * frame.mcusPerColumn;
     }
+
     var h, v;
+
     while (mcu < mcuExpected) {
       var mcuToRead = resetInterval ? Math.min(mcuExpected - mcu, resetInterval) : mcuExpected;
+
       for (i = 0; i < componentsLength; i++) {
         components[i].pred = 0;
       }
+
       eobrun = 0;
+
       if (componentsLength === 1) {
         component = components[0];
+
         for (n = 0; n < mcuToRead; n++) {
           decodeBlock(component, decodeFn, mcu);
           mcu++;
@@ -346,47 +442,60 @@ var JpegImage = function JpegImageClosure() {
             component = components[i];
             h = component.h;
             v = component.v;
+
             for (j = 0; j < v; j++) {
               for (k = 0; k < h; k++) {
                 decodeMcu(component, decodeFn, mcu, j, k);
               }
             }
           }
+
           mcu++;
         }
       }
+
       bitsCount = 0;
       fileMarker = findNextFileMarker(data, offset);
+
       if (fileMarker && fileMarker.invalid) {
         (0, _util.warn)('decodeScan - unexpected MCU data, current marker is: ' + fileMarker.invalid);
         offset = fileMarker.offset;
       }
+
       var marker = fileMarker && fileMarker.marker;
+
       if (!marker || marker <= 0xFF00) {
         throw new JpegError('marker was not found');
       }
+
       if (marker >= 0xFFD0 && marker <= 0xFFD7) {
         offset += 2;
       } else {
         break;
       }
     }
+
     fileMarker = findNextFileMarker(data, offset);
+
     if (fileMarker && fileMarker.invalid) {
       (0, _util.warn)('decodeScan - unexpected Scan data, current marker is: ' + fileMarker.invalid);
       offset = fileMarker.offset;
     }
+
     return offset - startOffset;
   }
+
   function quantizeAndInverse(component, blockBufferOffset, p) {
     var qt = component.quantizationTable,
         blockData = component.blockData;
     var v0, v1, v2, v3, v4, v5, v6, v7;
     var p0, p1, p2, p3, p4, p5, p6, p7;
     var t;
+
     if (!qt) {
       throw new JpegError('missing required Quantization Table.');
     }
+
     for (var row = 0; row < 64; row += 8) {
       p0 = blockData[blockBufferOffset + row];
       p1 = blockData[blockBufferOffset + row + 1];
@@ -397,6 +506,7 @@ var JpegImage = function JpegImageClosure() {
       p6 = blockData[blockBufferOffset + row + 6];
       p7 = blockData[blockBufferOffset + row + 7];
       p0 *= qt[row];
+
       if ((p1 | p2 | p3 | p4 | p5 | p6 | p7) === 0) {
         t = dctSqrt2 * p0 + 512 >> 10;
         p[row] = t;
@@ -409,6 +519,7 @@ var JpegImage = function JpegImageClosure() {
         p[row + 7] = t;
         continue;
       }
+
       p1 *= qt[row + 1];
       p2 *= qt[row + 2];
       p3 *= qt[row + 3];
@@ -452,6 +563,7 @@ var JpegImage = function JpegImageClosure() {
       p[row + 3] = v3 + v4;
       p[row + 4] = v3 - v4;
     }
+
     for (var col = 0; col < 8; ++col) {
       p0 = p[col];
       p1 = p[col + 8];
@@ -461,6 +573,7 @@ var JpegImage = function JpegImageClosure() {
       p5 = p[col + 40];
       p6 = p[col + 48];
       p7 = p[col + 56];
+
       if ((p1 | p2 | p3 | p4 | p5 | p6 | p7) === 0) {
         t = dctSqrt2 * p0 + 8192 >> 14;
         t = t < -2040 ? 0 : t >= 2024 ? 255 : t + 2056 >> 4;
@@ -474,6 +587,7 @@ var JpegImage = function JpegImageClosure() {
         blockData[blockBufferOffset + col + 56] = t;
         continue;
       }
+
       v0 = dctSqrt2 * p0 + 2048 >> 12;
       v1 = dctSqrt2 * p4 + 2048 >> 12;
       v2 = p2;
@@ -527,30 +641,38 @@ var JpegImage = function JpegImageClosure() {
       blockData[blockBufferOffset + col + 56] = p7;
     }
   }
+
   function buildComponentData(frame, component) {
     var blocksPerLine = component.blocksPerLine;
     var blocksPerColumn = component.blocksPerColumn;
     var computationBuffer = new Int16Array(64);
+
     for (var blockRow = 0; blockRow < blocksPerColumn; blockRow++) {
       for (var blockCol = 0; blockCol < blocksPerLine; blockCol++) {
         var offset = getBlockBufferOffset(component, blockRow, blockCol);
         quantizeAndInverse(component, offset, computationBuffer);
       }
     }
+
     return component.blockData;
   }
+
   function findNextFileMarker(data, currentPos) {
     var startPos = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : currentPos;
 
     function peekUint16(pos) {
       return data[pos] << 8 | data[pos + 1];
     }
+
     var maxPos = data.length - 1;
     var newPos = startPos < currentPos ? startPos : currentPos;
+
     if (currentPos >= maxPos) {
       return null;
     }
+
     var currentMarker = peekUint16(currentPos);
+
     if (currentMarker >= 0xFFC0 && currentMarker <= 0xFFFE) {
       return {
         invalid: null,
@@ -558,45 +680,55 @@ var JpegImage = function JpegImageClosure() {
         offset: currentPos
       };
     }
+
     var newMarker = peekUint16(newPos);
+
     while (!(newMarker >= 0xFFC0 && newMarker <= 0xFFFE)) {
       if (++newPos >= maxPos) {
         return null;
       }
+
       newMarker = peekUint16(newPos);
     }
+
     return {
       invalid: currentMarker.toString(16),
       marker: newMarker,
       offset: newPos
     };
   }
+
   JpegImage.prototype = {
     parse: function parse(data) {
-      var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
-          _ref$dnlScanLines = _ref.dnlScanLines,
-          dnlScanLines = _ref$dnlScanLines === undefined ? null : _ref$dnlScanLines;
+      var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
+          _ref2$dnlScanLines = _ref2.dnlScanLines,
+          dnlScanLines = _ref2$dnlScanLines === void 0 ? null : _ref2$dnlScanLines;
 
       function readUint16() {
         var value = data[offset] << 8 | data[offset + 1];
         offset += 2;
         return value;
       }
+
       function readDataBlock() {
         var length = readUint16();
         var endOffset = offset + length - 2;
         var fileMarker = findNextFileMarker(data, endOffset, offset);
+
         if (fileMarker && fileMarker.invalid) {
           (0, _util.warn)('readDataBlock - incorrect length, current marker is: ' + fileMarker.invalid);
           endOffset = fileMarker.offset;
         }
+
         var array = data.subarray(offset, endOffset);
         offset += array.length;
         return array;
       }
+
       function prepareComponents(frame) {
         var mcusPerLine = Math.ceil(frame.samplesPerLine / 8 / frame.maxH);
         var mcusPerColumn = Math.ceil(frame.scanLines / 8 / frame.maxV);
+
         for (var i = 0; i < frame.components.length; i++) {
           component = frame.components[i];
           var blocksPerLine = Math.ceil(Math.ceil(frame.samplesPerLine / 8) * component.h / frame.maxH);
@@ -608,9 +740,11 @@ var JpegImage = function JpegImageClosure() {
           component.blocksPerLine = blocksPerLine;
           component.blocksPerColumn = blocksPerColumn;
         }
+
         frame.mcusPerLine = mcusPerLine;
         frame.mcusPerColumn = mcusPerColumn;
       }
+
       var offset = 0;
       var jfif = null;
       var adobe = null;
@@ -620,12 +754,16 @@ var JpegImage = function JpegImageClosure() {
       var huffmanTablesAC = [],
           huffmanTablesDC = [];
       var fileMarker = readUint16();
+
       if (fileMarker !== 0xFFD8) {
         throw new JpegError('SOI not found');
       }
+
       fileMarker = readUint16();
-      while (fileMarker !== 0xFFD9) {
+
+      markerLoop: while (fileMarker !== 0xFFD9) {
         var i, j, l;
+
         switch (fileMarker) {
           case 0xFFE0:
           case 0xFFE1:
@@ -645,6 +783,7 @@ var JpegImage = function JpegImageClosure() {
           case 0xFFEF:
           case 0xFFFE:
             var appData = readDataBlock();
+
             if (fileMarker === 0xFFE0) {
               if (appData[0] === 0x4A && appData[1] === 0x46 && appData[2] === 0x49 && appData[3] === 0x46 && appData[4] === 0) {
                 jfif = {
@@ -661,6 +800,7 @@ var JpegImage = function JpegImageClosure() {
                 };
               }
             }
+
             if (fileMarker === 0xFFEE) {
               if (appData[0] === 0x41 && appData[1] === 0x64 && appData[2] === 0x6F && appData[3] === 0x62 && appData[4] === 0x65) {
                 adobe = {
@@ -671,14 +811,18 @@ var JpegImage = function JpegImageClosure() {
                 };
               }
             }
+
             break;
+
           case 0xFFDB:
             var quantizationTablesLength = readUint16();
             var quantizationTablesEnd = quantizationTablesLength + offset - 2;
             var z;
+
             while (offset < quantizationTablesEnd) {
               var quantizationTableSpec = data[offset++];
               var tableData = new Uint16Array(64);
+
               if (quantizationTableSpec >> 4 === 0) {
                 for (j = 0; j < 64; j++) {
                   z = dctZigZag[j];
@@ -692,15 +836,19 @@ var JpegImage = function JpegImageClosure() {
               } else {
                 throw new JpegError('DQT - invalid table spec');
               }
+
               quantizationTables[quantizationTableSpec & 15] = tableData;
             }
+
             break;
+
           case 0xFFC0:
           case 0xFFC1:
           case 0xFFC2:
             if (frame) {
               throw new JpegError('Only single frame JPEGs supported');
             }
+
             readUint16();
             frame = {};
             frame.extended = fileMarker === 0xFFC1;
@@ -715,16 +863,20 @@ var JpegImage = function JpegImageClosure() {
                 componentId;
             var maxH = 0,
                 maxV = 0;
+
             for (i = 0; i < componentsCount; i++) {
               componentId = data[offset];
               var h = data[offset + 1] >> 4;
               var v = data[offset + 1] & 15;
+
               if (maxH < h) {
                 maxH = h;
               }
+
               if (maxV < v) {
                 maxV = v;
               }
+
               var qId = data[offset + 2];
               l = frame.components.push({
                 h: h,
@@ -735,37 +887,48 @@ var JpegImage = function JpegImageClosure() {
               frame.componentIds[componentId] = l - 1;
               offset += 3;
             }
+
             frame.maxH = maxH;
             frame.maxV = maxV;
             prepareComponents(frame);
             break;
+
           case 0xFFC4:
             var huffmanLength = readUint16();
+
             for (i = 2; i < huffmanLength;) {
               var huffmanTableSpec = data[offset++];
               var codeLengths = new Uint8Array(16);
               var codeLengthSum = 0;
+
               for (j = 0; j < 16; j++, offset++) {
                 codeLengthSum += codeLengths[j] = data[offset];
               }
+
               var huffmanValues = new Uint8Array(codeLengthSum);
+
               for (j = 0; j < codeLengthSum; j++, offset++) {
                 huffmanValues[j] = data[offset];
               }
+
               i += 17 + codeLengthSum;
               (huffmanTableSpec >> 4 === 0 ? huffmanTablesDC : huffmanTablesAC)[huffmanTableSpec & 15] = buildHuffmanTable(codeLengths, huffmanValues);
             }
+
             break;
+
           case 0xFFDD:
             readUint16();
             resetInterval = readUint16();
             break;
+
           case 0xFFDA:
             var parseDNLMarker = ++numSOSMarkers === 1 && !dnlScanLines;
             readUint16();
             var selectorsCount = data[offset++];
             var components = [],
                 component;
+
             for (i = 0; i < selectorsCount; i++) {
               var componentIndex = frame.componentIds[data[offset++]];
               component = frame.components[componentIndex];
@@ -774,54 +937,75 @@ var JpegImage = function JpegImageClosure() {
               component.huffmanTableAC = huffmanTablesAC[tableSpec & 15];
               components.push(component);
             }
+
             var spectralStart = data[offset++];
             var spectralEnd = data[offset++];
             var successiveApproximation = data[offset++];
+
             try {
               var processed = decodeScan(data, offset, frame, components, resetInterval, spectralStart, spectralEnd, successiveApproximation >> 4, successiveApproximation & 15, parseDNLMarker);
               offset += processed;
             } catch (ex) {
               if (ex instanceof DNLMarkerError) {
-                (0, _util.warn)('Attempting to re-parse JPEG image using "scanLines" ' + 'parameter found in DNL marker (0xFFDC) segment.');
-                return this.parse(data, { dnlScanLines: ex.scanLines });
+                (0, _util.warn)("".concat(ex.message, " -- attempting to re-parse the JPEG image."));
+                return this.parse(data, {
+                  dnlScanLines: ex.scanLines
+                });
+              } else if (ex instanceof EOIMarkerError) {
+                (0, _util.warn)("".concat(ex.message, " -- ignoring the rest of the image data."));
+                break markerLoop;
               }
+
               throw ex;
             }
+
             break;
+
           case 0xFFDC:
             offset += 4;
             break;
+
           case 0xFFFF:
             if (data[offset] !== 0xFF) {
               offset--;
             }
+
             break;
+
           default:
             if (data[offset - 3] === 0xFF && data[offset - 2] >= 0xC0 && data[offset - 2] <= 0xFE) {
               offset -= 3;
               break;
             }
+
             var nextFileMarker = findNextFileMarker(data, offset - 2);
+
             if (nextFileMarker && nextFileMarker.invalid) {
               (0, _util.warn)('JpegImage.parse - unexpected data, current marker is: ' + nextFileMarker.invalid);
               offset = nextFileMarker.offset;
               break;
             }
+
             throw new JpegError('unknown marker ' + fileMarker.toString(16));
         }
+
         fileMarker = readUint16();
       }
+
       this.width = frame.samplesPerLine;
       this.height = frame.scanLines;
       this.jfif = jfif;
       this.adobe = adobe;
       this.components = [];
+
       for (i = 0; i < frame.components.length; i++) {
         component = frame.components[i];
         var quantizationTable = quantizationTables[component.quantizationId];
+
         if (quantizationTable) {
           component.quantizationTable = quantizationTable;
         }
+
         this.components.push({
           output: buildComponentData(frame, component),
           scaleX: component.h / frame.maxH,
@@ -830,10 +1014,11 @@ var JpegImage = function JpegImageClosure() {
           blocksPerColumn: component.blocksPerColumn
         });
       }
+
       this.numComponents = this.components.length;
     },
-
-    _getLinearizedBlockData: function getLinearizedBlockData(width, height) {
+    _getLinearizedBlockData: function _getLinearizedBlockData(width, height) {
+      var isSourcePDF = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
       var scaleX = this.width / width,
           scaleY = this.height / height;
       var component, componentScaleX, componentScaleY, blocksPerScanline;
@@ -846,6 +1031,7 @@ var JpegImage = function JpegImageClosure() {
       var data = new Uint8ClampedArray(dataLength);
       var xScaleBlockOffset = new Uint32Array(width);
       var mask3LSB = 0xfffffff8;
+
       for (i = 0; i < numComponents; i++) {
         component = this.components[i];
         componentScaleX = component.scaleX * scaleX;
@@ -853,20 +1039,29 @@ var JpegImage = function JpegImageClosure() {
         offset = i;
         output = component.output;
         blocksPerScanline = component.blocksPerLine + 1 << 3;
+
         for (x = 0; x < width; x++) {
           j = 0 | x * componentScaleX;
           xScaleBlockOffset[x] = (j & mask3LSB) << 3 | j & 7;
         }
+
         for (y = 0; y < height; y++) {
           j = 0 | y * componentScaleY;
           index = blocksPerScanline * (j & mask3LSB) | (j & 7) << 3;
+
           for (x = 0; x < width; x++) {
             data[offset] = output[index + xScaleBlockOffset[x]];
             offset += numComponents;
           }
         }
       }
-      var transform = this.decodeTransform;
+
+      var transform = this._decodeTransform;
+
+      if (!isSourcePDF && numComponents === 4 && !transform) {
+        transform = new Int32Array([-256, 255, -256, 255, -256, 255, -256, 255]);
+      }
+
       if (transform) {
         for (i = 0; i < dataLength;) {
           for (j = 0, k = 0; j < numComponents; j++, i++, k += 2) {
@@ -874,26 +1069,33 @@ var JpegImage = function JpegImageClosure() {
           }
         }
       }
+
       return data;
     },
-    _isColorConversionNeeded: function _isColorConversionNeeded() {
+
+    get _isColorConversionNeeded() {
       if (this.adobe) {
         return !!this.adobe.transformCode;
       }
+
       if (this.numComponents === 3) {
-        if (this.colorTransform === 0) {
+        if (this._colorTransform === 0) {
           return false;
         }
+
         return true;
       }
-      if (this.colorTransform === 1) {
+
+      if (this._colorTransform === 1) {
         return true;
       }
+
       return false;
     },
 
     _convertYccToRgb: function convertYccToRgb(data) {
       var Y, Cb, Cr;
+
       for (var i = 0, length = data.length; i < length; i += 3) {
         Y = data[i];
         Cb = data[i + 1];
@@ -902,11 +1104,13 @@ var JpegImage = function JpegImageClosure() {
         data[i + 1] = Y + 135.459 - 0.344 * Cb - 0.714 * Cr;
         data[i + 2] = Y - 226.816 + 1.772 * Cb;
       }
+
       return data;
     },
     _convertYcckToRgb: function convertYcckToRgb(data) {
       var Y, Cb, Cr, k;
       var offset = 0;
+
       for (var i = 0, length = data.length; i < length; i += 4) {
         Y = data[i];
         Cb = data[i + 1];
@@ -916,10 +1120,12 @@ var JpegImage = function JpegImageClosure() {
         data[offset++] = 107.268039397724 + Cb * (2.19927104525741e-5 * Cb - 0.000640992018297945 * Cr + 0.000659397001245577 * Y + 0.000426105652938837 * k - 0.176491792462875) + Cr * (-0.000778269941513683 * Cr + 0.00130872261408275 * Y + 0.000770482631801132 * k - 0.151051492775562) + Y * (0.00126935368114843 * Y - 0.00265090189010898 * k + 0.25802910206845) + k * (-0.000318913117588328 * k - 0.213742400323665);
         data[offset++] = -20.810012546947 + Cb * (-0.000570115196973677 * Cb - 2.63409051004589e-5 * Cr + 0.0020741088115012 * Y - 0.00288260236853442 * k + 0.814272968359295) + Cr * (-1.53496057440975e-5 * Cr - 0.000132689043961446 * Y + 0.000560833691242812 * k - 0.195152027534049) + Y * (0.00174418132927582 * Y - 0.00255243321439347 * k + 0.116935020465145) + k * (-0.000343531996510555 * k + 0.24165260232407);
       }
+
       return data.subarray(0, offset);
     },
     _convertYcckToCmyk: function convertYcckToCmyk(data) {
       var Y, Cb, Cr;
+
       for (var i = 0, length = data.length; i < length; i += 4) {
         Y = data[i];
         Cb = data[i + 1];
@@ -928,12 +1134,14 @@ var JpegImage = function JpegImageClosure() {
         data[i + 1] = 119.541 - Y + 0.344 * Cb + 0.714 * Cr;
         data[i + 2] = 481.816 - Y - 1.772 * Cb;
       }
+
       return data;
     },
     _convertCmykToRgb: function convertCmykToRgb(data) {
       var c, m, y, k;
       var offset = 0;
       var scale = 1 / 255;
+
       for (var i = 0, length = data.length; i < length; i += 4) {
         c = data[i] * scale;
         m = data[i + 1] * scale;
@@ -943,39 +1151,54 @@ var JpegImage = function JpegImageClosure() {
         data[offset++] = 255 + c * (8.841041422036149 * c + 60.118027045597366 * m + 6.871425592049007 * y + 31.159100130055922 * k - 79.2970844816548) + m * (-15.310361306967817 * m + 17.575251261109482 * y + 131.35250912493976 * k - 190.9453302588951) + y * (4.444339102852739 * y + 9.8632861493405 * k - 24.86741582555878) - k * (20.737325471181034 * k + 187.80453709719578);
         data[offset++] = 255 + c * (0.8842522430003296 * c + 8.078677503112928 * m + 30.89978309703729 * y - 0.23883238689178934 * k - 14.183576799673286) + m * (10.49593273432072 * m + 63.02378494754052 * y + 50.606957656360734 * k - 112.23884253719248) + y * (0.03296041114873217 * y + 115.60384449646641 * k - 193.58209356861505) - k * (22.33816807309886 * k + 180.12613974708367);
       }
+
       return data.subarray(0, offset);
     },
-    getData: function getData(width, height, forceRGBoutput) {
+    getData: function getData(_ref3) {
+      var width = _ref3.width,
+          height = _ref3.height,
+          _ref3$forceRGB = _ref3.forceRGB,
+          forceRGB = _ref3$forceRGB === void 0 ? false : _ref3$forceRGB,
+          _ref3$isSourcePDF = _ref3.isSourcePDF,
+          isSourcePDF = _ref3$isSourcePDF === void 0 ? false : _ref3$isSourcePDF;
+
       if (this.numComponents > 4) {
         throw new JpegError('Unsupported color mode');
       }
-      var data = this._getLinearizedBlockData(width, height);
-      if (this.numComponents === 1 && forceRGBoutput) {
+
+      var data = this._getLinearizedBlockData(width, height, isSourcePDF);
+
+      if (this.numComponents === 1 && forceRGB) {
         var dataLength = data.length;
         var rgbData = new Uint8ClampedArray(dataLength * 3);
         var offset = 0;
+
         for (var i = 0; i < dataLength; i++) {
           var grayColor = data[i];
           rgbData[offset++] = grayColor;
           rgbData[offset++] = grayColor;
           rgbData[offset++] = grayColor;
         }
+
         return rgbData;
-      } else if (this.numComponents === 3 && this._isColorConversionNeeded()) {
+      } else if (this.numComponents === 3 && this._isColorConversionNeeded) {
         return this._convertYccToRgb(data);
       } else if (this.numComponents === 4) {
-        if (this._isColorConversionNeeded()) {
-          if (forceRGBoutput) {
+        if (this._isColorConversionNeeded) {
+          if (forceRGB) {
             return this._convertYcckToRgb(data);
           }
+
           return this._convertYcckToCmyk(data);
-        } else if (forceRGBoutput) {
+        } else if (forceRGB) {
           return this._convertCmykToRgb(data);
         }
       }
+
       return data;
     }
   };
   return JpegImage;
 }();
+
 exports.JpegImage = JpegImage;

File diff suppressed because it is too large
+ 216 - 6
lib/core/jpx.js


+ 18 - 6
lib/core/jpx_stream.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,18 +19,18 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.JpxStream = undefined;
+exports.JpxStream = void 0;
 
-var _stream = require('./stream');
+var _stream = require("./stream");
 
-var _jpx = require('./jpx');
+var _jpx = require("./jpx");
 
-var _util = require('../shared/util');
+var _util = require("../shared/util");
 
 var JpxStream = function JpxStreamClosure() {
   function JpxStream(stream, maybeLength, dict, params) {
@@ -38,8 +38,10 @@ var JpxStream = function JpxStreamClosure() {
     this.maybeLength = maybeLength;
     this.dict = dict;
     this.params = params;
+
     _stream.DecodeStream.call(this, maybeLength);
   }
+
   JpxStream.prototype = Object.create(_stream.DecodeStream.prototype);
   Object.defineProperty(JpxStream.prototype, 'bytes', {
     get: function JpxStream_bytes() {
@@ -47,21 +49,26 @@ var JpxStream = function JpxStreamClosure() {
     },
     configurable: true
   });
+
   JpxStream.prototype.ensureBuffer = function (requested) {};
+
   JpxStream.prototype.readBlock = function () {
     if (this.eof) {
       return;
     }
+
     var jpxImage = new _jpx.JpxImage();
     jpxImage.parse(this.bytes);
     var width = jpxImage.width;
     var height = jpxImage.height;
     var componentsCount = jpxImage.componentsCount;
     var tileCount = jpxImage.tiles.length;
+
     if (tileCount === 1) {
       this.buffer = jpxImage.tiles[0].items;
     } else {
       var data = new Uint8ClampedArray(width * height * componentsCount);
+
       for (var k = 0; k < tileCount; k++) {
         var tileComponents = jpxImage.tiles[k];
         var tileWidth = tileComponents.width;
@@ -73,6 +80,7 @@ var JpxStream = function JpxStreamClosure() {
         var dataPosition = (width * tileTop + tileLeft) * componentsCount;
         var imgRowSize = width * componentsCount;
         var tileRowSize = tileWidth * componentsCount;
+
         for (var j = 0; j < tileHeight; j++) {
           var rowBytes = src.subarray(srcPosition, srcPosition + tileRowSize);
           data.set(rowBytes, dataPosition);
@@ -80,11 +88,15 @@ var JpxStream = function JpxStreamClosure() {
           dataPosition += imgRowSize;
         }
       }
+
       this.buffer = data;
     }
+
     this.bufferLength = this.buffer.length;
     this.eof = true;
   };
+
   return JpxStream;
 }();
+
 exports.JpxStream = JpxStream;

+ 4 - 4
lib/core/metrics.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,14 +19,14 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.getMetrics = undefined;
+exports.getMetrics = void 0;
 
-var _util = require('../shared/util');
+var _util = require("../shared/util");
 
 var getMetrics = (0, _util.getLookupTableFactory)(function (t) {
   t['Courier'] = 600;

+ 24 - 6
lib/core/murmurhash3.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,32 +19,36 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.MurmurHash3_64 = undefined;
+exports.MurmurHash3_64 = void 0;
 
-var _util = require('../shared/util');
+var _util = require("../shared/util");
 
 var MurmurHash3_64 = function MurmurHash3_64Closure(seed) {
   var MASK_HIGH = 0xffff0000;
   var MASK_LOW = 0xffff;
+
   function MurmurHash3_64(seed) {
     var SEED = 0xc3d2e1f0;
     this.h1 = seed ? seed & 0xffffffff : SEED;
     this.h2 = seed ? seed & 0xffffffff : SEED;
   }
+
   MurmurHash3_64.prototype = {
     update: function MurmurHash3_64_update(input) {
-      var data = void 0,
-          length = void 0;
+      var data, length;
+
       if ((0, _util.isString)(input)) {
         data = new Uint8Array(input.length * 2);
         length = 0;
+
         for (var i = 0, ii = input.length; i < ii; i++) {
           var code = input.charCodeAt(i);
+
           if (code <= 0xff) {
             data[length++] = code;
           } else {
@@ -58,6 +62,7 @@ var MurmurHash3_64 = function MurmurHash3_64Closure(seed) {
       } else {
         throw new Error('Wrong data format in MurmurHash3_64_update. ' + 'Input must be a string or array.');
       }
+
       var blockCounts = length >> 2;
       var tailLength = length - blockCounts * 4;
       var dataUint32 = new Uint32Array(data.buffer, 0, blockCounts);
@@ -69,6 +74,7 @@ var MurmurHash3_64 = function MurmurHash3_64Closure(seed) {
       var C2 = 0x1b873593;
       var C1_LOW = C1 & MASK_LOW;
       var C2_LOW = C2 & MASK_LOW;
+
       for (var _i = 0; _i < blockCounts; _i++) {
         if (_i & 1) {
           k1 = dataUint32[_i];
@@ -88,23 +94,30 @@ var MurmurHash3_64 = function MurmurHash3_64Closure(seed) {
           h2 = h2 * 5 + 0xe6546b64;
         }
       }
+
       k1 = 0;
+
       switch (tailLength) {
         case 3:
           k1 ^= data[blockCounts * 4 + 2] << 16;
+
         case 2:
           k1 ^= data[blockCounts * 4 + 1] << 8;
+
         case 1:
           k1 ^= data[blockCounts * 4];
           k1 = k1 * C1 & MASK_HIGH | k1 * C1_LOW & MASK_LOW;
           k1 = k1 << 15 | k1 >>> 17;
           k1 = k1 * C2 & MASK_HIGH | k1 * C2_LOW & MASK_LOW;
+
           if (blockCounts & 1) {
             h1 ^= k1;
           } else {
             h2 ^= k1;
           }
+
       }
+
       this.h1 = h1;
       this.h2 = h2;
       return this;
@@ -119,16 +132,21 @@ var MurmurHash3_64 = function MurmurHash3_64Closure(seed) {
       h1 = h1 * 0x1a85ec53 & MASK_HIGH | h1 * 0xec53 & MASK_LOW;
       h2 = h2 * 0xc4ceb9fe & MASK_HIGH | ((h2 << 16 | h1 >>> 16) * 0xb9fe1a85 & MASK_HIGH) >>> 16;
       h1 ^= h2 >>> 1;
+
       for (var i = 0, arr = [h1, h2], str = ''; i < arr.length; i++) {
         var hex = (arr[i] >>> 0).toString(16);
+
         while (hex.length < 8) {
           hex = '0' + hex;
         }
+
         str += hex;
       }
+
       return str;
     }
   };
   return MurmurHash3_64;
 }();
+
 exports.MurmurHash3_64 = MurmurHash3_64;

File diff suppressed because it is too large
+ 694 - 377
lib/core/obj.js


+ 108 - 6
lib/core/operator_list.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,53 +19,65 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.OperatorList = undefined;
+exports.OperatorList = void 0;
 
-var _util = require('../shared/util');
+var _util = require("../shared/util");
 
 var QueueOptimizer = function QueueOptimizerClosure() {
   function addState(parentState, pattern, checkFn, iterateFn, processFn) {
     var state = parentState;
+
     for (var i = 0, ii = pattern.length - 1; i < ii; i++) {
       var item = pattern[i];
       state = state[item] || (state[item] = []);
     }
+
     state[pattern[pattern.length - 1]] = {
       checkFn: checkFn,
       iterateFn: iterateFn,
       processFn: processFn
     };
   }
+
   function handlePaintSolidColorImageMask(iFirstSave, count, fnArray, argsArray) {
     var iFirstPIMXO = iFirstSave + 2;
+
     for (var i = 0; i < count; i++) {
       var arg = argsArray[iFirstPIMXO + 4 * i];
       var imageMask = arg.length === 1 && arg[0];
+
       if (imageMask && imageMask.width === 1 && imageMask.height === 1 && (!imageMask.data.length || imageMask.data.length === 1 && imageMask.data[0] === 0)) {
         fnArray[iFirstPIMXO + 4 * i] = _util.OPS.paintSolidColorImageMask;
         continue;
       }
+
       break;
     }
+
     return count - i;
   }
+
   var InitialState = [];
   addState(InitialState, [_util.OPS.save, _util.OPS.transform, _util.OPS.paintInlineImageXObject, _util.OPS.restore], null, function iterateInlineImageGroup(context, i) {
     var fnArray = context.fnArray;
     var iFirstSave = context.iCurr - 3;
     var pos = (i - iFirstSave) % 4;
+
     switch (pos) {
       case 0:
         return fnArray[i] === _util.OPS.save;
+
       case 1:
         return fnArray[i] === _util.OPS.transform;
+
       case 2:
         return fnArray[i] === _util.OPS.paintInlineImageXObject;
+
       case 3:
         return fnArray[i] === _util.OPS.restore;
     }
@@ -81,24 +93,29 @@ var QueueOptimizer = function QueueOptimizerClosure() {
     var iFirstTransform = curr - 2;
     var iFirstPIIXO = curr - 1;
     var count = Math.min(Math.floor((i - iFirstSave) / 4), MAX_IMAGES_IN_INLINE_IMAGES_BLOCK);
+
     if (count < MIN_IMAGES_IN_INLINE_IMAGES_BLOCK) {
       return i - (i - iFirstSave) % 4;
     }
+
     var maxX = 0;
     var map = [],
         maxLineHeight = 0;
     var currentX = IMAGE_PADDING,
         currentY = IMAGE_PADDING;
     var q;
+
     for (q = 0; q < count; q++) {
       var transform = argsArray[iFirstTransform + (q << 2)];
       var img = argsArray[iFirstPIIXO + (q << 2)][0];
+
       if (currentX + img.width > MAX_WIDTH) {
         maxX = Math.max(maxX, currentX);
         currentY += maxLineHeight + 2 * IMAGE_PADDING;
         currentX = 0;
         maxLineHeight = 0;
       }
+
       map.push({
         transform: transform,
         x: currentX,
@@ -109,22 +126,27 @@ var QueueOptimizer = function QueueOptimizerClosure() {
       currentX += img.width + 2 * IMAGE_PADDING;
       maxLineHeight = Math.max(maxLineHeight, img.height);
     }
+
     var imgWidth = Math.max(maxX, currentX) + IMAGE_PADDING;
     var imgHeight = currentY + maxLineHeight + IMAGE_PADDING;
-    var imgData = new Uint8Array(imgWidth * imgHeight * 4);
+    var imgData = new Uint8ClampedArray(imgWidth * imgHeight * 4);
     var imgRowSize = imgWidth << 2;
+
     for (q = 0; q < count; q++) {
       var data = argsArray[iFirstPIIXO + (q << 2)][0].data;
       var rowSize = map[q].w << 2;
       var dataOffset = 0;
       var offset = map[q].x + map[q].y * imgWidth << 2;
       imgData.set(data.subarray(0, rowSize), offset - imgRowSize);
+
       for (var k = 0, kk = map[q].h; k < kk; k++) {
         imgData.set(data.subarray(dataOffset, dataOffset + rowSize), offset);
         dataOffset += rowSize;
         offset += imgRowSize;
       }
+
       imgData.set(data.subarray(dataOffset - rowSize, dataOffset), offset);
+
       while (offset >= 0) {
         data[offset - 4] = data[offset];
         data[offset - 3] = data[offset + 1];
@@ -137,6 +159,7 @@ var QueueOptimizer = function QueueOptimizerClosure() {
         offset -= imgRowSize;
       }
     }
+
     fnArray.splice(iFirstSave, count * 4, _util.OPS.paintInlineImageXObjectGroup);
     argsArray.splice(iFirstSave, count * 4, [{
       width: imgWidth,
@@ -150,13 +173,17 @@ var QueueOptimizer = function QueueOptimizerClosure() {
     var fnArray = context.fnArray;
     var iFirstSave = context.iCurr - 3;
     var pos = (i - iFirstSave) % 4;
+
     switch (pos) {
       case 0:
         return fnArray[i] === _util.OPS.save;
+
       case 1:
         return fnArray[i] === _util.OPS.transform;
+
       case 2:
         return fnArray[i] === _util.OPS.paintImageMaskXObject;
+
       case 3:
         return fnArray[i] === _util.OPS.restore;
     }
@@ -172,45 +199,55 @@ var QueueOptimizer = function QueueOptimizerClosure() {
     var iFirstPIMXO = curr - 1;
     var count = Math.floor((i - iFirstSave) / 4);
     count = handlePaintSolidColorImageMask(iFirstSave, count, fnArray, argsArray);
+
     if (count < MIN_IMAGES_IN_MASKS_BLOCK) {
       return i - (i - iFirstSave) % 4;
     }
+
     var q;
     var isSameImage = false;
     var iTransform, transformArgs;
     var firstPIMXOArg0 = argsArray[iFirstPIMXO][0];
+
     if (argsArray[iFirstTransform][1] === 0 && argsArray[iFirstTransform][2] === 0) {
       isSameImage = true;
       var firstTransformArg0 = argsArray[iFirstTransform][0];
       var firstTransformArg3 = argsArray[iFirstTransform][3];
       iTransform = iFirstTransform + 4;
       var iPIMXO = iFirstPIMXO + 4;
+
       for (q = 1; q < count; q++, iTransform += 4, iPIMXO += 4) {
         transformArgs = argsArray[iTransform];
+
         if (argsArray[iPIMXO][0] !== firstPIMXOArg0 || transformArgs[0] !== firstTransformArg0 || transformArgs[1] !== 0 || transformArgs[2] !== 0 || transformArgs[3] !== firstTransformArg3) {
           if (q < MIN_IMAGES_IN_MASKS_BLOCK) {
             isSameImage = false;
           } else {
             count = q;
           }
+
           break;
         }
       }
     }
+
     if (isSameImage) {
       count = Math.min(count, MAX_SAME_IMAGES_IN_MASKS_BLOCK);
       var positions = new Float32Array(count * 2);
       iTransform = iFirstTransform;
+
       for (q = 0; q < count; q++, iTransform += 4) {
         transformArgs = argsArray[iTransform];
         positions[q << 1] = transformArgs[4];
         positions[(q << 1) + 1] = transformArgs[5];
       }
+
       fnArray.splice(iFirstSave, count * 4, _util.OPS.paintImageMaskXObjectRepeat);
       argsArray.splice(iFirstSave, count * 4, [firstPIMXOArg0, firstTransformArg0, firstTransformArg3, positions]);
     } else {
       count = Math.min(count, MAX_IMAGES_IN_MASKS_BLOCK);
       var images = [];
+
       for (q = 0; q < count; q++) {
         transformArgs = argsArray[iFirstTransform + (q << 2)];
         var maskParams = argsArray[iFirstPIMXO + (q << 2)][0];
@@ -221,9 +258,11 @@ var QueueOptimizer = function QueueOptimizerClosure() {
           transform: transformArgs
         });
       }
+
       fnArray.splice(iFirstSave, count * 4, _util.OPS.paintImageMaskXObjectGroup);
       argsArray.splice(iFirstSave, count * 4, [images]);
     }
+
     return iFirstSave + 1;
   });
   addState(InitialState, [_util.OPS.save, _util.OPS.transform, _util.OPS.paintImageXObject, _util.OPS.restore], function (context) {
@@ -235,30 +274,40 @@ var QueueOptimizer = function QueueOptimizerClosure() {
         argsArray = context.argsArray;
     var iFirstSave = context.iCurr - 3;
     var pos = (i - iFirstSave) % 4;
+
     switch (pos) {
       case 0:
         return fnArray[i] === _util.OPS.save;
+
       case 1:
         if (fnArray[i] !== _util.OPS.transform) {
           return false;
         }
+
         var iFirstTransform = context.iCurr - 2;
         var firstTransformArg0 = argsArray[iFirstTransform][0];
         var firstTransformArg3 = argsArray[iFirstTransform][3];
+
         if (argsArray[i][0] !== firstTransformArg0 || argsArray[i][1] !== 0 || argsArray[i][2] !== 0 || argsArray[i][3] !== firstTransformArg3) {
           return false;
         }
+
         return true;
+
       case 2:
         if (fnArray[i] !== _util.OPS.paintImageXObject) {
           return false;
         }
+
         var iFirstPIXO = context.iCurr - 1;
         var firstPIXOArg0 = argsArray[iFirstPIXO][0];
+
         if (argsArray[i][0] !== firstPIXOArg0) {
           return false;
         }
+
         return true;
+
       case 3:
         return fnArray[i] === _util.OPS.restore;
     }
@@ -275,16 +324,20 @@ var QueueOptimizer = function QueueOptimizerClosure() {
     var firstTransformArg0 = argsArray[iFirstTransform][0];
     var firstTransformArg3 = argsArray[iFirstTransform][3];
     var count = Math.min(Math.floor((i - iFirstSave) / 4), MAX_IMAGES_IN_BLOCK);
+
     if (count < MIN_IMAGES_IN_BLOCK) {
       return i - (i - iFirstSave) % 4;
     }
+
     var positions = new Float32Array(count * 2);
     var iTransform = iFirstTransform;
+
     for (var q = 0; q < count; q++, iTransform += 4) {
       var transformArgs = argsArray[iTransform];
       positions[q << 1] = transformArgs[4];
       positions[(q << 1) + 1] = transformArgs[5];
     }
+
     var args = [firstPIXOArg0, firstTransformArg0, firstTransformArg3, positions];
     fnArray.splice(iFirstSave, count * 4, _util.OPS.paintImageXObjectRepeat);
     argsArray.splice(iFirstSave, count * 4, args);
@@ -295,24 +348,32 @@ var QueueOptimizer = function QueueOptimizerClosure() {
         argsArray = context.argsArray;
     var iFirstSave = context.iCurr - 4;
     var pos = (i - iFirstSave) % 5;
+
     switch (pos) {
       case 0:
         return fnArray[i] === _util.OPS.beginText;
+
       case 1:
         return fnArray[i] === _util.OPS.setFont;
+
       case 2:
         return fnArray[i] === _util.OPS.setTextMatrix;
+
       case 3:
         if (fnArray[i] !== _util.OPS.showText) {
           return false;
         }
+
         var iFirstSetFont = context.iCurr - 3;
         var firstSetFontArg0 = argsArray[iFirstSetFont][0];
         var firstSetFontArg1 = argsArray[iFirstSetFont][1];
+
         if (argsArray[i][0] !== firstSetFontArg0 || argsArray[i][1] !== firstSetFontArg1) {
           return false;
         }
+
         return true;
+
       case 4:
         return fnArray[i] === _util.OPS.endText;
     }
@@ -330,22 +391,29 @@ var QueueOptimizer = function QueueOptimizerClosure() {
     var firstSetFontArg0 = argsArray[iFirstSetFont][0];
     var firstSetFontArg1 = argsArray[iFirstSetFont][1];
     var count = Math.min(Math.floor((i - iFirstBeginText) / 5), MAX_CHARS_IN_BLOCK);
+
     if (count < MIN_CHARS_IN_BLOCK) {
       return i - (i - iFirstBeginText) % 5;
     }
+
     var iFirst = iFirstBeginText;
+
     if (iFirstBeginText >= 4 && fnArray[iFirstBeginText - 4] === fnArray[iFirstSetFont] && fnArray[iFirstBeginText - 3] === fnArray[iFirstSetTextMatrix] && fnArray[iFirstBeginText - 2] === fnArray[iFirstShowText] && fnArray[iFirstBeginText - 1] === fnArray[iFirstEndText] && argsArray[iFirstBeginText - 4][0] === firstSetFontArg0 && argsArray[iFirstBeginText - 4][1] === firstSetFontArg1) {
       count++;
       iFirst -= 5;
     }
+
     var iEndText = iFirst + 4;
+
     for (var q = 1; q < count; q++) {
       fnArray.splice(iEndText, 3);
       argsArray.splice(iEndText, 3);
       iEndText += 2;
     }
+
     return iEndText + 1;
   });
+
   function QueueOptimizer(queue) {
     this.queue = queue;
     this.state = null;
@@ -357,6 +425,7 @@ var QueueOptimizer = function QueueOptimizerClosure() {
     this.match = null;
     this.lastProcessed = 0;
   }
+
   QueueOptimizer.prototype = {
     _optimize: function _optimize() {
       var fnArray = this.queue.fnArray;
@@ -364,40 +433,52 @@ var QueueOptimizer = function QueueOptimizerClosure() {
           ii = fnArray.length;
       var state = this.state;
       var match = this.match;
+
       if (!state && !match && i + 1 === ii && !InitialState[fnArray[i]]) {
         this.lastProcessed = ii;
         return;
       }
+
       var context = this.context;
+
       while (i < ii) {
         if (match) {
           var iterate = (0, match.iterateFn)(context, i);
+
           if (iterate) {
             i++;
             continue;
           }
+
           i = (0, match.processFn)(context, i + 1);
           ii = fnArray.length;
           match = null;
           state = null;
+
           if (i >= ii) {
             break;
           }
         }
+
         state = (state || InitialState)[fnArray[i]];
+
         if (!state || Array.isArray(state)) {
           i++;
           continue;
         }
+
         context.iCurr = i;
         i++;
+
         if (state.checkFn && !(0, state.checkFn)(context)) {
           state = null;
           continue;
         }
+
         match = state;
         state = null;
       }
+
       this.state = state;
       this.match = match;
       this.lastProcessed = i;
@@ -405,6 +486,7 @@ var QueueOptimizer = function QueueOptimizerClosure() {
     push: function push(fn, args) {
       this.queue.fnArray.push(fn);
       this.queue.argsArray.push(args);
+
       this._optimize();
     },
     flush: function flush() {
@@ -413,6 +495,7 @@ var QueueOptimizer = function QueueOptimizerClosure() {
         this.lastProcessed = (0, this.match.processFn)(this.context, length);
         this.match = null;
         this.state = null;
+
         this._optimize();
       }
     },
@@ -424,10 +507,12 @@ var QueueOptimizer = function QueueOptimizerClosure() {
   };
   return QueueOptimizer;
 }();
+
 var NullOptimizer = function NullOptimizerClosure() {
   function NullOptimizer(queue) {
     this.queue = queue;
   }
+
   NullOptimizer.prototype = {
     push: function push(fn, args) {
       this.queue.fnArray.push(fn);
@@ -437,52 +522,66 @@ var NullOptimizer = function NullOptimizerClosure() {
   };
   return NullOptimizer;
 }();
+
 var OperatorList = function OperatorListClosure() {
   var CHUNK_SIZE = 1000;
   var CHUNK_SIZE_ABOUT = CHUNK_SIZE - 5;
+
   function getTransfers(queue) {
     var transfers = [];
     var fnArray = queue.fnArray,
         argsArray = queue.argsArray;
+
     for (var i = 0, ii = queue.length; i < ii; i++) {
       switch (fnArray[i]) {
         case _util.OPS.paintInlineImageXObject:
         case _util.OPS.paintInlineImageXObjectGroup:
         case _util.OPS.paintImageMaskXObject:
           var arg = argsArray[i][0];
+          ;
+
           if (!arg.cached) {
             transfers.push(arg.data.buffer);
           }
+
           break;
       }
     }
+
     return transfers;
   }
+
   function OperatorList(intent, messageHandler, pageIndex) {
     this.messageHandler = messageHandler;
     this.fnArray = [];
     this.argsArray = [];
+
     if (messageHandler && this.intent !== 'oplist') {
       this.optimizer = new QueueOptimizer(this);
     } else {
       this.optimizer = new NullOptimizer(this);
     }
+
     this.dependencies = Object.create(null);
     this._totalLength = 0;
     this.pageIndex = pageIndex;
     this.intent = intent;
     this.weight = 0;
   }
+
   OperatorList.prototype = {
     get length() {
       return this.argsArray.length;
     },
+
     get totalLength() {
       return this._totalLength + this.length;
     },
+
     addOp: function addOp(fn, args) {
       this.optimizer.push(fn, args);
       this.weight++;
+
       if (this.messageHandler) {
         if (this.weight >= CHUNK_SIZE) {
           this.flush();
@@ -495,6 +594,7 @@ var OperatorList = function OperatorListClosure() {
       if (dependency in this.dependencies) {
         return;
       }
+
       this.dependencies[dependency] = true;
       this.addOp(_util.OPS.dependency, [dependency]);
     },
@@ -504,7 +604,8 @@ var OperatorList = function OperatorListClosure() {
       }
     },
     addOpList: function addOpList(opList) {
-      _util.Util.extendObj(this.dependencies, opList.dependencies);
+      Object.assign(this.dependencies, opList.dependencies);
+
       for (var i = 0, ii = opList.length; i < ii; i++) {
         this.addOp(opList.fnArray[i], opList.argsArray[i]);
       }
@@ -540,4 +641,5 @@ var OperatorList = function OperatorListClosure() {
   };
   return OperatorList;
 }();
+
 exports.OperatorList = OperatorList;

File diff suppressed because it is too large
+ 278 - 63
lib/core/parser.js


+ 145 - 13
lib/core/pattern.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,18 +19,19 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.getTilingPatternIR = exports.Pattern = undefined;
+exports.getTilingPatternIR = getTilingPatternIR;
+exports.Pattern = void 0;
 
-var _util = require('../shared/util');
+var _util = require("../shared/util");
 
-var _colorspace = require('./colorspace');
+var _colorspace = require("./colorspace");
 
-var _primitives = require('./primitives');
+var _primitives = require("./primitives");
 
 var ShadingType = {
   FUNCTION_BASED: 1,
@@ -41,28 +42,34 @@ var ShadingType = {
   COONS_PATCH_MESH: 6,
   TENSOR_PATCH_MESH: 7
 };
+
 var Pattern = function PatternClosure() {
   function Pattern() {
     (0, _util.unreachable)('should not call Pattern constructor');
   }
+
   Pattern.prototype = {
     getPattern: function Pattern_getPattern(ctx) {
-      (0, _util.unreachable)('Should not call Pattern.getStyle: ' + ctx);
+      (0, _util.unreachable)("Should not call Pattern.getStyle: ".concat(ctx));
     }
   };
+
   Pattern.parseShading = function (shading, matrix, xref, res, handler, pdfFunctionFactory) {
     var dict = (0, _primitives.isStream)(shading) ? shading.dict : shading;
     var type = dict.get('ShadingType');
+
     try {
       switch (type) {
         case ShadingType.AXIAL:
         case ShadingType.RADIAL:
           return new Shadings.RadialAxial(dict, matrix, xref, res, pdfFunctionFactory);
+
         case ShadingType.FREE_FORM_MESH:
         case ShadingType.LATTICE_FORM_MESH:
         case ShadingType.COONS_PATCH_MESH:
         case ShadingType.TENSOR_PATCH_MESH:
           return new Shadings.Mesh(shading, matrix, xref, res, pdfFunctionFactory);
+
         default:
           throw new _util.FormatError('Unsupported ShadingType: ' + type);
       }
@@ -70,15 +77,22 @@ var Pattern = function PatternClosure() {
       if (ex instanceof _util.MissingDataException) {
         throw ex;
       }
-      handler.send('UnsupportedFeature', { featureId: _util.UNSUPPORTED_FEATURES.shadingPattern });
+
+      handler.send('UnsupportedFeature', {
+        featureId: _util.UNSUPPORTED_FEATURES.shadingPattern
+      });
       (0, _util.warn)(ex);
       return new Shadings.Dummy();
     }
   };
+
   return Pattern;
 }();
+
+exports.Pattern = Pattern;
 var Shadings = {};
 Shadings.SMALL_NUMBER = 1e-6;
+
 Shadings.RadialAxial = function RadialAxialClosure() {
   function RadialAxial(dict, matrix, xref, res, pdfFunctionFactory) {
     this.matrix = matrix;
@@ -90,18 +104,22 @@ Shadings.RadialAxial = function RadialAxialClosure() {
     this.cs = cs;
     var t0 = 0.0,
         t1 = 1.0;
+
     if (dict.has('Domain')) {
       var domainArr = dict.getArray('Domain');
       t0 = domainArr[0];
       t1 = domainArr[1];
     }
+
     var extendStart = false,
         extendEnd = false;
+
     if (dict.has('Extend')) {
       var extendArr = dict.getArray('Extend');
       extendStart = extendArr[0];
       extendEnd = extendArr[1];
     }
+
     if (this.shadingType === ShadingType.RADIAL && (!extendStart || !extendEnd)) {
       var x1 = this.coordsArr[0];
       var y1 = this.coordsArr[1];
@@ -110,10 +128,12 @@ Shadings.RadialAxial = function RadialAxialClosure() {
       var y2 = this.coordsArr[4];
       var r2 = this.coordsArr[5];
       var distance = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
+
       if (r1 <= r2 + distance && r2 <= r1 + distance) {
         (0, _util.warn)('Unsupported radial gradient.');
       }
     }
+
     this.extendStart = extendStart;
     this.extendEnd = extendEnd;
     var fnObj = dict.get('Function');
@@ -121,40 +141,52 @@ Shadings.RadialAxial = function RadialAxialClosure() {
     var diff = t1 - t0;
     var step = diff / 10;
     var colorStops = this.colorStops = [];
+
     if (t0 >= t1 || step <= 0) {
       (0, _util.info)('Bad shading domain.');
       return;
     }
+
     var color = new Float32Array(cs.numComps),
         ratio = new Float32Array(1);
     var rgbColor;
+
     for (var i = t0; i <= t1; i += step) {
       ratio[0] = i;
       fn(ratio, 0, color, 0);
       rgbColor = cs.getRgb(color, 0);
+
       var cssColor = _util.Util.makeCssRgb(rgbColor[0], rgbColor[1], rgbColor[2]);
+
       colorStops.push([(i - t0) / diff, cssColor]);
     }
+
     var background = 'transparent';
+
     if (dict.has('Background')) {
       rgbColor = cs.getRgb(dict.get('Background'), 0);
       background = _util.Util.makeCssRgb(rgbColor[0], rgbColor[1], rgbColor[2]);
     }
+
     if (!extendStart) {
       colorStops.unshift([0, background]);
       colorStops[1][0] += Shadings.SMALL_NUMBER;
     }
+
     if (!extendEnd) {
       colorStops[colorStops.length - 1][0] -= Shadings.SMALL_NUMBER;
       colorStops.push([1, background]);
     }
+
     this.colorStops = colorStops;
   }
+
   RadialAxial.prototype = {
     getIR: function RadialAxial_getIR() {
       var coordsArr = this.coordsArr;
       var shadingType = this.shadingType;
       var type, p0, p1, r0, r1;
+
       if (shadingType === ShadingType.AXIAL) {
         p0 = [coordsArr[0], coordsArr[1]];
         p1 = [coordsArr[2], coordsArr[3]];
@@ -168,23 +200,29 @@ Shadings.RadialAxial = function RadialAxialClosure() {
         r1 = coordsArr[5];
         type = 'radial';
       } else {
-        (0, _util.unreachable)('getPattern type unknown: ' + shadingType);
+        (0, _util.unreachable)("getPattern type unknown: ".concat(shadingType));
       }
+
       var matrix = this.matrix;
+
       if (matrix) {
         p0 = _util.Util.applyTransform(p0, matrix);
         p1 = _util.Util.applyTransform(p1, matrix);
+
         if (shadingType === ShadingType.RADIAL) {
           var scale = _util.Util.singularValueDecompose2dScale(matrix);
+
           r0 *= scale[0];
           r1 *= scale[1];
         }
       }
+
       return ['RadialAxial', type, this.colorStops, p0, p1, r0, r1];
     }
   };
   return RadialAxial;
 }();
+
 Shadings.Mesh = function MeshClosure() {
   function MeshStreamReader(stream, context) {
     this.stream = stream;
@@ -196,41 +234,52 @@ Shadings.Mesh = function MeshClosure() {
     var csNumComps = context.colorSpace.numComps;
     this.tmpCsCompsBuf = context.colorFn ? new Float32Array(csNumComps) : this.tmpCompsBuf;
   }
+
   MeshStreamReader.prototype = {
     get hasData() {
       if (this.stream.end) {
         return this.stream.pos < this.stream.end;
       }
+
       if (this.bufferLength > 0) {
         return true;
       }
+
       var nextByte = this.stream.getByte();
+
       if (nextByte < 0) {
         return false;
       }
+
       this.buffer = nextByte;
       this.bufferLength = 8;
       return true;
     },
+
     readBits: function MeshStreamReader_readBits(n) {
       var buffer = this.buffer;
       var bufferLength = this.bufferLength;
+
       if (n === 32) {
         if (bufferLength === 0) {
           return (this.stream.getByte() << 24 | this.stream.getByte() << 16 | this.stream.getByte() << 8 | this.stream.getByte()) >>> 0;
         }
+
         buffer = buffer << 24 | this.stream.getByte() << 16 | this.stream.getByte() << 8 | this.stream.getByte();
         var nextByte = this.stream.getByte();
         this.buffer = nextByte & (1 << bufferLength) - 1;
         return (buffer << 8 - bufferLength | (nextByte & 0xFF) >> bufferLength) >>> 0;
       }
+
       if (n === 8 && bufferLength === 0) {
         return this.stream.getByte();
       }
+
       while (bufferLength < n) {
         buffer = buffer << 8 | this.stream.getByte();
         bufferLength += 8;
       }
+
       bufferLength -= n;
       this.bufferLength = bufferLength;
       this.buffer = buffer & (1 << bufferLength) - 1;
@@ -257,62 +306,77 @@ Shadings.Mesh = function MeshClosure() {
       var scale = bitsPerComponent < 32 ? 1 / ((1 << bitsPerComponent) - 1) : 2.3283064365386963e-10;
       var decode = this.context.decode;
       var components = this.tmpCompsBuf;
+
       for (var i = 0, j = 4; i < numComps; i++, j += 2) {
         var ci = this.readBits(bitsPerComponent);
         components[i] = ci * scale * (decode[j + 1] - decode[j]) + decode[j];
       }
+
       var color = this.tmpCsCompsBuf;
+
       if (this.context.colorFn) {
         this.context.colorFn(components, 0, color, 0);
       }
+
       return this.context.colorSpace.getRgb(color, 0);
     }
   };
+
   function decodeType4Shading(mesh, reader) {
     var coords = mesh.coords;
     var colors = mesh.colors;
     var operators = [];
     var ps = [];
     var verticesLeft = 0;
+
     while (reader.hasData) {
       var f = reader.readFlag();
       var coord = reader.readCoordinate();
       var color = reader.readComponents();
+
       if (verticesLeft === 0) {
         if (!(0 <= f && f <= 2)) {
           throw new _util.FormatError('Unknown type4 flag');
         }
+
         switch (f) {
           case 0:
             verticesLeft = 3;
             break;
+
           case 1:
             ps.push(ps[ps.length - 2], ps[ps.length - 1]);
             verticesLeft = 1;
             break;
+
           case 2:
             ps.push(ps[ps.length - 3], ps[ps.length - 1]);
             verticesLeft = 1;
             break;
         }
+
         operators.push(f);
       }
+
       ps.push(coords.length);
       coords.push(coord);
       colors.push(color);
       verticesLeft--;
       reader.align();
     }
+
     mesh.figures.push({
       type: 'triangles',
       coords: new Int32Array(ps),
       colors: new Int32Array(ps)
     });
   }
+
   function decodeType5Shading(mesh, reader, verticesPerRow) {
     var coords = mesh.coords;
     var colors = mesh.colors;
     var ps = [];
+
     while (reader.hasData) {
       var coord = reader.readCoordinate();
       var color = reader.readComponents();
@@ -320,6 +384,7 @@ Shadings.Mesh = function MeshClosure() {
       coords.push(coord);
       colors.push(color);
     }
+
     mesh.figures.push({
       type: 'lattice',
       coords: new Int32Array(ps),
@@ -327,27 +392,34 @@ Shadings.Mesh = function MeshClosure() {
       verticesPerRow: verticesPerRow
     });
   }
+
   var MIN_SPLIT_PATCH_CHUNKS_AMOUNT = 3;
   var MAX_SPLIT_PATCH_CHUNKS_AMOUNT = 20;
   var TRIANGLE_DENSITY = 20;
+
   var getB = function getBClosure() {
     function buildB(count) {
       var lut = [];
+
       for (var i = 0; i <= count; i++) {
         var t = i / count,
             t_ = 1 - t;
         lut.push(new Float32Array([t_ * t_ * t_, 3 * t * t_ * t_, 3 * t * t * t_, t * t * t]));
       }
+
       return lut;
     }
+
     var cache = [];
     return function getB(count) {
       if (!cache[count]) {
         cache[count] = buildB(count);
       }
+
       return cache[count];
     };
   }();
+
   function buildFigureFromPatch(mesh, index) {
     var figure = mesh.figures[index];
     (0, _util.assert)(figure.type === 'patch', 'Unexpected patch mesh figure');
@@ -375,6 +447,7 @@ Shadings.Mesh = function MeshClosure() {
         c3 = colors[ci[3]];
     var bRow = getB(splitYBy),
         bCol = getB(splitXBy);
+
     for (var row = 0; row <= splitYBy; row++) {
       cl[0] = (c0[0] * (splitYBy - row) + c2[0] * row) / splitYBy | 0;
       cl[1] = (c0[1] * (splitYBy - row) + c2[1] * row) / splitYBy | 0;
@@ -382,13 +455,16 @@ Shadings.Mesh = function MeshClosure() {
       cr[0] = (c1[0] * (splitYBy - row) + c3[0] * row) / splitYBy | 0;
       cr[1] = (c1[1] * (splitYBy - row) + c3[1] * row) / splitYBy | 0;
       cr[2] = (c1[2] * (splitYBy - row) + c3[2] * row) / splitYBy | 0;
+
       for (var col = 0; col <= splitXBy; col++, k++) {
         if ((row === 0 || row === splitYBy) && (col === 0 || col === splitXBy)) {
           continue;
         }
+
         var x = 0,
             y = 0;
         var q = 0;
+
         for (var i = 0; i <= 3; i++) {
           for (var j = 0; j <= 3; j++, q++) {
             var m = bRow[row][i] * bCol[col][j];
@@ -396,6 +472,7 @@ Shadings.Mesh = function MeshClosure() {
             y += coords[pi[q]][1] * m;
           }
         }
+
         figureCoords[k] = coords.length;
         coords.push([x, y]);
         figureColors[k] = colors.length;
@@ -406,6 +483,7 @@ Shadings.Mesh = function MeshClosure() {
         colors.push(newColor);
       }
     }
+
     figureCoords[0] = pi[0];
     figureColors[0] = ci[0];
     figureCoords[splitXBy] = pi[3];
@@ -421,26 +499,35 @@ Shadings.Mesh = function MeshClosure() {
       verticesPerRow: verticesPerRow
     };
   }
+
   function decodeType6Shading(mesh, reader) {
     var coords = mesh.coords;
     var colors = mesh.colors;
     var ps = new Int32Array(16);
     var cs = new Int32Array(4);
+
     while (reader.hasData) {
       var f = reader.readFlag();
+
       if (!(0 <= f && f <= 3)) {
         throw new _util.FormatError('Unknown type6 flag');
       }
+
       var i, ii;
       var pi = coords.length;
+
       for (i = 0, ii = f !== 0 ? 8 : 12; i < ii; i++) {
         coords.push(reader.readCoordinate());
       }
+
       var ci = colors.length;
+
       for (i = 0, ii = f !== 0 ? 2 : 4; i < ii; i++) {
         colors.push(reader.readComponents());
       }
+
       var tmp1, tmp2, tmp3, tmp4;
+
       switch (f) {
         case 0:
           ps[12] = pi + 3;
@@ -460,6 +547,7 @@ Shadings.Mesh = function MeshClosure() {
           cs[0] = ci;
           cs[1] = ci + 3;
           break;
+
         case 1:
           tmp1 = ps[12];
           tmp2 = ps[13];
@@ -484,6 +572,7 @@ Shadings.Mesh = function MeshClosure() {
           cs[0] = tmp1;
           cs[1] = ci + 1;
           break;
+
         case 2:
           tmp1 = ps[15];
           tmp2 = ps[11];
@@ -505,6 +594,7 @@ Shadings.Mesh = function MeshClosure() {
           cs[0] = tmp1;
           cs[1] = ci + 1;
           break;
+
         case 3:
           ps[12] = ps[0];
           ps[13] = pi + 0;
@@ -524,6 +614,7 @@ Shadings.Mesh = function MeshClosure() {
           cs[1] = ci + 1;
           break;
       }
+
       ps[5] = coords.length;
       coords.push([(-4 * coords[ps[0]][0] - coords[ps[15]][0] + 6 * (coords[ps[4]][0] + coords[ps[1]][0]) - 2 * (coords[ps[12]][0] + coords[ps[3]][0]) + 3 * (coords[ps[13]][0] + coords[ps[7]][0])) / 9, (-4 * coords[ps[0]][1] - coords[ps[15]][1] + 6 * (coords[ps[4]][1] + coords[ps[1]][1]) - 2 * (coords[ps[12]][1] + coords[ps[3]][1]) + 3 * (coords[ps[13]][1] + coords[ps[7]][1])) / 9]);
       ps[6] = coords.length;
@@ -539,26 +630,35 @@ Shadings.Mesh = function MeshClosure() {
       });
     }
   }
+
   function decodeType7Shading(mesh, reader) {
     var coords = mesh.coords;
     var colors = mesh.colors;
     var ps = new Int32Array(16);
     var cs = new Int32Array(4);
+
     while (reader.hasData) {
       var f = reader.readFlag();
+
       if (!(0 <= f && f <= 3)) {
         throw new _util.FormatError('Unknown type7 flag');
       }
+
       var i, ii;
       var pi = coords.length;
+
       for (i = 0, ii = f !== 0 ? 12 : 16; i < ii; i++) {
         coords.push(reader.readCoordinate());
       }
+
       var ci = colors.length;
+
       for (i = 0, ii = f !== 0 ? 2 : 4; i < ii; i++) {
         colors.push(reader.readComponents());
       }
+
       var tmp1, tmp2, tmp3, tmp4;
+
       switch (f) {
         case 0:
           ps[12] = pi + 3;
@@ -582,6 +682,7 @@ Shadings.Mesh = function MeshClosure() {
           cs[0] = ci;
           cs[1] = ci + 3;
           break;
+
         case 1:
           tmp1 = ps[12];
           tmp2 = ps[13];
@@ -610,6 +711,7 @@ Shadings.Mesh = function MeshClosure() {
           cs[0] = tmp1;
           cs[1] = ci + 1;
           break;
+
         case 2:
           tmp1 = ps[15];
           tmp2 = ps[11];
@@ -635,6 +737,7 @@ Shadings.Mesh = function MeshClosure() {
           cs[0] = tmp1;
           cs[1] = ci + 1;
           break;
+
         case 3:
           ps[12] = ps[0];
           ps[13] = pi + 0;
@@ -658,6 +761,7 @@ Shadings.Mesh = function MeshClosure() {
           cs[1] = ci + 1;
           break;
       }
+
       mesh.figures.push({
         type: 'patch',
         coords: new Int32Array(ps),
@@ -665,11 +769,13 @@ Shadings.Mesh = function MeshClosure() {
       });
     }
   }
+
   function updateBounds(mesh) {
     var minX = mesh.coords[0][0],
         minY = mesh.coords[0][1],
         maxX = minX,
         maxY = minY;
+
     for (var i = 1, ii = mesh.coords.length; i < ii; i++) {
       var x = mesh.coords[i][0],
           y = mesh.coords[i][1];
@@ -678,42 +784,52 @@ Shadings.Mesh = function MeshClosure() {
       maxX = maxX < x ? x : maxX;
       maxY = maxY < y ? y : maxY;
     }
+
     mesh.bounds = [minX, minY, maxX, maxY];
   }
+
   function packData(mesh) {
     var i, ii, j, jj;
     var coords = mesh.coords;
     var coordsPacked = new Float32Array(coords.length * 2);
+
     for (i = 0, j = 0, ii = coords.length; i < ii; i++) {
       var xy = coords[i];
       coordsPacked[j++] = xy[0];
       coordsPacked[j++] = xy[1];
     }
+
     mesh.coords = coordsPacked;
     var colors = mesh.colors;
     var colorsPacked = new Uint8Array(colors.length * 3);
+
     for (i = 0, j = 0, ii = colors.length; i < ii; i++) {
       var c = colors[i];
       colorsPacked[j++] = c[0];
       colorsPacked[j++] = c[1];
       colorsPacked[j++] = c[2];
     }
+
     mesh.colors = colorsPacked;
     var figures = mesh.figures;
+
     for (i = 0, ii = figures.length; i < ii; i++) {
       var figure = figures[i],
           ps = figure.coords,
           cs = figure.colors;
+
       for (j = 0, jj = ps.length; j < jj; j++) {
         ps[j] *= 2;
         cs[j] *= 3;
       }
     }
   }
+
   function Mesh(stream, matrix, xref, res, pdfFunctionFactory) {
     if (!(0, _primitives.isStream)(stream)) {
       throw new _util.FormatError('Mesh data is not a stream');
     }
+
     var dict = stream.dict;
     this.matrix = matrix;
     this.shadingType = dict.get('ShadingType');
@@ -739,38 +855,49 @@ Shadings.Mesh = function MeshClosure() {
     };
     var reader = new MeshStreamReader(stream, decodeContext);
     var patchMesh = false;
+
     switch (this.shadingType) {
       case ShadingType.FREE_FORM_MESH:
         decodeType4Shading(this, reader);
         break;
+
       case ShadingType.LATTICE_FORM_MESH:
         var verticesPerRow = dict.get('VerticesPerRow') | 0;
+
         if (verticesPerRow < 2) {
           throw new _util.FormatError('Invalid VerticesPerRow');
         }
+
         decodeType5Shading(this, reader, verticesPerRow);
         break;
+
       case ShadingType.COONS_PATCH_MESH:
         decodeType6Shading(this, reader);
         patchMesh = true;
         break;
+
       case ShadingType.TENSOR_PATCH_MESH:
         decodeType7Shading(this, reader);
         patchMesh = true;
         break;
+
       default:
         (0, _util.unreachable)('Unsupported mesh type.');
         break;
     }
+
     if (patchMesh) {
       updateBounds(this);
+
       for (var i = 0, ii = this.figures.length; i < ii; i++) {
         buildFigureFromPatch(this, i);
       }
     }
+
     updateBounds(this);
     packData(this);
   }
+
   Mesh.prototype = {
     getIR: function Mesh_getIR() {
       return ['Mesh', this.shadingType, this.coords, this.colors, this.figures, this.bounds, this.matrix, this.bbox, this.background];
@@ -778,10 +905,12 @@ Shadings.Mesh = function MeshClosure() {
   };
   return Mesh;
 }();
+
 Shadings.Dummy = function DummyClosure() {
   function Dummy() {
     this.type = 'Pattern';
   }
+
   Dummy.prototype = {
     getIR: function Dummy_getIR() {
       return ['Dummy'];
@@ -789,17 +918,20 @@ Shadings.Dummy = function DummyClosure() {
   };
   return Dummy;
 }();
+
 function getTilingPatternIR(operatorList, dict, args) {
   var matrix = dict.getArray('Matrix');
+
   var bbox = _util.Util.normalizeRect(dict.getArray('BBox'));
+
   var xstep = dict.get('XStep');
   var ystep = dict.get('YStep');
   var paintType = dict.get('PaintType');
   var tilingType = dict.get('TilingType');
+
   if (bbox[2] - bbox[0] === 0 || bbox[3] - bbox[1] === 0) {
-    throw new _util.FormatError('Invalid getTilingPatternIR /BBox array: [' + bbox + '].');
+    throw new _util.FormatError("Invalid getTilingPatternIR /BBox array: [".concat(bbox, "]."));
   }
+
   return ['TilingPattern', args, operatorList, matrix, bbox, xstep, ystep, paintType, tilingType];
-}
-exports.Pattern = Pattern;
-exports.getTilingPatternIR = getTilingPatternIR;
+}

+ 321 - 133
lib/core/pdf_manager.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,181 +19,369 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.NetworkPdfManager = exports.LocalPdfManager = undefined;
+exports.NetworkPdfManager = exports.LocalPdfManager = void 0;
 
-var _util = require('../shared/util');
+var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
 
-var _chunked_stream = require('./chunked_stream');
+var _util = require("../shared/util");
 
-var _document = require('./document');
+var _chunked_stream = require("./chunked_stream");
 
-var _stream = require('./stream');
+var _document = require("./document");
 
-var BasePdfManager = function BasePdfManagerClosure() {
+var _stream = require("./stream");
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
+
+function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
+
+function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
+
+function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
+
+function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
+
+function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
+
+function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
+
+function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
+
+var BasePdfManager =
+/*#__PURE__*/
+function () {
   function BasePdfManager() {
-    (0, _util.unreachable)('Cannot initialize BaseManagerManager');
+    _classCallCheck(this, BasePdfManager);
+
+    if (this.constructor === BasePdfManager) {
+      (0, _util.unreachable)('Cannot initialize BasePdfManager.');
+    }
   }
-  BasePdfManager.prototype = {
-    get docId() {
+
+  _createClass(BasePdfManager, [{
+    key: "onLoadedStream",
+    value: function onLoadedStream() {
+      (0, _util.unreachable)('Abstract method `onLoadedStream` called');
+    }
+  }, {
+    key: "ensureDoc",
+    value: function ensureDoc(prop, args) {
+      return this.ensure(this.pdfDocument, prop, args);
+    }
+  }, {
+    key: "ensureXRef",
+    value: function ensureXRef(prop, args) {
+      return this.ensure(this.pdfDocument.xref, prop, args);
+    }
+  }, {
+    key: "ensureCatalog",
+    value: function ensureCatalog(prop, args) {
+      return this.ensure(this.pdfDocument.catalog, prop, args);
+    }
+  }, {
+    key: "getPage",
+    value: function getPage(pageIndex) {
+      return this.pdfDocument.getPage(pageIndex);
+    }
+  }, {
+    key: "fontFallback",
+    value: function fontFallback(id, handler) {
+      return this.pdfDocument.fontFallback(id, handler);
+    }
+  }, {
+    key: "cleanup",
+    value: function cleanup() {
+      return this.pdfDocument.cleanup();
+    }
+  }, {
+    key: "ensure",
+    value: function () {
+      var _ensure = _asyncToGenerator(
+      /*#__PURE__*/
+      _regenerator.default.mark(function _callee(obj, prop, args) {
+        return _regenerator.default.wrap(function _callee$(_context) {
+          while (1) {
+            switch (_context.prev = _context.next) {
+              case 0:
+                (0, _util.unreachable)('Abstract method `ensure` called');
+
+              case 1:
+              case "end":
+                return _context.stop();
+            }
+          }
+        }, _callee, this);
+      }));
+
+      function ensure(_x, _x2, _x3) {
+        return _ensure.apply(this, arguments);
+      }
+
+      return ensure;
+    }()
+  }, {
+    key: "requestRange",
+    value: function requestRange(begin, end) {
+      (0, _util.unreachable)('Abstract method `requestRange` called');
+    }
+  }, {
+    key: "requestLoadedStream",
+    value: function requestLoadedStream() {
+      (0, _util.unreachable)('Abstract method `requestLoadedStream` called');
+    }
+  }, {
+    key: "sendProgressiveData",
+    value: function sendProgressiveData(chunk) {
+      (0, _util.unreachable)('Abstract method `sendProgressiveData` called');
+    }
+  }, {
+    key: "updatePassword",
+    value: function updatePassword(password) {
+      this._password = password;
+    }
+  }, {
+    key: "terminate",
+    value: function terminate() {
+      (0, _util.unreachable)('Abstract method `terminate` called');
+    }
+  }, {
+    key: "docId",
+    get: function get() {
       return this._docId;
-    },
-    get password() {
+    }
+  }, {
+    key: "password",
+    get: function get() {
       return this._password;
-    },
-    get docBaseUrl() {
+    }
+  }, {
+    key: "docBaseUrl",
+    get: function get() {
       var docBaseUrl = null;
+
       if (this._docBaseUrl) {
         var absoluteUrl = (0, _util.createValidAbsoluteUrl)(this._docBaseUrl);
+
         if (absoluteUrl) {
           docBaseUrl = absoluteUrl.href;
         } else {
-          (0, _util.warn)('Invalid absolute docBaseUrl: "' + this._docBaseUrl + '".');
+          (0, _util.warn)("Invalid absolute docBaseUrl: \"".concat(this._docBaseUrl, "\"."));
         }
       }
+
       return (0, _util.shadow)(this, 'docBaseUrl', docBaseUrl);
-    },
-    onLoadedStream: function BasePdfManager_onLoadedStream() {
-      throw new _util.NotImplementedException();
-    },
-    ensureDoc: function BasePdfManager_ensureDoc(prop, args) {
-      return this.ensure(this.pdfDocument, prop, args);
-    },
-    ensureXRef: function BasePdfManager_ensureXRef(prop, args) {
-      return this.ensure(this.pdfDocument.xref, prop, args);
-    },
-    ensureCatalog: function BasePdfManager_ensureCatalog(prop, args) {
-      return this.ensure(this.pdfDocument.catalog, prop, args);
-    },
-    getPage: function BasePdfManager_getPage(pageIndex) {
-      return this.pdfDocument.getPage(pageIndex);
-    },
-    cleanup: function BasePdfManager_cleanup() {
-      return this.pdfDocument.cleanup();
-    },
-    ensure: function BasePdfManager_ensure(obj, prop, args) {
-      return new _util.NotImplementedException();
-    },
-    requestRange: function BasePdfManager_requestRange(begin, end) {
-      return new _util.NotImplementedException();
-    },
-    requestLoadedStream: function BasePdfManager_requestLoadedStream() {
-      return new _util.NotImplementedException();
-    },
-    sendProgressiveData: function BasePdfManager_sendProgressiveData(chunk) {
-      return new _util.NotImplementedException();
-    },
-    updatePassword: function BasePdfManager_updatePassword(password) {
-      this._password = password;
-    },
-    terminate: function BasePdfManager_terminate() {
-      return new _util.NotImplementedException();
     }
-  };
+  }]);
+
   return BasePdfManager;
 }();
-var LocalPdfManager = function LocalPdfManagerClosure() {
+
+var LocalPdfManager =
+/*#__PURE__*/
+function (_BasePdfManager) {
+  _inherits(LocalPdfManager, _BasePdfManager);
+
   function LocalPdfManager(docId, data, password, evaluatorOptions, docBaseUrl) {
-    this._docId = docId;
-    this._password = password;
-    this._docBaseUrl = docBaseUrl;
-    this.evaluatorOptions = evaluatorOptions;
+    var _this;
+
+    _classCallCheck(this, LocalPdfManager);
+
+    _this = _possibleConstructorReturn(this, _getPrototypeOf(LocalPdfManager).call(this));
+    _this._docId = docId;
+    _this._password = password;
+    _this._docBaseUrl = docBaseUrl;
+    _this.evaluatorOptions = evaluatorOptions;
     var stream = new _stream.Stream(data);
-    this.pdfDocument = new _document.PDFDocument(this, stream);
-    this._loadedStreamCapability = (0, _util.createPromiseCapability)();
-    this._loadedStreamCapability.resolve(stream);
+    _this.pdfDocument = new _document.PDFDocument(_assertThisInitialized(_assertThisInitialized(_this)), stream);
+    _this._loadedStreamPromise = Promise.resolve(stream);
+    return _this;
   }
-  _util.Util.inherit(LocalPdfManager, BasePdfManager, {
-    ensure: function LocalPdfManager_ensure(obj, prop, args) {
-      return new Promise(function (resolve, reject) {
-        try {
-          var value = obj[prop];
-          var result;
-          if (typeof value === 'function') {
-            result = value.apply(obj, args);
-          } else {
-            result = value;
+
+  _createClass(LocalPdfManager, [{
+    key: "ensure",
+    value: function () {
+      var _ensure2 = _asyncToGenerator(
+      /*#__PURE__*/
+      _regenerator.default.mark(function _callee2(obj, prop, args) {
+        var value;
+        return _regenerator.default.wrap(function _callee2$(_context2) {
+          while (1) {
+            switch (_context2.prev = _context2.next) {
+              case 0:
+                value = obj[prop];
+
+                if (!(typeof value === 'function')) {
+                  _context2.next = 3;
+                  break;
+                }
+
+                return _context2.abrupt("return", value.apply(obj, args));
+
+              case 3:
+                return _context2.abrupt("return", value);
+
+              case 4:
+              case "end":
+                return _context2.stop();
+            }
           }
-          resolve(result);
-        } catch (e) {
-          reject(e);
-        }
-      });
-    },
-    requestRange: function LocalPdfManager_requestRange(begin, end) {
+        }, _callee2, this);
+      }));
+
+      function ensure(_x4, _x5, _x6) {
+        return _ensure2.apply(this, arguments);
+      }
+
+      return ensure;
+    }()
+  }, {
+    key: "requestRange",
+    value: function requestRange(begin, end) {
       return Promise.resolve();
-    },
-    requestLoadedStream: function LocalPdfManager_requestLoadedStream() {},
-    onLoadedStream: function LocalPdfManager_onLoadedStream() {
-      return this._loadedStreamCapability.promise;
-    },
-    terminate: function LocalPdfManager_terminate() {}
-  });
+    }
+  }, {
+    key: "requestLoadedStream",
+    value: function requestLoadedStream() {}
+  }, {
+    key: "onLoadedStream",
+    value: function onLoadedStream() {
+      return this._loadedStreamPromise;
+    }
+  }, {
+    key: "terminate",
+    value: function terminate() {}
+  }]);
+
   return LocalPdfManager;
-}();
-var NetworkPdfManager = function NetworkPdfManagerClosure() {
+}(BasePdfManager);
+
+exports.LocalPdfManager = LocalPdfManager;
+
+var NetworkPdfManager =
+/*#__PURE__*/
+function (_BasePdfManager2) {
+  _inherits(NetworkPdfManager, _BasePdfManager2);
+
   function NetworkPdfManager(docId, pdfNetworkStream, args, evaluatorOptions, docBaseUrl) {
-    this._docId = docId;
-    this._password = args.password;
-    this._docBaseUrl = docBaseUrl;
-    this.msgHandler = args.msgHandler;
-    this.evaluatorOptions = evaluatorOptions;
-    var params = {
+    var _this2;
+
+    _classCallCheck(this, NetworkPdfManager);
+
+    _this2 = _possibleConstructorReturn(this, _getPrototypeOf(NetworkPdfManager).call(this));
+    _this2._docId = docId;
+    _this2._password = args.password;
+    _this2._docBaseUrl = docBaseUrl;
+    _this2.msgHandler = args.msgHandler;
+    _this2.evaluatorOptions = evaluatorOptions;
+    _this2.streamManager = new _chunked_stream.ChunkedStreamManager(pdfNetworkStream, {
       msgHandler: args.msgHandler,
-      url: args.url,
       length: args.length,
       disableAutoFetch: args.disableAutoFetch,
       rangeChunkSize: args.rangeChunkSize
-    };
-    this.streamManager = new _chunked_stream.ChunkedStreamManager(pdfNetworkStream, params);
-    this.pdfDocument = new _document.PDFDocument(this, this.streamManager.getStream());
+    });
+    _this2.pdfDocument = new _document.PDFDocument(_assertThisInitialized(_assertThisInitialized(_this2)), _this2.streamManager.getStream());
+    return _this2;
   }
-  _util.Util.inherit(NetworkPdfManager, BasePdfManager, {
-    ensure: function NetworkPdfManager_ensure(obj, prop, args) {
-      var pdfManager = this;
-      return new Promise(function (resolve, reject) {
-        function ensureHelper() {
-          try {
-            var result;
-            var value = obj[prop];
-            if (typeof value === 'function') {
-              result = value.apply(obj, args);
-            } else {
-              result = value;
-            }
-            resolve(result);
-          } catch (e) {
-            if (!(e instanceof _util.MissingDataException)) {
-              reject(e);
-              return;
+
+  _createClass(NetworkPdfManager, [{
+    key: "ensure",
+    value: function () {
+      var _ensure3 = _asyncToGenerator(
+      /*#__PURE__*/
+      _regenerator.default.mark(function _callee3(obj, prop, args) {
+        var value;
+        return _regenerator.default.wrap(function _callee3$(_context3) {
+          while (1) {
+            switch (_context3.prev = _context3.next) {
+              case 0:
+                _context3.prev = 0;
+                value = obj[prop];
+
+                if (!(typeof value === 'function')) {
+                  _context3.next = 4;
+                  break;
+                }
+
+                return _context3.abrupt("return", value.apply(obj, args));
+
+              case 4:
+                return _context3.abrupt("return", value);
+
+              case 7:
+                _context3.prev = 7;
+                _context3.t0 = _context3["catch"](0);
+
+                if (_context3.t0 instanceof _util.MissingDataException) {
+                  _context3.next = 11;
+                  break;
+                }
+
+                throw _context3.t0;
+
+              case 11:
+                _context3.next = 13;
+                return this.requestRange(_context3.t0.begin, _context3.t0.end);
+
+              case 13:
+                return _context3.abrupt("return", this.ensure(obj, prop, args));
+
+              case 14:
+              case "end":
+                return _context3.stop();
             }
-            pdfManager.streamManager.requestRange(e.begin, e.end).then(ensureHelper, reject);
           }
-        }
-        ensureHelper();
-      });
-    },
-    requestRange: function NetworkPdfManager_requestRange(begin, end) {
+        }, _callee3, this, [[0, 7]]);
+      }));
+
+      function ensure(_x7, _x8, _x9) {
+        return _ensure3.apply(this, arguments);
+      }
+
+      return ensure;
+    }()
+  }, {
+    key: "requestRange",
+    value: function requestRange(begin, end) {
       return this.streamManager.requestRange(begin, end);
-    },
-    requestLoadedStream: function NetworkPdfManager_requestLoadedStream() {
+    }
+  }, {
+    key: "requestLoadedStream",
+    value: function requestLoadedStream() {
       this.streamManager.requestAllChunks();
-    },
-    sendProgressiveData: function NetworkPdfManager_sendProgressiveData(chunk) {
-      this.streamManager.onReceiveData({ chunk: chunk });
-    },
-    onLoadedStream: function NetworkPdfManager_onLoadedStream() {
+    }
+  }, {
+    key: "sendProgressiveData",
+    value: function sendProgressiveData(chunk) {
+      this.streamManager.onReceiveData({
+        chunk: chunk
+      });
+    }
+  }, {
+    key: "onLoadedStream",
+    value: function onLoadedStream() {
       return this.streamManager.onLoadedStream();
-    },
-    terminate: function NetworkPdfManager_terminate() {
+    }
+  }, {
+    key: "terminate",
+    value: function terminate() {
       this.streamManager.abort();
     }
-  });
+  }]);
+
   return NetworkPdfManager;
-}();
-exports.LocalPdfManager = LocalPdfManager;
+}(BasePdfManager);
+
 exports.NetworkPdfManager = NetworkPdfManager;

+ 75 - 22
lib/core/primitives.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,43 +19,66 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
+exports.isEOF = isEOF;
+exports.isCmd = isCmd;
+exports.isDict = isDict;
+exports.isName = isName;
+exports.isRef = isRef;
+exports.isRefsEqual = isRefsEqual;
+exports.isStream = isStream;
+exports.RefSetCache = exports.RefSet = exports.Ref = exports.Name = exports.Dict = exports.Cmd = exports.EOF = void 0;
 
-var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
+function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
 
 var EOF = {};
+exports.EOF = EOF;
+
 var Name = function NameClosure() {
   function Name(name) {
     this.name = name;
   }
+
   Name.prototype = {};
   var nameCache = Object.create(null);
+
   Name.get = function Name_get(name) {
     var nameValue = nameCache[name];
     return nameValue ? nameValue : nameCache[name] = new Name(name);
   };
+
   return Name;
 }();
+
+exports.Name = Name;
+
 var Cmd = function CmdClosure() {
   function Cmd(cmd) {
     this.cmd = cmd;
   }
+
   Cmd.prototype = {};
   var cmdCache = Object.create(null);
+
   Cmd.get = function Cmd_get(cmd) {
     var cmdValue = cmdCache[cmd];
     return cmdValue ? cmdValue : cmdCache[cmd] = new Cmd(cmd);
   };
+
   return Cmd;
 }();
+
+exports.Cmd = Cmd;
+
 var Dict = function DictClosure() {
   var nonSerializable = function nonSerializableClosure() {
     return nonSerializable;
   };
+
   function Dict(xref) {
     this._map = Object.create(null);
     this.xref = xref;
@@ -63,6 +86,7 @@ var Dict = function DictClosure() {
     this.suppressEncryption = false;
     this.__nonSerializable__ = nonSerializable;
   }
+
   Dict.prototype = {
     assignXref: function Dict_assignXref(newXref) {
       this.xref = newXref;
@@ -71,12 +95,15 @@ var Dict = function DictClosure() {
       var value;
       var xref = this.xref,
           suppressEncryption = this.suppressEncryption;
+
       if (typeof (value = this._map[key1]) !== 'undefined' || key1 in this._map || typeof key2 === 'undefined') {
         return xref ? xref.fetchIfRef(value, suppressEncryption) : value;
       }
+
       if (typeof (value = this._map[key2]) !== 'undefined' || key2 in this._map || typeof key3 === 'undefined') {
         return xref ? xref.fetchIfRef(value, suppressEncryption) : value;
       }
+
       value = this._map[key3] || null;
       return xref ? xref.fetchIfRef(value, suppressEncryption) : value;
     },
@@ -84,38 +111,50 @@ var Dict = function DictClosure() {
       var value;
       var xref = this.xref,
           suppressEncryption = this.suppressEncryption;
+
       if (typeof (value = this._map[key1]) !== 'undefined' || key1 in this._map || typeof key2 === 'undefined') {
         if (xref) {
           return xref.fetchIfRefAsync(value, suppressEncryption);
         }
+
         return Promise.resolve(value);
       }
+
       if (typeof (value = this._map[key2]) !== 'undefined' || key2 in this._map || typeof key3 === 'undefined') {
         if (xref) {
           return xref.fetchIfRefAsync(value, suppressEncryption);
         }
+
         return Promise.resolve(value);
       }
+
       value = this._map[key3] || null;
+
       if (xref) {
         return xref.fetchIfRefAsync(value, suppressEncryption);
       }
+
       return Promise.resolve(value);
     },
     getArray: function Dict_getArray(key1, key2, key3) {
       var value = this.get(key1, key2, key3);
       var xref = this.xref,
           suppressEncryption = this.suppressEncryption;
+
       if (!Array.isArray(value) || !xref) {
         return value;
       }
+
       value = value.slice();
+
       for (var i = 0, ii = value.length; i < ii; i++) {
         if (!isRef(value[i])) {
           continue;
         }
+
         value[i] = xref.fetch(value[i], suppressEncryption);
       }
+
       return value;
     },
     getRaw: function Dict_getRaw(key) {
@@ -137,44 +176,59 @@ var Dict = function DictClosure() {
     }
   };
   Dict.empty = new Dict(null);
+
   Dict.merge = function (xref, dictArray) {
     var mergedDict = new Dict(xref);
+
     for (var i = 0, ii = dictArray.length; i < ii; i++) {
       var dict = dictArray[i];
+
       if (!isDict(dict)) {
         continue;
       }
+
       for (var keyName in dict._map) {
         if (mergedDict._map[keyName] !== undefined) {
           continue;
         }
+
         mergedDict._map[keyName] = dict._map[keyName];
       }
     }
+
     return mergedDict;
   };
+
   return Dict;
 }();
+
+exports.Dict = Dict;
+
 var Ref = function RefClosure() {
   function Ref(num, gen) {
     this.num = num;
     this.gen = gen;
   }
+
   Ref.prototype = {
     toString: function Ref_toString() {
-      var str = this.num + 'R';
       if (this.gen !== 0) {
-        str += this.gen;
+        return "".concat(this.num, "R").concat(this.gen);
       }
-      return str;
+
+      return "".concat(this.num, "R");
     }
   };
   return Ref;
 }();
+
+exports.Ref = Ref;
+
 var RefSet = function RefSetClosure() {
   function RefSet() {
     this.dict = Object.create(null);
   }
+
   RefSet.prototype = {
     has: function RefSet_has(ref) {
       return ref.toString() in this.dict;
@@ -188,10 +242,14 @@ var RefSet = function RefSetClosure() {
   };
   return RefSet;
 }();
+
+exports.RefSet = RefSet;
+
 var RefSetCache = function RefSetCacheClosure() {
   function RefSetCache() {
     this.dict = Object.create(null);
   }
+
   RefSetCache.prototype = {
     get: function RefSetCache_get(ref) {
       return this.dict[ref.toString()];
@@ -216,38 +274,33 @@ var RefSetCache = function RefSetCacheClosure() {
   };
   return RefSetCache;
 }();
+
+exports.RefSetCache = RefSetCache;
+
 function isEOF(v) {
   return v === EOF;
 }
+
 function isName(v, name) {
   return v instanceof Name && (name === undefined || v.name === name);
 }
+
 function isCmd(v, cmd) {
   return v instanceof Cmd && (cmd === undefined || v.cmd === cmd);
 }
+
 function isDict(v, type) {
   return v instanceof Dict && (type === undefined || isName(v.get('Type'), type));
 }
+
 function isRef(v) {
   return v instanceof Ref;
 }
+
 function isRefsEqual(v1, v2) {
   return v1.num === v2.num && v1.gen === v2.gen;
 }
+
 function isStream(v) {
-  return (typeof v === 'undefined' ? 'undefined' : _typeof(v)) === 'object' && v !== null && v.getBytes !== undefined;
-}
-exports.EOF = EOF;
-exports.Cmd = Cmd;
-exports.Dict = Dict;
-exports.Name = Name;
-exports.Ref = Ref;
-exports.RefSet = RefSet;
-exports.RefSetCache = RefSetCache;
-exports.isEOF = isEOF;
-exports.isCmd = isCmd;
-exports.isDict = isDict;
-exports.isName = isName;
-exports.isRef = isRef;
-exports.isRefsEqual = isRefsEqual;
-exports.isStream = isStream;
+  return _typeof(v) === 'object' && v !== null && v.getBytes !== undefined;
+}

+ 134 - 45
lib/core/ps_parser.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,50 +19,72 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.PostScriptParser = exports.PostScriptLexer = undefined;
+exports.PostScriptParser = exports.PostScriptLexer = void 0;
 
-var _util = require('../shared/util');
+var _util = require("../shared/util");
 
-var _primitives = require('./primitives');
+var _primitives = require("./primitives");
 
-var PostScriptParser = function PostScriptParserClosure() {
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
+
+function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
+
+var PostScriptParser =
+/*#__PURE__*/
+function () {
   function PostScriptParser(lexer) {
+    _classCallCheck(this, PostScriptParser);
+
     this.lexer = lexer;
     this.operators = [];
     this.token = null;
     this.prev = null;
   }
-  PostScriptParser.prototype = {
-    nextToken: function PostScriptParser_nextToken() {
+
+  _createClass(PostScriptParser, [{
+    key: "nextToken",
+    value: function nextToken() {
       this.prev = this.token;
       this.token = this.lexer.getToken();
-    },
-    accept: function PostScriptParser_accept(type) {
+    }
+  }, {
+    key: "accept",
+    value: function accept(type) {
       if (this.token.type === type) {
         this.nextToken();
         return true;
       }
+
       return false;
-    },
-    expect: function PostScriptParser_expect(type) {
+    }
+  }, {
+    key: "expect",
+    value: function expect(type) {
       if (this.accept(type)) {
         return true;
       }
-      throw new _util.FormatError('Unexpected symbol: found ' + this.token.type + ' expected ' + type + '.');
-    },
-    parse: function PostScriptParser_parse() {
+
+      throw new _util.FormatError("Unexpected symbol: found ".concat(this.token.type, " expected ").concat(type, "."));
+    }
+  }, {
+    key: "parse",
+    value: function parse() {
       this.nextToken();
       this.expect(PostScriptTokenTypes.LBRACE);
       this.parseBlock();
       this.expect(PostScriptTokenTypes.RBRACE);
       return this.operators;
-    },
-    parseBlock: function PostScriptParser_parseBlock() {
+    }
+  }, {
+    key: "parseBlock",
+    value: function parseBlock() {
       while (true) {
         if (this.accept(PostScriptTokenTypes.NUMBER)) {
           this.operators.push(this.prev.value);
@@ -74,12 +96,15 @@ var PostScriptParser = function PostScriptParserClosure() {
           return;
         }
       }
-    },
-    parseCondition: function PostScriptParser_parseCondition() {
+    }
+  }, {
+    key: "parseCondition",
+    value: function parseCondition() {
       var conditionLocation = this.operators.length;
       this.operators.push(null, null);
       this.parseBlock();
       this.expect(PostScriptTokenTypes.RBRACE);
+
       if (this.accept(PostScriptTokenTypes.IF)) {
         this.operators[conditionLocation] = this.operators.length;
         this.operators[conditionLocation + 1] = 'jz';
@@ -98,9 +123,12 @@ var PostScriptParser = function PostScriptParserClosure() {
         throw new _util.FormatError('PS Function: error parsing conditional.');
       }
     }
-  };
+  }]);
+
   return PostScriptParser;
 }();
+
+exports.PostScriptParser = PostScriptParser;
 var PostScriptTokenTypes = {
   LBRACE: 0,
   RBRACE: 1,
@@ -109,42 +137,86 @@ var PostScriptTokenTypes = {
   IF: 4,
   IFELSE: 5
 };
+
 var PostScriptToken = function PostScriptTokenClosure() {
-  function PostScriptToken(type, value) {
-    this.type = type;
-    this.value = value;
-  }
   var opCache = Object.create(null);
-  PostScriptToken.getOperator = function PostScriptToken_getOperator(op) {
-    var opValue = opCache[op];
-    if (opValue) {
-      return opValue;
+
+  var PostScriptToken =
+  /*#__PURE__*/
+  function () {
+    function PostScriptToken(type, value) {
+      _classCallCheck(this, PostScriptToken);
+
+      this.type = type;
+      this.value = value;
     }
-    return opCache[op] = new PostScriptToken(PostScriptTokenTypes.OPERATOR, op);
-  };
-  PostScriptToken.LBRACE = new PostScriptToken(PostScriptTokenTypes.LBRACE, '{');
-  PostScriptToken.RBRACE = new PostScriptToken(PostScriptTokenTypes.RBRACE, '}');
-  PostScriptToken.IF = new PostScriptToken(PostScriptTokenTypes.IF, 'IF');
-  PostScriptToken.IFELSE = new PostScriptToken(PostScriptTokenTypes.IFELSE, 'IFELSE');
+
+    _createClass(PostScriptToken, null, [{
+      key: "getOperator",
+      value: function getOperator(op) {
+        var opValue = opCache[op];
+
+        if (opValue) {
+          return opValue;
+        }
+
+        return opCache[op] = new PostScriptToken(PostScriptTokenTypes.OPERATOR, op);
+      }
+    }, {
+      key: "LBRACE",
+      get: function get() {
+        return (0, _util.shadow)(this, 'LBRACE', new PostScriptToken(PostScriptTokenTypes.LBRACE, '{'));
+      }
+    }, {
+      key: "RBRACE",
+      get: function get() {
+        return (0, _util.shadow)(this, 'RBRACE', new PostScriptToken(PostScriptTokenTypes.RBRACE, '}'));
+      }
+    }, {
+      key: "IF",
+      get: function get() {
+        return (0, _util.shadow)(this, 'IF', new PostScriptToken(PostScriptTokenTypes.IF, 'IF'));
+      }
+    }, {
+      key: "IFELSE",
+      get: function get() {
+        return (0, _util.shadow)(this, 'IFELSE', new PostScriptToken(PostScriptTokenTypes.IFELSE, 'IFELSE'));
+      }
+    }]);
+
+    return PostScriptToken;
+  }();
+
   return PostScriptToken;
 }();
-var PostScriptLexer = function PostScriptLexerClosure() {
+
+var PostScriptLexer =
+/*#__PURE__*/
+function () {
   function PostScriptLexer(stream) {
+    _classCallCheck(this, PostScriptLexer);
+
     this.stream = stream;
     this.nextChar();
     this.strBuf = [];
   }
-  PostScriptLexer.prototype = {
-    nextChar: function PostScriptLexer_nextChar() {
+
+  _createClass(PostScriptLexer, [{
+    key: "nextChar",
+    value: function nextChar() {
       return this.currentChar = this.stream.getByte();
-    },
-    getToken: function PostScriptLexer_getToken() {
+    }
+  }, {
+    key: "getToken",
+    value: function getToken() {
       var comment = false;
       var ch = this.currentChar;
+
       while (true) {
         if (ch < 0) {
           return _primitives.EOF;
         }
+
         if (comment) {
           if (ch === 0x0A || ch === 0x0D) {
             comment = false;
@@ -154,8 +226,10 @@ var PostScriptLexer = function PostScriptLexerClosure() {
         } else if (!(0, _util.isSpace)(ch)) {
           break;
         }
+
         ch = this.nextChar();
       }
+
       switch (ch | 0) {
         case 0x30:
         case 0x31:
@@ -171,34 +245,45 @@ var PostScriptLexer = function PostScriptLexerClosure() {
         case 0x2D:
         case 0x2E:
           return new PostScriptToken(PostScriptTokenTypes.NUMBER, this.getNumber());
+
         case 0x7B:
           this.nextChar();
           return PostScriptToken.LBRACE;
+
         case 0x7D:
           this.nextChar();
           return PostScriptToken.RBRACE;
       }
+
       var strBuf = this.strBuf;
       strBuf.length = 0;
       strBuf[0] = String.fromCharCode(ch);
+
       while ((ch = this.nextChar()) >= 0 && (ch >= 0x41 && ch <= 0x5A || ch >= 0x61 && ch <= 0x7A)) {
         strBuf.push(String.fromCharCode(ch));
       }
+
       var str = strBuf.join('');
+
       switch (str.toLowerCase()) {
         case 'if':
           return PostScriptToken.IF;
+
         case 'ifelse':
           return PostScriptToken.IFELSE;
+
         default:
           return PostScriptToken.getOperator(str);
       }
-    },
-    getNumber: function PostScriptLexer_getNumber() {
+    }
+  }, {
+    key: "getNumber",
+    value: function getNumber() {
       var ch = this.currentChar;
       var strBuf = this.strBuf;
       strBuf.length = 0;
       strBuf[0] = String.fromCharCode(ch);
+
       while ((ch = this.nextChar()) >= 0) {
         if (ch >= 0x30 && ch <= 0x39 || ch === 0x2D || ch === 0x2E) {
           strBuf.push(String.fromCharCode(ch));
@@ -206,14 +291,18 @@ var PostScriptLexer = function PostScriptLexerClosure() {
           break;
         }
       }
+
       var value = parseFloat(strBuf.join(''));
+
       if (isNaN(value)) {
-        throw new _util.FormatError('Invalid floating point number: ' + value);
+        throw new _util.FormatError("Invalid floating point number: ".concat(value));
       }
+
       return value;
     }
-  };
+  }]);
+
   return PostScriptLexer;
 }();
-exports.PostScriptLexer = PostScriptLexer;
-exports.PostScriptParser = PostScriptParser;
+
+exports.PostScriptLexer = PostScriptLexer;

+ 10 - 10
lib/core/standard_fonts.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,14 +19,14 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.getSupplementalGlyphMapForCalibri = exports.getSupplementalGlyphMapForArialBlack = exports.getGlyphMapForStandardFonts = exports.getSymbolsFonts = exports.getSerifFonts = exports.getNonStdFontMap = exports.getStdFontMap = undefined;
+exports.getSupplementalGlyphMapForCalibri = exports.getSupplementalGlyphMapForArialBlack = exports.getGlyphMapForStandardFonts = exports.getSymbolsFonts = exports.getSerifFonts = exports.getNonStdFontMap = exports.getStdFontMap = void 0;
 
-var _util = require('../shared/util');
+var _util = require("../shared/util");
 
 var getStdFontMap = (0, _util.getLookupTableFactory)(function (t) {
   t['ArialNarrow'] = 'Helvetica';
@@ -86,6 +86,7 @@ var getStdFontMap = (0, _util.getLookupTableFactory)(function (t) {
   t['TimesNewRomanPSMT-BoldItalic'] = 'Times-BoldItalic';
   t['TimesNewRomanPSMT-Italic'] = 'Times-Italic';
 });
+exports.getStdFontMap = getStdFontMap;
 var getNonStdFontMap = (0, _util.getLookupTableFactory)(function (t) {
   t['Calibri'] = 'Helvetica';
   t['Calibri-Bold'] = 'Helvetica-Bold';
@@ -123,6 +124,7 @@ var getNonStdFontMap = (0, _util.getLookupTableFactory)(function (t) {
   t['NuptialScript'] = 'Times-Italic';
   t['Wingdings'] = 'ZapfDingbats';
 });
+exports.getNonStdFontMap = getNonStdFontMap;
 var getSerifFonts = (0, _util.getLookupTableFactory)(function (t) {
   t['Adobe Jenson'] = true;
   t['Adobe Text'] = true;
@@ -258,11 +260,13 @@ var getSerifFonts = (0, _util.getLookupTableFactory)(function (t) {
   t['Windsor'] = true;
   t['XITS'] = true;
 });
+exports.getSerifFonts = getSerifFonts;
 var getSymbolsFonts = (0, _util.getLookupTableFactory)(function (t) {
   t['Dingbats'] = true;
   t['Symbol'] = true;
   t['ZapfDingbats'] = true;
 });
+exports.getSymbolsFonts = getSymbolsFonts;
 var getGlyphMapForStandardFonts = (0, _util.getLookupTableFactory)(function (t) {
   t[2] = 10;
   t[3] = 32;
@@ -658,11 +662,13 @@ var getGlyphMapForStandardFonts = (0, _util.getLookupTableFactory)(function (t)
   t[3393] = 1159;
   t[3416] = 8377;
 });
+exports.getGlyphMapForStandardFonts = getGlyphMapForStandardFonts;
 var getSupplementalGlyphMapForArialBlack = (0, _util.getLookupTableFactory)(function (t) {
   t[227] = 322;
   t[264] = 261;
   t[291] = 346;
 });
+exports.getSupplementalGlyphMapForArialBlack = getSupplementalGlyphMapForArialBlack;
 var getSupplementalGlyphMapForCalibri = (0, _util.getLookupTableFactory)(function (t) {
   t[1] = 32;
   t[4] = 65;
@@ -749,10 +755,4 @@ var getSupplementalGlyphMapForCalibri = (0, _util.getLookupTableFactory)(functio
   t[1085] = 43;
   t[1086] = 45;
 });
-exports.getStdFontMap = getStdFontMap;
-exports.getNonStdFontMap = getNonStdFontMap;
-exports.getSerifFonts = getSerifFonts;
-exports.getSymbolsFonts = getSymbolsFonts;
-exports.getGlyphMapForStandardFonts = getGlyphMapForStandardFonts;
-exports.getSupplementalGlyphMapForArialBlack = getSupplementalGlyphMapForArialBlack;
 exports.getSupplementalGlyphMapForCalibri = getSupplementalGlyphMapForCalibri;

File diff suppressed because it is too large
+ 102 - 16
lib/core/stream.js


+ 143 - 13
lib/core/type1_parser.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,20 +19,21 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.Type1Parser = undefined;
+exports.Type1Parser = void 0;
 
-var _util = require('../shared/util');
+var _util = require("../shared/util");
 
-var _encodings = require('./encodings');
+var _encodings = require("./encodings");
 
-var _stream = require('./stream');
+var _stream = require("./stream");
 
 var HINTING_ENABLED = false;
+
 var Type1CharString = function Type1CharStringClosure() {
   var COMMAND_MAP = {
     'hstem': [1],
@@ -51,6 +52,7 @@ var Type1CharString = function Type1CharStringClosure() {
     'vhcurveto': [30],
     'hvcurveto': [31]
   };
+
   function Type1CharString() {
     this.width = 0;
     this.lsb = 0;
@@ -58,78 +60,100 @@ var Type1CharString = function Type1CharStringClosure() {
     this.output = [];
     this.stack = [];
   }
+
   Type1CharString.prototype = {
     convert: function Type1CharString_convert(encoded, subrs, seacAnalysisEnabled) {
       var count = encoded.length;
       var error = false;
       var wx, sbx, subrNumber;
+
       for (var i = 0; i < count; i++) {
         var value = encoded[i];
+
         if (value < 32) {
           if (value === 12) {
             value = (value << 8) + encoded[++i];
           }
+
           switch (value) {
             case 1:
               if (!HINTING_ENABLED) {
                 this.stack = [];
                 break;
               }
+
               error = this.executeCommand(2, COMMAND_MAP.hstem);
               break;
+
             case 3:
               if (!HINTING_ENABLED) {
                 this.stack = [];
                 break;
               }
+
               error = this.executeCommand(2, COMMAND_MAP.vstem);
               break;
+
             case 4:
               if (this.flexing) {
                 if (this.stack.length < 1) {
                   error = true;
                   break;
                 }
+
                 var dy = this.stack.pop();
                 this.stack.push(0, dy);
                 break;
               }
+
               error = this.executeCommand(1, COMMAND_MAP.vmoveto);
               break;
+
             case 5:
               error = this.executeCommand(2, COMMAND_MAP.rlineto);
               break;
+
             case 6:
               error = this.executeCommand(1, COMMAND_MAP.hlineto);
               break;
+
             case 7:
               error = this.executeCommand(1, COMMAND_MAP.vlineto);
               break;
+
             case 8:
               error = this.executeCommand(6, COMMAND_MAP.rrcurveto);
               break;
+
             case 9:
               this.stack = [];
               break;
+
             case 10:
               if (this.stack.length < 1) {
                 error = true;
                 break;
               }
+
               subrNumber = this.stack.pop();
+
               if (!subrs[subrNumber]) {
                 error = true;
                 break;
               }
+
               error = this.convert(subrs[subrNumber], subrs, seacAnalysisEnabled);
               break;
+
             case 11:
               return error;
+
             case 13:
               if (this.stack.length < 2) {
                 error = true;
                 break;
               }
+
               wx = this.stack.pop();
               sbx = this.stack.pop();
               this.lsb = sbx;
@@ -137,45 +161,58 @@ var Type1CharString = function Type1CharStringClosure() {
               this.stack.push(wx, sbx);
               error = this.executeCommand(2, COMMAND_MAP.hmoveto);
               break;
+
             case 14:
               this.output.push(COMMAND_MAP.endchar[0]);
               break;
+
             case 21:
               if (this.flexing) {
                 break;
               }
+
               error = this.executeCommand(2, COMMAND_MAP.rmoveto);
               break;
+
             case 22:
               if (this.flexing) {
                 this.stack.push(0);
                 break;
               }
+
               error = this.executeCommand(1, COMMAND_MAP.hmoveto);
               break;
+
             case 30:
               error = this.executeCommand(4, COMMAND_MAP.vhcurveto);
               break;
+
             case 31:
               error = this.executeCommand(4, COMMAND_MAP.hvcurveto);
               break;
+
             case (12 << 8) + 0:
               this.stack = [];
               break;
+
             case (12 << 8) + 1:
               if (!HINTING_ENABLED) {
                 this.stack = [];
                 break;
               }
+
               error = this.executeCommand(2, COMMAND_MAP.vstem);
               break;
+
             case (12 << 8) + 2:
               if (!HINTING_ENABLED) {
                 this.stack = [];
                 break;
               }
+
               error = this.executeCommand(2, COMMAND_MAP.hstem);
               break;
+
             case (12 << 8) + 6:
               if (seacAnalysisEnabled) {
                 this.seac = this.stack.splice(-4, 4);
@@ -183,12 +220,15 @@ var Type1CharString = function Type1CharStringClosure() {
               } else {
                 error = this.executeCommand(4, COMMAND_MAP.endchar);
               }
+
               break;
+
             case (12 << 8) + 7:
               if (this.stack.length < 4) {
                 error = true;
                 break;
               }
+
               this.stack.pop();
               wx = this.stack.pop();
               var sby = this.stack.pop();
@@ -198,22 +238,27 @@ var Type1CharString = function Type1CharStringClosure() {
               this.stack.push(wx, sbx, sby);
               error = this.executeCommand(3, COMMAND_MAP.rmoveto);
               break;
+
             case (12 << 8) + 12:
               if (this.stack.length < 2) {
                 error = true;
                 break;
               }
+
               var num2 = this.stack.pop();
               var num1 = this.stack.pop();
               this.stack.push(num1 / num2);
               break;
+
             case (12 << 8) + 16:
               if (this.stack.length < 2) {
                 error = true;
                 break;
               }
+
               subrNumber = this.stack.pop();
               var numArgs = this.stack.pop();
+
               if (subrNumber === 0 && numArgs === 3) {
                 var flexArgs = this.stack.splice(this.stack.length - 17, 17);
                 this.stack.push(flexArgs[2] + flexArgs[0], flexArgs[3] + flexArgs[1], flexArgs[4], flexArgs[5], flexArgs[6], flexArgs[7], flexArgs[8], flexArgs[9], flexArgs[10], flexArgs[11], flexArgs[12], flexArgs[13], flexArgs[14]);
@@ -223,19 +268,25 @@ var Type1CharString = function Type1CharStringClosure() {
               } else if (subrNumber === 1 && numArgs === 0) {
                 this.flexing = true;
               }
+
               break;
+
             case (12 << 8) + 17:
               break;
+
             case (12 << 8) + 33:
               this.stack = [];
               break;
+
             default:
               (0, _util.warn)('Unknown type 1 charstring command of "' + value + '"');
               break;
           }
+
           if (error) {
             break;
           }
+
           continue;
         } else if (value <= 246) {
           value = value - 139;
@@ -246,18 +297,24 @@ var Type1CharString = function Type1CharStringClosure() {
         } else {
           value = (encoded[++i] & 0xff) << 24 | (encoded[++i] & 0xff) << 16 | (encoded[++i] & 0xff) << 8 | (encoded[++i] & 0xff) << 0;
         }
+
         this.stack.push(value);
       }
+
       return error;
     },
     executeCommand: function executeCommand(howManyArgs, command, keepStack) {
       var stackLength = this.stack.length;
+
       if (howManyArgs > stackLength) {
         return true;
       }
+
       var start = stackLength - howManyArgs;
+
       for (var i = start; i < stackLength; i++) {
         var value = this.stack[i];
+
         if (Number.isInteger(value)) {
           this.output.push(28, value >> 8 & 0xff, value & 0xff);
         } else {
@@ -265,44 +322,56 @@ var Type1CharString = function Type1CharStringClosure() {
           this.output.push(255, value >> 24 & 0xFF, value >> 16 & 0xFF, value >> 8 & 0xFF, value & 0xFF);
         }
       }
+
       this.output.push.apply(this.output, command);
+
       if (keepStack) {
         this.stack.splice(start, howManyArgs);
       } else {
         this.stack.length = 0;
       }
+
       return false;
     }
   };
   return Type1CharString;
 }();
+
 var Type1Parser = function Type1ParserClosure() {
   var EEXEC_ENCRYPT_KEY = 55665;
   var CHAR_STRS_ENCRYPT_KEY = 4330;
+
   function isHexDigit(code) {
     return code >= 48 && code <= 57 || code >= 65 && code <= 70 || code >= 97 && code <= 102;
   }
+
   function decrypt(data, key, discardNumber) {
     if (discardNumber >= data.length) {
       return new Uint8Array(0);
     }
+
     var r = key | 0,
         c1 = 52845,
         c2 = 22719,
         i,
         j;
+
     for (i = 0; i < discardNumber; i++) {
       r = (data[i] + r) * c1 + c2 & (1 << 16) - 1;
     }
+
     var count = data.length - discardNumber;
     var decrypted = new Uint8Array(count);
+
     for (i = discardNumber, j = 0; j < count; i++, j++) {
       var value = data[i];
       decrypted[j] = value ^ r >> 8;
       r = (value + r) * c1 + c2 & (1 << 16) - 1;
     }
+
     return decrypted;
   }
+
   function decryptAscii(data, key, discardNumber) {
     var r = key | 0,
         c1 = 52845,
@@ -311,48 +380,62 @@ var Type1Parser = function Type1ParserClosure() {
         maybeLength = count >>> 1;
     var decrypted = new Uint8Array(maybeLength);
     var i, j;
+
     for (i = 0, j = 0; i < count; i++) {
       var digit1 = data[i];
+
       if (!isHexDigit(digit1)) {
         continue;
       }
+
       i++;
       var digit2;
+
       while (i < count && !isHexDigit(digit2 = data[i])) {
         i++;
       }
+
       if (i < count) {
         var value = parseInt(String.fromCharCode(digit1, digit2), 16);
         decrypted[j++] = value ^ r >> 8;
         r = (value + r) * c1 + c2 & (1 << 16) - 1;
       }
     }
+
     return Array.prototype.slice.call(decrypted, discardNumber, j);
   }
+
   function isSpecial(c) {
     return c === 0x2F || c === 0x5B || c === 0x5D || c === 0x7B || c === 0x7D || c === 0x28 || c === 0x29;
   }
+
   function Type1Parser(stream, encrypted, seacAnalysisEnabled) {
     if (encrypted) {
       var data = stream.getBytes();
       var isBinary = !(isHexDigit(data[0]) && isHexDigit(data[1]) && isHexDigit(data[2]) && isHexDigit(data[3]));
       stream = new _stream.Stream(isBinary ? decrypt(data, EEXEC_ENCRYPT_KEY, 4) : decryptAscii(data, EEXEC_ENCRYPT_KEY, 4));
     }
+
     this.seacAnalysisEnabled = !!seacAnalysisEnabled;
     this.stream = stream;
     this.nextChar();
   }
+
   Type1Parser.prototype = {
     readNumberArray: function Type1Parser_readNumberArray() {
       this.getToken();
       var array = [];
+
       while (true) {
         var token = this.getToken();
+
         if (token === null || token === ']' || token === '}') {
           break;
         }
+
         array.push(parseFloat(token || 0));
       }
+
       return array;
     },
     readNumber: function Type1Parser_readNumber() {
@@ -373,10 +456,12 @@ var Type1Parser = function Type1ParserClosure() {
     getToken: function Type1Parser_getToken() {
       var comment = false;
       var ch = this.currentChar;
+
       while (true) {
         if (ch === -1) {
           return null;
         }
+
         if (comment) {
           if (ch === 0x0A || ch === 0x0D) {
             comment = false;
@@ -386,23 +471,29 @@ var Type1Parser = function Type1ParserClosure() {
         } else if (!(0, _util.isSpace)(ch)) {
           break;
         }
+
         ch = this.nextChar();
       }
+
       if (isSpecial(ch)) {
         this.nextChar();
         return String.fromCharCode(ch);
       }
+
       var token = '';
+
       do {
         token += String.fromCharCode(ch);
         ch = this.nextChar();
       } while (ch >= 0 && !(0, _util.isSpace)(ch) && !isSpecial(ch));
+
       return token;
     },
     readCharStrings: function Type1Parser_readCharStrings(bytes, lenIV) {
       if (lenIV === -1) {
         return bytes;
       }
+
       return decrypt(bytes, CHAR_STRS_ENCRYPT_KEY, lenIV);
     },
     extractFontProgram: function Type1Parser_extractFontProgram() {
@@ -414,82 +505,103 @@ var Type1Parser = function Type1ParserClosure() {
       var program = {
         subrs: [],
         charstrings: [],
-        properties: { 'privateData': privateData }
+        properties: {
+          'privateData': privateData
+        }
       };
       var token, length, data, lenIV, encoded;
+
       while ((token = this.getToken()) !== null) {
         if (token !== '/') {
           continue;
         }
+
         token = this.getToken();
+
         switch (token) {
           case 'CharStrings':
             this.getToken();
             this.getToken();
             this.getToken();
             this.getToken();
+
             while (true) {
               token = this.getToken();
+
               if (token === null || token === 'end') {
                 break;
               }
+
               if (token !== '/') {
                 continue;
               }
+
               var glyph = this.getToken();
               length = this.readInt();
               this.getToken();
-              data = stream.makeSubStream(stream.pos, length);
+              data = length > 0 ? stream.getBytes(length) : new Uint8Array(0);
               lenIV = program.properties.privateData['lenIV'];
-              encoded = this.readCharStrings(data.getBytes(), lenIV);
-              stream.skip(length);
+              encoded = this.readCharStrings(data, lenIV);
               this.nextChar();
               token = this.getToken();
+
               if (token === 'noaccess') {
                 this.getToken();
               }
+
               charstrings.push({
                 glyph: glyph,
                 encoded: encoded
               });
             }
+
             break;
+
           case 'Subrs':
             this.readInt();
             this.getToken();
+
             while (this.getToken() === 'dup') {
               var index = this.readInt();
               length = this.readInt();
               this.getToken();
-              data = stream.makeSubStream(stream.pos, length);
+              data = length > 0 ? stream.getBytes(length) : new Uint8Array(0);
               lenIV = program.properties.privateData['lenIV'];
-              encoded = this.readCharStrings(data.getBytes(), lenIV);
-              stream.skip(length);
+              encoded = this.readCharStrings(data, lenIV);
               this.nextChar();
               token = this.getToken();
+
               if (token === 'noaccess') {
                 this.getToken();
               }
+
               subrs[index] = encoded;
             }
+
             break;
+
           case 'BlueValues':
           case 'OtherBlues':
           case 'FamilyBlues':
           case 'FamilyOtherBlues':
             var blueArray = this.readNumberArray();
+
             if (blueArray.length > 0 && blueArray.length % 2 === 0 && HINTING_ENABLED) {
               program.properties.privateData[token] = blueArray;
             }
+
             break;
+
           case 'StemSnapH':
           case 'StemSnapV':
             program.properties.privateData[token] = this.readNumberArray();
             break;
+
           case 'StdHW':
           case 'StdVW':
             program.properties.privateData[token] = this.readNumberArray()[0];
             break;
+
           case 'BlueShift':
           case 'lenIV':
           case 'BlueFuzz':
@@ -498,20 +610,24 @@ var Type1Parser = function Type1ParserClosure() {
           case 'ExpansionFactor':
             program.properties.privateData[token] = this.readNumber();
             break;
+
           case 'ForceBold':
             program.properties.privateData[token] = this.readBoolean();
             break;
         }
       }
+
       for (var i = 0; i < charstrings.length; i++) {
         glyph = charstrings[i].glyph;
         encoded = charstrings[i].encoded;
         var charString = new Type1CharString();
         var error = charString.convert(encoded, subrs, this.seacAnalysisEnabled);
         var output = charString.output;
+
         if (error) {
           output = [14];
         }
+
         program.charstrings.push({
           glyphName: glyph,
           charstring: output,
@@ -520,40 +636,51 @@ var Type1Parser = function Type1ParserClosure() {
           seac: charString.seac
         });
       }
+
       return program;
     },
     extractFontHeader: function Type1Parser_extractFontHeader(properties) {
       var token;
+
       while ((token = this.getToken()) !== null) {
         if (token !== '/') {
           continue;
         }
+
         token = this.getToken();
+
         switch (token) {
           case 'FontMatrix':
             var matrix = this.readNumberArray();
             properties.fontMatrix = matrix;
             break;
+
           case 'Encoding':
             var encodingArg = this.getToken();
             var encoding;
+
             if (!/^\d+$/.test(encodingArg)) {
               encoding = (0, _encodings.getEncoding)(encodingArg);
             } else {
               encoding = [];
               var size = parseInt(encodingArg, 10) | 0;
               this.getToken();
+
               for (var j = 0; j < size; j++) {
                 token = this.getToken();
+
                 while (token !== 'dup' && token !== 'def') {
                   token = this.getToken();
+
                   if (token === null) {
                     return;
                   }
                 }
+
                 if (token === 'def') {
                   break;
                 }
+
                 var index = this.readInt();
                 this.getToken();
                 var glyph = this.getToken();
@@ -561,8 +688,10 @@ var Type1Parser = function Type1ParserClosure() {
                 this.getToken();
               }
             }
+
             properties.builtInEncoding = encoding;
             break;
+
           case 'FontBBox':
             var fontBBox = this.readNumberArray();
             properties.ascent = Math.max(fontBBox[3], fontBBox[1]);
@@ -575,4 +704,5 @@ var Type1Parser = function Type1ParserClosure() {
   };
   return Type1Parser;
 }();
+
 exports.Type1Parser = Type1Parser;

+ 31 - 4
lib/core/unicode.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,9 +19,10 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 var getLookupTableFactory = require('../shared/util').getLookupTableFactory;
+
 var getSpecialPUASymbols = getLookupTableFactory(function (t) {
   t[63721] = 0x00A9;
   t[63193] = 0x00A9;
@@ -48,6 +49,7 @@ var getSpecialPUASymbols = getLookupTableFactory(function (t) {
   t[63735] = 0x239F;
   t[63736] = 0x23A0;
 });
+
 function mapSpecialUnicodeValues(code) {
   if (code >= 0xFFF0 && code <= 0xFFFF) {
     return 0;
@@ -56,35 +58,45 @@ function mapSpecialUnicodeValues(code) {
   } else if (code === 0x00AD) {
     return 0x002D;
   }
+
   return code;
 }
+
 function getUnicodeForGlyph(name, glyphsUnicodeMap) {
   var unicode = glyphsUnicodeMap[name];
+
   if (unicode !== undefined) {
     return unicode;
   }
+
   if (!name) {
     return -1;
   }
+
   if (name[0] === 'u') {
     var nameLen = name.length,
         hexStr;
+
     if (nameLen === 7 && name[1] === 'n' && name[2] === 'i') {
-      hexStr = name.substr(3);
+      hexStr = name.substring(3);
     } else if (nameLen >= 5 && nameLen <= 7) {
-      hexStr = name.substr(1);
+      hexStr = name.substring(1);
     } else {
       return -1;
     }
+
     if (hexStr === hexStr.toUpperCase()) {
       unicode = parseInt(hexStr, 16);
+
       if (unicode >= 0) {
         return unicode;
       }
     }
   }
+
   return -1;
 }
+
 var UnicodeRanges = [{
   'begin': 0x0000,
   'end': 0x007F
@@ -455,26 +467,35 @@ var UnicodeRanges = [{
   'begin': 0x1F030,
   'end': 0x1F09F
 }];
+
 function getUnicodeRangeFor(value) {
   for (var i = 0, ii = UnicodeRanges.length; i < ii; i++) {
     var range = UnicodeRanges[i];
+
     if (value >= range.begin && value < range.end) {
       return i;
     }
   }
+
   return -1;
 }
+
 function isRTLRangeFor(value) {
   var range = UnicodeRanges[13];
+
   if (value >= range.begin && value < range.end) {
     return true;
   }
+
   range = UnicodeRanges[11];
+
   if (value >= range.begin && value < range.end) {
     return true;
   }
+
   return false;
 }
+
 var getNormalizedUnicodes = getLookupTableFactory(function (t) {
   t['\u00A8'] = '\u0020\u0308';
   t['\u00AF'] = '\u0020\u0304';
@@ -1854,17 +1875,23 @@ var getNormalizedUnicodes = getLookupTableFactory(function (t) {
   t['\uFEFB'] = '\u0644\u0627';
   t['\uFEFC'] = '\u0644\u0627';
 });
+
 function reverseIfRtl(chars) {
   var charsLength = chars.length;
+
   if (charsLength <= 1 || !isRTLRangeFor(chars.charCodeAt(0))) {
     return chars;
   }
+
   var s = '';
+
   for (var ii = charsLength - 1; ii >= 0; ii--) {
     s += chars[ii];
   }
+
   return s;
 }
+
 exports.mapSpecialUnicodeValues = mapSpecialUnicodeValues;
 exports.reverseIfRtl = reverseIfRtl;
 exports.getUnicodeRangeFor = getUnicodeRangeFor;

+ 210 - 66
lib/core/worker.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,39 +19,53 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.WorkerMessageHandler = exports.WorkerTask = undefined;
+exports.WorkerMessageHandler = exports.WorkerTask = void 0;
 
-var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
+var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
 
-var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
+var _util = require("../shared/util");
 
-var _util = require('../shared/util');
+var _pdf_manager = require("./pdf_manager");
 
-var _pdf_manager = require('./pdf_manager');
+var _is_node = _interopRequireDefault(require("../shared/is_node"));
 
-var _is_node = require('../shared/is_node');
+var _message_handler = require("../shared/message_handler");
 
-var _is_node2 = _interopRequireDefault(_is_node);
-
-var _primitives = require('./primitives');
+var _primitives = require("./primitives");
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
+function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
+
+function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
+
+function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
+
+function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
+
+function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
+
+function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
+
+function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
+
 var WorkerTask = function WorkerTaskClosure() {
   function WorkerTask(name) {
     this.name = name;
     this.terminated = false;
     this._capability = (0, _util.createPromiseCapability)();
   }
+
   WorkerTask.prototype = {
     get finished() {
       return this._capability.promise;
     },
+
     finish: function finish() {
       this._capability.resolve();
     },
@@ -66,7 +80,9 @@ var WorkerTask = function WorkerTaskClosure() {
   };
   return WorkerTask;
 }();
-;
+
+exports.WorkerTask = WorkerTask;
+
 var PDFWorkerStream = function PDFWorkerStreamClosure() {
   function PDFWorkerStream(msgHandler) {
     this._msgHandler = msgHandler;
@@ -74,6 +90,7 @@ var PDFWorkerStream = function PDFWorkerStreamClosure() {
     this._fullRequestReader = null;
     this._rangeRequestReaders = [];
   }
+
   PDFWorkerStream.prototype = {
     getFullReader: function getFullReader() {
       (0, _util.assert)(!this._fullRequestReader);
@@ -82,19 +99,24 @@ var PDFWorkerStream = function PDFWorkerStreamClosure() {
     },
     getRangeReader: function getRangeReader(begin, end) {
       var reader = new PDFWorkerStreamRangeReader(begin, end, this._msgHandler);
+
       this._rangeRequestReaders.push(reader);
+
       return reader;
     },
     cancelAllRequests: function cancelAllRequests(reason) {
       if (this._fullRequestReader) {
         this._fullRequestReader.cancel(reason);
       }
+
       var readers = this._rangeRequestReaders.slice(0);
+
       readers.forEach(function (reader) {
         reader.cancel(reason);
       });
     }
   };
+
   function PDFWorkerStreamReader(msgHandler) {
     var _this = this;
 
@@ -102,7 +124,9 @@ var PDFWorkerStream = function PDFWorkerStreamClosure() {
     this._contentLength = null;
     this._isRangeSupported = false;
     this._isStreamingSupported = false;
+
     var readableStream = this._msgHandler.sendWithStream('GetReader');
+
     this._reader = readableStream.getReader();
     this._headersReady = this._msgHandler.sendWithPromise('ReaderHeadersReady').then(function (data) {
       _this._isStreamingSupported = data.isStreamingSupported;
@@ -110,19 +134,24 @@ var PDFWorkerStream = function PDFWorkerStreamClosure() {
       _this._contentLength = data.contentLength;
     });
   }
+
   PDFWorkerStreamReader.prototype = {
     get headersReady() {
       return this._headersReady;
     },
+
     get contentLength() {
       return this._contentLength;
     },
+
     get isStreamingSupported() {
       return this._isStreamingSupported;
     },
+
     get isRangeSupported() {
       return this._isRangeSupported;
     },
+
     read: function read() {
       return this._reader.read().then(function (_ref) {
         var value = _ref.value,
@@ -134,6 +163,7 @@ var PDFWorkerStream = function PDFWorkerStreamClosure() {
             done: true
           };
         }
+
         return {
           value: value.buffer,
           done: false
@@ -144,19 +174,24 @@ var PDFWorkerStream = function PDFWorkerStreamClosure() {
       this._reader.cancel(reason);
     }
   };
+
   function PDFWorkerStreamRangeReader(begin, end, msgHandler) {
     this._msgHandler = msgHandler;
     this.onProgress = null;
+
     var readableStream = this._msgHandler.sendWithStream('GetRangeReader', {
       begin: begin,
       end: end
     });
+
     this._reader = readableStream.getReader();
   }
+
   PDFWorkerStreamRangeReader.prototype = {
     get isStreamingSupported() {
       return false;
     },
+
     read: function read() {
       return this._reader.read().then(function (_ref2) {
         var value = _ref2.value,
@@ -168,6 +203,7 @@ var PDFWorkerStream = function PDFWorkerStreamClosure() {
             done: true
           };
         }
+
         return {
           value: value.buffer,
           done: false
@@ -180,6 +216,7 @@ var PDFWorkerStream = function PDFWorkerStreamClosure() {
   };
   return PDFWorkerStream;
 }();
+
 var WorkerMessageHandler = {
   setup: function setup(handler, port) {
     var testMessageProcessed = false;
@@ -187,24 +224,30 @@ var WorkerMessageHandler = {
       if (testMessageProcessed) {
         return;
       }
+
       testMessageProcessed = true;
+
       if (!(data instanceof Uint8Array)) {
-        handler.send('test', 'main', false);
+        handler.send('test', false);
         return;
       }
+
       var supportTransfers = data[0] === 255;
       handler.postMessageTransfers = supportTransfers;
       var xhr = new XMLHttpRequest();
       var responseExists = 'response' in xhr;
+
       try {
         xhr.responseType;
       } catch (e) {
         responseExists = false;
       }
+
       if (!responseExists) {
         handler.send('test', false);
         return;
       }
+
       handler.send('test', {
         supportTypedArray: true,
         supportTransfers: supportTransfers
@@ -223,56 +266,97 @@ var WorkerMessageHandler = {
     var cancelXHRs = null;
     var WorkerTasks = [];
     var apiVersion = docParams.apiVersion;
-    var workerVersion = '2.0.489';
-    if (apiVersion !== null && apiVersion !== workerVersion) {
-      throw new Error('The API version "' + apiVersion + '" does not match ' + ('the Worker version "' + workerVersion + '".'));
+    var workerVersion = '2.1.266';
+
+    if (apiVersion !== workerVersion) {
+      throw new Error("The API version \"".concat(apiVersion, "\" does not match ") + "the Worker version \"".concat(workerVersion, "\"."));
     }
+
     var docId = docParams.docId;
     var docBaseUrl = docParams.docBaseUrl;
     var workerHandlerName = docParams.docId + '_worker';
-    var handler = new _util.MessageHandler(workerHandlerName, docId, port);
+    var handler = new _message_handler.MessageHandler(workerHandlerName, docId, port);
     handler.postMessageTransfers = docParams.postMessageTransfers;
+
     function ensureNotTerminated() {
       if (terminated) {
         throw new Error('Worker was terminated');
       }
     }
+
     function startWorkerTask(task) {
       WorkerTasks.push(task);
     }
+
     function finishWorkerTask(task) {
       task.finish();
       var i = WorkerTasks.indexOf(task);
       WorkerTasks.splice(i, 1);
     }
-    function loadDocument(recoveryMode) {
-      var loadDocumentCapability = (0, _util.createPromiseCapability)();
-      var parseSuccess = function parseSuccess() {
-        Promise.all([pdfManager.ensureDoc('numPages'), pdfManager.ensureDoc('fingerprint')]).then(function (_ref3) {
-          var _ref4 = _slicedToArray(_ref3, 2),
-              numPages = _ref4[0],
-              fingerprint = _ref4[1];
-
-          loadDocumentCapability.resolve({
-            numPages: numPages,
-            fingerprint: fingerprint
-          });
-        }, parseFailure);
-      };
-      var parseFailure = function parseFailure(e) {
-        loadDocumentCapability.reject(e);
-      };
-      pdfManager.ensureDoc('checkHeader', []).then(function () {
-        pdfManager.ensureDoc('parseStartXRef', []).then(function () {
-          pdfManager.ensureDoc('parse', [recoveryMode]).then(parseSuccess, parseFailure);
-        }, parseFailure);
-      }, parseFailure);
-      return loadDocumentCapability.promise;
+
+    function loadDocument(_x) {
+      return _loadDocument.apply(this, arguments);
+    }
+
+    function _loadDocument() {
+      _loadDocument = _asyncToGenerator(
+      /*#__PURE__*/
+      _regenerator.default.mark(function _callee(recoveryMode) {
+        var _ref6, _ref7, numPages, fingerprint;
+
+        return _regenerator.default.wrap(function _callee$(_context) {
+          while (1) {
+            switch (_context.prev = _context.next) {
+              case 0:
+                _context.next = 2;
+                return pdfManager.ensureDoc('checkHeader');
+
+              case 2:
+                _context.next = 4;
+                return pdfManager.ensureDoc('parseStartXRef');
+
+              case 4:
+                _context.next = 6;
+                return pdfManager.ensureDoc('parse', [recoveryMode]);
+
+              case 6:
+                if (recoveryMode) {
+                  _context.next = 9;
+                  break;
+                }
+
+                _context.next = 9;
+                return pdfManager.ensureDoc('checkFirstPage');
+
+              case 9:
+                _context.next = 11;
+                return Promise.all([pdfManager.ensureDoc('numPages'), pdfManager.ensureDoc('fingerprint')]);
+
+              case 11:
+                _ref6 = _context.sent;
+                _ref7 = _slicedToArray(_ref6, 2);
+                numPages = _ref7[0];
+                fingerprint = _ref7[1];
+                return _context.abrupt("return", {
+                  numPages: numPages,
+                  fingerprint: fingerprint
+                });
+
+              case 16:
+              case "end":
+                return _context.stop();
+            }
+          }
+        }, _callee, this);
+      }));
+      return _loadDocument.apply(this, arguments);
     }
+
     function getPdfManager(data, evaluatorOptions) {
       var pdfManagerCapability = (0, _util.createPromiseCapability)();
       var pdfManager;
       var source = data.source;
+
       if (source.data) {
         try {
           pdfManager = new _pdf_manager.LocalPdfManager(docId, source.data, source.password, evaluatorOptions, docBaseUrl);
@@ -280,33 +364,39 @@ var WorkerMessageHandler = {
         } catch (ex) {
           pdfManagerCapability.reject(ex);
         }
+
         return pdfManagerCapability.promise;
       }
+
       var pdfStream,
           cachedChunks = [];
+
       try {
         pdfStream = new PDFWorkerStream(handler);
       } catch (ex) {
         pdfManagerCapability.reject(ex);
         return pdfManagerCapability.promise;
       }
+
       var fullRequest = pdfStream.getFullReader();
       fullRequest.headersReady.then(function () {
         if (!fullRequest.isRangeSupported) {
           return;
         }
+
         var disableAutoFetch = source.disableAutoFetch || fullRequest.isStreamingSupported;
         pdfManager = new _pdf_manager.NetworkPdfManager(docId, pdfStream, {
           msgHandler: handler,
-          url: source.url,
           password: source.password,
           length: fullRequest.contentLength,
           disableAutoFetch: disableAutoFetch,
           rangeChunkSize: source.rangeChunkSize
         }, evaluatorOptions, docBaseUrl);
+
         for (var i = 0; i < cachedChunks.length; i++) {
           pdfManager.sendProgressiveData(cachedChunks[i]);
         }
+
         cachedChunks = [];
         pdfManagerCapability.resolve(pdfManager);
         cancelXHRs = null;
@@ -315,66 +405,85 @@ var WorkerMessageHandler = {
         cancelXHRs = null;
       });
       var loaded = 0;
+
       var flushChunks = function flushChunks() {
         var pdfFile = (0, _util.arraysToBytes)(cachedChunks);
+
         if (source.length && pdfFile.length !== source.length) {
           (0, _util.warn)('reported HTTP length is different from actual');
         }
+
         try {
           pdfManager = new _pdf_manager.LocalPdfManager(docId, pdfFile, source.password, evaluatorOptions, docBaseUrl);
           pdfManagerCapability.resolve(pdfManager);
         } catch (ex) {
           pdfManagerCapability.reject(ex);
         }
+
         cachedChunks = [];
       };
+
       var readPromise = new Promise(function (resolve, reject) {
         var readChunk = function readChunk(chunk) {
           try {
             ensureNotTerminated();
+
             if (chunk.done) {
               if (!pdfManager) {
                 flushChunks();
               }
+
               cancelXHRs = null;
               return;
             }
+
             var data = chunk.value;
             loaded += (0, _util.arrayByteLength)(data);
+
             if (!fullRequest.isStreamingSupported) {
               handler.send('DocProgress', {
                 loaded: loaded,
                 total: Math.max(loaded, fullRequest.contentLength || 0)
               });
             }
+
             if (pdfManager) {
               pdfManager.sendProgressiveData(data);
             } else {
               cachedChunks.push(data);
             }
+
             fullRequest.read().then(readChunk, reject);
           } catch (e) {
             reject(e);
           }
         };
+
         fullRequest.read().then(readChunk, reject);
       });
       readPromise.catch(function (e) {
         pdfManagerCapability.reject(e);
         cancelXHRs = null;
       });
+
       cancelXHRs = function cancelXHRs() {
         pdfStream.cancelAllRequests('abort');
       };
+
       return pdfManagerCapability.promise;
     }
+
     function setupDoc(data) {
       function onSuccess(doc) {
         ensureNotTerminated();
-        handler.send('GetDoc', { pdfInfo: doc });
+        handler.send('GetDoc', {
+          pdfInfo: doc
+        });
       }
+
       function onFailure(e) {
         ensureNotTerminated();
+
         if (e instanceof _util.PasswordException) {
           var task = new WorkerTask('PasswordException: response ' + e.code);
           startWorkerTask(task);
@@ -382,9 +491,9 @@ var WorkerMessageHandler = {
             finishWorkerTask(task);
             pdfManager.updatePassword(data.password);
             pdfManagerReady();
-          }).catch(function (ex) {
+          }).catch(function (boundException) {
             finishWorkerTask(task);
-            handler.send('PasswordException', ex);
+            handler.send('PasswordException', boundException);
           }.bind(null, e));
         } else if (e instanceof _util.InvalidPDFException) {
           handler.send('InvalidPDF', e);
@@ -396,14 +505,17 @@ var WorkerMessageHandler = {
           handler.send('UnknownError', new _util.UnknownErrorException(e.message, e.toString()));
         }
       }
+
       function pdfManagerReady() {
         ensureNotTerminated();
         loadDocument(false).then(onSuccess, function loadFailure(ex) {
           ensureNotTerminated();
+
           if (!(ex instanceof _util.XRefParseException)) {
             onFailure(ex);
             return;
           }
+
           pdfManager.requestLoadedStream();
           pdfManager.onLoadedStream().then(function () {
             ensureNotTerminated();
@@ -411,6 +523,7 @@ var WorkerMessageHandler = {
           });
         }, onFailure);
       }
+
       ensureNotTerminated();
       var evaluatorOptions = {
         forceDataSchema: data.disableCreateObjectURL,
@@ -425,25 +538,30 @@ var WorkerMessageHandler = {
           newPdfManager.terminate();
           throw new Error('Worker was terminated');
         }
+
         pdfManager = newPdfManager;
-        handler.send('PDFManagerReady', null);
         pdfManager.onLoadedStream().then(function (stream) {
-          handler.send('DataLoaded', { length: stream.bytes.byteLength });
+          handler.send('DataLoaded', {
+            length: stream.bytes.byteLength
+          });
         });
       }).then(pdfManagerReady, onFailure);
     }
+
     handler.on('GetPage', function wphSetupGetPage(data) {
       return pdfManager.getPage(data.pageIndex).then(function (page) {
-        var rotatePromise = pdfManager.ensure(page, 'rotate');
-        var refPromise = pdfManager.ensure(page, 'ref');
-        var userUnitPromise = pdfManager.ensure(page, 'userUnit');
-        var viewPromise = pdfManager.ensure(page, 'view');
-        return Promise.all([rotatePromise, refPromise, userUnitPromise, viewPromise]).then(function (results) {
+        return Promise.all([pdfManager.ensure(page, 'rotate'), pdfManager.ensure(page, 'ref'), pdfManager.ensure(page, 'userUnit'), pdfManager.ensure(page, 'view')]).then(function (_ref3) {
+          var _ref4 = _slicedToArray(_ref3, 4),
+              rotate = _ref4[0],
+              ref = _ref4[1],
+              userUnit = _ref4[2],
+              view = _ref4[3];
+
           return {
-            rotate: results[0],
-            ref: results[1],
-            userUnit: results[2],
-            view: results[3]
+            rotate: rotate,
+            ref: ref,
+            userUnit: userUnit,
+            view: view
           };
         });
       });
@@ -465,6 +583,9 @@ var WorkerMessageHandler = {
     handler.on('GetPageMode', function wphSetupGetPageMode(data) {
       return pdfManager.ensureCatalog('pageMode');
     });
+    handler.on('getOpenActionDestination', function (data) {
+      return pdfManager.ensureCatalog('openActionDestination');
+    });
     handler.on('GetAttachments', function wphSetupGetAttachments(data) {
       return pdfManager.ensureCatalog('attachments');
     });
@@ -474,6 +595,9 @@ var WorkerMessageHandler = {
     handler.on('GetOutline', function wphSetupGetOutline(data) {
       return pdfManager.ensureCatalog('documentOutline');
     });
+    handler.on('GetPermissions', function (data) {
+      return pdfManager.ensureCatalog('permissions');
+    });
     handler.on('GetMetadata', function wphSetupGetMetadata(data) {
       return Promise.all([pdfManager.ensureDoc('documentInfo'), pdfManager.ensureCatalog('metadata')]);
     });
@@ -486,9 +610,11 @@ var WorkerMessageHandler = {
     handler.on('GetStats', function wphSetupGetStats(data) {
       return pdfManager.pdfDocument.xref.stats;
     });
-    handler.on('GetAnnotations', function wphSetupGetAnnotations(data) {
-      return pdfManager.getPage(data.pageIndex).then(function (page) {
-        return pdfManager.ensure(page, 'getAnnotationsData', [data.intent]);
+    handler.on('GetAnnotations', function (_ref5) {
+      var pageIndex = _ref5.pageIndex,
+          intent = _ref5.intent;
+      return pdfManager.getPage(pageIndex).then(function (page) {
+        return page.getAnnotationsData(intent);
       });
     });
     handler.on('RenderPageRequest', function wphSetupRenderPage(data) {
@@ -508,28 +634,34 @@ var WorkerMessageHandler = {
           (0, _util.info)('page=' + pageNum + ' - getOperatorList: time=' + (Date.now() - start) + 'ms, len=' + operatorList.totalLength);
         }, function (e) {
           finishWorkerTask(task);
+
           if (task.terminated) {
             return;
           }
-          handler.send('UnsupportedFeature', { featureId: _util.UNSUPPORTED_FEATURES.unknown });
+
+          handler.send('UnsupportedFeature', {
+            featureId: _util.UNSUPPORTED_FEATURES.unknown
+          });
           var minimumStackMessage = 'worker.js: while trying to getPage() and getOperatorList()';
           var wrappedException;
+
           if (typeof e === 'string') {
             wrappedException = {
               message: e,
               stack: minimumStackMessage
             };
-          } else if ((typeof e === 'undefined' ? 'undefined' : _typeof(e)) === 'object') {
+          } else if (_typeof(e) === 'object') {
             wrappedException = {
               message: e.message || e.toString(),
               stack: e.stack || minimumStackMessage
             };
           } else {
             wrappedException = {
-              message: 'Unknown exception type: ' + (typeof e === 'undefined' ? 'undefined' : _typeof(e)),
+              message: 'Unknown exception type: ' + _typeof(e),
               stack: minimumStackMessage
             };
           }
+
           handler.send('PageError', {
             pageNum: pageNum,
             error: wrappedException,
@@ -540,8 +672,11 @@ var WorkerMessageHandler = {
     }, this);
     handler.on('GetTextContent', function wphExtractText(data, sink) {
       var pageIndex = data.pageIndex;
+
       sink.onPull = function (desiredSize) {};
+
       sink.onCancel = function (reason) {};
+
       pdfManager.getPage(pageIndex).then(function (page) {
         var task = new WorkerTask('GetTextContent: page ' + pageIndex);
         startWorkerTask(task);
@@ -559,26 +694,34 @@ var WorkerMessageHandler = {
           sink.close();
         }, function (reason) {
           finishWorkerTask(task);
+
           if (task.terminated) {
             return;
           }
+
           sink.error(reason);
           throw reason;
         });
       });
     });
+    handler.on('FontFallback', function (data) {
+      return pdfManager.fontFallback(data.id, handler);
+    });
     handler.on('Cleanup', function wphCleanup(data) {
       return pdfManager.cleanup();
     });
     handler.on('Terminate', function wphTerminate(data) {
       terminated = true;
+
       if (pdfManager) {
         pdfManager.terminate();
         pdfManager = null;
       }
+
       if (cancelXHRs) {
         cancelXHRs();
       }
+
       var waitOn = [];
       WorkerTasks.forEach(function (task) {
         waitOn.push(task.finished);
@@ -596,16 +739,17 @@ var WorkerMessageHandler = {
     return workerHandlerName;
   },
   initializeFromPort: function initializeFromPort(port) {
-    var handler = new _util.MessageHandler('worker', 'main', port);
+    var handler = new _message_handler.MessageHandler('worker', 'main', port);
     WorkerMessageHandler.setup(handler, port);
     handler.send('ready', null);
   }
 };
+exports.WorkerMessageHandler = WorkerMessageHandler;
+
 function isMessagePort(maybePort) {
   return typeof maybePort.postMessage === 'function' && 'onmessage' in maybePort;
 }
-if (typeof window === 'undefined' && !(0, _is_node2.default)() && typeof self !== 'undefined' && isMessagePort(self)) {
+
+if (typeof window === 'undefined' && !(0, _is_node.default)() && typeof self !== 'undefined' && isMessagePort(self)) {
   WorkerMessageHandler.initializeFromPort(self);
-}
-exports.WorkerTask = WorkerTask;
-exports.WorkerMessageHandler = WorkerMessageHandler;
+}

File diff suppressed because it is too large
+ 291 - 89
lib/display/annotation_layer.js


File diff suppressed because it is too large
+ 513 - 212
lib/display/api.js


+ 11 - 13
lib/display/api_compatibility.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,29 +19,27 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
-Object.defineProperty(exports, "__esModule", {
-  value: true
-});
 var compatibilityParams = Object.create(null);
 {
+  var isNodeJS = require('../shared/is_node');
+
   var userAgent = typeof navigator !== 'undefined' && navigator.userAgent || '';
   var isIE = /Trident/.test(userAgent);
-  var isIOS = /\b(iPad|iPhone|iPod)(?=;)/.test(userAgent);
   var isIOSChrome = /CriOS/.test(userAgent);
-  var isSafari = /Safari\//.test(userAgent) && !/(Chrome\/|Android\s)/.test(userAgent);
+
   (function checkOnBlobSupport() {
     if (isIE || isIOSChrome) {
       compatibilityParams.disableCreateObjectURL = true;
     }
   })();
-  (function checkRangeRequests() {
-    if (isSafari || isIOS) {
-      compatibilityParams.disableRange = true;
-      compatibilityParams.disableStream = true;
+
+  (function checkFontFaceAndImage() {
+    if (isNodeJS()) {
+      compatibilityParams.disableFontFace = true;
+      compatibilityParams.nativeImageDecoderSupport = 'none';
     }
   })();
 }
-var apiCompatibilityParams = Object.freeze(compatibilityParams);
-exports.apiCompatibilityParams = apiCompatibilityParams;
+exports.apiCompatibilityParams = Object.freeze(compatibilityParams);

File diff suppressed because it is too large
+ 202 - 18
lib/display/canvas.js


+ 83 - 32
lib/display/content_disposition.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,17 +19,25 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
+exports.getFilenameFromContentDispositionHeader = getFilenameFromContentDispositionHeader;
 
-var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
+function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
+
+function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
+
+function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
+
+function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
 
 function getFilenameFromContentDispositionHeader(contentDisposition) {
   var needsEncodingFixup = true;
   var tmp = toParamRegExp('filename\\*', 'i').exec(contentDisposition);
+
   if (tmp) {
     tmp = tmp[1];
     var filename = rfc2616unquote(tmp);
@@ -38,53 +46,75 @@ function getFilenameFromContentDispositionHeader(contentDisposition) {
     filename = rfc2047decode(filename);
     return fixupEncoding(filename);
   }
+
   tmp = rfc2231getparam(contentDisposition);
+
   if (tmp) {
     var _filename = rfc2047decode(tmp);
+
     return fixupEncoding(_filename);
   }
+
   tmp = toParamRegExp('filename', 'i').exec(contentDisposition);
+
   if (tmp) {
     tmp = tmp[1];
+
     var _filename2 = rfc2616unquote(tmp);
+
     _filename2 = rfc2047decode(_filename2);
     return fixupEncoding(_filename2);
   }
+
   function toParamRegExp(attributePattern, flags) {
     return new RegExp('(?:^|;)\\s*' + attributePattern + '\\s*=\\s*' + '(' + '[^";\\s][^;\\s]*' + '|' + '"(?:[^"\\\\]|\\\\"?)+"?' + ')', flags);
   }
+
   function textdecode(encoding, value) {
     if (encoding) {
-      if (!/^[^\x00-\xFF]+$/.test(value)) {
+      if (!/^[\x00-\xFF]+$/.test(value)) {
         return value;
       }
+
       try {
-        var decoder = new TextDecoder(encoding, { fatal: true });
-        var bytes = new Array(value.length);
-        for (var i = 0; i < value.length; ++i) {
-          bytes[i] = value.charCodeAt(0);
-        }
+        var decoder = new TextDecoder(encoding, {
+          fatal: true
+        });
+        var bytes = Array.from(value, function (ch) {
+          return ch.charCodeAt(0) & 0xFF;
+        });
         value = decoder.decode(new Uint8Array(bytes));
         needsEncodingFixup = false;
       } catch (e) {
         if (/^utf-?8$/i.test(encoding)) {
-          value = decodeURIComponent(escape(value));
-          needsEncodingFixup = false;
+          try {
+            value = decodeURIComponent(escape(value));
+            needsEncodingFixup = false;
+          } catch (err) {}
         }
       }
     }
+
     return value;
   }
+
   function fixupEncoding(value) {
     if (needsEncodingFixup && /[\x80-\xff]/.test(value)) {
-      return textdecode('utf-8', value);
+      value = textdecode('utf-8', value);
+
+      if (needsEncodingFixup) {
+        value = textdecode('iso-8859-1', value);
+      }
     }
+
     return value;
   }
+
   function rfc2231getparam(contentDisposition) {
     var matches = [],
-        match = void 0;
+        match;
     var iter = toParamRegExp('filename\\*((?!0\\d)\\d+)(\\*?)', 'ig');
+
     while ((match = iter.exec(contentDisposition)) !== null) {
       var _match = match,
           _match2 = _slicedToArray(_match, 4),
@@ -93,64 +123,84 @@ function getFilenameFromContentDispositionHeader(contentDisposition) {
           part = _match2[3];
 
       n = parseInt(n, 10);
+
       if (n in matches) {
         if (n === 0) {
           break;
         }
+
         continue;
       }
+
       matches[n] = [quot, part];
     }
+
     var parts = [];
-    for (var _n = 0; _n < matches.length; ++_n) {
-      if (!(_n in matches)) {
+
+    for (var n = 0; n < matches.length; ++n) {
+      if (!(n in matches)) {
         break;
       }
 
-      var _matches$_n = _slicedToArray(matches[_n], 2),
-          _quot = _matches$_n[0],
-          _part = _matches$_n[1];
+      var _matches$n = _slicedToArray(matches[n], 2),
+          quot = _matches$n[0],
+          part = _matches$n[1];
 
-      _part = rfc2616unquote(_part);
-      if (_quot) {
-        _part = unescape(_part);
-        if (_n === 0) {
-          _part = rfc5987decode(_part);
+      part = rfc2616unquote(part);
+
+      if (quot) {
+        part = unescape(part);
+
+        if (n === 0) {
+          part = rfc5987decode(part);
         }
       }
-      parts.push(_part);
+
+      parts.push(part);
     }
+
     return parts.join('');
   }
+
   function rfc2616unquote(value) {
-    if (value.charAt(0) === '"') {
+    if (value.startsWith('"')) {
       var parts = value.slice(1).split('\\"');
+
       for (var i = 0; i < parts.length; ++i) {
         var quotindex = parts[i].indexOf('"');
+
         if (quotindex !== -1) {
           parts[i] = parts[i].slice(0, quotindex);
           parts.length = i + 1;
         }
+
         parts[i] = parts[i].replace(/\\(.)/g, '$1');
       }
+
       value = parts.join('"');
     }
+
     return value;
   }
+
   function rfc5987decode(extvalue) {
     var encodingend = extvalue.indexOf('\'');
+
     if (encodingend === -1) {
       return extvalue;
     }
+
     var encoding = extvalue.slice(0, encodingend);
     var langvalue = extvalue.slice(encodingend + 1);
     var value = langvalue.replace(/^[^']*'/, '');
     return textdecode(encoding, value);
   }
+
   function rfc2047decode(value) {
-    if (value.slice(0, 2) !== '=?' || /[\x00-\x19\x80-\xff]/.test(value)) {
+    if (!value.startsWith('=?') || /[\x00-\x19\x80-\xff]/.test(value)) {
       return value;
     }
+
     return value.replace(/=\?([\w-]*)\?([QqBb])\?((?:[^?]|\?(?!=))*)\?=/g, function (_, charset, encoding, text) {
       if (encoding === 'q' || encoding === 'Q') {
         text = text.replace(/_/g, ' ');
@@ -159,13 +209,14 @@ function getFilenameFromContentDispositionHeader(contentDisposition) {
         });
         return textdecode(charset, text);
       }
+
       try {
-        return atob(text);
-      } catch (e) {
-        return text;
-      }
+        text = atob(text);
+      } catch (e) {}
+
+      return textdecode(charset, text);
     });
   }
+
   return '';
-}
-exports.getFilenameFromContentDispositionHeader = getFilenameFromContentDispositionHeader;
+}

+ 226 - 41
lib/display/dom_utils.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,33 +19,42 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.DummyStatTimer = exports.StatTimer = exports.DOMSVGFactory = exports.DOMCMapReaderFactory = exports.DOMCanvasFactory = exports.DEFAULT_LINK_REL = exports.LinkTarget = exports.getFilenameFromUrl = exports.addLinkAttributes = exports.RenderingCancelledException = undefined;
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+exports.addLinkAttributes = addLinkAttributes;
+exports.getFilenameFromUrl = getFilenameFromUrl;
+exports.loadScript = loadScript;
+exports.DummyStatTimer = exports.StatTimer = exports.DOMSVGFactory = exports.DOMCMapReaderFactory = exports.DOMCanvasFactory = exports.DEFAULT_LINK_REL = exports.LinkTarget = exports.RenderingCancelledException = exports.PageViewport = void 0;
 
-var _util = require('../shared/util');
+var _util = require("../shared/util");
 
 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
+function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
+
+function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
+
 var DEFAULT_LINK_REL = 'noopener noreferrer nofollow';
+exports.DEFAULT_LINK_REL = DEFAULT_LINK_REL;
 var SVG_NS = 'http://www.w3.org/2000/svg';
 
-var DOMCanvasFactory = function () {
+var DOMCanvasFactory =
+/*#__PURE__*/
+function () {
   function DOMCanvasFactory() {
     _classCallCheck(this, DOMCanvasFactory);
   }
 
   _createClass(DOMCanvasFactory, [{
-    key: 'create',
+    key: "create",
     value: function create(width, height) {
       if (width <= 0 || height <= 0) {
         throw new Error('invalid canvas size');
       }
+
       var canvas = document.createElement('canvas');
       var context = canvas.getContext('2d');
       canvas.width = width;
@@ -56,23 +65,26 @@ var DOMCanvasFactory = function () {
       };
     }
   }, {
-    key: 'reset',
+    key: "reset",
     value: function reset(canvasAndContext, width, height) {
       if (!canvasAndContext.canvas) {
         throw new Error('canvas is not specified');
       }
+
       if (width <= 0 || height <= 0) {
         throw new Error('invalid canvas size');
       }
+
       canvasAndContext.canvas.width = width;
       canvasAndContext.canvas.height = height;
     }
   }, {
-    key: 'destroy',
+    key: "destroy",
     value: function destroy(canvasAndContext) {
       if (!canvasAndContext.canvas) {
         throw new Error('canvas is not specified');
       }
+
       canvasAndContext.canvas.width = 0;
       canvasAndContext.canvas.height = 0;
       canvasAndContext.canvas = null;
@@ -83,12 +95,16 @@ var DOMCanvasFactory = function () {
   return DOMCanvasFactory;
 }();
 
-var DOMCMapReaderFactory = function () {
+exports.DOMCanvasFactory = DOMCanvasFactory;
+
+var DOMCMapReaderFactory =
+/*#__PURE__*/
+function () {
   function DOMCMapReaderFactory(_ref) {
     var _ref$baseUrl = _ref.baseUrl,
-        baseUrl = _ref$baseUrl === undefined ? null : _ref$baseUrl,
+        baseUrl = _ref$baseUrl === void 0 ? null : _ref$baseUrl,
         _ref$isCompressed = _ref.isCompressed,
-        isCompressed = _ref$isCompressed === undefined ? false : _ref$isCompressed;
+        isCompressed = _ref$isCompressed === void 0 ? false : _ref$isCompressed;
 
     _classCallCheck(this, DOMCMapReaderFactory);
 
@@ -97,7 +113,7 @@ var DOMCMapReaderFactory = function () {
   }
 
   _createClass(DOMCMapReaderFactory, [{
-    key: 'fetch',
+    key: "fetch",
     value: function fetch(_ref2) {
       var _this = this;
 
@@ -106,27 +122,34 @@ var DOMCMapReaderFactory = function () {
       if (!this.baseUrl) {
         return Promise.reject(new Error('The CMap "baseUrl" parameter must be specified, ensure that ' + 'the "cMapUrl" and "cMapPacked" API parameters are provided.'));
       }
+
       if (!name) {
         return Promise.reject(new Error('CMap name must be specified.'));
       }
+
       return new Promise(function (resolve, reject) {
         var url = _this.baseUrl + name + (_this.isCompressed ? '.bcmap' : '');
         var request = new XMLHttpRequest();
         request.open('GET', url, true);
+
         if (_this.isCompressed) {
           request.responseType = 'arraybuffer';
         }
+
         request.onreadystatechange = function () {
           if (request.readyState !== XMLHttpRequest.DONE) {
             return;
           }
+
           if (request.status === 200 || request.status === 0) {
-            var data = void 0;
+            var data;
+
             if (_this.isCompressed && request.response) {
               data = new Uint8Array(request.response);
             } else if (!_this.isCompressed && request.responseText) {
               data = (0, _util.stringToBytes)(request.responseText);
             }
+
             if (data) {
               resolve({
                 cMapData: data,
@@ -135,8 +158,10 @@ var DOMCMapReaderFactory = function () {
               return;
             }
           }
+
           reject(new Error('Unable to load ' + (_this.isCompressed ? 'binary ' : '') + 'CMap at: ' + url));
         };
+
         request.send(null);
       });
     }
@@ -145,13 +170,17 @@ var DOMCMapReaderFactory = function () {
   return DOMCMapReaderFactory;
 }();
 
-var DOMSVGFactory = function () {
+exports.DOMCMapReaderFactory = DOMCMapReaderFactory;
+
+var DOMSVGFactory =
+/*#__PURE__*/
+function () {
   function DOMSVGFactory() {
     _classCallCheck(this, DOMSVGFactory);
   }
 
   _createClass(DOMSVGFactory, [{
-    key: 'create',
+    key: "create",
     value: function create(width, height) {
       (0, _util.assert)(width > 0 && height > 0, 'Invalid SVG dimensions');
       var svg = document.createElementNS(SVG_NS, 'svg:svg');
@@ -163,7 +192,7 @@ var DOMSVGFactory = function () {
       return svg;
     }
   }, {
-    key: 'createElement',
+    key: "createElement",
     value: function createElement(type) {
       (0, _util.assert)(typeof type === 'string', 'Invalid SVG element type');
       return document.createElementNS(SVG_NS, type);
@@ -173,16 +202,149 @@ var DOMSVGFactory = function () {
   return DOMSVGFactory;
 }();
 
+exports.DOMSVGFactory = DOMSVGFactory;
+
+var PageViewport =
+/*#__PURE__*/
+function () {
+  function PageViewport(_ref3) {
+    var viewBox = _ref3.viewBox,
+        scale = _ref3.scale,
+        rotation = _ref3.rotation,
+        _ref3$offsetX = _ref3.offsetX,
+        offsetX = _ref3$offsetX === void 0 ? 0 : _ref3$offsetX,
+        _ref3$offsetY = _ref3.offsetY,
+        offsetY = _ref3$offsetY === void 0 ? 0 : _ref3$offsetY,
+        _ref3$dontFlip = _ref3.dontFlip,
+        dontFlip = _ref3$dontFlip === void 0 ? false : _ref3$dontFlip;
+
+    _classCallCheck(this, PageViewport);
+
+    this.viewBox = viewBox;
+    this.scale = scale;
+    this.rotation = rotation;
+    this.offsetX = offsetX;
+    this.offsetY = offsetY;
+    var centerX = (viewBox[2] + viewBox[0]) / 2;
+    var centerY = (viewBox[3] + viewBox[1]) / 2;
+    var rotateA, rotateB, rotateC, rotateD;
+    rotation = rotation % 360;
+    rotation = rotation < 0 ? rotation + 360 : rotation;
+
+    switch (rotation) {
+      case 180:
+        rotateA = -1;
+        rotateB = 0;
+        rotateC = 0;
+        rotateD = 1;
+        break;
+
+      case 90:
+        rotateA = 0;
+        rotateB = 1;
+        rotateC = 1;
+        rotateD = 0;
+        break;
+
+      case 270:
+        rotateA = 0;
+        rotateB = -1;
+        rotateC = -1;
+        rotateD = 0;
+        break;
+
+      default:
+        rotateA = 1;
+        rotateB = 0;
+        rotateC = 0;
+        rotateD = -1;
+        break;
+    }
+
+    if (dontFlip) {
+      rotateC = -rotateC;
+      rotateD = -rotateD;
+    }
+
+    var offsetCanvasX, offsetCanvasY;
+    var width, height;
+
+    if (rotateA === 0) {
+      offsetCanvasX = Math.abs(centerY - viewBox[1]) * scale + offsetX;
+      offsetCanvasY = Math.abs(centerX - viewBox[0]) * scale + offsetY;
+      width = Math.abs(viewBox[3] - viewBox[1]) * scale;
+      height = Math.abs(viewBox[2] - viewBox[0]) * scale;
+    } else {
+      offsetCanvasX = Math.abs(centerX - viewBox[0]) * scale + offsetX;
+      offsetCanvasY = Math.abs(centerY - viewBox[1]) * scale + offsetY;
+      width = Math.abs(viewBox[2] - viewBox[0]) * scale;
+      height = Math.abs(viewBox[3] - viewBox[1]) * scale;
+    }
+
+    this.transform = [rotateA * scale, rotateB * scale, rotateC * scale, rotateD * scale, offsetCanvasX - rotateA * scale * centerX - rotateC * scale * centerY, offsetCanvasY - rotateB * scale * centerX - rotateD * scale * centerY];
+    this.width = width;
+    this.height = height;
+  }
+
+  _createClass(PageViewport, [{
+    key: "clone",
+    value: function clone() {
+      var _ref4 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
+          _ref4$scale = _ref4.scale,
+          scale = _ref4$scale === void 0 ? this.scale : _ref4$scale,
+          _ref4$rotation = _ref4.rotation,
+          rotation = _ref4$rotation === void 0 ? this.rotation : _ref4$rotation,
+          _ref4$dontFlip = _ref4.dontFlip,
+          dontFlip = _ref4$dontFlip === void 0 ? false : _ref4$dontFlip;
+
+      return new PageViewport({
+        viewBox: this.viewBox.slice(),
+        scale: scale,
+        rotation: rotation,
+        offsetX: this.offsetX,
+        offsetY: this.offsetY,
+        dontFlip: dontFlip
+      });
+    }
+  }, {
+    key: "convertToViewportPoint",
+    value: function convertToViewportPoint(x, y) {
+      return _util.Util.applyTransform([x, y], this.transform);
+    }
+  }, {
+    key: "convertToViewportRectangle",
+    value: function convertToViewportRectangle(rect) {
+      var tl = _util.Util.applyTransform([rect[0], rect[1]], this.transform);
+
+      var br = _util.Util.applyTransform([rect[2], rect[3]], this.transform);
+
+      return [tl[0], tl[1], br[0], br[1]];
+    }
+  }, {
+    key: "convertToPdfPoint",
+    value: function convertToPdfPoint(x, y) {
+      return _util.Util.applyInverseTransform([x, y], this.transform);
+    }
+  }]);
+
+  return PageViewport;
+}();
+
+exports.PageViewport = PageViewport;
+
 var RenderingCancelledException = function RenderingCancelledException() {
   function RenderingCancelledException(msg, type) {
     this.message = msg;
     this.type = type;
   }
+
   RenderingCancelledException.prototype = new Error();
   RenderingCancelledException.prototype.name = 'RenderingCancelledException';
   RenderingCancelledException.constructor = RenderingCancelledException;
   return RenderingCancelledException;
 }();
+
+exports.RenderingCancelledException = RenderingCancelledException;
 var LinkTarget = {
   NONE: 0,
   SELF: 1,
@@ -190,14 +352,17 @@ var LinkTarget = {
   PARENT: 3,
   TOP: 4
 };
+exports.LinkTarget = LinkTarget;
 var LinkTargetStringMap = ['', '_self', '_blank', '_parent', '_top'];
+
 function addLinkAttributes(link) {
-  var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
-      url = _ref3.url,
-      target = _ref3.target,
-      rel = _ref3.rel;
+  var _ref5 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
+      url = _ref5.url,
+      target = _ref5.target,
+      rel = _ref5.rel;
 
   link.href = link.title = url ? (0, _util.removeNullCharacters)(url) : '';
+
   if (url) {
     var LinkTargetValues = Object.values(LinkTarget);
     var targetIndex = LinkTargetValues.includes(target) ? target : LinkTarget.NONE;
@@ -205,6 +370,7 @@ function addLinkAttributes(link) {
     link.rel = typeof rel === 'string' ? rel : DEFAULT_LINK_REL;
   }
 }
+
 function getFilenameFromUrl(url) {
   var anchor = url.indexOf('#');
   var query = url.indexOf('?');
@@ -212,7 +378,9 @@ function getFilenameFromUrl(url) {
   return url.substring(url.lastIndexOf('/', end) + 1, end);
 }
 
-var StatTimer = function () {
+var StatTimer =
+/*#__PURE__*/
+function () {
   function StatTimer() {
     var enable = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
 
@@ -224,25 +392,29 @@ var StatTimer = function () {
   }
 
   _createClass(StatTimer, [{
-    key: 'time',
+    key: "time",
     value: function time(name) {
       if (!this.enabled) {
         return;
       }
+
       if (name in this.started) {
         (0, _util.warn)('Timer is already running for ' + name);
       }
+
       this.started[name] = Date.now();
     }
   }, {
-    key: 'timeEnd',
+    key: "timeEnd",
     value: function timeEnd(name) {
       if (!this.enabled) {
         return;
       }
+
       if (!(name in this.started)) {
         (0, _util.warn)('Timer has not been started for ' + name);
       }
+
       this.times.push({
         'name': name,
         'start': this.started[name],
@@ -251,22 +423,26 @@ var StatTimer = function () {
       delete this.started[name];
     }
   }, {
-    key: 'toString',
+    key: "toString",
     value: function toString() {
       var times = this.times;
       var out = '',
           longest = 0;
+
       for (var i = 0, ii = times.length; i < ii; ++i) {
         var name = times[i]['name'];
+
         if (name.length > longest) {
           longest = name.length;
         }
       }
+
       for (var _i = 0, _ii = times.length; _i < _ii; ++_i) {
         var span = times[_i];
         var duration = span.end - span.start;
-        out += span['name'].padEnd(longest) + ' ' + duration + 'ms\n';
+        out += "".concat(span['name'].padEnd(longest), " ").concat(duration, "ms\n");
       }
+
       return out;
     }
   }]);
@@ -274,7 +450,11 @@ var StatTimer = function () {
   return StatTimer;
 }();
 
-var DummyStatTimer = function () {
+exports.StatTimer = StatTimer;
+
+var DummyStatTimer =
+/*#__PURE__*/
+function () {
   function DummyStatTimer() {
     _classCallCheck(this, DummyStatTimer);
 
@@ -282,13 +462,13 @@ var DummyStatTimer = function () {
   }
 
   _createClass(DummyStatTimer, null, [{
-    key: 'time',
+    key: "time",
     value: function time(name) {}
   }, {
-    key: 'timeEnd',
+    key: "timeEnd",
     value: function timeEnd(name) {}
   }, {
-    key: 'toString',
+    key: "toString",
     value: function toString() {
       return '';
     }
@@ -297,13 +477,18 @@ var DummyStatTimer = function () {
   return DummyStatTimer;
 }();
 
-exports.RenderingCancelledException = RenderingCancelledException;
-exports.addLinkAttributes = addLinkAttributes;
-exports.getFilenameFromUrl = getFilenameFromUrl;
-exports.LinkTarget = LinkTarget;
-exports.DEFAULT_LINK_REL = DEFAULT_LINK_REL;
-exports.DOMCanvasFactory = DOMCanvasFactory;
-exports.DOMCMapReaderFactory = DOMCMapReaderFactory;
-exports.DOMSVGFactory = DOMSVGFactory;
-exports.StatTimer = StatTimer;
-exports.DummyStatTimer = DummyStatTimer;
+exports.DummyStatTimer = DummyStatTimer;
+
+function loadScript(src) {
+  return new Promise(function (resolve, reject) {
+    var script = document.createElement('script');
+    script.src = src;
+    script.onload = resolve;
+
+    script.onerror = function () {
+      reject(new Error("Cannot load script at: ".concat(script.src)));
+    };
+
+    (document.head || document.documentElement).appendChild(script);
+  });
+}

+ 208 - 84
lib/display/fetch_stream.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,32 +19,45 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.PDFFetchStream = undefined;
+exports.PDFFetchStream = void 0;
 
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
 
-var _util = require('../shared/util');
+var _util = require("../shared/util");
 
-var _network_utils = require('./network_utils');
+var _network_utils = require("./network_utils");
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
+
+function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
 
 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
-function createFetchOptions(headers, withCredentials) {
+function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
+
+function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
+
+function createFetchOptions(headers, withCredentials, abortController) {
   return {
     method: 'GET',
     headers: headers,
+    signal: abortController && abortController.signal,
     mode: 'cors',
     credentials: withCredentials ? 'include' : 'same-origin',
     redirect: 'follow'
   };
 }
 
-var PDFFetchStream = function () {
+var PDFFetchStream =
+/*#__PURE__*/
+function () {
   function PDFFetchStream(source) {
     _classCallCheck(this, PDFFetchStream);
 
@@ -56,26 +69,30 @@ var PDFFetchStream = function () {
   }
 
   _createClass(PDFFetchStream, [{
-    key: 'getFullReader',
+    key: "getFullReader",
     value: function getFullReader() {
       (0, _util.assert)(!this._fullRequestReader);
       this._fullRequestReader = new PDFFetchStreamReader(this);
       return this._fullRequestReader;
     }
   }, {
-    key: 'getRangeReader',
+    key: "getRangeReader",
     value: function getRangeReader(begin, end) {
       var reader = new PDFFetchStreamRangeReader(this, begin, end);
+
       this._rangeRequestReaders.push(reader);
+
       return reader;
     }
   }, {
-    key: 'cancelAllRequests',
+    key: "cancelAllRequests",
     value: function cancelAllRequests(reason) {
       if (this._fullRequestReader) {
         this._fullRequestReader.cancel(reason);
       }
+
       var readers = this._rangeRequestReaders.slice(0);
+
       readers.forEach(function (reader) {
         reader.cancel(reason);
       });
@@ -85,7 +102,11 @@ var PDFFetchStream = function () {
   return PDFFetchStream;
 }();
 
-var PDFFetchStreamReader = function () {
+exports.PDFFetchStream = PDFFetchStream;
+
+var PDFFetchStreamReader =
+/*#__PURE__*/
+function () {
   function PDFFetchStreamReader(stream) {
     var _this = this;
 
@@ -101,26 +122,39 @@ var PDFFetchStreamReader = function () {
     this._headersCapability = (0, _util.createPromiseCapability)();
     this._disableRange = source.disableRange || false;
     this._rangeChunkSize = source.rangeChunkSize;
+
     if (!this._rangeChunkSize && !this._disableRange) {
       this._disableRange = true;
     }
+
+    if (typeof AbortController !== 'undefined') {
+      this._abortController = new AbortController();
+    }
+
     this._isStreamingSupported = !source.disableStream;
     this._isRangeSupported = !source.disableRange;
     this._headers = new Headers();
+
     for (var property in this._stream.httpHeaders) {
       var value = this._stream.httpHeaders[property];
+
       if (typeof value === 'undefined') {
         continue;
       }
+
       this._headers.append(property, value);
     }
+
     var url = source.url;
-    fetch(url, createFetchOptions(this._headers, this._withCredentials)).then(function (response) {
+    fetch(url, createFetchOptions(this._headers, this._withCredentials, this._abortController)).then(function (response) {
       if (!(0, _network_utils.validateResponseStatus)(response.status)) {
         throw (0, _network_utils.createResponseStatusError)(response.status, url);
       }
+
       _this._reader = response.body.getReader();
+
       _this._headersCapability.resolve();
+
       var getResponseHeader = function getResponseHeader(name) {
         return response.headers.get(name);
       };
@@ -137,6 +171,7 @@ var PDFFetchStreamReader = function () {
       _this._isRangeSupported = allowRangeRequests;
       _this._contentLength = suggestedLength || _this._contentLength;
       _this._filename = (0, _network_utils.extractFilenameFromHeader)(getResponseHeader);
+
       if (!_this._isStreamingSupported && _this._isRangeSupported) {
         _this.cancel(new _util.AbortException('streaming is disabled'));
       }
@@ -145,65 +180,102 @@ var PDFFetchStreamReader = function () {
   }
 
   _createClass(PDFFetchStreamReader, [{
-    key: 'read',
-    value: function read() {
-      var _this2 = this;
-
-      return this._headersCapability.promise.then(function () {
-        return _this2._reader.read().then(function (_ref) {
-          var value = _ref.value,
-              done = _ref.done;
-
-          if (done) {
-            return Promise.resolve({
-              value: value,
-              done: done
-            });
-          }
-          _this2._loaded += value.byteLength;
-          if (_this2.onProgress) {
-            _this2.onProgress({
-              loaded: _this2._loaded,
-              total: _this2._contentLength
-            });
+    key: "read",
+    value: function () {
+      var _read = _asyncToGenerator(
+      /*#__PURE__*/
+      _regenerator.default.mark(function _callee() {
+        var _ref, value, done, buffer;
+
+        return _regenerator.default.wrap(function _callee$(_context) {
+          while (1) {
+            switch (_context.prev = _context.next) {
+              case 0:
+                _context.next = 2;
+                return this._headersCapability.promise;
+
+              case 2:
+                _context.next = 4;
+                return this._reader.read();
+
+              case 4:
+                _ref = _context.sent;
+                value = _ref.value;
+                done = _ref.done;
+
+                if (!done) {
+                  _context.next = 9;
+                  break;
+                }
+
+                return _context.abrupt("return", {
+                  value: value,
+                  done: done
+                });
+
+              case 9:
+                this._loaded += value.byteLength;
+
+                if (this.onProgress) {
+                  this.onProgress({
+                    loaded: this._loaded,
+                    total: this._contentLength
+                  });
+                }
+
+                buffer = new Uint8Array(value).buffer;
+                return _context.abrupt("return", {
+                  value: buffer,
+                  done: false
+                });
+
+              case 13:
+              case "end":
+                return _context.stop();
+            }
           }
-          var buffer = new Uint8Array(value).buffer;
-          return Promise.resolve({
-            value: buffer,
-            done: false
-          });
-        });
-      });
-    }
+        }, _callee, this);
+      }));
+
+      function read() {
+        return _read.apply(this, arguments);
+      }
+
+      return read;
+    }()
   }, {
-    key: 'cancel',
+    key: "cancel",
     value: function cancel(reason) {
       if (this._reader) {
         this._reader.cancel(reason);
       }
+
+      if (this._abortController) {
+        this._abortController.abort();
+      }
     }
   }, {
-    key: 'headersReady',
+    key: "headersReady",
     get: function get() {
       return this._headersCapability.promise;
     }
   }, {
-    key: 'filename',
+    key: "filename",
     get: function get() {
       return this._filename;
     }
   }, {
-    key: 'contentLength',
+    key: "contentLength",
     get: function get() {
       return this._contentLength;
     }
   }, {
-    key: 'isRangeSupported',
+    key: "isRangeSupported",
     get: function get() {
       return this._isRangeSupported;
     }
   }, {
-    key: 'isStreamingSupported',
+    key: "isStreamingSupported",
     get: function get() {
       return this._isStreamingSupported;
     }
@@ -212,9 +284,11 @@ var PDFFetchStreamReader = function () {
   return PDFFetchStreamReader;
 }();
 
-var PDFFetchStreamRangeReader = function () {
+var PDFFetchStreamRangeReader =
+/*#__PURE__*/
+function () {
   function PDFFetchStreamRangeReader(stream, begin, end) {
-    var _this3 = this;
+    var _this2 = this;
 
     _classCallCheck(this, PDFFetchStreamRangeReader);
 
@@ -225,70 +299,120 @@ var PDFFetchStreamRangeReader = function () {
     this._withCredentials = source.withCredentials;
     this._readCapability = (0, _util.createPromiseCapability)();
     this._isStreamingSupported = !source.disableStream;
+
+    if (typeof AbortController !== 'undefined') {
+      this._abortController = new AbortController();
+    }
+
     this._headers = new Headers();
+
     for (var property in this._stream.httpHeaders) {
       var value = this._stream.httpHeaders[property];
+
       if (typeof value === 'undefined') {
         continue;
       }
+
       this._headers.append(property, value);
     }
+
     var rangeStr = begin + '-' + (end - 1);
+
     this._headers.append('Range', 'bytes=' + rangeStr);
+
     var url = source.url;
-    fetch(url, createFetchOptions(this._headers, this._withCredentials)).then(function (response) {
+    fetch(url, createFetchOptions(this._headers, this._withCredentials, this._abortController)).then(function (response) {
       if (!(0, _network_utils.validateResponseStatus)(response.status)) {
         throw (0, _network_utils.createResponseStatusError)(response.status, url);
       }
-      _this3._readCapability.resolve();
-      _this3._reader = response.body.getReader();
+
+      _this2._readCapability.resolve();
+
+      _this2._reader = response.body.getReader();
     });
     this.onProgress = null;
   }
 
   _createClass(PDFFetchStreamRangeReader, [{
-    key: 'read',
-    value: function read() {
-      var _this4 = this;
-
-      return this._readCapability.promise.then(function () {
-        return _this4._reader.read().then(function (_ref2) {
-          var value = _ref2.value,
-              done = _ref2.done;
-
-          if (done) {
-            return Promise.resolve({
-              value: value,
-              done: done
-            });
-          }
-          _this4._loaded += value.byteLength;
-          if (_this4.onProgress) {
-            _this4.onProgress({ loaded: _this4._loaded });
+    key: "read",
+    value: function () {
+      var _read2 = _asyncToGenerator(
+      /*#__PURE__*/
+      _regenerator.default.mark(function _callee2() {
+        var _ref2, value, done, buffer;
+
+        return _regenerator.default.wrap(function _callee2$(_context2) {
+          while (1) {
+            switch (_context2.prev = _context2.next) {
+              case 0:
+                _context2.next = 2;
+                return this._readCapability.promise;
+
+              case 2:
+                _context2.next = 4;
+                return this._reader.read();
+
+              case 4:
+                _ref2 = _context2.sent;
+                value = _ref2.value;
+                done = _ref2.done;
+
+                if (!done) {
+                  _context2.next = 9;
+                  break;
+                }
+
+                return _context2.abrupt("return", {
+                  value: value,
+                  done: done
+                });
+
+              case 9:
+                this._loaded += value.byteLength;
+
+                if (this.onProgress) {
+                  this.onProgress({
+                    loaded: this._loaded
+                  });
+                }
+
+                buffer = new Uint8Array(value).buffer;
+                return _context2.abrupt("return", {
+                  value: buffer,
+                  done: false
+                });
+
+              case 13:
+              case "end":
+                return _context2.stop();
+            }
           }
-          var buffer = new Uint8Array(value).buffer;
-          return Promise.resolve({
-            value: buffer,
-            done: false
-          });
-        });
-      });
-    }
+        }, _callee2, this);
+      }));
+
+      function read() {
+        return _read2.apply(this, arguments);
+      }
+
+      return read;
+    }()
   }, {
-    key: 'cancel',
+    key: "cancel",
     value: function cancel(reason) {
       if (this._reader) {
         this._reader.cancel(reason);
       }
+
+      if (this._abortController) {
+        this._abortController.abort();
+      }
     }
   }, {
-    key: 'isStreamingSupported',
+    key: "isStreamingSupported",
     get: function get() {
       return this._isStreamingSupported;
     }
   }]);
 
   return PDFFetchStreamRangeReader;
-}();
-
-exports.PDFFetchStream = PDFFetchStream;
+}();

+ 465 - 236
lib/display/font_loader.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,295 +19,524 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.FontLoader = exports.FontFaceObject = undefined;
-
-var _util = require('../shared/util');
-
-function FontLoader(docId) {
-  this.docId = docId;
-  this.styleElement = null;
-  this.nativeFontFaces = [];
-  this.loadTestFontId = 0;
-  this.loadingContext = {
-    requests: [],
-    nextRequestId: 0
-  };
-}
-FontLoader.prototype = {
-  insertRule: function fontLoaderInsertRule(rule) {
-    var styleElement = this.styleElement;
-    if (!styleElement) {
-      styleElement = this.styleElement = document.createElement('style');
-      styleElement.id = 'PDFJS_FONT_STYLE_TAG_' + this.docId;
-      document.documentElement.getElementsByTagName('head')[0].appendChild(styleElement);
-    }
-    var styleSheet = styleElement.sheet;
-    styleSheet.insertRule(rule, styleSheet.cssRules.length);
-  },
-  clear: function fontLoaderClear() {
-    if (this.styleElement) {
-      this.styleElement.remove();
-      this.styleElement = null;
+exports.FontLoader = exports.FontFaceObject = void 0;
+
+var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
+
+var _util = require("../shared/util");
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
+
+function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
+
+function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
+
+function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
+
+function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
+
+function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
+
+function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
+
+function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
+
+var BaseFontLoader =
+/*#__PURE__*/
+function () {
+  function BaseFontLoader(_ref) {
+    var docId = _ref.docId,
+        onUnsupportedFeature = _ref.onUnsupportedFeature;
+
+    _classCallCheck(this, BaseFontLoader);
+
+    if (this.constructor === BaseFontLoader) {
+      (0, _util.unreachable)('Cannot initialize BaseFontLoader.');
     }
-    this.nativeFontFaces.forEach(function (nativeFontFace) {
-      document.fonts.delete(nativeFontFace);
-    });
-    this.nativeFontFaces.length = 0;
+
+    this.docId = docId;
+    this._onUnsupportedFeature = onUnsupportedFeature;
+    this.nativeFontFaces = [];
+    this.styleElement = null;
   }
-};
-{
-  var getLoadTestFont = function getLoadTestFont() {
-    return atob('T1RUTwALAIAAAwAwQ0ZGIDHtZg4AAAOYAAAAgUZGVE1lkzZwAAAEHAAAABxHREVGABQAFQ' + 'AABDgAAAAeT1MvMlYNYwkAAAEgAAAAYGNtYXABDQLUAAACNAAAAUJoZWFk/xVFDQAAALwA' + 'AAA2aGhlYQdkA+oAAAD0AAAAJGhtdHgD6AAAAAAEWAAAAAZtYXhwAAJQAAAAARgAAAAGbm' + 'FtZVjmdH4AAAGAAAAAsXBvc3T/hgAzAAADeAAAACAAAQAAAAEAALZRFsRfDzz1AAsD6AAA' + 'AADOBOTLAAAAAM4KHDwAAAAAA+gDIQAAAAgAAgAAAAAAAAABAAADIQAAAFoD6AAAAAAD6A' + 'ABAAAAAAAAAAAAAAAAAAAAAQAAUAAAAgAAAAQD6AH0AAUAAAKKArwAAACMAooCvAAAAeAA' + 'MQECAAACAAYJAAAAAAAAAAAAAQAAAAAAAAAAAAAAAFBmRWQAwAAuAC4DIP84AFoDIQAAAA' + 'AAAQAAAAAAAAAAACAAIAABAAAADgCuAAEAAAAAAAAAAQAAAAEAAAAAAAEAAQAAAAEAAAAA' + 'AAIAAQAAAAEAAAAAAAMAAQAAAAEAAAAAAAQAAQAAAAEAAAAAAAUAAQAAAAEAAAAAAAYAAQ' + 'AAAAMAAQQJAAAAAgABAAMAAQQJAAEAAgABAAMAAQQJAAIAAgABAAMAAQQJAAMAAgABAAMA' + 'AQQJAAQAAgABAAMAAQQJAAUAAgABAAMAAQQJAAYAAgABWABYAAAAAAAAAwAAAAMAAAAcAA' + 'EAAAAAADwAAwABAAAAHAAEACAAAAAEAAQAAQAAAC7//wAAAC7////TAAEAAAAAAAABBgAA' + 'AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAA' + 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAA' + 'AAAAD/gwAyAAAAAQAAAAAAAAAAAAAAAAAAAAABAAQEAAEBAQJYAAEBASH4DwD4GwHEAvgc' + 'A/gXBIwMAYuL+nz5tQXkD5j3CBLnEQACAQEBIVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWF' + 'hYWFhYWFhYAAABAQAADwACAQEEE/t3Dov6fAH6fAT+fPp8+nwHDosMCvm1Cvm1DAz6fBQA' + 'AAAAAAABAAAAAMmJbzEAAAAAzgTjFQAAAADOBOQpAAEAAAAAAAAADAAUAAQAAAABAAAAAg' + 'ABAAAAAAAAAAAD6AAAAAAAAA==');
-  };
-  Object.defineProperty(FontLoader.prototype, 'loadTestFont', {
-    get: function get() {
-      return (0, _util.shadow)(this, 'loadTestFont', getLoadTestFont());
-    },
-
-    configurable: true
-  });
-  FontLoader.prototype.addNativeFontFace = function fontLoader_addNativeFontFace(nativeFontFace) {
-    this.nativeFontFaces.push(nativeFontFace);
-    document.fonts.add(nativeFontFace);
-  };
-  FontLoader.prototype.bind = function fontLoaderBind(fonts, callback) {
-    var rules = [];
-    var fontsToLoad = [];
-    var fontLoadPromises = [];
-    var getNativeFontPromise = function getNativeFontPromise(nativeFontFace) {
-      return nativeFontFace.loaded.catch(function (e) {
-        (0, _util.warn)('Failed to load font "' + nativeFontFace.family + '": ' + e);
-      });
-    };
-    var isFontLoadingAPISupported = FontLoader.isFontLoadingAPISupported && !FontLoader.isSyncFontLoadingSupported;
-    for (var i = 0, ii = fonts.length; i < ii; i++) {
-      var font = fonts[i];
-      if (font.attached || font.loading === false) {
-        continue;
-      }
-      font.attached = true;
-      if (isFontLoadingAPISupported) {
-        var nativeFontFace = font.createNativeFontFace();
-        if (nativeFontFace) {
-          this.addNativeFontFace(nativeFontFace);
-          fontLoadPromises.push(getNativeFontPromise(nativeFontFace));
-        }
-      } else {
-        var rule = font.createFontFaceRule();
-        if (rule) {
-          this.insertRule(rule);
-          rules.push(rule);
-          fontsToLoad.push(font);
-        }
+
+  _createClass(BaseFontLoader, [{
+    key: "addNativeFontFace",
+    value: function addNativeFontFace(nativeFontFace) {
+      this.nativeFontFaces.push(nativeFontFace);
+      document.fonts.add(nativeFontFace);
+    }
+  }, {
+    key: "insertRule",
+    value: function insertRule(rule) {
+      var styleElement = this.styleElement;
+
+      if (!styleElement) {
+        styleElement = this.styleElement = document.createElement('style');
+        styleElement.id = "PDFJS_FONT_STYLE_TAG_".concat(this.docId);
+        document.documentElement.getElementsByTagName('head')[0].appendChild(styleElement);
       }
+
+      var styleSheet = styleElement.sheet;
+      styleSheet.insertRule(rule, styleSheet.cssRules.length);
     }
-    var request = this.queueLoadingCallback(callback);
-    if (isFontLoadingAPISupported) {
-      Promise.all(fontLoadPromises).then(function () {
-        request.complete();
+  }, {
+    key: "clear",
+    value: function clear() {
+      this.nativeFontFaces.forEach(function (nativeFontFace) {
+        document.fonts.delete(nativeFontFace);
       });
-    } else if (rules.length > 0 && !FontLoader.isSyncFontLoadingSupported) {
-      this.prepareFontLoadEvent(rules, fontsToLoad, request);
-    } else {
-      request.complete();
-    }
-  };
-  FontLoader.prototype.queueLoadingCallback = function FontLoader_queueLoadingCallback(callback) {
-    function LoadLoader_completeRequest() {
-      (0, _util.assert)(!request.end, 'completeRequest() cannot be called twice');
-      request.end = Date.now();
-      while (context.requests.length > 0 && context.requests[0].end) {
-        var otherRequest = context.requests.shift();
-        setTimeout(otherRequest.callback, 0);
+      this.nativeFontFaces.length = 0;
+
+      if (this.styleElement) {
+        this.styleElement.remove();
+        this.styleElement = null;
       }
     }
-    var context = this.loadingContext;
-    var requestId = 'pdfjs-font-loading-' + context.nextRequestId++;
-    var request = {
-      id: requestId,
-      complete: LoadLoader_completeRequest,
-      callback: callback,
-      started: Date.now()
-    };
-    context.requests.push(request);
-    return request;
-  };
-  FontLoader.prototype.prepareFontLoadEvent = function fontLoaderPrepareFontLoadEvent(rules, fonts, request) {
-    function int32(data, offset) {
-      return data.charCodeAt(offset) << 24 | data.charCodeAt(offset + 1) << 16 | data.charCodeAt(offset + 2) << 8 | data.charCodeAt(offset + 3) & 0xff;
-    }
-    function spliceString(s, offset, remove, insert) {
-      var chunk1 = s.substr(0, offset);
-      var chunk2 = s.substr(offset + remove);
-      return chunk1 + insert + chunk2;
-    }
-    var i, ii;
-    var canvas = document.createElement('canvas');
-    canvas.width = 1;
-    canvas.height = 1;
-    var ctx = canvas.getContext('2d');
-    var called = 0;
-    function isFontReady(name, callback) {
-      called++;
-      if (called > 30) {
-        (0, _util.warn)('Load test font never loaded.');
-        callback();
-        return;
-      }
-      ctx.font = '30px ' + name;
-      ctx.fillText('.', 0, 20);
-      var imageData = ctx.getImageData(0, 0, 1, 1);
-      if (imageData.data[3] > 0) {
-        callback();
-        return;
+  }, {
+    key: "bind",
+    value: function () {
+      var _bind = _asyncToGenerator(
+      /*#__PURE__*/
+      _regenerator.default.mark(function _callee(font) {
+        var _this = this;
+
+        var nativeFontFace, rule;
+        return _regenerator.default.wrap(function _callee$(_context) {
+          while (1) {
+            switch (_context.prev = _context.next) {
+              case 0:
+                if (!(font.attached || font.missingFile)) {
+                  _context.next = 2;
+                  break;
+                }
+
+                return _context.abrupt("return");
+
+              case 2:
+                font.attached = true;
+
+                if (!this.isFontLoadingAPISupported) {
+                  _context.next = 19;
+                  break;
+                }
+
+                nativeFontFace = font.createNativeFontFace();
+
+                if (!nativeFontFace) {
+                  _context.next = 18;
+                  break;
+                }
+
+                this.addNativeFontFace(nativeFontFace);
+                _context.prev = 7;
+                _context.next = 10;
+                return nativeFontFace.loaded;
+
+              case 10:
+                _context.next = 18;
+                break;
+
+              case 12:
+                _context.prev = 12;
+                _context.t0 = _context["catch"](7);
+
+                this._onUnsupportedFeature({
+                  featureId: _util.UNSUPPORTED_FEATURES.font
+                });
+
+                (0, _util.warn)("Failed to load font '".concat(nativeFontFace.family, "': '").concat(_context.t0, "'."));
+                font.disableFontFace = true;
+                throw _context.t0;
+
+              case 18:
+                return _context.abrupt("return");
+
+              case 19:
+                rule = font.createFontFaceRule();
+
+                if (!rule) {
+                  _context.next = 25;
+                  break;
+                }
+
+                this.insertRule(rule);
+
+                if (!this.isSyncFontLoadingSupported) {
+                  _context.next = 24;
+                  break;
+                }
+
+                return _context.abrupt("return");
+
+              case 24:
+                return _context.abrupt("return", new Promise(function (resolve) {
+                  var request = _this._queueLoadingCallback(resolve);
+
+                  _this._prepareFontLoadEvent([rule], [font], request);
+                }));
+
+              case 25:
+              case "end":
+                return _context.stop();
+            }
+          }
+        }, _callee, this, [[7, 12]]);
+      }));
+
+      function bind(_x) {
+        return _bind.apply(this, arguments);
       }
-      setTimeout(isFontReady.bind(null, name, callback));
+
+      return bind;
+    }()
+  }, {
+    key: "_queueLoadingCallback",
+    value: function _queueLoadingCallback(callback) {
+      (0, _util.unreachable)('Abstract method `_queueLoadingCallback`.');
     }
-    var loadTestFontId = 'lt' + Date.now() + this.loadTestFontId++;
-    var data = this.loadTestFont;
-    var COMMENT_OFFSET = 976;
-    data = spliceString(data, COMMENT_OFFSET, loadTestFontId.length, loadTestFontId);
-    var CFF_CHECKSUM_OFFSET = 16;
-    var XXXX_VALUE = 0x58585858;
-    var checksum = int32(data, CFF_CHECKSUM_OFFSET);
-    for (i = 0, ii = loadTestFontId.length - 3; i < ii; i += 4) {
-      checksum = checksum - XXXX_VALUE + int32(loadTestFontId, i) | 0;
+  }, {
+    key: "_prepareFontLoadEvent",
+    value: function _prepareFontLoadEvent(rules, fontsToLoad, request) {
+      (0, _util.unreachable)('Abstract method `_prepareFontLoadEvent`.');
     }
-    if (i < loadTestFontId.length) {
-      checksum = checksum - XXXX_VALUE + int32(loadTestFontId + 'XXX', i) | 0;
+  }, {
+    key: "isFontLoadingAPISupported",
+    get: function get() {
+      (0, _util.unreachable)('Abstract method `isFontLoadingAPISupported`.');
     }
-    data = spliceString(data, CFF_CHECKSUM_OFFSET, 4, (0, _util.string32)(checksum));
-    var url = 'url(data:font/opentype;base64,' + btoa(data) + ');';
-    var rule = '@font-face { font-family:"' + loadTestFontId + '";src:' + url + '}';
-    this.insertRule(rule);
-    var names = [];
-    for (i = 0, ii = fonts.length; i < ii; i++) {
-      names.push(fonts[i].loadedName);
+  }, {
+    key: "isSyncFontLoadingSupported",
+    get: function get() {
+      (0, _util.unreachable)('Abstract method `isSyncFontLoadingSupported`.');
     }
-    names.push(loadTestFontId);
-    var div = document.createElement('div');
-    div.setAttribute('style', 'visibility: hidden;' + 'width: 10px; height: 10px;' + 'position: absolute; top: 0px; left: 0px;');
-    for (i = 0, ii = names.length; i < ii; ++i) {
-      var span = document.createElement('span');
-      span.textContent = 'Hi';
-      span.style.fontFamily = names[i];
-      div.appendChild(span);
+  }, {
+    key: "_loadTestFont",
+    get: function get() {
+      (0, _util.unreachable)('Abstract method `_loadTestFont`.');
     }
-    document.body.appendChild(div);
-    isFontReady(loadTestFontId, function () {
-      document.body.removeChild(div);
-      request.complete();
-    });
-  };
-}
-{
-  FontLoader.isFontLoadingAPISupported = typeof document !== 'undefined' && !!document.fonts;
-}
+  }]);
+
+  return BaseFontLoader;
+}();
+
+var FontLoader;
+exports.FontLoader = FontLoader;
 {
-  var isSyncFontLoadingSupported = function isSyncFontLoadingSupported() {
-    if (typeof navigator === 'undefined') {
-      return true;
-    }
-    var supported = false;
-    var m = /Mozilla\/5.0.*?rv:(\d+).*? Gecko/.exec(navigator.userAgent);
-    if (m && m[1] >= 14) {
-      supported = true;
+  exports.FontLoader = FontLoader =
+  /*#__PURE__*/
+  function (_BaseFontLoader) {
+    _inherits(GenericFontLoader, _BaseFontLoader);
+
+    function GenericFontLoader(docId) {
+      var _this2;
+
+      _classCallCheck(this, GenericFontLoader);
+
+      _this2 = _possibleConstructorReturn(this, _getPrototypeOf(GenericFontLoader).call(this, docId));
+      _this2.loadingContext = {
+        requests: [],
+        nextRequestId: 0
+      };
+      _this2.loadTestFontId = 0;
+      return _this2;
     }
-    return supported;
-  };
-  Object.defineProperty(FontLoader, 'isSyncFontLoadingSupported', {
-    get: function get() {
-      return (0, _util.shadow)(FontLoader, 'isSyncFontLoadingSupported', isSyncFontLoadingSupported());
-    },
 
-    enumerable: true,
-    configurable: true
-  });
+    _createClass(GenericFontLoader, [{
+      key: "_queueLoadingCallback",
+      value: function _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) {
+            var otherRequest = context.requests.shift();
+            setTimeout(otherRequest.callback, 0);
+          }
+        }
+
+        var context = this.loadingContext;
+        var request = {
+          id: "pdfjs-font-loading-".concat(context.nextRequestId++),
+          done: false,
+          complete: completeRequest,
+          callback: callback
+        };
+        context.requests.push(request);
+        return request;
+      }
+    }, {
+      key: "_prepareFontLoadEvent",
+      value: function _prepareFontLoadEvent(rules, fonts, request) {
+        function int32(data, offset) {
+          return data.charCodeAt(offset) << 24 | data.charCodeAt(offset + 1) << 16 | data.charCodeAt(offset + 2) << 8 | data.charCodeAt(offset + 3) & 0xff;
+        }
+
+        function spliceString(s, offset, remove, insert) {
+          var chunk1 = s.substring(0, offset);
+          var chunk2 = s.substring(offset + remove);
+          return chunk1 + insert + chunk2;
+        }
+
+        var i, ii;
+        var canvas = document.createElement('canvas');
+        canvas.width = 1;
+        canvas.height = 1;
+        var ctx = canvas.getContext('2d');
+        var called = 0;
+
+        function isFontReady(name, callback) {
+          called++;
+
+          if (called > 30) {
+            (0, _util.warn)('Load test font never loaded.');
+            callback();
+            return;
+          }
+
+          ctx.font = '30px ' + name;
+          ctx.fillText('.', 0, 20);
+          var imageData = ctx.getImageData(0, 0, 1, 1);
+
+          if (imageData.data[3] > 0) {
+            callback();
+            return;
+          }
+
+          setTimeout(isFontReady.bind(null, name, callback));
+        }
+
+        var loadTestFontId = "lt".concat(Date.now()).concat(this.loadTestFontId++);
+        var data = this._loadTestFont;
+        var COMMENT_OFFSET = 976;
+        data = spliceString(data, COMMENT_OFFSET, loadTestFontId.length, loadTestFontId);
+        var CFF_CHECKSUM_OFFSET = 16;
+        var XXXX_VALUE = 0x58585858;
+        var checksum = int32(data, CFF_CHECKSUM_OFFSET);
+
+        for (i = 0, ii = loadTestFontId.length - 3; i < ii; i += 4) {
+          checksum = checksum - XXXX_VALUE + int32(loadTestFontId, i) | 0;
+        }
+
+        if (i < loadTestFontId.length) {
+          checksum = checksum - XXXX_VALUE + int32(loadTestFontId + 'XXX', i) | 0;
+        }
+
+        data = spliceString(data, CFF_CHECKSUM_OFFSET, 4, (0, _util.string32)(checksum));
+        var url = "url(data:font/opentype;base64,".concat(btoa(data), ");");
+        var rule = "@font-face {font-family:\"".concat(loadTestFontId, "\";src:").concat(url, "}");
+        this.insertRule(rule);
+        var names = [];
+
+        for (i = 0, ii = fonts.length; i < ii; i++) {
+          names.push(fonts[i].loadedName);
+        }
+
+        names.push(loadTestFontId);
+        var div = document.createElement('div');
+        div.setAttribute('style', 'visibility: hidden;' + 'width: 10px; height: 10px;' + 'position: absolute; top: 0px; left: 0px;');
+
+        for (i = 0, ii = names.length; i < ii; ++i) {
+          var span = document.createElement('span');
+          span.textContent = 'Hi';
+          span.style.fontFamily = names[i];
+          div.appendChild(span);
+        }
+
+        document.body.appendChild(div);
+        isFontReady(loadTestFontId, function () {
+          document.body.removeChild(div);
+          request.complete();
+        });
+      }
+    }, {
+      key: "isFontLoadingAPISupported",
+      get: function get() {
+        var supported = typeof document !== 'undefined' && !!document.fonts;
+
+        if (supported && typeof navigator !== 'undefined') {
+          var m = /Mozilla\/5.0.*?rv:(\d+).*? Gecko/.exec(navigator.userAgent);
+
+          if (m && m[1] < 63) {
+            supported = false;
+          }
+        }
+
+        return (0, _util.shadow)(this, 'isFontLoadingAPISupported', supported);
+      }
+    }, {
+      key: "isSyncFontLoadingSupported",
+      get: function get() {
+        var supported = false;
+
+        if (typeof navigator === 'undefined') {
+          supported = true;
+        } else {
+          var m = /Mozilla\/5.0.*?rv:(\d+).*? Gecko/.exec(navigator.userAgent);
+
+          if (m && m[1] >= 14) {
+            supported = true;
+          }
+        }
+
+        return (0, _util.shadow)(this, 'isSyncFontLoadingSupported', supported);
+      }
+    }, {
+      key: "_loadTestFont",
+      get: function get() {
+        var getLoadTestFont = function getLoadTestFont() {
+          return atob('T1RUTwALAIAAAwAwQ0ZGIDHtZg4AAAOYAAAAgUZGVE1lkzZwAAAEHAAAABxHREVGABQA' + 'FQAABDgAAAAeT1MvMlYNYwkAAAEgAAAAYGNtYXABDQLUAAACNAAAAUJoZWFk/xVFDQAA' + 'ALwAAAA2aGhlYQdkA+oAAAD0AAAAJGhtdHgD6AAAAAAEWAAAAAZtYXhwAAJQAAAAARgA' + 'AAAGbmFtZVjmdH4AAAGAAAAAsXBvc3T/hgAzAAADeAAAACAAAQAAAAEAALZRFsRfDzz1' + 'AAsD6AAAAADOBOTLAAAAAM4KHDwAAAAAA+gDIQAAAAgAAgAAAAAAAAABAAADIQAAAFoD' + '6AAAAAAD6AABAAAAAAAAAAAAAAAAAAAAAQAAUAAAAgAAAAQD6AH0AAUAAAKKArwAAACM' + 'AooCvAAAAeAAMQECAAACAAYJAAAAAAAAAAAAAQAAAAAAAAAAAAAAAFBmRWQAwAAuAC4D' + 'IP84AFoDIQAAAAAAAQAAAAAAAAAAACAAIAABAAAADgCuAAEAAAAAAAAAAQAAAAEAAAAA' + 'AAEAAQAAAAEAAAAAAAIAAQAAAAEAAAAAAAMAAQAAAAEAAAAAAAQAAQAAAAEAAAAAAAUA' + 'AQAAAAEAAAAAAAYAAQAAAAMAAQQJAAAAAgABAAMAAQQJAAEAAgABAAMAAQQJAAIAAgAB' + 'AAMAAQQJAAMAAgABAAMAAQQJAAQAAgABAAMAAQQJAAUAAgABAAMAAQQJAAYAAgABWABY' + 'AAAAAAAAAwAAAAMAAAAcAAEAAAAAADwAAwABAAAAHAAEACAAAAAEAAQAAQAAAC7//wAA' + 'AC7////TAAEAAAAAAAABBgAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + 'AAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAD/gwAyAAAAAQAAAAAAAAAAAAAAAAAA' + 'AAABAAQEAAEBAQJYAAEBASH4DwD4GwHEAvgcA/gXBIwMAYuL+nz5tQXkD5j3CBLnEQAC' + 'AQEBIVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYAAABAQAADwACAQEEE/t3' + 'Dov6fAH6fAT+fPp8+nwHDosMCvm1Cvm1DAz6fBQAAAAAAAABAAAAAMmJbzEAAAAAzgTj' + 'FQAAAADOBOQpAAEAAAAAAAAADAAUAAQAAAABAAAAAgABAAAAAAAAAAAD6AAAAAAAAA==');
+        };
+
+        return (0, _util.shadow)(this, '_loadTestFont', getLoadTestFont());
+      }
+    }]);
+
+    return GenericFontLoader;
+  }(BaseFontLoader);
 }
 var IsEvalSupportedCached = {
   get value() {
     return (0, _util.shadow)(this, 'value', (0, _util.isEvalSupported)());
   }
+
 };
-var FontFaceObject = function FontFaceObjectClosure() {
-  function FontFaceObject(translatedData, _ref) {
-    var _ref$isEvalSupported = _ref.isEvalSupported,
-        isEvalSupported = _ref$isEvalSupported === undefined ? true : _ref$isEvalSupported,
-        _ref$disableFontFace = _ref.disableFontFace,
-        disableFontFace = _ref$disableFontFace === undefined ? false : _ref$disableFontFace,
-        _ref$fontRegistry = _ref.fontRegistry,
-        fontRegistry = _ref$fontRegistry === undefined ? null : _ref$fontRegistry;
+
+var FontFaceObject =
+/*#__PURE__*/
+function () {
+  function FontFaceObject(translatedData, _ref2) {
+    var _ref2$isEvalSupported = _ref2.isEvalSupported,
+        isEvalSupported = _ref2$isEvalSupported === void 0 ? true : _ref2$isEvalSupported,
+        _ref2$disableFontFace = _ref2.disableFontFace,
+        disableFontFace = _ref2$disableFontFace === void 0 ? false : _ref2$disableFontFace,
+        _ref2$ignoreErrors = _ref2.ignoreErrors,
+        ignoreErrors = _ref2$ignoreErrors === void 0 ? false : _ref2$ignoreErrors,
+        _ref2$onUnsupportedFe = _ref2.onUnsupportedFeature,
+        onUnsupportedFeature = _ref2$onUnsupportedFe === void 0 ? null : _ref2$onUnsupportedFe,
+        _ref2$fontRegistry = _ref2.fontRegistry,
+        fontRegistry = _ref2$fontRegistry === void 0 ? null : _ref2$fontRegistry;
+
+    _classCallCheck(this, FontFaceObject);
 
     this.compiledGlyphs = Object.create(null);
+
     for (var 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() {
+
+  _createClass(FontFaceObject, [{
+    key: "createNativeFontFace",
+    value: function createNativeFontFace() {
       if (!this.data || this.disableFontFace) {
         return null;
       }
+
       var nativeFontFace = new FontFace(this.loadedName, this.data, {});
+
       if (this.fontRegistry) {
         this.fontRegistry.registerFont(this);
       }
+
       return nativeFontFace;
-    },
-    createFontFaceRule: function FontFaceObject_createFontFaceRule() {
+    }
+  }, {
+    key: "createFontFaceRule",
+    value: function 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 + '}';
+      var url = "url(data:".concat(this.mimetype, ";base64,").concat(btoa(data), ");");
+      var rule = "@font-face {font-family:\"".concat(this.loadedName, "\";src:").concat(url, "}");
+
       if (this.fontRegistry) {
         this.fontRegistry.registerFont(this, url);
       }
+
       return rule;
-    },
-    getPathGenerator: function FontFaceObject_getPathGenerator(objs, character) {
-      if (!(character in this.compiledGlyphs)) {
-        var cmds = objs.get(this.loadedName + '_path_' + character);
-        var current, i, len;
-        if (this.isEvalSupported && IsEvalSupportedCached.value) {
-          var args,
-              js = '';
-          for (i = 0, len = cmds.length; i < len; i++) {
-            current = cmds[i];
-            if (current.args !== undefined) {
-              args = current.args.join(',');
-            } else {
-              args = '';
-            }
-            js += 'c.' + current.cmd + '(' + args + ');\n';
+    }
+  }, {
+    key: "getPathGenerator",
+    value: function getPathGenerator(objs, character) {
+      if (this.compiledGlyphs[character] !== undefined) {
+        return this.compiledGlyphs[character];
+      }
+
+      var 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: \"".concat(ex, "\"."));
+        return this.compiledGlyphs[character] = function (c, size) {};
+      }
+
+      if (this.isEvalSupported && IsEvalSupportedCached.value) {
+        var args,
+            js = '';
+
+        for (var i = 0, ii = cmds.length; i < ii; i++) {
+          current = cmds[i];
+
+          if (current.args !== undefined) {
+            args = current.args.join(',');
+          } else {
+            args = '';
           }
-          this.compiledGlyphs[character] = new Function('c', 'size', js);
-        } else {
-          this.compiledGlyphs[character] = function (c, size) {
-            for (i = 0, len = cmds.length; i < len; i++) {
-              current = cmds[i];
-              if (current.cmd === 'scale') {
-                current.args = [size, -size];
-              }
-              c[current.cmd].apply(c, current.args);
-            }
-          };
+
+          js += 'c.' + current.cmd + '(' + args + ');\n';
         }
+
+        return this.compiledGlyphs[character] = new Function('c', 'size', js);
       }
-      return this.compiledGlyphs[character];
+
+      return this.compiledGlyphs[character] = function (c, size) {
+        for (var _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;
 }();
-exports.FontFaceObject = FontFaceObject;
-exports.FontLoader = FontLoader;
+
+exports.FontFaceObject = FontFaceObject;

+ 38 - 16
lib/display/metadata.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,22 +19,26 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.Metadata = undefined;
+exports.Metadata = void 0;
 
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+var _util = require("../shared/util");
 
-var _util = require('../shared/util');
-
-var _xml_parser = require('./xml_parser');
+var _xml_parser = require("./xml_parser");
 
 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
-var Metadata = function () {
+function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
+
+function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
+
+var Metadata =
+/*#__PURE__*/
+function () {
   function Metadata(data) {
     _classCallCheck(this, Metadata);
 
@@ -43,64 +47,81 @@ var Metadata = function () {
     var parser = new _xml_parser.SimpleXMLParser();
     var xmlDocument = parser.parseFromString(data);
     this._metadata = Object.create(null);
+
     if (xmlDocument) {
       this._parse(xmlDocument);
     }
   }
 
   _createClass(Metadata, [{
-    key: '_repair',
+    key: "_repair",
     value: function _repair(data) {
-      return data.replace(/>\\376\\377([^<]+)/g, function (all, codes) {
+      return data.replace(/^([^<]+)/, '').replace(/>\\376\\377([^<]+)/g, function (all, codes) {
         var bytes = codes.replace(/\\([0-3])([0-7])([0-7])/g, function (code, d1, d2, d3) {
           return String.fromCharCode(d1 * 64 + d2 * 8 + d3 * 1);
         }).replace(/&(amp|apos|gt|lt|quot);/g, function (str, name) {
           switch (name) {
             case 'amp':
               return '&';
+
             case 'apos':
               return '\'';
+
             case 'gt':
               return '>';
+
             case 'lt':
               return '<';
+
             case 'quot':
               return '\"';
           }
-          throw new Error('_repair: ' + name + ' isn\'t defined.');
+
+          throw new Error("_repair: ".concat(name, " isn't defined."));
         });
         var chars = '';
+
         for (var i = 0, ii = bytes.length; i < ii; i += 2) {
           var code = bytes.charCodeAt(i) * 256 + bytes.charCodeAt(i + 1);
+
           if (code >= 32 && code < 127 && code !== 60 && code !== 62 && code !== 38) {
             chars += String.fromCharCode(code);
           } else {
             chars += '&#x' + (0x10000 + code).toString(16).substring(1) + ';';
           }
         }
+
         return '>' + chars;
       });
     }
   }, {
-    key: '_parse',
+    key: "_parse",
     value: function _parse(xmlDocument) {
       var rdf = xmlDocument.documentElement;
+
       if (rdf.nodeName.toLowerCase() !== 'rdf:rdf') {
         rdf = rdf.firstChild;
+
         while (rdf && rdf.nodeName.toLowerCase() !== 'rdf:rdf') {
           rdf = rdf.nextSibling;
         }
       }
+
       var nodeName = rdf ? rdf.nodeName.toLowerCase() : null;
+
       if (!rdf || nodeName !== 'rdf:rdf' || !rdf.hasChildNodes()) {
         return;
       }
+
       var children = rdf.childNodes;
+
       for (var i = 0, ii = children.length; i < ii; i++) {
         var desc = children[i];
+
         if (desc.nodeName.toLowerCase() !== 'rdf:description') {
           continue;
         }
+
         for (var j = 0, jj = desc.childNodes.length; j < jj; j++) {
           if (desc.childNodes[j].nodeName.toLowerCase() !== '#text') {
             var entry = desc.childNodes[j];
@@ -111,17 +132,18 @@ var Metadata = function () {
       }
     }
   }, {
-    key: 'get',
+    key: "get",
     value: function get(name) {
-      return this._metadata[name] || null;
+      var data = this._metadata[name];
+      return typeof data !== 'undefined' ? data : null;
     }
   }, {
-    key: 'getAll',
+    key: "getAll",
     value: function getAll() {
       return this._metadata;
     }
   }, {
-    key: 'has',
+    key: "has",
     value: function has(name) {
       return typeof this._metadata[name] !== 'undefined';
     }

+ 216 - 51
lib/display/network.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,66 +19,81 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.NetworkManager = exports.PDFNetworkStream = undefined;
+exports.PDFNetworkStream = PDFNetworkStream;
+exports.NetworkManager = NetworkManager;
 
-var _util = require('../shared/util');
+var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
 
-var _network_utils = require('./network_utils');
+var _util = require("../shared/util");
 
-var _global_scope = require('../shared/global_scope');
+var _network_utils = require("./network_utils");
 
-var _global_scope2 = _interopRequireDefault(_global_scope);
+var _global_scope = _interopRequireDefault(require("../shared/global_scope"));
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
+function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
+
+function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
+
 ;
 var OK_RESPONSE = 200;
 var PARTIAL_CONTENT_RESPONSE = 206;
+
 function NetworkManager(url, args) {
   this.url = url;
   args = args || {};
   this.isHttp = /^https?:/i.test(url);
   this.httpHeaders = this.isHttp && args.httpHeaders || {};
   this.withCredentials = args.withCredentials || false;
+
   this.getXhr = args.getXhr || function NetworkManager_getXhr() {
     return new XMLHttpRequest();
   };
+
   this.currXhrId = 0;
   this.pendingRequests = Object.create(null);
   this.loadedRequests = Object.create(null);
 }
+
 function getArrayBuffer(xhr) {
   var data = xhr.response;
+
   if (typeof data !== 'string') {
     return data;
   }
+
   var array = (0, _util.stringToBytes)(data);
   return array.buffer;
 }
+
 var supportsMozChunked = function supportsMozChunkedClosure() {
   try {
     var x = new XMLHttpRequest();
-    x.open('GET', _global_scope2.default.location.href);
+    x.open('GET', _global_scope.default.location.href);
     x.responseType = 'moz-chunked-arraybuffer';
     return x.responseType === 'moz-chunked-arraybuffer';
   } catch (e) {
     return false;
   }
 }();
+
 NetworkManager.prototype = {
   requestRange: function NetworkManager_requestRange(begin, end, listeners) {
     var args = {
       begin: begin,
       end: end
     };
+
     for (var prop in listeners) {
       args[prop] = listeners[prop];
     }
+
     return this.request(args);
   },
   requestFull: function NetworkManager_requestFull(listeners) {
@@ -87,16 +102,22 @@ NetworkManager.prototype = {
   request: function NetworkManager_request(args) {
     var xhr = this.getXhr();
     var xhrId = this.currXhrId++;
-    var pendingRequest = this.pendingRequests[xhrId] = { xhr: xhr };
+    var pendingRequest = this.pendingRequests[xhrId] = {
+      xhr: xhr
+    };
     xhr.open('GET', this.url);
     xhr.withCredentials = this.withCredentials;
+
     for (var property in this.httpHeaders) {
       var value = this.httpHeaders[property];
+
       if (typeof value === 'undefined') {
         continue;
       }
+
       xhr.setRequestHeader(property, value);
     }
+
     if (this.isHttp && 'begin' in args && 'end' in args) {
       var rangeStr = args.begin + '-' + (args.end - 1);
       xhr.setRequestHeader('Range', 'bytes=' + rangeStr);
@@ -104,7 +125,9 @@ NetworkManager.prototype = {
     } else {
       pendingRequest.expectedStatus = 200;
     }
+
     var useMozChunkedLoading = supportsMozChunked && !!args.onProgressiveData;
+
     if (useMozChunkedLoading) {
       xhr.responseType = 'moz-chunked-arraybuffer';
       pendingRequest.onProgressiveData = args.onProgressiveData;
@@ -112,11 +135,13 @@ NetworkManager.prototype = {
     } else {
       xhr.responseType = 'arraybuffer';
     }
+
     if (args.onError) {
       xhr.onerror = function (evt) {
         args.onError(xhr.status);
       };
     }
+
     xhr.onreadystatechange = this.onStateChange.bind(this, xhrId);
     xhr.onprogress = this.onProgress.bind(this, xhrId);
     pendingRequest.onHeadersReceived = args.onHeadersReceived;
@@ -128,51 +153,68 @@ NetworkManager.prototype = {
   },
   onProgress: function NetworkManager_onProgress(xhrId, evt) {
     var pendingRequest = this.pendingRequests[xhrId];
+
     if (!pendingRequest) {
       return;
     }
+
     if (pendingRequest.mozChunked) {
       var chunk = getArrayBuffer(pendingRequest.xhr);
       pendingRequest.onProgressiveData(chunk);
     }
+
     var onProgress = pendingRequest.onProgress;
+
     if (onProgress) {
       onProgress(evt);
     }
   },
   onStateChange: function NetworkManager_onStateChange(xhrId, evt) {
     var pendingRequest = this.pendingRequests[xhrId];
+
     if (!pendingRequest) {
       return;
     }
+
     var xhr = pendingRequest.xhr;
+
     if (xhr.readyState >= 2 && pendingRequest.onHeadersReceived) {
       pendingRequest.onHeadersReceived();
       delete pendingRequest.onHeadersReceived;
     }
+
     if (xhr.readyState !== 4) {
       return;
     }
+
     if (!(xhrId in this.pendingRequests)) {
       return;
     }
+
     delete this.pendingRequests[xhrId];
+
     if (xhr.status === 0 && this.isHttp) {
       if (pendingRequest.onError) {
         pendingRequest.onError(xhr.status);
       }
+
       return;
     }
+
     var xhrStatus = xhr.status || OK_RESPONSE;
     var ok_response_on_range_request = xhrStatus === OK_RESPONSE && pendingRequest.expectedStatus === PARTIAL_CONTENT_RESPONSE;
+
     if (!ok_response_on_range_request && xhrStatus !== pendingRequest.expectedStatus) {
       if (pendingRequest.onError) {
         pendingRequest.onError(xhr.status);
       }
+
       return;
     }
+
     this.loadedRequests[xhrId] = true;
     var chunk = getArrayBuffer(xhr);
+
     if (xhrStatus === PARTIAL_CONTENT_RESPONSE) {
       var rangeHeader = xhr.getResponseHeader('Content-Range');
       var matches = /bytes (\d+)-(\d+)\/(\d+)/.exec(rangeHeader);
@@ -196,6 +238,7 @@ NetworkManager.prototype = {
     for (var xhrId in this.pendingRequests) {
       return true;
     }
+
     return false;
   },
   getRequestXhr: function NetworkManager_getXhr(xhrId) {
@@ -221,6 +264,7 @@ NetworkManager.prototype = {
     xhr.abort();
   }
 };
+
 function PDFNetworkStream(source) {
   this._source = source;
   this._manager = new NetworkManager(source.url, {
@@ -231,9 +275,11 @@ function PDFNetworkStream(source) {
   this._fullRequestReader = null;
   this._rangeRequestReaders = [];
 }
+
 PDFNetworkStream.prototype = {
   _onRangeRequestReaderClosed: function PDFNetworkStream_onRangeRequestReaderClosed(reader) {
     var i = this._rangeRequestReaders.indexOf(reader);
+
     if (i >= 0) {
       this._rangeRequestReaders.splice(i, 1);
     }
@@ -246,19 +292,24 @@ PDFNetworkStream.prototype = {
   getRangeReader: function PDFNetworkStream_getRangeReader(begin, end) {
     var reader = new PDFNetworkStreamRangeRequestReader(this._manager, begin, end);
     reader.onClosed = this._onRangeRequestReaderClosed.bind(this);
+
     this._rangeRequestReaders.push(reader);
+
     return reader;
   },
   cancelAllRequests: function PDFNetworkStream_cancelAllRequests(reason) {
     if (this._fullRequestReader) {
       this._fullRequestReader.cancel(reason);
     }
+
     var readers = this._rangeRequestReaders.slice(0);
+
     readers.forEach(function (reader) {
       reader.cancel(reason);
     });
   }
 };
+
 function PDFNetworkStreamFullRequestReader(manager, source) {
   this._manager = manager;
   var args = {
@@ -274,9 +325,11 @@ function PDFNetworkStreamFullRequestReader(manager, source) {
   this._disableRange = source.disableRange || false;
   this._contentLength = source.length;
   this._rangeChunkSize = source.rangeChunkSize;
+
   if (!this._rangeChunkSize && !this._disableRange) {
     this._disableRange = true;
   }
+
   this._isStreamingSupported = false;
   this._isRangeSupported = false;
   this._cachedChunks = [];
@@ -286,10 +339,13 @@ function PDFNetworkStreamFullRequestReader(manager, source) {
   this._filename = null;
   this.onProgress = null;
 }
+
 PDFNetworkStreamFullRequestReader.prototype = {
   _onHeadersReceived: function PDFNetworkStreamFullRequestReader_onHeadersReceived() {
     var fullRequestXhrId = this._fullRequestId;
+
     var fullRequestXhr = this._manager.getRequestXhr(fullRequestXhrId);
+
     var getResponseHeader = function getResponseHeader(name) {
       return fullRequestXhr.getResponseHeader(name);
     };
@@ -306,19 +362,23 @@ PDFNetworkStreamFullRequestReader.prototype = {
     if (allowRangeRequests) {
       this._isRangeSupported = true;
     }
+
     this._contentLength = suggestedLength || this._contentLength;
     this._filename = (0, _network_utils.extractFilenameFromHeader)(getResponseHeader);
     var networkManager = this._manager;
+
     if (networkManager.isStreamingRequest(fullRequestXhrId)) {
       this._isStreamingSupported = true;
     } else if (this._isRangeSupported) {
       networkManager.abortRequest(fullRequestXhrId);
     }
+
     this._headersReceivedCapability.resolve();
   },
   _onProgressiveData: function PDFNetworkStreamFullRequestReader_onProgressiveData(chunk) {
     if (this._requests.length > 0) {
       var requestCapability = this._requests.shift();
+
       requestCapability.resolve({
         value: chunk,
         done: false
@@ -331,26 +391,33 @@ PDFNetworkStreamFullRequestReader.prototype = {
     if (args) {
       this._onProgressiveData(args.chunk);
     }
+
     this._done = true;
+
     if (this._cachedChunks.length > 0) {
       return;
     }
+
     this._requests.forEach(function (requestCapability) {
       requestCapability.resolve({
         value: undefined,
         done: true
       });
     });
+
     this._requests = [];
   },
   _onError: function PDFNetworkStreamFullRequestReader_onError(status) {
     var url = this._url;
     var exception = (0, _network_utils.createResponseStatusError)(status, url);
     this._storedError = exception;
+
     this._headersReceivedCapability.reject(exception);
+
     this._requests.forEach(function (requestCapability) {
       requestCapability.reject(exception);
     });
+
     this._requests = [];
     this._cachedChunks = [];
   },
@@ -362,58 +429,109 @@ PDFNetworkStreamFullRequestReader.prototype = {
       });
     }
   },
+
   get filename() {
     return this._filename;
   },
+
   get isRangeSupported() {
     return this._isRangeSupported;
   },
+
   get isStreamingSupported() {
     return this._isStreamingSupported;
   },
+
   get contentLength() {
     return this._contentLength;
   },
+
   get headersReady() {
     return this._headersReceivedCapability.promise;
   },
-  read: function PDFNetworkStreamFullRequestReader_read() {
-    if (this._storedError) {
-      return Promise.reject(this._storedError);
-    }
-    if (this._cachedChunks.length > 0) {
-      var chunk = this._cachedChunks.shift();
-      return Promise.resolve({
-        value: chunk,
-        done: false
-      });
-    }
-    if (this._done) {
-      return Promise.resolve({
-        value: undefined,
-        done: true
-      });
+
+  read: function () {
+    var _read = _asyncToGenerator(
+    /*#__PURE__*/
+    _regenerator.default.mark(function _callee() {
+      var chunk, requestCapability;
+      return _regenerator.default.wrap(function _callee$(_context) {
+        while (1) {
+          switch (_context.prev = _context.next) {
+            case 0:
+              if (!this._storedError) {
+                _context.next = 2;
+                break;
+              }
+
+              throw this._storedError;
+
+            case 2:
+              if (!(this._cachedChunks.length > 0)) {
+                _context.next = 5;
+                break;
+              }
+
+              chunk = this._cachedChunks.shift();
+              return _context.abrupt("return", {
+                value: chunk,
+                done: false
+              });
+
+            case 5:
+              if (!this._done) {
+                _context.next = 7;
+                break;
+              }
+
+              return _context.abrupt("return", {
+                value: undefined,
+                done: true
+              });
+
+            case 7:
+              requestCapability = (0, _util.createPromiseCapability)();
+
+              this._requests.push(requestCapability);
+
+              return _context.abrupt("return", requestCapability.promise);
+
+            case 10:
+            case "end":
+              return _context.stop();
+          }
+        }
+      }, _callee, this);
+    }));
+
+    function read() {
+      return _read.apply(this, arguments);
     }
-    var requestCapability = (0, _util.createPromiseCapability)();
-    this._requests.push(requestCapability);
-    return requestCapability.promise;
-  },
+
+    return read;
+  }(),
   cancel: function PDFNetworkStreamFullRequestReader_cancel(reason) {
     this._done = true;
+
     this._headersReceivedCapability.reject(reason);
+
     this._requests.forEach(function (requestCapability) {
       requestCapability.resolve({
         value: undefined,
         done: true
       });
     });
+
     this._requests = [];
+
     if (this._manager.isPendingRequest(this._fullRequestId)) {
       this._manager.abortRequest(this._fullRequestId);
     }
+
     this._fullRequestReader = null;
   }
 };
+
 function PDFNetworkStreamRangeRequestReader(manager, begin, end) {
   this._manager = manager;
   var args = {
@@ -427,6 +545,7 @@ function PDFNetworkStreamRangeRequestReader(manager, begin, end) {
   this.onProgress = null;
   this.onClosed = null;
 }
+
 PDFNetworkStreamRangeRequestReader.prototype = {
   _close: function PDFNetworkStreamRangeRequestReader_close() {
     if (this.onClosed) {
@@ -435,8 +554,10 @@ PDFNetworkStreamRangeRequestReader.prototype = {
   },
   _onDone: function PDFNetworkStreamRangeRequestReader_onDone(data) {
     var chunk = data.chunk;
+
     if (this._requests.length > 0) {
       var requestCapability = this._requests.shift();
+
       requestCapability.resolve({
         value: chunk,
         done: false
@@ -444,57 +565,101 @@ PDFNetworkStreamRangeRequestReader.prototype = {
     } else {
       this._queuedChunk = chunk;
     }
+
     this._done = true;
+
     this._requests.forEach(function (requestCapability) {
       requestCapability.resolve({
         value: undefined,
         done: true
       });
     });
+
     this._requests = [];
+
     this._close();
   },
   _onProgress: function PDFNetworkStreamRangeRequestReader_onProgress(evt) {
     if (!this.isStreamingSupported && this.onProgress) {
-      this.onProgress({ loaded: evt.loaded });
+      this.onProgress({
+        loaded: evt.loaded
+      });
     }
   },
+
   get isStreamingSupported() {
     return false;
   },
-  read: function PDFNetworkStreamRangeRequestReader_read() {
-    if (this._queuedChunk !== null) {
-      var chunk = this._queuedChunk;
-      this._queuedChunk = null;
-      return Promise.resolve({
-        value: chunk,
-        done: false
-      });
-    }
-    if (this._done) {
-      return Promise.resolve({
-        value: undefined,
-        done: true
-      });
+
+  read: function () {
+    var _read2 = _asyncToGenerator(
+    /*#__PURE__*/
+    _regenerator.default.mark(function _callee2() {
+      var chunk, requestCapability;
+      return _regenerator.default.wrap(function _callee2$(_context2) {
+        while (1) {
+          switch (_context2.prev = _context2.next) {
+            case 0:
+              if (!(this._queuedChunk !== null)) {
+                _context2.next = 4;
+                break;
+              }
+
+              chunk = this._queuedChunk;
+              this._queuedChunk = null;
+              return _context2.abrupt("return", {
+                value: chunk,
+                done: false
+              });
+
+            case 4:
+              if (!this._done) {
+                _context2.next = 6;
+                break;
+              }
+
+              return _context2.abrupt("return", {
+                value: undefined,
+                done: true
+              });
+
+            case 6:
+              requestCapability = (0, _util.createPromiseCapability)();
+
+              this._requests.push(requestCapability);
+
+              return _context2.abrupt("return", requestCapability.promise);
+
+            case 9:
+            case "end":
+              return _context2.stop();
+          }
+        }
+      }, _callee2, this);
+    }));
+
+    function read() {
+      return _read2.apply(this, arguments);
     }
-    var requestCapability = (0, _util.createPromiseCapability)();
-    this._requests.push(requestCapability);
-    return requestCapability.promise;
-  },
+
+    return read;
+  }(),
   cancel: function PDFNetworkStreamRangeRequestReader_cancel(reason) {
     this._done = true;
+
     this._requests.forEach(function (requestCapability) {
       requestCapability.resolve({
         value: undefined,
         done: true
       });
     });
+
     this._requests = [];
+
     if (this._manager.isPendingRequest(this._requestId)) {
       this._manager.abortRequest(this._requestId);
     }
+
     this._close();
   }
-};
-exports.PDFNetworkStream = PDFNetworkStream;
-exports.NetworkManager = NetworkManager;
+};

+ 32 - 19
lib/display/network_utils.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,69 +19,82 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.validateResponseStatus = exports.validateRangeRequestCapabilities = exports.extractFilenameFromHeader = exports.createResponseStatusError = undefined;
+exports.createResponseStatusError = createResponseStatusError;
+exports.extractFilenameFromHeader = extractFilenameFromHeader;
+exports.validateRangeRequestCapabilities = validateRangeRequestCapabilities;
+exports.validateResponseStatus = validateResponseStatus;
 
-var _util = require('../shared/util');
+var _util = require("../shared/util");
 
-var _content_disposition = require('./content_disposition');
+var _content_disposition = require("./content_disposition");
 
 function validateRangeRequestCapabilities(_ref) {
   var getResponseHeader = _ref.getResponseHeader,
       isHttp = _ref.isHttp,
       rangeChunkSize = _ref.rangeChunkSize,
       disableRange = _ref.disableRange;
-
   (0, _util.assert)(rangeChunkSize > 0, 'Range chunk size must be larger than zero');
   var returnValues = {
     allowRangeRequests: false,
     suggestedLength: undefined
   };
-  if (disableRange || !isHttp) {
+  var length = parseInt(getResponseHeader('Content-Length'), 10);
+
+  if (!Number.isInteger(length)) {
     return returnValues;
   }
-  if (getResponseHeader('Accept-Ranges') !== 'bytes') {
+
+  returnValues.suggestedLength = length;
+
+  if (length <= 2 * rangeChunkSize) {
     return returnValues;
   }
-  var contentEncoding = getResponseHeader('Content-Encoding') || 'identity';
-  if (contentEncoding !== 'identity') {
+
+  if (disableRange || !isHttp) {
     return returnValues;
   }
-  var length = parseInt(getResponseHeader('Content-Length'), 10);
-  if (!Number.isInteger(length)) {
+
+  if (getResponseHeader('Accept-Ranges') !== 'bytes') {
     return returnValues;
   }
-  returnValues.suggestedLength = length;
-  if (length <= 2 * rangeChunkSize) {
+
+  var contentEncoding = getResponseHeader('Content-Encoding') || 'identity';
+
+  if (contentEncoding !== 'identity') {
     return returnValues;
   }
+
   returnValues.allowRangeRequests = true;
   return returnValues;
 }
+
 function extractFilenameFromHeader(getResponseHeader) {
   var contentDisposition = getResponseHeader('Content-Disposition');
+
   if (contentDisposition) {
     var filename = (0, _content_disposition.getFilenameFromContentDispositionHeader)(contentDisposition);
+
     if (/\.pdf$/i.test(filename)) {
       return filename;
     }
   }
+
   return null;
 }
+
 function createResponseStatusError(status, url) {
   if (status === 404 || status === 0 && /^file:/.test(url)) {
     return new _util.MissingPDFException('Missing PDF "' + url + '".');
   }
+
   return new _util.UnexpectedResponseException('Unexpected server response (' + status + ') while retrieving PDF "' + url + '".', status);
 }
+
 function validateResponseStatus(status) {
   return status === 200 || status === 206;
-}
-exports.createResponseStatusError = createResponseStatusError;
-exports.extractFilenameFromHeader = extractFilenameFromHeader;
-exports.validateRangeRequestCapabilities = validateRangeRequestCapabilities;
-exports.validateResponseStatus = validateResponseStatus;
+}

+ 352 - 169
lib/display/node_stream.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,46 +19,74 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.PDFNodeStream = undefined;
+exports.PDFNodeStream = void 0;
 
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
 
-var _util = require('../shared/util');
+var _util = require("../shared/util");
 
-var _network_utils = require('./network_utils');
+var _network_utils = require("./network_utils");
 
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
+
+function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
+
+function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
+
+function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
+
+function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
+
+function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
+
+function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
 
 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
+function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
+
+function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
+
 var fs = require('fs');
+
 var http = require('http');
+
 var https = require('https');
+
 var url = require('url');
 
 var fileUriRegex = /^file:\/\/\/[a-zA-Z]:\//;
+
 function parseUrl(sourceUrl) {
   var parsedUrl = url.parse(sourceUrl);
+
   if (parsedUrl.protocol === 'file:' || parsedUrl.host) {
     return parsedUrl;
   }
+
   if (/^[a-z]:[/\\]/i.test(sourceUrl)) {
-    return url.parse('file:///' + sourceUrl);
+    return url.parse("file:///".concat(sourceUrl));
   }
+
   if (!parsedUrl.host) {
     parsedUrl.protocol = 'file:';
   }
+
   return parsedUrl;
 }
 
-var PDFNodeStream = function () {
+var PDFNodeStream =
+/*#__PURE__*/
+function () {
   function PDFNodeStream(source) {
     _classCallCheck(this, PDFNodeStream);
 
@@ -72,26 +100,30 @@ var PDFNodeStream = function () {
   }
 
   _createClass(PDFNodeStream, [{
-    key: 'getFullReader',
+    key: "getFullReader",
     value: function getFullReader() {
       (0, _util.assert)(!this._fullRequest);
       this._fullRequest = this.isFsUrl ? new PDFNodeStreamFsFullReader(this) : new PDFNodeStreamFullReader(this);
       return this._fullRequest;
     }
   }, {
-    key: 'getRangeReader',
+    key: "getRangeReader",
     value: function getRangeReader(start, end) {
       var rangeReader = this.isFsUrl ? new PDFNodeStreamFsRangeReader(this, start, end) : new PDFNodeStreamRangeReader(this, start, end);
+
       this._rangeRequestReaders.push(rangeReader);
+
       return rangeReader;
     }
   }, {
-    key: 'cancelAllRequests',
+    key: "cancelAllRequests",
     value: function cancelAllRequests(reason) {
       if (this._fullRequest) {
         this._fullRequest.cancel(reason);
       }
+
       var readers = this._rangeRequestReaders.slice(0);
+
       readers.forEach(function (reader) {
         reader.cancel(reason);
       });
@@ -101,14 +133,17 @@ var PDFNodeStream = function () {
   return PDFNodeStream;
 }();
 
-var BaseFullReader = function () {
+exports.PDFNodeStream = PDFNodeStream;
+
+var BaseFullReader =
+/*#__PURE__*/
+function () {
   function BaseFullReader(stream) {
     _classCallCheck(this, BaseFullReader);
 
     this._url = stream.url;
     this._done = false;
-    this._errored = false;
-    this._reason = null;
+    this._storedError = null;
     this.onProgress = null;
     var source = stream.source;
     this._contentLength = source.length;
@@ -116,9 +151,11 @@ var BaseFullReader = function () {
     this._filename = null;
     this._disableRange = source.disableRange || false;
     this._rangeChunkSize = source.rangeChunkSize;
+
     if (!this._rangeChunkSize && !this._disableRange) {
       this._disableRange = true;
     }
+
     this._isStreamingSupported = !source.disableStream;
     this._isRangeSupported = !source.disableRange;
     this._readableStream = null;
@@ -127,101 +164,146 @@ var BaseFullReader = function () {
   }
 
   _createClass(BaseFullReader, [{
-    key: 'read',
-    value: function read() {
-      var _this = this;
+    key: "read",
+    value: function () {
+      var _read = _asyncToGenerator(
+      /*#__PURE__*/
+      _regenerator.default.mark(function _callee() {
+        var chunk, buffer;
+        return _regenerator.default.wrap(function _callee$(_context) {
+          while (1) {
+            switch (_context.prev = _context.next) {
+              case 0:
+                _context.next = 2;
+                return this._readCapability.promise;
+
+              case 2:
+                if (!this._done) {
+                  _context.next = 4;
+                  break;
+                }
+
+                return _context.abrupt("return", {
+                  value: undefined,
+                  done: true
+                });
+
+              case 4:
+                if (!this._storedError) {
+                  _context.next = 6;
+                  break;
+                }
+
+                throw this._storedError;
+
+              case 6:
+                chunk = this._readableStream.read();
+
+                if (!(chunk === null)) {
+                  _context.next = 10;
+                  break;
+                }
+
+                this._readCapability = (0, _util.createPromiseCapability)();
+                return _context.abrupt("return", this.read());
+
+              case 10:
+                this._loaded += chunk.length;
+
+                if (this.onProgress) {
+                  this.onProgress({
+                    loaded: this._loaded,
+                    total: this._contentLength
+                  });
+                }
+
+                buffer = new Uint8Array(chunk).buffer;
+                return _context.abrupt("return", {
+                  value: buffer,
+                  done: false
+                });
+
+              case 14:
+              case "end":
+                return _context.stop();
+            }
+          }
+        }, _callee, this);
+      }));
+
+      function read() {
+        return _read.apply(this, arguments);
+      }
 
-      return this._readCapability.promise.then(function () {
-        if (_this._done) {
-          return Promise.resolve({
-            value: undefined,
-            done: true
-          });
-        }
-        if (_this._errored) {
-          return Promise.reject(_this._reason);
-        }
-        var chunk = _this._readableStream.read();
-        if (chunk === null) {
-          _this._readCapability = (0, _util.createPromiseCapability)();
-          return _this.read();
-        }
-        _this._loaded += chunk.length;
-        if (_this.onProgress) {
-          _this.onProgress({
-            loaded: _this._loaded,
-            total: _this._contentLength
-          });
-        }
-        var buffer = new Uint8Array(chunk).buffer;
-        return Promise.resolve({
-          value: buffer,
-          done: false
-        });
-      });
-    }
+      return read;
+    }()
   }, {
-    key: 'cancel',
+    key: "cancel",
     value: function cancel(reason) {
       if (!this._readableStream) {
         this._error(reason);
+
         return;
       }
+
       this._readableStream.destroy(reason);
     }
   }, {
-    key: '_error',
+    key: "_error",
     value: function _error(reason) {
-      this._errored = true;
-      this._reason = reason;
+      this._storedError = reason;
+
       this._readCapability.resolve();
     }
   }, {
-    key: '_setReadableStream',
+    key: "_setReadableStream",
     value: function _setReadableStream(readableStream) {
-      var _this2 = this;
+      var _this = this;
 
       this._readableStream = readableStream;
       readableStream.on('readable', function () {
-        _this2._readCapability.resolve();
+        _this._readCapability.resolve();
       });
       readableStream.on('end', function () {
         readableStream.destroy();
-        _this2._done = true;
-        _this2._readCapability.resolve();
+        _this._done = true;
+
+        _this._readCapability.resolve();
       });
       readableStream.on('error', function (reason) {
-        _this2._error(reason);
+        _this._error(reason);
       });
+
       if (!this._isStreamingSupported && this._isRangeSupported) {
         this._error(new _util.AbortException('streaming is disabled'));
       }
-      if (this._errored) {
-        this._readableStream.destroy(this._reason);
+
+      if (this._storedError) {
+        this._readableStream.destroy(this._storedError);
       }
     }
   }, {
-    key: 'headersReady',
+    key: "headersReady",
     get: function get() {
       return this._headersCapability.promise;
     }
   }, {
-    key: 'filename',
+    key: "filename",
     get: function get() {
       return this._filename;
     }
   }, {
-    key: 'contentLength',
+    key: "contentLength",
     get: function get() {
       return this._contentLength;
     }
   }, {
-    key: 'isRangeSupported',
+    key: "isRangeSupported",
     get: function get() {
       return this._isRangeSupported;
     }
   }, {
-    key: 'isStreamingSupported',
+    key: "isStreamingSupported",
     get: function get() {
       return this._isStreamingSupported;
     }
@@ -230,14 +312,15 @@ var BaseFullReader = function () {
   return BaseFullReader;
 }();
 
-var BaseRangeReader = function () {
+var BaseRangeReader =
+/*#__PURE__*/
+function () {
   function BaseRangeReader(stream) {
     _classCallCheck(this, BaseRangeReader);
 
     this._url = stream.url;
     this._done = false;
-    this._errored = false;
-    this._reason = null;
+    this._storedError = null;
     this.onProgress = null;
     this._loaded = 0;
     this._readableStream = null;
@@ -247,75 +330,121 @@ var BaseRangeReader = function () {
   }
 
   _createClass(BaseRangeReader, [{
-    key: 'read',
-    value: function read() {
-      var _this3 = this;
-
-      return this._readCapability.promise.then(function () {
-        if (_this3._done) {
-          return Promise.resolve({
-            value: undefined,
-            done: true
-          });
-        }
-        if (_this3._errored) {
-          return Promise.reject(_this3._reason);
-        }
-        var chunk = _this3._readableStream.read();
-        if (chunk === null) {
-          _this3._readCapability = (0, _util.createPromiseCapability)();
-          return _this3.read();
-        }
-        _this3._loaded += chunk.length;
-        if (_this3.onProgress) {
-          _this3.onProgress({ loaded: _this3._loaded });
-        }
-        var buffer = new Uint8Array(chunk).buffer;
-        return Promise.resolve({
-          value: buffer,
-          done: false
-        });
-      });
-    }
+    key: "read",
+    value: function () {
+      var _read2 = _asyncToGenerator(
+      /*#__PURE__*/
+      _regenerator.default.mark(function _callee2() {
+        var chunk, buffer;
+        return _regenerator.default.wrap(function _callee2$(_context2) {
+          while (1) {
+            switch (_context2.prev = _context2.next) {
+              case 0:
+                _context2.next = 2;
+                return this._readCapability.promise;
+
+              case 2:
+                if (!this._done) {
+                  _context2.next = 4;
+                  break;
+                }
+
+                return _context2.abrupt("return", {
+                  value: undefined,
+                  done: true
+                });
+
+              case 4:
+                if (!this._storedError) {
+                  _context2.next = 6;
+                  break;
+                }
+
+                throw this._storedError;
+
+              case 6:
+                chunk = this._readableStream.read();
+
+                if (!(chunk === null)) {
+                  _context2.next = 10;
+                  break;
+                }
+
+                this._readCapability = (0, _util.createPromiseCapability)();
+                return _context2.abrupt("return", this.read());
+
+              case 10:
+                this._loaded += chunk.length;
+
+                if (this.onProgress) {
+                  this.onProgress({
+                    loaded: this._loaded
+                  });
+                }
+
+                buffer = new Uint8Array(chunk).buffer;
+                return _context2.abrupt("return", {
+                  value: buffer,
+                  done: false
+                });
+
+              case 14:
+              case "end":
+                return _context2.stop();
+            }
+          }
+        }, _callee2, this);
+      }));
+
+      function read() {
+        return _read2.apply(this, arguments);
+      }
+
+      return read;
+    }()
   }, {
-    key: 'cancel',
+    key: "cancel",
     value: function cancel(reason) {
       if (!this._readableStream) {
         this._error(reason);
+
         return;
       }
+
       this._readableStream.destroy(reason);
     }
   }, {
-    key: '_error',
+    key: "_error",
     value: function _error(reason) {
-      this._errored = true;
-      this._reason = reason;
+      this._storedError = reason;
+
       this._readCapability.resolve();
     }
   }, {
-    key: '_setReadableStream',
+    key: "_setReadableStream",
     value: function _setReadableStream(readableStream) {
-      var _this4 = this;
+      var _this2 = this;
 
       this._readableStream = readableStream;
       readableStream.on('readable', function () {
-        _this4._readCapability.resolve();
+        _this2._readCapability.resolve();
       });
       readableStream.on('end', function () {
         readableStream.destroy();
-        _this4._done = true;
-        _this4._readCapability.resolve();
+        _this2._done = true;
+
+        _this2._readCapability.resolve();
       });
       readableStream.on('error', function (reason) {
-        _this4._error(reason);
+        _this2._error(reason);
       });
-      if (this._errored) {
-        this._readableStream.destroy(this._reason);
+
+      if (this._storedError) {
+        this._readableStream.destroy(this._storedError);
       }
     }
   }, {
-    key: 'isStreamingSupported',
+    key: "isStreamingSupported",
     get: function get() {
       return this._isStreamingSupported;
     }
@@ -336,139 +465,193 @@ function createRequestOptions(url, headers) {
   };
 }
 
-var PDFNodeStreamFullReader = function (_BaseFullReader) {
+var PDFNodeStreamFullReader =
+/*#__PURE__*/
+function (_BaseFullReader) {
   _inherits(PDFNodeStreamFullReader, _BaseFullReader);
 
   function PDFNodeStreamFullReader(stream) {
+    var _this3;
+
     _classCallCheck(this, PDFNodeStreamFullReader);
 
-    var _this5 = _possibleConstructorReturn(this, (PDFNodeStreamFullReader.__proto__ || Object.getPrototypeOf(PDFNodeStreamFullReader)).call(this, stream));
+    _this3 = _possibleConstructorReturn(this, _getPrototypeOf(PDFNodeStreamFullReader).call(this, stream));
 
     var handleResponse = function handleResponse(response) {
-      _this5._headersCapability.resolve();
-      _this5._setReadableStream(response);
+      if (response.statusCode === 404) {
+        var error = new _util.MissingPDFException("Missing PDF \"".concat(_this3._url, "\"."));
+        _this3._storedError = error;
+
+        _this3._headersCapability.reject(error);
+
+        return;
+      }
+
+      _this3._headersCapability.resolve();
+
+      _this3._setReadableStream(response);
+
       var getResponseHeader = function getResponseHeader(name) {
-        return _this5._readableStream.headers[name.toLowerCase()];
+        return _this3._readableStream.headers[name.toLowerCase()];
       };
 
       var _validateRangeRequest = (0, _network_utils.validateRangeRequestCapabilities)({
         getResponseHeader: getResponseHeader,
         isHttp: stream.isHttp,
-        rangeChunkSize: _this5._rangeChunkSize,
-        disableRange: _this5._disableRange
+        rangeChunkSize: _this3._rangeChunkSize,
+        disableRange: _this3._disableRange
       }),
           allowRangeRequests = _validateRangeRequest.allowRangeRequests,
           suggestedLength = _validateRangeRequest.suggestedLength;
 
-      _this5._isRangeSupported = allowRangeRequests;
-      _this5._contentLength = suggestedLength || _this5._contentLength;
-      _this5._filename = (0, _network_utils.extractFilenameFromHeader)(getResponseHeader);
+      _this3._isRangeSupported = allowRangeRequests;
+      _this3._contentLength = suggestedLength || _this3._contentLength;
+      _this3._filename = (0, _network_utils.extractFilenameFromHeader)(getResponseHeader);
     };
-    _this5._request = null;
-    if (_this5._url.protocol === 'http:') {
-      _this5._request = http.request(createRequestOptions(_this5._url, stream.httpHeaders), handleResponse);
+
+    _this3._request = null;
+
+    if (_this3._url.protocol === 'http:') {
+      _this3._request = http.request(createRequestOptions(_this3._url, stream.httpHeaders), handleResponse);
     } else {
-      _this5._request = https.request(createRequestOptions(_this5._url, stream.httpHeaders), handleResponse);
+      _this3._request = https.request(createRequestOptions(_this3._url, stream.httpHeaders), handleResponse);
     }
-    _this5._request.on('error', function (reason) {
-      _this5._errored = true;
-      _this5._reason = reason;
-      _this5._headersCapability.reject(reason);
+
+    _this3._request.on('error', function (reason) {
+      _this3._storedError = reason;
+
+      _this3._headersCapability.reject(reason);
     });
-    _this5._request.end();
-    return _this5;
+
+    _this3._request.end();
+
+    return _this3;
   }
 
   return PDFNodeStreamFullReader;
 }(BaseFullReader);
 
-var PDFNodeStreamRangeReader = function (_BaseRangeReader) {
+var PDFNodeStreamRangeReader =
+/*#__PURE__*/
+function (_BaseRangeReader) {
   _inherits(PDFNodeStreamRangeReader, _BaseRangeReader);
 
   function PDFNodeStreamRangeReader(stream, start, end) {
+    var _this4;
+
     _classCallCheck(this, PDFNodeStreamRangeReader);
 
-    var _this6 = _possibleConstructorReturn(this, (PDFNodeStreamRangeReader.__proto__ || Object.getPrototypeOf(PDFNodeStreamRangeReader)).call(this, stream));
+    _this4 = _possibleConstructorReturn(this, _getPrototypeOf(PDFNodeStreamRangeReader).call(this, stream));
+    _this4._httpHeaders = {};
 
-    _this6._httpHeaders = {};
     for (var property in stream.httpHeaders) {
       var value = stream.httpHeaders[property];
+
       if (typeof value === 'undefined') {
         continue;
       }
-      _this6._httpHeaders[property] = value;
+
+      _this4._httpHeaders[property] = value;
     }
-    _this6._httpHeaders['Range'] = 'bytes=' + start + '-' + (end - 1);
-    _this6._request = null;
-    if (_this6._url.protocol === 'http:') {
-      _this6._request = http.request(createRequestOptions(_this6._url, _this6._httpHeaders), function (response) {
-        _this6._setReadableStream(response);
-      });
+
+    _this4._httpHeaders['Range'] = "bytes=".concat(start, "-").concat(end - 1);
+
+    var handleResponse = function handleResponse(response) {
+      if (response.statusCode === 404) {
+        var error = new _util.MissingPDFException("Missing PDF \"".concat(_this4._url, "\"."));
+        _this4._storedError = error;
+        return;
+      }
+
+      _this4._setReadableStream(response);
+    };
+
+    _this4._request = null;
+
+    if (_this4._url.protocol === 'http:') {
+      _this4._request = http.request(createRequestOptions(_this4._url, _this4._httpHeaders), handleResponse);
     } else {
-      _this6._request = https.request(createRequestOptions(_this6._url, _this6._httpHeaders), function (response) {
-        _this6._setReadableStream(response);
-      });
+      _this4._request = https.request(createRequestOptions(_this4._url, _this4._httpHeaders), handleResponse);
     }
-    _this6._request.on('error', function (reason) {
-      _this6._errored = true;
-      _this6._reason = reason;
+
+    _this4._request.on('error', function (reason) {
+      _this4._storedError = reason;
     });
-    _this6._request.end();
-    return _this6;
+
+    _this4._request.end();
+
+    return _this4;
   }
 
   return PDFNodeStreamRangeReader;
 }(BaseRangeReader);
 
-var PDFNodeStreamFsFullReader = function (_BaseFullReader2) {
+var PDFNodeStreamFsFullReader =
+/*#__PURE__*/
+function (_BaseFullReader2) {
   _inherits(PDFNodeStreamFsFullReader, _BaseFullReader2);
 
   function PDFNodeStreamFsFullReader(stream) {
+    var _this5;
+
     _classCallCheck(this, PDFNodeStreamFsFullReader);
 
-    var _this7 = _possibleConstructorReturn(this, (PDFNodeStreamFsFullReader.__proto__ || Object.getPrototypeOf(PDFNodeStreamFsFullReader)).call(this, stream));
+    _this5 = _possibleConstructorReturn(this, _getPrototypeOf(PDFNodeStreamFsFullReader).call(this, stream));
+    var path = decodeURIComponent(_this5._url.path);
 
-    var path = decodeURIComponent(_this7._url.path);
-    if (fileUriRegex.test(_this7._url.href)) {
+    if (fileUriRegex.test(_this5._url.href)) {
       path = path.replace(/^\//, '');
     }
+
     fs.lstat(path, function (error, stat) {
       if (error) {
-        _this7._errored = true;
-        _this7._reason = error;
-        _this7._headersCapability.reject(error);
+        if (error.code === 'ENOENT') {
+          error = new _util.MissingPDFException("Missing PDF \"".concat(path, "\"."));
+        }
+
+        _this5._storedError = error;
+
+        _this5._headersCapability.reject(error);
+
         return;
       }
-      _this7._contentLength = stat.size;
-      _this7._setReadableStream(fs.createReadStream(path));
-      _this7._headersCapability.resolve();
+
+      _this5._contentLength = stat.size;
+
+      _this5._setReadableStream(fs.createReadStream(path));
+
+      _this5._headersCapability.resolve();
     });
-    return _this7;
+    return _this5;
   }
 
   return PDFNodeStreamFsFullReader;
 }(BaseFullReader);
 
-var PDFNodeStreamFsRangeReader = function (_BaseRangeReader2) {
+var PDFNodeStreamFsRangeReader =
+/*#__PURE__*/
+function (_BaseRangeReader2) {
   _inherits(PDFNodeStreamFsRangeReader, _BaseRangeReader2);
 
   function PDFNodeStreamFsRangeReader(stream, start, end) {
+    var _this6;
+
     _classCallCheck(this, PDFNodeStreamFsRangeReader);
 
-    var _this8 = _possibleConstructorReturn(this, (PDFNodeStreamFsRangeReader.__proto__ || Object.getPrototypeOf(PDFNodeStreamFsRangeReader)).call(this, stream));
+    _this6 = _possibleConstructorReturn(this, _getPrototypeOf(PDFNodeStreamFsRangeReader).call(this, stream));
+    var path = decodeURIComponent(_this6._url.path);
 
-    var path = decodeURIComponent(_this8._url.path);
-    if (fileUriRegex.test(_this8._url.href)) {
+    if (fileUriRegex.test(_this6._url.href)) {
       path = path.replace(/^\//, '');
     }
-    _this8._setReadableStream(fs.createReadStream(path, {
+
+    _this6._setReadableStream(fs.createReadStream(path, {
       start: start,
       end: end - 1
     }));
-    return _this8;
+
+    return _this6;
   }
 
   return PDFNodeStreamFsRangeReader;
-}(BaseRangeReader);
-
-exports.PDFNodeStream = PDFNodeStream;
+}(BaseRangeReader);

+ 58 - 7
lib/display/pattern_helper.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,14 +19,15 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.TilingPattern = exports.getShadingPatternFromIR = undefined;
+exports.getShadingPatternFromIR = getShadingPatternFromIR;
+exports.TilingPattern = void 0;
 
-var _util = require('../shared/util');
+var _util = require("../shared/util");
 
 var ShadingIRs = {};
 ShadingIRs.RadialAxial = {
@@ -41,20 +42,24 @@ ShadingIRs.RadialAxial = {
       type: 'Pattern',
       getPattern: function RadialAxial_getPattern(ctx) {
         var grad;
+
         if (type === 'axial') {
           grad = ctx.createLinearGradient(p0[0], p0[1], p1[0], p1[1]);
         } else if (type === 'radial') {
           grad = ctx.createRadialGradient(p0[0], p0[1], r0, p1[0], p1[1], r1);
         }
+
         for (var i = 0, ii = colorStops.length; i < ii; ++i) {
           var c = colorStops[i];
           grad.addColorStop(c[0], c[1]);
         }
+
         return grad;
       }
     };
   }
 };
+
 var createMeshCanvas = function createMeshCanvasClosure() {
   function drawTriangle(data, context, p1, p2, p3, c1, c2, c3) {
     var coords = context.coords,
@@ -62,6 +67,7 @@ var createMeshCanvas = function createMeshCanvasClosure() {
     var bytes = data.data,
         rowSize = data.width * 4;
     var tmp;
+
     if (coords[p1 + 1] > coords[p2 + 1]) {
       tmp = p1;
       p1 = p2;
@@ -70,6 +76,7 @@ var createMeshCanvas = function createMeshCanvasClosure() {
       c1 = c2;
       c2 = tmp;
     }
+
     if (coords[p2 + 1] > coords[p3 + 1]) {
       tmp = p2;
       p2 = p3;
@@ -78,6 +85,7 @@ var createMeshCanvas = function createMeshCanvasClosure() {
       c2 = c3;
       c3 = tmp;
     }
+
     if (coords[p1 + 1] > coords[p2 + 1]) {
       tmp = p1;
       p1 = p2;
@@ -86,15 +94,18 @@ var createMeshCanvas = function createMeshCanvasClosure() {
       c1 = c2;
       c2 = tmp;
     }
+
     var x1 = (coords[p1] + context.offsetX) * context.scaleX;
     var y1 = (coords[p1 + 1] + context.offsetY) * context.scaleY;
     var x2 = (coords[p2] + context.offsetX) * context.scaleX;
     var y2 = (coords[p2 + 1] + context.offsetY) * context.scaleY;
     var x3 = (coords[p3] + context.offsetX) * context.scaleX;
     var y3 = (coords[p3 + 1] + context.offsetY) * context.scaleY;
+
     if (y1 >= y3) {
       return;
     }
+
     var c1r = colors[c1],
         c1g = colors[c1 + 1],
         c1b = colors[c1 + 2];
@@ -109,6 +120,7 @@ var createMeshCanvas = function createMeshCanvasClosure() {
     var xa, car, cag, cab;
     var xb, cbr, cbg, cbb;
     var k;
+
     for (var y = minY; y <= maxY; y++) {
       if (y < y2) {
         k = y < y1 ? 0 : y1 === y2 ? 1 : (y1 - y) / (y1 - y2);
@@ -123,6 +135,7 @@ var createMeshCanvas = function createMeshCanvasClosure() {
         cag = c2g - (c2g - c3g) * k;
         cab = c2b - (c2b - c3b) * k;
       }
+
       k = y < y1 ? 0 : y > y3 ? 1 : (y1 - y) / (y1 - y3);
       xb = x1 - (x1 - x3) * k;
       cbr = c1r - (c1r - c3r) * k;
@@ -131,6 +144,7 @@ var createMeshCanvas = function createMeshCanvasClosure() {
       var x1_ = Math.round(Math.min(xa, xb));
       var x2_ = Math.round(Math.max(xa, xb));
       var j = rowSize * y + x1_ * 4;
+
       for (var x = x1_; x <= x2_; x++) {
         k = (xa - x) / (xa - xb);
         k = k < 0 ? 0 : k > 1 ? 1 : k;
@@ -141,32 +155,41 @@ var createMeshCanvas = function createMeshCanvasClosure() {
       }
     }
   }
+
   function drawFigure(data, figure, context) {
     var ps = figure.coords;
     var cs = figure.colors;
     var i, ii;
+
     switch (figure.type) {
       case 'lattice':
         var verticesPerRow = figure.verticesPerRow;
         var rows = Math.floor(ps.length / verticesPerRow) - 1;
         var cols = verticesPerRow - 1;
+
         for (i = 0; i < rows; i++) {
           var q = i * verticesPerRow;
+
           for (var j = 0; j < cols; j++, q++) {
             drawTriangle(data, context, ps[q], ps[q + 1], ps[q + verticesPerRow], cs[q], cs[q + 1], cs[q + verticesPerRow]);
             drawTriangle(data, context, ps[q + verticesPerRow + 1], ps[q + 1], ps[q + verticesPerRow], cs[q + verticesPerRow + 1], cs[q + 1], cs[q + verticesPerRow]);
           }
         }
+
         break;
+
       case 'triangles':
         for (i = 0, ii = ps.length; i < ii; i += 3) {
           drawTriangle(data, context, ps[i], ps[i + 1], ps[i + 2], cs[i], cs[i + 1], cs[i + 2]);
         }
+
         break;
+
       default:
         throw new Error('illegal figure');
     }
   }
+
   function createMeshCanvas(bounds, combinesScale, coords, colors, figures, backgroundColor, cachedCanvases, webGLContext) {
     var EXPECTED_SCALE = 1.1;
     var MAX_PATTERN_SIZE = 3000;
@@ -190,6 +213,7 @@ var createMeshCanvas = function createMeshCanvasClosure() {
     var paddedWidth = width + BORDER_SIZE * 2;
     var paddedHeight = height + BORDER_SIZE * 2;
     var canvas, tmpCanvas, i, ii;
+
     if (webGLContext.isEnabled) {
       canvas = webGLContext.drawFigures({
         width: width,
@@ -205,8 +229,10 @@ var createMeshCanvas = function createMeshCanvasClosure() {
       tmpCanvas = cachedCanvases.getCanvas('mesh', paddedWidth, paddedHeight, false);
       var tmpCtx = tmpCanvas.context;
       var data = tmpCtx.createImageData(width, height);
+
       if (backgroundColor) {
         var bytes = data.data;
+
         for (i = 0, ii = bytes.length; i < ii; i += 4) {
           bytes[i] = backgroundColor[0];
           bytes[i + 1] = backgroundColor[1];
@@ -214,12 +240,15 @@ var createMeshCanvas = function createMeshCanvasClosure() {
           bytes[i + 3] = 255;
         }
       }
+
       for (i = 0; i < figures.length; i++) {
         drawFigure(data, figures[i], context);
       }
+
       tmpCtx.putImageData(data, BORDER_SIZE, BORDER_SIZE);
       canvas = tmpCanvas.canvas;
     }
+
     return {
       canvas: canvas,
       offsetX: offsetX - BORDER_SIZE * scaleX,
@@ -228,8 +257,10 @@ var createMeshCanvas = function createMeshCanvasClosure() {
       scaleY: scaleY
     };
   }
+
   return createMeshCanvas;
 }();
+
 ShadingIRs.Mesh = {
   fromIR: function Mesh_fromIR(raw) {
     var coords = raw[2];
@@ -242,22 +273,29 @@ ShadingIRs.Mesh = {
       type: 'Pattern',
       getPattern: function Mesh_getPattern(ctx, owner, shadingFill) {
         var scale;
+
         if (shadingFill) {
           scale = _util.Util.singularValueDecompose2dScale(ctx.mozCurrentTransform);
         } else {
           scale = _util.Util.singularValueDecompose2dScale(owner.baseTransform);
+
           if (matrix) {
             var matrixScale = _util.Util.singularValueDecompose2dScale(matrix);
+
             scale = [scale[0] * matrixScale[0], scale[1] * matrixScale[1]];
           }
         }
+
         var temporaryPatternCanvas = createMeshCanvas(bounds, scale, coords, colors, figures, shadingFill ? null : background, owner.cachedCanvases, owner.webGLContext);
+
         if (!shadingFill) {
           ctx.setTransform.apply(ctx, owner.baseTransform);
+
           if (matrix) {
             ctx.transform.apply(ctx, matrix);
           }
         }
+
         ctx.translate(temporaryPatternCanvas.offsetX, temporaryPatternCanvas.offsetY);
         ctx.scale(temporaryPatternCanvas.scaleX, temporaryPatternCanvas.scaleY);
         return ctx.createPattern(temporaryPatternCanvas.canvas, 'no-repeat');
@@ -275,19 +313,24 @@ ShadingIRs.Dummy = {
     };
   }
 };
+
 function getShadingPatternFromIR(raw) {
   var shadingIR = ShadingIRs[raw[0]];
+
   if (!shadingIR) {
-    throw new Error('Unknown IR type: ' + raw[0]);
+    throw new Error("Unknown IR type: ".concat(raw[0]));
   }
+
   return shadingIR.fromIR(raw);
 }
+
 var TilingPattern = function TilingPatternClosure() {
   var PaintType = {
     COLORED: 1,
     UNCOLORED: 2
   };
   var MAX_PATTERN_SIZE = 3000;
+
   function TilingPattern(IR, color, ctx, canvasGraphicsFactory, baseTransform) {
     this.operatorList = IR[2];
     this.matrix = IR[3] || [1, 0, 0, 1, 0, 0];
@@ -302,6 +345,7 @@ var TilingPattern = function TilingPatternClosure() {
     this.type = 'Pattern';
     this.ctx = ctx;
   }
+
   TilingPattern.prototype = {
     createPatternCanvas: function TilinPattern_createPatternCanvas(owner) {
       var operatorList = this.operatorList;
@@ -321,8 +365,11 @@ var TilingPattern = function TilingPatternClosure() {
       var botRight = [x0 + xstep, y0 + ystep];
       var width = botRight[0] - topLeft[0];
       var height = botRight[1] - topLeft[1];
+
       var matrixScale = _util.Util.singularValueDecompose2dScale(this.matrix);
+
       var curMatrixScale = _util.Util.singularValueDecompose2dScale(this.baseTransform);
+
       var combinedScale = [matrixScale[0] * curMatrixScale[0], matrixScale[1] * curMatrixScale[1]];
       width = Math.min(Math.ceil(Math.abs(width * combinedScale[0])), MAX_PATTERN_SIZE);
       height = Math.min(Math.ceil(Math.abs(height * combinedScale[1])), MAX_PATTERN_SIZE);
@@ -363,6 +410,7 @@ var TilingPattern = function TilingPatternClosure() {
     setFillAndStrokeStyleToContext: function setFillAndStrokeStyleToContext(graphics, paintType, color) {
       var context = graphics.ctx,
           current = graphics.current;
+
       switch (paintType) {
         case PaintType.COLORED:
           var ctx = this.ctx;
@@ -371,15 +419,18 @@ var TilingPattern = function TilingPatternClosure() {
           current.fillColor = ctx.fillStyle;
           current.strokeColor = ctx.strokeStyle;
           break;
+
         case PaintType.UNCOLORED:
           var cssColor = _util.Util.makeCssRgb(color[0], color[1], color[2]);
+
           context.fillStyle = cssColor;
           context.strokeStyle = cssColor;
           current.fillColor = cssColor;
           current.strokeColor = cssColor;
           break;
+
         default:
-          throw new _util.FormatError('Unsupported paint type: ' + paintType);
+          throw new _util.FormatError("Unsupported paint type: ".concat(paintType));
       }
     },
     getPattern: function TilingPattern_getPattern(ctx, owner) {
@@ -393,5 +444,5 @@ var TilingPattern = function TilingPatternClosure() {
   };
   return TilingPattern;
 }();
-exports.getShadingPatternFromIR = getShadingPatternFromIR;
+
 exports.TilingPattern = TilingPattern;

File diff suppressed because it is too large
+ 238 - 26
lib/display/svg.js


+ 132 - 18
lib/display/text_layer.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,30 +19,31 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.renderTextLayer = undefined;
+exports.renderTextLayer = void 0;
 
-var _util = require('../shared/util');
+var _util = require("../shared/util");
 
-var _global_scope = require('../shared/global_scope');
-
-var _global_scope2 = _interopRequireDefault(_global_scope);
+var _global_scope = _interopRequireDefault(require("../shared/global_scope"));
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 var renderTextLayer = function renderTextLayerClosure() {
   var MAX_TEXT_DIVS_TO_RENDER = 100000;
   var NonWhitespaceRegexp = /\S/;
+
   function isAllWhitespace(str) {
     return !NonWhitespaceRegexp.test(str);
   }
+
   var styleBuf = ['left: ', 0, 'px; top: ', 0, 'px; font-size: ', 0, 'px; font-family: ', '', ';'];
+
   function appendText(task, geom, styles) {
-    var textDiv = document.createElement('div');
+    var textDiv = document.createElement('span');
     var textDivProperties = {
       style: null,
       angle: 0,
@@ -55,27 +56,38 @@ var renderTextLayer = function renderTextLayerClosure() {
       paddingTop: 0,
       scale: 1
     };
+
     task._textDivs.push(textDiv);
+
     if (isAllWhitespace(geom.str)) {
       textDivProperties.isWhitespace = true;
+
       task._textDivProperties.set(textDiv, textDivProperties);
+
       return;
     }
+
     var tx = _util.Util.transform(task._viewport.transform, geom.transform);
+
     var angle = Math.atan2(tx[1], tx[0]);
     var style = styles[geom.fontName];
+
     if (style.vertical) {
       angle += Math.PI / 2;
     }
+
     var fontHeight = Math.sqrt(tx[2] * tx[2] + tx[3] * tx[3]);
     var fontAscent = fontHeight;
+
     if (style.ascent) {
       fontAscent = style.ascent * fontAscent;
     } else if (style.descent) {
       fontAscent = (1 + style.descent) * fontAscent;
     }
+
     var left;
     var top;
+
     if (angle === 0) {
       left = tx[4];
       top = tx[5] - fontAscent;
@@ -83,6 +95,7 @@ var renderTextLayer = function renderTextLayerClosure() {
       left = tx[4] + fontAscent * Math.sin(angle);
       top = tx[5] - fontAscent * Math.cos(angle);
     }
+
     styleBuf[1] = left;
     styleBuf[3] = top;
     styleBuf[5] = fontHeight;
@@ -90,12 +103,15 @@ var renderTextLayer = function renderTextLayerClosure() {
     textDivProperties.style = styleBuf.join('');
     textDiv.setAttribute('style', textDivProperties.style);
     textDiv.textContent = geom.str;
+
     if (task._fontInspectorEnabled) {
       textDiv.dataset.fontName = geom.fontName;
     }
+
     if (angle !== 0) {
       textDivProperties.angle = angle * (180 / Math.PI);
     }
+
     if (geom.str.length > 1) {
       if (style.vertical) {
         textDivProperties.canvasWidth = geom.height * task._viewport.scale;
@@ -103,26 +119,33 @@ var renderTextLayer = function renderTextLayerClosure() {
         textDivProperties.canvasWidth = geom.width * task._viewport.scale;
       }
     }
+
     task._textDivProperties.set(textDiv, textDivProperties);
+
     if (task._textContentStream) {
       task._layoutText(textDiv);
     }
+
     if (task._enhanceTextSelection) {
       var angleCos = 1,
           angleSin = 0;
+
       if (angle !== 0) {
         angleCos = Math.cos(angle);
         angleSin = Math.sin(angle);
       }
+
       var divWidth = (style.vertical ? geom.height : geom.width) * task._viewport.scale;
       var divHeight = fontHeight;
       var m, b;
+
       if (angle !== 0) {
         m = [angleCos, angleSin, -angleSin, angleCos, left, top];
         b = _util.Util.getAxialAlignedBoundingBox([0, 0, divWidth, divHeight], m);
       } else {
         b = [left, top, left + divWidth, top + divHeight];
       }
+
       task._bounds.push({
         left: b[0],
         top: b[1],
@@ -134,41 +157,53 @@ var renderTextLayer = function renderTextLayerClosure() {
       });
     }
   }
+
   function render(task) {
     if (task._canceled) {
       return;
     }
+
     var textDivs = task._textDivs;
     var capability = task._capability;
     var textDivsLength = textDivs.length;
+
     if (textDivsLength > MAX_TEXT_DIVS_TO_RENDER) {
       task._renderingDone = true;
       capability.resolve();
       return;
     }
+
     if (!task._textContentStream) {
       for (var i = 0; i < textDivsLength; i++) {
         task._layoutText(textDivs[i]);
       }
     }
+
     task._renderingDone = true;
     capability.resolve();
   }
+
   function expand(task) {
     var bounds = task._bounds;
     var viewport = task._viewport;
     var expanded = expandBounds(viewport.width, viewport.height, bounds);
+
     for (var i = 0; i < expanded.length; i++) {
       var div = bounds[i].div;
+
       var divProperties = task._textDivProperties.get(div);
+
       if (divProperties.angle === 0) {
         divProperties.paddingLeft = bounds[i].left - expanded[i].left;
         divProperties.paddingTop = bounds[i].top - expanded[i].top;
         divProperties.paddingRight = expanded[i].right - bounds[i].right;
         divProperties.paddingBottom = expanded[i].bottom - bounds[i].bottom;
+
         task._textDivProperties.set(div, divProperties);
+
         continue;
       }
+
       var e = expanded[i],
           b = bounds[i];
       var m = b.m,
@@ -178,6 +213,7 @@ var renderTextLayer = function renderTextLayerClosure() {
       var ts = new Float64Array(64);
       points.forEach(function (p, i) {
         var t = _util.Util.applyTransform(p, m);
+
         ts[i + 0] = c && (e.left - t[0]) / c;
         ts[i + 4] = s && (e.top - t[1]) / s;
         ts[i + 8] = c && (e.right - t[0]) / c;
@@ -195,24 +231,31 @@ var renderTextLayer = function renderTextLayerClosure() {
         ts[i + 56] = s && (e.right - t[0]) / s;
         ts[i + 60] = c && (e.bottom - t[1]) / -c;
       });
+
       var findPositiveMin = function findPositiveMin(ts, offset, count) {
         var result = 0;
+
         for (var i = 0; i < count; i++) {
           var t = ts[offset++];
+
           if (t > 0) {
             result = result ? Math.min(t, result) : t;
           }
         }
+
         return result;
       };
+
       var boxScale = 1 + Math.min(Math.abs(c), Math.abs(s));
       divProperties.paddingLeft = findPositiveMin(ts, 32, 16) / boxScale;
       divProperties.paddingTop = findPositiveMin(ts, 48, 16) / boxScale;
       divProperties.paddingRight = findPositiveMin(ts, 0, 16) / boxScale;
       divProperties.paddingBottom = findPositiveMin(ts, 16, 16) / boxScale;
+
       task._textDivProperties.set(div, divProperties);
     }
   }
+
   function expandBounds(width, height, boxes) {
     var bounds = boxes.map(function (box, i) {
       return {
@@ -255,6 +298,7 @@ var renderTextLayer = function renderTextLayerClosure() {
     });
     return expanded;
   }
+
   function expandBoundsLTR(width, bounds) {
     bounds.sort(function (a, b) {
       return a.x1 - b.x1 || a.index - b.index;
@@ -275,21 +319,27 @@ var renderTextLayer = function renderTextLayerClosure() {
     }];
     bounds.forEach(function (boundary) {
       var i = 0;
+
       while (i < horizon.length && horizon[i].end <= boundary.y1) {
         i++;
       }
+
       var j = horizon.length - 1;
+
       while (j >= 0 && horizon[j].start >= boundary.y2) {
         j--;
       }
+
       var horizonPart, affectedBoundary;
       var q,
           k,
           maxXNew = -Infinity;
+
       for (q = i; q <= j; q++) {
         horizonPart = horizon[q];
         affectedBoundary = horizonPart.boundary;
         var xNew;
+
         if (affectedBoundary.x2 > boundary.x1) {
           xNew = affectedBoundary.index > boundary.index ? affectedBoundary.x1New : boundary.x1;
         } else if (affectedBoundary.x2New === undefined) {
@@ -297,14 +347,18 @@ var renderTextLayer = function renderTextLayerClosure() {
         } else {
           xNew = affectedBoundary.x2New;
         }
+
         if (xNew > maxXNew) {
           maxXNew = xNew;
         }
       }
+
       boundary.x1New = maxXNew;
+
       for (q = i; q <= j; q++) {
         horizonPart = horizon[q];
         affectedBoundary = horizonPart.boundary;
+
         if (affectedBoundary.x2New === undefined) {
           if (affectedBoundary.x2 > boundary.x1) {
             if (affectedBoundary.index > boundary.index) {
@@ -317,12 +371,15 @@ var renderTextLayer = function renderTextLayerClosure() {
           affectedBoundary.x2New = Math.max(maxXNew, affectedBoundary.x2);
         }
       }
+
       var changedHorizon = [],
           lastBoundary = null;
+
       for (q = i; q <= j; q++) {
         horizonPart = horizon[q];
         affectedBoundary = horizonPart.boundary;
         var useBoundary = affectedBoundary.x2 > boundary.x2 ? affectedBoundary : boundary;
+
         if (lastBoundary === useBoundary) {
           changedHorizon[changedHorizon.length - 1].end = horizonPart.end;
         } else {
@@ -334,6 +391,7 @@ var renderTextLayer = function renderTextLayerClosure() {
           lastBoundary = useBoundary;
         }
       }
+
       if (horizon[i].start < boundary.y1) {
         changedHorizon[0].start = boundary.y1;
         changedHorizon.unshift({
@@ -342,6 +400,7 @@ var renderTextLayer = function renderTextLayerClosure() {
           boundary: horizon[i].boundary
         });
       }
+
       if (boundary.y2 < horizon[j].end) {
         changedHorizon[changedHorizon.length - 1].end = boundary.y2;
         changedHorizon.push({
@@ -350,35 +409,45 @@ var renderTextLayer = function renderTextLayerClosure() {
           boundary: horizon[j].boundary
         });
       }
+
       for (q = i; q <= j; q++) {
         horizonPart = horizon[q];
         affectedBoundary = horizonPart.boundary;
+
         if (affectedBoundary.x2New !== undefined) {
           continue;
         }
+
         var used = false;
+
         for (k = i - 1; !used && k >= 0 && horizon[k].start >= affectedBoundary.y1; k--) {
           used = horizon[k].boundary === affectedBoundary;
         }
+
         for (k = j + 1; !used && k < horizon.length && horizon[k].end <= affectedBoundary.y2; k++) {
           used = horizon[k].boundary === affectedBoundary;
         }
+
         for (k = 0; !used && k < changedHorizon.length; k++) {
           used = changedHorizon[k].boundary === affectedBoundary;
         }
+
         if (!used) {
           affectedBoundary.x2New = maxXNew;
         }
       }
+
       Array.prototype.splice.apply(horizon, [i, j - i + 1].concat(changedHorizon));
     });
     horizon.forEach(function (horizonPart) {
       var affectedBoundary = horizonPart.boundary;
+
       if (affectedBoundary.x2New === undefined) {
         affectedBoundary.x2New = Math.max(width, affectedBoundary.x2);
       }
     });
   }
+
   function TextLayerRenderTask(_ref) {
     var textContent = _ref.textContent,
         textContentStream = _ref.textContentStream,
@@ -387,7 +456,6 @@ var renderTextLayer = function renderTextLayerClosure() {
         textDivs = _ref.textDivs,
         textContentItemsStr = _ref.textContentItemsStr,
         enhanceTextSelection = _ref.enhanceTextSelection;
-
     this._textContent = textContent;
     this._textContentStream = textContentStream;
     this._container = container;
@@ -395,7 +463,7 @@ var renderTextLayer = function renderTextLayerClosure() {
     this._textDivs = textDivs || [];
     this._textContentItemsStr = textContentItemsStr || [];
     this._enhanceTextSelection = !!enhanceTextSelection;
-    this._fontInspectorEnabled = !!(_global_scope2.default.FontInspector && _global_scope2.default.FontInspector.enabled);
+    this._fontInspectorEnabled = !!(_global_scope.default.FontInspector && _global_scope.default.FontInspector.enabled);
     this._reader = null;
     this._layoutTextLastFontSize = null;
     this._layoutTextLastFontFamily = null;
@@ -407,58 +475,75 @@ var renderTextLayer = function renderTextLayerClosure() {
     this._renderTimer = null;
     this._bounds = [];
   }
+
   TextLayerRenderTask.prototype = {
     get promise() {
       return this._capability.promise;
     },
+
     cancel: function TextLayer_cancel() {
       if (this._reader) {
         this._reader.cancel(new _util.AbortException('text layer task cancelled'));
+
         this._reader = null;
       }
+
       this._canceled = true;
+
       if (this._renderTimer !== null) {
         clearTimeout(this._renderTimer);
         this._renderTimer = null;
       }
+
       this._capability.reject('canceled');
     },
     _processItems: function _processItems(items, styleCache) {
       for (var i = 0, len = items.length; i < len; i++) {
         this._textContentItemsStr.push(items[i].str);
+
         appendText(this, items[i], styleCache);
       }
     },
     _layoutText: function _layoutText(textDiv) {
       var textLayerFrag = this._container;
+
       var textDivProperties = this._textDivProperties.get(textDiv);
+
       if (textDivProperties.isWhitespace) {
         return;
       }
+
       var fontSize = textDiv.style.fontSize;
       var fontFamily = textDiv.style.fontFamily;
+
       if (fontSize !== this._layoutTextLastFontSize || fontFamily !== this._layoutTextLastFontFamily) {
         this._layoutTextCtx.font = fontSize + ' ' + fontFamily;
-        this._lastFontSize = fontSize;
-        this._lastFontFamily = fontFamily;
+        this._layoutTextLastFontSize = fontSize;
+        this._layoutTextLastFontFamily = fontFamily;
       }
+
       var width = this._layoutTextCtx.measureText(textDiv.textContent).width;
+
       var transform = '';
+
       if (textDivProperties.canvasWidth !== 0 && width > 0) {
         textDivProperties.scale = textDivProperties.canvasWidth / width;
-        transform = 'scaleX(' + textDivProperties.scale + ')';
+        transform = "scaleX(".concat(textDivProperties.scale, ")");
       }
+
       if (textDivProperties.angle !== 0) {
-        transform = 'rotate(' + textDivProperties.angle + 'deg) ' + transform;
+        transform = "rotate(".concat(textDivProperties.angle, "deg) ").concat(transform);
       }
-      if (transform !== '') {
+
+      if (transform.length > 0) {
         textDivProperties.originalTransform = transform;
         textDiv.style.transform = transform;
       }
+
       this._textDivProperties.set(textDiv, textDivProperties);
+
       textLayerFrag.appendChild(textDiv);
     },
-
     _render: function TextLayer_render(timeout) {
       var _this = this;
 
@@ -466,11 +551,16 @@ var renderTextLayer = function renderTextLayerClosure() {
       var styleCache = Object.create(null);
       var canvas = document.createElement('canvas');
       canvas.mozOpaque = true;
-      this._layoutTextCtx = canvas.getContext('2d', { alpha: false });
+      this._layoutTextCtx = canvas.getContext('2d', {
+        alpha: false
+      });
+
       if (this._textContent) {
         var textItems = this._textContent.items;
         var textStyles = this._textContent.styles;
+
         this._processItems(textItems, textStyles);
+
         capability.resolve();
       } else if (this._textContentStream) {
         var pump = function pump() {
@@ -482,18 +572,24 @@ var renderTextLayer = function renderTextLayerClosure() {
               capability.resolve();
               return;
             }
-            _util.Util.extendObj(styleCache, value.styles);
+
+            Object.assign(styleCache, value.styles);
+
             _this._processItems(value.items, styleCache);
+
             pump();
           }, capability.reject);
         };
+
         this._reader = this._textContentStream.getReader();
         pump();
       } else {
         throw new Error('Neither "textContent" nor "textContentStream"' + ' parameters specified.');
       }
+
       capability.promise.then(function () {
         styleCache = null;
+
         if (!timeout) {
           render(_this);
         } else {
@@ -508,42 +604,55 @@ var renderTextLayer = function renderTextLayerClosure() {
       if (!this._enhanceTextSelection || !this._renderingDone) {
         return;
       }
+
       if (this._bounds !== null) {
         expand(this);
         this._bounds = null;
       }
+
       for (var i = 0, ii = this._textDivs.length; i < ii; i++) {
         var div = this._textDivs[i];
+
         var divProperties = this._textDivProperties.get(div);
+
         if (divProperties.isWhitespace) {
           continue;
         }
+
         if (expandDivs) {
           var transform = '',
               padding = '';
+
           if (divProperties.scale !== 1) {
             transform = 'scaleX(' + divProperties.scale + ')';
           }
+
           if (divProperties.angle !== 0) {
             transform = 'rotate(' + divProperties.angle + 'deg) ' + transform;
           }
+
           if (divProperties.paddingLeft !== 0) {
             padding += ' padding-left: ' + divProperties.paddingLeft / divProperties.scale + 'px;';
             transform += ' translateX(' + -divProperties.paddingLeft / divProperties.scale + 'px)';
           }
+
           if (divProperties.paddingTop !== 0) {
             padding += ' padding-top: ' + divProperties.paddingTop + 'px;';
             transform += ' translateY(' + -divProperties.paddingTop + 'px)';
           }
+
           if (divProperties.paddingRight !== 0) {
             padding += ' padding-right: ' + divProperties.paddingRight / divProperties.scale + 'px;';
           }
+
           if (divProperties.paddingBottom !== 0) {
             padding += ' padding-bottom: ' + divProperties.paddingBottom + 'px;';
           }
+
           if (padding !== '') {
             div.setAttribute('style', divProperties.style + padding);
           }
+
           if (transform !== '') {
             div.style.transform = transform;
           }
@@ -554,6 +663,7 @@ var renderTextLayer = function renderTextLayerClosure() {
       }
     }
   };
+
   function renderTextLayer(renderParameters) {
     var task = new TextLayerRenderTask({
       textContent: renderParameters.textContent,
@@ -564,9 +674,13 @@ var renderTextLayer = function renderTextLayerClosure() {
       textContentItemsStr: renderParameters.textContentItemsStr,
       enhanceTextSelection: renderParameters.enhanceTextSelection
     });
+
     task._render(renderParameters.timeout);
+
     return task;
   }
+
   return renderTextLayer;
 }();
+
 exports.renderTextLayer = renderTextLayer;

+ 171 - 42
lib/display/transport_stream.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,14 +19,22 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.PDFDataTransportStream = undefined;
+exports.PDFDataTransportStream = void 0;
 
-var _util = require('../shared/util');
+var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
+
+var _util = require("../shared/util");
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
+
+function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
 
 var PDFDataTransportStream = function PDFDataTransportStreamClosure() {
   function PDFDataTransportStream(params, pdfDataRangeTransport) {
@@ -35,33 +43,46 @@ var PDFDataTransportStream = function PDFDataTransportStreamClosure() {
     (0, _util.assert)(pdfDataRangeTransport);
     this._queuedChunks = [];
     var initialData = params.initialData;
+
     if (initialData && initialData.length > 0) {
       var buffer = new Uint8Array(initialData).buffer;
+
       this._queuedChunks.push(buffer);
     }
+
     this._pdfDataRangeTransport = pdfDataRangeTransport;
     this._isStreamingSupported = !params.disableStream;
     this._isRangeSupported = !params.disableRange;
     this._contentLength = params.length;
     this._fullRequestReader = null;
     this._rangeReaders = [];
+
     this._pdfDataRangeTransport.addRangeListener(function (begin, chunk) {
       _this._onReceiveData({
         begin: begin,
         chunk: chunk
       });
     });
+
     this._pdfDataRangeTransport.addProgressListener(function (loaded) {
-      _this._onProgress({ loaded: loaded });
+      _this._onProgress({
+        loaded: loaded
+      });
     });
+
     this._pdfDataRangeTransport.addProgressiveReadListener(function (chunk) {
-      _this._onReceiveData({ chunk: chunk });
+      _this._onReceiveData({
+        chunk: chunk
+      });
     });
+
     this._pdfDataRangeTransport.transportReady();
   }
+
   PDFDataTransportStream.prototype = {
     _onReceiveData: function PDFDataTransportStream_onReceiveData(args) {
       var buffer = new Uint8Array(args.chunk).buffer;
+
       if (args.begin === undefined) {
         if (this._fullRequestReader) {
           this._fullRequestReader._enqueue(buffer);
@@ -73,22 +94,29 @@ var PDFDataTransportStream = function PDFDataTransportStreamClosure() {
           if (rangeReader._begin !== args.begin) {
             return false;
           }
+
           rangeReader._enqueue(buffer);
+
           return true;
         });
+
         (0, _util.assert)(found);
       }
     },
     _onProgress: function PDFDataTransportStream_onDataProgress(evt) {
       if (this._rangeReaders.length > 0) {
         var firstReader = this._rangeReaders[0];
+
         if (firstReader.onProgress) {
-          firstReader.onProgress({ loaded: evt.loaded });
+          firstReader.onProgress({
+            loaded: evt.loaded
+          });
         }
       }
     },
     _removeRangeReader: function PDFDataTransportStream_removeRangeReader(reader) {
       var i = this._rangeReaders.indexOf(reader);
+
       if (i >= 0) {
         this._rangeReaders.splice(i, 1);
       }
@@ -101,21 +129,28 @@ var PDFDataTransportStream = function PDFDataTransportStreamClosure() {
     },
     getRangeReader: function PDFDataTransportStream_getRangeReader(begin, end) {
       var reader = new PDFDataTransportStreamRangeReader(this, begin, end);
+
       this._pdfDataRangeTransport.requestDataRange(begin, end);
+
       this._rangeReaders.push(reader);
+
       return reader;
     },
     cancelAllRequests: function PDFDataTransportStream_cancelAllRequests(reason) {
       if (this._fullRequestReader) {
         this._fullRequestReader.cancel(reason);
       }
+
       var readers = this._rangeReaders.slice(0);
+
       readers.forEach(function (rangeReader) {
         rangeReader.cancel(reason);
       });
+
       this._pdfDataRangeTransport.abort();
     }
   };
+
   function PDFDataTransportStreamReader(stream, queuedChunks) {
     this._stream = stream;
     this._done = false;
@@ -126,65 +161,112 @@ var PDFDataTransportStream = function PDFDataTransportStreamClosure() {
     stream._fullRequestReader = this;
     this.onProgress = null;
   }
+
   PDFDataTransportStreamReader.prototype = {
     _enqueue: function PDFDataTransportStreamReader_enqueue(chunk) {
       if (this._done) {
         return;
       }
+
       if (this._requests.length > 0) {
         var requestCapability = this._requests.shift();
+
         requestCapability.resolve({
           value: chunk,
           done: false
         });
         return;
       }
+
       this._queuedChunks.push(chunk);
     },
+
     get headersReady() {
       return this._headersReady;
     },
+
     get filename() {
       return this._filename;
     },
+
     get isRangeSupported() {
       return this._stream._isRangeSupported;
     },
+
     get isStreamingSupported() {
       return this._stream._isStreamingSupported;
     },
+
     get contentLength() {
       return this._stream._contentLength;
     },
-    read: function PDFDataTransportStreamReader_read() {
-      if (this._queuedChunks.length > 0) {
-        var chunk = this._queuedChunks.shift();
-        return Promise.resolve({
-          value: chunk,
-          done: false
-        });
-      }
-      if (this._done) {
-        return Promise.resolve({
-          value: undefined,
-          done: true
-        });
+
+    read: function () {
+      var _read = _asyncToGenerator(
+      /*#__PURE__*/
+      _regenerator.default.mark(function _callee() {
+        var chunk, requestCapability;
+        return _regenerator.default.wrap(function _callee$(_context) {
+          while (1) {
+            switch (_context.prev = _context.next) {
+              case 0:
+                if (!(this._queuedChunks.length > 0)) {
+                  _context.next = 3;
+                  break;
+                }
+
+                chunk = this._queuedChunks.shift();
+                return _context.abrupt("return", {
+                  value: chunk,
+                  done: false
+                });
+
+              case 3:
+                if (!this._done) {
+                  _context.next = 5;
+                  break;
+                }
+
+                return _context.abrupt("return", {
+                  value: undefined,
+                  done: true
+                });
+
+              case 5:
+                requestCapability = (0, _util.createPromiseCapability)();
+
+                this._requests.push(requestCapability);
+
+                return _context.abrupt("return", requestCapability.promise);
+
+              case 8:
+              case "end":
+                return _context.stop();
+            }
+          }
+        }, _callee, this);
+      }));
+
+      function read() {
+        return _read.apply(this, arguments);
       }
-      var requestCapability = (0, _util.createPromiseCapability)();
-      this._requests.push(requestCapability);
-      return requestCapability.promise;
-    },
+
+      return read;
+    }(),
     cancel: function PDFDataTransportStreamReader_cancel(reason) {
       this._done = true;
+
       this._requests.forEach(function (requestCapability) {
         requestCapability.resolve({
           value: undefined,
           done: true
         });
       });
+
       this._requests = [];
     }
   };
+
   function PDFDataTransportStreamRangeReader(stream, begin, end) {
     this._stream = stream;
     this._begin = begin;
@@ -194,64 +276,111 @@ var PDFDataTransportStream = function PDFDataTransportStreamClosure() {
     this._done = false;
     this.onProgress = null;
   }
+
   PDFDataTransportStreamRangeReader.prototype = {
     _enqueue: function PDFDataTransportStreamRangeReader_enqueue(chunk) {
       if (this._done) {
         return;
       }
+
       if (this._requests.length === 0) {
         this._queuedChunk = chunk;
       } else {
         var requestsCapability = this._requests.shift();
+
         requestsCapability.resolve({
           value: chunk,
           done: false
         });
+
         this._requests.forEach(function (requestCapability) {
           requestCapability.resolve({
             value: undefined,
             done: true
           });
         });
+
         this._requests = [];
       }
+
       this._done = true;
+
       this._stream._removeRangeReader(this);
     },
+
     get isStreamingSupported() {
       return false;
     },
-    read: function PDFDataTransportStreamRangeReader_read() {
-      if (this._queuedChunk) {
-        var chunk = this._queuedChunk;
-        this._queuedChunk = null;
-        return Promise.resolve({
-          value: chunk,
-          done: false
-        });
-      }
-      if (this._done) {
-        return Promise.resolve({
-          value: undefined,
-          done: true
-        });
+
+    read: function () {
+      var _read2 = _asyncToGenerator(
+      /*#__PURE__*/
+      _regenerator.default.mark(function _callee2() {
+        var chunk, requestCapability;
+        return _regenerator.default.wrap(function _callee2$(_context2) {
+          while (1) {
+            switch (_context2.prev = _context2.next) {
+              case 0:
+                if (!this._queuedChunk) {
+                  _context2.next = 4;
+                  break;
+                }
+
+                chunk = this._queuedChunk;
+                this._queuedChunk = null;
+                return _context2.abrupt("return", {
+                  value: chunk,
+                  done: false
+                });
+
+              case 4:
+                if (!this._done) {
+                  _context2.next = 6;
+                  break;
+                }
+
+                return _context2.abrupt("return", {
+                  value: undefined,
+                  done: true
+                });
+
+              case 6:
+                requestCapability = (0, _util.createPromiseCapability)();
+
+                this._requests.push(requestCapability);
+
+                return _context2.abrupt("return", requestCapability.promise);
+
+              case 9:
+              case "end":
+                return _context2.stop();
+            }
+          }
+        }, _callee2, this);
+      }));
+
+      function read() {
+        return _read2.apply(this, arguments);
       }
-      var requestCapability = (0, _util.createPromiseCapability)();
-      this._requests.push(requestCapability);
-      return requestCapability.promise;
-    },
+
+      return read;
+    }(),
     cancel: function PDFDataTransportStreamRangeReader_cancel(reason) {
       this._done = true;
+
       this._requests.forEach(function (requestCapability) {
         requestCapability.resolve({
           value: undefined,
           done: true
         });
       });
+
       this._requests = [];
+
       this._stream._removeRangeReader(this);
     }
   };
   return PDFDataTransportStream;
 }();
+
 exports.PDFDataTransportStream = PDFDataTransportStream;

+ 64 - 18
lib/display/webgl.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,23 +19,27 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.WebGLContext = undefined;
+exports.WebGLContext = void 0;
 
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-var _util = require('../shared/util');
+var _util = require("../shared/util");
 
 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
-var WebGLContext = function () {
+function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
+
+function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
+
+var WebGLContext =
+/*#__PURE__*/
+function () {
   function WebGLContext(_ref) {
     var _ref$enable = _ref.enable,
-        enable = _ref$enable === undefined ? false : _ref$enable;
+        enable = _ref$enable === void 0 ? false : _ref$enable;
 
     _classCallCheck(this, WebGLContext);
 
@@ -43,37 +47,37 @@ var WebGLContext = function () {
   }
 
   _createClass(WebGLContext, [{
-    key: 'composeSMask',
+    key: "composeSMask",
     value: function composeSMask(_ref2) {
       var layer = _ref2.layer,
           mask = _ref2.mask,
           properties = _ref2.properties;
-
       return WebGLUtils.composeSMask(layer, mask, properties);
     }
   }, {
-    key: 'drawFigures',
+    key: "drawFigures",
     value: function drawFigures(_ref3) {
       var width = _ref3.width,
           height = _ref3.height,
           backgroundColor = _ref3.backgroundColor,
           figures = _ref3.figures,
           context = _ref3.context;
-
       return WebGLUtils.drawFigures(width, height, backgroundColor, figures, context);
     }
   }, {
-    key: 'clear',
+    key: "clear",
     value: function clear() {
       WebGLUtils.cleanup();
     }
   }, {
-    key: 'isEnabled',
+    key: "isEnabled",
     get: function get() {
       var enabled = this._enabled;
+
       if (enabled) {
         enabled = WebGLUtils.tryInitGL();
       }
+
       return (0, _util.shadow)(this, 'isEnabled', enabled);
     }
   }]);
@@ -81,37 +85,49 @@ var WebGLContext = function () {
   return WebGLContext;
 }();
 
+exports.WebGLContext = WebGLContext;
+
 var WebGLUtils = function WebGLUtilsClosure() {
   function loadShader(gl, code, shaderType) {
     var shader = gl.createShader(shaderType);
     gl.shaderSource(shader, code);
     gl.compileShader(shader);
     var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
+
     if (!compiled) {
       var errorMsg = gl.getShaderInfoLog(shader);
       throw new Error('Error during shader compilation: ' + errorMsg);
     }
+
     return shader;
   }
+
   function createVertexShader(gl, code) {
     return loadShader(gl, code, gl.VERTEX_SHADER);
   }
+
   function createFragmentShader(gl, code) {
     return loadShader(gl, code, gl.FRAGMENT_SHADER);
   }
+
   function createProgram(gl, shaders) {
     var program = gl.createProgram();
+
     for (var i = 0, ii = shaders.length; i < ii; ++i) {
       gl.attachShader(program, shaders[i]);
     }
+
     gl.linkProgram(program);
     var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
+
     if (!linked) {
       var errorMsg = gl.getProgramInfoLog(program);
       throw new Error('Error during program linking: ' + errorMsg);
     }
+
     return program;
   }
+
   function createTexture(gl, image, textureId) {
     gl.activeTexture(textureId);
     var texture = gl.createTexture();
@@ -123,14 +139,20 @@ var WebGLUtils = function WebGLUtilsClosure() {
     gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
     return texture;
   }
+
   var currentGL, currentCanvas;
+
   function generateGL() {
     if (currentGL) {
       return;
     }
+
     currentCanvas = document.createElement('canvas');
-    currentGL = currentCanvas.getContext('webgl', { premultipliedalpha: false });
+    currentGL = currentCanvas.getContext('webgl', {
+      premultipliedalpha: false
+    });
   }
+
   var smaskVertexShaderCode = '\
   attribute vec2 a_position;                                    \
   attribute vec2 a_texCoord;                                    \
@@ -174,6 +196,7 @@ var WebGLUtils = function WebGLUtilsClosure() {
     gl_FragColor = imageColor;                                  \
   }                                                             ';
   var smaskCache = null;
+
   function initSmaskGL() {
     var canvas, gl;
     generateGL();
@@ -204,12 +227,15 @@ var WebGLUtils = function WebGLUtilsClosure() {
     gl.uniform1i(texMaskLocation, 1);
     smaskCache = cache;
   }
+
   function composeSMask(layer, mask, properties) {
     var width = layer.width,
         height = layer.height;
+
     if (!smaskCache) {
       initSmaskGL();
     }
+
     var cache = smaskCache,
         canvas = cache.canvas,
         gl = cache.gl;
@@ -217,11 +243,13 @@ var WebGLUtils = function WebGLUtilsClosure() {
     canvas.height = height;
     gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
     gl.uniform2f(cache.resolutionLocation, width, height);
+
     if (properties.backdrop) {
       gl.uniform4f(cache.resolutionLocation, properties.backdrop[0], properties.backdrop[1], properties.backdrop[2], 1);
     } else {
       gl.uniform4f(cache.resolutionLocation, 0, 0, 0, 0);
     }
+
     gl.uniform1i(cache.subtypeLocation, properties.subtype === 'Luminosity' ? 1 : 0);
     var texture = createTexture(gl, layer, gl.TEXTURE0);
     var maskTexture = createTexture(gl, mask, gl.TEXTURE1);
@@ -241,6 +269,7 @@ var WebGLUtils = function WebGLUtilsClosure() {
     gl.deleteBuffer(buffer);
     return canvas;
   }
+
   var figuresVertexShaderCode = '\
   attribute vec2 a_position;                                    \
   attribute vec3 a_color;                                       \
@@ -267,6 +296,7 @@ var WebGLUtils = function WebGLUtilsClosure() {
     gl_FragColor = v_color;                                     \
   }                                                             ';
   var figuresCache = null;
+
   function initFiguresGL() {
     var canvas, gl;
     generateGL();
@@ -288,10 +318,12 @@ var WebGLUtils = function WebGLUtilsClosure() {
     cache.colorLocation = gl.getAttribLocation(program, 'a_color');
     figuresCache = cache;
   }
+
   function drawFigures(width, height, backgroundColor, figures, context) {
     if (!figuresCache) {
       initFiguresGL();
     }
+
     var cache = figuresCache,
         canvas = cache.canvas,
         gl = cache.gl;
@@ -301,33 +333,40 @@ var WebGLUtils = function WebGLUtilsClosure() {
     gl.uniform2f(cache.resolutionLocation, width, height);
     var count = 0;
     var i, ii, rows;
+
     for (i = 0, ii = figures.length; i < ii; i++) {
       switch (figures[i].type) {
         case 'lattice':
           rows = figures[i].coords.length / figures[i].verticesPerRow | 0;
           count += (rows - 1) * (figures[i].verticesPerRow - 1) * 6;
           break;
+
         case 'triangles':
           count += figures[i].coords.length;
           break;
       }
     }
+
     var coords = new Float32Array(count * 2);
     var colors = new Uint8Array(count * 3);
     var coordsMap = context.coords,
         colorsMap = context.colors;
     var pIndex = 0,
         cIndex = 0;
+
     for (i = 0, ii = figures.length; i < ii; i++) {
       var figure = figures[i],
           ps = figure.coords,
           cs = figure.colors;
+
       switch (figure.type) {
         case 'lattice':
           var cols = figure.verticesPerRow;
           rows = ps.length / cols | 0;
+
           for (var row = 1; row < rows; row++) {
             var offset = row * cols + 1;
+
             for (var col = 1; col < cols; col++, offset++) {
               coords[pIndex] = coordsMap[ps[offset - cols - 1]];
               coords[pIndex + 1] = coordsMap[ps[offset - cols - 1] + 1];
@@ -363,7 +402,9 @@ var WebGLUtils = function WebGLUtilsClosure() {
               cIndex += 18;
             }
           }
+
           break;
+
         case 'triangles':
           for (var j = 0, jj = ps.length; j < jj; j++) {
             coords[pIndex] = coordsMap[ps[j]];
@@ -374,14 +415,17 @@ var WebGLUtils = function WebGLUtilsClosure() {
             pIndex += 2;
             cIndex += 3;
           }
+
           break;
       }
     }
+
     if (backgroundColor) {
       gl.clearColor(backgroundColor[0] / 255, backgroundColor[1] / 255, backgroundColor[2] / 255, 1.0);
     } else {
       gl.clearColor(0, 0, 0, 0);
     }
+
     gl.clear(gl.COLOR_BUFFER_BIT);
     var coordsBuffer = gl.createBuffer();
     gl.bindBuffer(gl.ARRAY_BUFFER, coordsBuffer);
@@ -401,15 +445,16 @@ var WebGLUtils = function WebGLUtilsClosure() {
     gl.deleteBuffer(colorsBuffer);
     return canvas;
   }
+
   return {
     tryInitGL: function tryInitGL() {
       try {
         generateGL();
         return !!currentGL;
       } catch (ex) {}
+
       return false;
     },
-
     composeSMask: composeSMask,
     drawFigures: drawFigures,
     cleanup: function cleanup() {
@@ -417,13 +462,14 @@ var WebGLUtils = function WebGLUtilsClosure() {
         smaskCache.canvas.width = 0;
         smaskCache.canvas.height = 0;
       }
+
       if (figuresCache && figuresCache.canvas) {
         figuresCache.canvas.width = 0;
         figuresCache.canvas.height = 0;
       }
+
       smaskCache = null;
       figuresCache = null;
     }
   };
-}();
-exports.WebGLContext = WebGLContext;
+}();

+ 5 - 4
lib/display/worker_options.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,12 +19,13 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
+exports.GlobalWorkerOptions = void 0;
 var GlobalWorkerOptions = Object.create(null);
+exports.GlobalWorkerOptions = GlobalWorkerOptions;
 GlobalWorkerOptions.workerPort = GlobalWorkerOptions.workerPort === undefined ? null : GlobalWorkerOptions.workerPort;
-GlobalWorkerOptions.workerSrc = GlobalWorkerOptions.workerSrc === undefined ? '' : GlobalWorkerOptions.workerSrc;
-exports.GlobalWorkerOptions = GlobalWorkerOptions;
+GlobalWorkerOptions.workerSrc = GlobalWorkerOptions.workerSrc === undefined ? '' : GlobalWorkerOptions.workerSrc;

+ 166 - 53
lib/display/xml_parser.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,24 +19,43 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
+exports.SimpleXMLParser = void 0;
 
-var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
+function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
 
-var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
+function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
 
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
 
-function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
 
-function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
+
+function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
+
+function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
+
+function _get(target, property, receiver) { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get; } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(receiver); } return desc.value; }; } return _get(target, property, receiver || target); }
+
+function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; }
+
+function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
+
+function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
 
 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
+function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
+
+function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
+
 var XMLParserErrorCode = {
   NoError: 0,
   EndOfDocument: -1,
@@ -50,84 +69,108 @@ var XMLParserErrorCode = {
   UnterminatedElement: -9,
   ElementNeverBegun: -10
 };
+
 function isWhitespace(s, index) {
   var ch = s[index];
   return ch === ' ' || ch === '\n' || ch === '\r' || ch === '\t';
 }
+
 function isWhitespaceString(s) {
   for (var i = 0, ii = s.length; i < ii; i++) {
     if (!isWhitespace(s, i)) {
       return false;
     }
   }
+
   return true;
 }
 
-var XMLParserBase = function () {
+var XMLParserBase =
+/*#__PURE__*/
+function () {
   function XMLParserBase() {
     _classCallCheck(this, XMLParserBase);
   }
 
   _createClass(XMLParserBase, [{
-    key: '_resolveEntities',
+    key: "_resolveEntities",
     value: function _resolveEntities(s) {
+      var _this = this;
+
       return s.replace(/&([^;]+);/g, function (all, entity) {
         if (entity.substring(0, 2) === '#x') {
           return String.fromCharCode(parseInt(entity.substring(2), 16));
         } else if (entity.substring(0, 1) === '#') {
           return String.fromCharCode(parseInt(entity.substring(1), 10));
         }
+
         switch (entity) {
           case 'lt':
             return '<';
+
           case 'gt':
             return '>';
+
           case 'amp':
             return '&';
+
           case 'quot':
             return '\"';
         }
-        return this.onResolveEntity(entity);
+
+        return _this.onResolveEntity(entity);
       });
     }
   }, {
-    key: '_parseContent',
+    key: "_parseContent",
     value: function _parseContent(s, start) {
       var pos = start,
-          name = void 0,
+          name,
           attributes = [];
+
       function skipWs() {
         while (pos < s.length && isWhitespace(s, pos)) {
           ++pos;
         }
       }
+
       while (pos < s.length && !isWhitespace(s, pos) && s[pos] !== '>' && s[pos] !== '/') {
         ++pos;
       }
+
       name = s.substring(start, pos);
       skipWs();
+
       while (pos < s.length && s[pos] !== '>' && s[pos] !== '/' && s[pos] !== '?') {
         skipWs();
         var attrName = '',
             attrValue = '';
+
         while (pos < s.length && !isWhitespace(s, pos) && s[pos] !== '=') {
           attrName += s[pos];
           ++pos;
         }
+
         skipWs();
+
         if (s[pos] !== '=') {
           return null;
         }
+
         ++pos;
         skipWs();
         var attrEndChar = s[pos];
+
         if (attrEndChar !== '\"' && attrEndChar !== '\'') {
           return null;
         }
+
         var attrEndIndex = s.indexOf(attrEndChar, ++pos);
+
         if (attrEndIndex < 0) {
           return null;
         }
+
         attrValue = s.substring(pos, attrEndIndex);
         attributes.push({
           name: attrName,
@@ -136,6 +179,7 @@ var XMLParserBase = function () {
         pos = attrEndIndex + 1;
         skipWs();
       }
+
       return {
         name: name,
         attributes: attributes,
@@ -143,25 +187,30 @@ var XMLParserBase = function () {
       };
     }
   }, {
-    key: '_parseProcessingInstruction',
+    key: "_parseProcessingInstruction",
     value: function _parseProcessingInstruction(s, start) {
       var pos = start,
-          name = void 0,
-          value = void 0;
+          name,
+          value;
+
       function skipWs() {
         while (pos < s.length && isWhitespace(s, pos)) {
           ++pos;
         }
       }
+
       while (pos < s.length && !isWhitespace(s, pos) && s[pos] !== '>' && s[pos] !== '/') {
         ++pos;
       }
+
       name = s.substring(start, pos);
       skipWs();
       var attrStart = pos;
+
       while (pos < s.length && (s[pos] !== '?' || s[pos + 1] !== '>')) {
         ++pos;
       }
+
       value = s.substring(attrStart, pos);
       return {
         name: name,
@@ -170,70 +219,89 @@ var XMLParserBase = function () {
       };
     }
   }, {
-    key: 'parseXml',
+    key: "parseXml",
     value: function parseXml(s) {
       var i = 0;
+
       while (i < s.length) {
         var ch = s[i];
         var j = i;
+
         if (ch === '<') {
           ++j;
           var ch2 = s[j];
           var q = void 0;
+
           switch (ch2) {
             case '/':
               ++j;
               q = s.indexOf('>', j);
+
               if (q < 0) {
                 this.onError(XMLParserErrorCode.UnterminatedElement);
                 return;
               }
+
               this.onEndElement(s.substring(j, q));
               j = q + 1;
               break;
+
             case '?':
               ++j;
+
               var pi = this._parseProcessingInstruction(s, j);
+
               if (s.substring(j + pi.parsed, j + pi.parsed + 2) !== '?>') {
                 this.onError(XMLParserErrorCode.UnterminatedXmlDeclaration);
                 return;
               }
+
               this.onPi(pi.name, pi.value);
               j += pi.parsed + 2;
               break;
+
             case '!':
               if (s.substring(j + 1, j + 3) === '--') {
                 q = s.indexOf('-->', j + 3);
+
                 if (q < 0) {
                   this.onError(XMLParserErrorCode.UnterminatedComment);
                   return;
                 }
+
                 this.onComment(s.substring(j + 3, q));
                 j = q + 3;
               } else if (s.substring(j + 1, j + 8) === '[CDATA[') {
                 q = s.indexOf(']]>', j + 8);
+
                 if (q < 0) {
                   this.onError(XMLParserErrorCode.UnterminatedCdat);
                   return;
                 }
+
                 this.onCdata(s.substring(j + 8, q));
                 j = q + 3;
               } else if (s.substring(j + 1, j + 8) === 'DOCTYPE') {
                 var q2 = s.indexOf('[', j + 8);
                 var complexDoctype = false;
                 q = s.indexOf('>', j + 8);
+
                 if (q < 0) {
                   this.onError(XMLParserErrorCode.UnterminatedDoctypeDeclaration);
                   return;
                 }
+
                 if (q2 > 0 && q > q2) {
                   q = s.indexOf(']>', j + 8);
+
                   if (q < 0) {
                     this.onError(XMLParserErrorCode.UnterminatedDoctypeDeclaration);
                     return;
                   }
+
                   complexDoctype = true;
                 }
+
                 var doctypeContent = s.substring(j + 8, q + (complexDoctype ? 1 : 0));
                 this.onDoctype(doctypeContent);
                 j = q + (complexDoctype ? 2 : 1);
@@ -241,20 +309,26 @@ var XMLParserBase = function () {
                 this.onError(XMLParserErrorCode.MalformedElement);
                 return;
               }
+
               break;
+
             default:
               var content = this._parseContent(s, j);
+
               if (content === null) {
                 this.onError(XMLParserErrorCode.MalformedElement);
                 return;
               }
+
               var isClosed = false;
+
               if (s.substring(j + content.parsed, j + content.parsed + 2) === '/>') {
                 isClosed = true;
               } else if (s.substring(j + content.parsed, j + content.parsed + 1) !== '>') {
                 this.onError(XMLParserErrorCode.UnterminatedElement);
                 return;
               }
+
               this.onBeginElement(content.name, content.attributes, isClosed);
               j += content.parsed + (isClosed ? 2 : 1);
               break;
@@ -263,47 +337,51 @@ var XMLParserBase = function () {
           while (j < s.length && s[j] !== '<') {
             j++;
           }
+
           var text = s.substring(i, j);
           this.onText(this._resolveEntities(text));
         }
+
         i = j;
       }
     }
   }, {
-    key: 'onResolveEntity',
+    key: "onResolveEntity",
     value: function onResolveEntity(name) {
-      return '&' + name + ';';
+      return "&".concat(name, ";");
     }
   }, {
-    key: 'onPi',
+    key: "onPi",
     value: function onPi(name, value) {}
   }, {
-    key: 'onComment',
+    key: "onComment",
     value: function onComment(text) {}
   }, {
-    key: 'onCdata',
+    key: "onCdata",
     value: function onCdata(text) {}
   }, {
-    key: 'onDoctype',
+    key: "onDoctype",
     value: function onDoctype(doctypeContent) {}
   }, {
-    key: 'onText',
+    key: "onText",
     value: function onText(text) {}
   }, {
-    key: 'onBeginElement',
+    key: "onBeginElement",
     value: function onBeginElement(name, attributes, isEmpty) {}
   }, {
-    key: 'onEndElement',
+    key: "onEndElement",
     value: function onEndElement(name) {}
   }, {
-    key: 'onError',
+    key: "onError",
     value: function onError(code) {}
   }]);
 
   return XMLParserBase;
 }();
 
-var SimpleDOMNode = function () {
+var SimpleDOMNode =
+/*#__PURE__*/
+function () {
   function SimpleDOMNode(nodeName, nodeValue) {
     _classCallCheck(this, SimpleDOMNode);
 
@@ -316,27 +394,39 @@ var SimpleDOMNode = function () {
   }
 
   _createClass(SimpleDOMNode, [{
-    key: 'hasChildNodes',
+    key: "hasChildNodes",
     value: function hasChildNodes() {
       return this.childNodes && this.childNodes.length > 0;
     }
   }, {
-    key: 'firstChild',
+    key: "firstChild",
     get: function get() {
-      return this.childNodes[0];
+      return this.childNodes && this.childNodes[0];
     }
   }, {
-    key: 'nextSibling',
+    key: "nextSibling",
     get: function get() {
-      var index = this.parentNode.childNodes.indexOf(this);
-      return this.parentNode.childNodes[index + 1];
+      var childNodes = this.parentNode.childNodes;
+
+      if (!childNodes) {
+        return undefined;
+      }
+
+      var index = childNodes.indexOf(this);
+
+      if (index === -1) {
+        return undefined;
+      }
+
+      return childNodes[index + 1];
     }
   }, {
-    key: 'textContent',
+    key: "textContent",
     get: function get() {
       if (!this.childNodes) {
         return this.nodeValue || '';
       }
+
       return this.childNodes.map(function (child) {
         return child.textContent;
       }).join('');
@@ -346,83 +436,106 @@ var SimpleDOMNode = function () {
   return SimpleDOMNode;
 }();
 
-var SimpleXMLParser = function (_XMLParserBase) {
+var SimpleXMLParser =
+/*#__PURE__*/
+function (_XMLParserBase) {
   _inherits(SimpleXMLParser, _XMLParserBase);
 
   function SimpleXMLParser() {
-    _classCallCheck(this, SimpleXMLParser);
+    var _this2;
 
-    var _this = _possibleConstructorReturn(this, (SimpleXMLParser.__proto__ || Object.getPrototypeOf(SimpleXMLParser)).call(this));
+    _classCallCheck(this, SimpleXMLParser);
 
-    _this._currentFragment = null;
-    _this._stack = null;
-    _this._errorCode = XMLParserErrorCode.NoError;
-    return _this;
+    _this2 = _possibleConstructorReturn(this, _getPrototypeOf(SimpleXMLParser).call(this));
+    _this2._currentFragment = null;
+    _this2._stack = null;
+    _this2._errorCode = XMLParserErrorCode.NoError;
+    return _this2;
   }
 
   _createClass(SimpleXMLParser, [{
-    key: 'parseFromString',
+    key: "parseFromString",
     value: function parseFromString(data) {
       this._currentFragment = [];
       this._stack = [];
       this._errorCode = XMLParserErrorCode.NoError;
       this.parseXml(data);
+
       if (this._errorCode !== XMLParserErrorCode.NoError) {
         return undefined;
       }
 
-      var _currentFragment = _slicedToArray(this._currentFragment, 1),
-          documentElement = _currentFragment[0];
+      var _this$_currentFragmen = _slicedToArray(this._currentFragment, 1),
+          documentElement = _this$_currentFragmen[0];
 
-      return { documentElement: documentElement };
+      if (!documentElement) {
+        return undefined;
+      }
+
+      return {
+        documentElement: documentElement
+      };
     }
   }, {
-    key: 'onResolveEntity',
+    key: "onResolveEntity",
     value: function onResolveEntity(name) {
       switch (name) {
         case 'apos':
           return '\'';
       }
-      return _get(SimpleXMLParser.prototype.__proto__ || Object.getPrototypeOf(SimpleXMLParser.prototype), 'onResolveEntity', this).call(this, name);
+
+      return _get(_getPrototypeOf(SimpleXMLParser.prototype), "onResolveEntity", this).call(this, name);
     }
   }, {
-    key: 'onText',
+    key: "onText",
     value: function onText(text) {
       if (isWhitespaceString(text)) {
         return;
       }
+
       var node = new SimpleDOMNode('#text', text);
+
       this._currentFragment.push(node);
     }
   }, {
-    key: 'onCdata',
+    key: "onCdata",
     value: function onCdata(text) {
       var node = new SimpleDOMNode('#text', text);
+
       this._currentFragment.push(node);
     }
   }, {
-    key: 'onBeginElement',
+    key: "onBeginElement",
     value: function onBeginElement(name, attributes, isEmpty) {
       var node = new SimpleDOMNode(name);
       node.childNodes = [];
+
       this._currentFragment.push(node);
+
       if (isEmpty) {
         return;
       }
+
       this._stack.push(this._currentFragment);
+
       this._currentFragment = node.childNodes;
     }
   }, {
-    key: 'onEndElement',
+    key: "onEndElement",
     value: function onEndElement(name) {
-      this._currentFragment = this._stack.pop();
+      this._currentFragment = this._stack.pop() || [];
       var lastElement = this._currentFragment[this._currentFragment.length - 1];
+
+      if (!lastElement) {
+        return;
+      }
+
       for (var i = 0, ii = lastElement.childNodes.length; i < ii; i++) {
         lastElement.childNodes[i].parentNode = lastElement;
       }
     }
   }, {
-    key: 'onError',
+    key: "onError",
     value: function onError(code) {
       this._errorCode = code;
     }

+ 57 - 4
lib/examples/node/domstubs.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,52 +19,66 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 function xmlEncode(s) {
   var i = 0,
       ch;
   s = String(s);
+
   while (i < s.length && (ch = s[i]) !== '&' && ch !== '<' && ch !== '\"' && ch !== '\n' && ch !== '\r' && ch !== '\t') {
     i++;
   }
+
   if (i >= s.length) {
     return s;
   }
+
   var buf = s.substring(0, i);
+
   while (i < s.length) {
     ch = s[i++];
+
     switch (ch) {
       case '&':
         buf += '&amp;';
         break;
+
       case '<':
         buf += '&lt;';
         break;
+
       case '\"':
         buf += '&quot;';
         break;
+
       case '\n':
         buf += '&#xA;';
         break;
+
       case '\r':
         buf += '&#xD;';
         break;
+
       case '\t':
         buf += '&#x9;';
         break;
+
       default:
         buf += ch;
         break;
     }
   }
+
   return buf;
 }
+
 function DOMElement(name) {
   this.nodeName = name;
   this.childNodes = [];
   this.attributes = {};
   this.textContent = '';
+
   if (name === 'style') {
     this.sheet = {
       cssRules: [],
@@ -74,25 +88,30 @@ function DOMElement(name) {
     };
   }
 }
+
 DOMElement.prototype = {
   getAttribute: function DOMElement_getAttribute(name) {
     if (name in this.attributes) {
       return this.attributes[name];
     }
+
     return null;
   },
   getAttributeNS: function DOMElement_getAttributeNS(NS, name) {
     if (name in this.attributes) {
       return this.attributes[name];
     }
+
     if (NS) {
       var suffix = ':' + name;
+
       for (var fullName in this.attributes) {
         if (fullName.slice(-suffix.length) === suffix) {
           return this.attributes[fullName];
         }
       }
     }
+
     return null;
   },
   setAttribute: function DOMElement_setAttribute(name, value) {
@@ -105,7 +124,8 @@ DOMElement.prototype = {
   },
   appendChild: function DOMElement_appendChild(element) {
     var childNodes = this.childNodes;
-    if (childNodes.indexOf(element) === -1) {
+
+    if (!childNodes.includes(element)) {
       childNodes.push(element);
     }
   },
@@ -120,15 +140,18 @@ DOMElement.prototype = {
     var buf = [];
     var serializer = this.getSerializer();
     var chunk;
+
     while ((chunk = serializer.getNext()) !== null) {
       buf.push(chunk);
     }
+
     return buf.join('');
   },
   getSerializer: function DOMElement_getSerializer() {
     return new DOMElementSerializer(this);
   }
 };
+
 function DOMElementSerializer(node) {
   this._node = node;
   this._state = 0;
@@ -136,44 +159,58 @@ function DOMElementSerializer(node) {
   this._attributeKeys = null;
   this._childSerializer = null;
 }
+
 DOMElementSerializer.prototype = {
   getNext: function DOMElementSerializer_getNext() {
     var node = this._node;
+
     switch (this._state) {
       case 0:
         ++this._state;
         return '<' + node.nodeName;
+
       case 1:
         ++this._state;
+
         if (node.nodeName === 'svg:svg') {
           return ' xmlns:xlink="http://www.w3.org/1999/xlink"' + ' xmlns:svg="http://www.w3.org/2000/svg"';
         }
+
       case 2:
         ++this._state;
         this._loopIndex = 0;
         this._attributeKeys = Object.keys(node.attributes);
+
       case 3:
         if (this._loopIndex < this._attributeKeys.length) {
           var name = this._attributeKeys[this._loopIndex++];
           return ' ' + name + '="' + xmlEncode(node.attributes[name]) + '"';
         }
+
         ++this._state;
         return '>';
+
       case 4:
         if (node.nodeName === 'svg:tspan' || node.nodeName === 'svg:style') {
           this._state = 6;
           return xmlEncode(node.textContent);
         }
+
         ++this._state;
         this._loopIndex = 0;
+
       case 5:
         var value;
+
         while (true) {
           value = this._childSerializer && this._childSerializer.getNext();
+
           if (value !== null) {
             return value;
           }
+
           var nextChild = node.childNodes[this._loopIndex++];
+
           if (nextChild) {
             this._childSerializer = new DOMElementSerializer(nextChild);
           } else {
@@ -182,11 +219,14 @@ DOMElementSerializer.prototype = {
             break;
           }
         }
+
       case 6:
         ++this._state;
         return '</' + node.nodeName + '>';
+
       case 7:
         return null;
+
       default:
         throw new Error('Unexpected serialization state: ' + this._state);
     }
@@ -194,12 +234,17 @@ DOMElementSerializer.prototype = {
 };
 var document = {
   childNodes: [],
+
   get currentScript() {
-    return { src: '' };
+    return {
+      src: ''
+    };
   },
+
   get documentElement() {
     return this;
   },
+
   createElementNS: function createElementNS(NS, element) {
     var elObject = new DOMElement(element);
     return elObject;
@@ -211,33 +256,41 @@ var document = {
     if (element === 'head') {
       return [this.head || (this.head = new DOMElement('head'))];
     }
+
     return [];
   }
 };
+
 function Image() {
   this._src = null;
   this.onload = null;
 }
+
 Image.prototype = {
   get src() {
     return this._src;
   },
+
   set src(value) {
     this._src = value;
+
     if (this.onload) {
       this.onload();
     }
   }
+
 };
 exports.document = document;
 exports.Image = Image;
 var exported_symbols = Object.keys(exports);
+
 exports.setStubs = function (namespace) {
   exported_symbols.forEach(function (key) {
     console.assert(!(key in namespace), 'property should not be set: ' + key);
     namespace[key] = exports[key];
   });
 };
+
 exports.unsetStubs = function (namespace) {
   exported_symbols.forEach(function (key) {
     console.assert(key in namespace, 'property should be set: ' + key);

+ 21 - 4
lib/pdf.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,30 +21,43 @@
  */
 'use strict';
 
-var pdfjsVersion = '2.0.489';
-var pdfjsBuild = '7d7bc80e';
+var pdfjsVersion = '2.1.266';
+var pdfjsBuild = '81f5835c';
+
 var pdfjsSharedUtil = require('./shared/util.js');
+
 var pdfjsDisplayAPI = require('./display/api.js');
+
 var pdfjsDisplayTextLayer = require('./display/text_layer.js');
+
 var pdfjsDisplayAnnotationLayer = require('./display/annotation_layer.js');
+
 var pdfjsDisplayDOMUtils = require('./display/dom_utils.js');
+
 var pdfjsDisplaySVG = require('./display/svg.js');
+
 var pdfjsDisplayWorkerOptions = require('./display/worker_options.js');
+
 var pdfjsDisplayAPICompatibility = require('./display/api_compatibility.js');
+
 {
   var isNodeJS = require('./shared/is_node.js');
+
   if (isNodeJS()) {
     var PDFNodeStream = require('./display/node_stream.js').PDFNodeStream;
+
     pdfjsDisplayAPI.setPDFNetworkStreamFactory(function (params) {
       return new PDFNodeStream(params);
     });
   } else if (typeof Response !== 'undefined' && 'body' in Response.prototype && typeof ReadableStream !== 'undefined') {
     var PDFFetchStream = require('./display/fetch_stream.js').PDFFetchStream;
+
     pdfjsDisplayAPI.setPDFNetworkStreamFactory(function (params) {
       return new PDFFetchStream(params);
     });
   } else {
     var PDFNetworkStream = require('./display/network.js').PDFNetworkStream;
+
     pdfjsDisplayAPI.setPDFNetworkStreamFactory(function (params) {
       return new PDFNetworkStream(params);
     });
@@ -64,6 +77,8 @@ exports.InvalidPDFException = pdfjsSharedUtil.InvalidPDFException;
 exports.MissingPDFException = pdfjsSharedUtil.MissingPDFException;
 exports.SVGGraphics = pdfjsDisplaySVG.SVGGraphics;
 exports.NativeImageDecoding = pdfjsSharedUtil.NativeImageDecoding;
+exports.CMapCompressionType = pdfjsSharedUtil.CMapCompressionType;
+exports.PermissionFlag = pdfjsSharedUtil.PermissionFlag;
 exports.UnexpectedResponseException = pdfjsSharedUtil.UnexpectedResponseException;
 exports.OPS = pdfjsSharedUtil.OPS;
 exports.VerbosityLevel = pdfjsSharedUtil.VerbosityLevel;
@@ -72,11 +87,13 @@ exports.createValidAbsoluteUrl = pdfjsSharedUtil.createValidAbsoluteUrl;
 exports.createObjectURL = pdfjsSharedUtil.createObjectURL;
 exports.removeNullCharacters = pdfjsSharedUtil.removeNullCharacters;
 exports.shadow = pdfjsSharedUtil.shadow;
-exports.createBlob = pdfjsSharedUtil.createBlob;
 exports.Util = pdfjsSharedUtil.Util;
+exports.ReadableStream = pdfjsSharedUtil.ReadableStream;
+exports.URL = pdfjsSharedUtil.URL;
 exports.RenderingCancelledException = pdfjsDisplayDOMUtils.RenderingCancelledException;
 exports.getFilenameFromUrl = pdfjsDisplayDOMUtils.getFilenameFromUrl;
 exports.LinkTarget = pdfjsDisplayDOMUtils.LinkTarget;
 exports.addLinkAttributes = pdfjsDisplayDOMUtils.addLinkAttributes;
+exports.loadScript = pdfjsDisplayDOMUtils.loadScript;
 exports.GlobalWorkerOptions = pdfjsDisplayWorkerOptions.GlobalWorkerOptions;
 exports.apiCompatibilityParams = pdfjsDisplayAPICompatibility.apiCompatibilityParams;

+ 5 - 3
lib/pdf.worker.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,7 +21,9 @@
  */
 'use strict';
 
-var pdfjsVersion = '2.0.489';
-var pdfjsBuild = '7d7bc80e';
+var pdfjsVersion = '2.1.266';
+var pdfjsBuild = '81f5835c';
+
 var pdfjsCoreWorker = require('./core/worker.js');
+
 exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;

+ 158 - 564
lib/shared/compatibility.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,657 +19,251 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
-var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
+function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
 
 var globalScope = require('./global_scope');
+
 if (!globalScope._pdfjsCompatibilityChecked) {
   globalScope._pdfjsCompatibilityChecked = true;
+
   var isNodeJS = require('./is_node');
-  var hasDOM = (typeof window === 'undefined' ? 'undefined' : _typeof(window)) === 'object' && (typeof document === 'undefined' ? 'undefined' : _typeof(document)) === 'object';
+
+  var hasDOM = (typeof window === "undefined" ? "undefined" : _typeof(window)) === 'object' && (typeof document === "undefined" ? "undefined" : _typeof(document)) === 'object';
+
   (function checkNodeBtoa() {
     if (globalScope.btoa || !isNodeJS()) {
       return;
     }
+
     globalScope.btoa = function (chars) {
       return Buffer.from(chars, 'binary').toString('base64');
     };
   })();
+
   (function checkNodeAtob() {
     if (globalScope.atob || !isNodeJS()) {
       return;
     }
+
     globalScope.atob = function (input) {
       return Buffer.from(input, 'base64').toString('binary');
     };
   })();
-  (function checkCurrentScript() {
-    if (!hasDOM) {
-      return;
-    }
-    if ('currentScript' in document) {
-      return;
-    }
-    Object.defineProperty(document, 'currentScript', {
-      get: function get() {
-        var scripts = document.getElementsByTagName('script');
-        return scripts[scripts.length - 1];
-      },
-
-      enumerable: true,
-      configurable: true
-    });
-  })();
+
   (function checkChildNodeRemove() {
     if (!hasDOM) {
       return;
     }
+
     if (typeof Element.prototype.remove !== 'undefined') {
       return;
     }
+
     Element.prototype.remove = function () {
       if (this.parentNode) {
         this.parentNode.removeChild(this);
       }
     };
   })();
+
+  (function checkDOMTokenListAddRemove() {
+    if (!hasDOM || isNodeJS()) {
+      return;
+    }
+
+    var div = document.createElement('div');
+    div.classList.add('testOne', 'testTwo');
+
+    if (div.classList.contains('testOne') === true && div.classList.contains('testTwo') === true) {
+      return;
+    }
+
+    var OriginalDOMTokenListAdd = DOMTokenList.prototype.add;
+    var OriginalDOMTokenListRemove = DOMTokenList.prototype.remove;
+
+    DOMTokenList.prototype.add = function () {
+      for (var _len = arguments.length, tokens = new Array(_len), _key = 0; _key < _len; _key++) {
+        tokens[_key] = arguments[_key];
+      }
+
+      for (var _i = 0; _i < tokens.length; _i++) {
+        var token = tokens[_i];
+        OriginalDOMTokenListAdd.call(this, token);
+      }
+    };
+
+    DOMTokenList.prototype.remove = function () {
+      for (var _len2 = arguments.length, tokens = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
+        tokens[_key2] = arguments[_key2];
+      }
+
+      for (var _i2 = 0; _i2 < tokens.length; _i2++) {
+        var token = tokens[_i2];
+        OriginalDOMTokenListRemove.call(this, token);
+      }
+    };
+  })();
+
+  (function checkDOMTokenListToggle() {
+    if (!hasDOM || isNodeJS()) {
+      return;
+    }
+
+    var div = document.createElement('div');
+
+    if (div.classList.toggle('test', 0) === false) {
+      return;
+    }
+
+    DOMTokenList.prototype.toggle = function (token) {
+      var force = arguments.length > 1 ? !!arguments[1] : !this.contains(token);
+      return this[force ? 'add' : 'remove'](token), force;
+    };
+  })();
+
+  (function checkStringStartsWith() {
+    if (String.prototype.startsWith) {
+      return;
+    }
+
+    require('core-js/fn/string/starts-with');
+  })();
+
+  (function checkStringEndsWith() {
+    if (String.prototype.endsWith) {
+      return;
+    }
+
+    require('core-js/fn/string/ends-with');
+  })();
+
   (function checkStringIncludes() {
     if (String.prototype.includes) {
       return;
     }
+
     require('core-js/fn/string/includes');
   })();
+
   (function checkArrayIncludes() {
     if (Array.prototype.includes) {
       return;
     }
+
     require('core-js/fn/array/includes');
   })();
+
+  (function checkArrayFrom() {
+    if (Array.from) {
+      return;
+    }
+
+    require('core-js/fn/array/from');
+  })();
+
+  (function checkObjectAssign() {
+    if (Object.assign) {
+      return;
+    }
+
+    require('core-js/fn/object/assign');
+  })();
+
   (function checkMathLog2() {
     if (Math.log2) {
       return;
     }
+
     Math.log2 = require('core-js/fn/math/log2');
   })();
+
   (function checkNumberIsNaN() {
     if (Number.isNaN) {
       return;
     }
+
     Number.isNaN = require('core-js/fn/number/is-nan');
   })();
+
   (function checkNumberIsInteger() {
     if (Number.isInteger) {
       return;
     }
+
     Number.isInteger = require('core-js/fn/number/is-integer');
   })();
+
   (function checkPromise() {
-    if (globalScope.Promise) {
+    if (globalScope.Promise && globalScope.Promise.prototype && globalScope.Promise.prototype.finally) {
       return;
     }
+
     globalScope.Promise = require('core-js/fn/promise');
   })();
+
   (function checkWeakMap() {
     if (globalScope.WeakMap) {
       return;
     }
+
     globalScope.WeakMap = require('core-js/fn/weak-map');
   })();
-  (function checkURLConstructor() {
-    var hasWorkingUrl = false;
-    try {
-      if (typeof URL === 'function' && _typeof(URL.prototype) === 'object' && 'origin' in URL.prototype) {
-        var u = new URL('b', 'http://a');
-        u.pathname = 'c%20d';
-        hasWorkingUrl = u.href === 'http://a/c%20d';
-      }
-    } catch (e) {}
-    if (hasWorkingUrl) {
+
+  (function checkWeakSet() {
+    if (globalScope.WeakSet) {
       return;
     }
-    var relative = Object.create(null);
-    relative['ftp'] = 21;
-    relative['file'] = 0;
-    relative['gopher'] = 70;
-    relative['http'] = 80;
-    relative['https'] = 443;
-    relative['ws'] = 80;
-    relative['wss'] = 443;
-    var relativePathDotMapping = Object.create(null);
-    relativePathDotMapping['%2e'] = '.';
-    relativePathDotMapping['.%2e'] = '..';
-    relativePathDotMapping['%2e.'] = '..';
-    relativePathDotMapping['%2e%2e'] = '..';
-    function isRelativeScheme(scheme) {
-      return relative[scheme] !== undefined;
-    }
-    function invalid() {
-      clear.call(this);
-      this._isInvalid = true;
-    }
-    function IDNAToASCII(h) {
-      if (h === '') {
-        invalid.call(this);
-      }
-      return h.toLowerCase();
-    }
-    function percentEscape(c) {
-      var unicode = c.charCodeAt(0);
-      if (unicode > 0x20 && unicode < 0x7F && [0x22, 0x23, 0x3C, 0x3E, 0x3F, 0x60].indexOf(unicode) === -1) {
-        return c;
-      }
-      return encodeURIComponent(c);
-    }
-    function percentEscapeQuery(c) {
-      var unicode = c.charCodeAt(0);
-      if (unicode > 0x20 && unicode < 0x7F && [0x22, 0x23, 0x3C, 0x3E, 0x60].indexOf(unicode) === -1) {
-        return c;
-      }
-      return encodeURIComponent(c);
+
+    globalScope.WeakSet = require('core-js/fn/weak-set');
+  })();
+
+  (function checkStringCodePointAt() {
+    if (String.codePointAt) {
+      return;
     }
-    var EOF,
-        ALPHA = /[a-zA-Z]/,
-        ALPHANUMERIC = /[a-zA-Z0-9\+\-\.]/;
-    function parse(input, stateOverride, base) {
-      function err(message) {
-        errors.push(message);
-      }
-      var state = stateOverride || 'scheme start',
-          cursor = 0,
-          buffer = '',
-          seenAt = false,
-          seenBracket = false,
-          errors = [];
-      loop: while ((input[cursor - 1] !== EOF || cursor === 0) && !this._isInvalid) {
-        var c = input[cursor];
-        switch (state) {
-          case 'scheme start':
-            if (c && ALPHA.test(c)) {
-              buffer += c.toLowerCase();
-              state = 'scheme';
-            } else if (!stateOverride) {
-              buffer = '';
-              state = 'no scheme';
-              continue;
-            } else {
-              err('Invalid scheme.');
-              break loop;
-            }
-            break;
-          case 'scheme':
-            if (c && ALPHANUMERIC.test(c)) {
-              buffer += c.toLowerCase();
-            } else if (c === ':') {
-              this._scheme = buffer;
-              buffer = '';
-              if (stateOverride) {
-                break loop;
-              }
-              if (isRelativeScheme(this._scheme)) {
-                this._isRelative = true;
-              }
-              if (this._scheme === 'file') {
-                state = 'relative';
-              } else if (this._isRelative && base && base._scheme === this._scheme) {
-                state = 'relative or authority';
-              } else if (this._isRelative) {
-                state = 'authority first slash';
-              } else {
-                state = 'scheme data';
-              }
-            } else if (!stateOverride) {
-              buffer = '';
-              cursor = 0;
-              state = 'no scheme';
-              continue;
-            } else if (c === EOF) {
-              break loop;
-            } else {
-              err('Code point not allowed in scheme: ' + c);
-              break loop;
-            }
-            break;
-          case 'scheme data':
-            if (c === '?') {
-              this._query = '?';
-              state = 'query';
-            } else if (c === '#') {
-              this._fragment = '#';
-              state = 'fragment';
-            } else {
-              if (c !== EOF && c !== '\t' && c !== '\n' && c !== '\r') {
-                this._schemeData += percentEscape(c);
-              }
-            }
-            break;
-          case 'no scheme':
-            if (!base || !isRelativeScheme(base._scheme)) {
-              err('Missing scheme.');
-              invalid.call(this);
-            } else {
-              state = 'relative';
-              continue;
-            }
-            break;
-          case 'relative or authority':
-            if (c === '/' && input[cursor + 1] === '/') {
-              state = 'authority ignore slashes';
-            } else {
-              err('Expected /, got: ' + c);
-              state = 'relative';
-              continue;
-            }
-            break;
-          case 'relative':
-            this._isRelative = true;
-            if (this._scheme !== 'file') {
-              this._scheme = base._scheme;
-            }
-            if (c === EOF) {
-              this._host = base._host;
-              this._port = base._port;
-              this._path = base._path.slice();
-              this._query = base._query;
-              this._username = base._username;
-              this._password = base._password;
-              break loop;
-            } else if (c === '/' || c === '\\') {
-              if (c === '\\') {
-                err('\\ is an invalid code point.');
-              }
-              state = 'relative slash';
-            } else if (c === '?') {
-              this._host = base._host;
-              this._port = base._port;
-              this._path = base._path.slice();
-              this._query = '?';
-              this._username = base._username;
-              this._password = base._password;
-              state = 'query';
-            } else if (c === '#') {
-              this._host = base._host;
-              this._port = base._port;
-              this._path = base._path.slice();
-              this._query = base._query;
-              this._fragment = '#';
-              this._username = base._username;
-              this._password = base._password;
-              state = 'fragment';
-            } else {
-              var nextC = input[cursor + 1];
-              var nextNextC = input[cursor + 2];
-              if (this._scheme !== 'file' || !ALPHA.test(c) || nextC !== ':' && nextC !== '|' || nextNextC !== EOF && nextNextC !== '/' && nextNextC !== '\\' && nextNextC !== '?' && nextNextC !== '#') {
-                this._host = base._host;
-                this._port = base._port;
-                this._username = base._username;
-                this._password = base._password;
-                this._path = base._path.slice();
-                this._path.pop();
-              }
-              state = 'relative path';
-              continue;
-            }
-            break;
-          case 'relative slash':
-            if (c === '/' || c === '\\') {
-              if (c === '\\') {
-                err('\\ is an invalid code point.');
-              }
-              if (this._scheme === 'file') {
-                state = 'file host';
-              } else {
-                state = 'authority ignore slashes';
-              }
-            } else {
-              if (this._scheme !== 'file') {
-                this._host = base._host;
-                this._port = base._port;
-                this._username = base._username;
-                this._password = base._password;
-              }
-              state = 'relative path';
-              continue;
-            }
-            break;
-          case 'authority first slash':
-            if (c === '/') {
-              state = 'authority second slash';
-            } else {
-              err('Expected \'/\', got: ' + c);
-              state = 'authority ignore slashes';
-              continue;
-            }
-            break;
-          case 'authority second slash':
-            state = 'authority ignore slashes';
-            if (c !== '/') {
-              err('Expected \'/\', got: ' + c);
-              continue;
-            }
-            break;
-          case 'authority ignore slashes':
-            if (c !== '/' && c !== '\\') {
-              state = 'authority';
-              continue;
-            } else {
-              err('Expected authority, got: ' + c);
-            }
-            break;
-          case 'authority':
-            if (c === '@') {
-              if (seenAt) {
-                err('@ already seen.');
-                buffer += '%40';
-              }
-              seenAt = true;
-              for (var i = 0; i < buffer.length; i++) {
-                var cp = buffer[i];
-                if (cp === '\t' || cp === '\n' || cp === '\r') {
-                  err('Invalid whitespace in authority.');
-                  continue;
-                }
-                if (cp === ':' && this._password === null) {
-                  this._password = '';
-                  continue;
-                }
-                var tempC = percentEscape(cp);
-                if (this._password !== null) {
-                  this._password += tempC;
-                } else {
-                  this._username += tempC;
-                }
-              }
-              buffer = '';
-            } else if (c === EOF || c === '/' || c === '\\' || c === '?' || c === '#') {
-              cursor -= buffer.length;
-              buffer = '';
-              state = 'host';
-              continue;
-            } else {
-              buffer += c;
-            }
-            break;
-          case 'file host':
-            if (c === EOF || c === '/' || c === '\\' || c === '?' || c === '#') {
-              if (buffer.length === 2 && ALPHA.test(buffer[0]) && (buffer[1] === ':' || buffer[1] === '|')) {
-                state = 'relative path';
-              } else if (buffer.length === 0) {
-                state = 'relative path start';
-              } else {
-                this._host = IDNAToASCII.call(this, buffer);
-                buffer = '';
-                state = 'relative path start';
-              }
-              continue;
-            } else if (c === '\t' || c === '\n' || c === '\r') {
-              err('Invalid whitespace in file host.');
-            } else {
-              buffer += c;
-            }
-            break;
-          case 'host':
-          case 'hostname':
-            if (c === ':' && !seenBracket) {
-              this._host = IDNAToASCII.call(this, buffer);
-              buffer = '';
-              state = 'port';
-              if (stateOverride === 'hostname') {
-                break loop;
-              }
-            } else if (c === EOF || c === '/' || c === '\\' || c === '?' || c === '#') {
-              this._host = IDNAToASCII.call(this, buffer);
-              buffer = '';
-              state = 'relative path start';
-              if (stateOverride) {
-                break loop;
-              }
-              continue;
-            } else if (c !== '\t' && c !== '\n' && c !== '\r') {
-              if (c === '[') {
-                seenBracket = true;
-              } else if (c === ']') {
-                seenBracket = false;
-              }
-              buffer += c;
-            } else {
-              err('Invalid code point in host/hostname: ' + c);
-            }
-            break;
-          case 'port':
-            if (/[0-9]/.test(c)) {
-              buffer += c;
-            } else if (c === EOF || c === '/' || c === '\\' || c === '?' || c === '#' || stateOverride) {
-              if (buffer !== '') {
-                var temp = parseInt(buffer, 10);
-                if (temp !== relative[this._scheme]) {
-                  this._port = temp + '';
-                }
-                buffer = '';
-              }
-              if (stateOverride) {
-                break loop;
-              }
-              state = 'relative path start';
-              continue;
-            } else if (c === '\t' || c === '\n' || c === '\r') {
-              err('Invalid code point in port: ' + c);
-            } else {
-              invalid.call(this);
-            }
-            break;
-          case 'relative path start':
-            if (c === '\\') {
-              err('\'\\\' not allowed in path.');
-            }
-            state = 'relative path';
-            if (c !== '/' && c !== '\\') {
-              continue;
-            }
-            break;
-          case 'relative path':
-            if (c === EOF || c === '/' || c === '\\' || !stateOverride && (c === '?' || c === '#')) {
-              if (c === '\\') {
-                err('\\ not allowed in relative path.');
-              }
-              var tmp;
-              if (tmp = relativePathDotMapping[buffer.toLowerCase()]) {
-                buffer = tmp;
-              }
-              if (buffer === '..') {
-                this._path.pop();
-                if (c !== '/' && c !== '\\') {
-                  this._path.push('');
-                }
-              } else if (buffer === '.' && c !== '/' && c !== '\\') {
-                this._path.push('');
-              } else if (buffer !== '.') {
-                if (this._scheme === 'file' && this._path.length === 0 && buffer.length === 2 && ALPHA.test(buffer[0]) && buffer[1] === '|') {
-                  buffer = buffer[0] + ':';
-                }
-                this._path.push(buffer);
-              }
-              buffer = '';
-              if (c === '?') {
-                this._query = '?';
-                state = 'query';
-              } else if (c === '#') {
-                this._fragment = '#';
-                state = 'fragment';
-              }
-            } else if (c !== '\t' && c !== '\n' && c !== '\r') {
-              buffer += percentEscape(c);
-            }
-            break;
-          case 'query':
-            if (!stateOverride && c === '#') {
-              this._fragment = '#';
-              state = 'fragment';
-            } else if (c !== EOF && c !== '\t' && c !== '\n' && c !== '\r') {
-              this._query += percentEscapeQuery(c);
-            }
-            break;
-          case 'fragment':
-            if (c !== EOF && c !== '\t' && c !== '\n' && c !== '\r') {
-              this._fragment += c;
-            }
-            break;
-        }
-        cursor++;
-      }
+
+    String.codePointAt = require('core-js/fn/string/code-point-at');
+  })();
+
+  (function checkStringFromCodePoint() {
+    if (String.fromCodePoint) {
+      return;
     }
-    function clear() {
-      this._scheme = '';
-      this._schemeData = '';
-      this._username = '';
-      this._password = null;
-      this._host = '';
-      this._port = '';
-      this._path = [];
-      this._query = '';
-      this._fragment = '';
-      this._isInvalid = false;
-      this._isRelative = false;
+
+    String.fromCodePoint = require('core-js/fn/string/from-code-point');
+  })();
+
+  (function checkSymbol() {
+    if (globalScope.Symbol) {
+      return;
     }
-    function JURL(url, base) {
-      if (base !== undefined && !(base instanceof JURL)) {
-        base = new JURL(String(base));
-      }
-      this._url = url;
-      clear.call(this);
-      var input = url.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g, '');
-      parse.call(this, input, null, base);
+
+    require('core-js/es6/symbol');
+  })();
+
+  (function checkStringPadStart() {
+    if (String.prototype.padStart) {
+      return;
     }
-    JURL.prototype = {
-      toString: function toString() {
-        return this.href;
-      },
-
-      get href() {
-        if (this._isInvalid) {
-          return this._url;
-        }
-        var authority = '';
-        if (this._username !== '' || this._password !== null) {
-          authority = this._username + (this._password !== null ? ':' + this._password : '') + '@';
-        }
-        return this.protocol + (this._isRelative ? '//' + authority + this.host : '') + this.pathname + this._query + this._fragment;
-      },
-      set href(value) {
-        clear.call(this);
-        parse.call(this, value);
-      },
-      get protocol() {
-        return this._scheme + ':';
-      },
-      set protocol(value) {
-        if (this._isInvalid) {
-          return;
-        }
-        parse.call(this, value + ':', 'scheme start');
-      },
-      get host() {
-        return this._isInvalid ? '' : this._port ? this._host + ':' + this._port : this._host;
-      },
-      set host(value) {
-        if (this._isInvalid || !this._isRelative) {
-          return;
-        }
-        parse.call(this, value, 'host');
-      },
-      get hostname() {
-        return this._host;
-      },
-      set hostname(value) {
-        if (this._isInvalid || !this._isRelative) {
-          return;
-        }
-        parse.call(this, value, 'hostname');
-      },
-      get port() {
-        return this._port;
-      },
-      set port(value) {
-        if (this._isInvalid || !this._isRelative) {
-          return;
-        }
-        parse.call(this, value, 'port');
-      },
-      get pathname() {
-        return this._isInvalid ? '' : this._isRelative ? '/' + this._path.join('/') : this._schemeData;
-      },
-      set pathname(value) {
-        if (this._isInvalid || !this._isRelative) {
-          return;
-        }
-        this._path = [];
-        parse.call(this, value, 'relative path start');
-      },
-      get search() {
-        return this._isInvalid || !this._query || this._query === '?' ? '' : this._query;
-      },
-      set search(value) {
-        if (this._isInvalid || !this._isRelative) {
-          return;
-        }
-        this._query = '?';
-        if (value[0] === '?') {
-          value = value.slice(1);
-        }
-        parse.call(this, value, 'query');
-      },
-      get hash() {
-        return this._isInvalid || !this._fragment || this._fragment === '#' ? '' : this._fragment;
-      },
-      set hash(value) {
-        if (this._isInvalid) {
-          return;
-        }
-        this._fragment = '#';
-        if (value[0] === '#') {
-          value = value.slice(1);
-        }
-        parse.call(this, value, 'fragment');
-      },
-      get origin() {
-        var host;
-        if (this._isInvalid || !this._scheme) {
-          return '';
-        }
-        switch (this._scheme) {
-          case 'data':
-          case 'file':
-          case 'javascript':
-          case 'mailto':
-            return 'null';
-          case 'blob':
-            try {
-              return new JURL(this._schemeData).origin || 'null';
-            } catch (_) {}
-            return 'null';
-        }
-        host = this.host;
-        if (!host) {
-          return '';
-        }
-        return this._scheme + '://' + host;
-      }
-    };
-    var OriginalURL = globalScope.URL;
-    if (OriginalURL) {
-      JURL.createObjectURL = function (blob) {
-        return OriginalURL.createObjectURL.apply(OriginalURL, arguments);
-      };
-      JURL.revokeObjectURL = function (url) {
-        OriginalURL.revokeObjectURL(url);
-      };
+
+    require('core-js/fn/string/pad-start');
+  })();
+
+  (function checkStringPadEnd() {
+    if (String.prototype.padEnd) {
+      return;
     }
-    globalScope.URL = JURL;
+
+    require('core-js/fn/string/pad-end');
   })();
+
   (function checkObjectValues() {
     if (Object.values) {
       return;
     }
+
     Object.values = require('core-js/fn/object/values');
   })();
 }

+ 2 - 2
lib/shared/global_scope.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,6 +19,6 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 module.exports = typeof window !== 'undefined' && window.Math === Math ? window : typeof global !== 'undefined' && global.Math === Math ? global : typeof self !== 'undefined' && self.Math === Math ? self : {};

+ 4 - 4
lib/shared/is_node.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,10 +19,10 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
-var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
+function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
 
 module.exports = function isNodeJS() {
-  return (typeof process === 'undefined' ? 'undefined' : _typeof(process)) === 'object' && process + '' === '[object process]';
+  return (typeof process === "undefined" ? "undefined" : _typeof(process)) === 'object' && process + '' === '[object process]' && !process.versions['nw'];
 };

+ 521 - 0
lib/shared/message_handler.js

@@ -0,0 +1,521 @@
+/**
+ * @licstart The following is the entire license notice for the
+ * Javascript code in this page
+ *
+ * Copyright 2018 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @licend The above is the entire license notice for the
+ * Javascript code in this page
+ */
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.MessageHandler = MessageHandler;
+
+var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
+
+var _util = require("./util");
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
+
+function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
+
+function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
+
+function resolveCall(_x, _x2) {
+  return _resolveCall.apply(this, arguments);
+}
+
+function _resolveCall() {
+  _resolveCall = _asyncToGenerator(
+  /*#__PURE__*/
+  _regenerator.default.mark(function _callee(fn, args) {
+    var thisArg,
+        _args = arguments;
+    return _regenerator.default.wrap(function _callee$(_context) {
+      while (1) {
+        switch (_context.prev = _context.next) {
+          case 0:
+            thisArg = _args.length > 2 && _args[2] !== undefined ? _args[2] : null;
+
+            if (fn) {
+              _context.next = 3;
+              break;
+            }
+
+            return _context.abrupt("return");
+
+          case 3:
+            return _context.abrupt("return", fn.apply(thisArg, args));
+
+          case 4:
+          case "end":
+            return _context.stop();
+        }
+      }
+    }, _callee, this);
+  }));
+  return _resolveCall.apply(this, arguments);
+}
+
+function wrapReason(reason) {
+  if (_typeof(reason) !== 'object') {
+    return reason;
+  }
+
+  switch (reason.name) {
+    case 'AbortException':
+      return new _util.AbortException(reason.message);
+
+    case 'MissingPDFException':
+      return new _util.MissingPDFException(reason.message);
+
+    case 'UnexpectedResponseException':
+      return new _util.UnexpectedResponseException(reason.message, reason.status);
+
+    default:
+      return new _util.UnknownErrorException(reason.message, reason.details);
+  }
+}
+
+function makeReasonSerializable(reason) {
+  if (!(reason instanceof Error) || reason instanceof _util.AbortException || reason instanceof _util.MissingPDFException || reason instanceof _util.UnexpectedResponseException || reason instanceof _util.UnknownErrorException) {
+    return reason;
+  }
+
+  return new _util.UnknownErrorException(reason.message, reason.toString());
+}
+
+function resolveOrReject(capability, success, reason) {
+  if (success) {
+    capability.resolve();
+  } else {
+    capability.reject(reason);
+  }
+}
+
+function finalize(promise) {
+  return Promise.resolve(promise).catch(function () {});
+}
+
+function MessageHandler(sourceName, targetName, comObj) {
+  var _this = this;
+
+  this.sourceName = sourceName;
+  this.targetName = targetName;
+  this.comObj = comObj;
+  this.callbackId = 1;
+  this.streamId = 1;
+  this.postMessageTransfers = true;
+  this.streamSinks = Object.create(null);
+  this.streamControllers = Object.create(null);
+  var callbacksCapabilities = this.callbacksCapabilities = Object.create(null);
+  var ah = this.actionHandler = Object.create(null);
+
+  this._onComObjOnMessage = function (event) {
+    var data = event.data;
+
+    if (data.targetName !== _this.sourceName) {
+      return;
+    }
+
+    if (data.stream) {
+      _this._processStreamMessage(data);
+    } else if (data.isReply) {
+      var callbackId = data.callbackId;
+
+      if (data.callbackId in callbacksCapabilities) {
+        var callback = callbacksCapabilities[callbackId];
+        delete callbacksCapabilities[callbackId];
+
+        if ('error' in data) {
+          callback.reject(wrapReason(data.error));
+        } else {
+          callback.resolve(data.data);
+        }
+      } else {
+        throw new Error("Cannot resolve callback ".concat(callbackId));
+      }
+    } else if (data.action in ah) {
+      var action = ah[data.action];
+
+      if (data.callbackId) {
+        var _sourceName = _this.sourceName;
+        var _targetName = data.sourceName;
+        Promise.resolve().then(function () {
+          return action[0].call(action[1], data.data);
+        }).then(function (result) {
+          comObj.postMessage({
+            sourceName: _sourceName,
+            targetName: _targetName,
+            isReply: true,
+            callbackId: data.callbackId,
+            data: result
+          });
+        }, function (reason) {
+          comObj.postMessage({
+            sourceName: _sourceName,
+            targetName: _targetName,
+            isReply: true,
+            callbackId: data.callbackId,
+            error: makeReasonSerializable(reason)
+          });
+        });
+      } else if (data.streamId) {
+        _this._createStreamSink(data);
+      } else {
+        action[0].call(action[1], data.data);
+      }
+    } else {
+      throw new Error("Unknown action from worker: ".concat(data.action));
+    }
+  };
+
+  comObj.addEventListener('message', this._onComObjOnMessage);
+}
+
+MessageHandler.prototype = {
+  on: function on(actionName, handler, scope) {
+    var ah = this.actionHandler;
+
+    if (ah[actionName]) {
+      throw new Error("There is already an actionName called \"".concat(actionName, "\""));
+    }
+
+    ah[actionName] = [handler, scope];
+  },
+  send: function send(actionName, data, transfers) {
+    var message = {
+      sourceName: this.sourceName,
+      targetName: this.targetName,
+      action: actionName,
+      data: data
+    };
+    this.postMessage(message, transfers);
+  },
+  sendWithPromise: function sendWithPromise(actionName, data, transfers) {
+    var callbackId = this.callbackId++;
+    var message = {
+      sourceName: this.sourceName,
+      targetName: this.targetName,
+      action: actionName,
+      data: data,
+      callbackId: callbackId
+    };
+    var capability = (0, _util.createPromiseCapability)();
+    this.callbacksCapabilities[callbackId] = capability;
+
+    try {
+      this.postMessage(message, transfers);
+    } catch (e) {
+      capability.reject(e);
+    }
+
+    return capability.promise;
+  },
+  sendWithStream: function sendWithStream(actionName, data, queueingStrategy, transfers) {
+    var _this2 = this;
+
+    var streamId = this.streamId++;
+    var sourceName = this.sourceName;
+    var targetName = this.targetName;
+    return new _util.ReadableStream({
+      start: function start(controller) {
+        var startCapability = (0, _util.createPromiseCapability)();
+        _this2.streamControllers[streamId] = {
+          controller: controller,
+          startCall: startCapability,
+          isClosed: false
+        };
+
+        _this2.postMessage({
+          sourceName: sourceName,
+          targetName: targetName,
+          action: actionName,
+          streamId: streamId,
+          data: data,
+          desiredSize: controller.desiredSize
+        });
+
+        return startCapability.promise;
+      },
+      pull: function pull(controller) {
+        var pullCapability = (0, _util.createPromiseCapability)();
+        _this2.streamControllers[streamId].pullCall = pullCapability;
+
+        _this2.postMessage({
+          sourceName: sourceName,
+          targetName: targetName,
+          stream: 'pull',
+          streamId: streamId,
+          desiredSize: controller.desiredSize
+        });
+
+        return pullCapability.promise;
+      },
+      cancel: function cancel(reason) {
+        var cancelCapability = (0, _util.createPromiseCapability)();
+        _this2.streamControllers[streamId].cancelCall = cancelCapability;
+        _this2.streamControllers[streamId].isClosed = true;
+
+        _this2.postMessage({
+          sourceName: sourceName,
+          targetName: targetName,
+          stream: 'cancel',
+          reason: reason,
+          streamId: streamId
+        });
+
+        return cancelCapability.promise;
+      }
+    }, queueingStrategy);
+  },
+  _createStreamSink: function _createStreamSink(data) {
+    var _this3 = this;
+
+    var self = this;
+    var action = this.actionHandler[data.action];
+    var streamId = data.streamId;
+    var desiredSize = data.desiredSize;
+    var sourceName = this.sourceName;
+    var targetName = data.sourceName;
+    var capability = (0, _util.createPromiseCapability)();
+
+    var sendStreamRequest = function sendStreamRequest(_ref) {
+      var stream = _ref.stream,
+          chunk = _ref.chunk,
+          transfers = _ref.transfers,
+          success = _ref.success,
+          reason = _ref.reason;
+
+      _this3.postMessage({
+        sourceName: sourceName,
+        targetName: targetName,
+        stream: stream,
+        streamId: streamId,
+        chunk: chunk,
+        success: success,
+        reason: reason
+      }, transfers);
+    };
+
+    var streamSink = {
+      enqueue: function enqueue(chunk) {
+        var size = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
+        var transfers = arguments.length > 2 ? arguments[2] : undefined;
+
+        if (this.isCancelled) {
+          return;
+        }
+
+        var lastDesiredSize = this.desiredSize;
+        this.desiredSize -= size;
+
+        if (lastDesiredSize > 0 && this.desiredSize <= 0) {
+          this.sinkCapability = (0, _util.createPromiseCapability)();
+          this.ready = this.sinkCapability.promise;
+        }
+
+        sendStreamRequest({
+          stream: 'enqueue',
+          chunk: chunk,
+          transfers: transfers
+        });
+      },
+      close: function close() {
+        if (this.isCancelled) {
+          return;
+        }
+
+        this.isCancelled = true;
+        sendStreamRequest({
+          stream: 'close'
+        });
+        delete self.streamSinks[streamId];
+      },
+      error: function error(reason) {
+        if (this.isCancelled) {
+          return;
+        }
+
+        this.isCancelled = true;
+        sendStreamRequest({
+          stream: 'error',
+          reason: reason
+        });
+      },
+      sinkCapability: capability,
+      onPull: null,
+      onCancel: null,
+      isCancelled: false,
+      desiredSize: desiredSize,
+      ready: null
+    };
+    streamSink.sinkCapability.resolve();
+    streamSink.ready = streamSink.sinkCapability.promise;
+    this.streamSinks[streamId] = streamSink;
+    resolveCall(action[0], [data.data, streamSink], action[1]).then(function () {
+      sendStreamRequest({
+        stream: 'start_complete',
+        success: true
+      });
+    }, function (reason) {
+      sendStreamRequest({
+        stream: 'start_complete',
+        success: false,
+        reason: reason
+      });
+    });
+  },
+  _processStreamMessage: function _processStreamMessage(data) {
+    var _this4 = this;
+
+    var sourceName = this.sourceName;
+    var targetName = data.sourceName;
+    var streamId = data.streamId;
+
+    var sendStreamResponse = function sendStreamResponse(_ref2) {
+      var stream = _ref2.stream,
+          success = _ref2.success,
+          reason = _ref2.reason;
+
+      _this4.comObj.postMessage({
+        sourceName: sourceName,
+        targetName: targetName,
+        stream: stream,
+        success: success,
+        streamId: streamId,
+        reason: reason
+      });
+    };
+
+    var deleteStreamController = function deleteStreamController() {
+      Promise.all([_this4.streamControllers[data.streamId].startCall, _this4.streamControllers[data.streamId].pullCall, _this4.streamControllers[data.streamId].cancelCall].map(function (capability) {
+        return capability && finalize(capability.promise);
+      })).then(function () {
+        delete _this4.streamControllers[data.streamId];
+      });
+    };
+
+    switch (data.stream) {
+      case 'start_complete':
+        resolveOrReject(this.streamControllers[data.streamId].startCall, data.success, wrapReason(data.reason));
+        break;
+
+      case 'pull_complete':
+        resolveOrReject(this.streamControllers[data.streamId].pullCall, data.success, wrapReason(data.reason));
+        break;
+
+      case 'pull':
+        if (!this.streamSinks[data.streamId]) {
+          sendStreamResponse({
+            stream: 'pull_complete',
+            success: true
+          });
+          break;
+        }
+
+        if (this.streamSinks[data.streamId].desiredSize <= 0 && data.desiredSize > 0) {
+          this.streamSinks[data.streamId].sinkCapability.resolve();
+        }
+
+        this.streamSinks[data.streamId].desiredSize = data.desiredSize;
+        resolveCall(this.streamSinks[data.streamId].onPull).then(function () {
+          sendStreamResponse({
+            stream: 'pull_complete',
+            success: true
+          });
+        }, function (reason) {
+          sendStreamResponse({
+            stream: 'pull_complete',
+            success: false,
+            reason: reason
+          });
+        });
+        break;
+
+      case 'enqueue':
+        (0, _util.assert)(this.streamControllers[data.streamId], 'enqueue should have stream controller');
+
+        if (!this.streamControllers[data.streamId].isClosed) {
+          this.streamControllers[data.streamId].controller.enqueue(data.chunk);
+        }
+
+        break;
+
+      case 'close':
+        (0, _util.assert)(this.streamControllers[data.streamId], 'close should have stream controller');
+
+        if (this.streamControllers[data.streamId].isClosed) {
+          break;
+        }
+
+        this.streamControllers[data.streamId].isClosed = true;
+        this.streamControllers[data.streamId].controller.close();
+        deleteStreamController();
+        break;
+
+      case 'error':
+        (0, _util.assert)(this.streamControllers[data.streamId], 'error should have stream controller');
+        this.streamControllers[data.streamId].controller.error(wrapReason(data.reason));
+        deleteStreamController();
+        break;
+
+      case 'cancel_complete':
+        resolveOrReject(this.streamControllers[data.streamId].cancelCall, data.success, wrapReason(data.reason));
+        deleteStreamController();
+        break;
+
+      case 'cancel':
+        if (!this.streamSinks[data.streamId]) {
+          break;
+        }
+
+        resolveCall(this.streamSinks[data.streamId].onCancel, [wrapReason(data.reason)]).then(function () {
+          sendStreamResponse({
+            stream: 'cancel_complete',
+            success: true
+          });
+        }, function (reason) {
+          sendStreamResponse({
+            stream: 'cancel_complete',
+            success: false,
+            reason: reason
+          });
+        });
+        this.streamSinks[data.streamId].sinkCapability.reject(wrapReason(data.reason));
+        this.streamSinks[data.streamId].isCancelled = true;
+        delete this.streamSinks[data.streamId];
+        break;
+
+      default:
+        throw new Error('Unexpected stream case');
+    }
+  },
+  postMessage: function postMessage(message, transfers) {
+    if (transfers && this.postMessageTransfers) {
+      this.comObj.postMessage(message, transfers);
+    } else {
+      this.comObj.postMessage(message);
+    }
+  },
+  destroy: function destroy() {
+    this.comObj.removeEventListener('message', this._onComObjOnMessage);
+  }
+};

+ 21 - 17
lib/shared/streams_polyfill.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,21 +19,25 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
-var isReadableStreamSupported = false;
-if (typeof ReadableStream !== 'undefined') {
-  try {
-    new ReadableStream({
-      start: function start(controller) {
-        controller.close();
-      }
-    });
-    isReadableStreamSupported = true;
-  } catch (e) {}
-}
-if (isReadableStreamSupported) {
-  exports.ReadableStream = ReadableStream;
-} else {
-  exports.ReadableStream = require('../../external/streams/streams-lib').ReadableStream;
+{
+  var isReadableStreamSupported = false;
+
+  if (typeof ReadableStream !== 'undefined') {
+    try {
+      new ReadableStream({
+        start: function start(controller) {
+          controller.close();
+        }
+      });
+      isReadableStreamSupported = true;
+    } catch (e) {}
+  }
+
+  if (isReadableStreamSupported) {
+    exports.ReadableStream = ReadableStream;
+  } else {
+    exports.ReadableStream = require('../../external/streams/streams-lib').ReadableStream;
+  }
 }

+ 56 - 0
lib/shared/url_polyfill.js

@@ -0,0 +1,56 @@
+/**
+ * @licstart The following is the entire license notice for the
+ * Javascript code in this page
+ *
+ * Copyright 2018 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @licend The above is the entire license notice for the
+ * Javascript code in this page
+ */
+"use strict";
+
+function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
+
+{
+  var isURLSupported = false;
+
+  try {
+    if (typeof URL === 'function' && _typeof(URL.prototype) === 'object' && 'origin' in URL.prototype) {
+      var u = new URL('b', 'http://a');
+      u.pathname = 'c%20d';
+      isURLSupported = u.href === 'http://a/c%20d';
+    }
+  } catch (ex) {}
+
+  if (isURLSupported) {
+    exports.URL = URL;
+  } else {
+    var PolyfillURL = require('../../external/url/url-lib').URL;
+
+    var OriginalURL = require('./global_scope').URL;
+
+    if (OriginalURL) {
+      PolyfillURL.createObjectURL = function (blob) {
+        return OriginalURL.createObjectURL.apply(OriginalURL, arguments);
+      };
+
+      PolyfillURL.revokeObjectURL = function (url) {
+        OriginalURL.revokeObjectURL(url);
+      };
+    }
+
+    exports.URL = PolyfillURL;
+  }
+}

+ 295 - 650
lib/shared/util.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,25 +19,89 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.unreachable = exports.warn = exports.utf8StringToString = exports.stringToUTF8String = exports.stringToPDFString = exports.stringToBytes = exports.string32 = exports.shadow = exports.setVerbosityLevel = exports.ReadableStream = exports.removeNullCharacters = exports.readUint32 = exports.readUint16 = exports.readInt8 = exports.log2 = exports.isEvalSupported = exports.isLittleEndian = exports.createValidAbsoluteUrl = exports.isSameOrigin = exports.isSpace = exports.isString = exports.isNum = exports.isEmptyObj = exports.isBool = exports.isArrayBuffer = exports.info = exports.getVerbosityLevel = exports.getLookupTableFactory = exports.getInheritableProperty = exports.deprecated = exports.createObjectURL = exports.createPromiseCapability = exports.createBlob = exports.bytesToString = exports.assert = exports.arraysToBytes = exports.arrayByteLength = exports.FormatError = exports.XRefParseException = exports.Util = exports.UnknownErrorException = exports.UnexpectedResponseException = exports.TextRenderingMode = exports.StreamType = exports.PasswordResponses = exports.PasswordException = exports.PageViewport = exports.NotImplementedException = exports.NativeImageDecoding = exports.MissingPDFException = exports.MissingDataException = exports.MessageHandler = exports.InvalidPDFException = exports.AbortException = exports.CMapCompressionType = exports.ImageKind = exports.FontType = exports.AnnotationType = exports.AnnotationFlag = exports.AnnotationFieldFlag = exports.AnnotationBorderStyleType = exports.UNSUPPORTED_FEATURES = exports.VerbosityLevel = exports.OPS = exports.IDENTITY_MATRIX = exports.FONT_IDENTITY_MATRIX = undefined;
+exports.toRomanNumerals = toRomanNumerals;
+exports.arrayByteLength = arrayByteLength;
+exports.arraysToBytes = arraysToBytes;
+exports.assert = assert;
+exports.bytesToString = bytesToString;
+exports.createPromiseCapability = createPromiseCapability;
+exports.deprecated = deprecated;
+exports.getInheritableProperty = getInheritableProperty;
+exports.getLookupTableFactory = getLookupTableFactory;
+exports.getVerbosityLevel = getVerbosityLevel;
+exports.info = info;
+exports.isArrayBuffer = isArrayBuffer;
+exports.isBool = isBool;
+exports.isEmptyObj = isEmptyObj;
+exports.isNum = isNum;
+exports.isString = isString;
+exports.isSpace = isSpace;
+exports.isSameOrigin = isSameOrigin;
+exports.createValidAbsoluteUrl = createValidAbsoluteUrl;
+exports.isLittleEndian = isLittleEndian;
+exports.isEvalSupported = isEvalSupported;
+exports.log2 = log2;
+exports.readInt8 = readInt8;
+exports.readUint16 = readUint16;
+exports.readUint32 = readUint32;
+exports.removeNullCharacters = removeNullCharacters;
+exports.setVerbosityLevel = setVerbosityLevel;
+exports.shadow = shadow;
+exports.string32 = string32;
+exports.stringToBytes = stringToBytes;
+exports.stringToPDFString = stringToPDFString;
+exports.stringToUTF8String = stringToUTF8String;
+exports.utf8StringToString = utf8StringToString;
+exports.warn = warn;
+exports.unreachable = unreachable;
+Object.defineProperty(exports, "ReadableStream", {
+  enumerable: true,
+  get: function get() {
+    return _streams_polyfill.ReadableStream;
+  }
+});
+Object.defineProperty(exports, "URL", {
+  enumerable: true,
+  get: function get() {
+    return _url_polyfill.URL;
+  }
+});
+exports.createObjectURL = exports.FormatError = exports.XRefParseException = exports.XRefEntryException = exports.Util = exports.UnknownErrorException = exports.UnexpectedResponseException = exports.TextRenderingMode = exports.StreamType = exports.PermissionFlag = exports.PasswordResponses = exports.PasswordException = exports.NativeImageDecoding = exports.MissingPDFException = exports.MissingDataException = exports.InvalidPDFException = exports.AbortException = exports.CMapCompressionType = exports.ImageKind = exports.FontType = exports.AnnotationType = exports.AnnotationFlag = exports.AnnotationFieldFlag = exports.AnnotationBorderStyleType = exports.UNSUPPORTED_FEATURES = exports.VerbosityLevel = exports.OPS = exports.IDENTITY_MATRIX = exports.FONT_IDENTITY_MATRIX = void 0;
+
+require("./compatibility");
 
-var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
+var _streams_polyfill = require("./streams_polyfill");
 
-require('./compatibility');
+var _url_polyfill = require("./url_polyfill");
 
-var _streams_polyfill = require('./streams_polyfill');
+function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
 
+var IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0];
+exports.IDENTITY_MATRIX = IDENTITY_MATRIX;
 var FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];
+exports.FONT_IDENTITY_MATRIX = FONT_IDENTITY_MATRIX;
 var NativeImageDecoding = {
   NONE: 'none',
   DECODE: 'decode',
   DISPLAY: 'display'
 };
+exports.NativeImageDecoding = NativeImageDecoding;
+var PermissionFlag = {
+  PRINT: 0x04,
+  MODIFY_CONTENTS: 0x08,
+  COPY: 0x10,
+  MODIFY_ANNOTATIONS: 0x20,
+  FILL_INTERACTIVE_FORMS: 0x100,
+  COPY_FOR_ACCESSIBILITY: 0x200,
+  ASSEMBLE: 0x400,
+  PRINT_HIGH_QUALITY: 0x800
+};
+exports.PermissionFlag = PermissionFlag;
 var TextRenderingMode = {
   FILL: 0,
   STROKE: 1,
@@ -50,11 +114,13 @@ var TextRenderingMode = {
   FILL_STROKE_MASK: 3,
   ADD_TO_PATH_FLAG: 4
 };
+exports.TextRenderingMode = TextRenderingMode;
 var ImageKind = {
   GRAYSCALE_1BPP: 1,
   RGB_24BPP: 2,
   RGBA_32BPP: 3
 };
+exports.ImageKind = ImageKind;
 var AnnotationType = {
   TEXT: 1,
   LINK: 2,
@@ -83,6 +149,7 @@ var AnnotationType = {
   THREED: 25,
   REDACT: 26
 };
+exports.AnnotationType = AnnotationType;
 var AnnotationFlag = {
   INVISIBLE: 0x01,
   HIDDEN: 0x02,
@@ -95,6 +162,7 @@ var AnnotationFlag = {
   TOGGLENOVIEW: 0x100,
   LOCKEDCONTENTS: 0x200
 };
+exports.AnnotationFlag = AnnotationFlag;
 var AnnotationFieldFlag = {
   READONLY: 0x0000001,
   REQUIRED: 0x0000002,
@@ -116,6 +184,7 @@ var AnnotationFieldFlag = {
   RADIOSINUNISON: 0x2000000,
   COMMITONSELCHANGE: 0x4000000
 };
+exports.AnnotationFieldFlag = AnnotationFieldFlag;
 var AnnotationBorderStyleType = {
   SOLID: 1,
   DASHED: 2,
@@ -123,6 +192,7 @@ var AnnotationBorderStyleType = {
   INSET: 4,
   UNDERLINE: 5
 };
+exports.AnnotationBorderStyleType = AnnotationBorderStyleType;
 var StreamType = {
   UNKNOWN: 0,
   FLATE: 1,
@@ -135,6 +205,7 @@ var StreamType = {
   CCF: 8,
   RL: 9
 };
+exports.StreamType = StreamType;
 var FontType = {
   UNKNOWN: 0,
   TYPE1: 1,
@@ -148,16 +219,19 @@ var FontType = {
   TYPE0: 9,
   MMTYPE1: 10
 };
+exports.FontType = FontType;
 var VerbosityLevel = {
   ERRORS: 0,
   WARNINGS: 1,
   INFOS: 5
 };
+exports.VerbosityLevel = VerbosityLevel;
 var CMapCompressionType = {
   NONE: 0,
   BINARY: 1,
   STREAM: 2
 };
+exports.CMapCompressionType = CMapCompressionType;
 var OPS = {
   dependency: 1,
   setLineWidth: 2,
@@ -251,60 +325,79 @@ var OPS = {
   paintSolidColorImageMask: 90,
   constructPath: 91
 };
+exports.OPS = OPS;
+var UNSUPPORTED_FEATURES = {
+  unknown: 'unknown',
+  forms: 'forms',
+  javaScript: 'javaScript',
+  smask: 'smask',
+  shadingPattern: 'shadingPattern',
+  font: 'font'
+};
+exports.UNSUPPORTED_FEATURES = UNSUPPORTED_FEATURES;
+var PasswordResponses = {
+  NEED_PASSWORD: 1,
+  INCORRECT_PASSWORD: 2
+};
+exports.PasswordResponses = PasswordResponses;
 var verbosity = VerbosityLevel.WARNINGS;
+
 function setVerbosityLevel(level) {
   if (Number.isInteger(level)) {
     verbosity = level;
   }
 }
+
 function getVerbosityLevel() {
   return verbosity;
 }
+
 function info(msg) {
   if (verbosity >= VerbosityLevel.INFOS) {
     console.log('Info: ' + msg);
   }
 }
+
 function warn(msg) {
   if (verbosity >= VerbosityLevel.WARNINGS) {
     console.log('Warning: ' + msg);
   }
 }
+
 function deprecated(details) {
   console.log('Deprecated API usage: ' + details);
 }
+
 function unreachable(msg) {
   throw new Error(msg);
 }
+
 function assert(cond, msg) {
   if (!cond) {
     unreachable(msg);
   }
 }
-var UNSUPPORTED_FEATURES = {
-  unknown: 'unknown',
-  forms: 'forms',
-  javaScript: 'javaScript',
-  smask: 'smask',
-  shadingPattern: 'shadingPattern',
-  font: 'font'
-};
+
 function isSameOrigin(baseUrl, otherUrl) {
   try {
-    var base = new URL(baseUrl);
+    var base = new _url_polyfill.URL(baseUrl);
+
     if (!base.origin || base.origin === 'null') {
       return false;
     }
   } catch (e) {
     return false;
   }
-  var other = new URL(otherUrl, base);
+
+  var other = new _url_polyfill.URL(otherUrl, base);
   return base.origin === other.origin;
 }
-function isValidProtocol(url) {
+
+function _isValidProtocol(url) {
   if (!url) {
     return false;
   }
+
   switch (url.protocol) {
     case 'http:':
     case 'https:':
@@ -312,22 +405,28 @@ function isValidProtocol(url) {
     case 'mailto:':
     case 'tel:':
       return true;
+
     default:
       return false;
   }
 }
+
 function createValidAbsoluteUrl(url, baseUrl) {
   if (!url) {
     return null;
   }
+
   try {
-    var absoluteUrl = baseUrl ? new URL(url, baseUrl) : new URL(url);
-    if (isValidProtocol(absoluteUrl)) {
+    var absoluteUrl = baseUrl ? new _url_polyfill.URL(url, baseUrl) : new _url_polyfill.URL(url);
+
+    if (_isValidProtocol(absoluteUrl)) {
       return absoluteUrl;
     }
   } catch (ex) {}
+
   return null;
 }
+
 function shadow(obj, prop, value) {
   Object.defineProperty(obj, prop, {
     value: value,
@@ -337,6 +436,7 @@ function shadow(obj, prop, value) {
   });
   return value;
 }
+
 function getLookupTableFactory(initializer) {
   var lookup;
   return function () {
@@ -345,164 +445,219 @@ function getLookupTableFactory(initializer) {
       initializer(lookup);
       initializer = null;
     }
+
     return lookup;
   };
 }
-var PasswordResponses = {
-  NEED_PASSWORD: 1,
-  INCORRECT_PASSWORD: 2
-};
+
 var PasswordException = function PasswordExceptionClosure() {
   function PasswordException(msg, code) {
     this.name = 'PasswordException';
     this.message = msg;
     this.code = code;
   }
+
   PasswordException.prototype = new Error();
   PasswordException.constructor = PasswordException;
   return PasswordException;
 }();
+
+exports.PasswordException = PasswordException;
+
 var UnknownErrorException = function UnknownErrorExceptionClosure() {
   function UnknownErrorException(msg, details) {
     this.name = 'UnknownErrorException';
     this.message = msg;
     this.details = details;
   }
+
   UnknownErrorException.prototype = new Error();
   UnknownErrorException.constructor = UnknownErrorException;
   return UnknownErrorException;
 }();
+
+exports.UnknownErrorException = UnknownErrorException;
+
 var InvalidPDFException = function InvalidPDFExceptionClosure() {
   function InvalidPDFException(msg) {
     this.name = 'InvalidPDFException';
     this.message = msg;
   }
+
   InvalidPDFException.prototype = new Error();
   InvalidPDFException.constructor = InvalidPDFException;
   return InvalidPDFException;
 }();
+
+exports.InvalidPDFException = InvalidPDFException;
+
 var MissingPDFException = function MissingPDFExceptionClosure() {
   function MissingPDFException(msg) {
     this.name = 'MissingPDFException';
     this.message = msg;
   }
+
   MissingPDFException.prototype = new Error();
   MissingPDFException.constructor = MissingPDFException;
   return MissingPDFException;
 }();
+
+exports.MissingPDFException = MissingPDFException;
+
 var UnexpectedResponseException = function UnexpectedResponseExceptionClosure() {
   function UnexpectedResponseException(msg, status) {
     this.name = 'UnexpectedResponseException';
     this.message = msg;
     this.status = status;
   }
+
   UnexpectedResponseException.prototype = new Error();
   UnexpectedResponseException.constructor = UnexpectedResponseException;
   return UnexpectedResponseException;
 }();
-var NotImplementedException = function NotImplementedExceptionClosure() {
-  function NotImplementedException(msg) {
-    this.message = msg;
-  }
-  NotImplementedException.prototype = new Error();
-  NotImplementedException.prototype.name = 'NotImplementedException';
-  NotImplementedException.constructor = NotImplementedException;
-  return NotImplementedException;
-}();
+
+exports.UnexpectedResponseException = UnexpectedResponseException;
+
 var MissingDataException = function MissingDataExceptionClosure() {
   function MissingDataException(begin, end) {
     this.begin = begin;
     this.end = end;
     this.message = 'Missing data [' + begin + ', ' + end + ')';
   }
+
   MissingDataException.prototype = new Error();
   MissingDataException.prototype.name = 'MissingDataException';
   MissingDataException.constructor = MissingDataException;
   return MissingDataException;
 }();
+
+exports.MissingDataException = MissingDataException;
+
+var XRefEntryException = function XRefEntryExceptionClosure() {
+  function XRefEntryException(msg) {
+    this.message = msg;
+  }
+
+  XRefEntryException.prototype = new Error();
+  XRefEntryException.prototype.name = 'XRefEntryException';
+  XRefEntryException.constructor = XRefEntryException;
+  return XRefEntryException;
+}();
+
+exports.XRefEntryException = XRefEntryException;
+
 var XRefParseException = function XRefParseExceptionClosure() {
   function XRefParseException(msg) {
     this.message = msg;
   }
+
   XRefParseException.prototype = new Error();
   XRefParseException.prototype.name = 'XRefParseException';
   XRefParseException.constructor = XRefParseException;
   return XRefParseException;
 }();
+
+exports.XRefParseException = XRefParseException;
+
 var FormatError = function FormatErrorClosure() {
   function FormatError(msg) {
     this.message = msg;
   }
+
   FormatError.prototype = new Error();
   FormatError.prototype.name = 'FormatError';
   FormatError.constructor = FormatError;
   return FormatError;
 }();
+
+exports.FormatError = FormatError;
+
 var AbortException = function AbortExceptionClosure() {
   function AbortException(msg) {
     this.name = 'AbortException';
     this.message = msg;
   }
+
   AbortException.prototype = new Error();
   AbortException.constructor = AbortException;
   return AbortException;
 }();
+
+exports.AbortException = AbortException;
 var NullCharactersRegExp = /\x00/g;
+
 function removeNullCharacters(str) {
   if (typeof str !== 'string') {
     warn('The argument for removeNullCharacters must be a string.');
     return str;
   }
+
   return str.replace(NullCharactersRegExp, '');
 }
+
 function bytesToString(bytes) {
-  assert(bytes !== null && (typeof bytes === 'undefined' ? 'undefined' : _typeof(bytes)) === 'object' && bytes.length !== undefined, 'Invalid argument for bytesToString');
+  assert(bytes !== null && _typeof(bytes) === 'object' && bytes.length !== undefined, 'Invalid argument for bytesToString');
   var length = bytes.length;
   var MAX_ARGUMENT_COUNT = 8192;
+
   if (length < MAX_ARGUMENT_COUNT) {
     return String.fromCharCode.apply(null, bytes);
   }
+
   var strBuf = [];
+
   for (var i = 0; i < length; i += MAX_ARGUMENT_COUNT) {
     var chunkEnd = Math.min(i + MAX_ARGUMENT_COUNT, length);
     var chunk = bytes.subarray(i, chunkEnd);
     strBuf.push(String.fromCharCode.apply(null, chunk));
   }
+
   return strBuf.join('');
 }
+
 function stringToBytes(str) {
   assert(typeof str === 'string', 'Invalid argument for stringToBytes');
   var length = str.length;
   var bytes = new Uint8Array(length);
+
   for (var i = 0; i < length; ++i) {
     bytes[i] = str.charCodeAt(i) & 0xFF;
   }
+
   return bytes;
 }
+
 function arrayByteLength(arr) {
   if (arr.length !== undefined) {
     return arr.length;
   }
+
   assert(arr.byteLength !== undefined);
   return arr.byteLength;
 }
+
 function arraysToBytes(arr) {
   if (arr.length === 1 && arr[0] instanceof Uint8Array) {
     return arr[0];
   }
+
   var resultLength = 0;
   var i,
       ii = arr.length;
   var item, itemLength;
+
   for (i = 0; i < ii; i++) {
     item = arr[i];
     itemLength = arrayByteLength(item);
     resultLength += itemLength;
   }
+
   var pos = 0;
   var data = new Uint8Array(resultLength);
+
   for (i = 0; i < ii; i++) {
     item = arr[i];
+
     if (!(item instanceof Uint8Array)) {
       if (typeof item === 'string') {
         item = stringToBytes(item);
@@ -510,36 +665,46 @@ function arraysToBytes(arr) {
         item = new Uint8Array(item);
       }
     }
+
     itemLength = item.byteLength;
     data.set(item, pos);
     pos += itemLength;
   }
+
   return data;
 }
+
 function string32(value) {
   return String.fromCharCode(value >> 24 & 0xff, value >> 16 & 0xff, value >> 8 & 0xff, value & 0xff);
 }
+
 function log2(x) {
   if (x <= 0) {
     return 0;
   }
+
   return Math.ceil(Math.log2(x));
 }
+
 function readInt8(data, start) {
   return data[start] << 24 >> 24;
 }
+
 function readUint16(data, offset) {
   return data[offset] << 8 | data[offset + 1];
 }
+
 function readUint32(data, offset) {
   return (data[offset] << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3]) >>> 0;
 }
+
 function isLittleEndian() {
   var buffer8 = new Uint8Array(4);
   buffer8[0] = 1;
   var view32 = new Uint32Array(buffer8.buffer, 0, 1);
   return view32[0] === 1;
 }
+
 function isEvalSupported() {
   try {
     new Function('');
@@ -548,60 +713,73 @@ function isEvalSupported() {
     return false;
   }
 }
+
 function getInheritableProperty(_ref) {
   var dict = _ref.dict,
       key = _ref.key,
       _ref$getArray = _ref.getArray,
-      getArray = _ref$getArray === undefined ? false : _ref$getArray,
+      getArray = _ref$getArray === void 0 ? false : _ref$getArray,
       _ref$stopWhenFound = _ref.stopWhenFound,
-      stopWhenFound = _ref$stopWhenFound === undefined ? true : _ref$stopWhenFound;
-
+      stopWhenFound = _ref$stopWhenFound === void 0 ? true : _ref$stopWhenFound;
   var LOOP_LIMIT = 100;
   var loopCount = 0;
-  var values = void 0;
+  var values;
+
   while (dict) {
     var value = getArray ? dict.getArray(key) : dict.get(key);
+
     if (value !== undefined) {
       if (stopWhenFound) {
         return value;
       }
+
       if (!values) {
         values = [];
       }
+
       values.push(value);
     }
+
     if (++loopCount > LOOP_LIMIT) {
-      warn('getInheritableProperty: maximum loop count exceeded for "' + key + '"');
+      warn("getInheritableProperty: maximum loop count exceeded for \"".concat(key, "\""));
       break;
     }
+
     dict = dict.get('Parent');
   }
+
   return values;
 }
-var IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0];
+
 var Util = function UtilClosure() {
   function Util() {}
+
   var rgbBuf = ['rgb(', 0, ',', 0, ',', 0, ')'];
+
   Util.makeCssRgb = function Util_makeCssRgb(r, g, b) {
     rgbBuf[1] = r;
     rgbBuf[3] = g;
     rgbBuf[5] = b;
     return rgbBuf.join('');
   };
+
   Util.transform = function Util_transform(m1, m2) {
     return [m1[0] * m2[0] + m1[2] * m2[1], m1[1] * m2[0] + m1[3] * m2[1], m1[0] * m2[2] + m1[2] * m2[3], m1[1] * m2[2] + m1[3] * m2[3], m1[0] * m2[4] + m1[2] * m2[5] + m1[4], m1[1] * m2[4] + m1[3] * m2[5] + m1[5]];
   };
+
   Util.applyTransform = function Util_applyTransform(p, m) {
     var xt = p[0] * m[0] + p[1] * m[2] + m[4];
     var yt = p[0] * m[1] + p[1] * m[3] + m[5];
     return [xt, yt];
   };
+
   Util.applyInverseTransform = function Util_applyInverseTransform(p, m) {
     var d = m[0] * m[3] - m[1] * m[2];
     var xt = (p[0] * m[3] - p[1] * m[2] + m[2] * m[5] - m[4] * m[3]) / d;
     var yt = (-p[0] * m[1] + p[1] * m[0] + m[4] * m[1] - m[5] * m[0]) / d;
     return [xt, yt];
   };
+
   Util.getAxialAlignedBoundingBox = function Util_getAxialAlignedBoundingBox(r, m) {
     var p1 = Util.applyTransform(r, m);
     var p2 = Util.applyTransform(r.slice(2, 4), m);
@@ -609,13 +787,16 @@ var Util = function UtilClosure() {
     var p4 = Util.applyTransform([r[2], r[1]], m);
     return [Math.min(p1[0], p2[0], p3[0], p4[0]), Math.min(p1[1], p2[1], p3[1], p4[1]), Math.max(p1[0], p2[0], p3[0], p4[0]), Math.max(p1[1], p2[1], p3[1], p4[1])];
   };
+
   Util.inverseTransform = function Util_inverseTransform(m) {
     var d = m[0] * m[3] - m[1] * m[2];
     return [m[3] / d, -m[1] / d, -m[2] / d, m[0] / d, (m[2] * m[5] - m[4] * m[3]) / d, (m[4] * m[1] - m[5] * m[0]) / d];
   };
+
   Util.apply3dTransform = function Util_apply3dTransform(m, v) {
     return [m[0] * v[0] + m[1] * v[1] + m[2] * v[2], m[3] * v[0] + m[4] * v[1] + m[5] * v[2], m[6] * v[0] + m[7] * v[1] + m[8] * v[2]];
   };
+
   Util.singularValueDecompose2dScale = function Util_singularValueDecompose2dScale(m) {
     var transpose = [m[0], m[2], m[1], m[3]];
     var a = m[0] * transpose[0] + m[1] * transpose[2];
@@ -628,180 +809,86 @@ var Util = function UtilClosure() {
     var sy = first - second || 1;
     return [Math.sqrt(sx), Math.sqrt(sy)];
   };
+
   Util.normalizeRect = function Util_normalizeRect(rect) {
     var r = rect.slice(0);
+
     if (rect[0] > rect[2]) {
       r[0] = rect[2];
       r[2] = rect[0];
     }
+
     if (rect[1] > rect[3]) {
       r[1] = rect[3];
       r[3] = rect[1];
     }
+
     return r;
   };
+
   Util.intersect = function Util_intersect(rect1, rect2) {
     function compare(a, b) {
       return a - b;
     }
+
     var orderedX = [rect1[0], rect1[2], rect2[0], rect2[2]].sort(compare),
         orderedY = [rect1[1], rect1[3], rect2[1], rect2[3]].sort(compare),
         result = [];
     rect1 = Util.normalizeRect(rect1);
     rect2 = Util.normalizeRect(rect2);
+
     if (orderedX[0] === rect1[0] && orderedX[1] === rect2[0] || orderedX[0] === rect2[0] && orderedX[1] === rect1[0]) {
       result[0] = orderedX[1];
       result[2] = orderedX[2];
     } else {
       return false;
     }
+
     if (orderedY[0] === rect1[1] && orderedY[1] === rect2[1] || orderedY[0] === rect2[1] && orderedY[1] === rect1[1]) {
       result[1] = orderedY[1];
       result[3] = orderedY[2];
     } else {
       return false;
     }
+
     return result;
   };
-  var ROMAN_NUMBER_MAP = ['', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM', '', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC', '', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX'];
-  Util.toRoman = function Util_toRoman(number, lowerCase) {
-    assert(Number.isInteger(number) && number > 0, 'The number should be a positive integer.');
-    var pos,
-        romanBuf = [];
-    while (number >= 1000) {
-      number -= 1000;
-      romanBuf.push('M');
-    }
-    pos = number / 100 | 0;
-    number %= 100;
-    romanBuf.push(ROMAN_NUMBER_MAP[pos]);
-    pos = number / 10 | 0;
-    number %= 10;
-    romanBuf.push(ROMAN_NUMBER_MAP[10 + pos]);
-    romanBuf.push(ROMAN_NUMBER_MAP[20 + number]);
-    var romanStr = romanBuf.join('');
-    return lowerCase ? romanStr.toLowerCase() : romanStr;
-  };
-  Util.appendToArray = function Util_appendToArray(arr1, arr2) {
-    Array.prototype.push.apply(arr1, arr2);
-  };
-  Util.prependToArray = function Util_prependToArray(arr1, arr2) {
-    Array.prototype.unshift.apply(arr1, arr2);
-  };
-  Util.extendObj = function extendObj(obj1, obj2) {
-    for (var key in obj2) {
-      obj1[key] = obj2[key];
-    }
-  };
-  Util.inherit = function Util_inherit(sub, base, prototype) {
-    sub.prototype = Object.create(base.prototype);
-    sub.prototype.constructor = sub;
-    for (var prop in prototype) {
-      sub.prototype[prop] = prototype[prop];
-    }
-  };
-  Util.loadScript = function Util_loadScript(src, callback) {
-    var script = document.createElement('script');
-    var loaded = false;
-    script.setAttribute('src', src);
-    if (callback) {
-      script.onload = function () {
-        if (!loaded) {
-          callback();
-        }
-        loaded = true;
-      };
-    }
-    document.getElementsByTagName('head')[0].appendChild(script);
-  };
+
   return Util;
 }();
-var PageViewport = function PageViewportClosure() {
-  function PageViewport(viewBox, scale, rotation, offsetX, offsetY, dontFlip) {
-    this.viewBox = viewBox;
-    this.scale = scale;
-    this.rotation = rotation;
-    this.offsetX = offsetX;
-    this.offsetY = offsetY;
-    var centerX = (viewBox[2] + viewBox[0]) / 2;
-    var centerY = (viewBox[3] + viewBox[1]) / 2;
-    var rotateA, rotateB, rotateC, rotateD;
-    rotation = rotation % 360;
-    rotation = rotation < 0 ? rotation + 360 : rotation;
-    switch (rotation) {
-      case 180:
-        rotateA = -1;
-        rotateB = 0;
-        rotateC = 0;
-        rotateD = 1;
-        break;
-      case 90:
-        rotateA = 0;
-        rotateB = 1;
-        rotateC = 1;
-        rotateD = 0;
-        break;
-      case 270:
-        rotateA = 0;
-        rotateB = -1;
-        rotateC = -1;
-        rotateD = 0;
-        break;
-      default:
-        rotateA = 1;
-        rotateB = 0;
-        rotateC = 0;
-        rotateD = -1;
-        break;
-    }
-    if (dontFlip) {
-      rotateC = -rotateC;
-      rotateD = -rotateD;
-    }
-    var offsetCanvasX, offsetCanvasY;
-    var width, height;
-    if (rotateA === 0) {
-      offsetCanvasX = Math.abs(centerY - viewBox[1]) * scale + offsetX;
-      offsetCanvasY = Math.abs(centerX - viewBox[0]) * scale + offsetY;
-      width = Math.abs(viewBox[3] - viewBox[1]) * scale;
-      height = Math.abs(viewBox[2] - viewBox[0]) * scale;
-    } else {
-      offsetCanvasX = Math.abs(centerX - viewBox[0]) * scale + offsetX;
-      offsetCanvasY = Math.abs(centerY - viewBox[1]) * scale + offsetY;
-      width = Math.abs(viewBox[2] - viewBox[0]) * scale;
-      height = Math.abs(viewBox[3] - viewBox[1]) * scale;
-    }
-    this.transform = [rotateA * scale, rotateB * scale, rotateC * scale, rotateD * scale, offsetCanvasX - rotateA * scale * centerX - rotateC * scale * centerY, offsetCanvasY - rotateB * scale * centerX - rotateD * scale * centerY];
-    this.width = width;
-    this.height = height;
-    this.fontScale = scale;
+
+exports.Util = Util;
+var ROMAN_NUMBER_MAP = ['', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM', '', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC', '', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX'];
+
+function toRomanNumerals(number) {
+  var lowerCase = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
+  assert(Number.isInteger(number) && number > 0, 'The number should be a positive integer.');
+  var pos,
+      romanBuf = [];
+
+  while (number >= 1000) {
+    number -= 1000;
+    romanBuf.push('M');
   }
-  PageViewport.prototype = {
-    clone: function PageViewPort_clone(args) {
-      args = args || {};
-      var scale = 'scale' in args ? args.scale : this.scale;
-      var rotation = 'rotation' in args ? args.rotation : this.rotation;
-      return new PageViewport(this.viewBox.slice(), scale, rotation, this.offsetX, this.offsetY, args.dontFlip);
-    },
-    convertToViewportPoint: function PageViewport_convertToViewportPoint(x, y) {
-      return Util.applyTransform([x, y], this.transform);
-    },
-    convertToViewportRectangle: function PageViewport_convertToViewportRectangle(rect) {
-      var tl = Util.applyTransform([rect[0], rect[1]], this.transform);
-      var br = Util.applyTransform([rect[2], rect[3]], this.transform);
-      return [tl[0], tl[1], br[0], br[1]];
-    },
-    convertToPdfPoint: function PageViewport_convertToPdfPoint(x, y) {
-      return Util.applyInverseTransform([x, y], this.transform);
-    }
-  };
-  return PageViewport;
-}();
+
+  pos = number / 100 | 0;
+  number %= 100;
+  romanBuf.push(ROMAN_NUMBER_MAP[pos]);
+  pos = number / 10 | 0;
+  number %= 10;
+  romanBuf.push(ROMAN_NUMBER_MAP[10 + pos]);
+  romanBuf.push(ROMAN_NUMBER_MAP[20 + number]);
+  var romanStr = romanBuf.join('');
+  return lowerCase ? romanStr.toLowerCase() : romanStr;
+}
+
 var PDFStringTranslateTable = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2D8, 0x2C7, 0x2C6, 0x2D9, 0x2DD, 0x2DB, 0x2DA, 0x2DC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x192, 0x2044, 0x2039, 0x203A, 0x2212, 0x2030, 0x201E, 0x201C, 0x201D, 0x2018, 0x2019, 0x201A, 0x2122, 0xFB01, 0xFB02, 0x141, 0x152, 0x160, 0x178, 0x17D, 0x131, 0x142, 0x153, 0x161, 0x17E, 0, 0x20AC];
+
 function stringToPDFString(str) {
   var i,
       n = str.length,
       strBuf = [];
+
   if (str[0] === '\xFE' && str[1] === '\xFF') {
     for (i = 2; i < n; i += 2) {
       strBuf.push(String.fromCharCode(str.charCodeAt(i) << 8 | str.charCodeAt(i + 1)));
@@ -812,59 +899,82 @@ function stringToPDFString(str) {
       strBuf.push(code ? String.fromCharCode(code) : str.charAt(i));
     }
   }
+
   return strBuf.join('');
 }
+
 function stringToUTF8String(str) {
   return decodeURIComponent(escape(str));
 }
+
 function utf8StringToString(str) {
   return unescape(encodeURIComponent(str));
 }
+
 function isEmptyObj(obj) {
   for (var key in obj) {
     return false;
   }
+
   return true;
 }
+
 function isBool(v) {
   return typeof v === 'boolean';
 }
+
 function isNum(v) {
   return typeof v === 'number';
 }
+
 function isString(v) {
   return typeof v === 'string';
 }
+
 function isArrayBuffer(v) {
-  return (typeof v === 'undefined' ? 'undefined' : _typeof(v)) === 'object' && v !== null && v.byteLength !== undefined;
+  return _typeof(v) === 'object' && v !== null && v.byteLength !== undefined;
 }
+
 function isSpace(ch) {
   return ch === 0x20 || ch === 0x09 || ch === 0x0D || ch === 0x0A;
 }
+
 function createPromiseCapability() {
-  var capability = {};
+  var capability = Object.create(null);
+  var isSettled = false;
+  Object.defineProperty(capability, 'settled', {
+    get: function get() {
+      return isSettled;
+    }
+  });
   capability.promise = new Promise(function (resolve, reject) {
-    capability.resolve = resolve;
-    capability.reject = reject;
+    capability.resolve = function (data) {
+      isSettled = true;
+      resolve(data);
+    };
+
+    capability.reject = function (reason) {
+      isSettled = true;
+      reject(reason);
+    };
   });
   return capability;
 }
-var createBlob = function createBlob(data, contentType) {
-  if (typeof Blob !== 'undefined') {
-    return new Blob([data], { type: contentType });
-  }
-  throw new Error('The "Blob" constructor is not supported.');
-};
+
 var createObjectURL = function createObjectURLClosure() {
   var digits = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
   return function createObjectURL(data, contentType) {
     var forceDataSchema = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
 
-    if (!forceDataSchema && URL.createObjectURL) {
-      var blob = createBlob(data, contentType);
-      return URL.createObjectURL(blob);
+    if (!forceDataSchema && _url_polyfill.URL.createObjectURL) {
+      var blob = new Blob([data], {
+        type: contentType
+      });
+      return _url_polyfill.URL.createObjectURL(blob);
     }
+
     var buffer = 'data:' + contentType + ';base64,';
+
     for (var i = 0, ii = data.length; i < ii; i += 3) {
       var b1 = data[i] & 0xFF;
       var b2 = data[i + 1] & 0xFF;
@@ -875,474 +985,9 @@ var createObjectURL = function createObjectURLClosure() {
       var d4 = i + 2 < ii ? b3 & 0x3F : 64;
       buffer += digits[d1] + digits[d2] + digits[d3] + digits[d4];
     }
+
     return buffer;
   };
 }();
-function resolveCall(fn, args) {
-  var thisArg = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
 
-  if (!fn) {
-    return Promise.resolve(undefined);
-  }
-  return new Promise(function (resolve, reject) {
-    resolve(fn.apply(thisArg, args));
-  });
-}
-function wrapReason(reason) {
-  if ((typeof reason === 'undefined' ? 'undefined' : _typeof(reason)) !== 'object') {
-    return reason;
-  }
-  switch (reason.name) {
-    case 'AbortException':
-      return new AbortException(reason.message);
-    case 'MissingPDFException':
-      return new MissingPDFException(reason.message);
-    case 'UnexpectedResponseException':
-      return new UnexpectedResponseException(reason.message, reason.status);
-    default:
-      return new UnknownErrorException(reason.message, reason.details);
-  }
-}
-function makeReasonSerializable(reason) {
-  if (!(reason instanceof Error) || reason instanceof AbortException || reason instanceof MissingPDFException || reason instanceof UnexpectedResponseException || reason instanceof UnknownErrorException) {
-    return reason;
-  }
-  return new UnknownErrorException(reason.message, reason.toString());
-}
-function resolveOrReject(capability, success, reason) {
-  if (success) {
-    capability.resolve();
-  } else {
-    capability.reject(reason);
-  }
-}
-function finalize(promise) {
-  return Promise.resolve(promise).catch(function () {});
-}
-function MessageHandler(sourceName, targetName, comObj) {
-  var _this = this;
-
-  this.sourceName = sourceName;
-  this.targetName = targetName;
-  this.comObj = comObj;
-  this.callbackId = 1;
-  this.streamId = 1;
-  this.postMessageTransfers = true;
-  this.streamSinks = Object.create(null);
-  this.streamControllers = Object.create(null);
-  var callbacksCapabilities = this.callbacksCapabilities = Object.create(null);
-  var ah = this.actionHandler = Object.create(null);
-  this._onComObjOnMessage = function (event) {
-    var data = event.data;
-    if (data.targetName !== _this.sourceName) {
-      return;
-    }
-    if (data.stream) {
-      _this._processStreamMessage(data);
-    } else if (data.isReply) {
-      var callbackId = data.callbackId;
-      if (data.callbackId in callbacksCapabilities) {
-        var callback = callbacksCapabilities[callbackId];
-        delete callbacksCapabilities[callbackId];
-        if ('error' in data) {
-          callback.reject(wrapReason(data.error));
-        } else {
-          callback.resolve(data.data);
-        }
-      } else {
-        throw new Error('Cannot resolve callback ' + callbackId);
-      }
-    } else if (data.action in ah) {
-      var action = ah[data.action];
-      if (data.callbackId) {
-        var _sourceName = _this.sourceName;
-        var _targetName = data.sourceName;
-        Promise.resolve().then(function () {
-          return action[0].call(action[1], data.data);
-        }).then(function (result) {
-          comObj.postMessage({
-            sourceName: _sourceName,
-            targetName: _targetName,
-            isReply: true,
-            callbackId: data.callbackId,
-            data: result
-          });
-        }, function (reason) {
-          comObj.postMessage({
-            sourceName: _sourceName,
-            targetName: _targetName,
-            isReply: true,
-            callbackId: data.callbackId,
-            error: makeReasonSerializable(reason)
-          });
-        });
-      } else if (data.streamId) {
-        _this._createStreamSink(data);
-      } else {
-        action[0].call(action[1], data.data);
-      }
-    } else {
-      throw new Error('Unknown action from worker: ' + data.action);
-    }
-  };
-  comObj.addEventListener('message', this._onComObjOnMessage);
-}
-MessageHandler.prototype = {
-  on: function on(actionName, handler, scope) {
-    var ah = this.actionHandler;
-    if (ah[actionName]) {
-      throw new Error('There is already an actionName called "' + actionName + '"');
-    }
-    ah[actionName] = [handler, scope];
-  },
-  send: function send(actionName, data, transfers) {
-    var message = {
-      sourceName: this.sourceName,
-      targetName: this.targetName,
-      action: actionName,
-      data: data
-    };
-    this.postMessage(message, transfers);
-  },
-  sendWithPromise: function sendWithPromise(actionName, data, transfers) {
-    var callbackId = this.callbackId++;
-    var message = {
-      sourceName: this.sourceName,
-      targetName: this.targetName,
-      action: actionName,
-      data: data,
-      callbackId: callbackId
-    };
-    var capability = createPromiseCapability();
-    this.callbacksCapabilities[callbackId] = capability;
-    try {
-      this.postMessage(message, transfers);
-    } catch (e) {
-      capability.reject(e);
-    }
-    return capability.promise;
-  },
-  sendWithStream: function sendWithStream(actionName, data, queueingStrategy, transfers) {
-    var _this2 = this;
-
-    var streamId = this.streamId++;
-    var sourceName = this.sourceName;
-    var targetName = this.targetName;
-    return new _streams_polyfill.ReadableStream({
-      start: function start(controller) {
-        var startCapability = createPromiseCapability();
-        _this2.streamControllers[streamId] = {
-          controller: controller,
-          startCall: startCapability,
-          isClosed: false
-        };
-        _this2.postMessage({
-          sourceName: sourceName,
-          targetName: targetName,
-          action: actionName,
-          streamId: streamId,
-          data: data,
-          desiredSize: controller.desiredSize
-        });
-        return startCapability.promise;
-      },
-      pull: function pull(controller) {
-        var pullCapability = createPromiseCapability();
-        _this2.streamControllers[streamId].pullCall = pullCapability;
-        _this2.postMessage({
-          sourceName: sourceName,
-          targetName: targetName,
-          stream: 'pull',
-          streamId: streamId,
-          desiredSize: controller.desiredSize
-        });
-        return pullCapability.promise;
-      },
-      cancel: function cancel(reason) {
-        var cancelCapability = createPromiseCapability();
-        _this2.streamControllers[streamId].cancelCall = cancelCapability;
-        _this2.streamControllers[streamId].isClosed = true;
-        _this2.postMessage({
-          sourceName: sourceName,
-          targetName: targetName,
-          stream: 'cancel',
-          reason: reason,
-          streamId: streamId
-        });
-        return cancelCapability.promise;
-      }
-    }, queueingStrategy);
-  },
-  _createStreamSink: function _createStreamSink(data) {
-    var _this3 = this;
-
-    var self = this;
-    var action = this.actionHandler[data.action];
-    var streamId = data.streamId;
-    var desiredSize = data.desiredSize;
-    var sourceName = this.sourceName;
-    var targetName = data.sourceName;
-    var capability = createPromiseCapability();
-    var sendStreamRequest = function sendStreamRequest(_ref2) {
-      var stream = _ref2.stream,
-          chunk = _ref2.chunk,
-          transfers = _ref2.transfers,
-          success = _ref2.success,
-          reason = _ref2.reason;
-
-      _this3.postMessage({
-        sourceName: sourceName,
-        targetName: targetName,
-        stream: stream,
-        streamId: streamId,
-        chunk: chunk,
-        success: success,
-        reason: reason
-      }, transfers);
-    };
-    var streamSink = {
-      enqueue: function enqueue(chunk) {
-        var size = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
-        var transfers = arguments[2];
-
-        if (this.isCancelled) {
-          return;
-        }
-        var lastDesiredSize = this.desiredSize;
-        this.desiredSize -= size;
-        if (lastDesiredSize > 0 && this.desiredSize <= 0) {
-          this.sinkCapability = createPromiseCapability();
-          this.ready = this.sinkCapability.promise;
-        }
-        sendStreamRequest({
-          stream: 'enqueue',
-          chunk: chunk,
-          transfers: transfers
-        });
-      },
-      close: function close() {
-        if (this.isCancelled) {
-          return;
-        }
-        this.isCancelled = true;
-        sendStreamRequest({ stream: 'close' });
-        delete self.streamSinks[streamId];
-      },
-      error: function error(reason) {
-        if (this.isCancelled) {
-          return;
-        }
-        this.isCancelled = true;
-        sendStreamRequest({
-          stream: 'error',
-          reason: reason
-        });
-      },
-
-      sinkCapability: capability,
-      onPull: null,
-      onCancel: null,
-      isCancelled: false,
-      desiredSize: desiredSize,
-      ready: null
-    };
-    streamSink.sinkCapability.resolve();
-    streamSink.ready = streamSink.sinkCapability.promise;
-    this.streamSinks[streamId] = streamSink;
-    resolveCall(action[0], [data.data, streamSink], action[1]).then(function () {
-      sendStreamRequest({
-        stream: 'start_complete',
-        success: true
-      });
-    }, function (reason) {
-      sendStreamRequest({
-        stream: 'start_complete',
-        success: false,
-        reason: reason
-      });
-    });
-  },
-  _processStreamMessage: function _processStreamMessage(data) {
-    var _this4 = this;
-
-    var sourceName = this.sourceName;
-    var targetName = data.sourceName;
-    var streamId = data.streamId;
-    var sendStreamResponse = function sendStreamResponse(_ref3) {
-      var stream = _ref3.stream,
-          success = _ref3.success,
-          reason = _ref3.reason;
-
-      _this4.comObj.postMessage({
-        sourceName: sourceName,
-        targetName: targetName,
-        stream: stream,
-        success: success,
-        streamId: streamId,
-        reason: reason
-      });
-    };
-    var deleteStreamController = function deleteStreamController() {
-      Promise.all([_this4.streamControllers[data.streamId].startCall, _this4.streamControllers[data.streamId].pullCall, _this4.streamControllers[data.streamId].cancelCall].map(function (capability) {
-        return capability && finalize(capability.promise);
-      })).then(function () {
-        delete _this4.streamControllers[data.streamId];
-      });
-    };
-    switch (data.stream) {
-      case 'start_complete':
-        resolveOrReject(this.streamControllers[data.streamId].startCall, data.success, wrapReason(data.reason));
-        break;
-      case 'pull_complete':
-        resolveOrReject(this.streamControllers[data.streamId].pullCall, data.success, wrapReason(data.reason));
-        break;
-      case 'pull':
-        if (!this.streamSinks[data.streamId]) {
-          sendStreamResponse({
-            stream: 'pull_complete',
-            success: true
-          });
-          break;
-        }
-        if (this.streamSinks[data.streamId].desiredSize <= 0 && data.desiredSize > 0) {
-          this.streamSinks[data.streamId].sinkCapability.resolve();
-        }
-        this.streamSinks[data.streamId].desiredSize = data.desiredSize;
-        resolveCall(this.streamSinks[data.streamId].onPull).then(function () {
-          sendStreamResponse({
-            stream: 'pull_complete',
-            success: true
-          });
-        }, function (reason) {
-          sendStreamResponse({
-            stream: 'pull_complete',
-            success: false,
-            reason: reason
-          });
-        });
-        break;
-      case 'enqueue':
-        assert(this.streamControllers[data.streamId], 'enqueue should have stream controller');
-        if (!this.streamControllers[data.streamId].isClosed) {
-          this.streamControllers[data.streamId].controller.enqueue(data.chunk);
-        }
-        break;
-      case 'close':
-        assert(this.streamControllers[data.streamId], 'close should have stream controller');
-        if (this.streamControllers[data.streamId].isClosed) {
-          break;
-        }
-        this.streamControllers[data.streamId].isClosed = true;
-        this.streamControllers[data.streamId].controller.close();
-        deleteStreamController();
-        break;
-      case 'error':
-        assert(this.streamControllers[data.streamId], 'error should have stream controller');
-        this.streamControllers[data.streamId].controller.error(wrapReason(data.reason));
-        deleteStreamController();
-        break;
-      case 'cancel_complete':
-        resolveOrReject(this.streamControllers[data.streamId].cancelCall, data.success, wrapReason(data.reason));
-        deleteStreamController();
-        break;
-      case 'cancel':
-        if (!this.streamSinks[data.streamId]) {
-          break;
-        }
-        resolveCall(this.streamSinks[data.streamId].onCancel, [wrapReason(data.reason)]).then(function () {
-          sendStreamResponse({
-            stream: 'cancel_complete',
-            success: true
-          });
-        }, function (reason) {
-          sendStreamResponse({
-            stream: 'cancel_complete',
-            success: false,
-            reason: reason
-          });
-        });
-        this.streamSinks[data.streamId].sinkCapability.reject(wrapReason(data.reason));
-        this.streamSinks[data.streamId].isCancelled = true;
-        delete this.streamSinks[data.streamId];
-        break;
-      default:
-        throw new Error('Unexpected stream case');
-    }
-  },
-  postMessage: function postMessage(message, transfers) {
-    if (transfers && this.postMessageTransfers) {
-      this.comObj.postMessage(message, transfers);
-    } else {
-      this.comObj.postMessage(message);
-    }
-  },
-  destroy: function destroy() {
-    this.comObj.removeEventListener('message', this._onComObjOnMessage);
-  }
-};
-exports.FONT_IDENTITY_MATRIX = FONT_IDENTITY_MATRIX;
-exports.IDENTITY_MATRIX = IDENTITY_MATRIX;
-exports.OPS = OPS;
-exports.VerbosityLevel = VerbosityLevel;
-exports.UNSUPPORTED_FEATURES = UNSUPPORTED_FEATURES;
-exports.AnnotationBorderStyleType = AnnotationBorderStyleType;
-exports.AnnotationFieldFlag = AnnotationFieldFlag;
-exports.AnnotationFlag = AnnotationFlag;
-exports.AnnotationType = AnnotationType;
-exports.FontType = FontType;
-exports.ImageKind = ImageKind;
-exports.CMapCompressionType = CMapCompressionType;
-exports.AbortException = AbortException;
-exports.InvalidPDFException = InvalidPDFException;
-exports.MessageHandler = MessageHandler;
-exports.MissingDataException = MissingDataException;
-exports.MissingPDFException = MissingPDFException;
-exports.NativeImageDecoding = NativeImageDecoding;
-exports.NotImplementedException = NotImplementedException;
-exports.PageViewport = PageViewport;
-exports.PasswordException = PasswordException;
-exports.PasswordResponses = PasswordResponses;
-exports.StreamType = StreamType;
-exports.TextRenderingMode = TextRenderingMode;
-exports.UnexpectedResponseException = UnexpectedResponseException;
-exports.UnknownErrorException = UnknownErrorException;
-exports.Util = Util;
-exports.XRefParseException = XRefParseException;
-exports.FormatError = FormatError;
-exports.arrayByteLength = arrayByteLength;
-exports.arraysToBytes = arraysToBytes;
-exports.assert = assert;
-exports.bytesToString = bytesToString;
-exports.createBlob = createBlob;
-exports.createPromiseCapability = createPromiseCapability;
-exports.createObjectURL = createObjectURL;
-exports.deprecated = deprecated;
-exports.getInheritableProperty = getInheritableProperty;
-exports.getLookupTableFactory = getLookupTableFactory;
-exports.getVerbosityLevel = getVerbosityLevel;
-exports.info = info;
-exports.isArrayBuffer = isArrayBuffer;
-exports.isBool = isBool;
-exports.isEmptyObj = isEmptyObj;
-exports.isNum = isNum;
-exports.isString = isString;
-exports.isSpace = isSpace;
-exports.isSameOrigin = isSameOrigin;
-exports.createValidAbsoluteUrl = createValidAbsoluteUrl;
-exports.isLittleEndian = isLittleEndian;
-exports.isEvalSupported = isEvalSupported;
-exports.log2 = log2;
-exports.readInt8 = readInt8;
-exports.readUint16 = readUint16;
-exports.readUint32 = readUint32;
-exports.removeNullCharacters = removeNullCharacters;
-exports.ReadableStream = _streams_polyfill.ReadableStream;
-exports.setVerbosityLevel = setVerbosityLevel;
-exports.shadow = shadow;
-exports.string32 = string32;
-exports.stringToBytes = stringToBytes;
-exports.stringToPDFString = stringToPDFString;
-exports.stringToUTF8String = stringToUTF8String;
-exports.utf8StringToString = utf8StringToString;
-exports.warn = warn;
-exports.unreachable = unreachable;
+exports.createObjectURL = createObjectURL;

File diff suppressed because it is too large
+ 439 - 263
lib/test/unit/annotation_spec.js


File diff suppressed because it is too large
+ 326 - 186
lib/test/unit/api_spec.js


+ 7 - 7
lib/test/unit/bidi_spec.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,21 +19,21 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
-var _bidi = require('../../core/bidi');
+var _bidi = require("../../core/bidi");
 
 describe('bidi', function () {
   it('should mark text as RTL if more than 30% of text is RTL', function () {
-    var test = '\u0645\u0635\u0631 Egypt';
-    var result = 'Egypt \u0631\u0635\u0645';
+    var test = "\u0645\u0635\u0631 Egypt";
+    var result = "Egypt \u0631\u0635\u0645";
     var bidiText = (0, _bidi.bidi)(test, -1, false);
     expect(bidiText.str).toEqual(result);
     expect(bidiText.dir).toEqual('rtl');
   });
   it('should mark text as LTR if less than 30% of text is RTL', function () {
-    var test = 'Egypt is known as \u0645\u0635\u0631 in Arabic.';
-    var result = 'Egypt is known as \u0631\u0635\u0645 in Arabic.';
+    var test = "Egypt is known as \u0645\u0635\u0631 in Arabic.";
+    var result = "Egypt is known as \u0631\u0635\u0645 in Arabic.";
     var bidiText = (0, _bidi.bidi)(test, -1, false);
     expect(bidiText.str).toEqual(result);
     expect(bidiText.dir).toEqual('ltr');

+ 40 - 11
lib/test/unit/cff_parser_spec.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,22 +19,25 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
-var _cff_parser = require('../../core/cff_parser');
+var _cff_parser = require("../../core/cff_parser");
 
-var _fonts = require('../../core/fonts');
+var _fonts = require("../../core/fonts");
 
-var _stream = require('../../core/stream');
+var _stream = require("../../core/stream");
 
 describe('CFFParser', function () {
   function createWithNullProto(obj) {
     var result = Object.create(null);
+
     for (var i in obj) {
       result[i] = obj[i];
     }
+
     return result;
   }
+
   var privateDictStub = {
     getByName: function getByName(name) {
       return 0;
@@ -44,10 +47,12 @@ describe('CFFParser', function () {
   beforeAll(function (done) {
     var exampleFont = '0100040100010101134142434445462b' + '54696d65732d526f6d616e000101011f' + 'f81b00f81c02f81d03f819041c6f000d' + 'fb3cfb6efa7cfa1605e911b8f1120003' + '01010813183030312e30303754696d65' + '7320526f6d616e54696d657300000002' + '010102030e0e7d99f92a99fb7695f773' + '8b06f79a93fc7c8c077d99f85695f75e' + '9908fb6e8cf87393f7108b09a70adf0b' + 'f78e14';
     var fontArr = [];
+
     for (var i = 0, ii = exampleFont.length; i < ii; i += 2) {
-      var hex = exampleFont.substr(i, 2);
+      var hex = exampleFont.substring(i, i + 2);
       fontArr.push(parseInt(hex, 16));
     }
+
     fontData = new _stream.Stream(fontArr);
     done();
   });
@@ -103,9 +108,11 @@ describe('CFFParser', function () {
     parser.bytes = bytes;
     var topDict = cff.topDict;
     topDict.setByName('Private', [bytes.length, 0]);
+
     var parsePrivateDict = function parsePrivateDict() {
       parser.parsePrivateDict(topDict);
     };
+
     expect(parsePrivateDict).not.toThrow();
     var privateDict = topDict.privateDict;
     expect(privateDict.getByName('BlueValues')).toBeNull();
@@ -198,7 +205,9 @@ describe('CFFParser', function () {
     var bytes = new Uint8Array([0x00, 0x00, 0x00, 0x01, 0x08]);
     parser.bytes = bytes;
     var encoding = parser.parseEncoding(2, {}, new _cff_parser.CFFStrings(), null);
-    expect(encoding.encoding).toEqual(createWithNullProto({ 0x8: 1 }));
+    expect(encoding.encoding).toEqual(createWithNullProto({
+      0x8: 1
+    }));
   });
   it('parses encoding format 1', function () {
     var bytes = new Uint8Array([0x00, 0x00, 0x01, 0x01, 0x07, 0x01]);
@@ -214,22 +223,21 @@ describe('CFFParser', function () {
     parser.bytes = bytes.slice();
     var fdSelect = parser.parseFDSelect(0, 2);
     expect(fdSelect.fdSelect).toEqual([0, 1]);
-    expect(fdSelect.raw).toEqual(bytes);
+    expect(fdSelect.format).toEqual(0);
   });
   it('parses fdselect format 3', function () {
     var bytes = new Uint8Array([0x03, 0x00, 0x02, 0x00, 0x00, 0x09, 0x00, 0x02, 0x0a, 0x00, 0x04]);
     parser.bytes = bytes.slice();
     var fdSelect = parser.parseFDSelect(0, 4);
     expect(fdSelect.fdSelect).toEqual([9, 9, 0xa, 0xa]);
-    expect(fdSelect.raw).toEqual(bytes);
+    expect(fdSelect.format).toEqual(3);
   });
   it('parses invalid fdselect format 3 (bug 1146106)', function () {
     var bytes = new Uint8Array([0x03, 0x00, 0x02, 0x00, 0x01, 0x09, 0x00, 0x02, 0x0a, 0x00, 0x04]);
     parser.bytes = bytes.slice();
     var fdSelect = parser.parseFDSelect(0, 4);
     expect(fdSelect.fdSelect).toEqual([9, 9, 0xa, 0xa]);
-    bytes[3] = bytes[4] = 0x00;
-    expect(fdSelect.raw).toEqual(bytes);
+    expect(fdSelect.format).toEqual(3);
   });
 });
 describe('CFFCompiler', function () {
@@ -241,6 +249,7 @@ describe('CFFCompiler', function () {
       }
     }, {}, _fonts.SEAC_ANALYSIS_ENABLED);
   }
+
   it('encodes integers', function () {
     var c = new _cff_parser.CFFCompiler();
     expect(c.encodeInteger(0)).toEqual([0x8b]);
@@ -266,13 +275,33 @@ describe('CFFCompiler', function () {
     var names = parser.parseNameIndex(nameIndex.obj);
     expect(names).toEqual(['_a']);
     var longName = '';
+
     for (var i = 0; i < 129; i++) {
       longName += '_';
     }
+
     nameIndexCompiled = c.compileNameIndex([longName]);
     parser = testParser(nameIndexCompiled);
     nameIndex = parser.parseIndex(0);
     names = parser.parseNameIndex(nameIndex.obj);
     expect(names[0].length).toEqual(127);
   });
+  it('compiles fdselect format 0', function () {
+    var fdSelect = new _cff_parser.CFFFDSelect(0, [3, 2, 1]);
+    var c = new _cff_parser.CFFCompiler();
+    var out = c.compileFDSelect(fdSelect);
+    expect(out).toEqual([0, 3, 2, 1]);
+  });
+  it('compiles fdselect format 3', function () {
+    var fdSelect = new _cff_parser.CFFFDSelect(3, [0, 0, 1, 1]);
+    var c = new _cff_parser.CFFCompiler();
+    var out = c.compileFDSelect(fdSelect);
+    expect(out).toEqual([3, 0, 2, 0, 0, 0, 0, 2, 1, 0, 4]);
+  });
+  it('compiles fdselect format 3, single range', function () {
+    var fdSelect = new _cff_parser.CFFFDSelect(3, [0, 0]);
+    var c = new _cff_parser.CFFCompiler();
+    var out = c.compileFDSelect(fdSelect);
+    expect(out).toEqual([3, 0, 1, 0, 0, 0, 0, 2]);
+  });
 });

+ 9 - 7
lib/test/unit/clitests_helper.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,21 +19,23 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
-var _is_node = require('../../shared/is_node');
+var _util = require("../../shared/util");
 
-var _is_node2 = _interopRequireDefault(_is_node);
+var _is_node = _interopRequireDefault(require("../../shared/is_node"));
 
-var _node_stream = require('../../display/node_stream');
+var _node_stream = require("../../display/node_stream");
 
-var _api = require('../../display/api');
+var _api = require("../../display/api");
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
-if (!(0, _is_node2.default)()) {
+if (!(0, _is_node.default)()) {
   throw new Error('The `gulp unittestcli` command can only be used in ' + 'Node.js environments.');
 }
+
+(0, _util.setVerbosityLevel)(_util.VerbosityLevel.ERRORS);
 (0, _api.setPDFNetworkStreamFactory)(function (params) {
   return new _node_stream.PDFNodeStream(params);
 });

+ 80 - 26
lib/test/unit/cmap_spec.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,21 +19,19 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
-var _cmap = require('../../core/cmap');
+var _cmap = require("../../core/cmap");
 
-var _dom_utils = require('../../display/dom_utils');
+var _dom_utils = require("../../display/dom_utils");
 
-var _is_node = require('../../shared/is_node');
+var _is_node = _interopRequireDefault(require("../../shared/is_node"));
 
-var _is_node2 = _interopRequireDefault(_is_node);
+var _primitives = require("../../core/primitives");
 
-var _primitives = require('../../core/primitives');
+var _test_utils = require("./test_utils");
 
-var _test_utils = require('./test_utils');
-
-var _stream = require('../../core/stream');
+var _stream = require("../../core/stream");
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
@@ -46,7 +44,8 @@ describe('cmap', function () {
   var fetchBuiltInCMap;
   beforeAll(function (done) {
     var CMapReaderFactory;
-    if ((0, _is_node2.default)()) {
+
+    if ((0, _is_node.default)()) {
       CMapReaderFactory = new _test_utils.NodeCMapReaderFactory({
         baseUrl: cMapUrl.node,
         isCompressed: cMapPacked
@@ -57,9 +56,13 @@ describe('cmap', function () {
         isCompressed: cMapPacked
       });
     }
+
     fetchBuiltInCMap = function fetchBuiltInCMap(name) {
-      return CMapReaderFactory.fetch({ name: name });
+      return CMapReaderFactory.fetch({
+        name: name
+      });
     };
+
     done();
   });
   afterAll(function () {
@@ -68,7 +71,11 @@ describe('cmap', function () {
   it('parses beginbfchar', function (done) {
     var str = '2 beginbfchar\n' + '<03> <00>\n' + '<04> <01>\n' + 'endbfchar\n';
     var stream = new _stream.StringStream(str);
-    var cmapPromise = _cmap.CMapFactory.create({ encoding: stream });
+
+    var cmapPromise = _cmap.CMapFactory.create({
+      encoding: stream
+    });
+
     cmapPromise.then(function (cmap) {
       expect(cmap.lookup(0x03)).toEqual(String.fromCharCode(0x00));
       expect(cmap.lookup(0x04)).toEqual(String.fromCharCode(0x01));
@@ -81,7 +88,11 @@ describe('cmap', function () {
   it('parses beginbfrange with range', function (done) {
     var str = '1 beginbfrange\n' + '<06> <0B> 0\n' + 'endbfrange\n';
     var stream = new _stream.StringStream(str);
-    var cmapPromise = _cmap.CMapFactory.create({ encoding: stream });
+
+    var cmapPromise = _cmap.CMapFactory.create({
+      encoding: stream
+    });
+
     cmapPromise.then(function (cmap) {
       expect(cmap.lookup(0x05)).toBeUndefined();
       expect(cmap.lookup(0x06)).toEqual(String.fromCharCode(0x00));
@@ -95,7 +106,11 @@ describe('cmap', function () {
   it('parses beginbfrange with array', function (done) {
     var str = '1 beginbfrange\n' + '<0D> <12> [ 0 1 2 3 4 5 ]\n' + 'endbfrange\n';
     var stream = new _stream.StringStream(str);
-    var cmapPromise = _cmap.CMapFactory.create({ encoding: stream });
+
+    var cmapPromise = _cmap.CMapFactory.create({
+      encoding: stream
+    });
+
     cmapPromise.then(function (cmap) {
       expect(cmap.lookup(0x0C)).toBeUndefined();
       expect(cmap.lookup(0x0D)).toEqual(0x00);
@@ -109,7 +124,11 @@ describe('cmap', function () {
   it('parses begincidchar', function (done) {
     var str = '1 begincidchar\n' + '<14> 0\n' + 'endcidchar\n';
     var stream = new _stream.StringStream(str);
-    var cmapPromise = _cmap.CMapFactory.create({ encoding: stream });
+
+    var cmapPromise = _cmap.CMapFactory.create({
+      encoding: stream
+    });
+
     cmapPromise.then(function (cmap) {
       expect(cmap.lookup(0x14)).toEqual(0x00);
       expect(cmap.lookup(0x15)).toBeUndefined();
@@ -121,7 +140,11 @@ describe('cmap', function () {
   it('parses begincidrange', function (done) {
     var str = '1 begincidrange\n' + '<0016> <001B>   0\n' + 'endcidrange\n';
     var stream = new _stream.StringStream(str);
-    var cmapPromise = _cmap.CMapFactory.create({ encoding: stream });
+
+    var cmapPromise = _cmap.CMapFactory.create({
+      encoding: stream
+    });
+
     cmapPromise.then(function (cmap) {
       expect(cmap.lookup(0x15)).toBeUndefined();
       expect(cmap.lookup(0x16)).toEqual(0x00);
@@ -135,7 +158,11 @@ describe('cmap', function () {
   it('decodes codespace ranges', function (done) {
     var str = '1 begincodespacerange\n' + '<01> <02>\n' + '<00000003> <00000004>\n' + 'endcodespacerange\n';
     var stream = new _stream.StringStream(str);
-    var cmapPromise = _cmap.CMapFactory.create({ encoding: stream });
+
+    var cmapPromise = _cmap.CMapFactory.create({
+      encoding: stream
+    });
+
     cmapPromise.then(function (cmap) {
       var c = {};
       cmap.readCharCode(String.fromCharCode(1), 0, c);
@@ -152,7 +179,11 @@ describe('cmap', function () {
   it('decodes 4 byte codespace ranges', function (done) {
     var str = '1 begincodespacerange\n' + '<8EA1A1A1> <8EA1FEFE>\n' + 'endcodespacerange\n';
     var stream = new _stream.StringStream(str);
-    var cmapPromise = _cmap.CMapFactory.create({ encoding: stream });
+
+    var cmapPromise = _cmap.CMapFactory.create({
+      encoding: stream
+    });
+
     cmapPromise.then(function (cmap) {
       var c = {};
       cmap.readCharCode(String.fromCharCode(0x8E, 0xA1, 0xA1, 0xA1), 0, c);
@@ -166,11 +197,13 @@ describe('cmap', function () {
   it('read usecmap', function (done) {
     var str = '/Adobe-Japan1-1 usecmap\n';
     var stream = new _stream.StringStream(str);
+
     var cmapPromise = _cmap.CMapFactory.create({
       encoding: stream,
       fetchBuiltInCMap: fetchBuiltInCMap,
       useCMap: null
     });
+
     cmapPromise.then(function (cmap) {
       expect(cmap instanceof _cmap.CMap).toEqual(true);
       expect(cmap.useCMap).not.toBeNull();
@@ -185,7 +218,11 @@ describe('cmap', function () {
   it('parses cmapname', function (done) {
     var str = '/CMapName /Identity-H def\n';
     var stream = new _stream.StringStream(str);
-    var cmapPromise = _cmap.CMapFactory.create({ encoding: stream });
+
+    var cmapPromise = _cmap.CMapFactory.create({
+      encoding: stream
+    });
+
     cmapPromise.then(function (cmap) {
       expect(cmap.name).toEqual('Identity-H');
       done();
@@ -196,7 +233,11 @@ describe('cmap', function () {
   it('parses wmode', function (done) {
     var str = '/WMode 1 def\n';
     var stream = new _stream.StringStream(str);
-    var cmapPromise = _cmap.CMapFactory.create({ encoding: stream });
+
+    var cmapPromise = _cmap.CMapFactory.create({
+      encoding: stream
+    });
+
     cmapPromise.then(function (cmap) {
       expect(cmap.vertical).toEqual(true);
       done();
@@ -210,6 +251,7 @@ describe('cmap', function () {
       fetchBuiltInCMap: fetchBuiltInCMap,
       useCMap: null
     });
+
     cmapPromise.then(function (cmap) {
       expect(cmap instanceof _cmap.CMap).toEqual(true);
       expect(cmap.useCMap).toBeNull();
@@ -227,6 +269,7 @@ describe('cmap', function () {
       fetchBuiltInCMap: fetchBuiltInCMap,
       useCMap: null
     });
+
     cmapPromise.then(function (cmap) {
       expect(cmap instanceof _cmap.IdentityCMap).toEqual(true);
       expect(cmap.vertical).toEqual(false);
@@ -245,6 +288,7 @@ describe('cmap', function () {
       fetchBuiltInCMap: fetchBuiltInCMap,
       useCMap: null
     });
+
     cmapPromise.then(function () {
       done.fail('No CMap should be loaded');
     }, function (reason) {
@@ -255,14 +299,18 @@ describe('cmap', function () {
   });
   it('attempts to load a built-in CMap without the necessary API parameters', function (done) {
     function tmpFetchBuiltInCMap(name) {
-      var CMapReaderFactory = (0, _is_node2.default)() ? new _test_utils.NodeCMapReaderFactory({}) : new _dom_utils.DOMCMapReaderFactory({});
-      return CMapReaderFactory.fetch({ name: name });
+      var CMapReaderFactory = (0, _is_node.default)() ? new _test_utils.NodeCMapReaderFactory({}) : new _dom_utils.DOMCMapReaderFactory({});
+      return CMapReaderFactory.fetch({
+        name: name
+      });
     }
+
     var cmapPromise = _cmap.CMapFactory.create({
       encoding: _primitives.Name.get('Adobe-Japan1-1'),
       fetchBuiltInCMap: tmpFetchBuiltInCMap,
       useCMap: null
     });
+
     cmapPromise.then(function () {
       done.fail('No CMap should be loaded');
     }, function (reason) {
@@ -273,8 +321,9 @@ describe('cmap', function () {
   });
   it('attempts to load a built-in CMap with inconsistent API parameters', function (done) {
     function tmpFetchBuiltInCMap(name) {
-      var CMapReaderFactory = void 0;
-      if ((0, _is_node2.default)()) {
+      var CMapReaderFactory;
+
+      if ((0, _is_node.default)()) {
         CMapReaderFactory = new _test_utils.NodeCMapReaderFactory({
           baseUrl: cMapUrl.node,
           isCompressed: false
@@ -285,13 +334,18 @@ describe('cmap', function () {
           isCompressed: false
         });
       }
-      return CMapReaderFactory.fetch({ name: name });
+
+      return CMapReaderFactory.fetch({
+        name: name
+      });
     }
+
     var cmapPromise = _cmap.CMapFactory.create({
       encoding: _primitives.Name.get('Adobe-Japan1-1'),
       fetchBuiltInCMap: tmpFetchBuiltInCMap,
       useCMap: null
     });
+
     cmapPromise.then(function () {
       done.fail('No CMap should be loaded');
     }, function (reason) {

+ 99 - 52
lib/test/unit/colorspace_spec.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,17 +19,17 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
-var _primitives = require('../../core/primitives');
+var _primitives = require("../../core/primitives");
 
-var _stream = require('../../core/stream');
+var _stream = require("../../core/stream");
 
-var _colorspace = require('../../core/colorspace');
+var _colorspace = require("../../core/colorspace");
 
-var _function = require('../../core/function');
+var _function = require("../../core/function");
 
-var _test_utils = require('./test_utils');
+var _test_utils = require("./test_utils");
 
 describe('colorspace', function () {
   describe('ColorSpace', function () {
@@ -53,18 +53,23 @@ describe('colorspace', function () {
   describe('DeviceGrayCS', function () {
     it('should handle the case when cs is a Name object', function () {
       var cs = _primitives.Name.get('DeviceGray');
+
       var xref = new _test_utils.XRefMock([{
         ref: new _primitives.Ref(10, 0),
         data: new _primitives.Dict()
       }]);
       var res = new _primitives.Dict();
-      var pdfFunctionFactory = new _function.PDFFunctionFactory({ xref: xref });
+      var pdfFunctionFactory = new _function.PDFFunctionFactory({
+        xref: xref
+      });
+
       var colorSpace = _colorspace.ColorSpace.parse(cs, xref, res, pdfFunctionFactory);
+
       var testSrc = new Uint8Array([27, 125, 250, 131]);
-      var testDest = new Uint8Array(4 * 4 * 3);
-      var expectedDest = new Uint8Array([27, 27, 27, 27, 27, 27, 125, 125, 125, 125, 125, 125, 27, 27, 27, 27, 27, 27, 125, 125, 125, 125, 125, 125, 250, 250, 250, 250, 250, 250, 131, 131, 131, 131, 131, 131, 250, 250, 250, 250, 250, 250, 131, 131, 131, 131, 131, 131]);
+      var testDest = new Uint8ClampedArray(4 * 4 * 3);
+      var expectedDest = new Uint8ClampedArray([27, 27, 27, 27, 27, 27, 125, 125, 125, 125, 125, 125, 27, 27, 27, 27, 27, 27, 125, 125, 125, 125, 125, 125, 250, 250, 250, 250, 250, 250, 131, 131, 131, 131, 131, 131, 250, 250, 250, 250, 250, 250, 131, 131, 131, 131, 131, 131]);
       colorSpace.fillRgb(testDest, 2, 2, 4, 4, 4, 8, testSrc, 0);
-      expect(colorSpace.getRgb(new Float32Array([0.1]), 0)).toEqual(new Uint8Array([25, 25, 25]));
+      expect(colorSpace.getRgb(new Float32Array([0.1]), 0)).toEqual(new Uint8ClampedArray([26, 26, 26]));
       expect(colorSpace.getOutputLength(2, 0)).toEqual(6);
       expect(colorSpace.isPassthrough(8)).toBeFalsy();
       expect(testDest).toEqual(expectedDest);
@@ -76,13 +81,17 @@ describe('colorspace', function () {
         data: _primitives.Name.get('DeviceGray')
       }]);
       var res = new _primitives.Dict();
-      var pdfFunctionFactory = new _function.PDFFunctionFactory({ xref: xref });
+      var pdfFunctionFactory = new _function.PDFFunctionFactory({
+        xref: xref
+      });
+
       var colorSpace = _colorspace.ColorSpace.parse(cs, xref, res, pdfFunctionFactory);
+
       var testSrc = new Uint8Array([27, 125, 250, 131]);
-      var testDest = new Uint8Array(3 * 3 * 3);
-      var expectedDest = new Uint8Array([27, 27, 27, 27, 27, 27, 125, 125, 125, 27, 27, 27, 27, 27, 27, 125, 125, 125, 250, 250, 250, 250, 250, 250, 131, 131, 131]);
+      var testDest = new Uint8ClampedArray(3 * 3 * 3);
+      var expectedDest = new Uint8ClampedArray([27, 27, 27, 27, 27, 27, 125, 125, 125, 27, 27, 27, 27, 27, 27, 125, 125, 125, 250, 250, 250, 250, 250, 250, 131, 131, 131]);
       colorSpace.fillRgb(testDest, 2, 2, 3, 3, 3, 8, testSrc, 0);
-      expect(colorSpace.getRgb(new Float32Array([0.2]), 0)).toEqual(new Uint8Array([51, 51, 51]));
+      expect(colorSpace.getRgb(new Float32Array([0.2]), 0)).toEqual(new Uint8ClampedArray([51, 51, 51]));
       expect(colorSpace.getOutputLength(3, 1)).toEqual(12);
       expect(colorSpace.isPassthrough(8)).toBeFalsy();
       expect(testDest).toEqual(expectedDest);
@@ -91,18 +100,23 @@ describe('colorspace', function () {
   describe('DeviceRgbCS', function () {
     it('should handle the case when cs is a Name object', function () {
       var cs = _primitives.Name.get('DeviceRGB');
+
       var xref = new _test_utils.XRefMock([{
         ref: new _primitives.Ref(10, 0),
         data: new _primitives.Dict()
       }]);
       var res = new _primitives.Dict();
-      var pdfFunctionFactory = new _function.PDFFunctionFactory({ xref: xref });
+      var pdfFunctionFactory = new _function.PDFFunctionFactory({
+        xref: xref
+      });
+
       var colorSpace = _colorspace.ColorSpace.parse(cs, xref, res, pdfFunctionFactory);
+
       var testSrc = new Uint8Array([27, 125, 250, 131, 139, 140, 111, 25, 198, 21, 147, 255]);
-      var testDest = new Uint8Array(4 * 4 * 3);
-      var expectedDest = new Uint8Array([27, 125, 250, 27, 125, 250, 131, 139, 140, 131, 139, 140, 27, 125, 250, 27, 125, 250, 131, 139, 140, 131, 139, 140, 111, 25, 198, 111, 25, 198, 21, 147, 255, 21, 147, 255, 111, 25, 198, 111, 25, 198, 21, 147, 255, 21, 147, 255]);
+      var testDest = new Uint8ClampedArray(4 * 4 * 3);
+      var expectedDest = new Uint8ClampedArray([27, 125, 250, 27, 125, 250, 131, 139, 140, 131, 139, 140, 27, 125, 250, 27, 125, 250, 131, 139, 140, 131, 139, 140, 111, 25, 198, 111, 25, 198, 21, 147, 255, 21, 147, 255, 111, 25, 198, 111, 25, 198, 21, 147, 255, 21, 147, 255]);
       colorSpace.fillRgb(testDest, 2, 2, 4, 4, 4, 8, testSrc, 0);
-      expect(colorSpace.getRgb(new Float32Array([0.1, 0.2, 0.3]), 0)).toEqual(new Uint8Array([25, 51, 76]));
+      expect(colorSpace.getRgb(new Float32Array([0.1, 0.2, 0.3]), 0)).toEqual(new Uint8ClampedArray([26, 51, 77]));
       expect(colorSpace.getOutputLength(4, 0)).toEqual(4);
       expect(colorSpace.isPassthrough(8)).toBeTruthy();
       expect(testDest).toEqual(expectedDest);
@@ -114,13 +128,17 @@ describe('colorspace', function () {
         data: _primitives.Name.get('DeviceRGB')
       }]);
       var res = new _primitives.Dict();
-      var pdfFunctionFactory = new _function.PDFFunctionFactory({ xref: xref });
+      var pdfFunctionFactory = new _function.PDFFunctionFactory({
+        xref: xref
+      });
+
       var colorSpace = _colorspace.ColorSpace.parse(cs, xref, res, pdfFunctionFactory);
+
       var testSrc = new Uint8Array([27, 125, 250, 131, 139, 140, 111, 25, 198, 21, 147, 255]);
-      var testDest = new Uint8Array(3 * 3 * 3);
-      var expectedDest = new Uint8Array([27, 125, 250, 27, 125, 250, 131, 139, 140, 27, 125, 250, 27, 125, 250, 131, 139, 140, 111, 25, 198, 111, 25, 198, 21, 147, 255]);
+      var testDest = new Uint8ClampedArray(3 * 3 * 3);
+      var expectedDest = new Uint8ClampedArray([27, 125, 250, 27, 125, 250, 131, 139, 140, 27, 125, 250, 27, 125, 250, 131, 139, 140, 111, 25, 198, 111, 25, 198, 21, 147, 255]);
       colorSpace.fillRgb(testDest, 2, 2, 3, 3, 3, 8, testSrc, 0);
-      expect(colorSpace.getRgb(new Float32Array([0.1, 0.2, 0.3]), 0)).toEqual(new Uint8Array([25, 51, 76]));
+      expect(colorSpace.getRgb(new Float32Array([0.1, 0.2, 0.3]), 0)).toEqual(new Uint8ClampedArray([26, 51, 77]));
       expect(colorSpace.getOutputLength(4, 1)).toEqual(5);
       expect(colorSpace.isPassthrough(8)).toBeTruthy();
       expect(testDest).toEqual(expectedDest);
@@ -129,18 +147,23 @@ describe('colorspace', function () {
   describe('DeviceCmykCS', function () {
     it('should handle the case when cs is a Name object', function () {
       var cs = _primitives.Name.get('DeviceCMYK');
+
       var xref = new _test_utils.XRefMock([{
         ref: new _primitives.Ref(10, 0),
         data: new _primitives.Dict()
       }]);
       var res = new _primitives.Dict();
-      var pdfFunctionFactory = new _function.PDFFunctionFactory({ xref: xref });
+      var pdfFunctionFactory = new _function.PDFFunctionFactory({
+        xref: xref
+      });
+
       var colorSpace = _colorspace.ColorSpace.parse(cs, xref, res, pdfFunctionFactory);
+
       var testSrc = new Uint8Array([27, 125, 250, 128, 131, 139, 140, 45, 111, 25, 198, 78, 21, 147, 255, 69]);
-      var testDest = new Uint8Array(4 * 4 * 3);
-      var expectedDest = new Uint8Array([135, 80, 18, 135, 80, 18, 113, 102, 97, 113, 102, 97, 135, 80, 18, 135, 80, 18, 113, 102, 97, 113, 102, 97, 112, 143, 75, 112, 143, 75, 188, 98, 27, 188, 98, 27, 112, 143, 75, 112, 143, 75, 188, 98, 27, 188, 98, 27]);
+      var testDest = new Uint8ClampedArray(4 * 4 * 3);
+      var expectedDest = new Uint8ClampedArray([135, 81, 18, 135, 81, 18, 114, 102, 97, 114, 102, 97, 135, 81, 18, 135, 81, 18, 114, 102, 97, 114, 102, 97, 112, 144, 75, 112, 144, 75, 188, 98, 27, 188, 98, 27, 112, 144, 75, 112, 144, 75, 188, 98, 27, 188, 98, 27]);
       colorSpace.fillRgb(testDest, 2, 2, 4, 4, 4, 8, testSrc, 0);
-      expect(colorSpace.getRgb(new Float32Array([0.1, 0.2, 0.3, 1]), 0)).toEqual(new Uint8Array([31, 27, 20]));
+      expect(colorSpace.getRgb(new Float32Array([0.1, 0.2, 0.3, 1]), 0)).toEqual(new Uint8ClampedArray([32, 28, 21]));
       expect(colorSpace.getOutputLength(4, 0)).toEqual(3);
       expect(colorSpace.isPassthrough(8)).toBeFalsy();
       expect(testDest).toEqual(expectedDest);
@@ -152,13 +175,17 @@ describe('colorspace', function () {
         data: _primitives.Name.get('DeviceCMYK')
       }]);
       var res = new _primitives.Dict();
-      var pdfFunctionFactory = new _function.PDFFunctionFactory({ xref: xref });
+      var pdfFunctionFactory = new _function.PDFFunctionFactory({
+        xref: xref
+      });
+
       var colorSpace = _colorspace.ColorSpace.parse(cs, xref, res, pdfFunctionFactory);
+
       var testSrc = new Uint8Array([27, 125, 250, 128, 131, 139, 140, 45, 111, 25, 198, 78, 21, 147, 255, 69]);
-      var testDest = new Uint8Array(3 * 3 * 3);
-      var expectedDest = new Uint8Array([135, 80, 18, 135, 80, 18, 113, 102, 97, 135, 80, 18, 135, 80, 18, 113, 102, 97, 112, 143, 75, 112, 143, 75, 188, 98, 27]);
+      var testDest = new Uint8ClampedArray(3 * 3 * 3);
+      var expectedDest = new Uint8ClampedArray([135, 81, 18, 135, 81, 18, 114, 102, 97, 135, 81, 18, 135, 81, 18, 114, 102, 97, 112, 144, 75, 112, 144, 75, 188, 98, 27]);
       colorSpace.fillRgb(testDest, 2, 2, 3, 3, 3, 8, testSrc, 0);
-      expect(colorSpace.getRgb(new Float32Array([0.1, 0.2, 0.3, 1]), 0)).toEqual(new Uint8Array([31, 27, 20]));
+      expect(colorSpace.getRgb(new Float32Array([0.1, 0.2, 0.3, 1]), 0)).toEqual(new Uint8ClampedArray([32, 28, 21]));
       expect(colorSpace.getOutputLength(4, 1)).toEqual(4);
       expect(colorSpace.isPassthrough(8)).toBeFalsy();
       expect(testDest).toEqual(expectedDest);
@@ -176,13 +203,17 @@ describe('colorspace', function () {
         data: new _primitives.Dict()
       }]);
       var res = new _primitives.Dict();
-      var pdfFunctionFactory = new _function.PDFFunctionFactory({ xref: xref });
+      var pdfFunctionFactory = new _function.PDFFunctionFactory({
+        xref: xref
+      });
+
       var colorSpace = _colorspace.ColorSpace.parse(cs, xref, res, pdfFunctionFactory);
+
       var testSrc = new Uint8Array([27, 125, 250, 131]);
-      var testDest = new Uint8Array(4 * 4 * 3);
-      var expectedDest = new Uint8Array([25, 25, 25, 25, 25, 25, 143, 143, 143, 143, 143, 143, 25, 25, 25, 25, 25, 25, 143, 143, 143, 143, 143, 143, 251, 251, 251, 251, 251, 251, 148, 148, 148, 148, 148, 148, 251, 251, 251, 251, 251, 251, 148, 148, 148, 148, 148, 148]);
+      var testDest = new Uint8ClampedArray(4 * 4 * 3);
+      var expectedDest = new Uint8ClampedArray([25, 25, 25, 25, 25, 25, 143, 143, 143, 143, 143, 143, 25, 25, 25, 25, 25, 25, 143, 143, 143, 143, 143, 143, 251, 251, 251, 251, 251, 251, 149, 149, 149, 149, 149, 149, 251, 251, 251, 251, 251, 251, 149, 149, 149, 149, 149, 149]);
       colorSpace.fillRgb(testDest, 2, 2, 4, 4, 4, 8, testSrc, 0);
-      expect(colorSpace.getRgb(new Float32Array([1.0]), 0)).toEqual(new Uint8Array([255, 255, 255]));
+      expect(colorSpace.getRgb(new Float32Array([1.0]), 0)).toEqual(new Uint8ClampedArray([255, 255, 255]));
       expect(colorSpace.getOutputLength(4, 0)).toEqual(12);
       expect(colorSpace.isPassthrough(8)).toBeFalsy();
       expect(testDest).toEqual(expectedDest);
@@ -201,13 +232,17 @@ describe('colorspace', function () {
         data: new _primitives.Dict()
       }]);
       var res = new _primitives.Dict();
-      var pdfFunctionFactory = new _function.PDFFunctionFactory({ xref: xref });
+      var pdfFunctionFactory = new _function.PDFFunctionFactory({
+        xref: xref
+      });
+
       var colorSpace = _colorspace.ColorSpace.parse(cs, xref, res, pdfFunctionFactory);
+
       var testSrc = new Uint8Array([27, 125, 250, 131, 139, 140, 111, 25, 198, 21, 147, 255]);
-      var testDest = new Uint8Array(3 * 3 * 3);
-      var expectedDest = new Uint8Array([0, 238, 255, 0, 238, 255, 185, 196, 195, 0, 238, 255, 0, 238, 255, 185, 196, 195, 235, 0, 243, 235, 0, 243, 0, 255, 255]);
+      var testDest = new Uint8ClampedArray(3 * 3 * 3);
+      var expectedDest = new Uint8ClampedArray([0, 238, 255, 0, 238, 255, 185, 196, 195, 0, 238, 255, 0, 238, 255, 185, 196, 195, 235, 0, 243, 235, 0, 243, 0, 255, 255]);
       colorSpace.fillRgb(testDest, 2, 2, 3, 3, 3, 8, testSrc, 0);
-      expect(colorSpace.getRgb(new Float32Array([0.1, 0.2, 0.3]), 0)).toEqual(new Uint8Array([0, 147, 151]));
+      expect(colorSpace.getRgb(new Float32Array([0.1, 0.2, 0.3]), 0)).toEqual(new Uint8ClampedArray([0, 147, 151]));
       expect(colorSpace.getOutputLength(4, 0)).toEqual(4);
       expect(colorSpace.isPassthrough(8)).toBeFalsy();
       expect(testDest).toEqual(expectedDest);
@@ -225,13 +260,17 @@ describe('colorspace', function () {
         data: new _primitives.Dict()
       }]);
       var res = new _primitives.Dict();
-      var pdfFunctionFactory = new _function.PDFFunctionFactory({ xref: xref });
+      var pdfFunctionFactory = new _function.PDFFunctionFactory({
+        xref: xref
+      });
+
       var colorSpace = _colorspace.ColorSpace.parse(cs, xref, res, pdfFunctionFactory);
+
       var testSrc = new Uint8Array([27, 25, 50, 31, 19, 40, 11, 25, 98, 21, 47, 55]);
-      var testDest = new Uint8Array(3 * 3 * 3);
-      var expectedDest = new Uint8Array([0, 49, 101, 0, 49, 101, 0, 53, 116, 0, 49, 101, 0, 49, 101, 0, 53, 116, 0, 40, 39, 0, 40, 39, 0, 43, 90]);
+      var testDest = new Uint8ClampedArray(3 * 3 * 3);
+      var expectedDest = new Uint8ClampedArray([0, 49, 101, 0, 49, 101, 0, 53, 117, 0, 49, 101, 0, 49, 101, 0, 53, 117, 0, 41, 40, 0, 41, 40, 0, 43, 90]);
       colorSpace.fillRgb(testDest, 2, 2, 3, 3, 3, 8, testSrc, 0);
-      expect(colorSpace.getRgb([55, 25, 35], 0)).toEqual(new Uint8Array([188, 99, 61]));
+      expect(colorSpace.getRgb([55, 25, 35], 0)).toEqual(new Uint8ClampedArray([188, 100, 61]));
       expect(colorSpace.getOutputLength(4, 0)).toEqual(4);
       expect(colorSpace.isPassthrough(8)).toBeFalsy();
       expect(colorSpace.isDefaultDecode([0, 1])).toBeTruthy();
@@ -247,15 +286,19 @@ describe('colorspace', function () {
         data: new _primitives.Dict()
       }]);
       var res = new _primitives.Dict();
-      var pdfFunctionFactory = new _function.PDFFunctionFactory({ xref: xref });
+      var pdfFunctionFactory = new _function.PDFFunctionFactory({
+        xref: xref
+      });
+
       var colorSpace = _colorspace.ColorSpace.parse(cs, xref, res, pdfFunctionFactory);
+
       var testSrc = new Uint8Array([2, 2, 0, 1]);
-      var testDest = new Uint8Array(3 * 3 * 3);
-      var expectedDest = new Uint8Array([255, 109, 70, 255, 109, 70, 255, 109, 70, 255, 109, 70, 255, 109, 70, 255, 109, 70, 23, 155, 35, 23, 155, 35, 147, 69, 93]);
+      var testDest = new Uint8ClampedArray(3 * 3 * 3);
+      var expectedDest = new Uint8ClampedArray([255, 109, 70, 255, 109, 70, 255, 109, 70, 255, 109, 70, 255, 109, 70, 255, 109, 70, 23, 155, 35, 23, 155, 35, 147, 69, 93]);
       colorSpace.fillRgb(testDest, 2, 2, 3, 3, 3, 8, testSrc, 0);
-      expect(colorSpace.getRgb([2], 0)).toEqual(new Uint8Array([255, 109, 70]));
+      expect(colorSpace.getRgb([2], 0)).toEqual(new Uint8ClampedArray([255, 109, 70]));
       expect(colorSpace.isPassthrough(8)).toBeFalsy();
-      expect(colorSpace.isDefaultDecode([0, 1])).toBeTruthy();
+      expect(colorSpace.isDefaultDecode([0, 1], 1)).toBeTruthy();
       expect(testDest).toEqual(expectedDest);
     });
   });
@@ -275,13 +318,17 @@ describe('colorspace', function () {
         data: fn
       }]);
       var res = new _primitives.Dict();
-      var pdfFunctionFactory = new _function.PDFFunctionFactory({ xref: xref });
+      var pdfFunctionFactory = new _function.PDFFunctionFactory({
+        xref: xref
+      });
+
       var colorSpace = _colorspace.ColorSpace.parse(cs, xref, res, pdfFunctionFactory);
+
       var testSrc = new Uint8Array([27, 25, 50, 31]);
-      var testDest = new Uint8Array(3 * 3 * 3);
-      var expectedDest = new Uint8Array([227, 243, 242, 227, 243, 242, 228, 243, 242, 227, 243, 242, 227, 243, 242, 228, 243, 242, 203, 233, 229, 203, 233, 229, 222, 241, 239]);
+      var testDest = new Uint8ClampedArray(3 * 3 * 3);
+      var expectedDest = new Uint8ClampedArray([226, 242, 241, 226, 242, 241, 229, 244, 242, 226, 242, 241, 226, 242, 241, 229, 244, 242, 203, 232, 229, 203, 232, 229, 222, 241, 238]);
       colorSpace.fillRgb(testDest, 2, 2, 3, 3, 3, 8, testSrc, 0);
-      expect(colorSpace.getRgb([0.1], 0)).toEqual(new Uint8Array([228, 243, 241]));
+      expect(colorSpace.getRgb([0.1], 0)).toEqual(new Uint8ClampedArray([228, 243, 242]));
       expect(colorSpace.isPassthrough(8)).toBeFalsy();
       expect(colorSpace.isDefaultDecode([0, 1])).toBeTruthy();
       expect(testDest).toEqual(expectedDest);

+ 17 - 5
lib/test/unit/crypto_spec.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,13 +19,13 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
-var _crypto = require('../../core/crypto');
+var _crypto = require("../../core/crypto");
 
-var _primitives = require('../../core/primitives');
+var _primitives = require("../../core/primitives");
 
-var _util = require('../../shared/util');
+var _util = require("../../shared/util");
 
 describe('crypto', function () {
   function hex2binary(s) {
@@ -35,14 +35,17 @@ describe('crypto', function () {
         i,
         j;
     var result = new Uint8Array(n);
+
     for (i = 0, j = 0; i < n; ++i) {
       var d1 = s.charAt(j++);
       var d2 = s.charAt(j++);
       var value = digits.indexOf(d1) << 4 | digits.indexOf(d2);
       result[i] = value;
     }
+
     return result;
   }
+
   describe('calculateMD5', function () {
     it('should pass RFC 1321 test #1', function () {
       var input, result, expected;
@@ -357,11 +360,14 @@ describe('crypto', function () {
 describe('CipherTransformFactory', function () {
   function buildDict(map) {
     var dict = new _primitives.Dict();
+
     for (var key in map) {
       dict.set(key, map[key]);
     }
+
     return dict;
   }
+
   function ensurePasswordCorrect(done, dict, fileId, password) {
     try {
       var factory = new _crypto.CipherTransformFactory(dict, fileId, password);
@@ -370,8 +376,10 @@ describe('CipherTransformFactory', function () {
       done.fail('Password should be accepted: ' + ex);
       return;
     }
+
     done();
   }
+
   function ensurePasswordNeeded(done, dict, fileId, password) {
     try {
       new _crypto.CipherTransformFactory(dict, fileId, password);
@@ -381,8 +389,10 @@ describe('CipherTransformFactory', function () {
       done();
       return;
     }
+
     done.fail('Password should be rejected.');
   }
+
   function ensurePasswordIncorrect(done, dict, fileId, password) {
     try {
       new _crypto.CipherTransformFactory(dict, fileId, password);
@@ -392,8 +402,10 @@ describe('CipherTransformFactory', function () {
       done();
       return;
     }
+
     done.fail('Password should be rejected.');
   }
+
   var fileId1, fileId2, dict1, dict2;
   var aes256Dict, aes256IsoDict, aes256BlankDict, aes256IsoBlankDict;
   beforeAll(function (done) {

+ 41 - 53
lib/test/unit/custom_spec.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,17 +19,15 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
-var _test_utils = require('./test_utils');
+var _test_utils = require("./test_utils");
 
-var _dom_utils = require('../../display/dom_utils');
+var _dom_utils = require("../../display/dom_utils");
 
-var _api = require('../../display/api');
+var _api = require("../../display/api");
 
-var _is_node = require('../../shared/is_node');
-
-var _is_node2 = _interopRequireDefault(_is_node);
+var _is_node = _interopRequireDefault(require("../../shared/is_node"));
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
@@ -42,24 +40,26 @@ function getTopLeftPixel(canvasContext) {
     a: imgData.data[3]
   };
 }
+
 describe('custom canvas rendering', function () {
   var transparentGetDocumentParams = (0, _test_utils.buildGetDocumentParams)('transparent.pdf');
-  var CanvasFactory = void 0;
-  var loadingTask = void 0;
-  var page = void 0;
+  var CanvasFactory;
+  var loadingTask;
+  var page;
   beforeAll(function (done) {
-    if ((0, _is_node2.default)()) {} else {
+    if ((0, _is_node.default)()) {
+      CanvasFactory = new _test_utils.NodeCanvasFactory();
+    } else {
       CanvasFactory = new _dom_utils.DOMCanvasFactory();
     }
+
     loadingTask = (0, _api.getDocument)(transparentGetDocumentParams);
     loadingTask.promise.then(function (doc) {
       return doc.getPage(1);
     }).then(function (data) {
       page = data;
       done();
-    }).catch(function (reason) {
-      done.fail(reason);
-    });
+    }).catch(done.fail);
   });
   afterAll(function (done) {
     CanvasFactory = null;
@@ -67,56 +67,44 @@ describe('custom canvas rendering', function () {
     loadingTask.destroy().then(done);
   });
   it('renders to canvas with a default white background', function (done) {
-    if ((0, _is_node2.default)()) {
-      pending('TODO: Support Canvas testing in Node.js.');
-    }
-    var viewport = page.getViewport(1);
+    var viewport = page.getViewport({
+      scale: 1
+    });
     var canvasAndCtx = CanvasFactory.create(viewport.width, viewport.height);
-    page.render({
+    var renderTask = page.render({
       canvasContext: canvasAndCtx.context,
       viewport: viewport
-    }).then(function () {
-      var _getTopLeftPixel = getTopLeftPixel(canvasAndCtx.context),
-          r = _getTopLeftPixel.r,
-          g = _getTopLeftPixel.g,
-          b = _getTopLeftPixel.b,
-          a = _getTopLeftPixel.a;
-
+    });
+    renderTask.promise.then(function () {
+      expect(getTopLeftPixel(canvasAndCtx.context)).toEqual({
+        r: 255,
+        g: 255,
+        b: 255,
+        a: 255
+      });
       CanvasFactory.destroy(canvasAndCtx);
-      expect(r).toEqual(255);
-      expect(g).toEqual(255);
-      expect(b).toEqual(255);
-      expect(a).toEqual(255);
       done();
-    }).catch(function (reason) {
-      done(reason);
-    });
+    }).catch(done.fail);
   });
   it('renders to canvas with a custom background', function (done) {
-    if ((0, _is_node2.default)()) {
-      pending('TODO: Support Canvas testing in Node.js.');
-    }
-    var viewport = page.getViewport(1);
+    var viewport = page.getViewport({
+      scale: 1
+    });
     var canvasAndCtx = CanvasFactory.create(viewport.width, viewport.height);
-    page.render({
+    var renderTask = page.render({
       canvasContext: canvasAndCtx.context,
       viewport: viewport,
       background: 'rgba(255,0,0,1.0)'
-    }).then(function () {
-      var _getTopLeftPixel2 = getTopLeftPixel(canvasAndCtx.context),
-          r = _getTopLeftPixel2.r,
-          g = _getTopLeftPixel2.g,
-          b = _getTopLeftPixel2.b,
-          a = _getTopLeftPixel2.a;
-
+    });
+    renderTask.promise.then(function () {
+      expect(getTopLeftPixel(canvasAndCtx.context)).toEqual({
+        r: 255,
+        g: 0,
+        b: 0,
+        a: 255
+      });
       CanvasFactory.destroy(canvasAndCtx);
-      expect(r).toEqual(255);
-      expect(g).toEqual(0);
-      expect(b).toEqual(0);
-      expect(a).toEqual(255);
       done();
-    }).catch(function (reason) {
-      done(reason);
-    });
+    }).catch(done.fail);
   });
 });

+ 33 - 17
lib/test/unit/display_svg_spec.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,55 +19,64 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
-var _domstubs = require('../../examples/node/domstubs');
+var _domstubs = require("../../examples/node/domstubs");
 
-var _test_utils = require('./test_utils');
+var _test_utils = require("./test_utils");
 
-var _api = require('../../display/api');
+var _api = require("../../display/api");
 
-var _is_node = require('../../shared/is_node');
+var _is_node = _interopRequireDefault(require("../../shared/is_node"));
 
-var _is_node2 = _interopRequireDefault(_is_node);
+var _util = require("../../shared/util");
 
-var _util = require('../../shared/util');
-
-var _svg = require('../../display/svg');
+var _svg = require("../../display/svg");
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 var XLINK_NS = 'http://www.w3.org/1999/xlink';
+
 function withZlib(isZlibRequired, callback) {
   if (isZlibRequired) {
-    if (!(0, _is_node2.default)()) {
+    if (!(0, _is_node.default)()) {
       throw new Error('zlib test can only be run in Node.js');
     }
+
     return callback();
   }
-  if (!(0, _is_node2.default)()) {
+
+  if (!(0, _is_node.default)()) {
     return callback();
   }
+
   var zlib = require('zlib');
+
   var deflateSync = zlib.deflateSync;
   zlib.deflateSync = disabledDeflateSync;
+
   function disabledDeflateSync() {
     throw new Error('zlib.deflateSync is explicitly disabled for testing.');
   }
+
   function restoreDeflateSync() {
     if (zlib.deflateSync === disabledDeflateSync) {
       zlib.deflateSync = deflateSync;
     }
   }
+
   var promise = callback();
   promise.then(restoreDeflateSync, restoreDeflateSync);
   return promise;
 }
+
 describe('SVGGraphics', function () {
   var loadingTask;
   var page;
   beforeAll(function (done) {
-    loadingTask = (0, _api.getDocument)((0, _test_utils.buildGetDocumentParams)('xobject-image.pdf', { nativeImageDecoderSupport: _util.NativeImageDecoding.DISPLAY }));
+    loadingTask = (0, _api.getDocument)((0, _test_utils.buildGetDocumentParams)('xobject-image.pdf', {
+      nativeImageDecoderSupport: _util.NativeImageDecoding.DISPLAY
+    }));
     loadingTask.promise.then(function (doc) {
       doc.getPage(1).then(function (firstPage) {
         page = firstPage;
@@ -93,35 +102,42 @@ describe('SVGGraphics', function () {
           }
         };
         var xobjectObjId = 'img_p0_1';
-        if ((0, _is_node2.default)()) {
+
+        if ((0, _is_node.default)()) {
           (0, _domstubs.setStubs)(global);
         }
+
         try {
           var imgData = svgGfx.objs.get(xobjectObjId);
           svgGfx.paintInlineImageXObject(imgData, elementContainer);
         } finally {
-          if ((0, _is_node2.default)()) {
+          if ((0, _is_node.default)()) {
             (0, _domstubs.unsetStubs)(global);
           }
         }
+
         return svgImg;
       });
     }
+
     it('should fail require("zlib") unless in Node.js', function () {
       function testFunc() {
         require('zlib');
       }
+
       expect(testFunc.toString()).toMatch(/\srequire\(["']zlib["']\)/);
-      if ((0, _is_node2.default)()) {
+
+      if ((0, _is_node.default)()) {
         expect(testFunc).not.toThrow();
       } else {
         expect(testFunc).toThrow();
       }
     });
     it('should produce a reasonably small svg:image', function (done) {
-      if (!(0, _is_node2.default)()) {
+      if (!(0, _is_node.default)()) {
         pending('zlib.deflateSync is not supported in non-Node environments.');
       }
+
       withZlib(true, getSVGImage).then(function (svgImg) {
         expect(svgImg.nodeName).toBe('svg:image');
         expect(svgImg.getAttributeNS(null, 'width')).toBe('200px');

+ 3 - 3
lib/test/unit/document_spec.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,9 +19,9 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
-var _document = require('../../core/document');
+var _document = require("../../core/document");
 
 describe('document', function () {
   describe('Page', function () {

+ 9 - 9
lib/test/unit/dom_utils_spec.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,19 +19,17 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
-var _dom_utils = require('../../display/dom_utils');
+var _dom_utils = require("../../display/dom_utils");
 
-var _is_node = require('../../shared/is_node');
-
-var _is_node2 = _interopRequireDefault(_is_node);
+var _is_node = _interopRequireDefault(require("../../shared/is_node"));
 
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 describe('dom_utils', function () {
   describe('DOMSVGFactory', function () {
-    var svgFactory = void 0;
+    var svgFactory;
     beforeAll(function (done) {
       svgFactory = new _dom_utils.DOMSVGFactory();
       done();
@@ -48,9 +46,10 @@ describe('dom_utils', function () {
       }).toThrow(new Error('Invalid SVG dimensions'));
     });
     it('`create` should return an SVG element if the dimensions are valid', function () {
-      if ((0, _is_node2.default)()) {
+      if ((0, _is_node.default)()) {
         pending('Document is not supported in Node.js.');
       }
+
       var svg = svgFactory.create(20, 40);
       expect(svg instanceof SVGSVGElement).toBe(true);
       expect(svg.getAttribute('version')).toBe('1.1');
@@ -65,9 +64,10 @@ describe('dom_utils', function () {
       }).toThrow(new Error('Invalid SVG element type'));
     });
     it('`createElement` should return an SVG element if the type is valid', function () {
-      if ((0, _is_node2.default)()) {
+      if ((0, _is_node.default)()) {
         pending('Document is not supported in Node.js.');
       }
+
       var svg = svgFactory.createElement('svg:rect');
       expect(svg instanceof SVGRectElement).toBe(true);
     });

+ 25 - 45
lib/test/unit/encodings_spec.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,65 +19,45 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
-var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
+var _encodings = require("../../core/encodings");
 
-var _encodings = require('../../core/encodings');
+function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
 
 describe('encodings', function () {
   describe('getEncoding', function () {
     it('fetches a valid array for known encoding names', function () {
       var knownEncodingNames = ['ExpertEncoding', 'MacExpertEncoding', 'MacRomanEncoding', 'StandardEncoding', 'SymbolSetEncoding', 'WinAnsiEncoding', 'ZapfDingbatsEncoding'];
-      var _iteratorNormalCompletion = true;
-      var _didIteratorError = false;
-      var _iteratorError = undefined;
 
-      try {
-        for (var _iterator = knownEncodingNames[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
-          var knownEncodingName = _step.value;
-
-          var encoding = (0, _encodings.getEncoding)(knownEncodingName);
-          expect(Array.isArray(encoding)).toEqual(true);
-          expect(encoding.length).toEqual(256);
-          var _iteratorNormalCompletion2 = true;
-          var _didIteratorError2 = false;
-          var _iteratorError2 = undefined;
+      for (var _i = 0; _i < knownEncodingNames.length; _i++) {
+        var knownEncodingName = knownEncodingNames[_i];
+        var encoding = (0, _encodings.getEncoding)(knownEncodingName);
+        expect(Array.isArray(encoding)).toEqual(true);
+        expect(encoding.length).toEqual(256);
+        var _iteratorNormalCompletion = true;
+        var _didIteratorError = false;
+        var _iteratorError = undefined;
 
+        try {
+          for (var _iterator = encoding[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+            var item = _step.value;
+            expect(_typeof(item)).toEqual('string');
+          }
+        } catch (err) {
+          _didIteratorError = true;
+          _iteratorError = err;
+        } finally {
           try {
-            for (var _iterator2 = encoding[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
-              var item = _step2.value;
-
-              expect(typeof item === 'undefined' ? 'undefined' : _typeof(item)).toEqual('string');
+            if (!_iteratorNormalCompletion && _iterator.return != null) {
+              _iterator.return();
             }
-          } catch (err) {
-            _didIteratorError2 = true;
-            _iteratorError2 = err;
           } finally {
-            try {
-              if (!_iteratorNormalCompletion2 && _iterator2.return) {
-                _iterator2.return();
-              }
-            } finally {
-              if (_didIteratorError2) {
-                throw _iteratorError2;
-              }
+            if (_didIteratorError) {
+              throw _iteratorError;
             }
           }
         }
-      } catch (err) {
-        _didIteratorError = true;
-        _iteratorError = err;
-      } finally {
-        try {
-          if (!_iteratorNormalCompletion && _iterator.return) {
-            _iterator.return();
-          }
-        } finally {
-          if (_didIteratorError) {
-            throw _iteratorError;
-          }
-        }
       }
     });
     it('fetches `null` for unknown encoding names', function () {

+ 34 - 9
lib/test/unit/evaluator_spec.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,26 +19,27 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
-var _primitives = require('../../core/primitives');
+var _primitives = require("../../core/primitives");
 
-var _util = require('../../shared/util');
+var _util = require("../../shared/util");
 
-var _stream = require('../../core/stream');
+var _stream = require("../../core/stream");
 
-var _operator_list = require('../../core/operator_list');
+var _operator_list = require("../../core/operator_list");
 
-var _evaluator = require('../../core/evaluator');
+var _evaluator = require("../../core/evaluator");
 
-var _worker = require('../../core/worker');
+var _worker = require("../../core/worker");
 
-var _test_utils = require('./test_utils');
+var _test_utils = require("./test_utils");
 
 describe('evaluator', function () {
   function HandlerMock() {
     this.inputs = [];
   }
+
   HandlerMock.prototype = {
     send: function send(name, data) {
       this.inputs.push({
@@ -47,13 +48,17 @@ describe('evaluator', function () {
       });
     }
   };
+
   function ResourcesMock() {}
+
   ResourcesMock.prototype = {
     get: function get(name) {
       return this[name];
     }
   };
+
   function PdfManagerMock() {}
+
   function runOperatorListCheck(evaluator, stream, resources, callback) {
     var result = new _operator_list.OperatorList();
     var task = new _worker.WorkerTask('OperatorListCheck');
@@ -68,6 +73,7 @@ describe('evaluator', function () {
       callback(reason);
     });
   }
+
   var partialEvaluator;
   beforeAll(function (done) {
     partialEvaluator = new _evaluator.PartialEvaluator({
@@ -209,6 +215,24 @@ describe('evaluator', function () {
         done();
       });
     });
+    it('should error if (many) path operators have too few arguments ' + '(bug 1443140)', function (done) {
+      var NUM_INVALID_OPS = 25;
+      var tempArr = new Array(NUM_INVALID_OPS + 1);
+      var invalidMoveText = tempArr.join('10 Td\n');
+      var moveTextStream = new _stream.StringStream(invalidMoveText);
+      runOperatorListCheck(partialEvaluator, moveTextStream, new ResourcesMock(), function (result) {
+        expect(result.argsArray).toEqual([]);
+        expect(result.fnArray).toEqual([]);
+        done();
+      });
+      var invalidLineTo = tempArr.join('20 l\n');
+      var lineToStream = new _stream.StringStream(invalidLineTo);
+      runOperatorListCheck(partialEvaluator, lineToStream, new ResourcesMock(), function (error) {
+        expect(error instanceof _util.FormatError).toEqual(true);
+        expect(error.message).toEqual('Invalid command l: expected 2 args, but received 1 args.');
+        done();
+      });
+    });
     it('should close opened saves', function (done) {
       var stream = new _stream.StringStream('qq');
       runOperatorListCheck(partialEvaluator, stream, new ResourcesMock(), function (result) {
@@ -280,6 +304,7 @@ describe('evaluator', function () {
   });
   describe('operator list', function () {
     function MessageHandlerMock() {}
+
     MessageHandlerMock.prototype = {
       send: function send() {}
     };

+ 0 - 81
lib/test/unit/fonts_spec.js

@@ -1,81 +0,0 @@
-/**
- * @licstart The following is the entire license notice for the
- * Javascript code in this page
- *
- * Copyright 2017 Mozilla Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @licend The above is the entire license notice for the
- * Javascript code in this page
- */
-'use strict';
-
-var _fonts = require('../../core/fonts');
-
-var checkProblematicCharRanges = function checkProblematicCharRanges() {
-  function printRange(limits) {
-    return '[' + limits.lower.toString('16').toUpperCase() + ', ' + limits.upper.toString('16').toUpperCase() + ')';
-  }
-  var numRanges = _fonts.ProblematicCharRanges.length;
-  if (numRanges % 2 !== 0) {
-    throw new Error('Char ranges must contain an even number of elements.');
-  }
-  var prevLimits,
-      numChars = 0;
-  for (var i = 0; i < numRanges; i += 2) {
-    var limits = {
-      lower: _fonts.ProblematicCharRanges[i],
-      upper: _fonts.ProblematicCharRanges[i + 1]
-    };
-    if (!Number.isInteger(limits.lower) || !Number.isInteger(limits.upper)) {
-      throw new Error('Range endpoints must be integers: ' + printRange(limits));
-    }
-    if (limits.lower < 0 || limits.upper < 0) {
-      throw new Error('Range endpoints must be non-negative: ' + printRange(limits));
-    }
-    var range = limits.upper - limits.lower;
-    if (range < 1) {
-      throw new Error('Range must contain at least one element: ' + printRange(limits));
-    }
-    if (prevLimits) {
-      if (limits.lower < prevLimits.lower) {
-        throw new Error('Ranges must be sorted in ascending order: ' + printRange(limits) + ', ' + printRange(prevLimits));
-      }
-      if (limits.lower < prevLimits.upper) {
-        throw new Error('Ranges must not overlap: ' + printRange(limits) + ', ' + printRange(prevLimits));
-      }
-    }
-    prevLimits = {
-      lower: limits.lower,
-      upper: limits.upper
-    };
-    numChars += range;
-  }
-  var puaLength = _fonts.PRIVATE_USE_OFFSET_END + 1 - _fonts.PRIVATE_USE_OFFSET_START;
-  if (numChars > puaLength) {
-    throw new Error('Total number of chars must not exceed the PUA length.');
-  }
-  return {
-    numChars: numChars,
-    puaLength: puaLength,
-    percentage: 100 * (numChars / puaLength)
-  };
-};
-describe('Fonts', function () {
-  it('checkProblematicCharRanges', function () {
-    var EXPECTED_PERCENTAGE = 100;
-    var result = checkProblematicCharRanges();
-    expect(result.percentage).toBeLessThan(EXPECTED_PERCENTAGE);
-  });
-});

+ 17 - 5
lib/test/unit/function_spec.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,13 +19,13 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
-var _function = require('../../core/function');
+var _function = require("../../core/function");
 
-var _ps_parser = require('../../core/ps_parser');
+var _ps_parser = require("../../core/ps_parser");
 
-var _stream = require('../../core/stream');
+var _stream = require("../../core/stream");
 
 describe('function', function () {
   beforeEach(function () {
@@ -34,23 +34,29 @@ describe('function', function () {
         return {
           compare: function compare(actual, expected) {
             var result = {};
+
             if (actual.length !== expected.length) {
               result.pass = false;
               result.message = 'Array length: ' + actual.length + ', expected: ' + expected.length;
               return result;
             }
+
             result.pass = true;
+
             for (var i = 0; i < expected.length; i++) {
               var a = actual[i],
                   b = expected[i];
+
               if (Array.isArray(b)) {
                 if (a.length !== b.length) {
                   result.pass = false;
                   break;
                 }
+
                 for (var j = 0; j < a.length; j++) {
                   var suba = a[j],
                       subb = b[j];
+
                   if (suba !== subb) {
                     result.pass = false;
                     break;
@@ -63,6 +69,7 @@ describe('function', function () {
                 }
               }
             }
+
             return result;
           }
         };
@@ -75,6 +82,7 @@ describe('function', function () {
       var parser = new _ps_parser.PostScriptParser(new _ps_parser.PostScriptLexer(stream));
       return parser.parse();
     }
+
     it('parses empty programs', function () {
       var output = parse('{}');
       expect(output.length).toEqual(0);
@@ -133,6 +141,7 @@ describe('function', function () {
       var output = evaluator.execute();
       return output;
     }
+
     it('pushes stack', function () {
       var stack = evaluate('{ 99 }');
       var expectedStack = [99];
@@ -448,11 +457,13 @@ describe('function', function () {
     function check(code, domain, range, samples) {
       var compiler = new _function.PostScriptCompiler();
       var compiledCode = compiler.compile(code, domain, range);
+
       if (samples === null) {
         expect(compiledCode).toBeNull();
       } else {
         expect(compiledCode).not.toBeNull();
         var fn = new Function('src', 'srcOffset', 'dest', 'destOffset', compiledCode);
+
         for (var i = 0; i < samples.length; i++) {
           var out = new Float32Array(samples[i].output.length);
           fn(samples[i].input, 0, out, 0);
@@ -460,6 +471,7 @@ describe('function', function () {
         }
       }
     }
+
     it('check compiled add', function () {
       check([0.25, 0.5, 'add'], [], [0, 1], [{
         input: [],

+ 31 - 18
lib/test/unit/jasmine-boot.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@
 'use strict';
 
 function initializePDFJS(callback) {
-  Promise.all(['pdfjs/display/api', 'pdfjs/display/worker_options', 'pdfjs/display/network', 'pdfjs/display/fetch_stream', 'pdfjs/shared/is_node', 'pdfjs-test/unit/annotation_spec', 'pdfjs-test/unit/api_spec', 'pdfjs-test/unit/bidi_spec', 'pdfjs-test/unit/cff_parser_spec', 'pdfjs-test/unit/cmap_spec', 'pdfjs-test/unit/colorspace_spec', 'pdfjs-test/unit/crypto_spec', 'pdfjs-test/unit/custom_spec', 'pdfjs-test/unit/display_svg_spec', 'pdfjs-test/unit/document_spec', 'pdfjs-test/unit/dom_utils_spec', 'pdfjs-test/unit/encodings_spec', 'pdfjs-test/unit/evaluator_spec', 'pdfjs-test/unit/fonts_spec', 'pdfjs-test/unit/function_spec', 'pdfjs-test/unit/metadata_spec', 'pdfjs-test/unit/murmurhash3_spec', 'pdfjs-test/unit/network_spec', 'pdfjs-test/unit/network_utils_spec', 'pdfjs-test/unit/parser_spec', 'pdfjs-test/unit/pdf_history_spec', 'pdfjs-test/unit/primitives_spec', 'pdfjs-test/unit/stream_spec', 'pdfjs-test/unit/type1_parser_spec', 'pdfjs-test/unit/ui_utils_spec', 'pdfjs-test/unit/unicode_spec', 'pdfjs-test/unit/util_spec', 'pdfjs-test/unit/util_stream_spec'].map(function (moduleName) {
+  Promise.all(['pdfjs/display/api', 'pdfjs/display/worker_options', 'pdfjs/display/network', 'pdfjs/display/fetch_stream', 'pdfjs/shared/is_node', 'pdfjs-test/unit/annotation_spec', 'pdfjs-test/unit/api_spec', 'pdfjs-test/unit/bidi_spec', 'pdfjs-test/unit/cff_parser_spec', 'pdfjs-test/unit/cmap_spec', 'pdfjs-test/unit/colorspace_spec', 'pdfjs-test/unit/crypto_spec', 'pdfjs-test/unit/custom_spec', 'pdfjs-test/unit/display_svg_spec', 'pdfjs-test/unit/document_spec', 'pdfjs-test/unit/dom_utils_spec', 'pdfjs-test/unit/encodings_spec', 'pdfjs-test/unit/evaluator_spec', 'pdfjs-test/unit/function_spec', 'pdfjs-test/unit/message_handler_spec', 'pdfjs-test/unit/metadata_spec', 'pdfjs-test/unit/murmurhash3_spec', 'pdfjs-test/unit/network_spec', 'pdfjs-test/unit/network_utils_spec', 'pdfjs-test/unit/parser_spec', 'pdfjs-test/unit/pdf_find_controller_spec', 'pdfjs-test/unit/pdf_find_utils_spec', 'pdfjs-test/unit/pdf_history_spec', 'pdfjs-test/unit/primitives_spec', 'pdfjs-test/unit/stream_spec', 'pdfjs-test/unit/type1_parser_spec', 'pdfjs-test/unit/ui_utils_spec', 'pdfjs-test/unit/unicode_spec', 'pdfjs-test/unit/util_spec'].map(function (moduleName) {
     return SystemJS.import(moduleName);
   })).then(function (modules) {
     var displayApi = modules[0];
@@ -30,9 +30,11 @@ function initializePDFJS(callback) {
     var PDFNetworkStream = modules[2].PDFNetworkStream;
     var PDFFetchStream = modules[3].PDFFetchStream;
     var isNodeJS = modules[4];
+
     if (isNodeJS()) {
       throw new Error('The `gulp unittest` command cannot be used in ' + 'Node.js environments.');
     }
+
     if (typeof Response !== 'undefined' && 'body' in Response.prototype && typeof ReadableStream !== 'undefined') {
       displayApi.setPDFNetworkStreamFactory(function (params) {
         return new PDFFetchStream(params);
@@ -42,10 +44,12 @@ function initializePDFJS(callback) {
         return new PDFNetworkStream(params);
       });
     }
+
     GlobalWorkerOptions.workerSrc = '../../build/generic/build/pdf.worker.js';
     callback();
   });
 }
+
 (function () {
   window.jasmine = jasmineRequire.core(jasmineRequire);
   jasmineRequire.html(jasmine);
@@ -57,26 +61,27 @@ function initializePDFJS(callback) {
       return window.location;
     }
   });
-  var stoppingOnSpecFailure = queryString.getParam('failFast');
-  env.stopOnSpecFailure(typeof stoppingOnSpecFailure === 'undefined' ? false : stoppingOnSpecFailure);
-  var throwingExpectationFailures = queryString.getParam('throwFailures');
-  env.throwOnExpectationFailure(throwingExpectationFailures);
+  var config = {
+    failFast: queryString.getParam('failFast'),
+    oneFailurePerSpec: queryString.getParam('oneFailurePerSpec'),
+    hideDisabled: queryString.getParam('hideDisabled')
+  };
   var random = queryString.getParam('random');
-  env.randomizeTests(random);
+
+  if (random !== undefined && random !== '') {
+    config.random = random;
+  }
+
   var seed = queryString.getParam('seed');
+
   if (seed) {
-    env.seed(seed);
+    config.seed = seed;
   }
+
   var htmlReporter = new jasmine.HtmlReporter({
     env: env,
-    onStopExecutionClick: function onStopExecutionClick() {
-      queryString.navigateWithNewParam('failFast', env.stoppingOnSpecFailure());
-    },
-    onThrowExpectationsClick: function onThrowExpectationsClick() {
-      queryString.navigateWithNewParam('throwFailures', !env.throwingExpectationFailures());
-    },
-    onRandomClick: function onRandomClick() {
-      queryString.navigateWithNewParam('random', !env.randomTests());
+    navigateWithNewParam: function navigateWithNewParam(key, value) {
+      return queryString.navigateWithNewParam(key, value);
     },
     addToExistingQueryString: function addToExistingQueryString(key, value) {
       return queryString.fullStringWithNewParam(key, value);
@@ -90,37 +95,45 @@ function initializePDFJS(callback) {
     createTextNode: function createTextNode() {
       return document.createTextNode.apply(document, arguments);
     },
-
     timer: new jasmine.Timer()
   });
   env.addReporter(htmlReporter);
+
   if (queryString.getParam('browser')) {
     var testReporter = new TestReporter(queryString.getParam('browser'), queryString.getParam('path'));
     env.addReporter(testReporter);
   }
+
   var specFilter = new jasmine.HtmlSpecFilter({
     filterString: function filterString() {
       return queryString.getParam('spec');
     }
   });
-  env.specFilter = function (spec) {
+
+  config.specFilter = function (spec) {
     return specFilter.matches(spec.getFullName());
   };
+
+  env.configure(config);
   jasmine.DEFAULT_TIMEOUT_INTERVAL = 30000;
   var currentWindowOnload = window.onload;
+
   window.onload = function () {
     if (currentWindowOnload) {
       currentWindowOnload();
     }
+
     initializePDFJS(function () {
       htmlReporter.initialize();
       env.execute();
     });
   };
+
   function extend(destination, source) {
     for (var property in source) {
       destination[property] = source[property];
     }
+
     return destination;
   }
 })();

+ 41 - 69
lib/test/unit/util_stream_spec.js → lib/test/unit/message_handler_spec.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,83 +19,45 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
-var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
+var _util = require("../../shared/util");
 
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+var _api = require("../../display/api");
 
-var _util = require('../../shared/util');
+var _message_handler = require("../../shared/message_handler");
 
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-describe('util_stream', function () {
-  var FakePort = function () {
-    function FakePort() {
-      _classCallCheck(this, FakePort);
-
-      this._listeners = [];
-      this._deferred = Promise.resolve(undefined);
-    }
-
-    _createClass(FakePort, [{
-      key: 'postMessage',
-      value: function postMessage(obj) {
-        var _this = this;
-
-        var event = { data: obj };
-        this._deferred.then(function () {
-          _this._listeners.forEach(function (listener) {
-            listener.call(this, event);
-          }, _this);
-        });
-      }
-    }, {
-      key: 'addEventListener',
-      value: function addEventListener(name, listener) {
-        this._listeners.push(listener);
-      }
-    }, {
-      key: 'removeEventListener',
-      value: function removeEventListener(name, listener) {
-        var i = this._listeners.indexOf(listener);
-        this._listeners.splice(i, 1);
-      }
-    }, {
-      key: 'terminate',
-      value: function terminate() {
-        this._listeners = [];
-      }
-    }]);
-
-    return FakePort;
-  }();
+function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
 
+describe('message_handler', function () {
   function sleep(ticks) {
     return Promise.resolve().then(function () {
       return ticks && sleep(ticks - 1);
     });
   }
+
   describe('sendWithStream', function () {
     it('should return a ReadableStream', function () {
-      var port = new FakePort();
-      var messageHandler1 = new _util.MessageHandler('main', 'worker', port);
+      var port = new _api.LoopbackPort();
+      var messageHandler1 = new _message_handler.MessageHandler('main', 'worker', port);
       var readable = messageHandler1.sendWithStream('fakeHandler');
-      expect(typeof readable === 'undefined' ? 'undefined' : _typeof(readable)).toEqual('object');
+      expect(_typeof(readable)).toEqual('object');
       expect(_typeof(readable.getReader)).toEqual('function');
     });
     it('should read using a reader', function (done) {
       var log = '';
-      var port = new FakePort();
-      var messageHandler1 = new _util.MessageHandler('main', 'worker', port);
-      var messageHandler2 = new _util.MessageHandler('worker', 'main', port);
+      var port = new _api.LoopbackPort();
+      var messageHandler1 = new _message_handler.MessageHandler('main', 'worker', port);
+      var messageHandler2 = new _message_handler.MessageHandler('worker', 'main', port);
       messageHandler2.on('fakeHandler', function (data, sink) {
         sink.onPull = function () {
           log += 'p';
         };
+
         sink.onCancel = function (reason) {
           log += 'c';
         };
+
         sink.ready.then(function () {
           sink.enqueue('hi');
           return sink.ready;
@@ -129,15 +91,17 @@ describe('util_stream', function () {
     });
     it('should not read any data when cancelled', function (done) {
       var log = '';
-      var port = new FakePort();
-      var messageHandler2 = new _util.MessageHandler('worker', 'main', port);
+      var port = new _api.LoopbackPort();
+      var messageHandler2 = new _message_handler.MessageHandler('worker', 'main', port);
       messageHandler2.on('fakeHandler', function (data, sink) {
         sink.onPull = function () {
           log += 'p';
         };
+
         sink.onCancel = function (reason) {
           log += 'c';
         };
+
         log += '0';
         sink.ready.then(function () {
           log += '1';
@@ -154,7 +118,7 @@ describe('util_stream', function () {
           log += '4';
         });
       });
-      var messageHandler1 = new _util.MessageHandler('main', 'worker', port);
+      var messageHandler1 = new _message_handler.MessageHandler('main', 'worker', port);
       var readable = messageHandler1.sendWithStream('fakeHandler', {}, {
         highWaterMark: 4,
         size: function size(arr) {
@@ -179,15 +143,17 @@ describe('util_stream', function () {
     });
     it('should not read when errored', function (done) {
       var log = '';
-      var port = new FakePort();
-      var messageHandler2 = new _util.MessageHandler('worker', 'main', port);
+      var port = new _api.LoopbackPort();
+      var messageHandler2 = new _message_handler.MessageHandler('worker', 'main', port);
       messageHandler2.on('fakeHandler', function (data, sink) {
         sink.onPull = function () {
           log += 'p';
         };
+
         sink.onCancel = function (reason) {
           log += 'c';
         };
+
         sink.ready.then(function () {
           sink.enqueue([1, 2, 3, 4], 4);
           return sink.ready;
@@ -196,7 +162,7 @@ describe('util_stream', function () {
           sink.error('error');
         });
       });
-      var messageHandler1 = new _util.MessageHandler('main', 'worker', port);
+      var messageHandler1 = new _message_handler.MessageHandler('main', 'worker', port);
       var readable = messageHandler1.sendWithStream('fakeHandler', {}, {
         highWaterMark: 4,
         size: function size(arr) {
@@ -218,15 +184,17 @@ describe('util_stream', function () {
     });
     it('should read data with blocking promise', function (done) {
       var log = '';
-      var port = new FakePort();
-      var messageHandler2 = new _util.MessageHandler('worker', 'main', port);
+      var port = new _api.LoopbackPort();
+      var messageHandler2 = new _message_handler.MessageHandler('worker', 'main', port);
       messageHandler2.on('fakeHandler', function (data, sink) {
         sink.onPull = function () {
           log += 'p';
         };
+
         sink.onCancel = function (reason) {
           log += 'c';
         };
+
         log += '0';
         sink.ready.then(function () {
           log += '1';
@@ -240,7 +208,7 @@ describe('util_stream', function () {
           sink.close();
         });
       });
-      var messageHandler1 = new _util.MessageHandler('main', 'worker', port);
+      var messageHandler1 = new _message_handler.MessageHandler('main', 'worker', port);
       var readable = messageHandler1.sendWithStream('fakeHandler', {}, {
         highWaterMark: 4,
         size: function size(arr) {
@@ -273,15 +241,17 @@ describe('util_stream', function () {
     });
     it('should read data with blocking promise and buffer whole data' + ' into stream', function (done) {
       var log = '';
-      var port = new FakePort();
-      var messageHandler2 = new _util.MessageHandler('worker', 'main', port);
+      var port = new _api.LoopbackPort();
+      var messageHandler2 = new _message_handler.MessageHandler('worker', 'main', port);
       messageHandler2.on('fakeHandler', function (data, sink) {
         sink.onPull = function () {
           log += 'p';
         };
+
         sink.onCancel = function (reason) {
           log += 'c';
         };
+
         log += '0';
         sink.ready.then(function () {
           log += '1';
@@ -296,7 +266,7 @@ describe('util_stream', function () {
         });
         return sleep(10);
       });
-      var messageHandler1 = new _util.MessageHandler('main', 'worker', port);
+      var messageHandler1 = new _message_handler.MessageHandler('main', 'worker', port);
       var readable = messageHandler1.sendWithStream('fakeHandler', {}, {
         highWaterMark: 8,
         size: function size(arr) {
@@ -329,16 +299,18 @@ describe('util_stream', function () {
     });
     it('should ignore any pull after close is called', function (done) {
       var log = '';
-      var port = new FakePort();
+      var port = new _api.LoopbackPort();
       var capability = (0, _util.createPromiseCapability)();
-      var messageHandler2 = new _util.MessageHandler('worker', 'main', port);
+      var messageHandler2 = new _message_handler.MessageHandler('worker', 'main', port);
       messageHandler2.on('fakeHandler', function (data, sink) {
         sink.onPull = function () {
           log += 'p';
         };
+
         sink.onCancel = function (reason) {
           log += 'c';
         };
+
         log += '0';
         sink.ready.then(function () {
           log += '1';
@@ -348,7 +320,7 @@ describe('util_stream', function () {
           sink.close();
         });
       });
-      var messageHandler1 = new _util.MessageHandler('main', 'worker', port);
+      var messageHandler1 = new _message_handler.MessageHandler('main', 'worker', port);
       var readable = messageHandler1.sendWithStream('fakeHandler', {}, {
         highWaterMark: 10,
         size: function size(arr) {

+ 71 - 11
lib/test/unit/metadata_spec.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,32 +19,38 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
-var _metadata = require('../../display/metadata');
+var _util = require("../../shared/util");
+
+var _metadata = require("../../display/metadata");
 
 describe('metadata', function () {
   it('should handle valid metadata', function () {
-    var validData = '<x:xmpmeta xmlns:x=\'adobe:ns:meta/\'>' + '<rdf:RDF xmlns:rdf=\'http://www.w3.org/1999/02/22-rdf-syntax-ns#\'>' + '<rdf:Description xmlns:dc=\'http://purl.org/dc/elements/1.1/\'>' + '<dc:title><rdf:Alt><rdf:li xml:lang="x-default">Foo bar baz</rdf:li>' + '</rdf:Alt></dc:title></rdf:Description></rdf:RDF></x:xmpmeta>';
-    var metadata = new _metadata.Metadata(validData);
+    var data = '<x:xmpmeta xmlns:x=\'adobe:ns:meta/\'>' + '<rdf:RDF xmlns:rdf=\'http://www.w3.org/1999/02/22-rdf-syntax-ns#\'>' + '<rdf:Description xmlns:dc=\'http://purl.org/dc/elements/1.1/\'>' + '<dc:title><rdf:Alt><rdf:li xml:lang="x-default">Foo bar baz</rdf:li>' + '</rdf:Alt></dc:title></rdf:Description></rdf:RDF></x:xmpmeta>';
+    var metadata = new _metadata.Metadata(data);
     expect(metadata.has('dc:title')).toBeTruthy();
     expect(metadata.has('dc:qux')).toBeFalsy();
     expect(metadata.get('dc:title')).toEqual('Foo bar baz');
     expect(metadata.get('dc:qux')).toEqual(null);
-    expect(metadata.getAll()).toEqual({ 'dc:title': 'Foo bar baz' });
+    expect(metadata.getAll()).toEqual({
+      'dc:title': 'Foo bar baz'
+    });
   });
   it('should repair and handle invalid metadata', function () {
-    var invalidData = '<x:xmpmeta xmlns:x=\'adobe:ns:meta/\'>' + '<rdf:RDF xmlns:rdf=\'http://www.w3.org/1999/02/22-rdf-syntax-ns#\'>' + '<rdf:Description xmlns:dc=\'http://purl.org/dc/elements/1.1/\'>' + '<dc:title>\\376\\377\\000P\\000D\\000F\\000&</dc:title>' + '</rdf:Description></rdf:RDF></x:xmpmeta>';
-    var metadata = new _metadata.Metadata(invalidData);
+    var data = '<x:xmpmeta xmlns:x=\'adobe:ns:meta/\'>' + '<rdf:RDF xmlns:rdf=\'http://www.w3.org/1999/02/22-rdf-syntax-ns#\'>' + '<rdf:Description xmlns:dc=\'http://purl.org/dc/elements/1.1/\'>' + '<dc:title>\\376\\377\\000P\\000D\\000F\\000&</dc:title>' + '</rdf:Description></rdf:RDF></x:xmpmeta>';
+    var metadata = new _metadata.Metadata(data);
     expect(metadata.has('dc:title')).toBeTruthy();
     expect(metadata.has('dc:qux')).toBeFalsy();
     expect(metadata.get('dc:title')).toEqual('PDF&');
     expect(metadata.get('dc:qux')).toEqual(null);
-    expect(metadata.getAll()).toEqual({ 'dc:title': 'PDF&' });
+    expect(metadata.getAll()).toEqual({
+      'dc:title': 'PDF&'
+    });
   });
   it('should repair and handle invalid metadata (bug 1424938)', function () {
-    var invalidData = '<x:xmpmeta xmlns:x=\'adobe:ns:meta/\' ' + 'x:xmptk=\'XMP toolkit 2.9.1-13, framework 1.6\'>' + '<rdf:RDF xmlns:rdf=\'http://www.w3.org/1999/02/22-rdf-syntax-ns#\' ' + 'xmlns:iX=\'http://ns.adobe.com/iX/1.0/\'>' + '<rdf:Description rdf:about=\'61652fa7-fc1f-11dd-0000-ce81d41f9ecf\' ' + 'xmlns:pdf=\'http://ns.adobe.com/pdf/1.3/\' ' + 'pdf:Producer=\'GPL Ghostscript 8.63\'/>' + '<rdf:Description rdf:about=\'61652fa7-fc1f-11dd-0000-ce81d41f9ecf\' ' + 'xmlns:xap=\'http://ns.adobe.com/xap/1.0/\' ' + 'xap:ModifyDate=\'2009-02-13T12:42:54+01:00\' ' + 'xap:CreateDate=\'2009-02-13T12:42:54+01:00\'>' + '<xap:CreatorTool>\\376\\377\\000P\\000D\\000F\\000C\\000r\\000e\\000a' + '\\000t\\000o\\000r\\000 \\000V\\000e\\000r\\000s\\000i\\000o\\000n' + '\\000 \\0000\\000.\\0009\\000.\\0006</xap:CreatorTool>' + '</rdf:Description><rdf:Description ' + 'rdf:about=\'61652fa7-fc1f-11dd-0000-ce81d41f9ecf\' ' + 'xmlns:xapMM=\'http://ns.adobe.com/xap/1.0/mm/\' ' + 'xapMM:DocumentID=\'61652fa7-fc1f-11dd-0000-ce81d41f9ecf\'/>' + '<rdf:Description rdf:about=\'61652fa7-fc1f-11dd-0000-ce81d41f9ecf\' ' + 'xmlns:dc=\'http://purl.org/dc/elements/1.1/\' ' + 'dc:format=\'application/pdf\'><dc:title><rdf:Alt>' + '<rdf:li xml:lang=\'x-default\'>\\376\\377\\000L\\000&apos;\\000O\\000d' + '\\000i\\000s\\000s\\000e\\000e\\000 \\000t\\000h\\000\\351\\000m\\000a' + '\\000t\\000i\\000q\\000u\\000e\\000 \\000l\\000o\\000g\\000o\\000 ' + '\\000O\\000d\\000i\\000s\\000s\\000\\351\\000\\351\\000 \\000-\\000 ' + '\\000d\\000\\351\\000c\\000e\\000m\\000b\\000r\\000e\\000 \\0002\\0000' + '\\0000\\0008\\000.\\000p\\000u\\000b</rdf:li></rdf:Alt></dc:title>' + '<dc:creator><rdf:Seq><rdf:li>\\376\\377\\000O\\000D\\000I\\000S' + '</rdf:li></rdf:Seq></dc:creator></rdf:Description></rdf:RDF>' + '</x:xmpmeta>';
-    var metadata = new _metadata.Metadata(invalidData);
+    var data = '<x:xmpmeta xmlns:x=\'adobe:ns:meta/\' ' + 'x:xmptk=\'XMP toolkit 2.9.1-13, framework 1.6\'>' + '<rdf:RDF xmlns:rdf=\'http://www.w3.org/1999/02/22-rdf-syntax-ns#\' ' + 'xmlns:iX=\'http://ns.adobe.com/iX/1.0/\'>' + '<rdf:Description rdf:about=\'61652fa7-fc1f-11dd-0000-ce81d41f9ecf\' ' + 'xmlns:pdf=\'http://ns.adobe.com/pdf/1.3/\' ' + 'pdf:Producer=\'GPL Ghostscript 8.63\'/>' + '<rdf:Description rdf:about=\'61652fa7-fc1f-11dd-0000-ce81d41f9ecf\' ' + 'xmlns:xap=\'http://ns.adobe.com/xap/1.0/\' ' + 'xap:ModifyDate=\'2009-02-13T12:42:54+01:00\' ' + 'xap:CreateDate=\'2009-02-13T12:42:54+01:00\'>' + '<xap:CreatorTool>\\376\\377\\000P\\000D\\000F\\000C\\000r\\000e\\000a' + '\\000t\\000o\\000r\\000 \\000V\\000e\\000r\\000s\\000i\\000o\\000n' + '\\000 \\0000\\000.\\0009\\000.\\0006</xap:CreatorTool>' + '</rdf:Description><rdf:Description ' + 'rdf:about=\'61652fa7-fc1f-11dd-0000-ce81d41f9ecf\' ' + 'xmlns:xapMM=\'http://ns.adobe.com/xap/1.0/mm/\' ' + 'xapMM:DocumentID=\'61652fa7-fc1f-11dd-0000-ce81d41f9ecf\'/>' + '<rdf:Description rdf:about=\'61652fa7-fc1f-11dd-0000-ce81d41f9ecf\' ' + 'xmlns:dc=\'http://purl.org/dc/elements/1.1/\' ' + 'dc:format=\'application/pdf\'><dc:title><rdf:Alt>' + '<rdf:li xml:lang=\'x-default\'>\\376\\377\\000L\\000&apos;\\000O\\000d' + '\\000i\\000s\\000s\\000e\\000e\\000 \\000t\\000h\\000\\351\\000m\\000a' + '\\000t\\000i\\000q\\000u\\000e\\000 \\000l\\000o\\000g\\000o\\000 ' + '\\000O\\000d\\000i\\000s\\000s\\000\\351\\000\\351\\000 \\000-\\000 ' + '\\000d\\000\\351\\000c\\000e\\000m\\000b\\000r\\000e\\000 \\0002\\0000' + '\\0000\\0008\\000.\\000p\\000u\\000b</rdf:li></rdf:Alt></dc:title>' + '<dc:creator><rdf:Seq><rdf:li>\\376\\377\\000O\\000D\\000I\\000S' + '</rdf:li></rdf:Seq></dc:creator></rdf:Description></rdf:RDF>' + '</x:xmpmeta>';
+    var metadata = new _metadata.Metadata(data);
     expect(metadata.has('dc:title')).toBeTruthy();
     expect(metadata.has('dc:qux')).toBeFalsy();
     expect(metadata.get('dc:title')).toEqual('L\'Odissee thématique logo Odisséé - décembre 2008.pub');
@@ -55,4 +61,58 @@ describe('metadata', function () {
       'xap:creatortool': 'PDFCreator Version 0.9.6'
     });
   });
+  it('should gracefully handle incomplete tags (issue 8884)', function () {
+    var data = '<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d' + '<x:xmpmeta xmlns:x="adobe:ns:meta/">' + '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">' + '<rdf:Description rdf:about=""' + 'xmlns:pdfx="http://ns.adobe.com/pdfx/1.3/">' + '</rdf:Description>' + '<rdf:Description rdf:about=""' + 'xmlns:xap="http://ns.adobe.com/xap/1.0/">' + '<xap:ModifyDate>2010-03-25T11:20:09-04:00</xap:ModifyDate>' + '<xap:CreateDate>2010-03-25T11:20:09-04:00</xap:CreateDate>' + '<xap:MetadataDate>2010-03-25T11:20:09-04:00</xap:MetadataDate>' + '</rdf:Description>' + '<rdf:Description rdf:about=""' + 'xmlns:dc="http://purl.org/dc/elements/1.1/">' + '<dc:format>application/pdf</dc:format>' + '</rdf:Description>' + '<rdf:Description rdf:about=""' + 'xmlns:pdfaid="http://www.aiim.org/pdfa/ns/id/">' + '<pdfaid:part>1</pdfaid:part>' + '<pdfaid:conformance>A</pdfaid:conformance>' + '</rdf:Description>' + '</rdf:RDF>' + '</x:xmpmeta>' + '<?xpacket end="w"?>';
+    var metadata = new _metadata.Metadata(data);
+    expect((0, _util.isEmptyObj)(metadata.getAll())).toEqual(true);
+  });
+  it('should gracefully handle "junk" before the actual metadata (issue 10395)', function () {
+    var data = '<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>' + '<x:xmpmeta x:xmptk="TallComponents PDFObjects 1.0" ' + 'xmlns:x="adobe:ns:meta/">' + '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">' + '<rdf:Description rdf:about="" ' + 'xmlns:pdf="http://ns.adobe.com/pdf/1.3/">' + '<pdf:Producer>PDFKit.NET 4.0.102.0</pdf:Producer>' + '<pdf:Keywords></pdf:Keywords>' + '<pdf:PDFVersion>1.7</pdf:PDFVersion></rdf:Description>' + '<rdf:Description rdf:about="" ' + 'xmlns:xap="http://ns.adobe.com/xap/1.0/">' + '<xap:CreateDate>2018-12-27T13:50:36-08:00</xap:CreateDate>' + '<xap:ModifyDate>2018-12-27T13:50:38-08:00</xap:ModifyDate>' + '<xap:CreatorTool></xap:CreatorTool>' + '<xap:MetadataDate>2018-12-27T13:50:38-08:00</xap:MetadataDate>' + '</rdf:Description><rdf:Description rdf:about="" ' + 'xmlns:dc="http://purl.org/dc/elements/1.1/">' + '<dc:creator><rdf:Seq><rdf:li></rdf:li></rdf:Seq></dc:creator>' + '<dc:subject><rdf:Bag /></dc:subject>' + '<dc:description><rdf:Alt><rdf:li xml:lang="x-default">' + '</rdf:li></rdf:Alt></dc:description>' + '<dc:title><rdf:Alt><rdf:li xml:lang="x-default"></rdf:li>' + '</rdf:Alt></dc:title><dc:format>application/pdf</dc:format>' + '</rdf:Description></rdf:RDF></x:xmpmeta><?xpacket end="w"?>';
+    var metadata = new _metadata.Metadata(data);
+    expect(metadata.has('dc:title')).toBeTruthy();
+    expect(metadata.has('dc:qux')).toBeFalsy();
+    expect(metadata.get('dc:title')).toEqual('');
+    expect(metadata.get('dc:qux')).toEqual(null);
+    expect(metadata.getAll()).toEqual({
+      'dc:creator': '',
+      'dc:description': '',
+      'dc:format': 'application/pdf',
+      'dc:subject': '',
+      'dc:title': '',
+      'pdf:keywords': '',
+      'pdf:pdfversion': '1.7',
+      'pdf:producer': 'PDFKit.NET 4.0.102.0',
+      'xap:createdate': '2018-12-27T13:50:36-08:00',
+      'xap:creatortool': '',
+      'xap:metadatadate': '2018-12-27T13:50:38-08:00',
+      'xap:modifydate': '2018-12-27T13:50:38-08:00'
+    });
+  });
+  it('should correctly handle metadata containing "&apos" (issue 10407)', function () {
+    var data = '<x:xmpmeta xmlns:x=\'adobe:ns:meta/\'>' + '<rdf:RDF xmlns:rdf=\'http://www.w3.org/1999/02/22-rdf-syntax-ns#\'>' + '<rdf:Description xmlns:dc=\'http://purl.org/dc/elements/1.1/\'>' + '<dc:title><rdf:Alt>' + '<rdf:li xml:lang="x-default">&apos;Foo bar baz&apos;</rdf:li>' + '</rdf:Alt></dc:title></rdf:Description></rdf:RDF></x:xmpmeta>';
+    var metadata = new _metadata.Metadata(data);
+    expect(metadata.has('dc:title')).toBeTruthy();
+    expect(metadata.has('dc:qux')).toBeFalsy();
+    expect(metadata.get('dc:title')).toEqual('\'Foo bar baz\'');
+    expect(metadata.get('dc:qux')).toEqual(null);
+    expect(metadata.getAll()).toEqual({
+      'dc:title': '\'Foo bar baz\''
+    });
+  });
+  it('should gracefully handle unbalanced end tags (issue 10410)', function () {
+    var data = '<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>' + '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">' + '<rdf:Description rdf:about="" ' + 'xmlns:pdf="http://ns.adobe.com/pdf/1.3/">' + '<pdf:Producer>Soda PDF 5</pdf:Producer></rdf:Description>' + '<rdf:Description rdf:about="" ' + 'xmlns:xap="http://ns.adobe.com/xap/1.0/">' + '<xap:CreateDate>2018-10-02T08:14:49-05:00</xap:CreateDate>' + '<xap:CreatorTool>Soda PDF 5</xap:CreatorTool>' + '<xap:MetadataDate>2018-10-02T08:14:49-05:00</xap:MetadataDate> ' + '<xap:ModifyDate>2018-10-02T08:14:49-05:00</xap:ModifyDate>' + '</rdf:Description><rdf:Description rdf:about="" ' + 'xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/">' + '<xmpMM:DocumentID>uuid:00000000-1c84-3cf9-89ba-bef0e729c831' + '</xmpMM:DocumentID></rdf:Description>' + '</rdf:RDF></x:xmpmeta><?xpacket end="w"?>';
+    var metadata = new _metadata.Metadata(data);
+    expect((0, _util.isEmptyObj)(metadata.getAll())).toEqual(true);
+  });
+  it('should not be vulnerable to the billion laughs attack', function () {
+    var data = '<?xml version="1.0"?>' + '<!DOCTYPE lolz [' + '  <!ENTITY lol "lol">' + '  <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">' + '  <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">' + '  <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">' + '  <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">' + '  <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">' + '  <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">' + '  <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">' + '  <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">' + '  <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">' + ']>' + '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">' + '  <rdf:Description xmlns:dc="http://purl.org/dc/elements/1.1/">' + '    <dc:title>' + '      <rdf:Alt>' + '        <rdf:li xml:lang="x-default">a&lol9;b</rdf:li>' + '      </rdf:Alt>' + '    </dc:title>' + '  </rdf:Description>' + '</rdf:RDF>';
+    var metadata = new _metadata.Metadata(data);
+    expect(metadata.has('dc:title')).toBeTruthy();
+    expect(metadata.has('dc:qux')).toBeFalsy();
+    expect(metadata.get('dc:title')).toEqual('a&lol9;b');
+    expect(metadata.get('dc:qux')).toEqual(null);
+    expect(metadata.getAll()).toEqual({
+      'dc:title': 'a&lol9;b'
+    });
+  });
 });

+ 3 - 3
lib/test/unit/murmurhash3_spec.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,9 +19,9 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
-var _murmurhash = require('../../core/murmurhash3');
+var _murmurhash = require("../../core/murmurhash3");
 
 describe('MurmurHash3_64', function () {
   it('instantiates without seed', function () {

+ 20 - 5
lib/test/unit/network_spec.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2017 Mozilla Foundation
+ * Copyright 2018 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,9 +19,9 @@
  * @licend The above is the entire license notice for the
  * Javascript code in this page
  */
-'use strict';
+"use strict";
 
-var _network = require('../../display/network');
+var _network = require("../../display/network");
 
 describe('network', function () {
   var pdf1 = new URL('../pdfs/tracemonkey.pdf', window.location).href;
@@ -43,16 +43,19 @@ describe('network', function () {
     });
     var len = 0,
         count = 0;
+
     var read = function read() {
       return fullReader.read().then(function (result) {
         if (result.done) {
           return;
         }
+
         count++;
         len += result.value.byteLength;
         return read();
       });
     };
+
     var readPromise = Promise.all([read(), promise]);
     readPromise.then(function (page) {
       expect(len).toEqual(pdf1Length);
@@ -67,11 +70,13 @@ describe('network', function () {
   it('read with streaming', function (done) {
     var userAgent = window.navigator.userAgent;
     var m = /Mozilla\/5.0.*?rv:(\d+).*? Gecko/.exec(userAgent);
+
     if (!m || m[1] < 9) {
       expect(true).toEqual(true);
       done();
       return;
     }
+
     var stream = new _network.PDFNetworkStream({
       url: pdf2,
       rangeChunkSize: 65536,
@@ -86,16 +91,19 @@ describe('network', function () {
     });
     var len = 0,
         count = 0;
+
     var read = function read() {
       return fullReader.read().then(function (result) {
         if (result.done) {
           return;
         }
+
         count++;
         len += result.value.byteLength;
         return read();
       });
     };
+
     var readPromise = Promise.all([read(), promise]);
     readPromise.then(function () {
       expect(len).toEqual(pdf2Length);
@@ -127,17 +135,24 @@ describe('network', function () {
     var tailSize = pdf1Length % rangeSize || rangeSize;
     var range1Reader = stream.getRangeReader(pdf1Length - tailSize - rangeSize, pdf1Length - tailSize);
     var range2Reader = stream.getRangeReader(pdf1Length - tailSize, pdf1Length);
-    var result1 = { value: 0 },
-        result2 = { value: 0 };
+    var result1 = {
+      value: 0
+    },
+        result2 = {
+      value: 0
+    };
+
     var read = function read(reader, lenResult) {
       return reader.read().then(function (result) {
         if (result.done) {
           return;
         }
+
         lenResult.value += result.value.byteLength;
         return read(reader, lenResult);
       });
     };
+
     var readPromises = Promise.all([read(range1Reader, result1), read(range2Reader, result2), promise]);
     readPromises.then(function () {
       expect(result1.value).toEqual(rangeSize);

Some files were not shown because too many files changed in this diff