Diff
Modified: trunk/Source/WebCore/ChangeLog (97266 => 97267)
--- trunk/Source/WebCore/ChangeLog 2011-10-12 16:07:26 UTC (rev 97266)
+++ trunk/Source/WebCore/ChangeLog 2011-10-12 16:24:01 UTC (rev 97267)
@@ -1,5 +1,51 @@
2011-10-12 Vsevolod Vlasov <[email protected]>
+ Web Inspector: Searching in multiple scripts in the scripts tab
+ https://bugs.webkit.org/show_bug.cgi?id=38807
+
+ Reviewed by Pavel Feldman.
+
+ Added support for advanced search capabilities in inspector by means
+ of showing the new SearchView in Drawer. Advanced search is activated
+ with Ctrl+Shift+F (Cmd+Shift+F) shortcut.
+
+ * English.lproj/localizedStrings.js:
+ * WebCore.gypi:
+ * WebCore.vcproj/WebCore.vcproj:
+ * inspector/compile-front-end.sh:
+ * inspector/front-end/AdvancedSearchController.js: Added.
+ * inspector/front-end/DebuggerPresentationModel.js:
+ (WebInspector.DebuggerPresentationModel.prototype.uiSourceCodes):
+ * inspector/front-end/ScriptsPanel.js:
+ * inspector/front-end/ScriptsSearchScope.js: Added.
+ * inspector/front-end/UISourceCode.js:
+ (WebInspector.UISourceCode.prototype.searchInContent):
+ * inspector/front-end/WebKit.qrc:
+ * inspector/front-end/externs.js:
+ (WebInspector.showViewInDrawer):
+ * inspector/front-end/inspector.css:
+ (.search-view):
+ (.search-view .search-panel):
+ (.search-view .search-results):
+ (#search-results-pane-file-based .search-result):
+ (#search-results-pane-file-based .search-result:first-child):
+ (#search-results-pane-file-based .search-result .search-result-file-name):
+ (#search-results-pane-file-based .search-result .search-result-matches-count):
+ (#search-results-pane-file-based .search-match):
+ (#search-results-pane-file-based .search-match .webkit-line-number.search-match-line-number):
+ (#search-results-pane-file-based .search-match:not(:hover) .webkit-line-number.search-match-line-number):
+ (#search-results-pane-file-based .search-match:hover):
+ (#search-results-pane-file-based .search-match .highlighted-match):
+ (#search-results-pane-file-based a):
+ (#search-results-pane-file-based .search-match .search-match-content):
+ * inspector/front-end/inspector.html:
+ * inspector/front-end/inspector.js:
+ (WebInspector.documentKeyDown):
+ * inspector/front-end/utilities.js:
+ ():
+
+2011-10-12 Vsevolod Vlasov <[email protected]>
+
Web Inspector: Fix Drawer to make it possible to show views other than Console.
https://bugs.webkit.org/show_bug.cgi?id=69831
Modified: trunk/Source/WebCore/English.lproj/localizedStrings.js
(Binary files differ)
Modified: trunk/Source/WebCore/WebCore.gypi (97266 => 97267)
--- trunk/Source/WebCore/WebCore.gypi 2011-10-12 16:07:26 UTC (rev 97266)
+++ trunk/Source/WebCore/WebCore.gypi 2011-10-12 16:24:01 UTC (rev 97267)
@@ -6228,6 +6228,7 @@
],
'webinspector_files': [
'inspector/front-end/inspector.html',
+ 'inspector/front-end/AdvancedSearchController.js',
'inspector/front-end/ApplicationCacheItemsView.js',
'inspector/front-end/AuditCategories.js',
'inspector/front-end/AuditFormatters.js',
@@ -6334,6 +6335,7 @@
'inspector/front-end/ScriptFormatter.js',
'inspector/front-end/ScriptFormatterWorker.js',
'inspector/front-end/ScriptsPanel.js',
+ 'inspector/front-end/ScriptsSearchScope.js',
'inspector/front-end/SearchController.js',
'inspector/front-end/ShortcutsScreen.js',
'inspector/front-end/SettingsScreen.js',
Modified: trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj (97266 => 97267)
--- trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj 2011-10-12 16:07:26 UTC (rev 97266)
+++ trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj 2011-10-12 16:24:01 UTC (rev 97267)
@@ -69285,6 +69285,10 @@
Name="front-end"
>
<File
+ RelativePath="..\inspector\front-end\AdvancedSearchController.js"
+ >
+ </File>
+ <File
RelativePath="..\inspector\front-end\ApplicationCacheItemsView.js"
>
</File>
@@ -69769,6 +69773,10 @@
>
</File>
<File
+ RelativePath="..\inspector\front-end\ScriptsSearchScope.js"
+ >
+ </File>
+ <File
RelativePath="..\inspector\front-end\SearchController.js"
>
</File>
Modified: trunk/Source/WebCore/inspector/compile-front-end.sh (97266 => 97267)
--- trunk/Source/WebCore/inspector/compile-front-end.sh 2011-10-12 16:07:26 UTC (rev 97266)
+++ trunk/Source/WebCore/inspector/compile-front-end.sh 2011-10-12 16:24:01 UTC (rev 97267)
@@ -72,7 +72,8 @@
--js Source/WebCore/inspector/front-end/Resource.js \
--js Source/WebCore/inspector/front-end/NetworkManager.js \
--js Source/WebCore/inspector/front-end/UISourceCode.js \
- --module jsmodule_ui:34:jsmodule_common \
+ --module jsmodule_ui:35:jsmodule_common \
+ --js Source/WebCore/inspector/front-end/AdvancedSearchController.js \
--js Source/WebCore/inspector/front-end/Checkbox.js \
--js Source/WebCore/inspector/front-end/Color.js \
--js Source/WebCore/inspector/front-end/ContextMenu.js \
@@ -147,11 +148,12 @@
--js Source/WebCore/inspector/front-end/DatabaseTableView.js \
--js Source/WebCore/inspector/front-end/DOMStorageItemsView.js \
--js Source/WebCore/inspector/front-end/ResourcesPanel.js \
- --module jsmodule_scripts:7:jsmodule_components \
+ --module jsmodule_scripts:8:jsmodule_components \
--js Source/WebCore/inspector/front-end/CallStackSidebarPane.js \
--js Source/WebCore/inspector/front-end/ScopeChainSidebarPane.js \
--js Source/WebCore/inspector/front-end/_javascript_SourceFrame.js \
--js Source/WebCore/inspector/front-end/ScriptsPanel.js \
+ --js Source/WebCore/inspector/front-end/ScriptsSearchScope.js \
--js Source/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js \
--js Source/WebCore/inspector/front-end/WorkerManager.js \
--js Source/WebCore/inspector/front-end/WorkersSidebarPane.js \
Added: trunk/Source/WebCore/inspector/front-end/AdvancedSearchController.js (0 => 97267)
--- trunk/Source/WebCore/inspector/front-end/AdvancedSearchController.js (rev 0)
+++ trunk/Source/WebCore/inspector/front-end/AdvancedSearchController.js 2011-10-12 16:24:01 UTC (rev 97267)
@@ -0,0 +1,434 @@
+/*
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. 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 GOOGLE INC.
+ * 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.AdvancedSearchController = function()
+{
+ this._shortcut = WebInspector.AdvancedSearchController.createShortcut();
+ this._searchId = 0;
+
+ WebInspector.settings.advancedSearchConfig = WebInspector.settings.createSetting("advancedSearchConfig", new WebInspector.SearchConfig("", true, false));
+}
+
+WebInspector.AdvancedSearchController.createShortcut = function()
+{
+ return WebInspector.KeyboardShortcut.makeDescriptor("f", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta | WebInspector.KeyboardShortcut.Modifiers.Shift);
+}
+
+WebInspector.AdvancedSearchController.prototype = {
+ /**
+ * @param {Event} event
+ */
+ handleShortcut: function(event)
+ {
+ if (WebInspector.KeyboardShortcut.makeKeyFromEvent(event) === this._shortcut.key) {
+ this.show();
+ event.handled = true;
+ }
+ },
+
+ /**
+ * @param {WebInspector.SearchScope} searchScope
+ */
+ registerSearchScope: function(searchScope)
+ {
+ // FIXME: implement multiple search scopes.
+ this._searchScope = searchScope;
+ },
+
+ show: function()
+ {
+ if (!this._searchView)
+ this._searchView = new WebInspector.SearchView(this);
+
+ if (this._searchView.visible)
+ this._searchView.focus();
+ else
+ WebInspector.showViewInDrawer(this._searchView);
+ },
+
+ /**
+ * @param {number} searchId
+ * @param {Object} searchResult
+ */
+ _onSearchResult: function(searchId, searchResult)
+ {
+ if (searchId !== this._searchId)
+ return;
+
+ if (!this._searchResultsPane)
+ this._searchResultsPane = this._currentSearchScope.createSearchResultsPane(this._searchConfig);
+ this._searchView.resultsPane = this._searchResultsPane;
+ this._searchResultsPane.addSearchResult(searchResult);
+ },
+
+ /**
+ * @param {number} searchId
+ */
+ _onSearchFinished: function(searchId)
+ {
+ if (searchId !== this._searchId)
+ return;
+
+ if (!this._searchResultsPane)
+ this._searchView.nothingFound();
+
+ this._searchView.searchFinished();
+ },
+
+ /**
+ * @param {WebInspector.SearchConfig} searchConfig
+ */
+ startSearch: function(searchConfig)
+ {
+ this.stopSearch();
+
+ this._searchConfig = searchConfig;
+ // FIXME: this._currentSearchScope should be initialized based on searchConfig
+ this._currentSearchScope = this._searchScope;
+
+ this._searchView.searchStarted();
+ this._currentSearchScope.performSearch(searchConfig, this._onSearchResult.bind(this, this._searchId), this._onSearchFinished.bind(this, this._searchId));
+ },
+
+ stopSearch: function()
+ {
+ ++this._searchId;
+ delete this._searchResultsPane;
+ if (this._currentSearchScope)
+ this._currentSearchScope.stopSearch();
+ }
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.View}
+ * @param {WebInspector.AdvancedSearchController} controller
+ */
+WebInspector.SearchView = function(controller)
+{
+ WebInspector.View.call(this);
+
+ this._controller = controller;
+
+ this.element = document.createElement("div");
+ this.element.className = "search-view";
+
+ this._searchPanelElement = this.element.createChild("div");
+ this._searchPanelElement.tabIndex = 0;
+ this._searchPanelElement.className = "search-panel";
+ this._searchPanelElement.addEventListener("keydown", this._onKeyDown.bind(this), false);
+
+ this._searchResultsElement = this.element.createChild("div");
+ this._searchResultsElement.className = "search-results";
+
+ this._search = this._searchPanelElement.createChild("input");
+ this._search.setAttribute("type", "search");
+ this._search.setAttribute("results", "0");
+ this._search.setAttribute("size", 20);
+
+ this._load();
+}
+
+// Number of recent search queries to store.
+WebInspector.SearchView.maxQueriesCount = 20;
+
+WebInspector.SearchView.prototype = {
+ /**
+ * @type {WebInspector.SearchConfig}
+ */
+ get searchConfig()
+ {
+ var searchConfig = {};
+ searchConfig.query = this._search.value;
+ return searchConfig;
+ },
+
+ /**
+ * @type {WebInspector.SearchResultsPane}
+ */
+ set resultsPane(resultsPane)
+ {
+ this._searchResultsElement.removeChildren();
+ this._searchResultsElement.appendChild(resultsPane.element);
+ },
+
+ searchStarted: function()
+ {
+ // FIXME: This needs better UI.
+ var searchingView = new WebInspector.EmptyView(WebInspector.UIString("Searching..."))
+ this._searchResultsElement.removeChildren();
+ searchingView.show(this._searchResultsElement);
+ },
+
+ nothingFound: function()
+ {
+ // FIXME: This needs better UI.
+ var notFoundView = new WebInspector.EmptyView(WebInspector.UIString("Nothing found"))
+ this._searchResultsElement.removeChildren();
+ notFoundView.show(this._searchResultsElement);
+ },
+
+ searchFinished: function()
+ {
+ // FIXME: add message to drawer status bar
+ },
+
+ focus: function()
+ {
+ WebInspector.currentFocusElement = this._search;
+ this._search.select();
+ },
+
+ wasShown: function()
+ {
+ this.focus();
+ },
+
+ wasHidden: function()
+ {
+ this._controller.stopSearch();
+ },
+
+ /**
+ * @param {Event} event
+ */
+ _onKeyDown: function(event)
+ {
+ if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Enter.code)
+ this._onAction();
+ },
+
+ _save: function()
+ {
+ var searchConfig = new WebInspector.SearchConfig(this.searchConfig.query, this.searchConfig.ignoreCase, this.searchConfig.isRegex);
+ WebInspector.settings.advancedSearchConfig.set(searchConfig);
+ },
+
+ _load: function()
+ {
+ var searchConfig = WebInspector.settings.advancedSearchConfig.get();
+ this._search.value = searchConfig.query;
+ },
+
+ _onAction: function()
+ {
+ this._save();
+ this._controller.startSearch(this.searchConfig);
+ }
+}
+
+WebInspector.SearchView.prototype.__proto__ = WebInspector.View.prototype;
+
+/**
+ * @constructor
+ * @param {string} query
+ * @param {boolean} ignoreCase
+ * @param {boolean} isRegex
+ */
+WebInspector.SearchConfig = function(query, ignoreCase, isRegex)
+{
+ this.query = query;
+ this.ignoreCase = ignoreCase;
+ this.isRegex = isRegex;
+}
+
+/**
+ * @interface
+ */
+WebInspector.SearchScope = function()
+{
+}
+
+WebInspector.SearchScope.prototype = {
+ /**
+ * @param {WebInspector.SearchConfig} searchConfig
+ */
+ performSearch: function(searchConfig, searchResultCallback, searchFinishedCallback) { },
+
+ stopSearch: function() { },
+
+ /**
+ * @return WebInspector.SearchResultsPane}
+ */
+ createSearchResultsPane: function() { }
+}
+
+/**
+ * @constructor
+ * @param {WebInspector.SearchConfig} searchConfig
+ */
+WebInspector.SearchResultsPane = function(searchConfig)
+{
+ this._searchConfig = searchConfig;
+ this.element = document.createElement("div");
+}
+
+WebInspector.SearchResultsPane.prototype = {
+ /**
+ * @type {WebInspector.SearchConfig}
+ */
+ get searchConfig()
+ {
+ return this._searchConfig;
+ },
+
+ /**
+ * @param {Object} searchResult
+ */
+ addSearchResult: function(searchResult) { }
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.SearchResultsPane}
+ * @param {WebInspector.SearchConfig} searchConfig
+ */
+WebInspector.FileBasedSearchResultsPane = function(searchConfig)
+{
+ WebInspector.SearchResultsPane.call(this, searchConfig);
+
+ this._searchResults = [];
+
+ this.element.id ="search-results-pane-file-based";
+
+ this._treeOutlineElement = document.createElement("ol");
+ this._treeOutlineElement.className = "outline-disclosure";
+ this.element.appendChild(this._treeOutlineElement);
+ this._treeOutline = new TreeOutline(this._treeOutlineElement);
+}
+
+WebInspector.FileBasedSearchResultsPane.prototype = {
+ /**
+ * @param {Object} file
+ * @param {number} lineNumber
+ * @return {Element}
+ */
+ createAnchor: function(file, lineNumber) { },
+
+ /**
+ * @param {Object} file
+ * @return {string}
+ */
+ fileName: function(file) { },
+
+ /**
+ * @param {Object} searchResult
+ */
+ addSearchResult: function(searchResult)
+ {
+ this._searchResults.push(searchResult);
+ var file = searchResult.file;
+ var fileName = this.fileName(file);
+ var searchMatches = searchResult.searchMatches;
+
+ // Expand first file with matches only.
+ var fileTreeElement = this._addFileTreeElement(fileName, searchMatches.length, this._searchResults.length === 1);
+
+ var regexObject = createSearchRegex(this._searchConfig.query, "g");
+ for (var i = 0; i < searchMatches.length; i++) {
+ var lineNumber = searchMatches[i].lineNumber;
+
+ var anchor = this.createAnchor(file, lineNumber);
+
+ var numberString = numberToStringWithSpacesPadding(lineNumber + 1, 4);
+ var lineNumberSpan = document.createElement("span");
+ lineNumberSpan.addStyleClass("webkit-line-number");
+ lineNumberSpan.addStyleClass("search-match-line-number");
+ lineNumberSpan.textContent = numberString;
+ anchor.appendChild(lineNumberSpan);
+
+ var contentSpan = this._createContentSpan(searchMatches[i].lineContent, regexObject);
+ anchor.appendChild(contentSpan);
+
+ var searchMatchElement = new TreeElement("", null, false);
+ fileTreeElement.appendChild(searchMatchElement);
+ searchMatchElement.listItemElement.className = "search-match";
+ searchMatchElement.listItemElement.appendChild(anchor);
+ }
+ },
+
+ /**
+ * @param {string} fileName
+ * @param {number} searchMatchesCount
+ * @param {boolean} expanded
+ */
+ _addFileTreeElement: function(fileName, searchMatchesCount, expanded)
+ {
+ var fileTreeElement = new TreeElement("", null, true);
+ fileTreeElement.expanded = expanded;
+ fileTreeElement.toggleOnClick = true;
+ fileTreeElement.selectable = false;
+
+ this._treeOutline.appendChild(fileTreeElement);
+ fileTreeElement.listItemElement.addStyleClass("search-result");
+
+ var fileNameSpan = document.createElement("span");
+ fileNameSpan.className = "search-result-file-name";
+ fileNameSpan.textContent = fileName;
+ fileTreeElement.listItemElement.appendChild(fileNameSpan);
+
+ var matchesCountSpan = document.createElement("span");
+ matchesCountSpan.className = "search-result-matches-count";
+ if (searchMatchesCount === 1)
+ matchesCountSpan.textContent = WebInspector.UIString("(%d match)", searchMatchesCount);
+ else
+ matchesCountSpan.textContent = WebInspector.UIString("(%d matches)", searchMatchesCount);
+
+ fileTreeElement.listItemElement.appendChild(matchesCountSpan);
+
+ return fileTreeElement;
+ },
+
+ /**
+ * @param {string} lineContent
+ * @param {RegExp} regexObject
+ */
+ _createContentSpan: function(lineContent, regexObject)
+ {
+ var contentSpan = document.createElement("span");
+ contentSpan.className = "search-match-content";
+ contentSpan.textContent = lineContent;
+
+ regexObject.lastIndex = 0;
+ var match = regexObject.exec(lineContent);
+ var offset = 0;
+ var matchRanges = [];
+ while (match) {
+ matchRanges.push({ offset: match.index, length: match[0].length });
+ match = regexObject.exec(lineContent);
+ }
+ highlightRangesWithStyleClass(contentSpan, matchRanges, "highlighted-match");
+
+ return contentSpan;
+ }
+}
+
+WebInspector.FileBasedSearchResultsPane.prototype.__proto__ = WebInspector.SearchResultsPane.prototype;
Property changes on: trunk/Source/WebCore/inspector/front-end/AdvancedSearchController.js
___________________________________________________________________
Added: svn:eol-style
Modified: trunk/Source/WebCore/inspector/front-end/DebuggerPresentationModel.js (97266 => 97267)
--- trunk/Source/WebCore/inspector/front-end/DebuggerPresentationModel.js 2011-10-12 16:07:26 UTC (rev 97266)
+++ trunk/Source/WebCore/inspector/front-end/DebuggerPresentationModel.js 2011-10-12 16:24:01 UTC (rev 97267)
@@ -146,6 +146,20 @@
},
/**
+ * @return {Array.<WebInspector.UISourceCode>}
+ */
+ uiSourceCodes: function()
+ {
+ var result = [];
+ for (var id in this._rawSourceCode) {
+ var uiSourceCodeList = this._rawSourceCode[id].sourceMapping.uiSourceCodeList();
+ for (var i = 0; i < uiSourceCodeList.length; ++i)
+ result.push(uiSourceCodeList[i]);
+ }
+ return result;
+ },
+
+ /**
* @param {WebInspector.RawSourceCode} rawSourceCode
* @param {WebInspector.RawSourceCode.SourceMapping} oldSourceMapping
*/
Modified: trunk/Source/WebCore/inspector/front-end/ScriptsPanel.js (97266 => 97267)
--- trunk/Source/WebCore/inspector/front-end/ScriptsPanel.js 2011-10-12 16:07:26 UTC (rev 97266)
+++ trunk/Source/WebCore/inspector/front-end/ScriptsPanel.js 2011-10-12 16:24:01 UTC (rev 97267)
@@ -186,6 +186,8 @@
WebInspector.debuggerModel.enableDebugger();
WebInspector.settings.showScriptFolders.addChangeListener(this._showScriptFoldersSettingChanged.bind(this));
+
+ WebInspector.advancedSearchController.registerSearchScope(new WebInspector.ScriptsSearchScope());
}
// Keep these in sync with WebCore::ScriptDebugServer
Added: trunk/Source/WebCore/inspector/front-end/ScriptsSearchScope.js (0 => 97267)
--- trunk/Source/WebCore/inspector/front-end/ScriptsSearchScope.js (rev 0)
+++ trunk/Source/WebCore/inspector/front-end/ScriptsSearchScope.js 2011-10-12 16:24:01 UTC (rev 97267)
@@ -0,0 +1,159 @@
+/*
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. 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 GOOGLE INC.
+ * 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
+ * @implements {WebInspector.SearchScope}
+ */
+WebInspector.ScriptsSearchScope = function()
+{
+ // FIXME: Add title once it is used by search controller.
+ WebInspector.SearchScope.call(this)
+}
+
+WebInspector.ScriptsSearchScope.prototype = {
+ /**
+ * @param {WebInspector.SearchConfig} searchConfig
+ * @param {function(Object)} searchResultCallback
+ * @param {function()} searchFinishedCallback
+ */
+ performSearch: function(searchConfig, searchResultCallback, searchFinishedCallback)
+ {
+ var callbacksLeft = 0;
+
+ function maybeSearchFinished()
+ {
+ if (callbacksLeft === 0)
+ searchFinishedCallback();
+ }
+
+ function searchCallbackWrapper(uiSourceCode, searchMatches)
+ {
+ if (searchMatches.length) {
+ var searchResult = {file: uiSourceCode, searchMatches: searchMatches};
+ searchResultCallback(searchResult);
+ }
+ --callbacksLeft;
+ maybeSearchFinished();
+ }
+
+ var uiSourceCodes = this._sortedUISourceCodes();
+ // FIXME: Enable support for counting matches for incremental search.
+ // FIXME: Enable support for bounding search results/matches number to keep inspector responsive.
+ for (var i = 0; i < uiSourceCodes.length; i++) {
+ var uiSourceCode = uiSourceCodes[i];
+ // FIXME: Add setting to search in content scripts as well.
+ if (!uiSourceCode.isContentScript) {
+ // Increase callbacksLeft first because searchInContent call could be synchronous.
+ callbacksLeft++;
+ // FIXME: We should not request next searchInContent unless previous one is already finished.
+ uiSourceCode.searchInContent(searchConfig.query, searchCallbackWrapper.bind(this, uiSourceCode));
+ }
+ }
+ maybeSearchFinished();
+ },
+
+ stopSearch: function()
+ {
+ // FIXME: Implement search so that it could be stopped.
+ },
+
+ /**
+ * @param {WebInspector.SearchConfig} searchConfig
+ */
+ createSearchResultsPane: function(searchConfig)
+ {
+ return new WebInspector.ScriptsSearchResultsPane(searchConfig);
+ },
+
+ /**
+ * @return {Array.<WebInspector.UISourceCode>}
+ */
+ _sortedUISourceCodes: function()
+ {
+ function filterOutAnonymous(uiSourceCode)
+ {
+ return !!uiSourceCode.url;
+ }
+
+ function comparator(a, b)
+ {
+ return a.url.localeCompare(b.url);
+ }
+
+ var uiSourceCodes = WebInspector.debuggerPresentationModel.uiSourceCodes();
+
+ uiSourceCodes = uiSourceCodes.filter(filterOutAnonymous);
+ uiSourceCodes.sort(comparator);
+
+ return uiSourceCodes;
+ }
+}
+
+WebInspector.ScriptsSearchScope.prototype.__proto__ = WebInspector.SearchScope.prototype;
+
+/**
+ * @constructor
+ * @extends {WebInspector.FileBasedSearchResultsPane}
+ * @param {WebInspector.SearchConfig} searchConfig
+ */
+WebInspector.ScriptsSearchResultsPane = function(searchConfig)
+{
+ WebInspector.FileBasedSearchResultsPane.call(this, searchConfig)
+}
+
+WebInspector.ScriptsSearchResultsPane.prototype = {
+ /**
+ * @param {Object} file
+ * @param {number} lineNumber
+ */
+ createAnchor: function(file, lineNumber)
+ {
+ var uiSourceCode = file;
+
+ var anchor = WebInspector.linkifyURLAsNode(uiSourceCode.url, "");
+ anchor.setAttribute("preferred_panel", "scripts");
+ anchor.uiSourceCode = uiSourceCode;
+ anchor.lineNumber = lineNumber;
+ anchor.removeChildren();
+
+ return anchor;
+ },
+
+ /**
+ * @param {Object} file
+ * @return {string}
+ */
+ fileName: function(file)
+ {
+ var uiSourceCode = file;
+ return uiSourceCode.url;
+ },
+}
+
+WebInspector.ScriptsSearchResultsPane.prototype.__proto__ = WebInspector.FileBasedSearchResultsPane.prototype;
Property changes on: trunk/Source/WebCore/inspector/front-end/ScriptsSearchScope.js
___________________________________________________________________
Added: svn:eol-style
Modified: trunk/Source/WebCore/inspector/front-end/UISourceCode.js (97266 => 97267)
--- trunk/Source/WebCore/inspector/front-end/UISourceCode.js 2011-10-12 16:07:26 UTC (rev 97266)
+++ trunk/Source/WebCore/inspector/front-end/UISourceCode.js 2011-10-12 16:24:01 UTC (rev 97267)
@@ -113,6 +113,15 @@
},
/**
+ * @param {string} query
+ * @param {function(Array.<Object>)} callback
+ */
+ searchInContent: function(query, callback)
+ {
+ this._contentProvider.searchInContent(query, callback);
+ },
+
+ /**
* @param {string} mimeType
* @param {string} content
*/
Modified: trunk/Source/WebCore/inspector/front-end/WebKit.qrc (97266 => 97267)
--- trunk/Source/WebCore/inspector/front-end/WebKit.qrc 2011-10-12 16:07:26 UTC (rev 97266)
+++ trunk/Source/WebCore/inspector/front-end/WebKit.qrc 2011-10-12 16:24:01 UTC (rev 97267)
@@ -1,6 +1,7 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/webkit/inspector">
<file>inspector.html</file>
+ <file>AdvancedSearchController.js</file>
<file>ApplicationCacheItemsView.js</file>
<file>AuditCategories.js</file>
<file>AuditFormatters.js</file>
@@ -107,6 +108,7 @@
<file>ScriptFormatter.js</file>
<file>ScriptFormatterWorker.js</file>
<file>ScriptsPanel.js</file>
+ <file>ScriptsSearchScope.js</file>
<file>SearchController.js</file>
<file>Section.js</file>
<file>Settings.js</file>
Modified: trunk/Source/WebCore/inspector/front-end/externs.js (97266 => 97267)
--- trunk/Source/WebCore/inspector/front-end/externs.js 2011-10-12 16:07:26 UTC (rev 97266)
+++ trunk/Source/WebCore/inspector/front-end/externs.js 2011-10-12 16:24:01 UTC (rev 97267)
@@ -186,6 +186,16 @@
WebInspector.previousFocusElement = null;
/**
+ * @param {WebInspector.View} view
+ */
+WebInspector.showViewInDrawer = function(view) {}
+
+/**
+ * @type {WebInspector.AdvancedSearchController}
+ */
+WebInspector.advancedSearchController = null;
+
+/**
* @type {string}
*/
WebInspector.platformFlavor = "";
Modified: trunk/Source/WebCore/inspector/front-end/inspector.css (97266 => 97267)
--- trunk/Source/WebCore/inspector/front-end/inspector.css 2011-10-12 16:07:26 UTC (rev 97266)
+++ trunk/Source/WebCore/inspector/front-end/inspector.css 2011-10-12 16:24:01 UTC (rev 97267)
@@ -4113,3 +4113,91 @@
background-color: rgb(56, 121, 217);
color: white;
}
+
+.search-view {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+}
+
+.search-view .search-panel {
+ position: absolute;
+ top: 0;
+ height: 35px;
+ left: 0;
+ right: 0;
+ padding-top: 4px;
+ padding-left: 10px;
+ background-color: #EBEBEB;
+ border-bottom: 1px solid #BBB;
+
+ font-size: 11px;
+}
+
+.search-view .search-results {
+ position: absolute;
+ top: 35px;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ overflow-y: auto;
+
+ padding-bottom: 5px;
+}
+
+#search-results-pane-file-based .search-result {
+ font-size: 12px;
+ margin-top: 3px;
+}
+
+#search-results-pane-file-based .search-result:first-child {
+ margin-top: 1px;
+}
+
+
+#search-results-pane-file-based .search-result .search-result-file-name {
+ font-weight: bold;
+ color: #222;
+}
+
+#search-results-pane-file-based .search-result .search-result-matches-count {
+ margin-left: 5px;
+ color: #333;
+}
+
+#search-results-pane-file-based .search-match {
+ font-family: 'dejavu sans mono', monospace;
+ font-size: 11px;
+ word-wrap: normal;
+ white-space: pre;
+}
+
+#search-results-pane-file-based .search-match .webkit-line-number.search-match-line-number {
+ margin-right: 5px;
+ border-right: 1px solid #BBB;
+}
+
+#search-results-pane-file-based .search-match:not(:hover) .webkit-line-number.search-match-line-number {
+ background-color: #F0F0F0;
+}
+
+#search-results-pane-file-based .search-match:hover {
+ background-color: rgba(56, 121, 217, 0.1);
+ -webkit-border-radius: 5px;*/
+}
+
+#search-results-pane-file-based .search-match .highlighted-match {
+ background-color: #F1EA00;
+}
+
+#search-results-pane-file-based a {
+ text-decoration: none;
+ display: block;
+}
+
+#search-results-pane-file-based .search-match .search-match-content {
+ color: #000;
+ white-space: pre;
+}
Modified: trunk/Source/WebCore/inspector/front-end/inspector.html (97266 => 97267)
--- trunk/Source/WebCore/inspector/front-end/inspector.html 2011-10-12 16:07:26 UTC (rev 97266)
+++ trunk/Source/WebCore/inspector/front-end/inspector.html 2011-10-12 16:24:01 UTC (rev 97267)
@@ -65,6 +65,7 @@
<script type="text/_javascript_" src=""
<script type="text/_javascript_" src=""
<script type="text/_javascript_" src=""
+ <script type="text/_javascript_" src=""
<script type="text/_javascript_" src=""
<script type="text/_javascript_" src=""
<script type="text/_javascript_" src=""
@@ -114,6 +115,7 @@
<script type="text/_javascript_" src=""
<script type="text/_javascript_" src=""
<script type="text/_javascript_" src=""
+ <script type="text/_javascript_" src=""
<script type="text/_javascript_" src=""
<script type="text/_javascript_" src=""
<script type="text/_javascript_" src=""
Modified: trunk/Source/WebCore/inspector/front-end/inspector.js (97266 => 97267)
--- trunk/Source/WebCore/inspector/front-end/inspector.js 2011-10-12 16:07:26 UTC (rev 97266)
+++ trunk/Source/WebCore/inspector/front-end/inspector.js 2011-10-12 16:24:01 UTC (rev 97267)
@@ -479,6 +479,7 @@
this.cssModel = new WebInspector.CSSStyleModel();
this.searchController = new WebInspector.SearchController();
+ this.advancedSearchController = new WebInspector.AdvancedSearchController();
if (Preferences.nativeInstrumentationEnabled)
this.domBreakpointsSidebarPane = new WebInspector.DOMBreakpointsSidebarPane();
@@ -739,6 +740,7 @@
}
WebInspector.searchController.handleShortcut(event);
+ WebInspector.advancedSearchController.handleShortcut(event);
if (event.handled) {
event.preventDefault();
return;
Modified: trunk/Source/WebCore/inspector/front-end/utilities.js (97266 => 97267)
--- trunk/Source/WebCore/inspector/front-end/utilities.js 2011-10-12 16:07:26 UTC (rev 97266)
+++ trunk/Source/WebCore/inspector/front-end/utilities.js 2011-10-12 16:24:01 UTC (rev 97267)
@@ -837,6 +837,9 @@
}
/**
+ * @param {Element} element
+ * @param {number} offset
+ * @param {number} length
* @param {Array.<Object>=} domChanges
*/
function highlightSearchResult(element, offset, length, domChanges)
@@ -846,10 +849,24 @@
}
/**
+ * @param {Element} element
+ * @param {Array.<Object>} resultRanges
* @param {Array.<Object>=} changes
*/
function highlightSearchResults(element, resultRanges, changes)
{
+ return highlightRangesWithStyleClass(element, resultRanges, "webkit-search-result", changes);
+
+}
+
+/**
+ * @param {Element} element
+ * @param {Array.<Object>} resultRanges
+ * @param {string} styleClass
+ * @param {Array.<Object>=} changes
+ */
+function highlightRangesWithStyleClass(element, resultRanges, styleClass, changes)
+{
changes = changes || [];
var highlightNodes = [];
var lineText = element.textContent;
@@ -887,7 +904,7 @@
}
var highlightNode = ownerDocument.createElement("span");
- highlightNode.className = "webkit-search-result";
+ highlightNode.className = styleClass;
highlightNode.textContent = lineText.substring(startOffset, endOffset);
var text = textNode.textContent;
@@ -969,6 +986,7 @@
/**
* @param {string=} extraFlags
+ * @return {RegExp}
*/
function createSearchRegex(query, extraFlags)
{
@@ -984,6 +1002,11 @@
return new RegExp(regex, "i" + (extraFlags || ""));
}
+/**
+ * @param {RegExp} regex
+ * @param {string} content
+ * @return {number}
+ */
function countRegexMatches(regex, content)
{
var text = content;
@@ -998,6 +1021,19 @@
}
/**
+ * @param {number} value
+ * @param {number} symbolsCount
+ * @return {string}
+ */
+function numberToStringWithSpacesPadding(value, symbolsCount)
+{
+ var numberString = value.toString();
+ var paddingLength = Math.max(0, symbolsCount - numberString.length);
+ var paddingString = Array(paddingLength).join("\u00a0");
+ return paddingString + numberString;
+}
+
+/**
* @constructor
*/
function TextDiff()