Bug 1473118 - Update pdf.js to version 2.0.661. r=bdahl
authorRyan VanderMeulen <ryanvm@gmail.com>
Tue, 03 Jul 2018 15:15:46 -0400
changeset 479982 5d23b6e0b74d74eee52d7af5fa47573ef8afe979
parent 479981 9e9a332fe140be7a4935e79535e0fd61aa2b9625
child 479983 987ea0d6a000b95cf93928b25a74a7fb1dfe37b2
child 480016 9a2b02fe351bd65f6850a5c80b91dd0eec4a878a
push id9719
push userffxbld-merge
push dateFri, 24 Aug 2018 17:49:46 +0000
treeherdermozilla-beta@719ec98fba77 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbdahl
bugs1473118
milestone63.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1473118 - Update pdf.js to version 2.0.661. r=bdahl
browser/extensions/pdfjs/README.mozilla
browser/extensions/pdfjs/content/build/pdf.js
browser/extensions/pdfjs/content/build/pdf.worker.js
browser/extensions/pdfjs/content/web/viewer.js
--- 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.641
+Current extension version is: 2.0.661
 
-Taken from upstream commit: 6fa2c779
+Taken from upstream commit: 42922c9a
--- 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.641';
-var pdfjsBuild = '6fa2c779';
+var pdfjsVersion = '2.0.661';
+var pdfjsBuild = '42922c9a';
 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);
@@ -4218,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.641',
+    apiVersion: '2.0.661',
     source: {
       data: source.data,
       url: source.url,
       password: source.password,
       disableAutoFetch: source.disableAutoFetch,
       rangeChunkSize: source.rangeChunkSize,
       length: source.length
     },
@@ -5463,26 +5463,26 @@ var InternalRenderTask = function Intern
     this.capability = (0, _util.createPromiseCapability)();
     this.task = new RenderTask(this);
     this._continueBound = this._continue.bind(this);
     this._scheduleNextBound = this._scheduleNext.bind(this);
     this._nextBound = this._next.bind(this);
     this._canvas = params.canvasContext.canvas;
   }
   InternalRenderTask.prototype = {
-    initializeGraphics: function InternalRenderTask_initializeGraphics(transparency) {
+    initializeGraphics(transparency) {
+      if (this.cancelled) {
+        return;
+      }
       if (this._canvas) {
         if (canvasInRendering.has(this._canvas)) {
           throw new Error('Cannot use the same canvas during multiple render() operations. ' + 'Use different canvas or ensure previous operations were ' + 'cancelled or completed.');
         }
         canvasInRendering.set(this._canvas, this);
       }
-      if (this.cancelled) {
-        return;
-      }
       if (this._pdfBug && _global_scope2.default.StepperManager && _global_scope2.default.StepperManager.enabled) {
         this.stepper = _global_scope2.default.StepperManager.create(this.pageNumber - 1);
         this.stepper.init(this.operatorList);
         this.stepper.nextBreakPoint = this.stepper.getNextBreakPoint();
       }
       var params = this.params;
       this.gfx = new _canvas.CanvasGraphics(params.canvasContext, this.commonObjs, this.objs, this.canvasFactory, this.webGLContext, params.imageLayer);
       this.gfx.beginDrawing({
@@ -5558,18 +5558,18 @@ var InternalRenderTask = function Intern
         }
       });
     }
   };
   return InternalRenderTask;
 }();
 var version, build;
 {
-  exports.version = version = '2.0.641';
-  exports.build = build = '6fa2c779';
+  exports.version = version = '2.0.661';
+  exports.build = build = '42922c9a';
 }
 exports.getDocument = getDocument;
 exports.LoopbackPort = LoopbackPort;
 exports.PDFDataRangeTransport = PDFDataRangeTransport;
 exports.PDFWorker = PDFWorker;
 exports.PDFDocumentProxy = PDFDocumentProxy;
 exports.PDFPageProxy = PDFPageProxy;
 exports.setPDFNetworkStreamFactory = setPDFNetworkStreamFactory;
--- 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.641';
-var pdfjsBuild = '6fa2c779';
+var pdfjsVersion = '2.0.661';
+var pdfjsBuild = '42922c9a';
 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.641';
+    let workerVersion = '2.0.661';
     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;
