Chromium Code Reviews
|
| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 /** | |
| 6 * This view consists of two nested divs. The outer one has a horizontal | |
| 7 * scrollbar and the inner one has a height of 1 pixel and a width set to | |
| 8 * allow an appropriate scroll range. The view reports scroll events to | |
| 9 * a callback specified on construction. | |
| 10 * | |
| 11 * All this funkiness is necessary because there is no HTML scroll control. | |
| 12 * TODO(mmenke): Consider implementing our own scrollbar directly. | |
| 13 */ | |
| 14 var HorizontalScrollbarView = (function() { | |
| 15 'use strict'; | |
| 16 | |
| 17 // We inherit from DivView. | |
| 18 var superClass = DivView; | |
| 19 | |
| 20 /** | |
| 21 * @constructor | |
| 22 */ | |
| 23 function HorizontalScrollbarView(div, innerDiv, callback) { | |
|
eroman
2011/11/16 04:03:46
nit: innerDiv --> innerDivId; div --> divId
mmenke
2011/11/16 18:39:35
Done.
| |
| 24 superClass.call(this, div); | |
| 25 this.callback_ = callback; | |
| 26 this.innerDiv_ = $(innerDiv); | |
| 27 $(div).onscroll = this.onScroll_.bind(this); | |
| 28 | |
| 29 // The current range and position of the scrollbar. Because DOM updates | |
| 30 // are asynchronous, the current state cannot be read directly from the DOM | |
| 31 // after updating the range. | |
| 32 this.range_ = 0; | |
| 33 this.position_ = 0; | |
| 34 | |
| 35 // The DOM updates asynchronously, so sometimes we need a timer to update | |
| 36 // the current scroll position after resizing the scrollbar. | |
| 37 this.updatePositionTimerId_ = null; | |
| 38 } | |
| 39 | |
| 40 HorizontalScrollbarView.prototype = { | |
| 41 // Inherit the superclass's methods. | |
| 42 __proto__: superClass.prototype, | |
| 43 | |
| 44 setGeometry: function(left, top, width, height) { | |
| 45 superClass.prototype.setGeometry.call(this, left, top, width, height); | |
| 46 this.setRange(this.range_); | |
| 47 }, | |
| 48 | |
| 49 show: function(isVisible) { | |
| 50 superClass.prototype.show.call(this, isVisible); | |
| 51 }, | |
| 52 | |
| 53 /** | |
| 54 * Sets the range of the scrollbar. The scrollbar can have a value | |
| 55 * anywhere from 0 up to, and including, |range|. The width of the drag | |
| 56 * area on the scrollbar will generally be based on the width of the | |
| 57 * scrollbar relative to the size of |range|, so if the scrollbar is about | |
| 58 * the size of the thing we're scrolling, we get fairly nice behavior. | |
| 59 * | |
| 60 * If |range| is less than the original position, |position_| is set to | |
| 61 * |range|. Otherwise, it is not modified. | |
| 62 */ | |
| 63 setRange: function(range) { | |
| 64 this.range_ = range; | |
| 65 setNodeWidth(this.innerDiv_, this.getWidth() + range); | |
| 66 if (range < this.position_) | |
| 67 this.position_ = range; | |
| 68 this.setPosition(this.position_); | |
| 69 }, | |
| 70 | |
| 71 /** | |
| 72 * Sets the position of the scrollbar. |position| must be between 0 and | |
| 73 * |range|, inclusive. | |
| 74 */ | |
| 75 setPosition: function(position) { | |
| 76 this.position_ = position; | |
| 77 this.updatePosition_(); | |
| 78 }, | |
| 79 | |
| 80 /** | |
| 81 * Updates the visible position of the scrollbar to be |position_|. | |
| 82 * On failure, calls itself again after a timeout. This is needed because | |
| 83 * setPosition does not synchronously update the DOM. | |
| 84 */ | |
| 85 updatePosition_: function() { | |
| 86 // Clear timer if we have one, so we don't have two timers running at | |
| 87 // once, fighting over the position. Note that this is safe even if | |
| 88 // we were just call from the timer, in which case clearTimeout will | |
|
eroman
2011/11/16 04:03:46
nit: "just call from" --> "just called from".
mmenke
2011/11/16 18:39:35
Done.
| |
| 89 // silently fail. | |
| 90 if (this.updatePositionTimerId_ !== null) { | |
| 91 window.clearTimeout(this.updatePositionTimerId_); | |
| 92 this.updatePositionTimerId_ = null; | |
| 93 } | |
| 94 | |
| 95 this.getNode().scrollLeft = this.position_; | |
| 96 if (this.getNode().scrollLeft != this.position_) { | |
| 97 this.updatePositionTimerId_ = | |
| 98 window.setTimeout(this.updatePosition_.bind(this)); | |
| 99 } | |
| 100 }, | |
| 101 | |
| 102 getRange: function() { | |
| 103 return this.range_; | |
| 104 }, | |
| 105 | |
| 106 getPosition: function() { | |
| 107 return this.position_; | |
| 108 }, | |
| 109 | |
| 110 onScroll_: function() { | |
| 111 // If we're waiting to update the range, ignore messages from the | |
| 112 // scrollbar. | |
| 113 if (this.updatePositionTimerId_ !== null) | |
| 114 return; | |
| 115 var newPosition = this.getNode().scrollLeft; | |
| 116 if (newPosition == this.position_) | |
| 117 return; | |
| 118 this.position_ = newPosition; | |
| 119 this.callback_(); | |
| 120 } | |
| 121 }; | |
| 122 | |
| 123 return HorizontalScrollbarView; | |
| 124 })(); | |
| OLD | NEW |