Skip to content

Commit

Permalink
Add scrolling modes to web viewer
Browse files Browse the repository at this point in the history
In addition to the default scrolling mode (vertical), this commit adds
horizontal, grid, and grid+cover scrolling, implemented primarily with
flexbox CSS.
  • Loading branch information
rhendric committed Dec 13, 2017
1 parent e320243 commit 8b4dc92
Show file tree
Hide file tree
Showing 17 changed files with 165 additions and 3 deletions.
9 changes: 9 additions & 0 deletions l10n/en-US/viewer.properties
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,15 @@ cursor_text_select_tool_label=Text Selection Tool
cursor_hand_tool.title=Enable Hand Tool
cursor_hand_tool_label=Hand Tool

scroll_vertical.title=Use Vertical Scrolling
scroll_vertical_label=Vertical Scrolling
scroll_horizontal.title=Use Horizontal Scrolling
scroll_horizontal_label=Horizontal Scrolling
scroll_grid.title=Use Grid Scrolling
scroll_grid_label=Grid Scrolling
scroll_grid_cover.title=Use Grid Scrolling with a Cover Page
scroll_grid_cover_label=Grid Scrolling with Cover Page

# Document properties dialog box
document_properties.title=Document Properties…
document_properties_label=Document Properties…
Expand Down
5 changes: 5 additions & 0 deletions web/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -1367,6 +1367,7 @@ let PDFViewerApplication = {
eventBus.on('scalechanged', webViewerScaleChanged);
eventBus.on('rotatecw', webViewerRotateCw);
eventBus.on('rotateccw', webViewerRotateCcw);
eventBus.on('switchscrollmode', webViewerSwitchScrollMode);
eventBus.on('documentproperties', webViewerDocumentProperties);
eventBus.on('find', webViewerFind);
eventBus.on('findfromurlhash', webViewerFindFromUrlHash);
Expand Down Expand Up @@ -1433,6 +1434,7 @@ let PDFViewerApplication = {
eventBus.off('scalechanged', webViewerScaleChanged);
eventBus.off('rotatecw', webViewerRotateCw);
eventBus.off('rotateccw', webViewerRotateCcw);
eventBus.off('switchscrollmode', webViewerSwitchScrollMode);
eventBus.off('documentproperties', webViewerDocumentProperties);
eventBus.off('find', webViewerFind);
eventBus.off('findfromurlhash', webViewerFindFromUrlHash);
Expand Down Expand Up @@ -1908,6 +1910,9 @@ function webViewerRotateCw() {
function webViewerRotateCcw() {
PDFViewerApplication.rotatePages(-90);
}
function webViewerSwitchScrollMode(evt) {
PDFViewerApplication.pdfViewer.setScrollMode(evt.mode);
}
function webViewerDocumentProperties() {
PDFViewerApplication.pdfDocumentProperties.open();
}
Expand Down
Binary file added web/images/secondaryToolbarButton-scrollGrid.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added web/images/secondaryToolbarButton-scrollGrid@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added web/images/secondaryToolbarButton-scrollVertical.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 37 additions & 0 deletions web/pdf_viewer.css
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
background-clip: content-box;
border-image: url(images/shadow.png) 9 9 repeat;
background-color: white;
flex-shrink: 0;
}

.pdfViewer.removePageBorders .page {
Expand All @@ -46,6 +47,33 @@
border: none;
}

.pdfViewer.scrollHorizontal, .pdfViewer.scrollGrid {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 8px;
min-width: -moz-min-content;
min-width: min-content;
}

.pdfViewer.scrollGrid {
flex-wrap: wrap;
}

.pdfViewer.scrollGrid.coverPage::before {
content: '';
width: 100%;
}

.pdfViewer.scrollHorizontal .page, .pdfViewer.scrollGrid .page {
margin-left: -4px;
margin-right: -4px;
}

.pdfViewer.scrollGrid.coverPage .page:first-child {
order: -1;
}

.pdfViewer .page canvas {
margin: 0;
display: block;
Expand All @@ -65,6 +93,15 @@
background: url('images/loading-icon.gif') center no-repeat;
}

.pdfPresentationMode .pdfViewer {
display: block;
}

.pdfPresentationMode .pdfViewer .page {
margin-left: auto;
margin-right: auto;
}

.pdfPresentationMode:-webkit-full-screen .pdfViewer .page {
margin-bottom: 100%;
border: 0;
Expand Down
30 changes: 30 additions & 0 deletions web/pdf_viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,22 @@ import { getVisibleElements, scrollIntoView } from './ui_utils';
import { BaseViewer } from './base_viewer';
import { shadow } from 'pdfjs-lib';

const ScrollMode = {
VERTICAL: 0, // The default value.
HORIZONTAL: 1,
GRID: 2,
GRID_COVER: 3,
};

class PDFViewer extends BaseViewer {
get _setDocumentViewerElement() {
return shadow(this, '_setDocumentViewerElement', this.viewer);
}

_scrollIntoView({ pageDiv, pageSpot = null, }) {
if (!pageSpot && this._isHorizontallyScrolling) {
pageSpot = { left: 0, top: 0, };
}
scrollIntoView(pageDiv, pageSpot);
}

Expand Down Expand Up @@ -76,8 +86,28 @@ class PDFViewer extends BaseViewer {
location: this._location,
});
}

setScrollMode(mode) {
this.viewer.classList.remove('scrollHorizontal', 'scrollGrid', 'coverPage');
this._isHorizontallyScrolling = false;
switch (mode) {
case ScrollMode.HORIZONTAL:
this._isHorizontallyScrolling = true;
this.viewer.classList.add('scrollHorizontal');
break;
case ScrollMode.GRID_COVER:
this.viewer.classList.add('coverPage');
// fallthrough
case ScrollMode.GRID:
this.viewer.classList.add('scrollGrid');
break;
}
this.eventBus.dispatch('scrollmodechanged', { mode, });
this.scrollPageIntoView({ pageNumber: this._currentPageNumber, });
}
}

export {
PDFViewer,
ScrollMode,
};
31 changes: 30 additions & 1 deletion web/secondary_toolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import { CursorTool } from './pdf_cursor_tools';
import { SCROLLBAR_PADDING } from './ui_utils';
import { ScrollMode } from './pdf_viewer';

/**
* @typedef {Object} SecondaryToolbarOptions
Expand Down Expand Up @@ -76,6 +77,14 @@ class SecondaryToolbar {
eventDetails: { tool: CursorTool.SELECT, }, close: true, },
{ element: options.cursorHandToolButton, eventName: 'switchcursortool',
eventDetails: { tool: CursorTool.HAND, }, close: true, },
{ element: options.scrollVerticalButton, eventName: 'switchscrollmode',
eventDetails: { mode: ScrollMode.VERTICAL, }, close: true, },
{ element: options.scrollHorizontalButton, eventName: 'switchscrollmode',
eventDetails: { mode: ScrollMode.HORIZONTAL, }, close: true, },
{ element: options.scrollGridButton, eventName: 'switchscrollmode',
eventDetails: { mode: ScrollMode.GRID, }, close: true, },
{ element: options.scrollGridCoverButton, eventName: 'switchscrollmode',
eventDetails: { mode: ScrollMode.GRID_COVER, }, close: true, },
{ element: options.documentPropertiesButton,
eventName: 'documentproperties', close: true, },
];
Expand All @@ -95,9 +104,10 @@ class SecondaryToolbar {

this.reset();

// Bind the event listeners for click and cursor tool actions.
// Bind the event listeners for click, cursor tool, and scroll mode actions.
this._bindClickListeners();
this._bindCursorToolsListener(options);
this._bindScrollModeListener(options);

// Bind the event listener for adjusting the 'max-height' of the toolbar.
this.eventBus.on('resize', this._setMaxHeight.bind(this));
Expand Down Expand Up @@ -172,6 +182,25 @@ class SecondaryToolbar {
});
}

_bindScrollModeListener(buttons) {
this.eventBus.on('scrollmodechanged', function(evt) {
const scrollModeButtons = [];
scrollModeButtons[ScrollMode.VERTICAL] = buttons.scrollVerticalButton;
scrollModeButtons[ScrollMode.HORIZONTAL] = buttons.scrollHorizontalButton;
scrollModeButtons[ScrollMode.GRID] = buttons.scrollGridButton;
scrollModeButtons[ScrollMode.GRID_COVER] = buttons.scrollGridCoverButton;

for (let i = 0; i < scrollModeButtons.length; i++) {
const { classList, } = scrollModeButtons[i];
if (i === evt.mode) {
classList.add('toggled');
} else {
classList.remove('toggled');
}
}
});
}

open() {
if (this.opened) {
return;
Expand Down
3 changes: 2 additions & 1 deletion web/ui_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,8 @@ function scrollIntoView(element, spot, skipOverflowHiddenElements = false) {
}
let offsetY = element.offsetTop + element.clientTop;
let offsetX = element.offsetLeft + element.clientLeft;
while (parent.clientHeight === parent.scrollHeight ||
while ((parent.clientHeight === parent.scrollHeight &&
parent.clientWidth === parent.scrollWidth) ||
(skipOverflowHiddenElements &&
getComputedStyle(parent).overflow === 'hidden')) {
if (parent.dataset._scaleY) {
Expand Down
32 changes: 32 additions & 0 deletions web/viewer.css
Original file line number Diff line number Diff line change
Expand Up @@ -1064,6 +1064,22 @@ html[dir="rtl"] .secondaryToolbarButton > span {
content: url(images/secondaryToolbarButton-handTool.png);
}

.secondaryToolbarButton.scrollVertical::before {
content: url(images/secondaryToolbarButton-scrollVertical.png);
}

.secondaryToolbarButton.scrollHorizontal::before {
content: url(images/secondaryToolbarButton-scrollHorizontal.png);
}

.secondaryToolbarButton.scrollGrid::before {
content: url(images/secondaryToolbarButton-scrollGrid.png);
}

.secondaryToolbarButton.scrollGridCover::before {
content: url(images/secondaryToolbarButton-scrollGridCover.png);
}

.secondaryToolbarButton.documentProperties::before {
content: url(images/secondaryToolbarButton-documentProperties.png);
}
Expand Down Expand Up @@ -1798,6 +1814,22 @@ html[dir='rtl'] #documentPropertiesOverlay .row > * {
content: url(images/secondaryToolbarButton-handTool@2x.png);
}

.secondaryToolbarButton.scrollVertical::before {
content: url(images/secondaryToolbarButton-scrollVertical@2x.png);
}

.secondaryToolbarButton.scrollHorizontal::before {
content: url(images/secondaryToolbarButton-scrollHorizontal@2x.png);
}

.secondaryToolbarButton.scrollGrid::before {
content: url(images/secondaryToolbarButton-scrollGrid@2x.png);
}

.secondaryToolbarButton.scrollGridCover::before {
content: url(images/secondaryToolbarButton-scrollGridCover@2x.png);
}

.secondaryToolbarButton.documentProperties::before {
content: url(images/secondaryToolbarButton-documentProperties@2x.png);
}
Expand Down
17 changes: 16 additions & 1 deletion web/viewer.html
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,22 @@

<div class="horizontalToolbarSeparator"></div>

<button id="documentProperties" class="secondaryToolbarButton documentProperties" title="Document Properties…" tabindex="62" data-l10n-id="document_properties">
<button id="scrollVertical" class="secondaryToolbarButton scrollVertical toggled" title="Use Vertical Scrolling" tabindex="62" data-l10n-id="scroll_vertical">
<span data-l10n-id="scroll_vertical_label">Vertical Scrolling</span>
</button>
<button id="scrollHorizontal" class="secondaryToolbarButton scrollHorizontal" title="Use Horizontal Scrolling" tabindex="63" data-l10n-id="scroll_horizontal">
<span data-l10n-id="scroll_horizontal_label">Horizontal Scrolling</span>
</button>
<button id="scrollGrid" class="secondaryToolbarButton scrollGrid" title="Use Grid Scrolling" tabindex="64" data-l10n-id="scroll_grid">
<span data-l10n-id="scroll_grid_label">Grid Scrolling</span>
</button>
<button id="scrollGridCover" class="secondaryToolbarButton scrollGridCover" title="Use Grid Scrolling with a Cover Page" tabindex="65" data-l10n-id="scroll_grid_cover">
<span data-l10n-id="scroll_grid_cover_label">Grid Scrolling with Cover Page</span>
</button>

<div class="horizontalToolbarSeparator"></div>

<button id="documentProperties" class="secondaryToolbarButton documentProperties" title="Document Properties…" tabindex="66" data-l10n-id="document_properties">
<span data-l10n-id="document_properties_label">Document Properties…</span>
</button>
</div>
Expand Down
4 changes: 4 additions & 0 deletions web/viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ function getViewerConfiguration() {
pageRotateCcwButton: document.getElementById('pageRotateCcw'),
cursorSelectToolButton: document.getElementById('cursorSelectTool'),
cursorHandToolButton: document.getElementById('cursorHandTool'),
scrollVerticalButton: document.getElementById('scrollVertical'),
scrollHorizontalButton: document.getElementById('scrollHorizontal'),
scrollGridButton: document.getElementById('scrollGrid'),
scrollGridCoverButton: document.getElementById('scrollGridCover'),
documentPropertiesButton: document.getElementById('documentProperties'),
},
fullscreen: {
Expand Down

0 comments on commit 8b4dc92

Please sign in to comment.