Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(203)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/ui_lazy/OverviewGrid.js

Issue 2623743002: DevTools: extract modules (non-extensions) (Closed)
Patch Set: rebaseline Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 /**
32 * @unrestricted
33 */
34 UI.OverviewGrid = class {
35 /**
36 * @param {string} prefix
37 */
38 constructor(prefix) {
39 this.element = createElement('div');
40 this.element.id = prefix + '-overview-container';
41
42 this._grid = new UI.TimelineGrid();
43 this._grid.element.id = prefix + '-overview-grid';
44 this._grid.setScrollTop(0);
45
46 this.element.appendChild(this._grid.element);
47
48 this._window = new UI.OverviewGrid.Window(this.element, this._grid.dividersL abelBarElement);
49 }
50
51 /**
52 * @return {number}
53 */
54 clientWidth() {
55 return this.element.clientWidth;
56 }
57
58 /**
59 * @param {!UI.TimelineGrid.Calculator} calculator
60 */
61 updateDividers(calculator) {
62 this._grid.updateDividers(calculator);
63 }
64
65 /**
66 * @param {!Array.<!Element>} dividers
67 */
68 addEventDividers(dividers) {
69 this._grid.addEventDividers(dividers);
70 }
71
72 removeEventDividers() {
73 this._grid.removeEventDividers();
74 }
75
76 reset() {
77 this._window.reset();
78 }
79
80 /**
81 * @return {number}
82 */
83 windowLeft() {
84 return this._window.windowLeft;
85 }
86
87 /**
88 * @return {number}
89 */
90 windowRight() {
91 return this._window.windowRight;
92 }
93
94 /**
95 * @param {number} left
96 * @param {number} right
97 */
98 setWindow(left, right) {
99 this._window._setWindow(left, right);
100 }
101
102 /**
103 * @param {symbol} eventType
104 * @param {function(!Common.Event)} listener
105 * @param {!Object=} thisObject
106 * @return {!Common.EventTarget.EventDescriptor}
107 */
108 addEventListener(eventType, listener, thisObject) {
109 return this._window.addEventListener(eventType, listener, thisObject);
110 }
111
112 /**
113 * @param {?function(!Event):boolean} clickHandler
114 */
115 setClickHandler(clickHandler) {
116 this._window.setClickHandler(clickHandler);
117 }
118
119 /**
120 * @param {number} zoomFactor
121 * @param {number} referencePoint
122 */
123 zoom(zoomFactor, referencePoint) {
124 this._window._zoom(zoomFactor, referencePoint);
125 }
126
127 /**
128 * @param {boolean} enabled
129 */
130 setResizeEnabled(enabled) {
131 this._window.setEnabled(enabled);
132 }
133 };
134
135 UI.OverviewGrid.MinSelectableSize = 14;
136
137 UI.OverviewGrid.WindowScrollSpeedFactor = .3;
138
139 UI.OverviewGrid.ResizerOffset = 3.5; // half pixel because offset values are no t rounded but ceiled
140
141 /**
142 * @unrestricted
143 */
144 UI.OverviewGrid.Window = class extends Common.Object {
145 /**
146 * @param {!Element} parentElement
147 * @param {!Element=} dividersLabelBarElement
148 */
149 constructor(parentElement, dividersLabelBarElement) {
150 super();
151 this._parentElement = parentElement;
152
153 UI.installDragHandle(
154 this._parentElement, this._startWindowSelectorDragging.bind(this), this. _windowSelectorDragging.bind(this),
155 this._endWindowSelectorDragging.bind(this), 'text', null);
156 if (dividersLabelBarElement) {
157 UI.installDragHandle(
158 dividersLabelBarElement, this._startWindowDragging.bind(this), this._w indowDragging.bind(this), null,
159 '-webkit-grabbing', '-webkit-grab');
160 }
161
162 this._parentElement.addEventListener('mousewheel', this._onMouseWheel.bind(t his), true);
163 this._parentElement.addEventListener('dblclick', this._resizeWindowMaximum.b ind(this), true);
164 UI.appendStyle(this._parentElement, 'ui_lazy/overviewGrid.css');
165
166 this._leftResizeElement = parentElement.createChild('div', 'overview-grid-wi ndow-resizer');
167 UI.installDragHandle(
168 this._leftResizeElement, this._resizerElementStartDragging.bind(this),
169 this._leftResizeElementDragging.bind(this), null, 'ew-resize');
170 this._rightResizeElement = parentElement.createChild('div', 'overview-grid-w indow-resizer');
171 UI.installDragHandle(
172 this._rightResizeElement, this._resizerElementStartDragging.bind(this),
173 this._rightResizeElementDragging.bind(this), null, 'ew-resize');
174
175 this._leftCurtainElement = parentElement.createChild('div', 'window-curtain- left');
176 this._rightCurtainElement = parentElement.createChild('div', 'window-curtain -right');
177 this.reset();
178 }
179
180 reset() {
181 this.windowLeft = 0.0;
182 this.windowRight = 1.0;
183 this.setEnabled(true);
184 this._updateCurtains();
185 }
186
187 /**
188 * @param {boolean} enabled
189 */
190 setEnabled(enabled) {
191 this._enabled = enabled;
192 }
193
194 /**
195 * @param {?function(!Event):boolean} clickHandler
196 */
197 setClickHandler(clickHandler) {
198 this._clickHandler = clickHandler;
199 }
200
201 /**
202 * @param {!Event} event
203 */
204 _resizerElementStartDragging(event) {
205 if (!this._enabled)
206 return false;
207 this._resizerParentOffsetLeft = event.pageX - event.offsetX - event.target.o ffsetLeft;
208 event.stopPropagation();
209 return true;
210 }
211
212 /**
213 * @param {!Event} event
214 */
215 _leftResizeElementDragging(event) {
216 this._resizeWindowLeft(event.pageX - this._resizerParentOffsetLeft);
217 event.preventDefault();
218 }
219
220 /**
221 * @param {!Event} event
222 */
223 _rightResizeElementDragging(event) {
224 this._resizeWindowRight(event.pageX - this._resizerParentOffsetLeft);
225 event.preventDefault();
226 }
227
228 /**
229 * @param {!Event} event
230 * @return {boolean}
231 */
232 _startWindowSelectorDragging(event) {
233 if (!this._enabled)
234 return false;
235 this._offsetLeft = this._parentElement.totalOffsetLeft();
236 var position = event.x - this._offsetLeft;
237 this._overviewWindowSelector = new UI.OverviewGrid.WindowSelector(this._pare ntElement, position);
238 return true;
239 }
240
241 /**
242 * @param {!Event} event
243 */
244 _windowSelectorDragging(event) {
245 this._overviewWindowSelector._updatePosition(event.x - this._offsetLeft);
246 event.preventDefault();
247 }
248
249 /**
250 * @param {!Event} event
251 */
252 _endWindowSelectorDragging(event) {
253 var window = this._overviewWindowSelector._close(event.x - this._offsetLeft) ;
254 delete this._overviewWindowSelector;
255 var clickThreshold = 3;
256 if (window.end - window.start < clickThreshold) {
257 if (this._clickHandler && this._clickHandler.call(null, event))
258 return;
259 var middle = window.end;
260 window.start = Math.max(0, middle - UI.OverviewGrid.MinSelectableSize / 2) ;
261 window.end = Math.min(this._parentElement.clientWidth, middle + UI.Overvie wGrid.MinSelectableSize / 2);
262 } else if (window.end - window.start < UI.OverviewGrid.MinSelectableSize) {
263 if (this._parentElement.clientWidth - window.end > UI.OverviewGrid.MinSele ctableSize)
264 window.end = window.start + UI.OverviewGrid.MinSelectableSize;
265 else
266 window.start = window.end - UI.OverviewGrid.MinSelectableSize;
267 }
268 this._setWindowPosition(window.start, window.end);
269 }
270
271 /**
272 * @param {!Event} event
273 * @return {boolean}
274 */
275 _startWindowDragging(event) {
276 this._dragStartPoint = event.pageX;
277 this._dragStartLeft = this.windowLeft;
278 this._dragStartRight = this.windowRight;
279 event.stopPropagation();
280 return true;
281 }
282
283 /**
284 * @param {!Event} event
285 */
286 _windowDragging(event) {
287 event.preventDefault();
288 var delta = (event.pageX - this._dragStartPoint) / this._parentElement.clien tWidth;
289 if (this._dragStartLeft + delta < 0)
290 delta = -this._dragStartLeft;
291
292 if (this._dragStartRight + delta > 1)
293 delta = 1 - this._dragStartRight;
294
295 this._setWindow(this._dragStartLeft + delta, this._dragStartRight + delta);
296 }
297
298 /**
299 * @param {number} start
300 */
301 _resizeWindowLeft(start) {
302 // Glue to edge.
303 if (start < 10)
304 start = 0;
305 else if (start > this._rightResizeElement.offsetLeft - 4)
306 start = this._rightResizeElement.offsetLeft - 4;
307 this._setWindowPosition(start, null);
308 }
309
310 /**
311 * @param {number} end
312 */
313 _resizeWindowRight(end) {
314 // Glue to edge.
315 if (end > this._parentElement.clientWidth - 10)
316 end = this._parentElement.clientWidth;
317 else if (end < this._leftResizeElement.offsetLeft + UI.OverviewGrid.MinSelec tableSize)
318 end = this._leftResizeElement.offsetLeft + UI.OverviewGrid.MinSelectableSi ze;
319 this._setWindowPosition(null, end);
320 }
321
322 _resizeWindowMaximum() {
323 this._setWindowPosition(0, this._parentElement.clientWidth);
324 }
325
326 /**
327 * @param {number} windowLeft
328 * @param {number} windowRight
329 */
330 _setWindow(windowLeft, windowRight) {
331 this.windowLeft = windowLeft;
332 this.windowRight = windowRight;
333 this._updateCurtains();
334 this.dispatchEventToListeners(UI.OverviewGrid.Events.WindowChanged);
335 }
336
337 _updateCurtains() {
338 var left = this.windowLeft;
339 var right = this.windowRight;
340 var width = right - left;
341
342 // We allow actual time window to be arbitrarily small but don't want the UI window to be too small.
343 var widthInPixels = width * this._parentElement.clientWidth;
344 var minWidthInPixels = UI.OverviewGrid.MinSelectableSize / 2;
345 if (widthInPixels < minWidthInPixels) {
346 var factor = minWidthInPixels / widthInPixels;
347 left = ((this.windowRight + this.windowLeft) - width * factor) / 2;
348 right = ((this.windowRight + this.windowLeft) + width * factor) / 2;
349 }
350 this._leftResizeElement.style.left = (100 * left).toFixed(2) + '%';
351 this._rightResizeElement.style.left = (100 * right).toFixed(2) + '%';
352
353 this._leftCurtainElement.style.width = (100 * left).toFixed(2) + '%';
354 this._rightCurtainElement.style.width = (100 * (1 - right)).toFixed(2) + '%' ;
355 }
356
357 /**
358 * @param {?number} start
359 * @param {?number} end
360 */
361 _setWindowPosition(start, end) {
362 var clientWidth = this._parentElement.clientWidth;
363 var windowLeft = typeof start === 'number' ? start / clientWidth : this.wind owLeft;
364 var windowRight = typeof end === 'number' ? end / clientWidth : this.windowR ight;
365 this._setWindow(windowLeft, windowRight);
366 }
367
368 /**
369 * @param {!Event} event
370 */
371 _onMouseWheel(event) {
372 if (!this._enabled)
373 return;
374 if (typeof event.wheelDeltaY === 'number' && event.wheelDeltaY) {
375 const zoomFactor = 1.1;
376 const mouseWheelZoomSpeed = 1 / 120;
377
378 var reference = event.offsetX / event.target.clientWidth;
379 this._zoom(Math.pow(zoomFactor, -event.wheelDeltaY * mouseWheelZoomSpeed), reference);
380 }
381 if (typeof event.wheelDeltaX === 'number' && event.wheelDeltaX) {
382 var offset = Math.round(event.wheelDeltaX * UI.OverviewGrid.WindowScrollSp eedFactor);
383 var windowLeft = this._leftResizeElement.offsetLeft + UI.OverviewGrid.Resi zerOffset;
384 var windowRight = this._rightResizeElement.offsetLeft + UI.OverviewGrid.Re sizerOffset;
385
386 if (windowLeft - offset < 0)
387 offset = windowLeft;
388
389 if (windowRight - offset > this._parentElement.clientWidth)
390 offset = windowRight - this._parentElement.clientWidth;
391
392 this._setWindowPosition(windowLeft - offset, windowRight - offset);
393
394 event.preventDefault();
395 }
396 }
397
398 /**
399 * @param {number} factor
400 * @param {number} reference
401 */
402 _zoom(factor, reference) {
403 var left = this.windowLeft;
404 var right = this.windowRight;
405 var windowSize = right - left;
406 var newWindowSize = factor * windowSize;
407 if (newWindowSize > 1) {
408 newWindowSize = 1;
409 factor = newWindowSize / windowSize;
410 }
411 left = reference + (left - reference) * factor;
412 left = Number.constrain(left, 0, 1 - newWindowSize);
413
414 right = reference + (right - reference) * factor;
415 right = Number.constrain(right, newWindowSize, 1);
416 this._setWindow(left, right);
417 }
418 };
419
420 /** @enum {symbol} */
421 UI.OverviewGrid.Events = {
422 WindowChanged: Symbol('WindowChanged')
423 };
424
425 /**
426 * @unrestricted
427 */
428 UI.OverviewGrid.WindowSelector = class {
429 constructor(parent, position) {
430 this._startPosition = position;
431 this._width = parent.offsetWidth;
432 this._windowSelector = createElement('div');
433 this._windowSelector.className = 'overview-grid-window-selector';
434 this._windowSelector.style.left = this._startPosition + 'px';
435 this._windowSelector.style.right = this._width - this._startPosition + 'px';
436 parent.appendChild(this._windowSelector);
437 }
438
439 _close(position) {
440 position = Math.max(0, Math.min(position, this._width));
441 this._windowSelector.remove();
442 return this._startPosition < position ? {start: this._startPosition, end: po sition} :
443 {start: position, end: this._startPo sition};
444 }
445
446 _updatePosition(position) {
447 position = Math.max(0, Math.min(position, this._width));
448 if (position < this._startPosition) {
449 this._windowSelector.style.left = position + 'px';
450 this._windowSelector.style.right = this._width - this._startPosition + 'px ';
451 } else {
452 this._windowSelector.style.left = this._startPosition + 'px';
453 this._windowSelector.style.right = this._width - position + 'px';
454 }
455 }
456 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698