| 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;
|
|
|
|
|