Web Inspector: Script ProfileViews should be searchable
https://bugs.webkit.org/show_bug.cgi?id=157581
<rdar://problem/26228530>
Reviewed by Joseph Pecoraro.
* UserInterface/Views/DataGrid.js:
(WebInspector.DataGrid.prototype.get filterText):
Make filterText readable.
* UserInterface/Views/ProfileDataGridNode.js:
(WebInspector.ProfileDataGridNode.prototype.get callingContextTreeNode):
(WebInspector.ProfileDataGridNode.prototype.filterableDataForColumn):
Add filterable data for the "function" column.
(WebInspector.ProfileDataGridNode.prototype._updateChildrenForModifiers):
(WebInspector.ProfileDataGridNode.prototype.get node): Deleted.
Renamed callingContextTreeNode to be less ambiguous.
* UserInterface/Views/ProfileDataGridTree.js:
(WebInspector.ProfileDataGridTree.prototype._updateCurrentFocusDetails):
* UserInterface/Views/ProfileView.js:
(WebInspector.ProfileView.prototype.get dataGrid):
Expose data grid for use in parent view.
* UserInterface/Views/ScriptClusterTimelineView.js:
(WebInspector.ScriptClusterTimelineView.prototype.selectRecord):
Drive-by fix: forward property to current child TimelineView.
* UserInterface/Views/ScriptProfileTimelineView.js:
(WebInspector.ScriptProfileTimelineView):
(WebInspector.ScriptProfileTimelineView.prototype._scopeBarSelectionDidChange):
(WebInspector.ScriptProfileTimelineView.prototype._showProfileViewForOrientation):
Helper function to switch profile views. Persist filter text when
switching to the new profile view.
(WebInspector.ScriptProfileTimelineView.prototype.get showsFilterBar): Deleted.
Remove FIXME and show filter bar.
* UserInterface/Views/TimelineView.js:
(WebInspector.TimelineView.prototype.setupDataGrid):
Support switching to a new data grid.
(WebInspector.TimelineView.prototype.dataGridMatchNodeAgainstCustomFilters):
Hooking up filtering causes data grid nodes to be filtered based on the
ruler selection. Although ScriptProfileTimelineView performs its own
time-based filtering, this is necessary to prevent an assert.
(WebInspector.TimelineView.prototype._timelineDataGridSelectedNodeChanged):
(WebInspector.TimelineView.prototype._timelineDataGridNodeWasFiltered):
Converted arrow functions to member functions to allow unregistering
event listeners on outgoing data grid when swapping grids.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@200873 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebInspectorUI/ChangeLog b/Source/WebInspectorUI/ChangeLog
index dbb1ba7..a3d51f6 100644
--- a/Source/WebInspectorUI/ChangeLog
+++ b/Source/WebInspectorUI/ChangeLog
@@ -1,3 +1,57 @@
+2016-05-13 Matt Baker <mattbaker@apple.com>
+
+ Web Inspector: Script ProfileViews should be searchable
+ https://bugs.webkit.org/show_bug.cgi?id=157581
+ <rdar://problem/26228530>
+
+ Reviewed by Joseph Pecoraro.
+
+ * UserInterface/Views/DataGrid.js:
+ (WebInspector.DataGrid.prototype.get filterText):
+ Make filterText readable.
+
+ * UserInterface/Views/ProfileDataGridNode.js:
+ (WebInspector.ProfileDataGridNode.prototype.get callingContextTreeNode):
+ (WebInspector.ProfileDataGridNode.prototype.filterableDataForColumn):
+ Add filterable data for the "function" column.
+ (WebInspector.ProfileDataGridNode.prototype._updateChildrenForModifiers):
+ (WebInspector.ProfileDataGridNode.prototype.get node): Deleted.
+ Renamed callingContextTreeNode to be less ambiguous.
+
+ * UserInterface/Views/ProfileDataGridTree.js:
+ (WebInspector.ProfileDataGridTree.prototype._updateCurrentFocusDetails):
+
+ * UserInterface/Views/ProfileView.js:
+ (WebInspector.ProfileView.prototype.get dataGrid):
+ Expose data grid for use in parent view.
+
+ * UserInterface/Views/ScriptClusterTimelineView.js:
+ (WebInspector.ScriptClusterTimelineView.prototype.selectRecord):
+ Drive-by fix: forward property to current child TimelineView.
+
+ * UserInterface/Views/ScriptProfileTimelineView.js:
+ (WebInspector.ScriptProfileTimelineView):
+ (WebInspector.ScriptProfileTimelineView.prototype._scopeBarSelectionDidChange):
+ (WebInspector.ScriptProfileTimelineView.prototype._showProfileViewForOrientation):
+ Helper function to switch profile views. Persist filter text when
+ switching to the new profile view.
+
+ (WebInspector.ScriptProfileTimelineView.prototype.get showsFilterBar): Deleted.
+ Remove FIXME and show filter bar.
+
+ * UserInterface/Views/TimelineView.js:
+ (WebInspector.TimelineView.prototype.setupDataGrid):
+ Support switching to a new data grid.
+ (WebInspector.TimelineView.prototype.dataGridMatchNodeAgainstCustomFilters):
+ Hooking up filtering causes data grid nodes to be filtered based on the
+ ruler selection. Although ScriptProfileTimelineView performs its own
+ time-based filtering, this is necessary to prevent an assert.
+
+ (WebInspector.TimelineView.prototype._timelineDataGridSelectedNodeChanged):
+ (WebInspector.TimelineView.prototype._timelineDataGridNodeWasFiltered):
+ Converted arrow functions to member functions to allow unregistering
+ event listeners on outgoing data grid when swapping grids.
+
2016-05-12 Matt Baker <mattbaker@apple.com>
Web Inspector: Remove "Extra Scripts" folder from Resources sidebar if all children removed
diff --git a/Source/WebInspectorUI/UserInterface/Views/DataGrid.js b/Source/WebInspectorUI/UserInterface/Views/DataGrid.js
index 4205492..ca4b961 100644
--- a/Source/WebInspectorUI/UserInterface/Views/DataGrid.js
+++ b/Source/WebInspectorUI/UserInterface/Views/DataGrid.js
@@ -278,6 +278,8 @@
this._updateScrollListeners();
}
+ get filterText() { return this._filterText; }
+
set filterText(x)
{
if (this._filterText === x)
diff --git a/Source/WebInspectorUI/UserInterface/Views/ProfileDataGridNode.js b/Source/WebInspectorUI/UserInterface/Views/ProfileDataGridNode.js
index f839332..25f161f 100644
--- a/Source/WebInspectorUI/UserInterface/Views/ProfileDataGridNode.js
+++ b/Source/WebInspectorUI/UserInterface/Views/ProfileDataGridNode.js
@@ -46,7 +46,7 @@
// Public
- get node() { return this._node; }
+ get callingContextTreeNode() { return this._node; }
displayName()
{
@@ -124,6 +124,21 @@
contextMenu.appendSeparator();
}
+ // Protected
+
+ filterableDataForColumn(columnIdentifier)
+ {
+ if (columnIdentifier === "function") {
+ let filterableData = [this.displayName()];
+ let script = WebInspector.debuggerManager.scriptForIdentifier(this._node.sourceID);
+ if (script && script.url && this._node.line >= 0 && this._node.column >= 0)
+ filterableData.push(script.url);
+ return filterableData;
+ }
+
+ return super.filterableDataForColumn(columnIdentifier);
+ }
+
// Private
_updateChildrenForModifiers()
@@ -174,7 +189,7 @@
// Remove child data grid nodes that have been charged to us.
if (!this.shouldRefreshChildren && this._childrenToChargeToSelf.size) {
for (let childDataGridNode of this.children) {
- if (this._childrenToChargeToSelf.has(childDataGridNode.node))
+ if (this._childrenToChargeToSelf.has(childDataGridNode.callingContextTreeNode))
this.removeChild(childDataGridNode);
}
}
diff --git a/Source/WebInspectorUI/UserInterface/Views/ProfileDataGridTree.js b/Source/WebInspectorUI/UserInterface/Views/ProfileDataGridTree.js
index 00bc0c2..dcfd2c9 100644
--- a/Source/WebInspectorUI/UserInterface/Views/ProfileDataGridTree.js
+++ b/Source/WebInspectorUI/UserInterface/Views/ProfileDataGridTree.js
@@ -239,7 +239,7 @@
_updateCurrentFocusDetails(focusDataGridNode)
{
- let cctNode = focusDataGridNode.node;
+ let cctNode = focusDataGridNode.callingContextTreeNode;
let {timestamps, duration} = cctNode.filteredTimestampsAndDuration(this._startTime, this._endTime);
this._currentFocusStartTime = timestamps[0];
diff --git a/Source/WebInspectorUI/UserInterface/Views/ProfileView.js b/Source/WebInspectorUI/UserInterface/Views/ProfileView.js
index f40893b..64bb7e3 100644
--- a/Source/WebInspectorUI/UserInterface/Views/ProfileView.js
+++ b/Source/WebInspectorUI/UserInterface/Views/ProfileView.js
@@ -76,6 +76,7 @@
get callingContextTree() { return this._callingContextTree; }
get startTime() { return this._startTime; }
get endTime() { return this._endTime; }
+ get dataGrid() { return this._dataGrid; }
setStartAndEndTime(startTime, endTime)
{
diff --git a/Source/WebInspectorUI/UserInterface/Views/ScriptClusterTimelineView.js b/Source/WebInspectorUI/UserInterface/Views/ScriptClusterTimelineView.js
index cce1a49..ef2ae30 100644
--- a/Source/WebInspectorUI/UserInterface/Views/ScriptClusterTimelineView.js
+++ b/Source/WebInspectorUI/UserInterface/Views/ScriptClusterTimelineView.js
@@ -71,6 +71,8 @@
set endTime(x) { this._contentViewContainer.currentContentView.endTime = x; }
get currentTime() { return this._contentViewContainer.currentContentView.currentTime; }
set currentTime(x) { this._contentViewContainer.currentContentView.currentTime = x; }
+
+ selectRecord(record) { this._contentViewContainer.currentContentView.selectRecord(record); }
updateFilter(filters) { return this._contentViewContainer.currentContentView.updateFilter(filters); }
filterDidChange() { return this._contentViewContainer.currentContentView.filterDidChange(); }
matchDataGridNodeAgainstCustomFilters(node) { return this._contentViewContainer.currentContentView.matchDataGridNodeAgainstCustomFilters(node); }
diff --git a/Source/WebInspectorUI/UserInterface/Views/ScriptProfileTimelineView.js b/Source/WebInspectorUI/UserInterface/Views/ScriptProfileTimelineView.js
index 1540510..6d59e94 100644
--- a/Source/WebInspectorUI/UserInterface/Views/ScriptProfileTimelineView.js
+++ b/Source/WebInspectorUI/UserInterface/Views/ScriptProfileTimelineView.js
@@ -42,10 +42,7 @@
if (!WebInspector.ScriptProfileTimelineView.profileOrientationSetting)
WebInspector.ScriptProfileTimelineView.profileOrientationSetting = new WebInspector.Setting("script-profile-timeline-view-profile-orientation-setting", WebInspector.ScriptProfileTimelineView.ProfileOrientation.TopDown);
- let callingContextTree = this._callingContextTreeForOrientation(WebInspector.ScriptProfileTimelineView.profileOrientationSetting.value);
- this._profileView = new WebInspector.ProfileView(callingContextTree);
- this._profileView.addEventListener(WebInspector.ContentView.Event.SelectionPathComponentsDidChange, this._profileViewSelectionPathComponentsDidChange, this);
- this.addSubview(this._profileView);
+ this._showProfileViewForOrientation(WebInspector.ScriptProfileTimelineView.profileOrientationSetting.value);
let scopeBarItems = [
new WebInspector.ScopeBarItem(WebInspector.ScriptProfileTimelineView.ProfileOrientation.TopDown, WebInspector.UIString("Top Down"), true),
@@ -61,17 +58,12 @@
this._updateClearFocusNodesButtonItem();
timeline.addEventListener(WebInspector.Timeline.Event.Refreshed, this._scriptTimelineRecordRefreshed, this);
-
- // FIXME: Support filtering the ProfileView.
}
// Public
get showsLiveRecordingData() { return false; }
- // FIXME: <https://webkit.org/b/157581> Web Inspector: Script ProfileViews should be searchable
- get showsFilterBar() { return false; }
-
// Protected
closed()
@@ -130,17 +122,9 @@
{
let currentOrientation = WebInspector.ScriptProfileTimelineView.profileOrientationSetting.value;
let newOrientation = this._profileOrientationScopeBar.selectedItems[0].id;
- let callingContextTree = this._callingContextTreeForOrientation(newOrientation);
WebInspector.ScriptProfileTimelineView.profileOrientationSetting.value = newOrientation;
-
- this.removeSubview(this._profileView);
- this._profileView.removeEventListener(WebInspector.ContentView.Event.SelectionPathComponentsDidChange, this._profileViewSelectionPathComponentsDidChange, this);
-
- this._profileView = new WebInspector.ProfileView(callingContextTree);
-
- this._profileView.addEventListener(WebInspector.ContentView.Event.SelectionPathComponentsDidChange, this._profileViewSelectionPathComponentsDidChange, this);
- this.addSubview(this._profileView);
+ this._showProfileViewForOrientation(newOrientation);
this.dispatchEventToListeners(WebInspector.ContentView.Event.SelectionPathComponentsDidChange);
@@ -148,6 +132,26 @@
this.needsLayout();
}
+ _showProfileViewForOrientation(orientation)
+ {
+ let filterText;
+ if (this._profileView) {
+ this._profileView.removeEventListener(WebInspector.ContentView.Event.SelectionPathComponentsDidChange, this._profileViewSelectionPathComponentsDidChange, this);
+ this.removeSubview(this._profileView);
+ filterText = this._profileView.dataGrid.filterText;
+ }
+
+ let callingContextTree = this._callingContextTreeForOrientation(orientation);
+ this._profileView = new WebInspector.ProfileView(callingContextTree);
+ this._profileView.addEventListener(WebInspector.ContentView.Event.SelectionPathComponentsDidChange, this._profileViewSelectionPathComponentsDidChange, this);
+
+ this.addSubview(this._profileView);
+ this.setupDataGrid(this._profileView.dataGrid);
+
+ if (filterText)
+ this._profileView.dataGrid.filterText = filterText;
+ }
+
_updateClearFocusNodesButtonItem()
{
this._clearFocusNodesButtonItem.enabled = this._profileView.hasFocusNodes();
diff --git a/Source/WebInspectorUI/UserInterface/Views/TimelineView.js b/Source/WebInspectorUI/UserInterface/Views/TimelineView.js
index 628c743..56dc701 100644
--- a/Source/WebInspectorUI/UserInterface/Views/TimelineView.js
+++ b/Source/WebInspectorUI/UserInterface/Views/TimelineView.js
@@ -158,25 +158,18 @@
setupDataGrid(dataGrid)
{
- console.assert(!this._timelineDataGrid);
+ if (this._timelineDataGrid) {
+ this._timelineDataGrid.filterDelegate = null;
+ this._timelineDataGrid.removeEventListener(WebInspector.DataGrid.Event.SelectedNodeChanged, this._timelineDataGridSelectedNodeChanged, this);
+ this._timelineDataGrid.removeEventListener(WebInspector.DataGrid.Event.NodeWasFiltered, this._timelineDataGridNodeWasFiltered, this);
+ this._timelineDataGrid.removeEventListener(WebInspector.DataGrid.Event.FilterDidChange, this.filterDidChange, this);
+ }
this._timelineDataGrid = dataGrid;
this._timelineDataGrid.filterDelegate = this;
- this._timelineDataGrid.addEventListener(WebInspector.DataGrid.Event.SelectedNodeChanged, () => {
- this.dispatchEventToListeners(WebInspector.ContentView.Event.SelectionPathComponentsDidChange);
- });
-
- this._timelineDataGrid.addEventListener(WebInspector.DataGrid.Event.NodeWasFiltered, (event) => {
- let node = event.data.node;
- if (!(node instanceof WebInspector.TimelineDataGridNode))
- return;
-
- this.dispatchEventToListeners(WebInspector.TimelineView.Event.RecordWasFiltered, {record: node.record, filtered: node.hidden});
- });
-
- this._timelineDataGrid.addEventListener(WebInspector.DataGrid.Event.FilterDidChange, (event) => {
- this.filterDidChange();
- });
+ this._timelineDataGrid.addEventListener(WebInspector.DataGrid.Event.SelectedNodeChanged, this._timelineDataGridSelectedNodeChanged, this);
+ this._timelineDataGrid.addEventListener(WebInspector.DataGrid.Event.NodeWasFiltered, this._timelineDataGridNodeWasFiltered, this);
+ this._timelineDataGrid.addEventListener(WebInspector.DataGrid.Event.FilterDidChange, this.filterDidChange, this);
}
selectRecord(record)
@@ -284,6 +277,9 @@
return checkTimeBounds(record.startTime, record.endTime);
}
+ if (node instanceof WebInspector.ProfileDataGridNode)
+ return node.callingContextTreeNode.hasStackTraceInTimeRange(startTime, endTime);
+
console.error("Unknown DataGridNode, can't filter by time.");
return true;
}
@@ -302,6 +298,20 @@
// Private
+ _timelineDataGridSelectedNodeChanged(event)
+ {
+ this.dispatchEventToListeners(WebInspector.ContentView.Event.SelectionPathComponentsDidChange);
+ }
+
+ _timelineDataGridNodeWasFiltered(event)
+ {
+ let node = event.data.node;
+ if (!(node instanceof WebInspector.TimelineDataGridNode))
+ return;
+
+ this.dispatchEventToListeners(WebInspector.TimelineView.Event.RecordWasFiltered, {record: node.record, filtered: node.hidden});
+ }
+
_timesDidChange()
{
if (!WebInspector.timelineManager.isCapturing() || this.showsLiveRecordingData)