tizen beta release
[profile/ivi/webkit-efl.git] / debian / libwebkit-engine / usr / share / ewebkit-0 / webinspector / SplitView.js
1 /*
2  * Copyright (C) 2011 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  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following disclaimer
13  * in the documentation and/or other materials provided with the
14  * distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
20  * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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.
27  */
28
29 /**
30  * @constructor
31  * @extends {WebInspector.View}
32  * @param {string=} sidebarPosition
33  * @param {string=} sidebarWidthSettingName
34  * @param {number=} defaultSidebarWidth
35  */
36 WebInspector.SplitView = function(sidebarPosition, sidebarWidthSettingName, defaultSidebarWidth)
37 {
38     WebInspector.View.call(this);
39     this.registerRequiredCSS("splitView.css");
40
41     this.element.className = "split-view";
42
43     this._leftElement = document.createElement("div");
44     this._leftElement.className = "split-view-contents";
45     this.element.appendChild(this._leftElement);
46
47     this._rightElement = document.createElement("div");
48     this._rightElement.className = "split-view-contents";
49     this.element.appendChild(this._rightElement);
50
51     this.sidebarResizerElement = document.createElement("div");
52     this.sidebarResizerElement.className = "split-view-resizer";
53     this.installResizer(this.sidebarResizerElement);
54     this._resizable = true;
55     this.element.appendChild(this.sidebarResizerElement);
56
57     defaultSidebarWidth = defaultSidebarWidth || 200;
58     this._savedSidebarWidth = defaultSidebarWidth;
59
60     this._sidebarWidthSettingName = sidebarWidthSettingName;
61     if (this._sidebarWidthSettingName)
62         WebInspector.settings[this._sidebarWidthSettingName] = WebInspector.settings.createSetting(this._sidebarWidthSettingName, undefined);
63
64     this._minimalSidebarWidth = Preferences.minSidebarWidth;
65     this._minimalMainWidth = 0;
66     this._minimalSidebarWidthPercent = 0;
67     this._minimalMainWidthPercent = 50;
68
69     this._mainElementHidden = false;
70     this._sidebarElementHidden = false;
71
72     this._innerSetSidebarPosition(sidebarPosition || WebInspector.SplitView.SidebarPosition.Left);
73 }
74
75 WebInspector.SplitView.EventTypes = {
76     Resized: "Resized",
77 }
78
79 /**
80  * @enum {string}
81  */
82 WebInspector.SplitView.SidebarPosition = {
83     Left: "Left",
84     Right: "Right"
85 }
86
87 WebInspector.SplitView.prototype = {
88     /**
89      * @type {boolean}
90      */
91     get hasLeftSidebar()
92     {
93         return this._sidebarPosition === WebInspector.SplitView.SidebarPosition.Left;
94     },
95
96     /**
97      * @type {Element}
98      */
99     get mainElement()
100     {
101         return this.hasLeftSidebar ? this._rightElement : this._leftElement;
102     },
103
104     /**
105      * @type {Element}
106      */
107     get sidebarElement()
108     {
109         return this.hasLeftSidebar ? this._leftElement : this._rightElement;
110     },
111
112     /**
113      * @type {boolean}
114      */
115     get resizable()
116     {
117         return this._resizable && !this._mainElementHidden && !this._sidebarElementHidden
118     },
119
120     /**
121      * @type {boolean}
122      */
123     set resizable(resizable)
124     {
125         if (this._resizable === resizable)
126             return;
127         this._resizable = resizable;
128         this._updateResizer(resizable);
129     },
130
131     _updateResizer: function()
132     {
133         if (this._resizable)
134             this.sidebarResizerElement.removeStyleClass("hidden");
135         else
136             this.sidebarResizerElement.addStyleClass("hidden");
137     },
138
139     /**
140      * @type {string}
141      */
142     set sidebarPosition(sidebarPosition)
143     {
144         if (this._sidebarPosition === sidebarPosition)
145             return;
146         this._innerSetSidebarPosition(sidebarPosition);
147         this._restoreSidebarWidth();
148     },
149
150     /**
151      * @param {string} sidebarPosition
152      */
153     _innerSetSidebarPosition: function(sidebarPosition)
154     {
155         this._sidebarPosition = sidebarPosition;
156
157         this._leftElement.style.left = 0;
158         this._rightElement.style.right = 0;
159         if (this.hasLeftSidebar) {
160             this._leftElement.addStyleClass("split-view-sidebar-left");
161             this._rightElement.removeStyleClass("split-view-sidebar-right");
162             this._leftElement.style.removeProperty("right");
163             this._rightElement.style.removeProperty("width");
164             this.sidebarResizerElement.style.removeProperty("right");
165         } else {
166             this._rightElement.addStyleClass("split-view-sidebar-right");
167             this._leftElement.removeStyleClass("split-view-sidebar-left");
168             this._leftElement.style.removeProperty("width");
169             this._rightElement.style.removeProperty("left");
170             this.sidebarResizerElement.style.removeProperty("left");
171         }
172     },
173
174     /**
175      * @param {number} width
176      */
177     set minimalSidebarWidth(width)
178     {
179         this._minimalSidebarWidth = width;
180     },
181
182     /**
183      * @param {number} width
184      */
185     set minimalMainWidth(width)
186     {
187         this._minimalMainWidth = width;
188     },
189
190     /**
191      * @param {number} widthPercent
192      */
193     set minimalSidebarWidthPercent(widthPercent)
194     {
195         this._minimalSidebarWidthPercent = widthPercent;
196     },
197
198     /**
199      * @param {number} widthPercent
200      */
201     set minimalMainWidthPercent(widthPercent)
202     {
203         this._minimalMainWidthPercent = widthPercent;
204     },
205
206     /**
207      * @param {number} width
208      */
209     setMainWidth: function(width)
210     {
211         this.setSidebarWidth(this._totalWidth - width);
212     },
213
214     /**
215      * @param {number} width
216      */
217     setSidebarWidth: function(width)
218     {
219         if (this._sidebarWidth === width)
220             return;
221
222         this._innerSetSidebarWidth(width);
223         this.saveSidebarWidth();
224     },
225
226     /**
227      * @param {number} width
228      */
229     _innerSetSidebarWidth: function(width)
230     {
231         if (this.hasLeftSidebar)
232             this._innerSetLeftSidebarWidth(width);
233         else
234             this._innerSetRightSidebarWidth(width);
235         this._sidebarWidth = width;
236         this.doResize();
237         this.dispatchEventToListeners(WebInspector.SplitView.EventTypes.Resized, this._sidebarWidth);
238     },
239
240     /**
241      * @param {number} width
242      */
243     _innerSetLeftSidebarWidth: function(width)
244     {
245         this._leftElement.style.width = width + "px";
246         this._rightElement.style.left = width + "px";
247         this.sidebarResizerElement.style.left = (width - 3) + "px";
248     },
249
250     /**
251      * @param {number} width
252      */
253     _innerSetRightSidebarWidth: function(width)
254     {
255         this._rightElement.style.width = width + "px";
256         this._leftElement.style.right = width + "px";
257         this.sidebarResizerElement.style.right = (width - 3) + "px";
258     },
259
260     /**
261      * @param {number} width
262      */
263     _setSidebarWidthEnsuringConstraints: function(width)
264     {
265         var minWidth = Math.max(this._minimalSidebarWidth, this._totalWidth * this._minimalSidebarWidthPercent);
266         var maxWidth = Math.min(this._totalWidth - this._minimalMainWidth, this._totalWidth * (100 - this._minimalMainWidthPercent) / 100 );
267         width = Number.constrain(width, minWidth, maxWidth);
268
269         this.setSidebarWidth(width);
270     },
271
272     hideMainElement: function()
273     {
274         if (this._mainElementHidden)
275             return;
276
277         if (this._sidebarElementHidden)
278             this.showSidebarElement();
279
280         this.mainElement.addStyleClass("hidden");
281         this.sidebarElement.addStyleClass("maximized");
282         this._mainElementHidden = true;
283         this._updateResizer();
284         this._restoreSidebarWidth();
285     },
286
287     showMainElement: function()
288     {
289         if (!this._mainElementHidden)
290             return;
291
292         this.mainElement.removeStyleClass("hidden");
293         this.sidebarElement.removeStyleClass("maximized");
294         this._mainElementHidden = false;
295         this._updateResizer();
296         this._restoreSidebarWidth();
297     },
298
299     hideSidebarElement: function()
300     {
301         if (this._sidebarElementHidden)
302             return;
303
304         if (this._mainElementHidden)
305             this.showMainElement();
306
307         this.sidebarElement.addStyleClass("hidden");
308         this._sidebarElementHidden = true;
309         this._updateResizer();
310         this._restoreSidebarWidth();
311     },
312
313     showSidebarElement: function()
314     {
315         if (!this._sidebarElementHidden)
316             return;
317
318         this.sidebarElement.removeStyleClass("hidden");
319         this._sidebarElementHidden = false;
320         this._updateResizer();
321         this._restoreSidebarWidth();
322     },
323
324     wasShown: function()
325     {
326         this._totalWidth = this.element.offsetWidth;
327         this._restoreSidebarWidth();
328     },
329
330     onResize: function()
331     {
332         this._totalWidth = this.element.offsetWidth;
333     },
334
335     /**
336      * @param {Event} event
337      */
338     _startResizerDragging: function(event)
339     {
340         if (!this._resizable)
341             return;
342
343         var leftWidth = this.hasLeftSidebar ? this._sidebarWidth : this._totalWidth - this._sidebarWidth;
344         this._dragOffset = leftWidth - event.pageX;
345
346         WebInspector.elementDragStart(this.sidebarResizerElement, this._resizerDragging.bind(this), this._endResizerDragging.bind(this), event, "ew-resize");
347     },
348
349     /**
350      * @param {Event} event
351      */
352     _resizerDragging: function(event)
353     {
354         var leftWidth = event.pageX + this._dragOffset
355         var rightWidth = this._totalWidth - leftWidth;
356         var sidebarWidth = this.hasLeftSidebar ? leftWidth : rightWidth;
357
358         this._setSidebarWidthEnsuringConstraints(sidebarWidth);
359         event.preventDefault();
360     },
361
362     /**
363      * @param {Event} event
364      */
365     _endResizerDragging: function(event)
366     {
367         delete this._dragOffset;
368         WebInspector.elementDragEnd(event);
369     },
370
371     /**
372      * @param {Element} resizerElement
373      */
374     installResizer: function(resizerElement)
375     {
376         resizerElement.addEventListener("mousedown", this._startResizerDragging.bind(this), false);
377     },
378
379     /**
380      * @return {number}
381      */
382     preferredSidebarWidth: function()
383     {
384         if (!this._sidebarWidthSettingName)
385             return this._savedSidebarWidth;
386
387         return WebInspector.settings[this._sidebarWidthSettingName].get() || this._savedSidebarWidth;
388     },
389
390     _restoreSidebarWidth: function()
391     {
392         if (this._mainElementHidden) {
393             this._innerSetSidebarWidth(this._totalWidth);
394             return;
395         }
396
397         if (this._sidebarElementHidden) {
398             this._innerSetSidebarWidth(0);
399             return;
400         }
401
402         // Ensure restore satisfies constraints.
403         this._setSidebarWidthEnsuringConstraints(this.preferredSidebarWidth());
404     },
405
406     saveSidebarWidth: function()
407     {
408         this._savedSidebarWidth = this._sidebarWidth;
409         if (!this._sidebarWidthSettingName)
410             return;
411
412         WebInspector.settings[this._sidebarWidthSettingName].set(this._sidebarWidth);
413     },
414
415     /**
416      * @return {Array.<Element>}
417      */
418     elementsToRestoreScrollPositionsFor: function()
419     {
420         return [ this.mainElement, this.sidebarElement ];
421     }
422 }
423
424 WebInspector.SplitView.prototype.__proto__ = WebInspector.View.prototype;