| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * Returns the height of the intersection of two rectangles. | 6 * Returns the height of the intersection of two rectangles. |
| 7 * @param {Object} rect1 the first rect | 7 * @param {Object} rect1 the first rect |
| 8 * @param {Object} rect2 the second rect | 8 * @param {Object} rect2 the second rect |
| 9 * @return {number} the height of the intersection of the rects | 9 * @return {number} the height of the intersection of the rects |
| 10 */ | 10 */ |
| 11 function getIntersectionHeight(rect1, rect2) { | 11 function getIntersectionHeight(rect1, rect2) { |
| 12 return Math.max(0, | 12 return Math.max( |
| 13 Math.min(rect1.y + rect1.height, rect2.y + rect2.height) - | 13 0, Math.min(rect1.y + rect1.height, rect2.y + rect2.height) - |
| 14 Math.max(rect1.y, rect2.y)); | 14 Math.max(rect1.y, rect2.y)); |
| 15 } | 15 } |
| 16 | 16 |
| 17 /** | 17 /** |
| 18 * Makes sure that the scale level doesn't get out of the limits. | 18 * Makes sure that the scale level doesn't get out of the limits. |
| 19 * @param {number} scale The new scale level. | 19 * @param {number} scale The new scale level. |
| 20 * @return {number} The scale clamped within the limits. | 20 * @return {number} The scale clamped within the limits. |
| 21 */ | 21 */ |
| 22 function clampScale(scale) { | 22 function clampScale(scale) { |
| 23 return Math.min(5, Math.max(0.25, scale)); | 23 return Math.min(5, Math.max(0.25, scale)); |
| 24 } | 24 } |
| 25 | 25 |
| 26 /** | 26 /** |
| 27 * Computes vector between two points. | 27 * Computes vector between two points. |
| 28 * @param {!Object} p1 The first point. | 28 * @param {!Object} p1 The first point. |
| 29 * @param {!Object} p2 The second point. | 29 * @param {!Object} p2 The second point. |
| 30 * @return {!Object} The vector. | 30 * @return {!Object} The vector. |
| 31 */ | 31 */ |
| 32 function vectorDelta(p1, p2) { | 32 function vectorDelta(p1, p2) { |
| 33 return { | 33 return {x: p2.x - p1.x, y: p2.y - p1.y}; |
| 34 x: p2.x - p1.x, | |
| 35 y: p2.y - p1.y | |
| 36 }; | |
| 37 } | 34 } |
| 38 | 35 |
| 39 function frameToPluginCoordinate(coordinateInFrame) { | 36 function frameToPluginCoordinate(coordinateInFrame) { |
| 40 var container = $('plugin'); | 37 var container = $('plugin'); |
| 41 return { | 38 return { |
| 42 x: coordinateInFrame.x - container.getBoundingClientRect().left, | 39 x: coordinateInFrame.x - container.getBoundingClientRect().left, |
| 43 y: coordinateInFrame.y - container.getBoundingClientRect().top | 40 y: coordinateInFrame.y - container.getBoundingClientRect().top |
| 44 }; | 41 }; |
| 45 } | 42 } |
| 46 | 43 |
| 47 /** | 44 /** |
| 48 * Create a new viewport. | 45 * Create a new viewport. |
| 49 * @constructor | 46 * @constructor |
| 50 * @param {Window} window the window | 47 * @param {Window} window the window |
| 51 * @param {Object} sizer is the element which represents the size of the | 48 * @param {Object} sizer is the element which represents the size of the |
| 52 * document in the viewport | 49 * document in the viewport |
| 53 * @param {Function} viewportChangedCallback is run when the viewport changes | 50 * @param {Function} viewportChangedCallback is run when the viewport changes |
| 54 * @param {Function} beforeZoomCallback is run before a change in zoom | 51 * @param {Function} beforeZoomCallback is run before a change in zoom |
| 55 * @param {Function} afterZoomCallback is run after a change in zoom | 52 * @param {Function} afterZoomCallback is run after a change in zoom |
| 56 * @param {number} scrollbarWidth the width of scrollbars on the page | 53 * @param {number} scrollbarWidth the width of scrollbars on the page |
| 57 * @param {number} defaultZoom The default zoom level. | 54 * @param {number} defaultZoom The default zoom level. |
| 58 * @param {number} topToolbarHeight The number of pixels that should initially | 55 * @param {number} topToolbarHeight The number of pixels that should initially |
| 59 * be left blank above the document for the toolbar. | 56 * be left blank above the document for the toolbar. |
| 60 */ | 57 */ |
| 61 function Viewport(window, | 58 function Viewport( |
| 62 sizer, | 59 window, sizer, viewportChangedCallback, beforeZoomCallback, |
| 63 viewportChangedCallback, | 60 afterZoomCallback, scrollbarWidth, defaultZoom, topToolbarHeight) { |
| 64 beforeZoomCallback, | |
| 65 afterZoomCallback, | |
| 66 scrollbarWidth, | |
| 67 defaultZoom, | |
| 68 topToolbarHeight) { | |
| 69 this.window_ = window; | 61 this.window_ = window; |
| 70 this.sizer_ = sizer; | 62 this.sizer_ = sizer; |
| 71 this.viewportChangedCallback_ = viewportChangedCallback; | 63 this.viewportChangedCallback_ = viewportChangedCallback; |
| 72 this.beforeZoomCallback_ = beforeZoomCallback; | 64 this.beforeZoomCallback_ = beforeZoomCallback; |
| 73 this.afterZoomCallback_ = afterZoomCallback; | 65 this.afterZoomCallback_ = afterZoomCallback; |
| 74 this.allowedToChangeZoom_ = false; | 66 this.allowedToChangeZoom_ = false; |
| 75 this.internalZoom_ = 1; | 67 this.internalZoom_ = 1; |
| 76 this.zoomManager_ = new InactiveZoomManager(this, 1); | 68 this.zoomManager_ = new InactiveZoomManager(this, 1); |
| 77 this.documentDimensions_ = null; | 69 this.documentDimensions_ = null; |
| 78 this.pageDimensions_ = []; | 70 this.pageDimensions_ = []; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 * these events. | 112 * these events. |
| 121 */ | 113 */ |
| 122 Viewport.SCROLL_INCREMENT = 40; | 114 Viewport.SCROLL_INCREMENT = 40; |
| 123 | 115 |
| 124 /** | 116 /** |
| 125 * Predefined zoom factors to be used when zooming in/out. These are in | 117 * Predefined zoom factors to be used when zooming in/out. These are in |
| 126 * ascending order. This should match the lists in | 118 * ascending order. This should match the lists in |
| 127 * components/ui/zoom/page_zoom_constants.h and | 119 * components/ui/zoom/page_zoom_constants.h and |
| 128 * chrome/browser/resources/settings/appearance_page/appearance_page.js | 120 * chrome/browser/resources/settings/appearance_page/appearance_page.js |
| 129 */ | 121 */ |
| 130 Viewport.ZOOM_FACTORS = [0.25, 1 / 3, 0.5, 2 / 3, 0.75, 0.8, 0.9, | 122 Viewport.ZOOM_FACTORS = [ |
| 131 1, 1.1, 1.25, 1.5, 1.75, 2, 2.5, 3, 4, 5]; | 123 0.25, 1 / 3, 0.5, 2 / 3, 0.75, 0.8, 0.9, 1, 1.1, 1.25, 1.5, 1.75, 2, 2.5, 3, |
| 124 4, 5 |
| 125 ]; |
| 132 | 126 |
| 133 /** | 127 /** |
| 134 * The minimum and maximum range to be used to clip zoom factor. | 128 * The minimum and maximum range to be used to clip zoom factor. |
| 135 */ | 129 */ |
| 136 Viewport.ZOOM_FACTOR_RANGE = { | 130 Viewport.ZOOM_FACTOR_RANGE = { |
| 137 min: Viewport.ZOOM_FACTORS[0], | 131 min: Viewport.ZOOM_FACTORS[0], |
| 138 max: Viewport.ZOOM_FACTORS[Viewport.ZOOM_FACTORS.length - 1] | 132 max: Viewport.ZOOM_FACTORS[Viewport.ZOOM_FACTORS.length - 1] |
| 139 }; | 133 }; |
| 140 | 134 |
| 141 /** | 135 /** |
| 142 * The width of the page shadow around pages in pixels. | 136 * The width of the page shadow around pages in pixels. |
| 143 */ | 137 */ |
| 144 Viewport.PAGE_SHADOW = {top: 3, bottom: 7, left: 5, right: 5}; | 138 Viewport.PAGE_SHADOW = { |
| 139 top: 3, |
| 140 bottom: 7, |
| 141 left: 5, |
| 142 right: 5 |
| 143 }; |
| 145 | 144 |
| 146 Viewport.prototype = { | 145 Viewport.prototype = { |
| 147 /** | 146 /** |
| 148 * Returns the zoomed and rounded document dimensions for the given zoom. | 147 * Returns the zoomed and rounded document dimensions for the given zoom. |
| 149 * Rounding is necessary when interacting with the renderer which tends to | 148 * Rounding is necessary when interacting with the renderer which tends to |
| 150 * operate in integral values (for example for determining if scrollbars | 149 * operate in integral values (for example for determining if scrollbars |
| 151 * should be shown). | 150 * should be shown). |
| 152 * @param {number} zoom The zoom to use to compute the scaled dimensions. | 151 * @param {number} zoom The zoom to use to compute the scaled dimensions. |
| 153 * @return {Object} A dictionary with scaled 'width'/'height' of the document. | 152 * @return {Object} A dictionary with scaled 'width'/'height' of the document. |
| 154 * @private | 153 * @private |
| (...skipping 11 matching lines...) Expand all Loading... |
| 166 * @private | 165 * @private |
| 167 * Returns true if the document needs scrollbars at the given zoom level. | 166 * Returns true if the document needs scrollbars at the given zoom level. |
| 168 * @param {number} zoom compute whether scrollbars are needed at this zoom | 167 * @param {number} zoom compute whether scrollbars are needed at this zoom |
| 169 * @return {Object} with 'horizontal' and 'vertical' keys which map to bool | 168 * @return {Object} with 'horizontal' and 'vertical' keys which map to bool |
| 170 * values indicating if the horizontal and vertical scrollbars are needed | 169 * values indicating if the horizontal and vertical scrollbars are needed |
| 171 * respectively. | 170 * respectively. |
| 172 */ | 171 */ |
| 173 documentNeedsScrollbars_: function(zoom) { | 172 documentNeedsScrollbars_: function(zoom) { |
| 174 var zoomedDimensions = this.getZoomedDocumentDimensions_(zoom); | 173 var zoomedDimensions = this.getZoomedDocumentDimensions_(zoom); |
| 175 if (!zoomedDimensions) { | 174 if (!zoomedDimensions) { |
| 176 return { | 175 return {horizontal: false, vertical: false}; |
| 177 horizontal: false, | |
| 178 vertical: false | |
| 179 }; | |
| 180 } | 176 } |
| 181 | 177 |
| 182 // If scrollbars are required for one direction, expand the document in the | 178 // If scrollbars are required for one direction, expand the document in the |
| 183 // other direction to take the width of the scrollbars into account when | 179 // other direction to take the width of the scrollbars into account when |
| 184 // deciding whether the other direction needs scrollbars. | 180 // deciding whether the other direction needs scrollbars. |
| 185 if (zoomedDimensions.width > this.window_.innerWidth) | 181 if (zoomedDimensions.width > this.window_.innerWidth) |
| 186 zoomedDimensions.height += this.scrollbarWidth_; | 182 zoomedDimensions.height += this.scrollbarWidth_; |
| 187 else if (zoomedDimensions.height > this.window_.innerHeight) | 183 else if (zoomedDimensions.height > this.window_.innerHeight) |
| 188 zoomedDimensions.width += this.scrollbarWidth_; | 184 zoomedDimensions.width += this.scrollbarWidth_; |
| 189 return { | 185 return { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 204 }, | 200 }, |
| 205 | 201 |
| 206 /** | 202 /** |
| 207 * @private | 203 * @private |
| 208 * Helper function called when the zoomed document size changes. | 204 * Helper function called when the zoomed document size changes. |
| 209 */ | 205 */ |
| 210 contentSizeChanged_: function() { | 206 contentSizeChanged_: function() { |
| 211 var zoomedDimensions = this.getZoomedDocumentDimensions_(this.zoom); | 207 var zoomedDimensions = this.getZoomedDocumentDimensions_(this.zoom); |
| 212 if (zoomedDimensions) { | 208 if (zoomedDimensions) { |
| 213 this.sizer_.style.width = zoomedDimensions.width + 'px'; | 209 this.sizer_.style.width = zoomedDimensions.width + 'px'; |
| 214 this.sizer_.style.height = zoomedDimensions.height + | 210 this.sizer_.style.height = |
| 215 this.topToolbarHeight_ + 'px'; | 211 zoomedDimensions.height + this.topToolbarHeight_ + 'px'; |
| 216 } | 212 } |
| 217 }, | 213 }, |
| 218 | 214 |
| 219 /** | 215 /** |
| 220 * @private | 216 * @private |
| 221 * Called when the viewport should be updated. | 217 * Called when the viewport should be updated. |
| 222 */ | 218 */ |
| 223 updateViewport_: function() { | 219 updateViewport_: function() { |
| 224 this.viewportChangedCallback_(); | 220 this.viewportChangedCallback_(); |
| 225 }, | 221 }, |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 322 }, | 318 }, |
| 323 | 319 |
| 324 /** | 320 /** |
| 325 * @private | 321 * @private |
| 326 * Sets the zoom of the viewport. | 322 * Sets the zoom of the viewport. |
| 327 * @param {number} newZoom the zoom level to zoom to. | 323 * @param {number} newZoom the zoom level to zoom to. |
| 328 */ | 324 */ |
| 329 setZoomInternal_: function(newZoom) { | 325 setZoomInternal_: function(newZoom) { |
| 330 if (!this.allowedToChangeZoom_) { | 326 if (!this.allowedToChangeZoom_) { |
| 331 throw 'Called Viewport.setZoomInternal_ without calling ' + | 327 throw 'Called Viewport.setZoomInternal_ without calling ' + |
| 332 'Viewport.mightZoom_.'; | 328 'Viewport.mightZoom_.'; |
| 333 } | 329 } |
| 334 // Record the scroll position (relative to the top-left of the window). | 330 // Record the scroll position (relative to the top-left of the window). |
| 335 var currentScrollPos = { | 331 var currentScrollPos = { |
| 336 x: this.position.x / this.zoom, | 332 x: this.position.x / this.zoom, |
| 337 y: this.position.y / this.zoom | 333 y: this.position.y / this.zoom |
| 338 }; | 334 }; |
| 339 this.internalZoom_ = newZoom; | 335 this.internalZoom_ = newZoom; |
| 340 this.contentSizeChanged_(); | 336 this.contentSizeChanged_(); |
| 341 // Scroll to the scaled scroll position. | 337 // Scroll to the scaled scroll position. |
| 342 this.position = { | 338 this.position = { |
| 343 x: currentScrollPos.x * this.zoom, | 339 x: currentScrollPos.x * this.zoom, |
| 344 y: currentScrollPos.y * this.zoom | 340 y: currentScrollPos.y * this.zoom |
| 345 }; | 341 }; |
| 346 }, | 342 }, |
| 347 | 343 |
| 348 /** | 344 /** |
| 349 * @private | 345 * @private |
| 350 * Sets the zoom of the viewport. | 346 * Sets the zoom of the viewport. |
| 351 * Same as setZoomInternal_ but for pinch zoom we have some more operations. | 347 * Same as setZoomInternal_ but for pinch zoom we have some more operations. |
| 352 * @param {number} scaleDelta The zoom delta. | 348 * @param {number} scaleDelta The zoom delta. |
| 353 * @param {!Object} center The pinch center in content coordinates. | 349 * @param {!Object} center The pinch center in content coordinates. |
| 354 */ | 350 */ |
| 355 setPinchZoomInternal_: function(scaleDelta, center) { | 351 setPinchZoomInternal_: function(scaleDelta, center) { |
| 356 assert(this.allowedToChangeZoom_, | 352 assert( |
| 353 this.allowedToChangeZoom_, |
| 357 'Called Viewport.setPinchZoomInternal_ without calling ' + | 354 'Called Viewport.setPinchZoomInternal_ without calling ' + |
| 358 'Viewport.mightZoom_.'); | 355 'Viewport.mightZoom_.'); |
| 359 this.internalZoom_ = clampScale(this.internalZoom_ * scaleDelta); | 356 this.internalZoom_ = clampScale(this.internalZoom_ * scaleDelta); |
| 360 | 357 |
| 361 var newCenterInContent = this.frameToContent(center); | 358 var newCenterInContent = this.frameToContent(center); |
| 362 var delta = { | 359 var delta = { |
| 363 x: (newCenterInContent.x - this.oldCenterInContent.x), | 360 x: (newCenterInContent.x - this.oldCenterInContent.x), |
| 364 y: (newCenterInContent.y - this.oldCenterInContent.y) | 361 y: (newCenterInContent.y - this.oldCenterInContent.y) |
| 365 }; | 362 }; |
| 366 | 363 |
| 367 // Record the scroll position (relative to the pinch center). | 364 // Record the scroll position (relative to the pinch center). |
| 368 var currentScrollPos = { | 365 var currentScrollPos = { |
| 369 x: this.position.x - delta.x * this.zoom, | 366 x: this.position.x - delta.x * this.zoom, |
| 370 y: this.position.y - delta.y * this.zoom | 367 y: this.position.y - delta.y * this.zoom |
| 371 }; | 368 }; |
| 372 | 369 |
| 373 this.contentSizeChanged_(); | 370 this.contentSizeChanged_(); |
| 374 // Scroll to the scaled scroll position. | 371 // Scroll to the scaled scroll position. |
| 375 this.position = { | 372 this.position = {x: currentScrollPos.x, y: currentScrollPos.y}; |
| 376 x: currentScrollPos.x, | |
| 377 y: currentScrollPos.y | |
| 378 }; | |
| 379 }, | 373 }, |
| 380 | 374 |
| 381 /** | 375 /** |
| 382 * @private | 376 * @private |
| 383 * Converts a point from frame to content coordinates. | 377 * Converts a point from frame to content coordinates. |
| 384 * @param {!Object} framePoint The frame coordinates. | 378 * @param {!Object} framePoint The frame coordinates. |
| 385 * @return {!Object} The content coordinates. | 379 * @return {!Object} The content coordinates. |
| 386 */ | 380 */ |
| 387 frameToContent: function(framePoint) { | 381 frameToContent: function(framePoint) { |
| 388 // TODO(mcnee) Add a helper Point class to avoid duplicating operations | 382 // TODO(mcnee) Add a helper Point class to avoid duplicating operations |
| 389 // on plain {x,y} objects. | 383 // on plain {x,y} objects. |
| 390 return { | 384 return { |
| 391 x: (framePoint.x + this.position.x) / this.zoom, | 385 x: (framePoint.x + this.position.x) / this.zoom, |
| 392 y: (framePoint.y + this.position.y) / this.zoom | 386 y: (framePoint.y + this.position.y) / this.zoom |
| 393 }; | 387 }; |
| 394 }, | 388 }, |
| 395 | 389 |
| 396 /** | 390 /** |
| 397 * Sets the zoom to the given zoom level. | 391 * Sets the zoom to the given zoom level. |
| 398 * @param {number} newZoom the zoom level to zoom to. | 392 * @param {number} newZoom the zoom level to zoom to. |
| 399 */ | 393 */ |
| 400 setZoom: function(newZoom) { | 394 setZoom: function(newZoom) { |
| 401 this.fittingType_ = Viewport.FittingType.NONE; | 395 this.fittingType_ = Viewport.FittingType.NONE; |
| 402 newZoom = Math.max(Viewport.ZOOM_FACTOR_RANGE.min, | 396 newZoom = Math.max( |
| 403 Math.min(newZoom, Viewport.ZOOM_FACTOR_RANGE.max)); | 397 Viewport.ZOOM_FACTOR_RANGE.min, |
| 398 Math.min(newZoom, Viewport.ZOOM_FACTOR_RANGE.max)); |
| 404 this.mightZoom_(function() { | 399 this.mightZoom_(function() { |
| 405 this.setZoomInternal_(newZoom); | 400 this.setZoomInternal_(newZoom); |
| 406 this.updateViewport_(); | 401 this.updateViewport_(); |
| 407 }.bind(this)); | 402 }.bind(this)); |
| 408 }, | 403 }, |
| 409 | 404 |
| 410 /** | 405 /** |
| 411 * Gets notified of the browser zoom changing seperately from the | 406 * Gets notified of the browser zoom changing seperately from the |
| 412 * internal zoom. | 407 * internal zoom. |
| 413 * @param {number} oldBrowserZoom the previous value of the browser zoom. | 408 * @param {number} oldBrowserZoom the previous value of the browser zoom. |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 var max = this.pageDimensions_.length - 1; | 449 var max = this.pageDimensions_.length - 1; |
| 455 while (max >= min) { | 450 while (max >= min) { |
| 456 var page = Math.floor(min + ((max - min) / 2)); | 451 var page = Math.floor(min + ((max - min) / 2)); |
| 457 // There might be a gap between the pages, in which case use the bottom | 452 // There might be a gap between the pages, in which case use the bottom |
| 458 // of the previous page as the top for finding the page. | 453 // of the previous page as the top for finding the page. |
| 459 var top = 0; | 454 var top = 0; |
| 460 if (page > 0) { | 455 if (page > 0) { |
| 461 top = this.pageDimensions_[page - 1].y + | 456 top = this.pageDimensions_[page - 1].y + |
| 462 this.pageDimensions_[page - 1].height; | 457 this.pageDimensions_[page - 1].height; |
| 463 } | 458 } |
| 464 var bottom = this.pageDimensions_[page].y + | 459 var bottom = |
| 465 this.pageDimensions_[page].height; | 460 this.pageDimensions_[page].y + this.pageDimensions_[page].height; |
| 466 | 461 |
| 467 if (top <= y && bottom > y) | 462 if (top <= y && bottom > y) |
| 468 return page; | 463 return page; |
| 469 else if (top > y) | 464 else if (top > y) |
| 470 max = page - 1; | 465 max = page - 1; |
| 471 else | 466 else |
| 472 min = page + 1; | 467 min = page + 1; |
| 473 } | 468 } |
| 474 return 0; | 469 return 0; |
| 475 }, | 470 }, |
| 476 | 471 |
| 477 /** | 472 /** |
| 478 * Returns the page with the greatest proportion of its height in the current | 473 * Returns the page with the greatest proportion of its height in the current |
| 479 * viewport. | 474 * viewport. |
| 480 * @return {int} the index of the most visible page. | 475 * @return {int} the index of the most visible page. |
| 481 */ | 476 */ |
| 482 getMostVisiblePage: function() { | 477 getMostVisiblePage: function() { |
| 483 var firstVisiblePage = this.getPageAtY_(this.position.y / this.zoom); | 478 var firstVisiblePage = this.getPageAtY_(this.position.y / this.zoom); |
| 484 if (firstVisiblePage == this.pageDimensions_.length - 1) | 479 if (firstVisiblePage == this.pageDimensions_.length - 1) |
| 485 return firstVisiblePage; | 480 return firstVisiblePage; |
| 486 | 481 |
| 487 var viewportRect = { | 482 var viewportRect = { |
| 488 x: this.position.x / this.zoom, | 483 x: this.position.x / this.zoom, |
| 489 y: this.position.y / this.zoom, | 484 y: this.position.y / this.zoom, |
| 490 width: this.size.width / this.zoom, | 485 width: this.size.width / this.zoom, |
| 491 height: this.size.height / this.zoom | 486 height: this.size.height / this.zoom |
| 492 }; | 487 }; |
| 493 var firstVisiblePageVisibility = getIntersectionHeight( | 488 var firstVisiblePageVisibility = |
| 494 this.pageDimensions_[firstVisiblePage], viewportRect) / | 489 getIntersectionHeight( |
| 490 this.pageDimensions_[firstVisiblePage], viewportRect) / |
| 495 this.pageDimensions_[firstVisiblePage].height; | 491 this.pageDimensions_[firstVisiblePage].height; |
| 496 var nextPageVisibility = getIntersectionHeight( | 492 var nextPageVisibility = |
| 497 this.pageDimensions_[firstVisiblePage + 1], viewportRect) / | 493 getIntersectionHeight( |
| 494 this.pageDimensions_[firstVisiblePage + 1], viewportRect) / |
| 498 this.pageDimensions_[firstVisiblePage + 1].height; | 495 this.pageDimensions_[firstVisiblePage + 1].height; |
| 499 if (nextPageVisibility > firstVisiblePageVisibility) | 496 if (nextPageVisibility > firstVisiblePageVisibility) |
| 500 return firstVisiblePage + 1; | 497 return firstVisiblePage + 1; |
| 501 return firstVisiblePage; | 498 return firstVisiblePage; |
| 502 }, | 499 }, |
| 503 | 500 |
| 504 /** | 501 /** |
| 505 * @private | 502 * @private |
| 506 * Compute the zoom level for fit-to-page or fit-to-width. |pageDimensions| is | 503 * Compute the zoom level for fit-to-page or fit-to-width. |pageDimensions| is |
| 507 * the dimensions for a given page and if |widthOnly| is true, it indicates | 504 * the dimensions for a given page and if |widthOnly| is true, it indicates |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 566 /** | 563 /** |
| 567 * Zoom the viewport so that the page-width consumes the entire viewport. | 564 * Zoom the viewport so that the page-width consumes the entire viewport. |
| 568 */ | 565 */ |
| 569 fitToWidth: function() { | 566 fitToWidth: function() { |
| 570 this.mightZoom_(function() { | 567 this.mightZoom_(function() { |
| 571 this.fittingType_ = Viewport.FittingType.FIT_TO_WIDTH; | 568 this.fittingType_ = Viewport.FittingType.FIT_TO_WIDTH; |
| 572 if (!this.documentDimensions_) | 569 if (!this.documentDimensions_) |
| 573 return; | 570 return; |
| 574 // When computing fit-to-width, the maximum width of a page in the | 571 // When computing fit-to-width, the maximum width of a page in the |
| 575 // document is used, which is equal to the size of the document width. | 572 // document is used, which is equal to the size of the document width. |
| 576 this.setZoomInternal_(this.computeFittingZoom_(this.documentDimensions_, | 573 this.setZoomInternal_( |
| 577 true)); | 574 this.computeFittingZoom_(this.documentDimensions_, true)); |
| 578 var page = this.getMostVisiblePage(); | 575 var page = this.getMostVisiblePage(); |
| 579 this.updateViewport_(); | 576 this.updateViewport_(); |
| 580 }.bind(this)); | 577 }.bind(this)); |
| 581 }, | 578 }, |
| 582 | 579 |
| 583 /** | 580 /** |
| 584 * @private | 581 * @private |
| 585 * Zoom the viewport so that a page consumes the entire viewport. | 582 * Zoom the viewport so that a page consumes the entire viewport. |
| 586 * @param {boolean} scrollToTopOfPage Set to true if the viewport should be | 583 * @param {boolean} scrollToTopOfPage Set to true if the viewport should be |
| 587 * scrolled to the top of the current page. Set to false if the viewport | 584 * scrolled to the top of the current page. Set to false if the viewport |
| 588 * should remain at the current scroll position. | 585 * should remain at the current scroll position. |
| 589 */ | 586 */ |
| 590 fitToPageInternal_: function(scrollToTopOfPage) { | 587 fitToPageInternal_: function(scrollToTopOfPage) { |
| 591 this.mightZoom_(function() { | 588 this.mightZoom_(function() { |
| 592 this.fittingType_ = Viewport.FittingType.FIT_TO_PAGE; | 589 this.fittingType_ = Viewport.FittingType.FIT_TO_PAGE; |
| 593 if (!this.documentDimensions_) | 590 if (!this.documentDimensions_) |
| 594 return; | 591 return; |
| 595 var page = this.getMostVisiblePage(); | 592 var page = this.getMostVisiblePage(); |
| 596 // Fit to the current page's height and the widest page's width. | 593 // Fit to the current page's height and the widest page's width. |
| 597 var dimensions = { | 594 var dimensions = { |
| 598 width: this.documentDimensions_.width, | 595 width: this.documentDimensions_.width, |
| 599 height: this.pageDimensions_[page].height, | 596 height: this.pageDimensions_[page].height, |
| 600 }; | 597 }; |
| 601 this.setZoomInternal_(this.computeFittingZoom_(dimensions, false)); | 598 this.setZoomInternal_(this.computeFittingZoom_(dimensions, false)); |
| 602 if (scrollToTopOfPage) { | 599 if (scrollToTopOfPage) { |
| 603 this.position = { | 600 this.position = {x: 0, y: this.pageDimensions_[page].y * this.zoom}; |
| 604 x: 0, | |
| 605 y: this.pageDimensions_[page].y * this.zoom | |
| 606 }; | |
| 607 } | 601 } |
| 608 this.updateViewport_(); | 602 this.updateViewport_(); |
| 609 }.bind(this)); | 603 }.bind(this)); |
| 610 }, | 604 }, |
| 611 | 605 |
| 612 /** | 606 /** |
| 613 * Zoom the viewport so that a page consumes the entire viewport. Also scrolls | 607 * Zoom the viewport so that a page consumes the entire viewport. Also scrolls |
| 614 * the viewport to the top of the current page. | 608 * the viewport to the top of the current page. |
| 615 */ | 609 */ |
| 616 fitToPage: function() { | 610 fitToPage: function() { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 649 }.bind(this)); | 643 }.bind(this)); |
| 650 }, | 644 }, |
| 651 | 645 |
| 652 /** | 646 /** |
| 653 * Pinch zoom event handler. | 647 * Pinch zoom event handler. |
| 654 * @param {!Object} e The pinch event. | 648 * @param {!Object} e The pinch event. |
| 655 */ | 649 */ |
| 656 pinchZoom: function(e) { | 650 pinchZoom: function(e) { |
| 657 this.mightZoom_(function() { | 651 this.mightZoom_(function() { |
| 658 this.pinchPhase_ = e.direction == 'out' ? | 652 this.pinchPhase_ = e.direction == 'out' ? |
| 659 Viewport.PinchPhase.PINCH_UPDATE_ZOOM_OUT : | 653 Viewport.PinchPhase.PINCH_UPDATE_ZOOM_OUT : |
| 660 Viewport.PinchPhase.PINCH_UPDATE_ZOOM_IN; | 654 Viewport.PinchPhase.PINCH_UPDATE_ZOOM_IN; |
| 661 | 655 |
| 662 var scaleDelta = e.startScaleRatio / this.prevScale_; | 656 var scaleDelta = e.startScaleRatio / this.prevScale_; |
| 663 this.pinchPanVector_ = | 657 this.pinchPanVector_ = |
| 664 vectorDelta(e.center, this.firstPinchCenterInFrame_); | 658 vectorDelta(e.center, this.firstPinchCenterInFrame_); |
| 665 | 659 |
| 666 var needsScrollbars = this.documentNeedsScrollbars_( | 660 var needsScrollbars = |
| 667 this.zoomManager_.applyBrowserZoom( | 661 this.documentNeedsScrollbars_(this.zoomManager_.applyBrowserZoom( |
| 668 clampScale(this.internalZoom_ * scaleDelta))); | 662 clampScale(this.internalZoom_ * scaleDelta))); |
| 669 | 663 |
| 670 this.pinchCenter_ = e.center; | 664 this.pinchCenter_ = e.center; |
| 671 | 665 |
| 672 // If there's no horizontal scrolling, keep the content centered so the | 666 // If there's no horizontal scrolling, keep the content centered so the |
| 673 // user can't zoom in on the non-content area. | 667 // user can't zoom in on the non-content area. |
| 674 // TODO(mcnee) Investigate other ways of scaling when we don't have | 668 // TODO(mcnee) Investigate other ways of scaling when we don't have |
| 675 // horizontal scrolling. We want to keep the document centered, | 669 // horizontal scrolling. We want to keep the document centered, |
| 676 // but this causes a potentially awkward transition when we start | 670 // but this causes a potentially awkward transition when we start |
| 677 // using the gesture center. | 671 // using the gesture center. |
| 678 if (!needsScrollbars.horizontal) { | 672 if (!needsScrollbars.horizontal) { |
| 679 this.pinchCenter_ = { | 673 this.pinchCenter_ = { |
| 680 x: this.window_.innerWidth / 2, | 674 x: this.window_.innerWidth / 2, |
| 681 y: this.window_.innerHeight / 2 | 675 y: this.window_.innerHeight / 2 |
| 682 }; | 676 }; |
| 683 } else if (this.keepContentCentered_) { | 677 } else if (this.keepContentCentered_) { |
| 684 this.oldCenterInContent = | 678 this.oldCenterInContent = |
| 685 this.frameToContent(frameToPluginCoordinate(e.center)); | 679 this.frameToContent(frameToPluginCoordinate(e.center)); |
| 686 this.keepContentCentered_ = false; | 680 this.keepContentCentered_ = false; |
| 687 } | 681 } |
| 688 | 682 |
| 689 this.setPinchZoomInternal_( | 683 this.setPinchZoomInternal_(scaleDelta, frameToPluginCoordinate(e.center)); |
| 690 scaleDelta, frameToPluginCoordinate(e.center)); | |
| 691 this.updateViewport_(); | 684 this.updateViewport_(); |
| 692 this.prevScale_ = e.startScaleRatio; | 685 this.prevScale_ = e.startScaleRatio; |
| 693 }.bind(this)); | 686 }.bind(this)); |
| 694 }, | 687 }, |
| 695 | 688 |
| 696 pinchZoomStart: function(e) { | 689 pinchZoomStart: function(e) { |
| 697 this.pinchPhase_ = Viewport.PinchPhase.PINCH_START; | 690 this.pinchPhase_ = Viewport.PinchPhase.PINCH_START; |
| 698 this.prevScale_ = 1; | 691 this.prevScale_ = 1; |
| 699 this.oldCenterInContent = | 692 this.oldCenterInContent = |
| 700 this.frameToContent(frameToPluginCoordinate(e.center)); | 693 this.frameToContent(frameToPluginCoordinate(e.center)); |
| 701 | 694 |
| 702 var needsScrollbars = this.documentNeedsScrollbars_(this.zoom); | 695 var needsScrollbars = this.documentNeedsScrollbars_(this.zoom); |
| 703 this.keepContentCentered_ = !needsScrollbars.horizontal; | 696 this.keepContentCentered_ = !needsScrollbars.horizontal; |
| 704 // We keep track of begining of the pinch. | 697 // We keep track of begining of the pinch. |
| 705 // By doing so we will be able to compute the pan distance. | 698 // By doing so we will be able to compute the pan distance. |
| 706 this.firstPinchCenterInFrame_ = e.center; | 699 this.firstPinchCenterInFrame_ = e.center; |
| 707 }, | 700 }, |
| 708 | 701 |
| 709 pinchZoomEnd: function(e) { | 702 pinchZoomEnd: function(e) { |
| 710 this.mightZoom_(function() { | 703 this.mightZoom_(function() { |
| 711 this.pinchPhase_ = Viewport.PinchPhase.PINCH_END; | 704 this.pinchPhase_ = Viewport.PinchPhase.PINCH_END; |
| 712 var scaleDelta = e.startScaleRatio / this.prevScale_; | 705 var scaleDelta = e.startScaleRatio / this.prevScale_; |
| 713 this.pinchCenter_ = e.center; | 706 this.pinchCenter_ = e.center; |
| 714 | 707 |
| 715 this.setPinchZoomInternal_( | 708 this.setPinchZoomInternal_(scaleDelta, frameToPluginCoordinate(e.center)); |
| 716 scaleDelta, frameToPluginCoordinate(e.center)); | |
| 717 this.updateViewport_(); | 709 this.updateViewport_(); |
| 718 }.bind(this)); | 710 }.bind(this)); |
| 719 | 711 |
| 720 this.pinchPhase_ = Viewport.PinchPhase.PINCH_NONE; | 712 this.pinchPhase_ = Viewport.PinchPhase.PINCH_NONE; |
| 721 this.pinchPanVector_ = null; | 713 this.pinchPanVector_ = null; |
| 722 this.pinchCenter_ = null; | 714 this.pinchCenter_ = null; |
| 723 this.firstPinchCenterInFrame_ = null; | 715 this.firstPinchCenterInFrame_ = null; |
| 724 }, | 716 }, |
| 725 | 717 |
| 726 /** | 718 /** |
| (...skipping 26 matching lines...) Expand all Loading... |
| 753 /** | 745 /** |
| 754 * Set the dimensions of the document. | 746 * Set the dimensions of the document. |
| 755 * @param {Object} documentDimensions the dimensions of the document | 747 * @param {Object} documentDimensions the dimensions of the document |
| 756 */ | 748 */ |
| 757 setDocumentDimensions: function(documentDimensions) { | 749 setDocumentDimensions: function(documentDimensions) { |
| 758 this.mightZoom_(function() { | 750 this.mightZoom_(function() { |
| 759 var initialDimensions = !this.documentDimensions_; | 751 var initialDimensions = !this.documentDimensions_; |
| 760 this.documentDimensions_ = documentDimensions; | 752 this.documentDimensions_ = documentDimensions; |
| 761 this.pageDimensions_ = this.documentDimensions_.pageDimensions; | 753 this.pageDimensions_ = this.documentDimensions_.pageDimensions; |
| 762 if (initialDimensions) { | 754 if (initialDimensions) { |
| 763 this.setZoomInternal_( | 755 this.setZoomInternal_(Math.min( |
| 764 Math.min(this.defaultZoom_, | 756 this.defaultZoom_, |
| 765 this.computeFittingZoom_(this.documentDimensions_, true))); | 757 this.computeFittingZoom_(this.documentDimensions_, true))); |
| 766 this.position = { | 758 this.position = {x: 0, y: -this.topToolbarHeight_}; |
| 767 x: 0, | |
| 768 y: -this.topToolbarHeight_ | |
| 769 }; | |
| 770 } | 759 } |
| 771 this.contentSizeChanged_(); | 760 this.contentSizeChanged_(); |
| 772 this.resize_(); | 761 this.resize_(); |
| 773 }.bind(this)); | 762 }.bind(this)); |
| 774 }, | 763 }, |
| 775 | 764 |
| 776 /** | 765 /** |
| 777 * Get the coordinates of the page contents (excluding the page shadow) | 766 * Get the coordinates of the page contents (excluding the page shadow) |
| 778 * relative to the screen. | 767 * relative to the screen. |
| 779 * @param {number} page the index of the page to get the rect for. | 768 * @param {number} page the index of the page to get the rect for. |
| 780 * @return {Object} a rect representing the page in screen coordinates. | 769 * @return {Object} a rect representing the page in screen coordinates. |
| 781 */ | 770 */ |
| 782 getPageScreenRect: function(page) { | 771 getPageScreenRect: function(page) { |
| 783 if (!this.documentDimensions_) { | 772 if (!this.documentDimensions_) { |
| 784 return { | 773 return {x: 0, y: 0, width: 0, height: 0}; |
| 785 x: 0, | |
| 786 y: 0, | |
| 787 width: 0, | |
| 788 height: 0 | |
| 789 }; | |
| 790 } | 774 } |
| 791 if (page >= this.pageDimensions_.length) | 775 if (page >= this.pageDimensions_.length) |
| 792 page = this.pageDimensions_.length - 1; | 776 page = this.pageDimensions_.length - 1; |
| 793 | 777 |
| 794 var pageDimensions = this.pageDimensions_[page]; | 778 var pageDimensions = this.pageDimensions_[page]; |
| 795 | 779 |
| 796 // Compute the page dimensions minus the shadows. | 780 // Compute the page dimensions minus the shadows. |
| 797 var insetDimensions = { | 781 var insetDimensions = { |
| 798 x: pageDimensions.x + Viewport.PAGE_SHADOW.left, | 782 x: pageDimensions.x + Viewport.PAGE_SHADOW.left, |
| 799 y: pageDimensions.y + Viewport.PAGE_SHADOW.top, | 783 y: pageDimensions.y + Viewport.PAGE_SHADOW.top, |
| 800 width: pageDimensions.width - Viewport.PAGE_SHADOW.left - | 784 width: pageDimensions.width - Viewport.PAGE_SHADOW.left - |
| 801 Viewport.PAGE_SHADOW.right, | 785 Viewport.PAGE_SHADOW.right, |
| 802 height: pageDimensions.height - Viewport.PAGE_SHADOW.top - | 786 height: pageDimensions.height - Viewport.PAGE_SHADOW.top - |
| 803 Viewport.PAGE_SHADOW.bottom | 787 Viewport.PAGE_SHADOW.bottom |
| 804 }; | 788 }; |
| 805 | 789 |
| 806 // Compute the x-coordinate of the page within the document. | 790 // Compute the x-coordinate of the page within the document. |
| 807 // TODO(raymes): This should really be set when the PDF plugin passes the | 791 // TODO(raymes): This should really be set when the PDF plugin passes the |
| 808 // page coordinates, but it isn't yet. | 792 // page coordinates, but it isn't yet. |
| 809 var x = (this.documentDimensions_.width - pageDimensions.width) / 2 + | 793 var x = (this.documentDimensions_.width - pageDimensions.width) / 2 + |
| 810 Viewport.PAGE_SHADOW.left; | 794 Viewport.PAGE_SHADOW.left; |
| 811 // Compute the space on the left of the document if the document fits | 795 // Compute the space on the left of the document if the document fits |
| 812 // completely in the screen. | 796 // completely in the screen. |
| 813 var spaceOnLeft = (this.size.width - | 797 var spaceOnLeft = |
| 814 this.documentDimensions_.width * this.zoom) / 2; | 798 (this.size.width - this.documentDimensions_.width * this.zoom) / 2; |
| 815 spaceOnLeft = Math.max(spaceOnLeft, 0); | 799 spaceOnLeft = Math.max(spaceOnLeft, 0); |
| 816 | 800 |
| 817 return { | 801 return { |
| 818 x: x * this.zoom + spaceOnLeft - this.window_.pageXOffset, | 802 x: x * this.zoom + spaceOnLeft - this.window_.pageXOffset, |
| 819 y: insetDimensions.y * this.zoom - this.window_.pageYOffset, | 803 y: insetDimensions.y * this.zoom - this.window_.pageYOffset, |
| 820 width: insetDimensions.width * this.zoom, | 804 width: insetDimensions.width * this.zoom, |
| 821 height: insetDimensions.height * this.zoom | 805 height: insetDimensions.height * this.zoom |
| 822 }; | 806 }; |
| 823 } | 807 } |
| 824 }; | 808 }; |
| OLD | NEW |