From bfefadb87c10857a11a0e66451e77d35bcd20a31 Mon Sep 17 00:00:00 2001 From: Yury Delendik Date: Fri, 12 Sep 2014 13:39:23 -0500 Subject: [PATCH] Moves watchScroll and getVisibleElements from PDFView --- web/ui_utils.js | 85 ++++++++++++++++++++++++++++++++++++++++++++ web/viewer.js | 94 +++++-------------------------------------------- 2 files changed, 94 insertions(+), 85 deletions(-) diff --git a/web/ui_utils.js b/web/ui_utils.js index b38ec4bc3..04805c053 100644 --- a/web/ui_utils.js +++ b/web/ui_utils.js @@ -138,6 +138,91 @@ function scrollIntoView(element, spot) { parent.scrollTop = offsetY; } +/** + * Helper function to start monitoring the scroll event and converting them into + * PDF.js friendly one: with scroll debounce and scroll direction. + */ +function watchScroll(viewAreaElement, callback) { + var debounceScroll = function debounceScroll(evt) { + if (rAF) { + return; + } + // schedule an invocation of scroll for next animation frame. + rAF = window.requestAnimationFrame(function viewAreaElementScrolled() { + rAF = null; + + var currentY = viewAreaElement.scrollTop; + var lastY = state.lastY; + if (currentY > lastY) { + state.down = true; + } else if (currentY < lastY) { + state.down = false; + } + state.lastY = currentY; + // else do nothing and use previous value + callback(state); + }); + }; + + var state = { + down: true, + lastY: viewAreaElement.scrollTop, + _eventHandler: debounceScroll + }; + + var rAF = null; + viewAreaElement.addEventListener('scroll', debounceScroll, true); + return state; +} + +/** + * Generic helper to find out what elements are visible within a scroll pane. + */ +function getVisibleElements(scrollEl, views, sortByVisibility) { + var top = scrollEl.scrollTop, bottom = top + scrollEl.clientHeight; + var left = scrollEl.scrollLeft, right = left + scrollEl.clientWidth; + + var visible = [], view; + var currentHeight, viewHeight, hiddenHeight, percentHeight; + var currentWidth, viewWidth; + for (var i = 0, ii = views.length; i < ii; ++i) { + view = views[i]; + currentHeight = view.el.offsetTop + view.el.clientTop; + viewHeight = view.el.clientHeight; + if ((currentHeight + viewHeight) < top) { + continue; + } + if (currentHeight > bottom) { + break; + } + currentWidth = view.el.offsetLeft + view.el.clientLeft; + viewWidth = view.el.clientWidth; + if ((currentWidth + viewWidth) < left || currentWidth > right) { + continue; + } + hiddenHeight = Math.max(0, top - currentHeight) + + Math.max(0, currentHeight + viewHeight - bottom); + percentHeight = ((viewHeight - hiddenHeight) * 100 / viewHeight) | 0; + + visible.push({ id: view.id, x: currentWidth, y: currentHeight, + view: view, percent: percentHeight }); + } + + var first = visible[0]; + var last = visible[visible.length - 1]; + + if (sortByVisibility) { + visible.sort(function(a, b) { + var pc = a.percent - b.percent; + if (Math.abs(pc) > 0.001) { + return -pc; + } + return a.id - b.id; // ensure stability + }); + } + return {first: first, last: last, views: visible}; +} + /** * Event handler to suppress context menu. */ diff --git a/web/viewer.js b/web/viewer.js index 7828db204..6cd58fb0c 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -20,7 +20,8 @@ ThumbnailView, URL, noContextMenuHandler, SecondaryToolbar, PasswordPrompt, PresentationMode, HandTool, Promise, DocumentProperties, DocumentOutlineView, DocumentAttachmentsView, - OverlayManager, PDFFindController, PDFFindBar */ + OverlayManager, PDFFindController, PDFFindBar, getVisibleElements, + watchScroll */ 'use strict'; @@ -134,14 +135,14 @@ var PDFView = { initialize: function pdfViewInitialize() { var self = this; var container = this.container = document.getElementById('viewerContainer'); - this.pageViewScroll = {}; - this.watchScroll(container, this.pageViewScroll, updateViewarea); + this.pageViewScroll = watchScroll(container, updateViewarea); var thumbnailContainer = this.thumbnailContainer = document.getElementById('thumbnailView'); - this.thumbnailViewScroll = {}; - this.watchScroll(thumbnailContainer, this.thumbnailViewScroll, - this.renderHighestPriority.bind(this)); + this.thumbnailViewScroll = watchScroll(thumbnailContainer, function () { + this.renderHighestPriority(); + }.bind(this)); + Preferences.initialize(); @@ -272,36 +273,6 @@ var PDFView = { return this.pdfDocument.getPage(n); }, - // Helper function to keep track whether a div was scrolled up or down and - // then call a callback. - watchScroll: function pdfViewWatchScroll(viewAreaElement, state, callback) { - state.down = true; - state.lastY = viewAreaElement.scrollTop; - state.rAF = null; - viewAreaElement.addEventListener('scroll', function debounceScroll(evt) { - if (state.rAF) { - return; - } - // schedule an invocation of webViewerScrolled for next animation frame. - state.rAF = window.requestAnimationFrame(function webViewerScrolled() { - state.rAF = null; - if (!PDFView.pdfDocument) { - return; - } - var currentY = viewAreaElement.scrollTop; - var lastY = state.lastY; - if (currentY > lastY) { - state.down = true; - } else if (currentY < lastY) { - state.down = false; - } - // else do nothing and use previous value - state.lastY = currentY; - callback(); - }); - }, true); - }, - _setScaleUpdatePages: function pdfView_setScaleUpdatePages( newScale, newValue, resetAutoSettings, noScroll) { this.currentScaleValue = newValue; @@ -1490,7 +1461,7 @@ var PDFView = { getVisiblePages: function pdfViewGetVisiblePages() { if (!PresentationMode.active) { - return this.getVisibleElements(this.container, this.pages, true); + return getVisibleElements(this.container, this.pages, true); } else { // The algorithm in getVisibleElements doesn't work in all browsers and // configurations when presentation mode is active. @@ -1502,54 +1473,7 @@ var PDFView = { }, getVisibleThumbs: function pdfViewGetVisibleThumbs() { - return this.getVisibleElements(this.thumbnailContainer, this.thumbnails); - }, - - // Generic helper to find out what elements are visible within a scroll pane. - getVisibleElements: function pdfViewGetVisibleElements( - scrollEl, views, sortByVisibility) { - var top = scrollEl.scrollTop, bottom = top + scrollEl.clientHeight; - var left = scrollEl.scrollLeft, right = left + scrollEl.clientWidth; - - var visible = [], view; - var currentHeight, viewHeight, hiddenHeight, percentHeight; - var currentWidth, viewWidth; - for (var i = 0, ii = views.length; i < ii; ++i) { - view = views[i]; - currentHeight = view.el.offsetTop + view.el.clientTop; - viewHeight = view.el.clientHeight; - if ((currentHeight + viewHeight) < top) { - continue; - } - if (currentHeight > bottom) { - break; - } - currentWidth = view.el.offsetLeft + view.el.clientLeft; - viewWidth = view.el.clientWidth; - if ((currentWidth + viewWidth) < left || currentWidth > right) { - continue; - } - hiddenHeight = Math.max(0, top - currentHeight) + - Math.max(0, currentHeight + viewHeight - bottom); - percentHeight = ((viewHeight - hiddenHeight) * 100 / viewHeight) | 0; - - visible.push({ id: view.id, x: currentWidth, y: currentHeight, - view: view, percent: percentHeight }); - } - - var first = visible[0]; - var last = visible[visible.length - 1]; - - if (sortByVisibility) { - visible.sort(function(a, b) { - var pc = a.percent - b.percent; - if (Math.abs(pc) > 0.001) { - return -pc; - } - return a.id - b.id; // ensure stability - }); - } - return {first: first, last: last, views: visible}; + return getVisibleElements(this.thumbnailContainer, this.thumbnails); }, // Helper function to parse query string (e.g. ?param1=value&parm2=...).