2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2009 Joseph Pecoraro
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15 * its contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 WebInspector
.Drawer = function()
32 WebInspector
.View
.call(this, document
.getElementById("drawer"));
34 this._savedHeight
= 200; // Default.
35 this.state
= WebInspector
.Drawer
.State
.Hidden
;
36 this.fullPanel
= false;
38 this.mainElement
= document
.getElementById("main");
39 this.toolbarElement
= document
.getElementById("toolbar");
40 this.mainStatusBar
= document
.getElementById("main-status-bar");
41 this.mainStatusBar
.addEventListener("mousedown", this._startStatusBarDragging
.bind(this), true);
42 this.viewStatusBar
= document
.getElementById("other-drawer-status-bar-items");
45 WebInspector
.Drawer
.prototype = {
48 return this._visibleView
;
53 if (this._visibleView
=== x
) {
54 if (this.visible
&& this.fullPanel
)
56 this.visible
= !this.visible
;
60 var firstTime
= !this._visibleView
;
61 if (this._visibleView
)
62 this._visibleView
.hide();
64 this._visibleView
= x
;
66 if (x
&& !firstTime
) {
67 this._safelyRemoveChildren();
68 this.viewStatusBar
.removeChildren(); // optimize this? call old.detach()
69 x
.attach(this.element
, this.viewStatusBar
);
77 var height
= this._savedHeight
|| this.element
.offsetHeight
;
78 return Number
.constrain(height
, Preferences
.minConsoleHeight
, window
.innerHeight
- this.mainElement
.totalOffsetTop
- Preferences
.minConsoleHeight
);
81 showView: function(view
)
83 if (!this.visible
|| this.visibleView
!== view
)
84 this.visibleView
= view
;
89 if (this._animating
|| this.visible
)
93 this.visibleView
.show();
95 WebInspector
.View
.prototype.show
.call(this);
97 this._animating
= true;
99 document
.body
.addStyleClass("drawer-visible");
101 var anchoredItems
= document
.getElementById("anchored-status-bar-items");
102 var height
= (this.fullPanel
? window
.innerHeight
- this.toolbarElement
.offsetHeight
: this.savedHeight
);
104 {element
: this.element
, end
: {height
: height
}},
105 {element
: document
.getElementById("main"), end
: {bottom
: height
}},
106 {element
: document
.getElementById("main-status-bar"), start
: {"padding-left": anchoredItems
.offsetWidth
- 1}, end
: {"padding-left": 0}},
107 {element
: document
.getElementById("other-drawer-status-bar-items"), start
: {opacity
: 0}, end
: {opacity
: 1}}
110 var drawerStatusBar
= document
.getElementById("drawer-status-bar");
111 drawerStatusBar
.insertBefore(anchoredItems
, drawerStatusBar
.firstChild
);
113 function animationFinished()
115 if ("updateStatusBarItems" in WebInspector
.currentPanel
)
116 WebInspector
.currentPanel
.updateStatusBarItems();
117 if (this.visibleView
.afterShow
)
118 this.visibleView
.afterShow();
119 delete this._animating
;
120 delete this._currentAnimationInterval
;
121 this.state
= (this.fullPanel
? WebInspector
.Drawer
.State
.Full
: WebInspector
.Drawer
.State
.Variable
);
124 this._currentAnimationInterval
= WebInspector
.animateStyle(animations
, this._animationDuration(), animationFinished
.bind(this));
129 if (this._animating
|| !this.visible
)
132 WebInspector
.View
.prototype.hide
.call(this);
134 if (this.visibleView
)
135 this.visibleView
.hide();
137 this._animating
= true;
140 this._savedHeight
= this.element
.offsetHeight
;
142 if (this.element
=== WebInspector
.currentFocusElement
|| this.element
.isAncestor(WebInspector
.currentFocusElement
))
143 WebInspector
.currentFocusElement
= WebInspector
.previousFocusElement
;
145 var anchoredItems
= document
.getElementById("anchored-status-bar-items");
147 // Temporarily set properties and classes to mimic the post-animation values so panels
148 // like Elements in their updateStatusBarItems call will size things to fit the final location.
149 this.mainStatusBar
.style
.setProperty("padding-left", (anchoredItems
.offsetWidth
- 1) + "px");
150 document
.body
.removeStyleClass("drawer-visible");
151 if ("updateStatusBarItems" in WebInspector
.currentPanel
)
152 WebInspector
.currentPanel
.updateStatusBarItems();
153 document
.body
.addStyleClass("drawer-visible");
156 {element
: document
.getElementById("main"), end
: {bottom
: 0}},
157 {element
: document
.getElementById("main-status-bar"), start
: {"padding-left": 0}, end
: {"padding-left": anchoredItems
.offsetWidth
- 1}},
158 {element
: document
.getElementById("other-drawer-status-bar-items"), start
: {opacity
: 1}, end
: {opacity
: 0}}
161 function animationFinished()
163 var mainStatusBar
= document
.getElementById("main-status-bar");
164 mainStatusBar
.insertBefore(anchoredItems
, mainStatusBar
.firstChild
);
165 mainStatusBar
.style
.removeProperty("padding-left");
166 document
.body
.removeStyleClass("drawer-visible");
167 delete this._animating
;
168 delete this._currentAnimationInterval
;
169 this.state
= WebInspector
.Drawer
.State
.Hidden
;
172 this._currentAnimationInterval
= WebInspector
.animateStyle(animations
, this._animationDuration(), animationFinished
.bind(this));
177 if (this.state
=== WebInspector
.Drawer
.State
.Hidden
)
181 var mainElement
= document
.getElementById("main");
182 if (this.state
=== WebInspector
.Drawer
.State
.Variable
) {
183 height
= parseInt(this.element
.style
.height
);
184 height
= Number
.constrain(height
, Preferences
.minConsoleHeight
, window
.innerHeight
- mainElement
.totalOffsetTop
- Preferences
.minConsoleHeight
);
186 height
= window
.innerHeight
- this.toolbarElement
.offsetHeight
;
188 mainElement
.style
.bottom
= height
+ "px";
189 this.element
.style
.height
= height
+ "px";
192 enterPanelMode: function()
194 this._cancelAnimationIfNeeded();
195 this.fullPanel
= true;
198 this._savedHeight
= this.element
.offsetHeight
;
199 var height
= window
.innerHeight
- this.toolbarElement
.offsetHeight
;
200 this._animateDrawerHeight(height
, WebInspector
.Drawer
.State
.Full
);
204 exitPanelMode: function()
206 this._cancelAnimationIfNeeded();
207 this.fullPanel
= false;
210 // If this animation gets cancelled, we want the state of the drawer to be Variable,
211 // so that the new animation can't do an immediate transition between Hidden/Full states.
212 this.state
= WebInspector
.Drawer
.State
.Variable
;
213 var height
= this.savedHeight
;
214 this._animateDrawerHeight(height
, WebInspector
.Drawer
.State
.Variable
);
218 immediatelyExitPanelMode: function()
220 this.visible
= false;
221 this.fullPanel
= false;
224 _cancelAnimationIfNeeded: function()
226 if (this._animating
) {
227 clearInterval(this._currentAnimationInterval
);
228 delete this._animating
;
229 delete this._currentAnimationInterval
;
233 _animateDrawerHeight: function(height
, finalState
)
235 this._animating
= true;
237 {element
: this.element
, end
: {height
: height
}},
238 {element
: document
.getElementById("main"), end
: {bottom
: height
}}
241 function animationFinished()
243 delete this._animating
;
244 delete this._currentAnimationInterval
;
245 this.state
= finalState
;
248 this._currentAnimationInterval
= WebInspector
.animateStyle(animations
, this._animationDuration(), animationFinished
.bind(this));
251 _animationDuration: function()
253 // Immediate if going between Hidden and Full in full panel mode
254 if (this.fullPanel
&& (this.state
=== WebInspector
.Drawer
.State
.Hidden
|| this.state
=== WebInspector
.Drawer
.State
.Full
))
257 return (window
.event
&& window
.event
.shiftKey
? 2000 : 250);
260 _safelyRemoveChildren: function()
262 var child
= this.element
.firstChild
;
264 if (child
.id
!== "drawer-status-bar") {
265 var moveTo
= child
.nextSibling
;
266 this.element
.removeChild(child
);
269 child
= child
.nextSibling
;
273 _startStatusBarDragging: function(event
)
275 if (!this.visible
|| event
.target
!== this.mainStatusBar
)
278 WebInspector
.elementDragStart(this.mainStatusBar
, this._statusBarDragging
.bind(this), this._endStatusBarDragging
.bind(this), event
, "row-resize");
280 this._statusBarDragOffset
= event
.pageY
- this.element
.totalOffsetTop
;
282 event
.stopPropagation();
285 _statusBarDragging: function(event
)
287 var mainElement
= document
.getElementById("main");
288 var height
= window
.innerHeight
- event
.pageY
+ this._statusBarDragOffset
;
289 height
= Number
.constrain(height
, Preferences
.minConsoleHeight
, window
.innerHeight
- mainElement
.totalOffsetTop
- Preferences
.minConsoleHeight
);
291 mainElement
.style
.bottom
= height
+ "px";
292 this.element
.style
.height
= height
+ "px";
294 event
.preventDefault();
295 event
.stopPropagation();
298 _endStatusBarDragging: function(event
)
300 WebInspector
.elementDragEnd(event
);
302 this._savedHeight
= this.element
.offsetHeight
;
303 delete this._statusBarDragOffset
;
305 event
.stopPropagation();
309 WebInspector
.Drawer
.prototype.__proto__
= WebInspector
.View
.prototype;
311 WebInspector
.Drawer
.State
= {