| Index: chrome/resources/inspector/Panel.js
|
| ===================================================================
|
| --- chrome/resources/inspector/Panel.js (revision 0)
|
| +++ chrome/resources/inspector/Panel.js (revision 0)
|
| @@ -0,0 +1,347 @@
|
| +/*
|
| + * Copyright (C) 2007, 2008 Apple 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.
|
| + */
|
| +
|
| +WebInspector.Panel = function(createSidebar)
|
| +{
|
| + WebInspector.View.call(this);
|
| + if (createSidebar)
|
| + this._createSidebar();
|
| +
|
| + this.element.addStyleClass("panel");
|
| +}
|
| +
|
| +WebInspector.Panel.prototype = {
|
| + get toolbarItem()
|
| + {
|
| + if (this._toolbarItem)
|
| + return this._toolbarItem;
|
| +
|
| + // Sample toolbar item as markup:
|
| + // <button class="toolbar-item resources toggleable">
|
| + // <div class="toolbar-icon"></div>
|
| + // <div class="toolbar-label">Resources</div>
|
| + // </button>
|
| +
|
| + this._toolbarItem = document.createElement("button");
|
| + this._toolbarItem.className = "toolbar-item toggleable";
|
| + this._toolbarItem.panel = this;
|
| +
|
| + if ("toolbarItemClass" in this)
|
| + this._toolbarItem.addStyleClass(this.toolbarItemClass);
|
| +
|
| + var iconElement = document.createElement("div");
|
| + iconElement.className = "toolbar-icon";
|
| + this._toolbarItem.appendChild(iconElement);
|
| +
|
| + if ("toolbarItemLabel" in this) {
|
| + var labelElement = document.createElement("div");
|
| + labelElement.className = "toolbar-label";
|
| + labelElement.textContent = this.toolbarItemLabel;
|
| + this._toolbarItem.appendChild(labelElement);
|
| + }
|
| +
|
| + return this._toolbarItem;
|
| + },
|
| +
|
| + show: function()
|
| + {
|
| + WebInspector.View.prototype.show.call(this);
|
| +
|
| + var statusBarItems = this.statusBarItems;
|
| + if (statusBarItems) {
|
| + this._statusBarItemContainer = document.createElement("div");
|
| + for (var i = 0; i < statusBarItems.length; ++i)
|
| + this._statusBarItemContainer.appendChild(statusBarItems[i]);
|
| + document.getElementById("main-status-bar").appendChild(this._statusBarItemContainer);
|
| + }
|
| +
|
| + if ("_toolbarItem" in this)
|
| + this._toolbarItem.addStyleClass("toggled-on");
|
| +
|
| + WebInspector.currentFocusElement = document.getElementById("main-panels");
|
| + this._updateSidebarWidth();
|
| + },
|
| +
|
| + hide: function()
|
| + {
|
| + WebInspector.View.prototype.hide.call(this);
|
| +
|
| + if (this._statusBarItemContainer && this._statusBarItemContainer.parentNode)
|
| + this._statusBarItemContainer.parentNode.removeChild(this._statusBarItemContainer);
|
| + delete this._statusBarItemContainer;
|
| + if ("_toolbarItem" in this)
|
| + this._toolbarItem.removeStyleClass("toggled-on");
|
| + },
|
| +
|
| + attach: function()
|
| + {
|
| + if (!this.element.parentNode)
|
| + document.getElementById("main-panels").appendChild(this.element);
|
| + },
|
| +
|
| + searchCanceled: function(startingNewSearch)
|
| + {
|
| + if (this._searchResults) {
|
| + for (var i = 0; i < this._searchResults.length; ++i) {
|
| + var view = this._searchResults[i];
|
| + if (view.searchCanceled)
|
| + view.searchCanceled();
|
| + delete view.currentQuery;
|
| + }
|
| + }
|
| +
|
| + WebInspector.updateSearchMatchesCount(0, this);
|
| +
|
| + if (this._currentSearchChunkIntervalIdentifier) {
|
| + clearInterval(this._currentSearchChunkIntervalIdentifier);
|
| + delete this._currentSearchChunkIntervalIdentifier;
|
| + }
|
| +
|
| + this._totalSearchMatches = 0;
|
| + this._currentSearchResultIndex = 0;
|
| + this._searchResults = [];
|
| + },
|
| +
|
| + performSearch: function(query)
|
| + {
|
| + // Call searchCanceled since it will reset everything we need before doing a new search.
|
| + this.searchCanceled(true);
|
| +
|
| + var searchableViews = this.searchableViews;
|
| + if (!searchableViews || !searchableViews.length)
|
| + return;
|
| +
|
| + var parentElement = this.viewsContainerElement;
|
| + var visibleView = this.visibleView;
|
| + var sortFuction = this.searchResultsSortFunction;
|
| +
|
| + var matchesCountUpdateTimeout = null;
|
| +
|
| + function updateMatchesCount()
|
| + {
|
| + WebInspector.updateSearchMatchesCount(this._totalSearchMatches, this);
|
| + matchesCountUpdateTimeout = null;
|
| + }
|
| +
|
| + function updateMatchesCountSoon()
|
| + {
|
| + if (matchesCountUpdateTimeout)
|
| + return;
|
| + // Update the matches count every half-second so it doesn't feel twitchy.
|
| + matchesCountUpdateTimeout = setTimeout(updateMatchesCount.bind(this), 500);
|
| + }
|
| +
|
| + function finishedCallback(view, searchMatches)
|
| + {
|
| + if (!searchMatches)
|
| + return;
|
| +
|
| + this._totalSearchMatches += searchMatches;
|
| + this._searchResults.push(view);
|
| +
|
| + if (sortFuction)
|
| + this._searchResults.sort(sortFuction);
|
| +
|
| + if (this.searchMatchFound)
|
| + this.searchMatchFound(view, searchMatches);
|
| +
|
| + updateMatchesCountSoon.call(this);
|
| +
|
| + if (view === visibleView)
|
| + view.jumpToFirstSearchResult();
|
| + }
|
| +
|
| + var i = 0;
|
| + var panel = this;
|
| + var boundFinishedCallback = finishedCallback.bind(this);
|
| + var chunkIntervalIdentifier = null;
|
| +
|
| + // Split up the work into chunks so we don't block the
|
| + // UI thread while processing.
|
| +
|
| + function processChunk()
|
| + {
|
| + var view = searchableViews[i];
|
| +
|
| + if (++i >= searchableViews.length) {
|
| + if (panel._currentSearchChunkIntervalIdentifier === chunkIntervalIdentifier)
|
| + delete panel._currentSearchChunkIntervalIdentifier;
|
| + clearInterval(chunkIntervalIdentifier);
|
| + }
|
| +
|
| + if (!view)
|
| + return;
|
| +
|
| + if (view.element.parentNode !== parentElement && view.element.parentNode && parentElement)
|
| + view.detach();
|
| +
|
| + view.currentQuery = query;
|
| + view.performSearch(query, boundFinishedCallback);
|
| + }
|
| +
|
| + processChunk();
|
| +
|
| + chunkIntervalIdentifier = setInterval(processChunk, 25);
|
| + this._currentSearchChunkIntervalIdentifier = chunkIntervalIdentifier;
|
| + },
|
| +
|
| + jumpToNextSearchResult: function()
|
| + {
|
| + if (!this.showView || !this._searchResults || !this._searchResults.length)
|
| + return;
|
| +
|
| + var showFirstResult = false;
|
| +
|
| + this._currentSearchResultIndex = this._searchResults.indexOf(this.visibleView);
|
| + if (this._currentSearchResultIndex === -1) {
|
| + this._currentSearchResultIndex = 0;
|
| + showFirstResult = true;
|
| + }
|
| +
|
| + var currentView = this._searchResults[this._currentSearchResultIndex];
|
| +
|
| + if (currentView.showingLastSearchResult()) {
|
| + if (++this._currentSearchResultIndex >= this._searchResults.length)
|
| + this._currentSearchResultIndex = 0;
|
| + currentView = this._searchResults[this._currentSearchResultIndex];
|
| + showFirstResult = true;
|
| + }
|
| +
|
| + if (currentView !== this.visibleView)
|
| + this.showView(currentView);
|
| +
|
| + if (showFirstResult)
|
| + currentView.jumpToFirstSearchResult();
|
| + else
|
| + currentView.jumpToNextSearchResult();
|
| + },
|
| +
|
| + jumpToPreviousSearchResult: function()
|
| + {
|
| + if (!this.showView || !this._searchResults || !this._searchResults.length)
|
| + return;
|
| +
|
| + var showLastResult = false;
|
| +
|
| + this._currentSearchResultIndex = this._searchResults.indexOf(this.visibleView);
|
| + if (this._currentSearchResultIndex === -1) {
|
| + this._currentSearchResultIndex = 0;
|
| + showLastResult = true;
|
| + }
|
| +
|
| + var currentView = this._searchResults[this._currentSearchResultIndex];
|
| +
|
| + if (currentView.showingFirstSearchResult()) {
|
| + if (--this._currentSearchResultIndex < 0)
|
| + this._currentSearchResultIndex = (this._searchResults.length - 1);
|
| + currentView = this._searchResults[this._currentSearchResultIndex];
|
| + showLastResult = true;
|
| + }
|
| +
|
| + if (currentView !== this.visibleView)
|
| + this.showView(currentView);
|
| +
|
| + if (showLastResult)
|
| + currentView.jumpToLastSearchResult();
|
| + else
|
| + currentView.jumpToPreviousSearchResult();
|
| + },
|
| +
|
| + handleKeyEvent: function(event)
|
| + {
|
| + this.sidebarTree.handleKeyEvent(event);
|
| + },
|
| +
|
| + _createSidebar: function()
|
| + {
|
| + this.sidebarElement = document.createElement("div");
|
| + this.sidebarElement.className = "sidebar";
|
| + this.element.appendChild(this.sidebarElement);
|
| +
|
| + this.sidebarResizeElement = document.createElement("div");
|
| + this.sidebarResizeElement.className = "sidebar-resizer-vertical";
|
| + this.sidebarResizeElement.addEventListener("mousedown", this._startSidebarDragging.bind(this), false);
|
| + this.element.appendChild(this.sidebarResizeElement);
|
| +
|
| + this.sidebarTreeElement = document.createElement("ol");
|
| + this.sidebarTreeElement.className = "sidebar-tree";
|
| + this.sidebarElement.appendChild(this.sidebarTreeElement);
|
| + this.sidebarTree = new TreeOutline(this.sidebarTreeElement);
|
| + },
|
| +
|
| + _startSidebarDragging: function(event)
|
| + {
|
| + WebInspector.elementDragStart(this.sidebarResizeElement, this._sidebarDragging.bind(this), this._endSidebarDragging.bind(this), event, "col-resize");
|
| + },
|
| +
|
| + _sidebarDragging: function(event)
|
| + {
|
| + this._updateSidebarWidth(event.pageX);
|
| +
|
| + event.preventDefault();
|
| + },
|
| +
|
| + _endSidebarDragging: function(event)
|
| + {
|
| + WebInspector.elementDragEnd(event);
|
| + },
|
| +
|
| + _updateSidebarWidth: function(width)
|
| + {
|
| + if (this.sidebarElement.offsetWidth <= 0) {
|
| + // The stylesheet hasn't loaded yet or the window is closed,
|
| + // so we can't calculate what is need. Return early.
|
| + return;
|
| + }
|
| +
|
| + if (!("_currentSidebarWidth" in this))
|
| + this._currentSidebarWidth = this.sidebarElement.offsetWidth;
|
| +
|
| + if (typeof width === "undefined")
|
| + width = this._currentSidebarWidth;
|
| +
|
| + width = Number.constrain(width, Preferences.minSidebarWidth, window.innerWidth / 2);
|
| +
|
| + this._currentSidebarWidth = width;
|
| +
|
| + this.sidebarElement.style.width = width + "px";
|
| + this.setMainViewWidth(width);
|
| + this.sidebarResizeElement.style.left = (width - 3) + "px";
|
| +
|
| + var visibleView = this.visibleView;
|
| + if (visibleView && "resize" in visibleView)
|
| + visibleView.resize();
|
| + },
|
| +
|
| + setMainViewWidth: function(width)
|
| + {
|
| + // Should be implemented by ancestors.
|
| + }
|
| +}
|
| +
|
| +WebInspector.Panel.prototype.__proto__ = WebInspector.View.prototype;
|
|
|
| Property changes on: chrome/resources/inspector/Panel.js
|
| ___________________________________________________________________
|
| Added: svn:executable
|
| + *
|
|
|
|
|