diff --git a/web/pdf_presentation_mode.js b/web/pdf_presentation_mode.js index c9f3d8066..9b29bd5d3 100644 --- a/web/pdf_presentation_mode.js +++ b/web/pdf_presentation_mode.js @@ -15,10 +15,19 @@ import { normalizeWheelEventDelta } from './ui_utils'; -var DELAY_BEFORE_RESETTING_SWITCH_IN_PROGRESS = 1500; // in ms -var DELAY_BEFORE_HIDING_CONTROLS = 3000; // in ms -var ACTIVE_SELECTOR = 'pdfPresentationMode'; -var CONTROLS_SELECTOR = 'pdfPresentationModeControls'; +const DELAY_BEFORE_RESETTING_SWITCH_IN_PROGRESS = 1500; // in ms +const DELAY_BEFORE_HIDING_CONTROLS = 3000; // in ms +const ACTIVE_SELECTOR = 'pdfPresentationMode'; +const CONTROLS_SELECTOR = 'pdfPresentationModeControls'; +const MOUSE_SCROLL_COOLDOWN_TIME = 50; // in ms +const PAGE_SWITCH_THRESHOLD = 0.1; + +// Number of CSS pixels for a movement to count as a swipe. +const SWIPE_MIN_DISTANCE_THRESHOLD = 50; + +// Swipe angle deviation from the x or y axis before it is not +// considered a swipe in that direction any more. +const SWIPE_ANGLE_THRESHOLD = Math.PI / 6; /** * @typedef {Object} PDFPresentationModeOptions @@ -30,15 +39,11 @@ var CONTROLS_SELECTOR = 'pdfPresentationModeControls'; * to the context menu in Presentation Mode. */ -/** - * @class - */ -var PDFPresentationMode = (function PDFPresentationModeClosure() { +class PDFPresentationMode { /** - * @constructs PDFPresentationMode * @param {PDFPresentationModeOptions} options */ - function PDFPresentationMode(options) { + constructor(options) { this.container = options.container; this.viewer = options.viewer || options.container.firstElementChild; this.pdfViewer = options.pdfViewer; @@ -53,457 +58,432 @@ var PDFPresentationMode = (function PDFPresentationModeClosure() { this.touchSwipeState = null; if (contextMenuItems) { - contextMenuItems.contextFirstPage.addEventListener('click', - function PDFPresentationMode_contextFirstPageClick(e) { + contextMenuItems.contextFirstPage.addEventListener('click', () => { this.contextMenuOpen = false; this.eventBus.dispatch('firstpage'); - }.bind(this)); - contextMenuItems.contextLastPage.addEventListener('click', - function PDFPresentationMode_contextLastPageClick(e) { + }); + contextMenuItems.contextLastPage.addEventListener('click', () => { this.contextMenuOpen = false; this.eventBus.dispatch('lastpage'); - }.bind(this)); - contextMenuItems.contextPageRotateCw.addEventListener('click', - function PDFPresentationMode_contextPageRotateCwClick(e) { + }); + contextMenuItems.contextPageRotateCw.addEventListener('click', () => { this.contextMenuOpen = false; this.eventBus.dispatch('rotatecw'); - }.bind(this)); - contextMenuItems.contextPageRotateCcw.addEventListener('click', - function PDFPresentationMode_contextPageRotateCcwClick(e) { + }); + contextMenuItems.contextPageRotateCcw.addEventListener('click', () => { this.contextMenuOpen = false; this.eventBus.dispatch('rotateccw'); - }.bind(this)); + }); } } - PDFPresentationMode.prototype = { - /** - * Request the browser to enter fullscreen mode. - * @returns {boolean} Indicating if the request was successful. - */ - request: function PDFPresentationMode_request() { - if (this.switchInProgress || this.active || - !this.viewer.hasChildNodes()) { - return false; - } - this._addFullscreenChangeListeners(); - this._setSwitchInProgress(); - this._notifyStateChange(); + /** + * Request the browser to enter fullscreen mode. + * @returns {boolean} Indicating if the request was successful. + */ + request() { + if (this.switchInProgress || this.active || !this.viewer.hasChildNodes()) { + return false; + } + this._addFullscreenChangeListeners(); + this._setSwitchInProgress(); + this._notifyStateChange(); + + if (this.container.requestFullscreen) { + this.container.requestFullscreen(); + } else if (this.container.mozRequestFullScreen) { + this.container.mozRequestFullScreen(); + } else if (this.container.webkitRequestFullscreen) { + this.container.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT); + } else if (this.container.msRequestFullscreen) { + this.container.msRequestFullscreen(); + } else { + return false; + } - if (this.container.requestFullscreen) { - this.container.requestFullscreen(); - } else if (this.container.mozRequestFullScreen) { - this.container.mozRequestFullScreen(); - } else if (this.container.webkitRequestFullscreen) { - this.container.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT); - } else if (this.container.msRequestFullscreen) { - this.container.msRequestFullscreen(); - } else { - return false; - } + this.args = { + page: this.pdfViewer.currentPageNumber, + previousScale: this.pdfViewer.currentScaleValue, + }; - this.args = { - page: this.pdfViewer.currentPageNumber, - previousScale: this.pdfViewer.currentScaleValue, - }; + return true; + } - return true; - }, + /** + * @private + */ + _mouseWheel(evt) { + if (!this.active) { + return; + } - /** - * @private - */ - _mouseWheel: function PDFPresentationMode_mouseWheel(evt) { - if (!this.active) { - return; + evt.preventDefault(); + + var delta = normalizeWheelEventDelta(evt); + var currentTime = (new Date()).getTime(); + var storedTime = this.mouseScrollTimeStamp; + + // If we've already switched page, avoid accidentally switching again. + if (currentTime > storedTime && + currentTime - storedTime < MOUSE_SCROLL_COOLDOWN_TIME) { + return; + } + // If the scroll direction changed, reset the accumulated scroll delta. + if ((this.mouseScrollDelta > 0 && delta < 0) || + (this.mouseScrollDelta < 0 && delta > 0)) { + this._resetMouseScrollState(); + } + this.mouseScrollDelta += delta; + + if (Math.abs(this.mouseScrollDelta) >= PAGE_SWITCH_THRESHOLD) { + var totalDelta = this.mouseScrollDelta; + this._resetMouseScrollState(); + var success = totalDelta > 0 ? this._goToPreviousPage() + : this._goToNextPage(); + if (success) { + this.mouseScrollTimeStamp = currentTime; } + } + } - evt.preventDefault(); + get isFullscreen() { + return !!(document.fullscreenElement || document.mozFullScreen || + document.webkitIsFullScreen || document.msFullscreenElement); + } - var delta = normalizeWheelEventDelta(evt); + /** + * @private + */ + _goToPreviousPage() { + var page = this.pdfViewer.currentPageNumber; + // If we're at the first page, we don't need to do anything. + if (page <= 1) { + return false; + } + this.pdfViewer.currentPageNumber = (page - 1); + return true; + } - var MOUSE_SCROLL_COOLDOWN_TIME = 50; - var PAGE_SWITCH_THRESHOLD = 0.1; + /** + * @private + */ + _goToNextPage() { + var page = this.pdfViewer.currentPageNumber; + // If we're at the last page, we don't need to do anything. + if (page >= this.pdfViewer.pagesCount) { + return false; + } + this.pdfViewer.currentPageNumber = (page + 1); + return true; + } - var currentTime = (new Date()).getTime(); - var storedTime = this.mouseScrollTimeStamp; + /** + * @private + */ + _notifyStateChange() { + this.eventBus.dispatch('presentationmodechanged', { + source: this, + active: this.active, + switchInProgress: !!this.switchInProgress, + }); + } - // If we've already switched page, avoid accidentally switching again. - if (currentTime > storedTime && - currentTime - storedTime < MOUSE_SCROLL_COOLDOWN_TIME) { - return; - } - // If the scroll direction changed, reset the accumulated scroll delta. - if ((this.mouseScrollDelta > 0 && delta < 0) || - (this.mouseScrollDelta < 0 && delta > 0)) { - this._resetMouseScrollState(); - } - this.mouseScrollDelta += delta; - - if (Math.abs(this.mouseScrollDelta) >= PAGE_SWITCH_THRESHOLD) { - var totalDelta = this.mouseScrollDelta; - this._resetMouseScrollState(); - var success = totalDelta > 0 ? this._goToPreviousPage() - : this._goToNextPage(); - if (success) { - this.mouseScrollTimeStamp = currentTime; - } - } - }, - - get isFullscreen() { - return !!(document.fullscreenElement || - document.mozFullScreen || - document.webkitIsFullScreen || - document.msFullscreenElement); - }, - - /** - * @private - */ - _goToPreviousPage: function PDFPresentationMode_goToPreviousPage() { - var page = this.pdfViewer.currentPageNumber; - // If we're at the first page, we don't need to do anything. - if (page <= 1) { - return false; - } - this.pdfViewer.currentPageNumber = (page - 1); - return true; - }, - - /** - * @private - */ - _goToNextPage: function PDFPresentationMode_goToNextPage() { - var page = this.pdfViewer.currentPageNumber; - // If we're at the last page, we don't need to do anything. - if (page >= this.pdfViewer.pagesCount) { - return false; - } - this.pdfViewer.currentPageNumber = (page + 1); - return true; - }, - - /** - * @private - */ - _notifyStateChange: function PDFPresentationMode_notifyStateChange() { - this.eventBus.dispatch('presentationmodechanged', { - source: this, - active: this.active, - switchInProgress: !!this.switchInProgress - }); - }, - - /** - * Used to initialize a timeout when requesting Presentation Mode, - * i.e. when the browser is requested to enter fullscreen mode. - * This timeout is used to prevent the current page from being scrolled - * partially, or completely, out of view when entering Presentation Mode. - * NOTE: This issue seems limited to certain zoom levels (e.g. page-width). - * @private - */ - _setSwitchInProgress: function PDFPresentationMode_setSwitchInProgress() { - if (this.switchInProgress) { - clearTimeout(this.switchInProgress); - } - this.switchInProgress = setTimeout(function switchInProgressTimeout() { - this._removeFullscreenChangeListeners(); - delete this.switchInProgress; - this._notifyStateChange(); - }.bind(this), DELAY_BEFORE_RESETTING_SWITCH_IN_PROGRESS); - }, - - /** - * @private - */ - _resetSwitchInProgress: - function PDFPresentationMode_resetSwitchInProgress() { - if (this.switchInProgress) { - clearTimeout(this.switchInProgress); - delete this.switchInProgress; - } - }, - - /** - * @private - */ - _enter: function PDFPresentationMode_enter() { - this.active = true; - this._resetSwitchInProgress(); + /** + * Used to initialize a timeout when requesting Presentation Mode, + * i.e. when the browser is requested to enter fullscreen mode. + * This timeout is used to prevent the current page from being scrolled + * partially, or completely, out of view when entering Presentation Mode. + * NOTE: This issue seems limited to certain zoom levels (e.g. page-width). + * + * @private + */ + _setSwitchInProgress() { + if (this.switchInProgress) { + clearTimeout(this.switchInProgress); + } + this.switchInProgress = setTimeout(() => { + this._removeFullscreenChangeListeners(); + delete this.switchInProgress; this._notifyStateChange(); - this.container.classList.add(ACTIVE_SELECTOR); + }, DELAY_BEFORE_RESETTING_SWITCH_IN_PROGRESS); + } - // Ensure that the correct page is scrolled into view when entering - // Presentation Mode, by waiting until fullscreen mode in enabled. - setTimeout(function enterPresentationModeTimeout() { - this.pdfViewer.currentPageNumber = this.args.page; - this.pdfViewer.currentScaleValue = 'page-fit'; - }.bind(this), 0); + /** + * @private + */ + _resetSwitchInProgress() { + if (this.switchInProgress) { + clearTimeout(this.switchInProgress); + delete this.switchInProgress; + } + } - this._addWindowListeners(); - this._showControls(); - this.contextMenuOpen = false; - this.container.setAttribute('contextmenu', 'viewerContextMenu'); - - // Text selection is disabled in Presentation Mode, thus it's not possible - // for the user to deselect text that is selected (e.g. with "Select all") - // when entering Presentation Mode, hence we remove any active selection. - window.getSelection().removeAllRanges(); - }, - - /** - * @private - */ - _exit: function PDFPresentationMode_exit() { - var page = this.pdfViewer.currentPageNumber; - this.container.classList.remove(ACTIVE_SELECTOR); - - // Ensure that the correct page is scrolled into view when exiting - // Presentation Mode, by waiting until fullscreen mode is disabled. - setTimeout(function exitPresentationModeTimeout() { - this.active = false; - this._removeFullscreenChangeListeners(); - this._notifyStateChange(); - - this.pdfViewer.currentScaleValue = this.args.previousScale; - this.pdfViewer.currentPageNumber = page; - this.args = null; - }.bind(this), 0); - - this._removeWindowListeners(); - this._hideControls(); - this._resetMouseScrollState(); - this.container.removeAttribute('contextmenu'); - this.contextMenuOpen = false; - }, + /** + * @private + */ + _enter() { + this.active = true; + this._resetSwitchInProgress(); + this._notifyStateChange(); + this.container.classList.add(ACTIVE_SELECTOR); + + // Ensure that the correct page is scrolled into view when entering + // Presentation Mode, by waiting until fullscreen mode in enabled. + setTimeout(() => { + this.pdfViewer.currentPageNumber = this.args.page; + this.pdfViewer.currentScaleValue = 'page-fit'; + }, 0); + + this._addWindowListeners(); + this._showControls(); + this.contextMenuOpen = false; + this.container.setAttribute('contextmenu', 'viewerContextMenu'); - /** - * @private - */ - _mouseDown: function PDFPresentationMode_mouseDown(evt) { - if (this.contextMenuOpen) { - this.contextMenuOpen = false; + // Text selection is disabled in Presentation Mode, thus it's not possible + // for the user to deselect text that is selected (e.g. with "Select all") + // when entering Presentation Mode, hence we remove any active selection. + window.getSelection().removeAllRanges(); + } + + /** + * @private + */ + _exit() { + var page = this.pdfViewer.currentPageNumber; + this.container.classList.remove(ACTIVE_SELECTOR); + + // Ensure that the correct page is scrolled into view when exiting + // Presentation Mode, by waiting until fullscreen mode is disabled. + setTimeout(() => { + this.active = false; + this._removeFullscreenChangeListeners(); + this._notifyStateChange(); + + this.pdfViewer.currentScaleValue = this.args.previousScale; + this.pdfViewer.currentPageNumber = page; + this.args = null; + }, 0); + + this._removeWindowListeners(); + this._hideControls(); + this._resetMouseScrollState(); + this.container.removeAttribute('contextmenu'); + this.contextMenuOpen = false; + } + + /** + * @private + */ + _mouseDown(evt) { + if (this.contextMenuOpen) { + this.contextMenuOpen = false; + evt.preventDefault(); + return; + } + if (evt.button === 0) { + // Enable clicking of links in presentation mode. Note: only links + // pointing to destinations in the current PDF document work. + var isInternalLink = (evt.target.href && + evt.target.classList.contains('internalLink')); + if (!isInternalLink) { + // Unless an internal link was clicked, advance one page. evt.preventDefault(); - return; - } - if (evt.button === 0) { - // Enable clicking of links in presentation mode. Please note: - // Only links pointing to destinations in the current PDF document work. - var isInternalLink = (evt.target.href && - evt.target.classList.contains('internalLink')); - if (!isInternalLink) { - // Unless an internal link was clicked, advance one page. - evt.preventDefault(); - this.pdfViewer.currentPageNumber += (evt.shiftKey ? -1 : 1); - } - } - }, - - /** - * @private - */ - _contextMenu: function PDFPresentationMode_contextMenu() { - this.contextMenuOpen = true; - }, - - /** - * @private - */ - _showControls: function PDFPresentationMode_showControls() { - if (this.controlsTimeout) { - clearTimeout(this.controlsTimeout); - } else { - this.container.classList.add(CONTROLS_SELECTOR); - } - this.controlsTimeout = setTimeout(function showControlsTimeout() { - this.container.classList.remove(CONTROLS_SELECTOR); - delete this.controlsTimeout; - }.bind(this), DELAY_BEFORE_HIDING_CONTROLS); - }, - - /** - * @private - */ - _hideControls: function PDFPresentationMode_hideControls() { - if (!this.controlsTimeout) { - return; + this.pdfViewer.currentPageNumber += (evt.shiftKey ? -1 : 1); } + } + } + + /** + * @private + */ + _contextMenu() { + this.contextMenuOpen = true; + } + + /** + * @private + */ + _showControls() { + if (this.controlsTimeout) { clearTimeout(this.controlsTimeout); + } else { + this.container.classList.add(CONTROLS_SELECTOR); + } + this.controlsTimeout = setTimeout(() => { this.container.classList.remove(CONTROLS_SELECTOR); delete this.controlsTimeout; - }, - - /** - * Resets the properties used for tracking mouse scrolling events. - * @private - */ - _resetMouseScrollState: - function PDFPresentationMode_resetMouseScrollState() { - this.mouseScrollTimeStamp = 0; - this.mouseScrollDelta = 0; - }, - - /** - * @private - */ - _touchSwipe: function PDFPresentationMode_touchSwipe(evt) { - if (!this.active) { - return; - } + }, DELAY_BEFORE_HIDING_CONTROLS); + } - // Must move at least these many CSS pixels for it to count as a swipe - var SWIPE_MIN_DISTANCE_THRESHOLD = 50; - // The swipe angle is allowed to deviate from the x or y axis by this much - // before it is not considered a swipe in that direction any more. - var SWIPE_ANGLE_THRESHOLD = Math.PI / 6; + /** + * @private + */ + _hideControls() { + if (!this.controlsTimeout) { + return; + } + clearTimeout(this.controlsTimeout); + this.container.classList.remove(CONTROLS_SELECTOR); + delete this.controlsTimeout; + } - if (evt.touches.length > 1) { - // Multiple touch points detected, cancel the swipe. - this.touchSwipeState = null; - return; - } - switch (evt.type) { - case 'touchstart': - this.touchSwipeState = { - startX: evt.touches[0].pageX, - startY: evt.touches[0].pageY, - endX: evt.touches[0].pageX, - endY: evt.touches[0].pageY - }; - break; - case 'touchmove': - if (this.touchSwipeState === null) { - return; - } - this.touchSwipeState.endX = evt.touches[0].pageX; - this.touchSwipeState.endY = evt.touches[0].pageY; - // Do a preventDefault to avoid the swipe from triggering browser - // gestures (Chrome in particular has some sort of swipe gesture in - // fullscreen mode). - evt.preventDefault(); - break; - case 'touchend': - if (this.touchSwipeState === null) { - return; - } - var delta = 0; - var dx = this.touchSwipeState.endX - this.touchSwipeState.startX; - var dy = this.touchSwipeState.endY - this.touchSwipeState.startY; - var absAngle = Math.abs(Math.atan2(dy, dx)); - if (Math.abs(dx) > SWIPE_MIN_DISTANCE_THRESHOLD && - (absAngle <= SWIPE_ANGLE_THRESHOLD || - absAngle >= (Math.PI - SWIPE_ANGLE_THRESHOLD))) { - // horizontal swipe - delta = dx; - } else if (Math.abs(dy) > SWIPE_MIN_DISTANCE_THRESHOLD && - Math.abs(absAngle - (Math.PI / 2)) <= SWIPE_ANGLE_THRESHOLD) { - // vertical swipe - delta = dy; - } - if (delta > 0) { - this._goToPreviousPage(); - } else if (delta < 0) { - this._goToNextPage(); - } - break; - } - }, - - /** - * @private - */ - _addWindowListeners: function PDFPresentationMode_addWindowListeners() { - this.showControlsBind = this._showControls.bind(this); - this.mouseDownBind = this._mouseDown.bind(this); - this.mouseWheelBind = this._mouseWheel.bind(this); - this.resetMouseScrollStateBind = this._resetMouseScrollState.bind(this); - this.contextMenuBind = this._contextMenu.bind(this); - this.touchSwipeBind = this._touchSwipe.bind(this); - - window.addEventListener('mousemove', this.showControlsBind); - window.addEventListener('mousedown', this.mouseDownBind); - window.addEventListener('wheel', this.mouseWheelBind); - window.addEventListener('keydown', this.resetMouseScrollStateBind); - window.addEventListener('contextmenu', this.contextMenuBind); - window.addEventListener('touchstart', this.touchSwipeBind); - window.addEventListener('touchmove', this.touchSwipeBind); - window.addEventListener('touchend', this.touchSwipeBind); - }, - - /** - * @private - */ - _removeWindowListeners: - function PDFPresentationMode_removeWindowListeners() { - window.removeEventListener('mousemove', this.showControlsBind); - window.removeEventListener('mousedown', this.mouseDownBind); - window.removeEventListener('wheel', this.mouseWheelBind); - window.removeEventListener('keydown', this.resetMouseScrollStateBind); - window.removeEventListener('contextmenu', this.contextMenuBind); - window.removeEventListener('touchstart', this.touchSwipeBind); - window.removeEventListener('touchmove', this.touchSwipeBind); - window.removeEventListener('touchend', this.touchSwipeBind); - - delete this.showControlsBind; - delete this.mouseDownBind; - delete this.mouseWheelBind; - delete this.resetMouseScrollStateBind; - delete this.contextMenuBind; - delete this.touchSwipeBind; - }, - - /** - * @private - */ - _fullscreenChange: function PDFPresentationMode_fullscreenChange() { - if (this.isFullscreen) { - this._enter(); - } else { - this._exit(); - } - }, - - /** - * @private - */ - _addFullscreenChangeListeners: - function PDFPresentationMode_addFullscreenChangeListeners() { - this.fullscreenChangeBind = this._fullscreenChange.bind(this); - - window.addEventListener('fullscreenchange', this.fullscreenChangeBind); - window.addEventListener('mozfullscreenchange', this.fullscreenChangeBind); - if (typeof PDFJSDev === 'undefined' || - !PDFJSDev.test('FIREFOX || MOZCENTRAL')) { - window.addEventListener('webkitfullscreenchange', - this.fullscreenChangeBind); - window.addEventListener('MSFullscreenChange', - this.fullscreenChangeBind); - } - }, - - /** - * @private - */ - _removeFullscreenChangeListeners: - function PDFPresentationMode_removeFullscreenChangeListeners() { - window.removeEventListener('fullscreenchange', this.fullscreenChangeBind); - window.removeEventListener('mozfullscreenchange', - this.fullscreenChangeBind); - if (typeof PDFJSDev === 'undefined' || - !PDFJSDev.test('FIREFOX || MOZCENTRAL')) { - window.removeEventListener('webkitfullscreenchange', - this.fullscreenChangeBind); - window.removeEventListener('MSFullscreenChange', - this.fullscreenChangeBind); - } + /** + * Resets the properties used for tracking mouse scrolling events. + * + * @private + */ + _resetMouseScrollState() { + this.mouseScrollTimeStamp = 0; + this.mouseScrollDelta = 0; + } - delete this.fullscreenChangeBind; + /** + * @private + */ + _touchSwipe(evt) { + if (!this.active) { + return; + } + if (evt.touches.length > 1) { + // Multiple touch points detected; cancel the swipe. + this.touchSwipeState = null; + return; + } + + switch (evt.type) { + case 'touchstart': + this.touchSwipeState = { + startX: evt.touches[0].pageX, + startY: evt.touches[0].pageY, + endX: evt.touches[0].pageX, + endY: evt.touches[0].pageY, + }; + break; + case 'touchmove': + if (this.touchSwipeState === null) { + return; + } + this.touchSwipeState.endX = evt.touches[0].pageX; + this.touchSwipeState.endY = evt.touches[0].pageY; + // Avoid the swipe from triggering browser gestures (Chrome in + // particular has some sort of swipe gesture in fullscreen mode). + evt.preventDefault(); + break; + case 'touchend': + if (this.touchSwipeState === null) { + return; + } + var delta = 0; + var dx = this.touchSwipeState.endX - this.touchSwipeState.startX; + var dy = this.touchSwipeState.endY - this.touchSwipeState.startY; + var absAngle = Math.abs(Math.atan2(dy, dx)); + if (Math.abs(dx) > SWIPE_MIN_DISTANCE_THRESHOLD && + (absAngle <= SWIPE_ANGLE_THRESHOLD || + absAngle >= (Math.PI - SWIPE_ANGLE_THRESHOLD))) { + // Horizontal swipe. + delta = dx; + } else if (Math.abs(dy) > SWIPE_MIN_DISTANCE_THRESHOLD && + Math.abs(absAngle - (Math.PI / 2)) <= SWIPE_ANGLE_THRESHOLD) { + // Vertical swipe. + delta = dy; + } + if (delta > 0) { + this._goToPreviousPage(); + } else if (delta < 0) { + this._goToNextPage(); + } + break; + } + } + + /** + * @private + */ + _addWindowListeners() { + this.showControlsBind = this._showControls.bind(this); + this.mouseDownBind = this._mouseDown.bind(this); + this.mouseWheelBind = this._mouseWheel.bind(this); + this.resetMouseScrollStateBind = this._resetMouseScrollState.bind(this); + this.contextMenuBind = this._contextMenu.bind(this); + this.touchSwipeBind = this._touchSwipe.bind(this); + + window.addEventListener('mousemove', this.showControlsBind); + window.addEventListener('mousedown', this.mouseDownBind); + window.addEventListener('wheel', this.mouseWheelBind); + window.addEventListener('keydown', this.resetMouseScrollStateBind); + window.addEventListener('contextmenu', this.contextMenuBind); + window.addEventListener('touchstart', this.touchSwipeBind); + window.addEventListener('touchmove', this.touchSwipeBind); + window.addEventListener('touchend', this.touchSwipeBind); + } + + /** + * @private + */ + _removeWindowListeners() { + window.removeEventListener('mousemove', this.showControlsBind); + window.removeEventListener('mousedown', this.mouseDownBind); + window.removeEventListener('wheel', this.mouseWheelBind); + window.removeEventListener('keydown', this.resetMouseScrollStateBind); + window.removeEventListener('contextmenu', this.contextMenuBind); + window.removeEventListener('touchstart', this.touchSwipeBind); + window.removeEventListener('touchmove', this.touchSwipeBind); + window.removeEventListener('touchend', this.touchSwipeBind); + + delete this.showControlsBind; + delete this.mouseDownBind; + delete this.mouseWheelBind; + delete this.resetMouseScrollStateBind; + delete this.contextMenuBind; + delete this.touchSwipeBind; + } + + /** + * @private + */ + _fullscreenChange() { + if (this.isFullscreen) { + this._enter(); + } else { + this._exit(); + } + } + + /** + * @private + */ + _addFullscreenChangeListeners() { + this.fullscreenChangeBind = this._fullscreenChange.bind(this); + + window.addEventListener('fullscreenchange', this.fullscreenChangeBind); + window.addEventListener('mozfullscreenchange', this.fullscreenChangeBind); + if (typeof PDFJSDev === 'undefined' || + !PDFJSDev.test('FIREFOX || MOZCENTRAL')) { + window.addEventListener('webkitfullscreenchange', + this.fullscreenChangeBind); + window.addEventListener('MSFullscreenChange', + this.fullscreenChangeBind); } - }; + } - return PDFPresentationMode; -})(); + /** + * @private + */ + _removeFullscreenChangeListeners() { + window.removeEventListener('fullscreenchange', this.fullscreenChangeBind); + window.removeEventListener('mozfullscreenchange', + this.fullscreenChangeBind); + if (typeof PDFJSDev === 'undefined' || + !PDFJSDev.test('FIREFOX || MOZCENTRAL')) { + window.removeEventListener('webkitfullscreenchange', + this.fullscreenChangeBind); + window.removeEventListener('MSFullscreenChange', + this.fullscreenChangeBind); + } + + delete this.fullscreenChangeBind; + } +} export { PDFPresentationMode,