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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/ui/SplitWidget.js

Issue 2466123002: DevTools: reformat front-end code to match chromium style. (Closed)
Patch Set: all done Created 4 years, 1 month 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
1 /* 1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 10 *
11 * 2. Redistributions in binary form must reproduce the above 11 * 2. Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer 12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the 13 * in the documentation and/or other materials provided with the
14 * distribution. 14 * distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS 16 * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
20 * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 /**
29 * @unrestricted
30 */
31 WebInspector.SplitWidget = class extends WebInspector.Widget {
32 /**
33 * @param {boolean} isVertical
34 * @param {boolean} secondIsSidebar
35 * @param {string=} settingName
36 * @param {number=} defaultSidebarWidth
37 * @param {number=} defaultSidebarHeight
38 * @param {boolean=} constraintsInDip
39 */
40 constructor(isVertical, secondIsSidebar, settingName, defaultSidebarWidth, def aultSidebarHeight, constraintsInDip) {
41 super(true);
42 this.element.classList.add('split-widget');
43 this.registerRequiredCSS('ui/splitWidget.css');
28 44
29 /** 45 this.contentElement.classList.add('shadow-split-widget');
30 * @constructor 46 this._mainElement =
31 * @extends {WebInspector.Widget} 47 this.contentElement.createChild('div', 'shadow-split-widget-contents sha dow-split-widget-main vbox');
32 * @param {boolean} isVertical 48 this._mainElement.createChild('content').select = '.insertion-point-main';
33 * @param {boolean} secondIsSidebar 49 this._sidebarElement =
34 * @param {string=} settingName 50 this.contentElement.createChild('div', 'shadow-split-widget-contents sha dow-split-widget-sidebar vbox');
35 * @param {number=} defaultSidebarWidth 51 this._sidebarElement.createChild('content').select = '.insertion-point-sideb ar';
36 * @param {number=} defaultSidebarHeight 52 this._resizerElement = this.contentElement.createChild('div', 'shadow-split- widget-resizer');
37 * @param {boolean=} constraintsInDip
38 */
39 WebInspector.SplitWidget = function(isVertical, secondIsSidebar, settingName, de faultSidebarWidth, defaultSidebarHeight, constraintsInDip)
40 {
41 WebInspector.Widget.call(this, true);
42 this.element.classList.add("split-widget");
43 this.registerRequiredCSS("ui/splitWidget.css");
44
45 this.contentElement.classList.add("shadow-split-widget");
46 this._mainElement = this.contentElement.createChild("div", "shadow-split-wid get-contents shadow-split-widget-main vbox");
47 this._mainElement.createChild("content").select = ".insertion-point-main";
48 this._sidebarElement = this.contentElement.createChild("div", "shadow-split- widget-contents shadow-split-widget-sidebar vbox");
49 this._sidebarElement.createChild("content").select = ".insertion-point-sideb ar";
50 this._resizerElement = this.contentElement.createChild("div", "shadow-split- widget-resizer");
51 53
52 this._resizerWidget = new WebInspector.SimpleResizerWidget(); 54 this._resizerWidget = new WebInspector.SimpleResizerWidget();
53 this._resizerWidget.setEnabled(true); 55 this._resizerWidget.setEnabled(true);
54 this._resizerWidget.addEventListener(WebInspector.ResizerWidget.Events.Resiz eStart, this._onResizeStart, this); 56 this._resizerWidget.addEventListener(WebInspector.ResizerWidget.Events.Resiz eStart, this._onResizeStart, this);
55 this._resizerWidget.addEventListener(WebInspector.ResizerWidget.Events.Resiz eUpdate, this._onResizeUpdate, this); 57 this._resizerWidget.addEventListener(WebInspector.ResizerWidget.Events.Resiz eUpdate, this._onResizeUpdate, this);
56 this._resizerWidget.addEventListener(WebInspector.ResizerWidget.Events.Resiz eEnd, this._onResizeEnd, this); 58 this._resizerWidget.addEventListener(WebInspector.ResizerWidget.Events.Resiz eEnd, this._onResizeEnd, this);
57 59
58 this._defaultSidebarWidth = defaultSidebarWidth || 200; 60 this._defaultSidebarWidth = defaultSidebarWidth || 200;
59 this._defaultSidebarHeight = defaultSidebarHeight || this._defaultSidebarWid th; 61 this._defaultSidebarHeight = defaultSidebarHeight || this._defaultSidebarWid th;
60 this._constraintsInDip = !!constraintsInDip; 62 this._constraintsInDip = !!constraintsInDip;
61 this._setting = settingName ? WebInspector.settings.createSetting(settingNam e, {}) : null; 63 this._setting = settingName ? WebInspector.settings.createSetting(settingNam e, {}) : null;
62 64
63 this.setSecondIsSidebar(secondIsSidebar); 65 this.setSecondIsSidebar(secondIsSidebar);
64 66
65 this._innerSetVertical(isVertical); 67 this._innerSetVertical(isVertical);
66 this._showMode = WebInspector.SplitWidget.ShowMode.Both; 68 this._showMode = WebInspector.SplitWidget.ShowMode.Both;
67 69
68 // Should be called after isVertical has the right value. 70 // Should be called after isVertical has the right value.
69 this.installResizer(this._resizerElement); 71 this.installResizer(this._resizerElement);
72 }
73
74 /**
75 * @return {boolean}
76 */
77 isVertical() {
78 return this._isVertical;
79 }
80
81 /**
82 * @param {boolean} isVertical
83 */
84 setVertical(isVertical) {
85 if (this._isVertical === isVertical)
86 return;
87
88 this._innerSetVertical(isVertical);
89
90 if (this.isShowing())
91 this._updateLayout();
92 }
93
94 /**
95 * @param {boolean} isVertical
96 */
97 _innerSetVertical(isVertical) {
98 this.contentElement.classList.toggle('vbox', !isVertical);
99 this.contentElement.classList.toggle('hbox', isVertical);
100 this._isVertical = isVertical;
101
102 delete this._resizerElementSize;
103 this._sidebarSizeDIP = -1;
104 this._restoreSidebarSizeFromSettings();
105 if (this._shouldSaveShowMode)
106 this._restoreAndApplyShowModeFromSettings();
107 this._updateShowHideSidebarButton();
108 // FIXME: reverse SplitWidget.isVertical meaning.
109 this._resizerWidget.setVertical(!isVertical);
110 this.invalidateConstraints();
111 }
112
113 /**
114 * @param {boolean=} animate
115 */
116 _updateLayout(animate) {
117 delete this._totalSizeCSS; // Lazy update.
118 delete this._totalSizeOtherDimensionCSS;
119
120 // Remove properties that might affect total size calculation.
121 this._mainElement.style.removeProperty('width');
122 this._mainElement.style.removeProperty('height');
123 this._sidebarElement.style.removeProperty('width');
124 this._sidebarElement.style.removeProperty('height');
125
126 this._innerSetSidebarSizeDIP(this._preferredSidebarSizeDIP(), !!animate);
127 }
128
129 /**
130 * @param {!WebInspector.Widget} widget
131 */
132 setMainWidget(widget) {
133 if (this._mainWidget === widget)
134 return;
135 this.suspendInvalidations();
136 if (this._mainWidget)
137 this._mainWidget.detach();
138 this._mainWidget = widget;
139 if (widget) {
140 widget.element.classList.add('insertion-point-main');
141 widget.element.classList.remove('insertion-point-sidebar');
142 widget.attach(this);
143 if (this._showMode === WebInspector.SplitWidget.ShowMode.OnlyMain ||
144 this._showMode === WebInspector.SplitWidget.ShowMode.Both)
145 widget.showWidget(this.element);
146 this.setDefaultFocusedChild(widget);
147 }
148 this.resumeInvalidations();
149 }
150
151 /**
152 * @param {!WebInspector.Widget} widget
153 */
154 setSidebarWidget(widget) {
155 if (this._sidebarWidget === widget)
156 return;
157 this.suspendInvalidations();
158 if (this._sidebarWidget)
159 this._sidebarWidget.detach();
160 this._sidebarWidget = widget;
161 if (widget) {
162 widget.element.classList.add('insertion-point-sidebar');
163 widget.element.classList.remove('insertion-point-main');
164 widget.attach(this);
165 if (this._showMode === WebInspector.SplitWidget.ShowMode.OnlySidebar ||
166 this._showMode === WebInspector.SplitWidget.ShowMode.Both)
167 widget.showWidget(this.element);
168 }
169 this.resumeInvalidations();
170 }
171
172 /**
173 * @return {?WebInspector.Widget}
174 */
175 mainWidget() {
176 return this._mainWidget;
177 }
178
179 /**
180 * @return {?WebInspector.Widget}
181 */
182 sidebarWidget() {
183 return this._sidebarWidget;
184 }
185
186 /**
187 * @override
188 * @param {!WebInspector.Widget} widget
189 */
190 childWasDetached(widget) {
191 if (this._mainWidget === widget)
192 delete this._mainWidget;
193 if (this._sidebarWidget === widget)
194 delete this._sidebarWidget;
195 }
196
197 /**
198 * @return {boolean}
199 */
200 isSidebarSecond() {
201 return this._secondIsSidebar;
202 }
203
204 enableShowModeSaving() {
205 this._shouldSaveShowMode = true;
206 this._restoreAndApplyShowModeFromSettings();
207 }
208
209 /**
210 * @return {string}
211 */
212 showMode() {
213 return this._showMode;
214 }
215
216 /**
217 * @param {boolean} secondIsSidebar
218 */
219 setSecondIsSidebar(secondIsSidebar) {
220 this.contentElement.classList.toggle('shadow-split-widget-first-is-sidebar', !secondIsSidebar);
221 this._secondIsSidebar = secondIsSidebar;
222 }
223
224 /**
225 * @return {?string}
226 */
227 sidebarSide() {
228 if (this._showMode !== WebInspector.SplitWidget.ShowMode.Both)
229 return null;
230 return this._isVertical ? (this._secondIsSidebar ? 'right' : 'left') : (this ._secondIsSidebar ? 'bottom' : 'top');
231 }
232
233 /**
234 * @return {!Element}
235 */
236 resizerElement() {
237 return this._resizerElement;
238 }
239
240 /**
241 * @param {boolean=} animate
242 */
243 hideMain(animate) {
244 this._showOnly(this._sidebarWidget, this._mainWidget, this._sidebarElement, this._mainElement, animate);
245 this._updateShowMode(WebInspector.SplitWidget.ShowMode.OnlySidebar);
246 }
247
248 /**
249 * @param {boolean=} animate
250 */
251 hideSidebar(animate) {
252 this._showOnly(this._mainWidget, this._sidebarWidget, this._mainElement, thi s._sidebarElement, animate);
253 this._updateShowMode(WebInspector.SplitWidget.ShowMode.OnlyMain);
254 }
255
256 /**
257 * @param {boolean} minimized
258 */
259 setSidebarMinimized(minimized) {
260 this._sidebarMinimized = minimized;
261 this.invalidateConstraints();
262 }
263
264 /**
265 * @return {boolean}
266 */
267 isSidebarMinimized() {
268 return this._sidebarMinimized;
269 }
270
271 /**
272 * @param {!WebInspector.Widget} sideToShow
273 * @param {!WebInspector.Widget} sideToHide
274 * @param {!Element} shadowToShow
275 * @param {!Element} shadowToHide
276 * @param {boolean=} animate
277 */
278 _showOnly(sideToShow, sideToHide, shadowToShow, shadowToHide, animate) {
279 this._cancelAnimation();
280
281 /**
282 * @this {WebInspector.SplitWidget}
283 */
284 function callback() {
285 if (sideToShow) {
286 // Make sure main is first in the children list.
287 if (sideToShow === this._mainWidget)
288 this._mainWidget.showWidget(this.element);
289 else
290 this._sidebarWidget.showWidget(this.element);
291 }
292 if (sideToHide)
293 sideToHide.hideWidget();
294
295 this._resizerElement.classList.add('hidden');
296 shadowToShow.classList.remove('hidden');
297 shadowToShow.classList.add('maximized');
298 shadowToHide.classList.add('hidden');
299 shadowToHide.classList.remove('maximized');
300 this._removeAllLayoutProperties();
301 this.doResize();
302 }
303
304 if (animate)
305 this._animate(true, callback.bind(this));
306 else
307 callback.call(this);
308
309 this._sidebarSizeDIP = -1;
310 this.setResizable(false);
311 }
312
313 _removeAllLayoutProperties() {
314 this._sidebarElement.style.removeProperty('flexBasis');
315
316 this._mainElement.style.removeProperty('width');
317 this._mainElement.style.removeProperty('height');
318 this._sidebarElement.style.removeProperty('width');
319 this._sidebarElement.style.removeProperty('height');
320
321 this._resizerElement.style.removeProperty('left');
322 this._resizerElement.style.removeProperty('right');
323 this._resizerElement.style.removeProperty('top');
324 this._resizerElement.style.removeProperty('bottom');
325
326 this._resizerElement.style.removeProperty('margin-left');
327 this._resizerElement.style.removeProperty('margin-right');
328 this._resizerElement.style.removeProperty('margin-top');
329 this._resizerElement.style.removeProperty('margin-bottom');
330 }
331
332 /**
333 * @param {boolean=} animate
334 */
335 showBoth(animate) {
336 if (this._showMode === WebInspector.SplitWidget.ShowMode.Both)
337 animate = false;
338
339 this._cancelAnimation();
340 this._mainElement.classList.remove('maximized', 'hidden');
341 this._sidebarElement.classList.remove('maximized', 'hidden');
342 this._resizerElement.classList.remove('hidden');
343 this.setResizable(true);
344
345 // Make sure main is the first in the children list.
346 this.suspendInvalidations();
347 if (this._sidebarWidget)
348 this._sidebarWidget.showWidget(this.element);
349 if (this._mainWidget)
350 this._mainWidget.showWidget(this.element);
351 this.resumeInvalidations();
352 // Order widgets in DOM properly.
353 this.setSecondIsSidebar(this._secondIsSidebar);
354
355 this._sidebarSizeDIP = -1;
356 this._updateShowMode(WebInspector.SplitWidget.ShowMode.Both);
357 this._updateLayout(animate);
358 }
359
360 /**
361 * @param {boolean} resizable
362 */
363 setResizable(resizable) {
364 this._resizerWidget.setEnabled(resizable);
365 }
366
367 /**
368 * @return {boolean}
369 */
370 isResizable() {
371 return this._resizerWidget.isEnabled();
372 }
373
374 /**
375 * @param {number} size
376 */
377 setSidebarSize(size) {
378 var sizeDIP = WebInspector.zoomManager.cssToDIP(size);
379 this._savedSidebarSizeDIP = sizeDIP;
380 this._saveSetting();
381 this._innerSetSidebarSizeDIP(sizeDIP, false, true);
382 }
383
384 /**
385 * @return {number}
386 */
387 sidebarSize() {
388 var sizeDIP = Math.max(0, this._sidebarSizeDIP);
389 return WebInspector.zoomManager.dipToCSS(sizeDIP);
390 }
391
392 /**
393 * Returns total size in DIP.
394 * @return {number}
395 */
396 _totalSizeDIP() {
397 if (!this._totalSizeCSS) {
398 this._totalSizeCSS = this._isVertical ? this.contentElement.offsetWidth : this.contentElement.offsetHeight;
399 this._totalSizeOtherDimensionCSS =
400 this._isVertical ? this.contentElement.offsetHeight : this.contentElem ent.offsetWidth;
401 }
402 return WebInspector.zoomManager.cssToDIP(this._totalSizeCSS);
403 }
404
405 /**
406 * @param {string} showMode
407 */
408 _updateShowMode(showMode) {
409 this._showMode = showMode;
410 this._saveShowModeToSettings();
411 this._updateShowHideSidebarButton();
412 this.dispatchEventToListeners(WebInspector.SplitWidget.Events.ShowModeChange d, showMode);
413 this.invalidateConstraints();
414 }
415
416 /**
417 * @param {number} sizeDIP
418 * @param {boolean} animate
419 * @param {boolean=} userAction
420 */
421 _innerSetSidebarSizeDIP(sizeDIP, animate, userAction) {
422 if (this._showMode !== WebInspector.SplitWidget.ShowMode.Both || !this.isSho wing())
423 return;
424
425 sizeDIP = this._applyConstraints(sizeDIP, userAction);
426 if (this._sidebarSizeDIP === sizeDIP)
427 return;
428
429 if (!this._resizerElementSize)
430 this._resizerElementSize =
431 this._isVertical ? this._resizerElement.offsetWidth : this._resizerEle ment.offsetHeight;
432
433 // Invalidate layout below.
434
435 this._removeAllLayoutProperties();
436
437 // this._totalSizeDIP is available below since we successfully applied const raints.
438 var roundSizeCSS = Math.round(WebInspector.zoomManager.dipToCSS(sizeDIP));
439 var sidebarSizeValue = roundSizeCSS + 'px';
440 var mainSizeValue = (this._totalSizeCSS - roundSizeCSS) + 'px';
441 this._sidebarElement.style.flexBasis = sidebarSizeValue;
442
443 // Make both sides relayout boundaries.
444 if (this._isVertical) {
445 this._sidebarElement.style.width = sidebarSizeValue;
446 this._mainElement.style.width = mainSizeValue;
447 this._sidebarElement.style.height = this._totalSizeOtherDimensionCSS + 'px ';
448 this._mainElement.style.height = this._totalSizeOtherDimensionCSS + 'px';
449 } else {
450 this._sidebarElement.style.height = sidebarSizeValue;
451 this._mainElement.style.height = mainSizeValue;
452 this._sidebarElement.style.width = this._totalSizeOtherDimensionCSS + 'px' ;
453 this._mainElement.style.width = this._totalSizeOtherDimensionCSS + 'px';
454 }
455
456 // Position resizer.
457 if (this._isVertical) {
458 if (this._secondIsSidebar) {
459 this._resizerElement.style.right = sidebarSizeValue;
460 this._resizerElement.style.marginRight = -this._resizerElementSize / 2 + 'px';
461 } else {
462 this._resizerElement.style.left = sidebarSizeValue;
463 this._resizerElement.style.marginLeft = -this._resizerElementSize / 2 + 'px';
464 }
465 } else {
466 if (this._secondIsSidebar) {
467 this._resizerElement.style.bottom = sidebarSizeValue;
468 this._resizerElement.style.marginBottom = -this._resizerElementSize / 2 + 'px';
469 } else {
470 this._resizerElement.style.top = sidebarSizeValue;
471 this._resizerElement.style.marginTop = -this._resizerElementSize / 2 + ' px';
472 }
473 }
474
475 this._sidebarSizeDIP = sizeDIP;
476
477 // Force layout.
478
479 if (animate) {
480 this._animate(false);
481 } else {
482 // No need to recalculate this._sidebarSizeDIP and this._totalSizeDIP agai n.
483 this.doResize();
484 this.dispatchEventToListeners(WebInspector.SplitWidget.Events.SidebarSizeC hanged, this.sidebarSize());
485 }
486 }
487
488 /**
489 * @param {boolean} reverse
490 * @param {function()=} callback
491 */
492 _animate(reverse, callback) {
493 var animationTime = 50;
494 this._animationCallback = callback;
495
496 var animatedMarginPropertyName;
497 if (this._isVertical)
498 animatedMarginPropertyName = this._secondIsSidebar ? 'margin-right' : 'mar gin-left';
499 else
500 animatedMarginPropertyName = this._secondIsSidebar ? 'margin-bottom' : 'ma rgin-top';
501
502 var marginFrom = reverse ? '0' : '-' + WebInspector.zoomManager.dipToCSS(thi s._sidebarSizeDIP) + 'px';
503 var marginTo = reverse ? '-' + WebInspector.zoomManager.dipToCSS(this._sideb arSizeDIP) + 'px' : '0';
504
505 // This order of things is important.
506 // 1. Resize main element early and force layout.
507 this.contentElement.style.setProperty(animatedMarginPropertyName, marginFrom );
508 if (!reverse) {
509 suppressUnused(this._mainElement.offsetWidth);
510 suppressUnused(this._sidebarElement.offsetWidth);
511 }
512
513 // 2. Issue onresize to the sidebar element, its size won't change.
514 if (!reverse)
515 this._sidebarWidget.doResize();
516
517 // 3. Configure and run animation
518 this.contentElement.style.setProperty('transition', animatedMarginPropertyNa me + ' ' + animationTime + 'ms linear');
519
520 var boundAnimationFrame;
521 var startTime;
522 /**
523 * @this {WebInspector.SplitWidget}
524 */
525 function animationFrame() {
526 delete this._animationFrameHandle;
527
528 if (!startTime) {
529 // Kick animation on first frame.
530 this.contentElement.style.setProperty(animatedMarginPropertyName, margin To);
531 startTime = window.performance.now();
532 } else if (window.performance.now() < startTime + animationTime) {
533 // Process regular animation frame.
534 if (this._mainWidget)
535 this._mainWidget.doResize();
536 } else {
537 // Complete animation.
538 this._cancelAnimation();
539 if (this._mainWidget)
540 this._mainWidget.doResize();
541 this.dispatchEventToListeners(WebInspector.SplitWidget.Events.SidebarSiz eChanged, this.sidebarSize());
542 return;
543 }
544 this._animationFrameHandle = this.contentElement.window().requestAnimation Frame(boundAnimationFrame);
545 }
546 boundAnimationFrame = animationFrame.bind(this);
547 this._animationFrameHandle = this.contentElement.window().requestAnimationFr ame(boundAnimationFrame);
548 }
549
550 _cancelAnimation() {
551 this.contentElement.style.removeProperty('margin-top');
552 this.contentElement.style.removeProperty('margin-right');
553 this.contentElement.style.removeProperty('margin-bottom');
554 this.contentElement.style.removeProperty('margin-left');
555 this.contentElement.style.removeProperty('transition');
556
557 if (this._animationFrameHandle) {
558 this.contentElement.window().cancelAnimationFrame(this._animationFrameHand le);
559 delete this._animationFrameHandle;
560 }
561 if (this._animationCallback) {
562 this._animationCallback();
563 delete this._animationCallback;
564 }
565 }
566
567 /**
568 * @param {number} sidebarSize
569 * @param {boolean=} userAction
570 * @return {number}
571 */
572 _applyConstraints(sidebarSize, userAction) {
573 var totalSize = this._totalSizeDIP();
574 var zoomFactor = this._constraintsInDip ? 1 : WebInspector.zoomManager.zoomF actor();
575
576 var constraints = this._sidebarWidget ? this._sidebarWidget.constraints() : new Constraints();
577 var minSidebarSize = this.isVertical() ? constraints.minimum.width : constra ints.minimum.height;
578 if (!minSidebarSize)
579 minSidebarSize = WebInspector.SplitWidget.MinPadding;
580 minSidebarSize *= zoomFactor;
581 if (this._sidebarMinimized)
582 sidebarSize = minSidebarSize;
583
584 var preferredSidebarSize = this.isVertical() ? constraints.preferred.width : constraints.preferred.height;
585 if (!preferredSidebarSize)
586 preferredSidebarSize = WebInspector.SplitWidget.MinPadding;
587 preferredSidebarSize *= zoomFactor;
588 // Allow sidebar to be less than preferred by explicit user action.
589 if (sidebarSize < preferredSidebarSize)
590 preferredSidebarSize = Math.max(sidebarSize, minSidebarSize);
591 preferredSidebarSize += zoomFactor; // 1 css pixel for splitter border.
592
593 constraints = this._mainWidget ? this._mainWidget.constraints() : new Constr aints();
594 var minMainSize = this.isVertical() ? constraints.minimum.width : constraint s.minimum.height;
595 if (!minMainSize)
596 minMainSize = WebInspector.SplitWidget.MinPadding;
597 minMainSize *= zoomFactor;
598
599 var preferredMainSize = this.isVertical() ? constraints.preferred.width : co nstraints.preferred.height;
600 if (!preferredMainSize)
601 preferredMainSize = WebInspector.SplitWidget.MinPadding;
602 preferredMainSize *= zoomFactor;
603 var savedMainSize = this.isVertical() ? this._savedVerticalMainSize : this._ savedHorizontalMainSize;
604 if (typeof savedMainSize !== 'undefined')
605 preferredMainSize = Math.min(preferredMainSize, savedMainSize * zoomFactor );
606 if (userAction)
607 preferredMainSize = minMainSize;
608
609 // Enough space for preferred.
610 var totalPreferred = preferredMainSize + preferredSidebarSize;
611 if (totalPreferred <= totalSize)
612 return Number.constrain(sidebarSize, preferredSidebarSize, totalSize - pre ferredMainSize);
613
614 // Enough space for minimum.
615 if (minMainSize + minSidebarSize <= totalSize) {
616 var delta = totalPreferred - totalSize;
617 var sidebarDelta = delta * preferredSidebarSize / totalPreferred;
618 sidebarSize = preferredSidebarSize - sidebarDelta;
619 return Number.constrain(sidebarSize, minSidebarSize, totalSize - minMainSi ze);
620 }
621
622 // Not enough space even for minimum sizes.
623 return Math.max(0, totalSize - minMainSize);
624 }
625
626 /**
627 * @override
628 */
629 wasShown() {
630 this._forceUpdateLayout();
631 WebInspector.zoomManager.addEventListener(WebInspector.ZoomManager.Events.Zo omChanged, this._onZoomChanged, this);
632 }
633
634 /**
635 * @override
636 */
637 willHide() {
638 WebInspector.zoomManager.removeEventListener(
639 WebInspector.ZoomManager.Events.ZoomChanged, this._onZoomChanged, this);
640 }
641
642 /**
643 * @override
644 */
645 onResize() {
646 this._updateLayout();
647 }
648
649 /**
650 * @override
651 */
652 onLayout() {
653 this._updateLayout();
654 }
655
656 /**
657 * @override
658 * @return {!Constraints}
659 */
660 calculateConstraints() {
661 if (this._showMode === WebInspector.SplitWidget.ShowMode.OnlyMain)
662 return this._mainWidget ? this._mainWidget.constraints() : new Constraints ();
663 if (this._showMode === WebInspector.SplitWidget.ShowMode.OnlySidebar)
664 return this._sidebarWidget ? this._sidebarWidget.constraints() : new Const raints();
665
666 var mainConstraints = this._mainWidget ? this._mainWidget.constraints() : ne w Constraints();
667 var sidebarConstraints = this._sidebarWidget ? this._sidebarWidget.constrain ts() : new Constraints();
668 var min = WebInspector.SplitWidget.MinPadding;
669 if (this._isVertical) {
670 mainConstraints = mainConstraints.widthToMax(min).addWidth(1); // 1 for s plitter
671 sidebarConstraints = sidebarConstraints.widthToMax(min);
672 return mainConstraints.addWidth(sidebarConstraints).heightToMax(sidebarCon straints);
673 } else {
674 mainConstraints = mainConstraints.heightToMax(min).addHeight(1); // 1 for splitter
675 sidebarConstraints = sidebarConstraints.heightToMax(min);
676 return mainConstraints.widthToMax(sidebarConstraints).addHeight(sidebarCon straints);
677 }
678 }
679
680 /**
681 * @param {!WebInspector.Event} event
682 */
683 _onResizeStart(event) {
684 this._resizeStartSizeDIP = this._sidebarSizeDIP;
685 }
686
687 /**
688 * @param {!WebInspector.Event} event
689 */
690 _onResizeUpdate(event) {
691 var offset = event.data.currentPosition - event.data.startPosition;
692 var offsetDIP = WebInspector.zoomManager.cssToDIP(offset);
693 var newSizeDIP =
694 this._secondIsSidebar ? this._resizeStartSizeDIP - offsetDIP : this._res izeStartSizeDIP + offsetDIP;
695 var constrainedSizeDIP = this._applyConstraints(newSizeDIP, true);
696 this._savedSidebarSizeDIP = constrainedSizeDIP;
697 this._saveSetting();
698 this._innerSetSidebarSizeDIP(constrainedSizeDIP, false, true);
699 if (this.isVertical())
700 this._savedVerticalMainSize = this._totalSizeDIP() - this._sidebarSizeDIP;
701 else
702 this._savedHorizontalMainSize = this._totalSizeDIP() - this._sidebarSizeDI P;
703 }
704
705 /**
706 * @param {!WebInspector.Event} event
707 */
708 _onResizeEnd(event) {
709 delete this._resizeStartSizeDIP;
710 }
711
712 hideDefaultResizer() {
713 this.uninstallResizer(this._resizerElement);
714 }
715
716 /**
717 * @param {!Element} resizerElement
718 */
719 installResizer(resizerElement) {
720 this._resizerWidget.addElement(resizerElement);
721 }
722
723 /**
724 * @param {!Element} resizerElement
725 */
726 uninstallResizer(resizerElement) {
727 this._resizerWidget.removeElement(resizerElement);
728 }
729
730 /**
731 * @return {boolean}
732 */
733 hasCustomResizer() {
734 var elements = this._resizerWidget.elements();
735 return elements.length > 1 || (elements.length === 1 && elements[0] !== this ._resizerElement);
736 }
737
738 /**
739 * @param {!Element} resizer
740 * @param {boolean} on
741 */
742 toggleResizer(resizer, on) {
743 if (on)
744 this.installResizer(resizer);
745 else
746 this.uninstallResizer(resizer);
747 }
748
749 /**
750 * @return {?WebInspector.SplitWidget.SettingForOrientation}
751 */
752 _settingForOrientation() {
753 var state = this._setting ? this._setting.get() : {};
754 return this._isVertical ? state.vertical : state.horizontal;
755 }
756
757 /**
758 * @return {number}
759 */
760 _preferredSidebarSizeDIP() {
761 var size = this._savedSidebarSizeDIP;
762 if (!size) {
763 size = this._isVertical ? this._defaultSidebarWidth : this._defaultSidebar Height;
764 // If we have default value in percents, calculate it on first use.
765 if (0 < size && size < 1)
766 size *= this._totalSizeDIP();
767 }
768 return size;
769 }
770
771 _restoreSidebarSizeFromSettings() {
772 var settingForOrientation = this._settingForOrientation();
773 this._savedSidebarSizeDIP = settingForOrientation ? settingForOrientation.si ze : 0;
774 }
775
776 _restoreAndApplyShowModeFromSettings() {
777 var orientationState = this._settingForOrientation();
778 this._savedShowMode = orientationState && orientationState.showMode ? orient ationState.showMode : this._showMode;
779 this._showMode = this._savedShowMode;
780
781 switch (this._savedShowMode) {
782 case WebInspector.SplitWidget.ShowMode.Both:
783 this.showBoth();
784 break;
785 case WebInspector.SplitWidget.ShowMode.OnlyMain:
786 this.hideSidebar();
787 break;
788 case WebInspector.SplitWidget.ShowMode.OnlySidebar:
789 this.hideMain();
790 break;
791 }
792 }
793
794 _saveShowModeToSettings() {
795 this._savedShowMode = this._showMode;
796 this._saveSetting();
797 }
798
799 _saveSetting() {
800 if (!this._setting)
801 return;
802 var state = this._setting.get();
803 var orientationState = (this._isVertical ? state.vertical : state.horizontal ) || {};
804
805 orientationState.size = this._savedSidebarSizeDIP;
806 if (this._shouldSaveShowMode)
807 orientationState.showMode = this._savedShowMode;
808
809 if (this._isVertical)
810 state.vertical = orientationState;
811 else
812 state.horizontal = orientationState;
813 this._setting.set(state);
814 }
815
816 _forceUpdateLayout() {
817 // Force layout even if sidebar size does not change.
818 this._sidebarSizeDIP = -1;
819 this._updateLayout();
820 }
821
822 /**
823 * @param {!WebInspector.Event} event
824 */
825 _onZoomChanged(event) {
826 this._forceUpdateLayout();
827 }
828
829 /**
830 * @param {string} title
831 * @return {!WebInspector.ToolbarButton}
832 */
833 createShowHideSidebarButton(title) {
834 this._showHideSidebarButtonTitle = WebInspector.UIString(title);
835 this._showHideSidebarButton = new WebInspector.ToolbarButton('', 'sidebar-to olbar-item');
836 this._showHideSidebarButton.addEventListener('click', buttonClicked.bind(thi s));
837 this._updateShowHideSidebarButton();
838
839 /**
840 * @param {!WebInspector.Event} event
841 * @this {WebInspector.SplitWidget}
842 */
843 function buttonClicked(event) {
844 if (this._showMode !== WebInspector.SplitWidget.ShowMode.Both)
845 this.showBoth(true);
846 else
847 this.hideSidebar(true);
848 }
849
850 return this._showHideSidebarButton;
851 }
852
853 _updateShowHideSidebarButton() {
854 if (!this._showHideSidebarButton)
855 return;
856 var sidebarHidden = this._showMode === WebInspector.SplitWidget.ShowMode.Onl yMain;
857 var side =
858 this.isVertical() ? (this.isSidebarSecond() ? 'right' : 'left') : (this. isSidebarSecond() ? 'bottom' : 'top');
859 this._showHideSidebarButton.setState(side + '-' + (sidebarHidden ? 'show' : 'hide'));
860 this._showHideSidebarButton.setTitle(
861 sidebarHidden ? WebInspector.UIString('Show %s', this._showHideSidebarBu ttonTitle) :
862 WebInspector.UIString('Hide %s', this._showHideSidebarBu ttonTitle));
863 }
70 }; 864 };
71 865
72 /** @typedef {{showMode: string, size: number}} */ 866 /** @typedef {{showMode: string, size: number}} */
73 WebInspector.SplitWidget.SettingForOrientation; 867 WebInspector.SplitWidget.SettingForOrientation;
74 868
75 WebInspector.SplitWidget.ShowMode = { 869 WebInspector.SplitWidget.ShowMode = {
76 Both: "Both", 870 Both: 'Both',
77 OnlyMain: "OnlyMain", 871 OnlyMain: 'OnlyMain',
78 OnlySidebar: "OnlySidebar" 872 OnlySidebar: 'OnlySidebar'
79 }; 873 };
80 874
81 /** @enum {symbol} */ 875 /** @enum {symbol} */
82 WebInspector.SplitWidget.Events = { 876 WebInspector.SplitWidget.Events = {
83 SidebarSizeChanged: Symbol("SidebarSizeChanged"), 877 SidebarSizeChanged: Symbol('SidebarSizeChanged'),
84 ShowModeChanged: Symbol("ShowModeChanged") 878 ShowModeChanged: Symbol('ShowModeChanged')
85 }; 879 };
86 880
87 WebInspector.SplitWidget.MinPadding = 20; 881 WebInspector.SplitWidget.MinPadding = 20;
88
89 WebInspector.SplitWidget.prototype = {
90 /**
91 * @return {boolean}
92 */
93 isVertical: function()
94 {
95 return this._isVertical;
96 },
97
98 /**
99 * @param {boolean} isVertical
100 */
101 setVertical: function(isVertical)
102 {
103 if (this._isVertical === isVertical)
104 return;
105
106 this._innerSetVertical(isVertical);
107
108 if (this.isShowing())
109 this._updateLayout();
110 },
111
112 /**
113 * @param {boolean} isVertical
114 */
115 _innerSetVertical: function(isVertical)
116 {
117 this.contentElement.classList.toggle("vbox", !isVertical);
118 this.contentElement.classList.toggle("hbox", isVertical);
119 this._isVertical = isVertical;
120
121 delete this._resizerElementSize;
122 this._sidebarSizeDIP = -1;
123 this._restoreSidebarSizeFromSettings();
124 if (this._shouldSaveShowMode)
125 this._restoreAndApplyShowModeFromSettings();
126 this._updateShowHideSidebarButton();
127 // FIXME: reverse SplitWidget.isVertical meaning.
128 this._resizerWidget.setVertical(!isVertical);
129 this.invalidateConstraints();
130 },
131
132 /**
133 * @param {boolean=} animate
134 */
135 _updateLayout: function(animate)
136 {
137 delete this._totalSizeCSS; // Lazy update.
138 delete this._totalSizeOtherDimensionCSS;
139
140 // Remove properties that might affect total size calculation.
141 this._mainElement.style.removeProperty("width");
142 this._mainElement.style.removeProperty("height");
143 this._sidebarElement.style.removeProperty("width");
144 this._sidebarElement.style.removeProperty("height");
145
146 this._innerSetSidebarSizeDIP(this._preferredSidebarSizeDIP(), !!animate) ;
147 },
148
149 /**
150 * @param {!WebInspector.Widget} widget
151 */
152 setMainWidget: function(widget)
153 {
154 if (this._mainWidget === widget)
155 return;
156 this.suspendInvalidations();
157 if (this._mainWidget)
158 this._mainWidget.detach();
159 this._mainWidget = widget;
160 if (widget) {
161 widget.element.classList.add("insertion-point-main");
162 widget.element.classList.remove("insertion-point-sidebar");
163 widget.attach(this);
164 if (this._showMode === WebInspector.SplitWidget.ShowMode.OnlyMain || this._showMode === WebInspector.SplitWidget.ShowMode.Both)
165 widget.showWidget(this.element);
166 this.setDefaultFocusedChild(widget);
167 }
168 this.resumeInvalidations();
169 },
170
171 /**
172 * @param {!WebInspector.Widget} widget
173 */
174 setSidebarWidget: function(widget)
175 {
176 if (this._sidebarWidget === widget)
177 return;
178 this.suspendInvalidations();
179 if (this._sidebarWidget)
180 this._sidebarWidget.detach();
181 this._sidebarWidget = widget;
182 if (widget) {
183 widget.element.classList.add("insertion-point-sidebar");
184 widget.element.classList.remove("insertion-point-main");
185 widget.attach(this);
186 if (this._showMode === WebInspector.SplitWidget.ShowMode.OnlySidebar || this._showMode === WebInspector.SplitWidget.ShowMode.Both)
187 widget.showWidget(this.element);
188 }
189 this.resumeInvalidations();
190 },
191
192 /**
193 * @return {?WebInspector.Widget}
194 */
195 mainWidget: function()
196 {
197 return this._mainWidget;
198 },
199
200 /**
201 * @return {?WebInspector.Widget}
202 */
203 sidebarWidget: function()
204 {
205 return this._sidebarWidget;
206 },
207
208 /**
209 * @override
210 * @param {!WebInspector.Widget} widget
211 */
212 childWasDetached: function(widget)
213 {
214 if (this._mainWidget === widget)
215 delete this._mainWidget;
216 if (this._sidebarWidget === widget)
217 delete this._sidebarWidget;
218 },
219
220 /**
221 * @return {boolean}
222 */
223 isSidebarSecond: function()
224 {
225 return this._secondIsSidebar;
226 },
227
228 enableShowModeSaving: function()
229 {
230 this._shouldSaveShowMode = true;
231 this._restoreAndApplyShowModeFromSettings();
232 },
233
234 /**
235 * @return {string}
236 */
237 showMode: function()
238 {
239 return this._showMode;
240 },
241
242 /**
243 * @param {boolean} secondIsSidebar
244 */
245 setSecondIsSidebar: function(secondIsSidebar)
246 {
247 this.contentElement.classList.toggle("shadow-split-widget-first-is-sideb ar", !secondIsSidebar);
248 this._secondIsSidebar = secondIsSidebar;
249 },
250
251 /**
252 * @return {?string}
253 */
254 sidebarSide: function()
255 {
256 if (this._showMode !== WebInspector.SplitWidget.ShowMode.Both)
257 return null;
258 return this._isVertical ?
259 (this._secondIsSidebar ? "right" : "left") :
260 (this._secondIsSidebar ? "bottom" : "top");
261 },
262
263 /**
264 * @return {!Element}
265 */
266 resizerElement: function()
267 {
268 return this._resizerElement;
269 },
270
271 /**
272 * @param {boolean=} animate
273 */
274 hideMain: function(animate)
275 {
276 this._showOnly(this._sidebarWidget, this._mainWidget, this._sidebarEleme nt, this._mainElement, animate);
277 this._updateShowMode(WebInspector.SplitWidget.ShowMode.OnlySidebar);
278 },
279
280 /**
281 * @param {boolean=} animate
282 */
283 hideSidebar: function(animate)
284 {
285 this._showOnly(this._mainWidget, this._sidebarWidget, this._mainElement, this._sidebarElement, animate);
286 this._updateShowMode(WebInspector.SplitWidget.ShowMode.OnlyMain);
287 },
288
289 /**
290 * @param {boolean} minimized
291 */
292 setSidebarMinimized: function(minimized)
293 {
294 this._sidebarMinimized = minimized;
295 this.invalidateConstraints();
296 },
297
298 /**
299 * @return {boolean}
300 */
301 isSidebarMinimized: function()
302 {
303 return this._sidebarMinimized;
304 },
305
306 /**
307 * @param {!WebInspector.Widget} sideToShow
308 * @param {!WebInspector.Widget} sideToHide
309 * @param {!Element} shadowToShow
310 * @param {!Element} shadowToHide
311 * @param {boolean=} animate
312 */
313 _showOnly: function(sideToShow, sideToHide, shadowToShow, shadowToHide, anim ate)
314 {
315 this._cancelAnimation();
316
317 /**
318 * @this {WebInspector.SplitWidget}
319 */
320 function callback()
321 {
322 if (sideToShow) {
323 // Make sure main is first in the children list.
324 if (sideToShow === this._mainWidget)
325 this._mainWidget.showWidget(this.element);
326 else
327 this._sidebarWidget.showWidget(this.element);
328 }
329 if (sideToHide)
330 sideToHide.hideWidget();
331
332 this._resizerElement.classList.add("hidden");
333 shadowToShow.classList.remove("hidden");
334 shadowToShow.classList.add("maximized");
335 shadowToHide.classList.add("hidden");
336 shadowToHide.classList.remove("maximized");
337 this._removeAllLayoutProperties();
338 this.doResize();
339 }
340
341 if (animate)
342 this._animate(true, callback.bind(this));
343 else
344 callback.call(this);
345
346 this._sidebarSizeDIP = -1;
347 this.setResizable(false);
348 },
349
350 _removeAllLayoutProperties: function()
351 {
352 this._sidebarElement.style.removeProperty("flexBasis");
353
354 this._mainElement.style.removeProperty("width");
355 this._mainElement.style.removeProperty("height");
356 this._sidebarElement.style.removeProperty("width");
357 this._sidebarElement.style.removeProperty("height");
358
359 this._resizerElement.style.removeProperty("left");
360 this._resizerElement.style.removeProperty("right");
361 this._resizerElement.style.removeProperty("top");
362 this._resizerElement.style.removeProperty("bottom");
363
364 this._resizerElement.style.removeProperty("margin-left");
365 this._resizerElement.style.removeProperty("margin-right");
366 this._resizerElement.style.removeProperty("margin-top");
367 this._resizerElement.style.removeProperty("margin-bottom");
368 },
369
370 /**
371 * @param {boolean=} animate
372 */
373 showBoth: function(animate)
374 {
375 if (this._showMode === WebInspector.SplitWidget.ShowMode.Both)
376 animate = false;
377
378 this._cancelAnimation();
379 this._mainElement.classList.remove("maximized", "hidden");
380 this._sidebarElement.classList.remove("maximized", "hidden");
381 this._resizerElement.classList.remove("hidden");
382 this.setResizable(true);
383
384 // Make sure main is the first in the children list.
385 this.suspendInvalidations();
386 if (this._sidebarWidget)
387 this._sidebarWidget.showWidget(this.element);
388 if (this._mainWidget)
389 this._mainWidget.showWidget(this.element);
390 this.resumeInvalidations();
391 // Order widgets in DOM properly.
392 this.setSecondIsSidebar(this._secondIsSidebar);
393
394 this._sidebarSizeDIP = -1;
395 this._updateShowMode(WebInspector.SplitWidget.ShowMode.Both);
396 this._updateLayout(animate);
397 },
398
399 /**
400 * @param {boolean} resizable
401 */
402 setResizable: function(resizable)
403 {
404 this._resizerWidget.setEnabled(resizable);
405 },
406
407 /**
408 * @return {boolean}
409 */
410 isResizable: function()
411 {
412 return this._resizerWidget.isEnabled();
413 },
414
415 /**
416 * @param {number} size
417 */
418 setSidebarSize: function(size)
419 {
420 var sizeDIP = WebInspector.zoomManager.cssToDIP(size);
421 this._savedSidebarSizeDIP = sizeDIP;
422 this._saveSetting();
423 this._innerSetSidebarSizeDIP(sizeDIP, false, true);
424 },
425
426 /**
427 * @return {number}
428 */
429 sidebarSize: function()
430 {
431 var sizeDIP = Math.max(0, this._sidebarSizeDIP);
432 return WebInspector.zoomManager.dipToCSS(sizeDIP);
433 },
434
435 /**
436 * Returns total size in DIP.
437 * @return {number}
438 */
439 _totalSizeDIP: function()
440 {
441 if (!this._totalSizeCSS) {
442 this._totalSizeCSS = this._isVertical ? this.contentElement.offsetWi dth : this.contentElement.offsetHeight;
443 this._totalSizeOtherDimensionCSS = this._isVertical ? this.contentEl ement.offsetHeight : this.contentElement.offsetWidth;
444 }
445 return WebInspector.zoomManager.cssToDIP(this._totalSizeCSS);
446 },
447
448 /**
449 * @param {string} showMode
450 */
451 _updateShowMode: function(showMode)
452 {
453 this._showMode = showMode;
454 this._saveShowModeToSettings();
455 this._updateShowHideSidebarButton();
456 this.dispatchEventToListeners(WebInspector.SplitWidget.Events.ShowModeCh anged, showMode);
457 this.invalidateConstraints();
458 },
459
460 /**
461 * @param {number} sizeDIP
462 * @param {boolean} animate
463 * @param {boolean=} userAction
464 */
465 _innerSetSidebarSizeDIP: function(sizeDIP, animate, userAction)
466 {
467 if (this._showMode !== WebInspector.SplitWidget.ShowMode.Both || !this.i sShowing())
468 return;
469
470 sizeDIP = this._applyConstraints(sizeDIP, userAction);
471 if (this._sidebarSizeDIP === sizeDIP)
472 return;
473
474 if (!this._resizerElementSize)
475 this._resizerElementSize = this._isVertical ? this._resizerElement.o ffsetWidth : this._resizerElement.offsetHeight;
476
477 // Invalidate layout below.
478
479 this._removeAllLayoutProperties();
480
481 // this._totalSizeDIP is available below since we successfully applied c onstraints.
482 var roundSizeCSS = Math.round(WebInspector.zoomManager.dipToCSS(sizeDIP) );
483 var sidebarSizeValue = roundSizeCSS + "px";
484 var mainSizeValue = (this._totalSizeCSS - roundSizeCSS) + "px";
485 this._sidebarElement.style.flexBasis = sidebarSizeValue;
486
487 // Make both sides relayout boundaries.
488 if (this._isVertical) {
489 this._sidebarElement.style.width = sidebarSizeValue;
490 this._mainElement.style.width = mainSizeValue;
491 this._sidebarElement.style.height = this._totalSizeOtherDimensionCSS + "px";
492 this._mainElement.style.height = this._totalSizeOtherDimensionCSS + "px";
493 } else {
494 this._sidebarElement.style.height = sidebarSizeValue;
495 this._mainElement.style.height = mainSizeValue;
496 this._sidebarElement.style.width = this._totalSizeOtherDimensionCSS + "px";
497 this._mainElement.style.width = this._totalSizeOtherDimensionCSS + " px";
498 }
499
500 // Position resizer.
501 if (this._isVertical) {
502 if (this._secondIsSidebar) {
503 this._resizerElement.style.right = sidebarSizeValue;
504 this._resizerElement.style.marginRight = -this._resizerElementSi ze / 2 + "px";
505 } else {
506 this._resizerElement.style.left = sidebarSizeValue;
507 this._resizerElement.style.marginLeft = -this._resizerElementSiz e / 2 + "px";
508 }
509 } else {
510 if (this._secondIsSidebar) {
511 this._resizerElement.style.bottom = sidebarSizeValue;
512 this._resizerElement.style.marginBottom = -this._resizerElementS ize / 2 + "px";
513 } else {
514 this._resizerElement.style.top = sidebarSizeValue;
515 this._resizerElement.style.marginTop = -this._resizerElementSize / 2 + "px";
516 }
517 }
518
519 this._sidebarSizeDIP = sizeDIP;
520
521 // Force layout.
522
523 if (animate) {
524 this._animate(false);
525 } else {
526 // No need to recalculate this._sidebarSizeDIP and this._totalSizeDI P again.
527 this.doResize();
528 this.dispatchEventToListeners(WebInspector.SplitWidget.Events.Sideba rSizeChanged, this.sidebarSize());
529 }
530 },
531
532 /**
533 * @param {boolean} reverse
534 * @param {function()=} callback
535 */
536 _animate: function(reverse, callback)
537 {
538 var animationTime = 50;
539 this._animationCallback = callback;
540
541 var animatedMarginPropertyName;
542 if (this._isVertical)
543 animatedMarginPropertyName = this._secondIsSidebar ? "margin-right" : "margin-left";
544 else
545 animatedMarginPropertyName = this._secondIsSidebar ? "margin-bottom" : "margin-top";
546
547 var marginFrom = reverse ? "0" : "-" + WebInspector.zoomManager.dipToCSS (this._sidebarSizeDIP) + "px";
548 var marginTo = reverse ? "-" + WebInspector.zoomManager.dipToCSS(this._s idebarSizeDIP) + "px" : "0";
549
550 // This order of things is important.
551 // 1. Resize main element early and force layout.
552 this.contentElement.style.setProperty(animatedMarginPropertyName, margin From);
553 if (!reverse) {
554 suppressUnused(this._mainElement.offsetWidth);
555 suppressUnused(this._sidebarElement.offsetWidth);
556 }
557
558 // 2. Issue onresize to the sidebar element, its size won't change.
559 if (!reverse)
560 this._sidebarWidget.doResize();
561
562 // 3. Configure and run animation
563 this.contentElement.style.setProperty("transition", animatedMarginProper tyName + " " + animationTime + "ms linear");
564
565 var boundAnimationFrame;
566 var startTime;
567 /**
568 * @this {WebInspector.SplitWidget}
569 */
570 function animationFrame()
571 {
572 delete this._animationFrameHandle;
573
574 if (!startTime) {
575 // Kick animation on first frame.
576 this.contentElement.style.setProperty(animatedMarginPropertyName , marginTo);
577 startTime = window.performance.now();
578 } else if (window.performance.now() < startTime + animationTime) {
579 // Process regular animation frame.
580 if (this._mainWidget)
581 this._mainWidget.doResize();
582 } else {
583 // Complete animation.
584 this._cancelAnimation();
585 if (this._mainWidget)
586 this._mainWidget.doResize();
587 this.dispatchEventToListeners(WebInspector.SplitWidget.Events.Si debarSizeChanged, this.sidebarSize());
588 return;
589 }
590 this._animationFrameHandle = this.contentElement.window().requestAni mationFrame(boundAnimationFrame);
591 }
592 boundAnimationFrame = animationFrame.bind(this);
593 this._animationFrameHandle = this.contentElement.window().requestAnimati onFrame(boundAnimationFrame);
594 },
595
596 _cancelAnimation: function()
597 {
598 this.contentElement.style.removeProperty("margin-top");
599 this.contentElement.style.removeProperty("margin-right");
600 this.contentElement.style.removeProperty("margin-bottom");
601 this.contentElement.style.removeProperty("margin-left");
602 this.contentElement.style.removeProperty("transition");
603
604 if (this._animationFrameHandle) {
605 this.contentElement.window().cancelAnimationFrame(this._animationFra meHandle);
606 delete this._animationFrameHandle;
607 }
608 if (this._animationCallback) {
609 this._animationCallback();
610 delete this._animationCallback;
611 }
612 },
613
614 /**
615 * @param {number} sidebarSize
616 * @param {boolean=} userAction
617 * @return {number}
618 */
619 _applyConstraints: function(sidebarSize, userAction)
620 {
621 var totalSize = this._totalSizeDIP();
622 var zoomFactor = this._constraintsInDip ? 1 : WebInspector.zoomManager.z oomFactor();
623
624 var constraints = this._sidebarWidget ? this._sidebarWidget.constraints( ) : new Constraints();
625 var minSidebarSize = this.isVertical() ? constraints.minimum.width : con straints.minimum.height;
626 if (!minSidebarSize)
627 minSidebarSize = WebInspector.SplitWidget.MinPadding;
628 minSidebarSize *= zoomFactor;
629 if (this._sidebarMinimized)
630 sidebarSize = minSidebarSize;
631
632 var preferredSidebarSize = this.isVertical() ? constraints.preferred.wid th : constraints.preferred.height;
633 if (!preferredSidebarSize)
634 preferredSidebarSize = WebInspector.SplitWidget.MinPadding;
635 preferredSidebarSize *= zoomFactor;
636 // Allow sidebar to be less than preferred by explicit user action.
637 if (sidebarSize < preferredSidebarSize)
638 preferredSidebarSize = Math.max(sidebarSize, minSidebarSize);
639 preferredSidebarSize += zoomFactor; // 1 css pixel for splitter border.
640
641 constraints = this._mainWidget ? this._mainWidget.constraints() : new Co nstraints();
642 var minMainSize = this.isVertical() ? constraints.minimum.width : constr aints.minimum.height;
643 if (!minMainSize)
644 minMainSize = WebInspector.SplitWidget.MinPadding;
645 minMainSize *= zoomFactor;
646
647 var preferredMainSize = this.isVertical() ? constraints.preferred.width : constraints.preferred.height;
648 if (!preferredMainSize)
649 preferredMainSize = WebInspector.SplitWidget.MinPadding;
650 preferredMainSize *= zoomFactor;
651 var savedMainSize = this.isVertical() ? this._savedVerticalMainSize : th is._savedHorizontalMainSize;
652 if (typeof savedMainSize !== "undefined")
653 preferredMainSize = Math.min(preferredMainSize, savedMainSize * zoom Factor);
654 if (userAction)
655 preferredMainSize = minMainSize;
656
657 // Enough space for preferred.
658 var totalPreferred = preferredMainSize + preferredSidebarSize;
659 if (totalPreferred <= totalSize)
660 return Number.constrain(sidebarSize, preferredSidebarSize, totalSize - preferredMainSize);
661
662 // Enough space for minimum.
663 if (minMainSize + minSidebarSize <= totalSize) {
664 var delta = totalPreferred - totalSize;
665 var sidebarDelta = delta * preferredSidebarSize / totalPreferred;
666 sidebarSize = preferredSidebarSize - sidebarDelta;
667 return Number.constrain(sidebarSize, minSidebarSize, totalSize - min MainSize);
668 }
669
670 // Not enough space even for minimum sizes.
671 return Math.max(0, totalSize - minMainSize);
672 },
673
674 wasShown: function()
675 {
676 this._forceUpdateLayout();
677 WebInspector.zoomManager.addEventListener(WebInspector.ZoomManager.Event s.ZoomChanged, this._onZoomChanged, this);
678 },
679
680 willHide: function()
681 {
682 WebInspector.zoomManager.removeEventListener(WebInspector.ZoomManager.Ev ents.ZoomChanged, this._onZoomChanged, this);
683 },
684
685 onResize: function()
686 {
687 this._updateLayout();
688 },
689
690 onLayout: function()
691 {
692 this._updateLayout();
693 },
694
695 /**
696 * @override
697 * @return {!Constraints}
698 */
699 calculateConstraints: function()
700 {
701 if (this._showMode === WebInspector.SplitWidget.ShowMode.OnlyMain)
702 return this._mainWidget ? this._mainWidget.constraints() : new Const raints();
703 if (this._showMode === WebInspector.SplitWidget.ShowMode.OnlySidebar)
704 return this._sidebarWidget ? this._sidebarWidget.constraints() : new Constraints();
705
706 var mainConstraints = this._mainWidget ? this._mainWidget.constraints() : new Constraints();
707 var sidebarConstraints = this._sidebarWidget ? this._sidebarWidget.const raints() : new Constraints();
708 var min = WebInspector.SplitWidget.MinPadding;
709 if (this._isVertical) {
710 mainConstraints = mainConstraints.widthToMax(min).addWidth(1); // 1 for splitter
711 sidebarConstraints = sidebarConstraints.widthToMax(min);
712 return mainConstraints.addWidth(sidebarConstraints).heightToMax(side barConstraints);
713 } else {
714 mainConstraints = mainConstraints.heightToMax(min).addHeight(1); // 1 for splitter
715 sidebarConstraints = sidebarConstraints.heightToMax(min);
716 return mainConstraints.widthToMax(sidebarConstraints).addHeight(side barConstraints);
717 }
718 },
719
720 /**
721 * @param {!WebInspector.Event} event
722 */
723 _onResizeStart: function(event)
724 {
725 this._resizeStartSizeDIP = this._sidebarSizeDIP;
726 },
727
728 /**
729 * @param {!WebInspector.Event} event
730 */
731 _onResizeUpdate: function(event)
732 {
733 var offset = event.data.currentPosition - event.data.startPosition;
734 var offsetDIP = WebInspector.zoomManager.cssToDIP(offset);
735 var newSizeDIP = this._secondIsSidebar ? this._resizeStartSizeDIP - offs etDIP : this._resizeStartSizeDIP + offsetDIP;
736 var constrainedSizeDIP = this._applyConstraints(newSizeDIP, true);
737 this._savedSidebarSizeDIP = constrainedSizeDIP;
738 this._saveSetting();
739 this._innerSetSidebarSizeDIP(constrainedSizeDIP, false, true);
740 if (this.isVertical())
741 this._savedVerticalMainSize = this._totalSizeDIP() - this._sidebarSi zeDIP;
742 else
743 this._savedHorizontalMainSize = this._totalSizeDIP() - this._sidebar SizeDIP;
744 },
745
746 /**
747 * @param {!WebInspector.Event} event
748 */
749 _onResizeEnd: function(event)
750 {
751 delete this._resizeStartSizeDIP;
752 },
753
754 hideDefaultResizer: function()
755 {
756 this.uninstallResizer(this._resizerElement);
757 },
758
759 /**
760 * @param {!Element} resizerElement
761 */
762 installResizer: function(resizerElement)
763 {
764 this._resizerWidget.addElement(resizerElement);
765 },
766
767 /**
768 * @param {!Element} resizerElement
769 */
770 uninstallResizer: function(resizerElement)
771 {
772 this._resizerWidget.removeElement(resizerElement);
773 },
774
775 /**
776 * @return {boolean}
777 */
778 hasCustomResizer: function()
779 {
780 var elements = this._resizerWidget.elements();
781 return elements.length > 1 || (elements.length === 1 && elements[0] !== this._resizerElement);
782 },
783
784 /**
785 * @param {!Element} resizer
786 * @param {boolean} on
787 */
788 toggleResizer: function(resizer, on)
789 {
790 if (on)
791 this.installResizer(resizer);
792 else
793 this.uninstallResizer(resizer);
794 },
795
796 /**
797 * @return {?WebInspector.SplitWidget.SettingForOrientation}
798 */
799 _settingForOrientation: function()
800 {
801 var state = this._setting ? this._setting.get() : {};
802 return this._isVertical ? state.vertical : state.horizontal;
803 },
804
805 /**
806 * @return {number}
807 */
808 _preferredSidebarSizeDIP: function()
809 {
810 var size = this._savedSidebarSizeDIP;
811 if (!size) {
812 size = this._isVertical ? this._defaultSidebarWidth : this._defaultS idebarHeight;
813 // If we have default value in percents, calculate it on first use.
814 if (0 < size && size < 1)
815 size *= this._totalSizeDIP();
816 }
817 return size;
818 },
819
820 _restoreSidebarSizeFromSettings: function()
821 {
822 var settingForOrientation = this._settingForOrientation();
823 this._savedSidebarSizeDIP = settingForOrientation ? settingForOrientatio n.size : 0;
824 },
825
826 _restoreAndApplyShowModeFromSettings: function()
827 {
828 var orientationState = this._settingForOrientation();
829 this._savedShowMode = orientationState && orientationState.showMode ? or ientationState.showMode : this._showMode;
830 this._showMode = this._savedShowMode;
831
832 switch (this._savedShowMode) {
833 case WebInspector.SplitWidget.ShowMode.Both:
834 this.showBoth();
835 break;
836 case WebInspector.SplitWidget.ShowMode.OnlyMain:
837 this.hideSidebar();
838 break;
839 case WebInspector.SplitWidget.ShowMode.OnlySidebar:
840 this.hideMain();
841 break;
842 }
843 },
844
845 _saveShowModeToSettings: function()
846 {
847 this._savedShowMode = this._showMode;
848 this._saveSetting();
849 },
850
851 _saveSetting: function()
852 {
853 if (!this._setting)
854 return;
855 var state = this._setting.get();
856 var orientationState = (this._isVertical ? state.vertical : state.horizo ntal) || {};
857
858 orientationState.size = this._savedSidebarSizeDIP;
859 if (this._shouldSaveShowMode)
860 orientationState.showMode = this._savedShowMode;
861
862 if (this._isVertical)
863 state.vertical = orientationState;
864 else
865 state.horizontal = orientationState;
866 this._setting.set(state);
867 },
868
869 _forceUpdateLayout: function()
870 {
871 // Force layout even if sidebar size does not change.
872 this._sidebarSizeDIP = -1;
873 this._updateLayout();
874 },
875
876 /**
877 * @param {!WebInspector.Event} event
878 */
879 _onZoomChanged: function(event)
880 {
881 this._forceUpdateLayout();
882 },
883
884 /**
885 * @param {string} title
886 * @return {!WebInspector.ToolbarButton}
887 */
888 createShowHideSidebarButton: function(title)
889 {
890 this._showHideSidebarButtonTitle = WebInspector.UIString(title);
891 this._showHideSidebarButton = new WebInspector.ToolbarButton("", "sideba r-toolbar-item");
892 this._showHideSidebarButton.addEventListener("click", buttonClicked.bind (this));
893 this._updateShowHideSidebarButton();
894
895 /**
896 * @param {!WebInspector.Event} event
897 * @this {WebInspector.SplitWidget}
898 */
899 function buttonClicked(event)
900 {
901 if (this._showMode !== WebInspector.SplitWidget.ShowMode.Both)
902 this.showBoth(true);
903 else
904 this.hideSidebar(true);
905 }
906
907 return this._showHideSidebarButton;
908 },
909
910 _updateShowHideSidebarButton: function()
911 {
912 if (!this._showHideSidebarButton)
913 return;
914 var sidebarHidden = this._showMode === WebInspector.SplitWidget.ShowMode .OnlyMain;
915 var side = this.isVertical() ? (this.isSidebarSecond() ? "right" : "left ") : (this.isSidebarSecond() ? "bottom" : "top");
916 this._showHideSidebarButton.setState(side + "-" + (sidebarHidden ? "show " : "hide"));
917 this._showHideSidebarButton.setTitle(sidebarHidden ? WebInspector.UIStri ng("Show %s", this._showHideSidebarButtonTitle) : WebInspector.UIString("Hide %s ", this._showHideSidebarButtonTitle));
918 },
919
920 __proto__: WebInspector.Widget.prototype
921 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698