Merge inbound to mozilla-central. a=merge FIREFOX_NIGHTLY_62_END
authorCiure Andrei <aciure@mozilla.com>
Mon, 25 Jun 2018 12:49:17 +0300
changeset 810123 4f6e597104dabedfecfafa2ab63dc79fd7f8bc7a
parent 810122 14b72cf25160bc6e5849d5d97dd7f030ae5fb6ae (current diff)
parent 810094 6d0dcae0268b98e9c43bbed077502a51afed2311 (diff)
child 810124 b6b7aa28be536b08defb762465ffe24244171fb6
child 810127 52597940e0a1e27dad27dd30a94eb01027b6c75d
child 810214 1ae781567f82c55392d332f443e080700d26a2d6
child 810219 1ac623de80021eea0c5cb6a124da59b735c8abf5
child 810224 f91e4bb5610c8a68cd44b4f81e9872fac5854b85
child 810233 1677bc0674a3589d2310d6bb06e531f386d69e4b
child 810249 9887077d05f0ff93f8421541edf64129e627d470
child 810268 0b7baeee5cb62484c5a7412b96ee7e1ceabce35f
child 810277 e1b335c96362d0aa736d1c2fb9ad373c4f36f9d5
child 810280 63f8cca476e570b5e88de8df5fad9cea24766869
child 810287 1716b76aa7b8df189e74bf87394d3a11e0c5ac12
child 810296 f13c8767c4dd52dfb7c92a0e0d9d88d7822a9ad4
child 810300 d7225291d86c47ee6628b050353f32d01c15c39d
child 810304 d398014d19e7c37dfe10b8bb0e1dd4c240524233
child 810357 5d7823a838dea17e202c077ebd1a80ad863996bb
child 810399 9990e9b1468f736fa90cd85f90cab72d39f888c9
child 810433 4281bf0eebb949d4065fefed78e81db4456c46d3
child 810441 74392304f1a07f7e2d10e586f4606c1814514dde
child 810636 2af1ae7dabe7def014696aeb1dc78bd94452d02e
child 810638 a5d5e3cb15698716f4d3de18fbcfdcddf07eb3d8
child 810750 c91b345169d1edbe17508be65a0e5296a7f22995
child 810751 d72088c6d200cfdd38d59506055b6a632ece5bcc
child 810768 78cfced973e8825bbd90a832f60a3887cd725711
child 810769 99ffe21a35c7f1142ff645daf9e89db9a56a600e
child 810770 5552c21c5f2a4eee18e80131b0d897d82f12126a
child 810771 8c422ab7b3c73707453706342298153874fc5925
child 810791 9650f79154a92add64775fe79575e87693daa7d7
child 810897 0c7d25fc03d0cc9e7496225b2d140695dc1d11a6
child 811203 28b46ea8793ba76851c49e7aa59b895f32f01573
child 811208 59d7e841143bd21d4c0328d6d3e5a0e7171722c2
child 811209 7908d8621e9888e1e9654c7de03a20781dd0ddea
child 811210 e30d75e6ca50e798a11b7cb59ef2658f9921212e
child 811217 d5d0c60014199da544893003036fa3371b440c00
child 812168 99268a0d5f0e764411764d6494aeb6f62e824611
child 812169 e63d7a2b3193cfd33998d17175fa6c2ee18d8c9a
child 812473 9b93e0e2bb93a13eda0422650c694e66921430f3
child 812475 6a892dedd32d3707a3b7543f3623f6990e9c1cf2
child 813127 3aa1c9cd7ef379031cc02da77a0436b1bf36ef1b
child 813139 7c450980a3e8697b36ed44d83e91a46797efe850
child 813170 b172f3e778e38bb9250fad0d72fbb12eb602c5eb
child 813236 78404f390a0706d474184992c3f097f0adde7b3e
child 814091 49e979db71747693004170e69fc3fdc6569def4c
child 814556 b2ea01b5b545ea6fbef0cae90edc333c9b80919d
child 815624 de31b7bcc823aeece023dc401716ef07f60807c9
child 815626 203c3b3de60dd0ccdd5ff353304606d01b6290da
push id113899
push userbmo:hsivonen@hsivonen.fi
push dateMon, 25 Jun 2018 11:22:01 +0000
reviewersmerge
milestone62.0a1
Merge inbound to mozilla-central. a=merge
--- a/browser/extensions/pdfjs/README.mozilla
+++ b/browser/extensions/pdfjs/README.mozilla
@@ -1,5 +1,5 @@
 This is the PDF.js project output, https://github.com/mozilla/pdf.js
 
