123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517 |
- /*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2007 Matt Lilek (pewtermoose@gmail.com).
- * Copyright (C) 2009 Joseph Pecoraro
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- /**
- * @constructor
- */
- WebInspector.Toolbar = function()
- {
- this.element = document.getElementById("toolbar");
- WebInspector.installDragHandle(this.element, this._toolbarDragStart.bind(this), this._toolbarDrag.bind(this), this._toolbarDragEnd.bind(this), "default");
- this._dropdownButton = document.getElementById("toolbar-dropdown-arrow");
- this._dropdownButton.addEventListener("click", this._toggleDropdown.bind(this), false);
- this._panelsMenuButton = document.getElementById("toolbar-panels-menu");
- if (this._isToolbarCustomizable()) {
- this._panelsMenuButton.addEventListener("mousedown", this._togglePanelsMenu.bind(this), false);
- this._panelsMenuButton.removeStyleClass("hidden");
- }
- document.getElementById("close-button-left").addEventListener("click", this._onClose, true);
- document.getElementById("close-button-right").addEventListener("click", this._onClose, true);
- this._panelDescriptors = [];
- }
- WebInspector.Toolbar.prototype = {
- resize: function()
- {
- this._updateDropdownButtonAndHideDropdown();
- },
- /**
- * @param {!WebInspector.PanelDescriptor} panelDescriptor
- */
- addPanel: function(panelDescriptor)
- {
- this._panelDescriptors.push(panelDescriptor);
- panelDescriptor._toolbarElement = this._createPanelToolbarItem(panelDescriptor);
- if (!this._isToolbarCustomizable() || this._isPanelVisible(panelDescriptor.name()))
- this.element.insertBefore(panelDescriptor._toolbarElement, this._panelInsertLocation(panelDescriptor));
- this._updatePanelsMenuState();
- this.resize();
- },
- /**
- * @param {!WebInspector.PanelDescriptor} panelDescriptor
- * @return {Element}
- */
- _panelInsertLocation: function(panelDescriptor)
- {
- if (!this._isToolbarCustomizable())
- return null;
- if (this._isDefaultPanel(panelDescriptor.name()))
- return this._firstNonDefaultPanel || null;
- if (!this._firstNonDefaultPanel)
- this._firstNonDefaultPanel = panelDescriptor._toolbarElement;
- return null;
- },
- /**
- * @param {!string} name
- * @return {boolean}
- */
- _isDefaultPanel: function(name)
- {
- var defaultPanels = {
- "elements": true,
- "resources": true,
- "scripts": true,
- "console": true,
- "network": true,
- "timeline": true,
- };
- return !!defaultPanels[name];
- },
- /**
- * @param {!string} name
- * @return {boolean}
- */
- _isPanelVisibleByDefault: function(name)
- {
- var visible = {
- "elements": true,
- "console": true,
- "network": true,
- "scripts": true,
- "timeline": true,
- "profiles": true,
- "cpu-profiler": true,
- "heap-profiler": true,
- "audits": true,
- "resources": true,
- };
- return !!visible[name];
- },
- /**
- * @return {boolean}
- */
- _isToolbarCustomizable: function()
- {
- return WebInspector.experimentsSettings.customizableToolbar.isEnabled();
- },
- /**
- * @param {!string} name
- * @return {boolean}
- */
- _isPanelVisible: function(name)
- {
- if (!this._isToolbarCustomizable())
- return true;
- var visiblePanels = WebInspector.settings.visiblePanels.get();
- return visiblePanels.hasOwnProperty(name) ? visiblePanels[name] : this._isPanelVisibleByDefault(name);
- },
- /**
- * @param {!string} name
- * @param {boolean} visible
- */
- _setPanelVisible: function(name, visible)
- {
- var visiblePanels = WebInspector.settings.visiblePanels.get();
- visiblePanels[name] = visible;
- WebInspector.settings.visiblePanels.set(visiblePanels);
- },
- /**
- * @param {!WebInspector.PanelDescriptor} panelDescriptor
- */
- _hidePanel: function(panelDescriptor)
- {
- if (!this._isPanelVisible(panelDescriptor.name()))
- return;
- var switchToSibling = panelDescriptor._toolbarElement.nextSibling;
- if (!switchToSibling || !switchToSibling.classList.contains("toggleable"))
- switchToSibling = panelDescriptor._toolbarElement.previousSibling;
- if (!switchToSibling || !switchToSibling.classList || !switchToSibling.classList.contains("toggleable"))
- return;
- this._setPanelVisible(panelDescriptor.name(), false);
- this.element.removeChild(panelDescriptor._toolbarElement);
- if (WebInspector.inspectorView.currentPanel().name === panelDescriptor.name()) {
- for (var i = 0; i < this._panelDescriptors.length; ++i) {
- var descr = this._panelDescriptors[i];
- if (descr._toolbarElement === switchToSibling) {
- WebInspector.showPanel(descr.name());
- break;
- }
- }
- }
- this._updatePanelsMenuState();
- this.resize();
- },
- _updatePanelsMenuState: function()
- {
- if (this._panelDescriptors.every(function (descr) { return this._isPanelVisible(descr.name()); }, this) && this._allItemsFitOntoToolbar())
- document.getElementById("toolbar-panels-menu").addStyleClass("disabled");
- else
- document.getElementById("toolbar-panels-menu").removeStyleClass("disabled");
- },
- /**
- * @return {boolean}
- */
- _allItemsFitOntoToolbar: function()
- {
- var toolbarItems = this.element.querySelectorAll(".toolbar-item.toggleable");
- return toolbarItems.length === 0 || this.element.scrollHeight < toolbarItems[0].offsetHeight * 2;
- },
- /**
- * @param {!WebInspector.PanelDescriptor} panelDescriptor
- */
- _showPanel: function(panelDescriptor)
- {
- if (this._isPanelVisible(panelDescriptor.name()))
- return;
- this.element.appendChild(panelDescriptor._toolbarElement);
- panelDescriptor._toolbarElement.removeStyleClass("hidden");
- this._setPanelVisible(panelDescriptor.name(), true);
- this._updatePanelsMenuState();
- this.resize();
- },
- /**
- * @param {WebInspector.PanelDescriptor} panelDescriptor
- * @param {boolean=} noCloseButton
- * @return {Element}
- */
- _createPanelToolbarItem: function(panelDescriptor, noCloseButton)
- {
- var toolbarItem = document.createElement("button");
- toolbarItem.className = "toolbar-item toggleable";
- toolbarItem.panelDescriptor = panelDescriptor;
- toolbarItem.addStyleClass(panelDescriptor.name());
- /**
- * @param {Event} event
- */
- function onContextMenuEvent(event)
- {
- var contextMenu = new WebInspector.ContextMenu(event);
- contextMenu.appendItem(WebInspector.UIString("Close"), this._hidePanel.bind(this, panelDescriptor));
- contextMenu.show();
- }
- if (!this._isDefaultPanel(panelDescriptor.name()))
- toolbarItem.addEventListener("contextmenu", onContextMenuEvent.bind(this), true);
- function onToolbarItemClicked()
- {
- this._showPanel(panelDescriptor);
- this._updateDropdownButtonAndHideDropdown();
- WebInspector.inspectorView.setCurrentPanel(panelDescriptor.panel());
- }
- toolbarItem.addEventListener("click", onToolbarItemClicked.bind(this), false);
- function onToolbarItemCloseButtonClicked(event)
- {
- event.stopPropagation();
- this._hidePanel(panelDescriptor);
- }
- function panelSelected()
- {
- if (WebInspector.inspectorView.currentPanel() && panelDescriptor.name() === WebInspector.inspectorView.currentPanel().name)
- toolbarItem.addStyleClass("toggled-on");
- else
- toolbarItem.removeStyleClass("toggled-on");
- }
- WebInspector.inspectorView.addEventListener(WebInspector.InspectorView.Events.PanelSelected, panelSelected);
- toolbarItem.createChild("div", "toolbar-label").textContent = panelDescriptor.title();
- if (this._isToolbarCustomizable() && !this._isDefaultPanel(panelDescriptor.name()) && !noCloseButton) {
- var closeButton = toolbarItem.createChild("div", "close-button");
- closeButton.addEventListener("click", onToolbarItemCloseButtonClicked.bind(this), false);
- }
- panelSelected();
- return toolbarItem;
- },
- /**
- * @return {boolean}
- */
- _isDockedToBottom: function()
- {
- return !!WebInspector.dockController && WebInspector.dockController.dockSide() == WebInspector.DockController.State.DockedToBottom;
- },
- /**
- * @return {boolean}
- */
- _isUndocked: function()
- {
- return !!WebInspector.dockController && WebInspector.dockController.dockSide() == WebInspector.DockController.State.Undocked;
- },
- /**
- * @return {boolean}
- */
- _toolbarDragStart: function(event)
- {
- if (this._isUndocked())
- return false;
- var target = event.target;
- if (target.hasStyleClass("toolbar-item") && target.hasStyleClass("toggleable"))
- return false;
- if (target !== this.element && !target.hasStyleClass("toolbar-item"))
- return false;
- this._lastScreenX = event.screenX;
- this._lastScreenY = event.screenY;
- this._lastHeightDuringDrag = window.innerHeight;
- this._startDistanceToRight = window.innerWidth - event.clientX;
- this._startDinstanceToBottom = window.innerHeight - event.clientY;
- return true;
- },
- _toolbarDragEnd: function(event)
- {
- // We may not get the drag event at the end.
- // Apply last changes manually.
- this._toolbarDrag(event);
- delete this._lastScreenX;
- delete this._lastScreenY;
- delete this._lastHeightDuringDrag;
- delete this._startDistanceToRight;
- delete this._startDinstanceToBottom;
- },
- _toolbarDrag: function(event)
- {
- event.preventDefault();
- if (this._isUndocked())
- return this._toolbarDragMoveWindow(event);
- return this._toolbarDragChangeDocking(event);
- },
- _toolbarDragMoveWindow: function(event)
- {
- var x = event.screenX - this._lastScreenX;
- var y = event.screenY - this._lastScreenY;
- this._lastScreenX = event.screenX;
- this._lastScreenY = event.screenY;
- InspectorFrontendHost.moveWindowBy(x, y);
- },
- _toolbarDragChangeDocking: function(event)
- {
- if (this._isDockedToBottom()) {
- var distanceToRight = window.innerWidth - event.clientX;
- if (distanceToRight < this._startDistanceToRight * 2 / 3) {
- InspectorFrontendHost.requestSetDockSide(WebInspector.DockController.State.DockedToRight);
- return true;
- }
- } else {
- var distanceToBottom = window.innerHeight - event.clientY;
- if (distanceToBottom < this._startDinstanceToBottom * 2 / 3) {
- InspectorFrontendHost.requestSetDockSide(WebInspector.DockController.State.DockedToBottom);
- return true;
- }
- }
- },
- _onClose: function()
- {
- WebInspector.close();
- },
- _setDropdownVisible: function(visible)
- {
- if (!this._dropdown) {
- if (!visible)
- return;
- this._dropdown = new WebInspector.ToolbarDropdown(this);
- }
- if (visible)
- this._dropdown.show();
- else
- this._dropdown.hide();
- },
- _toggleDropdown: function()
- {
- this._setDropdownVisible(!this._dropdown || !this._dropdown.visible);
- },
- _togglePanelsMenu: function(event)
- {
- function activatePanel(panelDescriptor)
- {
- this._showPanel(panelDescriptor);
- WebInspector.showPanel(panelDescriptor.name());
- }
- var contextMenu = new WebInspector.ContextMenu(event);
- var currentPanelName = WebInspector.inspectorView.currentPanel().name;
- var toolbarItems = this.element.querySelectorAll(".toolbar-item.toggleable");
- for (var i = 0; i < toolbarItems.length; ++i) {
- if (toolbarItems[i].offsetTop >= toolbarItems[0].offsetHeight) {
- var descr = toolbarItems[i].panelDescriptor;
- if (descr.name() === currentPanelName)
- contextMenu.appendCheckboxItem(descr.title(), activatePanel.bind(this, descr), true);
- else
- contextMenu.appendItem(descr.title(), activatePanel.bind(this, descr));
- }
- }
- contextMenu.appendSeparator();
- for (var i = 0; i < this._panelDescriptors.length; ++i) {
- var descr = this._panelDescriptors[i];
- if (this._isPanelVisible(descr.name()))
- continue;
- contextMenu.appendItem(descr.title(), activatePanel.bind(this, descr));
- }
- contextMenu.showSoftMenu();
- },
- _updateDropdownButtonAndHideDropdown: function()
- {
- WebInspector.invokeOnceAfterBatchUpdate(this, this._innerUpdateDropdownButtonAndHideDropdown);
- },
- _innerUpdateDropdownButtonAndHideDropdown: function()
- {
- if (this._isToolbarCustomizable()) {
- this._updatePanelsMenuState();
- return;
- }
- this._setDropdownVisible(false);
- if (this.element.scrollHeight > this.element.offsetHeight)
- this._dropdownButton.removeStyleClass("hidden");
- else
- this._dropdownButton.addStyleClass("hidden");
- }
- }
- /**
- * @constructor
- * @param {WebInspector.Toolbar} toolbar
- */
- WebInspector.ToolbarDropdown = function(toolbar)
- {
- this._toolbar = toolbar;
- this._arrow = document.getElementById("toolbar-dropdown-arrow");
- this.element = document.createElement("div");
- this.element.id = "toolbar-dropdown";
- this.element.className = "toolbar-small";
- this._contentElement = this.element.createChild("div", "scrollable-content");
- this._contentElement.tabIndex = 0;
- this._contentElement.addEventListener("keydown", this._onKeyDown.bind(this), true);
- }
- WebInspector.ToolbarDropdown.prototype = {
- show: function()
- {
- if (this.visible)
- return;
- var style = this.element.style;
- this._populate();
- var top = this._arrow.totalOffsetTop() + this._arrow.clientHeight;
- this._arrow.addStyleClass("dropdown-visible");
- this.element.style.top = top + "px";
- this.element.style.right = window.innerWidth - this._arrow.totalOffsetLeft() - this._arrow.clientWidth + "px";
- this._contentElement.style.maxHeight = window.innerHeight - top - 20 + "px";
- this._toolbar.element.appendChild(this.element);
- },
- hide: function()
- {
- if (!this.visible)
- return;
- this._arrow.removeStyleClass("dropdown-visible");
- this.element.remove();
- this._contentElement.removeChildren();
- },
- get visible()
- {
- return !!this.element.parentNode;
- },
- _populate: function()
- {
- var toolbarItems = this._toolbar.element.querySelectorAll(".toolbar-item.toggleable");
- var needsSeparator = false;
- for (var i = 0; i < toolbarItems.length; ++i) {
- if (toolbarItems[i].offsetTop >= toolbarItems[0].offsetHeight) {
- this._contentElement.appendChild(this._toolbar._createPanelToolbarItem(toolbarItems[i].panelDescriptor, true));
- needsSeparator = true;
- }
- }
- var panelDescriptors = this._toolbar._panelDescriptors;
- for (var i = 0; i < panelDescriptors.length; ++i) {
- var descr = panelDescriptors[i];
- if (this._toolbar._isPanelVisible(descr.name()))
- continue;
- if (needsSeparator) {
- this._contentElement.createChild("div", "toolbar-items-separator");
- needsSeparator = false;
- }
- this._contentElement.appendChild(this._toolbar._createPanelToolbarItem(descr, true));
- }
- },
- _onKeyDown: function(event)
- {
- if (event.keyCode !== WebInspector.KeyboardShortcut.Keys.Esc.code)
- return;
- event.consume();
- this.hide();
- }
- }
- /**
- * @type {?WebInspector.Toolbar}
- */
- WebInspector.toolbar = null;
|