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 |
+ * |