-Current extension version is: 2.0.602
+Current extension version is: 2.0.625
 
-Taken from upstream commit: 3b07147d
+Taken from upstream commit: e8b50883
--- a/browser/extensions/pdfjs/content/build/pdf.js
+++ b/browser/extensions/pdfjs/content/build/pdf.js
@@ -118,18 +118,18 @@ return /******/ (function(modules) { // 
 /************************************************************************/
 /******/ ([
 /* 0 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
 
 
-var pdfjsVersion = '2.0.602';
-var pdfjsBuild = '3b07147d';
+var pdfjsVersion = '2.0.625';
+var pdfjsBuild = 'e8b50883';
 var pdfjsSharedUtil = __w_pdfjs_require__(1);
 var pdfjsDisplayAPI = __w_pdfjs_require__(6);
 var pdfjsDisplayTextLayer = __w_pdfjs_require__(18);
 var pdfjsDisplayAnnotationLayer = __w_pdfjs_require__(19);
 var pdfjsDisplayDOMUtils = __w_pdfjs_require__(7);
 var pdfjsDisplaySVG = __w_pdfjs_require__(20);
 let pdfjsDisplayWorkerOptions = __w_pdfjs_require__(12);
 let pdfjsDisplayAPICompatibility = __w_pdfjs_require__(9);
@@ -820,21 +820,16 @@ var Util = function UtilClosure() {
     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.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];
     }
   };
   return Util;
@@ -4150,20 +4145,20 @@ function getDocument(src) {
   }
   if (typeof params.isEvalSupported !== 'boolean') {
     params.isEvalSupported = true;
   }
   if (typeof params.disableFontFace !== 'boolean') {
     params.disableFontFace = _api_compatibility.apiCompatibilityParams.disableFontFace || false;
   }
   if (typeof params.disableRange !== 'boolean') {
-    params.disableRange = _api_compatibility.apiCompatibilityParams.disableRange || false;
+    params.disableRange = false;
   }
   if (typeof params.disableStream !== 'boolean') {
-    params.disableStream = _api_compatibility.apiCompatibilityParams.disableStream || false;
+    params.disableStream = false;
   }
   if (typeof params.disableAutoFetch !== 'boolean') {
     params.disableAutoFetch = false;
   }
   if (typeof params.disableCreateObjectURL !== 'boolean') {
     params.disableCreateObjectURL = _api_compatibility.apiCompatibilityParams.disableCreateObjectURL || false;
   }
   (0, _util.setVerbosityLevel)(params.verbosity);
@@ -4223,17 +4218,17 @@ function _fetchDocument(worker, source, 
     return Promise.reject(new Error('Worker was destroyed'));
   }
   if (pdfDataRangeTransport) {
     source.length = pdfDataRangeTransport.length;
     source.initialData = pdfDataRangeTransport.initialData;
   }
   return worker.messageHandler.sendWithPromise('GetDocRequest', {
     docId,
-    apiVersion: '2.0.602',
+    apiVersion: '2.0.625',
     source: {
       data: source.data,
       url: source.url,
       password: source.password,
       disableAutoFetch: source.disableAutoFetch,
       rangeChunkSize: source.rangeChunkSize,
       length: source.length
     },
@@ -4560,17 +4555,17 @@ var PDFPageProxy = function PDFPageProxy
       let readableStream = this.streamTextContent(params);
       return new Promise(function (resolve, reject) {
         function pump() {
           reader.read().then(function ({ value, done }) {
             if (done) {
               resolve(textContent);
               return;
             }
-            _util.Util.extendObj(textContent.styles, value.styles);
+            Object.assign(textContent.styles, value.styles);
             textContent.items.push(...value.items);
             pump();
           }, reject);
         }
         let reader = readableStream.getReader();
         let textContent = {
           items: [],
           styles: Object.create(null)
@@ -5357,18 +5352,16 @@ var WorkerTransport = function WorkerTra
         }
         this.commonObjs.clear();
         this.fontLoader.clear();
       });
     },
     get loadingParams() {
       let params = this._params;
       return (0, _util.shadow)(this, 'loadingParams', {
-        disableRange: params.disableRange,
-        disableStream: params.disableStream,
         disableAutoFetch: params.disableAutoFetch,
         disableCreateObjectURL: params.disableCreateObjectURL,
         disableFontFace: params.disableFontFace,
         nativeImageDecoderSupport: params.nativeImageDecoderSupport
       });
     }
   };
   return WorkerTransport;
@@ -5564,18 +5557,18 @@ var InternalRenderTask = function Intern
         }
       });
     }
   };
   return InternalRenderTask;
 }();
 var version, build;
 {
-  exports.version = version = '2.0.602';
-  exports.build = build = '3b07147d';
+  exports.version = version = '2.0.625';
+  exports.build = build = 'e8b50883';
 }
 exports.getDocument = getDocument;
 exports.LoopbackPort = LoopbackPort;
 exports.PDFDataRangeTransport = PDFDataRangeTransport;
 exports.PDFWorker = PDFWorker;
 exports.PDFDocumentProxy = PDFDocumentProxy;
 exports.PDFPageProxy = PDFPageProxy;
 exports.setPDFNetworkStreamFactory = setPDFNetworkStreamFactory;
@@ -10062,17 +10055,17 @@ var renderTextLayer = function renderTex
         capability.resolve();
       } else if (this._textContentStream) {
         let pump = () => {
           this._reader.read().then(({ value, done }) => {
             if (done) {
               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.');
--- a/browser/extensions/pdfjs/content/build/pdf.worker.js
+++ b/browser/extensions/pdfjs/content/build/pdf.worker.js
@@ -118,18 +118,18 @@ return /******/ (function(modules) { // 
 /************************************************************************/
 /******/ ([
 /* 0 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
 
 
-var pdfjsVersion = '2.0.602';
-var pdfjsBuild = '3b07147d';
+var pdfjsVersion = '2.0.625';
+var pdfjsBuild = 'e8b50883';
 var pdfjsCoreWorker = __w_pdfjs_require__(1);
 exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;
 
 /***/ }),
 /* 1 */
 /***/ (function(module, exports, __w_pdfjs_require__) {
 
 "use strict";
@@ -322,17 +322,17 @@ var WorkerMessageHandler = {
     });
   },
   createDocumentHandler(docParams, port) {
     var pdfManager;
     var terminated = false;
     var cancelXHRs = null;
     var WorkerTasks = [];
     let apiVersion = docParams.apiVersion;
-    let workerVersion = '2.0.602';
+    let workerVersion = '2.0.625';
     if (apiVersion !== workerVersion) {
       throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`);
     }
     var docId = docParams.docId;
     var docBaseUrl = docParams.docBaseUrl;
     var workerHandlerName = docParams.docId + '_worker';
     var handler = new _message_handler.MessageHandler(workerHandlerName, docId, port);
     handler.postMessageTransfers = docParams.postMessageTransfers;
@@ -1359,21 +1359,16 @@ var Util = function UtilClosure() {
     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.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];
     }
   };
   return Util;
@@ -6461,24 +6456,46 @@ var XRef = function XRefClosure() {
       if (!recoveryMode) {
         trailerDict = this.readXRef();
       } else {
         (0, _util.warn)('Indexing all PDF objects');
         trailerDict = this.indexObjects();
       }
       trailerDict.assignXref(this);
       this.trailer = trailerDict;
-      var encrypt = trailerDict.get('Encrypt');
+      let encrypt;
+      try {
+        encrypt = trailerDict.get('Encrypt');
+      } catch (ex) {
+        if (ex instanceof _util.MissingDataException) {
+          throw ex;
+        }
+        (0, _util.warn)(`XRef.parse - Invalid "Encrypt" reference: "${ex}".`);
+      }
       if ((0, _primitives.isDict)(encrypt)) {
         var ids = trailerDict.get('ID');
         var fileId = ids && ids.length ? ids[0] : '';
         encrypt.suppressEncryption = true;
         this.encrypt = new _crypto.CipherTransformFactory(encrypt, fileId, this.pdfManager.password);
       }
-      if (!(this.root = trailerDict.get('Root'))) {
+      let root;
+      try {
+        root = trailerDict.get('Root');
+      } catch (ex) {
+        if (ex instanceof _util.MissingDataException) {
+          throw ex;
+        }
+        (0, _util.warn)(`XRef.parse - Invalid "Root" reference: "${ex}".`);
+      }
+      if ((0, _primitives.isDict)(root) && root.has('Pages')) {
+        this.root = root;
+      } else {
+        if (!recoveryMode) {
+          throw new _util.XRefParseException();
+        }
         throw new _util.FormatError('Invalid root reference');
       }
     },
     processXRefTable: function XRef_processXRefTable(parser) {
       if (!('tableState' in this)) {
         this.tableState = {
           entryNum: 0,
           streamPos: parser.lexer.stream.pos,
@@ -6729,17 +6746,17 @@ var XRef = function XRefClosure() {
             } else {
               let objToken = nestedObjRegExp.exec(tokenStr);
               if (objToken && objToken[1]) {
                 (0, _util.warn)('indexObjects: Found new "obj" inside of another "obj", ' + 'caused by missing "endobj" -- trying to recover.');
                 contentLength -= objToken[1].length;
                 break;
               }
             }
-            startPos += contentLength;
+            startPos = endPos;
           }
           let content = buffer.subarray(position, position + contentLength);
           var xrefTagOffset = skipUntil(content, 0, xrefBytes);
           if (xrefTagOffset < contentLength && content[xrefTagOffset + 5] < 64) {
             xrefStms.push(position - stream.start);
             this.xrefstms[position - stream.start] = 1;
           }
           position += contentLength;
@@ -6750,34 +6767,47 @@ var XRef = function XRefClosure() {
           position += token.length + 1;
         }
       }
       var i, ii;
       for (i = 0, ii = xrefStms.length; i < ii; ++i) {
         this.startXRefQueue.push(xrefStms[i]);
         this.readXRef(true);
       }
-      var dict;
+      let trailerDict;
       for (i = 0, ii = trailers.length; i < ii; ++i) {
         stream.pos = trailers[i];
         var parser = new _parser.Parser(new _parser.Lexer(stream), true, this, true);
         var obj = parser.getObj();
         if (!(0, _primitives.isCmd)(obj, 'trailer')) {
           continue;
         }
-        dict = parser.getObj();
+        let dict = parser.getObj();
         if (!(0, _primitives.isDict)(dict)) {
           continue;
         }
+        let rootDict;
+        try {
+          rootDict = dict.get('Root');
+        } catch (ex) {
+          if (ex instanceof _util.MissingDataException) {
+            throw ex;
+          }
+          continue;
+        }
+        if (!(0, _primitives.isDict)(rootDict) || !rootDict.has('Pages')) {
+          continue;
+        }
         if (dict.has('ID')) {
           return dict;
         }
-      }
-      if (dict) {
-        return dict;
+        trailerDict = dict;
+      }
+      if (trailerDict) {
+        return trailerDict;
       }
       throw new _util.InvalidPDFException('Invalid PDF structure');
     },
     readXRef: function XRef_readXRef(recoveryMode) {
       var stream = this.stream;
       let startXRefParsedCache = Object.create(null);
       try {
         while (this.startXRefQueue.length) {
@@ -8110,38 +8140,44 @@ var Lexer = function LexerClosure() {
     },
     peekChar: function Lexer_peekChar() {
       return this.stream.peekByte();
     },
     getNumber: function Lexer_getNumber() {
       var ch = this.currentChar;
       var eNotation = false;
       var divideBy = 0;
-      var sign = 1;
+      var sign = 0;
       if (ch === 0x2D) {
         sign = -1;
         ch = this.nextChar();
         if (ch === 0x2D) {
           ch = this.nextChar();
         }
       } else if (ch === 0x2B) {
-        ch = this.nextChar();
-      }
-      if (ch === 0x2E) {
-        divideBy = 10;
+        sign = 1;
         ch = this.nextChar();
       }
       if (ch === 0x0A || ch === 0x0D) {
         do {
           ch = this.nextChar();
         } while (ch === 0x0A || ch === 0x0D);
       }
+      if (ch === 0x2E) {
+        divideBy = 10;
+        ch = this.nextChar();
+      }
       if (ch < 0x30 || ch > 0x39) {
+        if (divideBy === 10 && sign === 0 && ((0, _util.isSpace)(ch) || ch === -1)) {
+          (0, _util.warn)('Lexer.getNumber - treating a single decimal point as zero.');
+          return 0;
+        }
         throw new _util.FormatError(`Invalid number: ${String.fromCharCode(ch)} (charCode ${ch})`);
       }
+      sign = sign || 1;
       var baseValue = ch - 0x30;
       var powerValue = 0;
       var powerValueSign = 1;
       while ((ch = this.nextChar()) >= 0) {
         if (0x30 <= ch && ch <= 0x39) {
           var currentDigit = ch - 0x30;
           if (eNotation) {
             powerValue = powerValue * 10 + currentDigit;
@@ -18797,17 +18833,17 @@ var OperatorList = function OperatorList
       this.addOp(_util.OPS.dependency, [dependency]);
     },
     addDependencies(dependencies) {
       for (var key in dependencies) {
         this.addDependency(key);
       }
     },
     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]);
       }
     },
     getIR() {
       return {
         fnArray: this.fnArray,
         argsArray: this.argsArray,
--- a/browser/extensions/pdfjs/content/web/viewer.js
+++ b/browser/extensions/pdfjs/content/web/viewer.js
@@ -3201,20 +3201,16 @@ const defaultOptions = {
   externalLinkTarget: {
     value: 0,
     kind: OptionKind.VIEWER
   },
   imageResourcesPath: {
     value: './images/',
     kind: OptionKind.VIEWER
   },
-  locale: {
-    value: typeof navigator !== 'undefined' ? navigator.language : 'en-US',
-    kind: OptionKind.VIEWER
-  },
   maxCanvasPixels: {
     value: _viewer_compatibility.viewerCompatibilityParams.maxCanvasPixels || 16777216,
     kind: OptionKind.VIEWER
   },
   pdfBugEnabled: {
     value: false,
     kind: OptionKind.VIEWER
   },
@@ -3258,21 +3254,21 @@ const defaultOptions = {
     value: _pdfjsLib.apiCompatibilityParams.disableCreateObjectURL || false,
     kind: OptionKind.API
   },
   disableFontFace: {
     value: false,
     kind: OptionKind.API
   },
   disableRange: {
-    value: _pdfjsLib.apiCompatibilityParams.disableRange || false,
+    value: false,
     kind: OptionKind.API
   },
   disableStream: {
-    value: _pdfjsLib.apiCompatibilityParams.disableStream || false,
+    value: false,
     kind: OptionKind.API
   },
   isEvalSupported: {
     value: true,
     kind: OptionKind.API
   },
   maxImageSize: {
     value: -1,
@@ -3294,16 +3290,17 @@ const defaultOptions = {
     value: null,
     kind: OptionKind.WORKER
   },
   workerSrc: {
     value: '../build/pdf.worker.js',
     kind: OptionKind.WORKER
   }
 };
+;
 const userOptions = Object.create(null);
 class AppOptions {
   constructor() {
     throw new Error('Cannot initialize AppOptions.');
   }
   static get(name) {
     let defaultOption = defaultOptions[name],
         userOption = userOptions[name];
@@ -6344,17 +6341,17 @@ var _ui_utils = __webpack_require__(2);
 
 var _pdfjsLib = __webpack_require__(3);
 
 class PDFViewer extends _base_viewer.BaseViewer {
   get _setDocumentViewerElement() {
     return (0, _pdfjsLib.shadow)(this, '_setDocumentViewerElement', this.viewer);
   }
   _scrollIntoView({ pageDiv, pageSpot = null }) {
-    if (!pageSpot) {
+    if (!pageSpot && !this.isInPresentationMode) {
       const left = pageDiv.offsetLeft + pageDiv.clientLeft;
       const right = left + pageDiv.clientWidth;
       const { scrollLeft, clientWidth } = this.container;
       if (this.scrollMode === _base_viewer.ScrollMode.HORIZONTAL || left < scrollLeft || right > scrollLeft + clientWidth) {
         pageSpot = {
           left: 0,
           top: 0
         };
@@ -6405,37 +6402,79 @@ class PDFViewer extends _base_viewer.Bas
       this._setCurrentPageNumber(currentId);
     }
     this._updateLocation(visible.first);
     this.eventBus.dispatch('updateviewarea', {
       source: this,
       location: this._location
     });
   }
+  get _isScrollModeHorizontal() {
+    return this.isInPresentationMode ? false : this.scrollMode === _base_viewer.ScrollMode.HORIZONTAL;
+  }
+  setScrollMode(mode) {
+    if (mode === this.scrollMode) {
+      return;
+    }
+    super.setScrollMode(mode);
+    this.eventBus.dispatch('scrollmodechanged', { mode });
+    this._updateScrollModeClasses();
+    if (!this.pdfDocument) {
+      return;
+    }
+    const pageNumber = this._currentPageNumber;
+    if (isNaN(this._currentScaleValue)) {
+      this._setScale(this._currentScaleValue, true);
+    }
+    this.scrollPageIntoView({ pageNumber });
+    this.update();
+  }
+  _updateScrollModeClasses() {
+    const { scrollMode, viewer } = this;
+    if (scrollMode === _base_viewer.ScrollMode.HORIZONTAL) {
+      viewer.classList.add('scrollHorizontal');
+    } else {
+      viewer.classList.remove('scrollHorizontal');
+    }
+    if (scrollMode === _base_viewer.ScrollMode.WRAPPED) {
+      viewer.classList.add('scrollWrapped');
+    } else {
+      viewer.classList.remove('scrollWrapped');
+    }
+  }
+  setSpreadMode(mode) {
+    if (mode === this.spreadMode) {
+      return;
+    }
+    super.setSpreadMode(mode);
+    this.eventBus.dispatch('spreadmodechanged', { mode });
+    this._regroupSpreads();
+  }
   _regroupSpreads() {
-    const container = this._setDocumentViewerElement,
+    if (!this.pdfDocument) {
+      return;
+    }
+    const viewer = this.viewer,
           pages = this._pages;
-    while (container.firstChild) {
-      container.firstChild.remove();
-    }
+    viewer.textContent = '';
     if (this.spreadMode === _base_viewer.SpreadMode.NONE) {
       for (let i = 0, iMax = pages.length; i < iMax; ++i) {
-        container.appendChild(pages[i].div);
+        viewer.appendChild(pages[i].div);
       }
     } else {
       const parity = this.spreadMode - 1;
       let spread = null;
       for (let i = 0, iMax = pages.length; i < iMax; ++i) {
         if (spread === null) {
           spread = document.createElement('div');
           spread.className = 'spread';
-          container.appendChild(spread);
+          viewer.appendChild(spread);
         } else if (i % 2 === parity) {
           spread = spread.cloneNode(false);
-          container.appendChild(spread);
+          viewer.appendChild(spread);
         }
         spread.appendChild(pages[i].div);
       }
     }
     this.scrollPageIntoView({ pageNumber: this._currentPageNumber });
     this.update();
   }
 }
@@ -6549,17 +6588,19 @@ class BaseViewer {
       this.renderingQueue = options.renderingQueue;
     }
     this.scroll = (0, _ui_utils.watchScroll)(this.container, this._scrollUpdate.bind(this));
     this.presentationModeState = _ui_utils.PresentationModeState.UNKNOWN;
     this._resetView();
     if (this.removePageBorders) {
       this.viewer.classList.add('removePageBorders');
     }
-    this._updateScrollModeClasses();
+    if (this.scrollMode !== ScrollMode.VERTICAL) {
+      this._updateScrollModeClasses();
+    }
   }
   get pagesCount() {
     return this._pages.length;
   }
   getPageView(index) {
     return this._pages[index];
   }
   get pageViewsReady() {
@@ -6853,19 +6894,20 @@ class BaseViewer {
     let scale = parseFloat(value);
     if (scale > 0) {
       this._setScaleUpdatePages(scale, value, noScroll, false);
     } else {
       let currentPage = this._pages[this._currentPageNumber - 1];
       if (!currentPage) {
         return;
       }
-      let hPadding = this.isInPresentationMode || this.removePageBorders ? 0 : _ui_utils.SCROLLBAR_PADDING;
-      let vPadding = this.isInPresentationMode || this.removePageBorders ? 0 : _ui_utils.VERTICAL_PADDING;
-      if (this.scrollMode === ScrollMode.HORIZONTAL) {
+      const noPadding = this.isInPresentationMode || this.removePageBorders;
+      let hPadding = noPadding ? 0 : _ui_utils.SCROLLBAR_PADDING;
+      let vPadding = noPadding ? 0 : _ui_utils.VERTICAL_PADDING;
+      if (!noPadding && this._isScrollModeHorizontal) {
         const temp = hPadding;
         hPadding = vPadding;
         vPadding = temp;
       }
       let pageWidthScale = (this.container.clientWidth - hPadding) / currentPage.width * currentPage.scale;
       let pageHeightScale = (this.container.clientHeight - vPadding) / currentPage.height * currentPage.scale;
       switch (value) {
         case 'page-actual':
@@ -7025,16 +7067,19 @@ class BaseViewer {
     throw new Error('Not implemented: update');
   }
   containsElement(element) {
     return this.container.contains(element);
   }
   focus() {
     this.container.focus();
   }
+  get _isScrollModeHorizontal() {
+    throw new Error('Not implemented: _isScrollModeHorizontal');
+  }
   get isInPresentationMode() {
     return this.presentationModeState === _ui_utils.PresentationModeState.FULLSCREEN;
   }
   get isChangingPresentationMode() {
     return this.presentationModeState === _ui_utils.PresentationModeState.CHANGING;
   }
   get isHorizontalScrollbarEnabled() {
     return this.isInPresentationMode ? false : this.container.scrollWidth > this.container.clientWidth;
@@ -7077,17 +7122,17 @@ class BaseViewer {
       console.error('Unable to get page for page view', reason);
       this._pagesRequests[pageNumber] = null;
     });
     this._pagesRequests[pageNumber] = promise;
     return promise;
   }
   forceRendering(currentlyVisiblePages) {
     let visiblePages = currentlyVisiblePages || this._getVisiblePages();
-    let scrollAhead = this.scrollMode === ScrollMode.HORIZONTAL ? this.scroll.right : this.scroll.down;
+    let scrollAhead = this._isScrollModeHorizontal ? this.scroll.right : this.scroll.down;
     let pageView = this.renderingQueue.getHighestPriority(visiblePages, this._pages, scrollAhead);
     if (pageView) {
       this._ensurePdfPageLoaded(pageView).then(() => {
         this.renderingQueue.renderView(pageView);
       });
       return true;
     }
     return false;
@@ -7151,40 +7196,27 @@ class BaseViewer {
       return {
         width: size.height,
         height: size.width,
         rotation: (size.rotation + 90) % 360
       };
     });
   }
   setScrollMode(mode) {
-    if (mode !== this.scrollMode) {
-      this.scrollMode = mode;
-      this._updateScrollModeClasses();
-      this.eventBus.dispatch('scrollmodechanged', { mode });
-      const pageNumber = this._currentPageNumber;
-      if (isNaN(this._currentScaleValue)) {
-        this._setScale(this._currentScaleValue, this.isInPresentationMode);
-      }
-      this.scrollPageIntoView({ pageNumber });
-      this.update();
-    }
-  }
-  _updateScrollModeClasses() {
-    const mode = this.scrollMode,
-          { classList } = this.viewer;
-    classList.toggle('scrollHorizontal', mode === ScrollMode.HORIZONTAL);
-    classList.toggle('scrollWrapped', mode === ScrollMode.WRAPPED);
-  }
+    if (!Number.isInteger(mode) || !Object.values(ScrollMode).includes(mode)) {
+      throw new Error(`Invalid scroll mode: ${mode}`);
+    }
+    this.scrollMode = mode;
+  }
+  _updateScrollModeClasses() {}
   setSpreadMode(mode) {
-    if (mode !== this.spreadMode) {
-      this.spreadMode = mode;
-      this.eventBus.dispatch('spreadmodechanged', { mode });
-      this._regroupSpreads();
-    }
+    if (!Number.isInteger(mode) || !Object.values(SpreadMode).includes(mode)) {
+      throw new Error(`Invalid spread mode: ${mode}`);
+    }
+    this.spreadMode = mode;
   }
   _regroupSpreads() {}
 }
 exports.BaseViewer = BaseViewer;
 exports.ScrollMode = ScrollMode;
 exports.SpreadMode = SpreadMode;
 
 /***/ }),
@@ -8171,26 +8203,48 @@ class SecondaryToolbar {
         case _pdf_cursor_tools.CursorTool.HAND:
           buttons.cursorHandToolButton.classList.add('toggled');
           break;
       }
     });
   }
   _bindScrollModeListener(buttons) {
     this.eventBus.on('scrollmodechanged', function (evt) {
-      buttons.scrollVerticalButton.classList.toggle('toggled', evt.mode === _base_viewer.ScrollMode.VERTICAL);
-      buttons.scrollHorizontalButton.classList.toggle('toggled', evt.mode === _base_viewer.ScrollMode.HORIZONTAL);
-      buttons.scrollWrappedButton.classList.toggle('toggled', evt.mode === _base_viewer.ScrollMode.WRAPPED);
+      buttons.scrollVerticalButton.classList.remove('toggled');
+      buttons.scrollHorizontalButton.classList.remove('toggled');
+      buttons.scrollWrappedButton.classList.remove('toggled');
+      switch (evt.mode) {
+        case _base_viewer.ScrollMode.VERTICAL:
+          buttons.scrollVerticalButton.classList.add('toggled');
+          break;
+        case _base_viewer.ScrollMode.HORIZONTAL:
+          buttons.scrollHorizontalButton.classList.add('toggled');
+          break;
+        case _base_viewer.ScrollMode.WRAPPED:
+          buttons.scrollWrappedButton.classList.add('toggled');
+          break;
+      }
     });
   }
   _bindSpreadModeListener(buttons) {
     this.eventBus.on('spreadmodechanged', function (evt) {
-      buttons.spreadNoneButton.classList.toggle('toggled', evt.mode === _base_viewer.SpreadMode.NONE);
-      buttons.spreadOddButton.classList.toggle('toggled', evt.mode === _base_viewer.SpreadMode.ODD);
-      buttons.spreadEvenButton.classList.toggle('toggled', evt.mode === _base_viewer.SpreadMode.EVEN);
+      buttons.spreadNoneButton.classList.remove('toggled');
+      buttons.spreadOddButton.classList.remove('toggled');
+      buttons.spreadEvenButton.classList.remove('toggled');
+      switch (evt.mode) {
+        case _base_viewer.SpreadMode.NONE:
+          buttons.spreadNoneButton.classList.add('toggled');
+          break;
+        case _base_viewer.SpreadMode.ODD:
+          buttons.spreadOddButton.classList.add('toggled');
+          break;
+        case _base_viewer.SpreadMode.EVEN:
+          buttons.spreadEvenButton.classList.add('toggled');
+          break;
+      }
     });
   }
   open() {
     if (this.opened) {
       return;
     }
     this.opened = true;
     this._setMaxHeight();