OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 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 * @constructor | |
7 * @param {!WebInspector.StaticViewportControl.Provider} provider | |
8 */ | |
9 WebInspector.StaticViewportControl = function(provider) | |
10 { | |
11 this.element = createElement("div"); | |
12 this.element.style.overflow = "auto"; | |
13 this._innerElement = this.element.createChild("div"); | |
14 this._innerElement.style.height = "0px"; | |
15 this._innerElement.style.position = "relative"; | |
16 this._innerElement.style.overflow = "hidden"; | |
17 this._provider = provider; | |
18 this.element.addEventListener("scroll", this.refresh.bind(this), false); | |
19 | |
20 this._firstActiveIndex = 0; | |
21 this._lastActiveIndex = -1; | |
22 this._itemCount = 0; | |
23 } | |
24 | |
25 WebInspector.StaticViewportControl.prototype = { | |
26 invalidate: function() | |
27 { | |
28 this._itemCount = this._provider.itemCount(); | |
29 this._innerElement.removeChildren(); | |
30 this.refresh(); | |
31 }, | |
32 | |
33 refresh: function() | |
dgozman
2016/09/28 16:50:06
What's the difference from invalidate? Let's have
einbinder
2016/09/28 19:19:42
invalidate rebuilds the contents inside the viewpo
dgozman
2016/09/28 20:56:18
As a client of viewport, I still don't understand
einbinder
2016/09/29 01:04:20
Merged invalidate into refresh.
| |
34 { | |
35 if (!this._visibleHeight()) | |
36 return; // Do nothing for invisible controls. | |
37 | |
38 var height = 0; | |
39 this._cumulativeHeights = new Int32Array(this._itemCount); | |
40 for (var i = 0; i < this._itemCount; ++i) | |
41 this._cumulativeHeights[i] = height += this._provider.fastHeight(i); | |
dgozman
2016/09/28 16:50:05
style: this should be two lines
einbinder
2016/09/28 19:19:42
Done.
| |
42 this._innerElement.style.height = height + "px"; | |
43 | |
44 this._update(); | |
45 }, | |
46 | |
47 _update: function() | |
48 { | |
49 if (!this._cumulativeHeights) | |
50 return this.refresh(); | |
dgozman
2016/09/28 16:50:05
refresh does not return anything
einbinder
2016/09/28 19:19:42
Done.
| |
51 | |
52 var visibleHeight = this._visibleHeight(); | |
53 var visibleFrom = this.element.scrollTop; | |
54 var activeHeight = visibleHeight * 2; | |
55 this._firstActiveIndex = Math.max(Array.prototype.lowerBound.call(this._ cumulativeHeights, visibleFrom + 1 - (activeHeight - visibleHeight) / 2), 0); | |
56 this._lastActiveIndex = Math.min(Array.prototype.lowerBound.call(this._c umulativeHeights, visibleFrom + visibleHeight + (activeHeight - visibleHeight) / 2), this._itemCount - 1); | |
57 | |
58 for (var i = this._innerElement.children.length - 1; i >= 0; --i) { | |
59 var element = this._innerElement.children[i]; | |
60 if (element.__insertedAt < this._firstActiveIndex || element.__inser tedAt > this._lastActiveIndex) | |
61 element.remove(); | |
dgozman
2016/09/28 16:50:06
Remove/nullify element.__insertedAt
einbinder
2016/09/28 19:19:42
I'd have to do that above where I call this._inner
dgozman
2016/09/28 20:56:18
Nothing prevents me from moving my element to anot
einbinder
2016/09/29 01:04:20
Gave each instance of StaticViewportControl its ow
| |
62 } | |
63 | |
64 for (var i = this._firstActiveIndex; i <= this._lastActiveIndex; ++i) | |
65 this._insertElement(i); | |
66 }, | |
67 | |
68 /** | |
69 * @param {number} index | |
70 */ | |
71 _insertElement: function(index) | |
72 { | |
73 var element = this._provider.itemElement(index); | |
74 if (!element || element.parentElement) | |
75 return; | |
76 | |
77 element.style.position = "absolute"; | |
78 element.style.top = (this._cumulativeHeights[index - 1] || 0) + "px"; | |
79 element.style.left = "0"; | |
80 element.style.right = "0"; | |
81 element.__insertedAt = index; | |
dgozman
2016/09/28 16:50:06
Use symbol.
einbinder
2016/09/28 19:19:42
Done.
| |
82 this._innerElement.appendChild(element); | |
83 }, | |
84 | |
85 /** | |
86 * @return {number} | |
87 */ | |
88 firstVisibleIndex: function() | |
89 { | |
90 var firstVisibleIndex = Math.max(Array.prototype.lowerBound.call(this._c umulativeHeights, this.element.scrollTop + 1), 0); | |
91 return Math.max(firstVisibleIndex, this._firstActiveIndex); | |
dgozman
2016/09/28 16:50:06
I don't get why we use this._firstActiveIndex.
| |
92 }, | |
93 | |
94 /** | |
95 * @return {number} | |
96 */ | |
97 lastVisibleIndex: function() | |
98 { | |
99 var lastVisibleIndex = Math.max(Array.prototype.lowerBound.call(this._cu mulativeHeights, this.element.scrollTop + this._visibleHeight()), 0); | |
100 return Math.min(lastVisibleIndex, this._lastActiveIndex); | |
dgozman
2016/09/28 16:50:05
ditto
einbinder
2016/09/28 19:19:42
If the viewport has very few items, lastVisibleInd
dgozman
2016/09/28 20:56:18
Thanks for explaining.
This is the only place we u
einbinder
2016/09/29 01:04:20
Done.
| |
101 }, | |
102 | |
103 /** | |
104 * @param {number} index | |
105 * @param {boolean=} makeLast | |
106 */ | |
107 scrollItemIntoView: function(index, makeLast) | |
108 { | |
109 var firstVisibleIndex = this.firstVisibleIndex(); | |
110 var lastVisibleIndex = this.lastVisibleIndex(); | |
111 if (index > firstVisibleIndex && index < lastVisibleIndex) | |
112 return; | |
113 if (makeLast) | |
114 this.forceScrollItemToBeLast(index); | |
115 else if (index <= firstVisibleIndex) | |
116 this.forceScrollItemToBeFirst(index); | |
117 else if (index >= lastVisibleIndex) | |
118 this.forceScrollItemToBeLast(index); | |
119 }, | |
120 | |
121 /** | |
122 * @param {number} index | |
123 */ | |
124 forceScrollItemToBeFirst: function(index) | |
125 { | |
126 this.element.scrollTop = index > 0 ? this._cumulativeHeights[index - 1] : 0; | |
127 this._update(); | |
128 }, | |
129 | |
130 /** | |
131 * @param {number} index | |
132 */ | |
133 forceScrollItemToBeLast: function(index) | |
134 { | |
135 this.element.scrollTop = this._cumulativeHeights[index] - this._visibleH eight(); | |
136 this._update(); | |
137 }, | |
138 | |
139 /** | |
140 * @return {number} | |
141 */ | |
142 _visibleHeight: function() | |
143 { | |
144 return this.element.offsetHeight; | |
dgozman
2016/09/28 16:50:06
Maybe inline?
einbinder
2016/09/28 19:19:42
ViewportControl has a comment here about not using
| |
145 } | |
146 } | |
147 | |
148 /** | |
149 * @interface | |
150 */ | |
151 WebInspector.StaticViewportControl.Provider = function() | |
152 { | |
153 } | |
154 | |
155 WebInspector.StaticViewportControl.Provider.prototype = { | |
156 /** | |
157 * @param {number} index | |
158 * @return {number} | |
159 */ | |
160 fastHeight: function(index) { return 0; }, | |
161 | |
162 /** | |
163 * @return {number} | |
164 */ | |
165 itemCount: function() { return 0; }, | |
166 | |
167 /** | |
168 * @param {number} index | |
169 * @return {?Element} | |
170 */ | |
171 itemElement: function(index) { return null; } | |
172 } | |
OLD | NEW |