• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
3 * Copyright (C) 2009 Joseph Pecoraro
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
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.
17 *
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.
28 */
29
30/**
31 * @constructor
32 * @extends {WebInspector.VBox}
33 * @param {!WebInspector.SplitView} splitView
34 */
35WebInspector.Drawer = function(splitView)
36{
37    WebInspector.VBox.call(this);
38    this.element.id = "drawer-contents";
39
40    this._splitView = splitView;
41    splitView.hideDefaultResizer();
42    this.show(splitView.sidebarElement());
43
44    this._drawerEditorSplitView = new WebInspector.SplitView(true, true, "editorInDrawerSplitViewState", 0.5, 0.5);
45    this._drawerEditorSplitView.hideSidebar();
46    this._drawerEditorSplitView.addEventListener(WebInspector.SplitView.Events.ShowModeChanged, this._drawerEditorSplitViewShowModeChanged, this);
47    this._drawerEditorShownSetting = WebInspector.settings.createSetting("drawerEditorShown", true);
48    this._drawerEditorSplitView.show(this.element);
49
50    this._toggleDrawerButton = new WebInspector.StatusBarButton(WebInspector.UIString("Show drawer."), "console-status-bar-item");
51    this._toggleDrawerButton.addEventListener("click", this.toggle, this);
52
53    this._tabbedPane = new WebInspector.TabbedPane();
54    this._tabbedPane.element.id = "drawer-tabbed-pane";
55    this._tabbedPane.closeableTabs = false;
56    this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
57    new WebInspector.ExtensibleTabbedPaneController(this._tabbedPane, "drawer-view");
58
59    this._toggleDrawerEditorButton = this._drawerEditorSplitView.createShowHideSidebarButton("editor in drawer", "drawer-editor-show-hide-button");
60    this._tabbedPane.element.appendChild(this._toggleDrawerEditorButton.element);
61    if (!WebInspector.experimentsSettings.editorInDrawer.isEnabled())
62        this.setDrawerEditorAvailable(false);
63
64    splitView.installResizer(this._tabbedPane.headerElement());
65    this._lastSelectedViewSetting = WebInspector.settings.createSetting("WebInspector.Drawer.lastSelectedView", "console");
66    this._tabbedPane.show(this._drawerEditorSplitView.mainElement());
67}
68
69WebInspector.Drawer.prototype = {
70    /**
71     * @return {!Element}
72     */
73    toggleButtonElement: function()
74    {
75        return this._toggleDrawerButton.element;
76    },
77
78    /**
79     * @param {string} id
80     */
81    closeView: function(id)
82    {
83        this._tabbedPane.closeTab(id);
84    },
85
86    /**
87     * @param {string} id
88     * @param {boolean=} immediate
89     */
90    showView: function(id, immediate)
91    {
92        if (!this._tabbedPane.hasTab(id)) {
93            // Hidden tab.
94            this._innerShow(immediate);
95            return;
96        }
97        this._innerShow(immediate);
98        this._tabbedPane.selectTab(id, true);
99        // In case this id is already selected, anyways persist it as the last saved value.
100        this._lastSelectedViewSetting.set(id);
101    },
102
103    /**
104     * @param {string} id
105     * @param {string} title
106     * @param {!WebInspector.View} view
107     */
108    showCloseableView: function(id, title, view)
109    {
110        if (!this._tabbedPane.hasTab(id)) {
111            this._tabbedPane.appendTab(id, title, view, undefined, false, true);
112        } else {
113            this._tabbedPane.changeTabView(id, view);
114            this._tabbedPane.changeTabTitle(id, title);
115        }
116        this._innerShow();
117        this._tabbedPane.selectTab(id, true);
118    },
119
120    showDrawer: function()
121    {
122        this.showView(this._lastSelectedViewSetting.get());
123    },
124
125    wasShown: function()
126    {
127        this.showView(this._lastSelectedViewSetting.get());
128        this._toggleDrawerButton.toggled = true;
129        this._toggleDrawerButton.title = WebInspector.UIString("Hide drawer.");
130        this._ensureDrawerEditorExistsIfNeeded();
131    },
132
133    willHide: function()
134    {
135        this._toggleDrawerButton.toggled = false;
136        this._toggleDrawerButton.title = WebInspector.UIString("Show drawer.");
137    },
138
139    /**
140     * @param {boolean=} immediate
141     */
142    _innerShow: function(immediate)
143    {
144        if (this.isShowing())
145            return;
146
147        this._splitView.showBoth(!immediate);
148
149        if (this._visibleView())
150            this._visibleView().focus();
151    },
152
153    closeDrawer: function()
154    {
155        if (!this.isShowing())
156            return;
157
158        WebInspector.restoreFocusFromElement(this.element);
159        this._splitView.hideSidebar(true);
160    },
161
162    /**
163     * @return {?WebInspector.View} view
164     */
165    _visibleView: function()
166    {
167        return this._tabbedPane.visibleView;
168    },
169
170    /**
171     * @param {!WebInspector.Event} event
172     */
173    _tabSelected: function(event)
174    {
175        var tabId = this._tabbedPane.selectedTabId;
176        if (tabId && event.data["isUserGesture"] && !this._tabbedPane.isTabCloseable(tabId))
177            this._lastSelectedViewSetting.set(tabId);
178    },
179
180    toggle: function()
181    {
182        if (this._toggleDrawerButton.toggled)
183            this.closeDrawer();
184        else
185            this.showDrawer();
186    },
187
188    /**
189     * @return {boolean}
190     */
191    visible: function()
192    {
193        return this._toggleDrawerButton.toggled;
194    },
195
196    /**
197     * @return {?string}
198     */
199    selectedViewId: function()
200    {
201        return this._tabbedPane.selectedTabId;
202    },
203
204    /**
205     * @param {!WebInspector.Event} event
206     */
207    _drawerEditorSplitViewShowModeChanged: function(event)
208    {
209        var mode = /** @type {string} */ (event.data);
210        var shown = mode === WebInspector.SplitView.ShowMode.Both;
211
212        if (this._isHidingDrawerEditor)
213            return;
214
215        this._drawerEditorShownSetting.set(shown);
216
217        if (!shown)
218            return;
219
220        this._ensureDrawerEditor();
221        this._drawerEditor.view().show(this._drawerEditorSplitView.sidebarElement());
222    },
223
224    initialPanelShown: function()
225    {
226        this._initialPanelWasShown = true;
227        this._ensureDrawerEditorExistsIfNeeded();
228    },
229
230    _ensureDrawerEditorExistsIfNeeded: function()
231    {
232        if (!this._initialPanelWasShown || !this.isShowing() || !this._drawerEditorShownSetting.get() || !WebInspector.experimentsSettings.editorInDrawer.isEnabled())
233            return;
234        this._ensureDrawerEditor();
235    },
236
237    _ensureDrawerEditor: function()
238    {
239        if (this._drawerEditor)
240            return;
241        this._drawerEditor = WebInspector.moduleManager.instance(WebInspector.DrawerEditor);
242        this._drawerEditor.installedIntoDrawer();
243    },
244
245    /**
246     * @param {boolean} available
247     */
248    setDrawerEditorAvailable: function(available)
249    {
250        if (!WebInspector.experimentsSettings.editorInDrawer.isEnabled())
251            available = false;
252        this._toggleDrawerEditorButton.element.classList.toggle("hidden", !available);
253    },
254
255    showDrawerEditor: function()
256    {
257        if (!WebInspector.experimentsSettings.editorInDrawer.isEnabled())
258            return;
259
260        this._splitView.showBoth();
261        this._drawerEditorSplitView.showBoth();
262    },
263
264    hideDrawerEditor: function()
265    {
266        this._isHidingDrawerEditor = true;
267        this._drawerEditorSplitView.hideSidebar();
268        this._isHidingDrawerEditor = false;
269    },
270
271    /**
272     * @return {boolean}
273     */
274    isDrawerEditorShown: function()
275    {
276        return this._drawerEditorShownSetting.get();
277    },
278
279    __proto__: WebInspector.VBox.prototype
280}
281
282/**
283 * @interface
284 */
285WebInspector.Drawer.ViewFactory = function()
286{
287}
288
289WebInspector.Drawer.ViewFactory.prototype = {
290    /**
291     * @return {!WebInspector.View}
292     */
293    createView: function() {}
294}
295
296/**
297 * @constructor
298 * @implements {WebInspector.Drawer.ViewFactory}
299 * @param {function(new:T)} constructor
300 * @template T
301 */
302WebInspector.Drawer.SingletonViewFactory = function(constructor)
303{
304    this._constructor = constructor;
305}
306
307WebInspector.Drawer.SingletonViewFactory.prototype = {
308    /**
309     * @return {!WebInspector.View}
310     */
311    createView: function()
312    {
313        if (!this._instance)
314            this._instance = /** @type {!WebInspector.View} */(new this._constructor());
315        return this._instance;
316    }
317}
318
319/**
320 * @interface
321 */
322WebInspector.DrawerEditor = function()
323{
324}
325
326WebInspector.DrawerEditor.prototype = {
327    /**
328     * @return {!WebInspector.View}
329     */
330    view: function() { },
331
332    installedIntoDrawer: function() { },
333}
334