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 423466 4f6e597104da
parent 423464 14b72cf25160 (current diff)
parent 423465 6d0dcae0268b (diff)
child 423467 d7225291d86c
child 423506 5d7823a838de
child 423533 b6b7aa28be53
push id34184
push useraciure@mozilla.com
push dateMon, 25 Jun 2018 09:49:46 +0000
treeherdermozilla-central@4f6e597104da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone62.0a1
first release with
nightly linux32
4f6e597104da / 62.0a1 / 20180625100047 / files
nightly linux64
4f6e597104da / 62.0a1 / 20180625100047 / files
nightly mac
4f6e597104da / 62.0a1 / 20180625100047 / files
nightly win32
4f6e597104da / 62.0a1 / 20180625100047 / files
nightly win64
4f6e597104da / 62.0a1 / 20180625100047 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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();