Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2013 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 'use strict'; | |
| 6 | |
| 7 var ScrollBar = cr.ui.define('div'); | |
|
yoshiki
2013/04/17 08:12:00
Add JSdoc.
/**
* Creates a new scroll bar elemen
mtomasz
2013/04/17 08:52:21
Done.
| |
| 8 | |
| 9 /** | |
| 10 * Creates a vertical scrollbar. | |
| 11 * | |
| 12 * @param {Element} parent Parent element, must have a relative or absolute | |
| 13 * positioning. | |
| 14 * @param {Element=} opt_scrollableArea Element with scrollable contents. | |
| 15 * If not passed, then call attachToView manually when the scrollable | |
| 16 * element becomes available. | |
| 17 */ | |
| 18 ScrollBar.createVertical = function(parent, opt_scrollableArea) { | |
| 19 var scrollbar = new ScrollBar(); | |
| 20 parent.appendChild(scrollbar); | |
| 21 if (opt_scrollableArea) | |
| 22 scrollbar.attachToView(opt_scrollableArea); | |
| 23 }; | |
| 24 | |
| 25 /** | |
| 26 * Mode of the scrollbar. As for now, only vertical scrollbars are supported. | |
| 27 * @type {number} | |
| 28 */ | |
| 29 ScrollBar.Mode = { | |
| 30 VERTICAL: 0, | |
| 31 HORIZONTAL: 1 | |
| 32 }; | |
| 33 | |
| 34 ScrollBar.prototype = { | |
| 35 set mode(value) { | |
| 36 this.mode_ = value; | |
| 37 if (this.mode_ == ScrollBar.Mode.VERTICAL) { | |
| 38 this.classList.remove('scrollbar-horizontal'); | |
| 39 this.classList.add('scrollbar-vertical'); | |
| 40 } else { | |
| 41 this.classList.remove('scrollbar-vertical'); | |
| 42 this.classList.add('scrollbar-horizontal'); | |
| 43 } | |
| 44 this.redraw_(); | |
| 45 }, | |
| 46 get mode() { | |
| 47 return this.mode_; | |
| 48 } | |
| 49 }; | |
| 50 | |
| 51 /** | |
| 52 * Inherits after HTMLDivElement. | |
| 53 */ | |
| 54 ScrollBar.prototype.__proto__ = HTMLDivElement.prototype; | |
| 55 | |
| 56 /** | |
| 57 * Initializes the DOM structure of the scrollbar. | |
| 58 */ | |
| 59 ScrollBar.prototype.decorate = function() { | |
| 60 this.classList.add('scrollbar'); | |
| 61 this.button_ = util.createChild(this, 'scrollbar-button', 'div'); | |
| 62 this.mode = ScrollBar.Mode.VERTICAL; | |
| 63 | |
| 64 this.button_.addEventListener('mousedown', | |
| 65 this.onButtonPressed_.bind(this)); | |
| 66 window.addEventListener('mouseup', this.onMouseUp_.bind(this)); | |
| 67 window.addEventListener('mousemove', this.onMouseMove_.bind(this)); | |
| 68 | |
| 69 // Unfortunately we need to pool, since we can't easily detect resizing | |
| 70 // and content changes. | |
| 71 setInterval(this.redraw_.bind(this), 50); | |
| 72 }; | |
| 73 | |
| 74 /** | |
| 75 * Attaches the scrollbar to a scrollable element and attaches handlers. | |
| 76 * @param {Element} view Scrollable element. | |
| 77 */ | |
| 78 ScrollBar.prototype.attachToView = function(view) { | |
| 79 this.view_ = view; | |
| 80 this.view_.addEventListener('scroll', this.onScroll_.bind(this)); | |
| 81 this.redraw_(); | |
| 82 }; | |
| 83 | |
| 84 /** | |
| 85 * Scroll handler. | |
| 86 * @private | |
| 87 */ | |
| 88 ScrollBar.prototype.onScroll_ = function() { | |
| 89 this.redraw_(); | |
| 90 }; | |
| 91 | |
| 92 /** | |
| 93 * Pressing on the scrollbar's button handler. | |
| 94 * | |
| 95 * @param {Event} event Pressing event. | |
| 96 * @private | |
| 97 */ | |
| 98 ScrollBar.prototype.onButtonPressed_ = function(event) { | |
| 99 this.buttonPressed_ = true; | |
| 100 this.buttonPressedEvent_ = event; | |
| 101 this.buttonPressedPosition_ = this.button_.offsetTop - this.view_.offsetTop; | |
| 102 this.button_.classList.add('pressed'); | |
| 103 | |
| 104 event.preventDefault(); | |
| 105 }; | |
| 106 | |
| 107 /** | |
| 108 * Releasing the button handler. Note, that it may not be called when releasing | |
| 109 * outside of the window. Therefore this is also called from onMouseMove_. | |
| 110 * | |
| 111 * @param {Event} event Mouse event. | |
| 112 * @private | |
| 113 */ | |
| 114 ScrollBar.prototype.onMouseUp_ = function(event) { | |
| 115 this.buttonPressed_ = false; | |
| 116 this.button_.classList.remove('pressed'); | |
| 117 }; | |
| 118 | |
| 119 /** | |
| 120 * Mouse move handler. Updates the scroll position. | |
| 121 * | |
| 122 * @param {Event} event Mouse event. | |
| 123 * @private | |
| 124 */ | |
| 125 ScrollBar.prototype.onMouseMove_ = function(event) { | |
| 126 if (!this.buttonPressed_) | |
| 127 return; | |
| 128 if (!event.which) { | |
| 129 this.onMouseUp_(event); | |
| 130 return; | |
| 131 } | |
| 132 var clientSize = this.view_.clientHeight; | |
| 133 var totalSize = this.view_.scrollHeight; | |
| 134 var buttonSize = Math.max(50, clientSize / totalSize * clientSize); | |
| 135 | |
| 136 var buttonPosition = this.buttonPressedPosition_ + | |
| 137 (event.screenY - this.buttonPressedEvent_.screenY); | |
| 138 var scrollPosition = totalSize * (buttonPosition / clientSize); | |
| 139 | |
| 140 this.view_.scrollTop = scrollPosition; | |
| 141 this.redraw_(); | |
| 142 }; | |
| 143 | |
| 144 /** | |
| 145 * Redraws the scrollbar. | |
| 146 * @private | |
| 147 */ | |
| 148 ScrollBar.prototype.redraw_ = function() { | |
| 149 if (!this.view_) | |
| 150 return; | |
| 151 | |
| 152 var clientSize = this.view_.clientHeight; | |
| 153 var clientTop = this.view_.offsetTop; | |
| 154 var scrollPosition = this.view_.scrollTop; | |
| 155 var totalSize = this.view_.scrollHeight; | |
| 156 | |
| 157 this.hidden = totalSize <= clientSize; | |
| 158 | |
| 159 var buttonSize = Math.max(50, clientSize / totalSize * clientSize); | |
| 160 var buttonPosition = scrollPosition / (totalSize - clientSize) * | |
| 161 (clientSize - buttonSize); | |
| 162 | |
| 163 this.button_.style.top = buttonPosition + clientTop + 'px'; | |
| 164 this.button_.style.height = buttonSize + 'px'; | |
| 165 }; | |
| OLD | NEW |