Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(139)

Unified Diff: chrome/browser/resources/pdf/viewport.js

Issue 347763007: Improve scrolling performance in OOP PDF (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/pdf/viewport.js
diff --git a/chrome/browser/resources/pdf/viewport.js b/chrome/browser/resources/pdf/viewport.js
index 7da0143bacb2290ea475a212026e6b7261c408eb..77e715e0888985e6b9e90366ad5cbd86a8520a23 100644
--- a/chrome/browser/resources/pdf/viewport.js
+++ b/chrome/browser/resources/pdf/viewport.js
@@ -24,15 +24,22 @@ function getIntersectionArea(rect1, rect2) {
* @param {Object} sizer is the element which represents the size of the
* document in the viewport
* @param {Function} viewportChangedCallback is run when the viewport changes
+ * @param {Function} beforeZoomCallback is run before a change in zoom
+ * @param {Function} afterZoomCallback is run after a change in zoom
* @param {number} scrollbarWidth the width of scrollbars on the page
*/
function Viewport(window,
sizer,
viewportChangedCallback,
+ beforeZoomCallback,
+ afterZoomCallback,
scrollbarWidth) {
this.window_ = window;
this.sizer_ = sizer;
this.viewportChangedCallback_ = viewportChangedCallback;
+ this.beforeZoomCallback_ = beforeZoomCallback;
+ this.afterZoomCallback_ = afterZoomCallback;
+ this.allowedToChangeZoom_ = false;
this.zoom_ = 1;
this.documentDimensions_ = null;
this.pageDimensions_ = [];
@@ -83,6 +90,12 @@ Viewport.prototype = {
* respectively.
*/
documentNeedsScrollbars_: function(zoom) {
+ if (!this.documentDimensions_) {
+ return {
+ horizontal: false,
+ vertical: false
+ };
+ }
var documentWidth = this.documentDimensions_.width * zoom;
var documentHeight = this.documentDimensions_.height * zoom;
return {
@@ -175,10 +188,27 @@ Viewport.prototype = {
/**
* @private
+ * Used to wrap a function that might perform zooming on the viewport. This is
+ * required so that we can notify the plugin that zooming is in progress
+ * so that while zooming is taking place it can stop reacting to scroll events
+ * from the viewport. This is to avoid flickering.
+ */
+ mightZoom_: function(f) {
+ this.beforeZoomCallback_();
+ this.allowedToChangeZoom_ = true;
+ f();
+ this.allowedToChangeZoom_ = false;
+ this.afterZoomCallback_();
+ },
+
+ /**
+ * @private
* Sets the zoom of the viewport.
* @param {number} newZoom the zoom level to zoom to.
*/
setZoom_: function(newZoom) {
+ if (!this.allowedToChangeZoom_)
+ throw 'Called Viewport.setZoom_ without calling Viewport.mightZoom_.';
var oldZoom = this.zoom_;
this.zoom_ = newZoom;
// Record the scroll position (relative to the middle of the window).
@@ -194,6 +224,16 @@ Viewport.prototype = {
},
/**
+ * @private
+ * Sets the zoom for testing purposes.
+ */
+ setZoomForTest_: function(newZoom) {
+ this.mightZoom_(function() {
+ this.setZoom_(newZoom);
+ }.bind(this));
+ },
+
+ /**
* @type {number} the width of scrollbars in the viewport in pixels.
*/
get scrollbarWidth() {
@@ -333,17 +373,19 @@ Viewport.prototype = {
* Zoom the viewport so that the page-width consumes the entire viewport.
*/
fitToWidth: function() {
- this.fittingType_ = Viewport.FittingType.FIT_TO_WIDTH;
- if (!this.documentDimensions_)
- return;
- // Track the last y-position so we stay at the same position after zooming.
- var oldY = this.window_.pageYOffset / this.zoom_;
- // When computing fit-to-width, the maximum width of a page in the document
- // is used, which is equal to the size of the document width.
- this.setZoom_(this.computeFittingZoom_(this.documentDimensions_, true));
- var page = this.getMostVisiblePage();
- this.window_.scrollTo(0, oldY * this.zoom_);
- this.updateViewport_();
+ this.mightZoom_(function() {
+ this.fittingType_ = Viewport.FittingType.FIT_TO_WIDTH;
+ if (!this.documentDimensions_)
+ return;
+ // Track the last y-position to stay at the same position after zooming.
+ var oldY = this.window_.pageYOffset / this.zoom_;
+ // When computing fit-to-width, the maximum width of a page in the
+ // document is used, which is equal to the size of the document width.
+ this.setZoom_(this.computeFittingZoom_(this.documentDimensions_, true));
+ var page = this.getMostVisiblePage();
+ this.window_.scrollTo(0, oldY * this.zoom_);
+ this.updateViewport_();
+ }.bind(this));
},
/**
@@ -351,47 +393,54 @@ Viewport.prototype = {
* to the top of the most visible page.
*/
fitToPage: function() {
- this.fittingType_ = Viewport.FittingType.FIT_TO_PAGE;
- if (!this.documentDimensions_)
- return;
- var page = this.getMostVisiblePage();
- this.setZoom_(this.computeFittingZoom_(this.pageDimensions_[page], false));
- // Center the document in the page by scrolling by the amount of empty
- // space to the left of the document.
- var xOffset =
- (this.documentDimensions_.width - this.pageDimensions_[page].width) *
- this.zoom_ / 2;
- this.window_.scrollTo(xOffset,
- this.pageDimensions_[page].y * this.zoom_);
- this.updateViewport_();
+ this.mightZoom_(function() {
+ this.fittingType_ = Viewport.FittingType.FIT_TO_PAGE;
+ if (!this.documentDimensions_)
+ return;
+ var page = this.getMostVisiblePage();
+ this.setZoom_(this.computeFittingZoom_(
+ this.pageDimensions_[page], false));
+ // Center the document in the page by scrolling by the amount of empty
+ // space to the left of the document.
+ var xOffset =
+ (this.documentDimensions_.width - this.pageDimensions_[page].width) *
+ this.zoom_ / 2;
+ this.window_.scrollTo(xOffset,
+ this.pageDimensions_[page].y * this.zoom_);
+ this.updateViewport_();
+ }.bind(this));
},
/**
* Zoom out to the next predefined zoom level.
*/
zoomOut: function() {
- this.fittingType_ = Viewport.FittingType.NONE;
- var nextZoom = Viewport.ZOOM_FACTORS[0];
- for (var i = 0; i < Viewport.ZOOM_FACTORS.length; i++) {
- if (Viewport.ZOOM_FACTORS[i] < this.zoom_)
- nextZoom = Viewport.ZOOM_FACTORS[i];
- }
- this.setZoom_(nextZoom);
- this.updateViewport_();
+ this.mightZoom_(function() {
+ this.fittingType_ = Viewport.FittingType.NONE;
+ var nextZoom = Viewport.ZOOM_FACTORS[0];
+ for (var i = 0; i < Viewport.ZOOM_FACTORS.length; i++) {
+ if (Viewport.ZOOM_FACTORS[i] < this.zoom_)
+ nextZoom = Viewport.ZOOM_FACTORS[i];
+ }
+ this.setZoom_(nextZoom);
+ this.updateViewport_();
+ }.bind(this));
},
/**
* Zoom in to the next predefined zoom level.
*/
zoomIn: function() {
- this.fittingType_ = Viewport.FittingType.NONE;
- var nextZoom = Viewport.ZOOM_FACTORS[Viewport.ZOOM_FACTORS.length - 1];
- for (var i = Viewport.ZOOM_FACTORS.length - 1; i >= 0; i--) {
- if (Viewport.ZOOM_FACTORS[i] > this.zoom_)
- nextZoom = Viewport.ZOOM_FACTORS[i];
- }
- this.setZoom_(nextZoom);
- this.updateViewport_();
+ this.mightZoom_(function() {
+ this.fittingType_ = Viewport.FittingType.NONE;
+ var nextZoom = Viewport.ZOOM_FACTORS[Viewport.ZOOM_FACTORS.length - 1];
+ for (var i = Viewport.ZOOM_FACTORS.length - 1; i >= 0; i--) {
+ if (Viewport.ZOOM_FACTORS[i] > this.zoom_)
+ nextZoom = Viewport.ZOOM_FACTORS[i];
+ }
+ this.setZoom_(nextZoom);
+ this.updateViewport_();
+ }.bind(this));
},
/**
@@ -399,14 +448,18 @@ Viewport.prototype = {
* @param {number} page the index of the page to go to.
*/
goToPage: function(page) {
- if (this.pageDimensions_.length == 0)
- return;
- if (page < 0)
- page = 0;
- if (page >= this.pageDimensions_.length)
- page = this.pageDimensions_.length - 1;
- var dimensions = this.pageDimensions_[page];
- this.window_.scrollTo(dimensions.x * this.zoom_, dimensions.y * this.zoom_);
+ this.mightZoom_(function() {
+ if (this.pageDimensions_.length == 0)
+ return;
+ if (page < 0)
+ page = 0;
+ if (page >= this.pageDimensions_.length)
+ page = this.pageDimensions_.length - 1;
+ var dimensions = this.pageDimensions_[page];
+ this.window_.scrollTo(dimensions.x * this.zoom_,
+ dimensions.y * this.zoom_);
+ this.updateViewport_();
+ }.bind(this));
},
/**
@@ -414,17 +467,19 @@ Viewport.prototype = {
* @param {Object} documentDimensions the dimensions of the document
*/
setDocumentDimensions: function(documentDimensions) {
- var initialDimensions = !this.documentDimensions_;
- this.documentDimensions_ = documentDimensions;
- this.pageDimensions_ = this.documentDimensions_.pageDimensions;
- if (initialDimensions) {
- this.setZoom_(this.computeFittingZoom_(this.documentDimensions_, true));
- if (this.zoom_ > 1)
- this.setZoom_(1);
- this.window_.scrollTo(0, 0);
- }
- this.contentSizeChanged_();
- this.resize_();
+ this.mightZoom_(function() {
+ var initialDimensions = !this.documentDimensions_;
+ this.documentDimensions_ = documentDimensions;
+ this.pageDimensions_ = this.documentDimensions_.pageDimensions;
+ if (initialDimensions) {
+ this.setZoom_(this.computeFittingZoom_(this.documentDimensions_, true));
+ if (this.zoom_ > 1)
+ this.setZoom_(1);
+ this.window_.scrollTo(0, 0);
+ }
+ this.contentSizeChanged_();
+ this.resize_();
+ }.bind(this));
},
/**
@@ -434,6 +489,14 @@ Viewport.prototype = {
* @return {Object} a rect representing the page in screen coordinates.
*/
getPageScreenRect: function(page) {
+ if (!this.documentDimensions_) {
+ return {
+ x: 0,
+ y: 0,
+ width: 0,
+ height: 0
+ };
+ }
if (page >= this.pageDimensions_.length)
page = this.pageDimensions_.length - 1;

Powered by Google App Engine
This is Rietveld 408576698