Index: Source/devtools/front_end/console/ConsoleView.js |
diff --git a/Source/devtools/front_end/console/ConsoleView.js b/Source/devtools/front_end/console/ConsoleView.js |
index 41ea4f0530eb384215ace4ffd8beb1a3349ce30f..0f2314c62e4716c327be35868775a309f4eace18 100644 |
--- a/Source/devtools/front_end/console/ConsoleView.js |
+++ b/Source/devtools/front_end/console/ConsoleView.js |
@@ -39,7 +39,7 @@ WebInspector.ConsoleView = function() |
WebInspector.VBox.call(this); |
this.registerRequiredCSS("filter.css"); |
- this._searchableView = new WebInspector.SearchableView(this); |
+ this._searchableView = new WebInspector.SearchableView(this, true); |
this._searchableView.setMinimalSearchQuerySize(0); |
this._searchableView.show(this.element); |
@@ -574,7 +574,9 @@ WebInspector.ConsoleView.prototype = { |
this._visibleViewMessages.push(viewMessage); |
- if (this._searchRegex && viewMessage.matchesRegex(this._searchRegex)) { |
+ // TODO: Handle the regex search case |
+ if (!this._searchableView.enableRegex && this._searchRegex && |
+ viewMessage.matchesRegex(this._searchRegex)) { |
this._searchResults.push(viewMessage); |
this._searchableView.updateSearchMatchesCount(this._searchResults.length); |
} |
@@ -918,13 +920,100 @@ WebInspector.ConsoleView.prototype = { |
/** @type {!Array.<number>} */ |
this._searchResults = []; |
for (var i = 0; i < this._visibleViewMessages.length; i++) { |
- if (this._visibleViewMessages[i].matchesRegex(this._searchRegex)) |
+ if (this._visibleViewMessages[i].matchesRegex(this._searchRegex)) { |
this._searchResults.push(i); |
+ } |
} |
this._searchableView.updateSearchMatchesCount(this._searchResults.length); |
this._currentSearchResultIndex = -1; |
- if (shouldJump && this._searchResults.length) |
+ if (shouldJump && this._searchResults.length) { |
+ this._jumpToSearchResult(jumpBackwards ? -1 : 0); |
+ } |
+ this._viewport.refresh(); |
+ }, |
+ |
+ performRegexSearch: function(query, shouldJump, jumpBackwards) |
+ { |
+ this.searchCanceled(); |
+ this._searchableView.updateSearchMatchesCount(0); |
+ try { |
+ this._searchRegex = new RegExp(query, "gi"); |
+ } catch (e) { |
+ return; |
+ } |
+ |
+ this._searchResults = []; |
+ var messageRanges = []; |
+ var allText = ""; |
+ var textOffset = 0; |
+ for (var i = 0; i < this._visibleViewMessages.length; i++) { |
+ var currentText = this._visibleViewMessages[i].getText() + "\n"; |
+ allText += currentText; |
+ messageRanges.push({ |
+ start: textOffset, |
+ end: textOffset + currentText.length - 1, |
+ message: this._visibleViewMessages[i], |
+ messageIndex: i, |
+ }); |
+ textOffset += currentText.length; |
+ } |
+ var match = this._searchRegex.exec(allText); |
+ this._regexMatchRanges = []; |
+ while (match && match[0]) { |
+ this._regexMatchRanges.push({ |
+ start: match.index, |
+ end: match.index + match[0].length - 1, |
+ messageIndexes: [], |
+ messageRanges: [], |
+ }); |
+ match = this._searchRegex.exec(allText); |
+ } |
+ |
+ this._searchableView.updateSearchMatchesCount(this._regexMatchRanges.length); |
+ this._currentSearchResultIndex = -1; |
+ |
+ console.log('Matching'); |
+ // Per match range, find corresponding messages and have them highlight the match |
+ for (var i = 0; i < this._regexMatchRanges.length; ++i) { |
+ var matchRange = this._regexMatchRanges[i]; |
+ var matchStart = matchRange.start; |
+ var matchEnd = matchRange.end; |
+ for (var j = 0; j < messageRanges.length; ++j) { |
+ var messageRange = messageRanges[j]; |
+ var messageStart = messageRange.start; |
+ var messageEnd = messageRange.end; |
+ if ((messageStart <= matchStart && messageEnd >= matchStart) || |
+ (messageStart <= matchEnd && messageStart >= matchStart)) { |
+ console.log("Match " + i + " (" + matchStart + "," + matchEnd + ") matches message " + |
+ j + " (" + messageStart + ", " + messageEnd + ")"); |
+ var startWithinMsg; |
+ var endWithinMsg; |
+ if (matchStart > messageStart) { |
+ startWithinMsg = matchStart - messageStart; |
+ } else { |
+ startWithinMsg = 0; |
+ } |
+ if (matchEnd < messageEnd) { |
+ endWithinMsg = matchEnd - messageStart; |
+ } else { |
+ // Subtract the logical \n character from the message end position, since it's |
+ // not really part of the message |
+ endWithinMsg = messageEnd - 1; |
+ } |
+ |
+ messageRange.message.highlightMatch(startWithinMsg, endWithinMsg); |
+ this._searchResults.push(messageRange.messageIndex); |
+ matchRange.messageIndexes.push(messageRange.messageIndex); |
+ matchRange.messageRanges.push([startWithinMsg, endWithinMsg]); |
+ } |
+ } |
+ } |
+ // TODO: |
+ // 1. Jump to first matching message, and then to its matching element, which should be duly marked |
+ |
+ if (shouldJump && this._searchResults.length) { |
this._jumpToSearchResult(jumpBackwards ? -1 : 0); |
+ } |
this._viewport.refresh(); |
}, |
@@ -946,22 +1035,59 @@ WebInspector.ConsoleView.prototype = { |
{ |
if (!this._searchResults) |
return; |
- |
- var highlightedViewMessage = this._visibleViewMessages[this._searchResults[this._currentSearchResultIndex]]; |
- if (highlightedViewMessage) |
- highlightedViewMessage.clearHighlight(); |
- this._currentSearchResultIndex = -1; |
+ if (!this._searchableView.enableRegex) { |
+ var highlightedViewMessage = this._visibleViewMessages[this._searchResults[ |
+ this._currentSearchResultIndex]]; |
+ if (highlightedViewMessage) |
+ highlightedViewMessage.clearHighlight(); |
+ this._currentSearchResultIndex = -1; |
+ } else { |
+ for (var i = 0; i < this._searchResults.length; ++i) { |
+ this._visibleViewMessages[this._searchResults[i]].clearHighlight(); |
+ } |
+ } |
}, |
_jumpToSearchResult: function(index) |
{ |
- index = mod(index, this._searchResults.length); |
- this._clearCurrentSearchResultHighlight(); |
- this._currentSearchResultIndex = index; |
- this._searchableView.updateCurrentMatchIndex(this._currentSearchResultIndex); |
- var currentViewMessageIndex = this._searchResults[index]; |
- this._viewport.scrollItemIntoView(currentViewMessageIndex); |
- this._visibleViewMessages[currentViewMessageIndex].highlightSearchResults(this._searchRegex); |
+ if (!this._searchableView.enableRegex) { |
+ index = mod(index, this._searchResults.length); |
+ this._clearCurrentSearchResultHighlight(); |
+ this._currentSearchResultIndex = index; |
+ this._searchableView.updateCurrentMatchIndex(this._currentSearchResultIndex); |
+ var currentViewMessageIndex = this._searchResults[index]; |
+ this._viewport.scrollItemIntoView(currentViewMessageIndex); |
+ this._visibleViewMessages[currentViewMessageIndex].highlightSearchResults(this._searchRegex); |
+ } else { |
+ index = mod(index, this._regexMatchRanges.length); |
+ var matchRange; |
+ if (this._currentSearchResultIndex >= 0) { |
+ // Unmark current match range |
+ matchRange = this._regexMatchRanges[this._currentSearchResultIndex]; |
+ console.log("Unmarking current search result"); |
+ for (var i = 0; i < matchRange.messageIndexes.length; ++i) { |
+ var currentMessageIndex = matchRange.messageIndexes[i]; |
+ var message = this._visibleViewMessages[currentMessageIndex]; |
+ var start = matchRange.messageRanges[i][0]; |
+ var end = matchRange.messageRanges[i][1]; |
+ message.highlightMatch(start, end); |
+ } |
+ } |
+ this._currentSearchResultIndex = index; |
+ this._searchableView.updateCurrentMatchIndex(this._currentSearchResultIndex); |
+ matchRange = this._regexMatchRanges[this._currentSearchResultIndex]; |
+ console.log("Currently matched message indexes: " + matchRange.messageIndexes); |
+ this._viewport.scrollItemIntoView(matchRange.messageIndexes[0]); |
+ for (var i = 0; i < matchRange.messageIndexes.length; ++i) { |
+ var currentMessageIndex = matchRange.messageIndexes[i]; |
+ var message = this._visibleViewMessages[currentMessageIndex]; |
+ var start = matchRange.messageRanges[i][0]; |
+ var end = matchRange.messageRanges[i][1]; |
+ console.log("Highlighting range " + start + "," + end + " in message " + |
+ currentMessageIndex + " as part of the current match"); |
+ message.highlightMatch(start, end, true); |
+ } |
+ } |
}, |
__proto__: WebInspector.VBox.prototype |
@@ -1162,6 +1288,22 @@ WebInspector.ConsoleCommand.prototype = { |
this._formattedCommand.textContent = this.text; |
}, |
+ /** |
+ * @return {!string} |
+ */ |
+ getText: function() |
+ { |
+ return this.text; |
+ }, |
+ |
+ highlightMatch: function(start, end, isCurrent) |
+ { |
+ console.log("Highlighting from position " + start + " to " + end); |
+ WebInspector.highlightSearchResults(this._formattedCommand, |
+ [new WebInspector.SourceRange(start, end - start + 1)], undefined, isCurrent); |
+ this._element.scrollIntoViewIfNeeded(); |
+ }, |
+ |
__proto__: WebInspector.ConsoleViewMessage.prototype |
} |