-
Notifications
You must be signed in to change notification settings - Fork 116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New: Allow scrolling for multi-page image files #308
Merged
Merged
Changes from 5 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
d1434f1
New: Allow scrolling for multi-page image files
pramodsum a9ebfc6
Chore: unit tests
pramodsum 8c52781
New: Adding page number info/controls to the MultiImageViewer
pramodsum f1580d8
New: Updating multi-image page numbers on scroll
pramodsum 8da02a4
Chore: Moving strings into constants
pramodsum 9e6a9ec
Fix: Only check next page if one exists
pramodsum d266bea
Chore: PR cleanup
pramodsum e13756a
Chore: unit tests
pramodsum 8cdc415
Chore: The rest of the unit tests
pramodsum 10876d7
Merge branch 'master' into annotations
pramodsum c356a5f
Chore: last unit tests fix
pramodsum 8a0467d
Chore: Actually using the correct previousPage() method
pramodsum File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,231 @@ | ||
import EventEmitter from 'events'; | ||
import fullscreen from './Fullscreen'; | ||
import Browser from './Browser'; | ||
import { decodeKeydown } from './util'; | ||
import { ICON_DROP_DOWN, ICON_DROP_UP } from './icons/icons'; | ||
|
||
const SHOW_PAGE_NUM_INPUT_CLASS = 'show-page-number-input'; | ||
const CONTROLS_PAGE_NUM_WRAPPER_CLASS = 'bp-page-num-wrapper'; | ||
const CONTROLS_CURRENT_PAGE = 'bp-current-page'; | ||
const CONTROLS_PAGE_NUM_INPUT_CLASS = 'bp-page-num-input'; | ||
const CONTROLS_TOTAL_PAGES = 'bp-total-pages'; | ||
const PAGE_NUM = 'bp-page-num'; | ||
const PREV_PAGE = 'bp-previous-page'; | ||
const NEXT_PAGE = 'bp-next-page'; | ||
|
||
const pageNumTemplate = ` | ||
<div class='${CONTROLS_PAGE_NUM_WRAPPER_CLASS}'> | ||
<span class=${CONTROLS_CURRENT_PAGE}>1</span> | ||
<input type='number' pattern='[0-9]*' min='1' value='' size='3' class='${CONTROLS_PAGE_NUM_INPUT_CLASS}' /> | ||
<span class='bp-page-num-divider'> / </span> | ||
<span class='${CONTROLS_TOTAL_PAGES}'>1</span> | ||
</div>`.replace(/>\s*</g, '><'); | ||
|
||
class PageControls extends EventEmitter { | ||
/** | ||
* [constructor] | ||
* | ||
* @param {HTMLElement} controls - Viewer controls | ||
* @param {Function} previousPage - Previous page handler | ||
* @param {Function} nextPage - Next page handler | ||
* @return {Controls} Instance of controls | ||
*/ | ||
constructor(controls, previousPage, nextPage) { | ||
super(); | ||
|
||
this.controls = controls; | ||
this.controlsEl = controls.controlsEl; | ||
this.currentPageEl = controls.currentPageEl; | ||
this.pageNumInputEl = controls.pageNumInputEl; | ||
|
||
this.controls.add(__('previous_page'), previousPage, `bp-previous-page-icon ${PREV_PAGE}`, ICON_DROP_UP); | ||
this.controls.add(__('enter_page_num'), this.showPageNumInput.bind(this), PAGE_NUM, pageNumTemplate); | ||
this.controls.add(__('next_page'), nextPage, `bp-next-page-icon ${NEXT_PAGE}`, ICON_DROP_DOWN); | ||
} | ||
|
||
/** | ||
* Initializes page number selector. | ||
* | ||
* @private | ||
* @param {number} pagesCount - Total number of page | ||
* @return {void} | ||
*/ | ||
init(pagesCount) { | ||
const pageNumEl = this.controlsEl.querySelector(`.${PAGE_NUM}`); | ||
this.pagesCount = pagesCount; | ||
|
||
// Update total page number | ||
const totalPageEl = pageNumEl.querySelector(`.${CONTROLS_TOTAL_PAGES}`); | ||
totalPageEl.textContent = pagesCount; | ||
|
||
// Keep reference to page number input and current page elements | ||
this.pageNumInputEl = pageNumEl.querySelector(`.${CONTROLS_PAGE_NUM_INPUT_CLASS}`); | ||
this.pageNumInputEl.setAttribute('max', pagesCount); | ||
|
||
this.currentPageEl = pageNumEl.querySelector(`.${CONTROLS_CURRENT_PAGE}`); | ||
} | ||
|
||
/** | ||
* Replaces the page number display with an input box that allows the user to type in a page number | ||
* | ||
* @private | ||
* @return {void} | ||
*/ | ||
showPageNumInput() { | ||
// show the input box with the current page number selected within it | ||
this.controlsEl.classList.add(SHOW_PAGE_NUM_INPUT_CLASS); | ||
|
||
this.pageNumInputEl.value = this.currentPageEl.textContent; | ||
this.pageNumInputEl.focus(); | ||
this.pageNumInputEl.select(); | ||
|
||
// finish input when input is blurred or enter key is pressed | ||
this.pageNumInputEl.addEventListener('blur', this.pageNumInputBlurHandler.bind(this)); | ||
this.pageNumInputEl.addEventListener('keydown', this.pageNumInputKeydownHandler.bind(this)); | ||
} | ||
|
||
/** | ||
* Hide the page number input | ||
* | ||
* @private | ||
* @return {void} | ||
*/ | ||
hidePageNumInput() { | ||
this.controlsEl.classList.remove(SHOW_PAGE_NUM_INPUT_CLASS); | ||
this.pageNumInputEl.removeEventListener('blur', this.pageNumInputBlurHandler); | ||
this.pageNumInputEl.removeEventListener('keydown', this.pageNumInputKeydownHandler); | ||
} | ||
|
||
/** | ||
* Disables or enables previous/next pagination buttons depending on | ||
* current page number. | ||
* | ||
* @param {number} currentPageNum - Current page number | ||
* @param {number} pagesCount - Total number of page | ||
* @return {void} | ||
*/ | ||
checkPaginationButtons(currentPageNum, pagesCount) { | ||
const pageNumButtonEl = this.controlsEl.querySelector(`.${PAGE_NUM}`); | ||
const previousPageButtonEl = this.controlsEl.querySelector(`${PREV_PAGE}`); | ||
const nextPageButtonEl = this.controlsEl.querySelector(`.${NEXT_PAGE}`); | ||
|
||
// Safari disables keyboard input in fullscreen before Safari 10.1 | ||
const isSafariFullscreen = Browser.getName() === 'Safari' && fullscreen.isFullscreen(this.controlsEl); | ||
|
||
// Disable page number selector if there is only one page or less | ||
if (pageNumButtonEl) { | ||
if (pagesCount <= 1 || isSafariFullscreen) { | ||
pageNumButtonEl.disabled = true; | ||
} else { | ||
pageNumButtonEl.disabled = false; | ||
} | ||
} | ||
|
||
// Disable previous page if on first page, otherwise enable | ||
if (previousPageButtonEl) { | ||
if (currentPageNum === 1) { | ||
previousPageButtonEl.disabled = true; | ||
} else { | ||
previousPageButtonEl.disabled = false; | ||
} | ||
} | ||
|
||
// Disable next page if on last page, otherwise enable | ||
if (nextPageButtonEl) { | ||
if (currentPageNum === pagesCount) { | ||
nextPageButtonEl.disabled = true; | ||
} else { | ||
nextPageButtonEl.disabled = false; | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Update page number in page control widget. | ||
* | ||
* @private | ||
* @param {number} pageNum - Number of page to update to | ||
* @return {void} | ||
*/ | ||
updateCurrentPage(pageNum) { | ||
let truePageNum = pageNum; | ||
|
||
// refine the page number to fall within bounds | ||
if (pageNum > this.pagesCount) { | ||
truePageNum = this.pagesCount; | ||
} else if (pageNum < 1) { | ||
truePageNum = 1; | ||
} | ||
|
||
if (this.pageNumInputEl) { | ||
this.pageNumInputEl.value = truePageNum; | ||
} | ||
|
||
if (this.currentPageEl) { | ||
this.currentPageEl.textContent = truePageNum; | ||
} | ||
|
||
this.currentPageNumber = truePageNum; | ||
this.checkPaginationButtons(this.currentPageNumber, this.pagesCount); | ||
} | ||
|
||
/** | ||
* Blur handler for page number input. | ||
* | ||
* @private | ||
* @param {Event} event Blur event | ||
* @return {void} | ||
*/ | ||
pageNumInputBlurHandler(event) { | ||
const target = event.target; | ||
const pageNum = parseInt(target.value, 10); | ||
|
||
if (!isNaN(pageNum)) { | ||
this.emit('setpage', pageNum); | ||
} | ||
|
||
this.hidePageNumInput(); | ||
} | ||
|
||
/** | ||
* Keydown handler for page number input. | ||
* | ||
* @private | ||
* @param {Event} event - Keydown event | ||
* @return {void} | ||
*/ | ||
pageNumInputKeydownHandler(event) { | ||
const key = decodeKeydown(event); | ||
|
||
switch (key) { | ||
case 'Enter': | ||
case 'Tab': | ||
// The keycode of the 'next' key on Android Chrome is 9, which maps to 'Tab'. | ||
// this.docEl.focus(); | ||
// We normally trigger the blur handler by blurring the input | ||
// field, but this doesn't work for IE in fullscreen. For IE, | ||
// we blur the page behind the controls - this unfortunately | ||
// is an IE-only solution that doesn't work with other browsers | ||
if (Browser.getName() !== 'Explorer') { | ||
event.target.blur(); | ||
} | ||
|
||
event.stopPropagation(); | ||
event.preventDefault(); | ||
break; | ||
|
||
case 'Escape': | ||
this.hidePageNumInput(); | ||
// this.docEl.focus(); | ||
|
||
event.stopPropagation(); | ||
event.preventDefault(); | ||
break; | ||
|
||
default: | ||
break; | ||
} | ||
} | ||
} | ||
|
||
export default PageControls; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removing