Commit 2a358918 authored by rbpotter's avatar rbpotter Committed by Commit Bot

PDFViewerUpdate: Make zoom field respond to changes

- Modify the new toolbar's input field to display the current zoom
  level.
- Also update the fitting for the new toolbar for fit to width and fit
  to page to account for the toolbar height, since the new toolbar does
  not auto-hide.

Bug: 1105701
Change-Id: I34c0cf26f1d570023ea9904dd63da0da703e7781
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2303991Reviewed-by: default avatardpapad <dpapad@chromium.org>
Commit-Queue: Rebekah Potter <rbpotter@chromium.org>
Cr-Commit-Position: refs/heads/master@{#789720}
parent a4d4b817
...@@ -66,6 +66,10 @@ export class ViewerPdfToolbarNewElement extends PolymerElement { ...@@ -66,6 +66,10 @@ export class ViewerPdfToolbarNewElement extends PolymerElement {
pdfAnnotationsEnabled: Boolean, pdfAnnotationsEnabled: Boolean,
pdfFormSaveEnabled: Boolean, pdfFormSaveEnabled: Boolean,
printingEnabled: Boolean, printingEnabled: Boolean,
viewportZoom: {
type: Number,
observer: 'viewportZoomChanged_',
},
fittingType_: Number, fittingType_: Number,
...@@ -121,6 +125,12 @@ export class ViewerPdfToolbarNewElement extends PolymerElement { ...@@ -121,6 +125,12 @@ export class ViewerPdfToolbarNewElement extends PolymerElement {
this.loading_ = this.loadProgress < 100; this.loading_ = this.loadProgress < 100;
} }
/** @private */
viewportZoomChanged_() {
const zoom = Math.round(this.viewportZoom * 100);
this.shadowRoot.querySelector('#zoom-controls input').value = `${zoom}%`;
}
// <if expr="chromeos"> // <if expr="chromeos">
/** /**
* @return {boolean} * @return {boolean}
......
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
pdf-form-save-enabled="[[pdfFormSaveEnabled_]]" pdf-form-save-enabled="[[pdfFormSaveEnabled_]]"
printing-enabled="[[printingEnabled_]]" printing-enabled="[[printingEnabled_]]"
is-form-field-focused="[[isFormFieldFocused_]]" is-form-field-focused="[[isFormFieldFocused_]]"
viewport-zoom="[[viewportZoom_]]"
<if expr="chromeos"> <if expr="chromeos">
annotation-available="[[annotationAvailable_]]" annotation-available="[[annotationAvailable_]]"
ink-controller="[[inkController_]]" ink-controller="[[inkController_]]"
......
...@@ -146,6 +146,7 @@ export class PDFViewerElement extends PDFViewerBaseElement { ...@@ -146,6 +146,7 @@ export class PDFViewerElement extends PDFViewerBaseElement {
pdfFormSaveEnabled_: Boolean, pdfFormSaveEnabled_: Boolean,
pdfAnnotationsEnabled_: Boolean, pdfAnnotationsEnabled_: Boolean,
printingEnabled_: Boolean, printingEnabled_: Boolean,
viewportZoom_: Number,
}; };
} }
...@@ -197,6 +198,9 @@ export class PDFViewerElement extends PDFViewerBaseElement { ...@@ -197,6 +198,9 @@ export class PDFViewerElement extends PDFViewerBaseElement {
/** @private {boolean} */ /** @private {boolean} */
this.printingEnabled_ = false; this.printingEnabled_ = false;
/** @private {number} */
this.viewportZoom_ = 1;
// Non-Polymer properties // Non-Polymer properties
/** @private {number} */ /** @private {number} */
...@@ -247,6 +251,11 @@ export class PDFViewerElement extends PDFViewerBaseElement { ...@@ -247,6 +251,11 @@ export class PDFViewerElement extends PDFViewerBaseElement {
return this.toolbarEnabled_ ? MATERIAL_TOOLBAR_HEIGHT : 0; return this.toolbarEnabled_ ? MATERIAL_TOOLBAR_HEIGHT : 0;
} }
/** @override */
hasFixedToolbar() {
return this.pdfViewerUpdateEnabled_;
}
/** @override */ /** @override */
getContent() { getContent() {
return /** @type {!HTMLDivElement} */ (this.$$('#content')); return /** @type {!HTMLDivElement} */ (this.$$('#content'));
...@@ -724,6 +733,11 @@ export class PDFViewerElement extends PDFViewerBaseElement { ...@@ -724,6 +733,11 @@ export class PDFViewerElement extends PDFViewerBaseElement {
} }
} }
/** @override */
afterZoom(viewportZoom) {
this.viewportZoom_ = viewportZoom;
}
/** @override */ /** @override */
setDocumentDimensions(documentDimensions) { setDocumentDimensions(documentDimensions) {
super.setDocumentDimensions(documentDimensions); super.setDocumentDimensions(documentDimensions);
......
...@@ -120,6 +120,11 @@ export class PDFViewerBaseElement extends PolymerElement { ...@@ -120,6 +120,11 @@ export class PDFViewerBaseElement extends PolymerElement {
return 0; return 0;
} }
/** @return {boolean} Whether the top toolbar is fixed (does not auto-hide) */
hasFixedToolbar() {
return false;
}
/** /**
* @return {!HTMLDivElement} * @return {!HTMLDivElement}
* @protected * @protected
...@@ -144,6 +149,12 @@ export class PDFViewerBaseElement extends PolymerElement { ...@@ -144,6 +149,12 @@ export class PDFViewerBaseElement extends PolymerElement {
*/ */
forceFit(view) {} forceFit(view) {}
/**
* @param {number} viewportZoom
* @protected
*/
afterZoom(viewportZoom) {}
/** /**
* @param {string} query * @param {string} query
* @return {?Element} * @return {?Element}
...@@ -232,12 +243,14 @@ export class PDFViewerBaseElement extends PolymerElement { ...@@ -232,12 +243,14 @@ export class PDFViewerBaseElement extends PolymerElement {
1.0; 1.0;
this.viewport_ = new Viewport( this.viewport_ = new Viewport(
window, this.getSizer(), this.getContent(), getScrollbarWidth(), window, this.getSizer(), this.getContent(), getScrollbarWidth(),
defaultZoom, this.getToolbarHeight()); defaultZoom, this.getToolbarHeight(), this.hasFixedToolbar());
this.viewport_.setViewportChangedCallback(() => this.viewportChanged_()); this.viewport_.setViewportChangedCallback(() => this.viewportChanged_());
this.viewport_.setBeforeZoomCallback( this.viewport_.setBeforeZoomCallback(
() => this.currentController.beforeZoom()); () => this.currentController.beforeZoom());
this.viewport_.setAfterZoomCallback( this.viewport_.setAfterZoomCallback(() => {
() => this.currentController.afterZoom()); this.currentController.afterZoom();
this.afterZoom(this.viewport_.getZoom());
});
this.viewport_.setUserInitiatedCallback( this.viewport_.setUserInitiatedCallback(
userInitiated => this.setUserInitiated_(userInitiated)); userInitiated => this.setUserInitiated_(userInitiated));
window.addEventListener('beforeunload', () => this.resetTrackers_()); window.addEventListener('beforeunload', () => this.resetTrackers_());
......
...@@ -78,9 +78,12 @@ export class Viewport { ...@@ -78,9 +78,12 @@ export class Viewport {
* @param {number} defaultZoom The default zoom level. * @param {number} defaultZoom The default zoom level.
* @param {number} topToolbarHeight The number of pixels that should initially * @param {number} topToolbarHeight The number of pixels that should initially
* be left blank above the document for the toolbar. * be left blank above the document for the toolbar.
* @param {boolean} topToolbarFixed True if the top toolbar is fixed and does
* not automatically disappear in fit to page mode.
*/ */
constructor( constructor(
window, sizer, content, scrollbarWidth, defaultZoom, topToolbarHeight) { window, sizer, content, scrollbarWidth, defaultZoom, topToolbarHeight,
topToolbarFixed) {
/** @private {!Window} */ /** @private {!Window} */
this.window_ = window; this.window_ = window;
...@@ -99,6 +102,9 @@ export class Viewport { ...@@ -99,6 +102,9 @@ export class Viewport {
/** @private {number} */ /** @private {number} */
this.topToolbarHeight_ = topToolbarHeight; this.topToolbarHeight_ = topToolbarHeight;
/** @private {boolean} */
this.topToolbarFixed_ = topToolbarFixed;
/** @private {function():void} */ /** @private {function():void} */
this.viewportChangedCallback_ = function() {}; this.viewportChangedCallback_ = function() {};
...@@ -798,8 +804,12 @@ export class Viewport { ...@@ -798,8 +804,12 @@ export class Viewport {
'true.'); 'true.');
// First compute the zoom without scrollbars. // First compute the zoom without scrollbars.
let height = this.window_.innerHeight;
if (this.topToolbarFixed_) {
height -= this.topToolbarHeight_;
}
let zoom = this.computeFittingZoomGivenDimensions_( let zoom = this.computeFittingZoomGivenDimensions_(
fitWidth, fitHeight, this.window_.innerWidth, this.window_.innerHeight, fitWidth, fitHeight, this.window_.innerWidth, height,
pageDimensions.width, pageDimensions.height); pageDimensions.width, pageDimensions.height);
// Check if there needs to be any scrollbars. // Check if there needs to be any scrollbars.
...@@ -826,7 +836,7 @@ export class Viewport { ...@@ -826,7 +836,7 @@ export class Viewport {
// Compute available window space. // Compute available window space.
const windowWithScrollbars = { const windowWithScrollbars = {
width: this.window_.innerWidth, width: this.window_.innerWidth,
height: this.window_.innerHeight height: height,
}; };
if (needsScrollbars.horizontal) { if (needsScrollbars.horizontal) {
windowWithScrollbars.height -= scrollbarWidth; windowWithScrollbars.height -= scrollbarWidth;
...@@ -922,9 +932,10 @@ export class Viewport { ...@@ -922,9 +932,10 @@ export class Viewport {
}; };
this.setZoomInternal_(this.computeFittingZoom_(dimensions, false, true)); this.setZoomInternal_(this.computeFittingZoom_(dimensions, false, true));
if (scrollToTopOfPage) { if (scrollToTopOfPage) {
const offset = this.topToolbarFixed_ ? this.topToolbarHeight_ : 0;
this.position = { this.position = {
x: 0, x: 0,
y: this.pageDimensions_[page].y * this.getZoom() y: this.pageDimensions_[page].y * this.getZoom() - offset,
}; };
} }
this.updateViewport_(); this.updateViewport_();
...@@ -957,9 +968,10 @@ export class Viewport { ...@@ -957,9 +968,10 @@ export class Viewport {
}; };
this.setZoomInternal_(this.computeFittingZoom_(dimensions, true, true)); this.setZoomInternal_(this.computeFittingZoom_(dimensions, true, true));
if (scrollToTopOfPage) { if (scrollToTopOfPage) {
const offset = this.topToolbarFixed_ ? this.topToolbarHeight_ : 0;
this.position = { this.position = {
x: 0, x: 0,
y: this.pageDimensions_[page].y * this.getZoom() y: this.pageDimensions_[page].y * this.getZoom() - offset,
}; };
} }
this.updateViewport_(); this.updateViewport_();
...@@ -1219,7 +1231,7 @@ export class Viewport { ...@@ -1219,7 +1231,7 @@ export class Viewport {
// Unless we're in fit to page or fit to height mode, scroll above the // Unless we're in fit to page or fit to height mode, scroll above the
// page by |this.topToolbarHeight_| so that the toolbar isn't covering it // page by |this.topToolbarHeight_| so that the toolbar isn't covering it
// initially. // initially.
if (!this.isPagedMode_()) { if (!this.isPagedMode_() || this.topToolbarFixed_) {
toolbarOffset = this.topToolbarHeight_; toolbarOffset = this.topToolbarHeight_;
} }
this.position = { this.position = {
......
...@@ -242,7 +242,7 @@ export function getZoomableViewport( ...@@ -242,7 +242,7 @@ export function getZoomableViewport(
document.body.appendChild(dummyContent); document.body.appendChild(dummyContent);
const viewport = new Viewport( const viewport = new Viewport(
window, /** @type {!HTMLDivElement} */ (sizer), dummyContent, window, /** @type {!HTMLDivElement} */ (sizer), dummyContent,
scrollbarWidth, defaultZoom, topToolbarHeight); scrollbarWidth, defaultZoom, topToolbarHeight, false);
viewport.setZoomFactorRange([0.25, 0.4, 0.5, 1, 2]); viewport.setZoomFactorRange([0.25, 0.4, 0.5, 1, 2]);
return viewport; return viewport;
} }
......
...@@ -451,6 +451,75 @@ const tests = [ ...@@ -451,6 +451,75 @@ const tests = [
chrome.test.succeed(); chrome.test.succeed();
}, },
// Verifies that fitting computations work correctly for a fixed toolbar. In
// this case, the viewport should fit the document to the area below the
// toolbar, rather than the full window.
function testFitToPageFixedToolbar() {
const mockWindow = new MockWindow(100, 100);
const mockSizer = new MockSizer();
const mockCallback = new MockViewportChangedCallback();
const dummyContent =
/** @type {!HTMLDivElement} */ (document.createElement('div'));
document.body.appendChild(dummyContent);
const toolbarHeight = 10;
const viewport = new Viewport(
mockWindow, /** @type {!HTMLDivElement} */ (mockSizer), dummyContent, 0,
1, toolbarHeight, true);
viewport.setZoomFactorRange([0.25, 0.4, 0.5, 1, 2]);
viewport.setViewportChangedCallback(mockCallback.callback);
const documentDimensions = new MockDocumentDimensions();
function assertZoomed(expectedMockWidth, expectedMockHeight, expectedZoom) {
chrome.test.assertEq(FittingType.FIT_TO_PAGE, viewport.fittingType);
chrome.test.assertTrue(mockCallback.wasCalled);
chrome.test.assertEq(`${expectedMockWidth}px`, mockSizer.style.width);
chrome.test.assertEq(`${expectedMockHeight}px`, mockSizer.style.height);
chrome.test.assertEq(expectedZoom, viewport.getZoom());
// Should also make sure the viewport is correctly scrolled so that the
// entire page is visible, rather than covered by the toolbar.
chrome.test.assertEq(-1 * toolbarHeight, viewport.position.y);
chrome.test.assertEq(0, viewport.position.x);
}
function testForSize(
pageWidth, pageHeight, expectedMockWidth, expectedMockHeight,
expectedZoom) {
documentDimensions.reset();
documentDimensions.addPage(pageWidth, pageHeight);
viewport.setDocumentDimensions(documentDimensions);
viewport.setZoom(0.1);
mockCallback.reset();
viewport.fitToPage();
assertZoomed(expectedMockWidth, expectedMockHeight, expectedZoom);
}
// Note: Toolbar height is added to all expected heights below, as the sizer
// height includes the height of the toolbar.
// Page size which matches the window size.
testForSize(100, 100, 90, 90 + toolbarHeight, .9);
// Page size whose width is larger than its height.
testForSize(200, 100, 100, 50 + toolbarHeight, 0.5);
// Page size whose height is larger than its width.
testForSize(100, 200, 45, 90 + toolbarHeight, 0.45);
// Page size smaller than the window size in width but not height.
testForSize(50, 100, 45, 90 + toolbarHeight, .9);
// Page size smaller than the window size in height but not width.
testForSize(100, 50, 100, 50 + toolbarHeight, 1);
// Page size smaller than the window size in both width and height.
testForSize(25, 50, 45, 90 + toolbarHeight, 1.8);
// Page size smaller in one dimension and bigger in another.
testForSize(60, 200, 27, 90 + toolbarHeight, 0.45);
chrome.test.succeed();
},
function testFitToHeight() { function testFitToHeight() {
const mockWindow = new MockWindow(100, 100); const mockWindow = new MockWindow(100, 100);
const mockSizer = new MockSizer(); const mockSizer = new MockSizer();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment