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 |