Modified: trunk/Source/WebCore/inspector/front-end/TimelineOverviewPane.js (128280 => 128281)
--- trunk/Source/WebCore/inspector/front-end/TimelineOverviewPane.js 2012-09-12 09:17:25 UTC (rev 128280)
+++ trunk/Source/WebCore/inspector/front-end/TimelineOverviewPane.js 2012-09-12 09:32:39 UTC (rev 128281)
@@ -31,7 +31,6 @@
/**
* @constructor
* @extends {WebInspector.View}
- * @implements {WebInspector.TimelinePresentationModel.Filter}
* @param {WebInspector.TimelineModel} model
*/
WebInspector.TimelineOverviewPane = function(model)
@@ -274,14 +273,6 @@
this._update();
},
- /**
- * @param {WebInspector.TimelinePresentationModel.Record} record
- */
- accept: function(record)
- {
- return record.lastChildEndTime >= this._windowStartTime && record.startTime <= this._windowEndTime;
- },
-
windowStartTime: function()
{
return this._windowStartTime || this._model.minimumRecordTime();
@@ -1232,3 +1223,24 @@
}
WebInspector.TimelineFrameOverview.prototype.__proto__ = WebInspector.View.prototype;
+
+/**
+ * @param {WebInspector.TimelineOverviewPane} pane
+ * @constructor
+ * @implements {WebInspector.TimelinePresentationModel.Filter}
+ */
+WebInspector.TimelineWindowFilter = function(pane)
+{
+ this._pane = pane;
+}
+
+WebInspector.TimelineWindowFilter.prototype = {
+ /**
+ * @param {!WebInspector.TimelinePresentationModel.Record} record
+ * @return {boolean}
+ */
+ accept: function(record)
+ {
+ return record.lastChildEndTime >= this._pane._windowStartTime && record.startTime <= this._pane._windowEndTime;
+ }
+}
Modified: trunk/Source/WebCore/inspector/front-end/TimelinePanel.js (128280 => 128281)
--- trunk/Source/WebCore/inspector/front-end/TimelinePanel.js 2012-09-12 09:17:25 UTC (rev 128280)
+++ trunk/Source/WebCore/inspector/front-end/TimelinePanel.js 2012-09-12 09:32:39 UTC (rev 128281)
@@ -145,9 +145,9 @@
this._allRecordsCount = 0;
- this._presentationModel.addFilter(this._overviewPane);
+ this._presentationModel.addFilter(new WebInspector.TimelineWindowFilter(this._overviewPane));
this._presentationModel.addFilter(new WebInspector.TimelineCategoryFilter());
- this._presentationModel.addFilter(new WebInspector.TimelineIsLongFilter(this));
+ this._presentationModel.addFilter(new WebInspector.TimelineIsLongFilter(this));
}
// Define row height, should be in sync with styles for timeline graphs.
@@ -671,6 +671,7 @@
_invalidateAndScheduleRefresh: function(preserveBoundaries)
{
this._presentationModel.invalidateFilteredRecords();
+ delete this._searchResults;
this._scheduleRefresh(preserveBoundaries);
},
@@ -724,18 +725,19 @@
revealRecordAt: function(time)
{
- var recordsInWindow = this._presentationModel.filteredRecords();
var recordToReveal;
- for (var i = 0; i < recordsInWindow.length; ++i) {
- var record = recordsInWindow[i];
+ function findRecordToReveal(record)
+ {
if (record.containsTime(time)) {
recordToReveal = record;
- break;
+ return true;
}
// If there is no record containing the time than use the latest one before that time.
if (!recordToReveal || record.endTime < time && recordToReveal.endTime < record.endTime)
recordToReveal = record;
+ return false;
}
+ WebInspector.TimelinePresentationModel.forAllRecords(this._presentationModel.rootRecord().children, null, findRecordToReveal);
// The record ends before the window left bound so scroll to the top.
if (!recordToReveal) {
@@ -743,9 +745,21 @@
return;
}
+ this._revealRecord(recordToReveal);
+ },
+
+ _revealRecord: function(recordToReveal)
+ {
// Expand all ancestors.
- for (var parent = recordToReveal.parent; parent !== this._rootRecord(); parent = parent.parent)
+ var treeUpdated = false;
+ for (var parent = recordToReveal.parent; parent !== this._rootRecord(); parent = parent.parent) {
+ treeUpdated = treeUpdated || parent.collapsed;
parent.collapsed = false;
+ }
+ if (treeUpdated)
+ this._invalidateAndScheduleRefresh(true);
+
+ var recordsInWindow = this._presentationModel.filteredRecords();
var index = recordsInWindow.indexOf(recordToReveal);
this._containerElement.scrollTop = index * WebInspector.TimelinePanel.rowHeight;
},
@@ -832,6 +846,7 @@
this._itemsGraphsElement.insertBefore(this._graphRowsElement, this._bottomGapElement);
this._itemsGraphsElement.appendChild(this._expandElements);
this._adjustScrollPosition((recordsInWindow.length + this._headerLineCount) * rowHeight);
+ this._updateSearchHighlight(false);
return recordsInWindow.length;
},
@@ -1002,6 +1017,142 @@
style.textContent = Object.values(categories).map(WebInspector.TimelinePresentationModel.createStyleRuleForCategory).join("\n");
document.head.appendChild(style);
+ },
+
+ jumpToNextSearchResult: function()
+ {
+ this._jumpToAdjacentRecord(1);
+ },
+
+ jumpToPreviousSearchResult: function()
+ {
+ this._jumpToAdjacentRecord(-1);
+ },
+
+ _jumpToAdjacentRecord: function(offset)
+ {
+ if (!this._searchResults || !this._searchResults.length || !this._selectedSearchResult)
+ return;
+ var index = this._searchResults.indexOf(this._selectedSearchResult);
+ index = (index + offset + this._searchResults.length) % this._searchResults.length;
+ this._selectSearchResult(index);
+ this._highlightSelectedSearchResult(true);
+ },
+
+ _selectSearchResult: function(index)
+ {
+ this._selectedSearchResult = this._searchResults[index];
+ WebInspector.searchController.updateCurrentMatchIndex(index, this);
+ },
+
+ _highlightSelectedSearchResult: function(revealRecord)
+ {
+ this._clearHighlight();
+ if (this._searchFilter)
+ return;
+
+ var record = this._selectedSearchResult;
+ if (!record)
+ return;
+
+ for (var element = this._sidebarListElement.firstChild; element; element = element.nextSibling) {
+ if (element.row._record === record) {
+ element.row.highlight(this._searchRegExp, this._highlightDomChanges);
+ return;
+ }
+ }
+
+ if (revealRecord)
+ this._revealRecord(record);
+ },
+
+ _clearHighlight: function()
+ {
+ if (this._highlightDomChanges)
+ WebInspector.revertDomChanges(this._highlightDomChanges);
+ this._highlightDomChanges = [];
+ },
+
+ /**
+ * @param {boolean} revealRecord
+ */
+ _updateSearchHighlight: function(revealRecord)
+ {
+ if (this._searchFilter || !this._searchRegExp) {
+ this._clearHighlight();
+ return;
+ }
+
+ if (!this._searchResults)
+ this._updateSearchResults();
+
+ this._highlightSelectedSearchResult(revealRecord);
+ },
+
+ _updateSearchResults: function() {
+ var searchRegExp = this._searchRegExp;
+ if (!searchRegExp)
+ return;
+
+ var matches = [];
+ var presentationModel = this._presentationModel;
+
+ function processRecord(record)
+ {
+ if (presentationModel.isVisible(record) && WebInspector.TimelineRecordListRow.testContentMatching(record, searchRegExp))
+ matches.push(record);
+ return false;
+ }
+ WebInspector.TimelinePresentationModel.forAllRecords(presentationModel.rootRecord().children, processRecord);
+
+ var matchesCount = matches.length;
+ if (matchesCount) {
+ this._searchResults = matches;
+ WebInspector.searchController.updateSearchMatchesCount(matchesCount, this);
+
+ var selectedIndex = matches.indexOf(this._selectedSearchResult);
+ if (selectedIndex === -1)
+ selectedIndex = 0;
+ this._selectSearchResult(selectedIndex);
+ } else {
+ WebInspector.searchController.updateSearchMatchesCount(0, this);
+ delete this._selectedSearchResult;
+ }
+ },
+
+ searchCanceled: function()
+ {
+ this._clearHighlight();
+ delete this._searchResults;
+ delete this._selectedSearchResult;
+ delete this._searchRegExp;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ canFilter: function()
+ {
+ return true;
+ },
+
+ performFilter: function(searchQuery)
+ {
+ this._presentationModel.removeFilter(this._searchFilter);
+ delete this._searchFilter;
+ this.searchCanceled();
+ if (searchQuery) {
+ this._searchFilter = new WebInspector.TimelineSearchFilter(createPlainTextSearchRegex(searchQuery, "i"));
+ this._presentationModel.addFilter(this._searchFilter);
+ }
+ this._invalidateAndScheduleRefresh(true);
+ },
+
+ performSearch: function(searchQuery)
+ {
+ this._searchRegExp = createPlainTextSearchRegex(searchQuery, "i");
+ delete this._searchResults;
+ this._updateSearchHighlight(true);
}
}
@@ -1151,6 +1302,13 @@
}
},
+ highlight: function(regExp, domChanges)
+ {
+ var matchInfo = this.element.textContent.match(regExp);
+ if (matchInfo)
+ WebInspector.highlightSearchResult(this.element, matchInfo.index, matchInfo[0].length, domChanges);
+ },
+
dispose: function()
{
this.element.parentElement.removeChild(this.element);
@@ -1158,6 +1316,15 @@
}
/**
+ * @param {!WebInspector.TimelinePresentationModel.Record} record
+ * @param {!RegExp} regExp
+ */
+WebInspector.TimelineRecordListRow.testContentMatching = function(record, regExp)
+{
+ return regExp.test(record.title + " (" + record.details() + ")");
+}
+
+/**
* @constructor
*/
WebInspector.TimelineRecordGraphRow = function(graphContainer, scheduleRefresh)
@@ -1271,7 +1438,8 @@
WebInspector.TimelineCategoryFilter.prototype = {
/**
- * @param {WebInspector.TimelinePresentationModel.Record} record
+ * @param {!WebInspector.TimelinePresentationModel.Record} record
+ * @return {boolean}
*/
accept: function(record)
{
@@ -1291,10 +1459,33 @@
WebInspector.TimelineIsLongFilter.prototype = {
/**
- * @param {WebInspector.TimelinePresentationModel.Record} record
+ * @param {!WebInspector.TimelinePresentationModel.Record} record
+ * @return {boolean}
*/
accept: function(record)
{
return this._panel._showShortEvents || record.isLong();
}
}
+
+/**
+ * @param {!RegExp} regExp
+ * @constructor
+ * @implements {WebInspector.TimelinePresentationModel.Filter}
+ */
+WebInspector.TimelineSearchFilter = function(regExp)
+{
+ this._regExp = regExp;
+}
+
+WebInspector.TimelineSearchFilter.prototype = {
+
+ /**
+ * @param {!WebInspector.TimelinePresentationModel.Record} record
+ * @return {boolean}
+ */
+ accept: function(record)
+ {
+ return WebInspector.TimelineRecordListRow.testContentMatching(record, this._regExp);
+ }
+}
Modified: trunk/Source/WebCore/inspector/front-end/TimelinePresentationModel.js (128280 => 128281)
--- trunk/Source/WebCore/inspector/front-end/TimelinePresentationModel.js 2012-09-12 09:17:25 UTC (rev 128280)
+++ trunk/Source/WebCore/inspector/front-end/TimelinePresentationModel.js 2012-09-12 09:32:39 UTC (rev 128281)
@@ -226,13 +226,23 @@
WebInspector.TimelinePresentationModel.prototype = {
/**
- * @param {WebInspector.TimelinePresentationModel.Filter} filter
+ * @param {!WebInspector.TimelinePresentationModel.Filter} filter
*/
addFilter: function(filter)
{
this._filters.push(filter);
},
+ /**
+ * @param {!WebInspector.TimelinePresentationModel.Filter} filter
+ */
+ removeFilter: function(filter)
+ {
+ var index = this._filters.indexOf(filter);
+ if (index !== -1)
+ this._filters.splice(index, 1);
+ },
+
rootRecord: function()
{
return this._rootRecord;
@@ -1112,7 +1122,8 @@
WebInspector.TimelinePresentationModel.Filter.prototype = {
/**
- * @param {WebInspector.TimelinePresentationModel.Record} record
+ * @param {!WebInspector.TimelinePresentationModel.Record} record
+ * @return {boolean}
*/
accept: function(record) { return false; }
}