--- a/browser/extensions/pdfjs/content/web/viewer.js
+++ b/browser/extensions/pdfjs/content/web/viewer.js
@@ -565,17 +565,20 @@ let PDFViewerApplication = {
         l10n: this.l10n
       });
       pdfRenderingQueue.setThumbnailViewer(this.pdfThumbnailViewer);
       this.pdfHistory = new _pdf_history.PDFHistory({
         linkService: pdfLinkService,
         eventBus
       });
       pdfLinkService.setHistory(this.pdfHistory);
-      this.findController = new _pdf_find_controller.PDFFindController({ pdfViewer: this.pdfViewer });
+      this.findController = new _pdf_find_controller.PDFFindController({
+        pdfViewer: this.pdfViewer,
+        eventBus
+      });
       this.findController.onUpdateResultsCount = matchCount => {
         if (this.supportsIntegratedFind) {
           return;
         }
         this.findBar.updateResultsCount(matchCount);
       };
       this.findController.onUpdateState = (state, previous, matchCount) => {
         if (this.supportsIntegratedFind) {
@@ -927,34 +930,33 @@ let PDFViewerApplication = {
       this.loadingBar.hide();
       firstPagePromise.then(() => {
         this.eventBus.dispatch('documentload', { source: this });
       });
     });
     let pageModePromise = pdfDocument.getPageMode().catch(function () {});
     this.toolbar.setPagesCount(pdfDocument.numPages, false);
     this.secondaryToolbar.setPagesCount(pdfDocument.numPages);
-    let id = this.documentFingerprint = pdfDocument.fingerprint;
-    let store = this.store = new _view_history.ViewHistory(id);
+    const store = this.store = new _view_history.ViewHistory(pdfDocument.fingerprint);
     let baseDocumentUrl;
     baseDocumentUrl = this.baseUrl;
     this.pdfLinkService.setDocument(pdfDocument, baseDocumentUrl);
     this.pdfDocumentProperties.setDocument(pdfDocument, this.url);
     let pdfViewer = this.pdfViewer;
     pdfViewer.setDocument(pdfDocument);
     let firstPagePromise = pdfViewer.firstPagePromise;
     let pagesPromise = pdfViewer.pagesPromise;
     let onePageRendered = pdfViewer.onePageRendered;
     let pdfThumbnailViewer = this.pdfThumbnailViewer;
     pdfThumbnailViewer.setDocument(pdfDocument);
     firstPagePromise.then(pdfPage => {
       this.loadingBar.setWidth(this.appConfig.viewerContainer);
       if (!_app_options.AppOptions.get('disableHistory') && !this.isViewerEmbedded) {
         let resetHistory = !_app_options.AppOptions.get('showPreviousViewOnLoad');
-        this.pdfHistory.initialize(id, resetHistory);
+        this.pdfHistory.initialize(pdfDocument.fingerprint, resetHistory);
         if (this.pdfHistory.initialBookmark) {
           this.initialBookmark = this.pdfHistory.initialBookmark;
           this.initialRotation = this.pdfHistory.initialRotation;
         }
       }
       let initialParams = {
         bookmark: null,
         hash: null
@@ -975,22 +977,18 @@ let PDFViewerApplication = {
         let rotation = null;
         let sidebarView = _app_options.AppOptions.get('sidebarViewOnLoad');
         let scrollMode = _app_options.AppOptions.get('scrollModeOnLoad');
         let spreadMode = _app_options.AppOptions.get('spreadModeOnLoad');
         if (values.page && _app_options.AppOptions.get('showPreviousViewOnLoad')) {
           hash = 'page=' + values.page + '&zoom=' + (zoom || values.zoom) + ',' + values.scrollLeft + ',' + values.scrollTop;
           rotation = parseInt(values.rotation, 10);
           sidebarView = sidebarView || values.sidebarView | 0;
-          if (values.scrollMode !== null) {
-            scrollMode = values.scrollMode;
-          }
-          if (values.spreadMode !== null) {
-            spreadMode = values.spreadMode;
-          }
+          scrollMode = scrollMode || values.scrollMode | 0;
+          spreadMode = spreadMode || values.spreadMode | 0;
         }
         if (pageMode && !_app_options.AppOptions.get('disablePageMode')) {
           sidebarView = sidebarView || apiPageModeToSidebarView(pageMode);
         }
         return {
           hash,
           rotation,
           sidebarView,
@@ -1123,29 +1121,31 @@ let PDFViewerApplication = {
       this.externalServices.reportTelemetry({
         type: 'documentInfo',
         version: versionId,
         generator: generatorId,
         formType
       });
     });
   },
-  setInitialView(storedHash, values = {}) {
-    let { rotation, sidebarView, scrollMode, spreadMode } = values;
+  setInitialView(storedHash, { rotation, sidebarView, scrollMode, spreadMode } = {}) {
     let setRotation = angle => {
       if ((0, _ui_utils.isValidRotation)(angle)) {
         this.pdfViewer.pagesRotation = angle;
       }
     };
-    if (Number.isInteger(scrollMode)) {
-      this.pdfViewer.setScrollMode(scrollMode);
-    }
-    if (Number.isInteger(spreadMode)) {
-      this.pdfViewer.setSpreadMode(spreadMode);
-    }
+    let setViewerModes = (scroll, spread) => {
+      if (Number.isInteger(scroll)) {
+        this.pdfViewer.scrollMode = scroll;
+      }
+      if (Number.isInteger(spread)) {
+        this.pdfViewer.spreadMode = spread;
+      }
+    };
+    setViewerModes(scrollMode, spreadMode);
     this.isInitialViewSet = true;
     this.pdfSidebar.setInitialView(sidebarView);
     if (this.initialBookmark) {
       setRotation(this.initialRotation);
       delete this.initialRotation;
       this.pdfLinkService.setHash(this.initialBookmark);
       this.initialBookmark = null;
     } else if (storedHash) {
@@ -1579,20 +1579,20 @@ function webViewerScaleChanged(evt) {
 }
 function webViewerRotateCw() {
   PDFViewerApplication.rotatePages(90);
 }
 function webViewerRotateCcw() {
   PDFViewerApplication.rotatePages(-90);
 }
 function webViewerSwitchScrollMode(evt) {
-  PDFViewerApplication.pdfViewer.setScrollMode(evt.mode);
+  PDFViewerApplication.pdfViewer.scrollMode = evt.mode;
 }
 function webViewerSwitchSpreadMode(evt) {
-  PDFViewerApplication.pdfViewer.setSpreadMode(evt.mode);
+  PDFViewerApplication.pdfViewer.spreadMode = evt.mode;
 }
 function webViewerDocumentProperties() {
   PDFViewerApplication.pdfDocumentProperties.open();
 }
 function webViewerFind(evt) {
   PDFViewerApplication.findController.executeCommand('find' + evt.type, {
     query: evt.query,
     phraseSearch: evt.phraseSearch,
@@ -3217,16 +3217,24 @@ const defaultOptions = {
   showPreviousViewOnLoad: {
     value: true,
     kind: OptionKind.VIEWER
   },
   sidebarViewOnLoad: {
     value: 0,
     kind: OptionKind.VIEWER
   },
+  scrollModeOnLoad: {
+    value: 0,
+    kind: OptionKind.VIEWER
+  },
+  spreadModeOnLoad: {
+    value: 0,
+    kind: OptionKind.VIEWER
+  },
   textLayerMode: {
     value: 1,
     kind: OptionKind.VIEWER
   },
   useOnlyCssZoom: {
     value: false,
     kind: OptionKind.VIEWER
   },
@@ -4174,16 +4182,18 @@ exports.PDFFindBar = PDFFindBar;
 
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.PDFFindController = exports.FindState = undefined;
 
 var _pdfjsLib = __webpack_require__(3);
 
+var _dom_events = __webpack_require__(10);
+
 var _ui_utils = __webpack_require__(2);
 
 const FindState = {
   FOUND: 0,
   NOT_FOUND: 1,
   WRAPPED: 2,
   PENDING: 3
 };
@@ -4199,18 +4209,19 @@ const CHARACTERS_TO_NORMALIZE = {
   '\u201D': '"',
   '\u201E': '"',
   '\u201F': '"',
   '\u00BC': '1/4',
   '\u00BD': '1/2',
   '\u00BE': '3/4'
 };
 class PDFFindController {
-  constructor({ pdfViewer }) {
+  constructor({ pdfViewer, eventBus = (0, _dom_events.getGlobalEventBus)() }) {
     this.pdfViewer = pdfViewer;
+    this.eventBus = eventBus;
     this.onUpdateResultsCount = null;
     this.onUpdateState = null;
     this.reset();
     let replace = Object.keys(CHARACTERS_TO_NORMALIZE).join('');
     this.normalizationRegex = new RegExp('[' + replace + ']', 'g');
   }
   reset() {
     this.startedTextExtraction = false;
@@ -4230,17 +4241,21 @@ class PDFFindController {
       matchIdx: null
     };
     this.pagesToSearch = null;
     this.resumePageIdx = null;
     this.state = null;
     this.dirtyMatch = false;
     this.findTimeout = null;
     this._firstPagePromise = new Promise(resolve => {
-      this.resolveFirstPage = resolve;
+      const eventBus = this.eventBus;
+      eventBus.on('pagesinit', function onPagesInit() {
+        eventBus.off('pagesinit', onPagesInit);
+        resolve();
+      });
     });
   }
   executeCommand(cmd, state) {
     if (this.state === null || cmd !== 'findagain') {
       this.dirtyMatch = true;
     }
     this.state = state;
     this._updateUIState(FindState.PENDING);
@@ -6337,28 +6352,28 @@ class PDFViewer extends _base_viewer.Bas
   get _setDocumentViewerElement() {
     return (0, _pdfjsLib.shadow)(this, '_setDocumentViewerElement', this.viewer);
   }
   _scrollIntoView({ pageDiv, pageSpot = null }) {
     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) {
+      if (this._scrollMode === _base_viewer.ScrollMode.HORIZONTAL || left < scrollLeft || right > scrollLeft + clientWidth) {
         pageSpot = {
           left: 0,
           top: 0
         };
       }
     }
     (0, _ui_utils.scrollIntoView)(pageDiv, pageSpot);
   }
   _getVisiblePages() {
     if (!this.isInPresentationMode) {
-      return (0, _ui_utils.getVisibleElements)(this.container, this._pages, true, this.scrollMode === _base_viewer.ScrollMode.HORIZONTAL);
+      return (0, _ui_utils.getVisibleElements)(this.container, this._pages, true, this._scrollMode === _base_viewer.ScrollMode.HORIZONTAL);
     }
     let currentPage = this._pages[this._currentPageNumber - 1];
     let visible = [{
       id: currentPage.id,
       view: currentPage
     }];
     return {
       first: currentPage,
@@ -6395,84 +6410,17 @@ class PDFViewer extends _base_viewer.Bas
     }
     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() {
-    if (!this.pdfDocument) {
-      return;
-    }
-    const viewer = this.viewer,
-          pages = this._pages;
-    viewer.textContent = '';
-    if (this.spreadMode === _base_viewer.SpreadMode.NONE) {
-      for (let i = 0, iMax = pages.length; i < iMax; ++i) {
-        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';
-          viewer.appendChild(spread);
-        } else if (i % 2 === parity) {
-          spread = spread.cloneNode(false);
-          viewer.appendChild(spread);
-        }
-        spread.appendChild(pages[i].div);
-      }
-    }
-    this.scrollPageIntoView({ pageNumber: this._currentPageNumber });
-    this.update();
+    return this.isInPresentationMode ? false : this._scrollMode === _base_viewer.ScrollMode.HORIZONTAL;
   }
 }
 exports.PDFViewer = PDFViewer;
 
 /***/ }),
 /* 25 */
 /***/ (function(module, exports, __webpack_require__) {
 
@@ -6565,34 +6513,29 @@ class BaseViewer {
     this.imageResourcesPath = options.imageResourcesPath || '';
     this.renderInteractiveForms = options.renderInteractiveForms || false;
     this.enablePrintAutoRotate = options.enablePrintAutoRotate || false;
     this.renderer = options.renderer || _ui_utils.RendererType.CANVAS;
     this.enableWebGL = options.enableWebGL || false;
     this.useOnlyCssZoom = options.useOnlyCssZoom || false;
     this.maxCanvasPixels = options.maxCanvasPixels;
     this.l10n = options.l10n || _ui_utils.NullL10n;
-    this.scrollMode = options.scrollMode || ScrollMode.VERTICAL;
-    this.spreadMode = options.spreadMode || SpreadMode.NONE;
     this.defaultRenderingQueue = !options.renderingQueue;
     if (this.defaultRenderingQueue) {
       this.renderingQueue = new _pdf_rendering_queue.PDFRenderingQueue();
       this.renderingQueue.setViewer(this);
     } else {
       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');
     }
-    if (this.scrollMode !== ScrollMode.VERTICAL) {
-      this._updateScrollModeClasses();
-    }
   }
   get pagesCount() {
     return this._pages.length;
   }
   getPageView(index) {
     return this._pages[index];
   }
   get pageViewsReady() {
@@ -6760,18 +6703,18 @@ class BaseViewer {
           enableWebGL: this.enableWebGL,
           useOnlyCssZoom: this.useOnlyCssZoom,
           maxCanvasPixels: this.maxCanvasPixels,
           l10n: this.l10n
         });
         bindOnAfterAndBeforeDraw(pageView);
         this._pages.push(pageView);
       }
-      if (this.spreadMode !== SpreadMode.NONE) {
-        this._regroupSpreads();
+      if (this._spreadMode !== SpreadMode.NONE) {
+        this._updateSpreadMode();
       }
       onePageRenderedCapability.promise.then(() => {
         if (pdfDocument.loadingParams['disableAutoFetch']) {
           pagesCapability.resolve();
           return;
         }
         let getPagesLeft = pagesCount;
         for (let pageNum = 1; pageNum <= pagesCount; ++pageNum) {
@@ -6791,19 +6734,16 @@ class BaseViewer {
             }
           });
         }
       });
       this.eventBus.dispatch('pagesinit', { source: this });
       if (this.defaultRenderingQueue) {
         this.update();
       }
-      if (this.findController) {
-        this.findController.resolveFirstPage();
-      }
     }).catch(reason => {
       console.error('Unable to initialize viewer', reason);
     });
   }
   setPageLabels(labels) {
     if (!this.pdfDocument) {
       return;
     }
@@ -6827,17 +6767,20 @@ class BaseViewer {
     this._currentScale = _ui_utils.UNKNOWN_SCALE;
     this._currentScaleValue = null;
     this._pageLabels = null;
     this._buffer = new PDFPageViewBuffer(DEFAULT_CACHE_SIZE);
     this._location = null;
     this._pagesRotation = 0;
     this._pagesRequests = [];
     this._pageViewsReady = false;
+    this._scrollMode = ScrollMode.VERTICAL;
+    this._spreadMode = SpreadMode.NONE;
     this.viewer.textContent = '';
+    this._updateScrollMode();
   }
   _scrollUpdate() {
     if (this.pagesCount === 0) {
       return;
     }
     this.update();
   }
   _scrollIntoView({ pageDiv, pageSpot = null, pageNumber = null }) {
@@ -7187,30 +7130,106 @@ class BaseViewer {
       }
       return {
         width: size.height,
         height: size.width,
         rotation: (size.rotation + 90) % 360
       };
     });
   }
-  setScrollMode(mode) {
+  get scrollMode() {
+    return this._scrollMode;
+  }
+  set scrollMode(mode) {
+    if (this._scrollMode === mode) {
+      return;
+    }
     if (!Number.isInteger(mode) || !Object.values(ScrollMode).includes(mode)) {
       throw new Error(`Invalid scroll mode: ${mode}`);
     }
-    this.scrollMode = mode;
-  }
-  _updateScrollModeClasses() {}
-  setSpreadMode(mode) {
+    this._scrollMode = mode;
+    this.eventBus.dispatch('scrollmodechanged', {
+      source: this,
+      mode
+    });
+    this._updateScrollMode(this._currentPageNumber);
+  }
+  _updateScrollMode(pageNumber = null) {
+    const scrollMode = this._scrollMode,
+          viewer = this.viewer;
+    if (scrollMode === ScrollMode.HORIZONTAL) {
+      viewer.classList.add('scrollHorizontal');
+    } else {
+      viewer.classList.remove('scrollHorizontal');
+    }
+    if (scrollMode === ScrollMode.WRAPPED) {
+      viewer.classList.add('scrollWrapped');
+    } else {
+      viewer.classList.remove('scrollWrapped');
+    }
+    if (!this.pdfDocument || !pageNumber) {
+      return;
+    }
+    if (this._currentScaleValue && isNaN(this._currentScaleValue)) {
+      this._setScale(this._currentScaleValue, true);
+    }
+    this.scrollPageIntoView({ pageNumber });
+    this.update();
+  }
+  setScrollMode(mode) {}
+  get spreadMode() {
+    return this._spreadMode;
+  }
+  set spreadMode(mode) {
+    if (this._spreadMode === mode) {
+      return;
+    }
     if (!Number.isInteger(mode) || !Object.values(SpreadMode).includes(mode)) {
       throw new Error(`Invalid spread mode: ${mode}`);
     }
-    this.spreadMode = mode;
-  }
-  _regroupSpreads() {}
+    this._spreadMode = mode;
+    this.eventBus.dispatch('spreadmodechanged', {
+      source: this,
+      mode
+    });
+    this._updateSpreadMode(this._currentPageNumber);
+  }
+  _updateSpreadMode(pageNumber = null) {
+    if (!this.pdfDocument) {
+      return;
+    }
+    const viewer = this.viewer,
+          pages = this._pages;
+    viewer.textContent = '';
+    if (this._spreadMode === SpreadMode.NONE) {
+      for (let i = 0, iMax = pages.length; i < iMax; ++i) {
+        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';
+          viewer.appendChild(spread);
+        } else if (i % 2 === parity) {
+          spread = spread.cloneNode(false);
+          viewer.appendChild(spread);
+        }
+        spread.appendChild(pages[i].div);
+      }
+    }
+    if (!pageNumber) {
+      return;
+    }
+    this.scrollPageIntoView({ pageNumber });
+    this.update();
+  }
+  setSpreadMode(mode) {}
 }
 exports.BaseViewer = BaseViewer;
 exports.ScrollMode = ScrollMode;
 exports.SpreadMode = SpreadMode;
 
 /***/ }),
 /* 26 */
 /***/ (function(module, exports, __webpack_require__) {
@@ -8154,16 +8173,18 @@ class SecondaryToolbar {
   setPagesCount(pagesCount) {
     this.pagesCount = pagesCount;
     this._updateUIState();
   }
   reset() {
     this.pageNumber = 0;
     this.pagesCount = 0;
     this._updateUIState();
+    this.eventBus.dispatch('resetscrollmode', { source: this });
+    this.eventBus.dispatch('resetspreadmode', { source: this });
   }
   _updateUIState() {
     this.items.firstPage.disabled = this.pageNumber <= 1;
     this.items.lastPage.disabled = this.pageNumber >= this.pagesCount;
     this.items.pageRotateCw.disabled = this.pagesCount === 0;
     this.items.pageRotateCcw.disabled = this.pagesCount === 0;
   }
   _bindClickListeners() {
@@ -8194,49 +8215,61 @@ class SecondaryToolbar {
           break;
         case _pdf_cursor_tools.CursorTool.HAND:
           buttons.cursorHandToolButton.classList.add('toggled');
           break;
       }
     });
   }
   _bindScrollModeListener(buttons) {
-    this.eventBus.on('scrollmodechanged', function (evt) {
+    function scrollModeChanged(evt) {
       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;
       }
+    }
+    this.eventBus.on('scrollmodechanged', scrollModeChanged);
+    this.eventBus.on('resetscrollmode', evt => {
+      if (evt.source === this) {
+        scrollModeChanged({ mode: _base_viewer.ScrollMode.VERTICAL });
+      }
     });
   }
   _bindSpreadModeListener(buttons) {
-    this.eventBus.on('spreadmodechanged', function (evt) {
+    function spreadModeChanged(evt) {
       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;
       }
+    }
+    this.eventBus.on('spreadmodechanged', spreadModeChanged);
+    this.eventBus.on('resetspreadmode', evt => {
+      if (evt.source === this) {
+        spreadModeChanged({ mode: _base_viewer.SpreadMode.NONE });
+      }
     });
   }
   open() {
     if (this.opened) {
       return;
     }
     this.opened = true;
     this._setMaxHeight();